Init Commit

main
exsersewo 2 years ago
commit cca72cf225
Signed by: exsersewo
GPG Key ID: 9C6DDF9AC9BA14A0
  1. 5
      .gitignore
  2. 13
      .idea/.idea.DreamsCaster/.idea/.gitignore
  3. 8
      .idea/.idea.DreamsCaster/.idea/indexLayout.xml
  4. 6
      .idea/.idea.DreamsCaster/.idea/vcs.xml
  5. 16
      DreamsCaster.sln
  6. 25
      DreamsCaster/.dockerignore
  7. 26
      DreamsCaster/AppDbContext.cs
  8. 90
      DreamsCaster/Controllers/ConsoleController.cs
  9. 192
      DreamsCaster/Controllers/GameController.cs
  10. 20
      DreamsCaster/Dockerfile
  11. 17
      DreamsCaster/DreamsCaster.csproj
  12. 15
      DreamsCaster/Helpers/Optional.cs
  13. 17
      DreamsCaster/Models/Common.cs
  14. 10
      DreamsCaster/Models/Console.cs
  15. 10
      DreamsCaster/Models/Game.cs
  16. 19
      DreamsCaster/Models/Release.cs
  17. 25
      DreamsCaster/Program.cs
  18. 31
      DreamsCaster/Properties/launchSettings.json
  19. 8
      DreamsCaster/appsettings.Development.json
  20. 9
      DreamsCaster/appsettings.json

5
.gitignore vendored

@ -0,0 +1,5 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/.idea.DreamsCaster.iml
/contentModel.xml
/projectSettingsUpdater.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DreamsCaster", "DreamsCaster\DreamsCaster.csproj", "{7EF668EB-6D79-4A51-A161-F4E99DCCD789}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7EF668EB-6D79-4A51-A161-F4E99DCCD789}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EF668EB-6D79-4A51-A161-F4E99DCCD789}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EF668EB-6D79-4A51-A161-F4E99DCCD789}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EF668EB-6D79-4A51-A161-F4E99DCCD789}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

@ -0,0 +1,25 @@
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.idea
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

@ -0,0 +1,26 @@
using DreamsCaster.Models;
using Microsoft.EntityFrameworkCore;
using Console = DreamsCaster.Models.Console;
namespace DreamsCaster;
public class AppDbContext : DbContext
{
public DbSet<Game> Games;
public DbSet<Console> Consoles;
}
public static class DatabaseExtensions
{
public static bool TryGet<T>(this IEnumerable<T> haystack, Guid id, out T val) where T : IdEntity
{
if (haystack.Select(hay => hay.Id).Contains(id))
{
val = haystack.FirstOrDefault(hay => hay.Id.Equals(id));
return true;
}
val = null;
return false;
}
}

