├── assets ├── README.md └── raqamliavlod.plan.docx ├── deployment └── README.md ├── nima gap ├── Information.txt.txt └── Information.txt - Copy.txt ├── .github ├── workflows │ └── main-project.yml └── CODEOWNERS ├── README.md ├── src ├── RaqamliAvlod.Infrastructure.Core │ ├── Managers │ │ └── CheckerManager.cs │ ├── RabbitMq │ │ ├── RabbitMqCheckerProducer.cs │ │ └── RabbitMqCheckerConsumer.cs │ ├── Services │ │ ├── ContestCalculatorService.cs │ │ └── ProblemSetCalculatorService.cs │ ├── Interfaces │ │ ├── Shared │ │ │ ├── ICheckerConsumer.cs │ │ │ └── ICheckerProducer.cs │ │ ├── IContestCalculatorService.cs │ │ ├── Managers │ │ │ └── ICheckerManager.cs │ │ └── IProblemSetCalculatorService.cs │ ├── Models │ │ ├── CheckerSubmissionOptions.cs │ │ ├── CheckerSubmissionResponse.cs │ │ └── CheckerSubmissionRequest.cs │ └── RaqamliAvlod.Infrastructure.Core.csproj ├── RaqamliAvlod.Domain │ ├── Enums │ │ ├── ContestStatus.cs │ │ └── UserRole.cs │ ├── Common │ │ ├── BaseEntity.cs │ │ └── Auditable.cs │ ├── Entities │ │ ├── Questions │ │ │ ├── Tag.cs │ │ │ ├── QuestionTag.cs │ │ │ ├── Question.cs │ │ │ └── QuestionAnswer.cs │ │ ├── ProblemSets │ │ │ ├── ProblemSetTest.cs │ │ │ └── ProblemSet.cs │ │ ├── Courses │ │ │ ├── CourseComment.cs │ │ │ ├── Course.cs │ │ │ └── CourseVideo.cs │ │ ├── Contests │ │ │ ├── ContestStandings.cs │ │ │ ├── Contest.cs │ │ │ └── ContestSubmissionsInfo.cs │ │ ├── Users │ │ │ └── User.cs │ │ └── Submissions │ │ │ └── Submission.cs │ ├── Constants │ │ ├── ResourceConstants.cs │ │ └── EngineConstants.cs │ └── RaqamliAvlod.Domain.csproj ├── RaqamliAvlod.Application │ ├── ViewModels │ │ ├── Accounts │ │ │ └── AccountViewModel.cs │ │ ├── ProblemSets │ │ │ ├── ContestProblemSetBaseViewModel.cs │ │ │ ├── ProblemSetBaseViewModel.cs │ │ │ ├── ProblemSetTestViewModel.cs │ │ │ └── ProblemSetViewModel.cs │ │ ├── Questions │ │ │ ├── TagViewModel.cs │ │ │ ├── QuestionViewModel.cs │ │ │ ├── QuestionBaseViewModel.cs │ │ │ └── QuestionAnswerViewModel.cs │ │ ├── Contests │ │ │ ├── ContestStandingsViewModel.cs │ │ │ └── ContestViewModel.cs │ │ ├── Users │ │ │ ├── OwnerViewModel.cs │ │ │ └── UserViewModel.cs │ │ ├── Courses │ │ │ ├── CourseVideoGetViewModel.cs │ │ │ ├── CourseCommentViewModel.cs │ │ │ ├── CourseVideoGetAllViewModel.cs │ │ │ └── CourseViewModel.cs │ │ └── Submissions │ │ │ ├── SubmissionViewModel.cs │ │ │ └── ContestSubmissionViewModel.cs │ ├── Exceptions │ │ └── StatusCodeException.cs │ ├── Utils │ │ ├── PaginationParams.cs │ │ └── PaginationMetaData.cs │ └── RaqamliAvlod.Application.csproj ├── RaqamliAvlod.Api │ ├── appsettings.Development.json │ ├── wwwroot │ │ ├── Images │ │ │ ├── IMG_1604c0bb-aa5a-4ace-aea5-f246cb7b70e4.jpg │ │ │ ├── IMG_32989fce-6303-4c66-a4d9-b81d57b37bd1.jpg │ │ │ ├── IMG_430aa3b9-b9db-41e8-9e74-3ffb259a022b.jpg │ │ │ ├── IMG_555f647b-0c92-46b4-a83a-d7a91333edd4.jpg │ │ │ ├── IMG_57dfe211-8842-4264-8d53-f858086600d6.jpg │ │ │ ├── IMG_9d283cc2-bb1c-4c04-8289-39446a7dc579.jpg │ │ │ ├── IMG_ba8e097d-b22d-4fa2-acb8-305693c1a547.jpg │ │ │ ├── IMG_f111c748-0c2d-4fbe-95a5-9ef8638963ca.jpg │ │ │ └── IMG_f625d724-e82a-4e1e-819e-6b734ec202a2.jpg │ │ └── images │ │ │ └── IMG_e20ff889-091d-4200-a2ab-91545d6ac6f3.jpg │ ├── Configurations │ │ ├── LoggerConfiguration.cs │ │ ├── CorsPolicyConfiguration.cs │ │ ├── Dependencies │ │ │ ├── ApiLayerConfiguration.cs │ │ │ ├── DataAccessLayerConfiguration.cs │ │ │ └── ServiceLayerConfiguration.cs │ │ ├── JwtConfiguration.cs │ │ └── SwaggerAuthConfiguration.cs │ ├── Program.cs │ ├── Controllers │ │ ├── SubmissionsController.cs │ │ ├── AccountsController.cs │ │ ├── UsersController.cs │ │ ├── ContestsController.cs │ │ └── ProblemSetsController.cs │ ├── Properties │ │ └── launchSettings.json │ ├── RaqamliAvlod.Api.csproj │ ├── appsettings.json │ └── Middlewares │ │ └── ExceptionHandlerMiddleware.cs ├── RaqamliAvlod.Infrastructure.Service │ ├── Helpers │ │ ├── TimeHelper.cs │ │ ├── ImageHelper.cs │ │ ├── FileReader.cs │ │ └── ContestStatusHelper.cs │ ├── Dtos │ │ ├── Common │ │ │ ├── ErrorResponse.cs │ │ │ └── EmailMessage.cs │ │ ├── Courses │ │ │ ├── CourseCommentUpdateDto.cs │ │ │ ├── CourseVideoUpdateDto.cs │ │ │ ├── CourseCommentCreateDto.cs │ │ │ ├── CourseVideoCreateDto.cs │ │ │ ├── CourseUpdateDto.cs │ │ │ └── CourseCreateDto.cs │ │ ├── Accounts │ │ │ ├── SendToEmailDto.cs │ │ │ ├── VerifyEmailDto.cs │ │ │ ├── AccountLoginDto.cs │ │ │ ├── PasswordUpdateDto.cs │ │ │ ├── UserResetPasswordDto.cs │ │ │ ├── ImageUploadDto.cs │ │ │ └── AccountCreateDto.cs │ │ ├── ProblemSets │ │ │ ├── ContestProblemSetCreateDto.cs │ │ │ ├── ProblemSetTestCreateDto.cs │ │ │ └── ProblemSetCreateDto.cs │ │ ├── Questions │ │ │ ├── QuestionAnswerUpdateDto.cs │ │ │ ├── TagCreateDto.cs │ │ │ ├── QuestionPatchDto.cs │ │ │ ├── QuestionAnswerCreateDto.cs │ │ │ ├── QuestionUpdateDto.cs │ │ │ └── QuestionCreateDto.cs │ │ ├── Submissions │ │ │ ├── ContestSubmissionCreateDto.cs │ │ │ └── ProblemSetSubmissionCreateDto.cs │ │ ├── Users │ │ │ └── UserUpdateDto.cs │ │ └── Contests │ │ │ └── ContestCreateDto.cs │ ├── Interfaces │ │ ├── Common │ │ │ ├── IPaginatorService.cs │ │ │ ├── IAuthManager.cs │ │ │ ├── IEmailService.cs │ │ │ ├── IIdentityHelperService.cs │ │ │ └── IFileService.cs │ │ ├── Questions │ │ │ ├── IQuestionTagService.cs │ │ │ ├── ITagService.cs │ │ │ ├── IQuestionService.cs │ │ │ └── IQuestionAnswerService.cs │ │ ├── Users │ │ │ ├── IAccountService.cs │ │ │ └── IUserService.cs │ │ ├── ProblemSets │ │ │ ├── IProblemSetTestService.cs │ │ │ └── IProblemSetService.cs │ │ ├── Courses │ │ │ ├── ICourseVideoService.cs │ │ │ ├── ICourseService.cs │ │ │ └── ICourseCommentService.cs │ │ └── Contests │ │ │ └── IContestService.cs │ ├── RaqamliAvlod - Backup (2).Infrastructure.Service.csproj │ ├── RaqamliAvlod - Backup.Infrastructure.Service.csproj │ ├── Attributes │ │ ├── UsernameCheckAttribute.cs │ │ ├── IntegerAttribute.cs │ │ ├── PhoneNumberAttribute.cs │ │ ├── EmailAttribute.cs │ │ ├── MaxFileSizeAttribute.cs │ │ ├── NameAttribute.cs │ │ ├── AllowedFilesAttribute.cs │ │ └── StrongPasswordAttribute.cs │ ├── RaqamliAvlod - Backup (1).Infrastructure.Service.csproj │ ├── Services │ │ ├── Common │ │ │ ├── PaginatorServcie.cs │ │ │ ├── EmailService.cs │ │ │ └── FileService.cs │ │ ├── Questions │ │ │ ├── QuestionTagService.cs │ │ │ ├── TagService.cs │ │ │ └── QuestionService.cs │ │ ├── ProblemSets │ │ │ ├── ProblemSetTestService.cs │ │ │ └── ProblemSetService.cs │ │ ├── Contests │ │ │ └── ContestService.cs │ │ └── Courses │ │ │ └── CourseService.cs │ ├── RaqamliAvlod - Backup (3).Infrastructure.Service.csproj │ ├── Security │ │ ├── PasswordHasher.cs │ │ └── AuthManager.cs │ ├── RaqamliAvlod.Infrastructure.Service.csproj │ └── Managers │ │ └── IdentityHelperService.cs └── RaqamliAvlod.DataAccess │ ├── Common │ ├── Interfaces │ │ ├── IFindable.cs │ │ ├── ICreateable.cs │ │ ├── IDeleteable.cs │ │ ├── IUpdateable.cs │ │ └── IReadable.cs │ └── PagedList.cs │ ├── Interfaces │ ├── Submissions │ │ └── ISubmissionRepository.cs │ ├── IGenericRepository.cs │ ├── Contests │ │ ├── IContestRepository.cs │ │ ├── IContestStandingsRepository.cs │ │ └── IContestSubmissionInfoRepository.cs │ ├── ProblemSets │ │ ├── IProblemSetTestRepository.cs │ │ └── IProblemSetRepository.cs │ ├── IRepository.cs │ ├── Users │ │ └── IUserRepository.cs │ ├── Questions │ │ ├── ITagRepository.cs │ │ ├── IQuestionTagRepository.cs │ │ ├── IQuestionAnswerRepository.cs │ │ └── IQuestionRepository.cs │ ├── Courses │ │ ├── ICourseCommentRepository.cs │ │ ├── ICourseVideoRepository.cs │ │ └── ICourseRepository.cs │ └── IUnitOfWork.cs │ ├── Repositories │ ├── Submissions │ │ └── SubmissionRepository.cs │ ├── Contests │ │ ├── ContestRepository.cs │ │ ├── ContestStandingsRepository.cs │ │ └── ContestSubmissionInfoRepository.cs │ ├── GenericRepository.cs │ ├── ProblemSets │ │ ├── ProblemSetTestRepository.cs │ │ └── ProblemSetRepository.cs │ ├── Courses │ │ ├── CourseCommentRepository.cs │ │ ├── CourseVideoRepository.cs │ │ └── CourseRepository.cs │ ├── Users │ │ └── UserRepository.cs │ ├── Questions │ │ ├── TagRepository.cs │ │ ├── QuestionTagRepository.cs │ │ ├── QuestionAnswerRepository.cs │ │ └── QuestionRepository.cs │ ├── BaseRepository.cs │ └── UnitOfWork.cs │ ├── Configurations │ └── UserConfiguration.cs │ ├── RaqamliAvlod.DataAccess.csproj │ └── DbContexts │ └── AppDbContext.cs ├── test ├── RaqamliAvlod.UnitTest │ ├── UnitTest1.cs │ └── RaqamliAvlod.UnitTest.csproj └── RaqamliAvlod.IntegrationTest │ ├── UnitTest1.cs │ └── RaqamliAvlod.IntegrationTest.csproj └── LICENSE /assets/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /deployment/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nima gap/Information.txt.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/workflows/main-project.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nima gap/Information.txt - Copy.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # raqamliavlod 2 | Raqamli Avlod is an online competitive programming platform 3 | -------------------------------------------------------------------------------- /assets/raqamliavlod.plan.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/assets/raqamliavlod.plan.docx -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Managers/CheckerManager.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Managers 2 | { 3 | public class CheckerManager 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Enums/ContestStatus.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Domain.Enums 2 | { 3 | public enum ContestStatus 4 | { 5 | Pending, Started, Finished 6 | } 7 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Enums/UserRole.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Domain.Enums 2 | { 3 | public enum UserRole 4 | { 5 | SuperAdmin = 2, Admin = 1, User = 0 6 | } 7 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Accounts/AccountViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Application.ViewModels.Accounts 2 | { 3 | public class AccountViewModel 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Common/BaseEntity.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Domain.Common 2 | { 3 | public class BaseEntity 4 | { 5 | public long Id { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/RabbitMq/RabbitMqCheckerProducer.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.RabbitMQ 2 | { 3 | public class RabbitMqCheckerProducer 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Services/ContestCalculatorService.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Services 2 | { 3 | public class ContestCalculatorService 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Interfaces/Shared/ICheckerConsumer.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Interfaces.Shared 2 | { 3 | public interface ICheckerConsumer 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Interfaces/Shared/ICheckerProducer.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Interfaces.Shared 2 | { 3 | public interface ICheckerProducer 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Services/ProblemSetCalculatorService.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Services 2 | { 3 | public class ProblemSetCalculatorService 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Common/Auditable.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Domain.Common 2 | { 3 | public class Auditable : BaseEntity 4 | { 5 | public DateTime CreatedAt { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Interfaces/IContestCalculatorService.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Interfaces 2 | { 3 | public interface IContestCalculatorService 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Interfaces/Managers/ICheckerManager.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Interfaces.Managers 2 | { 3 | public interface ICheckerManager 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Interfaces/IProblemSetCalculatorService.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Interfaces 2 | { 3 | public interface IProblemSetCalculatorService 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_1604c0bb-aa5a-4ace-aea5-f246cb7b70e4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_1604c0bb-aa5a-4ace-aea5-f246cb7b70e4.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_32989fce-6303-4c66-a4d9-b81d57b37bd1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_32989fce-6303-4c66-a4d9-b81d57b37bd1.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_430aa3b9-b9db-41e8-9e74-3ffb259a022b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_430aa3b9-b9db-41e8-9e74-3ffb259a022b.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_555f647b-0c92-46b4-a83a-d7a91333edd4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_555f647b-0c92-46b4-a83a-d7a91333edd4.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_57dfe211-8842-4264-8d53-f858086600d6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_57dfe211-8842-4264-8d53-f858086600d6.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_9d283cc2-bb1c-4c04-8289-39446a7dc579.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_9d283cc2-bb1c-4c04-8289-39446a7dc579.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_ba8e097d-b22d-4fa2-acb8-305693c1a547.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_ba8e097d-b22d-4fa2-acb8-305693c1a547.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_f111c748-0c2d-4fbe-95a5-9ef8638963ca.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_f111c748-0c2d-4fbe-95a5-9ef8638963ca.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/Images/IMG_f625d724-e82a-4e1e-819e-6b734ec202a2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/Images/IMG_f625d724-e82a-4e1e-819e-6b734ec202a2.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/wwwroot/images/IMG_e20ff889-091d-4200-a2ab-91545d6ac6f3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khushboqof/raqamliavlod/HEAD/src/RaqamliAvlod.Api/wwwroot/images/IMG_e20ff889-091d-4200-a2ab-91545d6ac6f3.jpg -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Helpers/TimeHelper.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Service.Helpers; 2 | 3 | public class TimeHelper 4 | { 5 | public static DateTime GetCurrentDateTime() 6 | => DateTime.UtcNow; 7 | } 8 | -------------------------------------------------------------------------------- /test/RaqamliAvlod.UnitTest/UnitTest1.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace RaqamliAvlod.UnitTest 4 | { 5 | public class UnitTest1 6 | { 7 | [Fact] 8 | public void Test1() 9 | { 10 | 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /test/RaqamliAvlod.IntegrationTest/UnitTest1.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace RaqamliAvlod.IntegrationTest 4 | { 5 | public class UnitTest1 6 | { 7 | [Fact] 8 | public void Test1() 9 | { 10 | 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Common/Interfaces/IFindable.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace CodePower.DataAccess.Common.Interfaces; 4 | 5 | public interface IFindable where T : BaseEntity 6 | { 7 | public Task FindByIdAsync(long id); 8 | } 9 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Common/Interfaces/ICreateable.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace RaqamliAvlod.DataAccess.Common.Interfaces; 4 | 5 | public interface ICreateable where T : BaseEntity 6 | { 7 | public Task CreateAsync(T entity); 8 | } 9 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Common/Interfaces/IDeleteable.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace RaqamliAvlod.DataAccess.Common.Interfaces; 4 | 5 | public interface IDeleteable where T : BaseEntity 6 | { 7 | public Task DeleteAsync(long id); 8 | } 9 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Common/Interfaces/IUpdateable.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace CodePower.DataAccess.Common.Interfaces; 4 | 5 | public interface IUpdateable where T : BaseEntity 6 | { 7 | public Task UpdateAsync(long id, T entity); 8 | } 9 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Common/ErrorResponse.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 2 | { 3 | public class ErrorResponse 4 | { 5 | public int StatusCode { get; set; } 6 | 7 | public string Message { get; set; } = default!; 8 | } 9 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Models/CheckerSubmissionOptions.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Models 2 | { 3 | public class CheckerSubmissionOptions 4 | { 5 | public long SummissionId { get; set; } 6 | 7 | public bool IsTestable { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Common/IPaginatorService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Utils; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 4 | 5 | public interface IPaginatorService 6 | { 7 | void ToPagenator(PaginationMetaData metaData); 8 | } 9 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Submissions/ISubmissionRepository.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Submissions; 2 | 3 | namespace RaqamliAvlod.DataAccess.Interfaces.Submissions 4 | { 5 | public interface ISubmissionRepository : IGenericRepository 6 | { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Common/IAuthManager.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Users; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Common 4 | { 5 | public interface IAuthManager 6 | { 7 | public string GenerateToken(User user); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Questions/Tag.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace RaqamliAvlod.Domain.Entities.Questions 4 | { 5 | public class Tag : BaseEntity 6 | { 7 | public string TagName { get; set; } = default!; 8 | public int ViewCount { get; set; } = 0; 9 | } 10 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Common/IEmailService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Infrastructure.Service.Dtos; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Common 4 | { 5 | public interface IEmailService 6 | { 7 | public Task SendAsync(EmailMessage message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/IGenericRepository.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.DataAccess.Common.Interfaces; 2 | using RaqamliAvlod.Domain.Common; 3 | 4 | namespace RaqamliAvlod.DataAccess.Interfaces 5 | { 6 | public interface IGenericRepository : IRepository, IReadable 7 | where T : BaseEntity 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Contests/IContestRepository.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Contests; 2 | 3 | namespace RaqamliAvlod.DataAccess.Interfaces.Contests 4 | { 5 | public interface IContestRepository : IGenericRepository 6 | { 7 | public Task GetByTitleAsync(string title); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/ProblemSets/ContestProblemSetBaseViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Application.ViewModels.ProblemSets 2 | { 3 | public class ContestProblemSetBaseViewModel : ProblemSetBaseViewModel 4 | { 5 | public short ContestCoins { get; set; } 6 | public char ContestIdentifier { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Courses/CourseCommentUpdateDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 4 | { 5 | public class CourseCommentUpdateDto 6 | { 7 | [Required] 8 | public string CommentText { get; set; } = string.Empty; 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Accounts/SendToEmailDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Attributes; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos; 5 | 6 | public class SendToEmailDto 7 | { 8 | [Required(ErrorMessage = "Email is required"), Email] 9 | public string Email { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Courses/CourseVideoUpdateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Courses; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 5 | { 6 | public class CourseVideoUpdateDto 7 | { 8 | [Required] 9 | public string Link { get; set; } = string.Empty; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Common/Interfaces/IReadable.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Domain.Common; 4 | 5 | namespace RaqamliAvlod.DataAccess.Common.Interfaces 6 | { 7 | public interface IReadable where T : BaseEntity 8 | { 9 | public Task> GetAllAsync(PaginationParams @params); 10 | } 11 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Constants/ResourceConstants.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Domain.Constants 2 | { 3 | public class ResourceConstants 4 | { 5 | public readonly static string[] ALLOWED_IMAGE_EXTENSIONS = new string[] 6 | { 7 | ".jpg", ".jpeg", ".png" 8 | }; 9 | 10 | // Mesaure : MB 11 | public const int MAX_AVATAR_SIZE = 2; 12 | } 13 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/RaqamliAvlod.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Common/IIdentityHelperService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Enums; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Common 4 | { 5 | public interface IIdentityHelperService 6 | { 7 | UserRole? GetUserRole(); 8 | long? GetUserId(); 9 | string GetUserName(); 10 | string GetUserEmail(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/ProblemSets/IProblemSetTestRepository.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.ProblemSets; 2 | 3 | namespace RaqamliAvlod.DataAccess.Interfaces.ProblemSets 4 | { 5 | public interface IProblemSetTestRepository 6 | : IRepository 7 | { 8 | public Task> GetAllByProblemSetId(long problemSetId); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/IRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common.Interfaces; 2 | using RaqamliAvlod.DataAccess.Common.Interfaces; 3 | using RaqamliAvlod.Domain.Common; 4 | 5 | namespace RaqamliAvlod.DataAccess.Interfaces 6 | { 7 | public interface IRepository : ICreateable, 8 | IUpdateable, IFindable, IDeleteable 9 | where T : BaseEntity 10 | { 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Common/IFileService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Common 4 | { 5 | public interface IFileService 6 | { 7 | public string ImageFolderName { get; } 8 | Task SaveImageAsync(IFormFile image); 9 | Task DeleteImageAsync(string relativeFilePath); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Accounts/VerifyEmailDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Attributes; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos; 5 | 6 | public class VerifyEmailDto 7 | { 8 | [Required(ErrorMessage = "Email is required"), Email] 9 | public string Email { get; set; } = string.Empty; 10 | 11 | [Required] 12 | public int Code { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Helpers/ImageHelper.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Service.Helpers 2 | { 3 | public class ImageHelper 4 | { 5 | public static string MakeImageName(string fileName) 6 | { 7 | string strpath = Path.GetExtension(fileName); 8 | 9 | string guid = Guid.NewGuid().ToString(); 10 | return "IMG_" + guid + strpath; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Questions/QuestionTag.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace RaqamliAvlod.Domain.Entities.Questions 4 | { 5 | public class QuestionTag : BaseEntity 6 | { 7 | public long QuestionId { get; set; } 8 | public virtual Question Question { get; set; } = default!; 9 | 10 | public long TagId { get; set; } 11 | public virtual Tag Tag { get; set; } = default!; 12 | } 13 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Accounts/AccountLoginDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Attributes; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 5 | { 6 | public class AccountLoginDto 7 | { 8 | [Required] 9 | public string EmailOrUsername { get; set; } = string.Empty; 10 | [Required] 11 | public string Password { get; set; } = string.Empty; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Users/IUserRepository.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Users; 2 | 3 | namespace RaqamliAvlod.DataAccess.Interfaces.Users 4 | { 5 | public interface IUserRepository : IGenericRepository 6 | { 7 | public Task GetByEmailAsync(string email); 8 | 9 | public Task GetByUsernameAsync(string username); 10 | 11 | public Task GetByPhonNumberAsync(string phoneNumber); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Questions/ITagRepository.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | 3 | namespace RaqamliAvlod.DataAccess.Interfaces.Questions 4 | { 5 | public interface ITagRepository : IRepository 6 | { 7 | public Task FindByNameAsync(string name); 8 | 9 | public Task> SearchAsync(string name); 10 | 11 | public Task> AddRangeAsync(IEnumerable tags); 12 | } 13 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/ProblemSets/ProblemSetTest.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace RaqamliAvlod.Domain.Entities.ProblemSets 4 | { 5 | public class ProblemSetTest : BaseEntity 6 | { 7 | public string Input { get; set; } = String.Empty; 8 | public string Output { get; set; } = String.Empty; 9 | 10 | public long ProblemSetId { get; set; } 11 | public virtual ProblemSet ProblemSet { get; set; } = null!; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Configurations/LoggerConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Serilog; 2 | 3 | namespace RaqamliAvlod.Api.Configurations 4 | { 5 | public static class LoggerConfiguration 6 | { 7 | public static void ConfigureLogger(this WebApplicationBuilder builder) 8 | { 9 | builder.Host.UseSerilog((hostingContext, loggerConfiduration) => 10 | loggerConfiduration.ReadFrom.Configuration(hostingContext.Configuration)); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Courses/ICourseCommentRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Domain.Entities.Courses; 4 | 5 | namespace RaqamliAvlod.DataAccess.Interfaces.Courses 6 | { 7 | public interface ICourseCommentRepository 8 | : IRepository 9 | { 10 | public Task> GetAllByCourseIdAsync(long courseId, PaginationParams @params); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Common/EmailMessage.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 4 | { 5 | public class EmailMessage 6 | { 7 | [Required] 8 | public string To { get; set; } = string.Empty; 9 | 10 | [Required] 11 | public string Subject { get; set; } = string.Empty; 12 | 13 | [Required] 14 | public string Body { get; set; } = string.Empty; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Constants/EngineConstants.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Domain.Constants 2 | { 3 | public class EngineConstants 4 | { 5 | // Mesaure : KB 6 | public const int MAX_MEMORY_LIMIT = 512 * 1024; 7 | 8 | // Mesaure : ms 9 | public const int MAX_TIME_LIMIT = 5000; 10 | 11 | // Measure : % 12 | public const int MAX_DIFFICULTY = 100; 13 | 14 | // Measure : characters 15 | public const int MAX_CODE_LENGTH = 65000; 16 | } 17 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Contests/IContestStandingsRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Domain.Entities.Contests; 4 | 5 | namespace RaqamliAvlod.DataAccess.Interfaces.Contests 6 | { 7 | public interface IContestStandingsRepository 8 | : IRepository 9 | { 10 | public Task> GetAllByContestIdAsync(long contestId, PaginationParams @params); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Contests/IContestSubmissionInfoRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Domain.Entities.Contests; 4 | 5 | namespace RaqamliAvlod.DataAccess.Interfaces.Contests 6 | { 7 | public interface IContestSubmissionInfoRepository : IRepository 8 | { 9 | public Task> GetAllByContestIdAsync(long contestId, PaginationParams @params); 10 | } 11 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/ProblemSets/ContestProblemSetCreateDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 4 | { 5 | public class ContestProblemSetCreateDto : ProblemSetCreateDto 6 | { 7 | [Required] 8 | public short ContestCoins { get; set; } 9 | 10 | [Required] 11 | public char ContestIdentifier { get; set; } 12 | 13 | [Required] 14 | public long ContestId { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Accounts/PasswordUpdateDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 4 | { 5 | public class PasswordUpdateDto 6 | { 7 | [Required] 8 | public string OldPassword { get; set; } = string.Empty; 9 | [Required] 10 | public string NewPassword { get; set; } = string.Empty; 11 | [Required] 12 | public string ConfirmPassword { get; set; } = string.Empty; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/Exceptions/StatusCodeException.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace RaqamliAvlod.Application.Exceptions 4 | { 5 | public class StatusCodeException : Exception 6 | { 7 | public HttpStatusCode HttpStatusCode { get; set; } 8 | 9 | public StatusCodeException() { } 10 | 11 | public StatusCodeException(HttpStatusCode httpStatusCode, string message) 12 | : base(message) 13 | { 14 | this.HttpStatusCode = httpStatusCode; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Courses/ICourseVideoRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Courses; 4 | using RaqamliAvlod.Domain.Entities.Courses; 5 | 6 | namespace RaqamliAvlod.DataAccess.Interfaces.Courses 7 | { 8 | public interface ICourseVideoRepository : IRepository 9 | { 10 | public Task> GetAllByCourseIdAsync(long courseId, PaginationParams @params); 11 | } 12 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Submissions/SubmissionRepository.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.DataAccess.DbContexts; 2 | using RaqamliAvlod.DataAccess.Interfaces.Submissions; 3 | using RaqamliAvlod.Domain.Entities.Submissions; 4 | 5 | 6 | namespace RaqamliAvlod.DataAccess.Repositories.Submissions 7 | { 8 | public class SubmissionRepository : GenericRepository, ISubmissionRepository 9 | { 10 | public SubmissionRepository(AppDbContext context) : base(context) 11 | { 12 | 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Configurations/CorsPolicyConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Api.Configurations 2 | { 3 | public static class CorsPolicyConfiguration 4 | { 5 | public static void ConfigureCorsPolicy(this IServiceCollection services) 6 | { 7 | services.AddCors(options => 8 | { 9 | options.AddPolicy("AllowAll", builder => 10 | builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader() 11 | ); 12 | }); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Courses/CourseComment.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Entities.Users; 3 | 4 | namespace RaqamliAvlod.Domain.Entities.Courses 5 | { 6 | public class CourseComment : Auditable 7 | { 8 | public string CommentText { get; set; } = String.Empty; 9 | 10 | public long CourseId { get; set; } 11 | public Course Course { get; set; } = null!; 12 | 13 | public long OwnerId { get; set; } 14 | public virtual User Owner { get; set; } = null!; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Questions/Question.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Entities.Users; 3 | 4 | namespace RaqamliAvlod.Domain.Entities.Questions 5 | { 6 | public class Question : Auditable 7 | { 8 | public string Title { get; set; } = String.Empty; 9 | public string Description { get; set; } = String.Empty; 10 | public int ViewCount { get; set; } = 0; 11 | 12 | public long OwnerId { get; set; } 13 | public virtual User Owner { get; set; } = null!; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Helpers/FileReader.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Helpers 4 | { 5 | public class FileReader 6 | { 7 | public static byte[] ReadAsBytes(IFormFile file) 8 | { 9 | byte[] bytefile; 10 | using (var reader = new BinaryReader(file.OpenReadStream())) 11 | { 12 | bytefile = reader.ReadBytes((int)file.OpenReadStream().Length); 13 | } 14 | return bytefile; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Configurations/Dependencies/ApiLayerConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Api.Configurations.Dependencies 2 | { 3 | public static class ApiLayerConfiguration 4 | { 5 | public static void AddApiLayer(this WebApplicationBuilder builder) 6 | { 7 | builder.ConfigureLogger(); 8 | builder.Services.ConfigureCorsPolicy(); 9 | builder.Services.AddHttpContextAccessor(); 10 | builder.ConfigureJwt(); 11 | builder.Services.ConfigureSwaggerAuthorize(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Accounts/UserResetPasswordDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Attributes; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos; 5 | 6 | public class UserResetPasswordDto 7 | { 8 | [Required(ErrorMessage = "Email is required"), Email] 9 | public string Email { get; set; } = string.Empty; 10 | 11 | [Required] 12 | public int Code { get; set; } 13 | 14 | [Required(ErrorMessage = "Password is required")] 15 | public string Password { get; set; } = string.Empty; 16 | } 17 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Questions/IQuestionTagService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Questions 9 | { 10 | public interface IQuestionTagService 11 | { 12 | Task CreateAsync(Question question, IEnumerable tags); 13 | Task UpdateAsync(Question question, IEnumerable tags); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Contests/ContestStandings.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Entities.Users; 3 | 4 | namespace RaqamliAvlod.Domain.Entities.Contests 5 | { 6 | public class ContestStandings : Auditable 7 | { 8 | public long UserId { get; set; } 9 | public virtual User User { get; set; } = null!; 10 | public long ContestId { get; set; } 11 | public virtual Contest Contest { get; set; } = null!; 12 | public int ResultCoins { get; set; } 13 | public int Penalty { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Accounts/ImageUploadDto.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using RaqamliAvlod.Attributes; 3 | using System.ComponentModel.DataAnnotations; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Dtos.Accounts 6 | { 7 | public class ImageUploadDto 8 | { 9 | [Required(ErrorMessage = "Image is required")] 10 | [DataType(DataType.Upload)] 11 | [MaxFileSize(2)] 12 | [AllowedFiles(new string[] { ".jpg", ".png", ".jpeg", ".svg", ".webp" })] 13 | public IFormFile Image { get; set; } = null!; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/RaqamliAvlod - Backup (2).Infrastructure.Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Questions/TagViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Questions 4 | { 5 | public class TagViewModel 6 | { 7 | public long Id { get; set; } 8 | public string TagName { get; set; } = String.Empty; 9 | 10 | public static implicit operator TagViewModel(Tag tag) 11 | { 12 | return new TagViewModel() 13 | { 14 | Id = tag.Id, 15 | TagName = tag.TagName 16 | }; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Helpers/ContestStatusHelper.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Enums; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Helpers 4 | { 5 | public class ContestStatusHelper 6 | { 7 | public static ContestStatus GetStatus(DateTime startDate, DateTime endDate) 8 | { 9 | DateTime now = TimeHelper.GetCurrentDateTime(); 10 | if (now < startDate) return ContestStatus.Pending; 11 | else if (now >= startDate && now <= endDate) return ContestStatus.Started; 12 | else return ContestStatus.Finished; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Questions/QuestionAnswerUpdateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Dtos.Questions 4 | { 5 | public class QuestionAnswerUpdateDto 6 | { 7 | public string Description { get; set; } = String.Empty; 8 | 9 | public static implicit operator QuestionAnswerUpdateDto(QuestionAnswer questionAnswer) 10 | { 11 | return new QuestionAnswerUpdateDto() 12 | { 13 | Description = questionAnswer.Description 14 | }; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/RaqamliAvlod - Backup.Infrastructure.Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Questions/IQuestionTagRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Domain.Entities.Questions; 4 | 5 | namespace RaqamliAvlod.DataAccess.Interfaces.Questions 6 | { 7 | public interface IQuestionTagRepository : IRepository 8 | { 9 | public Task> GetAllTagsFromQuestionAsync(long questionId, PaginationParams @params); 10 | 11 | public Task AddRangeAsync(IEnumerable questionTags); 12 | public Task DeleteQuestionTagsAsync(long questionId); 13 | } 14 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Users/IAccountService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Infrastructure.Service.Dtos; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Users 4 | { 5 | public interface IAccountService 6 | { 7 | Task LogInAsync(AccountLoginDto accountLogin); 8 | 9 | Task RegisterAsync(AccountCreateDto accountCreate); 10 | 11 | Task VerifyEmailAsync(VerifyEmailDto verifyEmail); 12 | 13 | Task SendCodeAsync(SendToEmailDto sendToEmail); 14 | 15 | Task VerifyPasswordAsync(UserResetPasswordDto userResetPassword); 16 | } 17 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Attributes/UsernameCheckAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Attributes; 4 | 5 | [AttributeUsage(AttributeTargets.Property)] 6 | public class UsernameCheckAttribute : ValidationAttribute 7 | { 8 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 9 | { 10 | var username = (string)value!; 11 | if (!username.Contains("@")) 12 | return ValidationResult.Success; 13 | 14 | return new ValidationResult($"Cannot use '@' in username"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Contests/Contest.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace RaqamliAvlod.Domain.Entities.Contests 4 | { 5 | public class Contest : Auditable 6 | { 7 | public string Title { get; set; } = String.Empty; 8 | public string Description { get; set; } = String.Empty; 9 | public DateTime StartDate { get; set; } 10 | public DateTime EndDate { get; set; } 11 | public bool IsCompleted { get; set; } 12 | public bool IsPublic { get; set; } 13 | public DateTime UpdatedAt { get; set; } 14 | public DateTime CalculatedDate { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Models/CheckerSubmissionResponse.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Models 2 | { 3 | public class CheckerSubmissionResponse : CheckerSubmissionOptions 4 | { 5 | public string Result { get; set; } = string.Empty; 6 | 7 | public Dictionary ProcessingTimes { get; set; } 8 | = new Dictionary(); 9 | 10 | public Dictionary MemoryUsages { get; set; } 11 | = new Dictionary(); 12 | 13 | public bool IsSuccessfull { get; set; } 14 | 15 | public string ErrorMessage { get; set; } = string.Empty; 16 | } 17 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/ProblemSets/ProblemSetBaseViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Application.ViewModels.ProblemSets 2 | { 3 | public class ProblemSetBaseViewModel 4 | { 5 | public long Id { get; set; } 6 | 7 | public string Name { get; set; } = String.Empty; 8 | 9 | public string Type { get; set; } = String.Empty; 10 | 11 | public bool CurrentUserIsSolved { get; set; } 12 | 13 | public int TotalSubmissions { get; set; } 14 | 15 | public int CorrectSubmissions { get; set; } 16 | 17 | public int TotalParticipants { get; set; } 18 | 19 | public int Percentage { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Questions/TagCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Attributes; 2 | using RaqamliAvlod.Domain.Entities.Questions; 3 | using System.ComponentModel.DataAnnotations; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Dtos.Questions 6 | { 7 | public class TagCreateDto 8 | { 9 | [Required, Name] 10 | public string TagName { get; set; } = String.Empty; 11 | 12 | 13 | public static implicit operator Tag(TagCreateDto tagCreateDto) 14 | { 15 | return new Tag() 16 | { 17 | TagName = tagCreateDto.TagName.ToLower() 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Questions/IQuestionAnswerRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Questions; 4 | using RaqamliAvlod.Domain.Entities.Questions; 5 | 6 | namespace RaqamliAvlod.DataAccess.Interfaces.Questions 7 | { 8 | public interface IQuestionAnswerRepository : IRepository 9 | { 10 | public Task> GetAllByQuestionIdAsync(long questionId, PaginationParams @params); 11 | public Task> GetAllRepliesAsync(long answerId, PaginationParams @params); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Questions/ITagService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.ViewModels.Questions; 2 | using RaqamliAvlod.Domain.Enums; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos.Questions; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Questions 6 | { 7 | public interface ITagService 8 | { 9 | Task CreateAsync(TagCreateDto tagCreateDto, UserRole role); 10 | Task UpdateAsync(long id, TagCreateDto dto); 11 | Task DeleteAsync(long id); 12 | Task GetByIdAsync(long Id); 13 | Task> GetByNameAsync(string name); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/RaqamliAvlod - Backup (1).Infrastructure.Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Configurations/UserConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using RaqamliAvlod.Domain.Entities.Users; 4 | 5 | namespace RaqamliAvlod.DataAccess.Configurations 6 | { 7 | public class UserConfiguration : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasIndex(user => user.Email).IsUnique(); 12 | builder.HasIndex(user => user.PhoneNumber).IsUnique(); 13 | // create super admin 14 | // create admin 15 | // create user 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/ProblemSets/IProblemSetTestService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.ViewModels.ProblemSets; 2 | using RaqamliAvlod.Infrastructure.Service.Dtos; 3 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.ProblemSets; 4 | 5 | public interface IProblemSetTestService 6 | { 7 | public Task> GetAllAsync(long problemSetId); 8 | public Task GetAsync(long testId); 9 | public Task DeleteAsync(long testId); 10 | public Task CreateAsync(ProblemSetTestCreateDto testCreateDto); 11 | public Task UpdateAsync(long testId, ProblemSetTestCreateDto testCreateDto); 12 | } 13 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Contests/ContestRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using RaqamliAvlod.DataAccess.DbContexts; 3 | using RaqamliAvlod.DataAccess.Interfaces.Contests; 4 | using RaqamliAvlod.Domain.Entities.Contests; 5 | 6 | namespace RaqamliAvlod.DataAccess.Repositories.Contests 7 | { 8 | public class ContestRepository : GenericRepository, IContestRepository 9 | { 10 | public ContestRepository(AppDbContext context) : base(context) 11 | { 12 | } 13 | 14 | public async Task GetByTitleAsync(string title) 15 | => await _dbcontext.Contests.FirstOrDefaultAsync(o => o.Title == title); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Courses/Course.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Entities.Users; 3 | 4 | namespace RaqamliAvlod.Domain.Entities.Courses 5 | { 6 | public class Course : Auditable 7 | { 8 | public string Title { get; set; } = String.Empty; 9 | public string Info { get; set; } = String.Empty; 10 | public string Type { get; set; } = String.Empty; 11 | public string ImagePath { get; set; } = String.Empty; 12 | public float Price { get; set; } 13 | public DateTime UpdatedAt { get; set; } 14 | 15 | public long OwnerId { get; set; } 16 | public virtual User? Owner { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Courses/CourseCommentCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Courses; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 5 | { 6 | public class CourseCommentCreateDto 7 | { 8 | [Required, MinLength(3)] 9 | public string CommentText { get; set; } = string.Empty; 10 | 11 | public static implicit operator CourseComment(CourseCommentCreateDto courseCommentCreateDto) 12 | { 13 | return new CourseComment() 14 | { 15 | CommentText = courseCommentCreateDto.CommentText 16 | }; 17 | } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Courses/ICourseVideoService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Utils; 2 | using RaqamliAvlod.Application.ViewModels.Courses; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Courses; 6 | 7 | public interface ICourseVideoService 8 | { 9 | Task CreateAsync(CourseVideoCreateDto dto); 10 | Task UpdateAsync(long videoId, CourseVideoUpdateDto dto); 11 | Task DeleteAsync(long videoId); 12 | Task> GetAllAsync(long courseId, PaginationParams @params); 13 | Task GetAsync(long videoId); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Github configs PR reviewer 2 | /.github/* @sodiqjonovich 3 | /assets/* @sodiqjonovich 4 | /src/* @sodiqjonovich 5 | 6 | /src/RaqamliAvlod.Api/* @khayitmuradov 7 | /src/RaqamliAvlod.DataAccess/* @Maxamadzoidov 8 | /src/RaqamliAvlod.Application/* @AbdullayevAbbos 9 | /src/RaqamliAvlod.Domain/* @akhadov 10 | /src/RaqamliAvlod.Infrastructure.Core/* @sodiqjonovich 11 | /src/RaqamliAvlod.Infrastructure.Service/* @TemurbekUbaydullayev 12 | 13 | /test/* @aslonboyev -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Questions/QuestionPatchDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | 3 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 4 | { 5 | public class QuestionPatchDto 6 | { 7 | public string Title { get; set; } = String.Empty; 8 | public string Description { get; set; } = String.Empty; 9 | public string[]? Tags { get; set; } 10 | 11 | public static implicit operator Question(QuestionPatchDto question) 12 | { 13 | return new Question() 14 | { 15 | Title = question.Title, 16 | Description = question.Description, 17 | }; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Contests/ContestSubmissionsInfo.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Entities.ProblemSets; 3 | 4 | namespace RaqamliAvlod.Domain.Entities.Contests 5 | { 6 | public class ContestSubmissionsInfo : BaseEntity 7 | { 8 | public bool IsFixed { get; set; } 9 | public TimeOnly FixedTime { get; set; } 10 | public short PenaltySubmissions { get; set; } 11 | 12 | public long ProblemSetId { get; set; } 13 | public virtual ProblemSet ProblemSet { get; set; } = default!; 14 | 15 | public long ContestStandingsId { get; set; } 16 | public virtual ContestStandings ContestStandings { get; set; } = default!; 17 | } 18 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/RaqamliAvlod.Infrastructure.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Courses/CourseVideo.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | 3 | namespace RaqamliAvlod.Domain.Entities.Courses 4 | { 5 | public class CourseVideo : Auditable 6 | { 7 | public string Title { get; set; } = String.Empty; 8 | public string YouTubeThumbnail { get; set; } = String.Empty; 9 | public int ViewCount { get; set; } = 0; 10 | public string YouTubeLink { get; set; } = String.Empty; 11 | public string Description { get; set; } = String.Empty; 12 | public string Duration { get; set; } = string.Empty; 13 | 14 | public long CourseId { get; set; } 15 | public virtual Course Course { get; set; } = null!; 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Courses/CourseVideoCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Courses; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 5 | { 6 | public class CourseVideoCreateDto 7 | { 8 | [Required] 9 | public string Link { get; set; } = string.Empty; 10 | 11 | [Required] 12 | public long CourseId { get; set; } 13 | 14 | public static implicit operator CourseVideo(CourseVideoCreateDto courseVideoCreateDto) 15 | { 16 | return new CourseVideo() 17 | { 18 | CourseId = courseVideoCreateDto.CourseId 19 | }; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Courses/ICourseService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Utils; 2 | using RaqamliAvlod.Application.ViewModels.Courses; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Courses; 6 | 7 | public interface ICourseService 8 | { 9 | Task CreateAsync(CourseCreateDto dto); 10 | Task UpdateAsync(long courseId, CourseUpdateDto dto); 11 | Task DeleteAsync(long id); 12 | Task GetAsync(long id); 13 | Task> GetAllAsync(PaginationParams @params); 14 | Task> SearchByTitleAsync(string text, PaginationParams @params); 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Courses/ICourseRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Courses; 4 | using RaqamliAvlod.Domain.Entities.Courses; 5 | 6 | namespace RaqamliAvlod.DataAccess.Interfaces.Courses 7 | { 8 | public interface ICourseRepository : IGenericRepository 9 | { 10 | Task> SearchAsync(string text, PaginationParams @params); 11 | Task> SearchByTitleAsync(string text, PaginationParams @params); 12 | Task> GetAllViewAsync(PaginationParams @params); 13 | Task GetViewAsync(long id); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/Models/CheckerSubmissionRequest.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Core.Models 2 | { 3 | public class CheckerSubmissionRequest : CheckerSubmissionOptions 4 | { 5 | public string ProblemKey { get; set; } = String.Empty; 6 | 7 | public string Language { get; set; } = String.Empty; 8 | 9 | public byte[] Code { get; set; } = null!; 10 | 11 | public string CodeFileName { get; set; } = String.Empty; 12 | 13 | public ushort TimeLimit { get; set; } 14 | 15 | public uint MemoryLimit { get; set; } 16 | 17 | public string IdentityKey { get; set; } = String.Empty; 18 | 19 | public string Password { get; set; } = String.Empty; 20 | } 21 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Questions/QuestionAnswer.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Entities.Users; 3 | 4 | namespace RaqamliAvlod.Domain.Entities.Questions 5 | { 6 | public class QuestionAnswer : Auditable 7 | { 8 | public string Description { get; set; } = String.Empty; 9 | public bool HasReplied { get; set; } = false; 10 | 11 | public long OwnerId { get; set; } 12 | public virtual User Owner { get; set; } = null!; 13 | 14 | public long QuestionId { get; set; } 15 | public virtual Question Question { get; set; } = null!; 16 | 17 | public long? ParentId { get; set; } 18 | public virtual QuestionAnswer? Parent { get; set; } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Attributes/IntegerAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace RaqamliAvlod.Infrastructure.Service.Attributes; 9 | 10 | [AttributeUsage(AttributeTargets.Property)] 11 | public class IntegerAttribute : ValidationAttribute 12 | { 13 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 14 | { 15 | var price = (float)value!; 16 | 17 | if (price < 0) 18 | return new ValidationResult($"Price is a positive number!"); 19 | 20 | return ValidationResult.Success; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/ProblemSets/IProblemSetRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.ProblemSets; 4 | using RaqamliAvlod.Domain.Entities.ProblemSets; 5 | 6 | namespace RaqamliAvlod.DataAccess.Interfaces.ProblemSets 7 | { 8 | public interface IProblemSetRepository : IRepository 9 | { 10 | public Task FindByNameAsync(string problemSetName); 11 | 12 | public Task> GetAllViewAsync(PaginationParams @params, long userId); 13 | 14 | public Task> GetAllViewAsync(PaginationParams @params, long userId, long contestId); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/Common/PaginatorServcie.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Newtonsoft.Json; 3 | using RaqamliAvlod.Application.Utils; 4 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Services.Common; 7 | 8 | public class PaginatorServcie : IPaginatorService 9 | { 10 | private readonly IHttpContextAccessor _accessor; 11 | 12 | public PaginatorServcie(IHttpContextAccessor accessor) 13 | { 14 | _accessor = accessor; 15 | } 16 | public void ToPagenator(PaginationMetaData metaData) 17 | { 18 | _accessor.HttpContext.Response.Headers.Add("X-Pagination", 19 | JsonConvert.SerializeObject(metaData)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/Questions/IQuestionRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Questions; 4 | using RaqamliAvlod.Domain.Entities.Questions; 5 | 6 | namespace RaqamliAvlod.DataAccess.Interfaces.Questions 7 | { 8 | public interface IQuestionRepository : IGenericRepository 9 | { 10 | public Task GetViewAsync(long questionId); 11 | 12 | public Task> GetAllViewAsync(PaginationParams @params); 13 | 14 | public Task CountViewAsync(long questionId); 15 | 16 | Task> SearchAsync(string search, PaginationParams @params); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Contests/IContestService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Utils; 2 | using RaqamliAvlod.Application.ViewModels.Contests; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Contests 6 | { 7 | public interface IContestService 8 | { 9 | public Task CreateAsync(ContestCreateDto contestCreateDto); 10 | 11 | public Task GetAsync(long contestId); 12 | 13 | public Task> GetAllAsync(PaginationParams @params); 14 | 15 | public Task DeleteAsync(long contestId); 16 | 17 | public Task UpdateAsync(long courseId, ContestCreateDto createDto); 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/ProblemSets/ProblemSetTestViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.ProblemSets; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.ProblemSets 4 | { 5 | public class ProblemSetTestViewModel 6 | { 7 | public long Id { get; set; } 8 | public string Input { get; set; } = String.Empty; 9 | public string Output { get; set; } = String.Empty; 10 | 11 | public static implicit operator ProblemSetTestViewModel(ProblemSetTest problemSetTest) 12 | { 13 | return new ProblemSetTestViewModel() 14 | { 15 | Id = problemSetTest.Id, 16 | Input = problemSetTest.Input, 17 | Output = problemSetTest.Output 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Contests/ContestStandingsViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Contests; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Contests 4 | { 5 | public class ContestStandingsViewModel 6 | { 7 | public int ResultCoins { get; set; } 8 | public int Penalty { get; set; } 9 | 10 | public string Username { get; set; } = string.Empty; 11 | public string ContestName { get; set; } = string.Empty; 12 | 13 | public static implicit operator ContestStandingsViewModel(ContestStandings contest) 14 | { 15 | return new ContestStandingsViewModel() 16 | { 17 | ResultCoins = contest.ResultCoins, 18 | Penalty = contest.Penalty, 19 | }; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Questions/QuestionAnswerCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos.Questions 5 | { 6 | public class QuestionAnswerCreateDto 7 | { 8 | [Required] 9 | public string Description { get; set; } = String.Empty; 10 | public long? ParentId { get; set; } 11 | 12 | public static implicit operator QuestionAnswer(QuestionAnswerCreateDto questionAnswerCreateDto) 13 | { 14 | return new QuestionAnswer() 15 | { 16 | Description = questionAnswerCreateDto.Description, 17 | ParentId = questionAnswerCreateDto.ParentId 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Program.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Api.Configurations.Dependencies; 2 | using RaqamliAvlod.Api.Middlewares; 3 | 4 | //-> Services 5 | var builder = WebApplication.CreateBuilder(args); 6 | builder.Services.AddControllers(); 7 | builder.Services.AddEndpointsApiExplorer(); 8 | builder.Services.AddSwaggerGen(); 9 | builder.AddDataAccessLayer(); 10 | builder.AddServiceLayer(); 11 | builder.AddApiLayer(); 12 | 13 | //-> Middlewares 14 | var app = builder.Build(); 15 | if (app.Environment.IsDevelopment()) 16 | { 17 | app.UseSwagger(); 18 | app.UseSwaggerUI(); 19 | } 20 | app.UseStaticFiles(); 21 | app.UseMiddleware(); 22 | app.UseCors("AllowAll"); 23 | app.UseHttpsRedirection(); 24 | app.UseAuthentication(); 25 | app.UseAuthorization(); 26 | app.MapControllers(); 27 | app.Run(); 28 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Courses/ICourseCommentService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Utils; 2 | using RaqamliAvlod.Application.ViewModels.Courses; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Courses 6 | { 7 | public interface ICourseCommentService 8 | { 9 | Task CreateAsync(long userId, long ownerId, CourseCommentCreateDto dto); 10 | Task UpdateAsync(long userId,long courseCommentId, CourseCommentUpdateDto dto); 11 | Task DeleteAsync(long userId, long id); 12 | Task GetAsync(long? userId,long id); 13 | Task> GetAllByCourseIdAsync(long? userId, long courseId, PaginationParams @params); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/ProblemSets/IProblemSetService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Utils; 2 | using RaqamliAvlod.Application.ViewModels.ProblemSets; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.ProblemSets 6 | { 7 | public interface IProblemSetService 8 | { 9 | public Task> GetAllAsync(PaginationParams @params, long? userId); 10 | 11 | public Task GetAsync(long problemSetId); 12 | 13 | public Task CreateAsync(ProblemSetCreateDto createDto); 14 | 15 | public Task UpdateAsync(long problemSetId, ProblemSetCreateDto updateDto); 16 | 17 | public Task DeleteAsync(long problemSetId); 18 | } 19 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/GenericRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.DataAccess.DbContexts; 4 | using RaqamliAvlod.DataAccess.Interfaces; 5 | using RaqamliAvlod.Domain.Common; 6 | 7 | namespace RaqamliAvlod.DataAccess.Repositories 8 | { 9 | public class GenericRepository : BaseRepository, 10 | IGenericRepository where T : BaseEntity 11 | { 12 | public GenericRepository(AppDbContext context) : base(context) 13 | { 14 | } 15 | 16 | public virtual async Task> GetAllAsync(PaginationParams @params) 17 | { 18 | return await PagedList.ToPagedListAsync(_dbSet.OrderBy(x => x.Id), 19 | @params.PageNumber, @params.PageSize); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Questions/QuestionUpdateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 5 | { 6 | public class QuestionUpdateDto 7 | { 8 | [Required, MinLength(5)] 9 | public string Title { get; set; } = String.Empty; 10 | [Required, MinLength(10)] 11 | public string Description { get; set; } = String.Empty; 12 | public string[]? Tags { get; set; } 13 | 14 | public static implicit operator QuestionUpdateDto(Question question) 15 | { 16 | return new QuestionUpdateDto() 17 | { 18 | Title = question.Title, 19 | Description = question.Description, 20 | }; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Controllers/SubmissionsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using RaqamliAvlod.Application.Utils; 3 | 4 | namespace RaqamliAvlod.Api.Controllers; 5 | 6 | [Route("api/submissions")] 7 | [ApiController] 8 | public class SubmissionsController : ControllerBase 9 | { 10 | [HttpGet] 11 | public async Task GetAllAsync([FromQuery] PaginationParams @params) 12 | { 13 | return Ok(); 14 | } 15 | 16 | [HttpGet("{submissionId}")] 17 | public async Task GetAsync(long submissionId) 18 | { 19 | return Ok(); 20 | } 21 | 22 | [HttpGet("{problemSetId}/{userId}")] 23 | public async Task GetSubmissionUserAsync(long problemsetId, 24 | long userId, [FromQuery] PaginationParams @params) 25 | { 26 | return Ok(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/Utils/PaginationParams.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace RaqamliAvlod.Application.Utils 4 | { 5 | public class PaginationParams 6 | { 7 | private const int maxPageSize = 50; 8 | private int pageSize = 10; 9 | 10 | [JsonProperty("pageNumber")] 11 | public int PageNumber { get; set; } = 1; 12 | 13 | [JsonProperty("pageSize")] 14 | public int PageSize 15 | { 16 | get { return pageSize; } 17 | set { pageSize = (value > maxPageSize) ? maxPageSize : value; } 18 | } 19 | 20 | public PaginationParams(int pageNumber, int pageSize) 21 | { 22 | PageNumber = pageNumber; 23 | PageSize = pageSize; 24 | } 25 | 26 | public PaginationParams() 27 | { 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Submissions/ContestSubmissionCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Submissions; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 5 | { 6 | public class ContestSubmissionCreateDto : ProblemSetSubmissionCreateDto 7 | { 8 | [Required] 9 | public long ContestId { get; set; } 10 | 11 | public static implicit operator Submission(ContestSubmissionCreateDto contestSubmissionCreateDto) 12 | { 13 | return new Submission() 14 | { 15 | ContestId = contestSubmissionCreateDto.ContestId, 16 | ProblemSetId = contestSubmissionCreateDto.ProblemSetId, 17 | Language = contestSubmissionCreateDto.Language, 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/RaqamliAvlod.Application.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Users/OwnerViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Users; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Users 4 | { 5 | public class OwnerViewModel 6 | { 7 | public long UserId { get; set; } 8 | 9 | public string FullName { get; set; } = default!; 10 | 11 | public string ImagePath { get; set; } = default!; 12 | 13 | public string Username { get; set; } = default!; 14 | 15 | 16 | public static implicit operator OwnerViewModel(User user) 17 | { 18 | return new OwnerViewModel() 19 | { 20 | UserId = user.Id, 21 | FullName = user.FirstName + " " + user.LastName, 22 | ImagePath = user.ImagePath, 23 | Username = user.Username! 24 | }; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Attributes/PhoneNumberAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Attributes 5 | { 6 | [AttributeUsage(AttributeTargets.Property)] 7 | public class PhoneNumberAttribute : ValidationAttribute 8 | { 9 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 10 | { 11 | string phoneNumber = (string)value!; 12 | Regex regex = new Regex("^(?!0+$)(\\+\\d{1,3}[- ]?)?(?!0+$)\\d{10,15}$"); 13 | 14 | return regex.Match(phoneNumber).Success ? ValidationResult.Success 15 | : new ValidationResult("Please enter valid phone number. Phone must be contains only numbers or + character"); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Questions/IQuestionService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Utils; 2 | using RaqamliAvlod.Application.ViewModels.Questions; 3 | using RaqamliAvlod.Domain.Enums; 4 | using RaqamliAvlod.Infrastructure.Service.Dtos; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Questions; 7 | 8 | public interface IQuestionService 9 | { 10 | Task CreateAsync(QuestionCreateDto dto, long userId); 11 | Task UpdateAsync(long questionId, QuestionCreateDto dto, long userId); 12 | Task DeleteAsync(long questionId, long userId, UserRole userRole); 13 | Task GetAsync(long questionId, long? userId); 14 | Task> GetAllAsync(PaginationParams @params); 15 | Task> SearchAsync(string search, PaginationParams @params); 16 | } 17 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/ProblemSets/ProblemSetTestRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using RaqamliAvlod.DataAccess.DbContexts; 3 | using RaqamliAvlod.DataAccess.Interfaces.ProblemSets; 4 | using RaqamliAvlod.Domain.Entities.ProblemSets; 5 | 6 | namespace RaqamliAvlod.DataAccess.Repositories.ProblemSets 7 | { 8 | public class ProblemSetTestRepository : BaseRepository, 9 | IProblemSetTestRepository 10 | { 11 | public ProblemSetTestRepository(AppDbContext context) : base(context) 12 | { 13 | 14 | } 15 | 16 | public async Task> GetAllByProblemSetId(long problemSetId) 17 | { 18 | return await _dbSet.Where(problemSetTest => problemSetTest.ProblemSetId == problemSetId) 19 | .OrderBy(x => x.Id).ToListAsync(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Questions/QuestionCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 5 | { 6 | public class QuestionCreateDto 7 | { 8 | [Required, MinLength(5)] 9 | public string Title { get; set; } = String.Empty; 10 | [Required, MinLength(10)] 11 | public string Description { get; set; } = String.Empty; 12 | 13 | public IEnumerable Tags { get; set; } = new List(); 14 | 15 | public static implicit operator Question(QuestionCreateDto questionCreateDto) 16 | { 17 | return new Question() 18 | { 19 | Title = questionCreateDto.Title, 20 | Description = questionCreateDto.Description, 21 | }; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Users/IUserService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Users; 4 | using RaqamliAvlod.Infrastructure.Service.Dtos; 5 | using RaqamliAvlod.Infrastructure.Service.Dtos.Accounts; 6 | 7 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Users 8 | { 9 | public interface IUserService 10 | { 11 | Task UpdateAsync(long id, UserUpdateDto viewModel); 12 | Task DeleteAsync(long id); 13 | Task GetIdAsync(long id); 14 | Task GetUsernameAsync(string username); 15 | Task ImageUpdateAsync(long id, ImageUploadDto dto); 16 | Task> GetAllAsync(PaginationParams @params); 17 | Task RoleControlAsync(long userId, ushort roleNum); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Attributes/EmailAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Text.RegularExpressions; 3 | namespace RaqamliAvlod.Attributes 4 | { 5 | [AttributeUsage(AttributeTargets.Property)] 6 | public class EmailAttribute : ValidationAttribute 7 | { 8 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 9 | { 10 | if (value is null) return new ValidationResult("Email can not be null!"); 11 | 12 | Regex regex = new Regex(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); 13 | 14 | if (regex.Match(value.ToString()!).Success) 15 | return ValidationResult.Success; 16 | 17 | return new ValidationResult("Enter correct email!"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Courses/CourseVideoGetViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Courses; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Courses; 4 | 5 | public class CourseVideoGetViewModel : CourseVideoGetAllViewModel 6 | { public string Description { get; set; } = string.Empty; 7 | 8 | 9 | public static implicit operator CourseVideoGetViewModel(CourseVideo courseVideo) 10 | { 11 | return new CourseVideoGetViewModel() 12 | { 13 | Id = courseVideo.Id, 14 | Title = courseVideo.Title, 15 | YouTubeThumbnail = courseVideo.YouTubeThumbnail, 16 | ViewCount = courseVideo.ViewCount, 17 | YouTubeLink = courseVideo.YouTubeLink, 18 | Description = courseVideo.Description, 19 | Duration = courseVideo.Duration, 20 | CreatedAt = courseVideo.CreatedAt 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Interfaces/Questions/IQuestionAnswerService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Utils; 2 | using RaqamliAvlod.Application.ViewModels.Questions; 3 | using RaqamliAvlod.Domain.Enums; 4 | using RaqamliAvlod.Infrastructure.Service.Dtos.Questions; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Interfaces.Questions 7 | { 8 | public interface IQuestionAnswerService 9 | { 10 | Task CreateAsync(long questionId, QuestionAnswerCreateDto dto, long userId); 11 | Task UpdateAsync(long id, QuestionAnswerUpdateDto dto, long userId); 12 | Task DeleteAsync(long id, long userId, UserRole role); 13 | Task> GetAllAsync(long questionId, long? userId, PaginationParams? @params = null); 14 | Task> GetRepliesAsync(long answerId, long? userId, PaginationParams @params); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Attributes/MaxFileSizeAttribute.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using System.ComponentModel.DataAnnotations; 3 | namespace RaqamliAvlod.Attributes 4 | { 5 | public class MaxFileSizeAttribute : ValidationAttribute 6 | { 7 | private readonly int _maxFileSize; 8 | public MaxFileSizeAttribute(int maxFileSize) 9 | { 10 | _maxFileSize = maxFileSize; 11 | } 12 | 13 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 14 | { 15 | var file = value as IFormFile; 16 | if (file is not null) 17 | { 18 | if ((file.Length / 1024 / 1024) > _maxFileSize) 19 | return new ValidationResult($"File must be less than {_maxFileSize} MB"); 20 | } 21 | 22 | return ValidationResult.Success; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Configurations/Dependencies/DataAccessLayerConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using RaqamliAvlod.DataAccess.DbContexts; 3 | using RaqamliAvlod.DataAccess.Interfaces; 4 | using RaqamliAvlod.DataAccess.Repositories; 5 | 6 | namespace RaqamliAvlod.Api.Configurations.Dependencies 7 | { 8 | public static class DataAccessLayerConfiguration 9 | { 10 | public static void AddDataAccessLayer(this WebApplicationBuilder builder) 11 | { 12 | string connectionString = builder.Configuration.GetConnectionString("HerokuProductionDb"); 13 | builder.Services.AddDbContext(options => 14 | { 15 | options.UseNpgsql(connectionString); 16 | options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); 17 | }); 18 | 19 | builder.Services.AddScoped(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/RaqamliAvlod - Backup (3).Infrastructure.Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Questions/QuestionViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Questions; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Questions 4 | { 5 | public class QuestionViewModel : QuestionBaseViewModel 6 | { 7 | public IEnumerable Tags { get; set; } = default!; 8 | public string Description { get; set; } = String.Empty; 9 | public bool CurrentUserIsAuthor { get; set; } = false; 10 | 11 | public static implicit operator QuestionViewModel(Question question) 12 | { 13 | return new QuestionViewModel() 14 | { 15 | Id = question.Id, 16 | Title = question.Title, 17 | Description = question.Description, 18 | ViewCount = question.ViewCount, 19 | Owner = question.Owner, 20 | CreatedAt = question.CreatedAt, 21 | }; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Common/PagedList.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using RaqamliAvlod.Application.Utils; 3 | 4 | namespace CodePower.DataAccess.Common 5 | { 6 | public class PagedList : List 7 | { 8 | public PaginationMetaData MetaData { get; set; } 9 | 10 | public PagedList(List items, int count, int pageNumber, int pageSize) 11 | { 12 | MetaData = new PaginationMetaData(count, pageNumber, pageSize); 13 | AddRange(items); 14 | } 15 | public async static Task> ToPagedListAsync(IQueryable source, 16 | int pageNumber, int pageSize) 17 | { 18 | var count = await source.CountAsync(); 19 | var items = await source.Skip( 20 | (pageNumber - 1) * pageSize).Take(pageSize) 21 | .ToListAsync(); 22 | return new PagedList(items, count, pageNumber, pageSize); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /test/RaqamliAvlod.UnitTest/RaqamliAvlod.UnitTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | all 16 | 17 | 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | all 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:38198", 8 | "sslPort": 44357 9 | } 10 | }, 11 | "profiles": { 12 | "RaqamliAvlod.Api": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "https://localhost:7172;http://localhost:5172", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "swagger", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/RaqamliAvlod.IntegrationTest/RaqamliAvlod.IntegrationTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | all 16 | 17 | 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | all 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Courses/CourseCommentRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.DataAccess.DbContexts; 4 | using RaqamliAvlod.DataAccess.Interfaces.Courses; 5 | using RaqamliAvlod.Domain.Entities.Courses; 6 | 7 | namespace RaqamliAvlod.DataAccess.Repositories.Courses 8 | { 9 | public class CourseCommentRepository : BaseRepository, ICourseCommentRepository 10 | { 11 | public CourseCommentRepository(AppDbContext context) : base(context) 12 | { 13 | 14 | } 15 | public async Task> GetAllByCourseIdAsync(long courseId, PaginationParams @params) 16 | { 17 | var coursecomments = _dbSet.Where(comments => comments.CourseId == courseId).OrderBy(x => x.Id); 18 | 19 | return await PagedList.ToPagedListAsync(coursecomments, @params.PageNumber, @params.PageSize); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Users/User.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Enums; 3 | 4 | namespace RaqamliAvlod.Domain.Entities.Users 5 | { 6 | public class User : Auditable 7 | { 8 | public string FirstName { get; set; } = String.Empty; 9 | public string LastName { get; set; } = String.Empty; 10 | public string? Username { get; set; } 11 | public string ImagePath { get; set; } = String.Empty; 12 | public int ContestCoins { get; set; } 13 | public int ProblemSetCoins { get; set; } 14 | public string PhoneNumber { get; set; } = String.Empty; 15 | public string Email { get; set; } = String.Empty; 16 | public bool EmailConfirmed { get; set; } 17 | public string PasswordHash { get; set; } = String.Empty; 18 | public string Salt { get; set; } = String.Empty; 19 | public DateTime UpdatedAt { get; set; } 20 | public UserRole Role { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/ProblemSets/ProblemSetTestCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.ViewModels.ProblemSets; 2 | using RaqamliAvlod.Domain.Entities.ProblemSets; 3 | using System.ComponentModel.DataAnnotations; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 6 | { 7 | public class ProblemSetTestCreateDto 8 | { 9 | [Required] 10 | public string Input { get; set; } = String.Empty; 11 | 12 | [Required] 13 | public string Output { get; set; } = String.Empty; 14 | 15 | [Required] 16 | public long ProblemSetId { get; set; } 17 | 18 | public static implicit operator ProblemSetTest( ProblemSetTestCreateDto problemSetTest) 19 | { 20 | return new ProblemSetTest() 21 | { 22 | Input = problemSetTest.Input, 23 | Output = problemSetTest.Output, 24 | ProblemSetId = problemSetTest.ProblemSetId 25 | }; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Attributes/NameAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace RaqamliAvlod.Attributes 5 | { 6 | [AttributeUsage(AttributeTargets.Property)] 7 | public class NameAttribute : ValidationAttribute 8 | { 9 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 10 | { 11 | if (value is null) return new ValidationResult("Name cannot be null!"); 12 | else 13 | { 14 | string name = value.ToString()!; 15 | 16 | Regex regex = new Regex(@"^(?=.{1,40}$)[a-zA-Z]+(?:[-'\s][a-zA-Z]+)*$"); 17 | 18 | if (regex.Match(name).Success) 19 | return ValidationResult.Success; 20 | 21 | return new ValidationResult("Please enter valid name. Name must be contains only letters or ' character"); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Questions/QuestionBaseViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.ViewModels.Users; 2 | using RaqamliAvlod.Domain.Entities.Questions; 3 | 4 | namespace RaqamliAvlod.Application.ViewModels.Questions 5 | { 6 | public class QuestionBaseViewModel 7 | { 8 | public long Id { get; set; } 9 | public string Title { get; set; } = String.Empty; 10 | public int ViewCount { get; set; } 11 | public OwnerViewModel Owner { get; set; } = null!; 12 | public DateTime CreatedAt { get; set; } 13 | 14 | public static implicit operator QuestionBaseViewModel(Question question) 15 | { 16 | return new QuestionBaseViewModel() 17 | { 18 | Id = question.Id, 19 | Title = question.Title, 20 | ViewCount = question.ViewCount, 21 | Owner = (OwnerViewModel)question.Owner, 22 | CreatedAt = question.CreatedAt, 23 | }; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Contests/ContestStandingsRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.DataAccess.DbContexts; 4 | using RaqamliAvlod.DataAccess.Interfaces.Contests; 5 | using RaqamliAvlod.Domain.Entities.Contests; 6 | 7 | namespace RaqamliAvlod.DataAccess.Repositories.Contests 8 | { 9 | public class ContestStandingsRepository : BaseRepository, IContestStandingsRepository 10 | { 11 | public ContestStandingsRepository(AppDbContext context) : base(context) 12 | { 13 | 14 | } 15 | 16 | public async Task> GetAllByContestIdAsync(long contestId, PaginationParams @params) 17 | { 18 | var contestStandings = _dbSet.Where(standings => standings.ContestId == contestId).OrderBy(x => x.Id); 19 | 20 | return await PagedList.ToPagedListAsync(contestStandings, @params.PageNumber, @params.PageSize); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/RaqamliAvlod.DataAccess.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | all 22 | runtime; build; native; contentfiles; analyzers; buildtransitive 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Security/PasswordHasher.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Infrastructure.Service.Security 2 | { 3 | public class PasswordHasher 4 | { 5 | private const string _key = "fed9e0da-9169-41f2-9745-84790ddfabd9"; 6 | public static (string Hash, string Salt) Hash(string password) 7 | { 8 | string salt = GenerateSalt(); 9 | string hash = BCrypt.Net.BCrypt.HashPassword(salt + password + _key); 10 | return (Hash: hash, Salt: salt); 11 | } 12 | 13 | public static bool Verify(string password, string salt, string hash) 14 | { 15 | return BCrypt.Net.BCrypt.Verify(salt + password + _key, hash); 16 | } 17 | 18 | public static string Hash(string password, string salt) 19 | { 20 | return BCrypt.Net.BCrypt.HashPassword(salt + password + _key); 21 | } 22 | 23 | private static string GenerateSalt() 24 | { 25 | return Guid.NewGuid().ToString(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/Submissions/Submission.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Entities.Contests; 3 | using RaqamliAvlod.Domain.Entities.ProblemSets; 4 | using RaqamliAvlod.Domain.Entities.Users; 5 | 6 | namespace RaqamliAvlod.Domain.Entities.Submissions 7 | { 8 | public class Submission : Auditable 9 | { 10 | public string Result { get; set; } = String.Empty; 11 | public string Language { get; set; } = String.Empty; 12 | public int ExecutionTime { get; set; } 13 | public int MemoryUsage { get; set; } 14 | public int LengthOfCode { get; set; } 15 | public string Code { get; set; } = String.Empty; 16 | 17 | public long UserId { get; set; } 18 | public virtual User User { get; set; } = null!; 19 | 20 | public long ProblemSetId { get; set; } 21 | public virtual ProblemSet ProblemSet { get; set; } = null!; 22 | 23 | public long? ContestId { get; set; } 24 | public virtual Contest Contest { get; set; } = null!; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Submissions/ProblemSetSubmissionCreateDto.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using RaqamliAvlod.Attributes; 3 | using RaqamliAvlod.Domain.Entities.Submissions; 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 7 | { 8 | public class ProblemSetSubmissionCreateDto 9 | { 10 | [Required] 11 | public long ProblemSetId { get; set; } 12 | 13 | [Required] 14 | public string Language { get; set; } = string.Empty; 15 | 16 | [Required] 17 | [AllowedFiles(new string[] { ".c", ".cpp", ".py", ".java" })] 18 | public IFormFile Code { get; set; } = null!; 19 | 20 | public static implicit operator Submission(ProblemSetSubmissionCreateDto submissionCreateDto) 21 | { 22 | return new Submission() 23 | { 24 | ProblemSetId = submissionCreateDto.ProblemSetId, 25 | Language = submissionCreateDto.Language 26 | }; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Courses/CourseCommentViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.ViewModels.Users; 2 | using RaqamliAvlod.Domain.Entities.Courses; 3 | 4 | namespace RaqamliAvlod.Application.ViewModels.Courses 5 | { 6 | public class CourseCommentViewModel 7 | { 8 | public long Id { get; set; } 9 | public OwnerViewModel Owner { get; set; } = null!; 10 | public string CommentText { get; set; } = string.Empty; 11 | public bool IsCurrentUserIsAuthor { get; set; } 12 | public long CourseId { get; set; } 13 | 14 | public DateTime CreatedAt { get; set; } 15 | 16 | public static implicit operator CourseCommentViewModel(CourseComment courseComment) 17 | { 18 | return new CourseCommentViewModel() 19 | { 20 | Id = courseComment.Id, 21 | CommentText = courseComment.CommentText, 22 | CourseId = courseComment.CourseId, 23 | CreatedAt = courseComment.CreatedAt, 24 | }; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Contests/ContestSubmissionInfoRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.DataAccess.DbContexts; 4 | using RaqamliAvlod.DataAccess.Interfaces.Contests; 5 | using RaqamliAvlod.Domain.Entities.Contests; 6 | 7 | namespace RaqamliAvlod.DataAccess.Repositories.Contests 8 | { 9 | public class ContestSubmissionInfoRepository : BaseRepository, IContestSubmissionInfoRepository 10 | { 11 | public ContestSubmissionInfoRepository(AppDbContext context) : base(context) 12 | { 13 | } 14 | 15 | public async Task> GetAllByContestIdAsync(long contestId, PaginationParams @params) 16 | { 17 | var submissionInfo = _dbSet.Where(info => info.ContestStandingsId == contestId) 18 | .OrderBy(x => x.Id); 19 | 20 | return await PagedList.ToPagedListAsync(submissionInfo, 21 | @params.PageNumber, @params.PageSize); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Courses/CourseVideoRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Courses; 4 | using RaqamliAvlod.DataAccess.DbContexts; 5 | using RaqamliAvlod.DataAccess.Interfaces.Courses; 6 | using RaqamliAvlod.Domain.Entities.Courses; 7 | 8 | namespace RaqamliAvlod.DataAccess.Repositories.Courses 9 | { 10 | public class CourseVideoRepository : BaseRepository, ICourseVideoRepository 11 | { 12 | public CourseVideoRepository(AppDbContext context) : base(context) 13 | { 14 | } 15 | public async Task> GetAllByCourseIdAsync(long courseId, PaginationParams @params) 16 | { 17 | var query = _dbSet.Where(video => video.CourseId == courseId) 18 | .OrderByDescending(x => x.Id).Select(course => (CourseVideoGetAllViewModel)course); 19 | return await PagedList.ToPagedListAsync(query, @params.PageNumber, @params.PageSize); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Attributes/AllowedFilesAttribute.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Attributes 5 | { 6 | [AttributeUsage(AttributeTargets.Property)] 7 | public class AllowedFilesAttribute : ValidationAttribute 8 | { 9 | private readonly string[] _extensions; 10 | public AllowedFilesAttribute(string[] extensions) 11 | { 12 | _extensions = extensions; 13 | } 14 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 15 | { 16 | var file = value as IFormFile; 17 | if (file is not null) 18 | { 19 | var extension = Path.GetExtension(file.FileName); 20 | if (_extensions.Contains(extension.ToLower())) 21 | return ValidationResult.Success; 22 | else return new ValidationResult("This file extension is not supperted!"); 23 | } 24 | else return ValidationResult.Success; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Red Minds Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Configurations/JwtConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication.JwtBearer; 2 | using Microsoft.IdentityModel.Tokens; 3 | using System.Text; 4 | 5 | namespace RaqamliAvlod.Api.Configurations 6 | { 7 | public static class JwtConfiguration 8 | { 9 | public static void ConfigureJwt(this WebApplicationBuilder builder) 10 | { 11 | var _config = builder.Configuration.GetSection("Jwt"); 12 | builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 13 | .AddJwtBearer(options => 14 | { 15 | options.TokenValidationParameters = new TokenValidationParameters() 16 | { 17 | ValidateIssuer = true, 18 | ValidIssuer = _config["Issuer"], 19 | ValidateAudience = false, 20 | //ValidateLifetime = true, 21 | ValidateIssuerSigningKey = true, 22 | IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Key"])) 23 | }; 24 | }); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Contests/ContestViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Contests; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Contests 4 | { 5 | public class ContestViewModel 6 | { 7 | public long Id { get; set; } 8 | public string Title { get; set; } = String.Empty; 9 | public string Description { get; set; } = String.Empty; 10 | public DateTime StartDate { get; set; } 11 | public DateTime EndDate { get; set; } 12 | public int ProblemSetCount { get; set; } 13 | public bool IsCompleted { get; set; } 14 | public bool IsPublic { get; set; } 15 | 16 | public static implicit operator ContestViewModel(Contest contest) 17 | { 18 | return new ContestViewModel() 19 | { 20 | Id = contest.Id, 21 | Title = contest.Title, 22 | Description = contest.Description, 23 | StartDate = contest.StartDate, 24 | EndDate = contest.EndDate, 25 | IsCompleted = contest.IsCompleted, 26 | IsPublic = contest.IsPublic 27 | }; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Users/UserUpdateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Attributes; 2 | using RaqamliAvlod.Domain.Entities.Users; 3 | using RaqamliAvlod.Infrastructure.Service.Attributes; 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 7 | { 8 | public class UserUpdateDto 9 | { 10 | [Required, Name] 11 | public string Firstname { get; set; } = string.Empty; 12 | 13 | [Required, Name] 14 | public string Lastname { get; set; } = string.Empty; 15 | 16 | [Required, UsernameCheck] 17 | public string Username { get; set; } = string.Empty; 18 | 19 | [Required, PhoneNumber] 20 | public string PhoneNumber { get; set; } = string.Empty; 21 | 22 | public static implicit operator User(UserUpdateDto userUpdate) 23 | { 24 | return new User() 25 | { 26 | FirstName = userUpdate.Firstname, 27 | LastName = userUpdate.Lastname, 28 | Username = userUpdate.Username, 29 | PhoneNumber = userUpdate.PhoneNumber, 30 | }; 31 | } 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Contests/ContestCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Contests; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 5 | { 6 | public class ContestCreateDto 7 | { 8 | [Required, MinLength(5)] 9 | public string Title { get; set; } = String.Empty; 10 | [Required, MinLength(5)] 11 | public string Description { get; set; } = String.Empty; 12 | [Required] 13 | public DateTime StartDate { get; set; } 14 | [Required] 15 | public DateTime EndDate { get; set; } 16 | [Required] 17 | public bool IsPublic { get; set; } 18 | 19 | public static implicit operator Contest(ContestCreateDto contestCreateDto) 20 | { 21 | return new Contest() 22 | { 23 | Title = contestCreateDto.Title, 24 | Description = contestCreateDto.Description, 25 | StartDate = contestCreateDto.StartDate, 26 | EndDate = contestCreateDto.EndDate, 27 | IsPublic = contestCreateDto.IsPublic, 28 | }; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Courses/CourseUpdateDto.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using RaqamliAvlod.Attributes; 3 | using RaqamliAvlod.Domain.Entities.Courses; 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 7 | { 8 | public class CourseUpdateDto 9 | { 10 | [Required] 11 | public string Title { get; set; } = string.Empty; 12 | [Required] 13 | public string Info { get; set; } = string.Empty; 14 | [Required] 15 | public string Type { get; set; } = string.Empty; 16 | 17 | [AllowedFiles(new string[] { ".jpg", ".png", ".jpeg" })] 18 | public IFormFile? Image { get; set; } 19 | public float Price { get; set; } 20 | 21 | [Required] 22 | public long OwnerId { get; set; } 23 | 24 | public static implicit operator Course(CourseUpdateDto course) 25 | { 26 | return new Course() 27 | { 28 | Title = course.Title, 29 | Info = course.Info, 30 | Type = course.Type, 31 | Price = course.Price, 32 | OwnerId = course.OwnerId 33 | }; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Domain/Entities/ProblemSets/ProblemSet.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Common; 2 | using RaqamliAvlod.Domain.Entities.Contests; 3 | using RaqamliAvlod.Domain.Entities.Users; 4 | 5 | namespace RaqamliAvlod.Domain.Entities.ProblemSets 6 | { 7 | public class ProblemSet : Auditable 8 | { 9 | public string Name { get; set; } = String.Empty; 10 | public string Description { get; set; } = String.Empty; 11 | public string Type { get; set; } = String.Empty; 12 | public string InputDescription { get; set; } = String.Empty; 13 | public string OutputDescription { get; set; } = String.Empty; 14 | public string Note { get; set; } = String.Empty; 15 | public int TimeLimit { get; set; } 16 | public int MemoryLimit { get; set; } 17 | public short Difficulty { get; set; } 18 | public bool IsPublic { get; set; } = false; 19 | public short ContestCoins { get; set; } 20 | public char ContestIdentifier { get; set; } 21 | 22 | public long OwnerId { get; set; } 23 | public virtual User Owner { get; set; } = null!; 24 | 25 | public long? ContestId { get; set; } 26 | public virtual Contest Contest { get; set; } = null!; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Courses/CourseVideoGetAllViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Courses; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Courses 4 | { 5 | public class CourseVideoGetAllViewModel 6 | { 7 | public long Id { get; set; } 8 | public string Title { get; set; } = string.Empty; 9 | public string YouTubeThumbnail { get; set; } = string.Empty; 10 | public int ViewCount { get; set; } 11 | public string YouTubeLink { get; set; } = string.Empty; 12 | public string Duration { get; set; } = string.Empty; 13 | public DateTime CreatedAt { get; set; } 14 | 15 | public static implicit operator CourseVideoGetAllViewModel(CourseVideo courseVideo) 16 | { 17 | return new CourseVideoGetAllViewModel() 18 | { 19 | Id = courseVideo.Id, 20 | Title = courseVideo.Title, 21 | YouTubeThumbnail = courseVideo.YouTubeThumbnail, 22 | ViewCount = courseVideo.ViewCount, 23 | YouTubeLink = courseVideo.YouTubeLink, 24 | Duration = courseVideo.Duration, 25 | CreatedAt = courseVideo.CreatedAt 26 | }; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/RaqamliAvlod.Infrastructure.Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Users/UserViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Users; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Users 4 | { 5 | public class UserViewModel 6 | { 7 | public long Id { get; set; } 8 | public string Firstname { get; set; } = string.Empty; 9 | public string Lastname { get; set; } = string.Empty; 10 | public string Username { get; set; } = string.Empty; 11 | public string CreatedAt { get; set; } = string.Empty; 12 | public string ImagePath { get; set; } = string.Empty; 13 | public int ContestCoins { get; set; } 14 | public int ProblemSetCoins { get; set; } 15 | 16 | public static implicit operator UserViewModel(User user) 17 | { 18 | return new UserViewModel() 19 | { 20 | Id = user.Id, 21 | Firstname = user.FirstName, 22 | Lastname = user.LastName, 23 | Username = user.Username, 24 | ImagePath = user.ImagePath, 25 | CreatedAt = user.CreatedAt.ToString(), 26 | ContestCoins = user.ContestCoins, 27 | ProblemSetCoins = user.ProblemSetCoins 28 | }; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Submissions/SubmissionViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Submissions; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Submissions 4 | { 5 | public class SubmissionViewModel 6 | { 7 | public string Result { get; set; } = String.Empty; 8 | public string Language { get; set; } = String.Empty; 9 | public int ExecutionTime { get; set; } 10 | public int MemoryUsage { get; set; } 11 | public int LengthOfCode { get; set; } 12 | public string Username { get; set; } = string.Empty; 13 | public long ProblemSetId { get; set; } 14 | public DateTime CreatedAt { get; set; } 15 | 16 | public static implicit operator SubmissionViewModel(Submission submission) 17 | { 18 | return new SubmissionViewModel() 19 | { 20 | Result = submission.Result, 21 | Language = submission.Language, 22 | ExecutionTime = submission.ExecutionTime, 23 | MemoryUsage = submission.MemoryUsage, 24 | LengthOfCode = submission.LengthOfCode, 25 | ProblemSetId = submission.ProblemSetId, 26 | CreatedAt = submission.CreatedAt, 27 | }; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Submissions/ContestSubmissionViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Entities.Submissions; 2 | 3 | namespace RaqamliAvlod.Application.ViewModels.Submissions 4 | { 5 | public class ContestSubmissionViewModel 6 | { 7 | public string Result { get; set; } = String.Empty; 8 | public string Language { get; set; } = String.Empty; 9 | public int ExecutionTime { get; set; } 10 | public int MemoryUsage { get; set; } 11 | public int LengthOfCode { get; set; } 12 | public string Username { get; set; } = string.Empty; 13 | public long ProblemSetId { get; set; } 14 | public long ContestId { get; set; } 15 | 16 | public static implicit operator ContestSubmissionViewModel(Submission submission) 17 | { 18 | return new ContestSubmissionViewModel() 19 | { 20 | Result = submission.Result, 21 | Language = submission.Language, 22 | ExecutionTime = submission.ExecutionTime, 23 | MemoryUsage = submission.MemoryUsage, 24 | LengthOfCode = submission.LengthOfCode, 25 | ProblemSetId = submission.ProblemSetId, 26 | ContestId = (long)submission.ContestId! 27 | }; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/RaqamliAvlod.Api.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Accounts/AccountCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Attributes; 2 | using RaqamliAvlod.Domain.Entities.Users; 3 | using RaqamliAvlod.Infrastructure.Service.Attributes; 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 7 | { 8 | public class AccountCreateDto 9 | { 10 | [Required, MinLength(3), Name] 11 | public string Firstname { get; set; } = string.Empty; 12 | 13 | [Required, MinLength(3), Name] 14 | public string Lastname { get; set; } = string.Empty; 15 | 16 | [Required] 17 | [PhoneNumber] 18 | public string PhoneNumber { get; set; } = string.Empty; 19 | 20 | [Required, Email] 21 | public string Email { get; set; } = string.Empty; 22 | 23 | [Required, StrongPassword] 24 | public string Password { get; set; } = string.Empty; 25 | 26 | 27 | public static implicit operator User(AccountCreateDto accountCreateDto) 28 | { 29 | return new User() 30 | { 31 | FirstName = accountCreateDto.Firstname, 32 | LastName = accountCreateDto.Lastname, 33 | PhoneNumber = accountCreateDto.PhoneNumber, 34 | Email = accountCreateDto.Email, 35 | }; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Interfaces/IUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.DataAccess.Interfaces.Contests; 2 | using RaqamliAvlod.DataAccess.Interfaces.Courses; 3 | using RaqamliAvlod.DataAccess.Interfaces.ProblemSets; 4 | using RaqamliAvlod.DataAccess.Interfaces.Questions; 5 | using RaqamliAvlod.DataAccess.Interfaces.Submissions; 6 | using RaqamliAvlod.DataAccess.Interfaces.Users; 7 | 8 | namespace RaqamliAvlod.DataAccess.Interfaces 9 | { 10 | public interface IUnitOfWork 11 | { 12 | public IContestRepository Contests { get; } 13 | public IContestStandingsRepository ContestStandings { get; } 14 | public IContestSubmissionInfoRepository ContestSubmissionInfo { get; } 15 | public ICourseCommentRepository CourseComments { get; } 16 | public ICourseRepository Courses { get; } 17 | public ICourseVideoRepository CourseVideos { get; } 18 | public IProblemSetRepository ProblemSets { get; } 19 | public IProblemSetTestRepository ProblemSetTests { get; } 20 | public IQuestionAnswerRepository QuestionAnswers { get; } 21 | public IQuestionRepository Questions { get; } 22 | public IQuestionTagRepository QuestionTags { get; } 23 | public ITagRepository Tags { get; } 24 | public ISubmissionRepository Submissions { get; } 25 | public IUserRepository Users { get; } 26 | } 27 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Courses/CourseViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.ViewModels.Users; 2 | using RaqamliAvlod.Domain.Entities.Courses; 3 | 4 | namespace RaqamliAvlod.Application.ViewModels.Courses 5 | { 6 | public class CourseViewModel 7 | { 8 | public long Id { get; set; } 9 | public string Title { get; set; } = string.Empty; 10 | public string Info { get; set; } = string.Empty; 11 | public string Type { get; set; } = string.Empty; 12 | public string ImagePath { get; set; } = string.Empty; 13 | public float Price { get; set; } 14 | public DateTime CreatedAt { get; set; } 15 | public DateTime UpdatedAt { get; set; } 16 | 17 | public OwnerViewModel Owner { get; set; } = null!; 18 | 19 | public static implicit operator CourseViewModel(Course course) 20 | { 21 | return new CourseViewModel() 22 | { 23 | Id = course.Id, 24 | Title = course.Title, 25 | Info = course.Info, 26 | Type = course.Type, 27 | ImagePath = course.ImagePath, 28 | Price = course.Price, 29 | Owner = course.Owner, 30 | CreatedAt = course.CreatedAt, 31 | UpdatedAt = course.UpdatedAt 32 | }; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Users/UserRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using Microsoft.EntityFrameworkCore; 3 | using RaqamliAvlod.Application.Utils; 4 | using RaqamliAvlod.DataAccess.DbContexts; 5 | using RaqamliAvlod.DataAccess.Interfaces.Users; 6 | using RaqamliAvlod.Domain.Entities.Users; 7 | 8 | namespace RaqamliAvlod.DataAccess.Repositories.Users 9 | { 10 | public class UserRepository : GenericRepository, IUserRepository 11 | { 12 | public UserRepository(AppDbContext context) : base(context) 13 | { 14 | 15 | } 16 | 17 | public async Task GetByEmailAsync(string email) 18 | => await _dbcontext.Users.FirstOrDefaultAsync(user => user.Email == email); 19 | 20 | public async Task GetByUsernameAsync(string username) 21 | => await _dbcontext.Users.FirstOrDefaultAsync(user => user.Username == username); 22 | 23 | public async Task GetByPhonNumberAsync(string phoneNumber) 24 | => await _dbcontext.Users.FirstOrDefaultAsync(user => user.PhoneNumber == phoneNumber); 25 | public override async Task> GetAllAsync(PaginationParams @params) 26 | => (await PagedList.ToPagedListAsync(_dbSet.Where(p => p.EmailConfirmed.Equals(true)) 27 | .OrderBy(user => user.Id), @params.PageNumber, @params.PageSize)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/Courses/CourseCreateDto.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using RaqamliAvlod.Attributes; 3 | using RaqamliAvlod.Domain.Entities.Courses; 4 | using RaqamliAvlod.Infrastructure.Service.Attributes; 5 | using System.ComponentModel.DataAnnotations; 6 | 7 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 8 | { 9 | public class CourseCreateDto 10 | { 11 | [Required, MinLength(5)] 12 | public string Title { get; set; } = string.Empty; 13 | 14 | [Required] 15 | public string Info { get; set; } = string.Empty; 16 | 17 | [Required] 18 | public string Type { get; set; } = string.Empty; 19 | 20 | 21 | [AllowedFiles(new string[] { ".jpg", ".png", ".jpeg" })] 22 | public IFormFile? Image { get; set; } 23 | 24 | [Integer] 25 | public float Price { get; set; } 26 | 27 | [Required] 28 | public long OwnerId { get; set; } 29 | 30 | public static implicit operator Course(CourseCreateDto courseCreateDto) 31 | { 32 | return new Course() 33 | { 34 | Title = courseCreateDto.Title, 35 | Info = courseCreateDto.Info, 36 | Type = courseCreateDto.Type, 37 | Price = courseCreateDto.Price, 38 | OwnerId = courseCreateDto.OwnerId 39 | }; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Questions/TagRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using RaqamliAvlod.DataAccess.DbContexts; 3 | using RaqamliAvlod.DataAccess.Interfaces.Questions; 4 | using RaqamliAvlod.Domain.Entities.Questions; 5 | 6 | namespace RaqamliAvlod.DataAccess.Repositories.Questions 7 | { 8 | public class TagRepository : BaseRepository, ITagRepository 9 | { 10 | public TagRepository(AppDbContext context) : base(context) 11 | { 12 | } 13 | 14 | public async Task> AddRangeAsync(IEnumerable tags) 15 | { 16 | List entityTags = new(); 17 | foreach (var tag in tags) 18 | { 19 | var entityTag = new Tag() { TagName = tag, ViewCount = 0 }; 20 | _dbcontext.Add(entityTag); 21 | await _dbcontext.SaveChangesAsync(); 22 | entityTags.Add(entityTag); 23 | } 24 | return entityTags; 25 | } 26 | 27 | public async Task FindByNameAsync(string name) 28 | => await _dbSet.FirstOrDefaultAsync(tag => tag.TagName == name); 29 | 30 | public async Task> SearchAsync(string name) 31 | => await _dbSet.Where(p => p.TagName.Contains(name)) 32 | .OrderBy(x=>x.TagName).Take(10) 33 | .ToListAsync(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/Common/EmailService.cs: -------------------------------------------------------------------------------- 1 | using MailKit.Net.Smtp; 2 | using MailKit.Security; 3 | using Microsoft.Extensions.Configuration; 4 | using MimeKit; 5 | using MimeKit.Text; 6 | using RaqamliAvlod.Infrastructure.Service.Dtos; 7 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 8 | 9 | 10 | namespace RaqamliAvlod.Infrastructure.Service.Services.Common 11 | { 12 | public class EmailService : IEmailService 13 | { 14 | private readonly IConfigurationSection _config; 15 | 16 | public EmailService(IConfiguration configuration) 17 | { 18 | _config = configuration.GetSection("Email"); 19 | } 20 | 21 | public async Task SendAsync(EmailMessage message) 22 | { 23 | var email = new MimeMessage(); 24 | email.From.Add(MailboxAddress.Parse(_config["EmailAddress"])); 25 | email.To.Add(MailboxAddress.Parse(message.To)); 26 | email.Subject = message.Subject; 27 | email.Body = new TextPart(TextFormat.Html) { Text = message.Body.ToString() }; 28 | 29 | var smtp = new SmtpClient(); 30 | await smtp.ConnectAsync(_config["Host"], 587, SecureSocketOptions.StartTls); 31 | await smtp.AuthenticateAsync(_config["EmailAddress"], _config["Password"]); 32 | await smtp.SendAsync(email); 33 | await smtp.DisconnectAsync(true); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Configurations/SwaggerAuthConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.OpenApi.Models; 2 | 3 | namespace RaqamliAvlod.Api.Configurations 4 | { 5 | public static class SwaggerAuthConfiguration 6 | { 7 | public static void ConfigureSwaggerAuthorize(this IServiceCollection services) 8 | { 9 | services.AddSwaggerGen(c => 10 | { 11 | c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme 12 | { 13 | Name = "Authorization", 14 | Description = 15 | "JWT Authorization header using the Bearer scheme. " + 16 | "Example: \"Authorization: Bearer {token}\"", 17 | In = ParameterLocation.Header, 18 | Type = SecuritySchemeType.ApiKey 19 | }); 20 | 21 | c.AddSecurityRequirement(new OpenApiSecurityRequirement 22 | { 23 | { 24 | new OpenApiSecurityScheme 25 | { 26 | Reference = new OpenApiReference 27 | { 28 | Type = ReferenceType.SecurityScheme, 29 | Id = "Bearer" 30 | } 31 | }, 32 | new string[] { } 33 | } 34 | }); 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Questions/QuestionTagRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.DataAccess.DbContexts; 4 | using RaqamliAvlod.DataAccess.Interfaces.Questions; 5 | using RaqamliAvlod.Domain.Entities.Questions; 6 | 7 | namespace RaqamliAvlod.DataAccess.Repositories.Questions 8 | { 9 | public class QuestionTagRepository : BaseRepository, IQuestionTagRepository 10 | { 11 | public QuestionTagRepository(AppDbContext context) : base(context) 12 | { 13 | } 14 | 15 | public async Task> GetAllTagsFromQuestionAsync(long questionId, PaginationParams @params) 16 | { 17 | var questionTags = _dbSet.Where(tag => tag.QuestionId == questionId).OrderBy(x => x.Id); 18 | 19 | return await PagedList.ToPagedListAsync(questionTags, @params.PageNumber, @params.PageSize); 20 | } 21 | 22 | public async Task AddRangeAsync(IEnumerable questionTags) 23 | { 24 | await _dbSet.AddRangeAsync(questionTags); 25 | await _dbcontext.SaveChangesAsync(); 26 | } 27 | 28 | public async Task DeleteQuestionTagsAsync(long questionId) 29 | { 30 | var questionTags = _dbSet.Where(x => x.QuestionId == questionId); 31 | _dbSet.RemoveRange(questionTags); 32 | await _dbcontext.SaveChangesAsync(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Managers/IdentityHelperService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using RaqamliAvlod.Domain.Enums; 3 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Managers 6 | { 7 | public class IdentityHelperService : IIdentityHelperService 8 | { 9 | private readonly IHttpContextAccessor _accessor; 10 | 11 | public IdentityHelperService(IHttpContextAccessor accessor) 12 | { 13 | this._accessor = accessor; 14 | } 15 | 16 | public string GetUserEmail() 17 | { 18 | var res = _accessor.HttpContext!.User.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"); 19 | return res is not null ? res.Value : string.Empty; 20 | } 21 | 22 | public long? GetUserId() 23 | { 24 | var res = _accessor.HttpContext!.User.FindFirst("Id"); 25 | return res is not null ? long.Parse(res.Value) : null; 26 | } 27 | 28 | public string GetUserName() 29 | { 30 | var res = _accessor.HttpContext!.User.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"); 31 | return res is not null ? res.Value : string.Empty; 32 | } 33 | 34 | public UserRole? GetUserRole() 35 | { 36 | var res = _accessor.HttpContext!.User.FindFirst("http://schemas.microsoft.com/ws/2008/06/identity/claims/role"); 37 | return res is not null ? Enum.Parse(res.Value) : null; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Security/AuthManager.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.IdentityModel.Tokens; 3 | using RaqamliAvlod.Domain.Entities.Users; 4 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 5 | using System.IdentityModel.Tokens.Jwt; 6 | using System.Security.Claims; 7 | using System.Text; 8 | 9 | namespace RaqamliAvlod.Infrastructure.Service.Security 10 | { 11 | public class AuthManager : IAuthManager 12 | { 13 | private readonly IConfigurationSection _configuration; 14 | 15 | public AuthManager(IConfiguration configuration) 16 | { 17 | _configuration = configuration.GetSection("Jwt"); 18 | } 19 | 20 | public string GenerateToken(User user) 21 | { 22 | var claims = new[] 23 | { 24 | new Claim("Id", user.Id.ToString()), 25 | new Claim(ClaimTypes.Email, user.Email), 26 | new Claim(ClaimTypes.Name, user.FirstName), 27 | new Claim(ClaimTypes.Role, user.Role.ToString()) 28 | }; 29 | 30 | var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Key"])); 31 | var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature); 32 | var tokenDescription = new JwtSecurityToken(_configuration["Issuer"], _configuration["Audience"], claims, 33 | expires: DateTime.Now.AddMinutes(double.Parse(_configuration["Lifetime"])), 34 | signingCredentials: credentials); 35 | 36 | return new JwtSecurityTokenHandler().WriteToken(tokenDescription); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/Utils/PaginationMetaData.cs: -------------------------------------------------------------------------------- 1 | namespace RaqamliAvlod.Application.Utils 2 | { 3 | public class PaginationMetaData 4 | { 5 | public uint CurrentPage { get; private set; } 6 | public uint TotalPages { get; private set; } 7 | public uint PageSize { get; private set; } 8 | public uint TotalCount { get; private set; } 9 | public bool IsFirstPage { get; private set; } 10 | public bool IsLastPage { get; private set; } 11 | public bool HasPrevious { get; private set; } 12 | public bool HasNext { get; private set; } 13 | 14 | public PaginationMetaData(int totalCount, PaginationParams @params) 15 | { 16 | TotalCount = (uint)totalCount; 17 | CurrentPage = (uint)@params.PageNumber; 18 | PageSize = (uint)@params.PageSize; 19 | TotalPages = (uint)Math.Ceiling((double)totalCount / @params.PageSize); 20 | IsFirstPage = @params.PageNumber == 1; 21 | IsLastPage = @params.PageNumber == TotalPages; 22 | HasPrevious = @params.PageNumber > 1; 23 | HasNext = @params.PageNumber < TotalPages; 24 | } 25 | 26 | public PaginationMetaData(int totalCount, int pageIndex, int pageSize) 27 | { 28 | TotalCount = (uint)totalCount; 29 | CurrentPage = (uint)pageIndex; 30 | PageSize = (uint)pageSize; 31 | TotalPages = (uint)Math.Ceiling((double)totalCount / pageSize); 32 | IsFirstPage = pageIndex == 1; 33 | IsLastPage = pageIndex == TotalPages; 34 | HasPrevious = pageIndex > 1; 35 | HasNext = pageIndex < TotalPages; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Controllers/AccountsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos; 4 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Users; 5 | 6 | namespace RaqamliAvlod.Api.Controllers; 7 | 8 | [Route("api/accounts")] 9 | [ApiController] 10 | public class AccountsController : ControllerBase 11 | { 12 | private readonly IAccountService _accountService; 13 | public AccountsController(IAccountService accountService) 14 | { 15 | _accountService = accountService; 16 | } 17 | 18 | [HttpPost("register"), AllowAnonymous] 19 | public async Task RegistrateAsync([FromForm] AccountCreateDto accountCreateViewModel) 20 | => Ok(await _accountService.RegisterAsync(accountCreateViewModel)); 21 | 22 | [HttpPost("login"), AllowAnonymous] 23 | public async Task LoginAsync([FromForm] AccountLoginDto accountLoginViewModel) 24 | => Ok(new { Token = await _accountService.LogInAsync(accountLoginViewModel)}); 25 | 26 | [HttpPost("verifyemail")] 27 | public async Task VerifyEmail([FromForm] VerifyEmailDto verifyEmail) 28 | => Ok(await _accountService.VerifyEmailAsync(verifyEmail)); 29 | 30 | [HttpPost("reset-password"), AllowAnonymous] 31 | public async Task ForgotPasswordAsync([FromQuery] UserResetPasswordDto userReset) 32 | => Ok(await _accountService.VerifyPasswordAsync(userReset)); 33 | 34 | [HttpPost("sendcode"), AllowAnonymous] 35 | public async Task SendToEmail([FromBody] SendToEmailDto sendTo) 36 | { 37 | await _accountService.SendCodeAsync(sendTo); 38 | return Ok(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "Serilog": { 9 | "MinimumLevel": { 10 | "Default": "Warning", 11 | "Overrides": { 12 | "Microsoft": "Warning", 13 | "Microsoft.Hosting.Lifetime": "Warning" 14 | } 15 | }, 16 | "Using": [ "Serilog.Sinks.File", "Serilog.Sinks.TelegramBot" ], 17 | "WriteTo": [ 18 | { 19 | "Name": "File", 20 | "Args": { 21 | "path": "bin/logs/log.txt", 22 | "rollingInterval": "Day" 23 | } 24 | }, 25 | { 26 | "Name": "TelegramBot", 27 | "Args": { 28 | "Token": "5768516639:AAFs0Eq7qlgF_qba5pBeOlJbsCoYaZuL5os", 29 | "ChatId": "1001985365", 30 | "ReadableApplicationName": "SimpleApplication", 31 | "UseEmoji": true, 32 | "RestrictedToMinimumLevel": "Warning", 33 | "BatchPostingLimit": 5, 34 | "Period": "0.00:00:20", 35 | "Mode": "Logs" 36 | } 37 | } 38 | ] 39 | }, 40 | "ConnectionStrings": { 41 | "HerokuProductionDb": "Host=ec2-54-91-223-99.compute-1.amazonaws.com; Port=5432; Database=dfh40q63cvf6kc; User Id=ifmreqrxztsnmg; Password=ba9944d035b1549ed293880afa91869f03cf9365c41a85efc805ec1f44df7c67" 42 | }, 43 | "AllowedHosts": "*", 44 | "Jwt": { 45 | "Key": "62fd354d-3c02-4736-9451-b49fb41e2006", 46 | "Issuer": "https://www.RaqamliAvlod.com", 47 | "Audience": "RaqamliAvlod", 48 | "Lifetime": 300 49 | }, 50 | "Email": { 51 | "Host": "smtp.gmail.com", 52 | "EmailAddress": "khushboqof.elbek@gmail.com", 53 | "Password": "rfqapkwqkdyszyzo" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/ProblemSets/ProblemSetViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.ViewModels.Users; 2 | using RaqamliAvlod.Domain.Entities.ProblemSets; 3 | 4 | namespace RaqamliAvlod.Application.ViewModels.ProblemSets 5 | { 6 | public class ProblemSetViewModel 7 | { 8 | public long Id { get; set; } 9 | public string Name { get; set; } = String.Empty; 10 | public string Description { get; set; } = String.Empty; 11 | public string Type { get; set; } = String.Empty; 12 | public string InputDescription { get; set; } = String.Empty; 13 | public string OutputDescription { get; set; } = String.Empty; 14 | public string Note { get; set; } = String.Empty; 15 | public int TimeLimit { get; set; } 16 | public int MemoryLimit { get; set; } 17 | public short Difficulty { get; set; } 18 | public OwnerViewModel Owner { get; set; } = default!; 19 | public IEnumerable Tests { get; set; } = default!; 20 | 21 | public static implicit operator ProblemSetViewModel(ProblemSet problemSet) 22 | { 23 | return new ProblemSetViewModel() 24 | { 25 | Id = problemSet.Id, 26 | Name = problemSet.Name, 27 | Description = problemSet.Description, 28 | Type = problemSet.Type, 29 | InputDescription = problemSet.InputDescription, 30 | OutputDescription = problemSet.OutputDescription, 31 | Note = problemSet.Note, 32 | TimeLimit = problemSet.TimeLimit, 33 | MemoryLimit = problemSet.MemoryLimit, 34 | Difficulty = problemSet.Difficulty, 35 | Owner = (OwnerViewModel) problemSet.Owner 36 | }; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/Questions/QuestionTagService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.DataAccess.Interfaces; 2 | using RaqamliAvlod.Domain.Entities.Questions; 3 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Questions; 4 | 5 | namespace RaqamliAvlod.Infrastructure.Service.Services.Questions 6 | { 7 | public class QuestionTagService : IQuestionTagService 8 | { 9 | private readonly IUnitOfWork _unitOfWork; 10 | 11 | public QuestionTagService(IUnitOfWork unitOfWork) 12 | { 13 | this._unitOfWork = unitOfWork; 14 | } 15 | 16 | public async Task CreateAsync(Question question, IEnumerable newTags) 17 | { 18 | List questionTags = new(); 19 | List tags = new(); 20 | foreach (var tagdto in newTags) 21 | { 22 | var tag = await _unitOfWork.Tags.FindByNameAsync(tagdto); 23 | if (tag is null) 24 | tags.Add(tagdto.ToLower()); 25 | else questionTags.Add(new QuestionTag() { QuestionId = question.Id, TagId = tag.Id }); 26 | } 27 | var createdTags = await _unitOfWork.Tags.AddRangeAsync(tags.Distinct()); 28 | 29 | 30 | foreach (var tag in createdTags) 31 | questionTags.Add(new QuestionTag() { QuestionId = question.Id, TagId = tag.Id }); 32 | await _unitOfWork.QuestionTags.AddRangeAsync(questionTags.DistinctBy(x => x.TagId)); 33 | return true; 34 | } 35 | 36 | public async Task UpdateAsync(Question question, IEnumerable tags) 37 | { 38 | await _unitOfWork.QuestionTags.DeleteQuestionTagsAsync(question.Id); 39 | await CreateAsync(question, tags); 40 | return true; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Application/ViewModels/Questions/QuestionAnswerViewModel.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.ViewModels.Users; 2 | using RaqamliAvlod.Domain.Entities.Questions; 3 | 4 | namespace RaqamliAvlod.Application.ViewModels.Questions 5 | { 6 | public class QuestionAnswerViewModel 7 | { 8 | public long Id { get; set; } 9 | public string Description { get; set; } = String.Empty; 10 | public int ReplyCount { get; set; } = 0; 11 | public bool HasReplied { get; set; } 12 | public long? ParentId { get; set; } 13 | public OwnerViewModel Owner { get; set; } 14 | public bool CurrentUserIsAuthor { get; set; } = false; 15 | public long QuestionId { get; set; } 16 | 17 | public static implicit operator QuestionAnswerViewModel(QuestionAnswer questionAnswer) 18 | { 19 | return new QuestionAnswerViewModel() 20 | { 21 | Id = questionAnswer.Id, 22 | Description = questionAnswer.Description, 23 | HasReplied = questionAnswer.HasReplied, 24 | Owner = (OwnerViewModel)questionAnswer.Owner, 25 | QuestionId = questionAnswer.QuestionId, 26 | ParentId = questionAnswer.ParentId 27 | }; 28 | } 29 | public QuestionAnswerViewModel(QuestionAnswer questionAnswer, int replyCount) 30 | { 31 | Id = questionAnswer.Id; 32 | Description = questionAnswer.Description; 33 | HasReplied = questionAnswer.HasReplied; 34 | Owner = (OwnerViewModel)questionAnswer.Owner; 35 | QuestionId = questionAnswer.QuestionId; 36 | ParentId = questionAnswer.ParentId; 37 | ReplyCount = replyCount; 38 | } 39 | public QuestionAnswerViewModel() 40 | { 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Attributes/StrongPasswordAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace RaqamliAvlod.Attributes 4 | { 5 | public class StrongPasswordAttribute : ValidationAttribute 6 | { 7 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 8 | { 9 | if (value is null) return new ValidationResult("Password can not be null!"); 10 | else 11 | { 12 | string password = value.ToString()!; 13 | if (password.Length < 8) 14 | return new ValidationResult("Password must be at least 8 characters!"); 15 | else if (password.Length > 50) 16 | return new ValidationResult("Password must be less than 50 characters!"); 17 | var result = IsStrong(password); 18 | 19 | if (result.IsValid is false) return new ValidationResult(result.Message); 20 | return ValidationResult.Success; 21 | } 22 | } 23 | 24 | public (bool IsValid, string Message) IsStrong(string password) 25 | { 26 | bool isDigit = password.Any(x => char.IsDigit(x)); 27 | bool isLower = password.Any(x => char.IsLower(x)); 28 | bool isUpper = password.Any(x => char.IsUpper(x)); 29 | if (!isLower) 30 | return (IsValid: false, Message: "Password must be at least one lower letter!"); 31 | if (!isUpper) 32 | return (IsValid: false, Message: "Password must be at least one upper letter!"); 33 | if (!isDigit) 34 | return (IsValid: false, Message: "Password must be at least one digit!"); 35 | 36 | return (IsValid: true, Message: "Password is strong"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Questions/QuestionAnswerRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using Microsoft.EntityFrameworkCore; 3 | using RaqamliAvlod.Application.Utils; 4 | using RaqamliAvlod.Application.ViewModels.Questions; 5 | using RaqamliAvlod.DataAccess.DbContexts; 6 | using RaqamliAvlod.DataAccess.Interfaces.Questions; 7 | using RaqamliAvlod.Domain.Entities.Questions; 8 | 9 | namespace RaqamliAvlod.DataAccess.Repositories.Questions 10 | { 11 | public class QuestionAnswerRepository : BaseRepository, IQuestionAnswerRepository 12 | { 13 | public QuestionAnswerRepository(AppDbContext context) : base(context) 14 | { 15 | } 16 | 17 | public async Task> GetAllByQuestionIdAsync(long questionId, PaginationParams @params) 18 | { 19 | var questionAsnwerViews = from questionAnswer in _dbSet.Where(answers => (answers.QuestionId == questionId) && (answers.HasReplied == false)) 20 | .Include(x => x.Owner).OrderByDescending(x => x.CreatedAt) 21 | select new QuestionAnswerViewModel(questionAnswer, _dbSet.Count(x => x.ParentId == questionAnswer.Id)); 22 | 23 | return await PagedList.ToPagedListAsync(questionAsnwerViews, @params.PageNumber, @params.PageSize); 24 | 25 | } 26 | 27 | public async Task> GetAllRepliesAsync(long answerId, PaginationParams @params) 28 | { 29 | var res = _dbSet.Where(x => x.ParentId == answerId).OrderBy(x => x.CreatedAt).Include(x => x.Owner).Select(x => (QuestionAnswerViewModel)x); 30 | return await PagedList.ToPagedListAsync(res, @params.PageNumber, @params.PageSize); 31 | } 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/BaseRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using RaqamliAvlod.DataAccess.DbContexts; 3 | using RaqamliAvlod.DataAccess.Interfaces; 4 | using RaqamliAvlod.Domain.Common; 5 | 6 | namespace RaqamliAvlod.DataAccess.Repositories 7 | { 8 | public class BaseRepository : IRepository where T : BaseEntity 9 | { 10 | protected AppDbContext _dbcontext; 11 | protected DbSet _dbSet; 12 | 13 | public BaseRepository(AppDbContext context) 14 | { 15 | _dbcontext = context; 16 | _dbSet = context.Set(); 17 | } 18 | 19 | public virtual async Task CreateAsync(T entity) 20 | { 21 | await _dbSet.AddAsync(entity); 22 | await _dbcontext.SaveChangesAsync(); 23 | return entity; 24 | } 25 | 26 | public virtual async Task DeleteAsync(long id) 27 | { 28 | var entity = await _dbSet.FindAsync(id); 29 | if (entity is not null) 30 | { 31 | _dbSet.Remove(entity); 32 | await _dbcontext.SaveChangesAsync(); 33 | return entity; 34 | } 35 | else throw new NullReferenceException("Not found entity to remove"); 36 | } 37 | 38 | public virtual async Task FindByIdAsync(long id) 39 | { 40 | return await _dbSet.FindAsync(id); 41 | } 42 | 43 | public virtual async Task UpdateAsync(long id, T entity) 44 | { 45 | var oldEntity = await _dbSet.FindAsync(id); 46 | if (oldEntity is not null) 47 | { 48 | entity.Id = id; 49 | _dbSet.Update(entity); 50 | await _dbcontext.SaveChangesAsync(); 51 | return entity; 52 | } 53 | else throw new NullReferenceException("Not found entity to update"); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/Common/FileService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.AspNetCore.Http; 3 | using RaqamliAvlod.Infrastructure.Service.Helpers; 4 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Services.Common 7 | { 8 | public class FileService : IFileService 9 | { 10 | private readonly string _basePath = string.Empty; 11 | private readonly string _imageFolderName = "images"; 12 | 13 | public FileService(IWebHostEnvironment webHost) 14 | { 15 | _basePath = webHost.WebRootPath; 16 | } 17 | 18 | string IFileService.ImageFolderName => _imageFolderName; 19 | 20 | public async Task SaveImageAsync(IFormFile image) 21 | { 22 | if (image is null) 23 | return ""; 24 | 25 | if (!Directory.Exists(_basePath)) 26 | { 27 | Directory.CreateDirectory(_basePath); 28 | } 29 | 30 | if (!Directory.Exists(Path.Combine(_basePath, _imageFolderName))) 31 | { 32 | Directory.CreateDirectory(Path.Combine(_basePath, _imageFolderName)); 33 | } 34 | 35 | string fileName = ImageHelper.MakeImageName(image.FileName); 36 | string partPath = Path.Combine(_imageFolderName, fileName); 37 | string path = Path.Combine(_basePath, partPath); 38 | 39 | var stream = File.Create(path); 40 | await image.CopyToAsync(stream); 41 | stream.Close(); 42 | 43 | return partPath; 44 | } 45 | 46 | public Task DeleteImageAsync(string relativeFilePath) 47 | { 48 | string absoluteFilePath = Path.Combine(_basePath, relativeFilePath); 49 | 50 | if (!File.Exists(absoluteFilePath)) return Task.FromResult(false); 51 | 52 | try 53 | { 54 | File.Delete(absoluteFilePath); 55 | return Task.FromResult(true); 56 | } 57 | catch 58 | { 59 | return Task.FromResult(false); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Dtos/ProblemSets/ProblemSetCreateDto.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Domain.Constants; 2 | using RaqamliAvlod.Domain.Entities.ProblemSets; 3 | using RaqamliAvlod.Infrastructure.Service.Helpers; 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Service.Dtos 7 | { 8 | public class ProblemSetCreateDto 9 | { 10 | [Required] 11 | public string Name { get; set; } = String.Empty; 12 | 13 | [Required] 14 | public string Description { get; set; } = String.Empty; 15 | 16 | [Required] 17 | public string Type { get; set; } = String.Empty; 18 | 19 | public string? Note { get; set; } = String.Empty; 20 | 21 | [Required] 22 | public string InputDescription { get; set; } = String.Empty; 23 | 24 | [Required] 25 | public string OutputDescription { get; set; } = String.Empty; 26 | 27 | [Required, Range(0, EngineConstants.MAX_TIME_LIMIT)] 28 | public int TimeLimit { get; set; } 29 | 30 | [Required, Range(0, EngineConstants.MAX_MEMORY_LIMIT)] 31 | public int MemoryLimit { get; set; } 32 | 33 | [Required, Range(0, EngineConstants.MAX_DIFFICULTY)] 34 | public short Difficulty { get; set; } 35 | 36 | [Required] 37 | public long OwnerId { get; set; } 38 | 39 | public static implicit operator ProblemSet(ProblemSetCreateDto problemSetCreateDto) 40 | { 41 | return new ProblemSet() 42 | { 43 | Name = problemSetCreateDto.Name, 44 | Description = problemSetCreateDto.Description, 45 | Type = problemSetCreateDto.Type, 46 | Note = problemSetCreateDto.Note, 47 | InputDescription = problemSetCreateDto.InputDescription, 48 | OutputDescription = problemSetCreateDto.OutputDescription, 49 | TimeLimit = problemSetCreateDto.TimeLimit, 50 | MemoryLimit = problemSetCreateDto.MemoryLimit, 51 | Difficulty = problemSetCreateDto.Difficulty, 52 | IsPublic = true, 53 | OwnerId = problemSetCreateDto.OwnerId, 54 | CreatedAt = TimeHelper.GetCurrentDateTime() 55 | }; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Core/RabbitMq/RabbitMqCheckerConsumer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.Extensions.Hosting; 3 | using RabbitMQ.Client; 4 | using RabbitMQ.Client.Events; 5 | 6 | namespace RaqamliAvlod.Infrastructure.Core.RabbitMQ 7 | { 8 | public class RabbitMqCheckerConsumer : BackgroundService 9 | { 10 | private readonly ConnectionFactory _factory; 11 | private readonly IConnection _conn; 12 | private readonly IModel _channel; 13 | private readonly string _queueName = "LastRabbitQueue"; 14 | private readonly IServiceProvider _serviceProvider; 15 | 16 | public RabbitMqCheckerConsumer(IServiceProvider serviceProvider, IConfiguration configuration) 17 | { 18 | var subconfiguration = configuration.GetSection("RabbitMq"); 19 | _factory = new ConnectionFactory() 20 | { 21 | //HostName = subconfiguration.GetSection("Host").Value, 22 | //Port = int.Parse(subconfiguration.GetSection("Port").Value), 23 | //UserName = subconfiguration.GetSection("Username").Value, 24 | //Password = subconfiguration.GetSection("Password").Value, 25 | Uri = new Uri("amqps://vqgptogg:qF7mWZC7FfPEhvrcOQtfxKvaKkG4PPZW@armadillo.rmq.cloudamqp.com/vqgptogg") 26 | }; 27 | _conn = _factory.CreateConnection(); 28 | _channel = _conn.CreateModel(); 29 | _channel.QueueDeclare(queue: _queueName, 30 | durable: true, 31 | exclusive: false, 32 | autoDelete: false, 33 | arguments: null); 34 | _channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false); 35 | _serviceProvider = serviceProvider; 36 | } 37 | protected override async Task ExecuteAsync(CancellationToken stoppingToken) 38 | { 39 | var consumer = new EventingBasicConsumer(_channel); 40 | consumer.Received += Receive_Handle; 41 | _channel.BasicConsume(_queueName, false, consumer); 42 | } 43 | 44 | private void Receive_Handle(object sender, BasicDeliverEventArgs model) 45 | { 46 | 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Middlewares/ExceptionHandlerMiddleware.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using RaqamliAvlod.Application.Exceptions; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos; 4 | 5 | namespace RaqamliAvlod.Api.Middlewares 6 | { 7 | public class ExceptionHandlerMiddleware 8 | { 9 | private readonly RequestDelegate _next; 10 | private readonly IWebHostEnvironment _env; 11 | 12 | public ExceptionHandlerMiddleware(RequestDelegate next, IWebHostEnvironment env) 13 | { 14 | this._next = next; 15 | this._env = env; 16 | } 17 | 18 | public async Task InvokeAsync(HttpContext httpContext) 19 | { 20 | try 21 | { 22 | await _next(httpContext); 23 | } 24 | catch (StatusCodeException exception) 25 | { 26 | await ClientErrorHandleAsync(httpContext, exception); 27 | } 28 | catch (Exception exception) 29 | { 30 | await SystemErrorHandleAsync(httpContext, exception); 31 | } 32 | } 33 | 34 | public async Task ClientErrorHandleAsync(HttpContext httpContext, StatusCodeException exception) 35 | { 36 | httpContext.Response.ContentType = "application/json"; 37 | ErrorResponse result = new() 38 | { 39 | Message = exception.Message, 40 | StatusCode = (int)exception.HttpStatusCode 41 | }; 42 | httpContext.Response.StatusCode = (int)exception.HttpStatusCode; 43 | await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(result)); 44 | } 45 | 46 | public async Task SystemErrorHandleAsync(HttpContext httpContext, Exception exception) 47 | { 48 | httpContext.Response.ContentType = "application/json"; 49 | ErrorResponse result = new(); 50 | if (_env.IsProduction()) 51 | { 52 | result.Message = exception.Message; 53 | result.StatusCode = 500; 54 | } 55 | else 56 | { 57 | result.Message = exception.ToString(); 58 | result.StatusCode = 500; 59 | } 60 | httpContext.Response.StatusCode = 500; 61 | await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(result)); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Courses/CourseRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using Microsoft.EntityFrameworkCore; 3 | using RaqamliAvlod.Application.Utils; 4 | using RaqamliAvlod.Application.ViewModels.Courses; 5 | using RaqamliAvlod.Application.ViewModels.Users; 6 | using RaqamliAvlod.DataAccess.DbContexts; 7 | using RaqamliAvlod.DataAccess.Interfaces.Courses; 8 | using RaqamliAvlod.Domain.Entities.Courses; 9 | 10 | namespace RaqamliAvlod.DataAccess.Repositories.Courses 11 | { 12 | public class CourseRepository : GenericRepository, ICourseRepository 13 | { 14 | public CourseRepository(AppDbContext context) : base(context) 15 | { 16 | } 17 | 18 | public async Task> GetAllViewAsync(PaginationParams @params) 19 | { 20 | var query = _dbcontext.Courses.Include(p => p.Owner) 21 | .OrderByDescending(p => p.Id).Select(p => (CourseViewModel)p); 22 | 23 | return await PagedList.ToPagedListAsync(query, 24 | @params.PageNumber, @params.PageSize); 25 | } 26 | 27 | public async Task GetViewAsync(long id) 28 | { 29 | var query = await _dbcontext.Courses.Include(p => p.Owner).FirstOrDefaultAsync(p => p.Id == id); 30 | if(query is null) 31 | return null; 32 | return (CourseViewModel)query; 33 | } 34 | public async Task> SearchAsync(string text, PaginationParams @params) 35 | { 36 | return await PagedList.ToPagedListAsync( 37 | _dbSet.Where(course => course.Title.ToLower().Contains(text.ToLower())) 38 | .OrderBy(x => x.Id), 39 | @params.PageNumber, @params.PageSize); 40 | } 41 | 42 | public async Task> SearchByTitleAsync(string text, PaginationParams @params) 43 | { 44 | var query = from course in _dbcontext.Courses.Include(course => course.Owner) 45 | join owner in _dbcontext.Users on course.OwnerId equals owner.Id 46 | where course.Title.ToLower().Contains(text.ToLower()) 47 | select (CourseViewModel)course; 48 | 49 | return await PagedList.ToPagedListAsync(query, @params.PageNumber, @params.PageSize); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Configurations/Dependencies/ServiceLayerConfiguration.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 2 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Contests; 3 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Courses; 4 | using RaqamliAvlod.Infrastructure.Service.Interfaces.ProblemSets; 5 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Questions; 6 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Users; 7 | using RaqamliAvlod.Infrastructure.Service.Managers; 8 | using RaqamliAvlod.Infrastructure.Service.Security; 9 | using RaqamliAvlod.Infrastructure.Service.Services.Common; 10 | using RaqamliAvlod.Infrastructure.Service.Services.Contests; 11 | using RaqamliAvlod.Infrastructure.Service.Services.Courses; 12 | using RaqamliAvlod.Infrastructure.Service.Services.ProblemSets; 13 | using RaqamliAvlod.Infrastructure.Service.Services.Questions; 14 | using RaqamliAvlod.Infrastructure.Service.Services.Users; 15 | 16 | namespace RaqamliAvlod.Api.Configurations.Dependencies 17 | { 18 | public static class ServiceLayerConfiguration 19 | { 20 | public static void AddServiceLayer(this WebApplicationBuilder builder) 21 | { 22 | builder.Services.AddScoped(); 23 | builder.Services.AddScoped(); 24 | builder.Services.AddScoped(); 25 | builder.Services.AddScoped(); 26 | builder.Services.AddScoped(); 27 | builder.Services.AddScoped(); 28 | builder.Services.AddScoped(); 29 | builder.Services.AddScoped(); 30 | builder.Services.AddScoped(); 31 | builder.Services.AddScoped(); 32 | builder.Services.AddScoped(); 33 | builder.Services.AddScoped(); 34 | builder.Services.AddScoped(); 35 | builder.Services.AddScoped(); 36 | builder.Services.AddScoped(); 37 | builder.Services.AddScoped(); 38 | builder.Services.AddScoped(); 39 | builder.Services.AddMemoryCache(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Controllers/UsersController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using RaqamliAvlod.Application.Utils; 4 | using RaqamliAvlod.Infrastructure.Service.Dtos; 5 | using RaqamliAvlod.Infrastructure.Service.Dtos.Accounts; 6 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 7 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Users; 8 | 9 | namespace RaqamliAvlod.Api.Controllers; 10 | 11 | [Route("api/users")] 12 | [ApiController] 13 | public class UsersController : ControllerBase 14 | { 15 | private readonly IUserService _userService; 16 | private readonly IIdentityHelperService _identityHelperService; 17 | 18 | public UsersController(IUserService userService, IIdentityHelperService identityHelperService) 19 | { 20 | _userService = userService; 21 | _identityHelperService = identityHelperService; 22 | } 23 | 24 | [HttpGet, AllowAnonymous] 25 | public async Task GetAllAsync([FromQuery] PaginationParams @params) 26 | => Ok(await _userService.GetAllAsync(@params)); 27 | 28 | [HttpGet("{userId}"), AllowAnonymous] 29 | public async Task GetIdAsync(long userId) 30 | => Ok(await _userService.GetIdAsync(userId)); 31 | 32 | [HttpGet("username"), AllowAnonymous] 33 | public async Task GetUsernameAsync(string username) 34 | => Ok(await _userService.GetUsernameAsync(username)); 35 | 36 | [HttpPut, Authorize(Roles = "User, Admin, SuperAdmin")] 37 | public async Task UpdateAsync([FromForm] UserUpdateDto userUpdateViewModel) 38 | => Ok(await _userService.UpdateAsync((long)_identityHelperService.GetUserId()!, userUpdateViewModel)); 39 | 40 | [HttpDelete("{userId}"), Authorize(Roles = "Admin, SuperAdmin")] 41 | public async Task DeleteAsync(long userId) 42 | => Ok(await _userService.DeleteAsync(userId)); 43 | 44 | [HttpPost("images/upload"), Authorize(Roles = "Admin, User, SuperAdmin")] 45 | public async Task ImageUpdateAsync([FromForm] ImageUploadDto dto) 46 | => Ok(await _userService.ImageUpdateAsync((long)_identityHelperService.GetUserId()!, dto)); 47 | 48 | [HttpPatch("role/control"), Authorize(Roles = "SuperAdmin")] 49 | public async Task RoleControlAsync(long userId, ushort roleNum) 50 | => Ok(await _userService.RoleControlAsync(userId, roleNum)); 51 | 52 | [HttpGet("{userId}/submuissions")] 53 | public async Task GetSubmissionsAsync(long userId, [FromQuery] PaginationParams @params) 54 | { 55 | return Ok(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/ProblemSets/ProblemSetRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using Microsoft.EntityFrameworkCore; 3 | using RaqamliAvlod.Application.Utils; 4 | using RaqamliAvlod.Application.ViewModels.ProblemSets; 5 | using RaqamliAvlod.DataAccess.DbContexts; 6 | using RaqamliAvlod.DataAccess.Interfaces.ProblemSets; 7 | using RaqamliAvlod.Domain.Entities.ProblemSets; 8 | 9 | namespace RaqamliAvlod.DataAccess.Repositories.ProblemSets 10 | { 11 | public class ProblemSetRepository : BaseRepository, IProblemSetRepository 12 | { 13 | public ProblemSetRepository(AppDbContext context) : base(context) 14 | { 15 | } 16 | 17 | public async Task FindByNameAsync(string problemSetName) 18 | { 19 | return await _dbSet.FirstOrDefaultAsync(x => x.Name == problemSetName); 20 | } 21 | 22 | public override async Task FindByIdAsync(long id) 23 | { 24 | return await _dbSet.Include(x => x.Owner).FirstOrDefaultAsync(x => x.Id == id); 25 | } 26 | 27 | public async Task> GetAllViewAsync(PaginationParams @params, long userId) 28 | { 29 | var query = from problemSet in _dbcontext.ProblemSets.Where(x => x.IsPublic == true) 30 | .OrderBy(x=>x.Id) 31 | select new ProblemSetBaseViewModel() 32 | { 33 | Id = problemSet.Id, 34 | Name = problemSet.Name, 35 | Type = problemSet.Type, 36 | }; 37 | return await PagedList.ToPagedListAsync(query, @params.PageNumber, @params.PageSize); 38 | } 39 | 40 | public async Task> GetAllViewAsync(PaginationParams @params, long userId, long contestId) 41 | { 42 | var query = from problemSet in _dbcontext.ProblemSets.Where(x => x.ContestId == contestId) 43 | .OrderBy(problemSet=>problemSet.ContestIdentifier) 44 | select new ContestProblemSetBaseViewModel() 45 | { 46 | Id = problemSet.Id, 47 | Name = problemSet.Name, 48 | Type = problemSet.Type, 49 | ContestCoins = problemSet.ContestCoins, 50 | ContestIdentifier = problemSet.ContestIdentifier 51 | }; 52 | return await PagedList.ToPagedListAsync(query, @params.PageNumber, @params.PageSize); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/UnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.DataAccess.DbContexts; 2 | using RaqamliAvlod.DataAccess.Interfaces; 3 | using RaqamliAvlod.DataAccess.Interfaces.Contests; 4 | using RaqamliAvlod.DataAccess.Interfaces.Courses; 5 | using RaqamliAvlod.DataAccess.Interfaces.ProblemSets; 6 | using RaqamliAvlod.DataAccess.Interfaces.Questions; 7 | using RaqamliAvlod.DataAccess.Interfaces.Submissions; 8 | using RaqamliAvlod.DataAccess.Interfaces.Users; 9 | using RaqamliAvlod.DataAccess.Repositories.Contests; 10 | using RaqamliAvlod.DataAccess.Repositories.Courses; 11 | using RaqamliAvlod.DataAccess.Repositories.ProblemSets; 12 | using RaqamliAvlod.DataAccess.Repositories.Questions; 13 | using RaqamliAvlod.DataAccess.Repositories.Submissions; 14 | using RaqamliAvlod.DataAccess.Repositories.Users; 15 | 16 | namespace RaqamliAvlod.DataAccess.Repositories 17 | { 18 | public class UnitOfWork : IUnitOfWork 19 | { 20 | public IContestRepository Contests { get; } 21 | public IContestStandingsRepository ContestStandings { get; } 22 | public IContestSubmissionInfoRepository ContestSubmissionInfo { get; } 23 | public ICourseCommentRepository CourseComments { get; } 24 | public ICourseRepository Courses { get; } 25 | public ICourseVideoRepository CourseVideos { get; } 26 | public IProblemSetRepository ProblemSets { get; } 27 | public IProblemSetTestRepository ProblemSetTests { get; } 28 | public IQuestionAnswerRepository QuestionAnswers { get; } 29 | public IQuestionRepository Questions { get; } 30 | public IQuestionTagRepository QuestionTags { get; } 31 | public ITagRepository Tags { get; } 32 | public ISubmissionRepository Submissions { get; } 33 | public IUserRepository Users { get; } 34 | 35 | public UnitOfWork(AppDbContext appDbContext) 36 | { 37 | Contests = new ContestRepository(appDbContext); 38 | ContestStandings = new ContestStandingsRepository(appDbContext); 39 | ContestSubmissionInfo = new ContestSubmissionInfoRepository(appDbContext); 40 | Courses = new CourseRepository(appDbContext); 41 | CourseComments = new CourseCommentRepository(appDbContext); 42 | CourseVideos = new CourseVideoRepository(appDbContext); 43 | ProblemSets = new ProblemSetRepository(appDbContext); 44 | ProblemSetTests = new ProblemSetTestRepository(appDbContext); 45 | QuestionAnswers = new QuestionAnswerRepository(appDbContext); 46 | Questions = new QuestionRepository(appDbContext); 47 | QuestionTags = new QuestionTagRepository(appDbContext); 48 | Tags = new TagRepository(appDbContext); 49 | Submissions = new SubmissionRepository(appDbContext); 50 | Users = new UserRepository(appDbContext); 51 | } 52 | 53 | public void Dispose() 54 | { 55 | GC.Collect(); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/Questions/TagService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.IdentityModel.Tokens; 2 | using RaqamliAvlod.Application.Exceptions; 3 | using RaqamliAvlod.Application.ViewModels.Questions; 4 | using RaqamliAvlod.DataAccess.Interfaces; 5 | using RaqamliAvlod.Domain.Entities.Questions; 6 | using RaqamliAvlod.Domain.Enums; 7 | using RaqamliAvlod.Infrastructure.Service.Dtos.Questions; 8 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Questions; 9 | using System.Net; 10 | 11 | namespace RaqamliAvlod.Infrastructure.Service.Services.Questions 12 | { 13 | public class TagService : ITagService 14 | { 15 | private readonly IUnitOfWork _unitOfWork; 16 | 17 | public TagService(IUnitOfWork unitOfWork) 18 | { 19 | this._unitOfWork = unitOfWork; 20 | } 21 | 22 | public async Task CreateAsync(TagCreateDto tagCreateDto, UserRole role) 23 | { 24 | var tag = (Tag)tagCreateDto; 25 | var tags = await _unitOfWork.Tags.FindByNameAsync(tag.TagName.ToLower()); 26 | 27 | if (tags is not null) 28 | throw new StatusCodeException(HttpStatusCode.BadRequest, "Tag already exists"); 29 | 30 | return await _unitOfWork.Tags.CreateAsync(tag) is not null; 31 | } 32 | 33 | public async Task DeleteAsync(long id) 34 | { 35 | var tag = await _unitOfWork.Tags.FindByIdAsync(id); 36 | if (tag is null) 37 | throw new StatusCodeException(HttpStatusCode.NotFound, "Tag not found"); 38 | 39 | await _unitOfWork.Tags.DeleteAsync(id); 40 | 41 | return true; 42 | } 43 | 44 | public async Task UpdateAsync(long id, TagCreateDto dto) 45 | { 46 | var tag = await _unitOfWork.Tags.FindByIdAsync(id); 47 | 48 | if (tag is null) 49 | throw new StatusCodeException(HttpStatusCode.NotFound, "Tag not found"); 50 | 51 | await _unitOfWork.Tags.UpdateAsync(id, dto); 52 | 53 | return true; 54 | } 55 | 56 | public async Task GetByIdAsync(long tagId) 57 | { 58 | var tag = await _unitOfWork.Tags.FindByIdAsync(tagId); 59 | 60 | if (tag is null) 61 | throw new StatusCodeException(HttpStatusCode.NotFound, "Tag not found"); 62 | 63 | return (TagViewModel)tag; 64 | } 65 | 66 | public async Task> GetByNameAsync(string name) 67 | { 68 | var tag = await _unitOfWork.Tags.SearchAsync(name.ToLower()); 69 | 70 | if (tag.IsNullOrEmpty()) 71 | throw new StatusCodeException(HttpStatusCode.NotFound, "Tag not found"); 72 | 73 | ICollection result = new List(); 74 | 75 | foreach (var item in tag) 76 | result.Add((TagViewModel)item); 77 | 78 | return result; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/Repositories/Questions/QuestionRepository.cs: -------------------------------------------------------------------------------- 1 | using CodePower.DataAccess.Common; 2 | using Microsoft.EntityFrameworkCore; 3 | using RaqamliAvlod.Application.Utils; 4 | using RaqamliAvlod.Application.ViewModels.Questions; 5 | using RaqamliAvlod.DataAccess.DbContexts; 6 | using RaqamliAvlod.DataAccess.Interfaces.Questions; 7 | using RaqamliAvlod.Domain.Entities.Questions; 8 | 9 | namespace RaqamliAvlod.DataAccess.Repositories.Questions 10 | { 11 | public class QuestionRepository : GenericRepository, IQuestionRepository 12 | { 13 | public QuestionRepository(AppDbContext context) : base(context) 14 | { 15 | } 16 | 17 | public override async Task FindByIdAsync(long id) 18 | { 19 | return await _dbcontext.Questions.Include(x => x.Owner) 20 | .FirstOrDefaultAsync(x => x.Id == id); 21 | } 22 | 23 | public async Task> GetAllViewAsync(PaginationParams @params) 24 | { 25 | var query = from question in _dbcontext.Questions.Include(x => x.Owner) 26 | orderby question.CreatedAt descending 27 | select (QuestionBaseViewModel)question; 28 | 29 | return await PagedList.ToPagedListAsync(query, 30 | @params.PageNumber, @params.PageSize); 31 | } 32 | 33 | public async Task CountViewAsync(long questionId) 34 | { 35 | var question = await _dbcontext.Questions.FindAsync(questionId); 36 | if (question is not null) 37 | { 38 | question.ViewCount++; 39 | _dbcontext.Questions.Update(question); 40 | await _dbcontext.SaveChangesAsync(); 41 | } 42 | } 43 | 44 | public async Task GetViewAsync(long questionId) 45 | { 46 | var query = (await _dbcontext.Questions.Include(x => x.Owner) 47 | .FirstOrDefaultAsync(x => x.Id == questionId)); 48 | if (query is null) return null; 49 | else 50 | { 51 | var questionView = (QuestionViewModel)query; 52 | questionView.Tags = from questiontag in _dbcontext.QuestionTags 53 | join tag in _dbcontext.Tags on questiontag.TagId equals tag.Id 54 | where questiontag.QuestionId == query.Id 55 | select tag.TagName; 56 | return questionView; 57 | } 58 | } 59 | 60 | public async Task> SearchAsync(string search, PaginationParams @params) 61 | { 62 | var query = from q in _dbcontext.Questions.Include(q => q.Owner) 63 | join qt in _dbcontext.QuestionTags on q.Id equals qt.QuestionId 64 | join t in _dbcontext.Tags on qt.TagId equals t.Id 65 | where q.Title.Contains(search) || t.TagName.Contains(search) 66 | select (QuestionBaseViewModel)q; 67 | 68 | return await PagedList.ToPagedListAsync(query, @params.PageNumber, @params.PageSize); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/ProblemSets/ProblemSetTestService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Exceptions; 2 | using RaqamliAvlod.Application.ViewModels.ProblemSets; 3 | using RaqamliAvlod.DataAccess.Interfaces; 4 | using RaqamliAvlod.Domain.Entities.ProblemSets; 5 | using RaqamliAvlod.Infrastructure.Service.Dtos; 6 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 7 | using RaqamliAvlod.Infrastructure.Service.Interfaces.ProblemSets; 8 | using System.Net; 9 | 10 | namespace RaqamliAvlod.Infrastructure.Service.Services.ProblemSets 11 | { 12 | public class ProblemSetTestService : IProblemSetTestService 13 | { 14 | private readonly IUnitOfWork _unitOfWork; 15 | private readonly IPaginatorService _paginator; 16 | 17 | public ProblemSetTestService(IUnitOfWork unitOfWork, IPaginatorService paginator) 18 | { 19 | this._unitOfWork = unitOfWork; 20 | this._paginator = paginator; 21 | } 22 | public async Task CreateAsync(ProblemSetTestCreateDto testCreateDto) 23 | { 24 | var problemSet = await _unitOfWork.ProblemSets.FindByIdAsync(testCreateDto.ProblemSetId); 25 | if (problemSet is null) throw new StatusCodeException(HttpStatusCode.NotFound, "ProblemSet is not found"); 26 | 27 | var test = (ProblemSetTest) testCreateDto; 28 | 29 | await _unitOfWork.ProblemSetTests.CreateAsync(test); 30 | 31 | return true; 32 | } 33 | 34 | public async Task DeleteAsync(long testId) 35 | { 36 | var problemSetTest = await _unitOfWork.ProblemSetTests.FindByIdAsync(testId); 37 | if (problemSetTest is null) throw new StatusCodeException(HttpStatusCode.NotFound, "ProblemSet is not found"); 38 | 39 | await _unitOfWork.ProblemSetTests.DeleteAsync(testId); 40 | 41 | return true; 42 | } 43 | 44 | public async Task> GetAllAsync(long problemSetId) 45 | { 46 | var tests = await _unitOfWork.ProblemSetTests.GetAllByProblemSetId(problemSetId); 47 | 48 | var viewModels = new List(); 49 | foreach (var test in tests) 50 | { 51 | viewModels.Add(test); 52 | } 53 | return viewModels; 54 | } 55 | 56 | public async Task GetAsync(long testId) 57 | { 58 | var problemSetTest = await _unitOfWork.ProblemSetTests.FindByIdAsync(testId); 59 | if (problemSetTest is null) throw new StatusCodeException(HttpStatusCode.NotFound, "ProblemSet is not found"); 60 | 61 | return (ProblemSetTestViewModel)problemSetTest; 62 | } 63 | 64 | public async Task UpdateAsync(long testId, ProblemSetTestCreateDto testCreateDto) 65 | { 66 | var problemSetTest = await _unitOfWork.ProblemSetTests.FindByIdAsync(testId); 67 | if (problemSetTest is null) throw new StatusCodeException(HttpStatusCode.NotFound, "ProblemSet is not found"); 68 | 69 | problemSetTest = testCreateDto; 70 | 71 | await _unitOfWork.ProblemSetTests.UpdateAsync(testId, problemSetTest); 72 | 73 | return true; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Controllers/ContestsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Infrastructure.Service.Dtos; 4 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Contests; 5 | 6 | namespace RaqamliAvlod.Api.Controllers; 7 | 8 | [Route("api/contests")] 9 | [ApiController] 10 | public class ContestsController : ControllerBase 11 | { 12 | private readonly IContestService _contestService; 13 | 14 | public ContestsController(IContestService contestService) 15 | { 16 | _contestService = contestService; 17 | } 18 | 19 | [HttpGet] 20 | public async Task GetAllAsync([FromQuery] PaginationParams @params) 21 | => Ok(await _contestService.GetAllAsync(@params)); 22 | 23 | [HttpGet("{contestId}")] 24 | public async Task GetAsync(long contestId) 25 | => Ok(await _contestService.GetAsync(contestId)); 26 | 27 | [HttpPost] 28 | public async Task CreateAsync([FromForm] ContestCreateDto contestCreateViewModel) 29 | => Ok(await _contestService.CreateAsync(contestCreateViewModel)); 30 | 31 | [HttpPut("{contestId}")] 32 | public async Task UpdateAsync(long contestId, [FromForm] ContestCreateDto contestUpdateViewModel) 33 | => Ok(await _contestService.UpdateAsync(contestId, contestUpdateViewModel)); 34 | 35 | [HttpDelete("{contestId}")] 36 | public async Task DeleteAsync(long contestId) 37 | => Ok(await _contestService.DeleteAsync(contestId)); 38 | 39 | [HttpPost("register")] 40 | public async Task RegistrateAsync(long contestId) 41 | { 42 | return Ok(); 43 | } 44 | 45 | [HttpPost("submissions")] 46 | public async Task CreateSubmissionsAsync([FromForm] ContestSubmissionCreateDto viewModel) 47 | { 48 | return Ok(); 49 | } 50 | 51 | [HttpPost("problemsets")] 52 | public async Task CreateProblemSetAsync([FromForm] ContestProblemSetCreateDto createViewModel) 53 | { 54 | return Ok(); 55 | } 56 | 57 | [HttpPost("standings/calculate")] 58 | public async Task StandingsAsync(long contestId) 59 | { 60 | return Ok(); 61 | } 62 | 63 | [HttpGet("{contestId}/submissions")] 64 | public async Task GetAllSubmissionsAsync([FromQuery] PaginationParams @params, long contestId) 65 | { 66 | return Ok(); 67 | } 68 | 69 | [HttpGet("{contestId}/users/{userId}/submissions")] 70 | 71 | public async Task GetSubmissionsAsync([FromQuery] PaginationParams @params, 72 | long contestId, long userId) 73 | { 74 | return Ok(); 75 | } 76 | 77 | [HttpGet("{contestId}/problemsets")] 78 | public async Task GetAllProblemSetsAsync(long contestId) 79 | { 80 | return Ok(); 81 | } 82 | 83 | [HttpGet("{contestId}/problemsets/{problemSetId}")] 84 | public async Task GetProblemSetAsync(long contestId, long problemSetId) 85 | { 86 | return Ok(); 87 | } 88 | 89 | [HttpGet("{contestId}/participants")] 90 | public async Task GetParticipantsAsync([FromQuery] PaginationParams @params, long contestId) 91 | { 92 | return Ok(); 93 | } 94 | 95 | [HttpGet("{contestId}/standings")] 96 | public async Task StandingsAsync([FromQuery] PaginationParams @params, long contestId) 97 | { 98 | return Ok(); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.DataAccess/DbContexts/AppDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using RaqamliAvlod.Domain.Entities.Contests; 3 | using RaqamliAvlod.Domain.Entities.Courses; 4 | using RaqamliAvlod.Domain.Entities.ProblemSets; 5 | using RaqamliAvlod.Domain.Entities.Questions; 6 | using RaqamliAvlod.Domain.Entities.Submissions; 7 | using RaqamliAvlod.Domain.Entities.Users; 8 | 9 | namespace RaqamliAvlod.DataAccess.DbContexts 10 | { 11 | public class AppDbContext : DbContext 12 | { 13 | public AppDbContext(DbContextOptions options) 14 | : base(options) 15 | { 16 | 17 | } 18 | 19 | public virtual DbSet Contests { get; set; } = null!; 20 | public virtual DbSet ContestStandings { get; set; } = null!; 21 | public virtual DbSet ContestSubmissionsInfos { get; set; } = null!; 22 | public virtual DbSet Courses { get; set; } = null!; 23 | public virtual DbSet CourseComments { get; set; } = null!; 24 | public virtual DbSet CourseVideos { get; set; } = null!; 25 | public virtual DbSet ProblemSets { get; set; } = null!; 26 | public virtual DbSet ProblemSetTests { get; set; } = null!; 27 | public virtual DbSet Questions { get; set; } = null!; 28 | public virtual DbSet QuestionAnswers { get; set; } = null!; 29 | public virtual DbSet QuestionTags { get; set; } = null!; 30 | public virtual DbSet Tags { get; set; } = null!; 31 | public virtual DbSet Submissions { get; set; } = null!; 32 | public virtual DbSet Users { get; set; } = null!; 33 | 34 | protected override void OnModelCreating(ModelBuilder modelBuilder) 35 | { 36 | base.OnModelCreating(modelBuilder); 37 | 38 | #region Contests 39 | modelBuilder.Entity().HasIndex(x => x.Title).IsUnique(); 40 | modelBuilder.Entity().HasIndex(entity => 41 | new { entity.UserId, entity.ContestId } 42 | ).IsUnique(); 43 | modelBuilder.Entity() 44 | .HasIndex(entity => new { entity.ProblemSetId, entity.ContestStandingsId } 45 | ).IsUnique(); 46 | #endregion 47 | 48 | #region Courses 49 | modelBuilder.Entity().HasIndex(entity => 50 | new 51 | { 52 | entity.CourseId, 53 | entity.YouTubeLink 54 | }).IsUnique(); 55 | #endregion 56 | 57 | #region ProblemSets 58 | modelBuilder.Entity().HasIndex(entity => entity.Name).IsUnique(); 59 | modelBuilder.Entity().HasIndex(entity => new 60 | { 61 | entity.ContestIdentifier, 62 | entity.ContestId 63 | }).IsUnique(); 64 | 65 | #endregion 66 | 67 | #region Questions 68 | modelBuilder.Entity().HasIndex(entity => new 69 | { 70 | entity.TagId, 71 | entity.QuestionId 72 | }).IsUnique(); 73 | #endregion 74 | 75 | #region Tags 76 | modelBuilder.Entity().HasIndex(x => x.TagName).IsUnique(); 77 | #endregion 78 | 79 | #region Users 80 | modelBuilder.Entity().HasIndex(x => x.Email).IsUnique(); 81 | modelBuilder.Entity().HasIndex(x => x.PhoneNumber).IsUnique(); 82 | modelBuilder.Entity().HasIndex(x => x.Username).IsUnique(); 83 | #endregion 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Api/Controllers/ProblemSetsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using RaqamliAvlod.Application.Utils; 4 | using RaqamliAvlod.Infrastructure.Service.Dtos; 5 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 6 | using RaqamliAvlod.Infrastructure.Service.Interfaces.ProblemSets; 7 | 8 | namespace RaqamliAvlod.Api.Controllers; 9 | 10 | [Route("api/problemSets")] 11 | [ApiController] 12 | public class ProblemSetsController : ControllerBase 13 | { 14 | private readonly IProblemSetService _problemSetService; 15 | private readonly IIdentityHelperService _identityService; 16 | private readonly IProblemSetTestService _testService; 17 | 18 | public ProblemSetsController(IProblemSetService problemSetService, 19 | IIdentityHelperService identityHelperService, IProblemSetTestService testService) 20 | { 21 | this._problemSetService = problemSetService; 22 | this._identityService = identityHelperService; 23 | this._testService = testService; 24 | } 25 | 26 | [HttpGet("public"), AllowAnonymous] 27 | public async Task GetAllAsync([FromQuery] PaginationParams @params) 28 | => Ok(await _problemSetService.GetAllAsync(@params, _identityService.GetUserId())); 29 | 30 | [HttpGet("public/{problemSetId}"), AllowAnonymous] 31 | public async Task GetAsync(long problemSetId) 32 | => Ok(await _problemSetService.GetAsync(problemSetId)); 33 | 34 | [HttpPost("public"), Authorize(Roles = "Admin, SuperAdmin")] 35 | public async Task CreateAsync([FromForm] ProblemSetCreateDto problemSetCreateDto) 36 | => Ok(await _problemSetService.CreateAsync(problemSetCreateDto)); 37 | 38 | [HttpPut("public/{problemSetId}"), Authorize(Roles = "Admin, SuperAdmin")] 39 | public async Task UpdateAsync(long problemSetId, [FromForm] ProblemSetCreateDto problemSetCreateDto) 40 | => Ok(await _problemSetService.UpdateAsync(problemSetId, problemSetCreateDto)); 41 | 42 | [HttpDelete("public/{problemSetId}"), Authorize(Roles = "Admin, SuperAdmin")] 43 | public async Task DeleteAsync(long problemSetId) 44 | => Ok(await _problemSetService.DeleteAsync(problemSetId)); 45 | 46 | [HttpGet("public/search"), AllowAnonymous] 47 | public async Task SearchAsync(string search, [FromQuery] PaginationParams @params) 48 | { 49 | return Ok(); 50 | } 51 | 52 | [HttpGet("{problemSetId}/tests"), AllowAnonymous] 53 | public async Task GetProblemSetTestsAsync(long problemSetId) 54 | => Ok(await _testService.GetAllAsync(problemSetId)); 55 | 56 | [HttpGet("tests/{testId}"), AllowAnonymous] 57 | public async Task GetProblemSetsTestAsync(long testId) 58 | => Ok(await _testService.GetAsync(testId)); 59 | 60 | [HttpPost("tests"), Authorize(Roles = "Admin, SuperAdmin")] 61 | public async Task CreateProblemSetsTestAsync([FromForm] ProblemSetTestCreateDto viewModel) 62 | => Ok(await _testService.CreateAsync(viewModel)); 63 | 64 | [HttpPut("tests/{testId}"), Authorize(Roles = "Admin, SuperAdmin")] 65 | public async Task UpdateProblemSetsTestAsync(long testId, 66 | [FromForm] ProblemSetTestCreateDto viewModel) 67 | => Ok(await _testService.UpdateAsync(testId, viewModel)); 68 | 69 | [HttpDelete("tests/{testId}"), Authorize(Roles = "Admin, SuperAdmin")] 70 | public async Task DeleteProblemSetsTestAsync(long testId) 71 | => Ok(await _testService.DeleteAsync(testId)); 72 | 73 | 74 | [HttpPost("submissions")] 75 | public async Task CreateSubmissionAsync(ProblemSetSubmissionCreateDto viewModel) 76 | { 77 | return Ok(); 78 | } 79 | 80 | [HttpGet("{problemSetId}/submissions")] 81 | public async Task GetAllSubmissions([FromQuery] PaginationParams @params, long problemSetId) 82 | { 83 | return Ok(); 84 | } 85 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/Contests/ContestService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Exceptions; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Contests; 4 | using RaqamliAvlod.DataAccess.Interfaces; 5 | using RaqamliAvlod.Domain.Entities.Contests; 6 | using RaqamliAvlod.Infrastructure.Service.Dtos; 7 | using RaqamliAvlod.Infrastructure.Service.Helpers; 8 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 9 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Contests; 10 | using System.Net; 11 | 12 | namespace RaqamliAvlod.Infrastructure.Service.Services.Contests 13 | { 14 | public class ContestService : IContestService 15 | { 16 | private readonly IUnitOfWork _unitOfWork; 17 | private readonly IPaginatorService _paginatorService; 18 | 19 | public ContestService(IUnitOfWork unitOfWork, IPaginatorService paginatorService) 20 | { 21 | _unitOfWork = unitOfWork; 22 | _paginatorService = paginatorService; 23 | } 24 | 25 | public async Task CreateAsync(ContestCreateDto contestCreateDto) 26 | { 27 | var oldContest = await _unitOfWork.Contests.GetByTitleAsync(contestCreateDto.Title); 28 | if (oldContest is not null) throw new StatusCodeException(HttpStatusCode.BadRequest, $"There is alredy exist title named by {oldContest.Title}"); 29 | 30 | var contest = (Contest)contestCreateDto; 31 | contest.CreatedAt = TimeHelper.GetCurrentDateTime(); 32 | contest.UpdatedAt = TimeHelper.GetCurrentDateTime(); 33 | //DateTime date1 = contestCreateDto.StartDate; 34 | //DateTime date2 = contestCreateDto.EndDate; 35 | //TimeSpan ts = date2 - date1; 36 | //contest.CalculatedDate = Convert.ToDateTime(ts.ToString()); 37 | await _unitOfWork.Contests.CreateAsync(contest); 38 | return true; 39 | } 40 | 41 | public async Task DeleteAsync(long contestId) 42 | { 43 | var oldContest = await _unitOfWork.Contests.FindByIdAsync(contestId); 44 | if (oldContest is null) throw new StatusCodeException(HttpStatusCode.NotFound, message: "Contest don't exist"); 45 | 46 | await _unitOfWork.Contests.DeleteAsync(contestId); 47 | 48 | return true; 49 | } 50 | 51 | public async Task> GetAllAsync(PaginationParams @params) 52 | { 53 | var contests = await _unitOfWork.Contests.GetAllAsync(@params); 54 | _paginatorService.ToPagenator(contests.MetaData); 55 | 56 | var contestViews = new List(); 57 | 58 | foreach (var contest in contests) 59 | { 60 | var contestView = (ContestViewModel)contest; 61 | 62 | contestViews.Add(contestView); 63 | } 64 | 65 | return contestViews; 66 | } 67 | 68 | public async Task GetAsync(long contestId) 69 | { 70 | var contest = await _unitOfWork.Contests.FindByIdAsync(contestId); 71 | if (contest is null) throw new StatusCodeException(HttpStatusCode.NotFound, "Contest is not found"); 72 | 73 | return (ContestViewModel)contest; 74 | } 75 | 76 | public async Task UpdateAsync(long courseId, ContestCreateDto createDto) 77 | { 78 | var contest = await _unitOfWork.Contests.FindByIdAsync(courseId); 79 | if (contest is null) throw new StatusCodeException(HttpStatusCode.NotFound, message: "Contest is not found"); 80 | 81 | var contestTiltle = await _unitOfWork.Contests.GetByTitleAsync(createDto.Title); 82 | if (contestTiltle is not null && contestTiltle.Title == contest.Title) 83 | throw new StatusCodeException(HttpStatusCode.BadRequest, message: "This title already exist"); 84 | 85 | var newContest = (Contest)createDto; 86 | newContest.Id = courseId; 87 | newContest.UpdatedAt = TimeHelper.GetCurrentDateTime(); 88 | 89 | await _unitOfWork.Contests.UpdateAsync(courseId, newContest); 90 | 91 | return true; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/ProblemSets/ProblemSetService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Exceptions; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.ProblemSets; 4 | using RaqamliAvlod.DataAccess.Interfaces; 5 | using RaqamliAvlod.Domain.Entities.ProblemSets; 6 | using RaqamliAvlod.Infrastructure.Service.Dtos; 7 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 8 | using RaqamliAvlod.Infrastructure.Service.Interfaces.ProblemSets; 9 | using System; 10 | using System.Net; 11 | 12 | namespace RaqamliAvlod.Infrastructure.Service.Services.ProblemSets 13 | { 14 | public class ProblemSetService : IProblemSetService 15 | { 16 | private readonly IUnitOfWork _unitOfWork; 17 | private readonly IPaginatorService _paginator; 18 | private readonly IProblemSetTestService _testService; 19 | public ProblemSetService(IUnitOfWork unitOfWork, IPaginatorService paginator, 20 | IProblemSetTestService testService) 21 | { 22 | this._unitOfWork = unitOfWork; 23 | this._paginator = paginator; 24 | this._testService = testService; 25 | } 26 | 27 | public async Task CreateAsync(ProblemSetCreateDto createDto) 28 | { 29 | var oldProblemSet = await _unitOfWork.ProblemSets.FindByNameAsync(createDto.Name); 30 | if (oldProblemSet is not null) throw new StatusCodeException(HttpStatusCode.BadRequest, $"There is alredy exist problemset named by {createDto.Name}"); 31 | 32 | var ownerUser = await _unitOfWork.Users.FindByIdAsync(createDto.OwnerId); 33 | if (ownerUser is null) throw new StatusCodeException(HttpStatusCode.NotFound, $"Owner is not known. Owner id = {createDto.OwnerId} is not valid"); 34 | 35 | var problemSet = (ProblemSet)createDto; 36 | problemSet.ContestIdentifier = 'A'; 37 | await _unitOfWork.ProblemSets.CreateAsync(problemSet); 38 | return true; 39 | } 40 | 41 | public async Task DeleteAsync(long problemSetId) 42 | { 43 | var problemSet = await _unitOfWork.ProblemSets.FindByIdAsync(problemSetId); 44 | if (problemSet is null) throw new StatusCodeException(HttpStatusCode.NotFound, "ProblemSet is not found"); 45 | await _unitOfWork.ProblemSets.DeleteAsync(problemSetId); 46 | return true; 47 | } 48 | 49 | public async Task> GetAllAsync(PaginationParams @params, long? userId) 50 | { 51 | var pagedProblemSets = await _unitOfWork.ProblemSets.GetAllViewAsync(@params, (userId is null)?0:userId.Value); 52 | _paginator.ToPagenator(pagedProblemSets.MetaData); 53 | return pagedProblemSets; 54 | } 55 | 56 | public async Task GetAsync(long problemSetId) 57 | { 58 | var problemSet = await _unitOfWork.ProblemSets.FindByIdAsync(problemSetId); 59 | if (problemSet is null) throw new StatusCodeException(HttpStatusCode.NotFound, "ProblemSet is not found"); 60 | 61 | if (problemSet.IsPublic is false) 62 | throw new StatusCodeException(HttpStatusCode.Forbidden, "No access this problemSet"); 63 | 64 | var result = (ProblemSetViewModel) problemSet; 65 | result.Tests = await _testService.GetAllAsync(problemSetId); 66 | return result; 67 | } 68 | 69 | public async Task UpdateAsync(long problemSetId, ProblemSetCreateDto updateDto) 70 | { 71 | var oldProblemSet = await _unitOfWork.ProblemSets.FindByIdAsync(problemSetId); 72 | if (oldProblemSet is null) throw new StatusCodeException(HttpStatusCode.NotFound, "ProblemSet is not found"); 73 | 74 | var ownerUser = await _unitOfWork.Users.FindByIdAsync(updateDto.OwnerId); 75 | if (ownerUser is null) throw new StatusCodeException(HttpStatusCode.NotFound, $"Owner is not known. Owner id = {updateDto.OwnerId} is not valid"); 76 | 77 | var problemSet = (ProblemSet)updateDto; 78 | problemSet.ContestIdentifier = oldProblemSet.ContestIdentifier; 79 | problemSet.CreatedAt = oldProblemSet.CreatedAt; 80 | await _unitOfWork.ProblemSets.UpdateAsync(problemSetId, problemSet); 81 | return true; 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/Courses/CourseService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Exceptions; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Courses; 4 | using RaqamliAvlod.Application.ViewModels.Users; 5 | using RaqamliAvlod.DataAccess.Interfaces; 6 | using RaqamliAvlod.Domain.Entities.Courses; 7 | using RaqamliAvlod.Infrastructure.Service.Dtos; 8 | using RaqamliAvlod.Infrastructure.Service.Helpers; 9 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 10 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Courses; 11 | using System.Net; 12 | 13 | namespace RaqamliAvlod.Infrastructure.Service.Services.Courses 14 | { 15 | public class CourseService : ICourseService 16 | { 17 | private readonly IUnitOfWork _unitOfWork; 18 | private readonly IFileService _fileService; 19 | private readonly IPaginatorService _paginator; 20 | 21 | public CourseService(IUnitOfWork unitOfWork, 22 | IFileService fileService, 23 | IPaginatorService paginator) 24 | { 25 | _unitOfWork = unitOfWork; 26 | _fileService = fileService; 27 | _paginator = paginator; 28 | } 29 | public async Task CreateAsync(CourseCreateDto dto) 30 | { 31 | var user = await _unitOfWork.Users.FindByIdAsync(dto.OwnerId); 32 | 33 | if (user is null) 34 | throw new StatusCodeException(HttpStatusCode.BadRequest, "Owner not found!"); 35 | var course = (Course)dto; 36 | 37 | course.ImagePath = await _fileService.SaveImageAsync(dto.Image!); 38 | course.CreatedAt = TimeHelper.GetCurrentDateTime(); 39 | course.UpdatedAt = TimeHelper.GetCurrentDateTime(); 40 | 41 | var res = await _unitOfWork.Courses.CreateAsync(course); 42 | 43 | return res is not null; 44 | } 45 | 46 | public async Task DeleteAsync(long id) 47 | { 48 | var course = await _unitOfWork.Courses.FindByIdAsync(id); 49 | 50 | if (course is null) 51 | throw new StatusCodeException(HttpStatusCode.BadRequest, "Course not found!"); 52 | 53 | if(!string.IsNullOrEmpty(course.ImagePath)) 54 | await _fileService.DeleteImageAsync(course.ImagePath); 55 | 56 | var res = await _unitOfWork.Courses.DeleteAsync(id); 57 | 58 | return res is not null; 59 | } 60 | 61 | public async Task> GetAllAsync(PaginationParams @params) 62 | { 63 | var courses = await _unitOfWork.Courses.GetAllViewAsync(@params); 64 | _paginator.ToPagenator(courses.MetaData); 65 | 66 | return courses; 67 | } 68 | 69 | public async Task> SearchByTitleAsync(string text, PaginationParams @params) 70 | { 71 | var courseViews = await _unitOfWork.Courses.SearchByTitleAsync(text, @params); 72 | _paginator.ToPagenator(courseViews.MetaData); 73 | 74 | return courseViews; 75 | } 76 | public async Task GetAsync(long id) 77 | { 78 | var course = await _unitOfWork.Courses.GetViewAsync(id); 79 | 80 | if (course is null) 81 | throw new StatusCodeException(HttpStatusCode.BadRequest, "Course not found!"); 82 | 83 | return course; 84 | } 85 | 86 | 87 | public async Task UpdateAsync(long courseId, CourseUpdateDto dto) 88 | { 89 | var course = await _unitOfWork.Courses.FindByIdAsync(courseId); 90 | 91 | if (course is null) 92 | throw new StatusCodeException(HttpStatusCode.BadRequest, "Course not found!"); 93 | 94 | var updadetCourse = (Course)dto; 95 | 96 | if (dto.Image is not null) 97 | { 98 | await _fileService.DeleteImageAsync(course.ImagePath); 99 | updadetCourse.ImagePath = await _fileService.SaveImageAsync(dto.Image); 100 | } 101 | 102 | updadetCourse.Id = courseId; 103 | updadetCourse.CreatedAt = course.CreatedAt; 104 | updadetCourse.UpdatedAt = TimeHelper.GetCurrentDateTime(); 105 | 106 | var result = await _unitOfWork.Courses.UpdateAsync(courseId, updadetCourse); 107 | return result is not null; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/RaqamliAvlod.Infrastructure.Service/Services/Questions/QuestionService.cs: -------------------------------------------------------------------------------- 1 | using RaqamliAvlod.Application.Exceptions; 2 | using RaqamliAvlod.Application.Utils; 3 | using RaqamliAvlod.Application.ViewModels.Questions; 4 | using RaqamliAvlod.DataAccess.Interfaces; 5 | using RaqamliAvlod.Domain.Entities.Questions; 6 | using RaqamliAvlod.Domain.Enums; 7 | using RaqamliAvlod.Infrastructure.Service.Dtos; 8 | using RaqamliAvlod.Infrastructure.Service.Helpers; 9 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Common; 10 | using RaqamliAvlod.Infrastructure.Service.Interfaces.Questions; 11 | using System.Net; 12 | 13 | namespace RaqamliAvlod.Infrastructure.Service.Services.Questions; 14 | 15 | public class QuestionService : IQuestionService 16 | { 17 | private readonly IUnitOfWork _unitOfWork; 18 | private readonly IPaginatorService _paginator; 19 | private readonly IQuestionTagService _questionTagService; 20 | 21 | public QuestionService(IUnitOfWork unitOfWork, 22 | IPaginatorService paginator, IQuestionTagService service) 23 | { 24 | _unitOfWork = unitOfWork; 25 | _paginator = paginator; 26 | _questionTagService = service; 27 | } 28 | 29 | public async Task CreateAsync(QuestionCreateDto dto, long userId) 30 | { 31 | var question = (Question)dto; 32 | var user = await _unitOfWork.Users.FindByIdAsync(userId); 33 | if (user is null) throw new StatusCodeException(HttpStatusCode.NotFound, "User not found"); 34 | 35 | question.OwnerId = userId; 36 | question.CreatedAt = TimeHelper.GetCurrentDateTime(); 37 | var result = await _unitOfWork.Questions.CreateAsync(question); 38 | 39 | await _questionTagService.CreateAsync(result, dto.Tags); 40 | return result is not null; 41 | } 42 | 43 | public async Task DeleteAsync(long questionId, long userId, UserRole userRole) 44 | { 45 | var res = await _unitOfWork.Questions.FindByIdAsync(questionId); 46 | if (res is null) 47 | throw new StatusCodeException(HttpStatusCode.NotFound, "Question Not Found!"); 48 | if (res.OwnerId != userId && userRole == UserRole.User) 49 | throw new StatusCodeException(HttpStatusCode.Forbidden, "You cannot change it"); 50 | 51 | return await _unitOfWork.Questions.DeleteAsync(questionId) is not null; 52 | } 53 | 54 | public async Task> GetAllAsync(PaginationParams @params) 55 | { 56 | var questions = await _unitOfWork.Questions.GetAllViewAsync(@params); 57 | _paginator.ToPagenator(questions.MetaData); 58 | return questions; 59 | } 60 | 61 | public async Task GetAsync(long questionId, long? userId) 62 | { 63 | var questionView = await _unitOfWork.Questions.GetViewAsync(questionId); 64 | 65 | if (questionView is null) 66 | throw new StatusCodeException(HttpStatusCode.NotFound, "Question Not Found!"); 67 | if (userId is not null && questionView.Owner.UserId == userId) 68 | questionView.CurrentUserIsAuthor = true; 69 | await _unitOfWork.Questions.CountViewAsync(questionId); 70 | return questionView; 71 | } 72 | 73 | public async Task> SearchAsync(string search, PaginationParams @params) 74 | { 75 | var questions = await _unitOfWork.Questions.SearchAsync(search, @params); 76 | _paginator.ToPagenator(questions.MetaData); 77 | return questions.DistinctBy(x => x.Id); 78 | } 79 | 80 | public async Task UpdateAsync(long questionId, QuestionCreateDto dto, long userId) 81 | { 82 | var question = await _unitOfWork.Questions.FindByIdAsync(questionId); 83 | if (question is null) 84 | throw new StatusCodeException(HttpStatusCode.NotFound, "Question Not Found!"); 85 | 86 | var user = await _unitOfWork.Users.FindByIdAsync(userId); 87 | if (user is null) 88 | throw new StatusCodeException(HttpStatusCode.NotFound, "User not found"); 89 | 90 | if (userId != question.OwnerId) 91 | throw new StatusCodeException(HttpStatusCode.Forbidden, "You cannot change it!"); 92 | 93 | var editedQuestion = (Question)dto; 94 | editedQuestion.Id = question.Id; 95 | editedQuestion.OwnerId = userId; 96 | editedQuestion.CreatedAt = question.CreatedAt; 97 | await _questionTagService.UpdateAsync(editedQuestion, dto.Tags); 98 | 99 | return await _unitOfWork.Questions.UpdateAsync(questionId, editedQuestion) is not null; 100 | } 101 | } 102 | --------------------------------------------------------------------------------