Compare commits

..

No commits in common. "83ce315f876a813b526235d3275ec3a24c0c37e2" and "5bb4977876524096b9a2613c12fabe3ef0ad9057" have entirely different histories.

5 changed files with 64 additions and 55 deletions

View File

@ -17,12 +17,12 @@ jobs:
# https://github.com/docker/setup-qemu-action#usage # https://github.com/docker/setup-qemu-action#usage
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3.6.0 uses: docker/setup-qemu-action@v3.2.0
# https://github.com/marketplace/actions/docker-setup-buildx # https://github.com/marketplace/actions/docker-setup-buildx
- name: Set up Docker Buildx - name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v3.10.0 uses: docker/setup-buildx-action@v3.7.1
# https://github.com/docker/login-action#docker-hub # https://github.com/docker/login-action#docker-hub
- name: Login to Docker Hub - name: Login to Docker Hub
@ -33,7 +33,7 @@ jobs:
# https://github.com/docker/build-push-action#multi-platform-image # https://github.com/docker/build-push-action#multi-platform-image
- name: Build and push API - name: Build and push API
uses: docker/build-push-action@v6.15.0 uses: docker/build-push-action@v6.9.0
with: with:
context: ./ context: ./
file: ./Dockerfile file: ./Dockerfile

View File

@ -17,12 +17,12 @@ jobs:
# https://github.com/docker/setup-qemu-action#usage # https://github.com/docker/setup-qemu-action#usage
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3.6.0 uses: docker/setup-qemu-action@v3.2.0
# https://github.com/marketplace/actions/docker-setup-buildx # https://github.com/marketplace/actions/docker-setup-buildx
- name: Set up Docker Buildx - name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v3.10.0 uses: docker/setup-buildx-action@v3.7.1
# https://github.com/docker/login-action#docker-hub # https://github.com/docker/login-action#docker-hub
- name: Login to Docker Hub - name: Login to Docker Hub
@ -33,7 +33,7 @@ jobs:
# https://github.com/docker/build-push-action#multi-platform-image # https://github.com/docker/build-push-action#multi-platform-image
- name: Build and push API - name: Build and push API
uses: docker/build-push-action@v6.15.0 uses: docker/build-push-action@v6.9.0
with: with:
context: ./ context: ./
file: ./Dockerfile file: ./Dockerfile

View File

@ -17,12 +17,12 @@ jobs:
# https://github.com/docker/setup-qemu-action#usage # https://github.com/docker/setup-qemu-action#usage
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3.6.0 uses: docker/setup-qemu-action@v3.2.0
# https://github.com/marketplace/actions/docker-setup-buildx # https://github.com/marketplace/actions/docker-setup-buildx
- name: Set up Docker Buildx - name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v3.10.0 uses: docker/setup-buildx-action@v3.7.1
# https://github.com/docker/login-action#docker-hub # https://github.com/docker/login-action#docker-hub
- name: Login to Docker Hub - name: Login to Docker Hub
@ -33,7 +33,7 @@ jobs:
# https://github.com/docker/build-push-action#multi-platform-image # https://github.com/docker/build-push-action#multi-platform-image
- name: Build and push API - name: Build and push API
uses: docker/build-push-action@v6.15.0 uses: docker/build-push-action@v6.9.0
with: with:
context: ./ context: ./
file: ./Dockerfile file: ./Dockerfile

View File

@ -17,12 +17,12 @@ jobs:
# https://github.com/docker/setup-qemu-action#usage # https://github.com/docker/setup-qemu-action#usage
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3.6.0 uses: docker/setup-qemu-action@v3.2.0
# https://github.com/marketplace/actions/docker-setup-buildx # https://github.com/marketplace/actions/docker-setup-buildx
- name: Set up Docker Buildx - name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v3.10.0 uses: docker/setup-buildx-action@v3.7.1
# https://github.com/docker/login-action#docker-hub # https://github.com/docker/login-action#docker-hub
- name: Login to Docker Hub - name: Login to Docker Hub
@ -33,7 +33,7 @@ jobs:
# https://github.com/docker/build-push-action#multi-platform-image # https://github.com/docker/build-push-action#multi-platform-image
- name: Build and push API - name: Build and push API
uses: docker/build-push-action@v6.15.0 uses: docker/build-push-action@v6.9.0
with: with:
context: ./ context: ./
file: ./Dockerfile file: ./Dockerfile

View File

@ -17,7 +17,7 @@ public class Manganato : MangaConnector
{ {
Log($"Searching Publications. Term=\"{publicationTitle}\""); Log($"Searching Publications. Term=\"{publicationTitle}\"");
string sanitizedTitle = string.Join('_', Regex.Matches(publicationTitle, "[A-z]*").Where(str => str.Length > 0)).ToLower(); string sanitizedTitle = string.Join('_', Regex.Matches(publicationTitle, "[A-z]*").Where(str => str.Length > 0)).ToLower();
string requestUrl = $"https://manganato.gg/search/story/{sanitizedTitle}"; string requestUrl = $"https://manganato.com/search/story/{sanitizedTitle}";
RequestResult requestResult = RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, RequestType.Default); downloadClient.MakeRequest(requestUrl, RequestType.Default);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
@ -32,19 +32,13 @@ public class Manganato : MangaConnector
private Manga[] ParsePublicationsFromHtml(HtmlDocument document) private Manga[] ParsePublicationsFromHtml(HtmlDocument document)
{ {
List<HtmlNode> searchResults = document.DocumentNode.Descendants("div").Where(n => n.HasClass("panel_story_list")).ToList(); List<HtmlNode> searchResults = document.DocumentNode.Descendants("div").Where(n => n.HasClass("search-story-item")).ToList();
Log($"{searchResults.Count} items."); Log($"{searchResults.Count} items.");
List<string> urls = new(); List<string> urls = new();
foreach (HtmlNode mangaResult in searchResults) foreach (HtmlNode mangaResult in searchResults)
{ {
try urls.Add(mangaResult.Descendants("a").First(n => n.HasClass("item-title")).GetAttributes()
{ .First(a => a.Name == "href").Value);
urls.Add(mangaResult.Descendants("h3").First(n => n.HasClass("story_name"))
.Descendants("a").First().GetAttributeValue("href", ""));
} catch
{
//failed to get a url, send it to the void
}
} }
HashSet<Manga> ret = new(); HashSet<Manga> ret = new();
@ -84,47 +78,61 @@ public class Manganato : MangaConnector
string originalLanguage = ""; string originalLanguage = "";
Manga.ReleaseStatusByte releaseStatus = Manga.ReleaseStatusByte.Unreleased; Manga.ReleaseStatusByte releaseStatus = Manga.ReleaseStatusByte.Unreleased;
HtmlNode infoNode = document.DocumentNode.Descendants("ul").First(d => d.HasClass("manga-info-text")); HtmlNode infoNode = document.DocumentNode.Descendants("div").First(d => d.HasClass("story-info-right"));
string sortName = infoNode.Descendants("h1").First().InnerText; string sortName = infoNode.Descendants("h1").First().InnerText;
foreach (HtmlNode li in infoNode.Descendants("li")) HtmlNode infoTable = infoNode.Descendants().First(d => d.Name == "table");
foreach (HtmlNode row in infoTable.Descendants("tr"))
{ {
string text = li.InnerText.Trim().ToLower(); string key = row.SelectNodes("td").First().InnerText.ToLower();
string value = row.SelectNodes("td").Last().InnerText;
if (text.StartsWith("author(s) :")) string keySanitized = string.Concat(Regex.Matches(key, "[a-z]"));
switch (keySanitized)
{ {
authors = li.Descendants("a").Select(a => a.InnerText.Trim()).ToArray(); case "alternative":
} string[] alts = value.Split(" ; ");
else if (text.StartsWith("status :")) for(int i = 0; i < alts.Length; i++)
{ altTitles.Add(i.ToString(), alts[i]);
string status = text.Replace("status :", "").Trim().ToLower(); break;
if (status == "ongoing") case "authors":
releaseStatus = Manga.ReleaseStatusByte.Continuing; authors = value.Split('-');
else for (int i = 0; i < authors.Length; i++)
releaseStatus = Enum.Parse<Manga.ReleaseStatusByte>(status, true); authors[i] = authors[i].Replace("\r\n", "");
} break;
else if (li.HasClass("genres")) case "status":
{ switch (value.ToLower())
tags = li.Descendants("a").Select(a => a.InnerText.Trim()).ToHashSet(); {
case "ongoing": releaseStatus = Manga.ReleaseStatusByte.Continuing; break;
case "completed": releaseStatus = Manga.ReleaseStatusByte.Completed; break;
}
break;
case "genres":
string[] genres = value.Split(" - ");
for (int i = 0; i < genres.Length; i++)
genres[i] = genres[i].Replace("\r\n", "");
tags = genres.ToHashSet();
break;
} }
} }
string posterUrl = document.DocumentNode.Descendants("div").First(s => s.HasClass("manga-info-pic")).Descendants("img").First() string posterUrl = document.DocumentNode.Descendants("span").First(s => s.HasClass("info-image")).Descendants("img").First()
.GetAttributes().First(a => a.Name == "src").Value; .GetAttributes().First(a => a.Name == "src").Value;
string coverFileNameInCache = SaveCoverImageToCache(posterUrl, publicationId, RequestType.MangaCover, "https://www.manganato.gg/"); string coverFileNameInCache = SaveCoverImageToCache(posterUrl, publicationId, RequestType.MangaCover);
string description = document.DocumentNode.SelectSingleNode("//div[@id='contentBox']") string description = document.DocumentNode.Descendants("div").First(d => d.HasClass("panel-story-info-description"))
.InnerText.Replace("Description :", ""); .InnerText.Replace("Description :", "");
while (description.StartsWith('\n')) while (description.StartsWith('\n'))
description = description.Substring(1); description = description.Substring(1);
string pattern = "MMM-dd-yyyy HH:mm"; string pattern = "MMM dd,yyyy HH:mm";
HtmlNode? oldestChapter = document.DocumentNode HtmlNode? oldestChapter = document.DocumentNode
.SelectNodes("//div[contains(concat(' ',normalize-space(@class),' '),' row ')]/span[@title]").MaxBy( .SelectNodes("//span[contains(concat(' ',normalize-space(@class),' '),' chapter-time ')]").MaxBy(
node => DateTime.ParseExact(node.GetAttributeValue("title", "Dec-31-2400 23:59"), pattern, node => DateTime.ParseExact(node.GetAttributeValue("title", "Dec 31 2400, 23:59"), pattern,
CultureInfo.InvariantCulture).Millisecond); CultureInfo.InvariantCulture).Millisecond);
@ -140,7 +148,7 @@ public class Manganato : MangaConnector
public override Chapter[] GetChapters(Manga manga, string language="en") public override Chapter[] GetChapters(Manga manga, string language="en")
{ {
Log($"Getting chapters {manga}"); Log($"Getting chapters {manga}");
string requestUrl = manga.websiteUrl; string requestUrl = $"https://chapmanganato.com/{manga.publicationId}";
RequestResult requestResult = RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, RequestType.Default); downloadClient.MakeRequest(requestUrl, RequestType.Default);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
@ -158,20 +166,21 @@ public class Manganato : MangaConnector
{ {
List<Chapter> ret = new(); List<Chapter> ret = new();
HtmlNode chapterList = document.DocumentNode.Descendants("div").First(l => l.HasClass("chapter-list")); HtmlNode chapterList = document.DocumentNode.Descendants("ul").First(l => l.HasClass("row-content-chapter"));
Regex volRex = new(@"Vol\.([0-9]+).*"); Regex volRex = new(@"Vol\.([0-9]+).*");
Regex chapterRex = new(@"https:\/\/chapmanganato.[A-z]+\/manga-[A-z0-9]+\/chapter-([0-9\.]+)"); Regex chapterRex = new(@"https:\/\/chapmanganato.[A-z]+\/manga-[A-z0-9]+\/chapter-([0-9\.]+)");
Regex nameRex = new(@"Chapter ([0-9]+(\.[0-9]+)*){1}:? (.*)"); Regex nameRex = new(@"Chapter ([0-9]+(\.[0-9]+)*){1}:? (.*)");
foreach (HtmlNode chapterInfo in chapterList.Descendants("div").Where(x => x.HasClass("row"))) foreach (HtmlNode chapterInfo in chapterList.Descendants("li"))
{ {
string url = chapterInfo.Descendants("a").First().GetAttributeValue("href", ""); string fullString = chapterInfo.Descendants("a").First(d => d.HasClass("chapter-name")).InnerText;
string chapterName = chapterInfo.Descendants("a").First().GetAttributeValue("title", "");
string chapterNumber = Regex.Match(chapterName, @"Chapter ([0-9]+(\.[0-9]+)*)").Groups[1].Value; string url = chapterInfo.Descendants("a").First(d => d.HasClass("chapter-name"))
string? volumeNumber = Regex.Match(chapterName, @"Vol\.([0-9]+)").Groups[1].Value; .GetAttributeValue("href", "");
if (string.IsNullOrWhiteSpace(volumeNumber)) string? volumeNumber = volRex.IsMatch(fullString) ? volRex.Match(fullString).Groups[1].Value : null;
volumeNumber = "0"; string chapterNumber = chapterRex.Match(url).Groups[1].Value;
string chapterName = nameRex.Match(fullString).Groups[3].Value;
try try
{ {
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url)); ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));