Skip to content

Commit 42e594f

Browse files
committed
feat(anime_detect): perform tag trimming on series titles
1 parent 44f6338 commit 42e594f

5 files changed

Lines changed: 76 additions & 15 deletions

File tree

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

anime_detect/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ license.workspace = true
88
tap = "1.0.1"
99
thiserror = "2.0.18"
1010
tracing = "0.1.44"
11+
winnow = { version = "0.7.14", features = ["simd"] }
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use winnow::{
2+
Parser, Result,
3+
ascii::Caseless,
4+
combinator::{alt, delimited, eof, opt, repeat, repeat_till},
5+
token::{any, take_until},
6+
};
7+
8+
const RESOLUTION_TAGS: [Caseless<&str>; 5] = [
9+
Caseless("480p"),
10+
Caseless("720p"),
11+
Caseless("1080p"),
12+
Caseless("2160p"),
13+
Caseless("4320p"),
14+
];
15+
16+
pub fn trim_name(mut name: &str) -> Result<String> {
17+
let many_tags = repeat(0.., tag).map(|()| ()).void();
18+
19+
let title_until_tag_or_end =
20+
repeat_till(1.., any, alt((tag, eof))).map(|(chars, _)| -> Vec<char> { chars });
21+
22+
(many_tags, title_until_tag_or_end)
23+
.parse_next(&mut name)
24+
.map(|(_, name)| name.into_iter().collect())
25+
}
26+
27+
fn tag<'a>(input: &mut &'a str) -> Result<&'a str> {
28+
(
29+
opt(whitespace),
30+
alt((brackets, parens, alt(RESOLUTION_TAGS))),
31+
opt(whitespace),
32+
)
33+
.map(|(_, tag, _)| tag)
34+
.parse_next(input)
35+
}
36+
37+
fn parens<'a>(input: &mut &'a str) -> Result<&'a str> {
38+
delimited('(', take_until(0.., ')'), ')').parse_next(input)
39+
}
40+
41+
fn brackets<'a>(input: &mut &'a str) -> Result<&'a str> {
42+
delimited('[', take_until(0.., ']'), ']').parse_next(input)
43+
}
44+
45+
fn whitespace(input: &mut &str) -> Result<()> {
46+
repeat(1.., alt((' ', '_', '.')))
47+
.map(|()| ())
48+
.parse_next(input)
49+
}
Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
mod combinator;
2+
13
use std::{
24
collections::HashMap,
35
path::{Path, PathBuf},
46
};
57

6-
use tap::TapOptional;
8+
use tap::TapFallible;
79

810
use crate::{Episode, EpisodeSet};
911

@@ -34,16 +36,16 @@ impl Series {
3436
.ok_or(ParseSeriesError::InvalidPath)
3537
.map(|name| name.to_string_lossy())
3638
.map(|name| {
37-
trim_name(&name)
38-
.tap_none(|| {
39+
combinator::trim_name(&name)
40+
.tap_err(|err| {
3941
tracing::warn!(
40-
"no series name could be determined for `{}`, \
41-
defaulting to full directory name",
42+
%err,
43+
"failed to parse series name at `{}`; \
44+
using full directory name",
4245
dir.display()
4346
);
4447
})
45-
.unwrap_or(&name)
46-
.to_string()
48+
.unwrap_or_else(|_| name.into_owned())
4749
})?;
4850

4951
let mut season_episodes = HashMap::new();
@@ -57,11 +59,6 @@ impl Series {
5759
}
5860
}
5961

60-
fn trim_name(name: &str) -> Option<&str> {
61-
// TODO
62-
Some(name)
63-
}
64-
6562
fn collect_episodes_in_dir(
6663
dir: &Path,
6764
season_episodes: &mut HashMap<u32, EpisodeSet>,

anup/src/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use tracing_subscriber::util::SubscriberInitExt;
2-
31
fn main() {
4-
tracing_subscriber::registry().init();
2+
tracing_subscriber::fmt().init();
53

64
let dir = std::env::args().nth(1).expect("no path provided");
75

0 commit comments

Comments
 (0)