@ -0,0 +1,90 @@
using DreamsCaster.Helpers;
using DreamsCaster.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Console = System.Console;
namespace DreamsCaster.Controllers;
[ApiController]
[Route("[controller]")]
public class ConsoleController : ControllerBase
{
public AppDbContext Database { get; set; }
[HttpGet]
public IActionResult Get([FromQuery] Guid consoleId)
{
if (!Database.Consoles.TryGet(consoleId, out Game game)) return NotFound();
return Ok(game);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> DeleteAsync([FromQuery] Guid consoleId)
{
if (!Database.Games.TryGet(consoleId, out var game)) return NotFound();
foreach (var release in game.Releases)
{
Database.Remove(release);
}
await Database.SaveChangesAsync();
Database.Games.Remove(game);
await Database.SaveChangesAsync();
return Ok();
}
[HttpPatch]
[Authorize]
public async Task<IActionResult> PatchAsync([FromQuery] Guid consoleId)
{
}
[HttpPost]
[Authorize]
public async Task<IActionResult> PostAsync([FromBody] PostGame newGame)
{
try
{
var game = Database.Games.Add(new Game()
{
Name = newGame.Name,
Data = new MetaData<Game>()
{
CoverPhoto = newGame.CoverPhoto,
Description = newGame.Description
}
});
await Database.SaveChangesAsync();
foreach (var release in newGame.Releases)
{
if (!Database.Consoles.TryGet(release.ConsoleId, out var console)) continue;
game.Entity.Releases.Add(new Release()
{
ReleaseDate = release.Release,
Console = console
});
}
await Database.SaveChangesAsync();
return Ok(game);
}
catch (Exception ex)
{
Console.WriteLine(ex);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

@ -0,0 +1,192 @@
using System.Runtime.InteropServices.ComTypes;
using DreamsCaster.Helpers;
using DreamsCaster.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Console = System.Console;
namespace DreamsCaster.Controllers;
[ApiController]
[Route("[controller]")]
public class GameController : ControllerBase
{
public class PostRelease
{
public DateTime Release;
public Guid ConsoleId;
}
public class PostGame
{
public string Name;
public string Description;
public string CoverPhoto;
public List<PostRelease> Releases;
}
public class PatchGame
{
public Optional<string> Name;
public Optional<string> Description;
public Optional<string> CoverPhoto;
}
public AppDbContext Database { get; set; }
#region Game CRUD
[HttpGet]
public IActionResult Get([FromQuery] Guid gameId)
{
if (!Database.Games.TryGet(gameId, out Game game)) return NotFound();
return Ok(game);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> DeleteAsync([FromQuery] Guid gameId)
{
if (!Database.Games.TryGet(gameId, out var game)) return NotFound();
foreach (var release in game.Releases)
{
Database.Remove(release);
}
await Database.SaveChangesAsync();
Database.Games.Remove(game);
await Database.SaveChangesAsync();
return Ok();
}
[HttpPatch]
[Authorize]
public async Task<IActionResult> PatchAsync([FromQuery] Guid gameId, [FromBody] PatchGame newData)
{
if (!Database.Games.TryGet(gameId, out Game game)) return NotFound();
if (newData.Name.HasValue) game.Name = newData.Name;
if (newData.Description.HasValue) game.Data.Description = newData.Description;
if (newData.CoverPhoto.HasValue) game.Data.CoverPhoto = newData.CoverPhoto;
await Database.SaveChangesAsync();
return Ok(game);
}
[HttpPost]
[Authorize]
public async Task<IActionResult> PostAsync([FromBody] PostGame newGame)
{
try
{
var game = Database.Games.Add(new Game()
{
Name = newGame.Name,
Data = new MetaData<Game>()
{
CoverPhoto = newGame.CoverPhoto,
Description = newGame.Description
}
});
await Database.SaveChangesAsync();
foreach (var release in newGame.Releases)
{
if (!Database.Consoles.TryGet(release.ConsoleId, out var console)) continue;
game.Entity.Releases.Add(new Release()
{
ReleaseDate = release.Release,
Console = console
});
}
await Database.SaveChangesAsync();
return Ok(game);
}
catch (Exception ex)
{
Console.WriteLine(ex);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
#endregion Game CRUD
#region Releases CUD
[HttpPatch("{gameId:guid}/releases")]
[Authorize]
public async Task<IActionResult> PatchReleaseAsync([FromQuery] Guid gameId, [FromBody] PostRelease release)
{
if (!Database.Games.TryGet(gameId, out Game game)) return NotFound();
if (!Database.Consoles.TryGet(release.ConsoleId, out var console)) return NotFound();
try
{
game.Releases.Add(Release.New(release.Release, console));
await Database.SaveChangesAsync();
return Ok();
}
catch (Exception ex)
{
Console.WriteLine(ex);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut("{gameId:guid}/releases/{releaseId:guid}")]
[Authorize]
public async Task<IActionResult> PatchReleaseAsync([FromQuery] Guid gameId, [FromQuery] Guid releaseId, [FromBody] DateTime newReleaseDate)
{
if (!Database.Games.TryGet(gameId, out Game game)) return NotFound();
if (!game.Releases.TryGet(releaseId, out var release)) return NotFound();
try
{
release.ReleaseDate = newReleaseDate;
await Database.SaveChangesAsync();
return Ok();
}
catch (Exception ex)
{
Console.WriteLine(ex);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{gameId:guid}/releases/{releaseId:guid}")]
[Authorize]
public async Task<IActionResult> DeleteReleaseAsync([FromQuery] Guid gameId, [FromQuery] Guid releaseId)
{
if (!Database.Games.TryGet(gameId, out Game game)) return NotFound();
if (!game.Releases.TryGet(releaseId, out Release release)) return NotFound();
try
{
game.Releases.Remove(release);
return Ok();
}
catch (Exception ex)
{
Console.WriteLine(ex);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
#endregion Releases CUD
}

@ -0,0 +1,20 @@
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["DreamsCaster/DreamsCaster.csproj", "DreamsCaster/"]
RUN dotnet restore "DreamsCaster/DreamsCaster.csproj"
COPY . .
WORKDIR "/src/DreamsCaster"
RUN dotnet build "DreamsCaster.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DreamsCaster.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DreamsCaster.dll"]

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.10" />
<PackageReference Include="PagedList.EntityFramework" Version="1.0.1" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>

@ -0,0 +1,15 @@
namespace DreamsCaster.Helpers;
public struct Optional<T>
{
public bool HasValue;
public T Value;
public Optional(bool hasValue, T value)
{
HasValue = hasValue;
Value = value;
}
public static implicit operator T(Optional<T> d) => d.HasValue ? d.Value : default;
}

@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace DreamsCaster.Models;
public class IdEntity
{
public Guid Id;
}
public class MetaData<T> : IdEntity
{
public string Description;
public string CoverPhoto;
[Required]
public virtual T Owner { get; set; }
}

@ -0,0 +1,10 @@
namespace DreamsCaster.Models;
public class Console : IdEntity
{
public string Name;
public virtual ICollection<Game> Games { get; set; }
public virtual MetaData<Console> Data { get; set; }
}

@ -0,0 +1,10 @@
namespace DreamsCaster.Models;
public class Game : IdEntity
{
public string Name;
public ICollection<Release> Releases;
public virtual MetaData<Game> Data { get; set; }
}

@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
namespace DreamsCaster.Models;
public class Release : IdEntity
{
public DateTime ReleaseDate;
[Required]
public virtual Game Game { get; set; }
[Required]
public virtual Console Console { get; set; }
public static Release New(DateTime date, Console console)
=> new()
{
ReleaseDate = date, Console = console
};
}

@ -0,0 +1,25 @@
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:1386",
"sslPort": 44381
}
},
"profiles": {
"DreamsCaster": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7058;http://localhost:5273",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Loading…
Cancel
Save