[FA-6] Author's posts seem to work
All checks were successful
CI / build-backend (pull_request) Successful in 2m4s
CI / build-frontend (pull_request) Successful in 46s

This commit is contained in:
gamer147
2025-12-29 22:06:12 -05:00
parent 8b3faa8f6c
commit 176c94297b
3 changed files with 10034 additions and 10 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -133,6 +133,9 @@ public class NovelpiaAdapter : ISourceAdapter
novel.SourceTags.Add(tag); novel.SourceTags.Add(tag);
} }
// Author's posts (from notice_table in the page HTML)
var authorsPosts = ParseAuthorsPosts(novelData);
// Chapters // Chapters
uint page = 0; uint page = 0;
List<ChapterMetadata> chapters = new List<ChapterMetadata>(); List<ChapterMetadata> chapters = new List<ChapterMetadata>();
@@ -169,16 +172,24 @@ public class NovelpiaAdapter : ISourceAdapter
page++; page++;
} }
// Wrap all chapters in a single "Main Story" volume // Add Author's Posts volume if there are any
novel.Volumes = new List<VolumeMetadata> if (authorsPosts.Count > 0)
{ {
new VolumeMetadata novel.Volumes.Add(new VolumeMetadata
{ {
Order = 1, Order = 0,
Name = "Main Story", Name = "Author's Posts",
Chapters = chapters Chapters = authorsPosts
} });
}; }
// Main Story volume
novel.Volumes.Add(new VolumeMetadata
{
Order = 1,
Name = "Main Story",
Chapters = chapters
});
return novel; return novel;
} }
@@ -251,4 +262,40 @@ public class NovelpiaAdapter : ISourceAdapter
} }
return await image.Content.ReadAsByteArrayAsync(); return await image.Content.ReadAsByteArrayAsync();
} }
private List<ChapterMetadata> ParseAuthorsPosts(string novelHtml)
{
var posts = new List<ChapterMetadata>();
// Find the notice_table section
var noticeTableMatch = Regex.Match(novelHtml,
@"(?s)<table[^>]*class=""notice_table[^""]*""[^>]*>(.*?)</table>");
if (!noticeTableMatch.Success)
return posts;
var tableContent = noticeTableMatch.Groups[1].Value;
// Find all td elements with onclick containing viewer URL and extract title from <b>
// HTML structure: <td ... onclick="...location='/viewer/3330612';"><b>Title</b>
var postMatches = Regex.Matches(tableContent,
@"onclick=""[^""]*location='/viewer/(\d+)'[^""]*""[^>]*><b>([^<]+)</b>");
uint order = 1;
foreach (Match match in postMatches)
{
string viewerId = match.Groups[1].Value;
string title = WebUtility.HtmlDecode(match.Groups[2].Value.Trim());
posts.Add(new ChapterMetadata
{
Revision = 0,
Order = order,
Url = $"https://novelpia.com/viewer/{viewerId}",
Name = title
});
order++;
}
return posts;
}
} }

View File

@@ -707,7 +707,7 @@
/> />
<!-- Chapter link (if not cover) --> <!-- Chapter link (if not cover) -->
{#if !currentImage.isCover && currentImage.volumeOrder && currentImage.chapterOrder} {#if !currentImage.isCover && currentImage.volumeOrder != null && currentImage.chapterOrder}
<a <a
href="/novels/{novelId}/volumes/{currentImage.volumeOrder}/chapters/{currentImage.chapterOrder}" href="/novels/{novelId}/volumes/{currentImage.volumeOrder}/chapters/{currentImage.chapterOrder}"
class="text-white/80 hover:text-white text-sm inline-flex items-center gap-1 mt-3" class="text-white/80 hover:text-white text-sm inline-flex items-center gap-1 mt-3"