Skittyblock / aidoku-community-sources

Public sources for the Aidoku application
Apache License 2.0
444 stars 158 forks source link

fix(copymanga): chapters sorted incorrectly #502

Closed aphronyx closed 1 year ago

aphronyx commented 1 year ago

This PR fixes the bug that chapters are sorted incorrectly.

Checklist

Premise

Chapters in the same group are already sorted in the JSON file; but the current sorting method (sort by date updated) will mess up the correct order.

Changes

Screenshots

Before After
chapters_before chapters_after
version_before version_after

Notes

Please let me know if there are any issues with this PR. Thanks for taking the time to review!

Skittyblock commented 1 year ago

How come you just use an index for the chapter numbers rather than actually using the chapter number in the title? The ideal behavior is to strip out the number from the title, pass that number to aidoku as the chapter number, and then just pass a title back if there actually is one other than just the "Chapter X"

aphronyx commented 1 year ago

How come you just use an index for the chapter numbers rather than actually using the chapter number in the title? The ideal behavior is to strip out the number from the title, pass that number to aidoku as the chapter number, and then just pass a title back if there actually is one other than just the "Chapter X"

i’ll rewrite the source and try to do that after the new api is out, but they don’t seem to follow the same naming conventions, making it difficult to parse the number: 第 X 回 (Chapter X) 全一卷 (Only One Volume) 第 X 話 (Chapter X in Traditional Chinese) 第 X 话 (Chapter X in Simplified Chinese)
Screenshot 2023-11-02 at 23 14 37 Screenshot 2023-11-02 at 23 15 03 Screenshot 2023-11-02 at 23 15 17 Screenshot 2023-11-02 at 23 15 44
Skittyblock commented 1 year ago

yeah once the new api is out and sources are being rewritten I'll review sources a little closer now that I know everything to look for so I can provide some better feedback before they go through. I'm sure there's a good way to do it here.

aphronyx commented 1 year ago

to future me, not the best, but apply to most naming conventions

Regex

use chinese_number::{ChineseCountMethod, ChineseToNumber};
use regex::Regex;

pub trait Title {
    fn parse_title(&self) -> (f32, f32, String);
}

impl Title for String {
    fn parse_title(&self) -> (f32, f32, String) {
        let title = self.to_string();

        if self == "全一卷" {
            return (1.0, -1.0, title);
        }

        let re = Regex::new(
            r"^(单行本:)?(第?(?<volume>[\d零一二三四五六七八九十百千]+(\.\d)?)[卷部季]完?)?((第|连载|CH)?(?<chapter>[\d零一二三四五六七八九十百千]+([\.-]\d+)?)[話话回]?(-?[((]?(?<part>([前中后上下]|\d+))[))]?篇?)?(试看)?)?(\s.*|$)",
        )
        .unwrap();
        let Some(caps) = re.captures(self.as_str()) else {
            return (-1.0, -1.0, title);
        };

        let get_option_number = |name: &str| {
            caps.name(name).map(|m| m.as_str()).and_then(|str| {
                str.parse().map_or_else(
                    |_| str.to_number(ChineseCountMethod::TenThousand).ok(),
                    Some,
                )
            })
        };

        let volume = get_option_number("volume").unwrap_or(-1.0);

        let part = caps
            .name("part")
            .map(|m| match m.as_str() {
                "前" | "上" => "0",
                "中" => "25",
                "后" | "下" => "5",
                digit => digit,
            })
            .unwrap_or("0");
        let chapter = get_option_number("chapter")
            .and_then(|num| {
                format!("{}{}{}", num, if num % 1.0 == 0.0 { "." } else { "" }, part)
                    .parse()
                    .ok()
            })
            .unwrap_or(-1.0);

        (volume, chapter, title)
    }