diff --git a/.github/config/gitversion.yml b/.github/config/gitversion.yml index 9cab8c0..dbd1c3a 100644 --- a/.github/config/gitversion.yml +++ b/.github/config/gitversion.yml @@ -1,4 +1,4 @@ -next-version: 0.4.0 +next-version: 0.5.0 assembly-versioning-scheme: MajorMinorPatch assembly-file-versioning-scheme: MajorMinorPatch diff --git a/.github/workflows/dev_pr.yml b/.github/workflows/dev_pr.yml index 99c2f76..8a66de2 100644 --- a/.github/workflows/dev_pr.yml +++ b/.github/workflows/dev_pr.yml @@ -17,7 +17,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/.github/workflows/dev_push.yml b/.github/workflows/dev_push.yml index d8ff959..b57596d 100644 --- a/.github/workflows/dev_push.yml +++ b/.github/workflows/dev_push.yml @@ -17,7 +17,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/.github/workflows/master_pr.yml b/.github/workflows/master_pr.yml index da7ef70..3dae43b 100644 --- a/.github/workflows/master_pr.yml +++ b/.github/workflows/master_pr.yml @@ -15,7 +15,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore - name: Build solution @@ -42,4 +42,4 @@ jobs: with: string: ${{ matrix.app }} - name: Build image - run: docker build ${{ github.workspace }} -t ghcr.io/${{github.actor}}/${{ steps.name.outputs.lowercase }}:build-test -f ${{ github.workspace }}/${{ matrix.app }}/${{ matrix.app }}/Dockerfile + run: docker build ${{ github.workspace }} -t ghcr.io/${{github.actor}}/${{ steps.name.outputs.lowercase }}:build-test -f ${{ github.workspace }}/${{ matrix.app }}/Dockerfile diff --git a/.github/workflows/master_push.yml b/.github/workflows/master_push.yml index 3dd2878..028c87b 100644 --- a/.github/workflows/master_push.yml +++ b/.github/workflows/master_push.yml @@ -33,7 +33,7 @@ jobs: uses: microsoft/variable-substitution@v1 if: ${{ matrix.app == 'WatchIt.WebAPI' }} with: - files: ${{ github.workspace }}/${{ matrix.app }}/${{ matrix.app }}/appsettings.json + files: ${{ github.workspace }}/${{ matrix.app }}/appsettings.json env: ConnectionStrings.Default: ${{ secrets.CONNECTION_STRING }} RootUser.Email: ${{ secrets.ROOT_EMAIL }} @@ -43,7 +43,7 @@ jobs: uses: microsoft/variable-substitution@v1 if: ${{ matrix.app == 'WatchIt.Website' }} with: - files: ${{ github.workspace }}/${{ matrix.app }}/${{ matrix.app }}/appsettings.json + files: ${{ github.workspace }}/${{ matrix.app }}/appsettings.json env: Endpoints.Base: ${{ secrets.API_URL }} - name: Set up Docker Buildx @@ -60,7 +60,7 @@ jobs: with: string: ${{ matrix.app }} - name: Build image - run: docker build ${{ github.workspace }} -t ghcr.io/${{github.actor}}/${{ steps.name.outputs.lowercase }}:latest -t ghcr.io/${{github.actor}}/${{ steps.name.outputs.lowercase }}:${{steps.gitversion.outputs.SemVer}} -f ${{ github.workspace }}/${{ matrix.app }}/${{ matrix.app }}/Dockerfile + run: docker build ${{ github.workspace }} -t ghcr.io/${{github.actor}}/${{ steps.name.outputs.lowercase }}:latest -t ghcr.io/${{github.actor}}/${{ steps.name.outputs.lowercase }}:${{steps.gitversion.outputs.SemVer}} -f ${{ github.workspace }}/${{ matrix.app }}/Dockerfile - name: Publish image run: docker push ghcr.io/${{github.actor}}/${{ steps.name.outputs.lowercase }} --all-tags outputs: @@ -83,6 +83,7 @@ jobs: name: Deploy runs-on: watchit needs: publish + if: false steps: - name: Login to GitHub Container Registry uses: docker/login-action@v1 diff --git a/README.md b/README.md deleted file mode 100644 index 3871bbb..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# WatchIt diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/Account.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/Account.cs deleted file mode 100644 index e96ec0f..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/Account.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public abstract class Account -{ - #region PROPERTIES - - [JsonPropertyName("username")] - public required string Username { get; set; } - - [JsonPropertyName("email")] - public required string Email { get; set; } - - [JsonPropertyName("description")] - public string? Description { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountEmailRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountEmailRequest.cs deleted file mode 100644 index bdf5bab..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountEmailRequest.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountEmailRequest -{ - #region PROPERTIES - - [JsonPropertyName("new_email")] - public string NewEmail { get; set; } - - [JsonPropertyName("password")] - public string Password { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - public void UpdateAccount(Database.Model.Account.Account account) - { - account.Email = NewEmail; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountPasswordRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountPasswordRequest.cs deleted file mode 100644 index e0048c1..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountPasswordRequest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountPasswordRequest -{ - #region PROPERTIES - - [JsonPropertyName("old_password")] - public string OldPassword { get; set; } - - [JsonPropertyName("new_password")] - public string NewPassword { get; set; } - - [JsonPropertyName("new_password_confirmation")] - public string NewPasswordConfirmation { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfileBackgroundRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfileBackgroundRequest.cs deleted file mode 100644 index 6f8ce7b..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfileBackgroundRequest.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountProfileBackgroundRequest -{ - #region PROPERTIES - - [JsonPropertyName("id")] - public required Guid Id { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [SetsRequiredMembers] - public AccountProfileBackgroundRequest(Guid id) - { - Id = id; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfileInfoRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfileInfoRequest.cs deleted file mode 100644 index e26f615..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfileInfoRequest.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountProfileInfoRequest -{ - #region PROPERTIES - - [JsonPropertyName("description")] - public string? Description { get; set; } - - [JsonPropertyName("gender_id")] - public short? GenderId { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - public AccountProfileInfoRequest() { } - - public AccountProfileInfoRequest(AccountResponse accountResponse) - { - Description = accountResponse.Description; - GenderId = accountResponse.Gender?.Id; - } - - #endregion - - - - #region PUBLIC METHODS - - public void UpdateAccount(Database.Model.Account.Account account) - { - account.Description = Description; - account.GenderId = GenderId; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePicture.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePicture.cs deleted file mode 100644 index 06114ee..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePicture.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public abstract class AccountProfilePicture : Picture -{ - #region CONSTRUCTORS - - [JsonConstructor] - public AccountProfilePicture() {} - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePictureRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePictureRequest.cs deleted file mode 100644 index 1fbea18..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePictureRequest.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountProfilePictureRequest : AccountProfilePicture -{ - #region CONSTRUCTORS - - public AccountProfilePictureRequest() {} - - [SetsRequiredMembers] - public AccountProfilePictureRequest(Picture image) - { - Image = image.Image; - MimeType = image.MimeType; - } - - #endregion - - - public Database.Model.Account.AccountProfilePicture CreateMediaPosterImage() => new Database.Model.Account.AccountProfilePicture - { - Image = Image, - MimeType = MimeType, - }; - - public void UpdateMediaPosterImage(Database.Model.Account.AccountProfilePicture item) - { - item.Image = Image; - item.MimeType = MimeType; - item.UploadDate = DateTime.UtcNow; - } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePictureResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePictureResponse.cs deleted file mode 100644 index 4481524..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountProfilePictureResponse.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountProfilePictureResponse : AccountProfilePicture -{ - #region PROPERTIES - - [JsonPropertyName("id")] - public required Guid Id { get; set; } - - [JsonPropertyName("upload_date")] - public required DateTime UploadDate { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public AccountProfilePictureResponse() {} - - [SetsRequiredMembers] - public AccountProfilePictureResponse(Database.Model.Account.AccountProfilePicture accountProfilePicture) - { - Id = accountProfilePicture.Id; - Image = accountProfilePicture.Image; - MimeType = accountProfilePicture.MimeType; - UploadDate = accountProfilePicture.UploadDate; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountQueryParameters.cs deleted file mode 100644 index 88221db..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountQueryParameters.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "username")] - public string? Username { get; set; } - - [FromQuery(Name = "email")] - public string? Email { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - [FromQuery(Name = "gender_id")] - public short? GenderId { get; set; } - - [FromQuery(Name = "last_active")] - public DateOnly? LastActive { get; set; } - - [FromQuery(Name = "last_active_from")] - public DateOnly? LastActiveFrom { get; set; } - - [FromQuery(Name = "last_active_to")] - public DateOnly? LastActiveTo { get; set; } - - [FromQuery(Name = "creation_date")] - public DateOnly? CreationDate { get; set; } - - [FromQuery(Name = "creation_date_from")] - public DateOnly? CreationDateFrom { get; set; } - - [FromQuery(Name = "creation_date_to")] - public DateOnly? CreationDateTo { get; set; } - - [FromQuery(Name = "is_admin")] - public bool? IsAdmin { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(AccountResponse item) => - ( - TestStringWithRegex(item.Username, Username) - && - TestStringWithRegex(item.Email, Email) - && - TestStringWithRegex(item.Description, Description) - && - Test(item.Gender?.Id, GenderId) - && - TestComparable(item.LastActive, LastActive, LastActiveFrom, LastActiveTo) - && - TestComparable(item.CreationDate, CreationDate, CreationDateFrom, CreationDateTo) - && - Test(item.IsAdmin, IsAdmin) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountResponse.cs deleted file mode 100644 index 8ab8756..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountResponse.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Model.Genders; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountResponse : Account, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "username", x => x.Username }, - { "email", x => x.Email }, - { "description", x => x.Description }, - { "gender", x => x.Gender.Name }, - { "last_active", x => x.LastActive }, - { "creation_date", x => x.CreationDate }, - { "is_admin", x => x.IsAdmin } - }; - - - [JsonPropertyName("id")] - public required long Id { get; set; } - - [JsonPropertyName("gender")] - public GenderResponse? Gender { get; set; } - - [JsonPropertyName("last_active")] - public DateTime LastActive { get; set; } - - [JsonPropertyName("creation_date")] - public DateTime CreationDate { get; set; } - - [JsonPropertyName("is_admin")] - public bool IsAdmin { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public AccountResponse() {} - - [SetsRequiredMembers] - public AccountResponse(Database.Model.Account.Account account) - { - Id = account.Id; - Username = account.Username; - Email = account.Email; - Description = account.Description; - Gender = account.Gender is not null ? new GenderResponse(account.Gender) : null; - LastActive = account.LastActive; - CreationDate = account.CreationDate; - IsAdmin = account.IsAdmin; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountUsernameRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountUsernameRequest.cs deleted file mode 100644 index 5219594..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AccountUsernameRequest.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class AccountUsernameRequest -{ - #region PROPERTIES - - [JsonPropertyName("new_username")] - public string NewUsername { get; set; } - - [JsonPropertyName("password")] - public string Password { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - public void UpdateAccount(Database.Model.Account.Account account) - { - account.Username = NewUsername; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AuthenticateRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AuthenticateRequest.cs deleted file mode 100644 index 4be0f95..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AuthenticateRequest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class AuthenticateRequest -{ - #region PROPERTIES - - [JsonPropertyName("username_or_email")] - public required string UsernameOrEmail { get; set; } - - [JsonPropertyName("password")] - public required string Password { get; set; } - - [JsonPropertyName("remember_me")] - public bool RememberMe { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/AuthenticateResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/AuthenticateResponse.cs deleted file mode 100644 index 09d3502..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/AuthenticateResponse.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class AuthenticateResponse -{ - #region PROPERTIES - - [JsonPropertyName("access_token")] - public required string AccessToken { get; init; } - - [JsonPropertyName("refresh_token")] - public required string RefreshToken { get; init; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/RegisterRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/RegisterRequest.cs deleted file mode 100644 index 808efe4..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/RegisterRequest.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Accounts; - -public class RegisterRequest -{ - [JsonPropertyName("username")] - public required string Username { get; set; } - - [JsonPropertyName("email")] - public required string Email { get; set; } - - [JsonPropertyName("password")] - public required string Password { get; set; } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Accounts/RegisterResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Accounts/RegisterResponse.cs deleted file mode 100644 index b6d904e..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Accounts/RegisterResponse.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Account; - -namespace WatchIt.Common.Model.Accounts; - -public class RegisterResponse -{ - #region PROPERTIES - - [JsonPropertyName("id")] - public required long Id { get; init; } - - [JsonPropertyName("username")] - public required string Username { get; init; } - - [JsonPropertyName("email")] - public required string Email { get; init; } - - [JsonPropertyName("creation_date")] - public required DateTime CreationDate { get; init; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public RegisterResponse() {} - - [SetsRequiredMembers] - public RegisterResponse(Database.Model.Account.Account account) - { - Id = account.Id; - Username = account.Username; - Email = account.Email; - CreationDate = account.CreationDate; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genders/Gender.cs b/WatchIt.Common/WatchIt.Common.Model/Genders/Gender.cs deleted file mode 100644 index 9cb7c2e..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Genders/Gender.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Genders; - -public class Gender -{ - #region PROPERTIES - - [JsonPropertyName("name")] - public required string Name { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genders/GenderQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Genders/GenderQueryParameters.cs deleted file mode 100644 index 490a674..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Genders/GenderQueryParameters.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Genders; - -public class GenderQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "name")] - public string? Name { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(GenderResponse item) => TestStringWithRegex(item.Name, Name); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genders/GenderRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Genders/GenderRequest.cs deleted file mode 100644 index 60f5a42..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Genders/GenderRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace WatchIt.Common.Model.Genders; - -public class GenderRequest : Gender -{ - #region PUBLIC METHODS - - public Database.Model.Common.Gender CreateGender() => new Database.Model.Common.Gender() - { - Name = Name - }; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genders/GenderResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Genders/GenderResponse.cs deleted file mode 100644 index 16eeeec..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Genders/GenderResponse.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Genders; - -public class GenderResponse : Gender, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "name", item => item.Name } - }; - - - [JsonPropertyName("id")] - public required short? Id { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public GenderResponse() { } - - [SetsRequiredMembers] - public GenderResponse(Database.Model.Common.Gender gender) - { - Id = gender.Id; - Name = gender.Name; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/Genre.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/Genre.cs deleted file mode 100644 index 2a6a26f..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/Genre.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Genres; - -public class Genre -{ - [JsonPropertyName("name")] - public required string Name { get; set; } - - [JsonPropertyName("description")] - public string? Description { get; set; } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs deleted file mode 100644 index 220b5e4..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Genres; - -public class GenreQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "name")] - public string? Name { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(GenreResponse item) => - ( - TestStringWithRegex(item.Name, Name) - && - TestStringWithRegex(item.Description, Description) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreRequest.cs deleted file mode 100644 index 27e771c..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreRequest.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace WatchIt.Common.Model.Genres; - -public class GenreRequest : Genre -{ - #region PUBLIC METHODS - - public Database.Model.Common.Genre CreateGenre() => new Database.Model.Common.Genre - { - Name = Name, - Description = Description, - }; - - public void UpdateGenre(Database.Model.Common.Genre genre) - { - genre.Name = Name; - genre.Description = Description; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs deleted file mode 100644 index 9bb7cba..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Genres; - -public class GenreResponse : Genre, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "name", x => x.Name }, - { "description", x => x.Description } - }; - - - [JsonPropertyName("id")] - public short Id { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public GenreResponse() {} - - [SetsRequiredMembers] - public GenreResponse(Database.Model.Common.Genre genre) - { - Id = genre.Id; - Name = genre.Name; - Description = genre.Description; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/Media.cs b/WatchIt.Common/WatchIt.Common.Model/Media/Media.cs deleted file mode 100644 index 4fa5747..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Media/Media.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Media; - -public abstract class Media -{ - [JsonPropertyName("title")] - public required string Title { get; set; } - - [JsonPropertyName("original_title")] - public string? OriginalTitle { get; set; } - - [JsonPropertyName("description")] - public string? Description { get; set; } - - [JsonPropertyName("release_date")] - public DateOnly? ReleaseDate { get; set; } - - [JsonPropertyName("length")] - public short? Length { get; set; } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaPhotoRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaPhotoRequest.cs deleted file mode 100644 index 5481b2a..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaPhotoRequest.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using WatchIt.Common.Model.Photos; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Media; - -public class MediaPhotoRequest : Photo -{ - #region CONSTRUCTORS - - public MediaPhotoRequest() {} - - [SetsRequiredMembers] - public MediaPhotoRequest(PhotoResponse response) - { - Image = response.Image; - MimeType = response.MimeType; - } - - #endregion - - - - #region PUBLIC METHODS - - public MediaPhotoImage CreateMediaPhotoImage(long mediaId) => new MediaPhotoImage - { - MediaId = mediaId, - Image = Image, - MimeType = MimeType - }; - - public MediaPhotoImageBackground? CreateMediaPhotoImageBackground(Guid mediaPhotoImageId) => Background is null ? null : new MediaPhotoImageBackground - { - Id = mediaPhotoImageId, - IsUniversalBackground = Background.IsUniversalBackground, - FirstGradientColor = Background.FirstGradientColor, - SecondGradientColor = Background.SecondGradientColor - }; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaPoster.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaPoster.cs deleted file mode 100644 index d87668b..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaPoster.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Media; - -public abstract class MediaPoster : Picture -{ -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaPosterRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaPosterRequest.cs deleted file mode 100644 index 1b83f1a..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaPosterRequest.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Media; - -public class MediaPosterRequest : MediaPoster -{ - #region CONSTRUCTORS - - public MediaPosterRequest() {} - - [SetsRequiredMembers] - public MediaPosterRequest(Picture image) - { - Image = image.Image; - MimeType = image.MimeType; - } - - #endregion - - - public MediaPosterImage CreateMediaPosterImage() => new MediaPosterImage - { - Image = Image, - MimeType = MimeType, - }; - - public void UpdateMediaPosterImage(MediaPosterImage item) - { - item.Image = Image; - item.MimeType = MimeType; - item.UploadDate = DateTime.UtcNow; - } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaPosterResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaPosterResponse.cs deleted file mode 100644 index f2c1ff4..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaPosterResponse.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Media; - -public class MediaPosterResponse : MediaPoster -{ - #region PROPERTIES - - [JsonPropertyName("id")] - public Guid Id { get; set; } - - [JsonPropertyName("upload_date")] - public DateTime UploadDate { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public MediaPosterResponse() {} - - [SetsRequiredMembers] - public MediaPosterResponse(MediaPosterImage mediaPhotoImage) - { - Id = mediaPhotoImage.Id; - Image = mediaPhotoImage.Image; - MimeType = mediaPhotoImage.MimeType; - UploadDate = mediaPhotoImage.UploadDate; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs deleted file mode 100644 index b0952b0..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs +++ /dev/null @@ -1,89 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Media; - -public class MediaQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "type")] - public MediaType? Type { get; set; } - - [FromQuery(Name = "title")] - public string? Title { get; set; } - - [FromQuery(Name = "original_title")] - public string? OriginalTitle { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - [FromQuery(Name = "release_date")] - public DateOnly? ReleaseDate { get; set; } - - [FromQuery(Name = "release_date_from")] - public DateOnly? ReleaseDateFrom { get; set; } - - [FromQuery(Name = "release_date_to")] - public DateOnly? ReleaseDateTo { get; set; } - - [FromQuery(Name = "length")] - public short? Length { get; set; } - - [FromQuery(Name = "length_from")] - public short? LengthFrom { get; set; } - - [FromQuery(Name = "length_to")] - public short? LengthTo { get; set; } - - [FromQuery(Name = "rating_average")] - public decimal? RatingAverage { get; set; } - - [FromQuery(Name = "rating_average_from")] - public decimal? RatingAverageFrom { get; set; } - - [FromQuery(Name = "rating_average_to")] - public decimal? RatingAverageTo { get; set; } - - [FromQuery(Name = "rating_count")] - public long? RatingCount { get; set; } - - [FromQuery(Name = "rating_count_from")] - public long? RatingCountFrom { get; set; } - - [FromQuery(Name = "rating_count_to")] - public long? RatingCountTo { get; set; } - - [FromQuery(Name = "genre")] - public IEnumerable? Genres { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(MediaResponse item) => - ( - Test(item.Type, Type) - && - TestStringWithRegex(item.Title, Title) - && - TestStringWithRegex(item.OriginalTitle, OriginalTitle) - && - TestStringWithRegex(item.Description, Description) - && - TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo) - && - TestComparable(item.Length, Length, LengthFrom, LengthTo) - && - TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) - && - TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) - && - TestContains(Genres, item.Genres.Select(x => x.Id)) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs deleted file mode 100644 index 796c2b5..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Query; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Common.Model.Media; - -public class MediaResponse : Media, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "title", x => x.Title }, - { "original_title", x => x.OriginalTitle }, - { "description", x => x.Description }, - { "release_date", x => x.ReleaseDate }, - { "length", x => x.Length }, - { "rating.average", x => x.Rating.Average }, - { "rating.count", x => x.Rating.Count } - }; - - - [JsonPropertyName("id")] - public long Id { get; set; } - - [JsonPropertyName("type")] - public MediaType Type { get; set; } - - [JsonPropertyName("rating")] - public RatingResponse Rating { get; set; } - - [JsonPropertyName("genres")] - public IEnumerable Genres { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public MediaResponse() {} - - [SetsRequiredMembers] - public MediaResponse(Database.Model.Media.Media media, MediaType mediaType) - { - Id = media.Id; - Title = media.Title; - OriginalTitle = media.OriginalTitle; - Description = media.Description; - ReleaseDate = media.ReleaseDate; - Length = media.Length; - Type = mediaType; - Rating = RatingResponseBuilder.Initialize() - .Add(media.RatingMedia, x => x.Rating) - .Build(); - Genres = media.Genres.Select(x => new GenreResponse(x)).ToList(); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaType.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaType.cs deleted file mode 100644 index 71df0ad..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WatchIt.Common.Model.Media; - -public enum MediaType -{ - Movie, - Series -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/Movie.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/Movie.cs deleted file mode 100644 index cd2681d..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/Movie.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Movies; - -public class Movie : Media.Media -{ - [JsonPropertyName("budget")] - public decimal? Budget { get; set; } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs deleted file mode 100644 index 35c239c..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs +++ /dev/null @@ -1,95 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Movies; - -public class MovieQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "title")] - public string? Title { get; set; } - - [FromQuery(Name = "original_title")] - public string? OriginalTitle { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - [FromQuery(Name = "release_date")] - public DateOnly? ReleaseDate { get; set; } - - [FromQuery(Name = "release_date_from")] - public DateOnly? ReleaseDateFrom { get; set; } - - [FromQuery(Name = "release_date_to")] - public DateOnly? ReleaseDateTo { get; set; } - - [FromQuery(Name = "length")] - public short? Length { get; set; } - - [FromQuery(Name = "length_from")] - public short? LengthFrom { get; set; } - - [FromQuery(Name = "length_to")] - public short? LengthTo { get; set; } - - [FromQuery(Name = "budget")] - public decimal? Budget { get; set; } - - [FromQuery(Name = "budget_from")] - public decimal? BudgetFrom { get; set; } - - [FromQuery(Name = "budget_to")] - public decimal? BudgetTo { get; set; } - - [FromQuery(Name = "rating_average")] - public decimal? RatingAverage { get; set; } - - [FromQuery(Name = "rating_average_from")] - public decimal? RatingAverageFrom { get; set; } - - [FromQuery(Name = "rating_average_to")] - public decimal? RatingAverageTo { get; set; } - - [FromQuery(Name = "rating_count")] - public long? RatingCount { get; set; } - - [FromQuery(Name = "rating_count_from")] - public long? RatingCountFrom { get; set; } - - [FromQuery(Name = "rating_count_to")] - public long? RatingCountTo { get; set; } - - [FromQuery(Name = "genre")] - public IEnumerable? Genres { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(MovieResponse item) => - ( - TestStringWithRegex(item.Title, Title) - && - TestStringWithRegex(item.OriginalTitle, OriginalTitle) - && - TestStringWithRegex(item.Description, Description) - && - TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo) - && - TestComparable(item.Length, Length, LengthFrom, LengthTo) - && - TestComparable(item.Budget, Budget, BudgetFrom, BudgetTo) - && - TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) - && - TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) - && - TestContains(item.Genres.Select(x => x.Id), Genres) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedQueryParameters.cs deleted file mode 100644 index 5c5d2b7..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedQueryParameters.cs +++ /dev/null @@ -1,115 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Movies; - -public class MovieRatedQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "title")] - public string? Title { get; set; } - - [FromQuery(Name = "original_title")] - public string? OriginalTitle { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - [FromQuery(Name = "release_date")] - public DateOnly? ReleaseDate { get; set; } - - [FromQuery(Name = "release_date_from")] - public DateOnly? ReleaseDateFrom { get; set; } - - [FromQuery(Name = "release_date_to")] - public DateOnly? ReleaseDateTo { get; set; } - - [FromQuery(Name = "length")] - public short? Length { get; set; } - - [FromQuery(Name = "length_from")] - public short? LengthFrom { get; set; } - - [FromQuery(Name = "length_to")] - public short? LengthTo { get; set; } - - [FromQuery(Name = "budget")] - public decimal? Budget { get; set; } - - [FromQuery(Name = "budget_from")] - public decimal? BudgetFrom { get; set; } - - [FromQuery(Name = "budget_to")] - public decimal? BudgetTo { get; set; } - - [FromQuery(Name = "rating_average")] - public decimal? RatingAverage { get; set; } - - [FromQuery(Name = "rating_average_from")] - public decimal? RatingAverageFrom { get; set; } - - [FromQuery(Name = "rating_average_to")] - public decimal? RatingAverageTo { get; set; } - - [FromQuery(Name = "rating_count")] - public long? RatingCount { get; set; } - - [FromQuery(Name = "rating_count_from")] - public long? RatingCountFrom { get; set; } - - [FromQuery(Name = "rating_count_to")] - public long? RatingCountTo { get; set; } - - [FromQuery(Name = "genre")] - public IEnumerable? Genres { get; set; } - - [FromQuery(Name = "user_rating")] - public decimal? UserRating { get; set; } - - [FromQuery(Name = "user_rating_from")] - public decimal? UserRatingFrom { get; set; } - - [FromQuery(Name = "user_rating_to")] - public decimal? UserRatingTo { get; set; } - - [FromQuery(Name = "user_rating_date")] - public DateOnly? UserRatingDate { get; set; } - - [FromQuery(Name = "user_rating_date_from")] - public DateOnly? UserRatingDateFrom { get; set; } - - [FromQuery(Name = "user_rating_date_to")] - public DateOnly? UserRatingDateTo { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(MovieRatedResponse item) => - ( - TestStringWithRegex(item.Title, Title) - && - TestStringWithRegex(item.OriginalTitle, OriginalTitle) - && - TestStringWithRegex(item.Description, Description) - && - TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo) - && - TestComparable(item.Length, Length, LengthFrom, LengthTo) - && - TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) - && - TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) - && - TestContains(Genres, item.Genres.Select(x => x.Id)) - && - TestComparable((decimal)item.UserRating, UserRating, UserRatingFrom, UserRatingTo) - && - TestComparable(item.UserRatingDate, UserRatingDate, UserRatingDateFrom, UserRatingDateTo) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedResponse.cs deleted file mode 100644 index 5f3fa18..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedResponse.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Query; -using WatchIt.Database.Model.Media; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Common.Model.Movies; - -public class MovieRatedResponse : MovieResponse, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "title", x => x.Title }, - { "original_title", x => x.OriginalTitle }, - { "description", x => x.Description }, - { "release_date", x => x.ReleaseDate }, - { "length", x => x.Length }, - { "budget", x => x.Budget }, - { "rating.average", x => x.Rating.Average }, - { "rating.count", x => x.Rating.Count }, - { "user_rating", x => x.UserRating }, - { "user_rating_date", x => x.UserRatingDate } - }; - - [JsonPropertyName("user_rating")] - public short UserRating { get; set; } - - [JsonPropertyName("user_rating_date")] - public DateTime UserRatingDate { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public MovieRatedResponse() { } - - [SetsRequiredMembers] - public MovieRatedResponse(MediaMovie mediaMovie, RatingMedia response) - { - Id = mediaMovie.Media.Id; - Title = mediaMovie.Media.Title; - OriginalTitle = mediaMovie.Media.OriginalTitle; - Description = mediaMovie.Media.Description; - ReleaseDate = mediaMovie.Media.ReleaseDate; - Length = mediaMovie.Media.Length; - Budget = mediaMovie.Budget; - Rating = RatingResponseBuilder.Initialize() - .Add(mediaMovie.Media.RatingMedia, x => x.Rating) - .Build(); - Genres = mediaMovie.Media.Genres.Select(x => new GenreResponse(x)).ToList(); - UserRating = response.Rating; - UserRatingDate = response.Date; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRequest.cs deleted file mode 100644 index de8c9db..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRequest.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Movies; - -public class MovieRequest : Movie -{ - #region CONSTRUCTORS - - [SetsRequiredMembers] - public MovieRequest(MovieResponse initData) - { - Title = initData.Title; - OriginalTitle = initData.OriginalTitle; - Description = initData.Description; - ReleaseDate = initData.ReleaseDate; - Length = initData.Length; - Budget = initData.Budget; - } - - public MovieRequest() {} - - #endregion - - - - #region PUBLIC METHODS - - public Database.Model.Media.Media CreateMedia() => new Database.Model.Media.Media - { - Title = Title, - OriginalTitle = OriginalTitle, - Description = Description, - ReleaseDate = ReleaseDate, - Length = Length, - }; - - public MediaMovie CreateMediaMovie(long id) => new MediaMovie - { - Id = id, - Budget = Budget, - }; - - public void UpdateMedia(Database.Model.Media.Media media) - { - media.Title = Title; - media.OriginalTitle = OriginalTitle; - media.Description = Description; - media.ReleaseDate = ReleaseDate; - media.Length = Length; - } - - public void UpdateMediaMovie(MediaMovie mediaMovie) - { - mediaMovie.Budget = Budget; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs deleted file mode 100644 index a05e782..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Query; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Movies; - -public class MovieResponse : Movie, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "title", x => x.Title }, - { "original_title", x => x.OriginalTitle }, - { "description", x => x.Description }, - { "release_date", x => x.ReleaseDate }, - { "length", x => x.Length }, - { "budget", x => x.Budget }, - { "rating.average", x => x.Rating.Average }, - { "rating.count", x => x.Rating.Count } - }; - - - [JsonPropertyName("id")] - public long Id { get; set; } - - [JsonPropertyName("rating")] - public RatingResponse Rating { get; set; } - - [JsonPropertyName("genres")] - public IEnumerable Genres { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public MovieResponse() {} - - [SetsRequiredMembers] - public MovieResponse(MediaMovie mediaMovie) - { - Id = mediaMovie.Media.Id; - Title = mediaMovie.Media.Title; - OriginalTitle = mediaMovie.Media.OriginalTitle; - Description = mediaMovie.Media.Description; - ReleaseDate = mediaMovie.Media.ReleaseDate; - Length = mediaMovie.Media.Length; - Budget = mediaMovie.Budget; - Rating = RatingResponseBuilder.Initialize() - .Add(mediaMovie.Media.RatingMedia, x => x.Rating) - .Build(); - Genres = mediaMovie.Media.Genres.Select(x => new GenreResponse(x)).ToList(); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/Person.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/Person.cs deleted file mode 100644 index 0980294..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/Person.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Persons; - -public class Person -{ - #region PROPERTIES - - [JsonPropertyName("name")] - public required string Name { get; set; } - - [JsonPropertyName("full_name")] - public string? FullName { get; set; } - - [JsonPropertyName("description")] - public string? Description { get; set; } - - [JsonPropertyName("birth_date")] - public DateOnly? BirthDate { get; set; } - - [JsonPropertyName("death_date")] - public DateOnly? DeathDate { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhoto.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhoto.cs deleted file mode 100644 index 67094f6..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhoto.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace WatchIt.Common.Model.Persons; - -public class PersonPhoto : Picture -{ - -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhotoRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhotoRequest.cs deleted file mode 100644 index 8397887..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhotoRequest.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Persons; - -public class PersonPhotoRequest : PersonPhoto -{ - #region CONSTRUCTORS - - [JsonConstructor] - public PersonPhotoRequest() {} - - [SetsRequiredMembers] - public PersonPhotoRequest(Picture image) - { - Image = image.Image; - MimeType = image.MimeType; - } - - #endregion - - - - #region PUBLIC METHODS - - public PersonPhotoImage CreatePersonPhotoImage() => new PersonPhotoImage - { - Image = Image, - MimeType = MimeType, - }; - - public void UpdatePersonPhotoImage(PersonPhotoImage item) - { - item.Image = Image; - item.MimeType = MimeType; - item.UploadDate = DateTime.UtcNow; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhotoResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhotoResponse.cs deleted file mode 100644 index 957e76c..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonPhotoResponse.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Persons; - -public class PersonPhotoResponse : PersonPhoto -{ - #region PROPERTIES - - [JsonPropertyName("id")] - public Guid Id { get; set; } - - [JsonPropertyName("upload_date")] - public DateTime UploadDate { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public PersonPhotoResponse() {} - - [SetsRequiredMembers] - public PersonPhotoResponse(PersonPhotoImage personPhotoImage) - { - Id = personPhotoImage.Id; - Image = personPhotoImage.Image; - MimeType = personPhotoImage.MimeType; - UploadDate = personPhotoImage.UploadDate; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonQueryParameters.cs deleted file mode 100644 index 0cd03ed..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonQueryParameters.cs +++ /dev/null @@ -1,84 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Persons; - -public class PersonQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "name")] - public string? Name { get; set; } - - [FromQuery(Name = "full_name")] - public string? FullName { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - [FromQuery(Name = "birth_date")] - public DateOnly? BirthDate { get; set; } - - [FromQuery(Name = "birth_date_from")] - public DateOnly? BirthDateFrom { get; set; } - - [FromQuery(Name = "birth_date_to")] - public DateOnly? BirthDateTo { get; set; } - - [FromQuery(Name = "death_date")] - public DateOnly? DeathDate { get; set; } - - [FromQuery(Name = "death_date_from")] - public DateOnly? DeathDateFrom { get; set; } - - [FromQuery(Name = "death_date_to")] - public DateOnly? DeathDateTo { get; set; } - - [FromQuery(Name = "gender_id")] - public short? GenderId { get; set; } - - [FromQuery(Name = "rating_average")] - public decimal? RatingAverage { get; set; } - - [FromQuery(Name = "rating_average_from")] - public decimal? RatingAverageFrom { get; set; } - - [FromQuery(Name = "rating_average_to")] - public decimal? RatingAverageTo { get; set; } - - [FromQuery(Name = "rating_count")] - public long? RatingCount { get; set; } - - [FromQuery(Name = "rating_count_from")] - public long? RatingCountFrom { get; set; } - - [FromQuery(Name = "rating_count_to")] - public long? RatingCountTo { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - protected override bool IsMeetingConditions(PersonResponse item) => - ( - TestStringWithRegex(item.Name, Name) - && - TestStringWithRegex(item.FullName, FullName) - && - TestStringWithRegex(item.Description, Description) - && - TestComparable(item.BirthDate, BirthDate, BirthDateFrom, BirthDateTo) - && - TestComparable(item.DeathDate, DeathDate, DeathDateFrom, DeathDateTo) - && - Test(item.Gender?.Id, GenderId) - && - TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) - && - TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedQueryParameters.cs deleted file mode 100644 index dd1659b..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedQueryParameters.cs +++ /dev/null @@ -1,117 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Persons; - -public class PersonRatedQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "name")] - public string? Name { get; set; } - - [FromQuery(Name = "full_name")] - public string? FullName { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - [FromQuery(Name = "birth_date")] - public DateOnly? BirthDate { get; set; } - - [FromQuery(Name = "birth_date_from")] - public DateOnly? BirthDateFrom { get; set; } - - [FromQuery(Name = "birth_date_to")] - public DateOnly? BirthDateTo { get; set; } - - [FromQuery(Name = "death_date")] - public DateOnly? DeathDate { get; set; } - - [FromQuery(Name = "death_date_from")] - public DateOnly? DeathDateFrom { get; set; } - - [FromQuery(Name = "death_date_to")] - public DateOnly? DeathDateTo { get; set; } - - [FromQuery(Name = "gender_id")] - public short? GenderId { get; set; } - - [FromQuery(Name = "rating_average")] - public decimal? RatingAverage { get; set; } - - [FromQuery(Name = "rating_average_from")] - public decimal? RatingAverageFrom { get; set; } - - [FromQuery(Name = "rating_average_to")] - public decimal? RatingAverageTo { get; set; } - - [FromQuery(Name = "rating_count")] - public long? RatingCount { get; set; } - - [FromQuery(Name = "rating_count_from")] - public long? RatingCountFrom { get; set; } - - [FromQuery(Name = "rating_count_to")] - public long? RatingCountTo { get; set; } - - [FromQuery(Name = "user_rating_average")] - public decimal? UserRatingAverage { get; set; } - - [FromQuery(Name = "user_rating_average_from")] - public decimal? UserRatingAverageFrom { get; set; } - - [FromQuery(Name = "user_rating_average_to")] - public decimal? UserRatingAverageTo { get; set; } - - [FromQuery(Name = "user_rating_count")] - public long? UserRatingCount { get; set; } - - [FromQuery(Name = "user_rating_count_from")] - public long? UserRatingCountFrom { get; set; } - - [FromQuery(Name = "user_rating_count_to")] - public long? UserRatingCountTo { get; set; } - - [FromQuery(Name = "user_rating_date")] - public DateOnly? UserRatingLastDate { get; set; } - - [FromQuery(Name = "user_rating_date_from")] - public DateOnly? UserRatingLastDateFrom { get; set; } - - [FromQuery(Name = "user_rating_date_to")] - public DateOnly? UserRatingLastDateTo { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - protected override bool IsMeetingConditions(PersonRatedResponse item) => - ( - TestStringWithRegex(item.Name, Name) - && - TestStringWithRegex(item.FullName, FullName) - && - TestStringWithRegex(item.Description, Description) - && - TestComparable(item.BirthDate, BirthDate, BirthDateFrom, BirthDateTo) - && - TestComparable(item.DeathDate, DeathDate, DeathDateFrom, DeathDateTo) - && - Test(item.Gender?.Id, GenderId) - && - TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) - && - TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) - && - TestComparable(item.UserRating.Average, UserRatingAverage, UserRatingAverageFrom, UserRatingAverageTo) - && - TestComparable(item.UserRating.Count, UserRatingCount, UserRatingCountFrom, UserRatingCountTo) - && - TestComparable(item.UserRatingLastDate, UserRatingLastDate, UserRatingLastDateFrom, UserRatingLastDateTo) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedResponse.cs deleted file mode 100644 index d328b95..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedResponse.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Model.Genders; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Query; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Common.Model.Persons; - -public class PersonRatedResponse : PersonResponse, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "name", x => x.Name }, - { "full_name", x => x.FullName }, - { "description", x => x.Description }, - { "birth_date", x => x.BirthDate }, - { "death_date", x => x.BirthDate }, - { "gender", x => x.Gender.Name }, - { "rating.average", x => x.Rating.Average }, - { "rating.count", x => x.Rating.Count }, - { "user_rating.average", x => x.UserRating.Average }, - { "user_rating.count", x => x.UserRating.Count }, - { "user_rating_last_date", x => x.UserRatingLastDate } - }; - - [JsonPropertyName("user_rating")] - public RatingResponse UserRating { get; set; } - - [JsonPropertyName("user_rating_last_date")] - public DateTime UserRatingLastDate { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public PersonRatedResponse() { } - - [SetsRequiredMembers] - public PersonRatedResponse(Database.Model.Person.Person person, IEnumerable actorUserRatings, IEnumerable creatorUserRatings) - { - Id = person.Id; - Name = person.Name; - FullName = person.FullName; - Description = person.Description; - BirthDate = person.BirthDate; - DeathDate = person.DeathDate; - Gender = person.Gender is not null ? new GenderResponse(person.Gender) : null; - Rating = RatingResponseBuilder.Initialize() - .Add(person.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating) - .Add(person.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating) - .Build(); - UserRating = RatingResponseBuilder.Initialize() - .Add(actorUserRatings, x => x.Rating) - .Add(creatorUserRatings, x => x.Rating) - .Build(); - UserRatingLastDate = actorUserRatings.Select(x => x.Date) - .Union(creatorUserRatings.Select(x => x.Date)) - .Max(); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRequest.cs deleted file mode 100644 index 7e7052b..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRequest.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Persons; - -public class PersonRequest : Person -{ - #region PROPERTIES - - [JsonPropertyName("gender_id")] - public short? GenderId { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [SetsRequiredMembers] - public PersonRequest() - { - Name = string.Empty; - } - - [SetsRequiredMembers] - public PersonRequest(PersonResponse person) - { - Name = person.Name; - FullName = person.FullName; - Description = person.Description; - BirthDate = person.BirthDate; - DeathDate = person.DeathDate; - GenderId = person.Gender?.Id; - } - - #endregion - - - - #region PUBLIC METHODS - - public Database.Model.Person.Person CreatePerson() => new Database.Model.Person.Person - { - Name = Name, - FullName = FullName, - Description = Description, - BirthDate = BirthDate, - DeathDate = DeathDate, - GenderId = GenderId, - }; - - public void UpdatePerson(Database.Model.Person.Person person) - { - person.Name = Name; - person.FullName = FullName; - person.Description = Description; - person.BirthDate = BirthDate; - person.DeathDate = DeathDate; - person.GenderId = GenderId; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonResponse.cs deleted file mode 100644 index 1b3a264..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonResponse.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Model.Genders; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Query; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Common.Model.Persons; - -public class PersonResponse : Person, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "name", x => x.Name }, - { "full_name", x => x.FullName }, - { "description", x => x.Description }, - { "birth_date", x => x.BirthDate }, - { "death_date", x => x.BirthDate }, - { "gender", x => x.Gender.Name }, - { "rating.average", x => x.Rating.Average }, - { "rating.count", x => x.Rating.Count } - }; - - - [JsonPropertyName("id")] - public required long Id { get; set; } - - [JsonPropertyName("gender")] - public GenderResponse? Gender { get; set; } - - [JsonPropertyName("rating")] - public required RatingResponse Rating { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public PersonResponse() { } - - [SetsRequiredMembers] - public PersonResponse(Database.Model.Person.Person person) - { - Id = person.Id; - Name = person.Name; - FullName = person.FullName; - Description = person.Description; - BirthDate = person.BirthDate; - DeathDate = person.DeathDate; - Gender = person.Gender is not null ? new GenderResponse(person.Gender) : null; - Rating = RatingResponseBuilder.Initialize() - .Add(person.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating) - .Add(person.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating) - .Build(); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Photos/Photo.cs b/WatchIt.Common/WatchIt.Common.Model/Photos/Photo.cs deleted file mode 100644 index 39cabfd..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Photos/Photo.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Photos; - -public abstract class Photo : Picture -{ - #region PROPERTIES - - [JsonPropertyName("background")] - public PhotoBackgroundData? Background { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoBackgroundData.cs b/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoBackgroundData.cs deleted file mode 100644 index 09c31c3..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoBackgroundData.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Photos; - -public class PhotoBackgroundData -{ - #region PROPERTIES - - [JsonPropertyName("is_universal_background")] - public required bool IsUniversalBackground { get; set; } - - [JsonPropertyName("first_gradient_color")] - public required byte[] FirstGradientColor { get; set; } - - [JsonPropertyName("second_gradient_color")] - public required byte[] SecondGradientColor { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoBackgroundDataRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoBackgroundDataRequest.cs deleted file mode 100644 index 917548b..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoBackgroundDataRequest.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Photos; - -public class PhotoBackgroundDataRequest : PhotoBackgroundData -{ - #region CONSTRUCTORS - - public PhotoBackgroundDataRequest() {} - - [SetsRequiredMembers] - public PhotoBackgroundDataRequest(PhotoBackgroundData photoBackgroundData) - { - IsUniversalBackground = photoBackgroundData.IsUniversalBackground; - FirstGradientColor = photoBackgroundData.FirstGradientColor; - SecondGradientColor = photoBackgroundData.SecondGradientColor; - } - - #endregion - - - - #region PUBLIC METHODS - - public MediaPhotoImageBackground CreateMediaPhotoImageBackground(Guid photoId) => new MediaPhotoImageBackground - { - Id = photoId, - IsUniversalBackground = IsUniversalBackground, - FirstGradientColor = FirstGradientColor, - SecondGradientColor = SecondGradientColor, - }; - - public void UpdateMediaPhotoImageBackground(MediaPhotoImageBackground image) - { - image.IsUniversalBackground = IsUniversalBackground; - image.FirstGradientColor = FirstGradientColor; - image.SecondGradientColor = SecondGradientColor; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoQueryParameters.cs deleted file mode 100644 index 33b5610..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoQueryParameters.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Text.Json.Serialization; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Series; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Photos; - -public class PhotoQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "mime_type")] - public string? MimeType { get; set; } - - [FromQuery(Name = "is_background")] - public bool? IsBackground { get; set; } - - [FromQuery(Name = "is_universal_background")] - public bool? IsUniversalBackground { get; set; } - - [FromQuery(Name = "upload_date")] - public DateOnly? UploadDate { get; set; } - - [FromQuery(Name = "upload_date_from")] - public DateOnly? UploadDateFrom { get; set; } - - [FromQuery(Name = "upload_date_to")] - public DateOnly? UploadDateTo { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(PhotoResponse item) => - ( - TestStringWithRegex(item.MimeType, MimeType) - && - Test(item.Background is not null, IsBackground) - && - Test(item.Background is not null && item.Background.IsUniversalBackground, IsUniversalBackground) - && - TestComparable(item.UploadDate, UploadDate, UploadDateFrom, UploadDateTo) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoResponse.cs deleted file mode 100644 index b715235..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoResponse.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Query; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Photos; - -public class PhotoResponse : Photo, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "media_id", x => x.MediaId }, - { "mime_type", x => x.MimeType }, - { "is_background", x => x.Background is not null }, - { "is_universal_background", x => x.Background is not null && x.Background.IsUniversalBackground } - }; - - - [JsonPropertyName("id")] - public Guid Id { get; set; } - - [JsonPropertyName("media_id")] - public required long MediaId { get; set; } - - [JsonPropertyName("upload_date")] - public DateTime UploadDate { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public PhotoResponse() {} - - [SetsRequiredMembers] - public PhotoResponse(MediaPhotoImage mediaPhotoImage) - { - Id = mediaPhotoImage.Id; - MediaId = mediaPhotoImage.MediaId; - Image = mediaPhotoImage.Image; - MimeType = mediaPhotoImage.MimeType; - UploadDate = mediaPhotoImage.UploadDate; - - if (mediaPhotoImage.MediaPhotoImageBackground is not null) - { - Background = new PhotoBackgroundData - { - IsUniversalBackground = mediaPhotoImage.MediaPhotoImageBackground.IsUniversalBackground, - FirstGradientColor = mediaPhotoImage.MediaPhotoImageBackground.FirstGradientColor, - SecondGradientColor = mediaPhotoImage.MediaPhotoImageBackground.SecondGradientColor - }; - } - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Picture.cs b/WatchIt.Common/WatchIt.Common.Model/Picture.cs deleted file mode 100644 index b16065e..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Picture.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model; - -public class Picture -{ - #region PROPERTIES - - [JsonPropertyName("image")] - public required byte[] Image { get; set; } - - [JsonPropertyName("mime_type")] - public required string MimeType { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - public override string ToString() => $"data:{MimeType};base64,{Convert.ToBase64String(Image)}"; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingRequest.cs deleted file mode 100644 index 54b7ac2..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingRequest.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Rating; - -public class RatingRequest -{ - #region PROPERTIES - - [JsonPropertyName("rating")] - public required short Rating { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [SetsRequiredMembers] - public RatingRequest(short rating) - { - Rating = rating; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs deleted file mode 100644 index 483f298..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Common.Model.Rating; - -public class RatingResponse -{ - #region PROPERTIES - - [JsonPropertyName("average")] - public required decimal Average { get; set; } - - [JsonPropertyName("count")] - public required long Count { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public RatingResponse() {} - - [SetsRequiredMembers] - internal RatingResponse(long ratingSum, long ratingCount) - { - Average = ratingCount > 0 ? (decimal)ratingSum / ratingCount : 0; - Count = ratingCount; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponseBuilder.cs b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponseBuilder.cs deleted file mode 100644 index d53b4df..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponseBuilder.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace WatchIt.Common.Model.Rating; - -public class RatingResponseBuilder -{ - #region FIELDS - - private long _sum; - private long _count; - - #endregion - - - - #region CONSTRUCTORS - - private RatingResponseBuilder() { } - - public static RatingResponseBuilder Initialize() => new RatingResponseBuilder(); - - #endregion - - - - #region PUBLIC METHODS - - public RatingResponseBuilder Add(IEnumerable collection, Func selector) - { - _sum += collection.Sum(x => selector(x)); - _count += collection.Count(); - return this; - } - public RatingResponse Build() => new RatingResponse(_sum, _count); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRole.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRole.cs deleted file mode 100644 index 572748f..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRole.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Roles; - -public abstract class ActorRole -{ - #region PROPERTIES - - [JsonPropertyName("type_id")] - public short TypeId { get; set; } - - [JsonPropertyName("name")] - public string Name { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaQueryParameters.cs deleted file mode 100644 index aea4560..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaQueryParameters.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.Common.Model.Roles; - -public class ActorRoleMediaQueryParameters : ActorRoleQueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "person_id")] - public long? PersonId { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(ActorRoleResponse item) => - ( - base.IsMeetingConditions(item) - && - Test(item.PersonId, PersonId) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaRequest.cs deleted file mode 100644 index 66787b5..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaRequest.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Roles; - -public class ActorRoleMediaRequest : ActorRoleRequest, IActorRoleMediaRequest -{ - #region PROPERTIES - - [JsonPropertyName("person_id")] - public long PersonId { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - public PersonActorRole CreateActorRole(long mediaId) => base.CreateActorRole(mediaId, PersonId); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonQueryParameters.cs deleted file mode 100644 index b31e24f..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonQueryParameters.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.Common.Model.Roles; - -public class ActorRolePersonQueryParameters : ActorRoleQueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "media_id")] - public long? MediaId { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(ActorRoleResponse item) => - ( - base.IsMeetingConditions(item) - && - Test(item.MediaId, MediaId) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonRequest.cs deleted file mode 100644 index aba7c47..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonRequest.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Roles; - -public class ActorRolePersonRequest : ActorRoleRequest, IActorRolePersonRequest -{ - #region PROPERTIES - - [JsonPropertyName("media_id")] - public long MediaId { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - public PersonActorRole CreateActorRole(long personId) => base.CreateActorRole(MediaId, personId); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleQueryParameters.cs deleted file mode 100644 index b4a926c..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleQueryParameters.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Roles; - -public abstract class ActorRoleQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "type_id")] - public short? TypeId { get; set; } - - [FromQuery(Name = "name")] - public string? Name { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(ActorRoleResponse item) => - ( - Test(item.TypeId, TypeId) - && - TestStringWithRegex(item.Name, Name) - ); - - #endregion - - -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleRequest.cs deleted file mode 100644 index 8b096ad..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleRequest.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Roles; - -public abstract class ActorRoleRequest : ActorRole, IActorRoleRequest -{ - #region PUBLIC METHODS - - public PersonActorRole CreateActorRole(long mediaId, long personId) => new PersonActorRole - { - MediaId = mediaId, - PersonId = personId, - PersonActorRoleTypeId = TypeId, - RoleName = Name, - }; - - public void UpdateActorRole(PersonActorRole item, long mediaId, long personId) - { - item.MediaId = mediaId; - item.PersonId = personId; - item.PersonActorRoleTypeId = TypeId; - item.RoleName = Name; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleResponse.cs deleted file mode 100644 index 31d3926..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleResponse.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Roles; - -public class ActorRoleResponse : ActorRole, IQueryOrderable, IRoleResponse -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "name", item => item.Name }, - { "type_id", item => item.TypeId }, - }; - - - [JsonPropertyName("id")] - public required Guid Id { get; set; } - - [JsonPropertyName("media_id")] - public long MediaId { get; set; } - - [JsonPropertyName("person_id")] - public long PersonId { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public ActorRoleResponse() {} - - [SetsRequiredMembers] - public ActorRoleResponse(Database.Model.Person.PersonActorRole data) - { - Id = data.Id; - MediaId = data.MediaId; - PersonId = data.PersonId; - TypeId = data.PersonActorRoleTypeId; - Name = data.RoleName; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleUniversalRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleUniversalRequest.cs deleted file mode 100644 index 76ff560..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleUniversalRequest.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Roles; - -public class ActorRoleUniversalRequest : ActorRoleRequest, IActorRolePersonRequest, IActorRoleMediaRequest -{ - #region PROPERTIES - - [JsonPropertyName("person_id")] - public long PersonId { get; set; } - - [JsonPropertyName("media_id")] - public long MediaId { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - public ActorRoleUniversalRequest() { } - - public ActorRoleUniversalRequest(ActorRoleResponse data) - { - MediaId = data.MediaId; - PersonId = data.PersonId; - TypeId = data.TypeId; - Name = data.Name; - } - - #endregion - - - - #region PUBLIC METHODS - - public PersonActorRole CreateActorRole() => base.CreateActorRole(MediaId, PersonId); - - public void UpdateActorRole(PersonActorRole item) => base.UpdateActorRole(item, MediaId, PersonId); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRole.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRole.cs deleted file mode 100644 index 5262eed..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRole.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Roles; - -public abstract class CreatorRole -{ - #region PROPERTIES - - [JsonPropertyName("type_id")] - public short TypeId { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaQueryParameters.cs deleted file mode 100644 index 94daf61..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaQueryParameters.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.Common.Model.Roles; - -public class CreatorRoleMediaQueryParameters : CreatorRoleQueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "person_id")] - public long? PersonId { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(CreatorRoleResponse item) => - ( - base.IsMeetingConditions(item) - && - Test(item.PersonId, PersonId) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaRequest.cs deleted file mode 100644 index b256322..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaRequest.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Roles; - -public class CreatorRoleMediaRequest : CreatorRoleRequest, ICreatorRoleMediaRequest -{ - #region PROPERTIES - - [JsonPropertyName("person_id")] - public long PersonId { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - public PersonCreatorRole CreateCreatorRole(long mediaId) => base.CreateCreatorRole(mediaId, PersonId); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonQueryParameters.cs deleted file mode 100644 index a8604dd..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonQueryParameters.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.Common.Model.Roles; - -public class CreatorRolePersonQueryParameters : CreatorRoleQueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "media_id")] - public long? MediaId { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(CreatorRoleResponse item) => - ( - base.IsMeetingConditions(item) - && - Test(item.MediaId, MediaId) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonRequest.cs deleted file mode 100644 index 7bf53dd..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonRequest.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Roles; - -public class CreatorRolePersonRequest : CreatorRoleRequest, ICreatorRolePersonRequest -{ - #region PROPERTIES - - [JsonPropertyName("media_id")] - public long MediaId { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - public PersonCreatorRole CreateCreatorRole(long personId) => base.CreateCreatorRole(MediaId, personId); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleQueryParameters.cs deleted file mode 100644 index 8d416f6..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleQueryParameters.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Roles; - -public abstract class CreatorRoleQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "type_id")] - public short? TypeId { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(CreatorRoleResponse item) => - ( - Test(item.TypeId, TypeId) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleRequest.cs deleted file mode 100644 index 1aa45f7..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleRequest.cs +++ /dev/null @@ -1,24 +0,0 @@ -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Roles; - -public abstract class CreatorRoleRequest : CreatorRole, ICreatorRoleRequest -{ - #region PUBLIC METHODS - - public PersonCreatorRole CreateCreatorRole(long mediaId, long personId) => new PersonCreatorRole - { - MediaId = mediaId, - PersonId = personId, - PersonCreatorRoleTypeId = TypeId, - }; - - public void UpdateCreatorRole(PersonCreatorRole item, long mediaId, long personId) - { - item.MediaId = mediaId; - item.PersonId = personId; - item.PersonCreatorRoleTypeId = TypeId; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleResponse.cs deleted file mode 100644 index d0611ea..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleResponse.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Roles; - -public class CreatorRoleResponse : CreatorRole, IQueryOrderable, IRoleResponse -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "type_id", item => item.TypeId }, - }; - - - [JsonPropertyName("id")] - public required Guid Id { get; set; } - - [JsonPropertyName("media_id")] - public long MediaId { get; set; } - - [JsonPropertyName("person_id")] - public long PersonId { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public CreatorRoleResponse() {} - - [SetsRequiredMembers] - public CreatorRoleResponse(Database.Model.Person.PersonCreatorRole data) - { - Id = data.Id; - MediaId = data.MediaId; - PersonId = data.PersonId; - TypeId = data.PersonCreatorRoleTypeId; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleUniversalRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleUniversalRequest.cs deleted file mode 100644 index 931c794..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleUniversalRequest.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Text.Json.Serialization; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Common.Model.Roles; - -public class CreatorRoleUniversalRequest : CreatorRoleRequest, ICreatorRolePersonRequest, ICreatorRoleMediaRequest -{ - #region PROPERTIES - - [JsonPropertyName("person_id")] - public long PersonId { get; set; } - - [JsonPropertyName("media_id")] - public long MediaId { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - public CreatorRoleUniversalRequest() { } - - public CreatorRoleUniversalRequest(CreatorRoleResponse data) - { - MediaId = data.MediaId; - PersonId = data.PersonId; - TypeId = data.TypeId; - } - - #endregion - - - - #region PUBLIC METHODS - - public PersonCreatorRole CreateCreatorRole() => base.CreateCreatorRole(MediaId, PersonId); - - public void UpdateCreatorRole(PersonCreatorRole item) => base.UpdateCreatorRole(item, MediaId, PersonId); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleMediaRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleMediaRequest.cs deleted file mode 100644 index c99d824..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleMediaRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace WatchIt.Common.Model.Roles; - -public interface IActorRoleMediaRequest : IActorRoleRequest -{ - #region PROPERTIES - - public long PersonId { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRolePersonRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRolePersonRequest.cs deleted file mode 100644 index 37d2dfc..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRolePersonRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace WatchIt.Common.Model.Roles; - -public interface IActorRolePersonRequest : IActorRoleRequest -{ - #region PROPERTIES - - public long MediaId { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleRequest.cs deleted file mode 100644 index d61550f..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleRequest.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace WatchIt.Common.Model.Roles; - -public interface IActorRoleRequest -{ - #region PROPERTIES - - public short TypeId { get; set; } - - public string Name { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleMediaRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleMediaRequest.cs deleted file mode 100644 index 40fb45d..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleMediaRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace WatchIt.Common.Model.Roles; - -public interface ICreatorRoleMediaRequest : ICreatorRoleRequest -{ - #region PROPERTIES - - public long PersonId { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRolePersonRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRolePersonRequest.cs deleted file mode 100644 index 2e569e5..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRolePersonRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace WatchIt.Common.Model.Roles; - -public interface ICreatorRolePersonRequest : ICreatorRoleRequest -{ - #region PROPERTIES - - public long MediaId { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleRequest.cs deleted file mode 100644 index 150eba0..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace WatchIt.Common.Model.Roles; - -public interface ICreatorRoleRequest -{ - #region PROPERTIES - - public short TypeId { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/IRoleResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/IRoleResponse.cs deleted file mode 100644 index dbd62e3..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/IRoleResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace WatchIt.Common.Model.Roles; - -public interface IRoleResponse -{ - Guid Id { get; set; } - long MediaId { get; set; } - long PersonId { get; set; } - short TypeId { get; set; } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/RoleType.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/RoleType.cs deleted file mode 100644 index cb3ed4e..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/RoleType.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Roles; - -public class RoleType -{ - #region PROPERTIES - - [JsonPropertyName("name")] - public required string Name { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeQueryParameters.cs deleted file mode 100644 index 2198ee9..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeQueryParameters.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Roles; - -public class RoleTypeQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "name")] - public string? Name { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(RoleTypeResponse item) => TestStringWithRegex(item.Name, Name); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeRequest.cs deleted file mode 100644 index cfefe02..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeRequest.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace WatchIt.Common.Model.Roles; - -public class RoleTypeRequest : RoleType -{ - #region PUBLIC METHODS - - public Database.Model.Person.PersonActorRoleType CreateActorRoleType() => new Database.Model.Person.PersonActorRoleType() - { - Name = Name - }; - - public Database.Model.Person.PersonCreatorRoleType CreateCreatorRoleType() => new Database.Model.Person.PersonCreatorRoleType() - { - Name = Name - }; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeResponse.cs deleted file mode 100644 index 2b3dbe6..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Roles/RoleTypeResponse.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Roles; - -public class RoleTypeResponse : RoleType, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "name", item => item.Name } - }; - - - [JsonPropertyName("id")] - public required short Id { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public RoleTypeResponse() { } - - [SetsRequiredMembers] - public RoleTypeResponse(Database.Model.Person.PersonCreatorRoleType creatorRoleType) - { - Id = creatorRoleType.Id; - Name = creatorRoleType.Name; - } - - [SetsRequiredMembers] - public RoleTypeResponse(Database.Model.Person.PersonActorRoleType actorRoleType) - { - Id = actorRoleType.Id; - Name = actorRoleType.Name; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/Series.cs b/WatchIt.Common/WatchIt.Common.Model/Series/Series.cs deleted file mode 100644 index 08978de..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Series/Series.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Model.Series; - -public class Series : Media.Media -{ - [JsonPropertyName("has_ended")] - public bool HasEnded { get; set; } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs deleted file mode 100644 index 2cc5de4..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs +++ /dev/null @@ -1,89 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Series; - -public class SeriesQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "title")] - public string? Title { get; set; } - - [FromQuery(Name = "original_title")] - public string? OriginalTitle { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - [FromQuery(Name = "release_date")] - public DateOnly? ReleaseDate { get; set; } - - [FromQuery(Name = "release_date_from")] - public DateOnly? ReleaseDateFrom { get; set; } - - [FromQuery(Name = "release_date_to")] - public DateOnly? ReleaseDateTo { get; set; } - - [FromQuery(Name = "length")] - public short? Length { get; set; } - - [FromQuery(Name = "length_from")] - public short? LengthFrom { get; set; } - - [FromQuery(Name = "length_to")] - public short? LengthTo { get; set; } - - [FromQuery(Name = "has_ended")] - public bool? HasEnded { get; set; } - - [FromQuery(Name = "rating_average")] - public decimal? RatingAverage { get; set; } - - [FromQuery(Name = "rating_average_from")] - public decimal? RatingAverageFrom { get; set; } - - [FromQuery(Name = "rating_average_to")] - public decimal? RatingAverageTo { get; set; } - - [FromQuery(Name = "rating_count")] - public long? RatingCount { get; set; } - - [FromQuery(Name = "rating_count_from")] - public long? RatingCountFrom { get; set; } - - [FromQuery(Name = "rating_count_to")] - public long? RatingCountTo { get; set; } - - [FromQuery(Name = "genre")] - public IEnumerable? Genres { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(SeriesResponse item) => - ( - TestStringWithRegex(item.Title, Title) - && - TestStringWithRegex(item.OriginalTitle, OriginalTitle) - && - TestStringWithRegex(item.Description, Description) - && - TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo) - && - TestComparable(item.Length, Length, LengthFrom, LengthTo) - && - Test(item.HasEnded, HasEnded) - && - TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) - && - TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) - && - TestContains(item.Genres.Select(x => x.Id), Genres) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedQueryParameters.cs deleted file mode 100644 index b686626..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedQueryParameters.cs +++ /dev/null @@ -1,111 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Model.Series; - -public class SeriesRatedQueryParameters : QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "title")] - public string? Title { get; set; } - - [FromQuery(Name = "original_title")] - public string? OriginalTitle { get; set; } - - [FromQuery(Name = "description")] - public string? Description { get; set; } - - [FromQuery(Name = "release_date")] - public DateOnly? ReleaseDate { get; set; } - - [FromQuery(Name = "release_date_from")] - public DateOnly? ReleaseDateFrom { get; set; } - - [FromQuery(Name = "release_date_to")] - public DateOnly? ReleaseDateTo { get; set; } - - [FromQuery(Name = "length")] - public short? Length { get; set; } - - [FromQuery(Name = "length_from")] - public short? LengthFrom { get; set; } - - [FromQuery(Name = "length_to")] - public short? LengthTo { get; set; } - - [FromQuery(Name = "has_ended")] - public bool? HasEnded { get; set; } - - [FromQuery(Name = "rating_average")] - public decimal? RatingAverage { get; set; } - - [FromQuery(Name = "rating_average_from")] - public decimal? RatingAverageFrom { get; set; } - - [FromQuery(Name = "rating_average_to")] - public decimal? RatingAverageTo { get; set; } - - [FromQuery(Name = "rating_count")] - public long? RatingCount { get; set; } - - [FromQuery(Name = "rating_count_from")] - public long? RatingCountFrom { get; set; } - - [FromQuery(Name = "rating_count_to")] - public long? RatingCountTo { get; set; } - - [FromQuery(Name = "genre")] - public IEnumerable? Genres { get; set; } - - [FromQuery(Name = "user_rating")] - public decimal? UserRating { get; set; } - - [FromQuery(Name = "user_rating_from")] - public decimal? UserRatingFrom { get; set; } - - [FromQuery(Name = "user_rating_to")] - public decimal? UserRatingTo { get; set; } - - [FromQuery(Name = "user_rating_date")] - public DateOnly? UserRatingDate { get; set; } - - [FromQuery(Name = "user_rating_date_from")] - public DateOnly? UserRatingDateFrom { get; set; } - - [FromQuery(Name = "user_rating_date_to")] - public DateOnly? UserRatingDateTo { get; set; } - - #endregion - - - - #region PRIVATE METHODS - - protected override bool IsMeetingConditions(SeriesRatedResponse item) => - ( - TestStringWithRegex(item.Title, Title) - && - TestStringWithRegex(item.OriginalTitle, OriginalTitle) - && - TestStringWithRegex(item.Description, Description) - && - TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo) - && - TestComparable(item.Length, Length, LengthFrom, LengthTo) - && - Test(item.HasEnded, HasEnded) - && - TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) - && - TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) - && - TestContains(item.Genres.Select(x => x.Id), Genres) - && - TestComparable((decimal)item.UserRating, UserRating, UserRatingFrom, UserRatingTo) - && - TestComparable(item.UserRatingDate, UserRatingDate, UserRatingDateFrom, UserRatingDateTo) - ); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedResponse.cs deleted file mode 100644 index 8ac56a0..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedResponse.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Query; -using WatchIt.Database.Model.Media; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Common.Model.Series; - -public class SeriesRatedResponse : SeriesResponse, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "title", x => x.Title }, - { "original_title", x => x.OriginalTitle }, - { "description", x => x.Description }, - { "release_date", x => x.ReleaseDate }, - { "length", x => x.Length }, - { "has_ended", x => x.HasEnded }, - { "rating.average", x => x.Rating.Average }, - { "rating.count", x => x.Rating.Count }, - { "user_rating", x => x.UserRating }, - { "user_rating_date", x => x.UserRatingDate } - }; - - [JsonPropertyName("user_rating")] - public short UserRating { get; set; } - - [JsonPropertyName("user_rating_date")] - public DateTime UserRatingDate { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public SeriesRatedResponse() { } - - [SetsRequiredMembers] - public SeriesRatedResponse(MediaSeries mediaSeries, RatingMedia response) - { - Id = mediaSeries.Media.Id; - Title = mediaSeries.Media.Title; - OriginalTitle = mediaSeries.Media.OriginalTitle; - Description = mediaSeries.Media.Description; - ReleaseDate = mediaSeries.Media.ReleaseDate; - Length = mediaSeries.Media.Length; - HasEnded = mediaSeries.HasEnded; - Rating = RatingResponseBuilder.Initialize() - .Add(mediaSeries.Media.RatingMedia, x => x.Rating) - .Build(); - Genres = mediaSeries.Media.Genres.Select(x => new GenreResponse(x)).ToList(); - UserRating = response.Rating; - UserRatingDate = response.Date; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRequest.cs deleted file mode 100644 index baab8c2..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRequest.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Series; - -public class SeriesRequest : Series -{ - #region CONSTRUCTORS - - [SetsRequiredMembers] - public SeriesRequest(SeriesResponse initData) - { - Title = initData.Title; - OriginalTitle = initData.OriginalTitle; - Description = initData.Description; - ReleaseDate = initData.ReleaseDate; - Length = initData.Length; - HasEnded = initData.HasEnded; - } - - public SeriesRequest() {} - - #endregion - - - - #region PUBLIC METHODS - - public Database.Model.Media.Media CreateMedia() => new Database.Model.Media.Media - { - Title = Title, - OriginalTitle = OriginalTitle, - Description = Description, - ReleaseDate = ReleaseDate, - Length = Length, - }; - - public MediaSeries CreateMediaSeries(long id) => new MediaSeries - { - Id = id, - HasEnded = HasEnded, - }; - - public void UpdateMedia(Database.Model.Media.Media media) - { - media.Title = Title; - media.OriginalTitle = OriginalTitle; - media.Description = Description; - media.ReleaseDate = ReleaseDate; - media.Length = Length; - } - - public void UpdateMediaSeries(MediaSeries mediaSeries) - { - mediaSeries.HasEnded = HasEnded; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs deleted file mode 100644 index 7f1c1e3..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Query; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Common.Model.Series; - -public class SeriesResponse : Series, IQueryOrderable -{ - #region PROPERTIES - - [JsonIgnore] - public static IDictionary> OrderableProperties { get; } = new Dictionary> - { - { "id", x => x.Id }, - { "title", x => x.Title }, - { "original_title", x => x.OriginalTitle }, - { "description", x => x.Description }, - { "release_date", x => x.ReleaseDate }, - { "length", x => x.Length }, - { "has_ended", x => x.HasEnded }, - { "rating.average", x => x.Rating.Average }, - { "rating.count", x => x.Rating.Count } - }; - - - [JsonPropertyName("id")] - public long Id { get; set; } - - [JsonPropertyName("rating")] - public RatingResponse Rating { get; set; } - - [JsonPropertyName("genres")] - public IEnumerable Genres { get; set; } - - #endregion - - - - #region CONSTRUCTORS - - [JsonConstructor] - public SeriesResponse() {} - - [SetsRequiredMembers] - public SeriesResponse(MediaSeries mediaSeries) - { - Id = mediaSeries.Media.Id; - Title = mediaSeries.Media.Title; - OriginalTitle = mediaSeries.Media.OriginalTitle; - Description = mediaSeries.Media.Description; - ReleaseDate = mediaSeries.Media.ReleaseDate; - Length = mediaSeries.Media.Length; - HasEnded = mediaSeries.HasEnded; - Rating = RatingResponseBuilder.Initialize() - .Add(mediaSeries.Media.RatingMedia, x => x.Rating) - .Build(); - Genres = mediaSeries.Media.Genres.Select(x => new GenreResponse(x)).ToList(); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/WatchIt.Common.Model.csproj b/WatchIt.Common/WatchIt.Common.Model/WatchIt.Common.Model.csproj deleted file mode 100644 index 066e490..0000000 --- a/WatchIt.Common/WatchIt.Common.Model/WatchIt.Common.Model.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - diff --git a/WatchIt.Common/WatchIt.Common.Query/IQueryOrderable.cs b/WatchIt.Common/WatchIt.Common.Query/IQueryOrderable.cs deleted file mode 100644 index 4d4cdae..0000000 --- a/WatchIt.Common/WatchIt.Common.Query/IQueryOrderable.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Query; - -public interface IQueryOrderable -{ - [JsonIgnore] - public static abstract IDictionary> OrderableProperties { get; } -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs b/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs deleted file mode 100644 index 4f27d62..0000000 --- a/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System.Collections; -using System.Globalization; -using System.Reflection; -using System.Text; -using System.Text.Json.Serialization; -using System.Text.RegularExpressions; -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.Common.Query; - -public abstract class QueryParameters -{ - #region PROPERTIES - - [FromQuery(Name = "order_by")] - public string? OrderBy { get; set; } - - [FromQuery(Name = "order")] - public string? Order { get; set; } - - [FromQuery(Name = "first")] - public int? First { get; set; } - - [FromQuery(Name = "after")] - public int? After { get; set; } - - #endregion - - - - #region PUBLIC METHODS - - public override string ToString() - { - List queries = new List(); - PropertyInfo[] properties = this.GetType().GetProperties(); - foreach (PropertyInfo property in properties) - { - object? value = property.GetValue(this); - FromQueryAttribute? attribute = property.GetCustomAttributes(true).FirstOrDefault(); - if (value is not null && attribute is not null) - { - if (value is IEnumerable enumerable and not string) - { - IEnumerable arrayQueryElements = enumerable.Cast().Select(x => QueryElementToString(attribute.Name!, x.ToString())); - queries.AddRange(arrayQueryElements); - } - else - { - string query = QueryElementToString(attribute.Name!, value); - queries.Add(query); - } - } - } - - return $"?{string.Join('&', queries)}"; - } - - #endregion - - - - #region PRIVATE METHODS - - private string QueryElementToString(string name, object value) - { - string valueString = (value switch - { - decimal d => d.ToString(CultureInfo.InvariantCulture), - _ => value.ToString() - })!; - string query = $"{name}={valueString}"; - return query; - } - - - protected static bool Test(T? property, T? query) => - ( - query is null - || - ( - property is not null - && - property.Equals(query) - ) - ); - - protected static bool TestStringWithRegex(string? property, string? regexQuery) => - ( - string.IsNullOrEmpty(regexQuery) - || - ( - !string.IsNullOrEmpty(property) - && - Regex.IsMatch(property, regexQuery, RegexOptions.IgnoreCase) - ) - ); - - protected static bool TestComparable(IComparable? property, IComparable? exact, IComparable? from, IComparable? to) => - ( - ( - exact is null - || - ( - property is not null - && - property.CompareTo(exact) == 0 - ) - ) - && - ( - from is null - || - ( - property is not null - && - property.CompareTo(from) >= 0 - ) - ) - && - ( - to is null - || - ( - property is not null - && - property.CompareTo(to) < 0 - ) - ) - ); - - protected static bool TestContains(IEnumerable? shouldBeInCollection, IEnumerable? collection) => - ( - collection is null - || - shouldBeInCollection is null - || - shouldBeInCollection.All(collection.Contains) - ); - - #endregion -} - - - -public abstract class QueryParameters : QueryParameters where T : IQueryOrderable -{ - #region PUBLIC METHODS - - protected abstract bool IsMeetingConditions(T item); - - public IEnumerable PrepareData(IEnumerable data) - { - data = data.Where(IsMeetingConditions); - - if (OrderBy is not null) - { - if (T.OrderableProperties.TryGetValue(OrderBy, out Func? orderFunc)) - { - data = Order == "asc" ? data.OrderBy(orderFunc) : data.OrderByDescending(orderFunc); - } - } - if (After is not null) - { - data = data.Skip(After.Value); - } - if (First is not null) - { - data = data.Take(First.Value); - } - return data; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Query/WatchIt.Common.Query.csproj b/WatchIt.Common/WatchIt.Common.Query/WatchIt.Common.Query.csproj deleted file mode 100644 index dd9b769..0000000 --- a/WatchIt.Common/WatchIt.Common.Query/WatchIt.Common.Query.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - diff --git a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpClientService.cs b/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpClientService.cs deleted file mode 100644 index 3f53246..0000000 --- a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpClientService.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace WatchIt.Common.Services.HttpClient; - -public class HttpClientService(System.Net.Http.HttpClient httpClient) : IHttpClientService -{ - #region PUBLIC METHODS - - public async Task SendRequestAsync(HttpRequest request) - { - HttpMethod method = request.MethodType switch - { - HttpMethodType.Get => HttpMethod.Get, - HttpMethodType.Post => HttpMethod.Post, - HttpMethodType.Put => HttpMethod.Put, - HttpMethodType.Patch => HttpMethod.Patch, - HttpMethodType.Delete => HttpMethod.Delete, - _ => throw new ArgumentOutOfRangeException() - }; - - HttpRequestMessage httpRequest = new HttpRequestMessage(method, request.FullUrl); - - if (request.Body is not null) - { - string json = JsonSerializer.Serialize(request.Body); - HttpContent content = new StringContent(json); - content.Headers.ContentType!.MediaType = "application/json"; - httpRequest.Content = content; - } - - foreach (KeyValuePair header in request.Headers) - { - httpRequest.Headers.Add(header.Key, header.Value); - } - - HttpResponseMessage response = await httpClient.SendAsync(httpRequest); - - return new HttpResponse(response); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpMethodType.cs b/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpMethodType.cs deleted file mode 100644 index 79611b6..0000000 --- a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpMethodType.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace WatchIt.Common.Services.HttpClient; - -public enum HttpMethodType -{ - Get, - Post, - Put, - Patch, - Delete -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpRequest.cs b/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpRequest.cs deleted file mode 100644 index c0c0149..0000000 --- a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpRequest.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using WatchIt.Common.Query; - -namespace WatchIt.Common.Services.HttpClient; - -public class HttpRequest -{ - #region PROPERTIES - - public required HttpMethodType MethodType { get; set; } - public required string Url { get; set; } - public QueryParameters? Query { get; set; } - public object? Body { get; set; } - public Dictionary Headers { get; } = new Dictionary(); - - public string FullUrl => $"{Url}{(Query is not null ? Query.ToString() : string.Empty)}"; - - #endregion - - - - #region CONSTRUCTORS - - [SetsRequiredMembers] - public HttpRequest(HttpMethodType methodType, string url) - { - MethodType = methodType; - Url = url; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpResponse.cs b/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpResponse.cs deleted file mode 100644 index 4180f6e..0000000 --- a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/HttpResponse.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System.Text.Json; -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.Common.Services.HttpClient; - -public class HttpResponse -{ - #region FIELDS - - private readonly HttpResponseMessage _message; - - private Action? _2XXAction; - private Action? _400Action; - private Action? _401Action; - private Action? _403Action; - private Action? _404Action; - - #endregion - - - - #region CONSTRUCTORS - - internal HttpResponse(HttpResponseMessage message) - { - _message = message; - } - - #endregion - - - - #region PUBLIC METHODS - - public HttpResponse RegisterActionFor2XXSuccess(Action? action) - { - _2XXAction = action; - return this; - } - - public HttpResponse RegisterActionFor2XXSuccess(Action? action) - { - _2XXAction = () => Invoke(action); - return this; - } - - public HttpResponse RegisterActionFor400BadRequest(Action>? action) - { - _400Action = () => Invoke(action); - return this; - } - - public HttpResponse RegisterActionFor401Unauthorized(Action? action) - { - _401Action = action; - return this; - } - - public HttpResponse RegisterActionFor403Forbidden(Action? action) - { - _403Action = action; - return this; - } - - public HttpResponse RegisterActionFor404NotFound(Action? action) - { - _404Action = action; - return this; - } - - public void ExecuteAction() - { - switch ((int)_message.StatusCode) - { - case >= 200 and <= 299: _2XXAction?.Invoke(); break; - case 400: _400Action?.Invoke(); break; - case 401: _401Action?.Invoke(); break; - case 403: _403Action?.Invoke(); break; - case 404: _404Action?.Invoke(); break; - } - } - - #endregion - - - - #region PRIVATE METHODS - - private async void Invoke(Action? action) - { - Stream streamData = await _message.Content.ReadAsStreamAsync(); - T? data = await JsonSerializer.DeserializeAsync(streamData); - action?.Invoke(data!); - } - - private async void Invoke(Action>? action) - { - Stream streamData = await _message.Content.ReadAsStreamAsync(); - ValidationProblemDetails? data = await JsonSerializer.DeserializeAsync(streamData, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true, - }); - action?.Invoke(data!.Errors); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/IHttpClientService.cs b/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/IHttpClientService.cs deleted file mode 100644 index 484c01e..0000000 --- a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/IHttpClientService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace WatchIt.Common.Services.HttpClient; - -public interface IHttpClientService -{ - Task SendRequestAsync(HttpRequest request); -} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/WatchIt.Common.Services.HttpClient.csproj b/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/WatchIt.Common.Services.HttpClient.csproj deleted file mode 100644 index 026c6c4..0000000 --- a/WatchIt.Common/WatchIt.Common.Services/WatchIt.Common.Services.HttpClient/WatchIt.Common.Services.HttpClient.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - diff --git a/WatchIt.DTO/Converters/ColorJsonConverter.cs b/WatchIt.DTO/Converters/ColorJsonConverter.cs new file mode 100644 index 0000000..29137f2 --- /dev/null +++ b/WatchIt.DTO/Converters/ColorJsonConverter.cs @@ -0,0 +1,15 @@ +using System.Drawing; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace WatchIt.DTO.Converters; + +public class ColorJsonConverter : JsonConverter +{ + #region PUBLIC METHODS + + public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => ColorTranslator.FromHtml(reader.GetString()); + public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options) => writer.WriteStringValue("#" + value.R.ToString("X2") + value.G.ToString("X2") + value.B.ToString("X2")); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/CustomValidators.cs b/WatchIt.DTO/CustomValidators.cs similarity index 96% rename from WatchIt.WebAPI/WatchIt.WebAPI.Validators/CustomValidators.cs rename to WatchIt.DTO/CustomValidators.cs index d243004..2ae4ec7 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/CustomValidators.cs +++ b/WatchIt.DTO/CustomValidators.cs @@ -1,6 +1,6 @@ using FluentValidation; -namespace WatchIt.WebAPI.Validators; +namespace WatchIt.DTO; public static class CustomValidators { diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountFilterQuery.cs new file mode 100644 index 0000000..2b2cc84 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountFilterQuery.cs @@ -0,0 +1,58 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account; + +public class AccountFilterQuery : IFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "username")] + public string? Username { get; set; } + + [FromQuery(Name = "email")] + public string? Email { get; set; } + + [FromQuery(Name = "is_admin")] + public bool? IsAdmin { get; set; } + + [FromQuery(Name = "active_date_from")] + public DateOnly? ActiveDateFrom { get; set; } + + [FromQuery(Name = "active_date_to")] + public DateOnly? ActiveDateTo { get; set; } + + [FromQuery(Name = "join_date_from")] + public DateOnly? JoinDateFrom { get; set; } + + [FromQuery(Name = "join_date_to")] + public DateOnly? JoinDateTo { get; set; } + + [FromQuery(Name = "description")] + public string? Description { get; set; } + + [FromQuery(Name = "gender_id")] + public short? GenderId { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new AccountUsernameFilter(Username), + new AccountEmailFilter(Email), + new AccountIsAdminFilter(IsAdmin), + new AccountActiveDateFromFilter(ActiveDateFrom), + new AccountActiveDateToFilter(ActiveDateTo), + new AccountJoinDateFromFilter(JoinDateFrom), + new AccountJoinDateToFilter(JoinDateTo), + new AccountDescriptionFilter(Description), + new AccountGenderIdFilter(GenderId), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountOrderKeys.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountOrderKeys.cs new file mode 100644 index 0000000..7a49d17 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountOrderKeys.cs @@ -0,0 +1,18 @@ +using System.Linq.Expressions; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account; + +public static class AccountOrderKeys +{ + public static readonly Dictionary>> Base = new Dictionary>> + { + { "id", x => x.Id }, + { "username", x => x.Username }, + { "email", x => x.Email }, + { "is_admin", x => x.IsAdmin }, + { "active_date", x => x.ActiveDate }, + { "join_date", x => x.JoinDate }, + { "description", x => x.Description }, + { "gender", x => x.Gender != null ? x.Gender.Name : null }, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountRequest.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountRequest.cs new file mode 100644 index 0000000..382685d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountRequest.cs @@ -0,0 +1,9 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts.Account; + +public class AccountRequest : IPasswordEditRequest +{ + public string Username { get; set; } = null!; + public string Email { get; set; } = null!; + public string Password { get; set; } = null!; + public string PasswordConfirmation { get; set; } = null!; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountRequestValidator.cs new file mode 100644 index 0000000..0fa2418 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountRequestValidator.cs @@ -0,0 +1,17 @@ +using FluentValidation; +using WatchIt.Database; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account; + +public class AccountRequestValidator : AbstractValidator +{ + public AccountRequestValidator(DatabaseContext database) + { + Include(new PasswordEditRequestValidator()); + RuleFor(x => x.Username).MinimumLength(5) + .MaximumLength(50) + .CannotBeIn(database.Accounts, x => x.Username).WithMessage("Username was already used"); + RuleFor(x => x.Email).EmailAddress() + .CannotBeIn(database.Accounts, x => x.Email).WithMessage("Email was already used"); + } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountResponse.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountResponse.cs new file mode 100644 index 0000000..c047cdc --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/AccountResponse.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Models.Generics.Image; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account; + +public class AccountResponse +{ + public long Id { get; set; } + public string Username { get; set; } = null!; + public string Email { get; set; } = null!; + public bool IsAdmin { get; set; } + public DateTimeOffset ActiveDate { get; set; } + public DateTimeOffset JoinDate { get; set; } + public string? Description { get; set; } + public GenderResponse? Gender { get; set; } + public ImageResponse? ProfilePicture { get; set; } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountActiveDateFromFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountActiveDateFromFilter.cs new file mode 100644 index 0000000..186fbc5 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountActiveDateFromFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountActiveDateFromFilter : Filter +{ + public AccountActiveDateFromFilter(DateOnly? query) : base(x => + ( + query == null + || + x.ActiveDate.UtcDateTime.CompareTo(query.Value) >= 0 + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountActiveDateToFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountActiveDateToFilter.cs new file mode 100644 index 0000000..40af3e8 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountActiveDateToFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountActiveDateToFilter : Filter +{ + public AccountActiveDateToFilter(DateOnly? query) : base(x => + ( + query == null + || + x.ActiveDate.UtcDateTime.CompareTo(query.Value) <= 0 + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountDescriptionFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountDescriptionFilter.cs new file mode 100644 index 0000000..cda7abb --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountDescriptionFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountDescriptionFilter : Filter +{ + public AccountDescriptionFilter(string? descriptionRegex) : base(x => + ( + string.IsNullOrWhiteSpace(descriptionRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Description) + && + Regex.IsMatch(x.Description, descriptionRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountEmailFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountEmailFilter.cs new file mode 100644 index 0000000..4246434 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountEmailFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountEmailFilter : Filter +{ + public AccountEmailFilter(string? emailRegex) : base(x => + ( + string.IsNullOrWhiteSpace(emailRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Username) + && + Regex.IsMatch(x.Username, emailRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountGenderIdFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountGenderIdFilter.cs new file mode 100644 index 0000000..e1a5fb3 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountGenderIdFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountGenderIdFilter : Filter +{ + public AccountGenderIdFilter(short? genderId) : base(x => + ( + genderId == null + || + x.GenderId == genderId + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountIsAdminFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountIsAdminFilter.cs new file mode 100644 index 0000000..96602b4 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountIsAdminFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountIsAdminFilter : Filter +{ + public AccountIsAdminFilter(bool? query) : base(x => + ( + query == null + || + x.IsAdmin == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountJoinDateFromFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountJoinDateFromFilter.cs new file mode 100644 index 0000000..fdc7c61 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountJoinDateFromFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountJoinDateFromFilter : Filter +{ + public AccountJoinDateFromFilter(DateOnly? query) : base(x => + ( + query == null + || + x.JoinDate.UtcDateTime.CompareTo(query.Value) >= 0 + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountJoinDateToFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountJoinDateToFilter.cs new file mode 100644 index 0000000..9771da0 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountJoinDateToFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountJoinDateToFilter : Filter +{ + public AccountJoinDateToFilter(DateOnly? query) : base(x => + ( + query == null + || + x.JoinDate.UtcDateTime.CompareTo(query.Value) <= 0 + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountUsernameFilter.cs b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountUsernameFilter.cs new file mode 100644 index 0000000..51a5a8f --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/Account/Filters/AccountUsernameFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters; + +public record AccountUsernameFilter : Filter +{ + public AccountUsernameFilter(string? usernameRegex) : base(x => + ( + string.IsNullOrWhiteSpace(usernameRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Username) + && + Regex.IsMatch(x.Username, usernameRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountBackgroundPicture/AccountBackgroundPictureRequest.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountBackgroundPicture/AccountBackgroundPictureRequest.cs new file mode 100644 index 0000000..193c514 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountBackgroundPicture/AccountBackgroundPictureRequest.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture; + +public class AccountBackgroundPictureRequest +{ + #region PROPERTIES + + public Guid Id { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountBackgroundPicture/AccountBackgroundPictureRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountBackgroundPicture/AccountBackgroundPictureRequestValidator.cs new file mode 100644 index 0000000..a8eafc0 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountBackgroundPicture/AccountBackgroundPictureRequestValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; +using WatchIt.Database; + +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture; + +public class AccountBackgroundPictureRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public AccountBackgroundPictureRequestValidator(DatabaseContext database) + { + RuleFor(x => x.Id).MustBeIn(database.PhotoBackgrounds, x => x.Id).WithMessage("Background does not exists"); + } + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountEmail/AccountEmailRequest.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountEmail/AccountEmailRequest.cs new file mode 100644 index 0000000..4c7576b --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountEmail/AccountEmailRequest.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountEmail; + +public class AccountEmailRequest +{ + #region PROPERTIES + + public string Email { get; set; } = null!; + public string Password { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountEmail/AccountEmailRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountEmail/AccountEmailRequestValidator.cs new file mode 100644 index 0000000..7907661 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountEmail/AccountEmailRequestValidator.cs @@ -0,0 +1,17 @@ +using FluentValidation; +using WatchIt.Database; + +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountEmail; + +public class AccountEmailRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public AccountEmailRequestValidator(DatabaseContext database) + { + RuleFor(x => x.Email).EmailAddress() + .CannotBeIn(database.Accounts, x => x.Email).WithMessage("Email is already used"); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountLogout/AccountLogoutRequest.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountLogout/AccountLogoutRequest.cs new file mode 100644 index 0000000..4954255 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountLogout/AccountLogoutRequest.cs @@ -0,0 +1,6 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountLogout; + +public class AccountLogoutRequest +{ + public string? RefreshToken { get; set; } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountPassword/AccountPasswordRequest.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountPassword/AccountPasswordRequest.cs new file mode 100644 index 0000000..44264c1 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountPassword/AccountPasswordRequest.cs @@ -0,0 +1,12 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountPassword; + +public class AccountPasswordRequest : IPasswordEditRequest +{ + #region PROPERTIES + + public string OldPassword { get; set; } = null!; + public string Password { get; set; } = null!; + public string PasswordConfirmation { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountPassword/AccountPasswordRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountPassword/AccountPasswordRequestValidator.cs new file mode 100644 index 0000000..2fd5b12 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountPassword/AccountPasswordRequestValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; + +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountPassword; + +public class AccountPasswordRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public AccountPasswordRequestValidator() + { + Include(new PasswordEditRequestValidator()); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountProfileInfo/AccountProfileInfoRequest.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountProfileInfo/AccountProfileInfoRequest.cs new file mode 100644 index 0000000..cdd2af8 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountProfileInfo/AccountProfileInfoRequest.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo; + +public class AccountProfileInfoRequest +{ + #region PROPERTIES + + public string? Description { get; set; } + public short? GenderId { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfileInfoRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountProfileInfo/AccountProfileInfoRequestValidator.cs similarity index 84% rename from WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfileInfoRequestValidator.cs rename to WatchIt.DTO/Models/Controllers/Accounts/AccountProfileInfo/AccountProfileInfoRequestValidator.cs index aa20074..8b43956 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfileInfoRequestValidator.cs +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountProfileInfo/AccountProfileInfoRequestValidator.cs @@ -1,8 +1,7 @@ using FluentValidation; -using WatchIt.Common.Model.Accounts; using WatchIt.Database; -namespace WatchIt.WebAPI.Validators.Accounts; +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo; public class AccountProfileInfoRequestValidator : AbstractValidator { diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountUsername/AccountUsernameRequest.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountUsername/AccountUsernameRequest.cs new file mode 100644 index 0000000..d53c58d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountUsername/AccountUsernameRequest.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountUsername; + +public class AccountUsernameRequest +{ + #region PROPERTIES + + public string Username { get; set; } = null!; + public string Password { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountUsername/AccountUsernameRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountUsername/AccountUsernameRequestValidator.cs new file mode 100644 index 0000000..63d3e1f --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountUsername/AccountUsernameRequestValidator.cs @@ -0,0 +1,18 @@ +using FluentValidation; +using WatchIt.Database; + +namespace WatchIt.DTO.Models.Controllers.Accounts.AccountUsername; + +public class AccountUsernameRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public AccountUsernameRequestValidator(DatabaseContext database) + { + RuleFor(x => x.Username).MinimumLength(5) + .MaximumLength(50) + .CannotBeIn(database.Accounts, x => x.Username).WithMessage("Username is already used"); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/AccountsMappers.cs b/WatchIt.DTO/Models/Controllers/Accounts/AccountsMappers.cs new file mode 100644 index 0000000..0a4bc69 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/AccountsMappers.cs @@ -0,0 +1,163 @@ +using WatchIt.Database.Model.Accounts; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture; +using WatchIt.DTO.Models.Controllers.Accounts.AccountEmail; +using WatchIt.DTO.Models.Controllers.Accounts.AccountPassword; +using WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo; +using WatchIt.DTO.Models.Controllers.Accounts.AccountUsername; +using WatchIt.DTO.Models.Controllers.Genders; +using WatchIt.DTO.Models.Generics.Image; + +namespace WatchIt.DTO.Models.Controllers.Accounts; + +public static class AccountsMappers +{ + #region PUBLIC METHODS + + #region Account + + public static Database.Model.Accounts.Account ToEntity(this AccountRequest request, Func passwordGenFunc) + { + PasswordData generatedPassword = passwordGenFunc(request.Password); + return new Database.Model.Accounts.Account + { + Username = request.Username, + Email = request.Email, + Password = generatedPassword.PasswordHash, + LeftSalt = generatedPassword.LeftSalt, + RightSalt = generatedPassword.RightSalt, + }; + } + + public static AccountResponse ToResponse(this Database.Model.Accounts.Account account) => new AccountResponse + { + Id = account.Id, + Username = account.Username, + Email = account.Email, + IsAdmin = account.IsAdmin, + JoinDate = account.JoinDate, + ActiveDate = account.ActiveDate, + Description = account.Description, + Gender = account.Gender?.ToResponse(), + ProfilePicture = account.ProfilePicture?.ToResponse(), + }; + + public static void UpdateActiveDate(this Database.Model.Accounts.Account account) + { + account.ActiveDate = DateTimeOffset.UtcNow; + } + + #endregion + + #region AccountUsername + + public static void UpdateWithRequest(this Database.Model.Accounts.Account account, AccountUsernameRequest request) + { + account.Username = request.Username; + } + + #endregion + + #region AccountEmail + + public static void UpdateWithRequest(this Database.Model.Accounts.Account account, AccountEmailRequest request) + { + account.Email = request.Email; + } + + #endregion + + #region AccountPassword + + public static void UpdateWithRequest(this Database.Model.Accounts.Account account, AccountPasswordRequest request, Func passwordGenFunc) + { + PasswordData generatedPassword = passwordGenFunc(request.Password); + account.Password = generatedPassword.PasswordHash; + account.LeftSalt = generatedPassword.LeftSalt; + account.RightSalt = generatedPassword.RightSalt; + } + + #endregion + + #region AccountProfileInfo + + public static void UpdateWithRequest(this Database.Model.Accounts.Account account, AccountProfileInfoRequest request) + { + account.Description = request.Description; + account.GenderId = request.GenderId; + } + + public static AccountProfileInfoRequest ToProfileInfoRequest(this AccountResponse response) => new AccountProfileInfoRequest + { + Description = response.Description, + GenderId = response.Gender?.Id + }; + + #endregion + + #region AccountProfilePicture + + public static AccountProfilePicture ToEntity(this ImageRequest request, long accountId) => new AccountProfilePicture + { + AccountId = accountId, + Image = request.Image, + MimeType = request.MimeType, + }; + + #endregion + + #region AccountBackgroundPicture + + public static Database.Model.Accounts.AccountBackgroundPicture ToEntity(this AccountBackgroundPictureRequest request, long accountId) => new Database.Model.Accounts.AccountBackgroundPicture + { + AccountId = accountId, + BackgroundId = request.Id, + }; + + public static void UpdateWithRequest(this Database.Model.Accounts.AccountBackgroundPicture entity, AccountBackgroundPictureRequest request) + { + entity.BackgroundId = request.Id; + } + + #endregion + + #region AccountRefreshToken + + public static AccountRefreshToken CreateAccountRefreshTokenEntity(Guid token, long accountId, DateTimeOffset expirationDate, bool isExtendable) => new AccountRefreshToken + { + Token = token, + AccountId = accountId, + ExpirationDate = expirationDate, + IsExtendable = isExtendable, + }; + + public static void UpdateExpirationDate(this AccountRefreshToken entity, DateTimeOffset expirationDate) + { + entity.ExpirationDate = expirationDate; + } + + #endregion + + #region AccountFollow + + public static AccountFollow CreateAccountFollowEntity(long accountFollowerId, long accountFollowedId) => new AccountFollow + { + FollowerId = accountFollowerId, + FollowedId = accountFollowedId, + }; + + #endregion + + #region PasswordData + + public static PasswordData GetPasswordData(this Database.Model.Accounts.Account account) => new PasswordData + { + PasswordHash = account.Password, + LeftSalt = account.LeftSalt, + RightSalt = account.RightSalt, + }; + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/IPasswordEditRequest.cs b/WatchIt.DTO/Models/Controllers/Accounts/IPasswordEditRequest.cs new file mode 100644 index 0000000..d61fb59 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/IPasswordEditRequest.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts; + +public interface IPasswordEditRequest +{ + #region PROPERTIES + + string Password { get; set; } + string PasswordConfirmation { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/PasswordData.cs b/WatchIt.DTO/Models/Controllers/Accounts/PasswordData.cs new file mode 100644 index 0000000..9ad8bc8 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/PasswordData.cs @@ -0,0 +1,12 @@ +namespace WatchIt.DTO.Models.Controllers.Accounts; + +public struct PasswordData +{ + #region PROPERTIES + + public required byte[] PasswordHash { get; set; } + public required string LeftSalt { get; set; } + public required string RightSalt { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Accounts/PasswordEditRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Accounts/PasswordEditRequestValidator.cs new file mode 100644 index 0000000..fe2b349 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Accounts/PasswordEditRequestValidator.cs @@ -0,0 +1,24 @@ +using FluentValidation; + +namespace WatchIt.DTO.Models.Controllers.Accounts; + +public class PasswordEditRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public PasswordEditRequestValidator() + { + RuleFor(x => x.Password).NotNull() + .NotEmpty(); + When(x => x.Password is not null, () => + { + RuleFor(x => x.Password).MinimumLength(8) + .Must(x => x.Any(char.IsUpper)).WithMessage("Password must contain at least one uppercase letter.") + .Must(x => x.Any(char.IsLower)).WithMessage("Password must contain at least one lowercase letter.") + .Must(x => x.Any(char.IsDigit)).WithMessage("Password must contain at least one digit."); + }); + RuleFor(x => x.PasswordConfirmation).Equal(x => x.Password); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationMappers.cs b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationMappers.cs new file mode 100644 index 0000000..ec019dd --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationMappers.cs @@ -0,0 +1,16 @@ +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.DTO.Models.Controllers.Authentication; + +public static class AuthenticationMappers +{ + #region Authentication + + public static AuthenticationResponse CreateAuthenticationResponse(string accessToken, string refreshToken) => new AuthenticationResponse + { + AccessToken = accessToken, + RefreshToken = refreshToken, + }; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRefreshRequest.cs b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRefreshRequest.cs new file mode 100644 index 0000000..a0a9228 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRefreshRequest.cs @@ -0,0 +1,7 @@ +namespace WatchIt.DTO.Models.Controllers.Authentication; + +public class AuthenticationRefreshRequest +{ + public string AccessToken { get; set; } = null!; + public string RefreshToken { get; set; } = null!; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRequest.cs b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRequest.cs new file mode 100644 index 0000000..84cc868 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRequest.cs @@ -0,0 +1,12 @@ +namespace WatchIt.DTO.Models.Controllers.Authentication; + +public class AuthenticationRequest +{ + #region PROPERTIES + + public string UsernameOrEmail { get; set; } = null!; + public string Password { get; set; } = null!; + public bool RememberMe { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRequestValidator.cs new file mode 100644 index 0000000..4b74f8a --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationRequestValidator.cs @@ -0,0 +1,12 @@ +using FluentValidation; + +namespace WatchIt.DTO.Models.Controllers.Authentication; + +public class AuthenticationRequestValidator : AbstractValidator +{ + public AuthenticationRequestValidator() + { + RuleFor(x => x.UsernameOrEmail).NotEmpty(); + RuleFor(x => x.Password).NotEmpty(); + } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationResponse.cs b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationResponse.cs new file mode 100644 index 0000000..a5a70bf --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Authentication/AuthenticationResponse.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Authentication; + +public class AuthenticationResponse +{ + #region PROPERTIES + + public string AccessToken { get; init; } = null!; + public string RefreshToken { get; init; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genders/Gender/Filters/GenderNameFilter.cs b/WatchIt.DTO/Models/Controllers/Genders/Gender/Filters/GenderNameFilter.cs new file mode 100644 index 0000000..8ec819e --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genders/Gender/Filters/GenderNameFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Genders.Gender.Filters; + +public record GenderNameFilter : Filter +{ + public GenderNameFilter(string? nameRegex) : base(x => + ( + string.IsNullOrWhiteSpace(nameRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Name) + && + Regex.IsMatch(x.Name, nameRegex, RegexOptions.IgnoreCase) + ) + )) { } +}; \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderFilterQuery.cs new file mode 100644 index 0000000..9358b06 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderFilterQuery.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Genders.Gender.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Genders.Gender; + +public class GenderFilterQuery : IFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "name")] + public string? Name { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new GenderNameFilter(Name), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderOrderKeys.cs b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderOrderKeys.cs new file mode 100644 index 0000000..29c1c8a --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderOrderKeys.cs @@ -0,0 +1,12 @@ +using System.Linq.Expressions; + +namespace WatchIt.DTO.Models.Controllers.Genders.Gender; + +public static class GenderOrderKeys +{ + public static readonly Dictionary>> Base = new Dictionary>> + { + { "id", x => x.Id }, + { "name", x => x.Name }, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderRequest.cs b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderRequest.cs new file mode 100644 index 0000000..16e413c --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderRequest.cs @@ -0,0 +1,6 @@ +namespace WatchIt.DTO.Models.Controllers.Genders.Gender; + +public class GenderRequest +{ + public string Name { get; set; } = null!; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderRequestValidator.cs new file mode 100644 index 0000000..93a0a96 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderRequestValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; + +namespace WatchIt.DTO.Models.Controllers.Genders.Gender; + +public class GenderRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public GenderRequestValidator() + { + RuleFor(x => x.Name).MaximumLength(100); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderResponse.cs b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderResponse.cs new file mode 100644 index 0000000..61c4418 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genders/Gender/GenderResponse.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Genders.Gender; + +public class GenderResponse +{ + #region PROPERTIES + + public short Id { get; set; } + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genders/GendersMappers.cs b/WatchIt.DTO/Models/Controllers/Genders/GendersMappers.cs new file mode 100644 index 0000000..6c96a88 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genders/GendersMappers.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Models.Controllers.Genders.Gender; + +namespace WatchIt.DTO.Models.Controllers.Genders; + +public static class GendersMappers +{ + public static GenderResponse ToResponse(this Database.Model.Genders.Gender entity) => new GenderResponse + { + Id = entity.Id, + Name = entity.Name, + }; + + public static Database.Model.Genders.Gender ToEntity(this GenderRequest request) => new Database.Model.Genders.Gender + { + Name = request.Name, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genres/Genre/Filters/GenreNameFilter.cs b/WatchIt.DTO/Models/Controllers/Genres/Genre/Filters/GenreNameFilter.cs new file mode 100644 index 0000000..873fe37 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genres/Genre/Filters/GenreNameFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Genres.Genre.Filters; + +public record GenreNameFilter : Filter +{ + public GenreNameFilter(string? nameRegex) : base(x => + ( + string.IsNullOrWhiteSpace(nameRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Name) + && + Regex.IsMatch(x.Name, nameRegex, RegexOptions.IgnoreCase) + ) + )) { } +}; \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreFilterQuery.cs new file mode 100644 index 0000000..cf7e55d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreFilterQuery.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Genres.Genre.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Genres.Genre; + +public class GenreFilterQuery : IFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "name")] + public string? Name { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new GenreNameFilter(Name), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreOrderKeys.cs b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreOrderKeys.cs new file mode 100644 index 0000000..059118d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreOrderKeys.cs @@ -0,0 +1,12 @@ +using System.Linq.Expressions; + +namespace WatchIt.DTO.Models.Controllers.Genres.Genre; + +public static class GenreOrderKeys +{ + public static readonly Dictionary>> Base = new Dictionary>> + { + { "id", x => x.Id }, + { "name", x => x.Name }, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreRequest.cs b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreRequest.cs new file mode 100644 index 0000000..a894555 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreRequest.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Genres.Genre; + +public class GenreRequest +{ + #region PROPERTIES + + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreRequestValidator.cs b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreRequestValidator.cs new file mode 100644 index 0000000..12743fb --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreRequestValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; + +namespace WatchIt.DTO.Models.Controllers.Genres.Genre; + +public class GenreRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public GenreRequestValidator() + { + RuleFor(x => x.Name).MaximumLength(100); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreResponse.cs b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreResponse.cs new file mode 100644 index 0000000..9c181dc --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genres/Genre/GenreResponse.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Genres.Genre; + +public class GenreResponse +{ + #region PROPERTIES + + public short Id { get; set; } + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Genres/GenresMappers.cs b/WatchIt.DTO/Models/Controllers/Genres/GenresMappers.cs new file mode 100644 index 0000000..cb44bfc --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Genres/GenresMappers.cs @@ -0,0 +1,21 @@ +using WatchIt.DTO.Models.Controllers.Genres.Genre; + +namespace WatchIt.DTO.Models.Controllers.Genres; + +public static class GenresMappers +{ + #region PUBLIC METHODS + + public static GenreResponse ToResponse(this Database.Model.Genres.Genre entity) => new GenreResponse + { + Id = entity.Id, + Name = entity.Name, + }; + + public static Database.Model.Genres.Genre ToEntity(this GenreRequest request) => new Database.Model.Genres.Genre + { + Name = request.Name, + }; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/MediaMappers.cs b/WatchIt.DTO/Models/Controllers/Media/MediaMappers.cs new file mode 100644 index 0000000..bd62a9c --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/MediaMappers.cs @@ -0,0 +1,208 @@ +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Models.Controllers.Genres; +using WatchIt.DTO.Models.Controllers.Media.Medium.Request; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Models.Generics.ViewCount; +using MediumType = WatchIt.Database.Model.Media.MediumType; + +namespace WatchIt.DTO.Models.Controllers.Media; + +public static class MediaMappers +{ + #region PUBLIC METHODS + + #region Medium + + public static MediumMovie ToEntity(this MediumMovieRequest request) + { + MediumMovie medium = new MediumMovie(); + medium.UpdateWithRequest(request); + return medium; + } + + public static void UpdateWithRequest(this MediumMovie entity, MediumMovieRequest request) + { + entity.SetMediumEntityProperties(request); + entity.Budget = request.Budget; + } + + public static MediumSeries ToEntity(this MediumSeriesRequest request) + { + MediumSeries medium = new MediumSeries(); + medium.UpdateWithRequest(request); + return medium; + } + + public static void UpdateWithRequest(this MediumSeries entity, MediumSeriesRequest request) + { + entity.SetMediumEntityProperties(request); + entity.HasEnded = request.HasEnded; + } + + public static MediumResponse ToResponse(this Database.Model.Media.Medium entity) + { + MediumResponse response = new MediumResponse(); + response.SetMediumResponseProperties(entity); + response.Type = entity.Type == MediumType.Movie ? Medium.Response.MediumResponseType.Movie : Medium.Response.MediumResponseType.Series; + return response; + } + + public static MediumMovieResponse ToResponse(this MediumMovie entity) + { + MediumMovieResponse response = new MediumMovieResponse(); + response.SetMediumResponseProperties(entity); + response.SetMediumMovieResponseProperties(entity); + return response; + } + + public static MediumSeriesResponse ToResponse(this MediumSeries entity) + { + MediumSeriesResponse response = new MediumSeriesResponse(); + response.SetMediumResponseProperties(entity); + response.SetMediumSeriesResponseProperties(entity); + return response; + } + + public static MediumUserRatedResponse ToResponse(this Database.Model.Media.Medium entity, long accountId) + { + MediumUserRatedResponse response = new MediumUserRatedResponse(); + response.SetMediumResponseProperties(entity); + response.SetMediumUserRatedResponseProperties(entity, accountId); + return response; + } + + public static MediumMovieUserRatedResponse ToResponse(this MediumMovie entity, long accountId) + { + MediumMovieUserRatedResponse response = new MediumMovieUserRatedResponse(); + response.SetMediumResponseProperties(entity); + response.SetMediumMovieResponseProperties(entity); + response.SetMediumUserRatedResponseProperties(entity, accountId); + return response; + } + + public static MediumSeriesUserRatedResponse ToResponse(this MediumSeries entity, long accountId) + { + MediumSeriesUserRatedResponse response = new MediumSeriesUserRatedResponse(); + response.SetMediumResponseProperties(entity); + response.SetMediumSeriesResponseProperties(entity); + response.SetMediumUserRatedResponseProperties(entity, accountId); + return response; + } + + public static MediumRequest ToRequest(this BaseMediumResponse response) + { + MediumRequest request = response switch + { + MediumMovieResponse mediumMovieResponse => new MediumMovieRequest + { + Budget = mediumMovieResponse.Budget, + }, + MediumSeriesResponse mediumSeriesResponse => new MediumSeriesRequest + { + HasEnded = mediumSeriesResponse.HasEnded, + } + }; + request.Title = response.Title; + request.Description = response.Description; + request.OriginalTitle = response.OriginalTitle; + request.ReleaseDate = response.ReleaseDate; + request.Duration = response.Duration; + return request; + } + + #endregion + + #region MediumPicture + + public static MediumPicture ToEntity(this ImageRequest request, long mediumId) => new Database.Model.Media.MediumPicture + { + MediumId = mediumId, + Image = request.Image, + MimeType = request.MimeType, + }; + + #endregion + + #region MediumGenre + + public static MediumGenre CreateMediumGenre(long mediumId, short genreId) => new MediumGenre + { + MediumId = mediumId, + GenreId = genreId, + }; + + #endregion + + #region MediumRating + + public static MediumRating ToEntity(this RatingRequest request, long mediumId, long userId) + { + MediumRating entity = new MediumRating + { + MediumId = mediumId, + AccountId = userId + }; + entity.UpdateWithRequest(request); + return entity; + } + + #endregion + + #region MediumViewCount + + public static MediumViewCount CreateMediumViewCountEntity(long mediumId) => new MediumViewCount + { + MediumId = mediumId, + ViewCount = 1, + }; + + #endregion + + #endregion + + + + #region PRIVATE METHODS + + private static void SetMediumEntityProperties(this Database.Model.Media.Medium entity, MediumRequest request) + { + entity.Title = request.Title; + entity.OriginalTitle = request.OriginalTitle; + entity.Description = request.Description; + entity.Duration = request.Duration; + entity.ReleaseDate = request.ReleaseDate; + } + + private static void SetMediumResponseProperties(this BaseMediumResponse response, Database.Model.Media.Medium entity) + { + response.Id = entity.Id; + response.Title = entity.Title; + response.OriginalTitle = entity.OriginalTitle; + response.Description = entity.Description; + response.ReleaseDate = entity.ReleaseDate; + response.Duration = entity.Duration; + response.Genres = entity.Genres.Select(x => x.ToResponse()); + response.Rating = entity.Ratings.ToOverallResponse(); + response.ViewCount = entity.ViewCounts.ToResponse(); + response.Picture = entity.Picture?.ToResponse(); + } + + private static void SetMediumMovieResponseProperties(this MediumMovieResponse response, MediumMovie entity) + { + response.Budget = entity.Budget; + } + + private static void SetMediumSeriesResponseProperties(this MediumSeriesResponse response, MediumSeries entity) + { + response.HasEnded = entity.HasEnded; + } + + private static void SetMediumUserRatedResponseProperties(this IMediumUserRatedResponse response, Database.Model.Media.Medium entity, long accountId) + { + response.RatingUser = entity.Ratings.SingleOrDefault(x => x.AccountId == accountId)?.ToUserResponse(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumDescriptionFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumDescriptionFilter.cs new file mode 100644 index 0000000..004e47d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumDescriptionFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumDescriptionFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumDescriptionFilter(string? descriptionRegex) : base(x => + ( + string.IsNullOrWhiteSpace(descriptionRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Description) + && + Regex.IsMatch(x.Description, descriptionRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumGenresFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumGenresFilter.cs new file mode 100644 index 0000000..23a4f2e --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumGenresFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumGenresFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumGenresFilter(IEnumerable? query) : base(x => + ( + query == null + || + query.All(y => x.Genres.Select(z => z.Id).Contains(y)) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumMovieBudgetFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumMovieBudgetFromFilter.cs new file mode 100644 index 0000000..9d46c1d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumMovieBudgetFromFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumMovieBudgetFromFilter : Filter +{ + public MediumMovieBudgetFromFilter(decimal? query) : base(x => + ( + query == null + || + x.Budget >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumMovieBudgetToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumMovieBudgetToFilter.cs new file mode 100644 index 0000000..1608fdd --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumMovieBudgetToFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumMovieBudgetToFilter : Filter +{ + public MediumMovieBudgetToFilter(decimal? query) : base(x => + ( + query == null + || + x.Budget <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumOriginalTitleFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumOriginalTitleFilter.cs new file mode 100644 index 0000000..a1077ac --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumOriginalTitleFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumOriginalTitleFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumOriginalTitleFilter(string? originalTitleRegex) : base(x => + ( + string.IsNullOrWhiteSpace(originalTitleRegex) + || + ( + !string.IsNullOrWhiteSpace(x.OriginalTitle) + && + Regex.IsMatch(x.OriginalTitle, originalTitleRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingAverageFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingAverageFromFilter.cs new file mode 100644 index 0000000..6df611d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingAverageFromFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumRatingAverageFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumRatingAverageFromFilter(decimal? query) : base(x => + ( + query == null + || + ( + x.Ratings.Any() + && + (decimal)x.Ratings.Average(y => y.Rating) >= query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingAverageToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingAverageToFilter.cs new file mode 100644 index 0000000..bd742ef --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingAverageToFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumRatingAverageToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumRatingAverageToFilter(decimal? query) : base(x => + ( + query == null + || + ( + x.Ratings.Any() + && + (decimal)x.Ratings.Average(y => y.Rating) <= query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingCountFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingCountFromFilter.cs new file mode 100644 index 0000000..ba5ed77 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingCountFromFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumRatingCountFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumRatingCountFromFilter(long? query) : base(x => + ( + query == null + || + x.Ratings.Count() >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingCountToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingCountToFilter.cs new file mode 100644 index 0000000..d775855 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingCountToFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumRatingCountToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumRatingCountToFilter(long? query) : base(x => + ( + query == null + || + x.Ratings.Count() <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserDateFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserDateFromFilter.cs new file mode 100644 index 0000000..0818aa9 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserDateFromFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumRatingUserDateFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumRatingUserDateFromFilter(DateOnly? query, long accountId) : base(x => + ( + query == null + || + ( + x.Ratings.Any(x => x.AccountId == accountId) + && + x.Ratings.First(x => x.AccountId == accountId).Date >= query.Value.ToDateTime(new TimeOnly(0, 0)) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserDateToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserDateToFilter.cs new file mode 100644 index 0000000..205b507 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserDateToFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumRatingUserDateToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumRatingUserDateToFilter(DateOnly? query, long accountId) : base(x => + ( + query == null + || + ( + x.Ratings.Any(x => x.AccountId == accountId) + && + x.Ratings.First(x => x.AccountId == accountId).Date <= query.Value.ToDateTime(new TimeOnly(23, 59)) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserRatingFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserRatingFromFilter.cs new file mode 100644 index 0000000..47963f2 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserRatingFromFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumRatingUserRatingFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumRatingUserRatingFromFilter(byte? query, long accountId) : base(x => + ( + query == null + || + ( + x.Ratings.Any(x => x.AccountId == accountId) + && + x.Ratings.First(x => x.AccountId == accountId).Rating >= query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserRatingToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserRatingToFilter.cs new file mode 100644 index 0000000..e5bbb62 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumRatingUserRatingToFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumRatingUserRatingToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumRatingUserRatingToFilter(byte? query, long accountId) : base(x => + ( + query == null + || + ( + x.Ratings.Any(x => x.AccountId == accountId) + && + x.Ratings.First(x => x.AccountId == accountId).Rating <= query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumReleaseDateFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumReleaseDateFromFilter.cs new file mode 100644 index 0000000..50a9861 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumReleaseDateFromFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumReleaseDateFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumReleaseDateFromFilter(DateOnly? query) : base(x => + ( + query == null + || + ( + x.ReleaseDate.HasValue + && + x.ReleaseDate.Value.CompareTo(query.Value) >= 0 + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumReleaseDateToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumReleaseDateToFilter.cs new file mode 100644 index 0000000..139d548 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumReleaseDateToFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumReleaseDateToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumReleaseDateToFilter(DateOnly? query) : base(x => + ( + query == null + || + ( + x.ReleaseDate.HasValue + && + x.ReleaseDate.Value.CompareTo(query.Value) <= 0 + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumSeriesHasEndedFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumSeriesHasEndedFilter.cs new file mode 100644 index 0000000..aec760d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumSeriesHasEndedFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumSeriesHasEndedFilter : Filter +{ + public MediumSeriesHasEndedFilter(bool? query) : base(x => + ( + query == null + || + x.HasEnded == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumTitleFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumTitleFilter.cs new file mode 100644 index 0000000..e83d492 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumTitleFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumTitleFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumTitleFilter(string? titleRegex) : base(x => + ( + string.IsNullOrWhiteSpace(titleRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Title) + && + Regex.IsMatch(x.Title, titleRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumTypeFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumTypeFilter.cs new file mode 100644 index 0000000..dfdf6f4 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumTypeFilter.cs @@ -0,0 +1,14 @@ +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumTypeFilter : Filter +{ + public MediumTypeFilter(MediumType? query) : base(x => + ( + query == null + || + x.Type == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLast24HoursFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLast24HoursFromFilter.cs new file mode 100644 index 0000000..0d2a17e --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLast24HoursFromFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumViewCountLast24HoursFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumViewCountLast24HoursFromFilter(long? query) : base(x => + ( + query == null + || + x.ViewCounts + .Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddDays(-1))) + .Sum(y => y.ViewCount) >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLast24HoursToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLast24HoursToFilter.cs new file mode 100644 index 0000000..6c7ff2f --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLast24HoursToFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumViewCountLast24HoursToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumViewCountLast24HoursToFilter(long? query) : base(x => + ( + query == null + || + x.ViewCounts + .Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddDays(-1))) + .Sum(y => y.ViewCount) <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastMonthFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastMonthFromFilter.cs new file mode 100644 index 0000000..8c22874 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastMonthFromFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumViewCountLastMonthFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumViewCountLastMonthFromFilter(long? query) : base(x => + ( + query == null + || + x.ViewCounts + .Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddMonths(-1))) + .Sum(y => y.ViewCount) >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastMonthToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastMonthToFilter.cs new file mode 100644 index 0000000..5f79c78 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastMonthToFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumViewCountLastMonthToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumViewCountLastMonthToFilter(long? query) : base(x => + ( + query == null + || + x.ViewCounts + .Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddMonths(-1))) + .Sum(y => y.ViewCount) <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastWeekFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastWeekFromFilter.cs new file mode 100644 index 0000000..9e5eb0a --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastWeekFromFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumViewCountLastWeekFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumViewCountLastWeekFromFilter(long? query) : base(x => + ( + query == null + || + x.ViewCounts + .Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddDays(-7))) + .Sum(y => y.ViewCount) >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastWeekToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastWeekToFilter.cs new file mode 100644 index 0000000..5d1774b --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastWeekToFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumViewCountLastWeekToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumViewCountLastWeekToFilter(long? query) : base(x => + ( + query == null + || + x.ViewCounts + .Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddDays(-7))) + .Sum(y => y.ViewCount) <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastYearFromFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastYearFromFilter.cs new file mode 100644 index 0000000..a0a2ffd --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastYearFromFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumViewCountLastYearFromFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumViewCountLastYearFromFilter(long? query) : base(x => + ( + query == null + || + x.ViewCounts + .Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddYears(-1))) + .Sum(y => y.ViewCount) >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastYearToFilter.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastYearToFilter.cs new file mode 100644 index 0000000..fbb1ae9 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Filters/MediumViewCountLastYearToFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Filters; + +public record MediumViewCountLastYearToFilter : Filter where T : Database.Model.Media.Medium +{ + public MediumViewCountLastYearToFilter(long? query) : base(x => + ( + query == null + || + x.ViewCounts + .Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddYears(-1))) + .Sum(y => y.ViewCount) <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/MediumOrderKeys.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/MediumOrderKeys.cs new file mode 100644 index 0000000..568cbe7 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/MediumOrderKeys.cs @@ -0,0 +1,43 @@ +using System.Linq.Expressions; +using WatchIt.Database.Model.Media; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium; + +public static class MediumOrderKeys +{ + public static Dictionary>> Base() where T : Database.Model.Media.Medium => new Dictionary>> + { + { "id", x => x.Id }, + { "title", x => x.Title }, + { "original_title", x => x.OriginalTitle }, + { "description", x => x.Description }, + { "release_date", x => x.ReleaseDate }, + { "rating.average", x => x.Ratings.Any() ? x.Ratings.Average(y => y.Rating) : 0 }, + { "rating.count", x => x.Ratings.Count() }, + { "view_count.last_24_hours", x => x.ViewCounts.Where(y => y.Date.ToDateTime(new TimeOnly(23, 59)) >= DateTime.Now.AddDays(-1)).Sum(y => y.ViewCount) }, + { "view_count.last_week", x => x.ViewCounts.Where(y => y.Date.ToDateTime(new TimeOnly(23, 59)) >= DateTime.Now.AddDays(-7)).Sum(y => y.ViewCount) }, + { "view_count.last_month", x => x.ViewCounts.Where(y => y.Date.ToDateTime(new TimeOnly(23, 59)) >= DateTime.Now.AddMonths(-1)).Sum(y => y.ViewCount) }, + { "view_count.last_year", x => x.ViewCounts.Where(y => y.Date.ToDateTime(new TimeOnly(23, 59)) >= DateTime.Now.AddYears(-1)).Sum(y => y.ViewCount) } + }; + + public static readonly Dictionary>> Medium = new Dictionary>> + { + { "type", x => x.Type }, + }; + + public static readonly Dictionary>> MediumMovie = new Dictionary>> + { + { "budget", x => x.Budget }, + }; + + public static readonly Dictionary>> MediumSeries = new Dictionary>> + { + { "has_ended", x => x.HasEnded }, + }; + + public static Dictionary>> MediumUserRated(long accountId) where T : Database.Model.Media.Medium => new Dictionary>> + { + { "rating_user.rating", x => x.Ratings.FirstOrDefault(x => x.AccountId == accountId) != null ? x.Ratings.FirstOrDefault(x => x.AccountId == accountId).Rating : null }, + { "rating_user.date", x => x.Ratings.FirstOrDefault(x => x.AccountId == accountId) != null ? x.Ratings.FirstOrDefault(x => x.AccountId == accountId).Date : null }, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Query/BaseMediumFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/BaseMediumFilterQuery.cs new file mode 100644 index 0000000..960c2cd --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/BaseMediumFilterQuery.cs @@ -0,0 +1,111 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.DTO.Models.Controllers.Media.Medium.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Query; + +public class BaseMediumFilterQuery : IFilterQuery where T : Database.Model.Media.Medium +{ + #region PROPERTIES + + [FromQuery(Name = "title")] + public string? Title { get; set; } + + [FromQuery(Name = "original_title")] + [AliasAs("original_title")] + public string? OriginalTitle { get; set; } + + [FromQuery(Name = "description")] + public string? Description { get; set; } + + [FromQuery(Name = "release_date_from")] + [AliasAs("release_date_from")] + public DateOnly? ReleaseDateFrom { get; set; } + + [FromQuery(Name = "release_date_to")] + [AliasAs("release_date_to")] + public DateOnly? ReleaseDateTo { get; set; } + + [AliasAs("genre")] + [FromQuery(Name = "genre")] + public IEnumerable? Genres { get; set; } + + [FromQuery(Name = "rating_average_from")] + [AliasAs("rating_average_from")] + public decimal? RatingAverageFrom { get; set; } + + [FromQuery(Name = "rating_average_to")] + [AliasAs("rating_average_to")] + public decimal? RatingAverageTo { get; set; } + + [FromQuery(Name = "rating_count_from")] + [AliasAs("rating_count_from")] + public long? RatingCountFrom { get; set; } + + [FromQuery(Name = "rating_count_to")] + [AliasAs("rating_count_to")] + public long? RatingCountTo { get; set; } + + [FromQuery(Name = "view_count_last_24_hours_from")] + [AliasAs("view_count_last_24_hours_from")] + public long? ViewCountLast24HoursFrom { get; set; } + + [FromQuery(Name = "view_count_last_24_hours_from")] + [AliasAs("view_count_last_24_hours_from")] + public long? ViewCountLast24HoursTo { get; set; } + + [FromQuery(Name = "view_count_last_week_from")] + [AliasAs("view_count_last_week_from")] + public long? ViewCountLastWeekFrom { get; set; } + + [FromQuery(Name = "view_count_last_week_to")] + [AliasAs("view_count_last_week_to")] + public long? ViewCountLastWeekTo { get; set; } + + [FromQuery(Name = "view_count_last_month_from")] + [AliasAs("view_count_last_month_from")] + public long? ViewCountLastMonthFrom { get; set; } + + [FromQuery(Name = "view_count_last_month_to")] + [AliasAs("view_count_last_month_to")] + public long? ViewCountLastMonthTo { get; set; } + + [FromQuery(Name = "view_count_last_year_from")] + [AliasAs("view_count_last_year_from")] + public long? ViewCountLastYearFrom { get; set; } + + [FromQuery(Name = "view_count_last_year_to")] + [AliasAs("view_count_last_year_to")] + public long? ViewCountLastYearTo { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public virtual IEnumerable> GetFilters() => + [ + new MediumTitleFilter(Title), + new MediumOriginalTitleFilter(OriginalTitle), + new MediumDescriptionFilter(Description), + new MediumReleaseDateFromFilter(ReleaseDateFrom), + new MediumReleaseDateToFilter(ReleaseDateTo), + new MediumGenresFilter(Genres), + new MediumRatingAverageFromFilter(RatingAverageFrom), + new MediumRatingAverageToFilter(RatingAverageTo), + new MediumRatingCountFromFilter(RatingCountFrom), + new MediumRatingCountToFilter(RatingCountTo), + new MediumViewCountLast24HoursFromFilter(ViewCountLast24HoursFrom), + new MediumViewCountLast24HoursToFilter(ViewCountLast24HoursTo), + new MediumViewCountLastWeekFromFilter(ViewCountLastWeekFrom), + new MediumViewCountLastWeekToFilter(ViewCountLastWeekTo), + new MediumViewCountLastMonthFromFilter(ViewCountLastMonthFrom), + new MediumViewCountLastMonthToFilter(ViewCountLastMonthTo), + new MediumViewCountLastYearFromFilter(ViewCountLastYearFrom), + new MediumViewCountLastYearToFilter(ViewCountLastYearTo), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumFilterQuery.cs new file mode 100644 index 0000000..b2ad4cc --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumFilterQuery.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Models.Controllers.Media.Medium.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Query; + +public class MediumFilterQuery : BaseMediumFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "type")] + public MediumType? Type { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public override IEnumerable> GetFilters() => base.GetFilters() + .Append(new MediumTypeFilter(Type)); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumMovieFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumMovieFilterQuery.cs new file mode 100644 index 0000000..1e97387 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumMovieFilterQuery.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Models.Controllers.Media.Medium.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Query; + +public class MediumMovieFilterQuery : BaseMediumFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "budget_from")] + [AliasAs("budget_from")] + public decimal? BudgetFrom { get; set; } + + [FromQuery(Name = "budget_to")] + [AliasAs("budget_to")] + public decimal? BudgetTo { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public override IEnumerable> GetFilters() => base.GetFilters() + .Append(new MediumMovieBudgetFromFilter(BudgetFrom)) + .Append(new MediumMovieBudgetToFilter(BudgetTo)); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumSeriesFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumSeriesFilterQuery.cs new file mode 100644 index 0000000..18ebcfe --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumSeriesFilterQuery.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Models.Controllers.Media.Medium.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Query; + +public class MediumSeriesFilterQuery : BaseMediumFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "has_ended")] + [AliasAs("has_ended")] + public bool? HasEnded { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public override IEnumerable> GetFilters() => base.GetFilters() + .Append(new MediumSeriesHasEndedFilter(HasEnded)); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumUserRatedFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumUserRatedFilterQuery.cs new file mode 100644 index 0000000..d784d29 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Query/MediumUserRatedFilterQuery.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.DTO.Models.Controllers.Media.Medium.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Query; + +public class MediumUserRatedFilterQuery : IFilterQuery where T : Database.Model.Media.Medium +{ + #region PROPERTIES + + [FromQuery(Name = "rating_user_rating_from")] + [AliasAs("rating_user_rating_from")] + public byte? RatingUserRatingFrom { get; set; } + + [FromQuery(Name = "rating_user_rating_to")] + [AliasAs("rating_user_rating_to")] + public byte? RatingUserRatingTo { get; set; } + + [FromQuery(Name = "rating_user_date_from")] + [AliasAs("rating_user_date_from")] + public DateOnly? RatingUserDateFrom { get; set; } + + [FromQuery(Name = "rating_user_date_to")] + [AliasAs("rating_user_date_to")] + public DateOnly? RatingUserDateTo { get; set; } + + + [FromRoute(Name = "id")] + public long AccountId { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new MediumRatingUserRatingFromFilter(RatingUserRatingFrom, AccountId), + new MediumRatingUserRatingToFilter(RatingUserRatingTo, AccountId), + new MediumRatingUserDateFromFilter(RatingUserDateFrom, AccountId), + new MediumRatingUserDateToFilter(RatingUserDateTo, AccountId) + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumMovieRequest.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumMovieRequest.cs new file mode 100644 index 0000000..f1dc13a --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumMovieRequest.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Request; + +public class MediumMovieRequest : MediumRequest +{ + #region PROPERTIES + + public decimal? Budget { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumRequest.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumRequest.cs new file mode 100644 index 0000000..3bab47e --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumRequest.cs @@ -0,0 +1,14 @@ +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Request; + +public abstract class MediumRequest +{ + #region PROPERTIES + + public string Title { get; set; } = null!; + public string? OriginalTitle { get; set; } + public string? Description { get; set; } + public DateOnly? ReleaseDate { get; set; } + public short? Duration { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumSeriesRequest.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumSeriesRequest.cs new file mode 100644 index 0000000..2a2650e --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Request/MediumSeriesRequest.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Request; + +public class MediumSeriesRequest : MediumRequest +{ + #region PROPERTIES + + public bool HasEnded { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/BaseMediumResponse.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/BaseMediumResponse.cs new file mode 100644 index 0000000..6a184c3 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/BaseMediumResponse.cs @@ -0,0 +1,24 @@ +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Models.Generics.ViewCount; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public abstract class BaseMediumResponse +{ + #region PROPERTIES + + public long Id { get; set; } + public string Title { get; set; } = null!; + public string? OriginalTitle { get; set; } + public string? Description { get; set; } + public DateOnly? ReleaseDate { get; set; } + public short? Duration { get; set; } + public IEnumerable Genres { get; set; } = null!; + public RatingOverallResponse Rating { get; set; } = null!; + public ViewCountResponse ViewCount { get; set; } = null!; + public ImageResponse? Picture { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/IMediumUserRatedResponse.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/IMediumUserRatedResponse.cs new file mode 100644 index 0000000..5b8cecc --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/IMediumUserRatedResponse.cs @@ -0,0 +1,12 @@ +using WatchIt.DTO.Models.Generics.Rating; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public interface IMediumUserRatedResponse +{ + #region PROPERTIES + + RatingUserResponse? RatingUser { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumMovieResponse.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumMovieResponse.cs new file mode 100644 index 0000000..4f325a1 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumMovieResponse.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public class MediumMovieResponse : BaseMediumResponse +{ + #region PROPERTIES + + public decimal? Budget { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumMovieUserRatedResponse.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumMovieUserRatedResponse.cs new file mode 100644 index 0000000..c0d1f8f --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumMovieUserRatedResponse.cs @@ -0,0 +1,12 @@ +using WatchIt.DTO.Models.Generics.Rating; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public class MediumMovieUserRatedResponse : MediumMovieResponse, IMediumUserRatedResponse +{ + #region PROPERTIES + + public RatingUserResponse? RatingUser { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumResponse.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumResponse.cs new file mode 100644 index 0000000..4fec674 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumResponse.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public class MediumResponse : BaseMediumResponse +{ + #region PROPERTIES + + public MediumResponseType Type { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumResponseType.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumResponseType.cs new file mode 100644 index 0000000..ddeece5 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumResponseType.cs @@ -0,0 +1,7 @@ +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public enum MediumResponseType +{ + Movie = 0, + Series = 1, +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumSeriesResponse.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumSeriesResponse.cs new file mode 100644 index 0000000..c4cc849 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumSeriesResponse.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public class MediumSeriesResponse : BaseMediumResponse +{ + #region PROPERTIES + + public bool HasEnded { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumSeriesUserRatedResponse.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumSeriesUserRatedResponse.cs new file mode 100644 index 0000000..844ded7 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumSeriesUserRatedResponse.cs @@ -0,0 +1,12 @@ +using WatchIt.DTO.Models.Generics.Rating; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public class MediumSeriesUserRatedResponse : MediumSeriesResponse, IMediumUserRatedResponse +{ + #region PROPERTIES + + public RatingUserResponse? RatingUser { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumUserRatedResponse.cs b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumUserRatedResponse.cs new file mode 100644 index 0000000..b1db92c --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Media/Medium/Response/MediumUserRatedResponse.cs @@ -0,0 +1,12 @@ +using WatchIt.DTO.Models.Generics.Rating; + +namespace WatchIt.DTO.Models.Controllers.Media.Medium.Response; + +public class MediumUserRatedResponse : MediumResponse, IMediumUserRatedResponse +{ + #region PROPERTIES + + public RatingUserResponse? RatingUser { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/PeopleMappers.cs b/WatchIt.DTO/Models/Controllers/People/PeopleMappers.cs new file mode 100644 index 0000000..291a099 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/PeopleMappers.cs @@ -0,0 +1,108 @@ +using WatchIt.Database.Model.People; +using WatchIt.DTO.Models.Controllers.Genders; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Models.Generics.ViewCount; + +namespace WatchIt.DTO.Models.Controllers.People; + +public static class PeopleMappers +{ + #region PUBLIC METHODS + + #region Person + + public static Database.Model.People.Person ToEntity(this PersonRequest request) => new Database.Model.People.Person + { + Name = request.Name, + FullName = request.FullName, + Description = request.Description, + BirthDate = request.BirthDate, + DeathDate = request.DeathDate, + GenderId = request.GenderId, + }; + + public static void UpdateWithRequest(this Database.Model.People.Person entity, PersonRequest request) + { + entity.Name = request.Name; + entity.FullName = request.FullName; + entity.Description = request.Description; + entity.BirthDate = request.BirthDate; + entity.DeathDate = request.DeathDate; + entity.GenderId = request.GenderId; + } + + public static PersonResponse ToResponse(this Database.Model.People.Person entity) + { + PersonResponse response = new PersonResponse(); + response.SetPersonResponseProperties(entity); + return response; + } + + public static PersonUserRatedResponse ToResponse(this Database.Model.People.Person entity, long accountId) + { + PersonUserRatedResponse response = new PersonUserRatedResponse(); + response.SetPersonResponseProperties(entity); + response.RatingUser = entity.Roles + .SelectMany(x => x.Ratings + .Where(y => y.AccountId == accountId)) + .ToUserOverallResponse(); + return response; + } + + public static PersonRequest ToRequest(this PersonResponse response) => new PersonRequest + { + Name = response.Name, + FullName = response.FullName, + Description = response.Description, + BirthDate = response.BirthDate, + DeathDate = response.DeathDate, + GenderId = response.Gender?.Id, + }; + + #endregion + + #region PersonPicture + + public static Database.Model.People.PersonPicture ToEntity(this ImageRequest request, long personId) => new Database.Model.People.PersonPicture + { + PersonId = personId, + Image = request.Image, + MimeType = request.MimeType, + }; + + #endregion + + #region MediumViewCount + + public static PersonViewCount CreatePersonViewCountEntity(long personId) => new PersonViewCount + { + PersonId = personId, + ViewCount = 1, + }; + + #endregion + + #endregion + + + + #region PRIVATE METHODS + + private static void SetPersonResponseProperties(this PersonResponse response, Database.Model.People.Person entity) + { + response.Id = entity.Id; + response.Name = entity.Name; + response.FullName = entity.FullName; + response.Description = entity.Description; + response.BirthDate = entity.BirthDate; + response.DeathDate = entity.DeathDate; + response.Gender = entity.Gender?.ToResponse(); + response.Rating = entity.Roles.SelectMany(x => x.Ratings).ToOverallResponse(); + response.ViewCount = entity.ViewCounts.ToResponse(); + response.Picture = entity.Picture?.ToResponse(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonBirthDateFromFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonBirthDateFromFilter.cs new file mode 100644 index 0000000..a48ae29 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonBirthDateFromFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonBirthDateFromFilter : Filter +{ + public PersonBirthDateFromFilter(DateOnly? query) : base(x => + ( + query == null + || + x.BirthDate >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonBirthDateToFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonBirthDateToFilter.cs new file mode 100644 index 0000000..3cc4762 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonBirthDateToFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonBirthDateToFilter : Filter +{ + public PersonBirthDateToFilter(DateOnly? query) : base(x => + ( + query == null + || + x.BirthDate <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDeathDateFromFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDeathDateFromFilter.cs new file mode 100644 index 0000000..ae070b0 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDeathDateFromFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonDeathDateFromFilter : Filter +{ + public PersonDeathDateFromFilter(DateOnly? query) : base(x => + ( + query == null + || + x.DeathDate >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDeathDateToFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDeathDateToFilter.cs new file mode 100644 index 0000000..8a548c3 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDeathDateToFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonDeathDateToFilter : Filter +{ + public PersonDeathDateToFilter(DateOnly? query) : base(x => + ( + query == null + || + x.DeathDate <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDescriptionFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDescriptionFilter.cs new file mode 100644 index 0000000..f21c575 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonDescriptionFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonDescriptionFilter : Filter +{ + public PersonDescriptionFilter(string? descriptionRegex) : base(x => + ( + string.IsNullOrWhiteSpace(descriptionRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Description) + && + Regex.IsMatch(x.Description, descriptionRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonFullNameFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonFullNameFilter.cs new file mode 100644 index 0000000..083129e --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonFullNameFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonFullNameFilter : Filter +{ + public PersonFullNameFilter(string? fullNameRegex) : base(x => + ( + string.IsNullOrWhiteSpace(fullNameRegex) + || + ( + !string.IsNullOrWhiteSpace(x.FullName) + && + Regex.IsMatch(x.FullName, fullNameRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonGenderIdFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonGenderIdFilter.cs new file mode 100644 index 0000000..a6655af --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonGenderIdFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonGenderIdFilter : Filter +{ + public PersonGenderIdFilter(short? query) : base(x => + ( + query == null + || + x.GenderId == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonNameFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonNameFilter.cs new file mode 100644 index 0000000..f164827 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonNameFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonNameFilter : Filter +{ + public PersonNameFilter(string? nameRegex) : base(x => + ( + string.IsNullOrWhiteSpace(nameRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Name) + && + Regex.IsMatch(x.Name, nameRegex, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingAverageFromFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingAverageFromFilter.cs new file mode 100644 index 0000000..d9c09b9 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingAverageFromFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingAverageFromFilter : Filter +{ + public PersonRatingAverageFromFilter(decimal? query) : base(x => + ( + query == null + || + ( + x.Roles.SelectMany(y => y.Ratings).Any() + && + (decimal)x.Roles.SelectMany(y => y.Ratings).Average(y => y.Rating) >= query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingAverageToFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingAverageToFilter.cs new file mode 100644 index 0000000..57b44c2 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingAverageToFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingAverageToFilter : Filter +{ + public PersonRatingAverageToFilter(decimal? query) : base(x => + ( + query == null + || + ( + x.Roles.SelectMany(y => y.Ratings).Any() + && + (decimal)x.Roles.SelectMany(y => y.Ratings).Average(y => y.Rating) <= query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingCountFromFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingCountFromFilter.cs new file mode 100644 index 0000000..32e8263 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingCountFromFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingCountFromFilter : Filter +{ + public PersonRatingCountFromFilter(long? query) : base(x => + ( + query == null + || + x.Roles.SelectMany(y => y.Ratings).Count() >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingCountToFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingCountToFilter.cs new file mode 100644 index 0000000..9088889 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingCountToFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingCountToFilter : Filter +{ + public PersonRatingCountToFilter(long? query) : base(x => + ( + query == null + || + x.Roles.SelectMany(y => y.Ratings).Count() <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserAverageFromFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserAverageFromFilter.cs new file mode 100644 index 0000000..a9e9c1a --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserAverageFromFilter.cs @@ -0,0 +1,22 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingUserAverageFromFilter : Filter +{ + public PersonRatingUserAverageFromFilter(decimal? query, long accountId) : base(x => + ( + query == null + || + ( + x.Roles + .SelectMany(y => y.Ratings) + .Any(y => y.AccountId == accountId) + && + (decimal)x.Roles + .SelectMany(y => y.Ratings) + .Where(y => y.AccountId == accountId) + .Average(y => y.Rating) >= query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserAverageToFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserAverageToFilter.cs new file mode 100644 index 0000000..8d22a16 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserAverageToFilter.cs @@ -0,0 +1,22 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingUserAverageToFilter : Filter +{ + public PersonRatingUserAverageToFilter(decimal? query, long accountId) : base(x => + ( + query == null + || + ( + x.Roles + .SelectMany(y => y.Ratings) + .Any(y => y.AccountId == accountId) + && + (decimal)x.Roles + .SelectMany(y => y.Ratings) + .Where(y => y.AccountId == accountId) + .Average(y => y.Rating) <= query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserCountFromFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserCountFromFilter.cs new file mode 100644 index 0000000..4e5dd09 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserCountFromFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingUserCountFromFilter : Filter +{ + public PersonRatingUserCountFromFilter(long? query, long accountId) : base(x => + ( + query == null + || + x.Roles + .SelectMany(y => y.Ratings) + .Count(y => y.AccountId == accountId) >= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserCountToFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserCountToFilter.cs new file mode 100644 index 0000000..b9f920c --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserCountToFilter.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingUserCountToFilter : Filter +{ + public PersonRatingUserCountToFilter(long? query, long accountId) : base(x => + ( + query == null + || + x.Roles + .SelectMany(y => y.Ratings) + .Count(y => y.AccountId == accountId) <= query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserLastRatingDateFromFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserLastRatingDateFromFilter.cs new file mode 100644 index 0000000..f7dc0d7 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserLastRatingDateFromFilter.cs @@ -0,0 +1,22 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingUserLastRatingDateFromFilter : Filter +{ + public PersonRatingUserLastRatingDateFromFilter(DateOnly? query, long accountId) : base(x => + ( + query == null + || + ( + x.Roles + .SelectMany(y => y.Ratings) + .Any(y => y.AccountId == accountId) + && + x.Roles + .SelectMany(y => y.Ratings) + .Where(y => y.AccountId == accountId) + .Max(y => y.Date) >= query.Value.ToDateTime(new TimeOnly(0, 0)) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserLastRatingDateToFilter.cs b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserLastRatingDateToFilter.cs new file mode 100644 index 0000000..47d130c --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Filters/PersonRatingUserLastRatingDateToFilter.cs @@ -0,0 +1,22 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Filters; + +public record PersonRatingUserLastRatingDateToFilter : Filter +{ + public PersonRatingUserLastRatingDateToFilter(DateOnly? query, long accountId) : base(x => + ( + query == null + || + ( + x.Roles + .SelectMany(y => y.Ratings) + .Any(y => y.AccountId == accountId) + && + x.Roles + .SelectMany(y => y.Ratings) + .Where(y => y.AccountId == accountId) + .Max(y => y.Date) <= query.Value.ToDateTime(new TimeOnly(23, 59)) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/PersonOrderKeys.cs b/WatchIt.DTO/Models/Controllers/People/Person/PersonOrderKeys.cs new file mode 100644 index 0000000..a45cf34 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/PersonOrderKeys.cs @@ -0,0 +1,30 @@ +using System.Linq.Expressions; + +namespace WatchIt.DTO.Models.Controllers.People.Person; + +public class PersonOrderKeys +{ + public static readonly Dictionary>> Base = new Dictionary>> + { + { "id", x => x.Id }, + { "name", x => x.Name }, + { "full_name", x => x.FullName }, + { "description", x => x.Description }, + { "birth_date", x => x.BirthDate }, + { "death_date", x => x.BirthDate }, + { "gender", x => x.Gender != null ? x.Gender.Name : null }, + { "rating.average", x => x.Roles.SelectMany(y => y.Ratings).Any() ? x.Roles.SelectMany(y => y.Ratings).Average(y => y.Rating) : 0 }, + { "rating.count", x => x.Roles.SelectMany(y => y.Ratings).Count() }, + { "view_count.last_24_hours", x => x.ViewCounts.Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddDays(-1))).Sum(y => y.ViewCount) }, + { "view_count.last_week", x => x.ViewCounts.Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddDays(-7))).Sum(y => y.ViewCount) }, + { "view_count.last_month", x => x.ViewCounts.Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddMonths(-1))).Sum(y => y.ViewCount) }, + { "view_count.last_year", x => x.ViewCounts.Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddYears(-1))).Sum(y => y.ViewCount) } + }; + + public static Dictionary>> UserRated(long accountId) => new Dictionary>> + { + { "rating_user.average", x => x.Roles.SelectMany(y => y.Ratings).Where(y => y.AccountId == accountId).Average(y => y.Rating) }, + { "rating_user.count", x => x.Roles.SelectMany(y => y.Ratings).Count(y => y.AccountId == accountId) }, + { "rating_user.last_date", x => x.Roles.SelectMany(y => y.Ratings).Where(y => y.AccountId == accountId).Max(y => y.Date) }, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/PersonRequest.cs b/WatchIt.DTO/Models/Controllers/People/Person/PersonRequest.cs new file mode 100644 index 0000000..d9b3cf1 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/PersonRequest.cs @@ -0,0 +1,15 @@ +namespace WatchIt.DTO.Models.Controllers.People.Person; + +public class PersonRequest +{ + #region PROPERTIES + + public string Name { get; set; } = null!; + public string? FullName { get; set; } + public string? Description { get; set; } + public DateOnly? BirthDate { get; set; } + public DateOnly? DeathDate { get; set; } + public short? GenderId { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Persons/PersonRequestValidator.cs b/WatchIt.DTO/Models/Controllers/People/Person/PersonRequestValidator.cs similarity index 70% rename from WatchIt.WebAPI/WatchIt.WebAPI.Validators/Persons/PersonRequestValidator.cs rename to WatchIt.DTO/Models/Controllers/People/Person/PersonRequestValidator.cs index 2f3618e..7d37dac 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Persons/PersonRequestValidator.cs +++ b/WatchIt.DTO/Models/Controllers/People/Person/PersonRequestValidator.cs @@ -1,14 +1,16 @@ using FluentValidation; -using WatchIt.Common.Model.Persons; using WatchIt.Database; -namespace WatchIt.WebAPI.Validators.Persons; +namespace WatchIt.DTO.Models.Controllers.People.Person; public class PersonRequestValidator : AbstractValidator { + #region CONSTRUCTORS + public PersonRequestValidator(DatabaseContext database) { - RuleFor(x => x.Name).NotEmpty().MaximumLength(100); + RuleFor(x => x.Name).NotEmpty() + .MaximumLength(100); RuleFor(x => x.FullName).MaximumLength(200); RuleFor(x => x.Description).MaximumLength(1000); When(x => x.GenderId.HasValue, () => @@ -16,4 +18,5 @@ public class PersonRequestValidator : AbstractValidator RuleFor(x => x.GenderId!.Value).MustBeIn(database.Genders.Select(g => g.Id)); }); } + #endregion } \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/PersonResponse.cs b/WatchIt.DTO/Models/Controllers/People/Person/PersonResponse.cs new file mode 100644 index 0000000..a076121 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/PersonResponse.cs @@ -0,0 +1,24 @@ +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Models.Generics.ViewCount; + +namespace WatchIt.DTO.Models.Controllers.People.Person; + +public class PersonResponse +{ + #region PROPERTIES + + public long Id { get; set; } + public string Name { get; set; } = null!; + public string? FullName { get; set; } + public string? Description { get; set; } + public DateOnly? BirthDate { get; set; } + public DateOnly? DeathDate { get; set; } + public GenderResponse? Gender { get; set; } + public RatingOverallResponse Rating { get; set; } = null!; + public ViewCountResponse ViewCount { get; set; } = null!; + public ImageResponse? Picture { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/PersonUserRatedResponse.cs b/WatchIt.DTO/Models/Controllers/People/Person/PersonUserRatedResponse.cs new file mode 100644 index 0000000..0d439a0 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/PersonUserRatedResponse.cs @@ -0,0 +1,12 @@ +using WatchIt.DTO.Models.Generics.Rating; + +namespace WatchIt.DTO.Models.Controllers.People.Person; + +public class PersonUserRatedResponse : PersonResponse +{ + #region PROPERTIES + + public RatingUserOverallResponse RatingUser { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Query/PersonFilterQuery.cs b/WatchIt.DTO/Models/Controllers/People/Person/Query/PersonFilterQuery.cs new file mode 100644 index 0000000..b091b05 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Query/PersonFilterQuery.cs @@ -0,0 +1,81 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.DTO.Models.Controllers.People.Person.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Query; + +public class PersonFilterQuery : IFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "name")] + public string? Name { get; set; } + + [FromQuery(Name = "full_name")] + [AliasAs("full_name")] + public string? FullName { get; set; } + + [FromQuery(Name = "description")] + public string? Description { get; set; } + + [FromQuery(Name = "birth_date_from")] + [AliasAs("birth_date_from")] + public DateOnly? BirthDateFrom { get; set; } + + [FromQuery(Name = "birth_date_to")] + [AliasAs("birth_date_to")] + public DateOnly? BirthDateTo { get; set; } + + [FromQuery(Name = "death_date_from")] + [AliasAs("death_date_from")] + public DateOnly? DeathDateFrom { get; set; } + + [FromQuery(Name = "death_date_to")] + [AliasAs("death_date_to")] + public DateOnly? DeathDateTo { get; set; } + + [FromQuery(Name = "gender_id")] + [AliasAs("gender_id")] + public short? GenderId { get; set; } + + [FromQuery(Name = "rating_average_from")] + [AliasAs("rating_average_from")] + public decimal? RatingAverageFrom { get; set; } + + [FromQuery(Name = "rating_average_to")] + [AliasAs("rating_average_to")] + public decimal? RatingAverageTo { get; set; } + + [FromQuery(Name = "rating_count_from")] + [AliasAs("rating_count_from")] + public long? RatingCountFrom { get; set; } + + [FromQuery(Name = "rating_count_to")] + [AliasAs("rating_count_to")] + public long? RatingCountTo { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new PersonNameFilter(Name), + new PersonFullNameFilter(FullName), + new PersonDescriptionFilter(Description), + new PersonBirthDateFromFilter(BirthDateFrom), + new PersonBirthDateToFilter(BirthDateTo), + new PersonDeathDateFromFilter(DeathDateFrom), + new PersonDeathDateToFilter(DeathDateTo), + new PersonGenderIdFilter(GenderId), + new PersonRatingAverageFromFilter(RatingAverageFrom), + new PersonRatingAverageToFilter(RatingAverageTo), + new PersonRatingCountFromFilter(RatingCountFrom), + new PersonRatingCountToFilter(RatingCountTo), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/People/Person/Query/PersonUserRatedFilterQuery.cs b/WatchIt.DTO/Models/Controllers/People/Person/Query/PersonUserRatedFilterQuery.cs new file mode 100644 index 0000000..5481be0 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/People/Person/Query/PersonUserRatedFilterQuery.cs @@ -0,0 +1,57 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.DTO.Models.Controllers.People.Person.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.People.Person.Query; + +public class PersonUserRatedFilterQuery : IFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "rating_user_average_from")] + [AliasAs("rating_user_average_from")] + public decimal? RatingUserAverageFrom { get; set; } + + [FromQuery(Name = "rating_user_average_to")] + [AliasAs("rating_user_average_to")] + public decimal? RatingUserAverageTo { get; set; } + + [FromQuery(Name = "rating_user_count_from")] + [AliasAs("rating_user_count_from")] + public long? RatingUserCountFrom { get; set; } + + [FromQuery(Name = "rating_user_count_to")] + [AliasAs("rating_user_count_to")] + public long? RatingUserCountTo { get; set; } + + [FromQuery(Name = "rating_user_last_rating_date_from")] + [AliasAs("rating_user_last_rating_date_from")] + public DateOnly? RatingUserLastRatingDateFrom { get; set; } + + [FromQuery(Name = "rating_user_last_rating_date_to")] + [AliasAs("rating_user_last_rating_date_to")] + public DateOnly? RatingUserLastRatingDateTo { get; set; } + + + [FromRoute(Name = "id")] + public long AccountId { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new PersonRatingUserAverageFromFilter(RatingUserAverageFrom, AccountId), + new PersonRatingUserAverageToFilter(RatingUserAverageTo, AccountId), + new PersonRatingUserCountFromFilter(RatingUserCountFrom, AccountId), + new PersonRatingUserCountToFilter(RatingUserCountTo, AccountId), + new PersonRatingUserLastRatingDateFromFilter(RatingUserLastRatingDateFrom, AccountId), + new PersonRatingUserLastRatingDateToFilter(RatingUserLastRatingDateTo, AccountId), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoIsBackgroundFilter.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoIsBackgroundFilter.cs new file mode 100644 index 0000000..fdc7296 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoIsBackgroundFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo.Filters; + +public record PhotoIsBackgroundFilter : Filter +{ + public PhotoIsBackgroundFilter(bool? query) : base(x => + ( + query == null + || + (x.Background != null) == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoIsUniversalBackgroundFilter.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoIsUniversalBackgroundFilter.cs new file mode 100644 index 0000000..abd8fe4 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoIsUniversalBackgroundFilter.cs @@ -0,0 +1,17 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo.Filters; + +public record PhotoIsUniversalBackgroundFilter : Filter +{ + public PhotoIsUniversalBackgroundFilter(bool? query) : base(x => + ( + query == null + || + ( + x.Background != null + && + x.Background.IsUniversal == query + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoMediumIdFilter.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoMediumIdFilter.cs new file mode 100644 index 0000000..b29ea5d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoMediumIdFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo.Filters; + +public record PhotoMediumIdFilter : Filter +{ + public PhotoMediumIdFilter(long? query) : base(x => + ( + query == null + || + x.MediumId == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoMimeTypeFilter.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoMimeTypeFilter.cs new file mode 100644 index 0000000..5a4cd87 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoMimeTypeFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo.Filters; + +public record PhotoMimeTypeFilter : Filter +{ + public PhotoMimeTypeFilter(string? queryRegex) : base(x => + ( + string.IsNullOrWhiteSpace(queryRegex) + || + ( + !string.IsNullOrWhiteSpace(x.MimeType) + && + Regex.IsMatch(x.MimeType, queryRegex, RegexOptions.IgnoreCase) + ) + )) { } +}; \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoUploadDateFromFilter.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoUploadDateFromFilter.cs new file mode 100644 index 0000000..387e5cd --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoUploadDateFromFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo.Filters; + +public record PhotoUploadDateFromFilter : Filter +{ + public PhotoUploadDateFromFilter(DateOnly? query) : base(x => + ( + query == null + || + x.UploadDate.DateTime.CompareTo(query.Value) >= 0 + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoUploadDateToFilter.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoUploadDateToFilter.cs new file mode 100644 index 0000000..e9f108b --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/Filters/PhotoUploadDateToFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo.Filters; + +public record PhotoUploadDateToFilter : Filter +{ + public PhotoUploadDateToFilter(DateOnly? query) : base(x => + ( + query == null + || + x.UploadDate.DateTime.CompareTo(query.Value) <= 0 + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoFilterQuery.cs new file mode 100644 index 0000000..92400c5 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoFilterQuery.cs @@ -0,0 +1,53 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.DTO.Models.Controllers.Photos.Photo.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo; + +public class PhotoFilterQuery : IFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "medium_id")] + [AliasAs("medium_id")] + public long? MediumId { get; set; } + + [FromQuery(Name = "mime_type")] + [AliasAs("mime_type")] + public string? MimeType { get; set; } + + [FromQuery(Name = "is_background")] + [AliasAs("is_background")] + public bool? IsBackground { get; set; } + + [FromQuery(Name = "is_universal_background")] + [AliasAs("is_universal_background")] + public bool? IsUniversalBackground { get; set; } + + [FromQuery(Name = "upload_date_from")] + [AliasAs("upload_date_from")] + public DateOnly? UploadDateFrom { get; set; } + + [FromQuery(Name = "upload_date_to")] + [AliasAs("upload_date_to")] + public DateOnly? UploadDateTo { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new PhotoMediumIdFilter(MediumId), + new PhotoMimeTypeFilter(MimeType), + new PhotoIsBackgroundFilter(IsBackground), + new PhotoIsUniversalBackgroundFilter(IsUniversalBackground), + new PhotoUploadDateFromFilter(UploadDateFrom), + new PhotoUploadDateToFilter(UploadDateTo), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoOrderKeys.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoOrderKeys.cs new file mode 100644 index 0000000..3af4039 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoOrderKeys.cs @@ -0,0 +1,15 @@ +using System.Linq.Expressions; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo; + +public static class PhotoOrderKeys +{ + public static readonly Dictionary>> Base = new Dictionary>> + { + { "id", x => x.Id }, + { "medium_id", x => x.MediumId }, + { "mime_type", x => x.MimeType }, + { "is_background", x => x.Background != null }, + { "is_universal_background", x => x.Background != null && x.Background.IsUniversal } + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoRequest.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoRequest.cs new file mode 100644 index 0000000..510f356 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoRequest.cs @@ -0,0 +1,14 @@ +using WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; +using WatchIt.DTO.Models.Generics.Image; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo; + +public class PhotoRequest : ImageRequest +{ + #region PROPERTIES + + public long MediumId { get; set; } + public PhotoBackgroundRequest? BackgroundData { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoResponse.cs b/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoResponse.cs new file mode 100644 index 0000000..b97da22 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/Photo/PhotoResponse.cs @@ -0,0 +1,15 @@ +using WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; +using WatchIt.DTO.Models.Generics.Image; + +namespace WatchIt.DTO.Models.Controllers.Photos.Photo; + +public class PhotoResponse : ImageResponse +{ + #region PROPERTIES + + public Guid Id { get; set; } + public long MediumId { get; set; } + public PhotoBackgroundResponse? Background { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/PhotoBackground/PhotoBackgroundRequest.cs b/WatchIt.DTO/Models/Controllers/Photos/PhotoBackground/PhotoBackgroundRequest.cs new file mode 100644 index 0000000..b818342 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/PhotoBackground/PhotoBackgroundRequest.cs @@ -0,0 +1,14 @@ +using System.Drawing; + +namespace WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; + +public class PhotoBackgroundRequest +{ + #region PROPERTIES + + public bool IsUniversal { get; set; } + public Color FirstGradientColor { get; set; } + public Color SecondGradientColor { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/PhotoBackground/PhotoBackgroundResponse.cs b/WatchIt.DTO/Models/Controllers/Photos/PhotoBackground/PhotoBackgroundResponse.cs new file mode 100644 index 0000000..d925357 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/PhotoBackground/PhotoBackgroundResponse.cs @@ -0,0 +1,15 @@ +using System.Drawing; + +namespace WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; + +public class PhotoBackgroundResponse +{ + #region PROPERTIES + + public Guid Id { get; set; } + public bool IsUniversal { get; set; } + public Color FirstGradientColor { get; set; } + public Color SecondGradientColor { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Photos/PhotosMappers.cs b/WatchIt.DTO/Models/Controllers/Photos/PhotosMappers.cs new file mode 100644 index 0000000..18d36c2 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Photos/PhotosMappers.cs @@ -0,0 +1,74 @@ +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; + +namespace WatchIt.DTO.Models.Controllers.Photos; + +public static class PhotosMappers +{ + #region PUBLIC METHODS + + #region Photo + + public static Database.Model.Photos.Photo ToEntity(this PhotoRequest request) => new Database.Model.Photos.Photo + { + MediumId = request.MediumId, + Image = request.Image, + MimeType = request.MimeType, + }; + + public static PhotoResponse ToResponse(this Database.Model.Photos.Photo entity) => new PhotoResponse + { + Id = entity.Id, + MediumId = entity.MediumId, + Image = entity.Image, + MimeType = entity.MimeType, + UploadDate = entity.UploadDate, + Background = entity.Background?.ToResponse() + }; + + public static PhotoRequest ToRequest(this PhotoResponse response) => new PhotoRequest + { + Image = response.Image, + MimeType = response.MimeType, + MediumId = response.MediumId, + BackgroundData = response.Background?.ToRequest() + }; + + #endregion + + #region PhotoBackground + + public static Database.Model.Photos.PhotoBackground ToEntity(this PhotoBackgroundRequest request, Guid photoId) => new Database.Model.Photos.PhotoBackground + { + PhotoId = photoId, + IsUniversal = request.IsUniversal, + FirstGradientColor = request.FirstGradientColor, + SecondGradientColor = request.SecondGradientColor, + }; + + public static void UpdateWithRequest(this Database.Model.Photos.PhotoBackground entity, PhotoBackgroundRequest request) + { + entity.IsUniversal = request.IsUniversal; + entity.FirstGradientColor = request.FirstGradientColor; + entity.SecondGradientColor = request.SecondGradientColor; + } + + public static PhotoBackgroundResponse ToResponse(this Database.Model.Photos.PhotoBackground entity) => new PhotoBackgroundResponse + { + Id = entity.Id, + IsUniversal = entity.IsUniversal, + FirstGradientColor = entity.FirstGradientColor, + SecondGradientColor = entity.SecondGradientColor, + }; + + public static PhotoBackgroundRequest ToRequest(this PhotoBackgroundResponse response) => new PhotoBackgroundRequest + { + IsUniversal = response.IsUniversal, + FirstGradientColor = response.FirstGradientColor, + SecondGradientColor = response.SecondGradientColor, + }; + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/IRoleTypeResponse.cs b/WatchIt.DTO/Models/Controllers/Roles/IRoleTypeResponse.cs new file mode 100644 index 0000000..3498913 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/IRoleTypeResponse.cs @@ -0,0 +1,7 @@ +namespace WatchIt.DTO.Models.Controllers.Roles; + +public interface IRoleTypeResponse +{ + short Id { get; set; } + string Name { get; set; } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleActorNameFilter.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleActorNameFilter.cs new file mode 100644 index 0000000..178878d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleActorNameFilter.cs @@ -0,0 +1,19 @@ +using System.Text.RegularExpressions; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Filters; + +public record RoleActorNameFilter : Filter +{ + public RoleActorNameFilter(string? regexQuery) : base(x => + ( + string.IsNullOrWhiteSpace(regexQuery) + || + ( + !string.IsNullOrWhiteSpace(x.Name) + && + Regex.IsMatch(x.Name, regexQuery, RegexOptions.IgnoreCase) + ) + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleActorTypeIdFilter.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleActorTypeIdFilter.cs new file mode 100644 index 0000000..0e7f0b5 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleActorTypeIdFilter.cs @@ -0,0 +1,14 @@ +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Filters; + +public record RoleActorTypeIdFilter : Filter +{ + public RoleActorTypeIdFilter(short? query) : base(x => + ( + query == null + || + x.ActorTypeId == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleCreatorTypeIdFilter.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleCreatorTypeIdFilter.cs new file mode 100644 index 0000000..8c5c6e4 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleCreatorTypeIdFilter.cs @@ -0,0 +1,14 @@ +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Filters; + +public record RoleCreatorTypeIdFilter : Filter +{ + public RoleCreatorTypeIdFilter(short? query) : base(x => + ( + query == null + || + x.CreatorTypeId == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleMediumIdFilter.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleMediumIdFilter.cs new file mode 100644 index 0000000..fbfd9bc --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RoleMediumIdFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Filters; + +public record RoleMediumIdFilter : Filter where T : Database.Model.Roles.Role +{ + public RoleMediumIdFilter(long? query) : base(x => + ( + query == null + || + x.MediumId == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RolePersonIdFilter.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RolePersonIdFilter.cs new file mode 100644 index 0000000..e0803a3 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Filters/RolePersonIdFilter.cs @@ -0,0 +1,13 @@ +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Filters; + +public record RolePersonIdFilter : Filter where T : Database.Model.Roles.Role +{ + public RolePersonIdFilter(long? query) : base(x => + ( + query == null + || + x.PersonId == query + )) { } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Query/BaseRoleFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Query/BaseRoleFilterQuery.cs new file mode 100644 index 0000000..2dc7f6f --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Query/BaseRoleFilterQuery.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.DTO.Models.Controllers.Roles.Role.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Query; + +public abstract class BaseRoleFilterQuery : IFilterQuery where T : Database.Model.Roles.Role +{ + #region PROPERTIES + + [FromQuery(Name = "person_id")] + [AliasAs("person_id")] + public long? PersonId { get; set; } + + [FromQuery(Name = "medium_id")] + [AliasAs("medium_id")] + public long? MediumId { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public virtual IEnumerable> GetFilters() => + [ + new RolePersonIdFilter(PersonId), + new RoleMediumIdFilter(MediumId), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Query/IRoleFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Query/IRoleFilterQuery.cs new file mode 100644 index 0000000..193e1db --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Query/IRoleFilterQuery.cs @@ -0,0 +1,8 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Query; + +public interface IRoleFilterQuery +{ + short? TypeId { get; set; } + long? PersonId { get; set; } + long? MediumId { get; set; } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Query/RoleActorFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Query/RoleActorFilterQuery.cs new file mode 100644 index 0000000..1d13b32 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Query/RoleActorFilterQuery.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Models.Controllers.Roles.Role.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Query; + +public class RoleActorFilterQuery : BaseRoleFilterQuery, IRoleFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "type_id")] + [AliasAs("type_id")] + public short? TypeId { get; set; } + + [FromQuery(Name = "name")] + [AliasAs("name")] + public string? Name { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public override IEnumerable> GetFilters() => base.GetFilters() + .Append(new RoleActorTypeIdFilter(TypeId)) + .Append(new RoleActorNameFilter(Name)); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Query/RoleCreatorFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Query/RoleCreatorFilterQuery.cs new file mode 100644 index 0000000..a751122 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Query/RoleCreatorFilterQuery.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Models.Controllers.Roles.Role.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Query; + +public class RoleCreatorFilterQuery : BaseRoleFilterQuery, IRoleFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "type_id")] + [AliasAs("type_id")] + public short? TypeId { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public override IEnumerable> GetFilters() => base.GetFilters() + .Append(new RoleCreatorTypeIdFilter(TypeId)); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleActorRequest.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleActorRequest.cs new file mode 100644 index 0000000..e06b57b --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleActorRequest.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Request; + +public class RoleActorRequest : RoleRequest +{ + #region PROPERTIES + + public short TypeId { get; set; } + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleCreatorRequest.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleCreatorRequest.cs new file mode 100644 index 0000000..96cdf32 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleCreatorRequest.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Request; + +public class RoleCreatorRequest : RoleRequest +{ + #region PROPERTIES + + public short TypeId { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleRequest.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleRequest.cs new file mode 100644 index 0000000..0fb9f66 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Request/RoleRequest.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Request; + +public abstract class RoleRequest +{ + #region PROPERTIES + + public long MediumId { get; set; } + public long PersonId { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleActorResponse.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleActorResponse.cs new file mode 100644 index 0000000..d33685f --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleActorResponse.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Response; + +public class RoleActorResponse : RoleResponse +{ + #region PROPERTIES + + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleCreatorResponse.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleCreatorResponse.cs new file mode 100644 index 0000000..681c2ba --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleCreatorResponse.cs @@ -0,0 +1,3 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Response; + +public class RoleCreatorResponse : RoleResponse; \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleResponse.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleResponse.cs new file mode 100644 index 0000000..6e7bede --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/Response/RoleResponse.cs @@ -0,0 +1,13 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.Role.Response; + +public abstract class RoleResponse +{ + #region PROPERTIES + + public Guid Id { get; set; } + public long MediumId { get; set; } + public long PersonId { get; set; } + public short TypeId { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/Role/RoleOrderKeys.cs b/WatchIt.DTO/Models/Controllers/Roles/Role/RoleOrderKeys.cs new file mode 100644 index 0000000..f747404 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/Role/RoleOrderKeys.cs @@ -0,0 +1,25 @@ +using System.Linq.Expressions; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.DTO.Models.Controllers.Roles.Role; + +public class RoleOrderKeys +{ + public static Dictionary>> Base() where T : Database.Model.Roles.Role => new Dictionary>> + { + { "person", item => item.PersonId }, + { "medium", item => item.MediumId }, + { "medium.release_date", item => item.Medium.ReleaseDate } + }; + + public static readonly Dictionary>> RoleActor = new Dictionary>> + { + { "type_id", x => x.ActorTypeId }, + { "name", x => x.Name }, + }; + + public static readonly Dictionary>> RoleCreator = new Dictionary>> + { + { "type_id", x => x.CreatorTypeId }, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/Filters/RoleActorTypeNameFilter.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/Filters/RoleActorTypeNameFilter.cs new file mode 100644 index 0000000..5157220 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/Filters/RoleActorTypeNameFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.RoleActorType.Filters; + +public record RoleActorTypeNameFilter : Filter +{ + public RoleActorTypeNameFilter(string? nameRegex) : base(x => + ( + string.IsNullOrWhiteSpace(nameRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Name) + && + Regex.IsMatch(x.Name, nameRegex, RegexOptions.IgnoreCase) + ) + )) { } +}; \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeFilterQuery.cs new file mode 100644 index 0000000..467ac5d --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeFilterQuery.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.RoleActorType; + +public class RoleActorTypeFilterQuery : IFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "name")] + public string? Name { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new RoleActorTypeNameFilter(Name), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeOrderKeys.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeOrderKeys.cs new file mode 100644 index 0000000..dcbcc15 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeOrderKeys.cs @@ -0,0 +1,12 @@ +using System.Linq.Expressions; + +namespace WatchIt.DTO.Models.Controllers.Roles.RoleActorType; + +public static class RoleActorTypeOrderKeys +{ + public static readonly Dictionary>> Base = new Dictionary>> + { + { "id", x => x.Id }, + { "name", x => x.Name }, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeRequest.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeRequest.cs new file mode 100644 index 0000000..eb4f5c1 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeRequest.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.RoleActorType; + +public class RoleActorTypeRequest +{ + #region PROPERTIES + + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeResponse.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeResponse.cs new file mode 100644 index 0000000..0908693 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleActorType/RoleActorTypeResponse.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.RoleActorType; + +public class RoleActorTypeResponse : IRoleTypeResponse +{ + #region PROPERTIES + + public short Id { get; set; } + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/Filters/RoleCreatorTypeNameFilter.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/Filters/RoleCreatorTypeNameFilter.cs new file mode 100644 index 0000000..1b26ffa --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/Filters/RoleCreatorTypeNameFilter.cs @@ -0,0 +1,18 @@ +using System.Text.RegularExpressions; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType.Filters; + +public record RoleCreatorTypeNameFilter : Filter +{ + public RoleCreatorTypeNameFilter(string? nameRegex) : base(x => + ( + string.IsNullOrWhiteSpace(nameRegex) + || + ( + !string.IsNullOrWhiteSpace(x.Name) + && + Regex.IsMatch(x.Name, nameRegex, RegexOptions.IgnoreCase) + ) + )) { } +}; \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeFilterQuery.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeFilterQuery.cs new file mode 100644 index 0000000..537bf97 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeFilterQuery.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType.Filters; +using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType.Filters; +using WatchIt.DTO.Query; + +namespace WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; + +public class RoleCreatorTypeFilterQuery : IFilterQuery +{ + #region PROPERTIES + + [FromQuery(Name = "name")] + public string? Name { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public IEnumerable> GetFilters() => + [ + new RoleCreatorTypeNameFilter(Name), + ]; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeOrderKeys.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeOrderKeys.cs new file mode 100644 index 0000000..3bfcb9c --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeOrderKeys.cs @@ -0,0 +1,12 @@ +using System.Linq.Expressions; + +namespace WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; + +public static class RoleCreatorTypeOrderKeys +{ + public static readonly Dictionary>> Base = new Dictionary>> + { + { "id", x => x.Id }, + { "name", x => x.Name }, + }; +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeRequest.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeRequest.cs new file mode 100644 index 0000000..357ad15 --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeRequest.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; + +public class RoleCreatorTypeRequest +{ + #region PROPERTIES + + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeResponse.cs b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeResponse.cs new file mode 100644 index 0000000..38b0d8a --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RoleCreatorType/RoleCreatorTypeResponse.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; + +public class RoleCreatorTypeResponse : IRoleTypeResponse +{ + #region PROPERTIES + + public short Id { get; set; } + public string Name { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Controllers/Roles/RolesMappers.cs b/WatchIt.DTO/Models/Controllers/Roles/RolesMappers.cs new file mode 100644 index 0000000..821f7ef --- /dev/null +++ b/WatchIt.DTO/Models/Controllers/Roles/RolesMappers.cs @@ -0,0 +1,130 @@ +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Models.Controllers.Roles.Role.Request; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType; +using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; +using WatchIt.DTO.Models.Generics.Rating; + +namespace WatchIt.DTO.Models.Controllers.Roles; + +public static class RolesMappers +{ + #region PUBLIC METHODS + + #region Roles + + public static RoleActor ToEntity(this RoleActorRequest request) + { + RoleActor roleActor = new RoleActor(); + roleActor.SetRoleEntityProperties(request); + roleActor.ActorTypeId = request.TypeId; + roleActor.Name = request.Name; + return roleActor; + } + + public static void UpdateWithRequest(this RoleActor entity, RoleActorRequest request) + { + entity.SetRoleEntityProperties(request); + entity.ActorTypeId = request.TypeId; + entity.Name = request.Name; + } + + public static RoleCreator ToEntity(this RoleCreatorRequest request) + { + RoleCreator roleActor = new RoleCreator(); + roleActor.SetRoleEntityProperties(request); + roleActor.CreatorTypeId = request.TypeId; + return roleActor; + } + + public static void UpdateWithRequest(this RoleCreator entity, RoleCreatorRequest request) + { + entity.SetRoleEntityProperties(request); + entity.CreatorTypeId = request.TypeId; + } + + public static RoleActorResponse ToResponse(this RoleActor entity) + { + RoleActorResponse response = new RoleActorResponse(); + response.SetRoleResponseProperties(entity); + response.Name = entity.Name; + response.TypeId = entity.ActorTypeId; + return response; + } + + public static RoleCreatorResponse ToResponse(this RoleCreator entity) + { + RoleCreatorResponse response = new RoleCreatorResponse(); + response.SetRoleResponseProperties(entity); + response.TypeId = entity.CreatorTypeId; + return response; + } + + #endregion + + #region RoleRating + + public static RoleRating ToEntity(this RatingRequest request, Guid roleId, long userId) + { + RoleRating entity = new RoleRating + { + RoleId = roleId, + AccountId = userId + }; + entity.UpdateWithRequest(request); + return entity; + } + + #endregion + + #region RoleActorType + + public static RoleActorTypeResponse ToResponse(this Database.Model.Roles.RoleActorType entity) => new RoleActorTypeResponse + { + Id = entity.Id, + Name = entity.Name, + }; + + public static Database.Model.Roles.RoleActorType ToEntity(this RoleActorTypeRequest request) => new Database.Model.Roles.RoleActorType + { + Name = request.Name, + }; + + #endregion + + #region RoleCreatorType + + public static RoleCreatorTypeResponse ToResponse(this Database.Model.Roles.RoleCreatorType entity) => new RoleCreatorTypeResponse + { + Id = entity.Id, + Name = entity.Name, + }; + + public static Database.Model.Roles.RoleCreatorType ToEntity(this RoleCreatorTypeRequest request) => new Database.Model.Roles.RoleCreatorType + { + Name = request.Name, + }; + + #endregion + + #endregion + + + + #region PRIVATE METHODS + + private static void SetRoleEntityProperties(this Database.Model.Roles.Role role, RoleRequest request) + { + role.MediumId = request.MediumId; + role.PersonId = request.PersonId; + } + + private static void SetRoleResponseProperties(this RoleResponse response, Database.Model.Roles.Role entity) + { + response.Id = entity.Id; + response.PersonId = entity.PersonId; + response.MediumId = entity.MediumId; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Image/ImageBase.cs b/WatchIt.DTO/Models/Generics/Image/ImageBase.cs new file mode 100644 index 0000000..a53e770 --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Image/ImageBase.cs @@ -0,0 +1,19 @@ +namespace WatchIt.DTO.Models.Generics.Image; + +public abstract class ImageBase +{ + #region PROPERTIES + + public byte[] Image { get; set; } = default!; + public string MimeType { get; set; } = default!; + + #endregion + + + + #region PUBLIC METHODS + + public override string ToString() => $"data:{MimeType};base64,{Convert.ToBase64String(Image)}"; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Image/ImageMappers.cs b/WatchIt.DTO/Models/Generics/Image/ImageMappers.cs new file mode 100644 index 0000000..7d9364a --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Image/ImageMappers.cs @@ -0,0 +1,24 @@ +using WatchIt.Database.Model; + +namespace WatchIt.DTO.Models.Generics.Image; + +public static class ImageMappers +{ + #region PUBLIC METHODS + + public static ImageResponse ToResponse(this IImageEntity entity) => new ImageResponse + { + Image = entity.Image, + MimeType = entity.MimeType, + UploadDate = entity.UploadDate, + }; + + public static void UpdateWithRequest(this IImageEntity entity, ImageRequest request) + { + entity.Image = request.Image; + entity.MimeType = request.MimeType; + entity.UploadDate = DateTimeOffset.UtcNow; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Image/ImageRequest.cs b/WatchIt.DTO/Models/Generics/Image/ImageRequest.cs new file mode 100644 index 0000000..2221116 --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Image/ImageRequest.cs @@ -0,0 +1,3 @@ +namespace WatchIt.DTO.Models.Generics.Image; + +public class ImageRequest : ImageBase; \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Image/ImageRequestValidator.cs b/WatchIt.DTO/Models/Generics/Image/ImageRequestValidator.cs new file mode 100644 index 0000000..04e4e77 --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Image/ImageRequestValidator.cs @@ -0,0 +1,16 @@ +using FluentValidation; + +namespace WatchIt.DTO.Models.Generics.Image; + +public class ImageRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public ImageRequestValidator() + { + RuleFor(x => x.Image).NotEmpty(); + RuleFor(x => x.MimeType).Matches(@"\w+/.+").WithMessage("Incorrect mimetype"); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Image/ImageResponse.cs b/WatchIt.DTO/Models/Generics/Image/ImageResponse.cs new file mode 100644 index 0000000..8a729ac --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Image/ImageResponse.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Generics.Image; + +public class ImageResponse : ImageBase +{ + #region PROPERTIES + + public DateTimeOffset UploadDate { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/IRatingOverallResponse.cs b/WatchIt.DTO/Models/Generics/Rating/IRatingOverallResponse.cs new file mode 100644 index 0000000..e95fe14 --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/IRatingOverallResponse.cs @@ -0,0 +1,6 @@ +namespace WatchIt.DTO.Models.Generics.Rating; + +public interface IRatingOverallResponse : IRatingResponse +{ + long Count { get; set; } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/IRatingResponse.cs b/WatchIt.DTO/Models/Generics/Rating/IRatingResponse.cs new file mode 100644 index 0000000..c0d8a1b --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/IRatingResponse.cs @@ -0,0 +1,6 @@ +namespace WatchIt.DTO.Models.Generics.Rating; + +public interface IRatingResponse +{ + decimal? Rating { get; } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/IRatingUserResponse.cs b/WatchIt.DTO/Models/Generics/Rating/IRatingUserResponse.cs new file mode 100644 index 0000000..cad37f7 --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/IRatingUserResponse.cs @@ -0,0 +1,6 @@ +namespace WatchIt.DTO.Models.Generics.Rating; + +public interface IRatingUserResponse : IRatingResponse +{ + DateTimeOffset? Date { get; } +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/RatingMappers.cs b/WatchIt.DTO/Models/Generics/Rating/RatingMappers.cs new file mode 100644 index 0000000..248f225 --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/RatingMappers.cs @@ -0,0 +1,51 @@ +using WatchIt.Database.Model; + +namespace WatchIt.DTO.Models.Generics.Rating; + +public static class RatingMappers +{ + #region PUBLIC METHODS + + public static void UpdateWithRequest(this IRatingEntity entity, RatingRequest ratingRequest) + { + entity.Rating = ratingRequest.Rating; + } + + public static RatingOverallResponse ToOverallResponse(this IEnumerable entities) + { + IEnumerable ratingEntities = entities.ToList(); + + long sum = ratingEntities.Sum(x => x.Rating); + long count = ratingEntities.Count(); + + return new RatingOverallResponse + { + Rating = count > 0 ? (decimal)sum / count : null, + Count = count + }; + } + + public static RatingUserResponse ToUserResponse(this IRatingEntity entity) => new RatingUserResponse + { + Date = entity.Date, + Rating = entity.Rating, + }; + + public static RatingUserOverallResponse ToUserOverallResponse(this IEnumerable entities) + { + IEnumerable ratingEntities = entities.ToList(); + + long sum = ratingEntities.Sum(x => x.Rating); + long count = ratingEntities.Count(); + DateTimeOffset? lastDate = count == 0 ? null : ratingEntities.Max(x => x.Date); + + return new RatingUserOverallResponse + { + Rating = count > 0 ? (decimal)sum / count : null, + Date = lastDate, + Count = count + }; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/RatingOverallResponse.cs b/WatchIt.DTO/Models/Generics/Rating/RatingOverallResponse.cs new file mode 100644 index 0000000..06b1bea --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/RatingOverallResponse.cs @@ -0,0 +1,11 @@ +namespace WatchIt.DTO.Models.Generics.Rating; + +public class RatingOverallResponse : IRatingOverallResponse +{ + #region PROPERTIES + + public decimal? Rating { get; set; } + public long Count { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/RatingRequest.cs b/WatchIt.DTO/Models/Generics/Rating/RatingRequest.cs new file mode 100644 index 0000000..4e62a4b --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/RatingRequest.cs @@ -0,0 +1,10 @@ +namespace WatchIt.DTO.Models.Generics.Rating; + +public class RatingRequest +{ + #region PROPERTIES + + public byte Rating { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/RatingRequestValidator.cs b/WatchIt.DTO/Models/Generics/Rating/RatingRequestValidator.cs new file mode 100644 index 0000000..b26935f --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/RatingRequestValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; + +namespace WatchIt.DTO.Models.Generics.Rating; + +public class RatingRequestValidator : AbstractValidator +{ + #region CONSTRUCTORS + + public RatingRequestValidator() + { + RuleFor(x => x.Rating).InclusiveBetween((byte)1, (byte)10); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/RatingUserOverallResponse.cs b/WatchIt.DTO/Models/Generics/Rating/RatingUserOverallResponse.cs new file mode 100644 index 0000000..6d6b89f --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/RatingUserOverallResponse.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace WatchIt.DTO.Models.Generics.Rating; + +public class RatingUserOverallResponse : IRatingUserResponse, IRatingOverallResponse +{ + #region PROPERTIES + + public decimal? Rating { get; set; } + public long Count { get; set; } + public DateTimeOffset? Date { get; set; } + + #endregion + +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/Rating/RatingUserResponse.cs b/WatchIt.DTO/Models/Generics/Rating/RatingUserResponse.cs new file mode 100644 index 0000000..295bf32 --- /dev/null +++ b/WatchIt.DTO/Models/Generics/Rating/RatingUserResponse.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace WatchIt.DTO.Models.Generics.Rating; + +public class RatingUserResponse : IRatingUserResponse +{ + #region PROPERTIES + + public byte Rating { get; set; } + public DateTimeOffset Date { get; set; } + + [JsonIgnore] decimal? IRatingResponse.Rating => Rating; + [JsonIgnore] DateTimeOffset? IRatingUserResponse.Date => Date; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/ViewCount/ViewCountMappers.cs b/WatchIt.DTO/Models/Generics/ViewCount/ViewCountMappers.cs new file mode 100644 index 0000000..e51d16b --- /dev/null +++ b/WatchIt.DTO/Models/Generics/ViewCount/ViewCountMappers.cs @@ -0,0 +1,30 @@ +using WatchIt.Database.Model; + +namespace WatchIt.DTO.Models.Generics.ViewCount; + +public static class ViewCountMappers +{ + #region PUBLIC METHODS + + public static ViewCountResponse ToResponse(this IEnumerable viewCounts) + { + IEnumerable viewCountEntities = viewCounts.ToList(); + return new ViewCountResponse + { + Last24Hours = viewCountEntities.CountFrom(DateTime.Now.AddDays(-1)), + LastWeek = viewCountEntities.CountFrom(DateTime.Now.AddDays(-7)), + LastMonth = viewCountEntities.CountFrom(DateTime.Now.AddMonths(-1)), + LastYear = viewCountEntities.CountFrom(DateTime.Now.AddYears(-1)), + }; + } + + #endregion + + + + #region PRIVATE METHODS + + private static long CountFrom(this IEnumerable viewCounts, DateTime date) => viewCounts.Where(x => x.Date >= DateOnly.FromDateTime(date)).Sum(x => x.ViewCount); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Models/Generics/ViewCount/ViewCountResponse.cs b/WatchIt.DTO/Models/Generics/ViewCount/ViewCountResponse.cs new file mode 100644 index 0000000..831eaec --- /dev/null +++ b/WatchIt.DTO/Models/Generics/ViewCount/ViewCountResponse.cs @@ -0,0 +1,13 @@ +namespace WatchIt.DTO.Models.Generics.ViewCount; + +public class ViewCountResponse +{ + #region PROPERTIES + + public long Last24Hours { get; set; } + public long LastWeek { get; set; } + public long LastMonth { get; set; } + public long LastYear { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.DTO/Query/Filter.cs b/WatchIt.DTO/Query/Filter.cs new file mode 100644 index 0000000..1011a2c --- /dev/null +++ b/WatchIt.DTO/Query/Filter.cs @@ -0,0 +1,8 @@ +using System.Linq.Expressions; + +namespace WatchIt.DTO.Query; + +public abstract record Filter(Expression> Condition) +{ + public static implicit operator Expression>(Filter filter) => filter.Condition; +} \ No newline at end of file diff --git a/WatchIt.DTO/Query/IFilterQuery.cs b/WatchIt.DTO/Query/IFilterQuery.cs new file mode 100644 index 0000000..e0f7908 --- /dev/null +++ b/WatchIt.DTO/Query/IFilterQuery.cs @@ -0,0 +1,20 @@ +namespace WatchIt.DTO.Query; + +public interface IFilterQuery; + +public interface IFilterQuery : IFilterQuery +{ + internal abstract IEnumerable> GetFilters(); +} + +public static class FilterQueryExtensions +{ + public static IQueryable ApplyFilter(this IQueryable data, IFilterQuery filterQuery) + { + foreach (Filter filter in filterQuery.GetFilters()) + { + data = data.Where(filter); + } + return data; + } +} \ No newline at end of file diff --git a/WatchIt.DTO/Query/OrderQuery.cs b/WatchIt.DTO/Query/OrderQuery.cs new file mode 100644 index 0000000..0ce5bd6 --- /dev/null +++ b/WatchIt.DTO/Query/OrderQuery.cs @@ -0,0 +1,38 @@ +using System.Linq.Expressions; +using Microsoft.AspNetCore.Mvc; +using Refit; +using WatchIt.Database.Model.Media; + +namespace WatchIt.DTO.Query; + +public class OrderQuery +{ + #region PROPERTIES + + [FromQuery(Name = "order_asc")] + [AliasAs("order_asc")] + public bool OrderAscending { get; set; } + + [FromQuery(Name = "order_by")] + [AliasAs("order_by")] + public string? OrderBy { get; set; } + + #endregion +} + +public static class OrderQueryExtensions +{ + public static IQueryable ApplyOrder(this IQueryable data, OrderQuery orderQuery, params IDictionary>>[] orderKeys) + { + if (orderQuery.OrderBy is not null) + { + Dictionary>> orderByKeys = orderKeys.SelectMany(x => x) + .ToDictionary(x => x.Key, x => x.Value); + if (orderByKeys.TryGetValue(orderQuery.OrderBy, out Expression>? orderFunc)) + { + data = orderQuery.OrderAscending ? data.OrderBy(orderFunc) : data.OrderByDescending(orderFunc); + } + } + return data; + } +} \ No newline at end of file diff --git a/WatchIt.DTO/Query/PagingQuery.cs b/WatchIt.DTO/Query/PagingQuery.cs new file mode 100644 index 0000000..d706050 --- /dev/null +++ b/WatchIt.DTO/Query/PagingQuery.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Mvc; + +namespace WatchIt.DTO.Query; + +public sealed record PagingQuery +{ + [FromQuery(Name = "first")] + public int? First { get; set; } + + [FromQuery(Name = "after")] + public int? After { get; set; } +} + +public static class PagingQueryExtensions +{ + public static IQueryable ApplyPaging(this IQueryable data, PagingQuery pagingQuery) + { + if (pagingQuery.After is not null) + { + data = data.Skip(pagingQuery.After.Value); + } + if (pagingQuery.First is not null) + { + data = data.Take(pagingQuery.First.Value); + } + return data; + } +} \ No newline at end of file diff --git a/WatchIt.DTO/WatchIt.DTO.csproj b/WatchIt.DTO/WatchIt.DTO.csproj new file mode 100644 index 0000000..ab8f43b --- /dev/null +++ b/WatchIt.DTO/WatchIt.DTO.csproj @@ -0,0 +1,19 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + + + diff --git a/WatchIt.Database/Configuration/Accounts/AccountBackgroundPictureConfiguration.cs b/WatchIt.Database/Configuration/Accounts/AccountBackgroundPictureConfiguration.cs new file mode 100644 index 0000000..2f0d43f --- /dev/null +++ b/WatchIt.Database/Configuration/Accounts/AccountBackgroundPictureConfiguration.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.Database.Configuration.Accounts; + +public class AccountBackgroundPictureConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("AccountBackgroundPictures", "accounts"); + + // Account + builder.HasKey(x => x.AccountId); + builder.HasIndex(x => x.AccountId) + .IsUnique(); + builder.HasOne(x => x.Account) + .WithOne(x => x.BackgroundPicture) + .HasForeignKey(x => x.AccountId) + .IsRequired(); + builder.Property(x => x.AccountId) + .IsRequired(); + + // Background + builder.HasOne(x => x.Background) + .WithMany(x => x.BackgroundUsages) + .HasForeignKey(x => x.BackgroundId) + .IsRequired(); + builder.Property(x => x.BackgroundId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Accounts/AccountConfiguration.cs b/WatchIt.Database/Configuration/Accounts/AccountConfiguration.cs new file mode 100644 index 0000000..e460e48 --- /dev/null +++ b/WatchIt.Database/Configuration/Accounts/AccountConfiguration.cs @@ -0,0 +1,98 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.Database.Configuration.Accounts; + +public class AccountConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Accounts", "accounts"); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired() + .UseIdentityAlwaysColumn(); + + // Username + builder.Property(x => x.Username) + .HasMaxLength(50) + .IsRequired(); + + // Email + builder.Property(x => x.Email) + .HasMaxLength(320) + .IsRequired(); + + // Password + builder.Property(x => x.Password) + .HasMaxLength(1000) + .IsRequired(); + + // Left salt + builder.Property(x => x.LeftSalt) + .HasMaxLength(20) + .IsRequired(); + + // Right salt + builder.Property(x => x.RightSalt) + .HasMaxLength(20) + .IsRequired(); + + // Is admin + builder.Property(x => x.IsAdmin) + .IsRequired() + .HasDefaultValue(false); + + // Join date + builder.Property(x => x.JoinDate) + .IsRequired() + .HasDefaultValueSql("now()"); + + // Active date + builder.Property(x => x.ActiveDate) + .IsRequired() + .HasDefaultValueSql("now()"); + + // Description + builder.Property(x => x.Description) + .HasMaxLength(1000); + + // Gender + builder.HasOne(x => x.Gender) + .WithMany(x => x.Accounts) + .HasForeignKey(x => x.GenderId); + builder.Property(x => x.GenderId); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + + #region Navigation + + // AccountFollow + builder.HasMany(x => x.Follows) + .WithMany(x => x.Followers) + .UsingEntity( + x => x.HasOne(y => y.Followed) + .WithMany(y => y.FollowersRelationshipObjects) + .HasForeignKey(y => y.FollowedId) + .IsRequired(), + x => x.HasOne(y => y.Follower) + .WithMany(y => y.FollowsRelationshipObjects) + .HasForeignKey(y => y.FollowerId) + .IsRequired() + ); + + #endregion + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Accounts/AccountFollowConfiguration.cs b/WatchIt.Database/Configuration/Accounts/AccountFollowConfiguration.cs new file mode 100644 index 0000000..ff9b9c0 --- /dev/null +++ b/WatchIt.Database/Configuration/Accounts/AccountFollowConfiguration.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.Database.Configuration.Accounts; + +public class AccountFollowConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("AccountFollows", "accounts"); + builder.HasKey(x => new { x.FollowerId, x.FollowedId }); + + // Follower + // FK configured in AccountConfiguration + builder.Property(x => x.FollowerId) + .IsRequired(); + + // Followed + // FK configured in AccountConfiguration + builder.Property(x => x.FollowedId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Accounts/AccountProfilePictureConfiguration.cs b/WatchIt.Database/Configuration/Accounts/AccountProfilePictureConfiguration.cs new file mode 100644 index 0000000..f8269d0 --- /dev/null +++ b/WatchIt.Database/Configuration/Accounts/AccountProfilePictureConfiguration.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.Database.Configuration.Accounts; + +public class AccountProfilePictureConfiguration : ImageEntityConfiguration +{ + #region PUBLIC METHODS + + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable($"AccountProfilePictures", "accounts"); + + // Account + builder.HasKey(x => x.AccountId); + builder.HasIndex(x => x.AccountId) + .IsUnique(); + builder.HasOne(x => x.Account) + .WithOne(x => x.ProfilePicture) + .HasForeignKey(x => x.AccountId) + .IsRequired(); + builder.Property(x => x.AccountId) + .IsRequired(); + + // Generic properties + base.Configure(builder); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountRefreshTokenConfiguration.cs b/WatchIt.Database/Configuration/Accounts/AccountRefreshTokenConfiguration.cs similarity index 51% rename from WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountRefreshTokenConfiguration.cs rename to WatchIt.Database/Configuration/Accounts/AccountRefreshTokenConfiguration.cs index f0e9e19..b3a2ed2 100644 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountRefreshTokenConfiguration.cs +++ b/WatchIt.Database/Configuration/Accounts/AccountRefreshTokenConfiguration.cs @@ -1,30 +1,44 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Account; +using WatchIt.Database.Model.Accounts; -namespace WatchIt.Database.Model.Configuration.Account; +namespace WatchIt.Database.Configuration.Accounts; public class AccountRefreshTokenConfiguration : IEntityTypeConfiguration { + #region PUBLIC METHODS + public void Configure(EntityTypeBuilder builder) { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) + builder.ToTable("AccountRefreshTokens", "accounts"); + + // Id + builder.HasKey(x => x.Token); + builder.HasIndex(x => x.Token) .IsUnique(); - builder.Property(x => x.Id) + builder.Property(x => x.Token) .IsRequired(); - + + // Account builder.HasOne(x => x.Account) - .WithMany(x => x.AccountRefreshTokens) + .WithMany(x => x.RefreshTokens) .HasForeignKey(x => x.AccountId) .IsRequired(); builder.Property(x => x.AccountId) .IsRequired(); - + + // Expiration date builder.Property(x => x.ExpirationDate) .IsRequired(); - + + // Is extendable builder.Property(x => x.IsExtendable) .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); } + + #endregion } \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Genders/GenderConfiguration.cs b/WatchIt.Database/Configuration/Genders/GenderConfiguration.cs new file mode 100644 index 0000000..c0fb1f2 --- /dev/null +++ b/WatchIt.Database/Configuration/Genders/GenderConfiguration.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Genders; + +namespace WatchIt.Database.Configuration.Genders; + +public class GenderConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Genders", "genders"); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired() + .UseIdentityAlwaysColumn(); + + // Name + builder.Property(x => x.Name) + .HasMaxLength(100) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Genres/GenreConfiguration.cs b/WatchIt.Database/Configuration/Genres/GenreConfiguration.cs new file mode 100644 index 0000000..a885faa --- /dev/null +++ b/WatchIt.Database/Configuration/Genres/GenreConfiguration.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Genres; + +namespace WatchIt.Database.Configuration.Genres; + +public class GenreConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Genres", "genres"); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired() + .UseIdentityAlwaysColumn(); + + // Name + builder.Property(x => x.Name) + .HasMaxLength(100) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/ImageEntityConfiguration.cs b/WatchIt.Database/Configuration/ImageEntityConfiguration.cs new file mode 100644 index 0000000..97605c3 --- /dev/null +++ b/WatchIt.Database/Configuration/ImageEntityConfiguration.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model; + +namespace WatchIt.Database.Configuration; + +public abstract class ImageEntityConfiguration : IEntityTypeConfiguration where T : class, IImageEntity +{ + #region PUBLIC METHODS + + public virtual void Configure(EntityTypeBuilder builder) + { + // Image + builder.Property(x => x.Image) + .HasMaxLength(-1) + .IsRequired(); + + // MimeType + builder.Property(x => x.MimeType) + .HasMaxLength(50) + .IsRequired(); + + // UploadDate + builder.Property(x => x.UploadDate) + .IsRequired() + .HasDefaultValueSql("now()"); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Media/MediumConfiguration.cs b/WatchIt.Database/Configuration/Media/MediumConfiguration.cs new file mode 100644 index 0000000..03e4207 --- /dev/null +++ b/WatchIt.Database/Configuration/Media/MediumConfiguration.cs @@ -0,0 +1,90 @@ +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Configuration.Media; + +public class MediumConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Media", "media"); + builder.HasDiscriminator("Type") + .HasValue(MediumType.Movie) + .HasValue(MediumType.Series); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired() + .UseIdentityAlwaysColumn(); + + // Type + builder.Property(x => x.Type) + .IsRequired(); + + // Title + builder.Property(x => x.Title) + .HasMaxLength(250) + .IsRequired(); + + // Original title + builder.Property(x => x.OriginalTitle) + .HasMaxLength(250); + + // Description + builder.Property(x => x.Description) + .HasMaxLength(1000); + + // Duration + builder.Property(x => x.Duration); + + // Release date + builder.Property(x => x.ReleaseDate); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + + #region Navigation + + // MediumGenre + builder.HasMany(x => x.Genres) + .WithMany(x => x.Media) + .UsingEntity( + x => x.HasOne(y => y.Genre) + .WithMany(y => y.MediaRelationObjects) + .HasForeignKey(y => y.GenreId) + .IsRequired(), + x => x.HasOne(y => y.Medium) + .WithMany(y => y.GenresRelationshipObjects) + .HasForeignKey(y => y.MediumId) + .IsRequired() + ); + + // MediumRating + builder.HasMany(x => x.RatedBy) + .WithMany(x => x.MediaRated) + .UsingEntity( + x => x.HasOne(y => y.Account) + .WithMany(y => y.MediaRatings) + .HasForeignKey(y => y.AccountId) + .IsRequired(), + x => x.HasOne(y => y.Medium) + .WithMany(y => y.Ratings) + .HasForeignKey(y => y.MediumId) + .IsRequired() + ); + + #endregion + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Media/MediumGenreConfiguration.cs b/WatchIt.Database/Configuration/Media/MediumGenreConfiguration.cs new file mode 100644 index 0000000..8f314a3 --- /dev/null +++ b/WatchIt.Database/Configuration/Media/MediumGenreConfiguration.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Configuration.Media; + +public class MediumGenreConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("MediumGenres", "media"); + builder.HasKey(x => new { x.GenreId, x.MediumId }); + + // Medium + // FK configured in MediumConfiguration + builder.Property(x => x.MediumId) + .IsRequired(); + + // Genre + // FK configured in MediumConfiguration + builder.Property(x => x.GenreId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Media/MediumMovieConfiguration.cs b/WatchIt.Database/Configuration/Media/MediumMovieConfiguration.cs new file mode 100644 index 0000000..c2ec076 --- /dev/null +++ b/WatchIt.Database/Configuration/Media/MediumMovieConfiguration.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Configuration.Media; + +public class MediumMovieConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + // Budget + builder.Property(x => x.Budget) + .HasColumnType("money"); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Media/MediumPictureConfiguration.cs b/WatchIt.Database/Configuration/Media/MediumPictureConfiguration.cs new file mode 100644 index 0000000..89243c9 --- /dev/null +++ b/WatchIt.Database/Configuration/Media/MediumPictureConfiguration.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Configuration.Media; + +public class MediumPictureConfiguration : ImageEntityConfiguration +{ + #region PUBLIC METHODS + + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("MediumPictures", "media"); + + // Medium + builder.HasKey(x => x.MediumId); + builder.HasIndex(x => x.MediumId) + .IsUnique(); + builder.HasOne(x => x.Medium) + .WithOne(x => x.Picture) + .HasForeignKey(x => x.MediumId) + .IsRequired(); + builder.Property(x => x.MediumId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + // Generic properties + base.Configure(builder); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Media/MediumRatingConfiguration.cs b/WatchIt.Database/Configuration/Media/MediumRatingConfiguration.cs new file mode 100644 index 0000000..896f04d --- /dev/null +++ b/WatchIt.Database/Configuration/Media/MediumRatingConfiguration.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Accounts; +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Configuration.Media; + +public class MediumRatingConfiguration : RatingEntityConfiguration +{ + #region PUBLIC METHODS + + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("MediumRatings", "media"); + builder.HasKey(x => new { x.AccountId, x.MediumId }); + + // Medium + // FK configured in MediumConfiguration + builder.Property(x => x.MediumId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + // Generic properties + base.Configure(builder); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Media/MediumSeriesConfiguration.cs b/WatchIt.Database/Configuration/Media/MediumSeriesConfiguration.cs new file mode 100644 index 0000000..949a69b --- /dev/null +++ b/WatchIt.Database/Configuration/Media/MediumSeriesConfiguration.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Configuration.Media; + +public class MediumSeriesConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + // Has ended + builder.Property(x => x.HasEnded) + .IsRequired() + .HasDefaultValue(false); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Media/MediumViewCountConfiguration.cs b/WatchIt.Database/Configuration/Media/MediumViewCountConfiguration.cs new file mode 100644 index 0000000..0e086bd --- /dev/null +++ b/WatchIt.Database/Configuration/Media/MediumViewCountConfiguration.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Configuration.Media; + +public class MediumViewCountConfiguration : ViewCountEntityConfiguration +{ + #region PUBLIC METHODS + + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("MediumViewCounts", "media"); + builder.HasKey(x => new { x.MediumId, x.Date }); + + // Medium + builder.HasOne(x => x.Medium) + .WithMany(x => x.ViewCounts) + .HasForeignKey(x => x.MediumId) + .IsRequired(); + builder.Property(x => x.MediumId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + // Generic properties + base.Configure(builder); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/People/PersonConfiguration.cs b/WatchIt.Database/Configuration/People/PersonConfiguration.cs new file mode 100644 index 0000000..4f7881f --- /dev/null +++ b/WatchIt.Database/Configuration/People/PersonConfiguration.cs @@ -0,0 +1,54 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.People; + +namespace WatchIt.Database.Configuration.People; + +public class PersonConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("People", "people"); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired() + .UseIdentityAlwaysColumn(); + + // Name + builder.Property(x => x.Name) + .HasMaxLength(100) + .IsRequired(); + + // Full name + builder.Property(x => x.FullName) + .HasMaxLength(200); + + // Description + builder.Property(x => x.Description) + .HasMaxLength(1000); + + // Birth date + builder.Property(x => x.BirthDate); + + // Death date + builder.Property(x => x.DeathDate); + + // Gender + builder.HasOne(x => x.Gender) + .WithMany(x => x.People) + .HasForeignKey(x => x.GenderId); + builder.Property(x => x.GenderId); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/People/PersonPictureConfiguration.cs b/WatchIt.Database/Configuration/People/PersonPictureConfiguration.cs new file mode 100644 index 0000000..d69372a --- /dev/null +++ b/WatchIt.Database/Configuration/People/PersonPictureConfiguration.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Media; +using WatchIt.Database.Model.People; + +namespace WatchIt.Database.Configuration.People; + +public class PersonPictureConfiguration : ImageEntityConfiguration +{ + #region PUBLIC METHODS + + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PersonPictures", "people"); + + // Person + builder.HasKey(x => x.PersonId); + builder.HasIndex(x => x.PersonId) + .IsUnique(); + builder.HasOne(x => x.Person) + .WithOne(x => x.Picture) + .HasForeignKey(x => x.PersonId) + .IsRequired(); + builder.Property(x => x.PersonId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + // Generic properties + base.Configure(builder); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/People/PersonViewCountConfiguration.cs b/WatchIt.Database/Configuration/People/PersonViewCountConfiguration.cs new file mode 100644 index 0000000..f71dd92 --- /dev/null +++ b/WatchIt.Database/Configuration/People/PersonViewCountConfiguration.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.People; + +namespace WatchIt.Database.Configuration.People; + +public class PersonViewCountConfiguration : ViewCountEntityConfiguration +{ + #region PUBLIC METHODS + + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PersonViewCounts", "people"); + builder.HasKey(x => new { x.PersonId, x.Date }); + + // Medium + builder.HasOne(x => x.Person) + .WithMany(x => x.ViewCounts) + .HasForeignKey(x => x.PersonId) + .IsRequired(); + builder.Property(x => x.PersonId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + // Generic properties + base.Configure(builder); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Photos/PhotoBackgroundConfiguration.cs b/WatchIt.Database/Configuration/Photos/PhotoBackgroundConfiguration.cs new file mode 100644 index 0000000..c353b31 --- /dev/null +++ b/WatchIt.Database/Configuration/Photos/PhotoBackgroundConfiguration.cs @@ -0,0 +1,54 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Converters; +using WatchIt.Database.Model.Photos; + +namespace WatchIt.Database.Configuration.Photos; + +public class PhotoBackgroundConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PhotoBackground", "photos"); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired(); + + // Photo + builder.HasOne(x => x.Photo) + .WithOne(x => x.Background) + .HasForeignKey(x => x.PhotoId) + .IsRequired(); + builder.HasIndex(x => x.PhotoId) + .IsUnique(); + builder.Property(x => x.PhotoId) + .IsRequired(); + + // Is universal + builder.Property(x => x.IsUniversal) + .IsRequired() + .HasDefaultValue(false); + + // First gradient color + builder.Property(x => x.FirstGradientColor) + .HasConversion() + .IsRequired(); + + // Second gradient color + builder.Property(x => x.SecondGradientColor) + .HasConversion() + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Photos/PhotoConfiguration.cs b/WatchIt.Database/Configuration/Photos/PhotoConfiguration.cs new file mode 100644 index 0000000..93575c0 --- /dev/null +++ b/WatchIt.Database/Configuration/Photos/PhotoConfiguration.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Photos; + +namespace WatchIt.Database.Configuration.Photos; + +public class PhotoConfiguration : ImageEntityConfiguration +{ + #region PUBLIC METHODS + + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Photos", "photos"); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired(); + + // Medium + builder.HasOne(x => x.Medium) + .WithMany(x => x.Photos) + .HasForeignKey(x => x.MediumId) + .IsRequired(); + builder.Property(x => x.MediumId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + // Generic properties + base.Configure(builder); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/RatingEntityConfiguration.cs b/WatchIt.Database/Configuration/RatingEntityConfiguration.cs new file mode 100644 index 0000000..a21e946 --- /dev/null +++ b/WatchIt.Database/Configuration/RatingEntityConfiguration.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model; +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.Database.Configuration; + +public abstract class RatingEntityConfiguration : IEntityTypeConfiguration where T : class, IRatingEntity +{ + #region PUBLIC METHODS + + public virtual void Configure(EntityTypeBuilder builder) + { + // Account + // You have to configure FK and PK by yourself + builder.Property(x => x.AccountId) + .IsRequired(); + + // Rating + builder.Property(x => x.Rating) + .IsRequired(); + + // Date + builder.Property(x => x.Date) + .IsRequired() + .HasDefaultValueSql("now()"); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Roles/RoleActorConfiguration.cs b/WatchIt.Database/Configuration/Roles/RoleActorConfiguration.cs new file mode 100644 index 0000000..ea77b9e --- /dev/null +++ b/WatchIt.Database/Configuration/Roles/RoleActorConfiguration.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Configuration.Roles; + +public class RoleActorConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + // Actor type + builder.HasOne(x => x.ActorType) + .WithMany(x => x.Roles) + .HasForeignKey(x => x.ActorTypeId) + .IsRequired(); + builder.Property(x => x.ActorTypeId) + .IsRequired(); + + // Name + builder.Property(x => x.Name) + .HasMaxLength(100) + .IsRequired(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Roles/RoleActorTypeConfiguration.cs b/WatchIt.Database/Configuration/Roles/RoleActorTypeConfiguration.cs new file mode 100644 index 0000000..a54a1e7 --- /dev/null +++ b/WatchIt.Database/Configuration/Roles/RoleActorTypeConfiguration.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Configuration.Roles; + +public class RoleActorTypeConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("RoleActorTypes", "roles"); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired() + .UseIdentityAlwaysColumn(); + + // Name + builder.Property(x => x.Name) + .HasMaxLength(100) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Roles/RoleConfiguration.cs b/WatchIt.Database/Configuration/Roles/RoleConfiguration.cs new file mode 100644 index 0000000..2792be0 --- /dev/null +++ b/WatchIt.Database/Configuration/Roles/RoleConfiguration.cs @@ -0,0 +1,70 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Configuration.Roles; + +public class RoleConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Roles", "roles"); + builder.HasDiscriminator("Type") + .HasValue(RoleType.Actor) + .HasValue(RoleType.Creator); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired(); + + // Type + builder.Property(x => x.Type) + .IsRequired(); + + // Medium + builder.HasOne(x => x.Medium) + .WithMany(x => x.Roles) + .HasForeignKey(x => x.MediumId) + .IsRequired(); + builder.Property(x => x.MediumId) + .IsRequired(); + + // Person + builder.HasOne(x => x.Person) + .WithMany(x => x.Roles) + .HasForeignKey(x => x.PersonId) + .IsRequired(); + builder.Property(x => x.PersonId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + + #region Navigation + + // RoleRating + builder.HasMany(x => x.RatedBy) + .WithMany(x => x.RolesRated) + .UsingEntity( + x => x.HasOne(y => y.Account) + .WithMany(y => y.RolesRatings) + .HasForeignKey(y => y.AccountId) + .IsRequired(), + x => x.HasOne(y => y.Role) + .WithMany(y => y.Ratings) + .HasForeignKey(y => y.RoleId) + .IsRequired() + ); + + #endregion + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Roles/RoleCreatorConfiguration.cs b/WatchIt.Database/Configuration/Roles/RoleCreatorConfiguration.cs new file mode 100644 index 0000000..14849e4 --- /dev/null +++ b/WatchIt.Database/Configuration/Roles/RoleCreatorConfiguration.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Configuration.Roles; + +public class RoleCreatorConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + // Creator type + builder.HasOne(x => x.CreatorType) + .WithMany(x => x.Roles) + .HasForeignKey(x => x.CreatorTypeId) + .IsRequired(); + builder.Property(x => x.CreatorTypeId) + .IsRequired(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Roles/RoleCreatorTypeConfiguration.cs b/WatchIt.Database/Configuration/Roles/RoleCreatorTypeConfiguration.cs new file mode 100644 index 0000000..4aca46d --- /dev/null +++ b/WatchIt.Database/Configuration/Roles/RoleCreatorTypeConfiguration.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Configuration.Roles; + +public class RoleCreatorTypeConfiguration : IEntityTypeConfiguration +{ + #region PUBLIC METHODS + + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("RoleCreatorTypes", "roles"); + + // Id + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired() + .UseIdentityAlwaysColumn(); + + // Name + builder.Property(x => x.Name) + .HasMaxLength(100) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/Roles/RoleRatingConfiguration.cs b/WatchIt.Database/Configuration/Roles/RoleRatingConfiguration.cs new file mode 100644 index 0000000..8227c27 --- /dev/null +++ b/WatchIt.Database/Configuration/Roles/RoleRatingConfiguration.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Configuration.Roles; + +public class RoleRatingConfiguration : RatingEntityConfiguration +{ + #region PUBLIC METHODS + + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("RoleRatings", "roles"); + builder.HasKey(x => new { x.AccountId, x.RoleId }); + + // Role + // FK configured in RoleConfiguration + builder.Property(x => x.RoleId) + .IsRequired(); + + // Version + builder.Property(b => b.Version) + .IsRowVersion(); + + // Generic properties + base.Configure(builder); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Configuration/ViewCountEntityConfiguration.cs b/WatchIt.Database/Configuration/ViewCountEntityConfiguration.cs new file mode 100644 index 0000000..974f684 --- /dev/null +++ b/WatchIt.Database/Configuration/ViewCountEntityConfiguration.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model; + +namespace WatchIt.Database.Configuration; + +public abstract class ViewCountEntityConfiguration : IEntityTypeConfiguration where T : class, IViewCountEntity +{ + #region PUBLIC METHODS + + public virtual void Configure(EntityTypeBuilder builder) + { + // Date + // You have to configure PK by yourself + builder.Property(x => x.Date) + .IsRequired() + .HasDefaultValueSql("now()"); + + // View count + builder.Property(x => x.ViewCount) + .IsRequired(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Converters/ColorToByteArrayConverter.cs b/WatchIt.Database/Converters/ColorToByteArrayConverter.cs new file mode 100644 index 0000000..820b9d5 --- /dev/null +++ b/WatchIt.Database/Converters/ColorToByteArrayConverter.cs @@ -0,0 +1,14 @@ +using System.Drawing; +using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace WatchIt.Database.Converters; + +public class ColorToByteArrayConverter : ValueConverter +{ + #region CONSTRUCTORS + + public ColorToByteArrayConverter() : base(x => new byte[] { x.R, x.G, x.B, x.A }, x => Color.FromArgb(x.Length > 3 ? x[3] : 0x00, x[0], x[1], x[2])) {} + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/DatabaseContext.cs b/WatchIt.Database/DatabaseContext.cs new file mode 100644 index 0000000..222f50c --- /dev/null +++ b/WatchIt.Database/DatabaseContext.cs @@ -0,0 +1,83 @@ +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using WatchIt.Database.Model.Accounts; +using WatchIt.Database.Model.Genders; +using WatchIt.Database.Model.Genres; +using WatchIt.Database.Model.Media; +using WatchIt.Database.Model.People; +using WatchIt.Database.Model.Photos; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database; + +public class DatabaseContext : DbContext +{ + #region CONSTRUCTORS + + public DatabaseContext() + { + } + + public DatabaseContext(DbContextOptions options) : base(options) + { + } + + #endregion + + + + #region PROPERTIES + + // Media + public virtual DbSet Media { get; set; } + public virtual DbSet MediumGenres { get; set; } + public virtual DbSet MediumRatings { get; set; } + public virtual DbSet MediumViewCounts { get; set; } + public virtual DbSet MediumPictures { get; set; } + + // People + public virtual DbSet People { get; set; } + public virtual DbSet PersonViewCounts { get; set; } + public virtual DbSet PersonPictures { get; set; } + + // Roles + public virtual DbSet Roles { get; set; } + public virtual DbSet RoleActorTypes { get; set; } + public virtual DbSet RoleCreatorTypes { get; set; } + public virtual DbSet RoleRatings { get; set; } + + // Accounts + public virtual DbSet Accounts { get; set; } + public virtual DbSet AccountFollows { get; set; } + public virtual DbSet AccountProfilePictures { get; set; } + public virtual DbSet AccountBackgroundPictures { get; set; } + public virtual DbSet AccountRefreshTokens { get; set; } + + // Photos + public virtual DbSet Photos { get; set; } + public virtual DbSet PhotoBackgrounds { get; set; } + + // Genders + public virtual DbSet Genders { get; set; } + + // Genres + public virtual DbSet Genres { get; set; } + + #endregion + + + + #region PROTECTED METHODS + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseNpgsql("name=Database"); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetAssembly(typeof(Account))!); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Migrations/20250302235216_Initial.Designer.cs b/WatchIt.Database/Migrations/20250302235216_Initial.Designer.cs new file mode 100644 index 0000000..d632d84 --- /dev/null +++ b/WatchIt.Database/Migrations/20250302235216_Initial.Designer.cs @@ -0,0 +1,1095 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using WatchIt.Database; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20250302235216_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("ActiveDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(320) + .HasColumnType("character varying(320)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("IsAdmin") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("JoinDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("LeftSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("bytea"); + + b.Property("RightSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Accounts", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountBackgroundPicture", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("BackgroundId") + .HasColumnType("uuid"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("AccountId"); + + b.HasIndex("AccountId") + .IsUnique(); + + b.HasIndex("BackgroundId"); + + b.ToTable("AccountBackgroundPictures", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountFollow", b => + { + b.Property("FollowerId") + .HasColumnType("bigint"); + + b.Property("FollowedId") + .HasColumnType("bigint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("FollowerId", "FollowedId"); + + b.HasIndex("FollowedId"); + + b.ToTable("AccountFollows", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountProfilePicture", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("AccountId"); + + b.HasIndex("AccountId") + .IsUnique(); + + b.ToTable("AccountProfilePictures", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountRefreshToken", b => + { + b.Property("Token") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("IsExtendable") + .HasColumnType("boolean"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Token"); + + b.HasIndex("AccountId"); + + b.HasIndex("Token") + .IsUnique(); + + b.ToTable("AccountRefreshTokens", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Genders.Gender", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genders", "genders"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Genres.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genres", "genres"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Medium", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Duration") + .HasColumnType("smallint"); + + b.Property("OriginalTitle") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("ReleaseDate") + .HasColumnType("date"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Media", "media"); + + b.HasDiscriminator("Type"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumGenre", b => + { + b.Property("GenreId") + .HasColumnType("smallint"); + + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("GenreId", "MediumId"); + + b.HasIndex("MediumId"); + + b.ToTable("MediumGenres", "media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumPicture", b => + { + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("MediumId"); + + b.HasIndex("MediumId") + .IsUnique(); + + b.ToTable("MediumPictures", "media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumRating", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("AccountId", "MediumId"); + + b.HasIndex("MediumId"); + + b.ToTable("MediumRatings", "media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumViewCount", b => + { + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.Property("ViewCount") + .HasColumnType("bigint"); + + b.HasKey("MediumId", "Date"); + + b.ToTable("MediumViewCounts", "media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("BirthDate") + .HasColumnType("date"); + + b.Property("DeathDate") + .HasColumnType("date"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("FullName") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("People", "people"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.PersonPicture", b => + { + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("PersonId"); + + b.HasIndex("PersonId") + .IsUnique(); + + b.ToTable("PersonPictures", "people"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.PersonViewCount", b => + { + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.Property("ViewCount") + .HasColumnType("bigint"); + + b.HasKey("PersonId", "Date"); + + b.ToTable("PersonViewCounts", "people"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.Photo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediumId"); + + b.ToTable("Photos", "photos"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.PhotoBackground", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FirstGradientColor") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("IsUniversal") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("PhotoId") + .HasColumnType("uuid"); + + b.Property("SecondGradientColor") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PhotoId") + .IsUnique(); + + b.ToTable("PhotoBackground", "photos"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediumId"); + + b.HasIndex("PersonId"); + + b.ToTable("Roles", "roles"); + + b.HasDiscriminator("Type"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleActorType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("RoleActorTypes", "roles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleCreatorType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("RoleCreatorTypes", "roles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleRating", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("AccountId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleRatings", "roles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumMovie", b => + { + b.HasBaseType("WatchIt.Database.Model.Media.Medium"); + + b.Property("Budget") + .HasColumnType("money"); + + b.HasDiscriminator().HasValue((byte)0); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumSeries", b => + { + b.HasBaseType("WatchIt.Database.Model.Media.Medium"); + + b.Property("HasEnded") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.HasDiscriminator().HasValue((byte)1); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleActor", b => + { + b.HasBaseType("WatchIt.Database.Model.Roles.Role"); + + b.Property("ActorTypeId") + .HasColumnType("smallint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasIndex("ActorTypeId"); + + b.HasDiscriminator().HasValue((byte)0); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleCreator", b => + { + b.HasBaseType("WatchIt.Database.Model.Roles.Role"); + + b.Property("CreatorTypeId") + .HasColumnType("smallint"); + + b.HasIndex("CreatorTypeId"); + + b.HasDiscriminator().HasValue((byte)1); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.Account", b => + { + b.HasOne("WatchIt.Database.Model.Genders.Gender", "Gender") + .WithMany("Accounts") + .HasForeignKey("GenderId"); + + b.Navigation("Gender"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountBackgroundPicture", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithOne("BackgroundPicture") + .HasForeignKey("WatchIt.Database.Model.Accounts.AccountBackgroundPicture", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Photos.PhotoBackground", "Background") + .WithMany("BackgroundUsages") + .HasForeignKey("BackgroundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Background"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountFollow", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Followed") + .WithMany("FollowersRelationshipObjects") + .HasForeignKey("FollowedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Follower") + .WithMany("FollowsRelationshipObjects") + .HasForeignKey("FollowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Followed"); + + b.Navigation("Follower"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountProfilePicture", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithOne("ProfilePicture") + .HasForeignKey("WatchIt.Database.Model.Accounts.AccountProfilePicture", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountRefreshToken", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithMany("RefreshTokens") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumGenre", b => + { + b.HasOne("WatchIt.Database.Model.Genres.Genre", "Genre") + .WithMany("MediaRelationObjects") + .HasForeignKey("GenreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("GenresRelationshipObjects") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Genre"); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumPicture", b => + { + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithOne("Picture") + .HasForeignKey("WatchIt.Database.Model.Media.MediumPicture", "MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumRating", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithMany("MediaRatings") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("Ratings") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumViewCount", b => + { + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("ViewCounts") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.Person", b => + { + b.HasOne("WatchIt.Database.Model.Genders.Gender", "Gender") + .WithMany("People") + .HasForeignKey("GenderId"); + + b.Navigation("Gender"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.PersonPicture", b => + { + b.HasOne("WatchIt.Database.Model.People.Person", "Person") + .WithOne("Picture") + .HasForeignKey("WatchIt.Database.Model.People.PersonPicture", "PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.PersonViewCount", b => + { + b.HasOne("WatchIt.Database.Model.People.Person", "Person") + .WithMany("ViewCounts") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.Photo", b => + { + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("Photos") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.PhotoBackground", b => + { + b.HasOne("WatchIt.Database.Model.Photos.Photo", "Photo") + .WithOne("Background") + .HasForeignKey("WatchIt.Database.Model.Photos.PhotoBackground", "PhotoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Photo"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.Role", b => + { + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("Roles") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.People.Person", "Person") + .WithMany("Roles") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Medium"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleRating", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithMany("RolesRatings") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Roles.Role", "Role") + .WithMany("Ratings") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleActor", b => + { + b.HasOne("WatchIt.Database.Model.Roles.RoleActorType", "ActorType") + .WithMany("Roles") + .HasForeignKey("ActorTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ActorType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleCreator", b => + { + b.HasOne("WatchIt.Database.Model.Roles.RoleCreatorType", "CreatorType") + .WithMany("Roles") + .HasForeignKey("CreatorTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.Account", b => + { + b.Navigation("BackgroundPicture"); + + b.Navigation("FollowersRelationshipObjects"); + + b.Navigation("FollowsRelationshipObjects"); + + b.Navigation("MediaRatings"); + + b.Navigation("ProfilePicture"); + + b.Navigation("RefreshTokens"); + + b.Navigation("RolesRatings"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Genders.Gender", b => + { + b.Navigation("Accounts"); + + b.Navigation("People"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Genres.Genre", b => + { + b.Navigation("MediaRelationObjects"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Medium", b => + { + b.Navigation("GenresRelationshipObjects"); + + b.Navigation("Photos"); + + b.Navigation("Picture"); + + b.Navigation("Ratings"); + + b.Navigation("Roles"); + + b.Navigation("ViewCounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.Person", b => + { + b.Navigation("Picture"); + + b.Navigation("Roles"); + + b.Navigation("ViewCounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.Photo", b => + { + b.Navigation("Background"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.PhotoBackground", b => + { + b.Navigation("BackgroundUsages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.Role", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleActorType", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleCreatorType", b => + { + b.Navigation("Roles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WatchIt.Database/Migrations/20250302235216_Initial.cs b/WatchIt.Database/Migrations/20250302235216_Initial.cs new file mode 100644 index 0000000..cd055fa --- /dev/null +++ b/WatchIt.Database/Migrations/20250302235216_Initial.cs @@ -0,0 +1,828 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "accounts"); + + migrationBuilder.EnsureSchema( + name: "genders"); + + migrationBuilder.EnsureSchema( + name: "genres"); + + migrationBuilder.EnsureSchema( + name: "media"); + + migrationBuilder.EnsureSchema( + name: "people"); + + migrationBuilder.EnsureSchema( + name: "photos"); + + migrationBuilder.EnsureSchema( + name: "roles"); + + migrationBuilder.CreateTable( + name: "Genders", + schema: "genders", + columns: table => new + { + Id = table.Column(type: "smallint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn), + Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Genders", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Genres", + schema: "genres", + columns: table => new + { + Id = table.Column(type: "smallint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn), + Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Genres", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Media", + schema: "media", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn), + Type = table.Column(type: "smallint", nullable: false), + Title = table.Column(type: "character varying(250)", maxLength: 250, nullable: false), + OriginalTitle = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + Duration = table.Column(type: "smallint", nullable: true), + ReleaseDate = table.Column(type: "date", nullable: true), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false), + Budget = table.Column(type: "money", nullable: true), + HasEnded = table.Column(type: "boolean", nullable: true, defaultValue: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Media", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "RoleActorTypes", + schema: "roles", + columns: table => new + { + Id = table.Column(type: "smallint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn), + Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleActorTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "RoleCreatorTypes", + schema: "roles", + columns: table => new + { + Id = table.Column(type: "smallint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn), + Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleCreatorTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Accounts", + schema: "accounts", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn), + Username = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + Email = table.Column(type: "character varying(320)", maxLength: 320, nullable: false), + Password = table.Column(type: "bytea", maxLength: 1000, nullable: false), + LeftSalt = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), + RightSalt = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), + IsAdmin = table.Column(type: "boolean", nullable: false, defaultValue: false), + JoinDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + ActiveDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + GenderId = table.Column(type: "smallint", nullable: true), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Accounts", x => x.Id); + table.ForeignKey( + name: "FK_Accounts_Genders_GenderId", + column: x => x.GenderId, + principalSchema: "genders", + principalTable: "Genders", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "People", + schema: "people", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn), + Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + FullName = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + BirthDate = table.Column(type: "date", nullable: true), + DeathDate = table.Column(type: "date", nullable: true), + GenderId = table.Column(type: "smallint", nullable: true), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_People", x => x.Id); + table.ForeignKey( + name: "FK_People_Genders_GenderId", + column: x => x.GenderId, + principalSchema: "genders", + principalTable: "Genders", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "MediumGenres", + schema: "media", + columns: table => new + { + MediumId = table.Column(type: "bigint", nullable: false), + GenreId = table.Column(type: "smallint", nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_MediumGenres", x => new { x.GenreId, x.MediumId }); + table.ForeignKey( + name: "FK_MediumGenres_Genres_GenreId", + column: x => x.GenreId, + principalSchema: "genres", + principalTable: "Genres", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_MediumGenres_Media_MediumId", + column: x => x.MediumId, + principalSchema: "media", + principalTable: "Media", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "MediumPictures", + schema: "media", + columns: table => new + { + MediumId = table.Column(type: "bigint", nullable: false), + Image = table.Column(type: "bytea", maxLength: -1, nullable: false), + MimeType = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + UploadDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_MediumPictures", x => x.MediumId); + table.ForeignKey( + name: "FK_MediumPictures_Media_MediumId", + column: x => x.MediumId, + principalSchema: "media", + principalTable: "Media", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "MediumViewCounts", + schema: "media", + columns: table => new + { + MediumId = table.Column(type: "bigint", nullable: false), + Date = table.Column(type: "date", nullable: false, defaultValueSql: "now()"), + ViewCount = table.Column(type: "bigint", nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_MediumViewCounts", x => new { x.MediumId, x.Date }); + table.ForeignKey( + name: "FK_MediumViewCounts_Media_MediumId", + column: x => x.MediumId, + principalSchema: "media", + principalTable: "Media", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Photos", + schema: "photos", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + MediumId = table.Column(type: "bigint", nullable: false), + Image = table.Column(type: "bytea", maxLength: -1, nullable: false), + MimeType = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + UploadDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Photos", x => x.Id); + table.ForeignKey( + name: "FK_Photos_Media_MediumId", + column: x => x.MediumId, + principalSchema: "media", + principalTable: "Media", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AccountFollows", + schema: "accounts", + columns: table => new + { + FollowerId = table.Column(type: "bigint", nullable: false), + FollowedId = table.Column(type: "bigint", nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AccountFollows", x => new { x.FollowerId, x.FollowedId }); + table.ForeignKey( + name: "FK_AccountFollows_Accounts_FollowedId", + column: x => x.FollowedId, + principalSchema: "accounts", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AccountFollows_Accounts_FollowerId", + column: x => x.FollowerId, + principalSchema: "accounts", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AccountProfilePictures", + schema: "accounts", + columns: table => new + { + AccountId = table.Column(type: "bigint", nullable: false), + Image = table.Column(type: "bytea", maxLength: -1, nullable: false), + MimeType = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + UploadDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AccountProfilePictures", x => x.AccountId); + table.ForeignKey( + name: "FK_AccountProfilePictures_Accounts_AccountId", + column: x => x.AccountId, + principalSchema: "accounts", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AccountRefreshTokens", + schema: "accounts", + columns: table => new + { + Token = table.Column(type: "uuid", nullable: false), + AccountId = table.Column(type: "bigint", nullable: false), + ExpirationDate = table.Column(type: "timestamp with time zone", nullable: false), + IsExtendable = table.Column(type: "boolean", nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AccountRefreshTokens", x => x.Token); + table.ForeignKey( + name: "FK_AccountRefreshTokens_Accounts_AccountId", + column: x => x.AccountId, + principalSchema: "accounts", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "MediumRatings", + schema: "media", + columns: table => new + { + AccountId = table.Column(type: "bigint", nullable: false), + MediumId = table.Column(type: "bigint", nullable: false), + Rating = table.Column(type: "smallint", nullable: false), + Date = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_MediumRatings", x => new { x.AccountId, x.MediumId }); + table.ForeignKey( + name: "FK_MediumRatings_Accounts_AccountId", + column: x => x.AccountId, + principalSchema: "accounts", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_MediumRatings_Media_MediumId", + column: x => x.MediumId, + principalSchema: "media", + principalTable: "Media", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PersonPictures", + schema: "people", + columns: table => new + { + PersonId = table.Column(type: "bigint", nullable: false), + Image = table.Column(type: "bytea", maxLength: -1, nullable: false), + MimeType = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + UploadDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersonPictures", x => x.PersonId); + table.ForeignKey( + name: "FK_PersonPictures_People_PersonId", + column: x => x.PersonId, + principalSchema: "people", + principalTable: "People", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PersonViewCounts", + schema: "people", + columns: table => new + { + PersonId = table.Column(type: "bigint", nullable: false), + Date = table.Column(type: "date", nullable: false, defaultValueSql: "now()"), + ViewCount = table.Column(type: "bigint", nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersonViewCounts", x => new { x.PersonId, x.Date }); + table.ForeignKey( + name: "FK_PersonViewCounts_People_PersonId", + column: x => x.PersonId, + principalSchema: "people", + principalTable: "People", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Roles", + schema: "roles", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Type = table.Column(type: "smallint", nullable: false), + MediumId = table.Column(type: "bigint", nullable: false), + PersonId = table.Column(type: "bigint", nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false), + ActorTypeId = table.Column(type: "smallint", nullable: true), + Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + CreatorTypeId = table.Column(type: "smallint", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + table.ForeignKey( + name: "FK_Roles_Media_MediumId", + column: x => x.MediumId, + principalSchema: "media", + principalTable: "Media", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Roles_People_PersonId", + column: x => x.PersonId, + principalSchema: "people", + principalTable: "People", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Roles_RoleActorTypes_ActorTypeId", + column: x => x.ActorTypeId, + principalSchema: "roles", + principalTable: "RoleActorTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Roles_RoleCreatorTypes_CreatorTypeId", + column: x => x.CreatorTypeId, + principalSchema: "roles", + principalTable: "RoleCreatorTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PhotoBackground", + schema: "photos", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + PhotoId = table.Column(type: "uuid", nullable: false), + IsUniversal = table.Column(type: "boolean", nullable: false, defaultValue: false), + FirstGradientColor = table.Column(type: "bytea", nullable: false), + SecondGradientColor = table.Column(type: "bytea", nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PhotoBackground", x => x.Id); + table.ForeignKey( + name: "FK_PhotoBackground_Photos_PhotoId", + column: x => x.PhotoId, + principalSchema: "photos", + principalTable: "Photos", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "RoleRatings", + schema: "roles", + columns: table => new + { + AccountId = table.Column(type: "bigint", nullable: false), + RoleId = table.Column(type: "uuid", nullable: false), + Rating = table.Column(type: "smallint", nullable: false), + Date = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleRatings", x => new { x.AccountId, x.RoleId }); + table.ForeignKey( + name: "FK_RoleRatings_Accounts_AccountId", + column: x => x.AccountId, + principalSchema: "accounts", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_RoleRatings_Roles_RoleId", + column: x => x.RoleId, + principalSchema: "roles", + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AccountBackgroundPictures", + schema: "accounts", + columns: table => new + { + AccountId = table.Column(type: "bigint", nullable: false), + BackgroundId = table.Column(type: "uuid", nullable: false), + xmin = table.Column(type: "xid", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AccountBackgroundPictures", x => x.AccountId); + table.ForeignKey( + name: "FK_AccountBackgroundPictures_Accounts_AccountId", + column: x => x.AccountId, + principalSchema: "accounts", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AccountBackgroundPictures_PhotoBackground_BackgroundId", + column: x => x.BackgroundId, + principalSchema: "photos", + principalTable: "PhotoBackground", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AccountBackgroundPictures_AccountId", + schema: "accounts", + table: "AccountBackgroundPictures", + column: "AccountId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AccountBackgroundPictures_BackgroundId", + schema: "accounts", + table: "AccountBackgroundPictures", + column: "BackgroundId"); + + migrationBuilder.CreateIndex( + name: "IX_AccountFollows_FollowedId", + schema: "accounts", + table: "AccountFollows", + column: "FollowedId"); + + migrationBuilder.CreateIndex( + name: "IX_AccountProfilePictures_AccountId", + schema: "accounts", + table: "AccountProfilePictures", + column: "AccountId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AccountRefreshTokens_AccountId", + schema: "accounts", + table: "AccountRefreshTokens", + column: "AccountId"); + + migrationBuilder.CreateIndex( + name: "IX_AccountRefreshTokens_Token", + schema: "accounts", + table: "AccountRefreshTokens", + column: "Token", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Accounts_GenderId", + schema: "accounts", + table: "Accounts", + column: "GenderId"); + + migrationBuilder.CreateIndex( + name: "IX_Accounts_Id", + schema: "accounts", + table: "Accounts", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Genders_Id", + schema: "genders", + table: "Genders", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Genres_Id", + schema: "genres", + table: "Genres", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Media_Id", + schema: "media", + table: "Media", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_MediumGenres_MediumId", + schema: "media", + table: "MediumGenres", + column: "MediumId"); + + migrationBuilder.CreateIndex( + name: "IX_MediumPictures_MediumId", + schema: "media", + table: "MediumPictures", + column: "MediumId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_MediumRatings_MediumId", + schema: "media", + table: "MediumRatings", + column: "MediumId"); + + migrationBuilder.CreateIndex( + name: "IX_People_GenderId", + schema: "people", + table: "People", + column: "GenderId"); + + migrationBuilder.CreateIndex( + name: "IX_People_Id", + schema: "people", + table: "People", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_PersonPictures_PersonId", + schema: "people", + table: "PersonPictures", + column: "PersonId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_PhotoBackground_Id", + schema: "photos", + table: "PhotoBackground", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_PhotoBackground_PhotoId", + schema: "photos", + table: "PhotoBackground", + column: "PhotoId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Photos_Id", + schema: "photos", + table: "Photos", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Photos_MediumId", + schema: "photos", + table: "Photos", + column: "MediumId"); + + migrationBuilder.CreateIndex( + name: "IX_RoleActorTypes_Id", + schema: "roles", + table: "RoleActorTypes", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_RoleCreatorTypes_Id", + schema: "roles", + table: "RoleCreatorTypes", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_RoleRatings_RoleId", + schema: "roles", + table: "RoleRatings", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "IX_Roles_ActorTypeId", + schema: "roles", + table: "Roles", + column: "ActorTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_Roles_CreatorTypeId", + schema: "roles", + table: "Roles", + column: "CreatorTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_Roles_Id", + schema: "roles", + table: "Roles", + column: "Id", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Roles_MediumId", + schema: "roles", + table: "Roles", + column: "MediumId"); + + migrationBuilder.CreateIndex( + name: "IX_Roles_PersonId", + schema: "roles", + table: "Roles", + column: "PersonId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AccountBackgroundPictures", + schema: "accounts"); + + migrationBuilder.DropTable( + name: "AccountFollows", + schema: "accounts"); + + migrationBuilder.DropTable( + name: "AccountProfilePictures", + schema: "accounts"); + + migrationBuilder.DropTable( + name: "AccountRefreshTokens", + schema: "accounts"); + + migrationBuilder.DropTable( + name: "MediumGenres", + schema: "media"); + + migrationBuilder.DropTable( + name: "MediumPictures", + schema: "media"); + + migrationBuilder.DropTable( + name: "MediumRatings", + schema: "media"); + + migrationBuilder.DropTable( + name: "MediumViewCounts", + schema: "media"); + + migrationBuilder.DropTable( + name: "PersonPictures", + schema: "people"); + + migrationBuilder.DropTable( + name: "PersonViewCounts", + schema: "people"); + + migrationBuilder.DropTable( + name: "RoleRatings", + schema: "roles"); + + migrationBuilder.DropTable( + name: "PhotoBackground", + schema: "photos"); + + migrationBuilder.DropTable( + name: "Genres", + schema: "genres"); + + migrationBuilder.DropTable( + name: "Accounts", + schema: "accounts"); + + migrationBuilder.DropTable( + name: "Roles", + schema: "roles"); + + migrationBuilder.DropTable( + name: "Photos", + schema: "photos"); + + migrationBuilder.DropTable( + name: "People", + schema: "people"); + + migrationBuilder.DropTable( + name: "RoleActorTypes", + schema: "roles"); + + migrationBuilder.DropTable( + name: "RoleCreatorTypes", + schema: "roles"); + + migrationBuilder.DropTable( + name: "Media", + schema: "media"); + + migrationBuilder.DropTable( + name: "Genders", + schema: "genders"); + } + } +} diff --git a/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs b/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs new file mode 100644 index 0000000..7d326b6 --- /dev/null +++ b/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs @@ -0,0 +1,1092 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using WatchIt.Database; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + [DbContext(typeof(DatabaseContext))] + partial class DatabaseContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("ActiveDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(320) + .HasColumnType("character varying(320)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("IsAdmin") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("JoinDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("LeftSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("bytea"); + + b.Property("RightSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Accounts", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountBackgroundPicture", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("BackgroundId") + .HasColumnType("uuid"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("AccountId"); + + b.HasIndex("AccountId") + .IsUnique(); + + b.HasIndex("BackgroundId"); + + b.ToTable("AccountBackgroundPictures", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountFollow", b => + { + b.Property("FollowerId") + .HasColumnType("bigint"); + + b.Property("FollowedId") + .HasColumnType("bigint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("FollowerId", "FollowedId"); + + b.HasIndex("FollowedId"); + + b.ToTable("AccountFollows", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountProfilePicture", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("AccountId"); + + b.HasIndex("AccountId") + .IsUnique(); + + b.ToTable("AccountProfilePictures", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountRefreshToken", b => + { + b.Property("Token") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("IsExtendable") + .HasColumnType("boolean"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Token"); + + b.HasIndex("AccountId"); + + b.HasIndex("Token") + .IsUnique(); + + b.ToTable("AccountRefreshTokens", "accounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Genders.Gender", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genders", "genders"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Genres.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genres", "genres"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Medium", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Duration") + .HasColumnType("smallint"); + + b.Property("OriginalTitle") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("ReleaseDate") + .HasColumnType("date"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Media", "media"); + + b.HasDiscriminator("Type"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumGenre", b => + { + b.Property("GenreId") + .HasColumnType("smallint"); + + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("GenreId", "MediumId"); + + b.HasIndex("MediumId"); + + b.ToTable("MediumGenres", "media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumPicture", b => + { + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("MediumId"); + + b.HasIndex("MediumId") + .IsUnique(); + + b.ToTable("MediumPictures", "media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumRating", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("AccountId", "MediumId"); + + b.HasIndex("MediumId"); + + b.ToTable("MediumRatings", "media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumViewCount", b => + { + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.Property("ViewCount") + .HasColumnType("bigint"); + + b.HasKey("MediumId", "Date"); + + b.ToTable("MediumViewCounts", "media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("BirthDate") + .HasColumnType("date"); + + b.Property("DeathDate") + .HasColumnType("date"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("FullName") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("People", "people"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.PersonPicture", b => + { + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("PersonId"); + + b.HasIndex("PersonId") + .IsUnique(); + + b.ToTable("PersonPictures", "people"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.PersonViewCount", b => + { + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.Property("ViewCount") + .HasColumnType("bigint"); + + b.HasKey("PersonId", "Date"); + + b.ToTable("PersonViewCounts", "people"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.Photo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediumId"); + + b.ToTable("Photos", "photos"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.PhotoBackground", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FirstGradientColor") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("IsUniversal") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("PhotoId") + .HasColumnType("uuid"); + + b.Property("SecondGradientColor") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PhotoId") + .IsUnique(); + + b.ToTable("PhotoBackground", "photos"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediumId") + .HasColumnType("bigint"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediumId"); + + b.HasIndex("PersonId"); + + b.ToTable("Roles", "roles"); + + b.HasDiscriminator("Type"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleActorType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("RoleActorTypes", "roles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleCreatorType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("RoleCreatorTypes", "roles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleRating", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("AccountId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleRatings", "roles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumMovie", b => + { + b.HasBaseType("WatchIt.Database.Model.Media.Medium"); + + b.Property("Budget") + .HasColumnType("money"); + + b.HasDiscriminator().HasValue((byte)0); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumSeries", b => + { + b.HasBaseType("WatchIt.Database.Model.Media.Medium"); + + b.Property("HasEnded") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.HasDiscriminator().HasValue((byte)1); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleActor", b => + { + b.HasBaseType("WatchIt.Database.Model.Roles.Role"); + + b.Property("ActorTypeId") + .HasColumnType("smallint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasIndex("ActorTypeId"); + + b.HasDiscriminator().HasValue((byte)0); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleCreator", b => + { + b.HasBaseType("WatchIt.Database.Model.Roles.Role"); + + b.Property("CreatorTypeId") + .HasColumnType("smallint"); + + b.HasIndex("CreatorTypeId"); + + b.HasDiscriminator().HasValue((byte)1); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.Account", b => + { + b.HasOne("WatchIt.Database.Model.Genders.Gender", "Gender") + .WithMany("Accounts") + .HasForeignKey("GenderId"); + + b.Navigation("Gender"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountBackgroundPicture", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithOne("BackgroundPicture") + .HasForeignKey("WatchIt.Database.Model.Accounts.AccountBackgroundPicture", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Photos.PhotoBackground", "Background") + .WithMany("BackgroundUsages") + .HasForeignKey("BackgroundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Background"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountFollow", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Followed") + .WithMany("FollowersRelationshipObjects") + .HasForeignKey("FollowedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Follower") + .WithMany("FollowsRelationshipObjects") + .HasForeignKey("FollowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Followed"); + + b.Navigation("Follower"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountProfilePicture", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithOne("ProfilePicture") + .HasForeignKey("WatchIt.Database.Model.Accounts.AccountProfilePicture", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.AccountRefreshToken", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithMany("RefreshTokens") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumGenre", b => + { + b.HasOne("WatchIt.Database.Model.Genres.Genre", "Genre") + .WithMany("MediaRelationObjects") + .HasForeignKey("GenreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("GenresRelationshipObjects") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Genre"); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumPicture", b => + { + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithOne("Picture") + .HasForeignKey("WatchIt.Database.Model.Media.MediumPicture", "MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumRating", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithMany("MediaRatings") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("Ratings") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediumViewCount", b => + { + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("ViewCounts") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.Person", b => + { + b.HasOne("WatchIt.Database.Model.Genders.Gender", "Gender") + .WithMany("People") + .HasForeignKey("GenderId"); + + b.Navigation("Gender"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.PersonPicture", b => + { + b.HasOne("WatchIt.Database.Model.People.Person", "Person") + .WithOne("Picture") + .HasForeignKey("WatchIt.Database.Model.People.PersonPicture", "PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.PersonViewCount", b => + { + b.HasOne("WatchIt.Database.Model.People.Person", "Person") + .WithMany("ViewCounts") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.Photo", b => + { + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("Photos") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Medium"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.PhotoBackground", b => + { + b.HasOne("WatchIt.Database.Model.Photos.Photo", "Photo") + .WithOne("Background") + .HasForeignKey("WatchIt.Database.Model.Photos.PhotoBackground", "PhotoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Photo"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.Role", b => + { + b.HasOne("WatchIt.Database.Model.Media.Medium", "Medium") + .WithMany("Roles") + .HasForeignKey("MediumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.People.Person", "Person") + .WithMany("Roles") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Medium"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleRating", b => + { + b.HasOne("WatchIt.Database.Model.Accounts.Account", "Account") + .WithMany("RolesRatings") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Roles.Role", "Role") + .WithMany("Ratings") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleActor", b => + { + b.HasOne("WatchIt.Database.Model.Roles.RoleActorType", "ActorType") + .WithMany("Roles") + .HasForeignKey("ActorTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ActorType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleCreator", b => + { + b.HasOne("WatchIt.Database.Model.Roles.RoleCreatorType", "CreatorType") + .WithMany("Roles") + .HasForeignKey("CreatorTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatorType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Accounts.Account", b => + { + b.Navigation("BackgroundPicture"); + + b.Navigation("FollowersRelationshipObjects"); + + b.Navigation("FollowsRelationshipObjects"); + + b.Navigation("MediaRatings"); + + b.Navigation("ProfilePicture"); + + b.Navigation("RefreshTokens"); + + b.Navigation("RolesRatings"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Genders.Gender", b => + { + b.Navigation("Accounts"); + + b.Navigation("People"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Genres.Genre", b => + { + b.Navigation("MediaRelationObjects"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Medium", b => + { + b.Navigation("GenresRelationshipObjects"); + + b.Navigation("Photos"); + + b.Navigation("Picture"); + + b.Navigation("Ratings"); + + b.Navigation("Roles"); + + b.Navigation("ViewCounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.People.Person", b => + { + b.Navigation("Picture"); + + b.Navigation("Roles"); + + b.Navigation("ViewCounts"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.Photo", b => + { + b.Navigation("Background"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Photos.PhotoBackground", b => + { + b.Navigation("BackgroundUsages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.Role", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleActorType", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Roles.RoleCreatorType", b => + { + b.Navigation("Roles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WatchIt.Database/Model/Accounts/Account.cs b/WatchIt.Database/Model/Accounts/Account.cs new file mode 100644 index 0000000..8ee8f5d --- /dev/null +++ b/WatchIt.Database/Model/Accounts/Account.cs @@ -0,0 +1,59 @@ +using WatchIt.Database.Model.Genders; +using WatchIt.Database.Model.Media; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Model.Accounts; + +public class Account +{ + #region PROPERTIES + + public long Id { get; set; } + public string Username { get; set; } = default!; + public string Email { get; set; } = default!; + public byte[] Password { get; set; } = default!; + public string LeftSalt { get; set; } = default!; + public string RightSalt { get; set; } = default!; + public bool IsAdmin { get; set; } = false; + public DateTimeOffset JoinDate { get; set; } + public DateTimeOffset ActiveDate { get; set; } + public string? Description { get; set; } + public short? GenderId { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Profile picture + public virtual AccountProfilePicture? ProfilePicture { get; set; } + + // Background picture + public virtual AccountBackgroundPicture? BackgroundPicture { get; set; } + + // Refresh tokens + public virtual IEnumerable RefreshTokens { get; set; } = new List(); + + // Follows + public virtual IEnumerable FollowsRelationshipObjects { get; set; } = new List(); + public virtual IEnumerable Follows { get; set; } = new List(); + + // Followers + public virtual IEnumerable FollowersRelationshipObjects { get; set; } = new List(); + public virtual IEnumerable Followers { get; set; } = new List(); + + // Gender + public virtual Gender? Gender { get; set; } + + // Media ratings + public virtual IEnumerable MediaRatings { get; set; } = new List(); + public virtual IEnumerable MediaRated { get; set; } = new List(); + + // Roles ratings + public virtual IEnumerable RolesRatings { get; set; } = new List(); + public virtual IEnumerable RolesRated { get; set; } = new List(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Accounts/AccountBackgroundPicture.cs b/WatchIt.Database/Model/Accounts/AccountBackgroundPicture.cs new file mode 100644 index 0000000..18728b4 --- /dev/null +++ b/WatchIt.Database/Model/Accounts/AccountBackgroundPicture.cs @@ -0,0 +1,26 @@ +using WatchIt.Database.Model.Photos; + +namespace WatchIt.Database.Model.Accounts; + +public class AccountBackgroundPicture +{ + #region PROPERTIES + + public long AccountId { get; set; } + public Guid BackgroundId { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Account + public virtual Account Account { get; set; } = default!; + + // Background + public virtual PhotoBackground Background { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Accounts/AccountFollow.cs b/WatchIt.Database/Model/Accounts/AccountFollow.cs new file mode 100644 index 0000000..8632b16 --- /dev/null +++ b/WatchIt.Database/Model/Accounts/AccountFollow.cs @@ -0,0 +1,24 @@ +namespace WatchIt.Database.Model.Accounts; + +public class AccountFollow +{ + #region PROPERTIES + + public long FollowerId { get; set; } + public long FollowedId { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Follower + public virtual Account Follower { get; set; } = default!; + + // Followed + public virtual Account Followed { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Accounts/AccountProfilePicture.cs b/WatchIt.Database/Model/Accounts/AccountProfilePicture.cs new file mode 100644 index 0000000..bda3a6c --- /dev/null +++ b/WatchIt.Database/Model/Accounts/AccountProfilePicture.cs @@ -0,0 +1,23 @@ +namespace WatchIt.Database.Model.Accounts; + +public class AccountProfilePicture : IImageEntity +{ + #region PROPERTIES + + public long AccountId { get; set; } + public byte[] Image { get; set; } = default!; + public string MimeType { get; set; } = default!; + public DateTimeOffset UploadDate { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Account + public virtual Account Account { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Accounts/AccountRefreshToken.cs b/WatchIt.Database/Model/Accounts/AccountRefreshToken.cs new file mode 100644 index 0000000..25e4388 --- /dev/null +++ b/WatchIt.Database/Model/Accounts/AccountRefreshToken.cs @@ -0,0 +1,23 @@ +namespace WatchIt.Database.Model.Accounts; + +public class AccountRefreshToken +{ + #region PROPERTIES + + public Guid Token { get; set; } + public long AccountId { get; set; } + public DateTimeOffset ExpirationDate { get; set; } + public bool IsExtendable { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Account + public virtual Account Account { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Genders/Gender.cs b/WatchIt.Database/Model/Genders/Gender.cs new file mode 100644 index 0000000..81f9a55 --- /dev/null +++ b/WatchIt.Database/Model/Genders/Gender.cs @@ -0,0 +1,26 @@ +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.Database.Model.Genders; + +public class Gender +{ + #region PROPERTIES + + public short Id { get; set; } + public string Name { get; set; } = default!; + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Accounts + public virtual IEnumerable Accounts { get; set; } = new List(); + + // People + public virtual IEnumerable People { get; set; } = new List(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Genres/Genre.cs b/WatchIt.Database/Model/Genres/Genre.cs new file mode 100644 index 0000000..3a363d1 --- /dev/null +++ b/WatchIt.Database/Model/Genres/Genre.cs @@ -0,0 +1,24 @@ +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Model.Genres; + +public class Genre +{ + #region PROPERTIES + + public short Id { get; set; } + public string Name { get; set; } = default!; + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Media + public virtual IEnumerable MediaRelationObjects { get; set; } = new List(); + public virtual IEnumerable Media { get; set; } = new List(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/IImageEntity.cs b/WatchIt.Database/Model/IImageEntity.cs new file mode 100644 index 0000000..5cbe996 --- /dev/null +++ b/WatchIt.Database/Model/IImageEntity.cs @@ -0,0 +1,12 @@ +namespace WatchIt.Database.Model; + +public interface IImageEntity +{ + #region PROPERTIES + + byte[] Image { get; set; } + string MimeType { get; set; } + DateTimeOffset UploadDate { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/IRatingEntity.cs b/WatchIt.Database/Model/IRatingEntity.cs new file mode 100644 index 0000000..3aea34c --- /dev/null +++ b/WatchIt.Database/Model/IRatingEntity.cs @@ -0,0 +1,23 @@ +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Model; + +public interface IRatingEntity +{ + #region PROPERTIES + + long AccountId { get; set; } + byte Rating { get; set; } + DateTime Date { get; set; } + + #endregion + + + + #region NAVIGATION + + // Account + Accounts.Account Account { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/IViewCountEntity.cs b/WatchIt.Database/Model/IViewCountEntity.cs new file mode 100644 index 0000000..8852828 --- /dev/null +++ b/WatchIt.Database/Model/IViewCountEntity.cs @@ -0,0 +1,11 @@ +namespace WatchIt.Database.Model; + +public interface IViewCountEntity +{ + #region PROPERTIES + + DateOnly Date { get; set; } + long ViewCount { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Media/Medium.cs b/WatchIt.Database/Model/Media/Medium.cs new file mode 100644 index 0000000..5136028 --- /dev/null +++ b/WatchIt.Database/Model/Media/Medium.cs @@ -0,0 +1,47 @@ +using WatchIt.Database.Model.Genres; +using WatchIt.Database.Model.Photos; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Model.Media; + +public abstract class Medium +{ + #region PROPERTIES + + public long Id { get; set; } + public MediumType Type { get; set; } + public string Title { get; set; } = default!; + public string? OriginalTitle { get; set; } + public string? Description { get; set; } + public short? Duration { get; set; } + public DateOnly? ReleaseDate { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Genres + public virtual IEnumerable GenresRelationshipObjects { get; set; } = new List(); + public virtual IEnumerable Genres { get; set; } = new List(); + + // Picture + public virtual MediumPicture? Picture { get; set; } + + // Photos + public virtual IEnumerable Photos { get; set; } = new List(); + + // View counts + public virtual IEnumerable ViewCounts { get; set; } = new List(); + + // Ratings + public virtual IEnumerable Ratings { get; set; } = new List(); + public virtual IEnumerable RatedBy { get; set; } = new List(); + + // Roles + public virtual IEnumerable Roles { get; set; } = new List(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Media/MediumGenre.cs b/WatchIt.Database/Model/Media/MediumGenre.cs new file mode 100644 index 0000000..d64190c --- /dev/null +++ b/WatchIt.Database/Model/Media/MediumGenre.cs @@ -0,0 +1,26 @@ +using WatchIt.Database.Model.Genres; + +namespace WatchIt.Database.Model.Media; + +public class MediumGenre +{ + #region PROPERTIES + + public long MediumId { get; set; } + public short GenreId { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Medium + public virtual Medium Medium { get; set; } = default!; + + // Genre + public virtual Genre Genre { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Media/MediumMovie.cs b/WatchIt.Database/Model/Media/MediumMovie.cs new file mode 100644 index 0000000..6eb7545 --- /dev/null +++ b/WatchIt.Database/Model/Media/MediumMovie.cs @@ -0,0 +1,10 @@ +namespace WatchIt.Database.Model.Media; + +public class MediumMovie : Medium +{ + #region PROPERTIES + + public decimal? Budget { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Media/MediumPicture.cs b/WatchIt.Database/Model/Media/MediumPicture.cs new file mode 100644 index 0000000..8c2709b --- /dev/null +++ b/WatchIt.Database/Model/Media/MediumPicture.cs @@ -0,0 +1,22 @@ +namespace WatchIt.Database.Model.Media; + +public class MediumPicture : IImageEntity +{ + #region PROPERTIES + + public long MediumId { get; set; } + public byte[] Image { get; set; } = default!; + public string MimeType { get; set; } = default!; + public DateTimeOffset UploadDate { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + public virtual Medium Medium { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Media/MediumRating.cs b/WatchIt.Database/Model/Media/MediumRating.cs new file mode 100644 index 0000000..96930a5 --- /dev/null +++ b/WatchIt.Database/Model/Media/MediumRating.cs @@ -0,0 +1,26 @@ +namespace WatchIt.Database.Model.Media; + +public class MediumRating : IRatingEntity +{ + #region PROPERTIES + + public long AccountId { get; set; } + public long MediumId { get; set; } + public byte Rating { get; set; } + public DateTime Date { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Account + public virtual Accounts.Account Account { get; set; } = default!; + + // Medium + public virtual Medium Medium { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Media/MediumSeries.cs b/WatchIt.Database/Model/Media/MediumSeries.cs new file mode 100644 index 0000000..6762951 --- /dev/null +++ b/WatchIt.Database/Model/Media/MediumSeries.cs @@ -0,0 +1,10 @@ +namespace WatchIt.Database.Model.Media; + +public class MediumSeries : Medium +{ + #region PROPERTIES + + public bool HasEnded { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Media/MediumType.cs b/WatchIt.Database/Model/Media/MediumType.cs new file mode 100644 index 0000000..5ed26d4 --- /dev/null +++ b/WatchIt.Database/Model/Media/MediumType.cs @@ -0,0 +1,7 @@ +namespace WatchIt.Database.Model.Media; + +public enum MediumType : byte +{ + Movie = 0, + Series = 1, +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Media/MediumViewCount.cs b/WatchIt.Database/Model/Media/MediumViewCount.cs new file mode 100644 index 0000000..0685c6e --- /dev/null +++ b/WatchIt.Database/Model/Media/MediumViewCount.cs @@ -0,0 +1,23 @@ +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Model.Media; + +public class MediumViewCount : IViewCountEntity +{ + #region PROPERTIES + + public long MediumId { get; set; } + public DateOnly Date { get; set; } + public long ViewCount { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + public virtual Medium Medium { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/People/Person.cs b/WatchIt.Database/Model/People/Person.cs new file mode 100644 index 0000000..874c45c --- /dev/null +++ b/WatchIt.Database/Model/People/Person.cs @@ -0,0 +1,38 @@ +using WatchIt.Database.Model.Genders; +using WatchIt.Database.Model.Roles; + +namespace WatchIt.Database.Model.People; + +public class Person +{ + #region PROPERTIES + + public long Id { get; set; } + public string Name { get; set; } = default!; + public string? FullName { get; set; } + public string? Description { get; set; } + public DateOnly? BirthDate { get; set; } + public DateOnly? DeathDate { get; set; } + public short? GenderId { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Gender + public virtual Gender? Gender { get; set; } + + // Picture + public virtual PersonPicture? Picture { get; set; } + + // View counts + public virtual IEnumerable ViewCounts { get; set; } = new List(); + + // Roles + public virtual IEnumerable Roles { get; set; } = new List(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/People/PersonPicture.cs b/WatchIt.Database/Model/People/PersonPicture.cs new file mode 100644 index 0000000..5068ec1 --- /dev/null +++ b/WatchIt.Database/Model/People/PersonPicture.cs @@ -0,0 +1,22 @@ +namespace WatchIt.Database.Model.People; + +public class PersonPicture : IImageEntity +{ + #region PROPERTIES + + public long PersonId { get; set; } + public byte[] Image { get; set; } = default!; + public string MimeType { get; set; } = default!; + public DateTimeOffset UploadDate { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + public virtual Person Person { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/People/PersonViewCount.cs b/WatchIt.Database/Model/People/PersonViewCount.cs new file mode 100644 index 0000000..d76fd66 --- /dev/null +++ b/WatchIt.Database/Model/People/PersonViewCount.cs @@ -0,0 +1,21 @@ +namespace WatchIt.Database.Model.People; + +public class PersonViewCount : IViewCountEntity +{ + #region PROPERTIES + + public long PersonId { get; set; } + public DateOnly Date { get; set; } + public long ViewCount { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + public virtual Person Person { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Photos/Photo.cs b/WatchIt.Database/Model/Photos/Photo.cs new file mode 100644 index 0000000..4624d89 --- /dev/null +++ b/WatchIt.Database/Model/Photos/Photo.cs @@ -0,0 +1,29 @@ +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Model.Photos; + +public class Photo : IImageEntity +{ + #region PROPERTIES + + public Guid Id { get; set; } + public long MediumId { get; set; } + public byte[] Image { get; set; } = null!; + public string MimeType { get; set; } = null!; + public DateTimeOffset UploadDate { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Medium + public virtual Medium Medium { get; set; } = default!; + + // Background settings + public virtual PhotoBackground? Background { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Photos/PhotoBackground.cs b/WatchIt.Database/Model/Photos/PhotoBackground.cs new file mode 100644 index 0000000..fc722bf --- /dev/null +++ b/WatchIt.Database/Model/Photos/PhotoBackground.cs @@ -0,0 +1,30 @@ +using System.Drawing; +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.Database.Model.Photos; + +public class PhotoBackground +{ + #region PROPERTIES + + public Guid Id { get; set; } + public Guid PhotoId { get; set; } + public bool IsUniversal { get; set; } + public Color FirstGradientColor { get; set; } + public Color SecondGradientColor { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Photo + public virtual Photo Photo { get; set; } = default!; + + // Background usages + public virtual IEnumerable BackgroundUsages { get; set; } = new List(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Roles/Role.cs b/WatchIt.Database/Model/Roles/Role.cs new file mode 100644 index 0000000..cbd92f8 --- /dev/null +++ b/WatchIt.Database/Model/Roles/Role.cs @@ -0,0 +1,32 @@ +using WatchIt.Database.Model.Media; + +namespace WatchIt.Database.Model.Roles; + +public abstract class Role +{ + #region PROPERTIES + + public Guid Id { get; set; } + public RoleType Type { get; set; } + public long MediumId { get; set; } + public long PersonId { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Medium + public virtual Medium Medium { get; set; } = default!; + + // Person + public virtual People.Person Person { get; set; } = default!; + + // Ratings + public virtual IEnumerable Ratings { get; set; } = default!; + public virtual IEnumerable RatedBy { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Roles/RoleActor.cs b/WatchIt.Database/Model/Roles/RoleActor.cs new file mode 100644 index 0000000..fb631e4 --- /dev/null +++ b/WatchIt.Database/Model/Roles/RoleActor.cs @@ -0,0 +1,20 @@ +namespace WatchIt.Database.Model.Roles; + +public class RoleActor : Role +{ + #region PROPERTIES + + public short ActorTypeId { get; set; } + public string Name { get; set; } = default!; + + #endregion + + + + #region NAVIGATION + + // Actor type + public virtual RoleActorType ActorType { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Roles/RoleActorType.cs b/WatchIt.Database/Model/Roles/RoleActorType.cs new file mode 100644 index 0000000..60092cb --- /dev/null +++ b/WatchIt.Database/Model/Roles/RoleActorType.cs @@ -0,0 +1,20 @@ +namespace WatchIt.Database.Model.Roles; + +public class RoleActorType +{ + #region PROPERTIES + + public short Id { get; set; } + public string Name { get; set; } = default!; + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + public virtual IEnumerable Roles { get; set; } = new List(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Roles/RoleCreator.cs b/WatchIt.Database/Model/Roles/RoleCreator.cs new file mode 100644 index 0000000..db09ce5 --- /dev/null +++ b/WatchIt.Database/Model/Roles/RoleCreator.cs @@ -0,0 +1,19 @@ +namespace WatchIt.Database.Model.Roles; + +public class RoleCreator : Role +{ + #region PROPERTIES + + public short CreatorTypeId { get; set; } + + #endregion + + + + #region NAVIGATION + + // Creator type + public virtual RoleCreatorType CreatorType { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Roles/RoleCreatorType.cs b/WatchIt.Database/Model/Roles/RoleCreatorType.cs new file mode 100644 index 0000000..c9cfd81 --- /dev/null +++ b/WatchIt.Database/Model/Roles/RoleCreatorType.cs @@ -0,0 +1,20 @@ +namespace WatchIt.Database.Model.Roles; + +public class RoleCreatorType +{ + #region PROPERTIES + + public short Id { get; set; } + public string Name { get; set; } = default!; + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + public virtual IEnumerable Roles { get; set; } = new List(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Roles/RoleRating.cs b/WatchIt.Database/Model/Roles/RoleRating.cs new file mode 100644 index 0000000..31c6518 --- /dev/null +++ b/WatchIt.Database/Model/Roles/RoleRating.cs @@ -0,0 +1,26 @@ +namespace WatchIt.Database.Model.Roles; + +public class RoleRating : IRatingEntity +{ + #region PROPERTIES + + public long AccountId { get; set; } + public Guid RoleId { get; set; } + public byte Rating { get; set; } + public DateTime Date { get; set; } + public uint Version { get; set; } + + #endregion + + + + #region NAVIGATION + + // Account + public virtual Accounts.Account Account { get; set; } = default!; + + // Role + public virtual Role Role { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/Model/Roles/RoleType.cs b/WatchIt.Database/Model/Roles/RoleType.cs new file mode 100644 index 0000000..98f71a4 --- /dev/null +++ b/WatchIt.Database/Model/Roles/RoleType.cs @@ -0,0 +1,7 @@ +namespace WatchIt.Database.Model.Roles; + +public enum RoleType : byte +{ + Actor = 0, + Creator = 1, +} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountConfiguration.cs deleted file mode 100644 index 5687c3a..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountConfiguration.cs +++ /dev/null @@ -1,66 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace WatchIt.Database.Model.Configuration.Account; - -public class AccountConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Username) - .HasMaxLength(50) - .IsRequired(); - - builder.Property(x => x.Email) - .HasMaxLength(320) - .IsRequired(); - - builder.Property(x => x.Description) - .HasMaxLength(1000); - - builder.HasOne(x => x.Gender) - .WithMany() - .HasForeignKey(x => x.GenderId); - builder.Property(x => x.GenderId); - - builder.HasOne(x => x.ProfilePicture) - .WithOne(x => x.Account) - .HasForeignKey(e => e.ProfilePictureId); - builder.Property(x => x.ProfilePictureId); - - builder.HasOne(x => x.BackgroundPicture) - .WithMany() - .HasForeignKey(x => x.BackgroundPictureId); - builder.Property(x => x.BackgroundPictureId); - - builder.Property(x => x.Password) - .HasMaxLength(1000) - .IsRequired(); - - builder.Property(x => x.LeftSalt) - .HasMaxLength(20) - .IsRequired(); - - builder.Property(x => x.RightSalt) - .HasMaxLength(20) - .IsRequired(); - - builder.Property(x => x.IsAdmin) - .IsRequired() - .HasDefaultValue(false); - - builder.Property(x => x.CreationDate) - .IsRequired() - .HasDefaultValueSql("now()"); - - builder.Property(x => x.LastActive) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountProfilePictureConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountProfilePictureConfiguration.cs deleted file mode 100644 index 1950a35..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountProfilePictureConfiguration.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Account; - -namespace WatchIt.Database.Model.Configuration.Account; - -public class AccountProfilePictureConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Image) - .HasMaxLength(-1) - .IsRequired(); - - builder.Property(x => x.MimeType) - .HasMaxLength(50) - .IsRequired(); - - builder.Property(x => x.UploadDate) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/CountryConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/CountryConfiguration.cs deleted file mode 100644 index 64d4292..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/CountryConfiguration.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Common; -using WatchIt.Database.Model.Media; -using WatchIt.Database.Model.Seeding; - -namespace WatchIt.Database.Model.Configuration.Common; - -public class CountryConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Name) - .HasMaxLength(100) - .IsRequired(); - - builder.Property(x => x.IsHistorical) - .HasDefaultValue(false) - .IsRequired(); - - // Navigation - builder.HasMany(x => x.MediaProduction) - .WithMany(x => x.ProductionCountries) - .UsingEntity(); - - // Data - builder.HasData(DataReader.Read()); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenderConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenderConfiguration.cs deleted file mode 100644 index 1133568..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenderConfiguration.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Common; -using WatchIt.Database.Model.Seeding; - -namespace WatchIt.Database.Model.Configuration.Common; - -public class GenderConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Name) - .IsRequired(); - - // Data - builder.HasData(DataReader.Read()); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenreConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenreConfiguration.cs deleted file mode 100644 index 4b4b665..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenreConfiguration.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Common; -using WatchIt.Database.Model.Media; -using WatchIt.Database.Model.Seeding; - -namespace WatchIt.Database.Model.Configuration.Common; - -public class GenreConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Name) - .HasMaxLength(100) - .IsRequired(); - - builder.Property(x => x.Description) - .HasMaxLength(1000); - - // Navigation - builder.HasMany(x => x.Media) - .WithMany(x => x.Genres) - .UsingEntity(); - - // Data - builder.HasData(DataReader.Read()); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaConfiguration.cs deleted file mode 100644 index 91af102..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaConfiguration.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Title) - .HasMaxLength(250) - .IsRequired(); - - builder.Property(x => x.OriginalTitle) - .HasMaxLength(250); - - builder.Property(x => x.Description) - .HasMaxLength(1000); - - builder.Property(x => x.ReleaseDate); - - builder.Property(x => x.Length); - - builder.HasOne(x => x.MediaPosterImage) - .WithOne(x => x.Media) - .HasForeignKey(x => x.MediaPosterImageId); - builder.Property(x => x.MediaPosterImageId); - - // Navigation - builder.HasMany(x => x.Genres) - .WithMany(x => x.Media) - .UsingEntity(); - builder.HasMany(x => x.ProductionCountries) - .WithMany(x => x.MediaProduction) - .UsingEntity(); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaGenreConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaGenreConfiguration.cs deleted file mode 100644 index 2c9deeb..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaGenreConfiguration.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaGenreConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasOne(x => x.Media) - .WithMany(x => x.MediaGenres) - .HasForeignKey(x => x.MediaId) - .IsRequired(); - builder.Property(x => x.MediaId) - .IsRequired(); - - builder.HasOne(x => x.Genre) - .WithMany(x => x.MediaGenres) - .HasForeignKey(x => x.GenreId) - .IsRequired(); - builder.Property(x => x.GenreId) - .IsRequired(); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaMovieConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaMovieConfiguration.cs deleted file mode 100644 index 4b4a2f0..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaMovieConfiguration.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaMovieConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasOne(x => x.Media) - .WithOne() - .HasForeignKey(x => x.Id) - .IsRequired(); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Budget) - .HasColumnType("money"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPhotoImageBackgroundConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPhotoImageBackgroundConfiguration.cs deleted file mode 100644 index eab319d..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPhotoImageBackgroundConfiguration.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaPhotoImageBackgroundConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.IsUniversalBackground) - .IsRequired() - .HasDefaultValue(false); - - builder.Property(x => x.FirstGradientColor) - .IsRequired() - .HasMaxLength(3); - - builder.Property(x => x.SecondGradientColor) - .IsRequired() - .HasMaxLength(3); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPhotoImageConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPhotoImageConfiguration.cs deleted file mode 100644 index b312d9c..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPhotoImageConfiguration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaPhotoImageConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.Media) - .WithMany(x => x.MediaPhotoImages) - .HasForeignKey(x => x.MediaId) - .IsRequired(); - builder.Property(x => x.MediaId) - .IsRequired(); - - builder.Property(x => x.Image) - .HasMaxLength(-1) - .IsRequired(); - - builder.Property(x => x.MimeType) - .HasMaxLength(50) - .IsRequired(); - - builder.Property(x => x.UploadDate) - .IsRequired() - .HasDefaultValueSql("now()"); - - builder.HasOne(x => x.MediaPhotoImageBackground) - .WithOne(x => x.MediaPhotoImage) - .HasForeignKey(); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPosterImageConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPosterImageConfiguration.cs deleted file mode 100644 index aad0529..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaPosterImageConfiguration.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaPosterImageConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Image) - .HasMaxLength(-1) - .IsRequired(); - - builder.Property(x => x.MimeType) - .HasMaxLength(50) - .IsRequired(); - - builder.Property(x => x.UploadDate) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaProductionCountryConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaProductionCountryConfiguration.cs deleted file mode 100644 index effca7a..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaProductionCountryConfiguration.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaProductionCountryConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasOne(x => x.Media) - .WithMany(x => x.MediaProductionCountries) - .HasForeignKey(x => x.MediaId) - .IsRequired(); - builder.Property(x => x.MediaId) - .IsRequired(); - - builder.HasOne(x => x.Country) - .WithMany(x => x.MediaProductionCountries) - .HasForeignKey(x => x.CountryId) - .IsRequired(); - builder.Property(x => x.CountryId) - .IsRequired(); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesConfiguration.cs deleted file mode 100644 index 966593b..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesConfiguration.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaSeriesConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasOne(x => x.Media) - .WithOne() - .HasForeignKey(x => x.Id) - .IsRequired(); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.HasEnded) - .IsRequired() - .HasDefaultValue(false); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesEpisodeConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesEpisodeConfiguration.cs deleted file mode 100644 index 7fd5d8d..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesEpisodeConfiguration.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaSeriesEpisodeConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.MediaSeriesSeason) - .WithMany(x => x.MediaSeriesEpisodes) - .HasForeignKey(x => x.MediaSeriesSeasonId) - .IsRequired(); - builder.Property(x => x.MediaSeriesSeasonId) - .IsRequired(); - - builder.Property(x => x.Number) - .IsRequired(); - - builder.Property(x => x.Name); - - builder.Property(x => x.IsSpecial) - .IsRequired() - .HasDefaultValue(false); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesSeasonConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesSeasonConfiguration.cs deleted file mode 100644 index 3bf8dd4..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Media/MediaSeriesSeasonConfiguration.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Configuration.Media; - -public class MediaSeriesSeasonConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.MediaSeries) - .WithMany(x => x.MediaSeriesSeasons) - .HasForeignKey(x => x.MediaSeriesId) - .IsRequired(); - builder.Property(x => x.MediaSeriesId) - .IsRequired(); - - builder.Property(x => x.Number) - .IsRequired(); - - builder.Property(x => x.Name); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonActorRoleConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonActorRoleConfiguration.cs deleted file mode 100644 index b6edd76..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonActorRoleConfiguration.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Database.Model.Configuration.Person; - -public class PersonActorRoleConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.Person) - .WithMany(x => x.PersonActorRoles) - .HasForeignKey(x => x.PersonId) - .IsRequired(); - builder.Property(x => x.PersonId) - .IsRequired(); - - builder.HasOne(x => x.Media) - .WithMany(x => x.PersonActorRoles) - .HasForeignKey(x => x.MediaId) - .IsRequired(); - builder.Property(x => x.MediaId) - .IsRequired(); - - builder.HasOne(x => x.PersonActorRoleType) - .WithMany() - .HasForeignKey(x => x.PersonActorRoleTypeId) - .IsRequired(); - builder.Property(x => x.PersonActorRoleTypeId) - .IsRequired(); - - builder.Property(x => x.RoleName) - .HasMaxLength(100) - .IsRequired(); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonActorRoleTypeConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonActorRoleTypeConfiguration.cs deleted file mode 100644 index bae2d0e..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonActorRoleTypeConfiguration.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Person; -using WatchIt.Database.Model.Seeding; - -namespace WatchIt.Database.Model.Configuration.Person; - -public class PersonActorRoleTypeConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Name) - .HasMaxLength(100) - .IsRequired(); - - // Data - builder.HasData(DataReader.Read()); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonConfiguration.cs deleted file mode 100644 index af5a767..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonConfiguration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace WatchIt.Database.Model.Configuration.Person; - -public class PersonConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Name) - .HasMaxLength(100) - .IsRequired(); - - builder.Property(x => x.FullName) - .HasMaxLength(200); - - builder.Property(x => x.Description) - .HasMaxLength(1000); - - builder.Property(x => x.BirthDate); - - builder.Property(x => x.DeathDate); - - builder.HasOne(x => x.Gender) - .WithMany() - .HasForeignKey(x => x.GenderId); - builder.Property(x => x.GenderId); - - builder.HasOne(x => x.PersonPhoto) - .WithOne(x => x.Person) - .HasForeignKey(e => e.PersonPhotoId); - builder.Property(x => x.PersonPhotoId); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonCreatorRoleConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonCreatorRoleConfiguration.cs deleted file mode 100644 index 1c0e2a6..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonCreatorRoleConfiguration.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Database.Model.Configuration.Person; - -public class PersonCreatorRoleConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.Person) - .WithMany(x => x.PersonCreatorRoles) - .HasForeignKey(x => x.PersonId) - .IsRequired(); - builder.Property(x => x.PersonId) - .IsRequired(); - - builder.HasOne(x => x.Media) - .WithMany(x => x.PersonCreatorRoles) - .HasForeignKey(x => x.MediaId) - .IsRequired(); - builder.Property(x => x.MediaId) - .IsRequired(); - - builder.HasOne(x => x.PersonCreatorRoleType) - .WithMany() - .HasForeignKey(x => x.PersonCreatorRoleTypeId) - .IsRequired(); - builder.Property(x => x.PersonCreatorRoleTypeId) - .IsRequired(); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonCreatorRoleTypeConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonCreatorRoleTypeConfiguration.cs deleted file mode 100644 index 6d456ae..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonCreatorRoleTypeConfiguration.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Person; -using WatchIt.Database.Model.Seeding; - -namespace WatchIt.Database.Model.Configuration.Person; - -public class PersonCreatorRoleTypeConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Name) - .HasMaxLength(100) - .IsRequired(); - - // Data - builder.HasData(DataReader.Read()); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonPhotoImageConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonPhotoImageConfiguration.cs deleted file mode 100644 index 2fe5f55..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Person/PersonPhotoImageConfiguration.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Person; - -namespace WatchIt.Database.Model.Configuration.Person; - -public class PersonPhotoImageConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.Property(x => x.Image) - .HasMaxLength(-1) - .IsRequired(); - - builder.Property(x => x.MimeType) - .HasMaxLength(50) - .IsRequired(); - - builder.Property(x => x.UploadDate) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaConfiguration.cs deleted file mode 100644 index 67eaf19..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaConfiguration.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Configuration.Rating; - -public class RatingMediaConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.Media) - .WithMany(x => x.RatingMedia) - .HasForeignKey(x => x.MediaId) - .IsRequired(); - builder.Property(x => x.MediaId) - .IsRequired(); - - builder.HasOne(x => x.Account) - .WithMany(x => x.RatingMedia) - .HasForeignKey(x => x.AccountId) - .IsRequired(); - builder.Property(x => x.AccountId) - .IsRequired(); - - builder.Property(x => x.Rating) - .IsRequired(); - - builder.Property(x => x.Date) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaSeriesEpisodeConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaSeriesEpisodeConfiguration.cs deleted file mode 100644 index c920705..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaSeriesEpisodeConfiguration.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Configuration.Rating; - -public class RatingMediaSeriesEpisodeConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.MediaSeriesEpisode) - .WithMany(x => x.RatingMediaSeriesEpisode) - .HasForeignKey(x => x.MediaSeriesEpisodeId) - .IsRequired(); - builder.Property(x => x.MediaSeriesEpisodeId) - .IsRequired(); - - builder.HasOne(x => x.Account) - .WithMany(x => x.RatingMediaSeriesEpisode) - .HasForeignKey(x => x.AccountId) - .IsRequired(); - builder.Property(x => x.AccountId) - .IsRequired(); - - builder.Property(x => x.Rating) - .IsRequired(); - - builder.Property(x => x.Date) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaSeriesSeasonConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaSeriesSeasonConfiguration.cs deleted file mode 100644 index 6da3070..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingMediaSeriesSeasonConfiguration.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Configuration.Rating; - -public class RatingMediaSeriesSeasonConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.MediaSeriesSeason) - .WithMany(x => x.RatingMediaSeriesSeason) - .HasForeignKey(x => x.MediaSeriesSeasonId) - .IsRequired(); - builder.Property(x => x.MediaSeriesSeasonId) - .IsRequired(); - - builder.HasOne(x => x.Account) - .WithMany(x => x.RatingMediaSeriesSeason) - .HasForeignKey(x => x.AccountId) - .IsRequired(); - builder.Property(x => x.AccountId) - .IsRequired(); - - builder.Property(x => x.Rating) - .IsRequired(); - - builder.Property(x => x.Date) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingPersonActorRoleConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingPersonActorRoleConfiguration.cs deleted file mode 100644 index 681f9f5..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingPersonActorRoleConfiguration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Configuration.Rating; - -public class RatingPersonActorRoleConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("RatingsPersonActorRole"); - - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.PersonActorRole) - .WithMany(x => x.RatingPersonActorRole) - .HasForeignKey(x => x.PersonActorRoleId) - .IsRequired(); - builder.Property(x => x.PersonActorRoleId) - .IsRequired(); - - builder.HasOne(x => x.Account) - .WithMany(x => x.RatingPersonActorRole) - .HasForeignKey(x => x.AccountId) - .IsRequired(); - builder.Property(x => x.AccountId) - .IsRequired(); - - builder.Property(x => x.Rating) - .IsRequired(); - - builder.Property(x => x.Date) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingPersonCreatorRoleConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingPersonCreatorRoleConfiguration.cs deleted file mode 100644 index 708c2d4..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Rating/RatingPersonCreatorRoleConfiguration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Configuration.Rating; - -public class RatingPersonCreatorRoleConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("RatingsPersonCreatorRole"); - - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.PersonCreatorRole) - .WithMany(x => x.RatingPersonCreatorRole) - .HasForeignKey(x => x.PersonCreatorRoleId) - .IsRequired(); - builder.Property(x => x.PersonCreatorRoleId) - .IsRequired(); - - builder.HasOne(x => x.Account) - .WithMany(x => x.RatingPersonCreatorRole) - .HasForeignKey(x => x.AccountId) - .IsRequired(); - builder.Property(x => x.AccountId) - .IsRequired(); - - builder.Property(x => x.Rating) - .IsRequired(); - - builder.Property(x => x.Date) - .IsRequired() - .HasDefaultValueSql("now()"); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/ViewCount/ViewCountMediaConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/ViewCount/ViewCountMediaConfiguration.cs deleted file mode 100644 index 9a81c42..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/ViewCount/ViewCountMediaConfiguration.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.ViewCount; - -namespace WatchIt.Database.Model.Configuration.ViewCount; - -public class ViewCountMediaConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("ViewCountsMedia"); - - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.Media) - .WithMany(x => x.ViewCountsMedia) - .HasForeignKey(x => x.MediaId) - .IsRequired(); - builder.Property(x => x.MediaId) - .IsRequired(); - - builder.Property(x => x.Date) - .IsRequired() - .HasDefaultValueSql("now()"); - - builder.Property(x => x.ViewCount) - .IsRequired() - .HasDefaultValue(0); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/ViewCount/ViewCountPersonConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/ViewCount/ViewCountPersonConfiguration.cs deleted file mode 100644 index cc7767c..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/ViewCount/ViewCountPersonConfiguration.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using WatchIt.Database.Model.ViewCount; - -namespace WatchIt.Database.Model.Configuration.ViewCount; - -public class ViewCountPersonConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("ViewCountsPerson"); - - builder.HasKey(x => x.Id); - builder.HasIndex(x => x.Id) - .IsUnique(); - builder.Property(x => x.Id) - .IsRequired(); - - builder.HasOne(x => x.Person) - .WithMany(x => x.ViewCountsPerson) - .HasForeignKey(x => x.PersonId) - .IsRequired(); - builder.Property(x => x.PersonId) - .IsRequired(); - - builder.Property(x => x.Date) - .IsRequired() - .HasDefaultValueSql("now()"); - - builder.Property(x => x.ViewCount) - .IsRequired() - .HasDefaultValue(0); - } -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/WatchIt.Database.Model.Configuration.csproj b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/WatchIt.Database.Model.Configuration.csproj deleted file mode 100644 index 96833d9..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/WatchIt.Database.Model.Configuration.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Country.json b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Country.json deleted file mode 100644 index dd0c82e..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Country.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "Id": 1, - "Name": "Afghanistan", - "IsHistorical": false - }, - { - "Id": 2, - "Name": "Albania", - "IsHistorical": false - } -] \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Gender.json b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Gender.json deleted file mode 100644 index b4605b0..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Gender.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "Id": 1, - "Name": "Male" - }, - { - "Id": 2, - "Name": "Female" - } -] \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Genre.json b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Genre.json deleted file mode 100644 index 4e0b2ae..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/Genre.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "Id": 1, - "Name": "Comedy" - }, - { - "Id": 2, - "Name": "Thriller" - }, - { - "Id": 3, - "Name": "Horror" - }, - { - "Id": 4, - "Name": "Action" - }, - { - "Id": 5, - "Name": "Drama" - } -] \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/PersonActorRoleType.json b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/PersonActorRoleType.json deleted file mode 100644 index be4fb31..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/PersonActorRoleType.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "Id": 1, - "Name": "Actor" - }, - { - "Id": 2, - "Name": "Supporting actor" - }, - { - "Id": 3, - "Name": "Voice actor" - } -] \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/PersonCreatorRoleType.json b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/PersonCreatorRoleType.json deleted file mode 100644 index c717fb0..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/Data/PersonCreatorRoleType.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "Id": 1, - "Name": "Director" - }, - { - "Id": 2, - "Name": "Producer" - }, - { - "Id": 3, - "Name": "Screenwriter" - } -] \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/DataReader.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/DataReader.cs deleted file mode 100644 index c71686b..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/DataReader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Diagnostics; -using System.Text.Json; - -namespace WatchIt.Database.Model.Seeding; - -public class DataReader -{ - #region METHODS - - public static IEnumerable Read() => Read(typeof(T).Name); - public static IEnumerable Read(string filename) - { - string jsonFile = $@"{AppContext.BaseDirectory}/Data/{filename}.json"; - string dataString = File.ReadAllText(jsonFile); - IEnumerable? data = JsonSerializer.Deserialize>(dataString); - if (data is null) - { - throw new JsonException(); - } - return data; - } - - #endregion -} diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/WatchIt.Database.Model.Seeding.csproj b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/WatchIt.Database.Model.Seeding.csproj deleted file mode 100644 index 12769b5..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Seeding/WatchIt.Database.Model.Seeding.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net8.0 - enable - enable - - - - - Always - - - Always - - - Always - - - Always - - - Always - - - - diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs deleted file mode 100644 index f7f5db4..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs +++ /dev/null @@ -1,44 +0,0 @@ -using WatchIt.Database.Model.Common; -using WatchIt.Database.Model.Media; -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Account; - -public class Account -{ - #region PROPERTIES - - public long Id { get; set; } - public required string Username { get; set; } - public required string Email { get; set; } - public string? Description { get; set; } - public short? GenderId { get; set; } - public Guid? ProfilePictureId { get; set; } - public Guid? BackgroundPictureId { get; set; } - public byte[] Password { get; set; } - public string LeftSalt { get; set; } - public string RightSalt { get; set; } - public bool IsAdmin { get; set; } = false; - public DateTime CreationDate { get; set; } - public DateTime LastActive { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Gender? Gender { get; set; } - public virtual AccountProfilePicture? ProfilePicture { get; set; } - public virtual MediaPhotoImage? BackgroundPicture { get; set; } - - public virtual IEnumerable RatingMedia { get; set; } = new List(); - public virtual IEnumerable RatingPersonActorRole { get; set; } = new List(); - public virtual IEnumerable RatingPersonCreatorRole { get; set; } = new List(); - public virtual IEnumerable RatingMediaSeriesSeason { get; set; } = new List(); - public virtual IEnumerable RatingMediaSeriesEpisode { get; set; } = new List(); - - public virtual IEnumerable AccountRefreshTokens { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountProfilePicture.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountProfilePicture.cs deleted file mode 100644 index 9020589..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountProfilePicture.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace WatchIt.Database.Model.Account; - -public class AccountProfilePicture -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required byte[] Image { get; set; } - public required string MimeType { get; set; } - public DateTime UploadDate { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Account Account { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountRefreshToken.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountRefreshToken.cs deleted file mode 100644 index d6da151..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountRefreshToken.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace WatchIt.Database.Model.Account; - -public class AccountRefreshToken -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required long AccountId { get; set; } - public required DateTime ExpirationDate { get; set; } - public required bool IsExtendable { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Account Account { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Country.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Country.cs deleted file mode 100644 index 3e05213..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Country.cs +++ /dev/null @@ -1,23 +0,0 @@ -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Common; - -public class Country -{ - #region PROPERTIES - - public short Id { get; set; } - public required string Name { get; set; } - public bool IsHistorical { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual IEnumerable MediaProductionCountries { get; set; } = new List(); - public virtual IEnumerable MediaProduction { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Gender.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Gender.cs deleted file mode 100644 index afcffe6..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Gender.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace WatchIt.Database.Model.Common; - -public class Gender -{ - #region PROPERTIES - - public short Id { get; set; } - public required string Name { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Genre.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Genre.cs deleted file mode 100644 index 5d3c63b..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Genre.cs +++ /dev/null @@ -1,23 +0,0 @@ -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Common; - -public class Genre -{ - #region PROPERTIES - - public short Id { get; set; } - public required string Name { get; set; } - public string? Description { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual IEnumerable MediaGenres { get; set; } = new List(); - public virtual IEnumerable Media { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/Media.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/Media.cs deleted file mode 100644 index 911d39e..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/Media.cs +++ /dev/null @@ -1,45 +0,0 @@ -using WatchIt.Database.Model.Common; -using WatchIt.Database.Model.Person; -using WatchIt.Database.Model.Rating; -using WatchIt.Database.Model.ViewCount; - -namespace WatchIt.Database.Model.Media; - -public class Media -{ - #region PROPERTIES - - public long Id { get; set; } - public required string Title { get; set; } - public string? OriginalTitle { get; set; } - public string? Description { get; set; } - public DateOnly? ReleaseDate { get; set; } - public short? Length { get; set; } - public Guid? MediaPosterImageId { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual MediaPosterImage? MediaPosterImage { get; set; } - - public virtual IEnumerable MediaPhotoImages { get; set; } = new List(); - - public virtual IEnumerable MediaGenres { get; set; } = new List(); - public virtual IEnumerable Genres { get; set; } = new List(); - - public virtual IEnumerable MediaProductionCountries { get; set; } = new List(); - public virtual IEnumerable ProductionCountries { get; set; } = new List(); - - public virtual IEnumerable PersonActorRoles { get; set; } = new List(); - - public virtual IEnumerable PersonCreatorRoles { get; set; } = new List(); - - public virtual IEnumerable RatingMedia { get; set; } = new List(); - - public virtual IEnumerable ViewCountsMedia { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaGenre.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaGenre.cs deleted file mode 100644 index a81e0c3..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaGenre.cs +++ /dev/null @@ -1,22 +0,0 @@ -using WatchIt.Database.Model.Common; - -namespace WatchIt.Database.Model.Media; - -public class MediaGenre -{ - #region PROPERTIES - - public required long MediaId { get; set; } - public required short GenreId { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Media Media { get; set; } = null!; - public virtual Genre Genre { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaMovie.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaMovie.cs deleted file mode 100644 index b90f0d9..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaMovie.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace WatchIt.Database.Model.Media; - -public class MediaMovie -{ - #region PROPERTIES - - public long Id { get; set; } - public decimal? Budget { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Media Media { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPhotoImage.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPhotoImage.cs deleted file mode 100644 index a94f8d7..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPhotoImage.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace WatchIt.Database.Model.Media; - -public class MediaPhotoImage -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required long MediaId { get; set; } - public required byte[] Image { get; set; } - public required string MimeType { get; set; } - public DateTime UploadDate { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Media Media { get; set; } = null!; - public virtual MediaPhotoImageBackground? MediaPhotoImageBackground { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPhotoImageBackground.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPhotoImageBackground.cs deleted file mode 100644 index 8d7cd83..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPhotoImageBackground.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace WatchIt.Database.Model.Media; - -public class MediaPhotoImageBackground -{ - #region PROPERTIES - - public required Guid Id { get; set; } - public required bool IsUniversalBackground { get; set; } - public required byte[] FirstGradientColor { get; set; } - public required byte[] SecondGradientColor { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual MediaPhotoImage MediaPhotoImage { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPosterImage.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPosterImage.cs deleted file mode 100644 index 046e838..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaPosterImage.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace WatchIt.Database.Model.Media; - -public class MediaPosterImage -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required byte[] Image { get; set; } - public required string MimeType { get; set; } - public DateTime UploadDate { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Media Media { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaProductionCountry.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaProductionCountry.cs deleted file mode 100644 index 715e338..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaProductionCountry.cs +++ /dev/null @@ -1,22 +0,0 @@ -using WatchIt.Database.Model.Common; - -namespace WatchIt.Database.Model.Media; - -public class MediaProductionCountry -{ - #region PROPERTIES - - public required long MediaId { get; set; } - public required short CountryId { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Media Media { get; set; } = null!; - public virtual Country Country { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeries.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeries.cs deleted file mode 100644 index 9f6eb8e..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeries.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace WatchIt.Database.Model.Media; - -public class MediaSeries -{ - #region PROPERTIES - - public required long Id { get; set; } - public bool HasEnded { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Media Media { get; set; } = null!; - public virtual IEnumerable MediaSeriesSeasons { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeriesEpisode.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeriesEpisode.cs deleted file mode 100644 index 6b87631..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeriesEpisode.cs +++ /dev/null @@ -1,25 +0,0 @@ -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Media; - -public class MediaSeriesEpisode -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required Guid MediaSeriesSeasonId { get; set; } - public required short Number { get; set; } - public string? Name { get; set; } - public bool IsSpecial { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual MediaSeriesSeason MediaSeriesSeason { get; set; } = null!; - public virtual IEnumerable RatingMediaSeriesEpisode { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeriesSeason.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeriesSeason.cs deleted file mode 100644 index 53e8a6f..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Media/MediaSeriesSeason.cs +++ /dev/null @@ -1,25 +0,0 @@ -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Media; - -public class MediaSeriesSeason -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required long MediaSeriesId { get; set; } - public required short Number { get; set; } - public string? Name { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual MediaSeries MediaSeries { get; set; } = null!; - public virtual IEnumerable MediaSeriesEpisodes { get; set; } = new List(); - public virtual IEnumerable RatingMediaSeriesSeason { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/Person.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/Person.cs deleted file mode 100644 index cccbe17..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/Person.cs +++ /dev/null @@ -1,32 +0,0 @@ -using WatchIt.Database.Model.Common; -using WatchIt.Database.Model.ViewCount; - -namespace WatchIt.Database.Model.Person; - -public class Person -{ - #region PROPERTIES - - public long Id { get; set; } - public required string Name { get; set; } - public string? FullName { get; set; } - public string? Description { get; set; } - public DateOnly? BirthDate { get; set; } - public DateOnly? DeathDate { get; set; } - public short? GenderId { get; set; } - public Guid? PersonPhotoId { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Gender? Gender { get; set; } - public virtual PersonPhotoImage? PersonPhoto { get; set; } - public virtual IEnumerable PersonActorRoles { get; set; } = new List(); - public virtual IEnumerable PersonCreatorRoles { get; set; } = new List(); - public virtual IEnumerable ViewCountsPerson { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonActorRole.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonActorRole.cs deleted file mode 100644 index 659236f..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonActorRole.cs +++ /dev/null @@ -1,28 +0,0 @@ -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Person; - -public class PersonActorRole -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required long PersonId { get; set; } - public required long MediaId { get; set; } - public required short PersonActorRoleTypeId { get; set; } - public required string RoleName { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Person Person { get; set; } = null!; - public virtual Media.Media Media { get; set; } = null!; - public virtual PersonActorRoleType PersonActorRoleType { get; set; } = null!; - - public virtual IEnumerable RatingPersonActorRole { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonActorRoleType.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonActorRoleType.cs deleted file mode 100644 index 2210a6f..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonActorRoleType.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace WatchIt.Database.Model.Person; - -public class PersonActorRoleType -{ - #region PROPERTIES - - public short Id { get; set; } - public required string Name { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonCreatorRole.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonCreatorRole.cs deleted file mode 100644 index 17a240d..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonCreatorRole.cs +++ /dev/null @@ -1,26 +0,0 @@ -using WatchIt.Database.Model.Rating; - -namespace WatchIt.Database.Model.Person; - -public class PersonCreatorRole -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required long PersonId { get; set; } - public required long MediaId { get; set; } - public required short PersonCreatorRoleTypeId { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Person Person { get; set; } = null!; - public virtual Media.Media Media { get; set; } = null!; - public virtual PersonCreatorRoleType PersonCreatorRoleType { get; set; } = null!; - public virtual IEnumerable RatingPersonCreatorRole { get; set; } = new List(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonCreatorRoleType.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonCreatorRoleType.cs deleted file mode 100644 index fb2ef60..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonCreatorRoleType.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace WatchIt.Database.Model.Person; - -public class PersonCreatorRoleType -{ - #region PROPERTIES - - public short Id { get; set; } - public required string Name { get; set; } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonPhotoImage.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonPhotoImage.cs deleted file mode 100644 index ce843f0..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Person/PersonPhotoImage.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace WatchIt.Database.Model.Person; - -public class PersonPhotoImage -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required byte[] Image { get; set; } - public required string MimeType { get; set; } - public DateTime UploadDate { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Person Person { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMedia.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMedia.cs deleted file mode 100644 index 9e7b49e..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMedia.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace WatchIt.Database.Model.Rating; - -public class RatingMedia -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required long MediaId { get; set; } - public required long AccountId { get; set; } - public required short Rating { get; set; } - public DateTime Date { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Model.Media.Media Media { get; set; } = null!; - public virtual Model.Account.Account Account { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMediaSeriesEpisode.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMediaSeriesEpisode.cs deleted file mode 100644 index 6f40392..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMediaSeriesEpisode.cs +++ /dev/null @@ -1,25 +0,0 @@ -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Rating; - -public class RatingMediaSeriesEpisode -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required Guid MediaSeriesEpisodeId { get; set; } - public required long AccountId { get; set; } - public required short Rating { get; set; } - public DateTime Date { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual MediaSeriesEpisode MediaSeriesEpisode { get; set; } = null!; - public virtual Account.Account Account { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMediaSeriesSeason.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMediaSeriesSeason.cs deleted file mode 100644 index dae110f..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingMediaSeriesSeason.cs +++ /dev/null @@ -1,25 +0,0 @@ -using WatchIt.Database.Model.Media; - -namespace WatchIt.Database.Model.Rating; - -public class RatingMediaSeriesSeason -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required Guid MediaSeriesSeasonId { get; set; } - public required long AccountId { get; set; } - public required short Rating { get; set; } - public DateTime Date { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual MediaSeriesSeason MediaSeriesSeason { get; set; } = null!; - public virtual Account.Account Account { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingPersonActorRole.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingPersonActorRole.cs deleted file mode 100644 index 4624faf..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingPersonActorRole.cs +++ /dev/null @@ -1,25 +0,0 @@ -using WatchIt.Database.Model.Person; - -namespace WatchIt.Database.Model.Rating; - -public class RatingPersonActorRole -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required Guid PersonActorRoleId { get; set; } - public required long AccountId { get; set; } - public required short Rating { get; set; } - public DateTime Date { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual PersonActorRole PersonActorRole { get; set; } = null!; - public virtual Account.Account Account { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingPersonCreatorRole.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingPersonCreatorRole.cs deleted file mode 100644 index c5b2399..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Rating/RatingPersonCreatorRole.cs +++ /dev/null @@ -1,25 +0,0 @@ -using WatchIt.Database.Model.Person; - -namespace WatchIt.Database.Model.Rating; - -public class RatingPersonCreatorRole -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required Guid PersonCreatorRoleId { get; set; } - public required long AccountId { get; set; } - public required short Rating { get; set; } - public DateTime Date { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual PersonCreatorRole PersonCreatorRole { get; set; } = null!; - public virtual Account.Account Account { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/ViewCount/ViewCountMedia.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/ViewCount/ViewCountMedia.cs deleted file mode 100644 index 2591d73..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/ViewCount/ViewCountMedia.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace WatchIt.Database.Model.ViewCount; - -public class ViewCountMedia -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required long MediaId { get; set; } - public DateOnly Date { get; set; } - public long ViewCount { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Media.Media Media { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/ViewCount/ViewCountPerson.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/ViewCount/ViewCountPerson.cs deleted file mode 100644 index 61ce17f..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/ViewCount/ViewCountPerson.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace WatchIt.Database.Model.ViewCount; - -public class ViewCountPerson -{ - #region PROPERTIES - - public Guid Id { get; set; } - public required long PersonId { get; set; } - public DateOnly Date { get; set; } - public long ViewCount { get; set; } - - #endregion - - - - #region NAVIGATION - - public virtual Person.Person Person { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/WatchIt.Database.Model.csproj b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/WatchIt.Database.Model.csproj deleted file mode 100644 index 3a63532..0000000 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/WatchIt.Database.Model.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net8.0 - enable - enable - - - diff --git a/WatchIt.Database/WatchIt.Database.csproj b/WatchIt.Database/WatchIt.Database.csproj new file mode 100644 index 0000000..3bc8bea --- /dev/null +++ b/WatchIt.Database/WatchIt.Database.csproj @@ -0,0 +1,24 @@ + + + + net9.0 + enable + enable + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/WatchIt.Database/WatchIt.Database/DatabaseContext.cs b/WatchIt.Database/WatchIt.Database/DatabaseContext.cs deleted file mode 100644 index d04598f..0000000 --- a/WatchIt.Database/WatchIt.Database/DatabaseContext.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Reflection; -using System.Security.Cryptography; -using System.Text; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.Extensions.Configuration; -using SimpleToolkit.Extensions; -using WatchIt.Database.Model.Account; -using WatchIt.Database.Model.Common; -using WatchIt.Database.Model.Configuration.Account; -using WatchIt.Database.Model.Media; -using WatchIt.Database.Model.Person; -using WatchIt.Database.Model.Rating; -using WatchIt.Database.Model.ViewCount; - -namespace WatchIt.Database; - -public class DatabaseContext : DbContext -{ - #region CONSTRUCTORS - - public DatabaseContext() - { - } - - public DatabaseContext(DbContextOptions options) : base(options) - { - } - - #endregion - - - - #region PROPERTIES - - // Common - public virtual DbSet Countries { get; set; } - public virtual DbSet Genres { get; set; } - public virtual DbSet Genders { get; set; } - - // Account - public virtual DbSet Accounts { get; set; } - public virtual DbSet AccountProfilePictures { get; set; } - public virtual DbSet AccountRefreshTokens { get; set; } - - // Media - public virtual DbSet Media { get; set; } - public virtual DbSet MediaMovies { get; set; } - public virtual DbSet MediaSeries { get; set; } - public virtual DbSet MediaSeriesSeasons { get; set; } - public virtual DbSet MediaSeriesEpisodes { get; set; } - public virtual DbSet MediaPosterImages { get; set; } - public virtual DbSet MediaPhotoImages { get; set; } - public virtual DbSet MediaPhotoImageBackgrounds { get; set; } - public virtual DbSet MediaGenres { get; set; } - public virtual DbSet MediaProductionCountries { get; set; } - - // Person - public virtual DbSet Persons { get; set; } - public virtual DbSet PersonPhotoImages { get; set; } - public virtual DbSet PersonActorRoles { get; set; } - public virtual DbSet PersonActorRoleTypes { get; set; } - public virtual DbSet PersonCreatorRoles { get; set; } - public virtual DbSet PersonCreatorRoleTypes { get; set; } - - // Rating - public virtual DbSet RatingsMedia { get; set; } - public virtual DbSet RatingsPersonActorRole { get; set; } - public virtual DbSet RatingsPersonCreatorRole { get; set; } - public virtual DbSet RatingsMediaSeriesSeason { get; set; } - public virtual DbSet RatingsMediaSeriesEpisode { get; set; } - - // ViewCount - public virtual DbSet ViewCountsPerson { get; set; } - public virtual DbSet ViewCountsMedia { get; set; } - - #endregion - - - - #region PROTECTED METHODS - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.UseNpgsql("name=Default"); - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetAssembly(typeof(AccountConfiguration))); - CreateRootUser(modelBuilder); - } - - protected void CreateRootUser(ModelBuilder modelBuilder) - { - IConfigurationSection configuration = this.GetService().GetSection("RootUser"); - - string leftSalt = StringExtensions.CreateRandom(20); - string rightSalt = StringExtensions.CreateRandom(20); - byte[] hash = SHA512.HashData(Encoding.UTF8.GetBytes($"{leftSalt}{configuration["Password"]}{rightSalt}")); - - modelBuilder.Entity().HasData(new Account - { - Id = 1, - Username = configuration["Username"]!, - Email = configuration["Email"]!, - Password = hash, - LeftSalt = leftSalt, - RightSalt = rightSalt, - IsAdmin = true, - }); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20240603125708_Initial.Designer.cs b/WatchIt.Database/WatchIt.Database/Migrations/20240603125708_Initial.Designer.cs deleted file mode 100644 index 644ec18..0000000 --- a/WatchIt.Database/WatchIt.Database/Migrations/20240603125708_Initial.Designer.cs +++ /dev/null @@ -1,1397 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using WatchIt.Database; - -#nullable disable - -namespace WatchIt.Database.Migrations -{ - [DbContext(typeof(DatabaseContext))] - [Migration("20240603125708_Initial")] - partial class Initial - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.5") - .HasAnnotation("Proxies:ChangeTracking", false) - .HasAnnotation("Proxies:CheckEquality", false) - .HasAnnotation("Proxies:LazyLoading", true) - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("BackgroundPictureId") - .HasColumnType("uuid"); - - b.Property("CreationDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Email") - .IsRequired() - .HasMaxLength(320) - .HasColumnType("character varying(320)"); - - b.Property("GenderId") - .HasColumnType("smallint"); - - b.Property("IsAdmin") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("LastActive") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("LeftSalt") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Password") - .IsRequired() - .HasMaxLength(1000) - .HasColumnType("bytea"); - - b.Property("ProfilePictureId") - .HasColumnType("uuid"); - - b.Property("RightSalt") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Username") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("BackgroundPictureId"); - - b.HasIndex("GenderId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("ProfilePictureId") - .IsUnique(); - - b.ToTable("Accounts"); - - b.HasData( - new - { - Id = 1L, - CreationDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - Email = "root@watch.it", - IsAdmin = true, - LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - LeftSalt = "Y&%]J>6Nc3&5~UUXnNxq", - Password = new byte[] { 68, 170, 8, 113, 134, 47, 98, 43, 96, 183, 126, 130, 204, 45, 4, 113, 81, 200, 244, 26, 54, 88, 161, 246, 84, 93, 159, 219, 12, 143, 128, 160, 198, 194, 47, 133, 216, 242, 158, 184, 43, 38, 134, 132, 175, 179, 42, 40, 0, 143, 111, 252, 156, 215, 17, 185, 12, 109, 119, 214, 211, 167, 32, 121 }, - RightSalt = "MV1jo~o3Oa^;NWb\\Q)t_", - Username = "root" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("AccountProfilePictures"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("ExpirationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("IsExtendable") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("AccountRefreshTokens"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("IsHistorical") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Countries"); - - b.HasData( - new - { - Id = (short)1, - IsHistorical = false, - Name = "Afghanistan" - }, - new - { - Id = (short)2, - IsHistorical = false, - Name = "Albania" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Gender", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Genders"); - - b.HasData( - new - { - Id = (short)1, - Name = "Male" - }, - new - { - Id = (short)2, - Name = "Female" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Genres"); - - b.HasData( - new - { - Id = (short)1, - Name = "Comedy" - }, - new - { - Id = (short)2, - Name = "Thriller" - }, - new - { - Id = (short)3, - Name = "Horror" - }, - new - { - Id = (short)4, - Name = "Action" - }, - new - { - Id = (short)5, - Name = "Drama" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Length") - .HasColumnType("smallint"); - - b.Property("MediaPosterImageId") - .HasColumnType("uuid"); - - b.Property("OriginalTitle") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.Property("ReleaseDate") - .HasColumnType("date"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaPosterImageId") - .IsUnique(); - - b.ToTable("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => - { - b.Property("GenreId") - .HasColumnType("smallint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.HasKey("GenreId", "MediaId"); - - b.HasIndex("MediaId"); - - b.ToTable("MediaGenres"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => - { - b.Property("Id") - .HasColumnType("bigint"); - - b.Property("Budget") - .HasColumnType("money"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaMovies"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("MediaPhotoImageBackgroundId") - .HasColumnType("uuid"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("MediaPhotoImageBackgroundId"); - - b.ToTable("MediaPhotoImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("FirstGradientColor") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("bytea"); - - b.Property("IsUniversalBackground") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SecondGradientColor") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("bytea"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaPhotoImageBackgrounds"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaPosterImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => - { - b.Property("CountryId") - .HasColumnType("smallint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.HasKey("CountryId", "MediaId"); - - b.HasIndex("MediaId"); - - b.ToTable("MediaProductionCountries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.Property("Id") - .HasColumnType("bigint"); - - b.Property("HasEnded") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaSeries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsSpecial") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("MediaSeriesSeasonId") - .HasColumnType("uuid"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Number") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesSeasonId"); - - b.ToTable("MediaSeriesEpisodes"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaSeriesId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Number") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesId"); - - b.ToTable("MediaSeriesSeasons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("BirthDate") - .HasColumnType("date"); - - b.Property("DeathDate") - .HasColumnType("date"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("FullName") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("GenderId") - .HasColumnType("smallint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("PersonPhotoId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("GenderId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonPhotoId") - .IsUnique(); - - b.ToTable("Persons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("PersonActorRoleTypeId") - .HasColumnType("smallint"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.Property("RoleName") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("PersonActorRoleTypeId"); - - b.HasIndex("PersonId"); - - b.ToTable("PersonActorRoles"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRoleType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonActorRoleTypes"); - - b.HasData( - new - { - Id = (short)1, - Name = "Actor" - }, - new - { - Id = (short)2, - Name = "Supporting actor" - }, - new - { - Id = (short)3, - Name = "Voice actor" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("PersonCreatorRoleTypeId") - .HasColumnType("smallint"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("PersonCreatorRoleTypeId"); - - b.HasIndex("PersonId"); - - b.ToTable("PersonCreatorRoles"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRoleType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonCreatorRoleTypes"); - - b.HasData( - new - { - Id = (short)1, - Name = "Director" - }, - new - { - Id = (short)2, - Name = "Producer" - }, - new - { - Id = (short)3, - Name = "Screenwriter" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonPhotoImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("RatingsMedia"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("MediaSeriesEpisodeId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesEpisodeId"); - - b.ToTable("RatingsMediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("MediaSeriesSeasonId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesSeasonId"); - - b.ToTable("RatingsMediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("PersonActorRoleId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonActorRoleId"); - - b.ToTable("RatingsPersonActorRole", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("PersonCreatorRoleId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonCreatorRoleId"); - - b.ToTable("RatingsPersonCreatorRole", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasDefaultValueSql("now()"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("ViewCount") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasDefaultValue(0L); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("ViewCountsMedia", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasDefaultValueSql("now()"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.Property("ViewCount") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasDefaultValue(0L); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonId"); - - b.ToTable("ViewCountsPerson", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "BackgroundPicture") - .WithMany() - .HasForeignKey("BackgroundPictureId"); - - b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") - .WithMany() - .HasForeignKey("GenderId"); - - b.HasOne("WatchIt.Database.Model.Account.AccountProfilePicture", "ProfilePicture") - .WithOne("Account") - .HasForeignKey("WatchIt.Database.Model.Account.Account", "ProfilePictureId"); - - b.Navigation("BackgroundPicture"); - - b.Navigation("Gender"); - - b.Navigation("ProfilePicture"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("AccountRefreshTokens") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPosterImage", "MediaPosterImage") - .WithOne("Media") - .HasForeignKey("WatchIt.Database.Model.Media.Media", "MediaPosterImageId"); - - b.Navigation("MediaPosterImage"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => - { - b.HasOne("WatchIt.Database.Model.Common.Genre", "Genre") - .WithMany("MediaGenres") - .HasForeignKey("GenreId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaGenres") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Genre"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithOne() - .HasForeignKey("WatchIt.Database.Model.Media.MediaMovie", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImageBackground", null) - .WithOne("MediaPhotoImage") - .HasForeignKey("WatchIt.Database.Model.Media.MediaPhotoImage", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaPhotoImages") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImageBackground", "MediaPhotoImageBackground") - .WithMany() - .HasForeignKey("MediaPhotoImageBackgroundId"); - - b.Navigation("Media"); - - b.Navigation("MediaPhotoImageBackground"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => - { - b.HasOne("WatchIt.Database.Model.Common.Country", "Country") - .WithMany("MediaProductionCountries") - .HasForeignKey("CountryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaProductionCountries") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Country"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithOne() - .HasForeignKey("WatchIt.Database.Model.Media.MediaSeries", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") - .WithMany("MediaSeriesEpisodes") - .HasForeignKey("MediaSeriesSeasonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaSeries", "MediaSeries") - .WithMany("MediaSeriesSeasons") - .HasForeignKey("MediaSeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaSeries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") - .WithMany() - .HasForeignKey("GenderId"); - - b.HasOne("WatchIt.Database.Model.Person.PersonPhotoImage", "PersonPhoto") - .WithOne("Person") - .HasForeignKey("WatchIt.Database.Model.Person.Person", "PersonPhotoId"); - - b.Navigation("Gender"); - - b.Navigation("PersonPhoto"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("PersonActorRoles") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonActorRoleType", "PersonActorRoleType") - .WithMany() - .HasForeignKey("PersonActorRoleTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("PersonActorRoles") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - - b.Navigation("Person"); - - b.Navigation("PersonActorRoleType"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("PersonCreatorRoles") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRoleType", "PersonCreatorRoleType") - .WithMany() - .HasForeignKey("PersonCreatorRoleTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("PersonCreatorRoles") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - - b.Navigation("Person"); - - b.Navigation("PersonCreatorRoleType"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMedia") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("RatingMedia") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMediaSeriesEpisode") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesEpisode", "MediaSeriesEpisode") - .WithMany("RatingMediaSeriesEpisode") - .HasForeignKey("MediaSeriesEpisodeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("MediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMediaSeriesSeason") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") - .WithMany("RatingMediaSeriesSeason") - .HasForeignKey("MediaSeriesSeasonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("MediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingPersonActorRole") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonActorRole", "PersonActorRole") - .WithMany("RatingPersonActorRole") - .HasForeignKey("PersonActorRoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("PersonActorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingPersonCreatorRole") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRole", "PersonCreatorRole") - .WithMany("RatingPersonCreatorRole") - .HasForeignKey("PersonCreatorRoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("PersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("ViewCountsMedia") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => - { - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("ViewCountsPerson") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Person"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.Navigation("AccountRefreshTokens"); - - b.Navigation("RatingMedia"); - - b.Navigation("RatingMediaSeriesEpisode"); - - b.Navigation("RatingMediaSeriesSeason"); - - b.Navigation("RatingPersonActorRole"); - - b.Navigation("RatingPersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => - { - b.Navigation("Account") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => - { - b.Navigation("MediaProductionCountries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => - { - b.Navigation("MediaGenres"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.Navigation("MediaGenres"); - - b.Navigation("MediaPhotoImages"); - - b.Navigation("MediaProductionCountries"); - - b.Navigation("PersonActorRoles"); - - b.Navigation("PersonCreatorRoles"); - - b.Navigation("RatingMedia"); - - b.Navigation("ViewCountsMedia"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => - { - b.Navigation("MediaPhotoImage") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => - { - b.Navigation("Media") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.Navigation("MediaSeriesSeasons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.Navigation("RatingMediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.Navigation("MediaSeriesEpisodes"); - - b.Navigation("RatingMediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.Navigation("PersonActorRoles"); - - b.Navigation("PersonCreatorRoles"); - - b.Navigation("ViewCountsPerson"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.Navigation("RatingPersonActorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.Navigation("RatingPersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => - { - b.Navigation("Person") - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20240603125708_Initial.cs b/WatchIt.Database/WatchIt.Database/Migrations/20240603125708_Initial.cs deleted file mode 100644 index cf3eeb5..0000000 --- a/WatchIt.Database/WatchIt.Database/Migrations/20240603125708_Initial.cs +++ /dev/null @@ -1,1111 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional - -namespace WatchIt.Database.Migrations -{ - /// - public partial class Initial : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AccountProfilePictures", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - Image = table.Column(type: "bytea", maxLength: -1, nullable: false), - MimeType = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - UploadDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("PK_AccountProfilePictures", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Countries", - columns: table => new - { - Id = table.Column(type: "smallint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - IsHistorical = table.Column(type: "boolean", nullable: false, defaultValue: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Countries", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Genders", - columns: table => new - { - Id = table.Column(type: "smallint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Genders", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Genres", - columns: table => new - { - Id = table.Column(type: "smallint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Genres", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "MediaPhotoImageBackgrounds", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - IsUniversalBackground = table.Column(type: "boolean", nullable: false, defaultValue: false), - FirstGradientColor = table.Column(type: "bytea", maxLength: 3, nullable: false), - SecondGradientColor = table.Column(type: "bytea", maxLength: 3, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_MediaPhotoImageBackgrounds", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "MediaPosterImages", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - Image = table.Column(type: "bytea", maxLength: -1, nullable: false), - MimeType = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - UploadDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("PK_MediaPosterImages", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "PersonActorRoleTypes", - columns: table => new - { - Id = table.Column(type: "smallint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_PersonActorRoleTypes", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "PersonCreatorRoleTypes", - columns: table => new - { - Id = table.Column(type: "smallint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_PersonCreatorRoleTypes", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "PersonPhotoImages", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - Image = table.Column(type: "bytea", maxLength: -1, nullable: false), - MimeType = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - UploadDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("PK_PersonPhotoImages", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Media", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Title = table.Column(type: "character varying(250)", maxLength: 250, nullable: false), - OriginalTitle = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), - Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - ReleaseDate = table.Column(type: "date", nullable: true), - Length = table.Column(type: "smallint", nullable: true), - MediaPosterImageId = table.Column(type: "uuid", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Media", x => x.Id); - table.ForeignKey( - name: "FK_Media_MediaPosterImages_MediaPosterImageId", - column: x => x.MediaPosterImageId, - principalTable: "MediaPosterImages", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "Persons", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - FullName = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - BirthDate = table.Column(type: "date", nullable: true), - DeathDate = table.Column(type: "date", nullable: true), - GenderId = table.Column(type: "smallint", nullable: true), - PersonPhotoId = table.Column(type: "uuid", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Persons", x => x.Id); - table.ForeignKey( - name: "FK_Persons_Genders_GenderId", - column: x => x.GenderId, - principalTable: "Genders", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_Persons_PersonPhotoImages_PersonPhotoId", - column: x => x.PersonPhotoId, - principalTable: "PersonPhotoImages", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "MediaGenres", - columns: table => new - { - MediaId = table.Column(type: "bigint", nullable: false), - GenreId = table.Column(type: "smallint", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_MediaGenres", x => new { x.GenreId, x.MediaId }); - table.ForeignKey( - name: "FK_MediaGenres_Genres_GenreId", - column: x => x.GenreId, - principalTable: "Genres", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_MediaGenres_Media_MediaId", - column: x => x.MediaId, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "MediaMovies", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false), - Budget = table.Column(type: "money", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_MediaMovies", x => x.Id); - table.ForeignKey( - name: "FK_MediaMovies_Media_Id", - column: x => x.Id, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "MediaPhotoImages", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - MediaId = table.Column(type: "bigint", nullable: false), - Image = table.Column(type: "bytea", maxLength: -1, nullable: false), - MimeType = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - UploadDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - MediaPhotoImageBackgroundId = table.Column(type: "uuid", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_MediaPhotoImages", x => x.Id); - table.ForeignKey( - name: "FK_MediaPhotoImages_MediaPhotoImageBackgrounds_Id", - column: x => x.Id, - principalTable: "MediaPhotoImageBackgrounds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_MediaPhotoImages_MediaPhotoImageBackgrounds_MediaPhotoImage~", - column: x => x.MediaPhotoImageBackgroundId, - principalTable: "MediaPhotoImageBackgrounds", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_MediaPhotoImages_Media_MediaId", - column: x => x.MediaId, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "MediaProductionCountries", - columns: table => new - { - MediaId = table.Column(type: "bigint", nullable: false), - CountryId = table.Column(type: "smallint", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_MediaProductionCountries", x => new { x.CountryId, x.MediaId }); - table.ForeignKey( - name: "FK_MediaProductionCountries_Countries_CountryId", - column: x => x.CountryId, - principalTable: "Countries", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_MediaProductionCountries_Media_MediaId", - column: x => x.MediaId, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "MediaSeries", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false), - HasEnded = table.Column(type: "boolean", nullable: false, defaultValue: false) - }, - constraints: table => - { - table.PrimaryKey("PK_MediaSeries", x => x.Id); - table.ForeignKey( - name: "FK_MediaSeries_Media_Id", - column: x => x.Id, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "ViewCountsMedia", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - MediaId = table.Column(type: "bigint", nullable: false), - Date = table.Column(type: "date", nullable: false, defaultValueSql: "now()"), - ViewCount = table.Column(type: "bigint", nullable: false, defaultValue: 0L) - }, - constraints: table => - { - table.PrimaryKey("PK_ViewCountsMedia", x => x.Id); - table.ForeignKey( - name: "FK_ViewCountsMedia_Media_MediaId", - column: x => x.MediaId, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "PersonActorRoles", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - PersonId = table.Column(type: "bigint", nullable: false), - MediaId = table.Column(type: "bigint", nullable: false), - PersonActorRoleTypeId = table.Column(type: "smallint", nullable: false), - RoleName = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_PersonActorRoles", x => x.Id); - table.ForeignKey( - name: "FK_PersonActorRoles_Media_MediaId", - column: x => x.MediaId, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_PersonActorRoles_PersonActorRoleTypes_PersonActorRoleTypeId", - column: x => x.PersonActorRoleTypeId, - principalTable: "PersonActorRoleTypes", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_PersonActorRoles_Persons_PersonId", - column: x => x.PersonId, - principalTable: "Persons", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "PersonCreatorRoles", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - PersonId = table.Column(type: "bigint", nullable: false), - MediaId = table.Column(type: "bigint", nullable: false), - PersonCreatorRoleTypeId = table.Column(type: "smallint", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_PersonCreatorRoles", x => x.Id); - table.ForeignKey( - name: "FK_PersonCreatorRoles_Media_MediaId", - column: x => x.MediaId, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_PersonCreatorRoles_PersonCreatorRoleTypes_PersonCreatorRole~", - column: x => x.PersonCreatorRoleTypeId, - principalTable: "PersonCreatorRoleTypes", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_PersonCreatorRoles_Persons_PersonId", - column: x => x.PersonId, - principalTable: "Persons", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "ViewCountsPerson", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - PersonId = table.Column(type: "bigint", nullable: false), - Date = table.Column(type: "date", nullable: false, defaultValueSql: "now()"), - ViewCount = table.Column(type: "bigint", nullable: false, defaultValue: 0L) - }, - constraints: table => - { - table.PrimaryKey("PK_ViewCountsPerson", x => x.Id); - table.ForeignKey( - name: "FK_ViewCountsPerson_Persons_PersonId", - column: x => x.PersonId, - principalTable: "Persons", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Accounts", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Username = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - Email = table.Column(type: "character varying(320)", maxLength: 320, nullable: false), - Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - GenderId = table.Column(type: "smallint", nullable: true), - ProfilePictureId = table.Column(type: "uuid", nullable: true), - BackgroundPictureId = table.Column(type: "uuid", nullable: true), - Password = table.Column(type: "bytea", maxLength: 1000, nullable: false), - LeftSalt = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - RightSalt = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - IsAdmin = table.Column(type: "boolean", nullable: false, defaultValue: false), - CreationDate = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - LastActive = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("PK_Accounts", x => x.Id); - table.ForeignKey( - name: "FK_Accounts_AccountProfilePictures_ProfilePictureId", - column: x => x.ProfilePictureId, - principalTable: "AccountProfilePictures", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_Accounts_Genders_GenderId", - column: x => x.GenderId, - principalTable: "Genders", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_Accounts_MediaPhotoImages_BackgroundPictureId", - column: x => x.BackgroundPictureId, - principalTable: "MediaPhotoImages", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "MediaSeriesSeasons", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - MediaSeriesId = table.Column(type: "bigint", nullable: false), - Number = table.Column(type: "smallint", nullable: false), - Name = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_MediaSeriesSeasons", x => x.Id); - table.ForeignKey( - name: "FK_MediaSeriesSeasons_MediaSeries_MediaSeriesId", - column: x => x.MediaSeriesId, - principalTable: "MediaSeries", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AccountRefreshTokens", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - AccountId = table.Column(type: "bigint", nullable: false), - ExpirationDate = table.Column(type: "timestamp with time zone", nullable: false), - IsExtendable = table.Column(type: "boolean", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountRefreshTokens", x => x.Id); - table.ForeignKey( - name: "FK_AccountRefreshTokens_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "RatingsMedia", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - MediaId = table.Column(type: "bigint", nullable: false), - AccountId = table.Column(type: "bigint", nullable: false), - Rating = table.Column(type: "smallint", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_RatingsMedia", x => x.Id); - table.ForeignKey( - name: "FK_RatingsMedia_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_RatingsMedia_Media_MediaId", - column: x => x.MediaId, - principalTable: "Media", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "RatingsPersonActorRole", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - PersonActorRoleId = table.Column(type: "uuid", nullable: false), - AccountId = table.Column(type: "bigint", nullable: false), - Rating = table.Column(type: "smallint", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_RatingsPersonActorRole", x => x.Id); - table.ForeignKey( - name: "FK_RatingsPersonActorRole_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_RatingsPersonActorRole_PersonActorRoles_PersonActorRoleId", - column: x => x.PersonActorRoleId, - principalTable: "PersonActorRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "RatingsPersonCreatorRole", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - PersonCreatorRoleId = table.Column(type: "uuid", nullable: false), - AccountId = table.Column(type: "bigint", nullable: false), - Rating = table.Column(type: "smallint", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_RatingsPersonCreatorRole", x => x.Id); - table.ForeignKey( - name: "FK_RatingsPersonCreatorRole_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_RatingsPersonCreatorRole_PersonCreatorRoles_PersonCreatorRo~", - column: x => x.PersonCreatorRoleId, - principalTable: "PersonCreatorRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "MediaSeriesEpisodes", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - MediaSeriesSeasonId = table.Column(type: "uuid", nullable: false), - Number = table.Column(type: "smallint", nullable: false), - Name = table.Column(type: "text", nullable: true), - IsSpecial = table.Column(type: "boolean", nullable: false, defaultValue: false) - }, - constraints: table => - { - table.PrimaryKey("PK_MediaSeriesEpisodes", x => x.Id); - table.ForeignKey( - name: "FK_MediaSeriesEpisodes_MediaSeriesSeasons_MediaSeriesSeasonId", - column: x => x.MediaSeriesSeasonId, - principalTable: "MediaSeriesSeasons", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "RatingsMediaSeriesSeason", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - MediaSeriesSeasonId = table.Column(type: "uuid", nullable: false), - AccountId = table.Column(type: "bigint", nullable: false), - Rating = table.Column(type: "smallint", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_RatingsMediaSeriesSeason", x => x.Id); - table.ForeignKey( - name: "FK_RatingsMediaSeriesSeason_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_RatingsMediaSeriesSeason_MediaSeriesSeasons_MediaSeriesSeas~", - column: x => x.MediaSeriesSeasonId, - principalTable: "MediaSeriesSeasons", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "RatingsMediaSeriesEpisode", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - MediaSeriesEpisodeId = table.Column(type: "uuid", nullable: false), - AccountId = table.Column(type: "bigint", nullable: false), - Rating = table.Column(type: "smallint", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_RatingsMediaSeriesEpisode", x => x.Id); - table.ForeignKey( - name: "FK_RatingsMediaSeriesEpisode_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_RatingsMediaSeriesEpisode_MediaSeriesEpisodes_MediaSeriesEp~", - column: x => x.MediaSeriesEpisodeId, - principalTable: "MediaSeriesEpisodes", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.InsertData( - table: "Accounts", - columns: new[] { "Id", "BackgroundPictureId", "Description", "Email", "GenderId", "IsAdmin", "LeftSalt", "Password", "ProfilePictureId", "RightSalt", "Username" }, - values: new object[] { 1L, null, null, "root@watch.it", null, true, "Y&%]J>6Nc3&5~UUXnNxq", new byte[] { 68, 170, 8, 113, 134, 47, 98, 43, 96, 183, 126, 130, 204, 45, 4, 113, 81, 200, 244, 26, 54, 88, 161, 246, 84, 93, 159, 219, 12, 143, 128, 160, 198, 194, 47, 133, 216, 242, 158, 184, 43, 38, 134, 132, 175, 179, 42, 40, 0, 143, 111, 252, 156, 215, 17, 185, 12, 109, 119, 214, 211, 167, 32, 121 }, null, "MV1jo~o3Oa^;NWb\\Q)t_", "root" }); - - migrationBuilder.InsertData( - table: "Countries", - columns: new[] { "Id", "Name" }, - values: new object[,] - { - { (short)1, "Afghanistan" }, - { (short)2, "Albania" } - }); - - migrationBuilder.InsertData( - table: "Genders", - columns: new[] { "Id", "Name" }, - values: new object[,] - { - { (short)1, "Male" }, - { (short)2, "Female" } - }); - - migrationBuilder.InsertData( - table: "Genres", - columns: new[] { "Id", "Description", "Name" }, - values: new object[,] - { - { (short)1, null, "Comedy" }, - { (short)2, null, "Thriller" }, - { (short)3, null, "Horror" }, - { (short)4, null, "Action" }, - { (short)5, null, "Drama" } - }); - - migrationBuilder.InsertData( - table: "PersonActorRoleTypes", - columns: new[] { "Id", "Name" }, - values: new object[,] - { - { (short)1, "Actor" }, - { (short)2, "Supporting actor" }, - { (short)3, "Voice actor" } - }); - - migrationBuilder.InsertData( - table: "PersonCreatorRoleTypes", - columns: new[] { "Id", "Name" }, - values: new object[,] - { - { (short)1, "Director" }, - { (short)2, "Producer" }, - { (short)3, "Screenwriter" } - }); - - migrationBuilder.CreateIndex( - name: "IX_AccountProfilePictures_Id", - table: "AccountProfilePictures", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_AccountRefreshTokens_AccountId", - table: "AccountRefreshTokens", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountRefreshTokens_Id", - table: "AccountRefreshTokens", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Accounts_BackgroundPictureId", - table: "Accounts", - column: "BackgroundPictureId"); - - migrationBuilder.CreateIndex( - name: "IX_Accounts_GenderId", - table: "Accounts", - column: "GenderId"); - - migrationBuilder.CreateIndex( - name: "IX_Accounts_Id", - table: "Accounts", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Accounts_ProfilePictureId", - table: "Accounts", - column: "ProfilePictureId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Countries_Id", - table: "Countries", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Genders_Id", - table: "Genders", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Genres_Id", - table: "Genres", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Media_Id", - table: "Media", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Media_MediaPosterImageId", - table: "Media", - column: "MediaPosterImageId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_MediaGenres_MediaId", - table: "MediaGenres", - column: "MediaId"); - - migrationBuilder.CreateIndex( - name: "IX_MediaMovies_Id", - table: "MediaMovies", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_MediaPhotoImageBackgrounds_Id", - table: "MediaPhotoImageBackgrounds", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_MediaPhotoImages_Id", - table: "MediaPhotoImages", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_MediaPhotoImages_MediaId", - table: "MediaPhotoImages", - column: "MediaId"); - - migrationBuilder.CreateIndex( - name: "IX_MediaPhotoImages_MediaPhotoImageBackgroundId", - table: "MediaPhotoImages", - column: "MediaPhotoImageBackgroundId"); - - migrationBuilder.CreateIndex( - name: "IX_MediaPosterImages_Id", - table: "MediaPosterImages", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_MediaProductionCountries_MediaId", - table: "MediaProductionCountries", - column: "MediaId"); - - migrationBuilder.CreateIndex( - name: "IX_MediaSeries_Id", - table: "MediaSeries", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_MediaSeriesEpisodes_Id", - table: "MediaSeriesEpisodes", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_MediaSeriesEpisodes_MediaSeriesSeasonId", - table: "MediaSeriesEpisodes", - column: "MediaSeriesSeasonId"); - - migrationBuilder.CreateIndex( - name: "IX_MediaSeriesSeasons_Id", - table: "MediaSeriesSeasons", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_MediaSeriesSeasons_MediaSeriesId", - table: "MediaSeriesSeasons", - column: "MediaSeriesId"); - - migrationBuilder.CreateIndex( - name: "IX_PersonActorRoles_Id", - table: "PersonActorRoles", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_PersonActorRoles_MediaId", - table: "PersonActorRoles", - column: "MediaId"); - - migrationBuilder.CreateIndex( - name: "IX_PersonActorRoles_PersonActorRoleTypeId", - table: "PersonActorRoles", - column: "PersonActorRoleTypeId"); - - migrationBuilder.CreateIndex( - name: "IX_PersonActorRoles_PersonId", - table: "PersonActorRoles", - column: "PersonId"); - - migrationBuilder.CreateIndex( - name: "IX_PersonActorRoleTypes_Id", - table: "PersonActorRoleTypes", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_PersonCreatorRoles_Id", - table: "PersonCreatorRoles", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_PersonCreatorRoles_MediaId", - table: "PersonCreatorRoles", - column: "MediaId"); - - migrationBuilder.CreateIndex( - name: "IX_PersonCreatorRoles_PersonCreatorRoleTypeId", - table: "PersonCreatorRoles", - column: "PersonCreatorRoleTypeId"); - - migrationBuilder.CreateIndex( - name: "IX_PersonCreatorRoles_PersonId", - table: "PersonCreatorRoles", - column: "PersonId"); - - migrationBuilder.CreateIndex( - name: "IX_PersonCreatorRoleTypes_Id", - table: "PersonCreatorRoleTypes", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_PersonPhotoImages_Id", - table: "PersonPhotoImages", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Persons_GenderId", - table: "Persons", - column: "GenderId"); - - migrationBuilder.CreateIndex( - name: "IX_Persons_Id", - table: "Persons", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Persons_PersonPhotoId", - table: "Persons", - column: "PersonPhotoId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMedia_AccountId", - table: "RatingsMedia", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMedia_Id", - table: "RatingsMedia", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMedia_MediaId", - table: "RatingsMedia", - column: "MediaId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMediaSeriesEpisode_AccountId", - table: "RatingsMediaSeriesEpisode", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMediaSeriesEpisode_Id", - table: "RatingsMediaSeriesEpisode", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMediaSeriesEpisode_MediaSeriesEpisodeId", - table: "RatingsMediaSeriesEpisode", - column: "MediaSeriesEpisodeId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMediaSeriesSeason_AccountId", - table: "RatingsMediaSeriesSeason", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMediaSeriesSeason_Id", - table: "RatingsMediaSeriesSeason", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_RatingsMediaSeriesSeason_MediaSeriesSeasonId", - table: "RatingsMediaSeriesSeason", - column: "MediaSeriesSeasonId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsPersonActorRole_AccountId", - table: "RatingsPersonActorRole", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsPersonActorRole_Id", - table: "RatingsPersonActorRole", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_RatingsPersonActorRole_PersonActorRoleId", - table: "RatingsPersonActorRole", - column: "PersonActorRoleId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsPersonCreatorRole_AccountId", - table: "RatingsPersonCreatorRole", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_RatingsPersonCreatorRole_Id", - table: "RatingsPersonCreatorRole", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_RatingsPersonCreatorRole_PersonCreatorRoleId", - table: "RatingsPersonCreatorRole", - column: "PersonCreatorRoleId"); - - migrationBuilder.CreateIndex( - name: "IX_ViewCountsMedia_Id", - table: "ViewCountsMedia", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_ViewCountsMedia_MediaId", - table: "ViewCountsMedia", - column: "MediaId"); - - migrationBuilder.CreateIndex( - name: "IX_ViewCountsPerson_Id", - table: "ViewCountsPerson", - column: "Id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_ViewCountsPerson_PersonId", - table: "ViewCountsPerson", - column: "PersonId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AccountRefreshTokens"); - - migrationBuilder.DropTable( - name: "MediaGenres"); - - migrationBuilder.DropTable( - name: "MediaMovies"); - - migrationBuilder.DropTable( - name: "MediaProductionCountries"); - - migrationBuilder.DropTable( - name: "RatingsMedia"); - - migrationBuilder.DropTable( - name: "RatingsMediaSeriesEpisode"); - - migrationBuilder.DropTable( - name: "RatingsMediaSeriesSeason"); - - migrationBuilder.DropTable( - name: "RatingsPersonActorRole"); - - migrationBuilder.DropTable( - name: "RatingsPersonCreatorRole"); - - migrationBuilder.DropTable( - name: "ViewCountsMedia"); - - migrationBuilder.DropTable( - name: "ViewCountsPerson"); - - migrationBuilder.DropTable( - name: "Genres"); - - migrationBuilder.DropTable( - name: "Countries"); - - migrationBuilder.DropTable( - name: "MediaSeriesEpisodes"); - - migrationBuilder.DropTable( - name: "PersonActorRoles"); - - migrationBuilder.DropTable( - name: "Accounts"); - - migrationBuilder.DropTable( - name: "PersonCreatorRoles"); - - migrationBuilder.DropTable( - name: "MediaSeriesSeasons"); - - migrationBuilder.DropTable( - name: "PersonActorRoleTypes"); - - migrationBuilder.DropTable( - name: "AccountProfilePictures"); - - migrationBuilder.DropTable( - name: "MediaPhotoImages"); - - migrationBuilder.DropTable( - name: "PersonCreatorRoleTypes"); - - migrationBuilder.DropTable( - name: "Persons"); - - migrationBuilder.DropTable( - name: "MediaSeries"); - - migrationBuilder.DropTable( - name: "MediaPhotoImageBackgrounds"); - - migrationBuilder.DropTable( - name: "Genders"); - - migrationBuilder.DropTable( - name: "PersonPhotoImages"); - - migrationBuilder.DropTable( - name: "Media"); - - migrationBuilder.DropTable( - name: "MediaPosterImages"); - } - } -} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20240603131015_Fix.Designer.cs b/WatchIt.Database/WatchIt.Database/Migrations/20240603131015_Fix.Designer.cs deleted file mode 100644 index 8cbfeef..0000000 --- a/WatchIt.Database/WatchIt.Database/Migrations/20240603131015_Fix.Designer.cs +++ /dev/null @@ -1,1390 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using WatchIt.Database; - -#nullable disable - -namespace WatchIt.Database.Migrations -{ - [DbContext(typeof(DatabaseContext))] - [Migration("20240603131015_Fix")] - partial class Fix - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.5") - .HasAnnotation("Proxies:ChangeTracking", false) - .HasAnnotation("Proxies:CheckEquality", false) - .HasAnnotation("Proxies:LazyLoading", true) - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("BackgroundPictureId") - .HasColumnType("uuid"); - - b.Property("CreationDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Email") - .IsRequired() - .HasMaxLength(320) - .HasColumnType("character varying(320)"); - - b.Property("GenderId") - .HasColumnType("smallint"); - - b.Property("IsAdmin") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("LastActive") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("LeftSalt") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Password") - .IsRequired() - .HasMaxLength(1000) - .HasColumnType("bytea"); - - b.Property("ProfilePictureId") - .HasColumnType("uuid"); - - b.Property("RightSalt") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Username") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("BackgroundPictureId"); - - b.HasIndex("GenderId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("ProfilePictureId") - .IsUnique(); - - b.ToTable("Accounts"); - - b.HasData( - new - { - Id = 1L, - CreationDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - Email = "root@watch.it", - IsAdmin = true, - LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - LeftSalt = "@(0PF{b6Ot?HO*:yF5`L", - Password = new byte[] { 254, 122, 19, 59, 187, 100, 174, 87, 55, 108, 14, 10, 123, 186, 129, 243, 145, 136, 152, 220, 72, 170, 196, 93, 54, 88, 192, 115, 128, 76, 133, 9, 181, 99, 181, 8, 102, 123, 197, 251, 85, 167, 146, 28, 116, 249, 118, 87, 146, 8, 194, 238, 127, 19, 33, 28, 14, 222, 218, 170, 74, 40, 223, 232 }, - RightSalt = "=pt,3T0#CfC1[}Zfp{/u", - Username = "root" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("AccountProfilePictures"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("ExpirationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("IsExtendable") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("AccountRefreshTokens"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("IsHistorical") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Countries"); - - b.HasData( - new - { - Id = (short)1, - IsHistorical = false, - Name = "Afghanistan" - }, - new - { - Id = (short)2, - IsHistorical = false, - Name = "Albania" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Gender", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Genders"); - - b.HasData( - new - { - Id = (short)1, - Name = "Male" - }, - new - { - Id = (short)2, - Name = "Female" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Genres"); - - b.HasData( - new - { - Id = (short)1, - Name = "Comedy" - }, - new - { - Id = (short)2, - Name = "Thriller" - }, - new - { - Id = (short)3, - Name = "Horror" - }, - new - { - Id = (short)4, - Name = "Action" - }, - new - { - Id = (short)5, - Name = "Drama" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Length") - .HasColumnType("smallint"); - - b.Property("MediaPosterImageId") - .HasColumnType("uuid"); - - b.Property("OriginalTitle") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.Property("ReleaseDate") - .HasColumnType("date"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaPosterImageId") - .IsUnique(); - - b.ToTable("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => - { - b.Property("GenreId") - .HasColumnType("smallint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.HasKey("GenreId", "MediaId"); - - b.HasIndex("MediaId"); - - b.ToTable("MediaGenres"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => - { - b.Property("Id") - .HasColumnType("bigint"); - - b.Property("Budget") - .HasColumnType("money"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaMovies"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("MediaPhotoImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("FirstGradientColor") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("bytea"); - - b.Property("IsUniversalBackground") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SecondGradientColor") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("bytea"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaPhotoImageBackgrounds"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaPosterImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => - { - b.Property("CountryId") - .HasColumnType("smallint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.HasKey("CountryId", "MediaId"); - - b.HasIndex("MediaId"); - - b.ToTable("MediaProductionCountries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.Property("Id") - .HasColumnType("bigint"); - - b.Property("HasEnded") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaSeries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsSpecial") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("MediaSeriesSeasonId") - .HasColumnType("uuid"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Number") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesSeasonId"); - - b.ToTable("MediaSeriesEpisodes"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaSeriesId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Number") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesId"); - - b.ToTable("MediaSeriesSeasons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("BirthDate") - .HasColumnType("date"); - - b.Property("DeathDate") - .HasColumnType("date"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("FullName") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("GenderId") - .HasColumnType("smallint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("PersonPhotoId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("GenderId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonPhotoId") - .IsUnique(); - - b.ToTable("Persons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("PersonActorRoleTypeId") - .HasColumnType("smallint"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.Property("RoleName") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("PersonActorRoleTypeId"); - - b.HasIndex("PersonId"); - - b.ToTable("PersonActorRoles"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRoleType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonActorRoleTypes"); - - b.HasData( - new - { - Id = (short)1, - Name = "Actor" - }, - new - { - Id = (short)2, - Name = "Supporting actor" - }, - new - { - Id = (short)3, - Name = "Voice actor" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("PersonCreatorRoleTypeId") - .HasColumnType("smallint"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("PersonCreatorRoleTypeId"); - - b.HasIndex("PersonId"); - - b.ToTable("PersonCreatorRoles"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRoleType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonCreatorRoleTypes"); - - b.HasData( - new - { - Id = (short)1, - Name = "Director" - }, - new - { - Id = (short)2, - Name = "Producer" - }, - new - { - Id = (short)3, - Name = "Screenwriter" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonPhotoImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("RatingsMedia"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("MediaSeriesEpisodeId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesEpisodeId"); - - b.ToTable("RatingsMediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("MediaSeriesSeasonId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesSeasonId"); - - b.ToTable("RatingsMediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("PersonActorRoleId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonActorRoleId"); - - b.ToTable("RatingsPersonActorRole", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("PersonCreatorRoleId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonCreatorRoleId"); - - b.ToTable("RatingsPersonCreatorRole", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasDefaultValueSql("now()"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("ViewCount") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasDefaultValue(0L); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("ViewCountsMedia", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasDefaultValueSql("now()"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.Property("ViewCount") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasDefaultValue(0L); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonId"); - - b.ToTable("ViewCountsPerson", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "BackgroundPicture") - .WithMany() - .HasForeignKey("BackgroundPictureId"); - - b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") - .WithMany() - .HasForeignKey("GenderId"); - - b.HasOne("WatchIt.Database.Model.Account.AccountProfilePicture", "ProfilePicture") - .WithOne("Account") - .HasForeignKey("WatchIt.Database.Model.Account.Account", "ProfilePictureId"); - - b.Navigation("BackgroundPicture"); - - b.Navigation("Gender"); - - b.Navigation("ProfilePicture"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("AccountRefreshTokens") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPosterImage", "MediaPosterImage") - .WithOne("Media") - .HasForeignKey("WatchIt.Database.Model.Media.Media", "MediaPosterImageId"); - - b.Navigation("MediaPosterImage"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => - { - b.HasOne("WatchIt.Database.Model.Common.Genre", "Genre") - .WithMany("MediaGenres") - .HasForeignKey("GenreId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaGenres") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Genre"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithOne() - .HasForeignKey("WatchIt.Database.Model.Media.MediaMovie", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaPhotoImages") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "MediaPhotoImage") - .WithOne("MediaPhotoImageBackground") - .HasForeignKey("WatchIt.Database.Model.Media.MediaPhotoImageBackground", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaPhotoImage"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => - { - b.HasOne("WatchIt.Database.Model.Common.Country", "Country") - .WithMany("MediaProductionCountries") - .HasForeignKey("CountryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaProductionCountries") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Country"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithOne() - .HasForeignKey("WatchIt.Database.Model.Media.MediaSeries", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") - .WithMany("MediaSeriesEpisodes") - .HasForeignKey("MediaSeriesSeasonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaSeries", "MediaSeries") - .WithMany("MediaSeriesSeasons") - .HasForeignKey("MediaSeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaSeries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") - .WithMany() - .HasForeignKey("GenderId"); - - b.HasOne("WatchIt.Database.Model.Person.PersonPhotoImage", "PersonPhoto") - .WithOne("Person") - .HasForeignKey("WatchIt.Database.Model.Person.Person", "PersonPhotoId"); - - b.Navigation("Gender"); - - b.Navigation("PersonPhoto"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("PersonActorRoles") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonActorRoleType", "PersonActorRoleType") - .WithMany() - .HasForeignKey("PersonActorRoleTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("PersonActorRoles") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - - b.Navigation("Person"); - - b.Navigation("PersonActorRoleType"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("PersonCreatorRoles") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRoleType", "PersonCreatorRoleType") - .WithMany() - .HasForeignKey("PersonCreatorRoleTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("PersonCreatorRoles") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - - b.Navigation("Person"); - - b.Navigation("PersonCreatorRoleType"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMedia") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("RatingMedia") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMediaSeriesEpisode") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesEpisode", "MediaSeriesEpisode") - .WithMany("RatingMediaSeriesEpisode") - .HasForeignKey("MediaSeriesEpisodeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("MediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMediaSeriesSeason") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") - .WithMany("RatingMediaSeriesSeason") - .HasForeignKey("MediaSeriesSeasonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("MediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingPersonActorRole") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonActorRole", "PersonActorRole") - .WithMany("RatingPersonActorRole") - .HasForeignKey("PersonActorRoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("PersonActorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingPersonCreatorRole") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRole", "PersonCreatorRole") - .WithMany("RatingPersonCreatorRole") - .HasForeignKey("PersonCreatorRoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("PersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("ViewCountsMedia") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => - { - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("ViewCountsPerson") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Person"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.Navigation("AccountRefreshTokens"); - - b.Navigation("RatingMedia"); - - b.Navigation("RatingMediaSeriesEpisode"); - - b.Navigation("RatingMediaSeriesSeason"); - - b.Navigation("RatingPersonActorRole"); - - b.Navigation("RatingPersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => - { - b.Navigation("Account") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => - { - b.Navigation("MediaProductionCountries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => - { - b.Navigation("MediaGenres"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.Navigation("MediaGenres"); - - b.Navigation("MediaPhotoImages"); - - b.Navigation("MediaProductionCountries"); - - b.Navigation("PersonActorRoles"); - - b.Navigation("PersonCreatorRoles"); - - b.Navigation("RatingMedia"); - - b.Navigation("ViewCountsMedia"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.Navigation("MediaPhotoImageBackground"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => - { - b.Navigation("Media") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.Navigation("MediaSeriesSeasons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.Navigation("RatingMediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.Navigation("MediaSeriesEpisodes"); - - b.Navigation("RatingMediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.Navigation("PersonActorRoles"); - - b.Navigation("PersonCreatorRoles"); - - b.Navigation("ViewCountsPerson"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.Navigation("RatingPersonActorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.Navigation("RatingPersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => - { - b.Navigation("Person") - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20240603131015_Fix.cs b/WatchIt.Database/WatchIt.Database/Migrations/20240603131015_Fix.cs deleted file mode 100644 index 8161c07..0000000 --- a/WatchIt.Database/WatchIt.Database/Migrations/20240603131015_Fix.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace WatchIt.Database.Migrations -{ - /// - public partial class Fix : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_MediaPhotoImages_MediaPhotoImageBackgrounds_Id", - table: "MediaPhotoImages"); - - migrationBuilder.DropForeignKey( - name: "FK_MediaPhotoImages_MediaPhotoImageBackgrounds_MediaPhotoImage~", - table: "MediaPhotoImages"); - - migrationBuilder.DropIndex( - name: "IX_MediaPhotoImages_MediaPhotoImageBackgroundId", - table: "MediaPhotoImages"); - - migrationBuilder.DropColumn( - name: "MediaPhotoImageBackgroundId", - table: "MediaPhotoImages"); - - migrationBuilder.UpdateData( - table: "Accounts", - keyColumn: "Id", - keyValue: 1L, - columns: new[] { "LeftSalt", "Password", "RightSalt" }, - values: new object[] { "@(0PF{b6Ot?HO*:yF5`L", new byte[] { 254, 122, 19, 59, 187, 100, 174, 87, 55, 108, 14, 10, 123, 186, 129, 243, 145, 136, 152, 220, 72, 170, 196, 93, 54, 88, 192, 115, 128, 76, 133, 9, 181, 99, 181, 8, 102, 123, 197, 251, 85, 167, 146, 28, 116, 249, 118, 87, 146, 8, 194, 238, 127, 19, 33, 28, 14, 222, 218, 170, 74, 40, 223, 232 }, "=pt,3T0#CfC1[}Zfp{/u" }); - - migrationBuilder.AddForeignKey( - name: "FK_MediaPhotoImageBackgrounds_MediaPhotoImages_Id", - table: "MediaPhotoImageBackgrounds", - column: "Id", - principalTable: "MediaPhotoImages", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_MediaPhotoImageBackgrounds_MediaPhotoImages_Id", - table: "MediaPhotoImageBackgrounds"); - - migrationBuilder.AddColumn( - name: "MediaPhotoImageBackgroundId", - table: "MediaPhotoImages", - type: "uuid", - nullable: true); - - migrationBuilder.UpdateData( - table: "Accounts", - keyColumn: "Id", - keyValue: 1L, - columns: new[] { "LeftSalt", "Password", "RightSalt" }, - values: new object[] { "Y&%]J>6Nc3&5~UUXnNxq", new byte[] { 68, 170, 8, 113, 134, 47, 98, 43, 96, 183, 126, 130, 204, 45, 4, 113, 81, 200, 244, 26, 54, 88, 161, 246, 84, 93, 159, 219, 12, 143, 128, 160, 198, 194, 47, 133, 216, 242, 158, 184, 43, 38, 134, 132, 175, 179, 42, 40, 0, 143, 111, 252, 156, 215, 17, 185, 12, 109, 119, 214, 211, 167, 32, 121 }, "MV1jo~o3Oa^;NWb\\Q)t_" }); - - migrationBuilder.CreateIndex( - name: "IX_MediaPhotoImages_MediaPhotoImageBackgroundId", - table: "MediaPhotoImages", - column: "MediaPhotoImageBackgroundId"); - - migrationBuilder.AddForeignKey( - name: "FK_MediaPhotoImages_MediaPhotoImageBackgrounds_Id", - table: "MediaPhotoImages", - column: "Id", - principalTable: "MediaPhotoImageBackgrounds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "FK_MediaPhotoImages_MediaPhotoImageBackgrounds_MediaPhotoImage~", - table: "MediaPhotoImages", - column: "MediaPhotoImageBackgroundId", - principalTable: "MediaPhotoImageBackgrounds", - principalColumn: "Id"); - } - } -} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20241102132802_RatingDate.Designer.cs b/WatchIt.Database/WatchIt.Database/Migrations/20241102132802_RatingDate.Designer.cs deleted file mode 100644 index d882d39..0000000 --- a/WatchIt.Database/WatchIt.Database/Migrations/20241102132802_RatingDate.Designer.cs +++ /dev/null @@ -1,1416 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using WatchIt.Database; - -#nullable disable - -namespace WatchIt.Database.Migrations -{ - [DbContext(typeof(DatabaseContext))] - [Migration("20241102132802_RatingDate")] - partial class RatingDate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.5") - .HasAnnotation("Proxies:ChangeTracking", false) - .HasAnnotation("Proxies:CheckEquality", false) - .HasAnnotation("Proxies:LazyLoading", true) - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("BackgroundPictureId") - .HasColumnType("uuid"); - - b.Property("CreationDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Email") - .IsRequired() - .HasMaxLength(320) - .HasColumnType("character varying(320)"); - - b.Property("GenderId") - .HasColumnType("smallint"); - - b.Property("IsAdmin") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("LastActive") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("LeftSalt") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Password") - .IsRequired() - .HasMaxLength(1000) - .HasColumnType("bytea"); - - b.Property("ProfilePictureId") - .HasColumnType("uuid"); - - b.Property("RightSalt") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Username") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("BackgroundPictureId"); - - b.HasIndex("GenderId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("ProfilePictureId") - .IsUnique(); - - b.ToTable("Accounts"); - - b.HasData( - new - { - Id = 1L, - CreationDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - Email = "root@watch.it", - IsAdmin = true, - LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - LeftSalt = "YuJiv1\"R'*0odl8${\\|S", - Password = new byte[] { 215, 154, 186, 191, 12, 223, 76, 105, 137, 67, 41, 138, 26, 3, 38, 36, 0, 71, 40, 84, 153, 152, 105, 239, 55, 60, 164, 15, 99, 175, 133, 175, 227, 245, 102, 9, 171, 119, 16, 234, 97, 179, 70, 29, 120, 112, 241, 91, 209, 91, 228, 164, 52, 244, 36, 207, 147, 60, 124, 66, 77, 252, 129, 151 }, - RightSalt = "oT2N=y7^5,2o'+N>d}~!", - Username = "root" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("AccountProfilePictures"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("ExpirationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("IsExtendable") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("AccountRefreshTokens"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("IsHistorical") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Countries"); - - b.HasData( - new - { - Id = (short)1, - IsHistorical = false, - Name = "Afghanistan" - }, - new - { - Id = (short)2, - IsHistorical = false, - Name = "Albania" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Gender", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Genders"); - - b.HasData( - new - { - Id = (short)1, - Name = "Male" - }, - new - { - Id = (short)2, - Name = "Female" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Genres"); - - b.HasData( - new - { - Id = (short)1, - Name = "Comedy" - }, - new - { - Id = (short)2, - Name = "Thriller" - }, - new - { - Id = (short)3, - Name = "Horror" - }, - new - { - Id = (short)4, - Name = "Action" - }, - new - { - Id = (short)5, - Name = "Drama" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Length") - .HasColumnType("smallint"); - - b.Property("MediaPosterImageId") - .HasColumnType("uuid"); - - b.Property("OriginalTitle") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.Property("ReleaseDate") - .HasColumnType("date"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaPosterImageId") - .IsUnique(); - - b.ToTable("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => - { - b.Property("GenreId") - .HasColumnType("smallint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.HasKey("GenreId", "MediaId"); - - b.HasIndex("MediaId"); - - b.ToTable("MediaGenres"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => - { - b.Property("Id") - .HasColumnType("bigint"); - - b.Property("Budget") - .HasColumnType("money"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaMovies"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("MediaPhotoImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("FirstGradientColor") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("bytea"); - - b.Property("IsUniversalBackground") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SecondGradientColor") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("bytea"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaPhotoImageBackgrounds"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaPosterImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => - { - b.Property("CountryId") - .HasColumnType("smallint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.HasKey("CountryId", "MediaId"); - - b.HasIndex("MediaId"); - - b.ToTable("MediaProductionCountries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.Property("Id") - .HasColumnType("bigint"); - - b.Property("HasEnded") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaSeries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsSpecial") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("MediaSeriesSeasonId") - .HasColumnType("uuid"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Number") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesSeasonId"); - - b.ToTable("MediaSeriesEpisodes"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaSeriesId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Number") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesId"); - - b.ToTable("MediaSeriesSeasons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("BirthDate") - .HasColumnType("date"); - - b.Property("DeathDate") - .HasColumnType("date"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("FullName") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("GenderId") - .HasColumnType("smallint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("PersonPhotoId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("GenderId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonPhotoId") - .IsUnique(); - - b.ToTable("Persons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("PersonActorRoleTypeId") - .HasColumnType("smallint"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.Property("RoleName") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("PersonActorRoleTypeId"); - - b.HasIndex("PersonId"); - - b.ToTable("PersonActorRoles"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRoleType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonActorRoleTypes"); - - b.HasData( - new - { - Id = (short)1, - Name = "Actor" - }, - new - { - Id = (short)2, - Name = "Supporting actor" - }, - new - { - Id = (short)3, - Name = "Voice actor" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("PersonCreatorRoleTypeId") - .HasColumnType("smallint"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("PersonCreatorRoleTypeId"); - - b.HasIndex("PersonId"); - - b.ToTable("PersonCreatorRoles"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRoleType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonCreatorRoleTypes"); - - b.HasData( - new - { - Id = (short)1, - Name = "Director" - }, - new - { - Id = (short)2, - Name = "Producer" - }, - new - { - Id = (short)3, - Name = "Screenwriter" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonPhotoImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("RatingsMedia"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("MediaSeriesEpisodeId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesEpisodeId"); - - b.ToTable("RatingsMediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("MediaSeriesSeasonId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesSeasonId"); - - b.ToTable("RatingsMediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("PersonActorRoleId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonActorRoleId"); - - b.ToTable("RatingsPersonActorRole", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("PersonCreatorRoleId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonCreatorRoleId"); - - b.ToTable("RatingsPersonCreatorRole", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasDefaultValueSql("now()"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("ViewCount") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasDefaultValue(0L); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("ViewCountsMedia", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasDefaultValueSql("now()"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.Property("ViewCount") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasDefaultValue(0L); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonId"); - - b.ToTable("ViewCountsPerson", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "BackgroundPicture") - .WithMany() - .HasForeignKey("BackgroundPictureId"); - - b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") - .WithMany() - .HasForeignKey("GenderId"); - - b.HasOne("WatchIt.Database.Model.Account.AccountProfilePicture", "ProfilePicture") - .WithOne("Account") - .HasForeignKey("WatchIt.Database.Model.Account.Account", "ProfilePictureId"); - - b.Navigation("BackgroundPicture"); - - b.Navigation("Gender"); - - b.Navigation("ProfilePicture"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("AccountRefreshTokens") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPosterImage", "MediaPosterImage") - .WithOne("Media") - .HasForeignKey("WatchIt.Database.Model.Media.Media", "MediaPosterImageId"); - - b.Navigation("MediaPosterImage"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => - { - b.HasOne("WatchIt.Database.Model.Common.Genre", "Genre") - .WithMany("MediaGenres") - .HasForeignKey("GenreId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaGenres") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Genre"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithOne() - .HasForeignKey("WatchIt.Database.Model.Media.MediaMovie", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaPhotoImages") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "MediaPhotoImage") - .WithOne("MediaPhotoImageBackground") - .HasForeignKey("WatchIt.Database.Model.Media.MediaPhotoImageBackground", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaPhotoImage"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => - { - b.HasOne("WatchIt.Database.Model.Common.Country", "Country") - .WithMany("MediaProductionCountries") - .HasForeignKey("CountryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaProductionCountries") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Country"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithOne() - .HasForeignKey("WatchIt.Database.Model.Media.MediaSeries", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") - .WithMany("MediaSeriesEpisodes") - .HasForeignKey("MediaSeriesSeasonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaSeries", "MediaSeries") - .WithMany("MediaSeriesSeasons") - .HasForeignKey("MediaSeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaSeries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") - .WithMany() - .HasForeignKey("GenderId"); - - b.HasOne("WatchIt.Database.Model.Person.PersonPhotoImage", "PersonPhoto") - .WithOne("Person") - .HasForeignKey("WatchIt.Database.Model.Person.Person", "PersonPhotoId"); - - b.Navigation("Gender"); - - b.Navigation("PersonPhoto"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("PersonActorRoles") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonActorRoleType", "PersonActorRoleType") - .WithMany() - .HasForeignKey("PersonActorRoleTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("PersonActorRoles") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - - b.Navigation("Person"); - - b.Navigation("PersonActorRoleType"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("PersonCreatorRoles") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRoleType", "PersonCreatorRoleType") - .WithMany() - .HasForeignKey("PersonCreatorRoleTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("PersonCreatorRoles") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - - b.Navigation("Person"); - - b.Navigation("PersonCreatorRoleType"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMedia") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("RatingMedia") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMediaSeriesEpisode") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesEpisode", "MediaSeriesEpisode") - .WithMany("RatingMediaSeriesEpisode") - .HasForeignKey("MediaSeriesEpisodeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("MediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMediaSeriesSeason") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") - .WithMany("RatingMediaSeriesSeason") - .HasForeignKey("MediaSeriesSeasonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("MediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingPersonActorRole") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonActorRole", "PersonActorRole") - .WithMany("RatingPersonActorRole") - .HasForeignKey("PersonActorRoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("PersonActorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingPersonCreatorRole") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRole", "PersonCreatorRole") - .WithMany("RatingPersonCreatorRole") - .HasForeignKey("PersonCreatorRoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("PersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("ViewCountsMedia") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => - { - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("ViewCountsPerson") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Person"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.Navigation("AccountRefreshTokens"); - - b.Navigation("RatingMedia"); - - b.Navigation("RatingMediaSeriesEpisode"); - - b.Navigation("RatingMediaSeriesSeason"); - - b.Navigation("RatingPersonActorRole"); - - b.Navigation("RatingPersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => - { - b.Navigation("Account") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => - { - b.Navigation("MediaProductionCountries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => - { - b.Navigation("MediaGenres"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.Navigation("MediaGenres"); - - b.Navigation("MediaPhotoImages"); - - b.Navigation("MediaProductionCountries"); - - b.Navigation("PersonActorRoles"); - - b.Navigation("PersonCreatorRoles"); - - b.Navigation("RatingMedia"); - - b.Navigation("ViewCountsMedia"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.Navigation("MediaPhotoImageBackground"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => - { - b.Navigation("Media") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.Navigation("MediaSeriesSeasons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.Navigation("RatingMediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.Navigation("MediaSeriesEpisodes"); - - b.Navigation("RatingMediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.Navigation("PersonActorRoles"); - - b.Navigation("PersonCreatorRoles"); - - b.Navigation("ViewCountsPerson"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.Navigation("RatingPersonActorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.Navigation("RatingPersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => - { - b.Navigation("Person") - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20241102132802_RatingDate.cs b/WatchIt.Database/WatchIt.Database/Migrations/20241102132802_RatingDate.cs deleted file mode 100644 index 8262578..0000000 --- a/WatchIt.Database/WatchIt.Database/Migrations/20241102132802_RatingDate.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace WatchIt.Database.Migrations -{ - /// - public partial class RatingDate : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Date", - table: "RatingsPersonCreatorRole", - type: "timestamp with time zone", - nullable: false, - defaultValueSql: "now()"); - - migrationBuilder.AddColumn( - name: "Date", - table: "RatingsPersonActorRole", - type: "timestamp with time zone", - nullable: false, - defaultValueSql: "now()"); - - migrationBuilder.AddColumn( - name: "Date", - table: "RatingsMediaSeriesSeason", - type: "timestamp with time zone", - nullable: false, - defaultValueSql: "now()"); - - migrationBuilder.AddColumn( - name: "Date", - table: "RatingsMediaSeriesEpisode", - type: "timestamp with time zone", - nullable: false, - defaultValueSql: "now()"); - - migrationBuilder.AddColumn( - name: "Date", - table: "RatingsMedia", - type: "timestamp with time zone", - nullable: false, - defaultValueSql: "now()"); - - migrationBuilder.AlterColumn( - name: "RoleName", - table: "PersonActorRoles", - type: "character varying(100)", - maxLength: 100, - nullable: false, - oldClrType: typeof(string), - oldType: "text"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Date", - table: "RatingsPersonCreatorRole"); - - migrationBuilder.DropColumn( - name: "Date", - table: "RatingsPersonActorRole"); - - migrationBuilder.DropColumn( - name: "Date", - table: "RatingsMediaSeriesSeason"); - - migrationBuilder.DropColumn( - name: "Date", - table: "RatingsMediaSeriesEpisode"); - - migrationBuilder.DropColumn( - name: "Date", - table: "RatingsMedia"); - - migrationBuilder.AlterColumn( - name: "RoleName", - table: "PersonActorRoles", - type: "text", - nullable: false, - oldClrType: typeof(string), - oldType: "character varying(100)", - oldMaxLength: 100); - } - } -} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs b/WatchIt.Database/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs deleted file mode 100644 index 40c20dc..0000000 --- a/WatchIt.Database/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs +++ /dev/null @@ -1,1413 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using WatchIt.Database; - -#nullable disable - -namespace WatchIt.Database.Migrations -{ - [DbContext(typeof(DatabaseContext))] - partial class DatabaseContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.5") - .HasAnnotation("Proxies:ChangeTracking", false) - .HasAnnotation("Proxies:CheckEquality", false) - .HasAnnotation("Proxies:LazyLoading", true) - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("BackgroundPictureId") - .HasColumnType("uuid"); - - b.Property("CreationDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Email") - .IsRequired() - .HasMaxLength(320) - .HasColumnType("character varying(320)"); - - b.Property("GenderId") - .HasColumnType("smallint"); - - b.Property("IsAdmin") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("LastActive") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("LeftSalt") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Password") - .IsRequired() - .HasMaxLength(1000) - .HasColumnType("bytea"); - - b.Property("ProfilePictureId") - .HasColumnType("uuid"); - - b.Property("RightSalt") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Username") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("BackgroundPictureId"); - - b.HasIndex("GenderId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("ProfilePictureId") - .IsUnique(); - - b.ToTable("Accounts"); - - b.HasData( - new - { - Id = 1L, - CreationDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - Email = "root@watch.it", - IsAdmin = true, - LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - LeftSalt = "YuJiv1\"R'*0odl8${\\|S", - Password = new byte[] { 215, 154, 186, 191, 12, 223, 76, 105, 137, 67, 41, 138, 26, 3, 38, 36, 0, 71, 40, 84, 153, 152, 105, 239, 55, 60, 164, 15, 99, 175, 133, 175, 227, 245, 102, 9, 171, 119, 16, 234, 97, 179, 70, 29, 120, 112, 241, 91, 209, 91, 228, 164, 52, 244, 36, 207, 147, 60, 124, 66, 77, 252, 129, 151 }, - RightSalt = "oT2N=y7^5,2o'+N>d}~!", - Username = "root" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("AccountProfilePictures"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("ExpirationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("IsExtendable") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("AccountRefreshTokens"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("IsHistorical") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Countries"); - - b.HasData( - new - { - Id = (short)1, - IsHistorical = false, - Name = "Afghanistan" - }, - new - { - Id = (short)2, - IsHistorical = false, - Name = "Albania" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Gender", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Genders"); - - b.HasData( - new - { - Id = (short)1, - Name = "Male" - }, - new - { - Id = (short)2, - Name = "Female" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("Genres"); - - b.HasData( - new - { - Id = (short)1, - Name = "Comedy" - }, - new - { - Id = (short)2, - Name = "Thriller" - }, - new - { - Id = (short)3, - Name = "Horror" - }, - new - { - Id = (short)4, - Name = "Action" - }, - new - { - Id = (short)5, - Name = "Drama" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("Length") - .HasColumnType("smallint"); - - b.Property("MediaPosterImageId") - .HasColumnType("uuid"); - - b.Property("OriginalTitle") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.Property("ReleaseDate") - .HasColumnType("date"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaPosterImageId") - .IsUnique(); - - b.ToTable("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => - { - b.Property("GenreId") - .HasColumnType("smallint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.HasKey("GenreId", "MediaId"); - - b.HasIndex("MediaId"); - - b.ToTable("MediaGenres"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => - { - b.Property("Id") - .HasColumnType("bigint"); - - b.Property("Budget") - .HasColumnType("money"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaMovies"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("MediaPhotoImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("FirstGradientColor") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("bytea"); - - b.Property("IsUniversalBackground") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SecondGradientColor") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("bytea"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaPhotoImageBackgrounds"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaPosterImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => - { - b.Property("CountryId") - .HasColumnType("smallint"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.HasKey("CountryId", "MediaId"); - - b.HasIndex("MediaId"); - - b.ToTable("MediaProductionCountries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.Property("Id") - .HasColumnType("bigint"); - - b.Property("HasEnded") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("MediaSeries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsSpecial") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("MediaSeriesSeasonId") - .HasColumnType("uuid"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Number") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesSeasonId"); - - b.ToTable("MediaSeriesEpisodes"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaSeriesId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Number") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesId"); - - b.ToTable("MediaSeriesSeasons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("BirthDate") - .HasColumnType("date"); - - b.Property("DeathDate") - .HasColumnType("date"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("FullName") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("GenderId") - .HasColumnType("smallint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("PersonPhotoId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("GenderId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonPhotoId") - .IsUnique(); - - b.ToTable("Persons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("PersonActorRoleTypeId") - .HasColumnType("smallint"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.Property("RoleName") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("PersonActorRoleTypeId"); - - b.HasIndex("PersonId"); - - b.ToTable("PersonActorRoles"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRoleType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonActorRoleTypes"); - - b.HasData( - new - { - Id = (short)1, - Name = "Actor" - }, - new - { - Id = (short)2, - Name = "Supporting actor" - }, - new - { - Id = (short)3, - Name = "Voice actor" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("PersonCreatorRoleTypeId") - .HasColumnType("smallint"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.HasIndex("PersonCreatorRoleTypeId"); - - b.HasIndex("PersonId"); - - b.ToTable("PersonCreatorRoles"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRoleType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("smallint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonCreatorRoleTypes"); - - b.HasData( - new - { - Id = (short)1, - Name = "Director" - }, - new - { - Id = (short)2, - Name = "Producer" - }, - new - { - Id = (short)3, - Name = "Screenwriter" - }); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Image") - .IsRequired() - .HasMaxLength(-1) - .HasColumnType("bytea"); - - b.Property("MimeType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UploadDate") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.ToTable("PersonPhotoImages"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("RatingsMedia"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("MediaSeriesEpisodeId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesEpisodeId"); - - b.ToTable("RatingsMediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("MediaSeriesSeasonId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaSeriesSeasonId"); - - b.ToTable("RatingsMediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("PersonActorRoleId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonActorRoleId"); - - b.ToTable("RatingsPersonActorRole", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("bigint"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasDefaultValueSql("now()"); - - b.Property("PersonCreatorRoleId") - .HasColumnType("uuid"); - - b.Property("Rating") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonCreatorRoleId"); - - b.ToTable("RatingsPersonCreatorRole", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasDefaultValueSql("now()"); - - b.Property("MediaId") - .HasColumnType("bigint"); - - b.Property("ViewCount") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasDefaultValue(0L); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("MediaId"); - - b.ToTable("ViewCountsMedia", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Date") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasDefaultValueSql("now()"); - - b.Property("PersonId") - .HasColumnType("bigint"); - - b.Property("ViewCount") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasDefaultValue(0L); - - b.HasKey("Id"); - - b.HasIndex("Id") - .IsUnique(); - - b.HasIndex("PersonId"); - - b.ToTable("ViewCountsPerson", (string)null); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "BackgroundPicture") - .WithMany() - .HasForeignKey("BackgroundPictureId"); - - b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") - .WithMany() - .HasForeignKey("GenderId"); - - b.HasOne("WatchIt.Database.Model.Account.AccountProfilePicture", "ProfilePicture") - .WithOne("Account") - .HasForeignKey("WatchIt.Database.Model.Account.Account", "ProfilePictureId"); - - b.Navigation("BackgroundPicture"); - - b.Navigation("Gender"); - - b.Navigation("ProfilePicture"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("AccountRefreshTokens") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPosterImage", "MediaPosterImage") - .WithOne("Media") - .HasForeignKey("WatchIt.Database.Model.Media.Media", "MediaPosterImageId"); - - b.Navigation("MediaPosterImage"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => - { - b.HasOne("WatchIt.Database.Model.Common.Genre", "Genre") - .WithMany("MediaGenres") - .HasForeignKey("GenreId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaGenres") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Genre"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithOne() - .HasForeignKey("WatchIt.Database.Model.Media.MediaMovie", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaPhotoImages") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "MediaPhotoImage") - .WithOne("MediaPhotoImageBackground") - .HasForeignKey("WatchIt.Database.Model.Media.MediaPhotoImageBackground", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaPhotoImage"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => - { - b.HasOne("WatchIt.Database.Model.Common.Country", "Country") - .WithMany("MediaProductionCountries") - .HasForeignKey("CountryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("MediaProductionCountries") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Country"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithOne() - .HasForeignKey("WatchIt.Database.Model.Media.MediaSeries", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") - .WithMany("MediaSeriesEpisodes") - .HasForeignKey("MediaSeriesSeasonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.HasOne("WatchIt.Database.Model.Media.MediaSeries", "MediaSeries") - .WithMany("MediaSeriesSeasons") - .HasForeignKey("MediaSeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("MediaSeries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") - .WithMany() - .HasForeignKey("GenderId"); - - b.HasOne("WatchIt.Database.Model.Person.PersonPhotoImage", "PersonPhoto") - .WithOne("Person") - .HasForeignKey("WatchIt.Database.Model.Person.Person", "PersonPhotoId"); - - b.Navigation("Gender"); - - b.Navigation("PersonPhoto"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("PersonActorRoles") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonActorRoleType", "PersonActorRoleType") - .WithMany() - .HasForeignKey("PersonActorRoleTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("PersonActorRoles") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - - b.Navigation("Person"); - - b.Navigation("PersonActorRoleType"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("PersonCreatorRoles") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRoleType", "PersonCreatorRoleType") - .WithMany() - .HasForeignKey("PersonCreatorRoleTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("PersonCreatorRoles") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - - b.Navigation("Person"); - - b.Navigation("PersonCreatorRoleType"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMedia") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("RatingMedia") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMediaSeriesEpisode") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesEpisode", "MediaSeriesEpisode") - .WithMany("RatingMediaSeriesEpisode") - .HasForeignKey("MediaSeriesEpisodeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("MediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingMediaSeriesSeason") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") - .WithMany("RatingMediaSeriesSeason") - .HasForeignKey("MediaSeriesSeasonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("MediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingPersonActorRole") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonActorRole", "PersonActorRole") - .WithMany("RatingPersonActorRole") - .HasForeignKey("PersonActorRoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("PersonActorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => - { - b.HasOne("WatchIt.Database.Model.Account.Account", "Account") - .WithMany("RatingPersonCreatorRole") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRole", "PersonCreatorRole") - .WithMany("RatingPersonCreatorRole") - .HasForeignKey("PersonCreatorRoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("PersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => - { - b.HasOne("WatchIt.Database.Model.Media.Media", "Media") - .WithMany("ViewCountsMedia") - .HasForeignKey("MediaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Media"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => - { - b.HasOne("WatchIt.Database.Model.Person.Person", "Person") - .WithMany("ViewCountsPerson") - .HasForeignKey("PersonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Person"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => - { - b.Navigation("AccountRefreshTokens"); - - b.Navigation("RatingMedia"); - - b.Navigation("RatingMediaSeriesEpisode"); - - b.Navigation("RatingMediaSeriesSeason"); - - b.Navigation("RatingPersonActorRole"); - - b.Navigation("RatingPersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => - { - b.Navigation("Account") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => - { - b.Navigation("MediaProductionCountries"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => - { - b.Navigation("MediaGenres"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => - { - b.Navigation("MediaGenres"); - - b.Navigation("MediaPhotoImages"); - - b.Navigation("MediaProductionCountries"); - - b.Navigation("PersonActorRoles"); - - b.Navigation("PersonCreatorRoles"); - - b.Navigation("RatingMedia"); - - b.Navigation("ViewCountsMedia"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => - { - b.Navigation("MediaPhotoImageBackground"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => - { - b.Navigation("Media") - .IsRequired(); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => - { - b.Navigation("MediaSeriesSeasons"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => - { - b.Navigation("RatingMediaSeriesEpisode"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => - { - b.Navigation("MediaSeriesEpisodes"); - - b.Navigation("RatingMediaSeriesSeason"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => - { - b.Navigation("PersonActorRoles"); - - b.Navigation("PersonCreatorRoles"); - - b.Navigation("ViewCountsPerson"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => - { - b.Navigation("RatingPersonActorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => - { - b.Navigation("RatingPersonCreatorRole"); - }); - - modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => - { - b.Navigation("Person") - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/WatchIt.Database/WatchIt.Database/WatchIt.Database.csproj b/WatchIt.Database/WatchIt.Database/WatchIt.Database.csproj deleted file mode 100644 index e836832..0000000 --- a/WatchIt.Database/WatchIt.Database/WatchIt.Database.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - diff --git a/WatchIt.WebAPI/BusinessLogic/Accounts/AccountsBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Accounts/AccountsBusinessLogic.cs new file mode 100644 index 0000000..98a517a --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Accounts/AccountsBusinessLogic.cs @@ -0,0 +1,353 @@ +using Ardalis.Result; +using Microsoft.EntityFrameworkCore; +using WatchIt.Database.Model.Accounts; +using WatchIt.Database.Model.Media; +using WatchIt.Database.Model.People; +using WatchIt.DTO.Models.Controllers.Accounts; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture; +using WatchIt.DTO.Models.Controllers.Accounts.AccountEmail; +using WatchIt.DTO.Models.Controllers.Accounts.AccountLogout; +using WatchIt.DTO.Models.Controllers.Accounts.AccountPassword; +using WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo; +using WatchIt.DTO.Models.Controllers.Accounts.AccountUsername; +using WatchIt.DTO.Models.Controllers.Media; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.People; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Models.Controllers.Photos; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.Helpers; +using WatchIt.WebAPI.Repositories.Accounts; +using WatchIt.WebAPI.Repositories.Media; +using WatchIt.WebAPI.Repositories.People; +using WatchIt.WebAPI.Services.Tokens; +using WatchIt.WebAPI.Services.User; + +namespace WatchIt.WebAPI.BusinessLogic.Accounts; + +public class AccountsBusinessLogic : IAccountsBusinessLogic +{ + #region SERVICES + + private readonly IUserService _userService; + private readonly ITokensService _tokensService; + private readonly IAccountsRepository _accountRepository; + private readonly IMediaRepository _mediaRepository; + private readonly IPeopleRepository _peopleRepository; + + #endregion + + + + #region CONSTRUCTORS + + public AccountsBusinessLogic(IUserService userService, ITokensService tokensService, IAccountsRepository accountRepository, IMediaRepository mediaRepository, IPeopleRepository peopleRepository) + { + _userService = userService; + _tokensService = tokensService; + _accountRepository = accountRepository; + _mediaRepository = mediaRepository; + _peopleRepository = peopleRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task>> GetAccounts(AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includeProfilePictures) + { + IEnumerable entities = await _accountRepository.GetAllAsync(x => IncludeForAccountResponse(x, includeProfilePictures)); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetAccount(long accountId, bool includeProfilePictures) + { + Account? account = await _accountRepository.GetAsync(accountId, x => IncludeForAccountResponse(x, includeProfilePictures)); + return account switch + { + null => Result.NotFound(), + _ => Result.Success(account.ToResponse()) + }; + } + + public async Task> PostAccount(AccountRequest body) + { + Account entity = body.ToEntity(PasswordHelpers.GeneratePasswordData); + await _accountRepository.AddAsync(entity); + AccountResponse response = entity.ToResponse(); + return Result.Created(response); + } + + #endregion + + #region Profile picture + + public async Task> GetAccountProfilePicture(long accountId) + { + AccountProfilePicture? picture = await _accountRepository.GetProfilePictureAsync(accountId); + return picture switch + { + null => Result.NotFound(), + _ => Result.Success(picture.ToResponse()) + }; + } + + public async Task> PutAccountProfilePicture(ImageRequest body) + { + Account account = await _userService.GetAccountAsync(); + AccountProfilePicture entity = await _accountRepository.UpdateOrAddProfilePictureAsync(account.Id, () => AccountsMappers.ToEntity(body, account.Id), x => x.UpdateWithRequest(body)); + return Result.Success(entity.ToResponse()); + } + + public async Task DeleteAccountProfilePicture() + { + Account account = await _userService.GetAccountAsync(); + await _accountRepository.DeleteProfilePictureAsync(account.Id); + return Result.NoContent(); + } + + #endregion + + #region Profile background + + public async Task> GetAccountBackgroundPicture(long accountId) + { + AccountBackgroundPicture? picture = await _accountRepository.GetBackgroundPictureAsync(accountId, x => x.Include(y => y.Background) + .ThenInclude(y => y.Photo)); + return picture switch + { + null => Result.NotFound(), + _ => Result.Success(picture.Background.Photo.ToResponse()) + }; + } + + public async Task> PutAccountBackgroundPicture(AccountBackgroundPictureRequest body) + { + Account account = await _userService.GetAccountAsync(); + AccountBackgroundPicture entity = await _accountRepository.UpdateOrAddBackgroundPictureAsync(account.Id, () => body.ToEntity(account.Id), x => x.UpdateWithRequest(body)); + PhotoResponse photo = await GetAccountBackgroundPicture(account.Id); + return Result.Success(photo); + } + + public async Task DeleteAccountBackgroundPicture() + { + Account account = await _userService.GetAccountAsync(); + await _accountRepository.DeleteBackgroundPictureAsync(account.Id); + return Result.NoContent(); + } + + #endregion + + #region Profile edit + + public async Task PatchAccountProfileInfo(AccountProfileInfoRequest body) + { + Account account = await _userService.GetAccountAsync(); + await _accountRepository.UpdateAsync(account, x => x.UpdateWithRequest(body)); + return Result.Success(); + } + + public async Task PatchAccountUsername(AccountUsernameRequest body) + { + Account account = await _userService.GetAccountAsync(); + if (!PasswordHelpers.ValidatePassword(body.Password, account.GetPasswordData())) + { + return Result.Unauthorized(); + } + await _accountRepository.UpdateAsync(account, x => x.UpdateWithRequest(body)); + return Result.Success(); + } + + public async Task PatchAccountEmail(AccountEmailRequest body) + { + Account account = await _userService.GetAccountAsync(); + if (!PasswordHelpers.ValidatePassword(body.Password, account.GetPasswordData())) + { + return Result.Unauthorized(); + } + await _accountRepository.UpdateAsync(account, x => x.UpdateWithRequest(body)); + return Result.Success(); + } + + public async Task PatchAccountPassword(AccountPasswordRequest body) + { + Account account = await _userService.GetAccountAsync(); + if (!PasswordHelpers.ValidatePassword(body.Password, account.GetPasswordData())) + { + return Result.Unauthorized(); + } + await _accountRepository.UpdateAsync(account, x => x.UpdateWithRequest(body, PasswordHelpers.GeneratePasswordData)); + return Result.Success(); + } + + #endregion + + #region Log out + + public async Task Logout(AccountLogoutRequest body) + { + if (body.RefreshToken is not null) + { + await _tokensService.RevokeRefreshTokenAsync(body.RefreshToken); + } + return Result.NoContent(); + } + + public async Task LogoutAll() + { + Account accountEntity = await _userService.GetAccountAsync(); + await _tokensService.RevokeAccountRefreshTokensAsync(accountEntity); + return Result.NoContent(); + } + + #endregion + + #region Follows + + public async Task>> GetAccountFollows(long accountId, AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + if (!await _accountRepository.ExistsAsync(accountId)) + { + return Result.NotFound(); + } + IEnumerable accounts = await _accountRepository.GetFollowsAsync(accountId, filterQuery, orderQuery, pagingQuery, x => x.Include(y => y.Gender)); + return Result.Success(accounts.Select(x => x.ToResponse())); + } + + public async Task>> GetAccountFollowers(long accountId, AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + if (!await _accountRepository.ExistsAsync(accountId)) + { + return Result.NotFound(); + } + IEnumerable accounts = await _accountRepository.GetFollowersAsync(accountId, filterQuery, orderQuery, pagingQuery, x => x.Include(y => y.Gender)); + return Result.Success(accounts.Select(x => x.ToResponse())); + } + + public async Task PostAccountFollow(long followedAccountId) + { + Account account = await _userService.GetAccountAsync(); + if (account.Id == followedAccountId) + { + return Result.Error("You cannot follow yourself"); + } + if (!await _accountRepository.ExistsAsync(followedAccountId)) + { + return Result.Error("User with this id doesn't exist"); + } + if (!await _accountRepository.FollowExistsAsync(account.Id, followedAccountId)) + { + await _accountRepository.AddFollowAsync(AccountsMappers.CreateAccountFollowEntity(account.Id, followedAccountId)); + } + return Result.Success(); + } + + public async Task DeleteAccountFollow(long followedAccountId) + { + Account account = await _userService.GetAccountAsync(); + await _accountRepository.DeleteFollowAsync(account.Id, followedAccountId); + return Result.NoContent(); + } + + #endregion + + #region Ratings + + public async Task>> GetAccountRatedMedia(long accountId, MediumFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures) + { + if (!await _accountRepository.ExistsAsync(accountId)) + { + return Result.NotFound(); + } + + IEnumerable media = await _mediaRepository.GetAllRatedByAccountAsync(accountId, filterQuery, userRatedFilterQuery, orderQuery, pagingQuery, x => IncludeForMediumResponse(x, includePictures)); + return Result.Success(media.Select(x => x.ToResponse(accountId))); + } + + public async Task>> GetAccountRatedMediaMovies(long accountId, MediumMovieFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures) + { + if (!await _accountRepository.ExistsAsync(accountId)) + { + return Result.NotFound(); + } + + IEnumerable mediumMovies = await _mediaRepository.GetAllMoviesRatedByAccountAsync(accountId, filterQuery, userRatedFilterQuery, orderQuery, pagingQuery, x => IncludeForMediumResponse(x, includePictures)); + return Result.Success(mediumMovies.Select(x => x.ToResponse(accountId))); + } + + public async Task>> GetAccountRatedMediaSeries(long accountId, MediumSeriesFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures) + { + if (!await _accountRepository.ExistsAsync(accountId)) + { + return Result.NotFound(); + } + + IEnumerable mediumSeries = await _mediaRepository.GetAllSeriesRatedByAccountAsync(accountId, filterQuery, userRatedFilterQuery, orderQuery, pagingQuery, x => IncludeForMediumResponse(x, includePictures)); + return Result.Success(mediumSeries.Select(x => x.ToResponse(accountId))); + } + + public async Task>> GetAccountRatedPeople(long accountId, PersonFilterQuery filterQuery, PersonUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures) + { + if (!await _accountRepository.ExistsAsync(accountId)) + { + return Result.NotFound(); + } + + IEnumerable people = await _peopleRepository.GetAllRatedByAccountAsync(accountId, filterQuery, userRatedFilterQuery, orderQuery, pagingQuery, x => IncludeForPersonResponse(x, includePictures)); + return Result.Success(people.Select(x => x.ToResponse(accountId))); + } + + #endregion + + #endregion + + + + #region PRIVATE METHODS + + private IQueryable IncludeForAccountResponse(IQueryable query, bool includeProfilePictures) + { + query = query.Include(y => y.Gender); + if (includeProfilePictures) + { + query = query.Include(y => y.ProfilePicture); + } + return query; + } + + private IQueryable IncludeForMediumResponse(IQueryable query, bool includePictures) where T : Medium + { + query = query.Include(y => y.Genres) + .Include(y => y.Ratings) + .Include(y => y.ViewCounts); + if (includePictures) + { + query = query.Include(y => y.Picture); + } + return query; + } + + private IQueryable IncludeForPersonResponse(IQueryable query, bool includeProfilePictures) + { + query = query.Include(y => y.Gender) + .Include(y => y.Roles) + .ThenInclude(y => y.Ratings) + .Include(y => y.ViewCounts); + if (includeProfilePictures) + { + query = query.Include(y => y.Picture); + } + return query; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Accounts/IAccountsBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Accounts/IAccountsBusinessLogic.cs new file mode 100644 index 0000000..ce4c016 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Accounts/IAccountsBusinessLogic.cs @@ -0,0 +1,79 @@ +using Ardalis.Result; +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture; +using WatchIt.DTO.Models.Controllers.Accounts.AccountEmail; +using WatchIt.DTO.Models.Controllers.Accounts.AccountLogout; +using WatchIt.DTO.Models.Controllers.Accounts.AccountPassword; +using WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo; +using WatchIt.DTO.Models.Controllers.Accounts.AccountUsername; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.BusinessLogic.Accounts; + +public interface IAccountsBusinessLogic +{ + #region Main + + Task>> GetAccounts(AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includeProfilePictures); + Task> GetAccount(long accountId, bool includeProfilePictures); + Task> PostAccount(AccountRequest body); + + #endregion + + #region Profile picture + + Task> GetAccountProfilePicture(long accountId); + Task> PutAccountProfilePicture(ImageRequest body); + Task DeleteAccountProfilePicture(); + + #endregion + + #region Background picture + + Task> GetAccountBackgroundPicture(long accountId); + Task> PutAccountBackgroundPicture(AccountBackgroundPictureRequest body); + Task DeleteAccountBackgroundPicture(); + + #endregion + + #region Profile edit + + Task PatchAccountProfileInfo(AccountProfileInfoRequest body); + Task PatchAccountUsername(AccountUsernameRequest body); + Task PatchAccountEmail(AccountEmailRequest body); + Task PatchAccountPassword(AccountPasswordRequest body); + + #endregion + + #region Log out + + Task Logout(AccountLogoutRequest body); + Task LogoutAll(); + + #endregion + + #region Follows + + Task>> GetAccountFollows(long accountId, AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task>> GetAccountFollowers(long accountId, AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task PostAccountFollow(long followedAccountId); + Task DeleteAccountFollow(long followedAccountId); + + #endregion + + #region Media + + Task>> GetAccountRatedMedia(long accountId, MediumFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures); + Task>> GetAccountRatedMediaMovies(long accountId, MediumMovieFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures); + Task>> GetAccountRatedMediaSeries(long accountId, MediumSeriesFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures); + Task>> GetAccountRatedPeople(long accountId, PersonFilterQuery filterQuery, PersonUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Authentication/AuthenticationBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Authentication/AuthenticationBusinessLogic.cs new file mode 100644 index 0000000..c482ab3 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Authentication/AuthenticationBusinessLogic.cs @@ -0,0 +1,68 @@ +using Ardalis.Result; +using WatchIt.Database.Model.Accounts; +using WatchIt.DTO.Models.Controllers.Accounts; +using WatchIt.DTO.Models.Controllers.Authentication; +using WatchIt.WebAPI.Helpers; +using WatchIt.WebAPI.Repositories.Accounts; +using WatchIt.WebAPI.Services.Tokens; +using WatchIt.WebAPI.Services.User; + +namespace WatchIt.WebAPI.BusinessLogic.Authentication; + +public class AuthenticationBusinessLogic : IAuthenticationBusinessLogic +{ + #region SERVICES + + private readonly ITokensService _tokensService; + private readonly IUserService _userService; + private readonly IAccountsRepository _accountRepository; + + #endregion + + + + #region CONSTRUCTORS + + public AuthenticationBusinessLogic(ITokensService tokensService, IUserService userService, IAccountsRepository accountRepository) + { + _tokensService = tokensService; + _userService = userService; + _accountRepository = accountRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + public async Task> Authenticate(AuthenticationRequest body) + { + Account? accountEntity = await _accountRepository.GetByUsernameOrEmailAsync(body.UsernameOrEmail); + if (accountEntity is null || !PasswordHelpers.ValidatePassword(body.Password, accountEntity.GetPasswordData())) + { + return Result.Unauthorized(); + } + + string accessToken = _tokensService.CreateAccessToken(accountEntity); + string refreshToken = await _tokensService.CreateRefreshTokenAsync(accountEntity, body.RememberMe); + AuthenticationResponse response = AuthenticationMappers.CreateAuthenticationResponse(accessToken, refreshToken); + + await _accountRepository.UpdateAsync(accountEntity, x => x.UpdateActiveDate()); + + return Result.Success(response); + } + + public async Task> AuthenticateRefresh(AuthenticationRefreshRequest body) + { + Account accountEntity = await _tokensService.ExtendRefreshTokenAsync(body.RefreshToken, body.AccessToken); + string accessToken = _tokensService.CreateAccessToken(accountEntity); + AuthenticationResponse response = AuthenticationMappers.CreateAuthenticationResponse(accessToken, body.RefreshToken); + + await _accountRepository.UpdateAsync(accountEntity, x => x.UpdateActiveDate()); + + return Result.Success(response); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Authentication/IAuthenticationBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Authentication/IAuthenticationBusinessLogic.cs new file mode 100644 index 0000000..7dcb379 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Authentication/IAuthenticationBusinessLogic.cs @@ -0,0 +1,11 @@ +using Ardalis.Result; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Authentication; + +namespace WatchIt.WebAPI.BusinessLogic.Authentication; + +public interface IAuthenticationBusinessLogic +{ + Task> Authenticate(AuthenticationRequest body); + Task> AuthenticateRefresh(AuthenticationRefreshRequest body); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Genders/GendersBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Genders/GendersBusinessLogic.cs new file mode 100644 index 0000000..2a74e4c --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Genders/GendersBusinessLogic.cs @@ -0,0 +1,68 @@ +using Ardalis.Result; +using Microsoft.EntityFrameworkCore; +using WatchIt.Database.Model.Genders; +using WatchIt.DTO; +using WatchIt.DTO.Models.Controllers.Genders; +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.Repositories.Genders; +using WatchIt.WebAPI.Services.User; + +namespace WatchIt.WebAPI.BusinessLogic.Genders; + +public class GendersBusinessLogic : IGendersBusinessLogic +{ + #region SERVICES + + private readonly IUserService _userService; + private readonly IGendersRepository _gendersRepository; + + #endregion + + + + #region CONSTRUCTORS + + public GendersBusinessLogic(IUserService userService, IGendersRepository gendersRepository) + { + _userService = userService; + _gendersRepository = gendersRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + public async Task>> GetGenders(GenderFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + IEnumerable entities = await _gendersRepository.GetAllAsync(filterQuery, orderQuery, pagingQuery); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetGender(short genderId) + { + Gender? entity = await _gendersRepository.GetAsync(genderId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task> PostGender(GenderRequest body) + { + Gender entity = body.ToEntity(); + await _gendersRepository.AddAsync(entity); + return Result.Created(entity.ToResponse()); + } + + public async Task DeleteGender(short genderId) + { + await _gendersRepository.DeleteAsync(x => x.Id == genderId); + return Result.NoContent(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Genders/IGendersBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Genders/IGendersBusinessLogic.cs new file mode 100644 index 0000000..4739b54 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Genders/IGendersBusinessLogic.cs @@ -0,0 +1,17 @@ +using Ardalis.Result; +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.BusinessLogic.Genders; + +public interface IGendersBusinessLogic +{ + #region PUBLIC METHODS + + Task>> GetGenders(GenderFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task> GetGender(short genderId); + Task> PostGender(GenderRequest body); + Task DeleteGender(short genderId); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Genres/GenresBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Genres/GenresBusinessLogic.cs new file mode 100644 index 0000000..24d01c7 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Genres/GenresBusinessLogic.cs @@ -0,0 +1,67 @@ +using Ardalis.Result; +using WatchIt.Database.Model.Genres; +using WatchIt.DTO; +using WatchIt.DTO.Models.Controllers.Genres; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.Repositories.Genres; +using WatchIt.WebAPI.Services.User; + +namespace WatchIt.WebAPI.BusinessLogic.Genres; + +public class GenresBusinessLogic : IGenresBusinessLogic +{ + #region SERVICES + + private readonly IUserService _userService; + private readonly IGenresRepository _genresRepository; + + #endregion + + + + #region CONSTRUCTORS + + public GenresBusinessLogic(IUserService userService, IGenresRepository genresRepository) + { + _userService = userService; + _genresRepository = genresRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + public async Task>> GetGenres(GenreFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + IEnumerable entities = await _genresRepository.GetAllAsync(filterQuery, orderQuery, pagingQuery); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetGenre(short genreId) + { + Genre? entity = await _genresRepository.GetAsync(genreId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task> PostGenre(GenreRequest body) + { + Genre entity = body.ToEntity(); + await _genresRepository.AddAsync(body.ToEntity()); + return Result.Created(entity.ToResponse()); + } + + public async Task DeleteGenre(short genreId) + { + await _genresRepository.DeleteAsync(x => x.Id == genreId); + return Result.NoContent(); + } + + #endregion +} diff --git a/WatchIt.WebAPI/BusinessLogic/Genres/IGenresBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Genres/IGenresBusinessLogic.cs new file mode 100644 index 0000000..ac3266b --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Genres/IGenresBusinessLogic.cs @@ -0,0 +1,13 @@ +using Ardalis.Result; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.BusinessLogic.Genres; + +public interface IGenresBusinessLogic +{ + Task>> GetGenres(GenreFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task> GetGenre(short genreId); + Task> PostGenre(GenreRequest body); + Task DeleteGenre(short genreId); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Media/IMediaBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Media/IMediaBusinessLogic.cs new file mode 100644 index 0000000..ba87368 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Media/IMediaBusinessLogic.cs @@ -0,0 +1,68 @@ +using Ardalis.Result; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Models.Controllers.Media.Medium.Request; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.BusinessLogic.Media; + +public interface IMediaBusinessLogic +{ + #region Main + + Task>> GetMedia(MediumFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures); + Task> GetMedium(long mediumId, bool includePictures); + Task>> GetMediumMovies(MediumMovieFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures); + Task> GetMediumMovie(long mediumId, bool includePictures); + Task>> GetMediumSeries(MediumSeriesFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures); + Task> GetMediumSeries(long mediumId, bool includePictures); + Task> PostMediumMovie(MediumMovieRequest body); + Task> PostMediumSeries(MediumSeriesRequest body); + Task> PutMediumMovie(long mediumId, MediumMovieRequest body); + Task> PutMediumSeries(long mediumId, MediumSeriesRequest body); + Task DeleteMedium(long mediumId); + + #endregion + + #region Genres + + Task>> GetMediumGenres(long mediumId, GenreFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task PostMediumGenre(long mediumId, short genreId); + Task DeleteMediumGenre(long mediumId, short genreId); + + #endregion + + #region Rating + + Task> GetMediumRating(long mediumId); + Task> GetMediumUserRating(long mediumId, long accountId); + Task PutMediumRating(long mediumId, RatingRequest body); + Task DeleteMediumRating(long mediumId); + + #endregion + + #region View count + + Task PutMediumViewCount(long mediumId); + + #endregion + + #region Picture + + Task> GetMediumPicture(long mediumId); + Task> PutMediumPicture(long mediumId, ImageRequest body); + Task DeleteMediumPicture(long mediumId); + + #endregion + + #region Photos + + Task> GetMediumPhotoBackground(long mediumId); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Media/MediaBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Media/MediaBusinessLogic.cs new file mode 100644 index 0000000..b89a73a --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Media/MediaBusinessLogic.cs @@ -0,0 +1,303 @@ +using Ardalis.Result; +using Microsoft.EntityFrameworkCore; +using SimpleToolkit.Extensions; +using WatchIt.Database.Model.Accounts; +using WatchIt.Database.Model.Genres; +using WatchIt.Database.Model.Media; +using WatchIt.Database.Model.Photos; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Models.Controllers.Genres; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Models.Controllers.Media; +using WatchIt.DTO.Models.Controllers.Media.Medium; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Models.Controllers.Media.Medium.Request; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.Photos; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Roles; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.Repositories.Genres; +using WatchIt.WebAPI.Repositories.Media; +using WatchIt.WebAPI.Repositories.Photos; +using WatchIt.WebAPI.Services.User; + +namespace WatchIt.WebAPI.BusinessLogic.Media; + +public class MediaBusinessLogic : IMediaBusinessLogic +{ + #region SERVICES + + private readonly IUserService _userService; + private readonly IMediaRepository _mediaRepository; + private readonly IGenresRepository _genresRepository; + private readonly IPhotosRepository _photosRepository; + + #endregion + + + + #region CONSTRUCTORS + + public MediaBusinessLogic(IUserService userService, IMediaRepository mediaRepository, IGenresRepository genresRepository, IPhotosRepository photosRepository) + { + _userService = userService; + _mediaRepository = mediaRepository; + _genresRepository = genresRepository; + _photosRepository = photosRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task>> GetMedia(MediumFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures) + { + IEnumerable entities = await _mediaRepository.GetAllAsync(filterQuery, orderQuery, pagingQuery, x => IncludeForMediumResponse(x, includePictures)); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetMedium(long mediumId, bool includePictures) + { + Medium? entity = await _mediaRepository.GetAsync(mediumId, x => IncludeForMediumResponse(x, includePictures)); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task>> GetMediumMovies(MediumMovieFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures) + { + IEnumerable entities = await _mediaRepository.GetAllMoviesAsync(filterQuery, orderQuery, pagingQuery, x => IncludeForMediumResponse(x, includePictures)); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetMediumMovie(long mediumId, bool includePictures) + { + MediumMovie? entity = await _mediaRepository.GetAsync(mediumId, x => IncludeForMediumResponse(x, includePictures)); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()), + }; + } + + public async Task>> GetMediumSeries(MediumSeriesFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures) + { + IEnumerable entities = await _mediaRepository.GetAllSeriesAsync(filterQuery, orderQuery, pagingQuery, x => IncludeForMediumResponse(x, includePictures)); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetMediumSeries(long mediumId, bool includePictures) + { + MediumSeries? entity = await _mediaRepository.GetAsync(mediumId, x => IncludeForMediumResponse(x, includePictures)); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()), + }; + } + + public async Task> PostMediumMovie(MediumMovieRequest body) + { + MediumMovie entity = body.ToEntity(); + await _mediaRepository.AddAsync(entity); + return Result.Created(entity.ToResponse()); + } + + public async Task> PostMediumSeries(MediumSeriesRequest body) + { + MediumSeries entity = body.ToEntity(); + await _mediaRepository.AddAsync(entity); + return Result.Created(entity.ToResponse()); + } + + public async Task> PutMediumMovie(long mediumId, MediumMovieRequest body) + { + return await _mediaRepository.UpdateAsync(mediumId, x => x.UpdateWithRequest(body)) switch + { + false => Result.NotFound(), + true => Result.Success() + }; + } + + public async Task> PutMediumSeries(long mediumId, MediumSeriesRequest body) + { + return await _mediaRepository.UpdateAsync(mediumId, x => x.UpdateWithRequest(body)) switch + { + false => Result.NotFound(), + true => Result.Success() + }; + } + + public async Task DeleteMedium(long mediumId) + { + await _mediaRepository.DeleteAsync(x => x.Id == mediumId); + return Result.NoContent(); + } + + #endregion + + #region Genres + + public async Task>> GetMediumGenres(long mediumId, GenreFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + if (!await _mediaRepository.ExistsAsync(mediumId)) + { + return Result.NotFound(); + } + IEnumerable genres = await _mediaRepository.GetMediumGenresAsync(mediumId, filterQuery, orderQuery, pagingQuery); + return Result.Success(genres.Select(x => x.ToResponse())); + } + + public async Task PostMediumGenre(long mediumId, short genreId) + { + bool mediumExists = await _mediaRepository.ExistsAsync(mediumId); + bool genreExists = await _genresRepository.ExistsAsync(genreId); + if (mediumExists && genreExists) + { + await _mediaRepository.AddMediumGenreAsync(mediumId, genreId); + return Result.Success(); + } + return Result.NotFound(); + } + + public async Task DeleteMediumGenre(long mediumId, short genreId) + { + await _mediaRepository.DeleteMediumGenreAsync(mediumId, genreId); + return Result.NoContent(); + } + + #endregion + + #region Rating + + public async Task> GetMediumRating(long mediumId) + { + Medium? entity = await _mediaRepository.GetAsync(mediumId, x => x.Include(y => y.Ratings)); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.Ratings.ToOverallResponse()) + }; + } + + public async Task> GetMediumUserRating(long mediumId, long accountId) + { + MediumRating? entity = await _mediaRepository.GetMediumUserRatingAsync(mediumId, accountId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToUserResponse()) + }; + } + + public async Task PutMediumRating(long mediumId, RatingRequest body) + { + Account accountEntity = await _userService.GetAccountAsync(); + Medium? mediumEntity = await _mediaRepository.GetAsync(mediumId); + if (mediumEntity is null) + { + return Result.NotFound(); + } + await _mediaRepository.UpdateOrAddMediumRatingAsync(mediumEntity.Id, accountEntity.Id, () => body.ToEntity(mediumEntity.Id, accountEntity.Id), x => x.UpdateWithRequest(body)); + return Result.Success(); + } + + public async Task DeleteMediumRating(long mediumId) + { + Account accountEntity = await _userService.GetAccountAsync(); + await _mediaRepository.DeleteMediumUserRatingAsync(mediumId, accountEntity.Id); + return Result.NoContent(); + } + + #endregion + + #region View count + + public async Task PutMediumViewCount(long mediumId) + { + Medium? entity = await _mediaRepository.GetAsync(mediumId); + if (entity is null) + { + return Result.NotFound(); + } + + DateOnly date = DateOnly.FromDateTime(DateTime.UtcNow); + await _mediaRepository.UpdateOrAddMediumViewCountAsync(mediumId, date, () => MediaMappers.CreateMediumViewCountEntity(mediumId), x => x.ViewCount++); + return Result.Success(); + } + + #endregion + + #region Pictures + + public async Task> GetMediumPicture(long mediumId) + { + MediumPicture? entity = await _mediaRepository.GetMediumPictureAsync(mediumId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task> PutMediumPicture(long mediumId, ImageRequest body) + { + return await _mediaRepository.ExistsAsync(mediumId) switch + { + true => Result.Success((await _mediaRepository.UpdateOrAddMediumPictureAsync(mediumId, () => body.ToEntity(mediumId), x => x.UpdateWithRequest(body))).ToResponse()), + false => Result.NotFound(), + }; + } + + public async Task DeleteMediumPicture(long mediumId) + { + await _mediaRepository.DeleteMediumPictureAsync(mediumId); + return Result.NoContent(); + } + + #endregion + + #region Photos + + public async Task> GetMediumPhotoBackground(long mediumId) + { + if (!await _mediaRepository.ExistsAsync(mediumId)) + { + return Result.NotFound(); + } + Photo photo = await _photosRepository.GetPhotoRandomBackgroundByMediumAsync(mediumId, x => x.Include(y => y.Background)); + return photo.ToResponse(); + } + + #endregion + + #endregion + + + + #region PRIVATE METHODS + + private IQueryable IncludeForMediumResponse(IQueryable query, bool includePictures) where T : Medium + { + query = query.Include(y => y.Genres) + .Include(y => y.Ratings) + .Include(y => y.ViewCounts); + if (includePictures) + { + query = query.Include(y => y.Picture); + } + return query; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/People/IPeopleBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/People/IPeopleBusinessLogic.cs new file mode 100644 index 0000000..aa5159c --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/People/IPeopleBusinessLogic.cs @@ -0,0 +1,23 @@ +using Ardalis.Result; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.BusinessLogic.People; + +public interface IPeopleBusinessLogic +{ + Task>> GetPeople(PersonFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures); + Task> GetPerson(long personId, bool includePictures); + Task> PostPerson(PersonRequest body); + Task> PutPerson(long personId, PersonRequest body); + Task DeletePerson(long personId); + Task> GetPersonRating(long personId); + Task> GetPersonUserRating(long personId, long accountId); + Task PutPeopleViewCount(long personId); + Task> GetPersonPicture(long personId); + Task> PutPersonPicture(long personId, ImageRequest body); + Task DeletePersonPicture(long personId); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/People/PeopleBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/People/PeopleBusinessLogic.cs new file mode 100644 index 0000000..5daa11e --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/People/PeopleBusinessLogic.cs @@ -0,0 +1,179 @@ +using Ardalis.Result; +using Microsoft.EntityFrameworkCore; +using WatchIt.Database.Model.Accounts; +using WatchIt.Database.Model.People; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO; +using WatchIt.DTO.Models.Controllers.People; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Models.Controllers.Roles; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.Repositories.People; +using WatchIt.WebAPI.Repositories.Roles; +using WatchIt.WebAPI.Services.User; + +namespace WatchIt.WebAPI.BusinessLogic.People; + +public class PeopleBusinessLogic : IPeopleBusinessLogic +{ + #region SERVICES + + private readonly IUserService _userService; + private readonly IPeopleRepository _peopleRepository; + private readonly IRolesRepository _rolesRepository; + + #endregion + + + + #region CONSTRUCTORS + + public PeopleBusinessLogic(IUserService userService, IPeopleRepository peopleRepository, IRolesRepository rolesRepository) + { + _userService = userService; + _peopleRepository = peopleRepository; + _rolesRepository = rolesRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task>> GetPeople(PersonFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, bool includePictures) + { + IEnumerable entities = await _peopleRepository.GetAllAsync(filterQuery, orderQuery, pagingQuery, x => IncludeForPersonResponse(x, includePictures)); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetPerson(long personId, bool includePictures) + { + Person? entity = await _peopleRepository.GetAsync(personId, x => IncludeForPersonResponse(x, includePictures)); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task> PostPerson(PersonRequest body) + { + Person entity = body.ToEntity(); + await _peopleRepository.AddAsync(entity); + return Result.Created(entity.ToResponse()); + } + + public async Task> PutPerson(long personId, PersonRequest body) + { + return await _peopleRepository.UpdateAsync(personId, x => x.UpdateWithRequest(body)) switch + { + false => Result.NotFound(), + true => Result.Success() + }; + } + + public async Task DeletePerson(long personId) + { + await _peopleRepository.DeleteAsync(personId); + return Result.NoContent(); + } + + #endregion + + #region Rating + + public async Task> GetPersonRating(long personId) + { + if (!await _peopleRepository.ExistsAsync(personId)) + { + return Result.NotFound(); + } + IEnumerable roleRatings = await _rolesRepository.GetPersonRoleRatingsAsync(personId); + return Result.Success(roleRatings.ToOverallResponse()); + } + + public async Task> GetPersonUserRating(long personId, long accountId) + { + if (!await _peopleRepository.ExistsAsync(personId)) + { + return Result.NotFound(); + } + IEnumerable roleRatings = await _rolesRepository.GetPersonRoleRatingsByAccountIdAsync(personId, accountId); + return Result.Success(roleRatings.ToUserOverallResponse()); + } + + #endregion + + #region View count + + public async Task PutPeopleViewCount(long personId) + { + Person? entity = await _peopleRepository.GetAsync(personId); + if (entity is null) + { + return Result.NotFound(); + } + + DateOnly date = DateOnly.FromDateTime(DateTime.UtcNow); + await _peopleRepository.UpdateOrAddPersonViewCountAsync(personId, date, () => PeopleMappers.CreatePersonViewCountEntity(personId), x => x.ViewCount++); + return Result.Success(); + } + + #endregion + + #region Pictures + + public async Task> GetPersonPicture(long personId) + { + PersonPicture? entity = await _peopleRepository.GetPersonPictureAsync(personId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task> PutPersonPicture(long personId, ImageRequest body) + { + return await _peopleRepository.ExistsAsync(personId) switch + { + true => Result.Success((await _peopleRepository.UpdateOrAddPersonPictureAsync(personId, () => body.ToEntity(personId), x => x.UpdateWithRequest(body))).ToResponse()), + false => Result.NotFound(), + }; + } + + public async Task DeletePersonPicture(long personId) + { + await _peopleRepository.DeletePersonPictureAsync(personId); + return Result.NoContent(); + } + + #endregion + + #endregion + + + + #region PRIVATE METHODS + + private IQueryable IncludeForPersonResponse(IQueryable query, bool includePictures) + { + query = query.Include(y => y.Gender) + .Include(y => y.ViewCounts) + .Include(y => y.Roles).ThenInclude(y => y.Ratings); + if (includePictures) + { + query = query.Include(y => y.Picture); + } + return query; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Photos/IPhotosBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Photos/IPhotosBusinessLogic.cs new file mode 100644 index 0000000..86ae97a --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Photos/IPhotosBusinessLogic.cs @@ -0,0 +1,19 @@ +using Ardalis.Result; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.BusinessLogic.Photos; + +public interface IPhotosBusinessLogic +{ + Task> GetPhoto(Guid photoId); + Task>> GetPhotos(PhotoFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task> GetPhotoBackground(); + Task> PostPhoto(PhotoRequest body); + Task> PutPhoto(Guid photoId, PhotoRequest body); + Task DeletePhoto(Guid photoId); + + Task> PutPhotoBackground(Guid photoId, PhotoBackgroundRequest body); + Task DeletePhotoBackground(Guid photoId); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Photos/PhotosBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Photos/PhotosBusinessLogic.cs new file mode 100644 index 0000000..0ea07c7 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Photos/PhotosBusinessLogic.cs @@ -0,0 +1,122 @@ +using Ardalis.Result; +using Microsoft.EntityFrameworkCore; +using WatchIt.Database.Model.Photos; +using WatchIt.DTO.Models.Controllers.Photos; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.Repositories.Photos; + +namespace WatchIt.WebAPI.BusinessLogic.Photos; + +public class PhotosBusinessLogic : IPhotosBusinessLogic +{ + #region SERVICES + + private readonly IPhotosRepository _photosRepository; + + #endregion + + + + #region CONSTRUCTORS + + public PhotosBusinessLogic(IPhotosRepository photosRepository) + { + _photosRepository = photosRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task> GetPhoto(Guid photoId) + { + Photo? entity = await _photosRepository.GetAsync(photoId, x => x.Include(y => y.Background)); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task>> GetPhotos(PhotoFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + IEnumerable entities = await _photosRepository.GetAllAsync(filterQuery, orderQuery, pagingQuery, x => x.Include(y => y.Background)); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> PostPhoto(PhotoRequest body) + { + Photo entity = body.ToEntity(); + await _photosRepository.AddAsync(entity); + if (body.BackgroundData is not null) + { + await _photosRepository.AddPhotoBackgroundAsync(body.BackgroundData.ToEntity(entity.Id)); + } + return Result.Created(entity.ToResponse()); + } + + public async Task> PutPhoto(Guid photoId, PhotoRequest body) + { + bool success = await _photosRepository.UpdateAsync(photoId, x => x.UpdateWithRequest(body)); + if (success) + { + if (body.BackgroundData is not null) + { + await _photosRepository.UpdateOrAddPhotoBackgroundAsync(photoId, () => body.BackgroundData.ToEntity(photoId), x => x.UpdateWithRequest(body.BackgroundData)); + } + else + { + await _photosRepository.DeletePhotoBackgroundAsync(photoId); + } + return Result.Success(); + } + return Result.NotFound(); + } + + public async Task DeletePhoto(Guid photoId) + { + await _photosRepository.DeleteAsync(photoId); + return Result.NoContent(); + } + + #endregion + + #region Background + + public async Task> GetPhotoBackground() + { + Photo? entity = await _photosRepository.GetPhotoRandomBackgroundAsync(x => x.Include(y => y.Background)); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task> PutPhotoBackground(Guid photoId, PhotoBackgroundRequest body) + { + if (await _photosRepository.ExistsAsync(photoId)) + { + return Result.NotFound(); + } + PhotoBackground entity = await _photosRepository.UpdateOrAddPhotoBackgroundAsync(photoId, () => body.ToEntity(photoId), x => x.UpdateWithRequest(body)); + return Result.Success(entity.ToResponse()); + } + + public async Task DeletePhotoBackground(Guid photoId) + { + await _photosRepository.DeletePhotoBackgroundAsync(photoId); + return Result.NoContent(); + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Roles/IRolesBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Roles/IRolesBusinessLogic.cs new file mode 100644 index 0000000..9678099 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Roles/IRolesBusinessLogic.cs @@ -0,0 +1,37 @@ +using Ardalis.Result; +using WatchIt.DTO.Models.Controllers.Roles.Role.Query; +using WatchIt.DTO.Models.Controllers.Roles.Role.Request; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType; +using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.BusinessLogic.Roles; + +public interface IRolesBusinessLogic +{ + Task>> GetRoleActors(RoleActorFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task> GetRoleActor(Guid roleId); + Task>> GetRoleCreators(RoleCreatorFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task> GetRoleCreator(Guid roleId); + Task> PostRoleActor(RoleActorRequest body); + Task> PostRoleCreator(RoleCreatorRequest body); + Task> PutRoleActor(Guid roleId, RoleActorRequest body); + Task> PutRoleCreator(Guid roleId, RoleCreatorRequest body); + Task DeleteRole(Guid roleId); + + Task> GetRoleRating(Guid roleId); + Task> GetRoleUserRating(Guid roleId, long accountId); + Task PutRoleRating(Guid roleId, RatingRequest body); + Task DeleteRoleRating(Guid roleId); + + Task>> GetRoleActorTypes(RoleActorTypeFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task> GetRoleActorType(short roleActorTypeId); + Task> PostRoleActorType(RoleActorTypeRequest body); + Task DeleteRoleActorType(short roleActorTypeId); + Task>> GetRoleCreatorTypes(RoleCreatorTypeFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery); + Task> GetRoleCreatorType(short roleCreatorTypeId); + Task> PostRoleCreatorType(RoleCreatorTypeRequest body); + Task DeleteRoleCreatorType(short roleCreatorTypeId); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/BusinessLogic/Roles/RolesBusinessLogic.cs b/WatchIt.WebAPI/BusinessLogic/Roles/RolesBusinessLogic.cs new file mode 100644 index 0000000..7921951 --- /dev/null +++ b/WatchIt.WebAPI/BusinessLogic/Roles/RolesBusinessLogic.cs @@ -0,0 +1,230 @@ +using Ardalis.Result; +using Microsoft.EntityFrameworkCore; +using WatchIt.Database.Model.Accounts; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO; +using WatchIt.DTO.Models.Controllers.Roles; +using WatchIt.DTO.Models.Controllers.Roles.Role.Query; +using WatchIt.DTO.Models.Controllers.Roles.Role.Request; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType; +using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.Repositories.Roles; +using WatchIt.WebAPI.Services.User; + +namespace WatchIt.WebAPI.BusinessLogic.Roles; + +public class RolesBusinessLogic : IRolesBusinessLogic +{ + #region SERVICES + + private readonly IUserService _userService; + private readonly IRolesRepository _rolesRepository; + + #endregion + + + + #region CONSTRUCTORS + + public RolesBusinessLogic(IUserService userService, IRolesRepository rolesRepository) + { + _userService = userService; + _rolesRepository = rolesRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + #region Main - CRUD + + public async Task>> GetRoleActors(RoleActorFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + IEnumerable entities = await _rolesRepository.GetAllActorsAsync(filterQuery, orderQuery, pagingQuery); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetRoleActor(Guid roleId) + { + RoleActor? entity = await _rolesRepository.GetAsync(roleId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()), + }; + } + + public async Task>> GetRoleCreators(RoleCreatorFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + IEnumerable entities = await _rolesRepository.GetAllCreatorsAsync(filterQuery, orderQuery, pagingQuery); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetRoleCreator(Guid roleId) + { + RoleCreator? entity = await _rolesRepository.GetAsync(roleId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()), + }; + } + + public async Task> PostRoleActor(RoleActorRequest body) + { + RoleActor entity = body.ToEntity(); + await _rolesRepository.AddAsync(entity); + return Result.Created(entity.ToResponse()); + } + + public async Task> PostRoleCreator(RoleCreatorRequest body) + { + RoleCreator entity = body.ToEntity(); + await _rolesRepository.AddAsync(entity); + return Result.Created(entity.ToResponse()); + } + + public async Task> PutRoleActor(Guid roleId, RoleActorRequest body) + { + return await _rolesRepository.UpdateAsync(roleId, x => x.UpdateWithRequest(body)) switch + { + false => Result.NotFound(), + true => Result.Success() + }; + } + + public async Task> PutRoleCreator(Guid roleId, RoleCreatorRequest body) + { + return await _rolesRepository.UpdateAsync(roleId, x => x.UpdateWithRequest(body)) switch + { + false => Result.NotFound(), + true => Result.Success() + }; + } + + public async Task DeleteRole(Guid roleId) + { + await _rolesRepository.DeleteAsync(roleId); + return Result.NoContent(); + } + + #endregion + + #region Main - Rating + + public async Task> GetRoleRating(Guid roleId) + { + if (!await _rolesRepository.ExistsAsync(roleId)) + { + return Result.NotFound(); + } + + IEnumerable ratings = await _rolesRepository.GetRoleRatingsAsync(roleId); + return Result.Success(ratings.ToOverallResponse()); + } + + public async Task> GetRoleUserRating(Guid roleId, long accountId) + { + RoleRating? entity = await _rolesRepository.GetRoleRatingByUserAsync(roleId, accountId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToUserResponse()) + }; + } + + public async Task PutRoleRating(Guid roleId, RatingRequest body) + { + Account accountEntity = await _userService.GetAccountAsync(); + Role? roleEntity = await _rolesRepository.GetAsync(roleId); + if (roleEntity is null) + { + return Result.NotFound(); + } + await _rolesRepository.UpdateOrAddRoleRatingAsync(roleEntity.Id, accountEntity.Id, () => body.ToEntity(roleEntity.Id, accountEntity.Id), x => x.UpdateWithRequest(body)); + return Result.Success(); + } + + public async Task DeleteRoleRating(Guid roleId) + { + Account accountEntity = await _userService.GetAccountAsync(); + await _rolesRepository.DeleteRoleUserRatingAsync(roleId, accountEntity.Id); + return Result.NoContent(); + } + + + #endregion + + #region ActorTypes + + public async Task>> GetRoleActorTypes(RoleActorTypeFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + IEnumerable entities = await _rolesRepository.GetAllActorTypesAsync(filterQuery, orderQuery, pagingQuery); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetRoleActorType(short roleActorTypeId) + { + RoleActorType? entity = await _rolesRepository.GetActorTypeAsync(roleActorTypeId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task> PostRoleActorType(RoleActorTypeRequest body) + { + RoleActorType entity = body.ToEntity(); + await _rolesRepository.AddActorTypeAsync(body.ToEntity()); + return Result.Created(entity.ToResponse()); + } + + public async Task DeleteRoleActorType(short roleActorTypeId) + { + await _rolesRepository.DeleteActorTypeAsync(roleActorTypeId); + return Result.NoContent(); + } + + #endregion + + #region CreatorTypes + + public async Task>> GetRoleCreatorTypes(RoleCreatorTypeFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery) + { + IEnumerable entities = await _rolesRepository.GetAllCreatorTypesAsync(filterQuery, orderQuery, pagingQuery); + return Result.Success(entities.Select(x => x.ToResponse())); + } + + public async Task> GetRoleCreatorType(short roleCreatorTypeId) + { + RoleCreatorType? entity = await _rolesRepository.GetCreatorTypeAsync(roleCreatorTypeId); + return entity switch + { + null => Result.NotFound(), + _ => Result.Success(entity.ToResponse()) + }; + } + + public async Task> PostRoleCreatorType(RoleCreatorTypeRequest body) + { + RoleCreatorType entity = body.ToEntity(); + await _rolesRepository.AddCreatorTypeAsync(body.ToEntity()); + return Result.Created(entity.ToResponse()); + } + + public async Task DeleteRoleCreatorType(short roleCreatorTypeId) + { + await _rolesRepository.DeleteActorTypeAsync(roleCreatorTypeId); + return Result.NoContent(); + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Constants/AdditionalClaimNames.cs b/WatchIt.WebAPI/Constants/AdditionalClaimNames.cs new file mode 100644 index 0000000..9c3bc81 --- /dev/null +++ b/WatchIt.WebAPI/Constants/AdditionalClaimNames.cs @@ -0,0 +1,10 @@ +namespace WatchIt.WebAPI.Constants; + +public struct AdditionalClaimNames +{ + #region CONSTANTS + + public const string Admin = "admin"; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Constants/Policies.cs b/WatchIt.WebAPI/Constants/Policies.cs new file mode 100644 index 0000000..93f848c --- /dev/null +++ b/WatchIt.WebAPI/Constants/Policies.cs @@ -0,0 +1,6 @@ +namespace WatchIt.WebAPI.Constants; + +public class Policies +{ + public const string Admin = "Admin"; +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Controllers/AccountsController.cs b/WatchIt.WebAPI/Controllers/AccountsController.cs new file mode 100644 index 0000000..acee6e2 --- /dev/null +++ b/WatchIt.WebAPI/Controllers/AccountsController.cs @@ -0,0 +1,193 @@ +using Ardalis.Result; +using Ardalis.Result.AspNetCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture; +using WatchIt.DTO.Models.Controllers.Accounts.AccountEmail; +using WatchIt.DTO.Models.Controllers.Accounts.AccountLogout; +using WatchIt.DTO.Models.Controllers.Accounts.AccountPassword; +using WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo; +using WatchIt.DTO.Models.Controllers.Accounts.AccountUsername; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.BusinessLogic.Accounts; + +namespace WatchIt.WebAPI.Controllers; + +[ApiController] +[Route("accounts")] +public class AccountsController(IAccountsBusinessLogic accountsBusinessLogic) : ControllerBase +{ + #region Main + + [HttpGet] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetAccounts([FromQuery]AccountFilterQuery filterQuery, [FromQuery]OrderQuery orderQuery, [FromQuery]PagingQuery pagingQuery, [FromQuery(Name = "include_profile_pictures")]bool includeProfilePictures = false) => + await accountsBusinessLogic.GetAccounts(filterQuery, orderQuery, pagingQuery, includeProfilePictures); + + [HttpGet("{id:long}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetAccount([FromRoute(Name = "id")] long id, [FromQuery(Name = "include_profile_pictures")]bool includeProfilePictures = false) => + await accountsBusinessLogic.GetAccount(id, includeProfilePictures); + + [HttpPost] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> PostAccount([FromBody]AccountRequest body) => + await accountsBusinessLogic.PostAccount(body); + + #endregion + + #region Profile picture + + [HttpGet("{id:long}/profile_picture")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetAccountProfilePicture([FromRoute(Name = "id")] long id) => + await accountsBusinessLogic.GetAccountProfilePicture(id); + + [HttpPut("profile_picture")] + [Authorize] + [TranslateResultToActionResult] + public async Task> PutAccountProfilePicture([FromBody] ImageRequest body) => + await accountsBusinessLogic.PutAccountProfilePicture(body); + + [HttpDelete("profile_picture")] + [Authorize] + [TranslateResultToActionResult] + public async Task DeleteAccountProfilePicture() => + await accountsBusinessLogic.DeleteAccountProfilePicture(); + + #endregion + + #region Background picture + + [HttpGet("{id:long}/background_picture")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetAccountBackgroundPicture([FromRoute(Name = "id")] long id) => + await accountsBusinessLogic.GetAccountBackgroundPicture(id); + + [HttpPut("background_picture")] + [Authorize] + [TranslateResultToActionResult] + public async Task> PutAccountBackgroundPicture([FromBody] AccountBackgroundPictureRequest body) => + await accountsBusinessLogic.PutAccountBackgroundPicture(body); + + [HttpDelete("background_picture")] + [Authorize] + [TranslateResultToActionResult] + public async Task DeleteAccountBackgroundPicture() => + await accountsBusinessLogic.DeleteAccountBackgroundPicture(); + + #endregion + + #region Profile edit + + [HttpPatch("profile_info")] + [Authorize] + [TranslateResultToActionResult] + public async Task PatchAccountProfileInfo([FromBody] AccountProfileInfoRequest body) => + await accountsBusinessLogic.PatchAccountProfileInfo(body); + + [HttpPatch("username")] + [Authorize] + [TranslateResultToActionResult] + public async Task PatchAccountUsername([FromBody] AccountUsernameRequest body) => + await accountsBusinessLogic.PatchAccountUsername(body); + + [HttpPatch("email")] + [Authorize] + [TranslateResultToActionResult] + public async Task PatchAccountEmail([FromBody] AccountEmailRequest body) => + await accountsBusinessLogic.PatchAccountEmail(body); + + [HttpPatch("password")] + [Authorize] + [TranslateResultToActionResult] + public async Task PatchAccountPassword([FromBody] AccountPasswordRequest body) => + await accountsBusinessLogic.PatchAccountPassword(body); + + #endregion + + #region Log out + + [HttpDelete("logout")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task Logout([FromBody]AccountLogoutRequest body) => + await accountsBusinessLogic.Logout(body); + + [HttpDelete("logout_all")] + [Authorize] + [TranslateResultToActionResult] + public async Task LogoutAll() => + await accountsBusinessLogic.LogoutAll(); + + #endregion + + #region Follows + + [HttpGet("{id:long}/follows")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetAccountFollows([FromRoute(Name = "id")] long id, [FromQuery] AccountFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await accountsBusinessLogic.GetAccountFollows(id, filterQuery, orderQuery, pagingQuery); + + [HttpGet("{id:long}/followers")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetAccountFollowers([FromRoute(Name = "id")] long id, [FromQuery] AccountFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await accountsBusinessLogic.GetAccountFollowers(id, filterQuery, orderQuery, pagingQuery); + + [HttpPost("follows/{followed_account_id:long}")] + [Authorize] + [TranslateResultToActionResult] + public async Task PostAccountFollow([FromRoute(Name = "followed_account_id")] long followedAccountId) => + await accountsBusinessLogic.PostAccountFollow(followedAccountId); + + [HttpDelete("follows/{followed_account_id:long}")] + [Authorize] + [TranslateResultToActionResult] + public async Task DeleteAccountFollow([FromRoute(Name = "followed_account_id")] long followedAccountId) => + await accountsBusinessLogic.DeleteAccountFollow(followedAccountId); + + #endregion + + #region Ratings + + [HttpGet("{id:long}/media")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetAccountRatedMedia([FromRoute(Name = "id")] long id, [FromQuery]MediumFilterQuery filterQuery, [FromQuery]MediumUserRatedFilterQuery userRatedFilterQuery, [FromQuery]OrderQuery orderQuery, [FromQuery]PagingQuery pagingQuery, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await accountsBusinessLogic.GetAccountRatedMedia(id, filterQuery, userRatedFilterQuery, orderQuery, pagingQuery, includePictures); + + [HttpGet("{id:long}/media/movies")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetAccountRatedMediaMovies([FromRoute(Name = "id")] long id, [FromQuery]MediumMovieFilterQuery filterQuery, [FromQuery]MediumUserRatedFilterQuery userRatedFilterQuery, [FromQuery]OrderQuery orderQuery, [FromQuery]PagingQuery pagingQuery, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await accountsBusinessLogic.GetAccountRatedMediaMovies(id, filterQuery, userRatedFilterQuery, orderQuery, pagingQuery, includePictures); + + [HttpGet("{id:long}/media/series")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetAccountRatedMediaSeries([FromRoute(Name = "id")] long id, [FromQuery]MediumSeriesFilterQuery filterQuery, [FromQuery]MediumUserRatedFilterQuery userRatedFilterQuery, [FromQuery]OrderQuery orderQuery, [FromQuery]PagingQuery pagingQuery, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await accountsBusinessLogic.GetAccountRatedMediaSeries(id, filterQuery, userRatedFilterQuery, orderQuery, pagingQuery, includePictures); + + [HttpGet("{id:long}/people")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetAccountRatedPeople([FromRoute(Name = "id")] long id, [FromQuery]PersonFilterQuery filterQuery, [FromQuery]PersonUserRatedFilterQuery userRatedFilterQuery, [FromQuery]OrderQuery orderQuery, [FromQuery]PagingQuery pagingQuery, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await accountsBusinessLogic.GetAccountRatedPeople(id, filterQuery, userRatedFilterQuery, orderQuery, pagingQuery, includePictures); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Controllers/AuthenticationController.cs b/WatchIt.WebAPI/Controllers/AuthenticationController.cs new file mode 100644 index 0000000..41b5c93 --- /dev/null +++ b/WatchIt.WebAPI/Controllers/AuthenticationController.cs @@ -0,0 +1,24 @@ +using Ardalis.Result; +using Ardalis.Result.AspNetCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Authentication; +using WatchIt.WebAPI.BusinessLogic.Authentication; + +namespace WatchIt.WebAPI.Controllers; + +[ApiController] +[Route("authentication")] +public class AuthenticationController(IAuthenticationBusinessLogic authenticationBusinessLogic) : ControllerBase +{ + [HttpPost("authenticate")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> Authenticate([FromBody]AuthenticationRequest body) => await authenticationBusinessLogic.Authenticate(body); + + [HttpPost("authenticate_refresh")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> AuthenticateRefresh([FromBody]AuthenticationRefreshRequest body) => await authenticationBusinessLogic.AuthenticateRefresh(body); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Controllers/GendersController.cs b/WatchIt.WebAPI/Controllers/GendersController.cs new file mode 100644 index 0000000..deea75e --- /dev/null +++ b/WatchIt.WebAPI/Controllers/GendersController.cs @@ -0,0 +1,39 @@ +using Ardalis.Result; +using Ardalis.Result.AspNetCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.BusinessLogic.Genders; +using WatchIt.WebAPI.Constants; + +namespace WatchIt.WebAPI.Controllers; + +[ApiController] +[Route("genders")] +public class GendersController(IGendersBusinessLogic gendersBusinessLogic) : ControllerBase +{ + [HttpGet] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetGenders([FromQuery] GenderFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await gendersBusinessLogic.GetGenders(filterQuery, orderQuery, pagingQuery); + + [HttpGet("{id}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetGender([FromRoute(Name = "id")] short id) => + await gendersBusinessLogic.GetGender(id); + + [HttpPost] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostGender([FromBody] GenderRequest body) => + await gendersBusinessLogic.PostGender(body); + + [HttpDelete("{id}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeleteGender([FromRoute(Name = "id")] short id) => + await gendersBusinessLogic.DeleteGender(id); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Controllers/GenresController.cs b/WatchIt.WebAPI/Controllers/GenresController.cs new file mode 100644 index 0000000..cdde59d --- /dev/null +++ b/WatchIt.WebAPI/Controllers/GenresController.cs @@ -0,0 +1,39 @@ +using Ardalis.Result; +using Ardalis.Result.AspNetCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.BusinessLogic.Genres; +using WatchIt.WebAPI.Constants; + +namespace WatchIt.WebAPI.Controllers; + +[ApiController] +[Route("genres")] +public class GenresController(IGenresBusinessLogic genresBusinessLogic) : ControllerBase +{ + [HttpGet] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetGenres([FromQuery] GenreFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await genresBusinessLogic.GetGenres(filterQuery, orderQuery, pagingQuery); + + [HttpGet("{id}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetGenre([FromRoute(Name = "id")] short id) => + await genresBusinessLogic.GetGenre(id); + + [HttpPost] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostGenre([FromBody] GenreRequest body) => + await genresBusinessLogic.PostGenre(body); + + [HttpDelete("{id}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeleteGenre([FromRoute(Name = "id")] short id) => + await genresBusinessLogic.DeleteGenre(id); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Controllers/MediaController.cs b/WatchIt.WebAPI/Controllers/MediaController.cs new file mode 100644 index 0000000..1964303 --- /dev/null +++ b/WatchIt.WebAPI/Controllers/MediaController.cs @@ -0,0 +1,184 @@ +using Ardalis.Result; +using Ardalis.Result.AspNetCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Models.Controllers.Media.Medium.Request; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.BusinessLogic.Media; +using WatchIt.WebAPI.Constants; + +namespace WatchIt.WebAPI.Controllers; + +[ApiController] +[Route("media")] +public class MediaController(IMediaBusinessLogic mediaBusinessLogic) : ControllerBase +{ + #region Main + + [HttpGet] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetMedia([FromQuery] MediumFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await mediaBusinessLogic.GetMedia(filterQuery, orderQuery, pagingQuery, includePictures); + + [HttpGet("{id:long}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetMedium([FromRoute(Name = "id")] long id, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await mediaBusinessLogic.GetMedium(id, includePictures); + + [HttpGet("movies")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetMediumMovies([FromQuery] MediumMovieFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await mediaBusinessLogic.GetMediumMovies(filterQuery, orderQuery, pagingQuery, includePictures); + + [HttpGet("movies/{id:long}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetMediumMovie([FromRoute(Name = "id")] long id, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await mediaBusinessLogic.GetMediumMovie(id, includePictures); + + [HttpGet("series")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetMediumSeries([FromQuery] MediumSeriesFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await mediaBusinessLogic.GetMediumSeries(filterQuery, orderQuery, pagingQuery, includePictures); + + [HttpGet("series/{id:long}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetMediumSeries([FromRoute(Name = "id")] long id, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await mediaBusinessLogic.GetMediumSeries(id, includePictures); + + [HttpPost("movies")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostMediumMovie([FromBody] MediumMovieRequest body) => + await mediaBusinessLogic.PostMediumMovie(body); + + [HttpPost("series")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostMediumSeries([FromBody] MediumSeriesRequest body) => + await mediaBusinessLogic.PostMediumSeries(body); + + [HttpPut("movies/{id:long}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutMediumMovie([FromRoute(Name = "id")] long id, [FromBody] MediumMovieRequest body) => + await mediaBusinessLogic.PutMediumMovie(id, body); + + [HttpPut("series/{id:long}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutMediumSeries([FromRoute(Name = "id")] long id, [FromBody] MediumSeriesRequest body) => + await mediaBusinessLogic.PutMediumSeries(id, body); + + [HttpDelete("{id:long}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeleteMedium([FromRoute(Name = "id")] long id) => + await mediaBusinessLogic.DeleteMedium(id); + + #endregion + + #region Genres + + [HttpGet("{id:long}/genres")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetMediumGenres([FromRoute(Name = "id")] long id, [FromQuery] GenreFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await mediaBusinessLogic.GetMediumGenres(id, filterQuery, orderQuery, pagingQuery); + + [HttpPost("{id:long}/genres/{genre_id}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task PostMediumGenre([FromRoute(Name = "id")] long id, [FromRoute(Name = "genre_id")] short genreId) => + await mediaBusinessLogic.PostMediumGenre(id, genreId); + + [HttpDelete("{id:long}/genres/{genre_id}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeleteMediumGenre([FromRoute(Name = "id")] long id, [FromRoute(Name = "genre_id")] short genreId) => + await mediaBusinessLogic.DeleteMediumGenre(id, genreId); + + #endregion + + #region Rating + + [HttpGet("{id:long}/rating")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetMediumRating([FromRoute(Name = "id")] long id) => + await mediaBusinessLogic.GetMediumRating(id); + + [HttpGet("{id:long}/rating/{account_id:long}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetMediumUserRating([FromRoute(Name = "id")] long id, [FromRoute(Name = "account_id")] long accountId) => + await mediaBusinessLogic.GetMediumUserRating(id, accountId); + + [HttpPut("{id:long}/rating")] + [Authorize] + [TranslateResultToActionResult] + public async Task PutMediumRating([FromRoute(Name = "id")] long id, [FromBody] RatingRequest body) => + await mediaBusinessLogic.PutMediumRating(id, body); + + [HttpDelete("{id:long}/rating")] + [Authorize] + [TranslateResultToActionResult] + public async Task DeleteMediumRating([FromRoute(Name = "id")] long id) => + await mediaBusinessLogic.DeleteMediumRating(id); + + #endregion + + #region View Count + + [HttpPut("{id:long}/view_count")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task PutMediumViewCount([FromRoute(Name = "id")] long id) => + await mediaBusinessLogic.PutMediumViewCount(id); + + #endregion + + #region Picture + + [HttpGet("{id:long}/picture")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetMediumPicture([FromRoute(Name = "id")] long id) => + await mediaBusinessLogic.GetMediumPicture(id); + + [HttpPut("{id:long}/picture")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutMediumPicture([FromRoute(Name = "id")] long id, [FromBody] ImageRequest body) => + await mediaBusinessLogic.PutMediumPicture(id, body); + + [HttpDelete("{id:long}/picture")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeleteMediumPicture([FromRoute(Name = "id")] long id) => + await mediaBusinessLogic.DeleteMediumPicture(id); + + #endregion + + #region Photos + + [HttpGet("{id:long}/photos/background")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetMediumBackgroundPhoto([FromRoute(Name = "id")] long id) => + await mediaBusinessLogic.GetMediumPhotoBackground(id); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Controllers/PeopleController.cs b/WatchIt.WebAPI/Controllers/PeopleController.cs new file mode 100644 index 0000000..6432241 --- /dev/null +++ b/WatchIt.WebAPI/Controllers/PeopleController.cs @@ -0,0 +1,100 @@ +using Ardalis.Result; +using Ardalis.Result.AspNetCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.BusinessLogic.People; +using WatchIt.WebAPI.Constants; + +namespace WatchIt.WebAPI.Controllers; + +[ApiController] +[Route("people")] +public class PeopleController(IPeopleBusinessLogic peopleBusinessLogic) : ControllerBase +{ + #region Main + + [HttpGet] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetPeople([FromQuery] PersonFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await peopleBusinessLogic.GetPeople(filterQuery, orderQuery, pagingQuery, includePictures); + + [HttpGet("{id:long}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetPerson([FromRoute(Name = "id")] long id, [FromQuery(Name = "include_pictures")]bool includePictures = false) => + await peopleBusinessLogic.GetPerson(id, includePictures); + + [HttpPost] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostPerson([FromBody] PersonRequest body) => + await peopleBusinessLogic.PostPerson(body); + + [HttpPut("{id:long}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutPerson([FromRoute(Name = "id")] long id, [FromBody] PersonRequest body) => + await peopleBusinessLogic.PutPerson(id, body); + + [HttpDelete("{id:long}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeletePerson([FromRoute(Name = "id")] long id) => + await peopleBusinessLogic.DeletePerson(id); + + #endregion + + #region Rating + + [HttpGet("{id:long}/rating")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetPersonRating([FromRoute(Name = "id")] long id) => + await peopleBusinessLogic.GetPersonRating(id); + + [HttpGet("{id:long}/rating/{account_id:long}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetPersonUserRating([FromRoute(Name = "id")] long id, [FromRoute(Name = "account_id")] long accountId) => + await peopleBusinessLogic.GetPersonUserRating(id, accountId); + + #endregion + + #region View Count + + [HttpPut("{id:long}/view_count")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task PutPeopleViewCount([FromRoute(Name = "id")] long id) => + await peopleBusinessLogic.PutPeopleViewCount(id); + + #endregion + + #region Picture + + [HttpGet("{id:long}/picture")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetPersonPicture([FromRoute(Name = "id")] long id) => + await peopleBusinessLogic.GetPersonPicture(id); + + [HttpPut("{id:long}/picture")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutPersonPicture([FromRoute(Name = "id")] long id, [FromBody] ImageRequest body) => + await peopleBusinessLogic.PutPersonPicture(id, body); + + [HttpDelete("{id:long}/picture")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeletePersonPicture([FromRoute(Name = "id")] long id) => + await peopleBusinessLogic.DeletePersonPicture(id); + + #endregion +} diff --git a/WatchIt.WebAPI/Controllers/PhotosController.cs b/WatchIt.WebAPI/Controllers/PhotosController.cs new file mode 100644 index 0000000..245aa96 --- /dev/null +++ b/WatchIt.WebAPI/Controllers/PhotosController.cs @@ -0,0 +1,72 @@ +using Ardalis.Result; +using Ardalis.Result.AspNetCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.BusinessLogic.Photos; +using WatchIt.WebAPI.Constants; + +namespace WatchIt.WebAPI.Controllers; + +[ApiController] +[Route("photos")] +public class PhotosController(IPhotosBusinessLogic photosBusinessLogic) : ControllerBase +{ + #region Main + + [HttpGet("{id:guid}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetPhoto([FromRoute(Name = "id")] Guid id) => + await photosBusinessLogic.GetPhoto(id); + + [HttpGet] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetPhotos([FromQuery] PhotoFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await photosBusinessLogic.GetPhotos(filterQuery, orderQuery, pagingQuery); + + [HttpPost] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostPhoto([FromBody] PhotoRequest body) => + await photosBusinessLogic.PostPhoto(body); + + [HttpPut("{id:guid}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutPhoto([FromRoute(Name = "id")] Guid id, [FromBody] PhotoRequest body) => + await photosBusinessLogic.PutPhoto(id, body); + + [HttpDelete("{id:guid}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeletePhoto([FromRoute(Name = "id")] Guid id) => + await photosBusinessLogic.DeletePhoto(id); + + #endregion + + #region Background + + [HttpGet("background")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetPhotoBackground() => + await photosBusinessLogic.GetPhotoBackground(); + + [HttpPut("{photo_id:guid}/background")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutPhotoBackground([FromRoute(Name = "photo_id")] Guid photoId, [FromBody] PhotoBackgroundRequest body) => + await photosBusinessLogic.PutPhotoBackground(photoId, body); + + [HttpDelete("{photo_id:guid}/background")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeletePhotoBackground([FromRoute(Name = "photo_id")] Guid photoId) => + await photosBusinessLogic.DeletePhotoBackground(photoId); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Controllers/RolesController.cs b/WatchIt.WebAPI/Controllers/RolesController.cs new file mode 100644 index 0000000..39092d6 --- /dev/null +++ b/WatchIt.WebAPI/Controllers/RolesController.cs @@ -0,0 +1,162 @@ +using Ardalis.Result; +using Ardalis.Result.AspNetCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using WatchIt.DTO.Models.Controllers.Roles.Role.Query; +using WatchIt.DTO.Models.Controllers.Roles.Role.Request; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType; +using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; +using WatchIt.WebAPI.BusinessLogic.Roles; +using WatchIt.WebAPI.Constants; + +namespace WatchIt.WebAPI.Controllers; + +[ApiController] +[Route("roles")] +public class RolesController(IRolesBusinessLogic rolesBusinessLogic) : ControllerBase +{ + #region Main - CRUD + + [HttpGet("actors")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetRoleActors([FromQuery] RoleActorFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await rolesBusinessLogic.GetRoleActors(filterQuery, orderQuery, pagingQuery); + + [HttpGet("actors/{id:guid}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetRoleActor([FromRoute] Guid id) => + await rolesBusinessLogic.GetRoleActor(id); + + [HttpGet("creators")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetRoleCreators([FromQuery] RoleCreatorFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await rolesBusinessLogic.GetRoleCreators(filterQuery, orderQuery, pagingQuery); + + [HttpGet("creators/{id:guid}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetRoleCreator([FromRoute] Guid id) => + await rolesBusinessLogic.GetRoleCreator(id); + + [HttpPost("actors")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostRoleActor([FromBody] RoleActorRequest body) => + await rolesBusinessLogic.PostRoleActor(body); + + [HttpPost("creators")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostRoleCreator([FromBody] RoleCreatorRequest body) => + await rolesBusinessLogic.PostRoleCreator(body); + + [HttpPut("actors/{id:guid}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutRoleActor([FromRoute] Guid id, [FromBody] RoleActorRequest body) => + await rolesBusinessLogic.PutRoleActor(id, body); + + [HttpPut("creators/{id:guid}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PutRoleCreator([FromRoute] Guid id, [FromBody] RoleCreatorRequest body) => + await rolesBusinessLogic.PutRoleCreator(id, body); + + [HttpDelete("{id:guid}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeleteRole([FromRoute] Guid id) => + await rolesBusinessLogic.DeleteRole(id); + + #endregion + + #region Main - Rating + + [HttpGet("{id:guid}/rating")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetRoleRating([FromRoute] Guid id) => + await rolesBusinessLogic.GetRoleRating(id); + + [HttpGet("{id:guid}/rating/{account_id:long}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetRoleUserRating([FromRoute] Guid id, [FromRoute(Name = "account_id")] long accountId) => + await rolesBusinessLogic.GetRoleUserRating(id, accountId); + + [HttpPut("{id:guid}/rating")] + [Authorize] + [TranslateResultToActionResult] + public async Task PutRoleRating([FromRoute] Guid id, [FromBody] RatingRequest body) => + await rolesBusinessLogic.PutRoleRating(id, body); + + [HttpDelete("{id:guid}/rating")] + [Authorize] + [TranslateResultToActionResult] + public async Task DeleteRoleRating([FromRoute] Guid id) => + await rolesBusinessLogic.DeleteRoleRating(id); + + #endregion + + #region ActorTypes + + [HttpGet("actors/types")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetRoleActorTypes([FromQuery] RoleActorTypeFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await rolesBusinessLogic.GetRoleActorTypes(filterQuery, orderQuery, pagingQuery); + + [HttpGet("actors/types/{role_actor_type_id}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetRoleActorType([FromRoute(Name = "role_actor_type_id")] short roleActorTypeId) => + await rolesBusinessLogic.GetRoleActorType(roleActorTypeId); + + [HttpPost("actors/types")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostRoleActorType([FromBody] RoleActorTypeRequest body) => + await rolesBusinessLogic.PostRoleActorType(body); + + [HttpDelete("actors/types/{role_actor_type_id}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeleteRoleActorType([FromRoute(Name = "role_actor_type_id")] short roleActorTypeId) => + await rolesBusinessLogic.DeleteRoleActorType(roleActorTypeId); + + #endregion + + #region CreatorTypes + + [HttpGet("creators/types")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task>> GetRoleCreatorTypes([FromQuery] RoleCreatorTypeFilterQuery filterQuery, [FromQuery] OrderQuery orderQuery, [FromQuery] PagingQuery pagingQuery) => + await rolesBusinessLogic.GetRoleCreatorTypes(filterQuery, orderQuery, pagingQuery); + + [HttpGet("creators/types/{role_creator_type_id}")] + [AllowAnonymous] + [TranslateResultToActionResult] + public async Task> GetRoleCreatorType([FromRoute(Name = "role_creator_type_id")] short roleCreatorTypeId) => + await rolesBusinessLogic.GetRoleCreatorType(roleCreatorTypeId); + + [HttpPost("creators/types")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task> PostRoleCreatorType([FromBody] RoleCreatorTypeRequest body) => + await rolesBusinessLogic.PostRoleCreatorType(body); + + [HttpDelete("creators/types/{role_creator_type_id}")] + [Authorize(Policy = Policies.Admin)] + [TranslateResultToActionResult] + public async Task DeleteRoleCreatorType([FromRoute(Name = "role_creator_type_id")] short roleCreatorTypeId) => + await rolesBusinessLogic.DeleteRoleCreatorType(roleCreatorTypeId); + + #endregion +} diff --git a/WatchIt.WebAPI/WatchIt.WebAPI/Dockerfile b/WatchIt.WebAPI/Dockerfile similarity index 53% rename from WatchIt.WebAPI/WatchIt.WebAPI/Dockerfile rename to WatchIt.WebAPI/Dockerfile index e6f8052..873de8f 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI/Dockerfile +++ b/WatchIt.WebAPI/Dockerfile @@ -1,21 +1,23 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base USER $APP_UID WORKDIR /app EXPOSE 8080 EXPOSE 8081 -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src -COPY [".", "/src"] -RUN dotnet restore "WatchIt.WebAPI/WatchIt.WebAPI/WatchIt.WebAPI.csproj" -WORKDIR "/src/WatchIt.WebAPI/WatchIt.WebAPI" +COPY ["WatchIt.WebAPI/WatchIt.WebAPI.csproj", "WatchIt.WebAPI/"] +COPY ["WatchIt.Database/WatchIt.Database.csproj", "WatchIt.Database/"] +COPY ["WatchIt.DTO/WatchIt.DTO.csproj", "WatchIt.DTO/"] +RUN dotnet restore "WatchIt.WebAPI/WatchIt.WebAPI.csproj" +COPY . . +WORKDIR "/src/WatchIt.WebAPI" RUN dotnet build "WatchIt.WebAPI.csproj" -c $BUILD_CONFIGURATION -o /app/build FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "WatchIt.WebAPI.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false -RUN dotnet dev-certs https --trust FROM base AS final WORKDIR /app diff --git a/WatchIt.WebAPI/Helpers/PasswordHelpers.cs b/WatchIt.WebAPI/Helpers/PasswordHelpers.cs new file mode 100644 index 0000000..7f93fbf --- /dev/null +++ b/WatchIt.WebAPI/Helpers/PasswordHelpers.cs @@ -0,0 +1,50 @@ +using System.Security.Cryptography; +using System.Text; +using SimpleToolkit.Extensions; +using WatchIt.DTO.Models.Controllers.Accounts; + +namespace WatchIt.WebAPI.Helpers; + +public static class PasswordHelpers +{ + #region CONSTANTS + + private const string RandomPasswordCharacters = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890!@#$%^&*()-_=+[{]};:'\"\\|,<.>/?"; + + #endregion + + + + #region PUBLIC METHODS + + public static PasswordData GeneratePasswordData(string password) + { + string leftSalt = StringExtensions.CreateRandom(20, RandomPasswordCharacters); + string rightSalt = StringExtensions.CreateRandom(20, RandomPasswordCharacters); + byte[] hash = ComputeHash(password, leftSalt, rightSalt); + return new PasswordData + { + LeftSalt = leftSalt, + RightSalt = rightSalt, + PasswordHash = hash, + }; + } + + public static byte[] ComputeHash(string password, string leftSalt, string rightSalt) + { + string stringToHash = $"{leftSalt}{password}{rightSalt}"; + byte[] encodedString = Encoding.UTF8.GetBytes(stringToHash); + byte[] hash = SHA512.HashData(encodedString); + return hash; + } + + public static bool ValidatePassword(string password, PasswordData passwordData) + { + byte[] checkedHash = ComputeHash(password, passwordData.LeftSalt, passwordData.RightSalt); + byte[] actualHash = passwordData.PasswordHash; + bool result = checkedHash.SequenceEqual(actualHash); + return result; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Program.cs b/WatchIt.WebAPI/Program.cs new file mode 100644 index 0000000..37fe72f --- /dev/null +++ b/WatchIt.WebAPI/Program.cs @@ -0,0 +1,206 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Reflection; +using System.Text; +using System.Text.Json; +using Delta; +using FluentValidation; +using FluentValidation.AspNetCore; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.HttpLogging; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.JsonWebTokens; +using Microsoft.IdentityModel.Tokens; +using WatchIt.Database; +using WatchIt.DTO; +using WatchIt.DTO.Converters; +using WatchIt.WebAPI.BusinessLogic.Accounts; +using WatchIt.WebAPI.BusinessLogic.Authentication; +using WatchIt.WebAPI.BusinessLogic.Genders; +using WatchIt.WebAPI.BusinessLogic.Genres; +using WatchIt.WebAPI.BusinessLogic.Media; +using WatchIt.WebAPI.BusinessLogic.People; +using WatchIt.WebAPI.BusinessLogic.Photos; +using WatchIt.WebAPI.BusinessLogic.Roles; +using WatchIt.WebAPI.Constants; +using WatchIt.WebAPI.Repositories.Accounts; +using WatchIt.WebAPI.Repositories.Genders; +using WatchIt.WebAPI.Repositories.Genres; +using WatchIt.WebAPI.Repositories.Media; +using WatchIt.WebAPI.Repositories.People; +using WatchIt.WebAPI.Repositories.Photos; +using WatchIt.WebAPI.Repositories.Roles; +using WatchIt.WebAPI.Services.Tokens; +using WatchIt.WebAPI.Services.User; + +namespace WatchIt.WebAPI; + +public static class Program +{ + #region PUBLIC METHODS + + public static void Main(string[] args) + { + WebApplicationBuilder builder = WebApplication.CreateBuilder(args); + builder.SetupAuthentication(); + builder.SetupDatabases(); + builder.Services.AddRepositories(); + builder.Services.AddHttpContextAccessor(); + builder.Services.AddServices(); + builder.Services.AddBusinessLogic(); + builder.Services.AddWorkers(); + builder.Services.AddFluentValidation(); + builder.Services.AddControllers() + .AddJsonOptions(x => + { + x.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower; + x.JsonSerializerOptions.Converters.Add(new ColorJsonConverter()); + }); + builder.Services.AddOpenApi(); + builder.Services.AddHttpLogging(o => { o.LoggingFields |= HttpLoggingFields.RequestQuery; }); + + + WebApplication app = builder.Build(); + + app.UseHttpLogging(); + + app.UseDelta(); + + app.InitializeDatabase(); + + if (app.Environment.IsDevelopment()) + { + app.MapOpenApi(); + } + + app.UseHttpsRedirection(); + + app.UseAuthentication(); + app.UseAuthorization(); + + app.MapControllers(); + + app.Run(); + } + + #endregion + + + + #region PRIVATE METHODS + + private static void AddRepositories(this IServiceCollection services) + { + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + } + + private static void AddServices(this IServiceCollection services) + { + services.AddTransient(); + services.AddTransient(); + } + + private static void AddBusinessLogic(this IServiceCollection services) + { + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + } + + private static void AddWorkers(this IServiceCollection services) + { + + } + + private static void AddFluentValidation(this IServiceCollection services) + { + services.AddValidatorsFromAssembly(Assembly.GetAssembly(typeof(CustomValidators))); + services.AddFluentValidationAutoValidation(); + } + + private static WebApplicationBuilder SetupAuthentication(this WebApplicationBuilder builder) + { + string issuer = builder.Configuration.GetValue("Authentication:JWT:Issuer")!; + string audience = builder.Configuration.GetValue("Authentication:JWT:Audience")!; + string key = builder.Configuration.GetValue("Authentication:JWT:Key")!; + byte[] encodedKey = Encoding.UTF8.GetBytes(key); + + JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear(); + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + + builder.Services + .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(x => + { + x.RequireHttpsMetadata = false; + x.SaveToken = true; + x.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ValidIssuer = issuer, + ValidAudience = audience, + IssuerSigningKey = new SymmetricSecurityKey(encodedKey), + ClockSkew = TimeSpan.FromMinutes(1), + }; + x.Events = new JwtBearerEvents + { + OnAuthenticationFailed = context => + { + if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) + { + context.Response.Headers.Append("Token-Expired", "true"); + } + return Task.CompletedTask; + } + }; + }); + builder.Services + .AddAuthorization(options => + { + options.AddPolicy(Policies.Admin, policy => policy.RequireAuthenticatedUser() + .RequireClaim(AdditionalClaimNames.Admin, bool.TrueString)); + }); + + return builder; + } + + private static WebApplicationBuilder SetupDatabases(this WebApplicationBuilder builder) + { + builder.Services + .AddDbContext(x => x.UseNpgsql(builder.Configuration + .GetConnectionString("Database")), + ServiceLifetime.Transient); + return builder; + } + + private static void InitializeDatabase(this WebApplication app) + { + using (IServiceScope scope = app.Services.CreateScope()) + { + DatabaseContext database = scope.ServiceProvider.GetRequiredService(); + + while (!database.Database.CanConnect()) + { + app.Logger.LogInformation("Waiting for database..."); + Thread.Sleep(1000); + } + + database.Database.Migrate(); + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Properties/launchSettings.json b/WatchIt.WebAPI/Properties/launchSettings.json new file mode 100644 index 0000000..5916c32 --- /dev/null +++ b/WatchIt.WebAPI/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5128", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7027;http://localhost:5128", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/WatchIt.WebAPI/Repositories/Accounts/AccountsRepository.cs b/WatchIt.WebAPI/Repositories/Accounts/AccountsRepository.cs new file mode 100644 index 0000000..7a4dfb4 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Accounts/AccountsRepository.cs @@ -0,0 +1,130 @@ +using Microsoft.EntityFrameworkCore; +using WatchIt.Database; +using WatchIt.Database.Model.Accounts; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Accounts; + +public class AccountsRepository : Repository, IAccountsRepository +{ + #region CONSTRUCTORS + + public AccountsRepository(DatabaseContext database) : base(database) {} + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task ExistsAsync(long id) => + await DefaultSet.AnyAsync(x => x.Id == id); + + public async Task GetAsync(long id, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task GetByUsernameOrEmailAsync(string usernameOrEmail, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Username == usernameOrEmail || x.Email == usernameOrEmail); + + public async Task> GetAllAsync(AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, AccountOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + #endregion + + #region Profile picture + + public async Task GetProfilePictureAsync(long id, Func, IQueryable>? additionalIncludes = null) => + await Database.AccountProfilePictures + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.AccountId == id); + + public async Task UpdateOrAddProfilePictureAsync(long id, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(await GetProfilePictureAsync(id), addFunc, updateFunc); + + public async Task DeleteProfilePictureAsync(long id) => + await DeleteAsync(x => x.AccountId == id); + + #endregion + + #region Background picture + + public async Task GetBackgroundPictureAsync(long id, Func, IQueryable>? additionalIncludes = null) => + await Database.AccountBackgroundPictures + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.AccountId == id); + + public async Task UpdateOrAddBackgroundPictureAsync(long id, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(await GetBackgroundPictureAsync(id, x => x.Include(y => y.Background) + .ThenInclude(y => y.Photo)), addFunc, updateFunc); + + public async Task DeleteBackgroundPictureAsync(long id) => + await DeleteAsync(x => x.AccountId == id); + + #endregion + + #region Follow + + public async Task FollowExistsAsync(long followerId, long followedId) => + await Database.AccountFollows + .AnyAsync(x => x.FollowerId == followerId && x.FollowedId == followedId); + + public async Task> GetFollowsAsync(long id, AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await Database.Accounts + .Where(x => x.Followers + .Any(y => y.Id == id)) + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, AccountOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task> GetFollowersAsync(long id, AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await Database.Accounts + .Where(x => x.Follows + .Any(y => y.Id == id)) + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, AccountOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task AddFollowAsync(AccountFollow entity) => + await AddAsync(entity); + + public async Task DeleteFollowAsync(long followerId, long followedId) => + await DeleteAsync(x => x.FollowerId == followerId && x.FollowedId == followedId); + + #endregion + + #region Refresh token + + public async Task UpdateRefreshTokenAsync(AccountRefreshToken refreshToken, Action updateFunc) => + await UpdateAsync(refreshToken, updateFunc); + + public async Task AddRefreshTokenAsync(AccountRefreshToken refreshToken) => + await AddAsync(refreshToken); + + public async Task DeleteRefreshTokenAsync(Guid refreshTokenId) => + await DeleteAsync(x => x.Token == refreshTokenId); + + public async Task DeleteUserRefreshTokensAsync(long id) + { + IQueryable tokens = Database.AccountRefreshTokens.Where(x => x.AccountId == id); + Database.AccountRefreshTokens.AttachRange(tokens); + Database.AccountRefreshTokens.RemoveRange(tokens); + await Database.SaveChangesAsync(); + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Accounts/IAccountsRepository.cs b/WatchIt.WebAPI/Repositories/Accounts/IAccountsRepository.cs new file mode 100644 index 0000000..84849d8 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Accounts/IAccountsRepository.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using WatchIt.Database.Model.Accounts; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Accounts; + +public interface IAccountsRepository : IRepository +{ + Task ExistsAsync(long id); + Task GetAsync(long id, Func, IQueryable>? additionalIncludes = null); + Task GetByUsernameOrEmailAsync(string usernameOrEmail, Func, IQueryable>? additionalIncludes = null); + Task> GetAllAsync(AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + + Task GetProfilePictureAsync(long id, Func, IQueryable>? additionalIncludes = null); + Task UpdateOrAddProfilePictureAsync(long id, Func addFunc, Action updateFunc); + Task DeleteProfilePictureAsync(long id); + + Task FollowExistsAsync(long followerId, long followedId); + Task> GetFollowsAsync(long id, AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task> GetFollowersAsync(long id, AccountFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task AddFollowAsync(AccountFollow entity); + Task DeleteFollowAsync(long followerId, long followedId); + + Task GetBackgroundPictureAsync(long id, Func, IQueryable>? additionalIncludes = null); + Task UpdateOrAddBackgroundPictureAsync(long id, Func addFunc, Action updateFunc); + Task DeleteBackgroundPictureAsync(long id); + + Task UpdateRefreshTokenAsync(AccountRefreshToken refreshToken, Action updateFunc); + Task AddRefreshTokenAsync(AccountRefreshToken refreshToken); + Task DeleteRefreshTokenAsync(Guid refreshTokenId); + Task DeleteUserRefreshTokensAsync(long id); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Genders/GendersRepository.cs b/WatchIt.WebAPI/Repositories/Genders/GendersRepository.cs new file mode 100644 index 0000000..b1fa539 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Genders/GendersRepository.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore; +using WatchIt.Database; +using WatchIt.Database.Model.Genders; +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Genders; + +public class GendersRepository : Repository, IGendersRepository +{ + #region CONSTRUCTORS + + public GendersRepository(DatabaseContext database) : base(database) {} + + #endregion + + + + #region PUBLIC METHODS + + public async Task ExistsAsync(short id) => + await DefaultSet.AnyAsync(x => x.Id == id); + + public async Task GetAsync(short id, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task> GetAllAsync(GenderFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, GenderOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Genders/IGendersRepository.cs b/WatchIt.WebAPI/Repositories/Genders/IGendersRepository.cs new file mode 100644 index 0000000..5f67929 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Genders/IGendersRepository.cs @@ -0,0 +1,12 @@ +using WatchIt.Database.Model.Genders; +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Genders; + +public interface IGendersRepository : IRepository +{ + Task ExistsAsync(short id); + Task GetAsync(short id, Func, IQueryable>? additionalIncludes = null); + Task> GetAllAsync(GenderFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Genres/GenresRepository.cs b/WatchIt.WebAPI/Repositories/Genres/GenresRepository.cs new file mode 100644 index 0000000..4445aa1 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Genres/GenresRepository.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore; +using WatchIt.Database; +using WatchIt.Database.Model.Genres; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Genres; + +public class GenresRepository : Repository, IGenresRepository +{ + #region CONSTRUCTORS + + public GenresRepository(DatabaseContext database) : base(database) {} + + #endregion + + + + #region PUBLIC METHODS + + public async Task ExistsAsync(short id) => + await DefaultSet.AnyAsync(x => x.Id == id); + + public async Task GetAsync(short id, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task> GetAllAsync(GenreFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, GenreOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Genres/IGenresRepository.cs b/WatchIt.WebAPI/Repositories/Genres/IGenresRepository.cs new file mode 100644 index 0000000..6b69868 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Genres/IGenresRepository.cs @@ -0,0 +1,12 @@ +using WatchIt.Database.Model.Genres; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Genres; + +public interface IGenresRepository : IRepository +{ + Task ExistsAsync(short id); + Task GetAsync(short id, Func, IQueryable>? additionalIncludes = null); + Task> GetAllAsync(GenreFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/IRepository.cs b/WatchIt.WebAPI/Repositories/IRepository.cs new file mode 100644 index 0000000..2762e31 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/IRepository.cs @@ -0,0 +1,15 @@ +using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories; + +public interface IRepository where T : class +{ + public Task> GetAllAsync(Func, IQueryable>? additionalIncludes = null); + public Task UpdateAsync(T entity, Action updateFunc); + public Task AddAsync(T entity); + public Task UpdateOrAddAsync(T? entity, Func addFunc, Action updateFunc); + public Task DeleteAsync(T entity); + public Task DeleteAsync(Expression> predicate); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Media/IMediaRepository.cs b/WatchIt.WebAPI/Repositories/Media/IMediaRepository.cs new file mode 100644 index 0000000..b11118c --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Media/IMediaRepository.cs @@ -0,0 +1,35 @@ +using WatchIt.Database.Model.Genres; +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Media; + +public interface IMediaRepository : IRepository +{ + Task ExistsAsync(long id); + Task GetAsync(long id, Func, IQueryable>? additionalIncludes = null); + Task GetAsync(long id, Func, IQueryable>? additionalIncludes = null) where T : Medium; + Task> GetAllAsync(MediumFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task> GetAllMoviesAsync(MediumMovieFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task> GetAllSeriesAsync(MediumSeriesFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task UpdateAsync(long id, Action updateFunc) where T : Medium; + + Task> GetMediumGenresAsync(long id, GenreFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task AddMediumGenreAsync(long mediumId, short genreId); + Task DeleteMediumGenreAsync(long mediumId, short genreId); + + Task> GetAllRatedByAccountAsync(long accountId, MediumFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task> GetAllMoviesRatedByAccountAsync(long accountId, MediumMovieFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task> GetAllSeriesRatedByAccountAsync(long accountId, MediumSeriesFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task GetMediumUserRatingAsync(long mediumId, long accountId, Func, IQueryable>? additionalIncludes = null); + Task UpdateOrAddMediumRatingAsync(long mediumId, long accountId, Func addFunc, Action updateFunc); + Task DeleteMediumUserRatingAsync(long mediumId, long accountId); + + Task UpdateOrAddMediumViewCountAsync(long mediumId, DateOnly date, Func addFunc, Action updateFunc); + + Task GetMediumPictureAsync(long id, Func, IQueryable>? additionalIncludes = null); + Task UpdateOrAddMediumPictureAsync(long id, Func addFunc, Action updateFunc); + Task DeleteMediumPictureAsync(long id); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Media/MediaRepository.cs b/WatchIt.WebAPI/Repositories/Media/MediaRepository.cs new file mode 100644 index 0000000..b8a004c --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Media/MediaRepository.cs @@ -0,0 +1,175 @@ +using Microsoft.EntityFrameworkCore; +using WatchIt.Database; +using WatchIt.Database.Model.Genres; +using WatchIt.Database.Model.Media; +using WatchIt.Database.Model.Photos; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Models.Controllers.Media.Medium; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Media; + +public class MediaRepository : Repository, IMediaRepository +{ + #region CONSTRUCTORS + + public MediaRepository(DatabaseContext database) : base(database) {} + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task ExistsAsync(long id) => + await DefaultSet.AnyAsync(x => x.Id == id); + + public async Task GetAsync(long id, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task GetAsync(long id, Func, IQueryable>? additionalIncludes = null) where T : Medium => + await DefaultSet.OfType() + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task> GetAllAsync(MediumFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.ApplyFilter(filterQuery) + .OrderByDescending(x => x.Id) + .ApplyOrder(orderQuery, MediumOrderKeys.Base(), MediumOrderKeys.Medium) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task> GetAllMoviesAsync(MediumMovieFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.OfType() + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, MediumOrderKeys.Base(), MediumOrderKeys.MediumMovie) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task> GetAllSeriesAsync(MediumSeriesFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.OfType() + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, MediumOrderKeys.Base(), MediumOrderKeys.MediumSeries) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task UpdateAsync(long id, Action updateFunc) where T : Medium + { + T? entity = await GetAsync(id); + if (entity is null) + { + return false; + } + + updateFunc(entity); + DefaultSet.Update(entity); + await Database.SaveChangesAsync(); + return true; + } + + #endregion + + #region Genres + + public async Task> GetMediumGenresAsync(long id, GenreFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await Database.Set() + .Where(x => x.MediumId == id) + .Select(x => x.Genre) + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, GenreOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task AddMediumGenreAsync(long mediumId, short genreId) + { + if (!Database.Set().Any(x => x.MediumId == mediumId && x.GenreId == genreId)) + { + await AddAsync(new MediumGenre { MediumId = mediumId, GenreId = genreId }); + } + } + + public async Task DeleteMediumGenreAsync(long mediumId, short genreId) => + await DeleteAsync(new MediumGenre { MediumId = mediumId, GenreId = genreId }); + + #endregion + + #region Rating + + public async Task> GetAllRatedByAccountAsync(long accountId, MediumFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Where(x => x.Ratings + .Any(y => y.AccountId == accountId)) + .ApplyFilter(filterQuery) + .ApplyFilter(userRatedFilterQuery) + .ApplyOrder(orderQuery, MediumOrderKeys.Base(), MediumOrderKeys.Medium, MediumOrderKeys.MediumUserRated(accountId)) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task> GetAllMoviesRatedByAccountAsync(long accountId, MediumMovieFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.OfType() + .Where(x => x.Ratings + .Any(y => y.AccountId == accountId)) + .ApplyFilter(filterQuery) + .ApplyFilter(userRatedFilterQuery) + .ApplyOrder(orderQuery, MediumOrderKeys.Base(), MediumOrderKeys.MediumMovie, MediumOrderKeys.MediumUserRated(accountId)) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task> GetAllSeriesRatedByAccountAsync(long accountId, MediumSeriesFilterQuery filterQuery, MediumUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.OfType() + .Where(x => x.Ratings + .Any(y => y.AccountId == accountId)) + .ApplyFilter(filterQuery) + .ApplyFilter(userRatedFilterQuery) + .ApplyOrder(orderQuery, MediumOrderKeys.Base(), MediumOrderKeys.MediumSeries, MediumOrderKeys.MediumUserRated(accountId)) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task GetMediumUserRatingAsync(long mediumId, long accountId, Func, IQueryable>? additionalIncludes = null) => + await Database.Set() + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.MediumId == mediumId && x.AccountId == accountId); + + public async Task UpdateOrAddMediumRatingAsync(long mediumId, long accountId, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(await GetMediumUserRatingAsync(mediumId, accountId), addFunc, updateFunc); + + public async Task DeleteMediumUserRatingAsync(long mediumId, long accountId) => + await DeleteAsync(x => x.MediumId == mediumId && x.AccountId == accountId); + + #endregion + + #region View count + + public async Task UpdateOrAddMediumViewCountAsync(long mediumId, DateOnly date, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(await Database.Set() + .FirstOrDefaultAsync(x => x.MediumId == mediumId && x.Date == date), addFunc, updateFunc); + + #endregion + + #region Picture + + public async Task GetMediumPictureAsync(long id, Func, IQueryable>? additionalIncludes = null) => + await Database.MediumPictures + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.MediumId == id); + + public async Task UpdateOrAddMediumPictureAsync(long id, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(await GetMediumPictureAsync(id), addFunc, updateFunc); + + public async Task DeleteMediumPictureAsync(long id) => + await DeleteAsync(new MediumPicture { MediumId = id }); + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/People/IPeopleRepository.cs b/WatchIt.WebAPI/Repositories/People/IPeopleRepository.cs new file mode 100644 index 0000000..62f71af --- /dev/null +++ b/WatchIt.WebAPI/Repositories/People/IPeopleRepository.cs @@ -0,0 +1,22 @@ +using WatchIt.Database.Model.People; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.People; + +public interface IPeopleRepository : IRepository +{ + Task ExistsAsync(long id); + Task GetAsync(long id, Func, IQueryable>? additionalIncludes = null); + Task> GetAllAsync(PersonFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task UpdateAsync(long id, Action updateFunc, Func, IQueryable>? additionalIncludes = null); + Task DeleteAsync(long id); + + Task UpdateOrAddPersonViewCountAsync(long personId, DateOnly date, Func addFunc, Action updateFunc); + + Task GetPersonPictureAsync(long id, Func, IQueryable>? additionalIncludes = null); + Task UpdateOrAddPersonPictureAsync(long id, Func addFunc, Action updateFunc); + Task DeletePersonPictureAsync(long id); + + Task> GetAllRatedByAccountAsync(long accountId, PersonFilterQuery filterQuery, PersonUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/People/PeopleRepository.cs b/WatchIt.WebAPI/Repositories/People/PeopleRepository.cs new file mode 100644 index 0000000..88daeb2 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/People/PeopleRepository.cs @@ -0,0 +1,94 @@ +using Microsoft.EntityFrameworkCore; +using WatchIt.Database; +using WatchIt.Database.Model.People; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.People; + +public class PeopleRepository : Repository, IPeopleRepository +{ + #region CONSTRUCTORS + + public PeopleRepository(DatabaseContext database) : base(database) {} + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task ExistsAsync(long id) => + await DefaultSet.AnyAsync(x => x.Id == id); + + public async Task GetAsync(long id, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task> GetAllAsync(PersonFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, PersonOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task UpdateAsync(long id, Action updateFunc, Func, IQueryable>? additionalIncludes = null) + { + Person? person = await GetAsync(id, additionalIncludes); + if (person is null) + { + return false; + } + await UpdateAsync(person, updateFunc); + return true; + } + + public async Task DeleteAsync(long id) => + await DeleteAsync(new Person { Id = id }); + + #endregion + + #region View count + + public async Task UpdateOrAddPersonViewCountAsync(long personId, DateOnly date, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(await Database.PersonViewCounts + .FirstOrDefaultAsync(x => x.PersonId == personId && x.Date == date), addFunc, updateFunc); + + #endregion + + #region Picture + + public async Task GetPersonPictureAsync(long id, Func, IQueryable>? additionalIncludes = null) => + await Database.PersonPictures + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.PersonId == id); + + public async Task UpdateOrAddPersonPictureAsync(long id, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(await GetPersonPictureAsync(id), addFunc, updateFunc); + + public async Task DeletePersonPictureAsync(long id) => + await DeleteAsync(new PersonPicture { PersonId = id }); + + #endregion + + #region Rating + + public async Task> GetAllRatedByAccountAsync(long accountId, PersonFilterQuery filterQuery, PersonUserRatedFilterQuery userRatedFilterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Where(x => x.Roles + .SelectMany(y => y.Ratings) + .Any(y => y.AccountId == accountId)) + .ApplyFilter(filterQuery) + .ApplyFilter(userRatedFilterQuery) + .ApplyOrder(orderQuery, PersonOrderKeys.Base, PersonOrderKeys.UserRated(accountId)) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Photos/IPhotosRepository.cs b/WatchIt.WebAPI/Repositories/Photos/IPhotosRepository.cs new file mode 100644 index 0000000..431e088 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Photos/IPhotosRepository.cs @@ -0,0 +1,21 @@ +using WatchIt.Database.Model.Photos; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Photos; + +public interface IPhotosRepository : IRepository +{ + Task ExistsAsync(Guid id); + Task GetAsync(Guid id, Func, IQueryable>? additionalIncludes = null); + Task> GetAllAsync(PhotoFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task GetPhotoRandomBackgroundAsync(Func, IQueryable>? additionalIncludes = null); + Task UpdateAsync(Guid id, Action updateFunc); + Task DeleteAsync(Guid id); + + Task AddPhotoBackgroundAsync(PhotoBackground photoBackground); + Task UpdateOrAddPhotoBackgroundAsync(Guid photoId, Func addFunc, Action updateFunc); + Task DeletePhotoBackgroundAsync(Guid photoId); + + Task GetPhotoRandomBackgroundByMediumAsync(long mediumId, Func, IQueryable>? additionalIncludes = null); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Photos/PhotosRepository.cs b/WatchIt.WebAPI/Repositories/Photos/PhotosRepository.cs new file mode 100644 index 0000000..1db8fbf --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Photos/PhotosRepository.cs @@ -0,0 +1,112 @@ +using Microsoft.EntityFrameworkCore; +using WatchIt.Database; +using WatchIt.Database.Model.Photos; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Photos; + +public class PhotosRepository : Repository, IPhotosRepository +{ + #region CONSTRUCTORS + + public PhotosRepository(DatabaseContext database) : base(database) {} + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task ExistsAsync(Guid id) => + await DefaultSet.AnyAsync(x => x.Id == id); + + public async Task GetAsync(Guid id, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task> GetAllAsync(PhotoFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, PhotoOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task GetPhotoRandomBackgroundAsync(Func, IQueryable>? additionalIncludes = null) + { + IQueryable query = DefaultSet.Where(x => x.Background != null && x.Background.IsUniversal); + int count = await query.CountAsync(); + int randomIndex = Random.Shared.Next(count); + return await query.Include(additionalIncludes) + .ElementAtAsync(randomIndex); + } + + public async Task UpdateAsync(Guid id, Action updateFunc) + { + Photo? entity = await GetAsync(id); + if (entity is null) + { + return false; + } + + updateFunc(entity); + DefaultSet.Update(entity); + await Database.SaveChangesAsync(); + return true; + } + + public async Task DeleteAsync(Guid id) + { + await DeleteAsync(x => x.PhotoId == id); + await DeleteAsync(x => x.Id == id); + } + + #endregion + + #region Background + + public async Task AddPhotoBackgroundAsync(PhotoBackground photoBackground) + { + await Database.PhotoBackgrounds.AddAsync(photoBackground); + await Database.SaveChangesAsync(); + } + + public async Task UpdateOrAddPhotoBackgroundAsync(Guid photoId, Func addFunc, Action updateFunc) + { + PhotoBackground? entity = await Database.PhotoBackgrounds.FirstOrDefaultAsync(x => x.PhotoId == photoId); + if (entity is null) + { + entity = addFunc(); + await Database.PhotoBackgrounds.AddAsync(entity); + } + else + { + updateFunc(entity); + Database.PhotoBackgrounds.Update(entity); + } + await Database.SaveChangesAsync(); + return entity; + } + + public async Task DeletePhotoBackgroundAsync(Guid photoId) => + await DeleteAsync(x => x.PhotoId == photoId); + + #endregion + + #region Medium + + public async Task GetPhotoRandomBackgroundByMediumAsync(long mediumId, Func, IQueryable>? additionalIncludes = null) + { + IQueryable query = DefaultSet.Where(x => x.MediumId == mediumId && x.Background != null); + int count = await query.CountAsync(); + int randomIndex = Random.Shared.Next(count); + return await query.Include(additionalIncludes) + .ElementAtAsync(randomIndex); + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/QueryableExtensions.cs b/WatchIt.WebAPI/Repositories/QueryableExtensions.cs new file mode 100644 index 0000000..4340bc1 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/QueryableExtensions.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Query; + +namespace WatchIt.WebAPI.Repositories; + +public static class QueryableExtensions +{ + internal static IQueryable Include(this IQueryable queryable, Func, IQueryable>? additionalIncludes = null) + { + if (additionalIncludes is not null) + { + queryable = additionalIncludes(queryable); + } + return queryable; + } +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Repository.cs b/WatchIt.WebAPI/Repositories/Repository.cs new file mode 100644 index 0000000..5fd5132 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Repository.cs @@ -0,0 +1,118 @@ +using System.Collections.Immutable; +using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore; +using WatchIt.Database; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories; + + +public abstract class Repository : IRepository where T : class +{ + #region SERVICES + + protected readonly DatabaseContext Database; + + #endregion + + + + #region FIELDS + + protected readonly DbSet DefaultSet; + + #endregion + + + + #region CONSTRUCTORS + + protected Repository(DatabaseContext database) + { + Database = database; + DefaultSet = database.Set(); + } + + #endregion + + + + #region PUBLIC METHODS + + public async Task> GetAllAsync(Func, IQueryable>? additionalIncludes = null) => + await GetAllAsync(additionalIncludes); + + public async Task UpdateAsync(T entity, Action updateFunc) => + await UpdateAsync(entity, updateFunc); + + public async Task AddAsync(T entity) => + await AddAsync(entity); + + public async Task UpdateOrAddAsync(T? entity, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(entity, addFunc, updateFunc); + + public async Task DeleteAsync(T entity) => + await DeleteAsync(entity); + + public async Task DeleteAsync(Expression> predicate) => + await DeleteAsync(predicate); + + #endregion + + + + #region PRIVATE METHODS + + protected async Task> GetAllAsync(Func, IQueryable>? additionalIncludes = null) where TEntity : class => + await Database.Set() + .Include(additionalIncludes) + .ToListAsync(); + + protected async Task UpdateAsync(TEntity entity, Action updateFunc) where TEntity : class + { + updateFunc(entity); + Database.Set().Update(entity); + await Database.SaveChangesAsync(); + } + + protected async Task AddAsync(TEntity entity) where TEntity : class + { + await Database.Set().AddAsync(entity); + await Database.SaveChangesAsync(); + } + + protected async Task UpdateOrAddAsync(TEntity? entity, Func addFunc, Action updateFunc) where TEntity : class + { + if (entity is null) + { + entity = addFunc(); + await Database.Set().AddAsync(entity); + } + else + { + updateFunc(entity); + Database.Set().Update(entity); + } + await Database.SaveChangesAsync(); + return entity; + } + + protected async Task DeleteAsync(TEntity entity) where TEntity : class + { + DbSet dbSet = Database.Set(); + dbSet.Attach(entity); + dbSet.Remove(entity); + await Database.SaveChangesAsync(); + } + + protected async Task DeleteAsync(Expression> predicate) where TEntity : class + { + DbSet dbSet = Database.Set(); + IQueryable entities = dbSet.Where(predicate); + dbSet.AttachRange(entities); + dbSet.RemoveRange(entities); + await Database.SaveChangesAsync(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Roles/IRolesRepository.cs b/WatchIt.WebAPI/Repositories/Roles/IRolesRepository.cs new file mode 100644 index 0000000..d369c08 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Roles/IRolesRepository.cs @@ -0,0 +1,38 @@ +using System.Linq.Expressions; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Models.Controllers.Roles.Role.Query; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType; +using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Roles; + +public interface IRolesRepository : IRepository +{ + Task ExistsAsync(Guid id); + Task GetAsync(Guid id, Func, IQueryable>? additionalIncludes = null); + Task GetAsync(Guid id, Func, IQueryable>? additionalIncludes = null) where T : Role; + Task> GetAllActorsAsync(RoleActorFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task> GetAllCreatorsAsync(RoleCreatorFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task UpdateAsync(Guid id, Action updateFunc) where T : Role; + Task DeleteAsync(Guid id); + + Task> GetRoleRatingsAsync(Guid roleId, Func, IQueryable>? additionalIncludes = null); + Task GetRoleRatingByUserAsync(Guid roleId, long accountId, Func, IQueryable>? additionalIncludes = null); + Task> GetPersonRoleRatingsAsync(long personId, Func, IQueryable>? additionalIncludes = null); + Task> GetPersonRoleRatingsByAccountIdAsync(long personId, long accountId, Func, IQueryable>? additionalIncludes = null); + Task UpdateOrAddRoleRatingAsync(Guid roleId, long accountId, Func addFunc, Action updateFunc); + Task DeleteRoleUserRatingAsync(Guid roleId, long accountId); + + Task ExistsActorTypeAsync(short id); + Task GetActorTypeAsync(short id, Func, IQueryable>? additionalIncludes = null); + Task> GetAllActorTypesAsync(RoleActorTypeFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task AddActorTypeAsync(RoleActorType actorType); + Task DeleteActorTypeAsync(short id); + + Task ExistsCreatorTypeAsync(short id); + Task GetCreatorTypeAsync(short id, Func, IQueryable>? additionalIncludes = null); + Task> GetAllCreatorTypesAsync(RoleCreatorTypeFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null); + Task AddCreatorTypeAsync(RoleCreatorType creatorType); + Task DeleteCreatorTypeAsync(short id); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Repositories/Roles/RolesRepository.cs b/WatchIt.WebAPI/Repositories/Roles/RolesRepository.cs new file mode 100644 index 0000000..dd1c706 --- /dev/null +++ b/WatchIt.WebAPI/Repositories/Roles/RolesRepository.cs @@ -0,0 +1,161 @@ +using Microsoft.EntityFrameworkCore; +using WatchIt.Database; +using WatchIt.Database.Model.Roles; +using WatchIt.DTO.Models.Controllers.Roles.Role; +using WatchIt.DTO.Models.Controllers.Roles.Role.Query; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType; +using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; +using WatchIt.DTO.Query; + +namespace WatchIt.WebAPI.Repositories.Roles; + +public class RolesRepository : Repository, IRolesRepository +{ + #region CONSTRUCTORS + + public RolesRepository(DatabaseContext database) : base(database) {} + + #endregion + + + + #region PUBLIC METHODS + + #region Main + + public async Task ExistsAsync(Guid id) => + await DefaultSet.AnyAsync(x => x.Id == id); + + public async Task GetAsync(Guid id, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task GetAsync(Guid id, Func, IQueryable>? additionalIncludes = null) where T : Role => + await DefaultSet.OfType() + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task> GetAllActorsAsync(RoleActorFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.OfType() + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, RoleOrderKeys.Base(), RoleOrderKeys.RoleActor) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task> GetAllCreatorsAsync(RoleCreatorFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await DefaultSet.OfType() + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, RoleOrderKeys.Base(), RoleOrderKeys.RoleCreator) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task UpdateAsync(Guid id, Action updateFunc) where T : Role + { + T? entity = await GetAsync(id); + if (entity is null) + { + return false; + } + + updateFunc(entity); + DefaultSet.Update(entity); + await Database.SaveChangesAsync(); + return true; + } + + public async Task DeleteAsync(Guid id) => + await DeleteAsync(x => x.Id == id); + + #endregion + + #region Rating + + public async Task> GetRoleRatingsAsync(Guid roleId, Func, IQueryable>? additionalIncludes = null) => + await Database.RoleRatings + .Where(x => x.RoleId == roleId) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task GetRoleRatingByUserAsync(Guid roleId, long accountId, Func, IQueryable>? additionalIncludes = null) => + await Database.RoleRatings + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.RoleId == roleId && x.AccountId == accountId); + + public async Task> GetPersonRoleRatingsAsync(long personId, Func, IQueryable>? additionalIncludes = null) => + await Database.RoleRatings + .Where(x => x.Role.PersonId == personId) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task> GetPersonRoleRatingsByAccountIdAsync(long personId, long accountId, Func, IQueryable>? additionalIncludes = null) => + await Database.RoleRatings + .Where(x => x.Role.PersonId == personId && x.AccountId == accountId) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task UpdateOrAddRoleRatingAsync(Guid roleId, long accountId, Func addFunc, Action updateFunc) => + await UpdateOrAddAsync(await GetRoleRatingByUserAsync(roleId, accountId), addFunc, updateFunc); + + public async Task DeleteRoleUserRatingAsync(Guid roleId, long accountId) => + await DeleteAsync(x => x.RoleId == roleId && x.AccountId == accountId); + + #endregion + + #region ActorTypes + + public async Task ExistsActorTypeAsync(short id) => + await Database.RoleActorTypes + .AnyAsync(x => x.Id == id); + + public async Task GetActorTypeAsync(short id, Func, IQueryable>? additionalIncludes = null) => + await Database.RoleActorTypes + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task> GetAllActorTypesAsync(RoleActorTypeFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await Database.RoleActorTypes + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, RoleActorTypeOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task AddActorTypeAsync(RoleActorType actorType) => + await AddAsync(actorType); + + public async Task DeleteActorTypeAsync(short id) => + await DeleteAsync(new RoleActorType { Id = id }); + + #endregion + + #region CreatorTypes + + public async Task ExistsCreatorTypeAsync(short id) => + await Database.RoleCreatorTypes + .AnyAsync(x => x.Id == id); + + public async Task GetCreatorTypeAsync(short id, Func, IQueryable>? additionalIncludes = null) => + await Database.RoleCreatorTypes + .Include(additionalIncludes) + .FirstOrDefaultAsync(x => x.Id == id); + + public async Task> GetAllCreatorTypesAsync(RoleCreatorTypeFilterQuery filterQuery, OrderQuery orderQuery, PagingQuery pagingQuery, Func, IQueryable>? additionalIncludes = null) => + await Database.RoleCreatorTypes + .ApplyFilter(filterQuery) + .ApplyOrder(orderQuery, RoleCreatorTypeOrderKeys.Base) + .ApplyPaging(pagingQuery) + .Include(additionalIncludes) + .ToListAsync(); + + public async Task AddCreatorTypeAsync(RoleCreatorType creatorType) => + await AddAsync(creatorType); + + public async Task DeleteCreatorTypeAsync(short id) => + await DeleteAsync(new RoleCreatorType { Id = id }); + + #endregion + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Services/Tokens/Configuration/JWT.cs b/WatchIt.WebAPI/Services/Tokens/Configuration/JWT.cs new file mode 100644 index 0000000..e7cdc2a --- /dev/null +++ b/WatchIt.WebAPI/Services/Tokens/Configuration/JWT.cs @@ -0,0 +1,14 @@ +namespace WatchIt.WebAPI.Services.Tokens.Configuration; + +public class JWT +{ + #region PROPERTIES + + public string Key { get; set; } = null!; + public string Issuer { get; set; } = null!; + public string Audience { get; set; } = null!; + public string Algorithm { get; set; } = null!; + public TokensLifetime Lifetime { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Services/Tokens/Configuration/TokenLifetime.cs b/WatchIt.WebAPI/Services/Tokens/Configuration/TokenLifetime.cs new file mode 100644 index 0000000..73aaf4c --- /dev/null +++ b/WatchIt.WebAPI/Services/Tokens/Configuration/TokenLifetime.cs @@ -0,0 +1,11 @@ +namespace WatchIt.WebAPI.Services.Tokens.Configuration; + +public class TokenLifetime +{ + #region PROPERTIES + + public int Normal { get; set; } + public int? Extended { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Services/Tokens/Configuration/TokensLifetime.cs b/WatchIt.WebAPI/Services/Tokens/Configuration/TokensLifetime.cs new file mode 100644 index 0000000..d72cd33 --- /dev/null +++ b/WatchIt.WebAPI/Services/Tokens/Configuration/TokensLifetime.cs @@ -0,0 +1,11 @@ +namespace WatchIt.WebAPI.Services.Tokens.Configuration; + +public class TokensLifetime +{ + #region PROPERTIES + + public TokenLifetime AccessToken { get; set; } = null!; + public TokenLifetime RefreshToken { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/Exceptions/TokenNotExtendableException.cs b/WatchIt.WebAPI/Services/Tokens/Exceptions/TokenNotExtendableException.cs similarity index 63% rename from WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/Exceptions/TokenNotExtendableException.cs rename to WatchIt.WebAPI/Services/Tokens/Exceptions/TokenNotExtendableException.cs index b890f6a..88d940f 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/Exceptions/TokenNotExtendableException.cs +++ b/WatchIt.WebAPI/Services/Tokens/Exceptions/TokenNotExtendableException.cs @@ -1,4 +1,4 @@ -namespace WatchIt.WebAPI.Services.Utility.Tokens.Exceptions; +namespace WatchIt.WebAPI.Services.Tokens.Exceptions; public class TokenNotExtendableException : Exception { diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/Exceptions/TokenNotFoundException.cs b/WatchIt.WebAPI/Services/Tokens/Exceptions/TokenNotFoundException.cs similarity index 61% rename from WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/Exceptions/TokenNotFoundException.cs rename to WatchIt.WebAPI/Services/Tokens/Exceptions/TokenNotFoundException.cs index 07980ae..33a9c05 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/Exceptions/TokenNotFoundException.cs +++ b/WatchIt.WebAPI/Services/Tokens/Exceptions/TokenNotFoundException.cs @@ -1,4 +1,4 @@ -namespace WatchIt.WebAPI.Services.Utility.Tokens.Exceptions; +namespace WatchIt.WebAPI.Services.Tokens.Exceptions; public class TokenNotFoundException : Exception { diff --git a/WatchIt.WebAPI/Services/Tokens/ITokensService.cs b/WatchIt.WebAPI/Services/Tokens/ITokensService.cs new file mode 100644 index 0000000..42cf26c --- /dev/null +++ b/WatchIt.WebAPI/Services/Tokens/ITokensService.cs @@ -0,0 +1,13 @@ +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.WebAPI.Services.Tokens; + +public interface ITokensService +{ + string CreateAccessToken(Account account); + Task CreateRefreshTokenAsync(Account account, bool isExtendable); + Task ExtendRefreshTokenAsync(string refreshToken, string accessToken); + Task RevokeRefreshTokenAsync(string stringToken); + Task RevokeRefreshTokenAsync(Guid token); + Task RevokeAccountRefreshTokensAsync(Account account); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Services/Tokens/SecurityTokenDescriptorExtensions.cs b/WatchIt.WebAPI/Services/Tokens/SecurityTokenDescriptorExtensions.cs new file mode 100644 index 0000000..b3cc8d8 --- /dev/null +++ b/WatchIt.WebAPI/Services/Tokens/SecurityTokenDescriptorExtensions.cs @@ -0,0 +1,21 @@ +using System.IdentityModel.Tokens.Jwt; +using Microsoft.IdentityModel.Tokens; + +namespace WatchIt.WebAPI.Services.Tokens; + +public static class SecurityTokenDescriptorExtensions +{ + #region PUBLIC METHODS + + public static string ToJwtString(this SecurityTokenDescriptor tokenDescriptor) + { + JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); + handler.InboundClaimTypeMap.Clear(); + + SecurityToken token = handler.CreateToken(tokenDescriptor); + + return handler.WriteToken(token); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Services/Tokens/TokensService.cs b/WatchIt.WebAPI/Services/Tokens/TokensService.cs new file mode 100644 index 0000000..2f83bf6 --- /dev/null +++ b/WatchIt.WebAPI/Services/Tokens/TokensService.cs @@ -0,0 +1,160 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using WatchIt.Database.Model.Accounts; +using WatchIt.DTO.Models.Controllers.Accounts; +using WatchIt.WebAPI.Constants; +using WatchIt.WebAPI.Repositories.Accounts; +using WatchIt.WebAPI.Services.Tokens.Configuration; +using WatchIt.WebAPI.Services.Tokens.Exceptions; + +namespace WatchIt.WebAPI.Services.Tokens; + +public class TokensService : ITokensService +{ + #region SERVICES + + private readonly JWT _configuration; + private readonly IAccountsRepository _accountsRepository; + + #endregion + + + + #region CONSTRUCTORS + + public TokensService(IConfiguration configuration, IAccountsRepository accountsRepository) + { + _configuration = configuration.GetSection("Authentication").GetSection("JWT").Get()!; + _accountsRepository = accountsRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + public string CreateAccessToken(Account account) + { + int lifetime = _configuration.Lifetime.AccessToken.Normal; + DateTimeOffset expirationDate = new DateTimeOffset(DateTime.UtcNow.AddMinutes(lifetime)); + + SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor + { + Subject = new ClaimsIdentity( + [ + new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), + new Claim(JwtRegisteredClaimNames.Sub, account.Id.ToString()), + new Claim(JwtRegisteredClaimNames.Exp, expirationDate.Ticks.ToString()), + new Claim(AdditionalClaimNames.Admin, account.IsAdmin.ToString()) + ]), + Issuer = _configuration.Issuer, + Audience = _configuration.Audience, + Expires = expirationDate.UtcDateTime, + SigningCredentials = new SigningCredentials(CreateSecurityKey(), _configuration.Algorithm), + }; + + return descriptor.ToJwtString(); + } + + public async Task CreateRefreshTokenAsync(Account account, bool isExtendable) + { + Guid newToken = Guid.NewGuid(); + DateTimeOffset expirationDate = GetExpirationDate(_configuration.Lifetime.RefreshToken, isExtendable); + + AccountRefreshToken tokenEntity = AccountsMappers.CreateAccountRefreshTokenEntity(newToken, account.Id, expirationDate, isExtendable); + await _accountsRepository.AddRefreshTokenAsync(tokenEntity); + + return Convert.ToBase64String(newToken.ToByteArray()); + } + + public async Task ExtendRefreshTokenAsync(string refreshToken, string accessToken) + { + long accountId = ValidateExpiredAccessTokenAndGetAccountId(accessToken); + Account? account = await _accountsRepository.GetAsync(accountId, x => x.Include(y => y.RefreshTokens)); + if (account is null) + { + throw new SecurityTokenException("Invalid token"); + } + + Guid token = new Guid(Convert.FromBase64String(refreshToken)); + AccountRefreshToken? tokenEntity = account.RefreshTokens.FirstOrDefault(x => x.Token == token); + if (tokenEntity is null) + { + throw new SecurityTokenException("Invalid token"); + } + if (tokenEntity.ExpirationDate < DateTimeOffset.Now) + { + throw new SecurityTokenExpiredException(); + } + + DateTimeOffset expirationDate = GetExpirationDate(_configuration.Lifetime.RefreshToken, tokenEntity.IsExtendable); + await _accountsRepository.UpdateRefreshTokenAsync(tokenEntity, x => x.UpdateExpirationDate(expirationDate)); + return account; + } + + public async Task RevokeRefreshTokenAsync(string stringToken) => + await RevokeRefreshTokenAsync(new Guid(Convert.FromBase64String(stringToken))); + + public async Task RevokeRefreshTokenAsync(Guid token) => + await _accountsRepository.DeleteRefreshTokenAsync(token); + + public async Task RevokeAccountRefreshTokensAsync(Account account) => + await _accountsRepository.DeleteUserRefreshTokensAsync(account.Id); + + #endregion + + + + #region PRIVATE METHODS + + private long ValidateExpiredAccessTokenAndGetAccountId(string accessToken) + { + TokenValidationParameters tokenValidation = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + ValidateAudience = true, + ValidateIssuer = true, + ValidateLifetime = false, + ValidIssuer = _configuration.Issuer, + ValidAudience = _configuration.Audience, + IssuerSigningKey = CreateSecurityKey(), + ClockSkew = TimeSpan.FromMinutes(1), + }; + JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); + tokenHandler.ValidateToken(accessToken, tokenValidation, out SecurityToken validatedToken); + JwtSecurityToken? jwtSecurityToken = validatedToken as JwtSecurityToken; + if (jwtSecurityToken is null || !jwtSecurityToken.Header.Alg.Equals(_configuration.Algorithm, StringComparison.InvariantCultureIgnoreCase)) + { + throw new SecurityTokenException("Invalid token"); + } + + Claim? sub = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Sub); + if (sub is null || !long.TryParse(sub.Value, out long accountId)) + { + throw new SecurityTokenException("Invalid token"); + } + + return accountId; + } + + private SymmetricSecurityKey CreateSecurityKey() + { + string stringKey = _configuration.Key; + byte[] encodedKey = Encoding.UTF8.GetBytes(stringKey); + SymmetricSecurityKey securityKey = new SymmetricSecurityKey(encodedKey); + return securityKey; + } + + private DateTimeOffset GetExpirationDate(TokenLifetime tokenConfiguration, bool isExtendable = false) + { + int lifetime = isExtendable ? tokenConfiguration.Extended ?? tokenConfiguration.Normal : tokenConfiguration.Normal; + DateTimeOffset expirationDate = DateTimeOffset.UtcNow.AddMinutes(lifetime); + return expirationDate; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Services/User/IUserService.cs b/WatchIt.WebAPI/Services/User/IUserService.cs new file mode 100644 index 0000000..fde5a0d --- /dev/null +++ b/WatchIt.WebAPI/Services/User/IUserService.cs @@ -0,0 +1,8 @@ +using WatchIt.Database.Model.Accounts; + +namespace WatchIt.WebAPI.Services.User; + +public interface IUserService +{ + Task GetAccountAsync(); +} \ No newline at end of file diff --git a/WatchIt.WebAPI/Services/User/UserService.cs b/WatchIt.WebAPI/Services/User/UserService.cs new file mode 100644 index 0000000..fc12cef --- /dev/null +++ b/WatchIt.WebAPI/Services/User/UserService.cs @@ -0,0 +1,80 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using Microsoft.IdentityModel.Tokens; +using WatchIt.Database.Model.Accounts; +using WatchIt.WebAPI.Constants; +using WatchIt.WebAPI.Repositories.Accounts; +using WatchIt.WebAPI.Services.Tokens; + +namespace WatchIt.WebAPI.Services.User; + +public class UserService : IUserService +{ + #region SERVICES + + private readonly IHttpContextAccessor _accessor; + private readonly IAccountsRepository _accountsRepository; + + #endregion + + + + #region CONSTRUCTORS + + public UserService(IHttpContextAccessor accessor, IAccountsRepository accountsRepository) + { + _accessor = accessor; + _accountsRepository = accountsRepository; + } + + #endregion + + + + #region PUBLIC METHODS + + public async Task GetAccountAsync() + { + long? id = GetAccountId(); + if (!id.HasValue) + { + throw new SecurityTokenException("Incorrect sub claim"); + } + + Account? account = await _accountsRepository.GetAsync(id.Value); + if (account is null) + { + throw new SecurityTokenException("Account with sub claim id not found"); + } + return account; + } + + #endregion + + + + #region PRIVATE METHODS + + private ClaimsPrincipal? GetClaims() + { + if (_accessor.HttpContext is null) + { + throw new NullReferenceException(); + } + return _accessor.HttpContext.User; + } + + private long? GetAccountId() + { + ClaimsPrincipal? user = GetClaims(); + Claim? subClaim = user?.FindFirst(JwtRegisteredClaimNames.Sub); + if (subClaim is null) + { + return null; + } + long.TryParse(subClaim.Value, out long accountId); + return accountId; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs deleted file mode 100644 index a57a424..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs +++ /dev/null @@ -1,155 +0,0 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Accounts; -using WatchIt.Common.Model.Movies; -using WatchIt.Common.Model.Persons; -using WatchIt.Common.Model.Photos; -using WatchIt.Common.Model.Series; -using WatchIt.WebAPI.Services.Controllers.Accounts; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("accounts")] -public class AccountsController(IAccountsControllerService accountsControllerService) : ControllerBase -{ - #region Basic - - [HttpPost("register")] - [AllowAnonymous] - [ProducesResponseType(typeof(RegisterResponse), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public async Task Register([FromBody]RegisterRequest body) => await accountsControllerService.Register(body); - - [HttpPost("authenticate")] - [AllowAnonymous] - [ProducesResponseType(typeof(AuthenticateResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task Authenticate([FromBody]AuthenticateRequest body) => await accountsControllerService.Authenticate(body); - - [HttpPost("authenticate_refresh")] - [Authorize(AuthenticationSchemes = "refresh")] - [ProducesResponseType(typeof(AuthenticateResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task AuthenticateRefresh() => await accountsControllerService.AuthenticateRefresh(); - - [HttpDelete("logout")] - [Authorize(AuthenticationSchemes = "refresh")] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - public async Task Logout() => await accountsControllerService.Logout(); - - #endregion - - #region Profile picture - - [HttpGet("{id}/profile_picture")] - [AllowAnonymous] - [ProducesResponseType(typeof(AccountProfilePictureResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetAccountProfilePicture([FromRoute(Name = "id")]long id) => await accountsControllerService.GetAccountProfilePicture(id); - - [HttpPut("profile_picture")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(AccountProfilePictureResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task PutAccountProfilePicture([FromBody]AccountProfilePictureRequest body) => await accountsControllerService.PutAccountProfilePicture(body); - - [HttpDelete("profile_picture")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task DeleteAccountProfilePicture() => await accountsControllerService.DeleteAccountProfilePicture(); - - #endregion - - #region Profile background - - [HttpGet("{id}/profile_background")] - [AllowAnonymous] - [ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetAccountProfileBackground([FromRoute(Name = "id")]long id) => await accountsControllerService.GetAccountProfileBackground(id); - - [HttpPut("profile_background")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task PutAccountProfileBackground([FromBody]AccountProfileBackgroundRequest body) => await accountsControllerService.PutAccountProfileBackground(body); - - [HttpDelete("profile_background")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task DeleteAccountProfileBackground() => await accountsControllerService.DeleteAccountProfileBackground(); - - #endregion - - #region Info - - [HttpGet] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAccounts(AccountQueryParameters query) => await accountsControllerService.GetAccounts(query); - - [HttpGet("{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(AccountResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetAccount([FromRoute]long id) => await accountsControllerService.GetAccount(id); - - [HttpPut("profile_info")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutAccountProfileInfo([FromBody]AccountProfileInfoRequest data) => await accountsControllerService.PutAccountProfileInfo(data); - - [HttpPatch("username")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task PatchAccountUsername([FromBody]AccountUsernameRequest data) => await accountsControllerService.PatchAccountUsername(data); - - [HttpPatch("email")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task PatchAccountEmail([FromBody]AccountEmailRequest data) => await accountsControllerService.PatchAccountEmail(data); - - [HttpPatch("password")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task PatchAccountPassword([FromBody]AccountPasswordRequest data) => await accountsControllerService.PatchAccountPassword(data); - - #endregion - - [HttpGet("{id}/movies")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetAccountRatedMovies([FromRoute]long id, MovieRatedQueryParameters query) => await accountsControllerService.GetAccountRatedMovies(id, query); - - [HttpGet("{id}/series")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetAccountRatedSeries([FromRoute]long id, SeriesRatedQueryParameters query) => await accountsControllerService.GetAccountRatedSeries(id, query); - - [HttpGet("{id}/persons")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetAccountRatedPersons([FromRoute]long id, PersonRatedQueryParameters query) => await accountsControllerService.GetAccountRatedPersons(id, query); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GendersController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GendersController.cs deleted file mode 100644 index 4f6e24d..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GendersController.cs +++ /dev/null @@ -1,66 +0,0 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Genders; -using WatchIt.WebAPI.Services.Controllers.Genders; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("genders")] -public class GendersController : ControllerBase -{ - #region SERVICES - - private readonly IGendersControllerService _gendersControllerService; - - #endregion - - - - #region CONSTRUCTORS - - public GendersController(IGendersControllerService gendersControllerService) - { - _gendersControllerService = gendersControllerService; - } - - #endregion - - - - #region METHODS - - #region Main - - [HttpGet] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAllGenders(GenderQueryParameters query) => await _gendersControllerService.GetAllGenders(query); - - [HttpGet("{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(GenderResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetGender([FromRoute]short id) => await _gendersControllerService.GetGender(id); - - [HttpPost] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(GenderResponse), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PostGender([FromBody]GenderRequest body) => await _gendersControllerService.PostGender(body); - - [HttpDelete("{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteGender([FromRoute]short id) => await _gendersControllerService.DeleteGender(id); - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GenresController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GenresController.cs deleted file mode 100644 index 5d48fbb..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GenresController.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Genres; -using WatchIt.WebAPI.Services.Controllers.Genres; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("genres")] -public class GenresController(IGenresControllerService genresControllerService) : ControllerBase -{ - [HttpGet] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAll(GenreQueryParameters query) => await genresControllerService.GetAll(query); - - [HttpGet("{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(GenreResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task Get([FromRoute]short id) => await genresControllerService.Get(id); - - [HttpPost] - [Authorize] - [ProducesResponseType(typeof(GenreResponse), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task Post([FromBody]GenreRequest body) => await genresControllerService.Post(body); - - [HttpPut("{id}")] - [Authorize] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task Put([FromRoute]short id, [FromBody]GenreRequest body) => await genresControllerService.Put(id, body); - - [HttpDelete("{id}")] - [Authorize] - [ProducesResponseType(typeof(GenreResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task Delete([FromRoute]short id) => await genresControllerService.Delete(id); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs deleted file mode 100644 index 6764675..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs +++ /dev/null @@ -1,206 +0,0 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Photos; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Roles; -using WatchIt.WebAPI.Services.Controllers.Media; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("media")] -public class MediaController : ControllerBase -{ - #region FIELDS - - private readonly IMediaControllerService _mediaControllerService; - - #endregion - - - - #region CONSTRUCTORS - - public MediaController(IMediaControllerService mediaControllerService) - { - _mediaControllerService = mediaControllerService; - } - - #endregion - - - - #region METHODS - - #region Main - - [HttpGet] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAllMedia(MediaQueryParameters query) => await _mediaControllerService.GetAllMedia(query); - - [HttpGet("{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(MediaResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMedia([FromRoute] long id) => await _mediaControllerService.GetMedia(id); - - #endregion - - #region Genres - - [HttpGet("{id}/genres")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMediaGenres([FromRoute]long id) => await _mediaControllerService.GetMediaGenres(id); - - [HttpPost("{id}/genres/{genre_id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostMediaGenre([FromRoute]long id, [FromRoute(Name = "genre_id")]short genreId) => await _mediaControllerService.PostMediaGenre(id, genreId); - - [HttpDelete("{id}/genres/{genre_id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task DeleteMediaGenre([FromRoute]long id, [FromRoute(Name = "genre_id")]short genreId) => await _mediaControllerService.DeleteMediaGenre(id, genreId); - - #endregion - - #region Rating - - [HttpGet("{id}/rating")] - [AllowAnonymous] - [ProducesResponseType(typeof(RatingResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMediaRating([FromRoute] long id) => await _mediaControllerService.GetMediaRating(id); - - [HttpGet("{id}/rating/{user_id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(short), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMediaRatingByUser([FromRoute] long id, [FromRoute(Name = "user_id")]long userId) => await _mediaControllerService.GetMediaRatingByUser(id, userId); - - [HttpPut("{id}/rating")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutMediaRating([FromRoute] long id, [FromBody] RatingRequest data) => await _mediaControllerService.PutMediaRating(id, data); - - [HttpDelete("{id}/rating")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task DeleteMediaRating([FromRoute] long id) => await _mediaControllerService.DeleteMediaRating(id); - - #endregion - - #region View count - - [HttpPost("{id}/view")] - [AllowAnonymous] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostMediaView([FromRoute] long id) => await _mediaControllerService.PostMediaView(id); - - #endregion - - #region Poster - - [HttpGet("{id}/poster")] - [AllowAnonymous] - [ProducesResponseType(typeof(MediaPosterResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMediaPoster([FromRoute] long id) => await _mediaControllerService.GetMediaPoster(id); - - [HttpPut("{id}/poster")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(MediaPosterResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PutMediaPoster([FromRoute]long id, [FromBody]MediaPosterRequest body) => await _mediaControllerService.PutMediaPoster(id, body); - - [HttpDelete("{id}/poster")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteMediaPoster([FromRoute]long id) => await _mediaControllerService.DeleteMediaPoster(id); - - #endregion - - #region Photos - - [HttpGet("{id}/photos")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMediaPhotos([FromRoute]long id, PhotoQueryParameters query) => await _mediaControllerService.GetMediaPhotos(id, query); - - [HttpGet("{id}/photos/random_background")] - [AllowAnonymous] - [ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMediaPhotoRandomBackground([FromRoute]long id) => await _mediaControllerService.GetMediaPhotoRandomBackground(id); - - [HttpPost("{id}/photos")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostPhoto([FromRoute]long id, [FromBody]MediaPhotoRequest body) => await _mediaControllerService.PostMediaPhoto(id, body); - - #endregion - - #region Roles - - [HttpGet("{id}/roles/actor")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMediaAllActorRoles([FromRoute]long id, ActorRoleMediaQueryParameters query) => await _mediaControllerService.GetMediaAllActorRoles(id, query); - - [HttpPost("{id}/roles/actor")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(ActorRoleResponse), StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostMediaActorRole([FromRoute]long id, [FromBody]ActorRoleMediaRequest body) => await _mediaControllerService.PostMediaActorRole(id, body); - - [HttpGet("{id}/roles/creator")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMediaAllCreatorRoles([FromRoute]long id, CreatorRoleMediaQueryParameters query) => await _mediaControllerService.GetMediaAllCreatorRoles(id, query); - - [HttpPost("{id}/roles/creator")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(CreatorRoleResponse), StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostMediaCreatorRole([FromRoute]long id, [FromBody]CreatorRoleMediaRequest body) => await _mediaControllerService.PostMediaCreatorRole(id, body); - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MoviesController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MoviesController.cs deleted file mode 100644 index dbad719..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MoviesController.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System.Net; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Movies; -using WatchIt.WebAPI.Services.Controllers.Movies; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("movies")] -public class MoviesController : ControllerBase -{ - #region SERVICES - - private readonly IMoviesControllerService _moviesControllerService; - - #endregion - - - - #region CONSTRUCTORS - - public MoviesController(IMoviesControllerService moviesControllerService) - { - _moviesControllerService = moviesControllerService; - } - - #endregion - - - - #region METHODS - - #region Main - - [HttpGet] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAllMovies(MovieQueryParameters query) => await _moviesControllerService.GetAllMovies(query); - - [HttpGet("{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(MovieResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMovie([FromRoute] long id) => await _moviesControllerService.GetMovie(id); - - [HttpPost] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(MovieResponse), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PostMovie([FromBody] MovieRequest body) => await _moviesControllerService.PostMovie(body); - - [HttpPut("{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PutMovie([FromRoute] long id, [FromBody]MovieRequest body) => await _moviesControllerService.PutMovie(id, body); - - [HttpDelete("{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteMovie([FromRoute] long id) => await _moviesControllerService.DeleteMovie(id); - - #endregion - - #region View count - - [HttpGet("view")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task GetMoviesViewRank([FromQuery] int first = 5, [FromQuery] int days = 7) => await _moviesControllerService.GetMoviesViewRank(first, days); - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/PersonsController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/PersonsController.cs deleted file mode 100644 index ed213b0..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/PersonsController.cs +++ /dev/null @@ -1,168 +0,0 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Persons; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Roles; -using WatchIt.WebAPI.Services.Controllers.Persons; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("persons")] -public class PersonsController : ControllerBase -{ - #region SERVICES - - private readonly IPersonsControllerService _personsControllerService; - - #endregion - - - - #region CONSTRUCTORS - - public PersonsController(IPersonsControllerService personsControllerService) - { - _personsControllerService = personsControllerService; - } - - #endregion - - - - #region METHODS - - #region Main - - [HttpGet] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAllMovies(PersonQueryParameters query) => await _personsControllerService.GetAllPersons(query); - - [HttpGet("{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(PersonResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetMovie([FromRoute] long id) => await _personsControllerService.GetPerson(id); - - [HttpPost] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(PersonResponse), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PostMovie([FromBody] PersonRequest body) => await _personsControllerService.PostPerson(body); - - [HttpPut("{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PutMovie([FromRoute] long id, [FromBody]PersonRequest body) => await _personsControllerService.PutPerson(id, body); - - [HttpDelete("{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteMovie([FromRoute] long id) => await _personsControllerService.DeletePerson(id); - - #endregion - - #region View count - - [HttpGet("view")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task GetPersonsViewRank([FromQuery] int first = 5, [FromQuery] int days = 7) => await _personsControllerService.GetPersonsViewRank(first, days); - - [HttpPost("{id}/view")] - [AllowAnonymous] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostPersonsView([FromRoute] long id) => await _personsControllerService.PostPersonsView(id); - - #endregion - - #region Photo - - [HttpGet("{id}/photo")] - [AllowAnonymous] - [ProducesResponseType(typeof(PersonPhotoResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetPersonPhoto([FromRoute] long id) => await _personsControllerService.GetPersonPhoto(id); - - [HttpPut("{id}/photo")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(PersonPhotoResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PutPersonPhoto([FromRoute]long id, [FromBody]PersonPhotoRequest body) => await _personsControllerService.PutPersonPhoto(id, body); - - [HttpDelete("{id}/photo")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeletePersonPhoto([FromRoute]long id) => await _personsControllerService.DeletePersonPhoto(id); - - #endregion - - #region Roles - - [HttpGet("{id}/roles/actor")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetPersonAllActorRoles([FromRoute]long id, ActorRolePersonQueryParameters query) => await _personsControllerService.GetPersonAllActorRoles(id, query); - - [HttpPost("{id}/roles/actor")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(ActorRoleResponse), StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostPersonActorRole([FromRoute]long id, [FromBody]ActorRolePersonRequest body) => await _personsControllerService.PostPersonActorRole(id, body); - - [HttpGet("{id}/roles/creator")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetPersonAllCreatorRoles([FromRoute]long id, CreatorRolePersonQueryParameters query) => await _personsControllerService.GetPersonAllCreatorRoles(id, query); - - [HttpPost("{id}/roles/creator")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(CreatorRoleResponse), StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostPersonCreatorRole([FromRoute]long id, [FromBody]CreatorRolePersonRequest body) => await _personsControllerService.PostPersonCreatorRole(id, body); - - #endregion - - #region Rating - - [HttpGet("{id}/rating")] - [AllowAnonymous] - [ProducesResponseType(typeof(RatingResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetPersonGlobalRating([FromRoute]long id) => await _personsControllerService.GetPersonGlobalRating(id); - - [HttpGet("{id}/rating/{user_id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(RatingResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetPersonUserRating([FromRoute]long id, [FromRoute(Name = "user_id")]long userId) => await _personsControllerService.GetPersonUserRating(id, userId); - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/PhotosController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/PhotosController.cs deleted file mode 100644 index 1b9316a..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/PhotosController.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Photos; -using WatchIt.WebAPI.Services.Controllers.Photos; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("photos")] -public class PhotosController : ControllerBase -{ - #region FIELDS - - private readonly IPhotosControllerService _photosControllerService; - - #endregion - - - - #region CONSTRUCTORS - - public PhotosController(IPhotosControllerService photosControllerService) - { - _photosControllerService = photosControllerService; - } - - #endregion - - - - #region METHODS - - #region Main - - [HttpGet("random_background")] - [AllowAnonymous] - [ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetPhotoRandomBackground() => await _photosControllerService.GetPhotoRandomBackground(); - - [HttpDelete("{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task DeletePhoto([FromRoute] Guid id) => await _photosControllerService.DeletePhoto(id); - - #endregion - - #region Background data - - [HttpPut("{id}/background_data")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutPhotoBackgroundData([FromRoute]Guid id, [FromBody] PhotoBackgroundDataRequest body) => await _photosControllerService.PutPhotoBackgroundData(id, body); - - [HttpDelete("{id}/background_data")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task DeletePhotoBackgroundData([FromRoute]Guid id) => await _photosControllerService.DeletePhotoBackgroundData(id); - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/RolesController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/RolesController.cs deleted file mode 100644 index b656bd9..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/RolesController.cs +++ /dev/null @@ -1,192 +0,0 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Roles; -using WatchIt.WebAPI.Services.Controllers.Roles; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("roles")] -public class RolesController : ControllerBase -{ - #region SERVICES - - private readonly IRolesControllerService _rolesControllerService; - - #endregion - - - - #region CONSTRUCTORS - - public RolesController(IRolesControllerService rolesControllerService) - { - _rolesControllerService = rolesControllerService; - } - - #endregion - - - - #region METHODS - - #region Actor - - [HttpGet("actor/{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetActorRole([FromRoute]Guid id) => await _rolesControllerService.GetActorRole(id); - - [HttpPut("actor/{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutActorRole([FromRoute]Guid id, [FromBody]ActorRoleUniversalRequest body) => await _rolesControllerService.PutActorRole(id, body); - - [HttpDelete("actor/{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteActorRole([FromRoute]Guid id) => await _rolesControllerService.DeleteActorRole(id); - - [HttpGet("actor/{id}/rating")] - [AllowAnonymous] - [ProducesResponseType(typeof(RatingResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetActorRoleRating([FromRoute] Guid id) => await _rolesControllerService.GetActorRoleRating(id); - - [HttpGet("actor/{id}/rating/{user_id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(short), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetActorRoleRatingByUser([FromRoute] Guid id, [FromRoute(Name = "user_id")]long userId) => await _rolesControllerService.GetActorRoleRatingByUser(id, userId); - - [HttpPut("actor/{id}/rating")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutActorRoleRating([FromRoute] Guid id, [FromBody] RatingRequest data) => await _rolesControllerService.PutActorRoleRating(id, data); - - [HttpDelete("actor/{id}/rating")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task DeleteActorRoleRating([FromRoute] Guid id) => await _rolesControllerService.DeleteActorRoleRating(id); - - [HttpGet("actor/type")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAllActorRoleTypes(RoleTypeQueryParameters query) => await _rolesControllerService.GetAllActorRoleTypes(query); - - [HttpGet("actor/type/{type_id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(RoleTypeResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetActorRoleType([FromRoute(Name = "type_id")]short typeId) => await _rolesControllerService.GetActorRoleType(typeId); - - [HttpPost("actor/type")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(RoleTypeResponse), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PostActorRoleType([FromBody]RoleTypeRequest body) => await _rolesControllerService.PostActorRoleType(body); - - [HttpDelete("actor/type/{type_id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteActorRoleType([FromRoute(Name = "type_id")]short typeId) => await _rolesControllerService.DeleteActorRoleType(typeId); - - #endregion - - #region Creator - - [HttpGet("creator/{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetCreatorRole([FromRoute]Guid id) => await _rolesControllerService.GetCreatorRole(id); - - [HttpPut("creator/{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutCreatorRole([FromRoute]Guid id, [FromBody]CreatorRoleUniversalRequest body) => await _rolesControllerService.PutCreatorRole(id, body); - - [HttpDelete("creator/{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteCreatorRole([FromRoute]Guid id) => await _rolesControllerService.DeleteCreatorRole(id); - - [HttpGet("creator/{id}/rating")] - [AllowAnonymous] - [ProducesResponseType(typeof(RatingResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetCreatorRoleRating([FromRoute] Guid id) => await _rolesControllerService.GetCreatorRoleRating(id); - - [HttpGet("creator/{id}/rating/{user_id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(short), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetCreatorRoleRatingByUser([FromRoute] Guid id, [FromRoute(Name = "user_id")] long userId) => await _rolesControllerService.GetCreatorRoleRatingByUser(id, userId); - - [HttpPut("creator/{id}/rating")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutCreatorRoleRating([FromRoute] Guid id, [FromBody] RatingRequest data) => await _rolesControllerService.PutCreatorRoleRating(id, data); - - [HttpDelete("creator/{id}/rating")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task DeleteCreatorRoleRating([FromRoute] Guid id) => await _rolesControllerService.DeleteCreatorRoleRating(id); - - [HttpGet("creator/type")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAllCreatorRoleTypes(RoleTypeQueryParameters query) => await _rolesControllerService.GetAllCreatorRoleTypes(query); - - [HttpGet("creator/type/{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(RoleTypeResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetCreatorRoleType([FromRoute]short id) => await _rolesControllerService.GetCreatorRoleType(id); - - [HttpPost("creator/type")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(RoleTypeResponse), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PostCreatorRoleType([FromBody]RoleTypeRequest body) => await _rolesControllerService.PostCreatorRoleType(body); - - [HttpDelete("creator/type/{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteCreatorRoleType([FromRoute]short id) => await _rolesControllerService.DeleteCreatorRoleType(id); - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/SeriesController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/SeriesController.cs deleted file mode 100644 index 5afe5ca..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/SeriesController.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using WatchIt.Common.Model.Series; -using WatchIt.Database; -using WatchIt.WebAPI.Services.Controllers.Series; - -namespace WatchIt.WebAPI.Controllers; - -[ApiController] -[Route("series")] -public class SeriesController : ControllerBase -{ - #region SERVICES - - private readonly ISeriesControllerService _seriesControllerService; - - #endregion - - - - #region CONSTRUCTORS - - public SeriesController(ISeriesControllerService seriesControllerService) - { - _seriesControllerService = seriesControllerService; - } - - #endregion - - - - #region PUBLIC METHODS - - #region Main - - [HttpGet] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAllSeries(SeriesQueryParameters query) => await _seriesControllerService.GetAllSeries(query); - - [HttpGet("{id}")] - [AllowAnonymous] - [ProducesResponseType(typeof(SeriesResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetSeries([FromRoute] long id) => await _seriesControllerService.GetSeries(id); - - [HttpPost] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(SeriesResponse), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PostSeries([FromBody] SeriesRequest body) => await _seriesControllerService.PostSeries(body); - - [HttpPut("{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task PutSeries([FromRoute] long id, [FromBody]SeriesRequest body) => await _seriesControllerService.PutSeries(id, body); - - [HttpDelete("{id}")] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task DeleteSeries([FromRoute] long id) => await _seriesControllerService.DeleteSeries(id); - - #endregion - - #region View count - - [HttpGet("view")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task GetSeriesViewRank([FromQuery] int first = 5, [FromQuery] int days = 7) => await _seriesControllerService.GetSeriesViewRank(first, days); - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/WatchIt.WebAPI.Controllers.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/WatchIt.WebAPI.Controllers.csproj deleted file mode 100644 index c2ab0dd..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/WatchIt.WebAPI.Controllers.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs deleted file mode 100644 index 14fc4ba..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs +++ /dev/null @@ -1,386 +0,0 @@ -using System.Security.Cryptography; -using System.Text; -using Microsoft.AspNetCore.Http; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using SimpleToolkit.Extensions; -using WatchIt.Common.Model.Accounts; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Movies; -using WatchIt.Common.Model.Persons; -using WatchIt.Common.Model.Photos; -using WatchIt.Common.Model.Series; -using WatchIt.Database; -using WatchIt.Database.Model.Account; -using WatchIt.Database.Model.Media; -using WatchIt.Database.Model.Rating; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.Tokens; -using WatchIt.WebAPI.Services.Utility.Tokens.Exceptions; -using WatchIt.WebAPI.Services.Utility.User; -using Account = WatchIt.Database.Model.Account.Account; -using AccountProfilePicture = WatchIt.Common.Model.Accounts.AccountProfilePicture; -using Person = WatchIt.Database.Model.Person.Person; - -namespace WatchIt.WebAPI.Services.Controllers.Accounts; - -public class AccountsControllerService( - ILogger logger, - DatabaseContext database, - ITokensService tokensService, - IUserService userService -) : IAccountsControllerService -{ - #region PUBLIC METHODS - - #region Basic - - public async Task Register(RegisterRequest data) - { - Account account = new Account - { - Username = data.Username, - Email = data.Email, - }; - - SetPassword(account, data.Password); - await database.Accounts.AddAsync(account); - await database.SaveChangesAsync(); - - logger.LogInformation($"New account with ID {account.Id} was created (username: {account.Username}; email: {account.Email})"); - return RequestResult.Created($"accounts/{account.Id}", new RegisterResponse(account)); - } - - public async Task Authenticate(AuthenticateRequest data) - { - Account? account = await database.Accounts.FirstOrDefaultAsync(x => string.Equals(x.Email, data.UsernameOrEmail) || string.Equals(x.Username, data.UsernameOrEmail)); - if (account is null || !ComputeHash(data.Password, account.LeftSalt, account.RightSalt).SequenceEqual(account.Password)) - { - return RequestResult.Unauthorized(); - } - - Task refreshTokenTask = tokensService.CreateRefreshTokenAsync(account, true); - Task accessTokenTask = tokensService.CreateAccessTokenAsync(account); - AuthenticateResponse response = new AuthenticateResponse - { - AccessToken = await accessTokenTask, - RefreshToken = await refreshTokenTask, - }; - - account.LastActive = DateTime.UtcNow; - await database.SaveChangesAsync(); - - logger.LogInformation($"Account with ID {account.Id} was authenticated"); - return RequestResult.Ok(response); - } - - public async Task AuthenticateRefresh() - { - Guid jti = userService.GetJti(); - AccountRefreshToken? token = await database.AccountRefreshTokens.FirstOrDefaultAsync(x => x.Id == jti); - if (token is null || token.ExpirationDate < DateTime.UtcNow) - { - return RequestResult.Unauthorized(); - } - - string refreshToken; - try - { - refreshToken = await tokensService.ExtendRefreshTokenAsync(token.Account, token.Id); - } - catch (TokenNotFoundException) - { - return RequestResult.Unauthorized(); - } - catch (TokenNotExtendableException) - { - refreshToken = userService.GetRawToken().Replace("Bearer ", string.Empty); - } - - string accessToken = await tokensService.CreateAccessTokenAsync(token.Account); - - token.Account.LastActive = DateTime.UtcNow; - await database.SaveChangesAsync(); - - logger.LogInformation($"Account with ID {token.AccountId} was authenticated by token refreshing"); - return RequestResult.Ok(new AuthenticateResponse - { - AccessToken = accessToken, - RefreshToken = refreshToken, - }); - } - - public async Task Logout() - { - Guid jti = userService.GetJti(); - AccountRefreshToken? token = await database.AccountRefreshTokens.FirstOrDefaultAsync(x => x.Id == jti); - if (token is not null) - { - database.AccountRefreshTokens.Attach(token); - database.AccountRefreshTokens.Remove(token); - await database.SaveChangesAsync(); - } - return RequestResult.NoContent(); - } - - #endregion - - #region Profile picture - - public async Task GetAccountProfilePicture(long id) - { - Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); - if (account is null) - { - return RequestResult.BadRequest() - .AddValidationError("id", "Account with this id does not exists"); - } - - if (account.ProfilePicture is null) - { - return RequestResult.NotFound(); - } - - AccountProfilePictureResponse picture = new AccountProfilePictureResponse(account.ProfilePicture); - return RequestResult.Ok(picture); - } - - public async Task PutAccountProfilePicture(AccountProfilePictureRequest data) - { - Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId()); - Database.Model.Account.AccountProfilePicture? picture = account.ProfilePicture; - - if (picture is null) - { - picture = data.CreateMediaPosterImage(); - await database.AccountProfilePictures.AddAsync(picture); - await database.SaveChangesAsync(); - - account.ProfilePictureId = picture.Id; - } - else - { - data.UpdateMediaPosterImage(picture); - } - - await database.SaveChangesAsync(); - - AccountProfilePictureResponse returnData = new AccountProfilePictureResponse(picture); - return RequestResult.Ok(returnData); - } - - public async Task DeleteAccountProfilePicture() - { - Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId()); - Database.Model.Account.AccountProfilePicture? picture = account.ProfilePicture; - - if (picture is not null) - { - account.ProfilePictureId = null; - await database.SaveChangesAsync(); - - database.AccountProfilePictures.Attach(picture); - database.AccountProfilePictures.Remove(picture); - await database.SaveChangesAsync(); - } - - return RequestResult.NoContent(); - } - - #endregion - - #region Profile background - - public async Task GetAccountProfileBackground(long id) - { - Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); - if (account is null) - { - return RequestResult.BadRequest() - .AddValidationError("id", "Account with this id does not exists"); - } - - if (account.BackgroundPicture is null) - { - return RequestResult.NotFound(); - } - - PhotoResponse response = new PhotoResponse(account.BackgroundPicture); - return RequestResult.Ok(response); - } - - public async Task PutAccountProfileBackground(AccountProfileBackgroundRequest data) - { - Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId()); - - account.BackgroundPictureId = data.Id; - - await database.SaveChangesAsync(); - - PhotoResponse returnData = new PhotoResponse(account.BackgroundPicture!); - return RequestResult.Ok(returnData); - } - - public async Task DeleteAccountProfileBackground() - { - Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId()); - - if (account.BackgroundPicture is not null) - { - account.BackgroundPictureId = null; - await database.SaveChangesAsync(); - } - - return RequestResult.NoContent(); - } - - #endregion - - #region Info - - public async Task GetAccounts(AccountQueryParameters query) - { - IEnumerable accounts = await database.Accounts.ToListAsync(); - IEnumerable accountsData = accounts.Select(x => new AccountResponse(x)); - accountsData = query.PrepareData(accountsData); - return RequestResult.Ok(accountsData); - } - - public async Task GetAccount(long id) - { - Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); - if (account is null) - { - return RequestResult.NotFound(); - } - - AccountResponse profileInfoResponse = new AccountResponse(account); - return RequestResult.Ok(profileInfoResponse); - } - - public async Task PutAccountProfileInfo(AccountProfileInfoRequest data) - { - Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == userService.GetUserId()); - if (account is null) - { - return RequestResult.NotFound(); - } - - data.UpdateAccount(account); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task PatchAccountUsername(AccountUsernameRequest data) - { - Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId()); - - if (!ComputeHash(data.Password, account.LeftSalt, account.RightSalt).SequenceEqual(account.Password)) - { - return RequestResult.Unauthorized(); - } - - data.UpdateAccount(account); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task PatchAccountEmail(AccountEmailRequest data) - { - Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId()); - - if (!ComputeHash(data.Password, account.LeftSalt, account.RightSalt).SequenceEqual(account.Password)) - { - return RequestResult.Unauthorized(); - } - - data.UpdateAccount(account); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task PatchAccountPassword(AccountPasswordRequest data) - { - Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId()); - - if (!ComputeHash(data.OldPassword, account.LeftSalt, account.RightSalt).SequenceEqual(account.Password)) - { - return RequestResult.Unauthorized(); - } - - SetPassword(account, data.NewPassword); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - #endregion - - public async Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query) - { - Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); - if (account is null) - { - return RequestResult.NotFound(); - } - - IEnumerable response = account.RatingMedia.Join(database.MediaMovies, x => x.MediaId, x => x.Id, (x, y) => new MovieRatedResponse(y, x)); - response = query.PrepareData(response); - return RequestResult.Ok(response); - } - - public async Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query) - { - Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); - if (account is null) - { - return RequestResult.NotFound(); - } - - IEnumerable response = account.RatingMedia.Join(database.MediaSeries, x => x.MediaId, x => x.Id, (x, y) => new SeriesRatedResponse(y, x)); - response = query.PrepareData(response); - return RequestResult.Ok(response); - } - - public async Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query) - { - Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); - if (account is null) - { - return RequestResult.NotFound(); - } - - IEnumerable actorRolesRatings = account.RatingPersonActorRole; - IEnumerable creatorRolesRatings = account.RatingPersonCreatorRole; - IEnumerable persons = actorRolesRatings.Select(x => x.PersonActorRole.Person) - .Union(creatorRolesRatings.Select(x => x.PersonCreatorRole.Person)); - - IEnumerable response = persons.Select(x => new PersonRatedResponse(x, actorRolesRatings.Where(y => y.PersonActorRole.Person.Id == x.Id), creatorRolesRatings.Where(y => y.PersonCreatorRole.Person.Id == x.Id))); - response = query.PrepareData(response); - return RequestResult.Ok(response); - } - - #endregion - - - - #region PRIVATE METHODS - - protected byte[] ComputeHash(string password, string leftSalt, string rightSalt) => SHA512.HashData(Encoding.UTF8.GetBytes($"{leftSalt}{password}{rightSalt}")); - - private void SetPassword(Account account, string password) - { - string leftSalt = StringExtensions.CreateRandom(20); - string rightSalt = StringExtensions.CreateRandom(20); - byte[] hash = ComputeHash(password, leftSalt, rightSalt); - - account.Password = hash; - account.LeftSalt = leftSalt; - account.RightSalt = rightSalt; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs deleted file mode 100644 index bb03dc5..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs +++ /dev/null @@ -1,31 +0,0 @@ -using WatchIt.Common.Model.Accounts; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Movies; -using WatchIt.Common.Model.Persons; -using WatchIt.Common.Model.Series; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Accounts; - -public interface IAccountsControllerService -{ - Task Register(RegisterRequest data); - Task Authenticate(AuthenticateRequest data); - Task AuthenticateRefresh(); - Task Logout(); - Task GetAccountProfilePicture(long id); - Task PutAccountProfilePicture(AccountProfilePictureRequest data); - Task DeleteAccountProfilePicture(); - Task GetAccountProfileBackground(long id); - Task PutAccountProfileBackground(AccountProfileBackgroundRequest data); - Task DeleteAccountProfileBackground(); - Task GetAccounts(AccountQueryParameters query); - Task GetAccount(long id); - Task PutAccountProfileInfo(AccountProfileInfoRequest data); - Task PatchAccountUsername(AccountUsernameRequest data); - Task PatchAccountEmail(AccountEmailRequest data); - Task PatchAccountPassword(AccountPasswordRequest data); - Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query); - Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query); - Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/WatchIt.WebAPI.Services.Controllers.Accounts.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/WatchIt.WebAPI.Services.Controllers.Accounts.csproj deleted file mode 100644 index 63b4303..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/WatchIt.WebAPI.Services.Controllers.Accounts.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestBadRequestResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestBadRequestResult.cs deleted file mode 100644 index 2389416..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestBadRequestResult.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ModelBinding; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public class RequestBadRequestResult : RequestResult -{ - #region FIELDS - - private readonly ModelStateDictionary _modelState; - - #endregion - - - - #region CONSTRUCTORS - - public RequestBadRequestResult() : base(RequestResultStatus.BadRequest) - { - _modelState = new ModelStateDictionary(); - } - - #endregion - - - - #region PUBLIC METHODS - - public RequestBadRequestResult AddValidationError(string propertyName, string message) - { - _modelState.AddModelError(propertyName, message); - return this; - } - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new BadRequestObjectResult(_modelState); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestConflictResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestConflictResult.cs deleted file mode 100644 index aa83308..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestConflictResult.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public class RequestConflictResult : RequestResult -{ - #region CONSTRUCTORS - - public RequestConflictResult() : base(RequestResultStatus.Conflict) - { - } - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new ConflictResult(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestCreatedResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestCreatedResult.cs deleted file mode 100644 index 823aa10..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestCreatedResult.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public class RequestCreatedResult : RequestResult -{ - #region PROPERTIES - - public string Location { get; } - public T Data { get; } - - #endregion - - - - #region CONSTRUCTORS - - internal RequestCreatedResult(string location, T data) : base(RequestResultStatus.Created) - { - Location = location; - Data = data; - } - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new CreatedResult(Location, Data); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestForbiddenResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestForbiddenResult.cs deleted file mode 100644 index a43e0b0..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestForbiddenResult.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public class RequestForbiddenResult : RequestResult -{ - #region CONSTRUCTORS - - public RequestForbiddenResult() : base(RequestResultStatus.Forbidden) - { - } - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new ForbidResult(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestNoContentResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestNoContentResult.cs deleted file mode 100644 index 3c89c1f..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestNoContentResult.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public class RequestNoContentResult : RequestResult -{ - #region CONSTRUCTORS - - internal RequestNoContentResult() : base(RequestResultStatus.NoContent) - { - } - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new NoContentResult(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestNotFoundResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestNotFoundResult.cs deleted file mode 100644 index c41927b..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestNotFoundResult.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public class RequestNotFoundResult : RequestResult -{ - #region CONSTRUCTORS - - public RequestNotFoundResult() : base(RequestResultStatus.NotFound) - { - } - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new NotFoundResult(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestOkResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestOkResult.cs deleted file mode 100644 index 07ffb41..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestOkResult.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public class RequestOkResult : RequestResult -{ - #region CONSTRUCTORS - - internal RequestOkResult() : base(RequestResultStatus.Ok) - { - } - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new OkResult(); - - #endregion -} - -public class RequestOkResult : RequestOkResult -{ - #region PROPERTIES - - public T Data { get; } - - #endregion - - - - #region CONSTRUCTORS - - internal RequestOkResult(T data) : base() => Data = data; - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new OkObjectResult(Data); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestResult.cs deleted file mode 100644 index 07ebebb..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestResult.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public abstract class RequestResult -{ - #region PROPERTIES - - public RequestResultStatus Status { get; } - - #endregion - - - - #region CONSTRUCTORS - - protected RequestResult(RequestResultStatus status) => Status = status; - - public static RequestOkResult Ok() => new RequestOkResult(); - public static RequestOkResult Ok(T data) => new RequestOkResult(data); - public static RequestCreatedResult Created(string location, T data) => new RequestCreatedResult(location, data); - public static RequestNoContentResult NoContent() => new RequestNoContentResult(); - public static RequestBadRequestResult BadRequest() => new RequestBadRequestResult(); - public static RequestUnauthorizedResult Unauthorized() => new RequestUnauthorizedResult(); - public static RequestForbiddenResult Forbidden() => new RequestForbiddenResult(); - public static RequestNotFoundResult NotFound() => new RequestNotFoundResult(); - public static RequestConflictResult Conflict() => new RequestConflictResult(); - - #endregion - - - - #region CONVERSION - - public static implicit operator ActionResult(RequestResult result) => result.ConvertToActionResult(); - - protected abstract ActionResult ConvertToActionResult(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestResultStatus.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestResultStatus.cs deleted file mode 100644 index 0d62a8e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestResultStatus.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public enum RequestResultStatus -{ - Ok = 200, - Created = 201, - NoContent = 204, - BadRequest = 400, - Unauthorized = 401, - Forbidden = 403, - NotFound = 404, - Conflict = 409, -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestUnauthorizedResult.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestUnauthorizedResult.cs deleted file mode 100644 index 1765125..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/RequestUnauthorizedResult.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ModelBinding; - -namespace WatchIt.WebAPI.Services.Controllers.Common; - -public class RequestUnauthorizedResult : RequestResult -{ - #region CONSTRUCTORS - - public RequestUnauthorizedResult() : base(RequestResultStatus.Unauthorized) - { - } - - #endregion - - - - #region CONVERTION - - protected override ActionResult ConvertToActionResult() => new UnauthorizedResult(); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/WatchIt.WebAPI.Services.Controllers.Common.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/WatchIt.WebAPI.Services.Controllers.Common.csproj deleted file mode 100644 index bdbaf02..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Common/WatchIt.WebAPI.Services.Controllers.Common.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net8.0 - enable - enable - - - - - ..\..\..\..\..\..\..\..\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.2\Microsoft.AspNetCore.Mvc.Core.dll - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/GendersControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/GendersControllerService.cs deleted file mode 100644 index 6c7d7dc..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/GendersControllerService.cs +++ /dev/null @@ -1,97 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using WatchIt.Common.Model.Genders; -using WatchIt.Database; -using WatchIt.Database.Model.Common; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.User; -using Gender = WatchIt.Database.Model.Common.Gender; - -namespace WatchIt.WebAPI.Services.Controllers.Genders; - -public class GendersControllerService : IGendersControllerService -{ - #region SERVICES - - private readonly DatabaseContext _database; - private readonly IUserService _userService; - - #endregion - - - - #region CONSTRUCTORS - - public GendersControllerService(DatabaseContext database, IUserService userService) - { - _database = database; - _userService = userService; - } - - #endregion - - - - #region PUBLIC METHODS - - #region Main - - public async Task GetAllGenders(GenderQueryParameters query) - { - IEnumerable rawData = await _database.Genders.ToListAsync(); - IEnumerable data = rawData.Select(x => new GenderResponse(x)); - data = query.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task GetGender(short id) - { - Gender? item = await _database.Genders.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - GenderResponse data = new GenderResponse(item); - return RequestResult.Ok(data); - } - - public async Task PostGender(GenderRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Gender item = data.CreateGender(); - await _database.Genders.AddAsync(item); - await _database.SaveChangesAsync(); - - return RequestResult.Created($"genres/{item.Id}", new GenderResponse(item)); - } - - public async Task DeleteGender(short id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Gender? item = await _database.Genders.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NoContent(); - } - - _database.Genders.Attach(item); - _database.Genders.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.NoContent(); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/IGendersControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/IGendersControllerService.cs deleted file mode 100644 index 92aec83..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/IGendersControllerService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using WatchIt.Common.Model.Genders; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Genders; - -public interface IGendersControllerService -{ - Task GetAllGenders(GenderQueryParameters query); - Task GetGender(short id); - Task PostGender(GenderRequest data); - Task DeleteGender(short id); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/WatchIt.WebAPI.Services.Controllers.Genders.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/WatchIt.WebAPI.Services.Controllers.Genders.csproj deleted file mode 100644 index 9e4603e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genders/WatchIt.WebAPI.Services.Controllers.Genders.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/GenresControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/GenresControllerService.cs deleted file mode 100644 index 5357aa8..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/GenresControllerService.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using WatchIt.Common.Model.Genres; -using WatchIt.Database; -using WatchIt.Database.Model.Media; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.User; -using Genre = WatchIt.Database.Model.Common.Genre; - -namespace WatchIt.WebAPI.Services.Controllers.Genres; - -public class GenresControllerService(DatabaseContext database, IUserService userService) : IGenresControllerService -{ - #region PUBLIC METHODS - - public async Task GetAll(GenreQueryParameters query) - { - IEnumerable data = await database.Genres.Select(x => new GenreResponse(x)).ToListAsync(); - data = query.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task Get(short id) - { - Genre? item = await database.Genres.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - GenreResponse data = new GenreResponse(item); - return RequestResult.Ok(data); - } - - public async Task Post(GenreRequest data) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Genre item = data.CreateGenre(); - await database.Genres.AddAsync(item); - await database.SaveChangesAsync(); - - return RequestResult.Created($"genres/{item.Id}", new GenreResponse(item)); - } - - public async Task Put(short id, GenreRequest data) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Genre? item = await database.Genres.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - data.UpdateGenre(item); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task Delete(short id) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Genre? item = await database.Genres.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - database.MediaGenres.AttachRange(item.MediaGenres); - database.MediaGenres.RemoveRange(item.MediaGenres); - database.Genres.Attach(item); - database.Genres.Remove(item); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/IGenresControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/IGenresControllerService.cs deleted file mode 100644 index 4fc50a9..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/IGenresControllerService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using WatchIt.Common.Model.Genres; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Genres; - -public interface IGenresControllerService -{ - Task GetAll(GenreQueryParameters query); - Task Get(short id); - Task Post(GenreRequest data); - Task Put(short id, GenreRequest data); - Task Delete(short id); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/WatchIt.WebAPI.Services.Controllers.Genres.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/WatchIt.WebAPI.Services.Controllers.Genres.csproj deleted file mode 100644 index 9e4603e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/WatchIt.WebAPI.Services.Controllers.Genres.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs deleted file mode 100644 index 8b073a0..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs +++ /dev/null @@ -1,37 +0,0 @@ -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Photos; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Roles; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Media; - -public interface IMediaControllerService -{ - Task GetAllMedia(MediaQueryParameters query); - Task GetMedia(long mediaId); - - Task GetMediaGenres(long mediaId); - Task PostMediaGenre(long mediaId, short genreId); - Task DeleteMediaGenre(long mediaId, short genreId); - - Task GetMediaRating(long mediaId); - Task GetMediaRatingByUser(long mediaId, long userId); - Task PutMediaRating(long mediaId, RatingRequest data); - Task DeleteMediaRating(long mediaId); - - Task PostMediaView(long mediaId); - - Task GetMediaPoster(long mediaId); - Task PutMediaPoster(long mediaId, MediaPosterRequest data); - Task DeleteMediaPoster(long mediaId); - - Task GetMediaPhotos(long mediaId, PhotoQueryParameters queryParameters); - Task GetMediaPhotoRandomBackground(long mediaId); - Task PostMediaPhoto(long mediaId, MediaPhotoRequest data); - - Task GetMediaAllActorRoles(long mediaId, ActorRoleMediaQueryParameters queryParameters); - Task PostMediaActorRole(long mediaId, ActorRoleMediaRequest data); - Task GetMediaAllCreatorRoles(long mediaId, CreatorRoleMediaQueryParameters queryParameters); - Task PostMediaCreatorRole(long mediaId, CreatorRoleMediaRequest data); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs deleted file mode 100644 index ac92c5f..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs +++ /dev/null @@ -1,429 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using SimpleToolkit.Extensions; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Photos; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Roles; -using WatchIt.Database; -using WatchIt.Database.Model.Media; -using WatchIt.Database.Model.Person; -using WatchIt.Database.Model.Rating; -using WatchIt.Database.Model.ViewCount; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.User; - -namespace WatchIt.WebAPI.Services.Controllers.Media; - -public class MediaControllerService(DatabaseContext database, IUserService userService) : IMediaControllerService -{ - #region PUBLIC METHODS - - #region Main - - public async Task GetAllMedia(MediaQueryParameters query) - { - IEnumerable rawData = await database.Media.ToListAsync(); - IEnumerable data = rawData.Select(x => new MediaResponse(x, database.MediaMovies.Any(y => y.Id == x.Id) ? MediaType.Movie : MediaType.Series)); - data = query.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task GetMedia(long mediaId) - { - Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (item is null) - { - return RequestResult.NotFound(); - } - - MediaMovie? movie = await database.MediaMovies.FirstOrDefaultAsync(x => x.Id == mediaId); - - MediaResponse mediaResponse = new MediaResponse(item, movie is not null ? MediaType.Movie : MediaType.Series); - - return RequestResult.Ok(mediaResponse); - } - - #endregion - - #region Genres - - public async Task GetMediaGenres(long mediaId) - { - Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (item is null) - { - return RequestResult.NotFound(); - } - - IEnumerable genres = item.MediaGenres.Select(x => new GenreResponse(x.Genre)); - return RequestResult.Ok(genres); - } - - public async Task PostMediaGenre(long mediaId, short genreId) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Database.Model.Media.Media? mediaItem = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - Database.Model.Common.Genre? genreItem = await database.Genres.FirstOrDefaultAsync(x => x.Id == genreId); - if (mediaItem is null || genreItem is null) - { - return RequestResult.NotFound(); - } - - await database.MediaGenres.AddAsync(new MediaGenre - { - GenreId = genreId, - MediaId = mediaId, - }); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeleteMediaGenre(long mediaId, short genreId) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - MediaGenre? item = await database.MediaGenres.FirstOrDefaultAsync(x => x.MediaId == mediaId && x.GenreId == genreId); - if (item is null) - { - return RequestResult.NotFound(); - } - - database.MediaGenres.Attach(item); - database.MediaGenres.Remove(item); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - #endregion - - #region Rating - - public async Task GetMediaRating(long mediaId) - { - Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (item is null) - { - return RequestResult.NotFound(); - } - - RatingResponse ratingResponse = RatingResponseBuilder.Initialize() - .Add(item.RatingMedia, x => x.Rating) - .Build(); - - return RequestResult.Ok(ratingResponse); - } - - public async Task GetMediaRatingByUser(long mediaId, long userId) - { - RatingMedia? rating = await database.RatingsMedia.FirstOrDefaultAsync(x => x.MediaId == mediaId && x.AccountId == userId); - if (rating is null) - { - return RequestResult.NotFound(); - } - - return RequestResult.Ok(rating.Rating); - } - - public async Task PutMediaRating(long mediaId, RatingRequest data) - { - Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (item is null) - { - return RequestResult.NotFound(); - } - - long userId = userService.GetUserId(); - - RatingMedia? rating = item.RatingMedia.FirstOrDefault(x => x.AccountId == userId); - if (rating is not null) - { - rating.Rating = data.Rating; - } - else - { - rating = new RatingMedia - { - AccountId = userId, - MediaId = mediaId, - Rating = data.Rating - }; - await database.RatingsMedia.AddAsync(rating); - } - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeleteMediaRating(long mediaId) - { - long userId = userService.GetUserId(); - - RatingMedia? item = await database.RatingsMedia.FirstOrDefaultAsync(x => x.MediaId == mediaId && x.AccountId == userId); - if (item is null) - { - return RequestResult.Ok(); - } - - database.RatingsMedia.Attach(item); - database.RatingsMedia.Remove(item); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - #endregion - - #region View count - - public async Task PostMediaView(long mediaId) - { - Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (item is null) - { - return RequestResult.NotFound(); - } - - DateOnly dateNow = DateOnly.FromDateTime(DateTime.Now); - ViewCountMedia? viewCount = await database.ViewCountsMedia.FirstOrDefaultAsync(x => x.MediaId == mediaId && x.Date == dateNow); - if (viewCount is null) - { - viewCount = new ViewCountMedia - { - MediaId = mediaId, - Date = dateNow, - ViewCount = 1 - }; - await database.ViewCountsMedia.AddAsync(viewCount); - } - else - { - viewCount.ViewCount++; - } - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - #endregion - - #region Poster - - public async Task GetMediaPoster(long mediaId) - { - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (media is null) - { - return RequestResult.BadRequest(); - } - - MediaPosterImage? poster = media.MediaPosterImage; - if (poster is null) - { - return RequestResult.NotFound(); - } - - MediaPosterResponse data = new MediaPosterResponse(poster); - return RequestResult.Ok(data); - } - - public async Task PutMediaPoster(long mediaId, MediaPosterRequest data) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (media is null) - { - return RequestResult.BadRequest(); - } - - if (media.MediaPosterImage is null) - { - MediaPosterImage image = data.CreateMediaPosterImage(); - await database.MediaPosterImages.AddAsync(image); - await database.SaveChangesAsync(); - - media.MediaPosterImageId = image.Id; - } - else - { - data.UpdateMediaPosterImage(media.MediaPosterImage); - } - - await database.SaveChangesAsync(); - - MediaPosterResponse returnData = new MediaPosterResponse(media.MediaPosterImage!); - return RequestResult.Ok(returnData); - } - - public async Task DeleteMediaPoster(long mediaId) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - - if (media?.MediaPosterImage != null) - { - database.MediaPosterImages.Attach(media.MediaPosterImage); - database.MediaPosterImages.Remove(media.MediaPosterImage); - await database.SaveChangesAsync(); - } - - return RequestResult.NoContent(); - } - - #endregion - - #region Photos - - public async Task GetMediaPhotos(long mediaId, PhotoQueryParameters queryParameters) - { - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (media is null) - { - return RequestResult.NotFound(); - } - - IEnumerable imagesRaw = await database.MediaPhotoImages.Where(x => x.MediaId == mediaId).ToListAsync(); - IEnumerable images = imagesRaw.Select(x => new PhotoResponse(x)); - images = queryParameters.PrepareData(images); - return RequestResult.Ok(images); - } - - public Task GetMediaPhotoRandomBackground(long mediaId) - { - MediaPhotoImage? image = database.MediaPhotoImages.Where(x => x.MediaId == mediaId && x.MediaPhotoImageBackground != null).Random(); - if (image is null) - { - return Task.FromResult(RequestResult.NotFound()); - } - - PhotoResponse data = new PhotoResponse(image); - return Task.FromResult(RequestResult.Ok(data)); - } - - public async Task PostMediaPhoto(long mediaId, MediaPhotoRequest data) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (media is null) - { - return RequestResult.NotFound(); - } - - MediaPhotoImage item = data.CreateMediaPhotoImage(mediaId); - await database.MediaPhotoImages.AddAsync(item); - await database.SaveChangesAsync(); - - MediaPhotoImageBackground? background = data.CreateMediaPhotoImageBackground(item.Id); - if (background is not null) - { - await database.MediaPhotoImageBackgrounds.AddAsync(background); - await database.SaveChangesAsync(); - } - - return RequestResult.Created($"photos/{item.Id}", new PhotoResponse(item)); - } - - #endregion - - #region Roles - - public async Task GetMediaAllActorRoles(long mediaId, ActorRoleMediaQueryParameters queryParameters) - { - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (media is null) - { - return RequestResult.NotFound(); - } - - IEnumerable dataRaw = await database.PersonActorRoles.Where(x => x.MediaId == mediaId).ToListAsync(); - IEnumerable data = dataRaw.Select(x => new ActorRoleResponse(x)); - data = queryParameters.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task PostMediaActorRole(long mediaId, ActorRoleMediaRequest data) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (media is null) - { - return RequestResult.NotFound(); - } - - PersonActorRole item = data.CreateActorRole(mediaId); - await database.PersonActorRoles.AddAsync(item); - await database.SaveChangesAsync(); - - return RequestResult.Created($"roles/actor/{item.Id}", new ActorRoleResponse(item)); - } - - public async Task GetMediaAllCreatorRoles(long mediaId, CreatorRoleMediaQueryParameters queryParameters) - { - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (media is null) - { - return RequestResult.NotFound(); - } - - IEnumerable dataRaw = await database.PersonCreatorRoles.Where(x => x.MediaId == mediaId).ToListAsync(); - IEnumerable data = dataRaw.Select(x => new CreatorRoleResponse(x)); - data = queryParameters.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task PostMediaCreatorRole(long mediaId, CreatorRoleMediaRequest data) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); - if (media is null) - { - return RequestResult.NotFound(); - } - - PersonCreatorRole item = data.CreateCreatorRole(mediaId); - await database.PersonCreatorRoles.AddAsync(item); - await database.SaveChangesAsync(); - - return RequestResult.Created($"roles/creator/{item.Id}", new CreatorRoleResponse(item)); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/WatchIt.WebAPI.Services.Controllers.Media.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/WatchIt.WebAPI.Services.Controllers.Media.csproj deleted file mode 100644 index 6e9f94c..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/WatchIt.WebAPI.Services.Controllers.Media.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/IMoviesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/IMoviesControllerService.cs deleted file mode 100644 index cc514a5..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/IMoviesControllerService.cs +++ /dev/null @@ -1,15 +0,0 @@ -using WatchIt.Common.Model.Movies; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Movies; - -public interface IMoviesControllerService -{ - Task GetAllMovies(MovieQueryParameters query); - Task GetMovie(long id); - Task PostMovie(MovieRequest data); - Task PutMovie(long id, MovieRequest data); - Task DeleteMovie(long id); - - Task GetMoviesViewRank(int first, int days); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/MoviesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/MoviesControllerService.cs deleted file mode 100644 index f94ce06..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/MoviesControllerService.cs +++ /dev/null @@ -1,163 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using WatchIt.Common.Model.Movies; -using WatchIt.Database; -using WatchIt.Database.Model.Media; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.User; - -namespace WatchIt.WebAPI.Services.Controllers.Movies; - -public class MoviesControllerService : IMoviesControllerService -{ - #region SERVICES - - private readonly DatabaseContext _database; - - private readonly IUserService _userService; - - #endregion - - - - #region CONSTRUCTORS - - public MoviesControllerService(DatabaseContext database, IUserService userService) - { - _database = database; - - _userService = userService; - } - - #endregion - - - - #region PUBLIC METHODS - - #region Main - - public async Task GetAllMovies(MovieQueryParameters query) - { - IEnumerable rawData = await _database.MediaMovies.ToListAsync(); - IEnumerable data = rawData.Select(x => new MovieResponse(x)); - data = query.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task GetMovie(long id) - { - MediaMovie? item = await _database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - MovieResponse data = new MovieResponse(item); - return RequestResult.Ok(data); - } - - public async Task PostMovie(MovieRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Media mediaItem = data.CreateMedia(); - await _database.Media.AddAsync(mediaItem); - await _database.SaveChangesAsync(); - MediaMovie mediaMovieItem = data.CreateMediaMovie(mediaItem.Id); - await _database.MediaMovies.AddAsync(mediaMovieItem); - await _database.SaveChangesAsync(); - - return RequestResult.Created($"movies/{mediaItem.Id}", new MovieResponse(mediaMovieItem)); - } - - public async Task PutMovie(long id, MovieRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - MediaMovie? item = await _database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - data.UpdateMediaMovie(item); - data.UpdateMedia(item.Media); - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeleteMovie(long id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - MediaMovie? item = await _database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - _database.MediaMovies.Attach(item); - _database.MediaMovies.Remove(item); - _database.MediaPosterImages.Attach(item.Media.MediaPosterImage!); - _database.MediaPosterImages.Remove(item.Media.MediaPosterImage!); - _database.MediaPhotoImages.AttachRange(item.Media.MediaPhotoImages); - _database.MediaPhotoImages.RemoveRange(item.Media.MediaPhotoImages); - _database.MediaGenres.AttachRange(item.Media.MediaGenres); - _database.MediaGenres.RemoveRange(item.Media.MediaGenres); - _database.MediaProductionCountries.AttachRange(item.Media.MediaProductionCountries); - _database.MediaProductionCountries.RemoveRange(item.Media.MediaProductionCountries); - _database.PersonActorRoles.AttachRange(item.Media.PersonActorRoles); - _database.PersonActorRoles.RemoveRange(item.Media.PersonActorRoles); - _database.PersonCreatorRoles.AttachRange(item.Media.PersonCreatorRoles); - _database.PersonCreatorRoles.RemoveRange(item.Media.PersonCreatorRoles); - _database.RatingsMedia.AttachRange(item.Media.RatingMedia); - _database.RatingsMedia.RemoveRange(item.Media.RatingMedia); - _database.ViewCountsMedia.AttachRange(item.Media.ViewCountsMedia); - _database.ViewCountsMedia.RemoveRange(item.Media.ViewCountsMedia); - _database.Media.Attach(item.Media); - _database.Media.Remove(item.Media); - await _database.SaveChangesAsync(); - - return RequestResult.NoContent(); - } - - #endregion - - #region View count - - public async Task GetMoviesViewRank(int first, int days) - { - if (first < 1 || days < 1) - { - return RequestResult.BadRequest(); - } - - DateOnly startDate = DateOnly.FromDateTime(DateTime.Now).AddDays(-days); - IEnumerable rawData = await _database.MediaMovies.OrderByDescending(x => x.Media.ViewCountsMedia.Where(y => y.Date >= startDate) - .Sum(y => y.ViewCount)) - .ThenBy(x => x.Id) - .Take(first) - .ToListAsync(); - - IEnumerable data = rawData.Select(x => new MovieResponse(x)); - - return RequestResult.Ok(data); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/WatchIt.WebAPI.Services.Controllers.Movies.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/WatchIt.WebAPI.Services.Controllers.Movies.csproj deleted file mode 100644 index 9e4603e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/WatchIt.WebAPI.Services.Controllers.Movies.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/IPersonsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/IPersonsControllerService.cs deleted file mode 100644 index 76599a3..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/IPersonsControllerService.cs +++ /dev/null @@ -1,29 +0,0 @@ -using WatchIt.Common.Model.Persons; -using WatchIt.Common.Model.Roles; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Persons; - -public interface IPersonsControllerService -{ - Task GetAllPersons(PersonQueryParameters query); - Task GetPerson(long id); - Task PostPerson(PersonRequest data); - Task PutPerson(long id, PersonRequest data); - Task DeletePerson(long id); - - Task GetPersonsViewRank(int first, int days); - Task PostPersonsView(long personId); - - Task GetPersonPhoto(long id); - Task PutPersonPhoto(long id, PersonPhotoRequest data); - Task DeletePersonPhoto(long id); - - Task GetPersonAllActorRoles(long personId, ActorRolePersonQueryParameters queryParameters); - Task PostPersonActorRole(long personId, ActorRolePersonRequest data); - Task GetPersonAllCreatorRoles(long personId, CreatorRolePersonQueryParameters queryParameters); - Task PostPersonCreatorRole(long personId, CreatorRolePersonRequest data); - - Task GetPersonGlobalRating(long id); - Task GetPersonUserRating(long id, long userId); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/PersonsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/PersonsControllerService.cs deleted file mode 100644 index a8857aa..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/PersonsControllerService.cs +++ /dev/null @@ -1,365 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using WatchIt.Common.Model.Persons; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Roles; -using WatchIt.Database; -using WatchIt.Database.Model.Person; -using WatchIt.Database.Model.Rating; -using WatchIt.Database.Model.ViewCount; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.User; -using Person = WatchIt.Database.Model.Person.Person; - -namespace WatchIt.WebAPI.Services.Controllers.Persons; - -public class PersonsControllerService : IPersonsControllerService -{ - #region SERVICES - - private readonly DatabaseContext _database; - private readonly IUserService _userService; - - #endregion - - - - #region CONSTRUCTORS - - public PersonsControllerService(DatabaseContext database, IUserService userService) - { - _database = database; - _userService = userService; - } - - #endregion - - - - #region PUBLIC METHODS - - #region Main - - public async Task GetAllPersons(PersonQueryParameters query) - { - IEnumerable rawData = await _database.Persons.ToListAsync(); - IEnumerable data = rawData.Select(x => new PersonResponse(x)); - data = query.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task GetPerson(long id) - { - Person? item = await _database.Persons.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - PersonResponse data = new PersonResponse(item); - return RequestResult.Ok(data); - } - - public async Task PostPerson(PersonRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Person personItem = data.CreatePerson(); - await _database.Persons.AddAsync(personItem); - await _database.SaveChangesAsync(); - - return RequestResult.Created($"persons/{personItem.Id}", new PersonResponse(personItem)); - } - - public async Task PutPerson(long id, PersonRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Person? item = await _database.Persons.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - data.UpdatePerson(item); - - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeletePerson(long id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Person? item = await _database.Persons.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - _database.PersonCreatorRoles.AttachRange(item.PersonCreatorRoles); - _database.PersonCreatorRoles.RemoveRange(item.PersonCreatorRoles); - _database.PersonActorRoles.AttachRange(item.PersonActorRoles); - _database.PersonActorRoles.RemoveRange(item.PersonActorRoles); - _database.ViewCountsPerson.AttachRange(item.ViewCountsPerson); - _database.ViewCountsPerson.RemoveRange(item.ViewCountsPerson); - _database.Persons.Attach(item); - _database.Persons.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.NoContent(); - } - - #endregion - - #region View count - - public async Task GetPersonsViewRank(int first, int days) - { - if (first < 1 || days < 1) - { - return RequestResult.BadRequest(); - } - - DateOnly startDate = DateOnly.FromDateTime(DateTime.Now).AddDays(-days); - IEnumerable rawData = await _database.Persons.OrderByDescending(x => x.ViewCountsPerson.Where(y => y.Date >= startDate) - .Sum(y => y.ViewCount)) - .ThenBy(x => x.Id) - .Take(first) - .ToListAsync(); - - IEnumerable data = rawData.Select(x => new PersonResponse(x)); - - return RequestResult.Ok(data); - } - - public async Task PostPersonsView(long personId) - { - Database.Model.Media.Media? item = await _database.Media.FirstOrDefaultAsync(x => x.Id == personId); - if (item is null) - { - return RequestResult.NotFound(); - } - - DateOnly dateNow = DateOnly.FromDateTime(DateTime.Now); - ViewCountPerson? viewCount = await _database.ViewCountsPerson.FirstOrDefaultAsync(x => x.PersonId == personId && x.Date == dateNow); - if (viewCount is null) - { - viewCount = new ViewCountPerson - { - PersonId = personId, - Date = dateNow, - ViewCount = 1 - }; - await _database.ViewCountsPerson.AddAsync(viewCount); - } - else - { - viewCount.ViewCount++; - } - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - #endregion - - #region Photo - - public async Task GetPersonPhoto(long id) - { - Person? person = await _database.Persons.FirstOrDefaultAsync(x => x.Id == id); - if (person is null) - { - return RequestResult.BadRequest(); - } - - PersonPhotoImage? photo = person.PersonPhoto; - if (photo is null) - { - return RequestResult.NotFound(); - } - - PersonPhotoResponse data = new PersonPhotoResponse(photo); - return RequestResult.Ok(data); - } - - public async Task PutPersonPhoto(long id, PersonPhotoRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Person? person = await _database.Persons.FirstOrDefaultAsync(x => x.Id == id); - if (person is null) - { - return RequestResult.BadRequest(); - } - - if (person.PersonPhoto is null) - { - PersonPhotoImage image = data.CreatePersonPhotoImage(); - await _database.PersonPhotoImages.AddAsync(image); - await _database.SaveChangesAsync(); - - person.PersonPhotoId = image.Id; - } - else - { - data.UpdatePersonPhotoImage(person.PersonPhoto); - } - - await _database.SaveChangesAsync(); - - PersonPhotoResponse returnData = new PersonPhotoResponse(person.PersonPhoto); - return RequestResult.Ok(returnData); - } - - public async Task DeletePersonPhoto(long id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Person? person = await _database.Persons.FirstOrDefaultAsync(x => x.Id == id); - - if (person?.PersonPhoto != null) - { - _database.PersonPhotoImages.Attach(person.PersonPhoto); - _database.PersonPhotoImages.Remove(person.PersonPhoto); - await _database.SaveChangesAsync(); - } - - return RequestResult.NoContent(); - } - - #endregion - - #region Roles - - public async Task GetPersonAllActorRoles(long personId, ActorRolePersonQueryParameters queryParameters) - { - Database.Model.Person.Person? person = await _database.Persons.FirstOrDefaultAsync(x => x.Id == personId); - if (person is null) - { - return RequestResult.NotFound(); - } - - IEnumerable dataRaw = await _database.PersonActorRoles.Where(x => x.PersonId == personId).ToListAsync(); - IEnumerable data = dataRaw.Select(x => new ActorRoleResponse(x)); - data = queryParameters.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task PostPersonActorRole(long personId, ActorRolePersonRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Person? person = await _database.Persons.FirstOrDefaultAsync(x => x.Id == personId); - if (person is null) - { - return RequestResult.NotFound(); - } - - PersonActorRole item = data.CreateActorRole(personId); - await _database.PersonActorRoles.AddAsync(item); - await _database.SaveChangesAsync(); - - return RequestResult.Created($"roles/actor/{item.Id}", new ActorRoleResponse(item)); - } - - public async Task GetPersonAllCreatorRoles(long personId, CreatorRolePersonQueryParameters queryParameters) - { - Person? media = await _database.Persons.FirstOrDefaultAsync(x => x.Id == personId); - if (media is null) - { - return RequestResult.NotFound(); - } - - IEnumerable dataRaw = await _database.PersonCreatorRoles.Where(x => x.PersonId == personId).ToListAsync(); - IEnumerable data = dataRaw.Select(x => new CreatorRoleResponse(x)); - data = queryParameters.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task PostPersonCreatorRole(long personId, CreatorRolePersonRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Person? media = await _database.Persons.FirstOrDefaultAsync(x => x.Id == personId); - if (media is null) - { - return RequestResult.NotFound(); - } - - PersonCreatorRole item = data.CreateCreatorRole(personId); - await _database.PersonCreatorRoles.AddAsync(item); - await _database.SaveChangesAsync(); - - return RequestResult.Created($"roles/creator/{item.Id}", new CreatorRoleResponse(item)); - } - - #endregion - - #region Rating - - public async Task GetPersonGlobalRating(long id) - { - Person? item = await _database.Persons.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - RatingResponse ratingResponse = RatingResponseBuilder.Initialize() - .Add(item.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating) - .Add(item.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating) - .Build(); - - return RequestResult.Ok(ratingResponse); - } - - public async Task GetPersonUserRating(long id, long userId) - { - Person? item = await _database.Persons.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - RatingResponse ratingResponse = RatingResponseBuilder.Initialize() - .Add(item.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole).Where(x => x.AccountId == userId), x => x.Rating) - .Add(item.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole).Where(x => x.AccountId == userId), x => x.Rating) - .Build(); - - return RequestResult.Ok(ratingResponse); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/WatchIt.WebAPI.Services.Controllers.Persons.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/WatchIt.WebAPI.Services.Controllers.Persons.csproj deleted file mode 100644 index 9e4603e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/WatchIt.WebAPI.Services.Controllers.Persons.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/IPhotosControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/IPhotosControllerService.cs deleted file mode 100644 index 8b17b02..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/IPhotosControllerService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using WatchIt.Common.Model.Photos; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Photos; - -public interface IPhotosControllerService -{ - Task GetPhotoRandomBackground(); - Task DeletePhoto(Guid photoId); - - Task PutPhotoBackgroundData(Guid id, PhotoBackgroundDataRequest data); - Task DeletePhotoBackgroundData(Guid id); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/PhotosControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/PhotosControllerService.cs deleted file mode 100644 index 68b0627..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/PhotosControllerService.cs +++ /dev/null @@ -1,140 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; -using SimpleToolkit.Extensions; -using WatchIt.Common.Model.Photos; -using WatchIt.Database; -using WatchIt.Database.Model.Media; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.User; - -namespace WatchIt.WebAPI.Services.Controllers.Photos; - -public class PhotosControllerService : IPhotosControllerService -{ - #region FIELDS - - private readonly DatabaseContext _database; - private readonly IUserService _userService; - - #endregion - - - - #region CONTRUCTORS - - public PhotosControllerService(DatabaseContext database, IUserService userService) - { - _database = database; - _userService = userService; - } - - #endregion - - - - #region PUBLIC METHODS - - #region Main - - public Task GetPhotoRandomBackground() - { - MediaPhotoImage? image = _database.MediaPhotoImages.Where(x => x.MediaPhotoImageBackground != null && x.MediaPhotoImageBackground.IsUniversalBackground).Random(); - if (image is null) - { - return Task.FromResult(RequestResult.NotFound()); - } - - PhotoResponse data = new PhotoResponse(image); - return Task.FromResult(RequestResult.Ok(data)); - } - - public async Task DeletePhoto(Guid photoId) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - MediaPhotoImage? item = await _database.MediaPhotoImages.FirstOrDefaultAsync(x => x.Id == photoId); - if (item is null) - { - return RequestResult.NotFound(); - } - - if (item.MediaPhotoImageBackground is not null) - { - _database.MediaPhotoImageBackgrounds.Attach(item.MediaPhotoImageBackground); - _database.MediaPhotoImageBackgrounds.Remove(item.MediaPhotoImageBackground); - await _database.SaveChangesAsync(); - } - - _database.MediaPhotoImages.Attach(item); - _database.MediaPhotoImages.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - #endregion - - #region Background data - - public async Task PutPhotoBackgroundData(Guid id, PhotoBackgroundDataRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - MediaPhotoImage? image = await _database.MediaPhotoImages.FirstOrDefaultAsync(x => x.Id == id); - if (image is null) - { - return RequestResult.NotFound(); - } - - MediaPhotoImageBackground? imageBackground = image.MediaPhotoImageBackground; - if (imageBackground is null) - { - imageBackground = data.CreateMediaPhotoImageBackground(id); - await _database.MediaPhotoImageBackgrounds.AddAsync(imageBackground); - } - else - { - data.UpdateMediaPhotoImageBackground(imageBackground); - } - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeletePhotoBackgroundData(Guid id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - MediaPhotoImage? image = await _database.MediaPhotoImages.FirstOrDefaultAsync(x => x.Id == id); - if (image is null) - { - return RequestResult.NotFound(); - } - - MediaPhotoImageBackground? imageBackground = image.MediaPhotoImageBackground; - if (imageBackground is not null) - { - _database.MediaPhotoImageBackgrounds.Attach(imageBackground); - _database.MediaPhotoImageBackgrounds.Remove(imageBackground); - await _database.SaveChangesAsync(); - } - - return RequestResult.Ok(); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/WatchIt.WebAPI.Services.Controllers.Photos.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/WatchIt.WebAPI.Services.Controllers.Photos.csproj deleted file mode 100644 index f5730de..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Photos/WatchIt.WebAPI.Services.Controllers.Photos.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/IRolesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/IRolesControllerService.cs deleted file mode 100644 index 5f9f67e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/IRolesControllerService.cs +++ /dev/null @@ -1,32 +0,0 @@ -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Roles; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Roles; - -public interface IRolesControllerService -{ - Task GetActorRole(Guid id); - Task PutActorRole(Guid id, ActorRoleUniversalRequest data); - Task DeleteActorRole(Guid id); - Task GetActorRoleRating(Guid id); - Task GetActorRoleRatingByUser(Guid id, long userId); - Task PutActorRoleRating(Guid id, RatingRequest data); - Task DeleteActorRoleRating(Guid id); - Task GetAllActorRoleTypes(RoleTypeQueryParameters query); - Task GetActorRoleType(short typeId); - Task PostActorRoleType(RoleTypeRequest data); - Task DeleteActorRoleType(short typeId); - - Task GetCreatorRole(Guid id); - Task PutCreatorRole(Guid id, CreatorRoleUniversalRequest data); - Task DeleteCreatorRole(Guid id); - Task GetCreatorRoleRating(Guid id); - Task GetCreatorRoleRatingByUser(Guid id, long userId); - Task PutCreatorRoleRating(Guid id, RatingRequest data); - Task DeleteCreatorRoleRating(Guid id); - Task GetAllCreatorRoleTypes(RoleTypeQueryParameters query); - Task GetCreatorRoleType(short typeId); - Task PostCreatorRoleType(RoleTypeRequest data); - Task DeleteCreatorRoleType(short typeId); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/RolesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/RolesControllerService.cs deleted file mode 100644 index b86b622..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/RolesControllerService.cs +++ /dev/null @@ -1,410 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Roles; -using WatchIt.Database; -using WatchIt.Database.Model.Person; -using WatchIt.Database.Model.Rating; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.User; - -namespace WatchIt.WebAPI.Services.Controllers.Roles; - -public class RolesControllerService : IRolesControllerService -{ - #region SERVICES - - private readonly DatabaseContext _database; - private readonly IUserService _userService; - - #endregion - - - - #region CONSTRUCTORS - - public RolesControllerService(DatabaseContext database, IUserService userService) - { - _database = database; - _userService = userService; - } - - #endregion - - - - #region PUBLIC METHODS - - #region Actor - - public async Task GetActorRole(Guid id) - { - PersonActorRole? item = await _database.PersonActorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - ActorRoleResponse data = new ActorRoleResponse(item); - return RequestResult.Ok(data); - } - - public async Task PutActorRole(Guid id, ActorRoleUniversalRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - PersonActorRole? item = await _database.PersonActorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - data.UpdateActorRole(item); - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeleteActorRole(Guid id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - PersonActorRole? item = await _database.PersonActorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NoContent(); - } - - _database.PersonActorRoles.Attach(item); - _database.PersonActorRoles.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.NoContent(); - } - - public async Task GetActorRoleRating(Guid id) - { - PersonActorRole? item = await _database.PersonActorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - RatingResponse ratingResponse = RatingResponseBuilder.Initialize() - .Add(item.RatingPersonActorRole, x => x.Rating) - .Build(); - - return RequestResult.Ok(ratingResponse); - } - - public async Task GetActorRoleRatingByUser(Guid id, long userId) - { - RatingPersonActorRole? rating = await _database.RatingsPersonActorRole.FirstOrDefaultAsync(x => x.PersonActorRoleId == id && x.AccountId == userId); - if (rating is null) - { - return RequestResult.NotFound(); - } - - return RequestResult.Ok(rating.Rating); - } - - public async Task PutActorRoleRating(Guid id, RatingRequest data) - { - PersonActorRole? item = await _database.PersonActorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - long userId = _userService.GetUserId(); - - RatingPersonActorRole? rating = item.RatingPersonActorRole.FirstOrDefault(x => x.AccountId == userId); - if (rating is not null) - { - rating.Rating = data.Rating; - } - else - { - rating = new RatingPersonActorRole - { - AccountId = userId, - PersonActorRoleId = id, - Rating = data.Rating - }; - await _database.RatingsPersonActorRole.AddAsync(rating); - } - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeleteActorRoleRating(Guid id) - { - long userId = _userService.GetUserId(); - - RatingPersonActorRole? item = await _database.RatingsPersonActorRole.FirstOrDefaultAsync(x => x.PersonActorRoleId == id && x.AccountId == userId); - if (item is null) - { - return RequestResult.Ok(); - } - - _database.RatingsPersonActorRole.Attach(item); - _database.RatingsPersonActorRole.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task GetAllActorRoleTypes(RoleTypeQueryParameters query) - { - IEnumerable rawData = await _database.PersonActorRoleTypes.ToListAsync(); - IEnumerable data = rawData.Select(x => new RoleTypeResponse(x)); - data = query.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task GetActorRoleType(short id) - { - PersonActorRoleType? item = await _database.PersonActorRoleTypes.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - RoleTypeResponse data = new RoleTypeResponse(item); - return RequestResult.Ok(data); - } - - public async Task PostActorRoleType(RoleTypeRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - PersonActorRoleType item = data.CreateActorRoleType(); - await _database.PersonActorRoleTypes.AddAsync(item); - await _database.SaveChangesAsync(); - - return RequestResult.Created($"roles/actor/{item.Id}", new RoleTypeResponse(item)); - } - - public async Task DeleteActorRoleType(short id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - PersonActorRoleType? item = await _database.PersonActorRoleTypes.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NoContent(); - } - - _database.PersonActorRoleTypes.Attach(item); - _database.PersonActorRoleTypes.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.NoContent(); - } - - #endregion - - #region Creator - - public async Task GetCreatorRole(Guid id) - { - PersonCreatorRole? item = await _database.PersonCreatorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - CreatorRoleResponse data = new CreatorRoleResponse(item); - return RequestResult.Ok(data); - } - - public async Task PutCreatorRole(Guid id, CreatorRoleUniversalRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - PersonCreatorRole? item = await _database.PersonCreatorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - data.UpdateCreatorRole(item); - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeleteCreatorRole(Guid id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - PersonCreatorRole? item = await _database.PersonCreatorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NoContent(); - } - - _database.PersonCreatorRoles.Attach(item); - _database.PersonCreatorRoles.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.NoContent(); - } - - public async Task GetCreatorRoleRating(Guid id) - { - PersonCreatorRole? item = await _database.PersonCreatorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - RatingResponse ratingResponse = RatingResponseBuilder.Initialize() - .Add(item.RatingPersonCreatorRole, x => x.Rating) - .Build(); - - return RequestResult.Ok(ratingResponse); - } - - public async Task GetCreatorRoleRatingByUser(Guid id, long userId) - { - RatingPersonCreatorRole? rating = await _database.RatingsPersonCreatorRole.FirstOrDefaultAsync(x => x.PersonCreatorRoleId == id && x.AccountId == userId); - if (rating is null) - { - return RequestResult.NotFound(); - } - - return RequestResult.Ok(rating.Rating); - } - - public async Task PutCreatorRoleRating(Guid id, RatingRequest data) - { - PersonCreatorRole? item = await _database.PersonCreatorRoles.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - long userId = _userService.GetUserId(); - - RatingPersonCreatorRole? rating = item.RatingPersonCreatorRole.FirstOrDefault(x => x.AccountId == userId); - if (rating is not null) - { - rating.Rating = data.Rating; - } - else - { - rating = new RatingPersonCreatorRole - { - AccountId = userId, - PersonCreatorRoleId = id, - Rating = data.Rating - }; - await _database.RatingsPersonCreatorRole.AddAsync(rating); - } - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeleteCreatorRoleRating(Guid id) - { - long userId = _userService.GetUserId(); - - RatingPersonCreatorRole? item = await _database.RatingsPersonCreatorRole.FirstOrDefaultAsync(x => x.PersonCreatorRoleId == id && x.AccountId == userId); - if (item is null) - { - return RequestResult.Ok(); - } - - _database.RatingsPersonCreatorRole.Attach(item); - _database.RatingsPersonCreatorRole.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task GetAllCreatorRoleTypes(RoleTypeQueryParameters query) - { - IEnumerable rawData = await _database.PersonCreatorRoleTypes.ToListAsync(); - IEnumerable data = rawData.Select(x => new RoleTypeResponse(x)); - data = query.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task GetCreatorRoleType(short id) - { - PersonCreatorRoleType? item = await _database.PersonCreatorRoleTypes.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - RoleTypeResponse data = new RoleTypeResponse(item); - return RequestResult.Ok(data); - } - - public async Task PostCreatorRoleType(RoleTypeRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - PersonCreatorRoleType item = data.CreateCreatorRoleType(); - await _database.PersonCreatorRoleTypes.AddAsync(item); - await _database.SaveChangesAsync(); - - return RequestResult.Created($"roles/creator/{item.Id}", new RoleTypeResponse(item)); - } - - public async Task DeleteCreatorRoleType(short id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - PersonCreatorRoleType? item = await _database.PersonCreatorRoleTypes.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NoContent(); - } - - _database.PersonCreatorRoleTypes.Attach(item); - _database.PersonCreatorRoleTypes.Remove(item); - await _database.SaveChangesAsync(); - - return RequestResult.NoContent(); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/WatchIt.WebAPI.Services.Controllers.Roles.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/WatchIt.WebAPI.Services.Controllers.Roles.csproj deleted file mode 100644 index 9e4603e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/WatchIt.WebAPI.Services.Controllers.Roles.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/ISeriesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/ISeriesControllerService.cs deleted file mode 100644 index aac8fdd..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/ISeriesControllerService.cs +++ /dev/null @@ -1,15 +0,0 @@ -using WatchIt.Common.Model.Series; -using WatchIt.WebAPI.Services.Controllers.Common; - -namespace WatchIt.WebAPI.Services.Controllers.Series; - -public interface ISeriesControllerService -{ - Task GetAllSeries(SeriesQueryParameters query); - Task GetSeries(long id); - Task PostSeries(SeriesRequest data); - Task PutSeries(long id, SeriesRequest data); - Task DeleteSeries(long id); - - Task GetSeriesViewRank(int first, int days); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/SeriesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/SeriesControllerService.cs deleted file mode 100644 index 15cee28..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/SeriesControllerService.cs +++ /dev/null @@ -1,163 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using WatchIt.Common.Model.Series; -using WatchIt.Database; -using WatchIt.Database.Model.Media; -using WatchIt.WebAPI.Services.Controllers.Common; -using WatchIt.WebAPI.Services.Utility.User; - -namespace WatchIt.WebAPI.Services.Controllers.Series; - -public class SeriesControllerService : ISeriesControllerService -{ - #region SERVICES - - private readonly DatabaseContext _database; - - private readonly IUserService _userService; - - #endregion - - - - #region CONSTRUCTORS - - public SeriesControllerService(DatabaseContext database, IUserService userService) - { - _database = database; - - _userService = userService; - } - - #endregion - - - - #region PUBLIC METHODS - - #region Main - - public async Task GetAllSeries(SeriesQueryParameters query) - { - IEnumerable rawData = await _database.MediaSeries.ToListAsync(); - IEnumerable data = rawData.Select(x => new SeriesResponse(x)); - data = query.PrepareData(data); - return RequestResult.Ok(data); - } - - public async Task GetSeries(long id) - { - MediaSeries? item = await _database.MediaSeries.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - SeriesResponse data = new SeriesResponse(item); - return RequestResult.Ok(data); - } - - public async Task PostSeries(SeriesRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Media mediaItem = data.CreateMedia(); - await _database.Media.AddAsync(mediaItem); - await _database.SaveChangesAsync(); - MediaSeries mediaSeriesItem = data.CreateMediaSeries(mediaItem.Id); - await _database.MediaSeries.AddAsync(mediaSeriesItem); - await _database.SaveChangesAsync(); - - return RequestResult.Created($"series/{mediaItem.Id}", new SeriesResponse(mediaSeriesItem)); - } - - public async Task PutSeries(long id, SeriesRequest data) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - MediaSeries? item = await _database.MediaSeries.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - data.UpdateMediaSeries(item); - data.UpdateMedia(item.Media); - await _database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - - public async Task DeleteSeries(long id) - { - UserValidator validator = _userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - MediaSeries? item = await _database.MediaSeries.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - _database.MediaSeries.Attach(item); - _database.MediaSeries.Remove(item); - _database.MediaPosterImages.Attach(item.Media.MediaPosterImage!); - _database.MediaPosterImages.Remove(item.Media.MediaPosterImage!); - _database.MediaPhotoImages.AttachRange(item.Media.MediaPhotoImages); - _database.MediaPhotoImages.RemoveRange(item.Media.MediaPhotoImages); - _database.MediaGenres.AttachRange(item.Media.MediaGenres); - _database.MediaGenres.RemoveRange(item.Media.MediaGenres); - _database.MediaProductionCountries.AttachRange(item.Media.MediaProductionCountries); - _database.MediaProductionCountries.RemoveRange(item.Media.MediaProductionCountries); - _database.PersonActorRoles.AttachRange(item.Media.PersonActorRoles); - _database.PersonActorRoles.RemoveRange(item.Media.PersonActorRoles); - _database.PersonCreatorRoles.AttachRange(item.Media.PersonCreatorRoles); - _database.PersonCreatorRoles.RemoveRange(item.Media.PersonCreatorRoles); - _database.RatingsMedia.AttachRange(item.Media.RatingMedia); - _database.RatingsMedia.RemoveRange(item.Media.RatingMedia); - _database.ViewCountsMedia.AttachRange(item.Media.ViewCountsMedia); - _database.ViewCountsMedia.RemoveRange(item.Media.ViewCountsMedia); - _database.Media.Attach(item.Media); - _database.Media.Remove(item.Media); - await _database.SaveChangesAsync(); - - return RequestResult.NoContent(); - } - - #endregion - - #region View count - - public async Task GetSeriesViewRank(int first, int days) - { - if (first < 1 || days < 1) - { - return RequestResult.BadRequest(); - } - - DateOnly startDate = DateOnly.FromDateTime(DateTime.Now).AddDays(-days); - IEnumerable rawData = await _database.MediaSeries.OrderByDescending(x => x.Media.ViewCountsMedia.Where(y => y.Date >= startDate) - .Sum(y => y.ViewCount)) - .ThenBy(x => x.Id) - .Take(first) - .ToListAsync(); - - IEnumerable data = rawData.Select(x => new SeriesResponse(x)); - - return RequestResult.Ok(data); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/WatchIt.WebAPI.Services.Controllers.Series.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/WatchIt.WebAPI.Services.Controllers.Series.csproj deleted file mode 100644 index 9e4603e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Series/WatchIt.WebAPI.Services.Controllers.Series.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/ConfigurationService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/ConfigurationService.cs deleted file mode 100644 index e8de848..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/ConfigurationService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.Extensions.Configuration; -using WatchIt.WebAPI.Services.Utility.Configuration.Model; - -namespace WatchIt.WebAPI.Services.Utility.Configuration; - -public class ConfigurationService(IConfiguration configuration) : IConfigurationService -{ - #region PROPERTIES - - public ConfigurationData Data => configuration.Get()!; - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/IConfigurationService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/IConfigurationService.cs deleted file mode 100644 index 47dbadf..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/IConfigurationService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using WatchIt.WebAPI.Services.Utility.Configuration.Model; - -namespace WatchIt.WebAPI.Services.Utility.Configuration; - -public interface IConfigurationService -{ - ConfigurationData Data { get; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Authentication.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Authentication.cs deleted file mode 100644 index 94da852..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Authentication.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class Authentication -{ - public string Key { get; set; } - public string Issuer { get; set; } - public Tokens Tokens { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/ConfigurationData.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/ConfigurationData.cs deleted file mode 100644 index d00b4e7..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/ConfigurationData.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class ConfigurationData -{ - public Logging Logging { get; set; } - public string AllowedHosts { get; set; } - public ConnectionStrings ConnectionStrings { get; set; } - public RootUser RootUser { get; set; } - public Authentication Authentication { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/ConnectionStrings.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/ConnectionStrings.cs deleted file mode 100644 index 576839a..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/ConnectionStrings.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class ConnectionStrings -{ - public string Default { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Console.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Console.cs deleted file mode 100644 index c5975ce..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Console.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class Console -{ - public FormatterOptions FormatterOptions { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/FormatterOptions.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/FormatterOptions.cs deleted file mode 100644 index 1fdc62d..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/FormatterOptions.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class FormatterOptions -{ - public string TimestampFormat { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/LogLevel.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/LogLevel.cs deleted file mode 100644 index 267673e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/LogLevel.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class LogLevel -{ - public string Default { get; set; } - public string Microsoft_AspNetCore { get; set; } - public string Microsoft_EntityFrameworkCore_Database_Command { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Logging.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Logging.cs deleted file mode 100644 index b681b2c..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Logging.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class Logging -{ - public LogLevel LogLevel { get; set; } - public Console Console { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/RootUser.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/RootUser.cs deleted file mode 100644 index fe47fbe..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/RootUser.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class RootUser -{ - public string Username { get; set; } - public string Email { get; set; } - public string Password { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Token.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Token.cs deleted file mode 100644 index 3a57eee..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Token.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class Token -{ - public int NormalLifetime { get; set; } - public int ExtendedLifetime { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Tokens.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Tokens.cs deleted file mode 100644 index bca6170..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/Model/Tokens.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WatchIt.WebAPI.Services.Utility.Configuration.Model; - -public class Tokens -{ - public Token RefreshToken { get; set; } - public Token AccessToken { get; set; } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/WatchIt.WebAPI.Services.Utility.Configuration.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/WatchIt.WebAPI.Services.Utility.Configuration.csproj deleted file mode 100644 index d26bd3e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Configuration/WatchIt.WebAPI.Services.Utility.Configuration.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/ITokensService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/ITokensService.cs deleted file mode 100644 index 3d699bb..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/ITokensService.cs +++ /dev/null @@ -1,11 +0,0 @@ -using WatchIt.Database.Model.Account; - -namespace WatchIt.WebAPI.Services.Utility.Tokens; - -public interface ITokensService -{ - Task CreateRefreshTokenAsync(Account account, bool extendable); - Task ExtendRefreshTokenAsync(Account account, Guid id); - Task CreateAccessTokenAsync(Account account); - string CreateAccessToken(Account account); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/TokensService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/TokensService.cs deleted file mode 100644 index 14fcff6..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/TokensService.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Globalization; -using System.IdentityModel.Tokens.Jwt; -using System.Security.Claims; -using System.Text; -using Microsoft.IdentityModel.Tokens; -using WatchIt.Database; -using WatchIt.Database.Model.Account; -using WatchIt.WebAPI.Services.Utility.Configuration; -using WatchIt.WebAPI.Services.Utility.Tokens.Exceptions; - -namespace WatchIt.WebAPI.Services.Utility.Tokens; - -public class TokensService(DatabaseContext database, IConfigurationService configurationService) : ITokensService -{ - #region FIELDS - - private readonly Configuration.Model.Tokens _tokensConfig = configurationService.Data.Authentication.Tokens; - - #endregion - - - - #region PUBLIC METHODS - - public async Task CreateRefreshTokenAsync(Account account, bool extendable) - { - int expirationMinutes = extendable ? _tokensConfig.RefreshToken.ExtendedLifetime : _tokensConfig.RefreshToken.NormalLifetime; - DateTime expirationDate = DateTime.UtcNow.AddMinutes(expirationMinutes); - Guid id = Guid.NewGuid(); - - database.AccountRefreshTokens.Add(new AccountRefreshToken - { - Id = id, - AccountId = account.Id, - ExpirationDate = expirationDate, - IsExtendable = extendable, - }); - await database.SaveChangesAsync(); - - return GenerateRefreshJwt(account, id, expirationDate, extendable); - } - - public async Task ExtendRefreshTokenAsync(Account account, Guid id) - { - AccountRefreshToken? token = account.AccountRefreshTokens.FirstOrDefault(x => x.Id == id); - switch (token) - { - case null: throw new TokenNotFoundException(); - case { IsExtendable: true }: throw new TokenNotExtendableException(); - } - - DateTime expirationDate = DateTime.UtcNow.AddMinutes(_tokensConfig.RefreshToken.ExtendedLifetime); - - token.ExpirationDate = expirationDate; - await database.SaveChangesAsync(); - - return GenerateRefreshJwt(account, id, expirationDate, true); - } - - public async Task CreateAccessTokenAsync(Account account) => await Task.Run(() => CreateAccessToken(account)); - - public string CreateAccessToken(Account account) - { - DateTime lifetime = DateTime.Now.AddMinutes(_tokensConfig.AccessToken.NormalLifetime); - Guid id = Guid.NewGuid(); - - SecurityTokenDescriptor tokenDescriptor = CreateBaseSecurityTokenDescriptor(account, id, lifetime); - tokenDescriptor.Audience = "access"; - - return TokenToString(tokenDescriptor); - } - - #endregion - - - - #region PRIVATE METHODS - - protected string GenerateRefreshJwt(Account account, Guid id, DateTime expirationDate, bool extendable) - { - SecurityTokenDescriptor tokenDescriptor = CreateBaseSecurityTokenDescriptor(account, id, expirationDate); - tokenDescriptor.Audience = "refresh"; - tokenDescriptor.Subject.AddClaim(new Claim("extend", extendable.ToString())); - - return TokenToString(tokenDescriptor); - } - - protected SecurityTokenDescriptor CreateBaseSecurityTokenDescriptor(Account account, Guid id, DateTime expirationTime) - { - return new SecurityTokenDescriptor - { - Subject = new ClaimsIdentity(new List - { - new Claim(JwtRegisteredClaimNames.Jti, id.ToString()), - new Claim(JwtRegisteredClaimNames.Sub, account.Id.ToString()), - new Claim(JwtRegisteredClaimNames.Email, account.Email), - new Claim(JwtRegisteredClaimNames.UniqueName, account.Username), - new Claim(JwtRegisteredClaimNames.Exp, expirationTime.Ticks.ToString()), - new Claim("admin", account.IsAdmin.ToString()), - }), - Expires = expirationTime, - Issuer = configurationService.Data.Authentication.Issuer, - SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configurationService.Data.Authentication.Key)), SecurityAlgorithms.HmacSha512) - }; - } - - protected string TokenToString(SecurityTokenDescriptor tokenDescriptor) - { - JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); - handler.InboundClaimTypeMap.Clear(); - - SecurityToken token = handler.CreateToken(tokenDescriptor); - - return handler.WriteToken(token); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/WatchIt.WebAPI.Services.Utility.Tokens.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/WatchIt.WebAPI.Services.Utility.Tokens.csproj deleted file mode 100644 index d5346c1..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.Tokens/WatchIt.WebAPI.Services.Utility.Tokens.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/IUserService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/IUserService.cs deleted file mode 100644 index 1b32d96..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/IUserService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Security.Claims; - -namespace WatchIt.WebAPI.Services.Utility.User; - -public interface IUserService -{ - ClaimsPrincipal GetRawUser(); - string? GetRawToken(); - UserValidator GetValidator(); - Guid GetJti(); - long GetUserId(); -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/UserService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/UserService.cs deleted file mode 100644 index 58c067d..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/UserService.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Security.Claims; -using Microsoft.AspNetCore.Http; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Services.Utility.User; - -public class UserService(DatabaseContext database, IHttpContextAccessor accessor) : IUserService -{ - #region PUBLIC METHODS - - public ClaimsPrincipal GetRawUser() - { - if (accessor.HttpContext is null) - { - throw new NullReferenceException(); - } - return accessor.HttpContext.User; - } - - public string? GetRawToken() - { - if (accessor.HttpContext is null) - { - throw new NullReferenceException(); - } - return accessor.HttpContext.Request.Headers.Authorization; - } - - public UserValidator GetValidator() - { - ClaimsPrincipal rawUser = GetRawUser(); - return new UserValidator(database, rawUser); - } - - public Guid GetJti() - { - ClaimsPrincipal user = GetRawUser(); - Claim jtiClaim = user.FindFirst(JwtRegisteredClaimNames.Jti)!; - Guid guid = Guid.Parse(jtiClaim.Value); - return guid; - } - - public long GetUserId() - { - ClaimsPrincipal user = GetRawUser(); - Claim subClaim = user.FindFirst(JwtRegisteredClaimNames.Sub)!; - long id = long.Parse(subClaim.Value); - return id; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/UserValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/UserValidator.cs deleted file mode 100644 index 3dc0c41..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/UserValidator.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Security.Claims; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Services.Utility.User; - -public class UserValidator -{ - #region FIELDS - - protected readonly DatabaseContext _database; - protected readonly ClaimsPrincipal _claimsPrincipal; - protected readonly List _validationErrors; - - #endregion - - - - #region PROPERTIES - - public bool IsValid { get; protected set; } - public IEnumerable ValidationErrors => _validationErrors; - - #endregion - - - - #region CONSTRUCTORS - - internal UserValidator(DatabaseContext database, ClaimsPrincipal claimsPrincipal) - { - _database = database; - _claimsPrincipal = claimsPrincipal; - _validationErrors = new List(); - - IsValid = true; - } - - #endregion - - - - #region PUBLIC METHODS - - public UserValidator MustBeAdmin() - { - Claim adminClaim = _claimsPrincipal.FindFirst(x => x.Type == "admin")!; - if (adminClaim.Value == bool.FalseString) - { - IsValid = false; - _validationErrors.Add("User is not admin"); - } - - return this; - } - - public UserValidator MustHaveId(long id) - { - Claim adminClaim = _claimsPrincipal.FindFirst(x => x.Type == JwtRegisteredClaimNames.Sub)!; - if (adminClaim.Value == id.ToString()) - { - IsValid = false; - _validationErrors.Add("User have wrong id"); - } - - return this; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/WatchIt.WebAPI.Services.Utility.User.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/WatchIt.WebAPI.Services.Utility.User.csproj deleted file mode 100644 index 6a8d36e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Utility/WatchIt.WebAPI.Services.Utility.User/WatchIt.WebAPI.Services.Utility.User.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountEmailRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountEmailRequestValidator.cs deleted file mode 100644 index 6bc7e63..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountEmailRequestValidator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Accounts; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Accounts; - -public class AccountEmailRequestValidator : AbstractValidator -{ - public AccountEmailRequestValidator(DatabaseContext database) - { - RuleFor(x => x.NewEmail).EmailAddress() - .CannotBeIn(database.Accounts, x => x.Email) - .WithMessage("Email was already used"); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountPasswordRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountPasswordRequestValidator.cs deleted file mode 100644 index ffa2096..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountPasswordRequestValidator.cs +++ /dev/null @@ -1,17 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Accounts; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Accounts; - -public class AccountPasswordRequestValidator : AbstractValidator -{ - public AccountPasswordRequestValidator(DatabaseContext database) - { - RuleFor(x => x.NewPassword).MinimumLength(8) - .Must(x => x.Any(char.IsUpper)).WithMessage("Password must contain at least one uppercase letter.") - .Must(x => x.Any(char.IsLower)).WithMessage("Password must contain at least one lowercase letter.") - .Must(x => x.Any(char.IsDigit)).WithMessage("Password must contain at least one digit.") - .Equal(x => x.NewPasswordConfirmation); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfileBackgroundRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfileBackgroundRequestValidator.cs deleted file mode 100644 index 205be53..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfileBackgroundRequestValidator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Accounts; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Accounts; - -public class AccountProfileBackgroundRequestValidator : AbstractValidator -{ - public AccountProfileBackgroundRequestValidator(DatabaseContext database) - { - RuleFor(x => x.Id).MustBeIn(database.MediaPhotoImages.Where(x => x.MediaPhotoImageBackground != null), x => x.Id) - .WithMessage("Image has to be background"); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfilePictureRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfilePictureRequestValidator.cs deleted file mode 100644 index 873766c..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountProfilePictureRequestValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Accounts; - -namespace WatchIt.WebAPI.Validators.Accounts; - -public class AccountProfilePictureRequestValidator : AbstractValidator -{ - public AccountProfilePictureRequestValidator() - { - RuleFor(x => x.Image).NotEmpty(); - RuleFor(x => x.MimeType).Matches(@"\w+/.+").WithMessage("Incorrect mimetype"); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountUsernameRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountUsernameRequestValidator.cs deleted file mode 100644 index 6c0ad30..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AccountUsernameRequestValidator.cs +++ /dev/null @@ -1,16 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Accounts; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Accounts; - -public class AccountUsernameRequestValidator : AbstractValidator -{ - public AccountUsernameRequestValidator(DatabaseContext database) - { - RuleFor(x => x.NewUsername).MinimumLength(5) - .MaximumLength(50) - .CannotBeIn(database.Accounts, x => x.Username) - .WithMessage("Username is already used"); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AuthenticateRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AuthenticateRequestValidator.cs deleted file mode 100644 index f14c417..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/AuthenticateRequestValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Accounts; - -namespace WatchIt.WebAPI.Validators.Accounts; - -public class AuthenticateRequestValidator : AbstractValidator -{ - public AuthenticateRequestValidator() - { - RuleFor(x => x.UsernameOrEmail).NotEmpty(); - RuleFor(x => x.Password).NotEmpty(); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/RegisterRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/RegisterRequestValidator.cs deleted file mode 100644 index a0ed98b..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Accounts/RegisterRequestValidator.cs +++ /dev/null @@ -1,21 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Accounts; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Accounts; - -public class RegisterRequestValidator : AbstractValidator -{ - public RegisterRequestValidator(DatabaseContext database) - { - RuleFor(x => x.Username).MinimumLength(5) - .MaximumLength(50) - .CannotBeIn(database.Accounts, x => x.Username).WithMessage("Username was already used"); - RuleFor(x => x.Email).EmailAddress() - .CannotBeIn(database.Accounts, x => x.Email).WithMessage("Email was already used"); - RuleFor(x => x.Password).MinimumLength(8) - .Must(x => x.Any(char.IsUpper)).WithMessage("Password must contain at least one uppercase letter.") - .Must(x => x.Any(char.IsLower)).WithMessage("Password must contain at least one lowercase letter.") - .Must(x => x.Any(char.IsDigit)).WithMessage("Password must contain at least one digit."); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Genres/GenreRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Genres/GenreRequestValidator.cs deleted file mode 100644 index cf5a9b9..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Genres/GenreRequestValidator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Genres; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Genres; - -public class GenreRequestValidator : AbstractValidator -{ - public GenreRequestValidator() - { - RuleFor(x => x.Name).MaximumLength(100); - When(x => !string.IsNullOrWhiteSpace(x.Description), () => RuleFor(x => x.Description).MaximumLength(1000)); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Media/MediaPhotoRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Media/MediaPhotoRequestValidator.cs deleted file mode 100644 index 4561c75..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Media/MediaPhotoRequestValidator.cs +++ /dev/null @@ -1,20 +0,0 @@ -using FluentValidation; -using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; -using WatchIt.Common.Model.Media; -using WatchIt.Database; -using WatchIt.WebAPI.Validators.Photos; - -namespace WatchIt.WebAPI.Validators.Media; - -public class MediaPhotoRequestValidator : AbstractValidator -{ - public MediaPhotoRequestValidator() - { - RuleFor(x => x.Image).NotEmpty(); - RuleFor(x => x.MimeType).Matches(@"\w+/.+").WithMessage("Incorrect mimetype"); - When(x => x.Background is not null, () => - { - RuleFor(x => x.Background!).SetValidator(new PhotoBackgroundDataValidator()); - }); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Media/MediaPosterRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Media/MediaPosterRequestValidator.cs deleted file mode 100644 index 1ba3d2f..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Media/MediaPosterRequestValidator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Media; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Media; - -public class MediaPosterRequestValidator : AbstractValidator -{ - public MediaPosterRequestValidator() - { - RuleFor(x => x.Image).NotEmpty(); - RuleFor(x => x.MimeType).Matches(@"\w+/.+").WithMessage("Incorrect mimetype"); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Movies/MovieRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Movies/MovieRequestValidator.cs deleted file mode 100644 index 838a450..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Movies/MovieRequestValidator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Movies; - -namespace WatchIt.WebAPI.Validators.Movies; - -public class MovieRequestValidator : AbstractValidator -{ - public MovieRequestValidator() - { - RuleFor(x => x.Title).NotEmpty().MaximumLength(250); - RuleFor(x => x.OriginalTitle).MaximumLength(250); - RuleFor(x => x.Description).MaximumLength(1000); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Photos/PhotoBackgroundDataRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Photos/PhotoBackgroundDataRequestValidator.cs deleted file mode 100644 index bbf414e..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Photos/PhotoBackgroundDataRequestValidator.cs +++ /dev/null @@ -1,12 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Photos; - -namespace WatchIt.WebAPI.Validators.Photos; - -public class PhotoBackgroundDataRequestValidator : AbstractValidator -{ - public PhotoBackgroundDataRequestValidator() - { - RuleFor(x => x).SetValidator(new PhotoBackgroundDataValidator()); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Photos/PhotoBackgroundDataValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Photos/PhotoBackgroundDataValidator.cs deleted file mode 100644 index 58f0d8a..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Photos/PhotoBackgroundDataValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Photos; - -namespace WatchIt.WebAPI.Validators.Photos; - -public class PhotoBackgroundDataValidator : AbstractValidator -{ - public PhotoBackgroundDataValidator() - { - RuleFor(x => x.FirstGradientColor).Must(x => x.Length == 3).WithMessage("First gradient color has to be 3 byte long"); - RuleFor(x => x.SecondGradientColor).Must(x => x.Length == 3).WithMessage("Second gradient color has to be 3 byte long"); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Rating/RatingRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Rating/RatingRequestValidator.cs deleted file mode 100644 index 0d300c4..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Rating/RatingRequestValidator.cs +++ /dev/null @@ -1,12 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Rating; - -namespace WatchIt.WebAPI.Validators.Rating; - -public class RatingRequestValidator : AbstractValidator -{ - public RatingRequestValidator() - { - RuleFor(x => x.Rating).InclusiveBetween((short)1, (short)10); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRoleMediaRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRoleMediaRequestValidator.cs deleted file mode 100644 index 12c2b5c..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRoleMediaRequestValidator.cs +++ /dev/null @@ -1,16 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Roles; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Roles; - -public class ActorRoleMediaRequestValidator : AbstractValidator -{ - public ActorRoleMediaRequestValidator(DatabaseContext database) - { - Include(new BaseActorRoleRequestValidator(database)); - RuleFor(x => x.PersonId).NotEmpty() - .NotNull() - .MustBeIn(database.Persons.Select(x => x.Id).ToList()); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRolePersonRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRolePersonRequestValidator.cs deleted file mode 100644 index c89142c..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRolePersonRequestValidator.cs +++ /dev/null @@ -1,16 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Roles; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Roles; - -public class ActorRolePersonRequestValidator : AbstractValidator -{ - public ActorRolePersonRequestValidator(DatabaseContext database) - { - Include(new BaseActorRoleRequestValidator(database)); - RuleFor(x => x.MediaId).NotEmpty() - .NotNull() - .MustBeIn(database.Media.Select(x => x.Id).ToList()); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRoleUniversalRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRoleUniversalRequestValidator.cs deleted file mode 100644 index d23f72d..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/ActorRoleUniversalRequestValidator.cs +++ /dev/null @@ -1,19 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Roles; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Roles; - -public class ActorRoleUniversalRequestValidator : AbstractValidator -{ - public ActorRoleUniversalRequestValidator(DatabaseContext database) - { - Include(new BaseActorRoleRequestValidator(database)); - RuleFor(x => x.PersonId).NotEmpty() - .NotNull() - .MustBeIn(database.Persons.Select(x => x.Id).ToList()); - RuleFor(x => x.MediaId).NotEmpty() - .NotNull() - .MustBeIn(database.Media.Select(x => x.Id).ToList()); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/BaseActorRoleRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/BaseActorRoleRequestValidator.cs deleted file mode 100644 index 5ead1e0..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Roles/BaseActorRoleRequestValidator.cs +++ /dev/null @@ -1,17 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Roles; -using WatchIt.Database; - -namespace WatchIt.WebAPI.Validators.Roles; - -public class BaseActorRoleRequestValidator : AbstractValidator -{ - public BaseActorRoleRequestValidator(DatabaseContext database) - { - RuleFor(x => x.Name).NotEmpty() - .MaximumLength(100); - RuleFor(x => x.TypeId).NotEmpty() - .NotNull() - .MustBeIn(database.PersonActorRoleTypes.Select(x => x.Id).ToList()); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Series/SeriesRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Series/SeriesRequestValidator.cs deleted file mode 100644 index ba38f66..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Series/SeriesRequestValidator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; -using WatchIt.Common.Model.Series; - -namespace WatchIt.WebAPI.Validators.Movies; - -public class SeriesRequestValidator : AbstractValidator -{ - public SeriesRequestValidator() - { - RuleFor(x => x.Title).NotEmpty().MaximumLength(250); - RuleFor(x => x.OriginalTitle).MaximumLength(250); - RuleFor(x => x.Description).MaximumLength(1000); - } -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/WatchIt.WebAPI.Validators.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/WatchIt.WebAPI.Validators.csproj deleted file mode 100644 index 84b3d21..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/WatchIt.WebAPI.Validators.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.WorkerServices/DeleteExpiredRefreshTokensService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.WorkerServices/DeleteExpiredRefreshTokensService.cs deleted file mode 100644 index 00c8d99..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.WorkerServices/DeleteExpiredRefreshTokensService.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using WatchIt.Database; -using WatchIt.Database.Model.Account; - -namespace WatchIt.WebAPI.WorkerServices; - -public class DeleteExpiredRefreshTokensService : BackgroundService -{ - #region SERVICES - - private readonly ILogger _logger; - private readonly IServiceScopeFactory _serviceScopeFactory; - - #endregion - - - - #region CONSTRUCTORS - - public DeleteExpiredRefreshTokensService(ILogger logger, IServiceScopeFactory serviceScopeFactory) - { - _logger = logger; - _serviceScopeFactory = serviceScopeFactory; - } - - #endregion - - - - #region PUBLIC METHODS - - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - while (!stoppingToken.IsCancellationRequested) - { - _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); - - Task delayTask = Task.Delay(300000, stoppingToken); - Task actionTask = Action(); - - await Task.WhenAll(delayTask, actionTask); - } - } - - protected async Task Action() - { - using (IServiceScope scope = _serviceScopeFactory.CreateScope()) - { - DatabaseContext database = scope.ServiceProvider.GetService(); - - IEnumerable tokens = database.AccountRefreshTokens.Where(x => x.ExpirationDate < DateTime.UtcNow); - database.AccountRefreshTokens.AttachRange(tokens); - database.AccountRefreshTokens.RemoveRange(tokens); - await database.SaveChangesAsync(); - } - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.WorkerServices/WatchIt.WebAPI.WorkerServices.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.WorkerServices/WatchIt.WebAPI.WorkerServices.csproj deleted file mode 100644 index 5f17238..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI.WorkerServices/WatchIt.WebAPI.WorkerServices.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.csproj b/WatchIt.WebAPI/WatchIt.WebAPI.csproj new file mode 100644 index 0000000..f7e5dfe --- /dev/null +++ b/WatchIt.WebAPI/WatchIt.WebAPI.csproj @@ -0,0 +1,48 @@ + + + + net9.0 + enable + enable + Linux + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + .dockerignore + + + + + <_ContentIncludedByDefault Remove="WatchIt.WebAPI.Controllers\obj\project.assets.json" /> + <_ContentIncludedByDefault Remove="WatchIt.WebAPI.Controllers\obj\project.packagespec.json" /> + <_ContentIncludedByDefault Remove="WatchIt.WebAPI.Controllers\obj\WatchIt.WebAPI.Controllers.csproj.nuget.dgspec.json" /> + <_ContentIncludedByDefault Remove="WatchIt.WebAPI.Validators\obj\project.assets.json" /> + <_ContentIncludedByDefault Remove="WatchIt.WebAPI.Validators\obj\project.packagespec.json" /> + <_ContentIncludedByDefault Remove="WatchIt.WebAPI.Validators\obj\WatchIt.WebAPI.Validators.csproj.nuget.dgspec.json" /> + + + diff --git a/WatchIt.WebAPI/WatchIt.WebAPI/Program.cs b/WatchIt.WebAPI/WatchIt.WebAPI/Program.cs deleted file mode 100644 index 581c7c6..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI/Program.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Reflection; -using System.Text; -using FluentValidation; -using FluentValidation.AspNetCore; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.EntityFrameworkCore; -using Microsoft.IdentityModel.JsonWebTokens; -using Microsoft.IdentityModel.Tokens; -using WatchIt.Database; -using WatchIt.WebAPI.Services.Controllers.Accounts; -using WatchIt.WebAPI.Services.Controllers.Genders; -using WatchIt.WebAPI.Services.Controllers.Genres; -using WatchIt.WebAPI.Services.Controllers.Media; -using WatchIt.WebAPI.Services.Controllers.Movies; -using WatchIt.WebAPI.Services.Controllers.Persons; -using WatchIt.WebAPI.Services.Controllers.Photos; -using WatchIt.WebAPI.Services.Controllers.Roles; -using WatchIt.WebAPI.Services.Controllers.Series; -using WatchIt.WebAPI.Services.Utility.Configuration; -using WatchIt.WebAPI.Services.Utility.Tokens; -using WatchIt.WebAPI.Services.Utility.User; -using WatchIt.WebAPI.Validators; -using WatchIt.WebAPI.WorkerServices; - -namespace WatchIt.WebAPI; - -public static class Program -{ - #region PUBLIC METHODS - - public static void Main(string[] args) - { - WebApplication app = WebApplication.CreateBuilder(args) - .SetupAuthentication() - .SetupDatabase() - .SetupWorkerServices() - .SetupServices() - .SetupApplication() - .Build(); - - using (IServiceScope scope = app.Services.CreateScope()) - { - DatabaseContext dbContext = scope.ServiceProvider.GetRequiredService(); - - while (!dbContext.Database.CanConnect()) - { - app.Logger.LogInformation("Waiting for database..."); - Thread.Sleep(1000); - } - - dbContext.Database.Migrate(); - } - - if (app.Environment.IsDevelopment()) - { - app.UseSwagger(); - app.UseSwaggerUI(); - } - - app.UseHttpsRedirection(); - - app.UseAuthentication(); - app.UseAuthorization(); - - app.MapControllers(); - - app.Run(); - } - - #endregion - - - - #region PRIVATE METHODS - - private static WebApplicationBuilder SetupAuthentication(this WebApplicationBuilder builder) - { - JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear(); - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - - AuthenticationBuilder authenticationBuilder = builder.Services.AddAuthentication(x => - { - x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }); - authenticationBuilder.AddJwtBearer(x => - { - x.RequireHttpsMetadata = false; - x.SaveToken = true; - x.TokenValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetValue("Authentication:Key")!)), - ValidateAudience = true, - ValidAudience = "access", - ValidIssuer = builder.Configuration.GetValue("Authentication:Issuer"), - ValidateLifetime = true, - ClockSkew = TimeSpan.FromMinutes(1), - }; - x.Events = new JwtBearerEvents - { - OnAuthenticationFailed = context => - { - if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) - { - context.Response.Headers.Append("Token-Expired", "true"); - } - - return Task.CompletedTask; - }, - }; - }); - authenticationBuilder.AddJwtBearer("refresh", x => - { - x.RequireHttpsMetadata = false; - x.SaveToken = true; - x.TokenValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetValue("Authentication:Key")!)), - ValidateAudience = true, - ValidIssuer = builder.Configuration.GetValue("Authentication:Issuer"), - ValidAudience = "refresh", - ValidateLifetime = true, - ClockSkew = TimeSpan.FromMinutes(1) - }; - x.Events = new JwtBearerEvents - { - OnAuthenticationFailed = context => - { - if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) - { - context.Response.Headers.Append("Token-Expired", "true"); - } - return Task.CompletedTask; - } - }; - }); - builder.Services.AddAuthorization(); - - return builder; - } - - private static WebApplicationBuilder SetupDatabase(this WebApplicationBuilder builder) - { - builder.Services.AddDbContext(x => x.UseLazyLoadingProxies().UseNpgsql(builder.Configuration.GetConnectionString("Default")), ServiceLifetime.Transient); - return builder; - } - - private static WebApplicationBuilder SetupWorkerServices(this WebApplicationBuilder builder) - { - builder.Services.AddHostedService(); - return builder; - } - - private static WebApplicationBuilder SetupServices(this WebApplicationBuilder builder) - { - // Utility - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - - // Controller - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - - return builder; - } - - private static WebApplicationBuilder SetupApplication(this WebApplicationBuilder builder) - { - builder.Services.AddValidatorsFromAssembly(Assembly.GetAssembly(typeof(CustomValidators))); - builder.Services.AddFluentValidationAutoValidation(); - builder.Services.AddHttpContextAccessor(); - builder.Services.AddControllers(); - builder.Services.AddEndpointsApiExplorer(); - builder.Services.AddSwaggerGen(); - - return builder; - } - - #endregion -} diff --git a/WatchIt.WebAPI/WatchIt.WebAPI/Properties/launchSettings.json b/WatchIt.WebAPI/WatchIt.WebAPI/Properties/launchSettings.json deleted file mode 100644 index 22794a2..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI/Properties/launchSettings.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:10207", - "sslPort": 44335 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "http://localhost:5179", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7160;http://localhost:5179", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/WatchIt.WebAPI/WatchIt.WebAPI/WatchIt.WebAPI.csproj b/WatchIt.WebAPI/WatchIt.WebAPI/WatchIt.WebAPI.csproj deleted file mode 100644 index 56996dc..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI/WatchIt.WebAPI.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - net8.0 - enable - enable - Linux - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - .dockerignore - - - - - - - - - - - - - - - diff --git a/WatchIt.WebAPI/WatchIt.WebAPI/appsettings.json b/WatchIt.WebAPI/WatchIt.WebAPI/appsettings.json deleted file mode 100644 index d416db6..0000000 --- a/WatchIt.WebAPI/WatchIt.WebAPI/appsettings.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning", - "Microsoft.EntityFrameworkCore.Database.Command": "Warning" - }, - "Console": { - "FormatterOptions": { - "TimestampFormat": "[yyyy-MM-dd HH:mm:ss] " - } - } - }, - "AllowedHosts": "*", - "ConnectionStrings": { - "Default": "Host=localhost;Database=watchit;Username=watchit;Password=Xdv2Etchavbuuho" - }, - "RootUser": { - "Username": "root", - "Email": "root@watch.it", - "Password": "bECdHfbus2QHr4QQjApM" - }, - "Authentication": { - "Key": "testkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytest", - "Issuer": "WatchIt", - "Tokens": { - "RefreshToken": { - "NormalLifetime": 1440, - "ExtendedLifetime": 10080 - }, - "AccessToken": { - "NormalLifetime": 5 - } - } - } -} diff --git a/WatchIt.WebAPI/appsettings.json b/WatchIt.WebAPI/appsettings.json new file mode 100644 index 0000000..4fc8fc7 --- /dev/null +++ b/WatchIt.WebAPI/appsettings.json @@ -0,0 +1,31 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "Database": "Host=192.168.55.70;Database=watchit_dev;Username=watchit;Password=Xdv2Etchavbuuho;Include Error Detail=True" + }, + "Authentication": { + "JWT": { + "Key": "testkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytestkeytest", + "Issuer": "id.watch.it", + "Audience": "watch.it", + "Algorithm": "HS512", + "Lifetime": { + "RefreshToken": { + "Normal": 1440, + "Extended": 10080 + }, + "AccessToken": { + "Normal": 5, + "Extended": null + } + } + } + } +} diff --git a/WatchIt.Website/Clients/IAccountsClient.cs b/WatchIt.Website/Clients/IAccountsClient.cs new file mode 100644 index 0000000..9da379d --- /dev/null +++ b/WatchIt.Website/Clients/IAccountsClient.cs @@ -0,0 +1,118 @@ +using Refit; +using WatchIt.Database.Model.Media; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture; +using WatchIt.DTO.Models.Controllers.Accounts.AccountEmail; +using WatchIt.DTO.Models.Controllers.Accounts.AccountLogout; +using WatchIt.DTO.Models.Controllers.Accounts.AccountPassword; +using WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo; +using WatchIt.DTO.Models.Controllers.Accounts.AccountUsername; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Clients; + +public interface IAccountsClient +{ + #region Main + + [Get("/")] + Task>> GetAccounts([Query] AccountFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_profile_pictures")] bool includeProfilePictures = false); + + [Get("/{id}")] + Task> GetAccount(long id, [Query][AliasAs("include_profile_pictures")] bool includeProfilePictures = false); + + [Post("/")] + Task> PostAccount([Body] AccountRequest body); + + #endregion + + #region Profile picture + + [Get("/{id}/profile_picture")] + Task> GetAccountProfilePicture(long id); + + [Put("/profile_picture")] + Task> PutAccountProfilePicture([Authorize]string token, [Body] ImageRequest body); + + [Delete("/profile_picture")] + Task DeleteAccountProfilePicture([Authorize]string token); + + #endregion + + #region Background picture + + [Get("/{id}/background_picture")] + Task> GetAccountBackgroundPicture(long id); + + [Put("/background_picture")] + Task> PutAccountBackgroundPicture([Authorize]string token, [Body] AccountBackgroundPictureRequest body); + + [Delete("/background_picture")] + Task DeleteAccountBackgroundPicture([Authorize]string token); + + #endregion + + #region Profile edit + + [Patch("/profile_info")] + Task PatchAccountProfileInfo([Authorize]string token, [Body] AccountProfileInfoRequest body); + + [Patch("/username")] + Task PatchAccountUsername([Authorize]string token, [Body] AccountUsernameRequest body); + + [Patch("/email")] + Task PatchAccountEmail([Authorize]string token, [Body] AccountEmailRequest body); + + [Patch("/password")] + Task PatchAccountPassword([Authorize]string token, [Body] AccountPasswordRequest body); + + #endregion + + #region Log out + + [Delete("/logout")] + Task Logout([Body] AccountLogoutRequest body); + + [Delete("/logout_all")] + Task LogoutAll([Authorize]string token); + + #endregion + + #region Follows + + [Get("/{id}/follows")] + Task>> GetAccountFollows(long id, [Query] AccountFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Get("/{id}/followers")] + Task>> GetAccountFollowers(long id, [Query] AccountFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Post("/follows/{followed_account_id}")] + Task PostAccountFollow([Authorize]string token, [AliasAs("followed_account_id")] long followedAccountId); + + [Delete("/follows/{followed_account_id}")] + Task DeleteAccountFollow([Authorize]string token, [AliasAs("followed_account_id")] long followedAccountId); + + #endregion + + #region Ratings + + [Get("/{id}/media")] + Task>> GetAccountRatedMedia(long id, [Query] MediumFilterQuery? filterQuery = null, [Query] MediumUserRatedFilterQuery? userRatedFilterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/{id}/media/movies")] + Task>> GetAccountRatedMediaMovies(long id, [Query] MediumMovieFilterQuery? filterQuery = null, [Query] MediumUserRatedFilterQuery? userRatedFilterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/{id}/media/series")] + Task>> GetAccountRatedMediaSeries(long id, [Query] MediumSeriesFilterQuery? filterQuery = null, [Query] MediumUserRatedFilterQuery? userRatedFilterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/{id}/people")] + Task>> GetAccountRatedPeople(long id, [Query] PersonFilterQuery? filterQuery = null, [Query] PersonUserRatedFilterQuery? userRatedFilterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_pictures")] bool includePictures = false); + + #endregion +} diff --git a/WatchIt.Website/Clients/IAuthenticationClient.cs b/WatchIt.Website/Clients/IAuthenticationClient.cs new file mode 100644 index 0000000..01c85d8 --- /dev/null +++ b/WatchIt.Website/Clients/IAuthenticationClient.cs @@ -0,0 +1,13 @@ +using Refit; +using WatchIt.DTO.Models.Controllers.Authentication; + +namespace WatchIt.Website.Clients; + +public interface IAuthenticationClient +{ + [Post("/authenticate")] + Task> Authenticate([Body] AuthenticationRequest body); + + [Post("/authenticate_refresh")] + Task> AuthenticateRefresh([Body] AuthenticationRefreshRequest body); +} \ No newline at end of file diff --git a/WatchIt.Website/Clients/IGendersClient.cs b/WatchIt.Website/Clients/IGendersClient.cs new file mode 100644 index 0000000..0b8e07b --- /dev/null +++ b/WatchIt.Website/Clients/IGendersClient.cs @@ -0,0 +1,20 @@ +using Refit; +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Clients; + +public interface IGendersClient +{ + [Get("/")] + Task>> GetGenders([Query] GenderFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Get("/{id}")] + Task> GetGender(short id); + + [Post("/")] + Task> PostGender([Authorize]string token, [Body] GenderRequest body); + + [Delete("/{id}")] + Task DeleteGender([Authorize]string token, short id); +} \ No newline at end of file diff --git a/WatchIt.Website/Clients/IGenresClient.cs b/WatchIt.Website/Clients/IGenresClient.cs new file mode 100644 index 0000000..551099c --- /dev/null +++ b/WatchIt.Website/Clients/IGenresClient.cs @@ -0,0 +1,20 @@ +using Refit; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Clients; + +public interface IGenresClient +{ + [Get("/")] + Task>> GetGenres([Query] GenreFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Get("/{id}")] + Task> GetGenre(short id); + + [Post("/")] + Task> PostGenre([Authorize]string token, [Body] GenreRequest body); + + [Delete("/{id}")] + Task DeleteGenre([Authorize]string token, short id); +} \ No newline at end of file diff --git a/WatchIt.Website/Clients/IMediaClient.cs b/WatchIt.Website/Clients/IMediaClient.cs new file mode 100644 index 0000000..242f82a --- /dev/null +++ b/WatchIt.Website/Clients/IMediaClient.cs @@ -0,0 +1,107 @@ +using Refit; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.DTO.Models.Controllers.Media.Medium.Query; +using WatchIt.DTO.Models.Controllers.Media.Medium.Request; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Clients; + +public interface IMediaClient +{ + #region Main + + [Get("/")] + Task>> GetMedia([Query(CollectionFormat.Multi)] MediumFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/{id}")] + Task> GetMedium(long id, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/movies")] + Task>> GetMediumMovies([Query(CollectionFormat.Multi)] MediumMovieFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/movies/{id}")] + Task> GetMediumMovie(long id, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/series")] + Task>> GetMediumSeries([Query(CollectionFormat.Multi)] MediumSeriesFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/series/{id}")] + Task> GetMediumSeries(long id, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Post("/movies")] + Task> PostMediumMovie([Authorize]string token, [Body] MediumMovieRequest body); + + [Post("/series")] + Task> PostMediumSeries([Authorize]string token, [Body] MediumSeriesRequest body); + + [Put("/movies/{id}")] + Task> PutMediumMovie([Authorize]string token, long id, [Body] MediumMovieRequest body); + + [Put("/series/{id}")] + Task> PutMediumSeries([Authorize]string token, long id, [Body] MediumSeriesRequest body); + + [Delete("/{id}")] + Task DeleteMedium([Authorize]string token, long id); + + #endregion + + #region Genres + + [Get("/{id}/genres")] + Task>> GetMediumGenres(long id, [Query] GenreFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Post("/{id}/genres/{genre_id}")] + Task PostMediumGenre([Authorize]string token, long id, [AliasAs("genre_id")] short genreId); + + [Delete("/{id}/genres/{genre_id}")] + Task DeleteMediumGenre([Authorize]string token, long id, [AliasAs("genre_id")] short genreId); + + #endregion + + #region Rating + + [Get("/{id}/rating")] + Task> GetMediumRating(long id); + + [Get("/{id}/rating/{account_id}")] + Task> GetMediumUserRating(long id, [AliasAs("account_id")] long accountId); + + [Put("/{id}/rating")] + Task PutMediumRating([Authorize]string token, long id, [Body] RatingRequest body); + + [Delete("/{id}/rating")] + Task DeleteMediumRating([Authorize]string token, long id); + + #endregion + + #region View Count + + [Put("/{id}/view_count")] + Task PutMediumViewCount(long id); + + #endregion + + #region Picture + + [Get("/{id}/picture")] + Task> GetMediumPicture(long id); + + [Put("/{id}/picture")] + Task> PutMediumPicture([Authorize]string token, long id, [Body] ImageRequest body); + + [Delete("/{id}/picture")] + Task DeleteMediumPicture([Authorize]string token, long id); + + #endregion + + #region Photos + + [Get("/{id}/photos/background")] + Task> GetMediumBackgroundPhoto(long id); + + #endregion +} diff --git a/WatchIt.Website/Clients/IPeopleClient.cs b/WatchIt.Website/Clients/IPeopleClient.cs new file mode 100644 index 0000000..71ae6d6 --- /dev/null +++ b/WatchIt.Website/Clients/IPeopleClient.cs @@ -0,0 +1,60 @@ +using Refit; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Clients; + +public interface IPeopleClient +{ + #region Main + + [Get("/")] + Task>> GetPeople([Query] PersonFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Get("/{id}")] + Task> GetPerson(long id, [Query][AliasAs("include_pictures")] bool includePictures = false); + + [Post("/")] + Task> PostPerson([Authorize]string token, [Body] PersonRequest body); + + [Put("/{id}")] + Task> PutPerson([Authorize]string token, long id, [Body] PersonRequest body); + + [Delete("/{id}")] + Task DeletePerson([Authorize]string token, long id); + + #endregion + + #region Rating + + [Get("/{id}/rating")] + Task> GetPersonRating(long id); + + [Get("/{id}/rating/{account_id}")] + Task> GetPersonUserRating(long id, [AliasAs("account_id")] long accountId); + + #endregion + + #region View Count + + [Put("/{id}/view_count")] + Task PutPeopleViewCount(long id); + + #endregion + + #region Picture + + [Get("/{id}/picture")] + Task> GetPersonPicture(long id); + + [Put("/{id}/picture")] + Task> PutPersonPicture([Authorize]string token, long id, [Body] ImageRequest body); + + [Delete("/{id}/picture")] + Task DeletePersonPicture([Authorize]string token, long id); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Clients/IPhotosClient.cs b/WatchIt.Website/Clients/IPhotosClient.cs new file mode 100644 index 0000000..2be5457 --- /dev/null +++ b/WatchIt.Website/Clients/IPhotosClient.cs @@ -0,0 +1,41 @@ +using Refit; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Clients; + +public interface IPhotosClient +{ + #region Main + + [Get("/{id}")] + Task> GetPhoto(Guid id); + + [Get("/")] + Task>> GetPhotos([Query] PhotoFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Post("/")] + Task> PostPhoto([Authorize]string token, [Body] PhotoRequest body); + + [Put("/{id}")] + Task PutPhoto([Authorize]string token, Guid id, [Body] PhotoRequest body); + + [Delete("/{id}")] + Task DeletePhoto([Authorize]string token, Guid id); + + #endregion + + #region Background + + [Get("/background")] + Task> GetPhotoBackground(); + + [Put("/{photo_id}/background")] + Task> PutPhotoBackground([Authorize]string token, [AliasAs("photo_id")] Guid photoId, [Body] PhotoBackgroundRequest body); + + [Delete("/{photo_id}/background")] + Task DeletePhotoBackground([Authorize]string token, [AliasAs("photo_id")] Guid photoId); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Clients/IRolesClient.cs b/WatchIt.Website/Clients/IRolesClient.cs new file mode 100644 index 0000000..d983985 --- /dev/null +++ b/WatchIt.Website/Clients/IRolesClient.cs @@ -0,0 +1,92 @@ +using Refit; +using WatchIt.DTO.Models.Controllers.Roles.Role.Query; +using WatchIt.DTO.Models.Controllers.Roles.Role.Request; +using WatchIt.DTO.Models.Controllers.Roles.Role.Response; +using WatchIt.DTO.Models.Controllers.Roles.RoleActorType; +using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Clients; + +public interface IRolesClient +{ + #region Main - CRUD + + [Get("/actors")] + Task>> GetRoleActors([Query] RoleActorFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Get("/actors/{id}")] + Task> GetRoleActor(Guid id); + + [Get("/creators")] + Task>> GetRoleCreators([Query] RoleCreatorFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Get("/creators/{id}")] + Task> GetRoleCreator(Guid id); + + [Post("/actors")] + Task> PostRoleActor([Authorize]string token, [Body] RoleActorRequest body); + + [Post("/creators")] + Task> PostRoleCreator([Authorize]string token, [Body] RoleCreatorRequest body); + + [Put("/actors/{id}")] + Task> PutRoleActor([Authorize]string token, Guid id, [Body] RoleActorRequest body); + + [Put("/creators/{id}")] + Task> PutRoleCreator([Authorize]string token, Guid id, [Body] RoleCreatorRequest body); + + [Delete("/{id}")] + Task DeleteRole([Authorize]string token, Guid id); + + #endregion + + #region Main - Rating + + [Get("/{id}/rating")] + Task> GetRoleRating(Guid id); + + [Get("/{id}/rating/{account_id}")] + Task> GetRoleUserRating(Guid id, [AliasAs("account_id")] long accountId); + + [Put("/{id}/rating")] + Task PutRoleRating([Authorize]string token, Guid id, [Body] RatingRequest body); + + [Delete("/{id}/rating")] + Task DeleteRoleRating([Authorize]string token, Guid id); + + #endregion + + #region ActorTypes + + [Get("/actors/types")] + Task>> GetRoleActorTypes([Query] RoleActorTypeFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Get("/actors/types/{role_actor_type_id}")] + Task> GetRoleActorType([AliasAs("role_actor_type_id")] short roleActorTypeId); + + [Post("/actors/types")] + Task> PostRoleActorType([Authorize]string token, [Body] RoleActorTypeRequest body); + + [Delete("/actors/types/{role_actor_type_id}")] + Task DeleteRoleActorType([Authorize]string token, [AliasAs("role_actor_type_id")] short roleActorTypeId); + + #endregion + + #region CreatorTypes + + [Get("/creators/types")] + Task>> GetRoleCreatorTypes([Query] RoleCreatorTypeFilterQuery? filterQuery = null, [Query] OrderQuery? orderQuery = null, [Query] PagingQuery? pagingQuery = null); + + [Get("/creators/types/{role_creator_type_id}")] + Task> GetRoleCreatorType([AliasAs("role_creator_type_id")] short roleCreatorTypeId); + + [Post("/creators/types")] + Task> PostRoleCreatorType([Authorize]string token, [Body] RoleCreatorTypeRequest body); + + [Delete("/creators/types/{role_creator_type_id}")] + Task DeleteRoleCreatorType([Authorize]string token, [AliasAs("role_creator_type_id")] short roleCreatorTypeId); + + #endregion +} diff --git a/WatchIt.Website/WatchIt.Website/App.razor b/WatchIt.Website/Components/App.razor similarity index 71% rename from WatchIt.Website/WatchIt.Website/App.razor rename to WatchIt.Website/Components/App.razor index f460abd..ea7c48c 100644 --- a/WatchIt.Website/WatchIt.Website/App.razor +++ b/WatchIt.Website/Components/App.razor @@ -9,13 +9,16 @@ - - - - - + + + + + + + + - + @@ -24,12 +27,14 @@ - + + - + + diff --git a/WatchIt.Website/Components/Component.cs b/WatchIt.Website/Components/Component.cs new file mode 100644 index 0000000..f66ed1c --- /dev/null +++ b/WatchIt.Website/Components/Component.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Website.Components.Layout; + +namespace WatchIt.Website.Components; + +public abstract class Component : ComponentBase +{ + #region PARAMETERS + + [CascadingParameter] public required BaseLayout Base { get; set; } + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + if (firstRender) + { + await OnFirstRenderAsync(); + } + } + + protected virtual async Task OnFirstRenderAsync() + { + await Task.CompletedTask; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Layout/BaseLayout.razor b/WatchIt.Website/Components/Layout/BaseLayout.razor new file mode 100644 index 0000000..313a308 --- /dev/null +++ b/WatchIt.Website/Components/Layout/BaseLayout.razor @@ -0,0 +1,16 @@ +@using Blazorise.Snackbar + +@inherits LayoutComponentBase + + + @(Body) + + + + + \ No newline at end of file diff --git a/WatchIt.Website/Components/Layout/BaseLayout.razor.cs b/WatchIt.Website/Components/Layout/BaseLayout.razor.cs new file mode 100644 index 0000000..6c1fa1c --- /dev/null +++ b/WatchIt.Website/Components/Layout/BaseLayout.razor.cs @@ -0,0 +1,123 @@ +using System.Drawing; +using Blazorise.Snackbar; +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Controllers.Photos.PhotoBackground; +using WatchIt.Website.Clients; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Layout; + +public partial class BaseLayout : LayoutComponentBase +{ + #region SERVICES + + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IPhotosClient PhotosClient { get; set; } = null!; + [Inject] private IAccountsClient AccountsClient { get; set; } = null!; + + #endregion + + + + #region FIELDS + + private static readonly PhotoBackgroundResponse StaticBackgroundSettings = new PhotoBackgroundResponse() + { + IsUniversal = true, + FirstGradientColor = Color.FromArgb(0xc6, 0x72, 0x1c), + SecondGradientColor = Color.FromArgb(0x85, 0x20, 0x0c), + }; + + private PhotoResponse? _defaultBackground; + + #endregion + + + + #region PROPERTIES + + private PhotoResponse? _customBackground; + public PhotoResponse? CustomBackground + { + get => _customBackground; + set + { + _customBackground = value; + StateHasChanged(); + } + } + public PhotoResponse? Background + { + get + { + if (CustomBackground?.Background is not null) + { + return CustomBackground; + } + return _defaultBackground?.Background is not null ? _defaultBackground : null; + } + } + public PhotoBackgroundResponse BackgroundSettings => Background is null ? StaticBackgroundSettings : Background.Background!; + + public AccountResponse? AuthorizedAccount { get; private set; } + public bool AuthorizationLoaded { get; private set; } + + public SnackbarStack SnackbarStack { get; set; } = null!; + + #endregion + + + + #region PUBLIC METHODS + + public async Task RefreshAuthorization() + { + long? accountId = await AuthenticationService.GetAccountIdAsync(); + if (accountId.HasValue) + { + IApiResponse accountResponse = await AccountsClient.GetAccount(accountId.Value, true); + if (accountResponse.IsSuccessful) + { + AuthorizedAccount = accountResponse.Content; + } + } + AuthorizationLoaded = true; + StateHasChanged(); + } + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + if (firstRender) + { + await OnFirstRenderAsync(); + } + } + + protected async Task OnFirstRenderAsync() => await Task.WhenAll( + [ + GetBackground(), + RefreshAuthorization(), + ]); + + protected async Task GetBackground() + { + IApiResponse response = await PhotosClient.GetPhotoBackground(); + if (response.IsSuccessStatusCode) + { + _defaultBackground = response.Content; + } + StateHasChanged(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Layout/EmptyLayout.razor b/WatchIt.Website/Components/Layout/EmptyLayout.razor new file mode 100644 index 0000000..ba057fa --- /dev/null +++ b/WatchIt.Website/Components/Layout/EmptyLayout.razor @@ -0,0 +1,7 @@ +@inherits LayoutComponentBase + +@layout BaseLayout + + + +@(Body) \ No newline at end of file diff --git a/WatchIt.Website/Components/Layout/MainLayout.razor b/WatchIt.Website/Components/Layout/MainLayout.razor new file mode 100644 index 0000000..1847dd4 --- /dev/null +++ b/WatchIt.Website/Components/Layout/MainLayout.razor @@ -0,0 +1,110 @@ +@using System.Drawing +@using System.Net +@using WatchIt.Website.Components.Subcomponents.Common +@using Blazorise +@using Microsoft.AspNetCore.Components.Authorization +@using WatchIt.DTO.Models.Controllers.Genres.Genre +@using Size = Blazorise.Size +@using Color = Blazorise.Color + +@inherits LayoutComponentBase + +@layout BaseLayout + + + +
+
+
+
+
+
+ +
+ @if (_searchbarVisible) + { + + } + else + { +
+ + Database + + Movies + TV Series + People + + + @if (_genres.Any()) + { + + Genres + + @foreach (GenreResponse genre in _genres) + { + @(genre.Name) + } + + + } + +
+ } +
+
+
+ + + + + + + Your profile + User settings + @if (BaseLayout.AuthorizedAccount!.IsAdmin) + { + + Administrator panel + } + + Log out + + + + + Sign in + + + + + +
+
+
+
+
+
+
+
+
+ @Body +
+
+
+ + \ No newline at end of file diff --git a/WatchIt.Website/Components/Layout/MainLayout.razor.cs b/WatchIt.Website/Components/Layout/MainLayout.razor.cs new file mode 100644 index 0000000..52a3305 --- /dev/null +++ b/WatchIt.Website/Components/Layout/MainLayout.razor.cs @@ -0,0 +1,68 @@ +using Blazorise.Snackbar; +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.Website.Clients; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Layout; + +public partial class MainLayout : LayoutComponentBase +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IGenresClient GenresClient { get; set; } = null!; + + #endregion + + + + #region FIELDS + + private bool _searchbarVisible; + + private IEnumerable _genres = []; + + #endregion + + + + #region PARAMETERS + + [CascadingParameter] public required BaseLayout BaseLayout { get; set; } + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await OnFirstRenderAsync(); + } + await base.OnAfterRenderAsync(firstRender); + } + + protected async Task OnFirstRenderAsync() + { + IApiResponse> genresResponse = await GenresClient.GetGenres(); + switch (genresResponse.IsSuccessful) + { + case true: _genres = genresResponse.Content; break; + case false: await BaseLayout.SnackbarStack.PushAsync("An error occured. Genres could not be loaded", SnackbarColor.Danger); break; + } + } + + private async Task Logout() + { + await AuthenticationService.Logout(); + NavigationManager.Refresh(true); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Layout/MainLayout.razor.css b/WatchIt.Website/Components/Layout/MainLayout.razor.css new file mode 100644 index 0000000..1365dbd --- /dev/null +++ b/WatchIt.Website/Components/Layout/MainLayout.razor.css @@ -0,0 +1,5 @@ +/* IDS */ + +#logo { + font-size: 40px; +} \ No newline at end of file diff --git a/WatchIt.Website/Components/List/Filter.cs b/WatchIt.Website/Components/List/Filter.cs new file mode 100644 index 0000000..5a605d1 --- /dev/null +++ b/WatchIt.Website/Components/List/Filter.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Components.List; + +public class Filter : Component where TEntity : class where TQuery : IFilterQuery +{ + #region PARAMETERS + + [CascadingParameter] + public required List Parent { get; set; } + + #endregion + + + + #region FIELDS + + protected TQuery? Query => Parent.Query; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor b/WatchIt.Website/Components/List/List.razor similarity index 67% rename from WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor rename to WatchIt.Website/Components/List/List.razor index 6b614f6..e5987c9 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor +++ b/WatchIt.Website/Components/List/List.razor @@ -1,15 +1,22 @@ -@typeparam TItem where TItem : WatchIt.Common.Query.IQueryOrderable -@typeparam TQuery where TQuery : WatchIt.Common.Query.QueryParameters +@using Blazorise +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common + +@typeparam TItem +@typeparam TEntity where TEntity : class +@typeparam TQuery where TQuery : WatchIt.DTO.Query.IFilterQuery + +@inherits Component
-
+
-

@(Title)

+

@(Title)

@@ -52,22 +59,21 @@ { foreach (TItem item in _items) { - long id = IdSource(item); + long id = IdFunc(item); string url = string.Format(UrlIdTemplate, id);
- +
} if (!_allItemsLoaded) @@ -98,13 +104,13 @@ } else { - + } } else {
- +
}
diff --git a/WatchIt.Website/Components/List/List.razor.cs b/WatchIt.Website/Components/List/List.razor.cs new file mode 100644 index 0000000..76baf25 --- /dev/null +++ b/WatchIt.Website/Components/List/List.razor.cs @@ -0,0 +1,124 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.DTO.Models.Generics.Rating; +using WatchIt.DTO.Query; + +namespace WatchIt.Website.Components.List; + +public partial class List : Component where TEntity : class where TQuery : IFilterQuery +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public required string Title { get; set; } + + [Parameter] public required Func>> GetItemsMethod { get; set; } + + [Parameter] public required Func IdFunc { get; set; } + [Parameter] public required Func NameFunc { get; set; } + [Parameter] public Func AdditionalNameInfoFunc { get; set; } = _ => null; + [Parameter] public required Func> PictureFunc { get; set; } + [Parameter] public required Func GlobalRatingFunc { get; set; } + + [Parameter] public required string UrlIdTemplate { get; set; } + [Parameter] public required string PicturePlaceholder { get; set; } + + [Parameter] public string? SecondaryRatingTitle { get; set; } + + [Parameter] public required Func> GetGlobalRatingMethod { get; set; } + [Parameter] public Func>? GetSecondaryRatingMethod { get; set; } + [Parameter] public Func>? GetYourRatingMethod { get; set; } + [Parameter] public Func? PutYourRatingMethod { get; set; } + [Parameter] public Func? DeleteYourRatingMethod { get; set; } + + [Parameter] public required RenderFragment ChildContent { get; set; } + + [Parameter] public TQuery Query { get; set; } = Activator.CreateInstance()!; + [Parameter] public required Dictionary SortingOptions { get; set; } + + #endregion + + + + #region FIELDS + + private OrderQuery _orderQuery = new OrderQuery(); + private PagingQuery _pagingQuery = new PagingQuery + { + First = 100, + }; + + private bool _loaded; + private string? _error; + + private List _items = new List(); + private bool _allItemsLoaded; + private bool _itemsLoading; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + _orderQuery.OrderBy = SortingOptions.Keys.First(); + await DownloadItems(); + + _loaded = true; + StateHasChanged(); + } + + private async Task DownloadItems() + { + _itemsLoading = true; + IEnumerable items = await GetItemsMethod(Query, _orderQuery, _pagingQuery); + _items.AddRange(items); + if (items.Count() < 100) + { + _allItemsLoaded = true; + } + else + { + _pagingQuery.After ??= 0; + _pagingQuery.After += 100; + } + _itemsLoading = false; + } + + private async Task UpdateItems() + { + _loaded = false; + _pagingQuery.First = 100; + _pagingQuery.After = null; + _items.Clear(); + await DownloadItems(); + _loaded = true; + } + + private async Task SortingAscendingChanged(ChangeEventArgs args) + { + _orderQuery.OrderAscending = (bool)args.Value!; + await UpdateItems(); + } + + private async Task SortingOptionChanged(ChangeEventArgs args) + { + _orderQuery.OrderBy = args.Value!.ToString(); + await UpdateItems(); + } + + private async Task FilterApplied() => await UpdateItems(); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/List/MediaFilter.razor b/WatchIt.Website/Components/List/MediaFilter.razor new file mode 100644 index 0000000..bc62902 --- /dev/null +++ b/WatchIt.Website/Components/List/MediaFilter.razor @@ -0,0 +1,63 @@ +@using WatchIt.Database.Model.Media +@using Blazorise + +@inherits Filter + + + + +
+
+
+ Type + + + + + +
+
+
+
+ Title + +
+
+
+
+ Original title + +
+
+
+
+ Description + +
+
+
+
+ Release date + + - + +
+
+
+
+ Rating (count) + + - + +
+
+
+
+ Rating (average) + + - + +
+
+
+
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/MoviesFilterFormComponent.razor b/WatchIt.Website/Components/List/MediumMoviesFilter.razor similarity index 82% rename from WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/MoviesFilterFormComponent.razor rename to WatchIt.Website/Components/List/MediumMoviesFilter.razor index eac3a8d..7413d6f 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/MoviesFilterFormComponent.razor +++ b/WatchIt.Website/Components/List/MediumMoviesFilter.razor @@ -1,4 +1,5 @@ -@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent +@using Blazorise +@inherits Filter @@ -30,14 +31,6 @@
-
-
- Length - - - - -
-
Budget diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/MoviesRatedFilterFormComponent.razor b/WatchIt.Website/Components/List/MediumMoviesUserRatedFilter.razor similarity index 64% rename from WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/MoviesRatedFilterFormComponent.razor rename to WatchIt.Website/Components/List/MediumMoviesUserRatedFilter.razor index a5ddc12..c3ac434 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/MoviesRatedFilterFormComponent.razor +++ b/WatchIt.Website/Components/List/MediumMoviesUserRatedFilter.razor @@ -1,4 +1,5 @@ -@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent +@using Blazorise +@inherits Filter @@ -30,14 +31,6 @@
-
-
- Length - - - - -
-
Budget @@ -62,21 +55,5 @@
-
-
- User rating - - - - -
-
-
-
- User rating date - - - - -
-
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/SeriesFilterFormComponent.razor b/WatchIt.Website/Components/List/MediumSeriesFilter.razor similarity index 84% rename from WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/SeriesFilterFormComponent.razor rename to WatchIt.Website/Components/List/MediumSeriesFilter.razor index 141a655..04e9b04 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/SeriesFilterFormComponent.razor +++ b/WatchIt.Website/Components/List/MediumSeriesFilter.razor @@ -1,4 +1,7 @@ -@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent +@using Blazorise +@inherits Filter + +
@@ -28,14 +31,6 @@
-
-
- Length - - - - -
-
Has ended diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/SeriesRatedFilterFormComponent.razor b/WatchIt.Website/Components/List/MediumSeriesUserRatedFilter.razor similarity index 68% rename from WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/SeriesRatedFilterFormComponent.razor rename to WatchIt.Website/Components/List/MediumSeriesUserRatedFilter.razor index 2a93f8d..ded2764 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/SeriesRatedFilterFormComponent.razor +++ b/WatchIt.Website/Components/List/MediumSeriesUserRatedFilter.razor @@ -1,4 +1,7 @@ -@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent +@using Blazorise +@inherits Filter + +
@@ -28,14 +31,6 @@
-
-
- Length - - - - -
-
Has ended @@ -65,21 +60,5 @@
-
-
- User rating - - - - -
-
-
-
- User rating date - - - - -
-
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/PersonsFilterFormComponent.razor b/WatchIt.Website/Components/List/PeopleFilter.razor similarity index 93% rename from WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/PersonsFilterFormComponent.razor rename to WatchIt.Website/Components/List/PeopleFilter.razor index 1979f14..bb729e8 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/DatabasePage/Subcomponents/PersonsFilterFormComponent.razor +++ b/WatchIt.Website/Components/List/PeopleFilter.razor @@ -1,5 +1,6 @@ -@using WatchIt.Common.Model.Genders -@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent +@using WatchIt.DTO.Models.Controllers.Genders.Gender +@using Blazorise +@inherits Filter diff --git a/WatchIt.Website/Components/List/PeopleFilter.razor.cs b/WatchIt.Website/Components/List/PeopleFilter.razor.cs new file mode 100644 index 0000000..383e14a --- /dev/null +++ b/WatchIt.Website/Components/List/PeopleFilter.razor.cs @@ -0,0 +1,50 @@ +using Blazorise.Snackbar; +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.Database.Model.People; +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; + +namespace WatchIt.Website.Components.List; + +public partial class PeopleFilter : Filter +{ + #region SERVICES + + [Inject] private IGendersClient GendersClient { get; set; } = default!; + + #endregion + + + + #region FIELDS + + private IEnumerable _genders = []; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + IApiResponse> response = await GendersClient.GetGenders(); + if (response.IsSuccessful) + { + _genders = response.Content; + } + else + { + await Base.SnackbarStack.PushAsync("An error has occured. List of genders could not be obtained.", SnackbarColor.Danger); + } + StateHasChanged(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor b/WatchIt.Website/Components/List/PeopleUserRatedFilter.razor similarity index 57% rename from WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor rename to WatchIt.Website/Components/List/PeopleUserRatedFilter.razor index e1fe738..ce1d49b 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor +++ b/WatchIt.Website/Components/List/PeopleUserRatedFilter.razor @@ -1,6 +1,6 @@ -@using WatchIt.Common.Model.Genders - -@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent +@using WatchIt.DTO.Models.Controllers.Genders.Gender +@using Blazorise +@inherits Filter @@ -8,25 +8,25 @@
- Name + Name
- Full name + Full name
- Description + Description
- Birth date + Birth date - @@ -34,7 +34,7 @@
- Death date + Death date - @@ -42,7 +42,7 @@
- Gender + Gender @foreach (GenderResponse gender in _genders) @@ -54,7 +54,7 @@
- Rating (count) + Rating (count) - @@ -62,35 +62,11 @@
- Rating (average) + Rating (average) -
-
-
- User rating (count) - - - - -
-
-
-
- User rating (average) - - - - -
-
-
-
- User rating (date) - - - - -
-
\ No newline at end of file diff --git a/WatchIt.Website/Components/List/PeopleUserRatedFilter.razor.cs b/WatchIt.Website/Components/List/PeopleUserRatedFilter.razor.cs new file mode 100644 index 0000000..8b428b6 --- /dev/null +++ b/WatchIt.Website/Components/List/PeopleUserRatedFilter.razor.cs @@ -0,0 +1,50 @@ +using Blazorise.Snackbar; +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.Database.Model.People; +using WatchIt.DTO.Models.Controllers.Genders.Gender; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.People.Person.Query; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; + +namespace WatchIt.Website.Components.List; + +public partial class PeopleUserRatedFilter : Filter +{ + #region SERVICES + + [Inject] private IGendersClient GendersClient { get; set; } = default!; + + #endregion + + + + #region FIELDS + + private IEnumerable _genders = []; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + IApiResponse> response = await GendersClient.GetGenders(); + if (response.IsSuccessful) + { + _genders = response.Content; + } + else + { + await Base.SnackbarStack.PushAsync("An error has occured. List of genders could not be obtained.", SnackbarColor.Danger); + } + StateHasChanged(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/AdminPage.razor b/WatchIt.Website/Components/Pages/AdminPage.razor new file mode 100644 index 0000000..80fa1e3 --- /dev/null +++ b/WatchIt.Website/Components/Pages/AdminPage.razor @@ -0,0 +1,64 @@ +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common + +@inherits Page + +@page "/admin" + +Administrator panel - WatchIt + + + + + +
+ +
+
+ + + + +
+ +
+
+
\ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/AdminPage.razor.cs b/WatchIt.Website/Components/Pages/AdminPage.razor.cs new file mode 100644 index 0000000..3dacba5 --- /dev/null +++ b/WatchIt.Website/Components/Pages/AdminPage.razor.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class AdminPage : Page +{ + #region PARAMETERS + + [CascadingParameter] public required BaseLayout Layout { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/AuthPage.razor b/WatchIt.Website/Components/Pages/AuthPage.razor new file mode 100644 index 0000000..fa72874 --- /dev/null +++ b/WatchIt.Website/Components/Pages/AuthPage.razor @@ -0,0 +1,54 @@ +@using System.Drawing +@using System.Text +@using WatchIt.Website.Components.Layout +@using Blazorise.Snackbar +@using WatchIt.Website.Components.Subcomponents.Pages.AuthPage + +@inherits Page + +@layout EmptyLayout + +@page "/auth" + +@{ + StringBuilder sb = new StringBuilder(" - WatchIt"); + + if (_isSingUp) sb.Insert(0, $"Sing up"); + else sb.Insert(0, $"Sing in"); + + @(sb.ToString()) +} + + + + +
+
+
+ + @if (_isSingUp) + { + + } + else + { + + } +
+ + + + +
+
+
+
+ + +
\ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/AuthPage.razor.cs b/WatchIt.Website/Components/Pages/AuthPage.razor.cs new file mode 100644 index 0000000..e2b4a70 --- /dev/null +++ b/WatchIt.Website/Components/Pages/AuthPage.razor.cs @@ -0,0 +1,50 @@ +using System.Net; +using Blazorise.Snackbar; +using Microsoft.AspNetCore.Components; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; +using WatchIt.Website.Services.Tokens; + +namespace WatchIt.Website.Components.Pages; + +public partial class AuthPage +{ + #region SERVICES + + [Inject] public NavigationManager NavigationManager { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [SupplyParameterFromQuery(Name = "redirect_to")] + private string RedirectTo { get; set; } = "/"; + + #endregion + + + + #region FIELDS + + private bool _isSingUp; + + #endregion + + + + #region METHODS + + protected override async Task OnFirstRenderAsync() + { + Base.CustomBackground = null; + if (Base.AuthorizedAccount is not null) + { + NavigationManager.NavigateTo(WebUtility.UrlDecode(RedirectTo)); + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/AuthPage.razor.css b/WatchIt.Website/Components/Pages/AuthPage.razor.css new file mode 100644 index 0000000..19a179e --- /dev/null +++ b/WatchIt.Website/Components/Pages/AuthPage.razor.css @@ -0,0 +1,18 @@ +/* TAGS */ + +html { + height: 100%; +} + + + +/* CLASSES */ + +.logo { + font-size: 60px; + margin: 10px; +} + +.panel-auth { + background-color: rgba(0, 0, 0, 0.8); +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/GenreMediaListPage.razor b/WatchIt.Website/Components/Pages/GenreMediaListPage.razor new file mode 100644 index 0000000..84a1f64 --- /dev/null +++ b/WatchIt.Website/Components/Pages/GenreMediaListPage.razor @@ -0,0 +1,99 @@ +@using System.Net +@using System.Text +@using Blazorise.Snackbar +@using Refit +@using WatchIt.Database.Model.Media +@using WatchIt.DTO.Models.Controllers.Media.Medium.Query +@using WatchIt.DTO.Models.Controllers.Media.Medium.Response +@using WatchIt.DTO.Models.Generics.Rating +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common +@using WatchIt.Website.Components.List + +@inherits Page + +@page "/genres/{id:int}/media" + +@{ + StringBuilder sb = new StringBuilder(" - WatchIt"); + + if (!_loaded) sb.Insert(0, "Loading..."); + else if (_data is null) sb.Insert(0, "Error"); + else sb.Insert(0, $"\"{_data.Name}\" genre"); + + @(sb.ToString()) +} + + + +@if (!_loaded) +{ +
+ +
+} +else if (_data is null) +{ + +} +else +{ + + + +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/GenreMediaListPage.razor.cs b/WatchIt.Website/Components/Pages/GenreMediaListPage.razor.cs new file mode 100644 index 0000000..8f5187b --- /dev/null +++ b/WatchIt.Website/Components/Pages/GenreMediaListPage.razor.cs @@ -0,0 +1,56 @@ +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Genres.Genre; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class GenreMediaListPage : Page +{ + #region SERVICES + + [Inject] private IGenresClient GenresClient { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public int Id { get; set; } + + #endregion + + + + #region FIELDS + + private bool _loaded; + private GenreResponse? _data; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + IApiResponse response = await GenresClient.GetGenre((short)Id); + if (response.IsSuccessful) + { + _data = response.Content; + } + + _loaded = true; + StateHasChanged(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/HomePage.razor b/WatchIt.Website/Components/Pages/HomePage.razor new file mode 100644 index 0000000..6fb48fa --- /dev/null +++ b/WatchIt.Website/Components/Pages/HomePage.razor @@ -0,0 +1,65 @@ +@using Refit +@using WatchIt.DTO.Models.Controllers.Media.Medium.Query +@using WatchIt.DTO.Models.Controllers.Media.Medium.Response +@using WatchIt.DTO.Models.Controllers.People.Person +@using WatchIt.DTO.Models.Generics.Image +@using WatchIt.DTO.Query +@using WatchIt.Website.Components.Panels.Common +@inherits Page + +@page "/" + +WatchIt + + + +
+ + + +
\ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/HomePage.razor.cs b/WatchIt.Website/Components/Pages/HomePage.razor.cs new file mode 100644 index 0000000..cfbc7ab --- /dev/null +++ b/WatchIt.Website/Components/Pages/HomePage.razor.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Website.Clients; + +namespace WatchIt.Website.Components.Pages; + +public partial class HomePage : Page +{ + #region SERVICES + + [Inject] public NavigationManager NavigationManager { get; set; } = default!; + [Inject] public IMediaClient MediaClient { get; set; } = default!; + [Inject] public IPeopleClient PeopleClient { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/MediumEditPage.razor b/WatchIt.Website/Components/Pages/MediumEditPage.razor new file mode 100644 index 0000000..b58c29b --- /dev/null +++ b/WatchIt.Website/Components/Pages/MediumEditPage.razor @@ -0,0 +1,154 @@ +@using System.Net +@using System.Text +@using Blazorise.Snackbar +@using Refit +@using WatchIt.DTO.Models.Generics.Image +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common +@using WatchIt.Website.Components.Panels.Pages.MediumEditPage +@using Authorization = WatchIt.Website.Components.Subcomponents.Common.Authorization +@using WatchIt.DTO.Models.Controllers.Media.Medium.Response +@using Blazorise + +@inherits Page + +@page "/media/{id:long}/edit" +@page "/media/new/{type?}" + +@{ + StringBuilder sb = new StringBuilder(" - WatchIt"); + + if (!_loaded) sb.Insert(0, "Loading..."); + else if (Base.AuthorizedAccount?.IsAdmin != true) sb.Insert(0, "Error"); + else + { + if (_data is not null) sb.Insert(0, $"Edit \"{_data.Title}\""); + else + { + if (Type == "series") sb.Insert(0, "TV series"); + else sb.Insert(0, "movie"); + sb.Insert(0, "New "); + } + } + + @(sb.ToString()) +} + + + +@if (_loaded) +{ + + +
+ +
+
+
+ +
+
+ +
+
+
+ + + Genres + Actors + Creators + Photos + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+
+
+} +else +{ +
+ +
+} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/MediumEditPage.razor.cs b/WatchIt.Website/Components/Pages/MediumEditPage.razor.cs new file mode 100644 index 0000000..f77201c --- /dev/null +++ b/WatchIt.Website/Components/Pages/MediumEditPage.razor.cs @@ -0,0 +1,114 @@ +using Blazorise.Snackbar; +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class MediumEditPage : Page +{ + #region SERVICES + + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IPeopleClient PeopleClient { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public long? Id { get; set; } + [Parameter] public string? Type { get; set; } + + #endregion + + + + #region FIELDS + + private bool _loaded; + + private BaseMediumResponse? _data; + private List? _people; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + await Task.WhenAll( + [ + LoadData(), + LoadPeople(), + LoadBackground(), + ]); + + _loaded = true; + StateHasChanged(); + } + + private async Task LoadData() + { + if (Id.HasValue) + { + IApiResponse response = await MediaClient.GetMedium(Id.Value); + if (response.IsSuccessful) + { + switch (response.Content.Type) + { + case MediumResponseType.Movie: + IApiResponse responseMovie = await MediaClient.GetMediumMovie(Id.Value, true); + _data = responseMovie.Content; + break; + case MediumResponseType.Series: + IApiResponse responseSeries = await MediaClient.GetMediumSeries(Id.Value, true); + _data = responseSeries.Content; + break; + } + } + else + { + await Base.SnackbarStack.PushAsync("An error occured. Medium data could not be obtained.", SnackbarColor.Danger); + } + } + } + + private async Task LoadPeople() + { + IApiResponse> response = await PeopleClient.GetPeople(); + if (response.IsSuccessful) + { + _people = response.Content.ToList(); + } + else + { + await Base.SnackbarStack.PushAsync("An error has occured during loading people.", SnackbarColor.Danger); + } + } + + private async Task LoadBackground() + { + if (Id.HasValue) + { + IApiResponse response = await MediaClient.GetMediumBackgroundPhoto(Id.Value); + if (response.IsSuccessful && response.Content is not null) + { + Base.CustomBackground = response.Content; + } + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/MediumPage.razor b/WatchIt.Website/Components/Pages/MediumPage.razor new file mode 100644 index 0000000..0f4ad7a --- /dev/null +++ b/WatchIt.Website/Components/Pages/MediumPage.razor @@ -0,0 +1,137 @@ +@using System.Text +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common +@using WatchIt.Website.Components.Panels.Pages.MediumPage +@using Blazorise +@using Blazorise.Snackbar +@using Refit +@using WatchIt.DTO.Models.Controllers.People.Person +@using WatchIt.DTO.Models.Controllers.Roles.Role.Query +@using WatchIt.DTO.Models.Controllers.Roles.Role.Response +@using WatchIt.DTO.Models.Controllers.Roles.RoleActorType +@using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType + +@inherits Page + +@page "/media/{id:long}" + +@{ + StringBuilder sb = new StringBuilder(" - WatchIt"); + + if (!_loaded) sb.Insert(0, "Loading..."); + else if (_data is null) sb.Insert(0, "Error"); + else + { + if (_data.ReleaseDate.HasValue) sb.Insert(0, $" ({_data.ReleaseDate.Value.Year})"); + sb.Insert(0, _data.Title); + } + + @(sb.ToString()) +} + + + +@if (!_loaded) +{ +
+ +
+} +else if (_data is null) +{ + +} +else +{ +
+ +
+
+
+ +
+
+ +
+
+
+ + + Actors + Creators + + + + + + + + + + +
+} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/MediumPage.razor.cs b/WatchIt.Website/Components/Pages/MediumPage.razor.cs new file mode 100644 index 0000000..e806655 --- /dev/null +++ b/WatchIt.Website/Components/Pages/MediumPage.razor.cs @@ -0,0 +1,96 @@ +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; + +namespace WatchIt.Website.Components.Pages; + +public partial class MediumPage : Page +{ + #region SERVICES + + [Inject] private IPeopleClient PeopleClient { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + [Inject] private IPhotosClient PhotosClient { get; set; } = null!; + [Inject] private IRolesClient RolesClient { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public long Id { get; set; } + + #endregion + + + + #region FIELDS + + //private RatingPanel _ratingPanel = null!; + + private bool _loaded; + + private MediumResponse? _data; + private IEnumerable? _people; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + await Task.WhenAll( + [ + LoadData(), + LoadPeople(), + IncrementViewCounter(), + LoadBackground(), + ]); + + _loaded = true; + StateHasChanged(); + } + + private async Task LoadData() + { + IApiResponse response = await MediaClient.GetMedium(Id, true); + if (response.IsSuccessful) + { + _data = response.Content; + } + } + + private async Task LoadPeople() + { + IApiResponse> response = await PeopleClient.GetPeople(includePictures: true); + if (response.IsSuccessful) + { + _people = response.Content; + } + } + + private async Task IncrementViewCounter() + { + await MediaClient.PutMediumViewCount(Id); + } + + private async Task LoadBackground() + { + IApiResponse response = await MediaClient.GetMediumBackgroundPhoto(Id); + if (response.IsSuccessful) + { + Base.CustomBackground = response.Content; + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/MoviesListPage.razor b/WatchIt.Website/Components/Pages/MoviesListPage.razor new file mode 100644 index 0000000..c3883b1 --- /dev/null +++ b/WatchIt.Website/Components/Pages/MoviesListPage.razor @@ -0,0 +1,74 @@ +@using System.Net +@using Blazorise.Snackbar +@using Refit +@using WatchIt.Database.Model.Media +@using WatchIt.DTO.Models.Controllers.Media.Medium.Query +@using WatchIt.DTO.Models.Controllers.Media.Medium.Response +@using WatchIt.DTO.Models.Generics.Rating +@using WatchIt.Website.Components.List + +@inherits Page + +@page "/media/movies" + +Movies - WatchIt + + + + + + \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/MoviesListPage.razor.cs b/WatchIt.Website/Components/Pages/MoviesListPage.razor.cs new file mode 100644 index 0000000..95660a5 --- /dev/null +++ b/WatchIt.Website/Components/Pages/MoviesListPage.razor.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class MoviesListPage : Page +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/Page.cs b/WatchIt.Website/Components/Pages/Page.cs new file mode 100644 index 0000000..f091ff9 --- /dev/null +++ b/WatchIt.Website/Components/Pages/Page.cs @@ -0,0 +1,16 @@ +namespace WatchIt.Website.Components.Pages; + +public abstract class Page : Component +{ + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + Base.CustomBackground = null; + StateHasChanged(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/PeopleListPage.razor b/WatchIt.Website/Components/Pages/PeopleListPage.razor new file mode 100644 index 0000000..6c9b6d9 --- /dev/null +++ b/WatchIt.Website/Components/Pages/PeopleListPage.razor @@ -0,0 +1,57 @@ +@using System.Net +@using Blazorise.Snackbar +@using Refit +@using WatchIt.Database.Model.People +@using WatchIt.DTO.Models.Controllers.People.Person +@using WatchIt.DTO.Models.Controllers.People.Person.Query +@using WatchIt.DTO.Models.Generics.Rating +@using WatchIt.Website.Components.List + +@inherits Page + +@page "/people" + +People - WatchIt + + + + + + \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/PeopleListPage.razor.cs b/WatchIt.Website/Components/Pages/PeopleListPage.razor.cs new file mode 100644 index 0000000..e5f2f84 --- /dev/null +++ b/WatchIt.Website/Components/Pages/PeopleListPage.razor.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class PeopleListPage : Page +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IPeopleClient PeopleClient { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/PersonEditPage.razor b/WatchIt.Website/Components/Pages/PersonEditPage.razor new file mode 100644 index 0000000..a8a1954 --- /dev/null +++ b/WatchIt.Website/Components/Pages/PersonEditPage.razor @@ -0,0 +1,138 @@ +@using System.Net +@using System.Text +@using Blazorise.Snackbar +@using Refit +@using WatchIt.DTO.Models.Generics.Image +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common +@using WatchIt.Website.Components.Panels.Pages.PersonEditPage +@using Authorization = WatchIt.Website.Components.Subcomponents.Common.Authorization +@using Blazorise + +@inherits Page + +@page "/people/{id:long}/edit" +@page "/people/new" + +@{ + StringBuilder sb = new StringBuilder(" - WatchIt"); + + if (!_loaded) sb.Insert(0, "Loading..."); + else if (Base.AuthorizedAccount?.IsAdmin == true) sb.Insert(0, "Error"); + else + { + if (_data is null) sb.Insert(0, "Create new person"); + else sb.Insert(0, $"Edit \"{_data.Name}\""); + } + + @(sb.ToString()) +} + + + +@if (_loaded) +{ + + +
+ +
+
+
+ +
+
+ +
+
+
+ + + Actor + Creator + + + + + + + + + + +
+
+ + + + +
+ +
+
+
+} +else +{ +
+ +
+} diff --git a/WatchIt.Website/Components/Pages/PersonEditPage.razor.cs b/WatchIt.Website/Components/Pages/PersonEditPage.razor.cs new file mode 100644 index 0000000..121c9a6 --- /dev/null +++ b/WatchIt.Website/Components/Pages/PersonEditPage.razor.cs @@ -0,0 +1,93 @@ +using Blazorise.Snackbar; +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class PersonEditPage : Page +{ + #region SERVICES + + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IPeopleClient PeopleClient { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public long? Id { get; set; } + + #endregion + + + + #region FIELDS + + private bool _loaded; + + private PersonResponse? _data; + private List? _media; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + await Task.WhenAll( + [ + LoadData(), + LoadMedia(), + ]); + + _loaded = true; + StateHasChanged(); + } + + private async Task LoadData() + { + if (!Id.HasValue) + { + return true; + } + + IApiResponse response = await PeopleClient.GetPerson(Id.Value, true); + if (response.IsSuccessful) + { + _data = response.Content; + } + else + { + await Base.SnackbarStack.PushAsync("An error has occured during loading person data.", SnackbarColor.Danger); + } + + return response.IsSuccessful; + } + + private async Task LoadMedia() + { + IApiResponse> response = await MediaClient.GetMedia(); + if (response.IsSuccessful) + { + _media = response.Content.ToList(); + } + else + { + await Base.SnackbarStack.PushAsync("An error has occured during loading media.", SnackbarColor.Danger); + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/PersonPage.razor b/WatchIt.Website/Components/Pages/PersonPage.razor new file mode 100644 index 0000000..9645a7f --- /dev/null +++ b/WatchIt.Website/Components/Pages/PersonPage.razor @@ -0,0 +1,135 @@ +@using System.Text +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common +@using WatchIt.Website.Components.Panels.Pages.PersonPage +@using Blazorise +@using Blazorise.Snackbar +@using Refit +@using WatchIt.DTO.Models.Controllers.Media.Medium.Response +@using WatchIt.DTO.Models.Controllers.Roles.Role.Query +@using WatchIt.DTO.Models.Controllers.Roles.Role.Response +@using WatchIt.DTO.Models.Controllers.Roles.RoleActorType +@using WatchIt.DTO.Models.Controllers.Roles.RoleCreatorType + +@inherits Page + +@page "/people/{id:long}" + +@{ + StringBuilder sb = new StringBuilder(" - WatchIt"); + + if (!_loaded) sb.Insert(0, "Loading..."); + else if (_data is null) sb.Insert(0, "Error"); + else sb.Insert(0, _data.Name); + + @(sb.ToString()) +} + + + +@if (!_loaded) +{ +
+ +
+} +else if (_data is null) +{ + +} +else +{ +
+ +
+
+
+ +
+
+ +
+
+
+ + + Actor + Creator + + + + + + + + + + +
+} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/PersonPage.razor.cs b/WatchIt.Website/Components/Pages/PersonPage.razor.cs new file mode 100644 index 0000000..7b41bab --- /dev/null +++ b/WatchIt.Website/Components/Pages/PersonPage.razor.cs @@ -0,0 +1,85 @@ +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Media.Medium.Response; +using WatchIt.DTO.Models.Controllers.People.Person; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Components.Panels.Pages.PersonPage; + +namespace WatchIt.Website.Components.Pages; + +public partial class PersonPage : Page +{ + #region SERVICES + + [Inject] private IPeopleClient PeopleClient { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + [Inject] private IRolesClient RolesClient { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public long Id { get; set; } + + #endregion + + + + #region FIELDS + + private RatingPanel _ratingPanel = null!; + + private bool _loaded; + + private PersonResponse? _data; + private IEnumerable? _media; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + await Task.WhenAll( + [ + LoadData(), + LoadMedia(), + IncrementViewCounter(), + ]); + + _loaded = true; + StateHasChanged(); + } + + private async Task LoadData() + { + IApiResponse response = await PeopleClient.GetPerson(Id, true); + if (response.IsSuccessful) + { + _data = response.Content; + } + } + + private async Task LoadMedia() + { + IApiResponse> response = await MediaClient.GetMedia(includePictures: true); + if (response.IsSuccessful) + { + _media = response.Content; + } + } + + private async Task IncrementViewCounter() + { + await PeopleClient.PutPeopleViewCount(Id); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/SearchPage.razor b/WatchIt.Website/Components/Pages/SearchPage.razor new file mode 100644 index 0000000..0850e33 --- /dev/null +++ b/WatchIt.Website/Components/Pages/SearchPage.razor @@ -0,0 +1,154 @@ +@using System.Net +@using Blazorise.Snackbar +@using Refit +@using WatchIt.DTO.Models.Controllers.Media.Medium.Query +@using WatchIt.DTO.Models.Controllers.Media.Medium.Response +@using WatchIt.DTO.Models.Controllers.People.Person +@using WatchIt.DTO.Models.Controllers.People.Person.Query +@using WatchIt.DTO.Models.Generics.Rating +@using WatchIt.Website.Components.Panels.Pages.SearchPage + +@inherits Page + +@page "/search/{query}" + +WatchIt - Searching "@(Query)" + + + +
+
+
+

+ Search results for phrase: "@(WebUtility.UrlDecode(Query))" +

+
+
+ + + + +
\ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/SearchPage.razor.cs b/WatchIt.Website/Components/Pages/SearchPage.razor.cs new file mode 100644 index 0000000..ed59f15 --- /dev/null +++ b/WatchIt.Website/Components/Pages/SearchPage.razor.cs @@ -0,0 +1,35 @@ +using System.Net; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class SearchPage : Page +{ + #region SERVICES + + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + [Inject] private IPeopleClient PeopleClient { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public required string Query { get; set; } + + #endregion + + + + #region FIELDS + + private string _decodedQuery => WebUtility.UrlDecode(Query); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/SeriesListPage.razor b/WatchIt.Website/Components/Pages/SeriesListPage.razor new file mode 100644 index 0000000..bf2df9c --- /dev/null +++ b/WatchIt.Website/Components/Pages/SeriesListPage.razor @@ -0,0 +1,74 @@ +@using System.Net +@using Blazorise.Snackbar +@using Refit +@using WatchIt.Database.Model.Media +@using WatchIt.DTO.Models.Controllers.Media.Medium.Query +@using WatchIt.DTO.Models.Controllers.Media.Medium.Response +@using WatchIt.DTO.Models.Generics.Rating +@using WatchIt.Website.Components.List + +@inherits Page + +@page "/media/series" + +TV series - WatchIt + + + + + + \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/SeriesListPage.razor.cs b/WatchIt.Website/Components/Pages/SeriesListPage.razor.cs new file mode 100644 index 0000000..1ca237c --- /dev/null +++ b/WatchIt.Website/Components/Pages/SeriesListPage.razor.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class SeriesListPage : Page +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/UserEditPage.razor b/WatchIt.Website/Components/Pages/UserEditPage.razor new file mode 100644 index 0000000..6792fb1 --- /dev/null +++ b/WatchIt.Website/Components/Pages/UserEditPage.razor @@ -0,0 +1,120 @@ +@using System.Net +@using System.Text +@using WatchIt.Website.Components.Panels.Pages.UserEditPage +@using Blazorise +@using Blazorise.Snackbar +@using Refit +@using WatchIt.DTO.Models.Generics.Image +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common +@using Authorization = WatchIt.Website.Components.Subcomponents.Common.Authorization + +@inherits Page + +@page "/user_settings" + +@{ + StringBuilder sb = new StringBuilder(" - WatchIt"); + + if (_data is null) sb.Insert(0, "Loading..."); + else sb.Insert(0, "User settings"); + + @(sb.ToString()) +} + + + + + +
+ + + + Profile + Account + + + +
+
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+ + + +
+
+
+
+
+
+ + + + +
+ +
+
+
diff --git a/WatchIt.Website/Components/Pages/UserEditPage.razor.cs b/WatchIt.Website/Components/Pages/UserEditPage.razor.cs new file mode 100644 index 0000000..e71cc24 --- /dev/null +++ b/WatchIt.Website/Components/Pages/UserEditPage.razor.cs @@ -0,0 +1,62 @@ +using System.Net; +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.DTO.Models.Generics.Image; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class UserEditPage : Page +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IAccountsClient AccountsClient { get; set; } = null!; + + #endregion + + + + #region FIELDS + + private AccountResponse? _data; + + //private HeaderPanel _header = default!; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await base.OnFirstRenderAsync(); + + while (!Base.AuthorizationLoaded) + { + await Task.Delay(10); + } + + if (Base.AuthorizedAccount is null) + { + NavigationManager.NavigateTo($"/auth?redirect_to={WebUtility.UrlEncode("/user_settings")}"); + return; + } + StateHasChanged(); + + IApiResponse backgroundResponse = await AccountsClient.GetAccountBackgroundPicture(Base.AuthorizedAccount.Id); + if (backgroundResponse.IsSuccessful) + { + Base.CustomBackground = backgroundResponse.Content; + } + StateHasChanged(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/UserPage.razor b/WatchIt.Website/Components/Pages/UserPage.razor new file mode 100644 index 0000000..ba36402 --- /dev/null +++ b/WatchIt.Website/Components/Pages/UserPage.razor @@ -0,0 +1,313 @@ +@using System.Net +@using System.Text +@using WatchIt.Website.Components.Subcomponents.Common +@using WatchIt.Website.Components.Panels.Common +@using WatchIt.Website.Components.Panels.Pages.UserPage +@using Blazorise +@using Blazorise.Snackbar +@using Refit +@using WatchIt.Database.Model.Media +@using WatchIt.Database.Model.People +@using WatchIt.DTO.Models.Controllers.Accounts.Account +@using WatchIt.DTO.Models.Controllers.Media.Medium.Query +@using WatchIt.DTO.Models.Controllers.Media.Medium.Response +@using WatchIt.DTO.Models.Controllers.People.Person +@using WatchIt.DTO.Models.Controllers.People.Person.Query +@using WatchIt.DTO.Models.Generics.Rating +@using WatchIt.DTO.Query +@using WatchIt.Website.Components.List + +@inherits Page + +@page "/users/{id:long?}" + +@{ + StringBuilder sb = new StringBuilder(" - WatchIt"); + + if (!_loaded) sb.Insert(0, "Loading..."); + else if (_data is null) sb.Insert(0, "Error"); + else + { + if (_owner) sb.Insert(0, "Your profile"); + else sb.Insert(0, $"\"{_data.Username}\" profile"); + } + + @(sb.ToString()) +} + + + +@if (!_loaded) +{ +
+ +
+} +else if (_data is null) +{ + +} +else +{ +
+ + + + Summary + Movies + TV Series + People + Follows + Followers + + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+} \ No newline at end of file diff --git a/WatchIt.Website/Components/Pages/UserPage.razor.cs b/WatchIt.Website/Components/Pages/UserPage.razor.cs new file mode 100644 index 0000000..622897a --- /dev/null +++ b/WatchIt.Website/Components/Pages/UserPage.razor.cs @@ -0,0 +1,127 @@ +using System.Net; +using Blazorise.Snackbar; +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Controllers.Accounts.Account; +using WatchIt.DTO.Models.Controllers.Photos.Photo; +using WatchIt.Website.Clients; +using WatchIt.Website.Components.Layout; +using WatchIt.Website.Services.Authentication; + +namespace WatchIt.Website.Components.Pages; + +public partial class UserPage : Page +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + [Inject] private IAuthenticationService AuthenticationService { get; set; } = null!; + [Inject] private IAccountsClient AccountsClient { get; set; } = null!; + [Inject] private IMediaClient MediaClient { get; set; } = null!; + [Inject] private IPeopleClient PeopleClient { get; set; } = null!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public long? Id { get; set; } + + #endregion + + + + #region FIELDS + + private bool _loaded; + private bool _redirection; + private bool _owner; + + private AccountResponse? _data; + private List _followers; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + await LoadUserData(); + if (_data is not null) + { + await Task.WhenAll( + [ + LoadProfileBackground(), + LoadFollowers() + ]); + } + + _loaded = !_redirection; + StateHasChanged(); + } + + private async Task LoadUserData() + { + if (Id.HasValue) + { + IApiResponse response = await AccountsClient.GetAccount(Id.Value); + if (!response.IsSuccessful) + { + await Base.SnackbarStack.PushAsync("An error occured. Account info could not be obtained.", SnackbarColor.Danger); + } + else + { + _data = response.Content; + } + } + else + { + while (!Base.AuthorizationLoaded) + { + await Task.Delay(10); + } + + if (Base.AuthorizedAccount is null) + { + NavigationManager.NavigateTo($"/auth?redirect_to={WebUtility.UrlEncode("/user")}"); + _redirection = true; + return; + } + + Id = Base.AuthorizedAccount.Id; + _data = Base.AuthorizedAccount; + } + _owner = Id.Value == Base.AuthorizedAccount?.Id; + } + + private async Task LoadProfileBackground() + { + IApiResponse response = await AccountsClient.GetAccountBackgroundPicture(_data!.Id); + if (response.IsSuccessful) + { + Base.CustomBackground = response.Content; + } + else if (response.StatusCode != HttpStatusCode.NotFound) + { + await Base.SnackbarStack.PushAsync("An error occured. Profile background loading failed.", SnackbarColor.Danger); + } + } + + private async Task LoadFollowers() + { + IApiResponse> response = await AccountsClient.GetAccountFollowers(_data!.Id); + if (response.IsSuccessful) + { + _followers = response.Content.ToList(); + } + else + { + await Base.SnackbarStack.PushAsync("An error occured. Followers could not be obtained.", SnackbarColor.Danger); + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/Panels/ErrorPanelComponent.razor b/WatchIt.Website/Components/Panels/Common/ErrorPanel.razor similarity index 95% rename from WatchIt.Website/WatchIt.Website/Components/Common/Panels/ErrorPanelComponent.razor rename to WatchIt.Website/Components/Panels/Common/ErrorPanel.razor index b611147..c7f3c84 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Common/Panels/ErrorPanelComponent.razor +++ b/WatchIt.Website/Components/Panels/Common/ErrorPanel.razor @@ -1,3 +1,7 @@ +@inherits Component + + +
diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/Panels/ErrorPanelComponent.razor.cs b/WatchIt.Website/Components/Panels/Common/ErrorPanel.razor.cs similarity index 57% rename from WatchIt.Website/WatchIt.Website/Components/Common/Panels/ErrorPanelComponent.razor.cs rename to WatchIt.Website/Components/Panels/Common/ErrorPanel.razor.cs index 4a860db..799b3ec 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Common/Panels/ErrorPanelComponent.razor.cs +++ b/WatchIt.Website/Components/Panels/Common/ErrorPanel.razor.cs @@ -1,8 +1,8 @@ using Microsoft.AspNetCore.Components; -namespace WatchIt.Website.Components.Common.Panels; +namespace WatchIt.Website.Components.Panels.Common; -public partial class ErrorPanelComponent : ComponentBase +public partial class ErrorPanel : Component { #region PARAMETERS diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/Panels/ErrorPanelComponent.razor.css b/WatchIt.Website/Components/Panels/Common/ErrorPanel.razor.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/Components/Common/Panels/ErrorPanelComponent.razor.css rename to WatchIt.Website/Components/Panels/Common/ErrorPanel.razor.css diff --git a/WatchIt.Website/Components/Panels/Common/HorizontalListPanel.razor b/WatchIt.Website/Components/Panels/Common/HorizontalListPanel.razor new file mode 100644 index 0000000..12e6512a --- /dev/null +++ b/WatchIt.Website/Components/Panels/Common/HorizontalListPanel.razor @@ -0,0 +1,49 @@ +@using WatchIt.Website.Components.Subcomponents.Common + +@inherits Component +@typeparam TItem + + + +
+
+ @(Title) + @if (_loaded) + { +
+
+ @if (_items.Count() > 0) + { + for (int i = 0; i < Count; i++) + { +
+ @if (_items.Count() > i) + { + + @{ int iCopy = i; } + + + } +
+ } + } + else if (!string.IsNullOrWhiteSpace(EmptyListMessage)) + { +
+
+ @(EmptyListMessage) +
+
+ } +
+
+ } + else + { + + } +
+
\ No newline at end of file diff --git a/WatchIt.Website/Components/Panels/Common/HorizontalListPanel.razor.cs b/WatchIt.Website/Components/Panels/Common/HorizontalListPanel.razor.cs new file mode 100644 index 0000000..9744846 --- /dev/null +++ b/WatchIt.Website/Components/Panels/Common/HorizontalListPanel.razor.cs @@ -0,0 +1,50 @@ +using Microsoft.AspNetCore.Components; +using Refit; +using WatchIt.DTO.Models.Generics.Image; + +namespace WatchIt.Website.Components.Panels.Common; + +public partial class HorizontalListPanel : Component +{ + #region PARAMETERS + + [Parameter] public int Count { get; set; } = 5; + [Parameter] public required string Title {get; set; } + [Parameter] public required Func>>> GetItemsAction { get; set; } + [Parameter] public required string ItemUrlFormatString { get; set; } + [Parameter] public required Func IdSource { get; set; } + [Parameter] public required Func NameSource { get; set; } + [Parameter] public required string PosterPlaceholder { get; set; } + [Parameter] public required Func> GetPictureAction { get; set; } + [Parameter] public bool HidePlace { get; set; } + [Parameter] public string? EmptyListMessage { get; set; } + + #endregion + + + + #region FIELDS + + private bool _loaded; + + private IEnumerable _items = default!; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnFirstRenderAsync() + { + IApiResponse> response = await GetItemsAction(); + if (response.IsSuccessful) + { + _items = response.Content; + } + _loaded = true; + StateHasChanged(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/Panels/PictureEditorPanelComponent.razor b/WatchIt.Website/Components/Panels/Common/ImageEditorPanel.razor similarity index 64% rename from WatchIt.Website/WatchIt.Website/Components/Common/Panels/PictureEditorPanelComponent.razor rename to WatchIt.Website/Components/Panels/Common/ImageEditorPanel.razor index 37613f4..b81e261 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Common/Panels/PictureEditorPanelComponent.razor +++ b/WatchIt.Website/Components/Panels/Common/ImageEditorPanel.razor @@ -1,19 +1,25 @@ +@using WatchIt.Website.Components.Subcomponents.Common + +@inherits Component + + +
@if (_loaded) {
- - - @if (_pictureChanged || _pictureSaved is not null) + + + @if (_imageChanged || _imageSaved is not null) {
- @if (_pictureChanged) + @if (_imageChanged) {
-
- +
} - else if (_pictureSaved is not null) + else if (_imageSaved is not null) { -
- - } - \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor.cs b/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor.cs deleted file mode 100644 index d0df615..0000000 --- a/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System.Net; -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model.Accounts; -using WatchIt.Common.Model.Photos; -using WatchIt.Website.Components.Common.Subcomponents; -using WatchIt.Website.Services.Authentication; -using WatchIt.Website.Services.Tokens; -using WatchIt.Website.Services.Client.Accounts; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Photos; - -namespace WatchIt.Website.Layout; - -public partial class MainLayout : LayoutComponentBase -{ - #region SERVICES - - [Inject] public ILogger Logger { get; set; } = default!; - [Inject] public NavigationManager NavigationManager { get; set; } = default!; - [Inject] public ITokensService TokensService { get; set; } = default!; - [Inject] public IAuthenticationService AuthenticationService { get; set; } = default!; - [Inject] public IMediaClientService MediaClientService { get; set; } = default!; - [Inject] public IPhotosClientService PhotosClientService { get; set; } = default!; - [Inject] public IAccountsClientService AccountsClientService { get; set; } = default!; - - #endregion - - - - #region FIELDS - - private AccountPictureComponent? _profilePicture; - - private bool _loaded; - - private User? _user; - private AccountResponse? _accountData; - private PhotoResponse? _defaultBackgroundPhoto; - - private bool _searchbarVisible; - private string _searchbarText = string.Empty; - - #endregion - - - - #region PROPERTIES - - private PhotoResponse? _backgroundPhoto; - public PhotoResponse? BackgroundPhoto - { - get => _backgroundPhoto; - set - { - _backgroundPhoto = value; - StateHasChanged(); - } - } - - #endregion - - - - #region PUBLIC METHODS - - public async Task ReloadProfilePicture() - { - if (_profilePicture is not null) - { - await _profilePicture.Reload(); - } - } - - #endregion - - - - #region PRIVATE METHODS - - #region Main - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await Task.WhenAll( - [ - Task.Run(async () => _user = await AuthenticationService.GetUserAsync()), - PhotosClientService.GetPhotoRandomBackground(data => _defaultBackgroundPhoto = data) - ]); - - if (_user is not null) - { - await AccountsClientService.GetAccount(_user.Id, data => _accountData = data); - } - - _loaded = true; - StateHasChanged(); - } - } - - private PhotoResponse? GetBackgroundPhoto() - { - if (BackgroundPhoto?.Background is not null) - { - return BackgroundPhoto; - } - else if (_defaultBackgroundPhoto?.Background is not null) - { - return _defaultBackgroundPhoto; - } - return null; - } - - #endregion - - #region Search - - private void SearchStart() - { - if (!string.IsNullOrWhiteSpace(_searchbarText)) - { - string query = WebUtility.UrlEncode(_searchbarText); - NavigationManager.NavigateTo($"/search/{query}", true); - } - } - - #endregion - - #region User menu - - private async Task UserMenuLogOut() - { - await AuthenticationService.LogoutAsync(); - await TokensService.RemoveAuthenticationData(); - NavigationManager.Refresh(true); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor.css b/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor.css deleted file mode 100644 index 9a467a1..0000000 --- a/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor.css +++ /dev/null @@ -1,18 +0,0 @@ -/* TAGS */ - -h1 { - margin: 0; -} - - - -/* IDS */ - -#logo { - font-size: 40px; -} - -#searchbarCancel { - cursor: pointer; - color: #6c757d; -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/AdminPage.razor b/WatchIt.Website/WatchIt.Website/Pages/AdminPage.razor deleted file mode 100644 index 885be66..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/AdminPage.razor +++ /dev/null @@ -1,46 +0,0 @@ -@page "/admin" - -WatchIt administrator panel - -
- @if (_loaded) - { - if (_authenticated) - { -
-
-

Add new data

-
-
- - } - else - { -
-
- -
-
- } - } - else - { -
-
-
- -
-
-
- } -
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/AdminPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/AdminPage.razor.cs deleted file mode 100644 index b8993a8..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/AdminPage.razor.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Microsoft.AspNetCore.Components; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Authentication; - -namespace WatchIt.Website.Pages; - -public partial class AdminPage -{ - #region SERVICES - - [Inject] public IAuthenticationService AuthenticationService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [CascadingParameter] public MainLayout Layout { get; set; } - - #endregion - - - - #region FIELDS - - private bool _loaded = false; - private bool _authenticated = false; - - #endregion - - - - #region PRIVATE METHODS - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - Layout.BackgroundPhoto = null; - - User? user = await AuthenticationService.GetUserAsync(); - if (user is not null && user.IsAdmin) - { - _authenticated = true; - } - _loaded = true; - StateHasChanged(); - } - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor b/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor deleted file mode 100644 index 0becab5..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor +++ /dev/null @@ -1,116 +0,0 @@ -@page "/auth" -@layout EmptyLayout - -WatchIt - @(_isSingUp ? "Sign up" : "Sign in") - - - -@if (_loaded) -{ -
-
-
- - @if (_isSingUp) - { - - -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
- @_formMessage -
-
- -
-
-
-
- } - else - { - - -
-
- -
- -
-
-
- -
- -
-
-
-
-
- - -
-
-
-
-
- @_formMessage -
-
- -
-
-
-
- } -
- - - - -
-
-
-
- - - - -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor.cs deleted file mode 100644 index 05f6be9..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System.Net; -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model.Accounts; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Photos; -using WatchIt.Website.Services.Authentication; -using WatchIt.Website.Services.Tokens; -using WatchIt.Website.Services.Client.Accounts; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Photos; - -namespace WatchIt.Website.Pages; - -public partial class AuthPage -{ - #region SERVICES - - [Inject] public ILogger Logger { get; set; } = default!; - [Inject] public IAuthenticationService AuthenticationService { get; set; } = default!; - [Inject] public ITokensService TokensService { get; set; } = default!; - [Inject] public IMediaClientService MediaClientService { get; set; } = default!; - [Inject] public IAccountsClientService AccountsClientService { get; set; } = default!; - [Inject] public IPhotosClientService PhotosClientService { get; set; } = default!; - [Inject] public NavigationManager NavigationManager { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [SupplyParameterFromQuery(Name = "redirect_to")] - private string RedirectTo { get; set; } = "/"; - - #endregion - - - - #region FIELDS - - private bool _loaded; - - private PhotoResponse? _background; - - private bool _isSingUp; - private string? _formMessage; - private bool _formMessageIsSuccess; - - private RegisterRequest _registerModel = new RegisterRequest - { - Username = null, - Email = null, - Password = null - }; - private string _registerPasswordConfirmation; - - private AuthenticateRequest _loginModel = new AuthenticateRequest - { - UsernameOrEmail = null, - Password = null - }; - - #endregion - - - - #region METHODS - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - if (await AuthenticationService.GetAuthenticationStatusAsync()) - { - NavigationManager.NavigateTo(WebUtility.UrlDecode(RedirectTo)); - } - - List endTasks = new List(); - - // STEP 0 - endTasks.AddRange( - [ - PhotosClientService.GetPhotoRandomBackground(data => _background = data) - ]); - - // END - await Task.WhenAll(endTasks); - - _loaded = true; - StateHasChanged(); - } - } - - private async Task Login() - { - void LoginBadRequest(IDictionary data) - { - _formMessageIsSuccess = false; - _formMessage = data.SelectMany(x => x.Value).FirstOrDefault(); - } - - void LoginUnauthorized() - { - _formMessageIsSuccess = false; - _formMessage = "Incorrect account data"; - } - - async Task LoginSuccess(AuthenticateResponse data) - { - await TokensService.SaveAuthenticationData(data); - NavigationManager.NavigateTo(RedirectTo); - } - - - await AccountsClientService.Authenticate(_loginModel, async (data) => await LoginSuccess(data), LoginBadRequest, LoginUnauthorized); - } - - private async Task Register() - { - void RegisterSuccess(RegisterResponse data) - { - _formMessageIsSuccess = true; - _formMessage = "You are registered. You can sign in now."; - _isSingUp = false; - } - - void RegisterBadRequest(IDictionary data) - { - _formMessageIsSuccess = false; - _formMessage = data.SelectMany(x => x.Value).FirstOrDefault(); - } - - - if (_registerModel.Password != _registerPasswordConfirmation) - { - _formMessageIsSuccess = false; - _formMessage = "Password fields don't match"; - return; - } - await AccountsClientService.Register(_registerModel, RegisterSuccess, RegisterBadRequest); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor.css b/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor.css deleted file mode 100644 index 0d8700d..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor.css +++ /dev/null @@ -1,22 +0,0 @@ -/* TAGS */ - -html { - height: 100%; -} - -body { - background-position: center; - background-repeat: no-repeat; - background-size: cover; - - height: 100%; -} - - - -/* CLASSES */ - -.logo { - font-size: 60px; - margin: 10px; -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor b/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor deleted file mode 100644 index c5e6630..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor +++ /dev/null @@ -1,108 +0,0 @@ -@using WatchIt.Common.Model.Movies -@using WatchIt.Common.Model.Persons -@using WatchIt.Common.Model.Series -@using WatchIt.Website.Components.Pages.DatabasePage -@using WatchIt.Website.Components.Pages.DatabasePage.Subcomponents -@using WatchIt.Website.Components.Common.ListComponent - -@page "/database/{type?}" - - - - - @("WatchIt - ") - @switch (Type) - { - case "movies": - @("Movies"); - break; - case "series": - @("Series"); - break; - case "people": - @("People"); - break; - } - @(" database") - - - - -@switch (Type) -{ - case "movies": - - - - break; - case "series": - - - - break; - case "people": - - - - break; -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.cs deleted file mode 100644 index 48ae59b..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Microsoft.AspNetCore.Components; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Movies; -using WatchIt.Website.Services.Client.Persons; -using WatchIt.Website.Services.Client.Series; - -namespace WatchIt.Website.Pages; - -public partial class DatabasePage : ComponentBase -{ - #region SERVICES - - [Inject] private NavigationManager NavigationManager { get; set; } = default!; - [Inject] private IMediaClientService MediaClientService { get; set; } = default!; - [Inject] private IMoviesClientService MoviesClientService { get; set; } = default!; - [Inject] private ISeriesClientService SeriesClientService { get; set; } = default!; - [Inject] private IPersonsClientService PersonsClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [Parameter] public string? Type { get; set; } - - [CascadingParameter] public MainLayout Layout { get; set; } - - #endregion - - - - #region FIELDS - - private static IEnumerable _databaseTypes = ["movies", "series", "people"]; - - #endregion - - - - #region PRIVATE METHODS - - protected override void OnParametersSet() - { - if (!_databaseTypes.Contains(Type)) - { - NavigationManager.NavigateTo($"/database/{_databaseTypes.First()}"); - } - } - - protected override void OnAfterRender(bool firstRender) - { - if (firstRender) - { - // INIT - Layout.BackgroundPhoto = null; - - StateHasChanged(); - } - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/HomePage.razor b/WatchIt.Website/WatchIt.Website/Pages/HomePage.razor deleted file mode 100644 index 459cd3c..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/HomePage.razor +++ /dev/null @@ -1,36 +0,0 @@ -@using WatchIt.Common.Model.Movies -@using WatchIt.Common.Model.Persons -@using WatchIt.Common.Model.Series - -@page "/" - -WatchIt - - - -
- - - -
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/HomePage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/HomePage.razor.cs deleted file mode 100644 index b623573..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/HomePage.razor.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Movies; -using WatchIt.Common.Model.Series; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Movies; -using WatchIt.Website.Services.Client.Persons; -using WatchIt.Website.Services.Client.Series; - -namespace WatchIt.Website.Pages; - -public partial class HomePage -{ - #region SERVICES - - [Inject] public NavigationManager NavigationManager { get; set; } = default!; - [Inject] public IMediaClientService MediaClientService { get; set; } = default!; - [Inject] public IMoviesClientService MoviesClientService { get; set; } = default!; - [Inject] public ISeriesClientService SeriesClientService { get; set; } = default!; - [Inject] public IPersonsClientService PersonsClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [CascadingParameter] public MainLayout Layout { get; set; } = default!; - - #endregion - - - - #region PRIVATE METHODS - - protected override void OnAfterRender(bool firstRender) - { - if (firstRender) - { - Layout.BackgroundPhoto = null; - - StateHasChanged(); - } - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor deleted file mode 100644 index f0aa505..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor +++ /dev/null @@ -1,367 +0,0 @@ -@using Microsoft.IdentityModel.Tokens -@using WatchIt.Common.Model.Movies -@using WatchIt.Common.Model.Photos -@using WatchIt.Common.Model.Series -@using WatchIt.Website.Components.Pages.MediaEditPage.Panels - -@page "/media/{id:long}/edit" -@page "/media/new/{type?}" - - - - WatchIt - - @if (_loaded) - { - if (string.IsNullOrWhiteSpace(_error) && _user?.IsAdmin == true) - { - if (_media is not null) - { - @($"Edit \"")@(_media.Title)@("\"") - } - else - { - if (_movieRequest is null) - { - @("New TV series") - } - else - { - @("New movie") - } - } - } - else - { - @("Error") - } - } - else - { - @("Loading") - } - - -
- @if (_loaded) - { - if (string.IsNullOrWhiteSpace(_error)) - { - if (_user?.IsAdmin == true) - { -
-
-
-
- @if (_media is not null) - { - -

Edit @(_movieRequest is not null ? "movie" : "series") "@(_media.Title)"

-
- } - else - { -

Create new @(_movieRequest is not null ? "movie" : "series")

- } -
-
-
-
-
-
- -
-
-
- - -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
- -
- -
-
- @if (_mediaRequest is MovieRequest) - { -
- -
- -
-
- } - else - { -
- -
-
- -
- - Yes -
-
- - No -
-
-
-
-
- } -
-
-
- @if (!string.IsNullOrWhiteSpace(_basicDataError)) - { -
@_basicDataError
- } - -
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-

Photos

-
-
-
- @if (!_photoEditMode) - { - - } - else - { -
- @if (!string.IsNullOrWhiteSpace(_photoEditError)) - { -
- @_photoEditError -
- } - - -
- } -
-
-
-
- @if (!_photoEditMode) - { - if (!_photos.IsNullOrEmpty()) - { -
- @foreach (PhotoResponse photo in _photos) - { -
-
-
- -
-
-
- @if (photo.Background is not null) - { -
-
-
- background_icon -
-
-
- } -
-
- Upload: @(photo.UploadDate.ToString()) -
-
-
- -
-
- -
-
-
- } -
- } - else - { -
- Photo list is empty -
- } - } - else - { -
-
-
-
-
-
- -
-
- @if (_photoEditId is null) - { -
-
- -
-
- } -
-
-
-
-
-
-
- - -
-
-
-
- - -
-
-
-
- -
- -
-
-
- -
- -
-
-
-
-
-
- } -
-
-
-
-
-
- } - else - { -
-
- -
-
- } - } - else - { -
-
- -
-
- } - } - else - { -
-
-
- -
-
-
- } -
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor.cs deleted file mode 100644 index ad6d54f..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor.cs +++ /dev/null @@ -1,396 +0,0 @@ -using System.Diagnostics; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Forms; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Movies; -using WatchIt.Common.Model.Persons; -using WatchIt.Common.Model.Photos; -using WatchIt.Common.Model.Series; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Authentication; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Movies; -using WatchIt.Website.Services.Client.Persons; -using WatchIt.Website.Services.Client.Photos; -using WatchIt.Website.Services.Client.Series; - -namespace WatchIt.Website.Pages; - -public partial class MediaEditPage : ComponentBase -{ - #region SERVICES - - [Inject] public NavigationManager NavigationManager { get; set; } = default!; - [Inject] public IAuthenticationService AuthenticationService { get; set; } = default!; - [Inject] public IMediaClientService MediaClientService { get; set; } = default!; - [Inject] public IMoviesClientService MoviesClientService { get; set; } = default!; - [Inject] public ISeriesClientService SeriesClientService { get; set; } = default!; - [Inject] public IPhotosClientService PhotosClientService { get; set; } = default!; - [Inject] public IPersonsClientService PersonsClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [Parameter] public long? Id { get; set; } - [Parameter] public string? Type { get; set; } - - [CascadingParameter] public MainLayout Layout { get; set; } - - #endregion - - - - #region FIELDS - - private bool _loaded = false; - private string? _error; - - private User? _user; - - private MediaResponse? _media; - private Dictionary _persons; - - private MovieRequest? _movieRequest; - private SeriesRequest? _seriesRequest; - private Media? _mediaRequest => _movieRequest is not null ? _movieRequest : _seriesRequest; - private bool _basicDataSaving; - private string? _basicDataError; - - private MediaPosterResponse? _mediaPosterSaved; - private MediaPosterRequest? _mediaPosterRequest; - private bool _mediaPosterChanged; - private bool _mediaPosterSaving; - private bool _mediaPosterDeleting; - - private IEnumerable _photos = new List(); - private List _photoDeleting = new List(); - private bool _photoEditMode; - private string? _photoEditError; - private Guid? _photoEditId; - private bool _photoEditSaving; - private bool _photoEditIsBackground; - private MediaPhotoRequest? _photoEditRequest; - private PhotoBackgroundDataRequest? _photoEditBackgroundData = new PhotoBackgroundDataRequest() - { - FirstGradientColor = [0xFF, 0xFF, 0xFF], - SecondGradientColor = [0x00, 0x00, 0x00], - IsUniversalBackground = false - }; - - #endregion - - - - #region PRIVATE METHODS - - #region Main - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - Layout.BackgroundPhoto = null; - - List step1Tasks = new List(); - List step2Tasks = new List(); - List endTasks = new List(); - - // STEP 0 - step1Tasks.AddRange( - [ - Task.Run(async () => _user = await AuthenticationService.GetUserAsync()) - ]); - - // STEP 1 - await Task.WhenAll(step1Tasks); - if (_user is not null && _user.IsAdmin) - { - step2Tasks.AddRange( - [ - InitializeMedia() - ]); - endTasks.AddRange( - [ - PersonsClientService.GetAllPersons(successAction: data => _persons = data.ToDictionary(x => x.Id, x => x)) - ]); - } - - // STEP 2 - await Task.WhenAll(step2Tasks); - if (_user is not null && _user.IsAdmin && _media is not null) - { - endTasks.AddRange( - [ - MediaClientService.GetMediaPhotoRandomBackground(Id.Value, data => Layout.BackgroundPhoto = data), - MediaClientService.GetMediaPoster(Id.Value, data => - { - _mediaPosterSaved = data; - _mediaPosterRequest = new MediaPosterRequest(data); - }), - MediaClientService.GetMediaPhotos(Id.Value, successAction: data => _photos = data) - ]); - } - - await Task.WhenAll(endTasks); - - _loaded = true; - StateHasChanged(); - } - } - - private async Task InitializeMedia() - { - if (Id.HasValue) - { - await MediaClientService.GetMedia(Id.Value, data => _media = data, () => NavigationManager.NavigateTo("/media/new/movie")); - if (_media.Type == MediaType.Movie) - { - await MoviesClientService.GetMovie(Id.Value, data => _movieRequest = new MovieRequest(data)); - } - else - { - await SeriesClientService.GetSeries(Id.Value, data => _seriesRequest = new SeriesRequest(data)); - } - } - else - { - if (!string.IsNullOrWhiteSpace(Type) && Type == "series") - { - _seriesRequest = new SeriesRequest - { - Title = string.Empty - }; - } - else - { - _movieRequest = new MovieRequest - { - Title = string.Empty - }; - } - } - } - - #endregion - - #region Poster - - private async Task LoadPoster(InputFileChangeEventArgs args) - { - if (args.File.ContentType.StartsWith("image")) - { - Stream stream = args.File.OpenReadStream(5242880); - byte[] array; - using (MemoryStream ms = new MemoryStream()) - { - await stream.CopyToAsync(ms); - array = ms.ToArray(); - } - - _mediaPosterRequest = new MediaPosterRequest() - { - Image = array, - MimeType = args.File.ContentType - }; - _mediaPosterChanged = true; - } - } - - private async Task SavePoster() - { - void Success(MediaPosterResponse data) - { - _mediaPosterSaved = data; - _mediaPosterRequest = new MediaPosterRequest(data); - _mediaPosterChanged = false; - _mediaPosterSaving = false; - } - - _mediaPosterSaving = true; - await MediaClientService.PutMediaPoster(Id.Value, _mediaPosterRequest, Success); - } - - private void CancelPoster() - { - _mediaPosterRequest = _mediaPosterSaved is not null ? new MediaPosterRequest(_mediaPosterSaved) : null; - _mediaPosterChanged = false; - } - - private async Task DeletePoster() - { - void Success() - { - _mediaPosterSaved = null; - _mediaPosterRequest = null; - _mediaPosterChanged = false; - _mediaPosterDeleting = false; - } - - _mediaPosterDeleting = true; - await MediaClientService.DeleteMediaPoster(Id.Value, Success); - } - - #endregion - - #region Basic data - - private async Task SaveBasicData() - { - void SuccessPost(long id) - { - _basicDataSaving = false; - NavigationManager.NavigateTo($"/media/{id}/edit", true); - } - - void BadRequest(IDictionary errors) - { - _basicDataError = errors.SelectMany(x => x.Value).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(_basicDataError)) - { - _basicDataSaving = false; - } - } - - _basicDataSaving = true; - if (_media is null) - { - if (_movieRequest is not null) - { - await MoviesClientService.PostMovie(_movieRequest, data => SuccessPost(data.Id), BadRequest); - } - else - { - await SeriesClientService.PostSeries(_seriesRequest, data => SuccessPost(data.Id), BadRequest); - } - } - else - { - if (_movieRequest is not null) - { - await MoviesClientService.PutMovie(Id.Value, _movieRequest, () => _basicDataSaving = false, BadRequest); - } - else - { - await SeriesClientService.PutSeries(Id.Value, _seriesRequest, () => _basicDataSaving = false, BadRequest); - } - } - } - - #endregion - - #region Photos - - private async Task DeletePhoto(Guid id) - { - async Task Success() - { - NavigationManager.Refresh(true); - } - - _photoDeleting.Add(id); - await PhotosClientService.DeletePhoto(id, async () => await Success()); - } - - private void InitEditPhoto(Guid? id) - { - _photoEditMode = true; - _photoEditId = id; - _photoEditRequest = null; - _photoEditIsBackground = false; - _photoEditBackgroundData = new PhotoBackgroundDataRequest - { - FirstGradientColor = [0xFF, 0xFF, 0xFF], - SecondGradientColor = [0x00, 0x00, 0x00], - IsUniversalBackground = false - }; - if (id is not null) - { - PhotoResponse response = _photos.First(x => x.Id == id); - _photoEditRequest = new MediaPhotoRequest(response); - if (response.Background is not null) - { - _photoEditIsBackground = true; - _photoEditBackgroundData = new PhotoBackgroundDataRequest(response.Background); - } - } - } - - private void CancelEditPhoto() - { - _photoEditMode = false; - _photoEditId = null; - _photoEditError = null; - } - - private async Task SaveEditPhoto() - { - void Success() - { - NavigationManager.Refresh(true); - } - - void BadRequest(IDictionary errors) - { - _photoEditError = errors.SelectMany(x => x.Value).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(_basicDataError)) - { - _photoEditSaving = false; - } - } - - _photoEditSaving = true; - if (_photoEditId is null) - { - _photoEditRequest.Background = _photoEditIsBackground ? _photoEditBackgroundData : null; - await MediaClientService.PostMediaPhoto(Id.Value, _photoEditRequest, Success, BadRequest); - } - else - { - if (_photoEditIsBackground) - { - await PhotosClientService.PutPhotoBackgroundData(_photoEditId.Value, _photoEditBackgroundData, Success, BadRequest); - } - else - { - await PhotosClientService.DeletePhotoBackgroundData(_photoEditId.Value, Success); - } - } - } - - private async Task LoadPhoto(InputFileChangeEventArgs args) - { - if (args.File.ContentType.StartsWith("image")) - { - Stream stream = args.File.OpenReadStream(5242880); - byte[] array; - using (MemoryStream ms = new MemoryStream()) - { - await stream.CopyToAsync(ms); - array = ms.ToArray(); - } - - _photoEditRequest = new MediaPhotoRequest - { - Image = array, - MimeType = args.File.ContentType - }; - } - } - - private void EditPhotoFirstGradientColorChanged(ChangeEventArgs e) - { - _photoEditBackgroundData.FirstGradientColor = Convert.FromHexString(e.Value.ToString().Replace("#", string.Empty)); - } - - private void EditPhotoSecondGradientColorChanged(ChangeEventArgs e) - { - _photoEditBackgroundData.SecondGradientColor = Convert.FromHexString(e.Value.ToString().Replace("#", string.Empty)); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor deleted file mode 100644 index 87b0359..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor +++ /dev/null @@ -1,212 +0,0 @@ -@using System.Text -@using Microsoft.IdentityModel.Tokens -@using WatchIt.Common.Model.Genres -@using WatchIt.Website.Components.Pages.MediaPage.Panels - -@page "/media/{id:long}" - -@layout MainLayout - -@if (_loaded) -{ - if (string.IsNullOrWhiteSpace(_error)) - { - @_media.Title@(_media.ReleaseDate is not null ? $" ({_media.ReleaseDate.Value.Year})" : string.Empty) - WatchIt - } - else - { - Error - WatchIt - } -} -else -{ - Loading... - WatchIt -} - - - -
- @if (_loaded) - { - if (string.IsNullOrWhiteSpace(_error)) - { -
-
- -
-
-
-
-
-
-
-
- -
-
-
-
-

Genres:

-
-
-
-
-
- @if (_genres.IsNullOrEmpty()) - { -
- No genres assigned. -
- } - else - { - foreach (GenreResponse genre in _genres) - { - - - - } - } -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-

- Your rating: -

-
-
-
-
- @if (_user is not null) - { -
- - - - - - - - - - - - - - - - - - - - -
- } - else - { -

You must be logged in to add a rating

- } -
-
-
-
-
-
-
-
- - - Actors - Creators - - - -
- -
-
- -
- -
-
-
-
-
-
- } - else - { -
-
- -
-
- } - } - else - { -
-
-
- -
-
-
- } -
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs deleted file mode 100644 index 047716f..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System.Diagnostics; -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model.Genres; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Movies; -using WatchIt.Common.Model.Photos; -using WatchIt.Common.Model.Rating; -using WatchIt.Common.Model.Series; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Authentication; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Movies; -using WatchIt.Website.Services.Client.Series; - -namespace WatchIt.Website.Pages; - -public partial class MediaPage : ComponentBase -{ - #region SERVICES - - [Inject] public NavigationManager NavigationManager { get; set; } = default!; - [Inject] public IAuthenticationService AuthenticationService { get; set; } = default!; - [Inject] public IMediaClientService MediaClientService { get; set; } = default!; - [Inject] public IMoviesClientService MoviesClientService { get; set; } = default!; - [Inject] public ISeriesClientService SeriesClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [Parameter] public long Id { get; set; } - - [CascadingParameter] public MainLayout Layout { get; set; } - - #endregion - - - - #region FIELDS - - private bool _loaded; - private string? _error; - - private MediaResponse? _media; - - private User? _user; - - private MediaPosterResponse? _poster; - private IEnumerable _genres; - private RatingResponse _globalRating; - private MovieResponse? _movie; - private SeriesResponse? _series; - - private short? _userRating; - - #endregion - - - - #region PRIVATE METHODS - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - Layout.BackgroundPhoto = null; - - List step1Tasks = new List(); - List step2Tasks = new List(); - List endTasks = new List(); - - // STEP 0 - step1Tasks.AddRange( - [ - MediaClientService.GetMedia(Id, data => _media = data, () => _error = $"Media with id {Id} was not found") - ]); - - // STEP 1 - await Task.WhenAll(step1Tasks); - if (_error is null) - { - step2Tasks.AddRange( - [ - Task.Run(async () => _user = await AuthenticationService.GetUserAsync()) - ]); - - endTasks.AddRange( - [ - MediaClientService.PostMediaView(Id), - MediaClientService.GetMediaPhotoRandomBackground(Id, data => Layout.BackgroundPhoto = data), - MediaClientService.GetMediaGenres(Id, data => _genres = data), - MediaClientService.GetMediaRating(Id, data => _globalRating = data), - _media.Type == MediaType.Movie ? MoviesClientService.GetMovie(Id, data => _movie = data) : SeriesClientService.GetSeries(Id, data => _series = data), - ]); - } - - // STEP 2 - await Task.WhenAll(step2Tasks); - if (_error is null && _user is not null) - { - endTasks.AddRange( - [ - MediaClientService.GetMediaRatingByUser(Id, _user.Id, data => _userRating = data) - ]); - } - - // END - await Task.WhenAll(endTasks); - - _loaded = true; - StateHasChanged(); - } - } - - private async Task AddRating(short rating) - { - if (_userRating == rating) - { - await MediaClientService.DeleteMediaRating(Id); - _userRating = null; - } - else - { - await MediaClientService.PutMediaRating(Id, new RatingRequest(rating)); - _userRating = rating; - } - await MediaClientService.GetMediaRating(Id, data => _globalRating = data); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.css b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.css deleted file mode 100644 index de598ce..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.css +++ /dev/null @@ -1,38 +0,0 @@ -/* CLASSES */ - -.metadata-pill { - border-color: gray; - border-width: 2px; - border-radius: 30px; - border-style: solid; - - padding: 2px 10px; -} - -.title-shadow { - text-shadow: 2px 2px 2px #000; -} - -.description-shadow { - text-shadow: 1px 1px 1px #000; -} - -.rating-separator { - border-color: black; - border-width: 1px; - - margin: 10px 0; -} - -.rating > input { - display: none; -} - -.rating > label { - font-size: 30px; -} - -.rating > label:hover, .rating > input:hover+label { - color: gray !important; - cursor: pointer; -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/PersonEditPage.razor b/WatchIt.Website/WatchIt.Website/Pages/PersonEditPage.razor deleted file mode 100644 index 466d05d..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/PersonEditPage.razor +++ /dev/null @@ -1,87 +0,0 @@ -@using WatchIt.Common.Model.Persons -@using WatchIt.Website.Components.Pages.PersonEditPage.Panels - -@page "/person/{id:long}/edit" -@page "/person/new" - - - - - WatchIt - - @if (_loaded) - { - if (string.IsNullOrWhiteSpace(_error) && _user?.IsAdmin == true) - { - if (_person is not null) - { - @("Edit \"")@(_person.Name)@("\"") - } - else - { - @("Create new person") - } - } - else - { - @("Error") - } - } - else - { - @("Loading") - } - - - - -@if (_loaded) -{ - if (_user?.IsAdmin == true) - { -
-
-
-
-

@(Id is not null ? "Edit" : "Create new") person @(_person is not null ? $" \"{_person.Name}\"" : string.Empty)

-
-
-
-
-
- -
-
- -
-
-
-
- -
-
-
-
- -
-
-
- } - else - { - - } -} -else -{ -
- -
-} diff --git a/WatchIt.Website/WatchIt.Website/Pages/PersonEditPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/PersonEditPage.razor.cs deleted file mode 100644 index 77bd731..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/PersonEditPage.razor.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model.Media; -using WatchIt.Common.Model.Persons; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Authentication; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Persons; - -namespace WatchIt.Website.Pages; - -public partial class PersonEditPage : ComponentBase -{ - #region SERVICES - - [Inject] private NavigationManager NavigationManager { get; set; } = default!; - [Inject] private IAuthenticationService AuthenticationService { get; set; } = default!; - [Inject] private IPersonsClientService PersonsClientService { get; set; } = default!; - [Inject] private IMediaClientService MediaClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [Parameter] public long? Id { get; set; } - - [CascadingParameter] public MainLayout Layout { get; set; } - - #endregion - - - - #region FIELDS - - private bool _loaded; - private string? _error; - - private User? _user; - - private PersonResponse? _person; - private Dictionary _media = []; - - #endregion - - - - #region PRIVATE METHODS - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - List step1Tasks = new List(); - List endTasks = new List(); - - // STEP 0 - step1Tasks.AddRange( - [ - Task.Run(async () => _user = await AuthenticationService.GetUserAsync()), - ]); - - // STEP 1 - await Task.WhenAll(step1Tasks); - if (_user?.IsAdmin == true && Id.HasValue) - { - endTasks.AddRange( - [ - PersonsClientService.GetPerson(Id.Value, data => _person = data, () => NavigationManager.NavigateTo("/person/new", true)), - MediaClientService.GetAllMedia(successAction: data => _media = data.ToDictionary(x => x.Id, x => x)), - ]); - } - - // END - await Task.WhenAll(endTasks); - - _loaded = true; - StateHasChanged(); - } - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/PersonPage.razor b/WatchIt.Website/WatchIt.Website/Pages/PersonPage.razor deleted file mode 100644 index bbd303c..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/PersonPage.razor +++ /dev/null @@ -1,89 +0,0 @@ -@using System.Text -@using WatchIt.Website.Components.Pages.PersonPage.Panels - -@page "/person/{id:long}" - -@{ - StringBuilder sb = new StringBuilder(" - WatchIt"); - - if (!_loaded) sb.Insert(0, "Loading..."); - else if (_person is null) sb.Insert(0, "Error"); - else sb.Insert(0, _person.Name); - - @(sb.ToString()) -} - - - -
- @if (_loaded) - { - if (_person is not null) - { -
-
- -
-
-
-
- -
-
- -
-
-
-
- - - Actor - Creator - - - -
- -
-
- -
- -
-
-
-
-
-
- } - else - { -
-
- -
-
- } - } - else - { -
-
-
- -
-
-
- } -
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/PersonPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/PersonPage.razor.cs deleted file mode 100644 index 29307ce..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/PersonPage.razor.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model.Persons; -using WatchIt.Website.Components.Pages.PersonPage.Panels; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Client.Persons; - -namespace WatchIt.Website.Pages; - -public partial class PersonPage : ComponentBase -{ - #region SERVICES - - [Inject] private IPersonsClientService PersonsClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [Parameter] public long Id { get; set; } - - [CascadingParameter] public MainLayout Layout { get; set; } = default!; - - #endregion - - - - #region FIELDS - - private bool _loaded; - - private PersonRatingPanel _ratingPanel = default!; - - private PersonResponse? _person; - - #endregion - - - - #region PRIVATE METHODS - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - // INIT - Layout.BackgroundPhoto = null; - - List step1Tasks = new List(1); - List endTasks = new List(1); - - // STEP 0 - step1Tasks.AddRange( - [ - PersonsClientService.GetPerson(Id, data => _person = data) - ]); - - // STEP 1 - await Task.WhenAll(step1Tasks); - if (_person is not null) - { - endTasks.AddRange( - [ - PersonsClientService.PostPersonView(Id), - ]); - } - - // END - await Task.WhenAll(endTasks); - - _loaded = true; - StateHasChanged(); - } - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor b/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor deleted file mode 100644 index afcbd75..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor +++ /dev/null @@ -1,68 +0,0 @@ -@using System.Net -@using WatchIt.Common.Model.Movies -@using WatchIt.Common.Model.Persons -@using WatchIt.Common.Model.Series -@using WatchIt.Website.Components.Pages.SearchPage.Panels - -@layout MainLayout - -@page "/search/{query}" - -WatchIt - Searching "@(Query)" - - - -
-
-
-

- Search results for phrase: "@(WebUtility.UrlDecode(Query))" -

-
-
- - - - -
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor.cs deleted file mode 100644 index baaef95..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Net; -using Microsoft.AspNetCore.Components; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Movies; -using WatchIt.Website.Services.Client.Persons; -using WatchIt.Website.Services.Client.Series; - -namespace WatchIt.Website.Pages; - -public partial class SearchPage : ComponentBase -{ - #region SERVICES - - [Inject] private IMoviesClientService MoviesClientService { get; set; } = default!; - [Inject] private ISeriesClientService SeriesClientService { get; set; } = default!; - [Inject] private IMediaClientService MediaClientService { get; set; } = default!; - [Inject] private IPersonsClientService PersonsClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [Parameter] public string Query { get; set; } - - [CascadingParameter] public MainLayout Layout { get; set; } - - #endregion - - - - #region PROPERTIES - - public string DecodedQuery => WebUtility.UrlDecode(Query); - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/UserEditPage.razor b/WatchIt.Website/WatchIt.Website/Pages/UserEditPage.razor deleted file mode 100644 index 1ef2c1b..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/UserEditPage.razor +++ /dev/null @@ -1,93 +0,0 @@ -@using System.Text -@using WatchIt.Common.Model -@using WatchIt.Common.Model.Photos -@using WatchIt.Website.Components.Pages.UserEditPage.Panels - - -@page "/user/edit" - -@{ - StringBuilder sb = new StringBuilder(" - WatchIt"); - - if (_accountData is null) sb.Insert(0, "Loading..."); - else sb.Insert(0, "User settings"); - - @(sb.ToString()) -} - - - -
- @if (_accountData is not null) - { -
-
- -
-
-
-
- - - Profile - Account - - - -
-
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
-
-
- -
- - - - -
-
-
-
-
-
- } - else - { -
-
-
- -
-
-
- } -
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/UserEditPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/UserEditPage.razor.cs deleted file mode 100644 index cb179b4..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/UserEditPage.razor.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System.Net; -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model; -using WatchIt.Common.Model.Accounts; -using WatchIt.Common.Model.Photos; -using WatchIt.Website.Components.Pages.UserEditPage.Panels; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Authentication; -using WatchIt.Website.Services.Client.Accounts; - -namespace WatchIt.Website.Pages; - -public partial class UserEditPage : ComponentBase -{ - #region SERVICES - - [Inject] private NavigationManager NavigationManager { get; set; } = default!; - [Inject] private IAuthenticationService AuthenticationService { get; set; } = default!; - [Inject] private IAccountsClientService AccountsClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [CascadingParameter] public MainLayout Layout { get; set; } = default!; - - #endregion - - - - #region FIELDS - - private AccountResponse? _accountData; - - private UserEditPageHeaderPanelComponent _header = default!; - - #endregion - - - - #region PRIVATE METHODS - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - Layout.BackgroundPhoto = null; - - User? user = await AuthenticationService.GetUserAsync(); - if (user is null) - { - NavigationManager.NavigateTo($"/auth?redirect_to={WebUtility.UrlEncode("/user/edit")}"); - return; - } - StateHasChanged(); - - await Task.WhenAll( - [ - AccountsClientService.GetAccount(user.Id, data => _accountData = data), - AccountsClientService.GetAccountProfileBackground(user.Id, data => Layout.BackgroundPhoto = data) - ]); - StateHasChanged(); - } - } - - private async Task PictureChanged() => await Task.WhenAll( - [ - _header.ReloadPicture(), - Layout.ReloadProfilePicture() - ]); - - private void BackgroundChanged(PhotoResponse? background) - { - Layout.BackgroundPhoto = background; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor deleted file mode 100644 index 722e501..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor +++ /dev/null @@ -1,184 +0,0 @@ -@using System.Text -@using WatchIt.Common.Model.Movies -@using WatchIt.Common.Model.Persons -@using WatchIt.Common.Model.Series -@using WatchIt.Website.Components.Pages.UserPage.Panels -@using WatchIt.Website.Components.Common.ListComponent -@using WatchIt.Website.Components.Pages.UserPage.Subcomponents -@using WatchIt.Website.Services.Client.Persons - -@page "/user/{id:long?}" - -@{ - StringBuilder sb = new StringBuilder(" - WatchIt"); - - if (!_loaded) sb.Insert(0, "Loading..."); - else if (_accountData is null) sb.Insert(0, "Error"); - else - { - if (_owner) sb.Insert(0, "Your profile"); - else sb.Insert(0, $"\"{_accountData.Username}\" profile"); - } - - @(sb.ToString()) -} - - - -
- @if (!_loaded) - { -
-
-
- -
-
-
- } - else if (_accountData is null) - { -
-
- -
-
- } - else - { -
-
- -
-
-
-
- - - Summary - Movies - TV Series - People - - - -
- - - -
-
- -
- - - -
-
- -
- - - -
-
- -
- - - -
-
-
-
-
-
- } -
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs deleted file mode 100644 index 41cec0a..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Net; -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model.Accounts; -using WatchIt.Website.Layout; -using WatchIt.Website.Services.Authentication; -using WatchIt.Website.Services.Client.Accounts; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Persons; - -namespace WatchIt.Website.Pages; - -public partial class UserPage : ComponentBase -{ - #region SERVICES - - [Inject] private NavigationManager NavigationManager { get; set; } = default!; - [Inject] private IAuthenticationService AuthenticationService { get; set; } = default!; - [Inject] private IAccountsClientService AccountsClientService { get; set; } = default!; - [Inject] private IMediaClientService MediaClientService { get; set; } = default!; - [Inject] private IPersonsClientService PersonsClientService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - [Parameter] public long? Id { get; set; } - - [CascadingParameter] public MainLayout Layout { get; set; } = default!; - - #endregion - - - - #region FIELDS - - private bool _loaded; - private bool _redirection; - private bool _owner; - private AccountResponse? _accountData; - - #endregion - - - - #region PRIVATE METHODS - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - List step1Tasks = new List(); - List endTasks = new List(); - - // INIT - Layout.BackgroundPhoto = null; - - // STEP 0 - step1Tasks.AddRange( - [ - GetUserData() - ]); - - // STEP 1 - await Task.WhenAll(step1Tasks); - endTasks.AddRange( - [ - AccountsClientService.GetAccountProfileBackground(_accountData.Id, data => Layout.BackgroundPhoto = data) - ]); - - // END - await Task.WhenAll(endTasks); - - _loaded = !_redirection; - StateHasChanged(); - } - } - - private async Task GetUserData() - { - User? user = await AuthenticationService.GetUserAsync(); - if (!Id.HasValue) - { - if (user is null) - { - NavigationManager.NavigateTo($"/auth?redirect_to={WebUtility.UrlEncode("/user")}"); - _redirection = true; - return; - } - Id = user.Id; - } - - await AccountsClientService.GetAccount(Id.Value, data => _accountData = data); - _owner = Id.Value == user?.Id; - } - - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Program.cs b/WatchIt.Website/WatchIt.Website/Program.cs deleted file mode 100644 index fe0c437..0000000 --- a/WatchIt.Website/WatchIt.Website/Program.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Blazorise; -using Blazorise.Bootstrap5; -using Blazorise.Icons.FontAwesome; -using Microsoft.AspNetCore.Components.Authorization; -using WatchIt.Common.Services.HttpClient; -using WatchIt.Website.Services.Authentication; -using WatchIt.Website.Services.Configuration; -using WatchIt.Website.Services.Tokens; -using WatchIt.Website.Services.Client.Accounts; -using WatchIt.Website.Services.Client.Genders; -using WatchIt.Website.Services.Client.Media; -using WatchIt.Website.Services.Client.Movies; -using WatchIt.Website.Services.Client.Persons; -using WatchIt.Website.Services.Client.Photos; -using WatchIt.Website.Services.Client.Roles; -using WatchIt.Website.Services.Client.Series; - -namespace WatchIt.Website; - -public static class Program -{ - #region PUBLIC METHODS - - public static void Main(string[] args) - { - WebApplication app = WebApplication.CreateBuilder(args) - .SetupServices() - .SetupAuthentication() - .SetupApplication() - .Build(); - - // Configure the HTTP request pipeline. - if (!app.Environment.IsDevelopment()) - { - app.UseExceptionHandler("/Error"); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - app.UseHttpsRedirection(); - - app.UseStaticFiles(); - app.UseAntiforgery(); - - app.MapRazorComponents() - .AddInteractiveServerRenderMode(); - - app.Run(); - } - - #endregion - - - - #region PRIVATE METHODS - - private static WebApplicationBuilder SetupServices(this WebApplicationBuilder builder) - { - builder.Services.AddSingleton(); - builder.Services.AddBlazorise(options => - { - options.Immediate = true; - }) - .AddBootstrap5Providers() - .AddFontAwesomeIcons(); - - // Utility - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - // WebAPI - builder.Services.AddScoped(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - - return builder; - } - - private static WebApplicationBuilder SetupAuthentication(this WebApplicationBuilder builder) - { - builder.Services.AddAuthorizationCore(); - builder.Services.AddScoped(); - - return builder; - } - - private static WebApplicationBuilder SetupApplication(this WebApplicationBuilder builder) - { - builder.Services.AddRazorComponents() - .AddInteractiveServerComponents(); - return builder; - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Properties/launchSettings.json b/WatchIt.Website/WatchIt.Website/Properties/launchSettings.json deleted file mode 100644 index 33d2d6c..0000000 --- a/WatchIt.Website/WatchIt.Website/Properties/launchSettings.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:44254", - "sslPort": 44356 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "http://localhost:5209", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "https://localhost:7111;http://localhost:5209", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } - } diff --git a/WatchIt.Website/WatchIt.Website/WatchIt.Website.csproj b/WatchIt.Website/WatchIt.Website/WatchIt.Website.csproj deleted file mode 100644 index d473aa5..0000000 --- a/WatchIt.Website/WatchIt.Website/WatchIt.Website.csproj +++ /dev/null @@ -1,50 +0,0 @@ - - - - net8.0 - enable - enable - Linux - - - - - .dockerignore - - - - - - - - - - - - <_ContentIncludedByDefault Remove="Components\Layout\EmptyLayout.razor" /> - <_ContentIncludedByDefault Remove="Components\Layout\MainLayout.razor" /> - <_ContentIncludedByDefault Remove="Components\Pages\Counter.razor" /> - <_ContentIncludedByDefault Remove="Components\Pages\Error.razor" /> - <_ContentIncludedByDefault Remove="Components\Pages\Home.razor" /> - <_ContentIncludedByDefault Remove="Components\Pages\Weather.razor" /> - <_ContentIncludedByDefault Remove="wwwroot\bootstrap\bootstrap.min.css" /> - <_ContentIncludedByDefault Remove="wwwroot\bootstrap\bootstrap.min.css.map" /> - <_ContentIncludedByDefault Remove="wwwroot\scripts\popper.min.js" /> - - - - - - - - - - - - - - - - - - diff --git a/WatchIt.Website/WatchIt.Website/_Imports.razor b/WatchIt.Website/WatchIt.Website/_Imports.razor deleted file mode 100644 index a1fd28e..0000000 --- a/WatchIt.Website/WatchIt.Website/_Imports.razor +++ /dev/null @@ -1,20 +0,0 @@ -@using System.Net.Http -@using System.Net.Http.Json -@using Microsoft.AspNetCore.Components.Forms -@using Microsoft.AspNetCore.Components.Routing -@using Microsoft.AspNetCore.Components.Web -@using static Microsoft.AspNetCore.Components.Web.RenderMode -@using Microsoft.AspNetCore.Components.Web.Virtualization -@using Microsoft.JSInterop -@using WatchIt.Website -@using WatchIt.Website.Layout -@using WatchIt.Website.Components.Common.Subcomponents -@using WatchIt.Website.Components.Common.Panels -@using WatchIt.Common.Model.Accounts -@using WatchIt.Common.Model.Media -@using WatchIt.Website.Services.Tokens -@using WatchIt.Website.Services.Authentication -@using WatchIt.Website.Services.Client.Accounts -@using WatchIt.Website.Services.Client.Media -@using Blazorise -@using Blazorise.Bootstrap5 \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/appsettings.json b/WatchIt.Website/WatchIt.Website/appsettings.json deleted file mode 100644 index 9f2429a..0000000 --- a/WatchIt.Website/WatchIt.Website/appsettings.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "StorageKeys": { - "AccessToken": "access_token", - "RefreshToken": "refresh_token" - }, - "Style": { - "DefaultPanelPadding": 4 - }, - "Endpoints": { - "Base": "https://localhost:7160", - "Accounts": { - "Base": "/accounts", - "Register": "/register", - "Authenticate": "/authenticate", - "AuthenticateRefresh": "/authenticate_refresh", - "Logout": "/logout", - "GetAccountProfilePicture": "/{0}/profile_picture", - "PutAccountProfilePicture": "/profile_picture", - "DeleteAccountProfilePicture": "/profile_picture", - "GetAccountProfileBackground": "/{0}/profile_background", - "PutAccountProfileBackground": "/profile_background", - "DeleteAccountProfileBackground": "/profile_background", - "GetAccounts": "", - "GetAccount": "/{0}", - "PutAccountProfileInfo": "/profile_info", - "PatchAccountUsername": "/username", - "PatchAccountEmail": "/email", - "PatchAccountPassword": "/password", - "GetAccountRatedMovies": "/{0}/movies", - "GetAccountRatedSeries": "/{0}/series", - "GetAccountRatedPersons": "/{0}/persons" - }, - "Genders": { - "Base": "/genders", - "GetAllGenders": "", - "GetGender": "/{0}", - "PostGender": "", - "DeleteGender": "/{0}" - }, - "Genres": { - "Base": "/genres", - "GetAll": "", - "Get": "/{0}", - "Post": "", - "Put": "/{0}", - "Delete": "/{0}" - }, - "Media": { - "Base": "/media", - "GetAllMedia": "", - "GetMedia": "/{0}", - "GetMediaGenres": "/{0}/genres", - "PostMediaGenre": "/{0}/genres/{1}", - "DeleteMediaGenre": "/{0}/genres/{1}", - "GetMediaRating": "/{0}/rating", - "GetMediaRatingByUser": "/{0}/rating/{1}", - "PutMediaRating": "/{0}/rating", - "DeleteMediaRating": "/{0}/rating", - "PostMediaView": "/{0}/view", - "GetMediaPoster": "/{0}/poster", - "PutMediaPoster": "/{0}/poster", - "DeleteMediaPoster": "/{0}/poster", - "GetMediaPhotos": "/{0}/photos", - "GetMediaPhotoRandomBackground": "/{0}/photos/random_background", - "PostMediaPhoto": "/{0}/photos", - "GetMediaAllActorRoles": "/{0}/roles/actor", - "PostMediaActorRole": "/{0}/roles/actor", - "GetMediaAllCreatorRoles": "/{0}/roles/creator", - "PostMediaCreatorRole": "/{0}/roles/creator" - }, - "Movies": { - "Base": "/movies", - "GetAllMovies": "", - "GetMovie": "/{0}", - "PostMovie": "", - "PutMovie": "/{0}", - "DeleteMovie": "/{0}", - "GetMoviesViewRank": "/view" - }, - "Series": { - "Base": "/series", - "GetAllSeries": "", - "GetSeries": "/{0}", - "PostSeries": "", - "PutSeries": "/{0}", - "DeleteSeries": "/{0}", - "GetSeriesViewRank": "/view" - }, - "Photos": { - "Base": "/photos", - "GetPhotoRandomBackground": "/random_background", - "DeletePhoto": "/{0}", - "PutPhotoBackgroundData": "/{0}/background_data", - "DeletePhotoBackgroundData": "/{0}/background_data" - }, - "Persons": { - "Base": "/persons", - "GetAllPersons": "", - "GetPerson": "/{0}", - "PostPerson": "", - "PutPerson": "/{0}", - "DeletePerson": "/{0}", - "GetPersonsViewRank": "/view", - "PostPersonsView": "/{0}/view", - "GetPersonPhoto": "/{0}/photo", - "PutPersonPhoto": "/{0}/photo", - "DeletePersonPhoto": "/{0}/photo", - "GetPersonAllActorRoles": "/{0}/roles/actor", - "PostPersonActorRole": "/{0}/roles/actor", - "GetPersonAllCreatorRoles": "/{0}/roles/creator", - "PostPersonCreatorRole": "/{0}/roles/creator", - "GetPersonGlobalRating": "/{0}/rating", - "GetPersonUserRating": "/{0}/rating/{1}" - }, - "Roles": { - "Base": "/roles", - "GetActorRole": "/actor/{0}", - "PutActorRole": "/actor/{0}", - "DeleteActorRole": "/actor/{0}", - "GetActorRoleRating": "/actor/{0}/rating", - "GetActorRoleRatingByUser": "/actor/{0}/rating/{1}", - "PutActorRoleRating": "/actor/{0}/rating", - "DeleteActorRoleRating": "/actor/{0}/rating", - "GetAllActorRoleTypes": "/actor/type", - "GetActorRoleType": "/actor/type/{0}", - "PostActorRoleType": "/actor/type", - "DeleteActorRoleType": "/actor/type/{0}", - "GetCreatorRole": "/creator/{0}", - "PutCreatorRole": "/creator/{0}", - "DeleteCreatorRole": "/creator/{0}", - "GetCreatorRoleRating": "/creator/{0}/rating", - "GetCreatorRoleRatingByUser": "/creator/{0}/rating/{1}", - "PutCreatorRoleRating": "/creator/{0}/rating", - "DeleteCreatorRoleRating": "/creator/{0}/rating", - "GetAllCreatorRoleTypes": "/creator/type", - "GetCreatorRoleType": "/creator/type/{0}", - "PostCreatorRoleType": "/creator/type", - "DeleteCreatorRoleType": "/creator/type/{0}" - } - } -} diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-Bold.ttf b/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-Bold.ttf deleted file mode 100644 index 9e2bdb9..0000000 Binary files a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-Bold.ttf and /dev/null differ diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-Regular.ttf b/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-Regular.ttf deleted file mode 100644 index 2a0f189..0000000 Binary files a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-Regular.ttf and /dev/null differ diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-SemiBold.ttf b/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-SemiBold.ttf deleted file mode 100644 index 317f0a8..0000000 Binary files a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/Belanosima-SemiBold.ttf and /dev/null differ diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/OpenSans-Italic.ttf b/WatchIt.Website/WatchIt.Website/wwwroot/fonts/OpenSans-Italic.ttf deleted file mode 100644 index 8312b2c..0000000 Binary files a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/OpenSans-Italic.ttf and /dev/null differ diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/OpenSans-Regular.ttf b/WatchIt.Website/WatchIt.Website/wwwroot/fonts/OpenSans-Regular.ttf deleted file mode 100644 index ac587b4..0000000 Binary files a/WatchIt.Website/WatchIt.Website/wwwroot/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/WatchIt.Website/appsettings.json b/WatchIt.Website/appsettings.json new file mode 100644 index 0000000..612ecf5 --- /dev/null +++ b/WatchIt.Website/appsettings.json @@ -0,0 +1,18 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Clients": { + "BaseAddress": "https://localhost:7027" + }, + "Tokens": { + "StorageKeys": { + "AccessToken": "access_token", + "RefreshToken": "refresh_token" + } + } +} diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/icons/background.png b/WatchIt.Website/wwwroot/assets/icons/background.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/icons/background.png rename to WatchIt.Website/wwwroot/assets/icons/background.png diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/icons/cancel.png b/WatchIt.Website/wwwroot/assets/icons/cancel.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/icons/cancel.png rename to WatchIt.Website/wwwroot/assets/icons/cancel.png diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/icons/delete.png b/WatchIt.Website/wwwroot/assets/icons/delete.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/icons/delete.png rename to WatchIt.Website/wwwroot/assets/icons/delete.png diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/icons/edit.png b/WatchIt.Website/wwwroot/assets/icons/edit.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/icons/edit.png rename to WatchIt.Website/wwwroot/assets/icons/edit.png diff --git a/WatchIt.Website/wwwroot/assets/icons/movie.png b/WatchIt.Website/wwwroot/assets/icons/movie.png new file mode 100644 index 0000000..2633cd2 Binary files /dev/null and b/WatchIt.Website/wwwroot/assets/icons/movie.png differ diff --git a/WatchIt.Website/wwwroot/assets/icons/person.png b/WatchIt.Website/wwwroot/assets/icons/person.png new file mode 100644 index 0000000..a0a0eb6 Binary files /dev/null and b/WatchIt.Website/wwwroot/assets/icons/person.png differ diff --git a/WatchIt.Website/wwwroot/assets/icons/series.png b/WatchIt.Website/wwwroot/assets/icons/series.png new file mode 100644 index 0000000..3b95346 Binary files /dev/null and b/WatchIt.Website/wwwroot/assets/icons/series.png differ diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/background_temp.jpg b/WatchIt.Website/wwwroot/assets/placeholders/background.jpg similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/background_temp.jpg rename to WatchIt.Website/wwwroot/assets/placeholders/background.jpg diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/media_poster.png b/WatchIt.Website/wwwroot/assets/placeholders/medium.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/media_poster.png rename to WatchIt.Website/wwwroot/assets/placeholders/medium.png diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/person_poster.png b/WatchIt.Website/wwwroot/assets/placeholders/person.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/person_poster.png rename to WatchIt.Website/wwwroot/assets/placeholders/person.png diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/photo.png b/WatchIt.Website/wwwroot/assets/placeholders/photo.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/photo.png rename to WatchIt.Website/wwwroot/assets/placeholders/photo.png diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/assets/user_placeholder.png b/WatchIt.Website/wwwroot/assets/placeholders/user.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/assets/user_placeholder.png rename to WatchIt.Website/wwwroot/assets/placeholders/user.png diff --git a/WatchIt.Website/wwwroot/css/blazor.css b/WatchIt.Website/wwwroot/css/blazor.css new file mode 100644 index 0000000..e54740a --- /dev/null +++ b/WatchIt.Website/wwwroot/css/blazor.css @@ -0,0 +1,64 @@ +a, .btn-link { + color: #006bb7; +} + +.btn-primary { + color: #fff; + background-color: #1b6ec2; + border-color: #1861ac; +} + +.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { + box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; +} + +.content { + padding-top: 1.1rem; +} + +h1:focus { + outline: none; +} + +.valid.modified:not([type=checkbox]) { + outline: 1px solid #26b050; +} + +.invalid { + outline: 1px solid #e50000; +} + +.validation-message { + color: #e50000; +} + +.blazor-error-boundary { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; + padding: 1rem 1rem 1rem 3.7rem; + color: #2b2b2b; +} + +.blazor-error-boundary::after { + content: "An error has occurred." +} + +.darker-border-checkbox.form-check-input { + border-color: #929292; +} + +.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { + color: var(--bs-secondary-color); + text-align: end; +} + +.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { + text-align: start; +} + +.components-reconnect-dialog { + background-color: rgba(0, 0, 0, 0.8) !important; +} + +.snackbar { + border-radius: 1.5rem !important; +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/css/gaps.css b/WatchIt.Website/wwwroot/css/gaps.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/css/gaps.css rename to WatchIt.Website/wwwroot/css/gaps.css diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/css/general.css b/WatchIt.Website/wwwroot/css/general.css similarity index 91% rename from WatchIt.Website/WatchIt.Website/wwwroot/css/general.css rename to WatchIt.Website/wwwroot/css/general.css index 319ee59..1c29330 100644 --- a/WatchIt.Website/WatchIt.Website/wwwroot/css/general.css +++ b/WatchIt.Website/wwwroot/css/general.css @@ -14,15 +14,12 @@ body { } body, html { - background-color: transparent; - - height: 100%; margin: 0; padding: 0; color: lightgray; - font-family: "PT Sans"; + font-family: "PT Sans", serif !important; } @@ -66,6 +63,11 @@ body, html { gap: 1rem; } +.metadata-pill-hoverable:hover { + background-color: gray; + color: black; +} + diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/css/main_button.css b/WatchIt.Website/wwwroot/css/main_button.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/css/main_button.css rename to WatchIt.Website/wwwroot/css/main_button.css diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/css/panel.css b/WatchIt.Website/wwwroot/css/panel.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/css/panel.css rename to WatchIt.Website/wwwroot/css/panel.css diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/favicon.png b/WatchIt.Website/wwwroot/favicon.png similarity index 100% rename from WatchIt.Website/WatchIt.Website/wwwroot/favicon.png rename to WatchIt.Website/wwwroot/favicon.png diff --git a/WatchIt.sln b/WatchIt.sln index 99c5e6d..8be1f29 100644 --- a/WatchIt.sln +++ b/WatchIt.sln @@ -1,82 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.Common", "WatchIt.Common", "{0EDF709C-99F4-3EE5-9136-4C92A768A3F8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI", "WatchIt.WebAPI\WatchIt.WebAPI.csproj", "{F25028D4-80E7-45B7-A627-403A90A817EA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Common.Model", "WatchIt.Common\WatchIt.Common.Model\WatchIt.Common.Model.csproj", "{F9E593F3-49A5-3F24-D468-932375E9971D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Website", "WatchIt.Website\WatchIt.Website.csproj", "{BD3CFA1A-4ABC-4680-8830-5C43EF269AA6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Common.Query", "WatchIt.Common\WatchIt.Common.Query\WatchIt.Common.Query.csproj", "{5E9025E1-41C3-A27B-99BE-5AAB5CF7EE27}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Database", "WatchIt.Database\WatchIt.Database.csproj", "{2B472CBA-26F3-4519-99D7-366C48B025D9}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.Common.Services", "WatchIt.Common.Services", "{DC2B5349-B77C-59FD-0E4D-E6749FACB96D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Common.Services.HttpClient", "WatchIt.Common\WatchIt.Common.Services\WatchIt.Common.Services.HttpClient\WatchIt.Common.Services.HttpClient.csproj", "{BCD06E73-4DF3-68A2-1A5A-F4870D5AEF84}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.Database", "WatchIt.Database", "{227CC20A-F08E-180E-2EE3-ADA5DB2A8891}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Database", "WatchIt.Database\WatchIt.Database\WatchIt.Database.csproj", "{B045DE15-B896-BB0E-3D0A-F2B55D2704FF}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.Database.Model", "WatchIt.Database.Model", "{90A007E0-353E-9587-79F1-149A51AEA943}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Database.Model.Configuration", "WatchIt.Database\WatchIt.Database.Model\WatchIt.Database.Model.Configuration\WatchIt.Database.Model.Configuration.csproj", "{C046FE28-DA43-139C-BA9E-289844A7CC9A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Database.Model.Seeding", "WatchIt.Database\WatchIt.Database.Model\WatchIt.Database.Model.Seeding\WatchIt.Database.Model.Seeding.csproj", "{3E2F07F5-838A-6141-5B48-D879F2B645E0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Database.Model", "WatchIt.Database\WatchIt.Database.Model\WatchIt.Database.Model\WatchIt.Database.Model.csproj", "{8B33B44E-0245-511C-C2AD-D47E6153670D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.WebAPI", "WatchIt.WebAPI", "{580BCC26-D6F3-27C7-CD4B-4CDBB56CF3A3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Controllers", "WatchIt.WebAPI\WatchIt.WebAPI.Controllers\WatchIt.WebAPI.Controllers.csproj", "{1E179F33-2D2F-752B-4AE6-5C72B29B4123}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Validators", "WatchIt.WebAPI\WatchIt.WebAPI.Validators\WatchIt.WebAPI.Validators.csproj", "{AD58457B-9326-03B8-5831-ED515464503A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.WorkerServices", "WatchIt.WebAPI\WatchIt.WebAPI.WorkerServices\WatchIt.WebAPI.WorkerServices.csproj", "{0F30275E-5CE6-D2A6-4D2C-01B0ECF8EC3C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI", "WatchIt.WebAPI\WatchIt.WebAPI\WatchIt.WebAPI.csproj", "{935F490B-5A14-87EA-A6F7-C808E8233619}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.WebAPI.Services", "WatchIt.WebAPI.Services", "{57D9D146-511A-42D7-C1C5-0D18D3E1ADAF}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.WebAPI.Services.Controllers", "WatchIt.WebAPI.Services.Controllers", "{8D8C51C4-760C-9908-3CE3-2A00341BA9B3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Accounts", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Accounts\WatchIt.WebAPI.Services.Controllers.Accounts.csproj", "{3C42534E-57D6-1270-FD53-1F85E7D1B136}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Common", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Common\WatchIt.WebAPI.Services.Controllers.Common.csproj", "{5D9EB880-7F26-85D2-0606-FFBA669CA8FB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Genders", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Genders\WatchIt.WebAPI.Services.Controllers.Genders.csproj", "{195DE0A1-20F2-DE84-330E-64EF72C116A1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Genres", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Genres\WatchIt.WebAPI.Services.Controllers.Genres.csproj", "{B400518F-D1EE-66BF-31C8-033E502F04C2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Media", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Media\WatchIt.WebAPI.Services.Controllers.Media.csproj", "{F5813724-3299-71CB-B219-1133BFB3CE49}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Movies", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Movies\WatchIt.WebAPI.Services.Controllers.Movies.csproj", "{CE807E91-B0E6-0E34-4842-4BCD74C15A71}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Persons", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Persons\WatchIt.WebAPI.Services.Controllers.Persons.csproj", "{F4521C82-C834-1392-313E-A23DD3C91379}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Photos", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Photos\WatchIt.WebAPI.Services.Controllers.Photos.csproj", "{3103A43A-694B-46B4-904D-84FCBAB3DDBE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Roles", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Roles\WatchIt.WebAPI.Services.Controllers.Roles.csproj", "{F6AAC506-626B-A519-AAA9-DED4C1511B7D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Controllers.Series", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Controllers\WatchIt.WebAPI.Services.Controllers.Series\WatchIt.WebAPI.Services.Controllers.Series.csproj", "{5FB4B0AA-09A7-11A8-D45F-73946CBDF400}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.WebAPI.Services.Utility", "WatchIt.WebAPI.Services.Utility", "{0D7F6705-9114-1C0D-61F6-E76D43BBFD95}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Utility.Configuration", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Utility\WatchIt.WebAPI.Services.Utility.Configuration\WatchIt.WebAPI.Services.Utility.Configuration.csproj", "{654F560F-B171-9B66-30C2-FA728CB812E1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Utility.Tokens", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Utility\WatchIt.WebAPI.Services.Utility.Tokens\WatchIt.WebAPI.Services.Utility.Tokens.csproj", "{115E0CB8-501B-F73A-B4E5-343DC9C0FC93}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.WebAPI.Services.Utility.User", "WatchIt.WebAPI\WatchIt.WebAPI.Services\WatchIt.WebAPI.Services.Utility\WatchIt.WebAPI.Services.Utility.User\WatchIt.WebAPI.Services.Utility.User.csproj", "{872394DD-5F95-2FD2-E30D-7E2B021F055B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.Website", "WatchIt.Website", "{A476FF40-6AD9-F237-094D-BC9CD170091F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Website", "WatchIt.Website\WatchIt.Website\WatchIt.Website.csproj", "{53AB0957-9473-8422-8FB2-2611339FAACC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WatchIt.Website.Services", "WatchIt.Website.Services", "{AE403159-2725-6961-6E01-1CB0FBD8C1DF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Website.Services.Authentication", "WatchIt.Website\WatchIt.Website.Services\WatchIt.Website.Services.Authentication\WatchIt.Website.Services.Authentication.csproj", "{27B65069-12AD-68A4-238F-58FA84F24813}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Website.Services.Client", "WatchIt.Website\WatchIt.Website.Services\WatchIt.Website.Services.Client\WatchIt.Website.Services.Client.csproj", "{F176F958-3A95-DDBC-8036-2B7E49B3254E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Website.Services.Configuration", "WatchIt.Website\WatchIt.Website.Services\WatchIt.Website.Services.Configuration\WatchIt.Website.Services.Configuration.csproj", "{979B1DA2-CEA0-95C6-3E85-9329D28A41D1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.Website.Services.Tokens", "WatchIt.Website\WatchIt.Website.Services\WatchIt.Website.Services.Tokens\WatchIt.Website.Services.Tokens.csproj", "{95A0DC72-B175-3174-5EE2-F1E3473DE428}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchIt.DTO", "WatchIt.DTO\WatchIt.DTO.csproj", "{07251172-E0EA-49DC-8BDE-488C0103006E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -84,158 +14,23 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F9E593F3-49A5-3F24-D468-932375E9971D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F9E593F3-49A5-3F24-D468-932375E9971D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F9E593F3-49A5-3F24-D468-932375E9971D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F9E593F3-49A5-3F24-D468-932375E9971D}.Release|Any CPU.Build.0 = Release|Any CPU - {5E9025E1-41C3-A27B-99BE-5AAB5CF7EE27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5E9025E1-41C3-A27B-99BE-5AAB5CF7EE27}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5E9025E1-41C3-A27B-99BE-5AAB5CF7EE27}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5E9025E1-41C3-A27B-99BE-5AAB5CF7EE27}.Release|Any CPU.Build.0 = Release|Any CPU - {BCD06E73-4DF3-68A2-1A5A-F4870D5AEF84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BCD06E73-4DF3-68A2-1A5A-F4870D5AEF84}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BCD06E73-4DF3-68A2-1A5A-F4870D5AEF84}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BCD06E73-4DF3-68A2-1A5A-F4870D5AEF84}.Release|Any CPU.Build.0 = Release|Any CPU - {B045DE15-B896-BB0E-3D0A-F2B55D2704FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B045DE15-B896-BB0E-3D0A-F2B55D2704FF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B045DE15-B896-BB0E-3D0A-F2B55D2704FF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B045DE15-B896-BB0E-3D0A-F2B55D2704FF}.Release|Any CPU.Build.0 = Release|Any CPU - {C046FE28-DA43-139C-BA9E-289844A7CC9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C046FE28-DA43-139C-BA9E-289844A7CC9A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C046FE28-DA43-139C-BA9E-289844A7CC9A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C046FE28-DA43-139C-BA9E-289844A7CC9A}.Release|Any CPU.Build.0 = Release|Any CPU - {3E2F07F5-838A-6141-5B48-D879F2B645E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E2F07F5-838A-6141-5B48-D879F2B645E0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E2F07F5-838A-6141-5B48-D879F2B645E0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E2F07F5-838A-6141-5B48-D879F2B645E0}.Release|Any CPU.Build.0 = Release|Any CPU - {8B33B44E-0245-511C-C2AD-D47E6153670D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8B33B44E-0245-511C-C2AD-D47E6153670D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8B33B44E-0245-511C-C2AD-D47E6153670D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8B33B44E-0245-511C-C2AD-D47E6153670D}.Release|Any CPU.Build.0 = Release|Any CPU - {1E179F33-2D2F-752B-4AE6-5C72B29B4123}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1E179F33-2D2F-752B-4AE6-5C72B29B4123}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1E179F33-2D2F-752B-4AE6-5C72B29B4123}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1E179F33-2D2F-752B-4AE6-5C72B29B4123}.Release|Any CPU.Build.0 = Release|Any CPU - {AD58457B-9326-03B8-5831-ED515464503A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD58457B-9326-03B8-5831-ED515464503A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD58457B-9326-03B8-5831-ED515464503A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD58457B-9326-03B8-5831-ED515464503A}.Release|Any CPU.Build.0 = Release|Any CPU - {0F30275E-5CE6-D2A6-4D2C-01B0ECF8EC3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0F30275E-5CE6-D2A6-4D2C-01B0ECF8EC3C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0F30275E-5CE6-D2A6-4D2C-01B0ECF8EC3C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0F30275E-5CE6-D2A6-4D2C-01B0ECF8EC3C}.Release|Any CPU.Build.0 = Release|Any CPU - {935F490B-5A14-87EA-A6F7-C808E8233619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {935F490B-5A14-87EA-A6F7-C808E8233619}.Debug|Any CPU.Build.0 = Debug|Any CPU - {935F490B-5A14-87EA-A6F7-C808E8233619}.Release|Any CPU.ActiveCfg = Release|Any CPU - {935F490B-5A14-87EA-A6F7-C808E8233619}.Release|Any CPU.Build.0 = Release|Any CPU - {3C42534E-57D6-1270-FD53-1F85E7D1B136}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3C42534E-57D6-1270-FD53-1F85E7D1B136}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3C42534E-57D6-1270-FD53-1F85E7D1B136}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3C42534E-57D6-1270-FD53-1F85E7D1B136}.Release|Any CPU.Build.0 = Release|Any CPU - {5D9EB880-7F26-85D2-0606-FFBA669CA8FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5D9EB880-7F26-85D2-0606-FFBA669CA8FB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D9EB880-7F26-85D2-0606-FFBA669CA8FB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5D9EB880-7F26-85D2-0606-FFBA669CA8FB}.Release|Any CPU.Build.0 = Release|Any CPU - {195DE0A1-20F2-DE84-330E-64EF72C116A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {195DE0A1-20F2-DE84-330E-64EF72C116A1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {195DE0A1-20F2-DE84-330E-64EF72C116A1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {195DE0A1-20F2-DE84-330E-64EF72C116A1}.Release|Any CPU.Build.0 = Release|Any CPU - {B400518F-D1EE-66BF-31C8-033E502F04C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B400518F-D1EE-66BF-31C8-033E502F04C2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B400518F-D1EE-66BF-31C8-033E502F04C2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B400518F-D1EE-66BF-31C8-033E502F04C2}.Release|Any CPU.Build.0 = Release|Any CPU - {F5813724-3299-71CB-B219-1133BFB3CE49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F5813724-3299-71CB-B219-1133BFB3CE49}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F5813724-3299-71CB-B219-1133BFB3CE49}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F5813724-3299-71CB-B219-1133BFB3CE49}.Release|Any CPU.Build.0 = Release|Any CPU - {CE807E91-B0E6-0E34-4842-4BCD74C15A71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CE807E91-B0E6-0E34-4842-4BCD74C15A71}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CE807E91-B0E6-0E34-4842-4BCD74C15A71}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CE807E91-B0E6-0E34-4842-4BCD74C15A71}.Release|Any CPU.Build.0 = Release|Any CPU - {F4521C82-C834-1392-313E-A23DD3C91379}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F4521C82-C834-1392-313E-A23DD3C91379}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F4521C82-C834-1392-313E-A23DD3C91379}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F4521C82-C834-1392-313E-A23DD3C91379}.Release|Any CPU.Build.0 = Release|Any CPU - {3103A43A-694B-46B4-904D-84FCBAB3DDBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3103A43A-694B-46B4-904D-84FCBAB3DDBE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3103A43A-694B-46B4-904D-84FCBAB3DDBE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3103A43A-694B-46B4-904D-84FCBAB3DDBE}.Release|Any CPU.Build.0 = Release|Any CPU - {F6AAC506-626B-A519-AAA9-DED4C1511B7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F6AAC506-626B-A519-AAA9-DED4C1511B7D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F6AAC506-626B-A519-AAA9-DED4C1511B7D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F6AAC506-626B-A519-AAA9-DED4C1511B7D}.Release|Any CPU.Build.0 = Release|Any CPU - {5FB4B0AA-09A7-11A8-D45F-73946CBDF400}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5FB4B0AA-09A7-11A8-D45F-73946CBDF400}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5FB4B0AA-09A7-11A8-D45F-73946CBDF400}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5FB4B0AA-09A7-11A8-D45F-73946CBDF400}.Release|Any CPU.Build.0 = Release|Any CPU - {654F560F-B171-9B66-30C2-FA728CB812E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {654F560F-B171-9B66-30C2-FA728CB812E1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {654F560F-B171-9B66-30C2-FA728CB812E1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {654F560F-B171-9B66-30C2-FA728CB812E1}.Release|Any CPU.Build.0 = Release|Any CPU - {115E0CB8-501B-F73A-B4E5-343DC9C0FC93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {115E0CB8-501B-F73A-B4E5-343DC9C0FC93}.Debug|Any CPU.Build.0 = Debug|Any CPU - {115E0CB8-501B-F73A-B4E5-343DC9C0FC93}.Release|Any CPU.ActiveCfg = Release|Any CPU - {115E0CB8-501B-F73A-B4E5-343DC9C0FC93}.Release|Any CPU.Build.0 = Release|Any CPU - {872394DD-5F95-2FD2-E30D-7E2B021F055B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {872394DD-5F95-2FD2-E30D-7E2B021F055B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {872394DD-5F95-2FD2-E30D-7E2B021F055B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {872394DD-5F95-2FD2-E30D-7E2B021F055B}.Release|Any CPU.Build.0 = Release|Any CPU - {53AB0957-9473-8422-8FB2-2611339FAACC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {53AB0957-9473-8422-8FB2-2611339FAACC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {53AB0957-9473-8422-8FB2-2611339FAACC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {53AB0957-9473-8422-8FB2-2611339FAACC}.Release|Any CPU.Build.0 = Release|Any CPU - {27B65069-12AD-68A4-238F-58FA84F24813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {27B65069-12AD-68A4-238F-58FA84F24813}.Debug|Any CPU.Build.0 = Debug|Any CPU - {27B65069-12AD-68A4-238F-58FA84F24813}.Release|Any CPU.ActiveCfg = Release|Any CPU - {27B65069-12AD-68A4-238F-58FA84F24813}.Release|Any CPU.Build.0 = Release|Any CPU - {F176F958-3A95-DDBC-8036-2B7E49B3254E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F176F958-3A95-DDBC-8036-2B7E49B3254E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F176F958-3A95-DDBC-8036-2B7E49B3254E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F176F958-3A95-DDBC-8036-2B7E49B3254E}.Release|Any CPU.Build.0 = Release|Any CPU - {979B1DA2-CEA0-95C6-3E85-9329D28A41D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {979B1DA2-CEA0-95C6-3E85-9329D28A41D1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {979B1DA2-CEA0-95C6-3E85-9329D28A41D1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {979B1DA2-CEA0-95C6-3E85-9329D28A41D1}.Release|Any CPU.Build.0 = Release|Any CPU - {95A0DC72-B175-3174-5EE2-F1E3473DE428}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {95A0DC72-B175-3174-5EE2-F1E3473DE428}.Debug|Any CPU.Build.0 = Debug|Any CPU - {95A0DC72-B175-3174-5EE2-F1E3473DE428}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95A0DC72-B175-3174-5EE2-F1E3473DE428}.Release|Any CPU.Build.0 = Release|Any CPU + {F25028D4-80E7-45B7-A627-403A90A817EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F25028D4-80E7-45B7-A627-403A90A817EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F25028D4-80E7-45B7-A627-403A90A817EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F25028D4-80E7-45B7-A627-403A90A817EA}.Release|Any CPU.Build.0 = Release|Any CPU + {BD3CFA1A-4ABC-4680-8830-5C43EF269AA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD3CFA1A-4ABC-4680-8830-5C43EF269AA6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD3CFA1A-4ABC-4680-8830-5C43EF269AA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD3CFA1A-4ABC-4680-8830-5C43EF269AA6}.Release|Any CPU.Build.0 = Release|Any CPU + {2B472CBA-26F3-4519-99D7-366C48B025D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B472CBA-26F3-4519-99D7-366C48B025D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B472CBA-26F3-4519-99D7-366C48B025D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B472CBA-26F3-4519-99D7-366C48B025D9}.Release|Any CPU.Build.0 = Release|Any CPU + {07251172-E0EA-49DC-8BDE-488C0103006E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07251172-E0EA-49DC-8BDE-488C0103006E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07251172-E0EA-49DC-8BDE-488C0103006E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07251172-E0EA-49DC-8BDE-488C0103006E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution - {F9E593F3-49A5-3F24-D468-932375E9971D} = {0EDF709C-99F4-3EE5-9136-4C92A768A3F8} - {5E9025E1-41C3-A27B-99BE-5AAB5CF7EE27} = {0EDF709C-99F4-3EE5-9136-4C92A768A3F8} - {DC2B5349-B77C-59FD-0E4D-E6749FACB96D} = {0EDF709C-99F4-3EE5-9136-4C92A768A3F8} - {BCD06E73-4DF3-68A2-1A5A-F4870D5AEF84} = {DC2B5349-B77C-59FD-0E4D-E6749FACB96D} - {B045DE15-B896-BB0E-3D0A-F2B55D2704FF} = {227CC20A-F08E-180E-2EE3-ADA5DB2A8891} - {90A007E0-353E-9587-79F1-149A51AEA943} = {227CC20A-F08E-180E-2EE3-ADA5DB2A8891} - {C046FE28-DA43-139C-BA9E-289844A7CC9A} = {90A007E0-353E-9587-79F1-149A51AEA943} - {3E2F07F5-838A-6141-5B48-D879F2B645E0} = {90A007E0-353E-9587-79F1-149A51AEA943} - {8B33B44E-0245-511C-C2AD-D47E6153670D} = {90A007E0-353E-9587-79F1-149A51AEA943} - {1E179F33-2D2F-752B-4AE6-5C72B29B4123} = {580BCC26-D6F3-27C7-CD4B-4CDBB56CF3A3} - {AD58457B-9326-03B8-5831-ED515464503A} = {580BCC26-D6F3-27C7-CD4B-4CDBB56CF3A3} - {0F30275E-5CE6-D2A6-4D2C-01B0ECF8EC3C} = {580BCC26-D6F3-27C7-CD4B-4CDBB56CF3A3} - {935F490B-5A14-87EA-A6F7-C808E8233619} = {580BCC26-D6F3-27C7-CD4B-4CDBB56CF3A3} - {57D9D146-511A-42D7-C1C5-0D18D3E1ADAF} = {580BCC26-D6F3-27C7-CD4B-4CDBB56CF3A3} - {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} = {57D9D146-511A-42D7-C1C5-0D18D3E1ADAF} - {0D7F6705-9114-1C0D-61F6-E76D43BBFD95} = {57D9D146-511A-42D7-C1C5-0D18D3E1ADAF} - {3C42534E-57D6-1270-FD53-1F85E7D1B136} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {5D9EB880-7F26-85D2-0606-FFBA669CA8FB} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {195DE0A1-20F2-DE84-330E-64EF72C116A1} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {B400518F-D1EE-66BF-31C8-033E502F04C2} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {F5813724-3299-71CB-B219-1133BFB3CE49} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {CE807E91-B0E6-0E34-4842-4BCD74C15A71} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {F4521C82-C834-1392-313E-A23DD3C91379} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {3103A43A-694B-46B4-904D-84FCBAB3DDBE} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {F6AAC506-626B-A519-AAA9-DED4C1511B7D} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {5FB4B0AA-09A7-11A8-D45F-73946CBDF400} = {8D8C51C4-760C-9908-3CE3-2A00341BA9B3} - {654F560F-B171-9B66-30C2-FA728CB812E1} = {0D7F6705-9114-1C0D-61F6-E76D43BBFD95} - {115E0CB8-501B-F73A-B4E5-343DC9C0FC93} = {0D7F6705-9114-1C0D-61F6-E76D43BBFD95} - {872394DD-5F95-2FD2-E30D-7E2B021F055B} = {0D7F6705-9114-1C0D-61F6-E76D43BBFD95} - {53AB0957-9473-8422-8FB2-2611339FAACC} = {A476FF40-6AD9-F237-094D-BC9CD170091F} - {AE403159-2725-6961-6E01-1CB0FBD8C1DF} = {A476FF40-6AD9-F237-094D-BC9CD170091F} - {27B65069-12AD-68A4-238F-58FA84F24813} = {AE403159-2725-6961-6E01-1CB0FBD8C1DF} - {F176F958-3A95-DDBC-8036-2B7E49B3254E} = {AE403159-2725-6961-6E01-1CB0FBD8C1DF} - {979B1DA2-CEA0-95C6-3E85-9329D28A41D1} = {AE403159-2725-6961-6E01-1CB0FBD8C1DF} - {95A0DC72-B175-3174-5EE2-F1E3473DE428} = {AE403159-2725-6961-6E01-1CB0FBD8C1DF} EndGlobalSection EndGlobal diff --git a/WatchIt.sln.DotSettings b/WatchIt.sln.DotSettings new file mode 100644 index 0000000..8930ba7 --- /dev/null +++ b/WatchIt.sln.DotSettings @@ -0,0 +1,2 @@ + + JWT \ No newline at end of file