diff --git a/RMuseum/DbContext/RMuseumDbContext.cs b/RMuseum/DbContext/RMuseumDbContext.cs index 2277d1a1..76529c41 100644 --- a/RMuseum/DbContext/RMuseumDbContext.cs +++ b/RMuseum/DbContext/RMuseumDbContext.cs @@ -569,5 +569,10 @@ namespace RMuseum.DbContext /// public DbSet DiscoverQuotedQueueItems { get; set; } + /// + /// paper sources + /// + public DbSet PaperSources { get; set; } + } } diff --git a/RMuseum/Models/PDFLibrary/GanjoorPoemMatchFinding.cs b/RMuseum/Models/PDFLibrary/GanjoorPoemMatchFinding.cs new file mode 100644 index 00000000..d1df3988 --- /dev/null +++ b/RMuseum/Models/PDFLibrary/GanjoorPoemMatchFinding.cs @@ -0,0 +1,102 @@ +using System; + +namespace RMuseum.Models.PDFLibrary +{ + public class GanjoorPoemMatchFinding + { + /// + /// id + /// + public Guid Id { get; set; } + + /// + /// cat id + /// + public int GanjoorCatId { get; set; } + + /// + /// cat full title + /// + public string GanjoorCatFullTitle { get; set; } + + /// + /// cat full url + /// + public string GanjoorCatFullUrl { get; set; } + + /// + /// start from this poem + /// + public int GanjoorPoemId { get; set; } = 0; + + /// + /// book id + /// + public int BookId { get; set; } + + /// + /// book title + /// + public string BookTitle { get; set; } + + /// + /// page number + /// + public int PageNumber { get; set; } + + /// + /// threshold + /// + public int Threshold { get; set; } + + /// + /// queue time + /// + public DateTime QueueTime { get; set; } + + /// + /// started + /// + public bool Started { get; set; } + + /// + /// start time + /// + public DateTime? StartTime { get; set; } + + /// + /// last update + /// + public DateTime? LastUpdate { get; set; } + + /// + /// updated by user + /// + public Guid? LastUpdatedByUserId { get; set; } + + /// + /// current poem id + /// + public int CurrentPoemId { get; set; } + + /// + /// progress + /// + public int Progress { get; set; } + + /// + /// current page number + /// + public int CurrentPageNumber { get; set; } + + /// + /// finished + /// + public bool Finished { get; set; } + + /// + /// finish time + /// + public DateTime? FinishTime { get; set; } + } +} diff --git a/RMuseum/RMuseum.xml b/RMuseum/RMuseum.xml index 01a07719..c2c84411 100644 --- a/RMuseum/RMuseum.xml +++ b/RMuseum/RMuseum.xml @@ -3508,6 +3508,11 @@ discover quoted q items + + + paper sources + + @@ -13076,6 +13081,101 @@ Manuscript + + + id + + + + + cat id + + + + + cat full title + + + + + cat full url + + + + + start from this poem + + + + + book id + + + + + book title + + + + + page number + + + + + threshold + + + + + queue time + + + + + started + + + + + start time + + + + + last update + + + + + updated by user + + + + + current poem id + + + + + progress + + + + + current page number + + + + + finished + + + + + finish time + + Multi Volume Book @@ -18068,6 +18168,22 @@ + + + import naskban ganjoor matchings + + + + + + + import naskban ganjoor matchings + + + + + number of synched items + return list of suggested spec lines diff --git a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Naskban.cs b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Naskban.cs index 3b126a82..1d1e8d51 100644 --- a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Naskban.cs +++ b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Naskban.cs @@ -19,6 +19,7 @@ using RSecurityBackend.Models.Generic.Db; using RMuseum.Models.PDFLibrary; using DNTPersianUtils.Core; using System.Collections.Generic; +using RMuseum.Migrations; namespace RMuseum.Services.Implementation { @@ -507,5 +508,118 @@ namespace RMuseum.Services.Implementation return new RServiceResult(false, exp.ToString()); } } + + /// + /// import naskban ganjoor matchings + /// + /// + /// + public void ImportNaskbanGanjoorPoemMatchFindings(string naskbanUserName, string naskbanPassword) + { + _backgroundTaskQueue.QueueBackgroundWorkItem + ( + async token => + { + using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions())) //this is long running job, so _context might be already been freed/collected by GC + { + LongRunningJobProgressServiceEF jobProgressServiceEF = new LongRunningJobProgressServiceEF(context); + var job = (await jobProgressServiceEF.NewJob("ImportNaskbanGanjoorPoemMatchFindings", "Query data")).Result; + var res = await _ImportNaskbanGanjoorPoemMatchFindingsAsync(context, naskbanUserName, naskbanPassword); + if (!string.IsNullOrEmpty(res.ExceptionString)) + { + await jobProgressServiceEF.UpdateJob(job.Id, 100, "", false, res.ExceptionString); + } + else + { + await jobProgressServiceEF.UpdateJob(job.Id, 100, "", true); + } + } + }); + } + + /// + /// import naskban ganjoor matchings + /// + /// + /// + /// + /// number of synched items + private async Task> _ImportNaskbanGanjoorPoemMatchFindingsAsync(RMuseumDbContext context, string naskbanUserName, string naskbanPassword) + { + try + { + LoggedOnUserModelEx loggedOnUser; + using (HttpClient client = new HttpClient()) + { + LoginViewModel loginViewModel = new LoginViewModel() + { + Username = naskbanUserName, + Password = naskbanPassword, + ClientAppName = "Ganjoor API", + Language = "fa-IR" + }; + var loginResponse = await client.PostAsync("https://api.naskban.ir/api/users/login", new StringContent(JsonConvert.SerializeObject(loginViewModel), Encoding.UTF8, "application/json")); + + if (loginResponse.StatusCode != HttpStatusCode.OK) + { + return new RServiceResult(0, "login error: " + JsonConvert.DeserializeObject(await loginResponse.Content.ReadAsStringAsync())); + } + loggedOnUser = JsonConvert.DeserializeObject(await loginResponse.Content.ReadAsStringAsync()); + } + + + using (HttpClient secureClient = new HttpClient()) + { + secureClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loggedOnUser.Token); + var unsyncedResponse = await secureClient.GetAsync("https://api.naskban.ir/api/pdf/ganjoor/matching"); + if (!unsyncedResponse.IsSuccessStatusCode) + { + return new RServiceResult(0, "unsync error: " + JsonConvert.DeserializeObject(await unsyncedResponse.Content.ReadAsStringAsync())); + } + var matchings = JsonConvert.DeserializeObject(await unsyncedResponse.Content.ReadAsStringAsync()); + foreach (var matching in matchings) + { + if (false == await context.PaperSources.Where(p => p.NaskbanBookId == matching.BookId).AnyAsync()) + { + HttpResponseMessage responseBook = await secureClient.GetAsync($"https://api.naskban.ir/api/pdf/{matching.BookId}?includePages=false&includeBookText=false&includePageText=false"); + if (responseBook.StatusCode != HttpStatusCode.OK) + { + return new RServiceResult(0, $"book fetch error bookid = {matching.BookId} matching id = {matching.Id} - " + JsonConvert.DeserializeObject(await responseBook.Content.ReadAsStringAsync())); + } + responseBook.EnsureSuccessStatusCode(); + + var book = JsonConvert.DeserializeObject(await responseBook.Content.ReadAsStringAsync()); + var cat = await context.GanjoorCategories.AsNoTracking().Where(c => c.Id == matching.GanjoorCatId).SingleAsync(); + PaperSource paperSource = new PaperSource() + { + GanjoorPoetId = cat.PoetId, + GanjoorCatId = matching.GanjoorCatId, + GanjoorCatFullTitle = matching.GanjoorCatFullTitle, + GanjoorCatFullUrl = matching.GanjoorCatFullUrl, + BookType = LinkType.Naskban, + BookFullUrl = $"https://naskban.ir/{matching.BookId}", + NaskbanBookId = matching.BookId, + BookFullTitle = matching.BookTitle, + CoverThumbnailImageUrl = book.ExtenalCoverImageUrl, + Description = "", + IsTextOriginalSource = false, + MatchPercent = 0, + HumanReviewed = false, + }; + context.PaperSources.Add(paperSource); + await context.SaveChangesAsync(); + } + } + + var logoutUrl = $"https://api.naskban.ir/api/users/delsession?userId={loggedOnUser.User.Id}&sessionId={loggedOnUser.SessionId}"; + await secureClient.DeleteAsync(logoutUrl); + return new RServiceResult(matchings.Length); + } + } + catch (Exception exp) + { + return new RServiceResult(0, exp.ToString()); + } + } } } \ No newline at end of file