diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml new file mode 100644 index 0000000..37f01a9 --- /dev/null +++ b/.github/workflows/unit-test.yml @@ -0,0 +1,29 @@ +name: On Pull Request Opened + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + test: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: ./src + + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install packages + run: npm i + + - name: Check syntax code + run: npm run eslint + + - name: Check typescript + run: npm run typecheck \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8bfb316..0d35a1f 100644 --- a/.gitignore +++ b/.gitignore @@ -405,3 +405,9 @@ Properties schemas.json Cesxhin.AnimeManga.Api.csproj + + +# node +node_modules +package-lock.json +.env \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d0a8a20 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "references"] + path = references + url = https://github.com/Anime-Manga/references.git + branch = refactory diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..0a67b54 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node-terminal", + "request": "launch", + "name": "Start", + "cwd": "${workspaceFolder}/src_refactory", + "command": "npm run start" + } + ] +} \ No newline at end of file diff --git a/src/Cesxhin.AnimeManga.Api/Cesxhin.AnimeManga.Api.csproj b/src/Cesxhin.AnimeManga.Api/Cesxhin.AnimeManga.Api.csproj deleted file mode 100644 index 0e1104a..0000000 --- a/src/Cesxhin.AnimeManga.Api/Cesxhin.AnimeManga.Api.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - net5.0 - f1d2050b-ac80-4560-808c-e1e1bb2c67ea - Linux - - - - - - - - - - - - - - - - - - - - - - - Always - - - - - - diff --git a/src/Cesxhin.AnimeManga.Api/Controllers/AccountController.cs b/src/Cesxhin.AnimeManga.Api/Controllers/AccountController.cs deleted file mode 100644 index d95aa4c..0000000 --- a/src/Cesxhin.AnimeManga.Api/Controllers/AccountController.cs +++ /dev/null @@ -1,134 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using System; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Api.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class AccountController : ControllerBase - { - private readonly IAccountService _accountService; - public AccountController(IAccountService accountService) - { - _accountService = accountService; - } - - //login - [HttpPost("/auth/login")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AuthDTO))] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task Login(AuthLoginDTO auth) - { - try - { - if (string.IsNullOrEmpty(auth.Username) || string.IsNullOrEmpty(auth.Password)) - return BadRequest(); - - var user = await _accountService.Login(auth.Username, auth.Password); - return Ok(user); - } - catch (ApiNotAuthorizeException) - { - return Unauthorized(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //register - [HttpPost("/auth/register")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AuthDTO))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task Register(AuthLoginDTO auth) - { - try - { - if (string.IsNullOrEmpty(auth.Username) || string.IsNullOrEmpty(auth.Password)) - return BadRequest(); - - var user = await _accountService.CreateAccount(auth.Username, auth.Password); - return Ok(user); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //add whiteList - [HttpPost("/auth/watchlist")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(WatchListDTO))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task AddWatchList(WatchListDTO whiteListDTO) - { - try - { - var rs = await _accountService.InsertWatchList(whiteListDTO); - return Ok(rs); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //delete whiteList - [HttpDelete("/auth/watchlist")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(WatchListDTO))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task DeleteWatchList(WatchListDTO whiteListDTO) - { - try - { - var rs = await _accountService.DeleteWatchList(whiteListDTO); - if (rs != null) - return Ok(rs); - - return Conflict(); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Api/Controllers/BookController.cs b/src/Cesxhin.AnimeManga.Api/Controllers/BookController.cs deleted file mode 100644 index 98dbcd5..0000000 --- a/src/Cesxhin.AnimeManga.Api/Controllers/BookController.cs +++ /dev/null @@ -1,1044 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Controllers; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Modules.HtmlAgilityPack; -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Domain.DTO; -using MassTransit; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json.Linq; -using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Api.Controllers -{ - [Route("api")] - [ApiController] - public class BookController : ControllerBase, IGeneralControllerBase - { - //interfaces - private readonly IDescriptionBookService _bookService; - private readonly IChapterService _chapterService; - private readonly IChapterRegisterService _chapterRegisterService; - private readonly IProgressChapterService _progressChapterService; - private readonly IChapterQueueService _chapterQueueService; - private readonly IAccountService _accountService; - private readonly IChapterBlackListService _chapterBlackListService; - private readonly IBus _publishEndpoint; - - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - private readonly string _folder = Environment.GetEnvironmentVariable("BASE_PATH") ?? "/"; - private readonly JObject _schema = JObject.Parse(Environment.GetEnvironmentVariable("SCHEMA")); - - public BookController( - IDescriptionBookService bookService, - IChapterService chapterService, - IChapterRegisterService chapterRegisterService, - IProgressChapterService progressChapterService, - IChapterQueueService chapterQueueService, - IAccountService accountService, - IChapterBlackListService chapterBlackListService, - IBus publishEndpoint - ) - { - _publishEndpoint = publishEndpoint; - _bookService = bookService; - _chapterService = chapterService; - _chapterRegisterService = chapterRegisterService; - _progressChapterService = progressChapterService; - _chapterQueueService = chapterQueueService; - _accountService = accountService; - _chapterBlackListService = chapterBlackListService; - } - - //get list all manga without filter - [HttpGet("/book")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetInfoAll(string nameCfg, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var listManga = await _bookService.GetNameAllAsync(nameCfg, username); - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(listManga)); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get manga by name - [HttpGet("/book/name/{name}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetInfoByName(string nameCfg, string name, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var anime = await _bookService.GetNameByNameAsync(nameCfg, name, username); - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(anime)); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get list manga by start name similar - [HttpGet("/book/names/{name}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetMostInfoByName(string nameCfg, string name, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var searchSchema = _schema.GetValue(nameCfg).ToObject().GetValue("search").ToObject(); - var bookUrls = RipperBookGeneric.GetBookUrl(searchSchema, name); - - //list anime - List listManga = new(); - - foreach (var book in bookUrls) - { - var bookDTO = GenericUrlDTO.GenericUrlToGenericUrlDTO(book); - - var checkManga = await _bookService.GetNameByNameAsync(nameCfg, book.Name, username); - if (checkManga != null) - bookDTO.Exists = true; - - listManga.Add(bookDTO); - } - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(listManga)); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get all db manga - [HttpGet("/book/all")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetAll(string nameCfg, string username) - { - try - { - if (nameCfg != null && _schema.ContainsKey(nameCfg)) - { - var listManga = await _bookService.GetNameAllWithAllAsync(nameCfg, username); - return Ok(listManga); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get chapter by name anime - [HttpGet("/chapter/name/{name}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectByName(string name) - { - try - { - var listChapters = await _chapterService.GetObjectsByNameAsync(name); - return Ok(listChapters); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get chapter by id - [HttpGet("/chapter/id/{id}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ChapterDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectById(string id) - { - try - { - var chapter = await _chapterService.GetObjectByIDAsync(id); - return Ok(chapter); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get chapterRegister by id - [HttpGet("/chapter/register/chapterid/{id}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ChapterRegisterDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectRegisterByObjectId(string id) - { - try - { - var chapterRegister = await _chapterRegisterService.GetObjectRegisterByObjectId(id); - return Ok(chapterRegister); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get list name by external db - [HttpGet("/book/list/name/{name}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetListSearchByName(string nameCfg, string name) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var searchSchema = _schema.GetValue(nameCfg).ToObject().GetValue("search").ToObject(); - var bookUrls = RipperBookGeneric.GetBookUrl(searchSchema, name); - - List listBlackList = new(); - try - { - listBlackList = await _chapterBlackListService.GetObjectsBlackList(); - } - catch (ApiNotFoundException) { } - - if (listBlackList.Any()) - { - bookUrls = bookUrls.Where(book => - listBlackList.Where(blackList => - book.Name == blackList.Name && - book.Url == blackList.Url && - nameCfg == blackList.NameCfg - ).ToList().Count == 0 - ).ToList(); - } - - //list manga - List list = new(); - - foreach (var bookUrl in bookUrls) - { - var bookUrlDTO = GenericUrlDTO.GenericUrlToGenericUrlDTO(bookUrl); - - //check if already exists - try - { - await _chapterService.GetObjectsByNameAsync(bookUrlDTO.Name); - bookUrlDTO.Exists = true; - } - catch (ApiNotFoundException) { } - - list.Add(bookUrlDTO); - } - return Ok(list); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //insert manga - [HttpPost("/book")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutInfo(string nameCfg, string infoClass) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - //insert - var mangaResult = await _bookService.InsertNameAsync(nameCfg, JObject.Parse(infoClass)); - return Created("none", Newtonsoft.Json.JsonConvert.SerializeObject(mangaResult)); - } - else - return BadRequest(); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //update manga - [HttpPut("/book")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task UpdateInfo([FromBody] string content) - { - try - { - var description = JObject.Parse(content); - string nameCfg = (string)description["nameCfg"]; - - if (_schema.ContainsKey(nameCfg)) - { - //update - var mangaResult = await _bookService.UpdateNameAsync(nameCfg, description); - return Created("none", Newtonsoft.Json.JsonConvert.SerializeObject(mangaResult)); - } - else - return BadRequest(); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //insert chapter - [HttpPost("/chapter")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(ChapterDTO))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObject(ChapterDTO objectClass) - { - try - { - //insert - var chapterResult = await _chapterService.InsertObjectAsync(objectClass); - return Created("none", chapterResult); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //insert list chapters - [HttpPost("/chapters")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObjects(List objectsClass) - { - try - { - //insert - var chaptersResult = await _chapterService.InsertObjectsAsync(objectsClass); - return Created("none", chaptersResult); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //insert list chaptersRegisters - [HttpPost("/chapters/registers")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObjectsRegisters(List objectsRegistersClass) - { - try - { - //insert - var chapterResult = await _chapterRegisterService.InsertObjectsRegistersAsync(objectsRegistersClass); - return Created("none", chapterResult); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //put chapterRegister into db - [HttpPut("/chapter/register")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ChapterRegisterDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task UpdateObjectRegister(ChapterRegisterDTO objectRegisterClass) - { - try - { - var chapterRegisterResult = await _chapterRegisterService.UpdateObjectRegisterAsync(objectRegisterClass); - return Ok(chapterRegisterResult); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - - //reset state download of chapterRegister into db - [HttpPut("/book/redownload")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List))] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task RedownloadObjectByUrlPage(string name, string username) - { - try - { - AuthDTO account = null; - try - { - account = await _accountService.FindAccountByUsername(username); - } - catch (ApiNotFoundException) - { - throw new ApiNotAuthorizeException(); - } - - if (account.Role != 100) - throw new ApiNotAuthorizeException(); - - var result = await _chapterService.ResetStatusMultipleDownloadObjectByIdAsync(name); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (ApiNotAuthorizeException) - { - return StatusCode(401); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //put manga into db - [HttpPost("/book/download")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task DownloadInfoByUrlPage(DownloadDTO downloadClass, string username) - { - try - { - AuthDTO account = null; - try - { - account = await _accountService.FindAccountByUsername(username); - } - catch (ApiNotFoundException) - { - throw new ApiNotAuthorizeException(); - } - - if (account.Role != 100) - throw new ApiNotAuthorizeException(); - - if (!_schema.ContainsKey(downloadClass.nameCfg)) - return BadRequest(); - - //get manga - var manga = RipperBookGeneric.GetDescriptionBook(_schema.GetValue(downloadClass.nameCfg).ToObject(), downloadClass.Url, downloadClass.nameCfg); - string name = manga.GetValue("name_id").ToString(); - string cover = manga.GetValue("cover").ToString(); - - //get chapters - var chapters = RipperBookGeneric.GetChapters( - _schema.GetValue(downloadClass.nameCfg).ToObject(), - downloadClass.Url, - name, - downloadClass.nameCfg - ); - - try - { - manga.GetValue("totalVolumes").ToObject(); - manga.GetValue("totalChapters").ToObject(); - } - catch - { - float maxVolumes = 0; - int maxChapters = chapters.Count; - - foreach (var chapter in chapters) - { - if (chapter.CurrentVolume > maxVolumes) - maxVolumes = chapter.CurrentVolume; - } - - manga["totalVolumes"] = maxVolumes; - manga["totalChapters"] = maxChapters; - } - - //insert manga - var resultDescription = await _bookService.InsertNameAsync(downloadClass.nameCfg, manga); - - //insert chapters - var listChapters = await _chapterService.InsertObjectsAsync(chapters); - - var listChapterRegister = new List(); - List chapterPaths = new(); - - foreach (var chapter in chapters) - { - - for (int i = 0; i <= chapter.NumberMaxImage; i++) - { - chapterPaths.Add($"{_folder}/{chapter.NameManga}/Volume {chapter.CurrentVolume}/Chapter {chapter.CurrentChapter}/{chapter.NameManga} s{chapter.CurrentVolume}c{chapter.CurrentChapter}n{i}.png"); - } - - listChapterRegister.Add(new ChapterRegisterDTO - { - ChapterId = chapter.ID, - ChapterPath = chapterPaths.ToArray() - }); - - chapterPaths.Clear(); - } - - //insert episodesRegisters - var episodeRegisterResult = await _chapterRegisterService.InsertObjectsRegistersAsync(listChapterRegister); - - //delete if exist queue - try - { - await _chapterQueueService.DeleteObjectQueue(new GenericQueueDTO - { - NameCfg = downloadClass.nameCfg, - Url = downloadClass.Url - }); - } - catch (ApiNotFoundException) { } - - //create message for notify - string message = $"Added: {name} [Manga]\n"; - - try - { - var messageNotify = new NotifyMangaDTO - { - Message = message, - Image = cover - }; - await _publishEndpoint.Publish(messageNotify); - } - catch (Exception ex) - { - _logger.Error($"Cannot send message rabbit, details: {ex.Message}"); - } - - return Created("none", Newtonsoft.Json.JsonConvert.SerializeObject(resultDescription)); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (ApiNotAuthorizeException) - { - return StatusCode(401); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - //update status chapter - [HttpPut("/book/statusDownload")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ChapterDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutUpdateStateDownload(ChapterDTO objectClass) - { - try - { - //update - var chapterResult = await _chapterService.UpdateStateDownloadAsync(objectClass); - return Ok(chapterResult); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - //delete manga - [HttpDelete("/book/{id}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task DeleteInfo(string nameCfg, string id, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - AuthDTO account = null; - try - { - account = await _accountService.FindAccountByUsername(username); - } - catch (ApiNotFoundException) - { - throw new ApiNotAuthorizeException(); - } - - if (account.Role != 100) - throw new ApiNotAuthorizeException(); - - var listChapterService = await _chapterService.GetObjectsByNameAsync(id); - var listChapterRegister = await _chapterRegisterService.GetObjectsRegistersByListObjectId(listChapterService.ToList()); - var bookDescription = await _bookService.GetNameByNameAsync(nameCfg, id, null); - - var book = await _bookService.DeleteNameByIdAsync(nameCfg, id); - - //create message for notify - string message = $"Removed: {id} [Manga]\n"; - - try - { - var messageNotify = new NotifyMangaDTO - { - Message = message, - Image = bookDescription.GetValue("cover").ToString() - }; - - await _publishEndpoint.Publish(messageNotify); - } - catch (Exception ex) - { - _logger.Error($"Cannot send message rabbit, details: {ex.Message}"); - } - - foreach (var chapterRegister in listChapterRegister) - { - try - { - await _publishEndpoint.Publish(chapterRegister); - } - catch (Exception ex) - { - _logger.Error($"Cannot send message rabbit, details: {ex.Message}"); - } - } - - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(book)); - } - else - return BadRequest(); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - //put progress for tracker - [HttpPut("/chapter/progress")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ProgressChapterDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutStateProgress(ProgressChapterDTO progress) - { - try - { - var result = await _progressChapterService.UpdateProgress(progress); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - //get progress for tracker - [HttpGet("/chapter/progress")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ProgressChapterDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetStateProgress(string name, string username, string nameCfg) - { - try - { - var result = await _progressChapterService.GetProgressByName(name, username, nameCfg); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpGet("/chapter/all-queue")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectsQueue() - { - try - { - var result = await _chapterQueueService.GetObjectsQueue(); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpPut("/chapter/queue")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericQueueDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObjectQueue(GenericQueueDTO objectClass) - { - try - { - var result = await _chapterQueueService.PutObjectQueue(objectClass); - - //create message for notify - string message = $"Someone likes: {objectClass.Name} [Manga]\n"; - - try - { - var messageNotify = new NotifyRequestMangaDTO - { - Message = message - }; - - await _publishEndpoint.Publish(messageNotify); - } - catch (Exception ex) - { - _logger.Error($"Cannot send message rabbit, details: {ex.Message}"); - } - - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpDelete("/chapter/queue")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericQueueDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task DeleteObjectQueue(GenericQueueDTO objectClass) - { - try - { - var result = await _chapterQueueService.DeleteObjectQueue(objectClass); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpGet("/chapter/queue")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericQueueDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectQueue(string name, string url, string nameCfg) - { - try - { - var result = await _chapterQueueService.GetObjectQueue(new GenericQueueDTO - { - Name = name, - NameCfg = nameCfg, - Url = url - }); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpPut("/chapter/blacklist")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericBlackListDTO))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObjectBlackList(GenericBlackListDTO objectClass) - { - try - { - var result = await _chapterBlackListService.PutObjectBlackList(objectClass); - - await _chapterQueueService.DeleteObjectQueue(new GenericQueueDTO - { - Name = objectClass.Name, - Url = objectClass.Url, - NameCfg = objectClass.NameCfg, - }); - - return Ok(result); - } - catch (ApiConflictException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Api/Controllers/GenericController.cs b/src/Cesxhin.AnimeManga.Api/Controllers/GenericController.cs deleted file mode 100644 index b50375a..0000000 --- a/src/Cesxhin.AnimeManga.Api/Controllers/GenericController.cs +++ /dev/null @@ -1,217 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Modules.Parallel; -using Cesxhin.AnimeManga.Domain.DTO; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Api.Controllers -{ - [Route("api")] - [ApiController] - public class GenericController : ControllerBase - { - //interfaces - private readonly IDescriptionVideoService _descriptionVideoService; - private readonly IDescriptionBookService _descriptionBookService; - - //env - private readonly JObject schemas = JObject.Parse(Environment.GetEnvironmentVariable("SCHEMA")); - - public GenericController( - IDescriptionVideoService descriptionVideoService, - IDescriptionBookService descriptionBookService - ) - { - _descriptionVideoService = descriptionVideoService; - _descriptionBookService = descriptionBookService; - } - //check test - [HttpGet("/cfg")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task getSchema() - { - try - { - return Ok(Environment.GetEnvironmentVariable("SCHEMA")); - } - catch - { - return StatusCode(500); - } - } - - //check test - [HttpGet("/check")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task Check() - { - try - { - return Ok("Ok"); - } - catch - { - return StatusCode(500); - } - } - //get all db only saved by account - [HttpGet("/all/watchlist")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetAllOnlyWatchList(string username) - { - List listGeneric = new(); - dynamic result; - try - { - foreach (var item in schemas) - { - var schema = schemas.GetValue(item.Key).ToObject(); - if (schema.GetValue("type").ToString() == "video") - { - result = await _descriptionVideoService.GetNameAllOnlyWatchListAsync(item.Key, username); - } - else - { - result = await _descriptionBookService.GetNameAllOnlyWatchListAsync(item.Key, username); - } - - if (result != null) - listGeneric.AddRange(result); - } - - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(listGeneric)); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get all db - [HttpGet("/all")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetAll(string username) - { - List listGeneric = new(); - dynamic result; - try - { - foreach (var item in schemas) - { - var schema = schemas.GetValue(item.Key).ToObject(); - result = null; - - if (schema.GetValue("type").ToString() == "video") - { - try - { - result = await _descriptionVideoService.GetNameAllAsync(item.Key, username); - } - catch (ApiNotFoundException) { } - } - else - { - try - { - result = await _descriptionBookService.GetNameAllAsync(item.Key, username); - } - catch (ApiNotFoundException) { } - } - - if (result != null) - listGeneric.AddRange(result); - } - - if (listGeneric.Count > 0) - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(listGeneric)); - else - throw new ApiNotFoundException(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get all db - [HttpGet("/search")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetSearch(string username) - { - List listGeneric = new(); - ParallelManager> parallel = new(); - List>> tasks = new(); - dynamic result; - try - { - foreach (var item in schemas) - { - var schema = schemas.GetValue(item.Key).ToObject(); - if (schema.GetValue("type").ToString() == "video") - { - var key = item.Key; - tasks.Add(new Func>(() => _descriptionVideoService.GetNameAllAsync(key, username).GetAwaiter().GetResult())); - } - else - { - var key = item.Key; - tasks.Add(new Func>(() => _descriptionBookService.GetNameAllAsync(key, username).GetAwaiter().GetResult())); - } - - } - - parallel.AddTasks(tasks); - parallel.Start(); - parallel.WhenCompleted(); - - result = parallel.GetResult(); - - foreach (var item in result) - listGeneric.AddRange(item); - - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(listGeneric)); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Api/Controllers/VideoController.cs b/src/Cesxhin.AnimeManga.Api/Controllers/VideoController.cs deleted file mode 100644 index ab992dd..0000000 --- a/src/Cesxhin.AnimeManga.Api/Controllers/VideoController.cs +++ /dev/null @@ -1,981 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Modules.HtmlAgilityPack; -using Cesxhin.AnimeManga.Application.Interfaces.Controllers; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.DTO; -using MassTransit; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json.Linq; -using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Api.Controllers -{ - [Route("api")] - [ApiController] - public class AnimeController : ControllerBase, IGeneralControllerBase - { - //interfaces - private readonly IDescriptionVideoService _descriptionService; - private readonly IEpisodeService _episodeService; - private readonly IEpisodeRegisterService _episodeRegisterService; - private readonly IProgressEpisodeService _progressEpisodeService; - private readonly IEpisodeQueueService _episodeQueueService; - private readonly IAccountService _accountService; - private readonly IEpisodeBlackListService _episodeBlackListService; - private readonly IBus _publishEndpoint; - - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - private readonly string _folder = Environment.GetEnvironmentVariable("BASE_PATH") ?? "/"; - private readonly JObject _schema = JObject.Parse(Environment.GetEnvironmentVariable("SCHEMA")); - - public AnimeController( - IEpisodeService episodeService, - IEpisodeRegisterService episodeRegisterService, - IDescriptionVideoService descriptionService, - IProgressEpisodeService progressEpisodeService, - IEpisodeQueueService episodeQueueService, - IEpisodeBlackListService episodeBlackListService, - IAccountService accountService, - IBus publishEndpoint - ) - { - _descriptionService = descriptionService; - _episodeService = episodeService; - _episodeRegisterService = episodeRegisterService; - _publishEndpoint = publishEndpoint; - _episodeQueueService = episodeQueueService; - _progressEpisodeService = progressEpisodeService; - _accountService = accountService; - _episodeBlackListService = episodeBlackListService; - } - - //get list all anime without filter - [HttpGet("/video")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetInfoAll(string nameCfg, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var listAll = await _descriptionService.GetNameAllAsync(nameCfg, username); - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(listAll)); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get anime by name - [HttpGet("/video/name/{name}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetInfoByName(string name, string nameCfg, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var description = await _descriptionService.GetNameByNameAsync(nameCfg, name, username); - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(description)); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get list anime by start name similar - [HttpGet("/video/names/{name}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetMostInfoByName(string nameCfg, string name, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var description = await _descriptionService.GetMostNameByNameAsync(nameCfg, name, username); - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(description)); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get episode by name anime - [HttpGet("/episode/name/{name}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectByName(string name) - { - try - { - var listEpisodes = await _episodeService.GetObjectsByNameAsync(name); - return Ok(listEpisodes); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get episode by id - [HttpGet("/episode/id/{id}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(EpisodeDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectById(string id) - { - try - { - var episode = await _episodeService.GetObjectByIDAsync(id); - return Ok(episode); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //get episodeRegister by id - [HttpGet("/episode/register/episodeid/{id}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(EpisodeRegisterDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectRegisterByObjectId(string id) - { - try - { - var episodeRegister = await _episodeRegisterService.GetObjectRegisterByObjectId(id); - return Ok(episodeRegister); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //insert anime - [HttpPost("/video")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutInfo(string nameCfg, string description) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - //insert - var descriptionResult = await _descriptionService.InsertNameAsync(nameCfg, JObject.Parse(description)); - return Created("none", Newtonsoft.Json.JsonConvert.SerializeObject(descriptionResult)); - } - else - return BadRequest(); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //update anime - [HttpPut("/video")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task UpdateInfo([FromBody] string content) - { - try - { - var description = JObject.Parse(content); - string nameCfg = (string)description["nameCfg"]; - - if (_schema.ContainsKey(nameCfg)) - { - //update - var descriptionResult = await _descriptionService.UpdateNameAsync(nameCfg, description); - return Created("none", Newtonsoft.Json.JsonConvert.SerializeObject(descriptionResult)); - } - else - return BadRequest(); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //insert episode - [HttpPost("/episode")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(EpisodeDTO))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObject(EpisodeDTO objectClass) - { - try - { - //insert - var episodeResult = await _episodeService.InsertObjectAsync(objectClass); - return Created("none", episodeResult); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //insert list episodes - [HttpPost("/episodes")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObjects(List objectsClass) - { - try - { - //insert - var episodeResult = await _episodeService.InsertObjectsAsync(objectsClass); - return Created("none", episodeResult); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //insert list episodesRegisters - [HttpPost("/episodes/registers")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObjectsRegisters(List objectsRegistersClass) - { - try - { - //insert - var episodeResult = await _episodeRegisterService.InsertObjectsRegistersAsync(objectsRegistersClass); - return Created("none", episodeResult); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //put episodeRegister into db - [HttpPut("/episode/register")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(EpisodeRegisterDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task UpdateObjectRegister(EpisodeRegisterDTO objectRegisterClass) - { - try - { - var rs = await _episodeRegisterService.UpdateObjectRegisterAsync(objectRegisterClass); - return Ok(rs); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - //put anime into db - [HttpPost("/video/download")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task DownloadInfoByUrlPage(DownloadDTO downloadClass, string username) - { - try - { - AuthDTO account = null; - try - { - account = await _accountService.FindAccountByUsername(username); - } - catch(ApiNotFoundException) - { - throw new ApiNotAuthorizeException(); - } - - if (account.Role != 100) - throw new ApiNotAuthorizeException(); - - JObject cfg = null; - - if (!_schema.ContainsKey(downloadClass.nameCfg)) - return BadRequest(); - - cfg = _schema.GetValue(downloadClass.nameCfg).ToObject(); - - //get anime and episodes - var description = RipperVideoGeneric.GetDescriptionVideo(cfg, downloadClass.Url, downloadClass.nameCfg); - var episodes = RipperVideoGeneric.GetEpisodes(cfg, downloadClass.Url, description["name_id"].ToString(), downloadClass.nameCfg); - - var listEpisodeRegister = new List(); - - foreach (var episode in episodes) - { - listEpisodeRegister.Add(new EpisodeRegisterDTO - { - EpisodeId = episode.ID, - EpisodePath = $"{_folder}/{episode.VideoId}/Season {episode.NumberSeasonCurrent.ToString("D2")}/{episode.VideoId} s{episode.NumberSeasonCurrent.ToString("D2")}e{episode.NumberEpisodeCurrent.ToString("D2")}.mp4" - }); - } - - var descriptionResult = await _descriptionService.InsertNameAsync(downloadClass.nameCfg, JObject.Parse(description.ToString())); - - //insert episodes - var episodeResult = await _episodeService.InsertObjectsAsync(episodes); - - //insert episodesRegisters - var episodeRegisterResult = await _episodeRegisterService.InsertObjectsRegistersAsync(listEpisodeRegister); - - //delete if exist queue - try - { - await _episodeQueueService.DeleteObjectQueue(new GenericQueueDTO { - NameCfg = downloadClass.nameCfg, - Url = downloadClass.Url - }); - } - catch (ApiNotFoundException) { } - - //create message for notify - string message = $"Added: {description["name_id"]} [Anime]\n"; - - try - { - var messageNotify = new NotifyAnimeDTO - { - Message = message, - Image = description["cover"].ToString() - }; - await _publishEndpoint.Publish(messageNotify); - } - catch (Exception ex) - { - _logger.Error($"Cannot send message rabbit, details: {ex.Message}"); - } - - return Created("none", Newtonsoft.Json.JsonConvert.SerializeObject(descriptionResult)); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (ApiNotAuthorizeException) - { - return StatusCode(401); - } - catch (Exception e) - { - _logger.Error(e); - return StatusCode(500); - } - } - - //reset state download of episodeRegister into db - [HttpPut("/video/redownload")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List))] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task RedownloadObjectByUrlPage(string name, string username) - { - try - { - AuthDTO account = null; - try - { - account = await _accountService.FindAccountByUsername(username); - } - catch (ApiNotFoundException) - { - throw new ApiNotAuthorizeException(); - } - - if (account.Role != 100) - throw new ApiNotAuthorizeException(); - - var rs = await _episodeService.ResetStatusMultipleDownloadObjectByIdAsync(name); - return Ok(rs); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (ApiNotAuthorizeException) - { - return StatusCode(401); - } - catch (Exception) - { - return StatusCode(500); - } - } - - //delete description - [HttpDelete("/video/{id}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task DeleteInfo(string nameCfg, string id, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - AuthDTO account = null; - try - { - account = await _accountService.FindAccountByUsername(username); - } - catch (ApiNotFoundException) - { - throw new ApiNotAuthorizeException(); - } - - if (account.Role != 100) - throw new ApiNotAuthorizeException(); - - var listEpisodeService = await _episodeService.GetObjectsByNameAsync(id); - var listEpisodeRegister = await _episodeRegisterService.GetObjectsRegistersByListObjectId(listEpisodeService.ToList()); - var videoDescription = await _descriptionService.GetNameByNameAsync(nameCfg, id, null); - - //delete - var videoResult = await _descriptionService.DeleteNameByIdAsync(nameCfg, id); - - //create message for notify - string message = $"Removed: {id} [Anime]\n"; - - try - { - var messageNotify = new NotifyAnimeDTO - { - Message = message, - Image = videoDescription.GetValue("cover").ToString() - }; - await _publishEndpoint.Publish(messageNotify); - } - catch (Exception ex) - { - _logger.Error($"Cannot send message rabbit, details: {ex.Message}"); - } - - foreach (var episode in listEpisodeRegister) - { - try - { - await _publishEndpoint.Publish(episode); - } - catch (Exception ex) - { - _logger.Error($"Cannot send message rabbit, details: {ex.Message}"); - } - } - - return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(videoResult)); - } - else - return BadRequest(); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception) - { - return StatusCode(500); - } - } - - //get all db anime - [HttpGet("/video/all")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetAll(string nameCfg, string username) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var listDescription = await _descriptionService.GetNameAllWithAllAsync(nameCfg, username); - return Ok(listDescription); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception) - { - return StatusCode(500); - } - } - - //get list name by external db - [HttpGet("/video/list/name/{name}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetListSearchByName(string nameCfg, string name) - { - try - { - if (_schema.ContainsKey(nameCfg)) - { - var searchSchema = _schema.GetValue(nameCfg).ToObject().GetValue("search").ToObject(); - var descriptionUrls = RipperVideoGeneric.GetVideoUrl(searchSchema, name); - - List listBlackList = new(); - try - { - listBlackList = await _episodeBlackListService.GetObjectsBlackList(); - } - catch (ApiNotFoundException) { } - - if (listBlackList.Any()) - { - descriptionUrls = descriptionUrls.Where(book => - listBlackList.Where(blackList => - book.Name == blackList.Name && - book.Url == blackList.Url && - nameCfg == blackList.NameCfg - ).ToList().Count == 0 - ).ToList(); - } - - //list anime - List list = new(); - - foreach (var descrptionUrl in descriptionUrls) - { - var descriptionUrlDTO = GenericUrlDTO.GenericUrlToGenericUrlDTO(descrptionUrl); - - //check if already exists - try - { - await _descriptionService.GetNameByNameAsync(nameCfg, descriptionUrlDTO.Name, null); - descriptionUrlDTO.Exists = true; - } - catch (ApiNotFoundException) { } - - list.Add(descriptionUrlDTO); - } - return Ok(list); - } - else - return BadRequest(); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception) - { - return StatusCode(500); - } - } - - //update status episode - [HttpPut("/video/statusDownload")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(EpisodeDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutUpdateStateDownload(EpisodeDTO objectClass) - { - try - { - //update - var resultEpisode = await _episodeService.UpdateStateDownloadAsync(objectClass); - return Ok(resultEpisode); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception) - { - return StatusCode(500); - } - } - - //put progress for tracker - [HttpPut("/episode/progress")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ProgressEpisodeDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutStateProgress(ProgressEpisodeDTO progress) - { - try - { - var result = await _progressEpisodeService.UpdateProgress(progress); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception) - { - return StatusCode(500); - } - } - - //put progress for tracker - [HttpGet("/episode/progress")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ProgressEpisodeDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetStateProgress(string name, string username, string nameCfg) - { - try - { - var result = await _progressEpisodeService.GetProgressByName(name, username, nameCfg); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception) - { - return StatusCode(500); - } - } - - [HttpGet("/episode/all-queue")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectsQueue() - { - try - { - var result = await _episodeQueueService.GetObjectsQueue(); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpPut("/episode/queue")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericQueueDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObjectQueue(GenericQueueDTO objectClass) - { - try - { - var result = await _episodeQueueService.PutObjectQueue(objectClass); - - //create message for notify - string message = $"Someone likes: {objectClass.Name} [Anime]\n"; - - try - { - var messageNotify = new NotifyRequestAnimeDTO - { - Message = message - }; - - await _publishEndpoint.Publish(messageNotify); - } - catch (Exception ex) - { - _logger.Error($"Cannot send message rabbit, details: {ex.Message}"); - } - - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (ApiConflictException) - { - return Conflict(); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpDelete("/episode/queue")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericQueueDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task DeleteObjectQueue(GenericQueueDTO objectClass) - { - try - { - var result = await _episodeQueueService.DeleteObjectQueue(objectClass); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpGet("/episode/queue")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericQueueDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task GetObjectQueue(string name, string url, string nameCfg) - { - try - { - var result = await _episodeQueueService.GetObjectQueue(new GenericQueueDTO - { - Name = name, - NameCfg = nameCfg, - Url = url - }); - return Ok(result); - } - catch (ApiNotFoundException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - - [HttpPut("/episode/blacklist")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericBlackListDTO))] - [ProducesResponseType(StatusCodes.Status409Conflict)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PutObjectBlackList(GenericBlackListDTO objectClass) - { - try - { - var result = await _episodeBlackListService.PutObjectBlackList(objectClass); - - await _episodeQueueService.DeleteObjectQueue(new GenericQueueDTO { - Name = objectClass.Name, - Url = objectClass.Url, - NameCfg = objectClass.NameCfg, - }); - - return Ok(result); - } - catch (ApiConflictException) - { - return NotFound(); - } - catch (ApiGenericException) - { - return StatusCode(500); - } - catch (Exception ex) - { - _logger.Error(ex.Message); - return StatusCode(500, ex.Message); - } - } - } -} \ No newline at end of file diff --git a/src/Cesxhin.AnimeManga.Api/Program.cs b/src/Cesxhin.AnimeManga.Api/Program.cs deleted file mode 100644 index a58a48f..0000000 --- a/src/Cesxhin.AnimeManga.Api/Program.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Hosting; - -namespace Cesxhin.AnimeManga.Api -{ - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } -} diff --git a/src/Cesxhin.AnimeManga.Api/Startup.cs b/src/Cesxhin.AnimeManga.Api/Startup.cs deleted file mode 100644 index d0928a7..0000000 --- a/src/Cesxhin.AnimeManga.Api/Startup.cs +++ /dev/null @@ -1,127 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Generic; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Modules.Schema; -using Cesxhin.AnimeManga.Application.Services; -using Cesxhin.AnimeManga.Persistence.Repositories; -using MassTransit; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using NLog; -using Quartz; -using System; - -namespace Cesxhin.AnimeManga.Api -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - - SchemaControl.Check(); - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - //interfaces - //services - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - - //repositories - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - - //init repoDb - RepoDb.PostgreSqlBootstrap.Initialize(); - - //rabbit - services.AddMassTransit( - x => - { - x.UsingRabbitMq((context, cfg) => - { - cfg.Host( - Environment.GetEnvironmentVariable("ADDRESS_RABBIT") ?? "localhost", - "/", - credentials => - { - credentials.Username(Environment.GetEnvironmentVariable("USERNAME_RABBIT") ?? "guest"); - credentials.Password(Environment.GetEnvironmentVariable("PASSWORD_RABBIT") ?? "guest"); - }); - }); - }); - - - services.AddCors(); - services.AddControllers(); - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "Cesxhin.AnimeManga.Api", Version = "v1" }); - }); - - //setup nlog - var level = Environment.GetEnvironmentVariable("LOG_LEVEL")?.ToLower() ?? "info"; - LogLevel logLevel = NLogManager.GetLevel(level); - NLogManager.Configure(logLevel); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - app.UseSwagger(); - app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Cesxhin.AnimeManga.Api v1")); - } - - app.UseHttpsRedirection(); - - app.UseRouting(); - - // global cors policy - app.UseCors(x => x - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed(origin => true)); - - app.UseAuthorization(); - app.UseAuthentication(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } - } -} diff --git a/src/Cesxhin.AnimeManga.Api/appsettings.Development.json b/src/Cesxhin.AnimeManga.Api/appsettings.Development.json deleted file mode 100644 index 8983e0f..0000000 --- a/src/Cesxhin.AnimeManga.Api/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - } -} diff --git a/src/Cesxhin.AnimeManga.Api/appsettings.json b/src/Cesxhin.AnimeManga.Api/appsettings.json deleted file mode 100644 index 222224e..0000000 --- a/src/Cesxhin.AnimeManga.Api/appsettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*" -} \ No newline at end of file diff --git a/src/Cesxhin.AnimeManga.Api/schema_template.json b/src/Cesxhin.AnimeManga.Api/schema_template.json deleted file mode 100644 index 305b5c8..0000000 --- a/src/Cesxhin.AnimeManga.Api/schema_template.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "*": { - "name": "string", - "type": "string", - "search": { - "url_search": "string", - "page": "boolean", - "prefixSearch": "string", - - "collection": "*", - - "description": { - "imageUrl": "*", - "urlPage": "*", - "name": "*" - } - }, - "description": { - "*": "*" - }, - "video": { - "collection": "*", - "procedure": { - "*":"*" - } - } - } -} \ No newline at end of file diff --git a/src/Cesxhin.AnimeManga.Application/Cesxhin.AnimeManga.Application.csproj b/src/Cesxhin.AnimeManga.Application/Cesxhin.AnimeManga.Application.csproj deleted file mode 100644 index 05a0d02..0000000 --- a/src/Cesxhin.AnimeManga.Application/Cesxhin.AnimeManga.Application.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - net5.0 - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Controllers/IGeneralControllerBase.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Controllers/IGeneralControllerBase.cs deleted file mode 100644 index ba293e2..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Controllers/IGeneralControllerBase.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Controllers -{ - public interface IGeneralControllerBase - { - //get - public Task GetInfoAll(string nameCfg, string username); - public Task GetInfoByName(string nameCfg, string name, string username); - public Task GetMostInfoByName(string nameCfg, string name, string username); - public Task GetAll(string nameCfg, string username); - public Task GetObjectByName(string name); - public Task GetObjectById(string id); - public Task GetObjectRegisterByObjectId(string id); - public Task GetListSearchByName(string nameCfg, string name); - public Task GetStateProgress(string name, string username, string nameCfg); - public Task GetObjectsQueue(); - public Task GetObjectQueue(string name, string url, string nameCfg); - - //put - public Task PutInfo(string nameCfg, I infoClass); - public Task UpdateInfo(string content); - public Task PutObject(O objectClass); - public Task PutObjects(List objectsClass); - public Task PutObjectsRegisters(List objectsRegistersClass); - public Task UpdateObjectRegister(R objectRegisterClass); - public Task RedownloadObjectByUrlPage(string id, string username); - public Task DownloadInfoByUrlPage(D objectsClass, string username); - public Task PutUpdateStateDownload(O objectClass); - public Task PutStateProgress(E objectClass); - public Task PutObjectQueue(Q objectClass); - public Task PutObjectBlackList(S objectClass); - - //delete - public Task DeleteInfo(string nameCfg, string id, string username); - public Task DeleteObjectQueue(Q objectClass); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IAccountRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IAccountRepository.cs deleted file mode 100644 index 395dd53..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IAccountRepository.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IAccountRepository - { - public Task CreateAccount(Auth auth); - public Task FindAccountByUsername(string username); - - //whitelist generic - public Task> GetListWatchListByUsername(string username); - public Task InsertWhiteList(WatchList whiteList); - public Task DeleteWhiteList(WatchList whiteList); - public Task WhiteListCheckByName(string name, string username); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterBlackListRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterBlackListRepository.cs deleted file mode 100644 index c54e089..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterBlackListRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IChapterBlackListRepository : IGeneralObjectBlackListRepository - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterQueueRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterQueueRepository.cs deleted file mode 100644 index c8f4c53..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterQueueRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IChapterQueueRepository : IGeneralObjectQueueRepository - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterRegisterRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterRegisterRepository.cs deleted file mode 100644 index dbb1c89..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterRegisterRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IChapterRegisterRepository : IGeneralObjectRegisterRepository - { - } -} \ No newline at end of file diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterRepository.cs deleted file mode 100644 index 7129947..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IChapterRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IChapterRepository : IGeneralObjectRepository - { - public Task DeleteByNameAsync(string id); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IDescriptionRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IDescriptionRepository.cs deleted file mode 100644 index d8b649c..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IDescriptionRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json.Linq; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IDescriptionRepository : IGeneralNameRepository - { - - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeBlackListRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeBlackListRepository.cs deleted file mode 100644 index 84c7681..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeBlackListRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IEpisodeBlackListRepository : IGeneralObjectBlackListRepository - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeQueueRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeQueueRepository.cs deleted file mode 100644 index 68d8d2a..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeQueueRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IEpisodeQueueRepository : IGeneralObjectQueueRepository - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeRegisterRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeRegisterRepository.cs deleted file mode 100644 index 98ab7f3..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeRegisterRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IEpisodeRegisterRepository : IGeneralObjectRegisterRepository - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeRepository.cs deleted file mode 100644 index 1d86b29..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IEpisodeRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IEpisodeRepository : IGeneralObjectRepository - { - public Task DeleteByNameAsync(string id); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralNameRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralNameRepository.cs deleted file mode 100644 index 537bb44..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralNameRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IGeneralNameRepository - { - //get - Task> GetNameAllAsync(string nameCfg); - Task GetNameByNameAsync(string nameCfg, string name); - Task> GetMostNameByNameAsync(string nameCfg, string name); - - //Insert - Task InsertNameAsync(string nameCfg, TGeneralName generalName); - - //Update - Task UpdateNameAsync(string nameCfg, TGeneralName generalName); - - //delete - Task DeleteNameAsync(string nameCfg, string id); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectBlackListRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectBlackListRepository.cs deleted file mode 100644 index dbca8bf..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectBlackListRepository.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IGeneralObjectBlackListRepository - { - //get - Task GetObjectBlackList(T objectGeneral); - Task> GetObjectsBlackList(); - - //put - Task PutObjectBlackList(T objectGeneral); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectQueueRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectQueueRepository.cs deleted file mode 100644 index a8bd2f4..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectQueueRepository.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IGeneralObjectQueueRepository - { - //get - Task> GetObjectsQueue(); - Task GetObjectQueue(T objectGeneral); - - //put - Task PutObjectQueue(T objectGeneral); - - //delete - Task DeleteObjectQueue(T objectGeneral); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectRegisterRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectRegisterRepository.cs deleted file mode 100644 index c71d4b8..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectRegisterRepository.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IGeneralObjectRegisterRepository - { - //get - Task GetObjectRegisterByObjectId(string id); - Task> GetObjectsRegistersByListObjectId(List listObjects); - - //insert - Task> InsertObjectsRegisterAsync(List objectRegister); - Task InsertObjectRegisterAsync(T objectRegister); - - //put - Task UpdateObjectRegisterAsync(T objectRegister); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectRepository.cs deleted file mode 100644 index b8cec89..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IGeneralObjectRepository.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IGeneralObjectRepository - { - //get - Task GetObjectByIDAsync(string id); - Task> GetObjectsByNameAsync(string nameGeneral); - - //insert - Task> InsertObjectsAsync(List objectsGeneral); - Task InsertObjectAsync(T objectGeneral); - - //update - Task UpdateStateDownloadAsync(T objectGeneral); - - //reset - Task ResetStatusDownloadObjectByIdAsync(T objectGeneral); - Task> ResetStatusDownloadObjectsByIdAsync(List objectsGeneral); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IProgressChapterRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IProgressChapterRepository.cs deleted file mode 100644 index 5a555f0..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IProgressChapterRepository.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IProgressChapterRepository - { - public Task UpdateProgress(ProgressChapter progress); - public Task CheckProgress(string name, string username, string nameCfg); - public Task CreateProgress(ProgressChapter progress); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IProgressEpisodeRepository.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IProgressEpisodeRepository.cs deleted file mode 100644 index 6c413ad..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Repositories/IProgressEpisodeRepository.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Repositories -{ - public interface IProgressEpisodeRepository - { - public Task UpdateProgress(ProgressEpisode progress); - public Task CheckProgress(string name, string username, string nameCfg); - public Task CreateProgress(ProgressEpisode progress); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IAccountService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IAccountService.cs deleted file mode 100644 index a8b1109..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IAccountService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IAccountService - { - public Task Login(string username, string password); - public Task CreateAccount(string username, string password); - public Task FindAccountByUsername(string username); - - //whitelist generic - public Task> GetListWatchListByUsername(string username); - public Task InsertWatchList(WatchListDTO whiteListDTO); - public Task DeleteWatchList(WatchListDTO whiteListDTO); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterBlackListService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterBlackListService.cs deleted file mode 100644 index 995bff4..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterBlackListService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IChapterBlackListService : IGeneralObjectBlackListService - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterQueueService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterQueueService.cs deleted file mode 100644 index f75139b..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterQueueService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IChapterQueueService : IGeneralObjectQueueService - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterRegisterService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterRegisterService.cs deleted file mode 100644 index 6196df2..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterRegisterService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IChapterRegisterService : IGeneralObjectRegister - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterService.cs deleted file mode 100644 index b3a07b8..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IChapterService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IChapterService : IGeneralObject - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IDescriptionBookService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IDescriptionBookService.cs deleted file mode 100644 index aa60034..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IDescriptionBookService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using Newtonsoft.Json.Linq; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IDescriptionBookService : IGeneralNameService - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IDescriptionVideoService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IDescriptionVideoService.cs deleted file mode 100644 index c460181..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IDescriptionVideoService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using Newtonsoft.Json.Linq; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IDescriptionVideoService : IGeneralNameService - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeBlackListService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeBlackListService.cs deleted file mode 100644 index f1a9e7c..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeBlackListService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IEpisodeBlackListService : IGeneralObjectBlackListService - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeQueueService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeQueueService.cs deleted file mode 100644 index 4d3fd7c..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeQueueService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IEpisodeQueueService : IGeneralObjectQueueService - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeRegisterService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeRegisterService.cs deleted file mode 100644 index 0067900..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeRegisterService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IEpisodeRegisterService : IGeneralObjectRegister - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeService.cs deleted file mode 100644 index 5757c3d..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IEpisodeService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IEpisodeService : IGeneralObject - { - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralNameService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralNameService.cs deleted file mode 100644 index 70c94ea..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralNameService.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IGeneralNameService - { - //get - Task> GetNameAllAsync(string nameCfg, string username); - Task GetNameByNameAsync(string nameCfg, string name, string username); - Task> GetMostNameByNameAsync(string nameCfg, string name, string username); - Task> GetNameAllWithAllAsync(string nameCfg, string username); - Task> GetNameAllOnlyWatchListAsync(string nameCfg, string username); - - //insert - Task InsertNameAsync(string nameCfg, TGeneralNameDTO anime); - - //update - Task UpdateNameAsync(string nameCfg, TGeneralNameDTO anime); - - //delete - Task DeleteNameByIdAsync(string nameCfg, string id); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObject.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObject.cs deleted file mode 100644 index f19fc2d..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObject.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IGeneralObject - { - //get - Task GetObjectByIDAsync(string id); - Task> GetObjectsByNameAsync(string name); - - //insert - Task> InsertObjectsAsync(List generalObjects); - Task InsertObjectAsync(TObjectDTO generalObject); - - //update - Task UpdateStateDownloadAsync(TObjectDTO generalObject); - - //reset - Task ResetStatusDownloadObjectByIdAsync(TObjectDTO generalObject); - Task> ResetStatusMultipleDownloadObjectByIdAsync(string name); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectBlackListService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectBlackListService.cs deleted file mode 100644 index 6b952de..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectBlackListService.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IGeneralObjectBlackListService - { - //get - Task GetObjectBlackList(TObjectDTO objectGeneral); - Task> GetObjectsBlackList(); - - //put - Task PutObjectBlackList(TObjectDTO objectGeneral); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectQueueService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectQueueService.cs deleted file mode 100644 index 5f74f49..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectQueueService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IGeneralObjectQueueService - { - //get - Task> GetObjectsQueue(); - Task GetObjectQueue(TObjectDTO objectGeneral); - - //put - Task PutObjectQueue(TObjectDTO objectGeneral); - - //delete - Task DeleteObjectQueue(TObjectDTO objectGeneral); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectRegister.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectRegister.cs deleted file mode 100644 index 2c70119..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IGeneralObjectRegister.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IGeneralObjectRegister - { - //get - Task GetObjectRegisterByObjectId(string id); - Task> GetObjectsRegistersByListObjectId(List objectDTOs); - - //insert - Task InsertObjectRegisterAsync(TObjectRegisterDTO objectGeneralRegister); - Task> InsertObjectsRegistersAsync(List objectGeneralRegister); - - //put - Task UpdateObjectRegisterAsync(TObjectRegisterDTO objectGeneralRegister); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IProgressChapterService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IProgressChapterService.cs deleted file mode 100644 index f0d1178..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IProgressChapterService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IProgressChapterService - { - //get - public Task GetProgressByName(string name, string username, string nameCfg); - - //update - public Task UpdateProgress(ProgressChapterDTO progress); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IProgressEpisodeService.cs b/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IProgressEpisodeService.cs deleted file mode 100644 index b7ef3f7..0000000 --- a/src/Cesxhin.AnimeManga.Application/Interfaces/Services/IProgressEpisodeService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Interfaces.Services -{ - public interface IProgressEpisodeService - { - //get - public Task GetProgressByName(string name, string username, string nameCfg); - - //update - public Task UpdateProgress(ProgressEpisodeDTO progress); - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/AccountService.cs b/src/Cesxhin.AnimeManga.Application/Services/AccountService.cs deleted file mode 100644 index 908b57d..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/AccountService.cs +++ /dev/null @@ -1,111 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class AccountService : IAccountService - { - public readonly IAccountRepository _accountRepository; - public AccountService(IAccountRepository accountRepository) - { - _accountRepository = accountRepository; - } - - private static bool ValidPassword(string password, string hasedPassword) - { - return BCrypt.Net.BCrypt.Verify(password, hasedPassword); - } - - private static string CryptPasword(string password) - { - return BCrypt.Net.BCrypt.HashPassword(password); - } - - public async Task CreateAccount(string username, string password) - { - try - { - await _accountRepository.FindAccountByUsername(username); - throw new ApiConflictException("Conflict CreateAccount"); - } - catch (ApiNotFoundException) - { - var auth = new Auth - { - Username = username, - Password = password - }; - - auth.Password = CryptPasword(auth.Password); - var authResult = await _accountRepository.CreateAccount(auth); - - return AuthDTO.AuthToAuthDTO(authResult); - } - } - - public async Task Login(string username, string password) - { - Auth findUser; - try - { - findUser = await _accountRepository.FindAccountByUsername(username); - } - catch (ApiNotFoundException) - { - throw new ApiNotAuthorizeException("Not Authorize Login"); - } - - if (findUser != null && ValidPassword(password, findUser.Password)) - return AuthDTO.AuthToAuthDTO(findUser); - else - throw new ApiNotAuthorizeException("Not Authorize Login"); - - } - - public async Task InsertWatchList(WatchListDTO whiteListDTO) - { - try - { - await _accountRepository.WhiteListCheckByName(whiteListDTO.Name, whiteListDTO.Username); - throw new ApiConflictException("Conflict InsertWatchList"); - } - catch (ApiNotFoundException) - { - var result = await _accountRepository.InsertWhiteList(WatchList.WatchListDTOToWatchList(whiteListDTO)); - return WatchListDTO.WatchListToWatchListDTO(result); - } - } - - public async Task DeleteWatchList(WatchListDTO whiteListDTO) - { - var result = await _accountRepository.DeleteWhiteList(WatchList.WatchListDTOToWatchList(whiteListDTO)); - return WatchListDTO.WatchListToWatchListDTO(result); - } - - public async Task> GetListWatchListByUsername(string username) - { - var result = await _accountRepository.GetListWatchListByUsername(username); - - var resultArray = new List(); - - foreach (var item in result) - { - resultArray.Add(WatchListDTO.WatchListToWatchListDTO(item)); - } - - return resultArray; - } - - public async Task FindAccountByUsername(string username) - { - var result = await _accountRepository.FindAccountByUsername(username); - - return AuthDTO.AuthToAuthDTO(result); - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/ChapterBlackListService.cs b/src/Cesxhin.AnimeManga.Application/Services/ChapterBlackListService.cs deleted file mode 100644 index 7d112db..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/ChapterBlackListService.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using Cesxhin.AnimeManga.Modules.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class ChapterBlackListService : IChapterBlackListService - { - public readonly IChapterBlackListRepository _chapterBlackListRepository; - public ChapterBlackListService(IChapterBlackListRepository chapterBlackListRepository) - { - _chapterBlackListRepository = chapterBlackListRepository; - } - - public async Task GetObjectBlackList(GenericBlackListDTO objectGeneral) - { - { - var find = await _chapterBlackListRepository.GetObjectBlackList(ChapterBlacklist.GenericQueueDTOToChapterBlacklist(objectGeneral)); - - return GenericBlackListDTO.ChapterBlackListToGenericBlackListDTO(find); - } - } - - public async Task> GetObjectsBlackList() - { - var rs = await _chapterBlackListRepository.GetObjectsBlackList(); - - List listGenericQueueDTO = new(); - - foreach (var EpisodeQueue in rs.ToList()) - { - listGenericQueueDTO.Add(GenericBlackListDTO.ChapterBlackListToGenericBlackListDTO(EpisodeQueue)); - } - - return listGenericQueueDTO; - } - - public async Task PutObjectBlackList(GenericBlackListDTO objectGeneral) - { - var objectGeneralRepository = ChapterBlacklist.GenericQueueDTOToChapterBlacklist(objectGeneral); - - try - { - await _chapterBlackListRepository.GetObjectBlackList(objectGeneralRepository); - throw new ApiConflictException("Conflict Chapter queue"); - } - catch (ApiNotFoundException) - { - var rs = await _chapterBlackListRepository.PutObjectBlackList(objectGeneralRepository); - return GenericBlackListDTO.ChapterBlackListToGenericBlackListDTO(rs); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/ChapterQueueService.cs b/src/Cesxhin.AnimeManga.Application/Services/ChapterQueueService.cs deleted file mode 100644 index ef29536..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/ChapterQueueService.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using Cesxhin.AnimeManga.Modules.Exceptions; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class ChapterQueueService : IChapterQueueService - { - public readonly IChapterQueueRepository _chapterQueueRepository; - public ChapterQueueService(IChapterQueueRepository chapterQueueRepository) - { - _chapterQueueRepository = chapterQueueRepository; - } - - public async Task DeleteObjectQueue(GenericQueueDTO objectGeneral) - { - var find = await _chapterQueueRepository.GetObjectQueue(ChapterQueue.GenericQueueDTOToChapterQueue(objectGeneral)); - await _chapterQueueRepository.DeleteObjectQueue(find); - - return objectGeneral; - } - - public async Task GetObjectQueue(GenericQueueDTO objectGeneral) - { - var find = await _chapterQueueRepository.GetObjectQueue(ChapterQueue.GenericQueueDTOToChapterQueue(objectGeneral)); - - return GenericQueueDTO.ChapterQueueToGenericQueueDTO(find); - } - - public async Task> GetObjectsQueue() - { - var rs = await _chapterQueueRepository.GetObjectsQueue(); - - List listGenericQueueDTO = new(); - - foreach (var ChapterQueue in rs.ToList()) - { - listGenericQueueDTO.Add(GenericQueueDTO.ChapterQueueToGenericQueueDTO(ChapterQueue)); - } - - return listGenericQueueDTO; - } - - public async Task PutObjectQueue(GenericQueueDTO objectGeneral) - { - var objectGeneralRepository = ChapterQueue.GenericQueueDTOToChapterQueue(objectGeneral); - - try - { - await _chapterQueueRepository.GetObjectQueue(objectGeneralRepository); - throw new ApiConflictException("Conflict Chapter queue"); - } - catch (ApiNotFoundException) - { - var rs = await _chapterQueueRepository.PutObjectQueue(objectGeneralRepository); - return GenericQueueDTO.ChapterQueueToGenericQueueDTO(rs); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/ChapterRegisterService.cs b/src/Cesxhin.AnimeManga.Application/Services/ChapterRegisterService.cs deleted file mode 100644 index d0b787d..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/ChapterRegisterService.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class ChapterRegisterService : IChapterRegisterService - { - //interfaces - private readonly IChapterRegisterRepository _chapterRegisterRepository; - - public ChapterRegisterService(IChapterRegisterRepository chapterRegisterRepository) - { - _chapterRegisterRepository = chapterRegisterRepository; - } - - //get chapterRegister by chapter id - public async Task GetObjectRegisterByObjectId(string id) - { - var chapterRegister = await _chapterRegisterRepository.GetObjectRegisterByObjectId(id); - return ChapterRegisterDTO.ChapterRegisterToChapterRegisterDTO(chapterRegister); - } - - public async Task> GetObjectsRegistersByListObjectId(List listChapterDTO) - { - List listChapter = new(); - - foreach (var chapterDTO in listChapterDTO) - { - listChapter.Add(Chapter.ChapterDTOToChapter(chapterDTO)); - } - - var rs = await _chapterRegisterRepository.GetObjectsRegistersByListObjectId(listChapter); - - - List listChapterRegisterDTO = new(); - - foreach (var chapterRegister in rs.ToList()) - { - listChapterRegisterDTO.Add(ChapterRegisterDTO.ChapterRegisterToChapterRegisterDTO(chapterRegister)); - } - - return listChapterRegisterDTO; - } - - //insert chapterRegister - public async Task InsertObjectRegisterAsync(ChapterRegisterDTO chapterRegister) - { - var result = await _chapterRegisterRepository.InsertObjectRegisterAsync(ChapterRegister.ChapterRegisterDTOToChapterRegister(chapterRegister)); - return ChapterRegisterDTO.ChapterRegisterToChapterRegisterDTO(result); - } - - //insert list chapterRegister - public async Task> InsertObjectsRegistersAsync(List chaptersRegisters) - { - List chapterRegistersConvert = new(); - foreach (var chapter in chaptersRegisters) - { - chapterRegistersConvert.Add(ChapterRegister.ChapterRegisterDTOToChapterRegister(chapter)); - } - - var resultChapters = await _chapterRegisterRepository.InsertObjectsRegisterAsync(chapterRegistersConvert); - - - List chapterRegistersDTOConvert = new(); - foreach (var chapter in resultChapters) - { - chapterRegistersDTOConvert.Add(ChapterRegisterDTO.ChapterRegisterToChapterRegisterDTO(chapter)); - } - - return chapterRegistersDTOConvert; - } - - //Update chapterRegister - public async Task UpdateObjectRegisterAsync(ChapterRegisterDTO chapterRegister) - { - var chapterResult = await _chapterRegisterRepository.UpdateObjectRegisterAsync(ChapterRegister.ChapterRegisterDTOToChapterRegister(chapterRegister)); - return ChapterRegisterDTO.ChapterRegisterToChapterRegisterDTO(chapterResult); - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/ChapterService.cs b/src/Cesxhin.AnimeManga.Application/Services/ChapterService.cs deleted file mode 100644 index 054774c..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/ChapterService.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class ChapterService : IChapterService - { - //interfaces - private readonly IChapterRepository _chapterRepository; - - public ChapterService(IChapterRepository chapterRepository) - { - _chapterRepository = chapterRepository; - } - - //get chapter by id - public async Task GetObjectByIDAsync(string id) - { - var rs = await _chapterRepository.GetObjectByIDAsync(id); - return ChapterDTO.ChapterToChapterDTO(rs); - } - - //get chapters by name - public async Task> GetObjectsByNameAsync(string name) - { - var listChapter = await _chapterRepository.GetObjectsByNameAsync(name); - - List chapters = new(); - foreach (var chapter in listChapter) - { - chapters.Add(ChapterDTO.ChapterToChapterDTO(chapter)); - } - - return chapters; - } - - //insert one chapter - public async Task InsertObjectAsync(ChapterDTO chapter) - { - var chapterResult = await _chapterRepository.InsertObjectAsync(Chapter.ChapterDTOToChapter(chapter)); - return ChapterDTO.ChapterToChapterDTO(chapterResult); - } - - //insert chapters - public async Task> InsertObjectsAsync(List chapters) - { - List chaptersConvert = new(); - foreach (var chapter in chapters) - { - chaptersConvert.Add(Chapter.ChapterDTOToChapter(chapter)); - } - - var resultChapters = await _chapterRepository.InsertObjectsAsync(chaptersConvert); - - List chaptersDTOConvert = new(); - foreach (var chapter in resultChapters) - { - chaptersDTOConvert.Add(ChapterDTO.ChapterToChapterDTO(chapter)); - } - - return chaptersDTOConvert; - } - - //reset manual - public async Task ResetStatusDownloadObjectByIdAsync(ChapterDTO chapter) - { - var rs = await _chapterRepository.ResetStatusDownloadObjectByIdAsync(Chapter.ChapterDTOToChapter(chapter)); - return ChapterDTO.ChapterToChapterDTO(rs); - } - - //reset automatic - public async Task> ResetStatusMultipleDownloadObjectByIdAsync(string name) - { - var listChapters = await _chapterRepository.GetObjectsByNameAsync(name); - - var resultChapters = await _chapterRepository.ResetStatusDownloadObjectsByIdAsync(listChapters.ToList()); - - List chaptersDTOConvert = new(); - foreach (var chapter in resultChapters) - { - chaptersDTOConvert.Add(ChapterDTO.ChapterToChapterDTO(chapter)); - } - - return chaptersDTOConvert; - } - - //update PercentualState - public async Task UpdateStateDownloadAsync(ChapterDTO chapter) - { - var chapterResult = await _chapterRepository.UpdateStateDownloadAsync(Chapter.ChapterDTOToChapter(chapter)); - return ChapterDTO.ChapterToChapterDTO(chapterResult); - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/DescriptionBookService.cs b/src/Cesxhin.AnimeManga.Application/Services/DescriptionBookService.cs deleted file mode 100644 index 3630acd..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/DescriptionBookService.cs +++ /dev/null @@ -1,278 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.DTO; -using Newtonsoft.Json.Linq; -using NLog; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class DescriptionBookService : IDescriptionBookService - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //interfaces - private readonly IDescriptionRepository _descriptionRepository; - private readonly IChapterRepository _chapterRepository; - private readonly IChapterRegisterRepository _chapterRegisterRepository; - private readonly IAccountService _accountService; - - public DescriptionBookService(IAccountService accountService, IDescriptionRepository descriptionRepository, IChapterRepository chapterRepository, IChapterRegisterRepository chapterRegisterRepository) - { - _descriptionRepository = descriptionRepository; - _chapterRepository = chapterRepository; - _chapterRegisterRepository = chapterRegisterRepository; - _accountService = accountService; - } - - public async Task DeleteNameByIdAsync(string nameCfg, string name) - { - //get episodes - var episodes = await _chapterRepository.GetObjectsByNameAsync(name); - - foreach (var episode in episodes) - { - if (!(episode.StateDownload == "completed" || episode.StateDownload == null)) - throw new ApiConflictException("Conflict DeleteNameByIdAsync"); - } - - try - { - await _descriptionRepository.DeleteNameAsync(nameCfg, name); - } - catch (ApiNotFoundException) - { - _logger.Warn($"I tried delete description book name: {name} nameCfg: {nameCfg}"); - } - - try - { - await _chapterRepository.DeleteByNameAsync(name); - } - catch (ApiNotFoundException) - { - _logger.Warn($"I tried delete chapters name: {name} nameCfg: {nameCfg}"); - } - - return name; - } - - public async Task> GetMostNameByNameAsync(string nameCfg, string name, string username) - { - var result = await _descriptionRepository.GetMostNameByNameAsync(nameCfg, name); - - try - { - var watchList = await _accountService.GetListWatchListByUsername(username); - result.ForEach(item => - { - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == item["name_id"].ToString() && singleWatchList.NameCfg == item["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - item["watchList"] = true; - else - item["watchList"] = false; - }); - } - catch (ApiNotFoundException) { } - - return result; - } - - public async Task> GetNameAllAsync(string nameCfg, string username) - { - var result = await _descriptionRepository.GetNameAllAsync(nameCfg); - - try - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - result.ForEach(item => - { - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == item["name_id"].ToString() && singleWatchList.NameCfg == item["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - item["watchList"] = true; - else - item["watchList"] = false; - }); - } - catch (ApiNotFoundException) { } - - return result; - } - - public async Task> GetNameAllOnlyWatchListAsync(string nameCfg, string username) - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - var result = new List(); - JObject resultFind; - - foreach (var watch in watchList) - { - if (watch.NameCfg == nameCfg) - { - try - { - resultFind = await _descriptionRepository.GetNameByNameAsync(watch.NameCfg, watch.Name); - - if (resultFind != null) - result.Add(resultFind); - } - catch (ApiNotFoundException) { } - } - } - - result.ForEach(item => - { - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == item["name_id"].ToString() && singleWatchList.NameCfg == item["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - item["watchList"] = true; - else - item["watchList"] = false; - }); - - return result; - } - - public async Task> GetNameAllWithAllAsync(string nameCfg, string username) - { - List listGenericDTO = new(); - List listEpisodeDTO = new(); - List listEpisodeRegisterDTO = new(); - - var listDescriptions = await _descriptionRepository.GetNameAllAsync(nameCfg); - - try - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - listDescriptions.ForEach(item => - { - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == item["name_id"].ToString() && singleWatchList.NameCfg == item["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - item["watchList"] = true; - else - item["watchList"] = false; - }); - } - catch (ApiNotFoundException) { } - - //anime - foreach (var description in listDescriptions) - { - var episodes = await _chapterRepository.GetObjectsByNameAsync(description.GetValue("name_id").ToString()); - - //episodes - foreach (var episode in episodes) - { - var episodeRegister = await _chapterRegisterRepository.GetObjectRegisterByObjectId(episode.ID); - - listEpisodeRegisterDTO.Add(ChapterRegisterDTO.ChapterRegisterToChapterRegisterDTO(episodeRegister)); - listEpisodeDTO.Add(ChapterDTO.ChapterToChapterDTO(episode)); - } - - listGenericDTO.Add(new GenericBookDTO - { - Book = description.ToString(), - Chapters = listEpisodeDTO, - ChapterRegister = listEpisodeRegisterDTO - }); - - //reset - listEpisodeDTO = new(); - listEpisodeRegisterDTO = new(); - } - - return listGenericDTO; - } - - public async Task GetNameByNameAsync(string nameCfg, string name, string username) - { - var result = await _descriptionRepository.GetNameByNameAsync(nameCfg, name); - - try - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == result["name_id"].ToString() && singleWatchList.NameCfg == result["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - result["watchList"] = true; - else - result["watchList"] = false; - } - catch (ApiNotFoundException) { } - - return result; - } - - public async Task InsertNameAsync(string nameCfg, JObject description) - { - if (description.ContainsKey("name_id")) - { - try - { - await _descriptionRepository.GetNameByNameAsync(nameCfg, description.GetValue("name_id").ToString()); - throw new ApiConflictException(); - } - catch (ApiNotFoundException) - { - return await _descriptionRepository.InsertNameAsync(nameCfg, description); - } - } - else - { - _logger.Error("Not found field 'name_id' of book"); - throw new ApiNotFoundException("Not found field 'name_id' of book"); - } - } - - public async Task UpdateNameAsync(string nameCfg, JObject description) - { - if (description.ContainsKey("name_id")) - { - await _descriptionRepository.GetNameByNameAsync(nameCfg, description.GetValue("name_id").ToString()); - return await _descriptionRepository.UpdateNameAsync(nameCfg, description); - } - else - { - _logger.Error("Not found field 'name_id' of book"); - throw new ApiNotFoundException("Not found field 'name_id' of book"); - } - } - } -} \ No newline at end of file diff --git a/src/Cesxhin.AnimeManga.Application/Services/DescriptionVideoService.cs b/src/Cesxhin.AnimeManga.Application/Services/DescriptionVideoService.cs deleted file mode 100644 index f51aa44..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/DescriptionVideoService.cs +++ /dev/null @@ -1,286 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.DTO; -using Newtonsoft.Json.Linq; -using NLog; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class DescriptionVideoService : IDescriptionVideoService - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //interfaces - private readonly IDescriptionRepository _descriptionRepository; - private readonly IEpisodeRepository _episodeRepository; - private readonly IEpisodeRegisterRepository _episodeRegisterRepository; - private readonly IAccountService _accountService; - - public DescriptionVideoService(IAccountService accountService, IDescriptionRepository descriptionRepository, IEpisodeRepository episodeRepository, IEpisodeRegisterRepository episodeRegisterRepository) - { - _descriptionRepository = descriptionRepository; - _episodeRepository = episodeRepository; - _episodeRegisterRepository = episodeRegisterRepository; - _accountService = accountService; - } - public async Task DeleteNameByIdAsync(string nameCfg, string name) - { - //get episodes - var episodes = await _episodeRepository.GetObjectsByNameAsync(name); - - foreach (var episode in episodes) - { - if (!(episode.StateDownload == "completed" || episode.StateDownload == null)) - throw new ApiConflictException(); - } - - try - { - await _descriptionRepository.DeleteNameAsync(nameCfg, name); - } - catch (ApiNotFoundException) - { - _logger.Warn($"I tried delete description video name: {name} nameCfg: {nameCfg}"); - } - - try - { - await _episodeRepository.DeleteByNameAsync(name); - } - catch (ApiNotFoundException) - { - _logger.Warn($"I tried delete episodes name: {name} nameCfg: {nameCfg}"); - } - - return name; - } - - public async Task> GetMostNameByNameAsync(string nameCfg, string name, string username) - { - var result = await _descriptionRepository.GetMostNameByNameAsync(nameCfg, name); - - try - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - result.ForEach(item => - { - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == item["name_id"].ToString() && singleWatchList.NameCfg == item["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - item["watchList"] = true; - else - item["watchList"] = false; - }); - } - catch (ApiNotFoundException) { } - - return result; - } - - public async Task> GetNameAllAsync(string nameCfg, string username) - { - var result = await _descriptionRepository.GetNameAllAsync(nameCfg); - - try - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - result.ForEach(item => - { - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == item["name_id"].ToString() && singleWatchList.NameCfg == item["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - item["watchList"] = true; - else - item["watchList"] = false; - }); - } - catch (ApiNotFoundException) { } - - return result; - } - - public async Task> GetNameAllOnlyWatchListAsync(string nameCfg, string username) - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - var result = new List(); - JObject resultFind; - - foreach (var watch in watchList) - { - if (watch.NameCfg == nameCfg) - { - try - { - resultFind = await _descriptionRepository.GetNameByNameAsync(watch.NameCfg, watch.Name); - - if (resultFind != null) - result.Add(resultFind); - } - catch (ApiNotFoundException) { } - } - } - - result.ForEach(item => - { - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == item["name_id"].ToString() && singleWatchList.NameCfg == item["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - item["watchList"] = true; - else - item["watchList"] = false; - }); - - return result; - } - - public async Task> GetNameAllWithAllAsync(string nameCfg, string username) - { - List listGenericDTO = new(); - - List listEpisodeDTO = new(); - List listEpisodeRegisterDTO = new(); - - var listDescriptions = await _descriptionRepository.GetNameAllAsync(nameCfg); - - try - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - listDescriptions.ForEach(item => - { - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == item["name_id"].ToString() && singleWatchList.NameCfg == item["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Any()) - item["watchList"] = true; - else - item["watchList"] = false; - }); - } - catch (ApiNotFoundException) { } - - //anime - foreach (var description in listDescriptions) - { - var episodes = await _episodeRepository.GetObjectsByNameAsync(description.GetValue("name_id").ToString()); - - //episodes - foreach (var episode in episodes) - { - var episodeRegister = await _episodeRegisterRepository.GetObjectRegisterByObjectId(episode.ID); - - listEpisodeRegisterDTO.Add(EpisodeRegisterDTO.EpisodeRegisterToEpisodeRegisterDTO(episodeRegister)); - listEpisodeDTO.Add(EpisodeDTO.EpisodeToEpisodeDTO(episode)); - } - - var objectAll = JObject.FromObject(new - { - description, - listEpisodeDTO, - listEpisodeRegisterDTO - }); - - listGenericDTO.Add(new GenericVideoDTO() - { - Video = description.ToString(), - Episodes = listEpisodeDTO, - EpisodesRegister = listEpisodeRegisterDTO - }); - - //reset - listEpisodeDTO = new(); - listEpisodeRegisterDTO = new(); - } - - return listGenericDTO; - } - - public async Task GetNameByNameAsync(string nameCfg, string name, string username) - { - var result = await _descriptionRepository.GetNameByNameAsync(nameCfg, name); - - try - { - var watchList = await _accountService.GetListWatchListByUsername(username); - - var filterWatchList = watchList.Where((singleWatchList) => - { - if (singleWatchList.Name == result["name_id"].ToString() && singleWatchList.NameCfg == result["nameCfg"].ToString()) - return true; - return false; - }); - - if (filterWatchList.Count() > 0) - result["watchList"] = true; - else - result["watchList"] = false; - } - catch (ApiNotFoundException) { } - - return result; - } - - public async Task InsertNameAsync(string nameCfg, JObject description) - { - if (description.ContainsKey("name_id")) - { - try - { - await _descriptionRepository.GetNameByNameAsync(nameCfg, description.GetValue("name_id").ToString()); - throw new ApiConflictException(); - } - catch (ApiNotFoundException) - { - return await _descriptionRepository.InsertNameAsync(nameCfg, description); - } - } - else - { - _logger.Error("Not found field 'name_id' of video"); - throw new ApiConflictException("Not found field 'name_id' of video"); - } - } - - public async Task UpdateNameAsync(string nameCfg, JObject description) - { - if (description.ContainsKey("name_id")) - { - await _descriptionRepository.GetNameByNameAsync(nameCfg, description.GetValue("name_id").ToString()); - return await _descriptionRepository.UpdateNameAsync(nameCfg, description); - } - else - { - _logger.Error("Not found field 'name_id' of video"); - throw new ApiConflictException("Not found field 'name_id' of video"); - } - } - } -} \ No newline at end of file diff --git a/src/Cesxhin.AnimeManga.Application/Services/EpisodeBlackListService.cs b/src/Cesxhin.AnimeManga.Application/Services/EpisodeBlackListService.cs deleted file mode 100644 index 850c265..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/EpisodeBlackListService.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using Cesxhin.AnimeManga.Modules.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class EpisodeBlackListService : IEpisodeBlackListService - { - public readonly IEpisodeBlackListRepository _episodeBlackListRepository; - public EpisodeBlackListService(IEpisodeBlackListRepository episodeBlackListRepository) - { - _episodeBlackListRepository = episodeBlackListRepository; - } - - public async Task GetObjectBlackList(GenericBlackListDTO objectGeneral) - { - { - var find = await _episodeBlackListRepository.GetObjectBlackList(EpisodeBlacklist.GenericQueueDTOToEpisodeBlacklist(objectGeneral)); - - return GenericBlackListDTO.EpisodeBlackListToGenericBlackListDTO(find); - } - } - - public async Task> GetObjectsBlackList() - { - var rs = await _episodeBlackListRepository.GetObjectsBlackList(); - - List listGenericQueueDTO = new(); - - foreach (var EpisodeQueue in rs.ToList()) - { - listGenericQueueDTO.Add(GenericBlackListDTO.EpisodeBlackListToGenericBlackListDTO(EpisodeQueue)); - } - - return listGenericQueueDTO; - } - - public async Task PutObjectBlackList(GenericBlackListDTO objectGeneral) - { - var objectGeneralRepository = EpisodeBlacklist.GenericQueueDTOToEpisodeBlacklist(objectGeneral); - - try - { - await _episodeBlackListRepository.GetObjectBlackList(objectGeneralRepository); - throw new ApiConflictException("Conflict Chapter BlackList"); - } - catch (ApiNotFoundException) - { - var rs = await _episodeBlackListRepository.PutObjectBlackList(objectGeneralRepository); - return GenericBlackListDTO.EpisodeBlackListToGenericBlackListDTO(rs); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/EpisodeQueueService.cs b/src/Cesxhin.AnimeManga.Application/Services/EpisodeQueueService.cs deleted file mode 100644 index 3b005ef..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/EpisodeQueueService.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using Cesxhin.AnimeManga.Modules.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class EpisodeQueueService : IEpisodeQueueService - { - public readonly IEpisodeQueueRepository _episodeQueueRepository; - public EpisodeQueueService(IEpisodeQueueRepository episodeQueueRepository) - { - _episodeQueueRepository = episodeQueueRepository; - } - - public async Task DeleteObjectQueue(GenericQueueDTO objectGeneral) - { - var find = await _episodeQueueRepository.GetObjectQueue(EpisodeQueue.GenericQueueDTOToEpisodeQueue(objectGeneral)); - await _episodeQueueRepository.DeleteObjectQueue(find); - - return objectGeneral; - } - - public async Task GetObjectQueue(GenericQueueDTO objectGeneral) - { - var find = await _episodeQueueRepository.GetObjectQueue(EpisodeQueue.GenericQueueDTOToEpisodeQueue(objectGeneral)); - - return GenericQueueDTO.EpisodeQueueToGenericQueueDTO(find); - } - - public async Task> GetObjectsQueue() - { - var rs = await _episodeQueueRepository.GetObjectsQueue(); - - List listGenericQueueDTO = new(); - - foreach (var EpisodeQueue in rs.ToList()) - { - listGenericQueueDTO.Add(GenericQueueDTO.EpisodeQueueToGenericQueueDTO(EpisodeQueue)); - } - - return listGenericQueueDTO; - } - - public async Task PutObjectQueue(GenericQueueDTO objectGeneral) - { - var objectGeneralRepository = EpisodeQueue.GenericQueueDTOToEpisodeQueue(objectGeneral); - - try - { - await _episodeQueueRepository.GetObjectQueue(objectGeneralRepository); - throw new ApiConflictException("Conflict Chapter queue"); - } - catch (ApiNotFoundException) - { - var rs = await _episodeQueueRepository.PutObjectQueue(objectGeneralRepository); - return GenericQueueDTO.EpisodeQueueToGenericQueueDTO(rs); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/EpisodeRegisterService.cs b/src/Cesxhin.AnimeManga.Application/Services/EpisodeRegisterService.cs deleted file mode 100644 index 86626ed..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/EpisodeRegisterService.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class EpisodeRegisterService : IEpisodeRegisterService - { - //interfaces - private readonly IEpisodeRegisterRepository _episodeRegisterRepository; - - public EpisodeRegisterService(IEpisodeRegisterRepository episodeRegisterRepository) - { - _episodeRegisterRepository = episodeRegisterRepository; - } - - //get episodeRegister by episode id - public async Task GetObjectRegisterByObjectId(string id) - { - var episodeRegister = await _episodeRegisterRepository.GetObjectRegisterByObjectId(id); - return EpisodeRegisterDTO.EpisodeRegisterToEpisodeRegisterDTO(episodeRegister); - } - - public async Task> GetObjectsRegistersByListObjectId(List listEpisodeDTO) - { - List listEpisode = new(); - - foreach(var episodeDTO in listEpisodeDTO) - { - listEpisode.Add(Episode.EpisodeDTOToEpisode(episodeDTO)); - } - - var rs = await _episodeRegisterRepository.GetObjectsRegistersByListObjectId(listEpisode); - - - List listEpisodeRegisterDTO = new(); - - foreach (var episodeRegister in rs.ToList()) - { - listEpisodeRegisterDTO.Add(EpisodeRegisterDTO.EpisodeRegisterToEpisodeRegisterDTO(episodeRegister)); - } - - return listEpisodeRegisterDTO; - } - - //insert episodeRegister - public async Task InsertObjectRegisterAsync(EpisodeRegisterDTO episodeRegister) - { - var rs = await _episodeRegisterRepository.InsertObjectRegisterAsync(EpisodeRegister.EpisodeRegisterToEpisodeRegisterDTO(episodeRegister)); - return EpisodeRegisterDTO.EpisodeRegisterToEpisodeRegisterDTO(rs); - } - - //insert list episodeRegister - public async Task> InsertObjectsRegistersAsync(List episodesRegistersDTO) - { - List resultEpisodes = new(); - foreach (var episode in episodesRegistersDTO) - { - var episodeResult = await _episodeRegisterRepository.InsertObjectRegisterAsync(EpisodeRegister.EpisodeRegisterToEpisodeRegisterDTO(episode)); - resultEpisodes.Add(EpisodeRegisterDTO.EpisodeRegisterToEpisodeRegisterDTO(episodeResult)); - } - return resultEpisodes; - } - - //Update episodeRegister - public async Task UpdateObjectRegisterAsync(EpisodeRegisterDTO episodeRegister) - { - var rs = await _episodeRegisterRepository.UpdateObjectRegisterAsync(EpisodeRegister.EpisodeRegisterToEpisodeRegisterDTO(episodeRegister)); - return EpisodeRegisterDTO.EpisodeRegisterToEpisodeRegisterDTO(rs); - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/EpisodeService.cs b/src/Cesxhin.AnimeManga.Application/Services/EpisodeService.cs deleted file mode 100644 index 06a24df..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/EpisodeService.cs +++ /dev/null @@ -1,95 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class EpisodeService : IEpisodeService - { - //interfaces - private readonly IEpisodeRepository _episodeRepository; - - public EpisodeService(IEpisodeRepository episodeRepository) - { - _episodeRepository = episodeRepository; - } - - //get episode by id - public async Task GetObjectByIDAsync(string id) - { - var episode = await _episodeRepository.GetObjectByIDAsync(id); - return EpisodeDTO.EpisodeToEpisodeDTO(episode); - } - - //get episodes by name - public async Task> GetObjectsByNameAsync(string name) - { - var listEpisode = await _episodeRepository.GetObjectsByNameAsync(name); - - List episodes = new(); - foreach (var episode in listEpisode) - { - episodes.Add(EpisodeDTO.EpisodeToEpisodeDTO(episode)); - } - - return episodes; - } - - //insert one episode - public async Task InsertObjectAsync(EpisodeDTO episode) - { - var episodeResult = await _episodeRepository.InsertObjectAsync(Episode.EpisodeDTOToEpisode(episode)); - return EpisodeDTO.EpisodeToEpisodeDTO(episodeResult); - } - - //insert episodes - public async Task> InsertObjectsAsync(List episodes) - { - List resultEpisodes = new(); - foreach (var episode in episodes) - { - var episodeResult = await _episodeRepository.InsertObjectAsync(Episode.EpisodeDTOToEpisode(episode)); - resultEpisodes.Add(EpisodeDTO.EpisodeToEpisodeDTO(episodeResult)); - } - return resultEpisodes; - } - - //reset StatusDownload to null - public async Task ResetStatusDownloadObjectByIdAsync(EpisodeDTO episode) - { - var episodeResult = await _episodeRepository.ResetStatusDownloadObjectByIdAsync(Episode.EpisodeDTOToEpisode(episode)); - return EpisodeDTO.EpisodeToEpisodeDTO(episodeResult); - } - - //reset all state - public async Task> ResetStatusMultipleDownloadObjectByIdAsync(string name) - { - var listEpisodes = await _episodeRepository.GetObjectsByNameAsync(name); - - var resultEpisodes = await _episodeRepository.ResetStatusDownloadObjectsByIdAsync(listEpisodes.ToList()); - - List episodesDTOConvert = new(); - foreach (var episode in resultEpisodes) - { - episodesDTOConvert.Add(EpisodeDTO.EpisodeToEpisodeDTO(episode)); - } - - return episodesDTOConvert; - } - - //update PercentualState - public async Task UpdateStateDownloadAsync(EpisodeDTO episode) - { - var episodeResult = await _episodeRepository.UpdateStateDownloadAsync(Episode.EpisodeDTOToEpisode(episode)); - - if (episodeResult == null) - return null; - - return EpisodeDTO.EpisodeToEpisodeDTO(episodeResult); - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/ProgressChapterService.cs b/src/Cesxhin.AnimeManga.Application/Services/ProgressChapterService.cs deleted file mode 100644 index 3bbb2e9..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/ProgressChapterService.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class ProgressChapterService : IProgressChapterService - { - public readonly IProgressChapterRepository _progressChapterRepository; - public ProgressChapterService(IProgressChapterRepository progressChapterRepository) - { - _progressChapterRepository = progressChapterRepository; - } - - public async Task GetProgressByName(string name, string username, string nameCfg) - { - var result = await _progressChapterRepository.CheckProgress(name, username, nameCfg); - return ProgressChapterDTO.ProgressChapterToProgressChapterDTO(result); - } - - public async Task UpdateProgress(ProgressChapterDTO progress) - { - ProgressChapter result; - - try - { - await _progressChapterRepository.CheckProgress(progress.Name, progress.Username, progress.NameCfg); - result = await _progressChapterRepository.UpdateProgress(ProgressChapter.ProgressChapterDTOToProgressChapter(progress)); - } - catch (ApiNotFoundException) - { - result = await _progressChapterRepository.CreateProgress(ProgressChapter.ProgressChapterDTOToProgressChapter(progress)); - } - - return ProgressChapterDTO.ProgressChapterToProgressChapterDTO(result); - - } - } -} diff --git a/src/Cesxhin.AnimeManga.Application/Services/ProgressEpisodeService.cs b/src/Cesxhin.AnimeManga.Application/Services/ProgressEpisodeService.cs deleted file mode 100644 index 27a9b72..0000000 --- a/src/Cesxhin.AnimeManga.Application/Services/ProgressEpisodeService.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Application.Interfaces.Services; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Application.Services -{ - public class ProgressEpisodeService : IProgressEpisodeService - { - public readonly IProgressEpisodeRepository _progressEpisodeRepository; - public ProgressEpisodeService(IProgressEpisodeRepository progressEpisodeRepository) - { - _progressEpisodeRepository = progressEpisodeRepository; - } - - public async Task GetProgressByName(string name, string username, string nameCfg) - { - var result = await _progressEpisodeRepository.CheckProgress(name, username, nameCfg); - return ProgressEpisodeDTO.ProgressEpisodeToProgressEpisodeDTO(result); - } - - public async Task UpdateProgress(ProgressEpisodeDTO progress) - { - ProgressEpisode result; - - try - { - await _progressEpisodeRepository.CheckProgress(progress.Name, progress.Username, progress.NameCfg); - result = await _progressEpisodeRepository.UpdateProgress(ProgressEpisode.ProgressEpisodeDTOToProgressEpisode(progress)); - } - catch (ApiNotFoundException) - { - result = await _progressEpisodeRepository.CreateProgress(ProgressEpisode.ProgressEpisodeDTOToProgressEpisode(progress)); - } - - return ProgressEpisodeDTO.ProgressEpisodeToProgressEpisodeDTO(result); - - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Cesxhin.AnimeManga.Persistence.csproj b/src/Cesxhin.AnimeManga.Persistence/Cesxhin.AnimeManga.Persistence.csproj deleted file mode 100644 index a8f81bf..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Cesxhin.AnimeManga.Persistence.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net5.0 - - - - - - - - - - - - - - - diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/AccountRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/AccountRepository.cs deleted file mode 100644 index dfb59e6..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/AccountRepository.cs +++ /dev/null @@ -1,152 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.Models; -using NLog; -using Npgsql; -using RepoDb; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class AccountRepository : IAccountRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task CreateAccount(Auth auth) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - try - { - rs = await connection.InsertAsync(auth); - } - catch (Exception ex) - { - _logger.Error($"Failed CreateAccount, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return auth; - else - throw new ApiNotFoundException("Not found CreateAccount"); - } - } - - public async Task DeleteWhiteList(WatchList whiteList) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.ExecuteQueryAsync($"DELETE FROM whitelist WHERE name = '{whiteList.Name}' AND username = '{whiteList.Username}' AND namecfg = '{whiteList.NameCfg}'"); - } - catch (Exception ex) - { - _logger.Error($"Failed DeleteWhiteList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - return whiteList; - } - } - - public async Task FindAccountByUsername(string username) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Username == username); - } - catch (Exception ex) - { - _logger.Error($"Failed findAccountByUsername, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found findAccountByUsername"); - } - } - - public async Task> GetListWatchListByUsername(string username) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Username == username); - } - catch (Exception ex) - { - _logger.Error($"Failed GetListWatchListByUsername, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs; - else - throw new ApiNotFoundException("Not found GetListWatchListByUsername"); - } - } - - public async Task InsertWhiteList(WatchList whiteList) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - try - { - rs = await connection.InsertAsync(whiteList); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertWhiteList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return whiteList; - else - throw new ApiNotFoundException("Not found InsertWhiteList"); - } - } - - public async Task WhiteListCheckByName(string name, string username) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Name == name && e.Username == username); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertWhiteList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return true; - else - throw new ApiNotFoundException("Not found InsertWhiteList"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterBlackListRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterBlackListRepository.cs deleted file mode 100644 index 156c9be..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterBlackListRepository.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Domain.Models; -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Modules.NlogManager; -using NLog; -using Npgsql; -using RepoDb; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class ChapterBlackListRepository : IChapterBlackListRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task GetObjectBlackList(ChapterBlacklist genericQueue) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Url == genericQueue.Url && e.NameCfg == genericQueue.NameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectBlackList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found GetObjectBlackList"); - } - } - - public async Task> GetObjectsBlackList() - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAllAsync(); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectsBlackList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs; - else - throw new ApiNotFoundException("Not found GetObjectsBlackList"); - } - } - - public async Task PutObjectBlackList(ChapterBlacklist genericQueue) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - try - { - rs = await connection.InsertAsync(genericQueue); - } - catch (Exception ex) - { - _logger.Error($"Failed PutObjectBlackList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return genericQueue; - else - throw new ApiNotFoundException("Not found PutObjectBlackList"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterQueueRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterQueueRepository.cs deleted file mode 100644 index a1c7861..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterQueueRepository.cs +++ /dev/null @@ -1,113 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Domain.Models; -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Modules.NlogManager; -using NLog; -using Npgsql; -using RepoDb; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class ChapterQueueRepository : IChapterQueueRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task DeleteObjectQueue(ChapterQueue objectGeneral) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs; - try - { - rs = await connection.DeleteAsync(e => e.Url == objectGeneral.Url && e.NameCfg == objectGeneral.NameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed DeleteChapterQueue, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - - if (rs > 0) - return rs; - else - throw new ApiNotFoundException("Not found DeleteChapterQueue"); - } - } - - public async Task GetObjectQueue(ChapterQueue genericQueue) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Url == genericQueue.Url && e.NameCfg == genericQueue.NameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed GetChapterQueue, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found GetChapterQueue"); - } - } - - public async Task> GetObjectsQueue() - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAllAsync(); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectsQueue, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs; - else - throw new ApiNotFoundException("Not found GetObjectsQueue"); - } - } - - public async Task PutObjectQueue(ChapterQueue genericQueue) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - try - { - rs = await connection.InsertAsync(genericQueue); - } - catch (Exception ex) - { - _logger.Error($"Failed PutChapterQueue, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return genericQueue; - else - throw new ApiNotFoundException("Not found PutChapterQueue"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterRegisterRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterRegisterRepository.cs deleted file mode 100644 index 6433230..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterRegisterRepository.cs +++ /dev/null @@ -1,136 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.Models; -using NLog; -using Npgsql; -using RepoDb; -using RepoDb.Enumerations; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class ChapterRegisterRepository : IChapterRegisterRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task GetObjectRegisterByObjectId(string id) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.ChapterId == id); - } - catch (Exception ex) - { - _logger.Error($"Failed GetChapterRegisterByChapterId, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found GetObjectsRegisterByObjectId"); - } - } - - public async Task> InsertObjectsRegisterAsync(List chapterRegister) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - try - { - rs = await connection.InsertAllAsync(chapterRegister); - - } - catch (Exception ex) - { - _logger.Error($"Failed InsertChapterRegisterAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return chapterRegister; - else - throw new ApiNotFoundException("Not found InsertObjectRegisterAsync"); - } - } - - public async Task InsertObjectRegisterAsync(ChapterRegister chapterRegister) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - try - { - rs = await connection.InsertAsync(chapterRegister); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertChapterRegisterAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return chapterRegister; - else - throw new ApiNotFoundException("Not found InsertObjectRegisterAsync"); - } - } - - public async Task UpdateObjectRegisterAsync(ChapterRegister chapterRegister) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - try - { - rs = await connection.UpdateAsync(chapterRegister, e => e.ChapterId == chapterRegister.ChapterId); - } - catch (Exception ex) - { - _logger.Error($"Failed UpdateEpisodeRegisterAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return chapterRegister; - else - throw new ApiNotFoundException("Not found UpdateObjectRegisterAsync"); - } - } - - public async Task> GetObjectsRegistersByListObjectId(List listChapters) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAsync(new QueryField("chapterid", Operation.In, listChapters.Select(e => e.ID))); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectsRegistersByListObjectId, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs; - else - throw new ApiNotFoundException("Not found GetObjectsRegistersByListObjectId"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterRepository.cs deleted file mode 100644 index 6926465..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/ChapterRepository.cs +++ /dev/null @@ -1,219 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Modules.Generic; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.Models; -using NLog; -using Npgsql; -using RepoDb; -using RepoDb.Enumerations; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class ChapterRepository : IChapterRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task DeleteByNameAsync(string id) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - try - { - rs = await connection.DeleteAsync(e => e.NameManga == id); - } - catch (Exception ex) - { - _logger.Error($"Failed GetChapterByIDAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return rs; - else - throw new ApiNotFoundException("Not found DeleteByNameAsync"); - } - } - - public async Task GetObjectByIDAsync(string id) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAsync(e => e.ID == id); - } - catch (Exception ex) - { - _logger.Error($"Failed GetChapterByIDAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found GetObjectsByIDAsync"); - } - } - - public async Task> GetObjectsByNameAsync(string nameManga) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAsync(e => e.NameManga == nameManga, orderBy: OrderField.Parse(new - { - currentchapter = Order.Ascending - })); - } - catch (Exception ex) - { - _logger.Error($"Failed GetChaptersByNameAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return ConvertGeneric.ConvertIEnurableToListCollection(rs); - else - throw new ApiNotFoundException("Not found GetObjectsByNameAsync"); - } - } - - public async Task InsertObjectAsync(Chapter chapter) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - - try - { - rs = await connection.InsertAsync(chapter); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertObjectAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return chapter; - else - throw new ApiNotFoundException("Not found InsertObjectAsync"); - } - } - - public async Task> InsertObjectsAsync(List chapters) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - rs = await connection.InsertAllAsync(chapters); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertChapterAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return chapters; - else - throw new ApiNotFoundException("Not found InsertObjectsAsync"); - } - } - - public async Task ResetStatusDownloadObjectByIdAsync(Chapter chapter) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - chapter.PercentualDownload = 0; - chapter.StateDownload = null; - - try - { - rs = await connection.UpdateAsync(chapter, e => e.StateDownload != "completed" && e.ID == chapter.ID); - } - catch (Exception ex) - { - _logger.Error($"Failed ResetStatusDownloadChaptersByIdAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return chapter; - else - throw new ApiNotFoundException("Not found ResetStatusDownloadObjectByIdAsync"); - } - } - - public async Task> ResetStatusDownloadObjectsByIdAsync(List chapters) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - try - { - var chaptersUpdate = chapters.Where(e => e.StateDownload != "completed").ToList(); - chaptersUpdate.ForEach(e => - { - e.PercentualDownload = 0; - e.StateDownload = null; - }); - - rs = await connection.UpdateAllAsync(chaptersUpdate); - } - catch (Exception ex) - { - _logger.Error($"Failed ResetStatusDownloadChaptersByIdAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return chapters; - else - throw new ApiNotFoundException("Not found ResetStatusDownloadObjectsByIdAsync"); - } - } - - public async Task UpdateStateDownloadAsync(Chapter chapter) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - try - { - rs = await connection.UpdateAsync(chapter); - } - catch (Exception ex) - { - _logger.Error($"Failed UpdateStateDownloadAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return chapter; - else - throw new ApiNotFoundException("Not found UpdateStateDownloadAsync"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/DescriptionRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/DescriptionRepository.cs deleted file mode 100644 index 381b8d9..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/DescriptionRepository.cs +++ /dev/null @@ -1,187 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Modules.NlogManager; -using MongoDB.Bson; -using MongoDB.Driver; -using Newtonsoft.Json.Linq; -using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class DescriptionRepository : IDescriptionRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION_MONGO"); - readonly string _nameDatabase = Environment.GetEnvironmentVariable("NAME_DATABASE_MONGO"); - readonly JObject _schema = JObject.Parse(Environment.GetEnvironmentVariable("SCHEMA")); - - private static string RemoveObjectId(string result) - { - var regex = new Regex(Regex.Escape("ObjectId(")); - var partOne = regex.Replace(result, "", 1); - - - regex = new Regex(Regex.Escape(")")); - return regex.Replace(partOne, "", 1); - - } - - private string GetNameTable(string nameCfg) - { - if (_schema.ContainsKey(nameCfg)) - { - return _schema.GetValue(nameCfg).ToObject().GetValue("name").ToString(); - } - - return null; - } - - public async Task DeleteNameAsync(string nameCfg, string id) - { - var client = new MongoClient(_connectionString); - - int rs = 0; - try - { - var database = client.GetDatabase(_nameDatabase); - var collection = database.GetCollection("description_" + GetNameTable(nameCfg)); - var deleteFilter = Builders.Filter.Eq("name_id", id); - var result = await collection.DeleteOneAsync(deleteFilter); - - rs = (int)result.DeletedCount; - } - catch (Exception ex) - { - client.Cluster.Dispose(); - _logger.Error($"Failed DeleteNameAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return rs; - else - throw new ApiNotFoundException("Not found DeleteNameAsync"); - } - - public Task> GetMostNameByNameAsync(string nameCfg, string name) - { - throw new NotImplementedException(); - } - - public async Task> GetNameAllAsync(string nameCfg) - { - var client = new MongoClient(_connectionString); - - List list; - try - { - var database = client.GetDatabase(_nameDatabase); - var collection = database.GetCollection("description_" + GetNameTable(nameCfg)); - list = collection.Find(Builders.Filter.Empty).ToList(); - } - catch (Exception ex) - { - client.Cluster.Dispose(); - _logger.Error($"Failed DeleteNameAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (list != null && list.Any()) - { - var listObject = new List(); - - foreach (var item in list) - { - listObject.Add(JObject.Parse(RemoveObjectId(item.ToString()))); - } - - return listObject; - } - else - throw new ApiNotFoundException("Not found GetNameAllAsync"); - } - - public async Task GetNameByNameAsync(string nameCfg, string name) - { - var client = new MongoClient(_connectionString); - - BsonDocument result; - try - { - var database = client.GetDatabase(_nameDatabase); - var collection = database.GetCollection("description_" + GetNameTable(nameCfg)); - var findFilter = Builders.Filter.Eq("name_id", name); - result = collection.Find(findFilter).FirstOrDefault(); - } - catch (Exception ex) - { - client.Cluster.Dispose(); - _logger.Error($"Failed DeleteNameAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (result != null && result.Any()) - return JObject.Parse(RemoveObjectId(result.ToString())); - else - throw new ApiNotFoundException("Not found GetNameByNameAsync"); - } - - public async Task InsertNameAsync(string nameCfg, JObject description) - { - var client = new MongoClient(_connectionString); - try - { - var database = client.GetDatabase(_nameDatabase); - var collection = database.GetCollection("description_" + GetNameTable(nameCfg)); - await collection.InsertOneAsync(BsonDocument.Parse(description.ToString())); - - return description; - } - catch (Exception ex) - { - client.Cluster.Dispose(); - _logger.Error($"Failed DeleteNameAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - } - - public async Task UpdateNameAsync(string nameCfg, JObject description) - { - var client = new MongoClient(_connectionString); - try - { - var database = client.GetDatabase(_nameDatabase); - var collection = database.GetCollection("description_" + GetNameTable(nameCfg)); - FilterDefinition findFilter = Builders.Filter.Eq("name_id", (string)description["name_id"]); - List> update = new(); - - update.Add(Builders.Update.Set("name_id", (string)description["name_id"])); - - foreach (var field in description) - { - if (field.Key == "_id") - continue; - update.Add(Builders.Update.Set(field.Key, (string)description[field.Key])); - } - - await collection.UpdateOneAsync(findFilter, Builders.Update.Combine(update)); - - return description; - } - catch (Exception ex) - { - client.Cluster.Dispose(); - _logger.Error($"Failed DeleteNameAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeBlackListRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeBlackListRepository.cs deleted file mode 100644 index ebe533c..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeBlackListRepository.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Domain.Models; -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Modules.NlogManager; -using NLog; -using Npgsql; -using RepoDb; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class EpisodeBlackListRepository : IEpisodeBlackListRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task GetObjectBlackList(EpisodeBlacklist genericQueue) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Url == genericQueue.Url && e.NameCfg == genericQueue.NameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectBlackList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found GetObjectBlackList"); - } - } - - public async Task> GetObjectsBlackList() - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAllAsync(); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectsBlackList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs; - else - throw new ApiNotFoundException("Not found GetObjectsBlackList"); - } - } - - public async Task PutObjectBlackList(EpisodeBlacklist genericQueue) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - try - { - rs = await connection.InsertAsync(genericQueue); - } - catch (Exception ex) - { - _logger.Error($"Failed PutObjectBlackList, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return genericQueue; - else - throw new ApiNotFoundException("Not found PutObjectBlackList"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeQueueRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeQueueRepository.cs deleted file mode 100644 index 2df7412..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeQueueRepository.cs +++ /dev/null @@ -1,113 +0,0 @@ -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Domain.Models; -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Modules.NlogManager; -using NLog; -using Npgsql; -using RepoDb; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class EpisodeQueueRepository : IEpisodeQueueRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task DeleteObjectQueue(EpisodeQueue objectGeneral) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs; - try - { - rs = await connection.DeleteAsync(e => e.Url == objectGeneral.Url && e.NameCfg == objectGeneral.NameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed DeleteEpisodeQueue, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - - if (rs > 0) - return rs; - else - throw new ApiNotFoundException("Not found DeleteEpisodeQueue"); - } - } - - public async Task GetObjectQueue(EpisodeQueue genericQueue) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Url == genericQueue.Url && e.NameCfg == genericQueue.NameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed GetEpisodeQueue, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found GetEpisodeQueue"); - } - } - - public async Task> GetObjectsQueue() - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAllAsync(); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectsQueue, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs; - else - throw new ApiNotFoundException("Not found GetObjectsQueue"); - } - } - - public async Task PutObjectQueue(EpisodeQueue genericQueue) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - try - { - rs = await connection.InsertAsync(genericQueue); - } - catch (Exception ex) - { - _logger.Error($"Failed PutEpisodeQueue, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return genericQueue; - else - throw new ApiNotFoundException("Not found PutEpisodeQueue"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeRegisterRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeRegisterRepository.cs deleted file mode 100644 index 9a6aaa6..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeRegisterRepository.cs +++ /dev/null @@ -1,141 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.Models; -using NLog; -using Npgsql; -using RepoDb; -using RepoDb.Enumerations; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class EpisodeRegisterRepository : IEpisodeRegisterRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - //get all episodesRegisters - public async Task GetObjectRegisterByObjectId(string id) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.EpisodeId == id); - } - catch (Exception ex) - { - _logger.Error($"Failed GetEpisodeRegisterByEpisodeId, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found GetObjectsRegisterByObjectId"); - } - } - - //insert - public async Task> InsertObjectsRegisterAsync(List episodeRegister) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - rs = await connection.InsertAllAsync(episodeRegister); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertEpisodeRegisterAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return episodeRegister; - else - throw new ApiNotFoundException("Not found InsertObjectRegisterAsync"); - } - } - - public async Task InsertObjectRegisterAsync(EpisodeRegister episodeRegister) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - - try - { - rs = await connection.InsertAsync(episodeRegister); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertEpisodeRegisterAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return episodeRegister; - else - throw new ApiNotFoundException("Not found InsertObjectRegisterAsync"); - } - } - - //update - public async Task UpdateObjectRegisterAsync(EpisodeRegister episodeRegister) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - rs = await connection.UpdateAsync(episodeRegister, e => e.EpisodeId == episodeRegister.EpisodeId); - } - catch (Exception ex) - { - _logger.Error($"Failed UpdateEpisodeRegisterAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return episodeRegister; - else - throw new ApiNotFoundException("Not found UpdateObjectRegisterAsync"); - } - } - - public async Task> GetObjectsRegistersByListObjectId(List listEpisodes) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAsync(new QueryField("episodeid", Operation.In, listEpisodes.Select(e => e.ID))); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectsRegistersByListObjectId, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs; - else - throw new ApiNotFoundException("Not found GetObjectsRegistersByListObjectId"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeRepository.cs deleted file mode 100644 index 1a6078d..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/EpisodeRepository.cs +++ /dev/null @@ -1,228 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.Models; -using NLog; -using Npgsql; -using RepoDb; -using RepoDb.Enumerations; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class EpisodeRepository : IEpisodeRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task DeleteByNameAsync(string id) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - rs = await connection.DeleteAsync(e => e.VideoId == id); - } - catch (Exception ex) - { - _logger.Error($"Failed DeleteByNameAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return rs; - else - throw new ApiNotFoundException("Not found DeleteByNameAsync"); - } - } - - //get episode by id - public async Task GetObjectByIDAsync(string id) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAsync(e => e.ID == id); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectByIDAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found GetObjectByIDAsync"); - } - } - - //get episodes by name - public async Task> GetObjectsByNameAsync(string name) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - - try - { - rs = await connection.QueryAsync(e => e.VideoId == name, orderBy: OrderField.Parse(new - { - numberepisodecurrent = Order.Ascending - })); - } - catch (Exception ex) - { - _logger.Error($"Failed GetObjectsByNameAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs; - else - throw new ApiNotFoundException("Not found GetObjectsByNameAsync"); - } - } - - //insert episode - public async Task InsertObjectAsync(Episode episode) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - - try - { - rs = await connection.InsertAsync(episode); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertObjectAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return episode; - else - throw new ApiNotFoundException("Not found InsertObjectAsync"); - } - } - - public async Task> InsertObjectsAsync(List episodes) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - rs = await connection.InsertAllAsync(episodes); - } - catch (Exception ex) - { - _logger.Error($"Failed InsertObjectsAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return episodes; - else - throw new ApiNotFoundException("Not found InsertObjectsAsync"); - } - } - - //reset StatusDownlod to null - public async Task ResetStatusDownloadObjectByIdAsync(Episode episode) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - episode.PercentualDownload = 0; - episode.StateDownload = null; - - try - { - - rs = await connection.UpdateAsync(episode, e => e.StateDownload != "completed" && e.ID == episode.ID); - - } - catch (Exception ex) - { - _logger.Error($"Failed ResetStatusDownloadObjectByIdAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return episode; - else - throw new ApiNotFoundException("Not found ResetStatusDownloadObjectByIdAsync"); - } - } - - public async Task> ResetStatusDownloadObjectsByIdAsync(List episodes) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - var episodesUpdate = episodes.Where(e => e.StateDownload != "completed").ToList(); - episodesUpdate.ForEach((e) => - { - e.PercentualDownload = 0; - e.StateDownload = null; - }); - - rs = await connection.UpdateAllAsync(episodesUpdate); - } - catch (Exception ex) - { - _logger.Error($"Failed ResetStatusDownloadObjectsByIdAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return episodes; - else - throw new ApiNotFoundException("Not found ResetStatusDownloadObjectsByIdAsync"); - } - } - - //update percentualDownload - public async Task UpdateStateDownloadAsync(Episode episode) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - rs = await connection.UpdateAsync(episode); - } - catch (Exception ex) - { - _logger.Error($"Failed UpdateStateDownloadAsync, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return episode; - else - throw new ApiNotFoundException("Not found UpdateStateDownloadAsync"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/ProgressChapterRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/ProgressChapterRepository.cs deleted file mode 100644 index ca40eaa..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/ProgressChapterRepository.cs +++ /dev/null @@ -1,91 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.Models; -using NLog; -using Npgsql; -using RepoDb; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class ProgressChapterRepository : IProgressChapterRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task CheckProgress(string name, string username, string nameCfg) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Name == name && e.Username == username && e.NameCfg == nameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed CheckProgress, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found CheckProgress"); - } - } - - public async Task CreateProgress(ProgressChapter progress) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - - try - { - rs = await connection.InsertAsync(progress); - } - catch (Exception ex) - { - _logger.Error($"Failed CreateProgress, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return progress; - else - throw new ApiNotFoundException("Not found CreateProgress"); - } - } - - public async Task UpdateProgress(ProgressChapter progress) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - rs = await connection.UpdateAsync(progress, e => e.Name == progress.Name && e.Username == progress.Username && e.NameCfg == progress.NameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed UpdateProgress, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return progress; - else - throw new ApiNotFoundException("Not found UpdateProgress"); - } - } - } -} diff --git a/src/Cesxhin.AnimeManga.Persistence/Repositories/ProgressEpisodeRepository.cs b/src/Cesxhin.AnimeManga.Persistence/Repositories/ProgressEpisodeRepository.cs deleted file mode 100644 index 38bf142..0000000 --- a/src/Cesxhin.AnimeManga.Persistence/Repositories/ProgressEpisodeRepository.cs +++ /dev/null @@ -1,91 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Cesxhin.AnimeManga.Application.Interfaces.Repositories; -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.Models; -using NLog; -using Npgsql; -using RepoDb; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Persistence.Repositories -{ - public class ProgressEpisodeRepository : IProgressEpisodeRepository - { - //log - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //env - readonly string _connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION"); - - public async Task CheckProgress(string name, string username, string nameCfg) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - IEnumerable rs; - try - { - rs = await connection.QueryAsync(e => e.Name == name && e.Username == username && e.NameCfg == nameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed CheckProgress, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && rs.Any()) - return rs.First(); - else - throw new ApiNotFoundException("Not found CheckProgress"); - } - } - - public async Task CreateProgress(ProgressEpisode progress) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - object rs = null; - - try - { - rs = await connection.InsertAsync(progress); - } - catch (Exception ex) - { - _logger.Error($"Failed CreateProgress, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs != null && !string.IsNullOrEmpty(rs.ToString())) - return progress; - else - throw new ApiNotFoundException("Not found CreateProgress"); - } - } - - public async Task UpdateProgress(ProgressEpisode progress) - { - using (var connection = new NpgsqlConnection(_connectionString)) - { - int rs = 0; - - try - { - rs = await connection.UpdateAsync(progress, e => e.Name == progress.Name && e.Username == progress.Username && e.NameCfg == progress.NameCfg); - } - catch (Exception ex) - { - _logger.Error($"Failed UpdateProgress, details error: {ex.Message}"); - throw new ApiGenericException(ex.Message); - } - - if (rs > 0) - return progress; - else - throw new ApiNotFoundException("Not found UpdateProgress"); - } - } - } -} diff --git a/src/applications/interfaces/repositories/IAccountRepository.ts b/src/applications/interfaces/repositories/IAccountRepository.ts new file mode 100644 index 0000000..1d6490c --- /dev/null +++ b/src/applications/interfaces/repositories/IAccountRepository.ts @@ -0,0 +1,13 @@ +import { IAccount } from "../../../domain/interfaces/models/IAccount"; +import IConnectionRepository from "./generic/IConnectionRepository"; + +export default interface IAccountRepository extends IConnectionRepository{ + //get + findFromUsername(username: string): Promise; + //put + createAccount(data: IAccount): Promise; + //post + updateAccount(username: string, data: Partial): Promise; + //delete + deleteAccount(username: string): Promise; +} // eslint-disable-line @stylistic/semi \ No newline at end of file diff --git a/src/applications/interfaces/repositories/IFriendRepository.ts b/src/applications/interfaces/repositories/IFriendRepository.ts new file mode 100644 index 0000000..191cd63 --- /dev/null +++ b/src/applications/interfaces/repositories/IFriendRepository.ts @@ -0,0 +1,15 @@ +import { IFriend } from "../../../domain/interfaces/models/IFriend"; +import IConnectionRepository from "./generic/IConnectionRepository"; + +export default interface IFriendRepository extends IConnectionRepository{ + //get + findByFriend(username: string, friend: string): Promise; + listPaginated(username: string, skip: number, length: number): Promise>; + countTotalFromUsername(username: string): Promise; + + //put + createFriend(data: Partial): Promise; + + //delete + deleteFriend(username: string, friend: string): Promise; +} // eslint-disable-line @stylistic/semi \ No newline at end of file diff --git a/src/applications/interfaces/repositories/IRequestRepository.ts b/src/applications/interfaces/repositories/IRequestRepository.ts new file mode 100644 index 0000000..7abd8a2 --- /dev/null +++ b/src/applications/interfaces/repositories/IRequestRepository.ts @@ -0,0 +1,17 @@ +import { IRequest } from "../../../domain/interfaces/models/IRequest"; +import { Request } from "../../../domain/models/Request"; +import IConnectionRepository from "./generic/IConnectionRepository"; + +export default interface IRequestRepository extends IConnectionRepository { + //get + findByRequest(request_from: string, request_to: string): Promise + listPaginatedFromRequestFrom(request_from: string, skip: number, length: number): Promise> + listPaginatedFromRequestTo(request_to: string, skip: number, length: number): Promise> + countTotalFromRequestFrom(request_from: string): Promise + + //put + create(data: IRequest): Promise + + //delete + delete(request_from: string, request_to: string): Promise +} // eslint-disable-line @stylistic/semi \ No newline at end of file diff --git a/src/applications/interfaces/repositories/generic/IConnectionRepository.ts b/src/applications/interfaces/repositories/generic/IConnectionRepository.ts new file mode 100644 index 0000000..1bba2fa --- /dev/null +++ b/src/applications/interfaces/repositories/generic/IConnectionRepository.ts @@ -0,0 +1,5 @@ +import { Repository } from "typeorm"; + +export default interface IConnectionRepository{ + connectionRepository: Repository; +} // eslint-disable-line @stylistic/semi \ No newline at end of file diff --git a/src/applications/interfaces/services/IAccountService.ts b/src/applications/interfaces/services/IAccountService.ts new file mode 100644 index 0000000..40e15da --- /dev/null +++ b/src/applications/interfaces/services/IAccountService.ts @@ -0,0 +1,14 @@ +import {IAccountDTO} from "../../../domain/interfaces/DTOs/IAccountDTO"; +import {IAccount} from "../../../domain/interfaces/models/IAccount"; + +export default interface IAccountService { + //get + findFromUsername(username: string): Promise; + login(username: string, password: string): Promise; + //put + createAccount(data: Partial): Promise; + //post + updateAccount(username: string, data: Partial): Promise; + //delete + deleteAccount(username: string): void; +} // eslint-disable-line @stylistic/semi \ No newline at end of file diff --git a/src/applications/interfaces/services/IFriendService.ts b/src/applications/interfaces/services/IFriendService.ts new file mode 100644 index 0000000..1c9b9c4 --- /dev/null +++ b/src/applications/interfaces/services/IFriendService.ts @@ -0,0 +1,9 @@ +import { ISchemaReturnPaginatedFriend } from "../../../schemas/friendSchema"; + +export default interface IFriendService { + //get + listPaginated(username: string, skip: number, length: number): Promise; + + //delete + deleteFriend(username: string, friend: string): Promise; +} // eslint-disable-line @stylistic/semi \ No newline at end of file diff --git a/src/applications/interfaces/services/IRequestService.ts b/src/applications/interfaces/services/IRequestService.ts new file mode 100644 index 0000000..7f6c783 --- /dev/null +++ b/src/applications/interfaces/services/IRequestService.ts @@ -0,0 +1,15 @@ +import { ISchemaReturnPaginatedRequest } from "../../../schemas/requestSchema"; + +export default interface IRequestService { + //get + listRequestWaitPaginated(request_from: string, skip: number, length: number): Promise + listRequestForActionPaginated(request_to: string, skip: number, length: number): Promise + + //post + create(auth_username: string, request_to: string): Promise + action(request_from: string, auth_username: string, accept: boolean): Promise + + //delete + delete(auth_username: string, request_to: string): Promise + +} // eslint-disable-line @stylistic/semi \ No newline at end of file diff --git a/src/applications/repositories/AccountRepository.ts b/src/applications/repositories/AccountRepository.ts new file mode 100644 index 0000000..1a8cccc --- /dev/null +++ b/src/applications/repositories/AccountRepository.ts @@ -0,0 +1,77 @@ +import { DeleteResult, UpdateResult } from "typeorm"; + +import {pg} from "../../server/postgres"; +import { ApiErrorGeneric, ApiNotFound } from "../../modules/api"; + +import IAccountRepository from "../interfaces/repositories/IAccountRepository"; +import { IAccount, IAccountEnv } from "../../domain/interfaces/models/IAccount"; + +import { Account } from "../../domain/models/Account"; + +import Logger from "../../modules/logger"; +const logger = new Logger("account-db"); + +export default class AccountRepository implements IAccountRepository { + connectionRepository = pg.getRepository(Account); + + //get + async findFromUsername(username: string): Promise { + let rs: IAccount | null = null; + + try { + rs = await this.connectionRepository.findOneBy({ [IAccountEnv.USERNAME]: username }); + } catch (err){ + logger.error("Failed exec query findFromUsername, details:", err); + throw new ApiErrorGeneric(err); + } + + if (rs === null){ + throw new ApiNotFound(`Not found this username '${username}'`); + } + + return rs; + } + + //post + async createAccount(data: Partial): Promise { + data[IAccountEnv.USERNAME] = data[IAccountEnv.USERNAME].toLowerCase(); + + try { + await this.connectionRepository.insert(data); + } catch (err){ + logger.error("Failed exec query createAccount, details:", err); + throw new ApiErrorGeneric(err); + } + } + + //put + async updateAccount(username: string, data: Partial): Promise { + let rs: UpdateResult; + try { + rs = await this.connectionRepository.update({ [IAccountEnv.USERNAME]: username }, data); + } catch (err){ + logger.error("Failed exec query updateAccount, details:", err); + throw new ApiErrorGeneric(err); + } + + if (rs.affected <= 0){ + throw new ApiNotFound(`Cannot update information of ${username}`); + } + } + + //delete + async deleteAccount(username: string): Promise { + let rs: DeleteResult; + try { + rs = await this.connectionRepository.delete({ [IAccountEnv.USERNAME]: username }); + } catch (err){ + logger.error("Failed exec query updateAccount, details:", err); + throw new ApiErrorGeneric(err); + } + + if (rs.affected <= 0){ + throw new ApiNotFound(`Cannot delete ${username}`); + } + } + +} \ No newline at end of file diff --git a/src/applications/repositories/FriendRepository.ts b/src/applications/repositories/FriendRepository.ts new file mode 100644 index 0000000..d426335 --- /dev/null +++ b/src/applications/repositories/FriendRepository.ts @@ -0,0 +1,79 @@ +import { DeleteResult } from "typeorm"; + +import {pg} from "../../server/postgres"; +import { ApiErrorGeneric, ApiNotFound } from "../../modules/api"; + +import IFriendRepository from "../interfaces/repositories/IFriendRepository"; + +import { IFriend, IFriendEnv } from "../../domain/interfaces/models/IFriend"; +import { Friend } from "../../domain/models/Friends"; + +import Logger from "../../modules/logger"; +const logger = new Logger("friend-db"); + +export default class FriendRepository implements IFriendRepository { + connectionRepository = pg.getRepository(Friend); + + //get + async findByFriend(username: string, friend: string): Promise { + let rs: IFriend | null = null; + + try { + rs = await this.connectionRepository.findOneBy({[IFriendEnv.USERNAME]: username, [IFriendEnv.FRIEND]: friend }); + } catch (err){ + logger.error("Failed exec query findByFriend, details:", err); + throw new ApiErrorGeneric(err); + } + + if (rs === null){ + throw new ApiNotFound(`Not found friend: ${friend}`); + } + + return rs; + } + async listPaginated(username: string, skip: number, length: number): Promise> { + let rs: Array = []; + + try { + rs = await this.connectionRepository.find({ where: { [IFriendEnv.USERNAME]: username }, order: { [IFriendEnv.BECOME_FRIEND_TIME]: "DESC" }, skip, take: length }); + } catch (err){ + logger.error("Failed exec query listPaginated, details:", err); + throw new ApiErrorGeneric(err); + } + + return rs; + } + async countTotalFromUsername(username: string): Promise { + try { + return await this.connectionRepository.countBy({ [IFriendEnv.USERNAME]: username }); + } catch (err){ + logger.error("Failed exec query countTotal, details:", err); + throw new ApiErrorGeneric(err); + } + } + + //post + async createFriend(data: Partial): Promise { + try { + await this.connectionRepository.insert(data); + } catch (err){ + logger.error("Failed exec query createFriend, details:", err); + throw new ApiErrorGeneric(err); + } + } + + //delete + async deleteFriend(username: string, friend: string): Promise { + let rs: DeleteResult; + try { + rs = await this.connectionRepository.delete({ [IFriendEnv.FRIEND]: friend, [IFriendEnv.USERNAME]: username }); + } catch (err){ + logger.error("Failed exec query deleteFriend, details:", err); + throw new ApiErrorGeneric(err); + } + + if (rs.affected <= 0){ + throw new ApiNotFound(`Cannot delete friend ${friend}`); + } + } +} \ No newline at end of file diff --git a/src/applications/repositories/RequestRepository.ts b/src/applications/repositories/RequestRepository.ts new file mode 100644 index 0000000..b1c55a0 --- /dev/null +++ b/src/applications/repositories/RequestRepository.ts @@ -0,0 +1,88 @@ +import { DeleteResult } from "typeorm"; + +import {pg} from "../../server/postgres"; +import { ApiErrorGeneric, ApiNotFound } from "../../modules/api"; + +import IRequestRepository from "../interfaces/repositories/IRequestRepository"; +import { IRequest, IRequestEnv } from "../../domain/interfaces/models/IRequest"; + +import { Request } from "../../domain/models/Request"; + +import Logger from "../../modules/logger"; +const logger = new Logger("request-db"); + +export default class RequestRepository implements IRequestRepository { + connectionRepository = pg.getRepository(Request); + + //get + async findByRequest(request_from: string, request_to: string): Promise { + let request: IRequest; + try { + request = await this.connectionRepository.findOneBy({ [IRequestEnv.REQUEST_FROM]: request_from, [IRequestEnv.REQUEST_TO]: request_to }); + } catch (err){ + logger.error("Failed exec query findByTarget, details:", err); + throw new ApiErrorGeneric(err); + } + + if (request === null){ + throw new ApiNotFound(`Not found request with request_from: "${request_from}" request_to: "${request_to}"`); + } + + return request; + } + async listPaginatedFromRequestFrom(request_from: string, skip: number = 0, length: number = 10): Promise> { + let rs: Array = []; + try { + rs = await this.connectionRepository.find({where: {[IRequestEnv.REQUEST_FROM]: request_from}, order: {[IRequestEnv.REQUEST_TIME]: "ASC"}, skip, take: length}); + } catch (err){ + logger.error("Failed exec query listPaginatedFromRequestFrom, details:", err); + throw new ApiErrorGeneric(err); + } + + return rs; + } + async listPaginatedFromRequestTo(request_to: string, skip: number = 0, length: number = 10): Promise> { + let rs: Array = []; + try { + rs = await this.connectionRepository.find({where: {[IRequestEnv.REQUEST_TO]: request_to}, order: {[IRequestEnv.REQUEST_TIME]: "ASC"}, skip, take: length}); + } catch (err){ + logger.error("Failed exec query listPaginatedFromRequestTo, details:", err); + throw new ApiErrorGeneric(err); + } + + return rs; + } + async countTotalFromRequestFrom(request_from: string): Promise { + try { + return await this.connectionRepository.count({where: {[IRequestEnv.REQUEST_FROM]: request_from}}); + } catch (err){ + logger.error("Failed exec query countTotal, details:", err); + throw new ApiErrorGeneric(err); + } + } + + //put + async create(data: Partial): Promise { + try { + await this.connectionRepository.insert(data); + } catch (err){ + logger.error("Failed exec query create, details:", err); + throw new ApiErrorGeneric(err); + } + } + + //delete + async delete(request_from: string, request_to: string): Promise { + let rs: DeleteResult; + try { + rs = await this.connectionRepository.delete({[IRequestEnv.REQUEST_FROM]: request_from, [IRequestEnv.REQUEST_TO]: request_to}); + } catch (err){ + logger.error("Failed exec query delete, details:", err); + throw new ApiErrorGeneric(err); + } + + if (rs.affected <= 0){ + throw new ApiNotFound(`Cannot delete request with request_from: "${request_from}" request_to: "${request_to}"`); + } + } +} \ No newline at end of file diff --git a/src/applications/services/AccountService.ts b/src/applications/services/AccountService.ts new file mode 100644 index 0000000..2a99c67 --- /dev/null +++ b/src/applications/services/AccountService.ts @@ -0,0 +1,80 @@ +import _ from "lodash"; + +import IAccountService from "../interfaces/services/IAccountService"; +import { IAccountDTO, IAccountDTOEnv } from "../../domain/interfaces/DTOs/IAccountDTO"; +import { IAccount, IAccountEnv } from "../../domain/interfaces/models/IAccount"; + +import AccountRepository from "../repositories/AccountRepository"; + +import {hashPassword} from "../../utils/accountUtils"; +import { ApiConflict, ApiNotFound, ApiUnauthorized } from "../../modules/api"; + +import { objectAssign } from "../../utils/genericUtils"; + +export class AccountService implements IAccountService { + accountRepository = new AccountRepository(); + + //get + async findFromUsername(username: string): Promise { + const user = await this.accountRepository.findFromUsername(username); + + return objectAssign(user, IAccountDTOEnv); + } + + //post + async login(username: string, password: string): Promise { + let user: IAccount; + + try { + user = await this.accountRepository.findFromUsername(username); + } catch (e){ + if (e instanceof ApiNotFound){ + throw new ApiUnauthorized("Username/Password wrong"); + } else { + throw new e; + } + } + + if (hashPassword(password) !== user[IAccountEnv.PASSWORD]){ + throw new ApiUnauthorized("Username/Password wrong"); + } + + return objectAssign(user, IAccountDTOEnv); + } + async createAccount(data: Partial): Promise { + const username = data[IAccountEnv.USERNAME]; + + try { + await this.accountRepository.findFromUsername(username); + } catch (e){ + if (e instanceof ApiNotFound){ + data[IAccountEnv.PASSWORD] = hashPassword(data[IAccountEnv.PASSWORD]); + await this.accountRepository.createAccount(data); + + const user = await this.accountRepository.findFromUsername(data[IAccountEnv.USERNAME]); + return objectAssign(user, IAccountDTOEnv); + } else { + throw new e; + } + } + + throw new ApiConflict(`This username already used ${username}`); + } + + //update + async updateAccount(username: string, data: Partial): Promise { + const user = await this.accountRepository.findFromUsername(username); + + await this.accountRepository.updateAccount(username, data); + + //update information + const newUser = _.merge(user, data); + + return objectAssign(newUser, IAccountDTOEnv); + } + + //delete + async deleteAccount(username: string): Promise { + await this.accountRepository.deleteAccount(username); + } +} \ No newline at end of file diff --git a/src/applications/services/FriendService.ts b/src/applications/services/FriendService.ts new file mode 100644 index 0000000..5ad1a62 --- /dev/null +++ b/src/applications/services/FriendService.ts @@ -0,0 +1,31 @@ +import async from "async"; + +import { objectAssign } from "../../utils/genericUtils"; + +import FriendRepository from "../repositories/FriendRepository"; +import IFriendService from "../interfaces/services/IFriendService"; + +import { ISchemaReturnPaginatedFriend } from "../../schemas/friendSchema"; +import { IFriendDTO, IFriendDTOEnv } from "../../domain/interfaces/DTOs/IFriendDTO"; + +export class FriendService implements IFriendService { + friendRepository = new FriendRepository(); + + //get + async listPaginated(username: string, skip: number, length: number): Promise { + const {count, list} = await async.parallel, count: number}>({ + list: async () => (await this.friendRepository.listPaginated(username, skip, length)).map((reqeust) => objectAssign(reqeust, IFriendDTOEnv)), + count: async () => await this.friendRepository.countTotalFromUsername(username) + }); + + return { + list, + max_count: count + }; + } + + //delete + async deleteFriend(username: string, friend: string): Promise { + this.friendRepository.deleteFriend(username, friend); + } +} \ No newline at end of file diff --git a/src/applications/services/RequestService.ts b/src/applications/services/RequestService.ts new file mode 100644 index 0000000..3a70868 --- /dev/null +++ b/src/applications/services/RequestService.ts @@ -0,0 +1,129 @@ +import async from "async"; + +import { ApiBadRequest, ApiConflict, ApiNotFound } from "../../modules/api"; + +import { objectAssign } from "../../utils/genericUtils"; + +import { IRequest, IRequestEnv } from "../../domain/interfaces/models/IRequest"; +import { IRequestDTO, IRequestDTOEnv } from "../../domain/interfaces/DTOs/IRequestDTO"; + +import { ISchemaReturnPaginatedRequest } from "../../schemas/requestSchema"; + +import IRequestService from "../interfaces/services/IRequestService"; + +import FriendRepository from "../repositories/FriendRepository"; +import RequestRepository from "../repositories/RequestRepository"; +import AccountRepository from "../repositories/AccountRepository"; +import { IFriend, IFriendEnv } from "../../domain/interfaces/models/IFriend"; + +export class RequestService implements IRequestService { + requestRepository = new RequestRepository(); + accountRepository = new AccountRepository(); + friendRepository = new FriendRepository(); + + //get + async listRequestWaitPaginated(request_from: string, skip: number, length: number): Promise { + const {count, list} = await async.parallel, count: number}>({ + list: async () => (await this.requestRepository.listPaginatedFromRequestFrom(request_from, skip, length)).map((reqeust) => objectAssign(reqeust, IRequestDTOEnv)), + count: async () => await this.requestRepository.countTotalFromRequestFrom(request_from) + }); + + return { + list, + max_count: count + }; + } + async listRequestForActionPaginated(request_to: string, skip: number, length: number): Promise { + const {count, list} = await async.parallel, count: number}>({ + list: async () => (await this.requestRepository.listPaginatedFromRequestTo(request_to, skip, length)).map((reqeust) => objectAssign(reqeust, IRequestDTOEnv)), + count: async () => await this.requestRepository.countTotalFromRequestFrom(request_to) + }); + + return { + list, + max_count: count + }; + } + + //post + async create(auth_username: string, request_to: string): Promise { + request_to = request_to.toLowerCase(); + + if (auth_username === request_to){ + throw new ApiBadRequest(`${IRequestEnv.REQUEST_FROM} cannot be same ${IRequestEnv.REQUEST_TO}`); + } + + const {findRequest, findRequestTO, alreadyFriend} = await async.parallel({ + findRequest: async () => { + try { + await this.requestRepository.findByRequest(auth_username, request_to); + } catch (err){ + if (err instanceof ApiNotFound){ + return false; + } else { + throw new err; + } + } + + return true; + }, + findRequestTO: async () => { + try { + await this.accountRepository.findFromUsername(request_to); + } catch (err){ + if (err instanceof ApiNotFound){ + return false; + } else { + throw new err; + } + } + + return true; + }, + alreadyFriend: async () => { + try { + await this.friendRepository.findByFriend(auth_username, request_to); + } catch (err){ + if (err instanceof ApiNotFound){ + return false; + } else { + throw new err; + } + } + + return true; + } + }); + + if (!findRequest && findRequestTO && !alreadyFriend){ + const data: Partial = { + [IRequestEnv.REQUEST_FROM]: auth_username, + [IRequestEnv.REQUEST_TO]: request_to + }; + return await this.requestRepository.create(data); + } else if (!findRequestTO){ + throw new ApiNotFound(`The user "${request_to}" not exist!`); + } else if (alreadyFriend){ + throw new ApiConflict("He is already your friend"); + } else { + throw new ApiConflict("The request to become a friend has already been sent"); + } + } + async action(request_from: string, auth_username: string, accept: boolean): Promise { + await this.requestRepository.findByRequest(request_from, auth_username); + + if (accept){ + const data: Partial = { + [IFriendEnv.USERNAME]: request_from, + [IFriendEnv.FRIEND]: auth_username + }; + + await this.friendRepository.createFriend(data); + } + + await this.requestRepository.delete(request_from, auth_username); + } + async delete(auth_username: string, request_to: string): Promise { + await this.requestRepository.delete(auth_username, request_to); + } +} \ No newline at end of file diff --git a/src/controllers/accountController/createRoute.ts b/src/controllers/accountController/createRoute.ts new file mode 100644 index 0000000..1f861c9 --- /dev/null +++ b/src/controllers/accountController/createRoute.ts @@ -0,0 +1,23 @@ +import { PATH_BASE_CONTROLLER, schemaCreateAccount, schemaReturnAccount } from "../../schemas/accountSchema"; +import { SCHEMA_BAD_REQUEST, SCHEMA_CONFLICT, SCHEMA_INTERNAL_SERVER, SCHEMA_UNAUTHORIZED } from "../../schemas/generic/genericSchema"; + +import { AccountService } from "../../applications/services/AccountService"; + +import fastify from "../../server/fastify"; + +const accountService = new AccountService(); + +fastify.post(`${PATH_BASE_CONTROLLER}/create`, { + schema: { + tags: ["account"], + summary: "Create new account", + body: schemaCreateAccount, + response: { + 200: schemaReturnAccount, + 500: { $ref: SCHEMA_INTERNAL_SERVER }, + 400: { $ref: SCHEMA_BAD_REQUEST }, + 409: { $ref: SCHEMA_CONFLICT }, + 401: { $ref: SCHEMA_UNAUTHORIZED } + } + } +}, async (request, replay) => replay.status(200).send(await accountService.createAccount(request.body))); \ No newline at end of file diff --git a/src/controllers/accountController/deleteRoute.ts b/src/controllers/accountController/deleteRoute.ts new file mode 100644 index 0000000..bc59929 --- /dev/null +++ b/src/controllers/accountController/deleteRoute.ts @@ -0,0 +1,28 @@ +import { SCHEMA_INTERNAL_SERVER, SCHEMA_NOT_FOUND, schemaReturnVoid } from "../../schemas/generic/genericSchema"; +import { PATH_BASE_CONTROLLER} from "../../schemas/accountSchema"; + +import { AccountService } from "../../applications/services/AccountService"; + +import fastify from "../../server/fastify"; +import { schemaQueryUsernameAuth } from "../../schemas/generic/authSchema"; + +const accountService = new AccountService(); + +fastify.delete(`${PATH_BASE_CONTROLLER}/delete`, { + schema: { + tags: ["account"], + summary: "Delete account", + querystring: schemaQueryUsernameAuth, + response: { + 200: schemaReturnVoid, + 500: { $ref: SCHEMA_INTERNAL_SERVER }, + 404: { $ref: SCHEMA_NOT_FOUND } + } + } +}, async (request, replay) => { + const {auth_username} = request.query; + + await accountService.deleteAccount(auth_username); + + replay.status(200).send({ response: "ok" }); +}); \ No newline at end of file diff --git a/src/controllers/accountController/findRoute.ts b/src/controllers/accountController/findRoute.ts new file mode 100644 index 0000000..a156bcd --- /dev/null +++ b/src/controllers/accountController/findRoute.ts @@ -0,0 +1,26 @@ +import { PATH_BASE_CONTROLLER, schemaReturnAccount } from "../../schemas/accountSchema"; +import { SCHEMA_INTERNAL_SERVER, SCHEMA_NOT_FOUND } from "../../schemas/generic/genericSchema"; + +import { AccountService } from "../../applications/services/AccountService"; + +import fastify from "../../server/fastify"; +import { schemaQueryUsernameAuth } from "../../schemas/generic/authSchema"; + +const accountService = new AccountService(); + +fastify.get(`${PATH_BASE_CONTROLLER}/find`, { + schema: { + tags: ["account"], + summary: "Find account", + querystring: schemaQueryUsernameAuth, + response: { + 200: schemaReturnAccount, + 500: { $ref: SCHEMA_INTERNAL_SERVER }, + 404: { $ref: SCHEMA_NOT_FOUND } + } + } +}, async (request, replay) => { + const {auth_username} = request.query; + + replay.status(200).send(await accountService.findFromUsername(auth_username)); +}); \ No newline at end of file diff --git a/src/controllers/accountController/updateRoute.ts b/src/controllers/accountController/updateRoute.ts new file mode 100644 index 0000000..bb4eb23 --- /dev/null +++ b/src/controllers/accountController/updateRoute.ts @@ -0,0 +1,28 @@ +import { PATH_BASE_CONTROLLER, schemaUpdateAccount, schemaReturnAccount } from "../../schemas/accountSchema"; +import { SCHEMA_INTERNAL_SERVER, SCHEMA_NOT_FOUND } from "../../schemas/generic/genericSchema"; + +import { AccountService } from "../../applications/services/AccountService"; + +import fastify from "../../server/fastify"; +import { schemaQueryUsernameAuth } from "../../schemas/generic/authSchema"; + +const accountService = new AccountService(); + +fastify.put(`${PATH_BASE_CONTROLLER}/update`, { + schema: { + tags: ["account"], + summary: "Update values of account", + querystring: schemaQueryUsernameAuth, + body: schemaUpdateAccount, + response: { + 200: schemaReturnAccount, + 500: { $ref: SCHEMA_INTERNAL_SERVER }, + 404: { $ref: SCHEMA_NOT_FOUND } + } + } +}, async (request, replay) => { + const {auth_username} = request.query; + const account = request.body; + + replay.status(200).send(await accountService.updateAccount(auth_username, account)); +}); \ No newline at end of file diff --git a/src/controllers/friendController/listRoute.ts b/src/controllers/friendController/listRoute.ts new file mode 100644 index 0000000..a072933 --- /dev/null +++ b/src/controllers/friendController/listRoute.ts @@ -0,0 +1,24 @@ +import { FriendService } from "../../applications/services/FriendService"; + +import { PATH_BASE_CONTROLLER, schemaQueryPaginatedFriend, schemaReturnPaginatedFriend } from "../../schemas/friendSchema"; +import { SCHEMA_INTERNAL_SERVER } from "../../schemas/generic/genericSchema"; + +import fastify from "../../server/fastify"; + +const friendService = new FriendService(); + +fastify.get(`${PATH_BASE_CONTROLLER}/list`, { + schema: { + tags: ["friend"], + summary: "List my friends", + querystring: schemaQueryPaginatedFriend, + response: { + 200: schemaReturnPaginatedFriend, + 500: { $ref: SCHEMA_INTERNAL_SERVER } + } + } +}, async (request, replay) => { + const {length, skip, auth_username} = request.query; + + replay.status(200).send(await friendService.listPaginated(auth_username, skip, length)); +}); \ No newline at end of file diff --git a/src/controllers/friendController/removeRoute.ts b/src/controllers/friendController/removeRoute.ts new file mode 100644 index 0000000..cc7eeeb --- /dev/null +++ b/src/controllers/friendController/removeRoute.ts @@ -0,0 +1,26 @@ +import { FriendService } from "../../applications/services/FriendService"; + +import { PATH_BASE_CONTROLLER, schemaQueryUsernameOfFriend } from "../../schemas/friendSchema"; +import { SCHEMA_INTERNAL_SERVER, schemaReturnVoid } from "../../schemas/generic/genericSchema"; + +import fastify from "../../server/fastify"; + +const friendService = new FriendService(); + +fastify.delete(`${PATH_BASE_CONTROLLER}/remove`, { + schema: { + tags: ["friend"], + summary: "Remove my friend", + querystring: schemaQueryUsernameOfFriend, + response: { + 200: schemaReturnVoid, + 500: { $ref: SCHEMA_INTERNAL_SERVER } + } + } +}, async (request, replay) => { + const {friend, auth_username} = request.query; + + await friendService.deleteFriend(auth_username, friend); + + replay.status(200).send({ response: "ok" }); +}); \ No newline at end of file diff --git a/src/controllers/requestController/actionRoute.ts b/src/controllers/requestController/actionRoute.ts new file mode 100644 index 0000000..42bc74b --- /dev/null +++ b/src/controllers/requestController/actionRoute.ts @@ -0,0 +1,26 @@ +import { RequestService } from "../../applications/services/RequestService"; + +import { PATH_BASE_CONTROLLER, schemaActionRequest } from "../../schemas/requestSchema"; +import { SCHEMA_INTERNAL_SERVER, schemaReturnVoid } from "../../schemas/generic/genericSchema"; + +import fastify from "../../server/fastify"; + +const requestService = new RequestService(); + +fastify.post(`${PATH_BASE_CONTROLLER}/action`, { + schema: { + tags: ["request"], + summary: "Choose accept or refuse request friend", + querystring: schemaActionRequest, + response: { + 200: schemaReturnVoid, + 500: { $ref: SCHEMA_INTERNAL_SERVER } + } + } +}, async (request, replay) => { + const {accept, request_from, auth_username} = request.query; + + await requestService.action(request_from, auth_username, accept); + + replay.status(200).send({ response: "ok" }); +}); \ No newline at end of file diff --git a/src/controllers/requestController/createRoute.ts b/src/controllers/requestController/createRoute.ts new file mode 100644 index 0000000..cf30f05 --- /dev/null +++ b/src/controllers/requestController/createRoute.ts @@ -0,0 +1,31 @@ +import { RequestService } from "../../applications/services/RequestService"; + +import { PATH_BASE_CONTROLLER, schemaCreateRequest } from "../../schemas/requestSchema"; +import { SCHEMA_BAD_REQUEST, SCHEMA_INTERNAL_SERVER, SCHEMA_NOT_FOUND, schemaReturnVoid } from "../../schemas/generic/genericSchema"; + +import fastify from "../../server/fastify"; +import { schemaQueryUsernameAuth } from "../../schemas/generic/authSchema"; + +const requestService = new RequestService(); + +fastify.post(`${PATH_BASE_CONTROLLER}/create`, { + schema: { + tags: ["request"], + summary: "Create request friend", + querystring: schemaQueryUsernameAuth, + body: schemaCreateRequest, + response: { + 200: schemaReturnVoid, + 401: { $ref: SCHEMA_BAD_REQUEST }, + 404: { $ref: SCHEMA_NOT_FOUND }, + 500: { $ref: SCHEMA_INTERNAL_SERVER } + } + } +}, async (request, replay) => { + const {auth_username} = request.query; + const {request_to} = request.body; + + await requestService.create(auth_username, request_to); + + replay.status(200).send({ response: "ok" }); +}); \ No newline at end of file diff --git a/src/controllers/requestController/listRequestActionRoute.ts b/src/controllers/requestController/listRequestActionRoute.ts new file mode 100644 index 0000000..dc59f08 --- /dev/null +++ b/src/controllers/requestController/listRequestActionRoute.ts @@ -0,0 +1,24 @@ +import { RequestService } from "../../applications/services/RequestService"; + +import { PATH_BASE_CONTROLLER, schemaQueryPaginatedRequest, schemaReturnPaginatedRequest } from "../../schemas/requestSchema"; +import { SCHEMA_INTERNAL_SERVER } from "../../schemas/generic/genericSchema"; + +import fastify from "../../server/fastify"; + +const requestService = new RequestService(); + +fastify.get(`${PATH_BASE_CONTROLLER}/list_request_for_action`, { + schema: { + tags: ["request"], + summary: "List request for accept or reject", + querystring: schemaQueryPaginatedRequest, + response: { + 200: schemaReturnPaginatedRequest, + 500: { $ref: SCHEMA_INTERNAL_SERVER } + } + } +}, async (request, replay) => { + const {length, auth_username, skip} = request.query; + + replay.status(200).send(await requestService.listRequestForActionPaginated(auth_username, skip, length)); +}); \ No newline at end of file diff --git a/src/controllers/requestController/listRequestWaitRoute.ts b/src/controllers/requestController/listRequestWaitRoute.ts new file mode 100644 index 0000000..60ae146 --- /dev/null +++ b/src/controllers/requestController/listRequestWaitRoute.ts @@ -0,0 +1,24 @@ +import { RequestService } from "../../applications/services/RequestService"; + +import { PATH_BASE_CONTROLLER, schemaQueryPaginatedRequest, schemaReturnPaginatedRequest } from "../../schemas/requestSchema"; +import { SCHEMA_INTERNAL_SERVER } from "../../schemas/generic/genericSchema"; + +import fastify from "../../server/fastify"; + +const requestService = new RequestService(); + +fastify.get(`${PATH_BASE_CONTROLLER}/list_request_wait`, { + schema: { + tags: ["request"], + summary: "List your request", + querystring: schemaQueryPaginatedRequest, + response: { + 200: schemaReturnPaginatedRequest, + 500: { $ref: SCHEMA_INTERNAL_SERVER } + } + } +}, async (request, replay) => { + const {length, auth_username, skip} = request.query; + + replay.status(200).send(await requestService.listRequestWaitPaginated(auth_username, skip, length)); +}); \ No newline at end of file diff --git a/src/controllers/requestController/removeRoute.ts b/src/controllers/requestController/removeRoute.ts new file mode 100644 index 0000000..e72ee89 --- /dev/null +++ b/src/controllers/requestController/removeRoute.ts @@ -0,0 +1,26 @@ +import { RequestService } from "../../applications/services/RequestService"; + +import { PATH_BASE_CONTROLLER, schemaQueryDeleteRequest } from "../../schemas/requestSchema"; +import { SCHEMA_INTERNAL_SERVER, schemaReturnVoid } from "../../schemas/generic/genericSchema"; + +import fastify from "../../server/fastify"; + +const requestService = new RequestService(); + +fastify.delete(`${PATH_BASE_CONTROLLER}/remove`, { + schema: { + tags: ["request"], + summary: "Remove request", + querystring: schemaQueryDeleteRequest, + response: { + 200: schemaReturnVoid, + 500: { $ref: SCHEMA_INTERNAL_SERVER } + } + } +}, async (request, replay) => { + const {request_to, auth_username} = request.query; + + await requestService.delete(auth_username, request_to); + + replay.status(200).send({ response: "ok" }); +}); \ No newline at end of file diff --git a/src/domain/interfaces/DTOs/IAccountDTO.ts b/src/domain/interfaces/DTOs/IAccountDTO.ts new file mode 100644 index 0000000..ebc1202 --- /dev/null +++ b/src/domain/interfaces/DTOs/IAccountDTO.ts @@ -0,0 +1,19 @@ +import { Type } from "@sinclair/typebox"; + +export enum IAccountDTOEnv { + USERNAME = "username", + LAST_ACCESS = "last_access", + CHANGE_PASSWORD = "change_password", + EXPIRE_PASSWORD = "expire_password", + PROFILE = "profile" +} + +export const accountDTOSchema = Type.Object({ + [IAccountDTOEnv.USERNAME]: Type.String({ maxLength: 250 }), + [IAccountDTOEnv.EXPIRE_PASSWORD]: Type.String({format: "date-time"}), + [IAccountDTOEnv.LAST_ACCESS]: Type.Union([Type.Null(), Type.String({format: "date-time"})]), + [IAccountDTOEnv.PROFILE]: Type.Union([Type.Null(), Type.String()]), + [IAccountDTOEnv.CHANGE_PASSWORD]: Type.Boolean({ default: false }) +}); + +export type IAccountDTO = typeof accountDTOSchema.static \ No newline at end of file diff --git a/src/domain/interfaces/DTOs/IFriendDTO.ts b/src/domain/interfaces/DTOs/IFriendDTO.ts new file mode 100644 index 0000000..e29ba55 --- /dev/null +++ b/src/domain/interfaces/DTOs/IFriendDTO.ts @@ -0,0 +1,15 @@ +import { Type } from "@sinclair/typebox"; + +export enum IFriendDTOEnv { + USERNAME = "username", + FRIEND = "friend", + BECOME_FRIEND_TIME = "become_friend_time" +} + +export const friendDTOSchema = Type.Object({ + [IFriendDTOEnv.USERNAME]: Type.String({ maxLength: 250 }), + [IFriendDTOEnv.FRIEND]: Type.String({ maxLength: 250 }), + [IFriendDTOEnv.BECOME_FRIEND_TIME]: Type.String({format: "date-time"}) +}); + +export type IFriendDTO = typeof friendDTOSchema.static \ No newline at end of file diff --git a/src/domain/interfaces/DTOs/IRequestDTO.ts b/src/domain/interfaces/DTOs/IRequestDTO.ts new file mode 100644 index 0000000..5d5b321 --- /dev/null +++ b/src/domain/interfaces/DTOs/IRequestDTO.ts @@ -0,0 +1,15 @@ +import { Type } from "@sinclair/typebox"; + +export enum IRequestDTOEnv { + REQUEST_TO = "request_to", + REQUEST_FROM = "request_from", + REQUEST_TIME = "request_time" +} + +export const requestDTOSchema = Type.Object({ + [IRequestDTOEnv.REQUEST_FROM]: Type.String({maxLength: 250}), + [IRequestDTOEnv.REQUEST_TO]: Type.String({maxLength: 250}), + [IRequestDTOEnv.REQUEST_TIME]: Type.String({format: "date-time"}) +}); + +export type IRequestDTO = typeof requestDTOSchema.static \ No newline at end of file diff --git a/src/domain/interfaces/models/IAccount.ts b/src/domain/interfaces/models/IAccount.ts new file mode 100644 index 0000000..8005c8a --- /dev/null +++ b/src/domain/interfaces/models/IAccount.ts @@ -0,0 +1,21 @@ +import { Type } from "@sinclair/typebox"; + +export enum IAccountEnv { + USERNAME = "username", + PASSWORD = "password", + LAST_ACCESS = "last_access", + CHANGE_PASSWORD = "change_password", + EXPIRE_PASSWORD = "expire_password", + PROFILE = "profile" +} + +export const accountSchema = Type.Object({ + [IAccountEnv.USERNAME]: Type.String({ maxLength: 250 }), + [IAccountEnv.PASSWORD]: Type.String({ maxLength: 250 }), + [IAccountEnv.EXPIRE_PASSWORD]: Type.String({format: "date-time"}), + [IAccountEnv.LAST_ACCESS]: Type.Union([Type.String({format: "date-time"}), Type.Null()]), + [IAccountEnv.PROFILE]: Type.Union([Type.String(), Type.Null()]), + [IAccountEnv.CHANGE_PASSWORD]: Type.Boolean({ default: false }) +}); + +export type IAccount = typeof accountSchema.static \ No newline at end of file diff --git a/src/domain/interfaces/models/IFriend.ts b/src/domain/interfaces/models/IFriend.ts new file mode 100644 index 0000000..ec87052 --- /dev/null +++ b/src/domain/interfaces/models/IFriend.ts @@ -0,0 +1,15 @@ +import { Type } from "@sinclair/typebox"; + +export enum IFriendEnv { + USERNAME = "username", + FRIEND = "friend", + BECOME_FRIEND_TIME = "become_friend_time" +} + +export const friendSchema = Type.Object({ + [IFriendEnv.USERNAME]: Type.String({ maxLength: 250 }), + [IFriendEnv.FRIEND]: Type.String({ maxLength: 250 }), + [IFriendEnv.BECOME_FRIEND_TIME]: Type.String({format: "date-time"}) +}); + +export type IFriend = typeof friendSchema.static \ No newline at end of file diff --git a/src/domain/interfaces/models/IRequest.ts b/src/domain/interfaces/models/IRequest.ts new file mode 100644 index 0000000..e7c851e --- /dev/null +++ b/src/domain/interfaces/models/IRequest.ts @@ -0,0 +1,15 @@ +import { Type } from "@sinclair/typebox"; + +export enum IRequestEnv { + REQUEST_TO = "request_to", + REQUEST_FROM = "request_from", + REQUEST_TIME = "request_time" +} + +export const requestSchema = Type.Object({ + [IRequestEnv.REQUEST_FROM]: Type.String({maxLength: 250}), + [IRequestEnv.REQUEST_TO]: Type.String({maxLength: 250}), + [IRequestEnv.REQUEST_TIME]: Type.String({format: "date-time"}) +}); + +export type IRequest = typeof requestSchema.static \ No newline at end of file diff --git a/src/domain/models/Account.ts b/src/domain/models/Account.ts new file mode 100644 index 0000000..5980cae --- /dev/null +++ b/src/domain/models/Account.ts @@ -0,0 +1,25 @@ +import { DateTime } from "luxon"; +import { Entity, PrimaryColumn, Column } from "typeorm"; + +import { IAccount, IAccountEnv } from "../interfaces/models/IAccount"; + +@Entity("accounts") +export class Account implements IAccount{ + @PrimaryColumn({type: "varchar", length: 250}) + [IAccountEnv.USERNAME]: string; + + @Column({type: "varchar", length: 500}) + [IAccountEnv.PASSWORD]: string; + + @Column({type: "timestamptz", nullable: true, default: null}) + [IAccountEnv.LAST_ACCESS]: string | null; + + @Column({type: "boolean", default: false}) + [IAccountEnv.CHANGE_PASSWORD]: boolean; + + @Column({type: "timestamptz", default: DateTime.now().plus({month: 1})}) + [IAccountEnv.EXPIRE_PASSWORD]: string; + + @Column({type: "text", default: null, nullable: true}) + [IAccountEnv.PROFILE]: string; +} \ No newline at end of file diff --git a/src/domain/models/Friends.ts b/src/domain/models/Friends.ts new file mode 100644 index 0000000..c418dcf --- /dev/null +++ b/src/domain/models/Friends.ts @@ -0,0 +1,16 @@ +import { DateTime } from "luxon"; +import { Entity, PrimaryColumn, Column } from "typeorm"; + +import { IFriend, IFriendEnv } from "../interfaces/models/IFriend"; + +@Entity("friends") +export class Friend implements IFriend{ + @PrimaryColumn({type: "varchar", length: 250}) + [IFriendEnv.USERNAME]: string; + + @Column({type: "varchar", length: 250}) + [IFriendEnv.FRIEND]: string; + + @Column({type: "timestamptz", default: DateTime.now()}) + [IFriendEnv.BECOME_FRIEND_TIME]: string; +} \ No newline at end of file diff --git a/src/domain/models/Request.ts b/src/domain/models/Request.ts new file mode 100644 index 0000000..e18575e --- /dev/null +++ b/src/domain/models/Request.ts @@ -0,0 +1,16 @@ +import { DateTime } from "luxon"; +import { Entity, PrimaryColumn, Column } from "typeorm"; + +import { IRequest, IRequestEnv } from "../interfaces/models/IRequest"; + +@Entity("requests") +export class Request implements IRequest{ + @PrimaryColumn({type: "varchar", length: 250}) + [IRequestEnv.REQUEST_FROM]: string; + + @PrimaryColumn({type: "varchar", length: 250}) + [IRequestEnv.REQUEST_TO]: string; + + @Column({type: "timestamptz", default: DateTime.now()}) + [IRequestEnv.REQUEST_TIME]: string; +} \ No newline at end of file diff --git a/src/eslint.config.js b/src/eslint.config.js new file mode 100644 index 0000000..b5c503b --- /dev/null +++ b/src/eslint.config.js @@ -0,0 +1,76 @@ +import globals from "globals"; +import pluginJs from "@eslint/js"; +import tseslint from "typescript-eslint"; +import stylisticJs from "@stylistic/eslint-plugin-js"; +import parserTs from "@typescript-eslint/parser"; +import checkFile from "eslint-plugin-check-file"; + + +export default [ + { + files: ["**/*.{js,mjs,cjs,ts}"] + }, + { + languageOptions: { + globals: globals.node, + parser: parserTs + } + }, + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + { + plugins: { + "@stylistic": stylisticJs, + "check-file": checkFile + }, + rules: { + //syntax code + "@typescript-eslint/no-unused-vars": "warn", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/ban-ts-comment": "off", + + //syntax code + plugin + "@stylistic/quotes": ["error", "double"], + "@stylistic/array-bracket-newline": ["error", { "multiline": true }], + "@stylistic/array-bracket-spacing": ["error", "never"], + "@stylistic/array-element-newline": ["error", "consistent"], + "@stylistic/arrow-parens": ["error", "always"], + "@stylistic/arrow-spacing": "error", + "@stylistic/block-spacing": "error", + "@stylistic/brace-style": ["error", "1tbs", { "allowSingleLine": true }], + "@stylistic/comma-dangle": ["error", "never"], + "@stylistic/comma-spacing": ["error", { "before": false, "after": true }], + "@stylistic/dot-location": ["error", "object"], + "@stylistic/keyword-spacing": ["error", { "before": true }], + "@stylistic/no-multi-spaces": "error", + "@stylistic/no-mixed-operators": "error", + "@stylistic/no-floating-decimal": "error", + "@stylistic/semi": "error", + "@stylistic/wrap-regex": "error", + + + //syntax name file + plugin + "check-file/filename-naming-convention": [ + "error", + { + "applications/interfaces/services/**/*.{js,ts}": "I+([A-Z])+([a-zA-Z])Service", + "applications/interfaces/repositories/**/*.{js,ts}": "I+([A-Z])+([a-zA-Z])Repository", + "applications/services/**/*.{js,ts}": "([A-Z])+([a-zA-Z])Service", + "applications/repositories/**/*.{js,ts}": "([A-Z])+([a-zA-Z])Repository", + "controllers/**/*": "*([a-zA-Z])Route", + "domain/interfaces/DTOs/**/*": "I+([A-Z])+([a-zA-Z])DTO", + "domain/interfaces/models/**/*": "I+([A-Z])+([a-zA-Z])", + "domain/models/**/*": "PASCAL_CASE", + "schemas/**/*": "*([a-zA-Z])Schema", + "utils/**/*": "*([a-z])Utils" + } + ], + "check-file/folder-naming-convention": [ + "error", + { + "controllers/*/": "*([a-z])Controller" + } + ] + } + } +]; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..ec64e68 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,15 @@ +import {config} from "dotenv"; + +import {init as initServerFastify} from "./server/fastify"; +import {init as initPostgres} from "./server/postgres"; + +//load env +config(); + +await initPostgres({ + username: process.env.POSTGRES_USERNAME, + password: process.env.POSTGRES_PASSWORD, + database: process.env.POSTGRES_DB +}); + +await initServerFastify({}); \ No newline at end of file diff --git a/src/modules/api.ts b/src/modules/api.ts new file mode 100644 index 0000000..c1bdf67 --- /dev/null +++ b/src/modules/api.ts @@ -0,0 +1,38 @@ +class ApiNotFound extends Error { + constructor(message: string) { + super(message); + this.name = "ApiNotFound"; + } +} +class ApiErrorGeneric extends Error { + constructor(message: string) { + super(message); + this.name = "ApiErrorGeneric"; + } +} +class ApiConflict extends Error { + constructor(message: string) { + super(message); + this.name = "ApiConflict"; + } +} +class ApiUnauthorized extends Error { + constructor(message: string) { + super(message); + this.name = "ApiUnauthorized"; + } +} +class ApiBadRequest extends Error { + constructor(message: string) { + super(message); + this.name = "ApiBadRequest"; + } +} + +export { + ApiNotFound, + ApiErrorGeneric, + ApiConflict, + ApiUnauthorized, + ApiBadRequest +}; \ No newline at end of file diff --git a/src/modules/logger.ts b/src/modules/logger.ts new file mode 100644 index 0000000..9a99a24 --- /dev/null +++ b/src/modules/logger.ts @@ -0,0 +1,64 @@ +import chalk from "chalk"; +import {DateTime} from "luxon"; + +class Logger { + nameService: string | null = null; + + constructor(nameService: string){ + this.nameService = nameService.toUpperCase(); + } + + debug(...args: Array){ + this.#baseLog("debug", ...args); + } + + info(...args: Array){ + this.#baseLog("info", ...args); + } + + warn(...args: Array){ + this.#baseLog("warning", ...args); + } + + error(...args: Array){ + this.#baseLog("error", ...args); + } + + fatal(...args: Array){ + this.#baseLog("fatal", ...args); + } + + #baseLog(type: "debug" | "info" | "warning" | "error" | "fatal", ...args: Array){ + let message = `[${DateTime.now().toFormat("dd-MM-yyyy hh:mm:ssZZ")}] [${type.toUpperCase()}] [${this.nameService}]`; + + args = args.map((message) => { + if (message instanceof Error){ + return message.stack; + } else { + return message; + } + }); + + switch (type){ + case "debug": + message = chalk.gray(message, ...args); + break; + case "info": + message = chalk.blue(message, ...args); + break; + case "warning": + message = chalk.yellow(message, ...args); + break; + case "error": + message = chalk.red(message, ...args); + break; + case "fatal": + message = chalk.redBright(message, ...args); + break; + } + + console.log(message); + } +} + +export default Logger; \ No newline at end of file diff --git a/src/package.json b/src/package.json new file mode 100644 index 0000000..458ad5b --- /dev/null +++ b/src/package.json @@ -0,0 +1,48 @@ +{ + "name": "api_service", + "version": "1.0.0", + "main": "index.js", + "type": "module", + "scripts": { + "start": "npx tsx index.ts", + "clear": "rm -rf node_modules package-lock.json", + "typecheck": "npx tsc --noEmit", + "eslint": "npx eslint .", + "eslint-fix": "npx eslint --fix ." + }, + "keywords": [], + "author": "cesxhin", + "license": "MIT", + "description": "", + "dependencies": { + "@fastify/swagger": "^9.0.0", + "@fastify/swagger-ui": "^5.0.1", + "@fastify/type-provider-typebox": "^5.0.0", + "@sinclair/typebox": "^0.33.7", + "@stylistic/eslint-plugin-js": "^2.8.0", + "@types/async": "^3.2.24", + "@types/crypto-js": "^4.2.2", + "@typescript-eslint/parser": "^8.6.0", + "async": "^3.2.6", + "chalk": "^5.3.0", + "crypto-js": "^4.2.0", + "dotenv": "^16.4.5", + "eslint-plugin-check-file": "^2.8.0", + "fastify": "^5.0.0", + "lodash": "^4.17.21", + "luxon": "^3.5.0", + "pg": "^8.12.0", + "typeorm": "^0.3.20", + "typescript": "5.5.4", + "@eslint/js": "^9.11.0", + "@types/lodash": "^4.17.7", + "@types/luxon": "^3.4.2", + "@types/node": "^22.5.0", + "@types/pg": "^8.11.6", + "@types/pg-pool": "^2.0.6", + "eslint": "^9.11.0", + "globals": "^15.9.0", + "tsx": "^4.16.2", + "typescript-eslint": "^8.6.0" + } +} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Cesxhin.AnimeManga.Domain.csproj b/src/references/Cesxhin.AnimeManga.Domain/Cesxhin.AnimeManga.Domain.csproj deleted file mode 100644 index 9b3a464..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Cesxhin.AnimeManga.Domain.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - net5.0 - - - - - - - - diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/AuthDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/AuthDTO.cs deleted file mode 100644 index ecfe7ea..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/AuthDTO.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class AuthDTO - { - public string Username { get; set; } - public int Role { get; set; } - - //convert Auth to AuthDTO - public static AuthDTO AuthToAuthDTO(Auth auth) - { - return new AuthDTO - { - Username = auth.Username, - Role = auth.Role - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/AuthLoginDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/AuthLoginDTO.cs deleted file mode 100644 index 1bb93a0..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/AuthLoginDTO.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class AuthLoginDTO - { - public string Username { get; set; } - public string Password { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/ChapterDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/ChapterDTO.cs deleted file mode 100644 index f504a50..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/ChapterDTO.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class ChapterDTO - { - public string ID { get; set; } - public string NameManga { get; set; } - public float CurrentVolume { get; set; } - public float CurrentChapter { get; set; } - public int NumberMaxImage { get; set; } - public string UrlPage { get; set; } - public string StateDownload { get; set; } - public int PercentualDownload { get; set; } - public string NameCfg { get; set; } - - //convert Chapter to ChapterDTO - public static ChapterDTO ChapterToChapterDTO(Chapter chapter) - { - return new ChapterDTO - { - ID = chapter.ID, - CurrentChapter = chapter.CurrentChapter, - UrlPage = chapter.UrlPage, - CurrentVolume = chapter.CurrentVolume, - NameManga = chapter.NameManga, - PercentualDownload = chapter.PercentualDownload, - StateDownload = chapter.StateDownload, - NumberMaxImage = chapter.NumberMaxImage, - NameCfg = chapter.NameCfg - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/ChapterRegisterDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/ChapterRegisterDTO.cs deleted file mode 100644 index 63ef493..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/ChapterRegisterDTO.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class ChapterRegisterDTO - { - public string ChapterId { get; set; } - public string[] ChapterPath { get; set; } - public string[] ChapterHash { get; set; } - - //convert ChapterRegister to ChapterRegisterDTO - public static ChapterRegisterDTO ChapterRegisterToChapterRegisterDTO(ChapterRegister chapter) - { - return new ChapterRegisterDTO - { - ChapterId = chapter.ChapterId, - ChapterPath = chapter.ChapterPath, - ChapterHash = chapter.ChapterHash - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/ConversionDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/ConversionDTO.cs deleted file mode 100644 index 9cd7481..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/ConversionDTO.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class ConversionDTO - { - public string ID { get; set; } - public List Paths { get; set; } - public string FilePath { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/DownloadDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/DownloadDTO.cs deleted file mode 100644 index a32e709..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/DownloadDTO.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class DownloadDTO - { - public string Url { get; set; } - public string nameCfg { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/EpisodeDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/EpisodeDTO.cs deleted file mode 100644 index ad7cba5..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/EpisodeDTO.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class EpisodeDTO - { - public string ID { get; set; } - public string VideoId { get; set; } - public string UrlVideo { get; set; } - public int NumberEpisodeCurrent { get; set; } - public int NumberSeasonCurrent { get; set; } - public string StateDownload { get; set; } - public int PercentualDownload { get; set; } - - /* - Download playlist: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/playlist.m3u8 - Select Resolution for download source: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/360p/playlist_360p.m3u8 - Download source: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/360p/360p-000.ts - */ - - //alternative source - public string BaseUrl { get; set; } - public string Playlist { get; set; } - public string Resolution { get; set; } - public string PlaylistSources { get; set; } - public int startNumberBuffer { get; set; } = 0; - public int endNumberBuffer { get; set; } - public string nameCfg { get; set; } - - //convert Episode to EpisodeDTO - public static EpisodeDTO EpisodeToEpisodeDTO(Episode episode) - { - return new EpisodeDTO - { - ID = episode.ID, - VideoId = episode.VideoId, - UrlVideo = episode.UrlVideo, - NumberEpisodeCurrent = episode.NumberEpisodeCurrent, - NumberSeasonCurrent = episode.NumberSeasonCurrent, - StateDownload = episode.StateDownload, - PercentualDownload = episode.PercentualDownload, - BaseUrl = episode.BaseUrl, - Playlist = episode.Playlist, - Resolution = episode.Resolution, - PlaylistSources = episode.PlaylistSources, - startNumberBuffer = episode.startNumberBuffer, - endNumberBuffer = episode.endNumberBuffer, - nameCfg = episode.nameCfg - - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/EpisodeRegisterDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/EpisodeRegisterDTO.cs deleted file mode 100644 index f84417f..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/EpisodeRegisterDTO.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class EpisodeRegisterDTO - { - public string EpisodeId { get; set; } - public string EpisodePath { get; set; } - public string EpisodeHash { get; set; } - - //convert EpisodeRegister to EpisodeRegisterDTO - public static EpisodeRegisterDTO EpisodeRegisterToEpisodeRegisterDTO(EpisodeRegister anime) - { - return new EpisodeRegisterDTO - { - EpisodeId = anime.EpisodeId, - EpisodePath = anime.EpisodePath, - EpisodeHash = anime.EpisodeHash - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericBlackListDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericBlackListDTO.cs deleted file mode 100644 index 207000e..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericBlackListDTO.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class GenericBlackListDTO - { - public string Name { get; set; } - public string Url { get; set; } - public string NameCfg { get; set; } - - //convert EpisodeBlackList to GenericBlackListDTO - public static GenericBlackListDTO EpisodeBlackListToGenericBlackListDTO(EpisodeBlacklist auth) - { - return new GenericBlackListDTO - { - Name = auth.Name, - Url = auth.Url, - NameCfg = auth.NameCfg, - }; - } - - //convert ChapterBlackList to GenericBlackListDTO - public static GenericBlackListDTO ChapterBlackListToGenericBlackListDTO(ChapterBlacklist auth) - { - return new GenericBlackListDTO - { - Name = auth.Name, - Url = auth.Url, - NameCfg = auth.NameCfg, - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericBookDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericBookDTO.cs deleted file mode 100644 index 5ec6592..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericBookDTO.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class GenericBookDTO - { - //Manga - public string Book { get; set; } - public List Chapters { get; set; } - public List ChapterRegister { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericQueueDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericQueueDTO.cs deleted file mode 100644 index c166b8e..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericQueueDTO.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; -using System; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class GenericQueueDTO - { - public string Name { get; set; } - public string Url { get; set; } - public string NameCfg { get; set; } - public long TimeRequest { get; set; } = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeMilliseconds(); - - //convert ChapterQueue to GenericQueueDTO - public static GenericQueueDTO ChapterQueueToGenericQueueDTO(ChapterQueue queue) - { - return new GenericQueueDTO - { - Name = queue.Name, - Url = queue.Url, - NameCfg = queue.NameCfg, - TimeRequest = queue.TimeRequest - }; - } - - //convert EpisodeQueue to GenericQueueDTO - public static GenericQueueDTO EpisodeQueueToGenericQueueDTO(EpisodeQueue queue) - { - return new GenericQueueDTO - { - Name = queue.Name, - Url = queue.Url, - NameCfg = queue.NameCfg, - TimeRequest = queue.TimeRequest - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericUrlDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericUrlDTO.cs deleted file mode 100644 index c6729db..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericUrlDTO.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class GenericUrlDTO - { - public string Name { get; set; } - public string UrlPageDownload { get; set; } - public string Image { get; set; } - public string Type { get; set; } - public bool Exists { get; set; } = false; - - //convert GenericUrl to GenericUrlDTO - public static GenericUrlDTO GenericUrlToGenericUrlDTO(GenericUrl anime) - { - return new GenericUrlDTO - { - Name = anime.Name, - UrlPageDownload = anime.Url, - Image = anime.UrlImage, - Type = anime.TypeView - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericVideoDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericVideoDTO.cs deleted file mode 100644 index 62749ed..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/GenericVideoDTO.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class GenericVideoDTO - { - //Video - public string Video { get; set; } - public List Episodes { get; set; } - public List EpisodesRegister { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyAnimeDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyAnimeDTO.cs deleted file mode 100644 index 00a4e49..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyAnimeDTO.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class NotifyAnimeDTO - { - public string Message { get; set; } - public string Image { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyMangaDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyMangaDTO.cs deleted file mode 100644 index d874b40..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyMangaDTO.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class NotifyMangaDTO - { - public string Message { get; set; } - public string Image { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyRequestAnimeDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyRequestAnimeDTO.cs deleted file mode 100644 index 79129df..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyRequestAnimeDTO.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class NotifyRequestAnimeDTO - { - public string Message { get; set; } - public string Image { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyRequestMangaDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyRequestMangaDTO.cs deleted file mode 100644 index 5645da1..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/NotifyRequestMangaDTO.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class NotifyRequestMangaDTO - { - public string Message { get; set; } - public string Image { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/ProgressChapterDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/ProgressChapterDTO.cs deleted file mode 100644 index 73c866b..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/ProgressChapterDTO.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class ProgressChapterDTO - { - public string ID { get; set; } - public string Username { get; set; } - public string Name { get; set; } - public string NameCfg { get; set; } - public string NameChapter { get; set; } - public int Page { get; set; } - - //convert ProgressEpisode to ProgressEpisodeDTO - public static ProgressChapterDTO ProgressChapterToProgressChapterDTO(ProgressChapter progress) - { - return new ProgressChapterDTO - { - ID = progress.ID, - Name = progress.Name, - Page = progress.Page, - Username = progress.Username, - NameChapter = progress.NameChapter, - NameCfg = progress.NameCfg, - }; - } - } -} \ No newline at end of file diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/ProgressEpisodeDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/ProgressEpisodeDTO.cs deleted file mode 100644 index 3137e56..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/ProgressEpisodeDTO.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class ProgressEpisodeDTO - { - public string ID { get; set; } - public string Username { get; set; } - public string Name { get; set; } - public string NameCfg { get; set; } - public string NameEpisode { get; set; } - public int Hours { get; set; } - public int Minutes { get; set; } - public int Seconds { get; set; } - - //convert ProgressChapter to ProgressChapterDTO - public static ProgressEpisodeDTO ProgressEpisodeToProgressEpisodeDTO(ProgressEpisode progress) - { - return new ProgressEpisodeDTO - { - ID = progress.ID, - Username = progress.Username, - Name = progress.Name, - Hours = progress.Hours, - Minutes = progress.Minutes, - Seconds = progress.Seconds, - NameEpisode = progress.NameEpisode, - NameCfg = progress.NameCfg, - }; - } - } -} \ No newline at end of file diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/ProxyDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/ProxyDTO.cs deleted file mode 100644 index e15bfc5..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/ProxyDTO.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class ProxyDTO - { - public string Action { get; set; } = "restart"; - public string Endpoint { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/DTO/WatchListDTO.cs b/src/references/Cesxhin.AnimeManga.Domain/DTO/WatchListDTO.cs deleted file mode 100644 index 127c33c..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/DTO/WatchListDTO.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Cesxhin.AnimeManga.Domain.Models; - -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class WatchListDTO - { - public string Name { get; set; } - public string Username { get; set; } - public string NameCfg { get; set; } - - //convert Auth to AuthDTO - public static WatchListDTO WatchListToWatchListDTO(WatchList watchList) - { - return new WatchListDTO - { - Name = watchList.Name, - Username = watchList.Username, - NameCfg = watchList.NameCfg - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/Auth.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/Auth.cs deleted file mode 100644 index 9bb9518..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/Auth.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("account")] - public class Auth - { - [Primary] - [Map("username")] - public string Username { get; set; } - - [Map("password")] - public string Password { get; set; } - - [Map("role")] - public int Role { get; set; } - - //convert AuthDTO to Auth - public static Auth AuthDTOToAuth(AuthDTO auth) - { - return new Auth - { - Username = auth.Username, - Role = auth.Role, - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/Chapter.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/Chapter.cs deleted file mode 100644 index f6e19b9..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/Chapter.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("chapter")] - public class Chapter - { - [Primary] - [Map("id")] - public string ID { get; set; } - - [Map("namemanga")] - public string NameManga { get; set; } - - [Map("currentvolume")] - public float CurrentVolume { get; set; } - - [Map("currentchapter")] - public float CurrentChapter { get; set; } - - [Map("numbermaximage")] - public int NumberMaxImage { get; set; } - - [Map("urlpage")] - public string UrlPage { get; set; } - - [Map("statedownload")] - public string StateDownload { get; set; } - - [Map("percentualdownload")] - public int PercentualDownload { get; set; } - - [Map("namecfg")] - public string NameCfg { get; set; } - - //convert ChapterDTO to Chapter - public static Chapter ChapterDTOToChapter(ChapterDTO chapter) - { - return new Chapter - { - ID = chapter.ID, - CurrentChapter = chapter.CurrentChapter, - UrlPage = chapter.UrlPage, - CurrentVolume = chapter.CurrentVolume, - NameManga = chapter.NameManga, - StateDownload = chapter.StateDownload, - PercentualDownload = chapter.PercentualDownload, - NumberMaxImage = chapter.NumberMaxImage, - NameCfg = chapter.NameCfg - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterBlacklist.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterBlacklist.cs deleted file mode 100644 index 7fc4f8b..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterBlacklist.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("chapterblacklist")] - public class ChapterBlacklist - { - [Primary] - [Map("namemanga")] - public string Name { get; set; } - - [Map("url")] - public string Url { get; set; } - - [Primary] - [Map("namecfg")] - public string NameCfg { get; set; } - - //convert GenericBlackListDTO to ChapterBlacklist - public static ChapterBlacklist GenericQueueDTOToChapterBlacklist(GenericBlackListDTO blackList) - { - return new ChapterBlacklist - { - Url = blackList.Url, - NameCfg = blackList.NameCfg, - Name = blackList.Name - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterQueue.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterQueue.cs deleted file mode 100644 index 031a34b..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterQueue.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("chapterqueue")] - public class ChapterQueue - { - [Primary] - [Map("namemanga")] - public string Name { get; set; } - - [Primary] - [Map("url")] - public string Url { get; set; } - - [Primary] - [Map("namecfg")] - public string NameCfg { get; set; } - - [Map("timerequest")] - public long TimeRequest { get; set; } - - - //convert GenericQueueDTO to ChapterQueue - public static ChapterQueue GenericQueueDTOToChapterQueue(GenericQueueDTO queue) - { - return new ChapterQueue - { - Name = queue.Name, - Url = queue.Url, - NameCfg = queue.NameCfg, - TimeRequest = queue.TimeRequest - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterRegister.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterRegister.cs deleted file mode 100644 index d54cfcf..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/ChapterRegister.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("chapterregister")] - public class ChapterRegister - { - [Primary] - [Map("chapterid")] - public string ChapterId { get; set; } - - [Map("chapterpath")] - public string[] ChapterPath { get; set; } - - [Map("chapterhash")] - public string[] ChapterHash { get; set; } - - //convert ChapterRegisterDTO to ChapterRegister - public static ChapterRegister ChapterRegisterDTOToChapterRegister(ChapterRegisterDTO anime) - { - return new ChapterRegister - { - ChapterId = anime.ChapterId, - ChapterPath = anime.ChapterPath, - ChapterHash = anime.ChapterHash - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/Episode.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/Episode.cs deleted file mode 100644 index 7733ed6..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/Episode.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("episode")] - public class Episode - { - [Primary] - [Map("id")] - public string ID { get; set; } - - [Map("videoid")] - public string VideoId { get; set; } - - [Map("urlvideo")] - public string UrlVideo { get; set; } - - [Map("numberepisodecurrent")] - public int NumberEpisodeCurrent { get; set; } - - [Map("numberseasoncurrent")] - public int NumberSeasonCurrent { get; set; } - - [Map("statedownload")] - public string StateDownload { get; set; } - - [Map("percentualdownload")] - public int PercentualDownload { get; set; } - - /* - Download playlist: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/playlist.m3u8 - Select Resolution for download source: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/360p/playlist_360p.m3u8 - Download source: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/360p/360p-000.ts - */ - - //alternative source - [Map("baseurl")] - public string BaseUrl { get; set; } - - [Map("playlist")] - public string Playlist { get; set; } - - [Map("resolution")] - public string Resolution { get; set; } - - [Map("playlistsources")] - public string PlaylistSources { get; set; } - - [Map("startnumberframe")] - public int startNumberBuffer { get; set; } = 0; - - [Map("endnumberframe")] - public int endNumberBuffer { get; set; } - - [Map("namecfg")] - public string nameCfg { get; set; } - - //convert EpisodeDTO to Episode - public static Episode EpisodeDTOToEpisode(EpisodeDTO episode) - { - return new Episode - { - ID = episode.ID, - VideoId = episode.VideoId, - UrlVideo = episode.UrlVideo, - NumberEpisodeCurrent = episode.NumberEpisodeCurrent, - NumberSeasonCurrent = episode.NumberSeasonCurrent, - StateDownload = episode.StateDownload, - PercentualDownload = episode.PercentualDownload, - startNumberBuffer = episode.startNumberBuffer, - endNumberBuffer = episode.endNumberBuffer, - Resolution = episode.Resolution, - PlaylistSources = episode.PlaylistSources, - Playlist = episode.Playlist, - BaseUrl = episode.BaseUrl, - nameCfg = episode.nameCfg - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeBlacklist.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeBlacklist.cs deleted file mode 100644 index 2ac5c25..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeBlacklist.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("episodeblacklist")] - public class EpisodeBlacklist - { - [Primary] - [Map("videoid")] - public string Name { get; set; } - - [Map("url")] - public string Url { get; set; } - - [Primary] - [Map("namecfg")] - public string NameCfg { get; set; } - - //convert GenericBlackListDTO to EpisodeBlacklist - public static EpisodeBlacklist GenericQueueDTOToEpisodeBlacklist(GenericBlackListDTO blackList) - { - return new EpisodeBlacklist - { - Url = blackList.Url, - NameCfg = blackList.NameCfg, - Name = blackList.Name - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeBuffer.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeBuffer.cs deleted file mode 100644 index 4af9f9b..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeBuffer.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.Models -{ - public class EpisodeBuffer - { - public int Id { get; set; } - public byte[] Data { get; set; } - - public string Path { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeQueue.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeQueue.cs deleted file mode 100644 index 9a25425..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeQueue.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("episodequeue")] - public class EpisodeQueue - { - [Primary] - [Map("videoid")] - public string Name { get; set; } - - [Primary] - [Map("url")] - public string Url { get; set; } - - [Primary] - [Map("namecfg")] - public string NameCfg { get; set; } - - [Map("timerequest")] - public long TimeRequest { get; set; } - - //convert GenericQueueDTO to EpisodeQueue - public static EpisodeQueue GenericQueueDTOToEpisodeQueue(GenericQueueDTO queue) - { - return new EpisodeQueue - { - Name = queue.Name, - Url = queue.Url, - NameCfg = queue.NameCfg, - TimeRequest = queue.TimeRequest - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeRegister.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeRegister.cs deleted file mode 100644 index bcaebfa..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/EpisodeRegister.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("episoderegister")] - public class EpisodeRegister - { - [Primary] - [Map("episodeid")] - public string EpisodeId { get; set; } - - [Map("episodepath")] - public string EpisodePath { get; set; } - - [Map("episodehash")] - public string EpisodeHash { get; set; } - - //convert EpisodeRegister to EpisodeRegisterDTO - public static EpisodeRegister EpisodeRegisterToEpisodeRegisterDTO(EpisodeRegisterDTO anime) - { - return new EpisodeRegister - { - EpisodeId = anime.EpisodeId, - EpisodePath = anime.EpisodePath, - EpisodeHash = anime.EpisodeHash - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/GenericNotify.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/GenericNotify.cs deleted file mode 100644 index db90fb7..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/GenericNotify.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.DTO -{ - public class GenericNotify - { - public string Message { get; set; } - public string Image { get; set; } - - //convert NotifyAnimeDTO to GenericNotify - public static GenericNotify NotifyAnimeDTOToGenericNotify(NotifyAnimeDTO notify) - { - return new GenericNotify - { - Message = notify.Message, - Image = notify.Image - }; - } - - //convert NotifyMangaDTO to GenericNotify - public static GenericNotify NotifyMangaDTOToGenericNotify(NotifyMangaDTO notify) - { - return new GenericNotify - { - Message = notify.Message, - Image = notify.Image - }; - } - - //convert NotifyRequestAnimeDTO to GenericNotify - public static GenericNotify NotifyRequestAnimeDTOToGenericNotify(NotifyRequestAnimeDTO notify) - { - return new GenericNotify - { - Message = notify.Message, - Image = notify.Image - }; - } - - //convert NotifyRequestMangaDTO to GenericNotify - public static GenericNotify NotifyRequestMangaDTOToGenericNotify(NotifyRequestMangaDTO notify) - { - return new GenericNotify - { - Message = notify.Message, - Image = notify.Image - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/GenericUrl.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/GenericUrl.cs deleted file mode 100644 index 352cf34..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/GenericUrl.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.Models -{ - public class GenericUrl - { - public string Name { get; set; } - public string Url { get; set; } - public string UrlImage { get; set; } - public string TypeView { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/PlayerUrl.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/PlayerUrl.cs deleted file mode 100644 index 3ab9cd1..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/PlayerUrl.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Cesxhin.AnimeManga.Domain.Models -{ - public class PlayerUrl - { - /* - Download playlist: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/playlist.m3u8 - Select Resolution for download source: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/360p/playlist_360p.m3u8 - Download source: https://www.saturnspeed49.org/DDL/ANIME/HatarakuSaibou2/01/360p/360p-000.ts - */ - - //alternative source - public string BaseUrl { get; set; } - public string Playlist { get; set; } - public string Resolution { get; set; } - public string PlaylistSources { get; set; } - public int startNumberBuffer { get; set; } = 0; - public int endNumberBuffer { get; set; } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/ProgressChapter.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/ProgressChapter.cs deleted file mode 100644 index 9bc8892..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/ProgressChapter.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("progresschapter")] - public class ProgressChapter - { - [Primary] - [Map("id")] - public string ID { get; set; } - [Map("username")] - public string Username { get; set; } - [Map("name")] - public string Name { get; set; } - [Map("namecfg")] - public string NameCfg { get; set; } - [Map("namechapter")] - public string NameChapter { get; set; } - [Map("page")] - public int Page { get; set; } - - //convert ProgressEpisodeDTO to ProgressEpisode - public static ProgressChapter ProgressChapterDTOToProgressChapter(ProgressChapterDTO progress) - { - return new ProgressChapter - { - ID = progress.ID, - Username = progress.Username, - Name = progress.Name, - Page = progress.Page, - NameChapter = progress.NameChapter, - NameCfg = progress.NameCfg, - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/ProgressEpisode.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/ProgressEpisode.cs deleted file mode 100644 index 22af28a..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/ProgressEpisode.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("progressepisode")] - public class ProgressEpisode - { - [Identity] - [Map("id")] - public string ID { get; set; } - [Map("username")] - public string Username { get; set; } - [Map("name")] - public string Name { get; set; } - [Map("namecfg")] - public string NameCfg { get; set; } - [Map("nameepisode")] - public string NameEpisode { get; set; } - [Map("hours")] - public int Hours { get; set; } - [Map("minutes")] - public int Minutes { get; set; } - [Map("seconds")] - public int Seconds { get; set; } - - //convert ProgressChapterDTO to ProgressChapter - public static ProgressEpisode ProgressEpisodeDTOToProgressEpisode(ProgressEpisodeDTO progress) - { - return new ProgressEpisode - { - ID = progress.ID, - Username = progress.Username, - Name = progress.Name, - Hours = progress.Hours, - Minutes = progress.Minutes, - Seconds = progress.Seconds, - NameEpisode = progress.NameEpisode, - NameCfg = progress.NameCfg, - }; - } - } -} \ No newline at end of file diff --git a/src/references/Cesxhin.AnimeManga.Domain/Models/WatchList.cs b/src/references/Cesxhin.AnimeManga.Domain/Models/WatchList.cs deleted file mode 100644 index f89e4c4..0000000 --- a/src/references/Cesxhin.AnimeManga.Domain/Models/WatchList.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Cesxhin.AnimeManga.Domain.DTO; -using RepoDb.Attributes; - -namespace Cesxhin.AnimeManga.Domain.Models -{ - [Map("whitelist")] - public class WatchList - { - [Primary] - [Map("name")] - public string Name { get; set; } - - [Primary] - [Map("username")] - public string Username { get; set; } - - [Primary] - [Map("namecfg")] - public string NameCfg { get; set; } - - //convert AuthDTO to Auth - public static WatchList WatchListDTOToWatchList(WatchListDTO watchListDTO) - { - return new WatchList - { - Name = watchListDTO.Name, - Username = watchListDTO.Username, - NameCfg = watchListDTO.NameCfg, - }; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Cesxhin.AnimeManga.Modules.csproj b/src/references/Cesxhin.AnimeManga.Modules/Cesxhin.AnimeManga.Modules.csproj deleted file mode 100644 index f8acc93..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Cesxhin.AnimeManga.Modules.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - net5.0 - - - - - - - - - - - - - - - - - - - - diff --git a/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiConflictException.cs b/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiConflictException.cs deleted file mode 100644 index 1d9017d..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiConflictException.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Cesxhin.AnimeManga.Modules.Exceptions -{ - public class ApiConflictException : Exception - { - public ApiConflictException() : base() { } - public ApiConflictException(string message) : base(message) { } - public ApiConflictException(string message, Exception inner) : base(message, inner) { } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiGenericException.cs b/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiGenericException.cs deleted file mode 100644 index b261e18..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiGenericException.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Cesxhin.AnimeManga.Modules.Exceptions -{ - public class ApiGenericException : Exception - { - public ApiGenericException() : base() { } - public ApiGenericException(string message) : base(message) { } - public ApiGenericException(string message, Exception inner) : base(message, inner) { } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiNotAuthorizeException.cs b/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiNotAuthorizeException.cs deleted file mode 100644 index 202bc77..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiNotAuthorizeException.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Cesxhin.AnimeManga.Modules.Exceptions -{ - public class ApiNotAuthorizeException : Exception - { - public ApiNotAuthorizeException() : base() { } - public ApiNotAuthorizeException(string message) : base(message) { } - public ApiNotAuthorizeException(string message, Exception inner) : base(message, inner) { } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiNotFoundException.cs b/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiNotFoundException.cs deleted file mode 100644 index 18f976a..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Exceptions/ApiNotFoundException.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Cesxhin.AnimeManga.Modules.Exceptions -{ - public class ApiNotFoundException : Exception - { - public ApiNotFoundException() : base() { } - public ApiNotFoundException(string message) : base(message) { } - public ApiNotFoundException(string message, Exception inner) : base(message, inner) { } - - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Generic/Api.cs b/src/references/Cesxhin.AnimeManga.Modules/Generic/Api.cs deleted file mode 100644 index e757913..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Generic/Api.cs +++ /dev/null @@ -1,238 +0,0 @@ -using Cesxhin.AnimeManga.Modules.Exceptions; -using Microsoft.AspNetCore.WebUtilities; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Text.Json; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Modules.Generic -{ - public class Api where T : class - { - //init - readonly string _address = Environment.GetEnvironmentVariable("ADDRESS_API") ?? "localhost"; - readonly string _port = Environment.GetEnvironmentVariable("PORT_API") ?? "5000"; - readonly string _protocol = Environment.GetEnvironmentVariable("PROTOCOL_API") ?? "http"; - - //settings deserialize - readonly JsonSerializerOptions options = new() - { - PropertyNameCaseInsensitive = true, - }; - - //get one object - public async Task GetOne(string path, Dictionary query = null) - { - using (var client = new HttpClient()) - { - string url = $"{_protocol}://{_address}:{_port}{path}"; - - if (query != null) - url = QueryHelpers.AddQueryString(url, query); - - var resultHttp = await client.GetAsync(url); - if (resultHttp.IsSuccessStatusCode) - { - //string to class object - return JsonSerializer.Deserialize(await resultHttp.Content.ReadAsStringAsync(), options); - } - else if (resultHttp.StatusCode == HttpStatusCode.NotFound) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else if (resultHttp.StatusCode == HttpStatusCode.Conflict) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else - { - throw new ApiConflictException(resultHttp.Content.ToString()); - } - } - } - - //get more object - public async Task> GetMore(string path, Dictionary query = null) - { - using (var client = new HttpClient()) - { - var url = QueryHelpers.AddQueryString($"{_protocol}://{_address}:{_port}{path}", query); - - var resultHttp = await client.GetAsync(url); - if (resultHttp.IsSuccessStatusCode) - { - //string to class object - return JsonSerializer.Deserialize>(await resultHttp.Content.ReadAsStringAsync(), options); - } - else if (resultHttp.StatusCode == HttpStatusCode.NotFound) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else if (resultHttp.StatusCode == HttpStatusCode.Conflict) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else - { - throw new ApiConflictException(resultHttp.Content.ToString()); - } - } - } - - //put one object - public async Task PutOne(string path, T classDTO) - { - using (var client = new HttpClient()) - using (var content = new StringContent(JsonSerializer.Serialize(classDTO), System.Text.Encoding.UTF8, "application/json")) - { - var resultHttp = await client.PutAsync($"{_protocol}://{_address}:{_port}{path}", content); - if (resultHttp.IsSuccessStatusCode) - { - return JsonSerializer.Deserialize(await resultHttp.Content.ReadAsStringAsync(), options); - } - else if (resultHttp.StatusCode == HttpStatusCode.NotFound) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else if (resultHttp.StatusCode == HttpStatusCode.Conflict) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else - { - throw new ApiConflictException(resultHttp.ReasonPhrase); - } - } - } - - //for JObject - public async Task PutOne(string path, JObject classDTO) - { - using (var client = new HttpClient()) - using (var content = new StringContent(JsonSerializer.Serialize(classDTO.ToString()), System.Text.Encoding.UTF8, "application/json")) - { - var resultHttp = await client.PutAsync($"{_protocol}://{_address}:{_port}{path}", content); - if (resultHttp.IsSuccessStatusCode) - { - var contentResponse = await resultHttp.Content.ReadAsStringAsync(); - return JObject.Parse(contentResponse); - } - else if (resultHttp.StatusCode == HttpStatusCode.NotFound) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else if (resultHttp.StatusCode == HttpStatusCode.Conflict) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else - { - throw new ApiConflictException(resultHttp.ReasonPhrase); - } - } - } - - //put more object - public async Task> PutMore(string path, List classDTO) - { - using (var client = new HttpClient()) - using (var content = new StringContent(JsonSerializer.Serialize(classDTO), System.Text.Encoding.UTF8, "application/json")) - { - var resultHttp = await client.PutAsync($"{_protocol}://{_address}:{_port}{path}", content); - if (resultHttp.IsSuccessStatusCode) - { - return JsonSerializer.Deserialize>(await resultHttp.Content.ReadAsStringAsync(), options); - } - else if (resultHttp.StatusCode == HttpStatusCode.NotFound) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else if (resultHttp.StatusCode == HttpStatusCode.Conflict) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else - { - throw new ApiConflictException(resultHttp.Content.ToString()); - } - } - } - - //post one object - public async Task PostOne(string path, T classDTO) - { - using (var client = new HttpClient()) - using (var content = new StringContent(JsonSerializer.Serialize(classDTO), System.Text.Encoding.UTF8, "application/json")) - { - var resultHttp = await client.PostAsync($"{_protocol}://{_address}:{_port}{path}", content); - if (resultHttp.IsSuccessStatusCode) - { - return JsonSerializer.Deserialize(await resultHttp.Content.ReadAsStringAsync(), options); - } - else if (resultHttp.StatusCode == HttpStatusCode.NotFound) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else if (resultHttp.StatusCode == HttpStatusCode.Conflict) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else - { - throw new ApiConflictException(resultHttp.Content.ToString()); - } - } - } - - //post more object - public async Task> PostMore(string path, List classDTO) - { - using (var client = new HttpClient()) - using (var content = new StringContent(JsonSerializer.Serialize(classDTO), System.Text.Encoding.UTF8, "application/json")) - { - var resultHttp = await client.PostAsync($"{_protocol}://{_address}:{_port}{path}", content); - if (resultHttp.IsSuccessStatusCode) - { - return JsonSerializer.Deserialize>(await resultHttp.Content.ReadAsStringAsync(), options); - } - else if (resultHttp.StatusCode == HttpStatusCode.NotFound) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else if (resultHttp.StatusCode == HttpStatusCode.Conflict) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else - { - throw new ApiConflictException(resultHttp.Content.ToString()); - } - } - } - - //post message to Discord - public void PostMessageDiscord(string path, T classDTO) - { - using (var client = new HttpClient()) - using (var content = new StringContent(JsonSerializer.Serialize(classDTO), System.Text.Encoding.UTF8, "application/json")) - { - var resultHttp = client.PostAsync(path, content).GetAwaiter().GetResult(); - if (resultHttp.IsSuccessStatusCode) - { - return; - } - else if (resultHttp.StatusCode == HttpStatusCode.NotFound) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - else if (resultHttp.StatusCode == HttpStatusCode.Conflict) - { - throw new ApiNotFoundException(resultHttp.Content.ToString()); - } - } - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Generic/ConvertGeneric.cs b/src/references/Cesxhin.AnimeManga.Modules/Generic/ConvertGeneric.cs deleted file mode 100644 index da15cd2..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Generic/ConvertGeneric.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; - -namespace Cesxhin.AnimeManga.Modules.Generic -{ - public static class ConvertGeneric where T : class - { - public static List ConvertIEnurableToListCollection(IEnumerable list) - { - List result = new(); - - foreach (T item in list) - { - result.Add(item); - } - return result; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Generic/Hash.cs b/src/references/Cesxhin.AnimeManga.Modules/Generic/Hash.cs deleted file mode 100644 index 8e9d8fa..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Generic/Hash.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.IO; -using System.Security.Cryptography; -using System.Text; - -namespace Cesxhin.AnimeManga.Modules.Generic -{ - public static class Hash - { - public static string GetHash(string path) - { - using (SHA256 hash = SHA256.Create()) - { - try - { - File.OpenRead(path).Close(); - - var content = File.ReadAllBytes(path); - - return BytesToStr(hash.ComputeHash(content)); - } - catch (IOException) - { - return null; - } - } - } - - private static string BytesToStr(byte[] bytes) - { - StringBuilder str = new(); - - for (int i = 0; i < bytes.Length; i++) - str.AppendFormat("{0:X2}", bytes[i]); - - return str.ToString(); - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperBookGeneric.cs b/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperBookGeneric.cs deleted file mode 100644 index 5662a8f..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperBookGeneric.cs +++ /dev/null @@ -1,223 +0,0 @@ -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Modules.Parallel; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using HtmlAgilityPack; -using Newtonsoft.Json.Linq; -using NLog; -using System; -using System.Collections.Generic; -using System.Net; - -namespace Cesxhin.AnimeManga.Modules.HtmlAgilityPack -{ - public static class RipperBookGeneric - { - //log - private static readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //parallel - private static readonly ParallelManager parallel = new(); - - public static JObject GetDescriptionBook(JObject schema, string urlPage, string nameCfg) - { - _logger.Info($"Start download page book: {urlPage}"); - - //get page - HtmlDocument doc = new HtmlWeb().Load(urlPage); - - //create empty for save to db - var descriptionDB = JObject.Parse("{}").ToObject(); - - //get dynamic fields - var fields = schema.GetValue("description").ToObject(); - foreach (var nameField in fields) - { - var result = RipperSchema.GetValue(fields.GetValue(nameField.Key).ToObject(), doc); - descriptionDB.Add(nameField.Key, result); - } - - descriptionDB["nameCfg"] = nameCfg; - descriptionDB["type"] = "book"; - descriptionDB["url_page"] = urlPage; - descriptionDB["name_id"] = RipperSchema.RemoveSpecialCharacters(descriptionDB.GetValue("name_id").ToString()); - - _logger.Info($"End download page book: {urlPage}"); - - return descriptionDB; - } - - public static List GetChapters(JObject schema, string urlPage, string name, string nameCfg) - { - List chaptersList = new(); - - _logger.Info($"Start download chapters manga: {urlPage}"); - - //collection - var collection = schema.GetValue("book").ToObject().GetValue("collection").ToObject(); - HtmlDocument doc = new HtmlWeb().Load(urlPage); - - var results = RipperSchema.GetValue(collection, doc); - - //procedure - var procedure = schema.GetValue("book").ToObject().GetValue("procedure").ToObject(); - var resultBooks = new List(); - - var reverseCount = schema.GetValue("book").ToObject().GetValue("collection").ToObject().GetValue("reverseCount").ToObject(); - - if (collection.GetValue("thread").ToObject() == true) - { - List> tasks = new(); - - foreach (var item in results) - { - var itemThread = item; - tasks.Add(new Func(() => { return GetChapterRecursive(procedure, procedure.Count, 0, itemThread, name, nameCfg); })); - } - - //when finish - parallel.AddTasks(tasks); - parallel.Start(); - parallel.WhenCompleted(); - resultBooks = parallel.GetResultAndClear(); - } - else - { - foreach (var item in results) - { - resultBooks.Add(GetChapterRecursive(procedure, procedure.Count, 0, item, name, nameCfg)); - } - } - - _logger.Info($"End download page episode: {urlPage}"); - - return resultBooks; - } - - private static ChapterDTO GetChapterRecursive(JObject actualProcedure, int step, int current, string urlPage, string name, string nameCfg) - { - - var stepSelect = actualProcedure[current.ToString()].ToObject(); - - var doc = new HtmlWeb().Load(urlPage); - var newUrlPage = RipperSchema.GetValue(stepSelect, doc, 0, 0, name, nameCfg); - - //set step - current += 1; - - if (current == step) - return newUrlPage; - - return GetChapterRecursive(actualProcedure, step, current, newUrlPage, name, nameCfg); - } - - public static byte[] GetImagePage(string urlPage, int page, ChapterDTO chapter) - { - JObject _schema = JObject.Parse(Environment.GetEnvironmentVariable("SCHEMA")); - var schema = _schema.GetValue(chapter.NameCfg).ToObject(); - var downloadSchema = schema.GetValue("book").ToObject().GetValue("download").ToObject(); - - if (downloadSchema.ContainsKey("startZero") && downloadSchema.GetValue("startZero").ToObject() == true) - downloadSchema["numberPage"] = page + 1; - else - downloadSchema["numberPage"] = page; - - var doc = new HtmlWeb().Load(urlPage); - - var imgUrl = RipperSchema.GetValue(downloadSchema, doc); - - using (var webClient = new WebClient()) - { - try - { - return webClient.DownloadData(imgUrl); - } - catch - { - _logger.Error($"Error download image from this url {imgUrl}"); - return null; - } - } - } - - public static List GetBookUrl(JObject schema, string name) - { - _logger.Info($"Start download list book, search: {name}"); - - List listUrlBook = new(); - - HtmlDocument doc; - - string url, prefixPage = null, prefixSearch, imageUrl = null, urlPage = null, nameBook = null; - var docBook = new HtmlDocument(); - - var page = 1; - while (true) - { - try - { - url = schema.GetValue("url_search").ToString(); - prefixSearch = schema.GetValue("prefixSearch").ToString(); - - if (schema.ContainsKey("prefixPage")) - prefixPage = schema.GetValue("prefixPage").ToString(); - - var isPage = schema.GetValue("page").ToObject(); - - if (isPage && prefixPage != null) - url = $"{url}{prefixSearch}={name}&{prefixPage}={page}"; - else - url = $"{url}{prefixSearch}={name}"; - - doc = new HtmlWeb().Load(url); - - - var collection = schema.GetValue("collection").ToObject(); - - var listBook = RipperSchema.GetValue(collection, doc); - - var description = schema.GetValue("description").ToObject(); - - foreach (var manga in listBook) - { - docBook.LoadHtml(manga.InnerHtml); - - //get image cover - var imageUrlSchema = description.GetValue("imageUrl").ToObject(); - imageUrl = RipperSchema.GetValue(imageUrlSchema, docBook); - - //url page - var urlPageSchema = description.GetValue("urlPage").ToObject(); - urlPage = RipperSchema.GetValue(urlPageSchema, docBook); - - //name - var nameBookSchema = description.GetValue("name").ToObject(); - nameBook = RipperSchema.GetValue(nameBookSchema, docBook); - - listUrlBook.Add(new GenericUrl - { - Name = RipperSchema.RemoveSpecialCharacters(nameBook), - Url = urlPage, - UrlImage = imageUrl, - TypeView = "book" - }); - } - - if (!isPage) - break; - } - catch - { - //not found other pages - break; - } - - page++; - } - - _logger.Info($"End download list book, search: {name}"); - - return listUrlBook; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperSchema.cs b/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperSchema.cs deleted file mode 100644 index 0a7a419..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperSchema.cs +++ /dev/null @@ -1,356 +0,0 @@ -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using HtmlAgilityPack; -using m3uParser; -using Newtonsoft.Json.Linq; -using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text.RegularExpressions; - -namespace Cesxhin.AnimeManga.Modules.HtmlAgilityPack -{ - public static class RipperSchema - { - //log - private static readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - public static dynamic GetValue(JObject schema, HtmlDocument doc, int numberSeason = 0, int numberEpisode = 0, string name = null, string nameCfg = null) - { - var paths = schema.GetValue("path").ToObject>(); - int i = 0, childNodesSelect = 0; - var types = schema.GetValue("type").ToObject>().ToArray(); - - //check nodes - if (schema.ContainsKey("child_nodes")) - childNodesSelect = (int)schema.GetValue("child_nodes"); - - //array for alternative paths - foreach (var path in paths) - { - try - { - //InnerHtml - if (types[i] == "string") - { - return doc.DocumentNode - .SelectNodes(path) - .First() - .ChildNodes[childNodesSelect] - .InnerHtml.Trim(); - } - else if (types[i] == "number") - { - var result = doc.DocumentNode - .SelectNodes(path) - .First() - .ChildNodes[childNodesSelect] - .InnerHtml; - - if (schema.ContainsKey("removeWords")) - { - var words = schema.GetValue("removeWords").ToObject>(); - - foreach (var word in words) - { - result = result.ToLower().Replace(word.ToLower(), ""); - } - - result = result.Trim(); - } - dynamic resultParse; - - if (schema.ContainsKey("parse") && schema.GetValue("parse").ToString() == "number") - { - try - { - resultParse = int.Parse(result); - } - catch (FormatException ex) - { - resultParse = null; - } - } - else - { - try - { - resultParse = float.Parse(result); - } - catch (FormatException ex) - { - resultParse = null; - } - } - - if (schema.ContainsKey("startZero") && schema.GetValue("startZero").ToObject() == true) - return (resultParse + 1); - - return resultParse; - } - else if (types[i] == "link") //Attributes.Value - { - var attributes = (string)schema.GetValue("attributes"); - - if (schema.ContainsKey("numberPage")) - { - return doc.DocumentNode - .SelectNodes(path.Replace("{numberPage}", (string)schema.GetValue("numberPage"))) - .First() - .Attributes[attributes].Value; - } - - return doc.DocumentNode - .SelectNodes(path) - .First() - .Attributes[attributes].Value; - } - else if (types[i] == "image") //Attributes.Value - { - var attributes = (string)schema.GetValue("attributes"); - string result = null; - - result = doc.DocumentNode - .SelectNodes(path) - .First() - .Attributes[attributes].Value; - - if (schema.ContainsKey("download") && (bool)schema.GetValue("download") == true) - { - try - { - using (var webClient = new WebClient()) - { - return Convert.ToBase64String(webClient.DownloadData(result)); - } - } - catch - { - _logger.Error($"Error download from this url {result}"); - } - } - return result; - } - else if (types[i] == "video/mp4") - { - var url = doc.DocumentNode - .SelectNodes(path) - .First() - .Attributes["src"].Value; - - return DownloadMetadataEpisode(numberSeason, numberEpisode, url, name, true, nameCfg); - } - else if (types[i] == "video/m3u8/script") - { - var script = doc.DocumentNode - .SelectNodes(path) - .First() - .InnerText; - - var startWord = schema.GetValue("startSearch").ToString(); - var endWord = schema.GetValue("endSearch").ToString(); - - var start = script.IndexOf(startWord); - - script = script.Substring(start + startWord.Length); - - var end = script.IndexOf(endWord); - - var url = script.Substring(0, end); - - return DownloadMetadataEpisode(numberSeason, numberEpisode, url, name, false, nameCfg); - } - else if (types[i] == "array") - { - var attributes = (string)schema.GetValue("attributes"); - - if (attributes == null) - { - return doc.DocumentNode - .SelectNodes(path) - .ToList(); - } - - var resultArray = new List(); - var list = doc.DocumentNode - .SelectNodes(path) - .ToList(); - - foreach (var item in list) - { - resultArray.Add(item.Attributes[attributes].Value); - } - - return resultArray; - } - else if (types[i] == "book/link") - { - var attributes = (string)schema.GetValue("attributes"); - - var url = doc.DocumentNode - .SelectNodes(path) - .First() - .Attributes[attributes].Value; - - if (schema.ContainsKey("addUrl")) - { - var addUrl = (string)schema.GetValue("addUrl"); - if (!url.Contains(addUrl)) - { - if (url.LastIndexOf('/') == (url.Trim().Length - 1)) - url = $"{url.Substring(0, url.LastIndexOf('/'))}/{addUrl}"; - else - url += addUrl; - } - } - - return DownloadMetadataChapter(schema, url, name, nameCfg); - } - break; - } - catch (Exception e) - { - _logger.Warn(e); - - continue; - } - finally - { - if ((i + 1) < types.Length) - i++; - } - } - - _logger.Error("Error get value by schema"); - return null; - } - - - public static string RemoveSpecialCharacters(string str) - { - //remove character special - return Regex.Replace(str, "[^a-zA-Z0-9_() ]+", "", RegexOptions.Compiled); - } - - private static ChapterDTO DownloadMetadataChapter(JObject schema, string urlBook, string name, string nameCfg) - { - int attempt = 5; - - while (attempt > 0) - { - var doc = new HtmlWeb().Load(urlBook); - - //get maxImage - var maxImageSchema = schema.GetValue("numberMaxImage").ToObject(); - var maxImage = GetValue(maxImageSchema, doc); - maxImage = maxImage[maxImage.Count - 1]; - maxImage = int.Parse(maxImage); - - if (maxImageSchema.ContainsKey("startZero") && maxImageSchema.GetValue("startZero").ToObject() == true) - maxImage += 1; - - //get number volume - var numberVolumeSchema = schema.GetValue("getVolume").ToObject(); - var numberVolume = GetValue(numberVolumeSchema, doc); - - if (numberVolume == null) - numberVolume = 1; - - //get number chapter - var numberChapterSchema = schema.GetValue("getChapter").ToObject(); - var numberChapter = GetValue(numberChapterSchema, doc); - - try - { - return new ChapterDTO - { - ID = $"{name}-v{numberVolume}-c{numberChapter}", - CurrentChapter = numberChapter, - CurrentVolume = numberVolume, - NameManga = name, - UrlPage = urlBook, - NumberMaxImage = maxImage, - NameCfg = nameCfg - }; - } - catch - { - attempt--; - _logger.Warn($"Failed download url: {urlBook}, remaining attempts {attempt}"); - } - } - - _logger.Fatal($"Impossible download this chapter, details: {urlBook}"); - return null; - } - - private static EpisodeDTO DownloadMetadataEpisode(int numberSeason, int numberEpisode, string urlVideo, string name, bool mp4, string nameCfg) - { - PlayerUrl playerUrl = null; - - if (mp4 == false) - { - _logger.Debug($"Start download url with buffer: {urlVideo}"); - - playerUrl = new PlayerUrl - { - Playlist = urlVideo - }; - - playerUrl.BaseUrl = playerUrl.Playlist.Replace("/playlist.m3u8", ""); - - //download source files - WebClient client = new(); - var bytes = client.DownloadData(playerUrl.Playlist); - var sourceFiles = System.Text.Encoding.UTF8.GetString(bytes); - - var contentM3u = M3U.Parse(sourceFiles); - string file = contentM3u.Warnings.First(); - - playerUrl.PlaylistSources = file.Substring(file.LastIndexOf("./") + 1); - playerUrl.Resolution = playerUrl.PlaylistSources.Substring(1, playerUrl.PlaylistSources.IndexOf("p")); - - //get list bytes for file - bytes = client.DownloadData(playerUrl.BaseUrl + playerUrl.PlaylistSources); - sourceFiles = System.Text.Encoding.UTF8.GetString(bytes); - contentM3u = M3U.Parse(sourceFiles); - playerUrl.endNumberBuffer = contentM3u.Medias.Count() - 1; //start 0 to xx - - _logger.Debug($"Done download url with buffer: {urlVideo}"); - } - - if (playerUrl != null) - { - return new EpisodeDTO - { - ID = $"{name}-s{numberSeason}-e{numberEpisode}", - VideoId = name, - NumberEpisodeCurrent = numberEpisode, - BaseUrl = playerUrl.BaseUrl, - Playlist = playerUrl.Playlist, - PlaylistSources = playerUrl.PlaylistSources, - Resolution = playerUrl.Resolution, - NumberSeasonCurrent = numberSeason, - endNumberBuffer = playerUrl.endNumberBuffer, - nameCfg = nameCfg - }; - } - else - { - return new EpisodeDTO - { - ID = $"{name}-s{numberSeason}-e{numberEpisode}", - VideoId = name, - UrlVideo = urlVideo, - NumberEpisodeCurrent = numberEpisode, - NumberSeasonCurrent = numberSeason, - nameCfg = nameCfg - - }; - } - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperVideoGeneric.cs b/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperVideoGeneric.cs deleted file mode 100644 index e97ae6c..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/HtmlAgilityPack/RipperVideoGeneric.cs +++ /dev/null @@ -1,200 +0,0 @@ -using Cesxhin.AnimeManga.Modules.NlogManager; -using Cesxhin.AnimeManga.Modules.Parallel; -using Cesxhin.AnimeManga.Domain.DTO; -using Cesxhin.AnimeManga.Domain.Models; -using HtmlAgilityPack; -using Newtonsoft.Json.Linq; -using NLog; -using System; -using System.Collections.Generic; - -namespace Cesxhin.AnimeManga.Modules.HtmlAgilityPack -{ - public static class RipperVideoGeneric - { - //log - private static readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //parallel - private static readonly ParallelManager parallel = new(); - private static readonly ParallelManager _parallel = new(); - - public static JObject GetDescriptionVideo(JObject schema, string urlPage, string nameCfg) - { - _logger.Info($"Start download page video: {urlPage}"); - - //get page - HtmlDocument doc = new HtmlWeb().Load(urlPage); - - //create empty for save to db - var descriptionDB = JObject.Parse("{}").ToObject(); - - //get dynamic fields - var fields = schema.GetValue("description").ToObject(); - foreach (var nameField in fields) - { - var result = RipperSchema.GetValue(fields.GetValue(nameField.Key).ToObject(), doc); - descriptionDB.Add(nameField.Key, result); - } - - descriptionDB["nameCfg"] = nameCfg; - descriptionDB["type"] = "video"; - descriptionDB["url_page"] = urlPage; - descriptionDB["name_id"] = RipperSchema.RemoveSpecialCharacters(descriptionDB.GetValue("name_id").ToString()); - - _logger.Info($"End download page video: {urlPage}"); - - return descriptionDB; - } - - public static dynamic GetEpisodesRecursive(JObject actualProcedure, int step, int current, string urlPage, int numberSeason, int numberEpisode, string name, string nameCfg) - { - var stepSelect = actualProcedure[current.ToString()].ToObject(); - - //array for alternative paths - var doc = new HtmlWeb().Load(urlPage); - var newUrlPage = RipperSchema.GetValue(stepSelect, doc, numberSeason, numberEpisode, name, nameCfg); - - //set step - current += 1; - - if (current == step) - return newUrlPage; - - return GetEpisodesRecursive(actualProcedure, step, current, newUrlPage, numberSeason, numberEpisode, name, nameCfg); - } - - public static List GetEpisodes(JObject schema, string urlPage, string name, string nameCfg) - { - //set variable - List episodes = new(); - int numberSeason = 1; //default - int numberEpisode = 1; - - _logger.Info($"Start download page episode: {urlPage}"); - - //collection - var collection = schema.GetValue("video").ToObject().GetValue("collection").ToObject(); - HtmlDocument doc = new HtmlWeb().Load(urlPage); - - var resultCollection = RipperSchema.GetValue(collection, doc); - - //procedure - var procedure = schema.GetValue("video").ToObject().GetValue("procedure").ToObject(); - var resultVideos = new List(); - - if (collection.GetValue("thread").ToObject() == true) - { - List> tasks = new(); - - foreach (var item in resultCollection) - { - var itemThread = item; - var numberSeasonThread = numberSeason; - var numberEpisodeThread = numberEpisode; - - tasks.Add(new Func(() => { return GetEpisodesRecursive(procedure, procedure.Count, 0, itemThread, numberSeasonThread, numberEpisodeThread, name, nameCfg); })); - numberEpisode += 1; - } - - //when finish - parallel.AddTasks(tasks); - parallel.Start(); - parallel.WhenCompleted(); - resultVideos = parallel.GetResultAndClear(); - } - else - { - foreach (var item in resultCollection) - { - resultVideos.Add(GetEpisodesRecursive(procedure, procedure.Count, 0, item, numberSeason, numberEpisode, name, nameCfg)); - numberEpisode += 1; - } - } - - _logger.Info($"End download page episode: {urlPage}"); - - return resultVideos; - } - - //get list anime external - public static List GetVideoUrl(JObject schema, string name) - { - _logger.Info($"Start download list video, search: {name}"); - - List listUrlVideo = new(); - - HtmlDocument doc; - - string url, prefixPage = null, prefixSearch, imageUrl = null, urlPage = null, nameVideo = null; - var docBook = new HtmlDocument(); - - var page = 1; - while (true) - { - try - { - url = schema.GetValue("url_search").ToString(); - prefixSearch = schema.GetValue("prefixSearch").ToString(); - - if (schema.ContainsKey("prefixPage")) - prefixPage = schema.GetValue("prefixPage").ToString(); - - var isPage = schema.GetValue("page").ToObject(); - - if (isPage && prefixPage != null) - url = $"{url}{prefixSearch}={name}&{prefixPage}={page}"; - else - url = $"{url}{prefixSearch}={name}"; - - doc = new HtmlWeb().Load(url); - - - var collection = schema.GetValue("collection").ToObject(); - - var listBook = RipperSchema.GetValue(collection, doc); - - var description = schema.GetValue("description").ToObject(); - - foreach (var manga in listBook) - { - docBook.LoadHtml(manga.InnerHtml); - - //get image cover - var imageUrlSchema = description.GetValue("imageUrl").ToObject(); - imageUrl = RipperSchema.GetValue(imageUrlSchema, docBook); - - //url page - var urlPageSchema = description.GetValue("urlPage").ToObject(); - urlPage = RipperSchema.GetValue(urlPageSchema, docBook); - - //name - var nameBookSchema = description.GetValue("name").ToObject(); - nameVideo = RipperSchema.GetValue(nameBookSchema, docBook); - - listUrlVideo.Add(new GenericUrl - { - Name = RipperSchema.RemoveSpecialCharacters(nameVideo), - Url = urlPage, - UrlImage = imageUrl, - TypeView = "video" - }); - } - - if (!isPage) - break; - } - catch - { - //not found other pages - break; - } - - page++; - } - - _logger.Info($"End download list video, search: {name}"); - return listUrlVideo; - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/NlogManager/NLogConsole.cs b/src/references/Cesxhin.AnimeManga.Modules/NlogManager/NLogConsole.cs deleted file mode 100644 index c847734..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/NlogManager/NLogConsole.cs +++ /dev/null @@ -1,108 +0,0 @@ -using Discord.Webhook; -using NLog; -using System; - -namespace Cesxhin.AnimeManga.Modules.NlogManager -{ - public class NLogConsole - { - private readonly Logger _logger; - private readonly DiscordWebhookClient discord; - - public NLogConsole(Logger logger) - { - //log - _logger = logger; - - //webhook - var webhookUrl = Environment.GetEnvironmentVariable("WEBHOOK_DISCORD_DEBUG") ?? null; - - if (webhookUrl != null) - discord = new DiscordWebhookClient(webhookUrl); - } - - private string DefaultMessage(LogLevel level, string msg) - { - string message = ""; - message += DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") + " | "; - - //set type error - switch (level.Name.ToLower()) - { - case "info": - message += "🔵 info: "; - break; - case "warn": - message += "🔶 warning: "; - break; - case "error": - message += "🔴 error: "; - break; - case "fatal": - message += "💀 fatal: "; - break; - } - message += msg; - - return message; - } - - //debug - public void Debug(object msg) - { - _logger.Debug(msg); - } - - //info - public void Info(object msg) - { - _logger.Info(msg); - - if (discord != null) - { - var _content = DefaultMessage(LogLevel.Info, msg.ToString()); - - discord.SendMessageAsync(_content).GetAwaiter().GetResult(); - } - } - - //warn - public void Warn(object msg) - { - _logger.Warn(msg); - - if (discord != null) - { - var _content = DefaultMessage(LogLevel.Warn, msg.ToString()); - - discord.SendMessageAsync(_content).GetAwaiter().GetResult(); - } - } - - //error - public void Error(object msg) - { - _logger.Error(msg); - - if (discord != null) - { - var _content = DefaultMessage(LogLevel.Error, msg.ToString()); - - discord.SendMessageAsync(_content).GetAwaiter().GetResult(); - } - } - - //fatal - public void Fatal(object msg) - { - _logger.Fatal(msg); - - if (discord != null) - { - var _content = DefaultMessage(LogLevel.Fatal, msg.ToString()); - - discord.SendMessageAsync(_content).GetAwaiter().GetResult(); - } - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/NlogManager/NLogManager.cs b/src/references/Cesxhin.AnimeManga.Modules/NlogManager/NLogManager.cs deleted file mode 100644 index 0661973..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/NlogManager/NLogManager.cs +++ /dev/null @@ -1,41 +0,0 @@ -using NLog; -using NLog.Config; -using NLog.Targets; - -namespace Cesxhin.AnimeManga.Modules.Generic -{ - public class NLogManager - { - public static void Configure(LogLevel minLevel) - { - var config = new LoggingConfiguration(); - - var consoleTarget = new ConsoleTarget(); - config.AddTarget("console", consoleTarget); - - var rule = new LoggingRule("*", minLevel, consoleTarget); - config.LoggingRules.Add(rule); - - LogManager.Configuration = config; - } - - public static LogLevel GetLevel(string level) - { - switch (level) - { - case "debug": - return LogLevel.Debug; - case "info": - return LogLevel.Info; - case "warn": - return LogLevel.Warn; - case "error": - return LogLevel.Error; - case "fatal": - return LogLevel.Fatal; - default: - return LogLevel.Info; - } - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Parallel/ParallelManager.cs b/src/references/Cesxhin.AnimeManga.Modules/Parallel/ParallelManager.cs deleted file mode 100644 index 80eacca..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Parallel/ParallelManager.cs +++ /dev/null @@ -1,154 +0,0 @@ -using Cesxhin.AnimeManga.Modules.NlogManager; -using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Cesxhin.AnimeManga.Modules.Parallel -{ - public class ParallelManager where T : class - { - //env - private readonly int NUMBER_PARALLEL_MAX = int.Parse(Environment.GetEnvironmentVariable("LIMIT_THREAD_PARALLEL") ?? "5"); - - //variable - private List> queue = new(); - private readonly List tasks = new(); - private readonly CancellationTokenSource tokenSource = new(); - - //nlog - private readonly NLogConsole _logger = new(LogManager.GetCurrentClassLogger()); - - //completed - private List list = new(); - - //task id - private Task process; - - private void Process(CancellationToken ct) - { - //thread for download parallel - int capacity = 0; - int count = 0; - - while (queue.Count != 0 || tasks.Count != 0) - { - if (ct.IsCancellationRequested) - ct.ThrowIfCancellationRequested(); - - //add task - while(capacity < NUMBER_PARALLEL_MAX && queue.Count > 0) - { - var task = queue.First(); - - if (task != null) - { - tasks.Add(Task.Run(task)); - capacity++; - queue.Remove(task); - } - else - { - _logger.Error($"Problem task null"); - } - } - - //must remove one task for continue download - do - { - List removeTask = new(); - foreach (var task in tasks) - { - if (task.IsCompleted) - { - var objectBuffer = ((Task)task).Result; - - list.Add(objectBuffer); - count++; - - capacity--; - removeTask.Add(task); - } - } - - //remove rask completed - foreach (var task in removeTask) - { - tasks.Remove(task); - } - - Thread.Sleep(1000); - } while (capacity >= NUMBER_PARALLEL_MAX); - } - } - - public void Start() - { - var token = tokenSource.Token; - process = Task.Run(() => Process(token), token); - } - - public void AddTasks(List> tasks) - { - queue = tasks; - } - - public bool CheckFinish() - { - if (tasks.Count == 0 && queue.Count == 0) - return true; - else - return false; - } - - public void WhenCompleted() - { - Task.WaitAll(process); - } - - public int PercentualCompleted() - { - if (list == null) - return 0; - return (list.Count * 100) / (list.Count + tasks.Count + queue.Count); //43 : 100 = 4 : x - } - - public List GetResult() - { - return list; - } - - public List GetResultAndClear() - { - List copy = new(list); - list.Clear(); - - return copy; - } - - public async void Kill() - { - tokenSource.Cancel(); - - while (process.IsCanceled == false) - { - Thread.Sleep(500); - } - - tasks.Clear(); - queue.Clear(); - } - - public bool checkError(T variableError) - { - return list.Contains(variableError); - } - - public void ClearList() - { - list.Clear(); - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Proxy/ProxyManagement.cs b/src/references/Cesxhin.AnimeManga.Modules/Proxy/ProxyManagement.cs deleted file mode 100644 index cb13ead..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Proxy/ProxyManagement.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Cesxhin.AnimeManga.Modules.Proxy -{ - public class ProxyManagement - { - private string blackList = ""; - private List listProxy = new(); - - public void InitProxy() - { - var enableProxy = Environment.GetEnvironmentVariable("PROXY_ENABLE") ?? "false"; - - if (enableProxy == "true") - { - listProxy = System.IO.File.ReadAllText("proxy.txt").Split(",").ToList(); - } - } - - public List GetAllIP() - { - return listProxy; - } - - public string GetIp() - { - if(EnableProxy()) - { - var listBlackProxy = blackList.Split(",").ToList(); - - foreach (var blackProxy in listBlackProxy) - { - listProxy = listProxy.Where(e => e != blackProxy).ToList(); - } - - if (listProxy.Count > 0) - { - return listProxy[new Random().Next(listProxy.Count)]; - } - } - - return null; - } - - public bool EnableProxy() - { - var enableProxy = Environment.GetEnvironmentVariable("PROXY_ENABLE") ?? "false"; - return enableProxy == "true"; - } - - public void BlackListAdd(string ip) - { - var list = blackList.Split(",").ToList(); - - if(list.Find(e => e == ip) == null) - { - list.Add(ip); - blackList = string.Join(",", list); - } - } - } -} diff --git a/src/references/Cesxhin.AnimeManga.Modules/Schema/SchemaControl.cs b/src/references/Cesxhin.AnimeManga.Modules/Schema/SchemaControl.cs deleted file mode 100644 index 6ef6011..0000000 --- a/src/references/Cesxhin.AnimeManga.Modules/Schema/SchemaControl.cs +++ /dev/null @@ -1,207 +0,0 @@ -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Cesxhin.AnimeManga.Modules.Schema -{ - public static class SchemaControl - { - public static void Check() - { - //check valid schema - Console.WriteLine("[STARTUP] Check schemas"); - var schemasFile = System.IO.File.ReadAllText("schemas.json"); - var schemaTemplateFile = System.IO.File.ReadAllText("schema_template.json"); - - var schema = JObject.Parse(schemasFile); - var schemaTemplate = JObject.Parse(schemaTemplateFile); - - CheckRecursive(schema, schemaTemplate, ""); - - Environment.SetEnvironmentVariable("SCHEMA", schemasFile); - } - - private static void CheckRecursive(JObject schema, JObject schemaTemplate, string path) - { - foreach (var field in schemaTemplate.ToObject()) - { - if (field.Key == "*" && path != "") - { - foreach(var fieldSchema in schema.ToObject()) - { - CheckRules(schema.GetValue(fieldSchema.Key).ToObject(), path+"/"+fieldSchema.Key); - } - } - else - { - if (field.Key != "*" && !schema.ContainsKey(field.Key)) - { - throw new Exception($"Missing this field: {field.Key}"); - } - - if (field.Value.Type == JTokenType.Object) - { - CheckRecursive(getKeyByField(schema, field.Key), schemaTemplate.GetValue(field.Key).ToObject(), path + "/" + field.Key); - } - else - { - //check type - if ((string)field.Value == "string") - { - if (schema.GetValue(field.Key).Type != JTokenType.String) - throw new Exception($"Field {field.Key} isn't type String"); - - //check rules - if (path == "/*" && field.Key == "type") - { - if (schema.Value(field.Key) != "video" && schema.Value(field.Key) != "book") - throw new Exception($"Field Type is incorrect, please select 'video' or 'book'"); - } - } - else if ((string)field.Value == "boolean") - { - if (schema.GetValue(field.Key).Type != JTokenType.Boolean) - throw new Exception($"Field {field.Key} isn't type Boolean"); - } - else if ((string)field.Value == "*") - { - CheckRules(schema.Value(field.Key), path + "/" + field.Key); - } - else - { - throw new Exception($"Uknow type, error schema template of this field {field.Key}, path: {path}"); - } - } - } - } - } - - private static void CheckRules(JObject schema, string path) - { - if (!schema.ContainsKey("type")) - throw new Exception("Missing field type for scapring"); - - if (!schema.ContainsKey("path")) - throw new Exception("Missing field path for scapring"); - - if(schema.GetValue("type").Type != JTokenType.Array) - throw new Exception("Field type for scapring isn't array"); - - if (schema.GetValue("path").Type != JTokenType.Array) - throw new Exception("Field path for scapring isn't array"); - - var arrayType = schema.GetValue("type").ToObject>(); - var arrayPath = schema.GetValue("path").ToObject>(); - - /*if (arrayType.Count() != arrayPath.Count()) - throw new Exception("Lenght between type and path is different, they should be equal");*/ - - foreach (var type in arrayType) - { - switch (type) - { - case "string": - if (schema.ContainsKey("child_nodes")) - { - if (schema.GetValue("child_nodes").Type != JTokenType.Integer) - throw new Exception($"Field child_nodes should be Interger"); - } - break; - case "image": - if(!schema.ContainsKey("attributes")) - throw new Exception($"Field attributes missing"); - - if(schema.GetValue("attributes").Type != JTokenType.String) - throw new Exception($"Field attributes should be String"); - - if (schema.ContainsKey("download")) - { - if (schema.GetValue("download").Type != JTokenType.Boolean) - throw new Exception($"Field attributes should be Boolean"); - } - - break; - - case "array": - if (schema.ContainsKey("attributes")) - { - if (schema.GetValue("attributes").Type != JTokenType.String) - throw new Exception($"Field attributes should be String"); - } - break; - - case "video/m3u8/script": - if (!schema.ContainsKey("startSearch")) - throw new Exception($"Field startSearch missing"); - - if (schema.GetValue("startSearch").Type != JTokenType.String) - throw new Exception($"Field startSearch should be String"); - - if (!schema.ContainsKey("endSearch")) - throw new Exception($"Field endSearch missing"); - - if (schema.GetValue("endSearch").Type != JTokenType.String) - throw new Exception($"Field endSearch should be String"); - break; - case "number": - if (schema.ContainsKey("parse")) - { - if (schema.GetValue("parse").Type != JTokenType.String) - throw new Exception($"Field parse should be String"); - - if (schema.Value("parse") != "number" && schema.Value("parse") != "float") - throw new Exception($"Field parse is incorrect, please select 'number' or 'float'"); - } - - if (schema.ContainsKey("removeWords")) - { - if (schema.GetValue("removeWords").Type != JTokenType.String) - throw new Exception($"Field removeWords should be String"); - } - break; - case "book/link": - if (!schema.ContainsKey("attributes")) - throw new Exception($"Field attributes missing"); - - if (schema.GetValue("attributes").Type != JTokenType.String) - throw new Exception($"Field attributes should be String"); - - if (schema.ContainsKey("addUrl")) - { - if (schema.GetValue("addUrl").Type != JTokenType.String) - throw new Exception($"Field addUrl should be String"); - } - break; - } - } - - //collection of video or book - if(path == "/*/book/collection" || path == "/*/video/collection") - { - if (!schema.ContainsKey("thread")) - throw new Exception($"Field thread missing"); - - if (schema.GetValue("thread").Type != JTokenType.Boolean) - throw new Exception($"Field thread should be Boolean"); - - if (schema.ContainsKey("reverseCount")) - { - if (schema.GetValue("reverseCount").Type != JTokenType.Boolean) - throw new Exception($"Field reverseCount should be Boolean"); - } - } - } - - private static JObject getKeyByField(JObject schema, string field) - { - if (field == "*") - { - var name = ((JProperty)schema.First).Name.ToString(); - return schema.GetValue(name).ToObject(); - } - else - return schema.GetValue(field).ToObject(); - } - } -} diff --git a/src/schemas/accountSchema.ts b/src/schemas/accountSchema.ts new file mode 100644 index 0000000..18b0deb --- /dev/null +++ b/src/schemas/accountSchema.ts @@ -0,0 +1,29 @@ +import { Type } from "@sinclair/typebox"; + +import { accountSchema, IAccountEnv } from "../domain/interfaces/models/IAccount"; +import { accountDTOSchema } from "../domain/interfaces/DTOs/IAccountDTO"; +import { convertToOptional } from "../utils/schemaUtils"; +import { requireAuth } from "./generic/authSchema"; + +//path base +const PATH_BASE_CONTROLLER = "/account"; + +//request +const schemaCreateAccount = Type.Pick(accountSchema, [IAccountEnv.USERNAME, IAccountEnv.PASSWORD, IAccountEnv.CHANGE_PASSWORD]); +const schemaUpdateAccount = convertToOptional(accountSchema, [IAccountEnv.PROFILE, IAccountEnv.CHANGE_PASSWORD]); +const schemaQueryUsernameAccount = requireAuth(Type.Pick(accountSchema, [IAccountEnv.USERNAME])); + +//replay +const schemaReturnAccount = accountDTOSchema; + +export { + PATH_BASE_CONTROLLER, + + //request + schemaCreateAccount, + schemaUpdateAccount, + schemaQueryUsernameAccount, + + //replay + schemaReturnAccount +}; \ No newline at end of file diff --git a/src/schemas/friendSchema.ts b/src/schemas/friendSchema.ts new file mode 100644 index 0000000..4acc520 --- /dev/null +++ b/src/schemas/friendSchema.ts @@ -0,0 +1,35 @@ +import { Type } from "@sinclair/typebox"; + +import { friendSchema, IFriendEnv } from "../domain/interfaces/models/IFriend"; +import { friendDTOSchema } from "../domain/interfaces/DTOs/IFriendDTO"; +import { queryPagination, schemaReturnPagination } from "./generic/paginationSchema"; +import { requireAuth } from "./generic/authSchema"; + +//path base +const PATH_BASE_CONTROLLER = "/friend"; + +//request +const schemaQueryUsernameOfFriend = requireAuth(Type.Pick(friendSchema, [IFriendEnv.FRIEND])); +const schemaQueryPaginatedFriend = requireAuth(queryPagination); + +//replay +const schemaReturnFriend = friendDTOSchema; +const schemaReturnPaginatedFriend = schemaReturnPagination(friendDTOSchema); + +//interface +type ISchemaReturnPaginatedFriend = typeof schemaReturnPaginatedFriend.static; + +export { + PATH_BASE_CONTROLLER, + + //request + schemaQueryUsernameOfFriend, + schemaQueryPaginatedFriend, + + //replay + schemaReturnFriend, + schemaReturnPaginatedFriend, + + //interface + ISchemaReturnPaginatedFriend +}; \ No newline at end of file diff --git a/src/schemas/generic/authSchema.ts b/src/schemas/generic/authSchema.ts new file mode 100644 index 0000000..4baac8c --- /dev/null +++ b/src/schemas/generic/authSchema.ts @@ -0,0 +1,15 @@ +import { Type, TObject } from "@sinclair/typebox"; + +const schemaQueryUsernameAuth = Type.Object({ + auth_username: Type.String({maxLength: 250}) +}); + +function requireAuth(query: T){ + return Type.Intersect([schemaQueryUsernameAuth, query]); +} + +export { + schemaQueryUsernameAuth, + + requireAuth +}; \ No newline at end of file diff --git a/src/schemas/generic/genericSchema.ts b/src/schemas/generic/genericSchema.ts new file mode 100644 index 0000000..10bfea0 --- /dev/null +++ b/src/schemas/generic/genericSchema.ts @@ -0,0 +1,56 @@ +import { Type } from "@sinclair/typebox"; + +const SCHEMA_NOT_FOUND = "SchemaNotFound"; +const SCHEMA_INTERNAL_SERVER = "SchemaInternalServer"; +const SCHEMA_CONFLICT = "SchemaConflict"; +const SCHEMA_BAD_REQUEST = "SchemaBadRequest"; +const SCHEMA_UNAUTHORIZED = "SchemaUnauthorized"; + +const schemaReturnVoid = Type.Object({ + response: Type.String({default: "ok"}) +}); + +const templateErrorSchema = Type.Object({ + message: Type.String({default: "Example error"}), + error: Type.String({default: "Name error"}) +}); + +const notFound = Type.Intersect([ + templateErrorSchema, Type.Object({ + statusCode: Type.Number({default: 404}) + }) +], { $id: SCHEMA_NOT_FOUND }); +const internalServer = Type.Intersect([ + templateErrorSchema, Type.Object({ + statusCode: Type.Number({default: 500}) + }) +], { $id: SCHEMA_INTERNAL_SERVER }); +const conflict = Type.Intersect([ + templateErrorSchema, Type.Object({ + statusCode: Type.Number({default: 409}) + }) +], { $id: SCHEMA_CONFLICT }); +const badRequest = Type.Intersect([ + templateErrorSchema, Type.Object({ + statusCode: Type.Number({default: 400}) + }) +], { $id: SCHEMA_BAD_REQUEST }); +const unauthorized = Type.Intersect([ + templateErrorSchema, Type.Object({ + statusCode: Type.Number({default: 401}) + }) +], { $id: SCHEMA_UNAUTHORIZED }); + +export default [notFound, internalServer, conflict, badRequest, unauthorized]; + +export { + //replay + schemaReturnVoid, + + //replay with ID + SCHEMA_NOT_FOUND, + SCHEMA_BAD_REQUEST, + SCHEMA_CONFLICT, + SCHEMA_INTERNAL_SERVER, + SCHEMA_UNAUTHORIZED +}; \ No newline at end of file diff --git a/src/schemas/generic/paginationSchema.ts b/src/schemas/generic/paginationSchema.ts new file mode 100644 index 0000000..a8ec748 --- /dev/null +++ b/src/schemas/generic/paginationSchema.ts @@ -0,0 +1,19 @@ +import { Type, TObject } from "@sinclair/typebox"; + +const queryPagination = Type.Object({ + skip: Type.Number({minimum: 0, default: 0}), + length: Type.Number({minimum: 10, default: 10}) +}); + +function schemaReturnPagination(schema: T){ + return Type.Object({ + max_count: Type.Number(), + list: Type.Array(schema) + }); +} + +export { + schemaReturnPagination, + + queryPagination +}; \ No newline at end of file diff --git a/src/schemas/requestSchema.ts b/src/schemas/requestSchema.ts new file mode 100644 index 0000000..8646e91 --- /dev/null +++ b/src/schemas/requestSchema.ts @@ -0,0 +1,42 @@ +import { Type } from "@sinclair/typebox"; +import { queryPagination, schemaReturnPagination } from "./generic/paginationSchema"; +import { requestDTOSchema } from "../domain/interfaces/DTOs/IRequestDTO"; +import { IRequestEnv, requestSchema } from "../domain/interfaces/models/IRequest"; +import { schemaQueryUsernameAuth, requireAuth } from "./generic/authSchema"; + +//path base +const PATH_BASE_CONTROLLER = "/request"; + +//request +const schemaCreateRequest = Type.Pick(requestSchema, [IRequestEnv.REQUEST_TO]); +const schemaActionRequest = Type.Intersect([ + schemaQueryUsernameAuth, + Type.Pick(requestSchema, [IRequestEnv.REQUEST_FROM]), + Type.Object({ + accept: Type.Boolean() + }) +]); +const schemaQueryPaginatedRequest = requireAuth(queryPagination); +const schemaQueryDeleteRequest = requireAuth(Type.Pick(requestSchema, [IRequestEnv.REQUEST_TO])); + +//replay +const schemaReturnPaginatedRequest = schemaReturnPagination(requestDTOSchema); + +//interface +type ISchemaReturnPaginatedRequest = typeof schemaReturnPaginatedRequest.static; + +export { + PATH_BASE_CONTROLLER, + + //request + schemaCreateRequest, + schemaActionRequest, + schemaQueryPaginatedRequest, + schemaQueryDeleteRequest, + + //replay + schemaReturnPaginatedRequest, + + //interfaces + ISchemaReturnPaginatedRequest +}; \ No newline at end of file diff --git a/src/server/fastify/index.ts b/src/server/fastify/index.ts new file mode 100644 index 0000000..1bbfc86 --- /dev/null +++ b/src/server/fastify/index.ts @@ -0,0 +1,260 @@ +import fs from "fs"; +import _ from "lodash"; +import path from "path"; +import Fastify from "fastify"; +import { DateTime } from "luxon"; +import { env, exit } from "process"; +import { TypeBoxTypeProvider } from "@fastify/type-provider-typebox"; + +import { IConfig } from "./interfaces/IConfig"; +import { ApiBadRequest, ApiConflict, ApiErrorGeneric, ApiNotFound, ApiUnauthorized } from "../../modules/api"; + +import Logger from "../../modules/logger"; +const logger = new Logger("server-fastify"); + +const __dirname = path.resolve(); + +//settings +const fastify = Fastify().withTypeProvider(); + +//init +async function init({pathControllers = "controllers", pathSchemas = "schemas", swagger = true}: IConfig){ + logger.info("Starting service fastify..."); + + //swagger + if (swagger){ + logger.debug("Starting load swagger"); + await fastify.register(await import("@fastify/swagger")); + await fastify.register(await import("@fastify/swagger-ui"), { + routePrefix: "/", + uiConfig: { + docExpansion: "list", + deepLinking: false + }, + uiHooks: { + onRequest: function (request, reply, next) { next(); }, + preHandler: function (request, reply, next) { next(); } + }, + logLevel: "error" + }); + logger.debug("Finish load swagger"); + } + + //controllers + logger.debug("Starting load controllers"); + await loadControllers(pathControllers); + logger.debug("Finish load all controllers"); + + //schemas + logger.debug("Starting load schemas"); + await loadSchemas(pathSchemas); + logger.debug("Finish load all schemas"); + + await fastify.ready(); + fastify.swagger(); + + //server + let connection = ""; + try { + connection = await fastify.listen({ + port: _.isNil(env.SERVER_PORT)? 3001 : parseInt(env.SERVER_PORT), + host: env.SERVER_PORT || "127.0.0.1" + }); + } catch (err){ + logger.fatal("Stop service fastify reason:", err); + exit(1); + } + + logger.info(`Connection established ${connection}`); +} + +//load controllers +async function loadControllers(pathControllers: string){ + const basePathController = path.join(__dirname, pathControllers); + + //get list folder inside controllers + let listFileControllers: Array = []; + try { + listFileControllers = fs.readdirSync(basePathController).filter((file) => file.indexOf(".") === -1).map((folder) => path.join(basePathController, folder)); + } catch (err){ + logger.fatal("Cannot read folder", pathControllers, "details: ", err); + exit(1); + } + + logger.debug("List controllers available:", listFileControllers.map((file) => path.basename(file))); + logger.debug("Controllers", `(${listFileControllers.length})`, "available"); + + let success = 0; + for (const fileController of listFileControllers) { + const totalRoutes = await loadRoutes(fileController); + + if (totalRoutes > 0){ + logger.debug("Done import controller", path.basename(fileController)); + success++; + } else { + logger.error("Controller", path.basename(fileController), "maybe has some error"); + } + } + + if (success === 0){ + logger.fatal("controllers none loaded"); + exit(1); + } + + logger.debug("Total controllers loaded", success); +} + +//load routes +async function loadRoutes(pathController: string){ + let listFileRoutes: Array = []; + + try { + listFileRoutes = fs.readdirSync(pathController).filter((file) => file.indexOf(".") !== -1).map((file) => path.join(pathController, file)); + } catch (err){ + logger.error("Cannot read controller", path.basename(pathController), "details:", err); + } + + logger.debug("List routes available", listFileRoutes.map((file) => path.basename(file))); + logger.debug("Routes", `(${listFileRoutes.length})`, "available"); + + let success = 0; + for (const fileRoute of listFileRoutes) { + try { + await import(fileRoute); + } catch (err){ + logger.error("Failed load route", `"${fileRoute}" details:`, err); + continue; + } + + logger.debug("Done import route", path.basename(fileRoute)); + success++; + } + + logger.debug("Loaded", `(${success}) routes from`, path.basename(pathController)); + return success; +} + +//load schemas +async function loadSchemas(pathSchemas){ + const basePathSchemas = path.join(__dirname, pathSchemas); + + if (!fs.existsSync(basePathSchemas)){ + logger.warn("Not exist root folder schemas, skip schemas"); + return; + } + + //get list folder inside controllers + const listFileSchemas = fs.readdirSync(basePathSchemas, {recursive: true, withFileTypes: true}).filter((singlePath) => singlePath.isFile()).map((singlePath) => path.join(singlePath.parentPath, singlePath.name)); + + logger.debug(`List schemas available: ${listFileSchemas.map((file) => path.basename(file))}`); + + let success = 0; + let listSchemas: Array; + for (const fileSchema of listFileSchemas) { + try { + listSchemas = (await import(fileSchema)).default; + } catch (err){ + logger.error(`Failed load schema "${path.basename(fileSchema)}", details:`, err); + continue; + } + + if (!_.isNil(listSchemas)){ + for (const schema of listSchemas) { + try { + fastify.addSchema(schema); + } catch (err){ + logger.error(`Failed add specific schema of ${schema["$id"]}, details:`, err); + } + } + } + + logger.debug("Done import schema", path.basename(fileSchema)); + success++; + } + + logger.debug("Total schemas loaded", success); +} + +//logging +fastify.addHook("onRequest", (req, replay, next) => { + //@ts-ignores + replay.startTime = DateTime.now().toISO(); + + next(); +}); + +fastify.addHook("onResponse", (req, replay, next) => { + //@ts-ignore + const time = DateTime.fromISO(replay.startTime); + + let bodyJson = {}; + + if (env.LOG_LEVEL === "debug"){ + const body = req.body; + + if (!_.isObject(body)){ + try { + bodyJson = JSON.parse(body as string); + } catch { + //ignore + } + } else { + bodyJson = body; + } + } + + const message = [req.raw.method, req.url.split("?")[0], JSON.stringify(req.query), JSON.stringify(bodyJson), replay.statusCode, `(${DateTime.now().diff(time).toMillis()} ms)`]; + + if (replay.statusCode === 500){ + logger.error(...message); + } else if (replay.statusCode !== 200){ + logger.warn(...message); + } else { + logger.info(...message); + } + + next(); +}); + +fastify.setErrorHandler((error, request, replay) => { + const message = { + error: error.name, + message: error.message + }; + + if (error instanceof ApiConflict){ + return replay.status(409).send({ + ...message, + statusCode: 409 + }); + } else if (error instanceof ApiNotFound){ + return replay.status(404).send({ + ...message, + statusCode: 404 + }); + } else if (error instanceof ApiUnauthorized){ + return replay.status(401).send({ + ...message, + statusCode: 401 + }); + } else if (error instanceof ApiErrorGeneric){ + return replay.status(500).send({ + ...message, + statusCode: 500 + }); + } else if (error instanceof ApiBadRequest){ + return replay.status(400).send({ + ...message, + statusCode: 400 + }); + } else { + logger.error(error); + return error; + } +}); + +export default fastify; + +export { + init +}; \ No newline at end of file diff --git a/src/server/fastify/interfaces/IConfig.ts b/src/server/fastify/interfaces/IConfig.ts new file mode 100644 index 0000000..aad06dd --- /dev/null +++ b/src/server/fastify/interfaces/IConfig.ts @@ -0,0 +1,5 @@ +export interface IConfig{ + pathControllers?: string, + pathSchemas?: string, + swagger?: boolean +} \ No newline at end of file diff --git a/src/server/postgres/index.ts b/src/server/postgres/index.ts new file mode 100644 index 0000000..8f0d2e1 --- /dev/null +++ b/src/server/postgres/index.ts @@ -0,0 +1,43 @@ +import { DataSource } from "typeorm"; + +import Logger from "../../modules/logger"; +const logger = new Logger("pg"); + +import path from "path"; + +let pg: DataSource; + +async function init({ + address = "localhost", + port = "5432", + username = "root", + password = "root", + database = "animemanga" +}){ + pg = new DataSource({ + type: "postgres", + host: address, + port: parseInt(port), + username, + password, + database, + entities: [`${path.resolve()}/domain/models/*.ts`], + synchronize: process.env.NODE_ENV === "dev", + connectTimeoutMS: 5000 + }); + + try { + pg = await pg.initialize(); + } catch (err){ + logger.error("Error initialize postgres, reason:", err); + return; + } + + logger.debug("String connection:", `${address}:${port}`); + logger.info("Connected to pg!"); +} + +export { + pg, + init +}; \ No newline at end of file diff --git a/src/server/postgres/interfaces/IConfigPostgres.ts b/src/server/postgres/interfaces/IConfigPostgres.ts new file mode 100644 index 0000000..c268f78 --- /dev/null +++ b/src/server/postgres/interfaces/IConfigPostgres.ts @@ -0,0 +1,7 @@ +export interface IConfigPostgres { + address: string, + port: string + username: string, + password: string, + database: string +} \ No newline at end of file diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 0000000..aa4bae3 --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "moduleResolution": "Bundler", + "module": "ESNext", + "target": "ESNext", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "sourceMap": true + } +} \ No newline at end of file diff --git a/src/utils/accountUtils.ts b/src/utils/accountUtils.ts new file mode 100644 index 0000000..346a933 --- /dev/null +++ b/src/utils/accountUtils.ts @@ -0,0 +1,9 @@ +import CryptoJS from "crypto-js"; + +function hashPassword(password: string){ + return CryptoJS.SHA256(password).toString(); +} + +export { + hashPassword +}; \ No newline at end of file diff --git a/src/utils/genericUtils.ts b/src/utils/genericUtils.ts new file mode 100644 index 0000000..57ff132 --- /dev/null +++ b/src/utils/genericUtils.ts @@ -0,0 +1,16 @@ +import _ from "lodash"; + +function objectAssign(data: any, Idata: any){ + const newData = {}; + for (const key in Idata) { + if (_.isObject(data)){ + newData[Idata[key]] = data[Idata[key]]; + } + } + + return newData as T; +} + +export { + objectAssign +}; \ No newline at end of file diff --git a/src/utils/schemaUtils.ts b/src/utils/schemaUtils.ts new file mode 100644 index 0000000..dfee626 --- /dev/null +++ b/src/utils/schemaUtils.ts @@ -0,0 +1,11 @@ +import { TSchema, Type } from "@sinclair/typebox"; + +function convertToOptional(schema: T, keys: Array){ + const pick = Type.Pick(schema, keys); + + return Type.Mapped(Type.KeyOf(pick), (K) => Type.Optional(Type.Index(pick, K))); +} + +export { + convertToOptional +}; \ No newline at end of file