Created
August 10, 2025 12:40
-
-
Save kuusei/f7cd57bb581337c02cb2c91932c12362 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package LANraragi::Plugin::Metadata::ExHentaiMangaManager; | |
| use strict; | |
| use warnings; | |
| use utf8; | |
| use v5.36; | |
| use URI::Escape; | |
| use Mojo::JSON qw(decode_json); | |
| use File::Basename qw(fileparse); | |
| use LANraragi::Utils::Logging qw(get_plugin_logger); | |
| use Encode qw(decode); | |
| use Encode::Guess; | |
| sub plugin_info { | |
| return ( | |
| name => "ExHentai Manga Manager 元数据获取", | |
| type => "metadata", | |
| namespace => "exhentai-manga-manager", | |
| author => "kuusei", | |
| version => "1.1", | |
| description => "通过自定义 API 使用文件名获取元数据,自动检测编码,并合并去重已有标签", | |
| parameters => [ | |
| { type => "string", desc => "API 基础 URL(不含 ?filter= 部分)" }, | |
| ], | |
| oneshot_arg => "文件名或过滤字符串", | |
| cooldown => 0, | |
| ); | |
| } | |
| sub decode_filename { | |
| my ($raw) = @_; | |
| my $decoder = Encode::Guess->guess($raw); | |
| if (ref($decoder)) { | |
| return $decoder->decode($raw); | |
| } else { | |
| eval { | |
| return decode('UTF-8', $raw, Encode::FB_CROAK); | |
| } or do { | |
| return $raw; | |
| }; | |
| } | |
| } | |
| sub get_tags { | |
| shift; | |
| my $lrr_info = shift; | |
| my ($base_api) = @_; | |
| my $logger = get_plugin_logger(); | |
| my $ua = $lrr_info->{user_agent}; | |
| my $raw_path = $lrr_info->{file_path} // ''; | |
| $logger->info("原始文件路径: $raw_path"); | |
| my $decoded_path = eval { decode_filename($raw_path) }; | |
| if ($@) { | |
| $logger->error("解码失败,使用原始路径: $@"); | |
| $decoded_path = $raw_path; | |
| } | |
| $logger->info("解码后文件路径: $decoded_path"); | |
| my ($filename, $filepath, $suffix) = fileparse($decoded_path, qr/\.[^.]*/); | |
| my $file = $filename . $suffix; | |
| $file =~ s{^/+}{}; | |
| $logger->info("用于API查询的文件名: '$file'"); | |
| my $url = $base_api // ''; | |
| $url =~ s/\/$//; | |
| $url .= "?filter=" . uri_escape_utf8($file) . "&length=1000000"; | |
| $logger->info("请求API的URL: $url"); | |
| my $res = $ua->max_redirects(5)->get($url)->result; | |
| if ($res->is_error) { | |
| $logger->error("API请求失败: " . $res->message); | |
| die "API请求失败: " . $res->message . "\n"; | |
| } | |
| my $json; | |
| eval { $json = decode_json($res->body); }; | |
| if ($@) { | |
| $logger->error("JSON解析失败: $@"); | |
| die "JSON解析失败\n"; | |
| } | |
| if (!exists $json->{data} || ref $json->{data} ne 'ARRAY' || !@{ $json->{data} }) { | |
| $logger->info("没有找到匹配的资源或数据格式无效"); | |
| die "No matching gallery found\n"; | |
| } | |
| my $first = $json->{data}[0]; | |
| my $tags_raw = $first->{tags} // ''; | |
| $tags_raw =~ s/^\s+|\s+$//g; | |
| if ($tags_raw =~ /\S/ && $tags_raw !~ /,/) { | |
| $tags_raw =~ s/\s+/, /g; | |
| } else { | |
| $tags_raw =~ s/\s*,\s*/, /g; | |
| } | |
| my @tags = grep { defined && $_ ne '' } map { s/^\s+|\s+$//g; $_ } split /,\s*/, $tags_raw; | |
| my $category = $first->{category} // ''; | |
| push @tags, "category:$category" if $category ne ''; | |
| if ($first->{url} && $first->{url} =~ m{https?://(.+)}) { | |
| push @tags, "source:" . $1; | |
| } | |
| my $existing_tags_str = $lrr_info->{existing_tags} // ''; | |
| $logger->debug("现有标签(原始): $existing_tags_str"); | |
| my @existing_tags = | |
| $existing_tags_str eq '' ? () : | |
| grep { defined && $_ ne '' } map { s/^\s+|\s+$//g; $_ } split /,\s*/, $existing_tags_str; | |
| my %seen; | |
| my @final_tags; | |
| for my $t (@existing_tags) { | |
| next unless defined $t && $t ne ''; | |
| push @final_tags, $t unless $seen{$t}++; | |
| } | |
| for my $t (@tags) { | |
| next unless defined $t && $t ne ''; | |
| push @final_tags, $t unless $seen{$t}++; | |
| } | |
| my $tags_final = join(", ", @final_tags); | |
| $logger->info("已有标签: " . ($existing_tags_str eq '' ? '(无)' : $existing_tags_str)); | |
| $logger->info("插件新增/合并后最终标签: $tags_final"); | |
| return ( | |
| tags => $tags_final, | |
| title => $first->{title} // '', | |
| source => $first->{url} // '' | |
| ); | |
| } | |
| 1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment