Skip to content

Commit

Permalink
Merge pull request #749 from kagoromo/dev
Browse files Browse the repository at this point in the history
Chaika plugin adds more tags
  • Loading branch information
Difegue authored Feb 14, 2023
2 parents 0b4e94b + db23e95 commit ee003e3
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 49 deletions.
67 changes: 51 additions & 16 deletions lib/LANraragi/Plugin/Metadata/Chaika.pm
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ sub plugin_info {
type => "metadata",
namespace => "trabant",
author => "Difegue",
version => "2.2",
version => "2.3",
description => "Searches chaika.moe for tags matching your archive. This will try to use the thumbnail first, and fallback to a default text search.",
icon =>
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA\nB3RJTUUH4wYCFQocjU4r+QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUH\nAAAEZElEQVQ4y42T3WtTdxzGn/M7J+fk5SRpTk7TxMZkXU84tTbVNrUT3YxO7HA4pdtQZDe7cgx2\ns8vBRvEPsOwFYTDYGJUpbDI2wV04cGXCGFLonIu1L2ptmtrmxeb1JDkvv121ZKVze66f74eH7/f5\nMmjRwMCAwrt4/9KDpflMJpPHvyiR2DPcJklJ3TRDDa0xk36cvrm8vDwHAAwAqKrqjjwXecPG205w\nHBuqa9rk77/d/qJYLD7cCht5deQIIczbgiAEKLVAKXWUiqVV06Tf35q8dYVJJBJem2A7Kwi2nQzD\nZig1CG93+PO5/KN6tf5NKpVqbsBUVVVFUUxwHJc1TXNBoxojS7IbhrnLMMx9pVJlBqFQKBKPxwcB\nkJYgjKIo3QCE1nSKoghbfJuKRqN2RVXexMaQzWaLezyeEUEQDjscjk78PxFFUYRkMsltJgGA3t7e\nyMLCwie6rr8iCILVbDbvMgwzYRjGxe0o4XC4s1AoHPP5fMP5/NNOyzLKAO6Ew+HrDADBbre/Ryk9\nnzx81FXJNlEpVpF+OqtpWu2MpmnXWmH9/f2umZmZi4cOHXnLbILLzOchhz1YerJAs9m1GwRAg2GY\nh7GYah488BJYzYW+2BD61AFBlmX/1nSNRqN9//792ujoaIPVRMjOKHoie3DytVGmp2fXCAEAjuMm\nu7u7Umosho6gjL/u/QHeEgvJZHJ2K/D+/fuL4+PjXyvPd5ldkShy1UXcmb4DnjgQj/fd5gDA6/XS\nYCAwTwh9oT3QzrS1+VDVi+vd3Tsy26yQVoFF3dAXJVmK96p9EJ0iLNOwKKU3CQCk0+lSOpP5WLDz\nF9Q9kZqyO0SloOs6gMfbHSU5NLRiUOuax2/HyZPHEOsLw2SbP83eu/fLxrkNp9P554XxCzVa16MC\n7+BPnTk9cfmH74KJE8nmga7Xy5JkZ8VKifGIHpoBb1VX8hNTd3/t/7lQ3OeXfFPvf/jBRw8ezD/a\n7M/aWq91cGgnJaZ2VcgSdnV1XRNNd3vAoBVVYusmnEQS65hfgSG6c+zy3Kre7nF/KrukcMW0Zg8O\nD08DoJutDxxOEb5IPUymwrq8ft1gLKfkFojkkRxemERCAQUACPFWRazYLJcrFGwQhyufbQQ7rFpy\nLMkCwGZC34qPIuwp+XPOjBFwazQ/txrdFS2GGS/Xuj+pUKLGk1Kjvlded3s72lyGW+PLbGVcmrAA\ngN0wTk1NWYODg9XOKltGtpazi5GigzroUnHN5nUHG1ylRsG7rDXHmnEpu4CeEtEKkqNc6QqlLc/M\n8uT5lLH5eq0aGxsju1O7GQB498a5s/0x9dRALPaQEDZnYwnhWJtMCCNrjeb0UP34Z6e/PW22zjPP\n+vwXBwfPvbw38XnXjk7GsiwKAIQQhjAMMrlsam45d+zLH6/8o6vkWcBcrXbVKQhf6bpucCwLjmUB\nSmmhXC419eblrbD/TAgAkUjE987xE0c7ZDmk66ajUCnq+cL63fErl25s5/8baQPaWLhx6goAAAAA\nSUVORK5CYII=",
parameters => [ { type => "bool", desc => "Save archive title" } ],
parameters => [
{ type => "bool", desc => "Save archive title" },
{ type => "bool", desc => "Add the following tags if available: download URL, gallery ID, category, timestamp" },
{ type => "bool", desc => "Add tags without a namespace to the 'other:' namespace instead, mirroring E-H's behavior of namespacing everything" },
{ type => "string", desc => "Add a custom 'source:' tag to your archive. Example: chaika. Will NOT add a tag if blank" }
],
oneshot_arg => "Chaika Gallery or Archive URL (Will attach matching tags to your archive)"
);

Expand All @@ -34,7 +39,7 @@ sub get_tags {

shift;
my $lrr_info = shift; # Global info hash
my ($savetitle) = @_; # Plugin parameters
my ( $savetitle, $addextra, $addother, $addsource ) = @_; # Plugin parameters

my $logger = get_plugin_logger();
my $newtags = "";
Expand All @@ -43,25 +48,24 @@ sub get_tags {
# Parse the given link to see if we can extract type and ID
my $oneshotarg = $lrr_info->{oneshot_param};
if ( $oneshotarg =~ /https?:\/\/panda\.chaika\.moe\/(gallery|archive)\/([0-9]*)\/?.*/ ) {
( $newtags, $newtitle ) = tags_from_chaika_id( $1, $2 );
( $newtags, $newtitle ) = tags_from_chaika_id( $1, $2, $addextra, $addother, $addsource );
} else {

# Try SHA-1 reverse search first
$logger->info("Using thumbnail hash " . $lrr_info->{thumbnail_hash});
( $newtags, $newtitle ) = tags_from_sha1( $lrr_info->{thumbnail_hash} );
( $newtags, $newtitle ) = tags_from_sha1( $lrr_info->{thumbnail_hash}, $addextra, $addother, $addsource );

# Try text search if it fails
if ( $newtags eq "" ) {
$logger->info("No results, falling back to text search.");
( $newtags, $newtitle ) = search_for_archive( $lrr_info->{archive_title}, $lrr_info->{existing_tags} );
( $newtags, $newtitle ) = search_for_archive( $lrr_info->{archive_title}, $lrr_info->{existing_tags}, $addextra, $addother, $addsource );
}
}

if ( $newtags eq "" ) {
$logger->info("No matching Chaika Archive Found!");
return ( error => "No matching Chaika Archive Found!" );
} else {

$logger->info("Sending the following tags to LRR: $newtags");
#Return a hash containing the new metadata
if ( $savetitle && $newtags ne "" ) { return ( tags => $newtags, title => $newtitle ); }
Expand All @@ -79,8 +83,7 @@ sub get_tags {
sub search_for_archive {

my $logger = get_plugin_logger();
my $title = $_[0];
my $tags = $_[1];
my ( $title, $tags, $addextra, $addother, $addsource ) = @_;

#Auto-lowercase the title for better results
$title = lc($title);
Expand All @@ -103,33 +106,33 @@ sub search_for_archive {
my $textrep = $res->body;
$logger->debug("Chaika API returned this JSON: $textrep");

my ( $chaitags, $chaititle ) = parse_chaika_json( $res->json->{"galleries"}->[0] );
my ( $chaitags, $chaititle ) = parse_chaika_json( $res->json->{"galleries"}->[0], $addextra, $addother, $addsource );

return ( $chaitags, $chaititle );
}

# Uses the jsearch API to get the best json for a file.
sub tags_from_chaika_id {

my ( $type, $ID ) = @_;
my ( $type, $ID, $addextra, $addother, $addsource ) = @_;

my $json = get_json_from_chaika( $type, $ID );
return parse_chaika_json( $json );
return parse_chaika_json( $json, $addextra, $addother, $addsource );
}

# tags_from_sha1
# Uses chaika's SHA-1 search with the first page hash we have.
sub tags_from_sha1 {

my ( $sha1 ) = @_;
my ( $sha1, $addextra, $addother, $addsource ) = @_;

my $logger = get_plugin_logger();

# The jsearch API immediately returns a JSON.
# Said JSON is an array containing multiple archive objects.
# We just take the first one.
my $json_by_sha1 = get_json_from_chaika( 'sha1', $sha1 );
return parse_chaika_json( $json_by_sha1->[0] );
return parse_chaika_json( $json_by_sha1->[0], $addextra, $addother, $addsource );
}

# Calls chaika's API
Expand All @@ -154,15 +157,47 @@ sub get_json_from_chaika {
# Parses the JSON obtained from the Chaika API to get the tags.
sub parse_chaika_json {

my ( $json ) = @_;
my ( $json, $addextra, $addother, $addsource ) = @_;

my $tags = $json->{"tags"} || ();
foreach my $tag (@$tags) {
#Replace underscores with spaces
$tag =~ s/_/ /g;

#Add 'other' namespace if none
if ($addother && index($tag, ":") == -1) {
$tag = "other:" . $tag;
}
}

return ( join( ', ', @$tags ), $json->{"title"} );
my $category = lc $json->{"category"};
my $download = $json->{"download"} ? $json->{"download"} : $json->{"archives"}->[0]->{"link"};
my $gallery = $json->{"gallery"} ? $json->{"gallery"} : $json->{"id"};
my $timestamp = $json->{"posted"};
if ($tags && $addextra) {
if ($category ne "") {
push(@$tags, "category:" . $category);
}
if ($download ne "") {
push(@$tags, "download:" . $download);
}
if ($gallery ne "") {
push(@$tags, "gallery:" . $gallery);
}
if ($timestamp ne "") {
push(@$tags, "timestamp:" . $timestamp);
}
}

if ($gallery && $gallery ne "") {
# add custom source, but only if having found gallery
if ($addsource && $addsource ne "") {
push(@$tags, "source:" . $addsource);
}
return ( join( ', ', @$tags ), $json->{"title"} );
} else {
return "";
}
}

1;
42 changes: 39 additions & 3 deletions tests/LANraragi/Plugin/Metadata/Chaika.t
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ my $SAMPLES = "$cwd/tests/samples";
require "$cwd/tests/mocks.pl";

my @tags_list= (
'female:sole female', 'male:sole male', 'artist:kemuri haku', 'full censorship',
'male:shotacon', 'female:defloration', 'female:nakadashi', 'female:big breasts',
'language:translated', 'language:english'
'full censorship', 'female:sole female', 'male:sole male', 'artist:kemuri haku', 'female:tall girl',
'female:cunnilingus', 'male:shotacon', 'female:defloration', 'female:nakadashi', 'female:x-ray',
'female:big breasts', 'language:translated', 'language:english'
);
my @tags_list_extra= (
'other:full censorship', 'female:sole female', 'male:sole male', 'artist:kemuri haku', 'female:tall girl',
'female:cunnilingus', 'male:shotacon', 'female:defloration', 'female:nakadashi', 'female:x-ray',
'female:big breasts', 'language:translated', 'language:english', 'category:manga', 'download:/archive/27240/download/',
'gallery:23532', 'timestamp:1521357552', 'source:chaika'
);

use_ok('LANraragi::Plugin::Metadata::Chaika');
Expand Down Expand Up @@ -58,4 +64,34 @@ note ( 'testing retrieving tags by SHA1 ...' );
cmp_deeply( \@type_params, [ 'sha1' ], 'API call sequence');
}

note ( 'testing retrieving tags by SHA1 with additional tags ...' );

{
my $json_by_sha1 = decode_json( Mojo::File->new("$SAMPLES/chaika/002_sha1_response.json")->slurp );
my $json = decode_json( Mojo::File->new("$SAMPLES/chaika/001_gid_27240.json")->slurp );
my @type_params = ();

no warnings 'once', 'redefine';
local *LANraragi::Plugin::Metadata::Chaika::get_plugin_logger = sub { return get_logger_mock(); };
local *LANraragi::Plugin::Metadata::Chaika::get_json_from_chaika = sub {
my ( $type, $value ) = @_;
push( @type_params, $type );
return ( $type eq 'sha1' ) ? $json_by_sha1 : $json;
};

my $addextra = 1;
my $addother = 1;
my $addsource = 'chaika';
my ( $tags, $title ) = LANraragi::Plugin::Metadata::Chaika::tags_from_sha1(
"my-hash",
$addextra,
$addother,
$addsource
);

is($title, $json->{title}, 'gallery title');
cmp_bag( [ split( ', ', $tags ) ] , \@tags_list_extra, 'gallery tag list');
cmp_deeply( \@type_params, [ 'sha1' ], 'API call sequence');
}

done_testing();
11 changes: 7 additions & 4 deletions tests/samples/chaika/001_gid_27240.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,24 @@
"filesize": 63418139,
"fjord": true,
"gallery": 23532,
"posted": 1521353952,
"rating": 4.45,
"posted": 1521357552,
"rating": 4.49,
"tags": [
"full_censorship",
"female:sole_female",
"male:sole_male",
"artist:kemuri_haku",
"full_censorship",
"female:tall_girl",
"female:cunnilingus",
"male:shotacon",
"female:defloration",
"female:nakadashi",
"female:x-ray",
"female:big_breasts",
"language:translated",
"language:english"
],
"title": "[Kemuri Haku] Zettai Seikou Keikaku | Absolute Intercourse Plan (COMIC Shitsurakuten 2016-03) [English] [Redlantern]",
"title_jpn": "[煙ハク] 絶対セイコウ計画 (COMIC 失楽天 2016年3月号) [英訳]",
"uploader": "dankestdungeon"
}
}
58 changes: 32 additions & 26 deletions tests/samples/chaika/002_sha1_response.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
[{
"category": "Manga",
"download": "/archive/27240/download/",
"expunged": false,
"filecount": 19,
"filesize": 63418139,
"fjord": true,
"gallery": 23532,
"posted": 1521353952,
"rating": 4.45,
"tags": [
"female:sole_female",
"male:sole_male",
"artist:kemuri_haku",
"full_censorship",
"male:shotacon",
"female:defloration",
"female:nakadashi",
"female:big_breasts",
"language:translated",
"language:english"
],
"title": "[Kemuri Haku] Zettai Seikou Keikaku | Absolute Intercourse Plan (COMIC Shitsurakuten 2016-03) [English] [Redlantern]",
"title_jpn": "[煙ハク] 絶対セイコウ計画 (COMIC 失楽天 2016年3月号) [英訳]",
"uploader": "dankestdungeon"
}]
[
{
"category": "Manga",
"download": "/archive/27240/download/",
"expunged": false,
"filecount": 19,
"filesize": 63418139,
"fjord": true,
"gallery": 23532,
"id": 27240,
"posted": 1521357552,
"rating": 4.49,
"tags": [
"full_censorship",
"female:sole_female",
"male:sole_male",
"artist:kemuri_haku",
"female:tall_girl",
"female:cunnilingus",
"male:shotacon",
"female:defloration",
"female:nakadashi",
"female:x-ray",
"female:big_breasts",
"language:translated",
"language:english"
],
"title": "[Kemuri Haku] Zettai Seikou Keikaku | Absolute Intercourse Plan (COMIC Shitsurakuten 2016-03) [English] [Redlantern]",
"title_jpn": "[煙ハク] 絶対セイコウ計画 (COMIC 失楽天 2016年3月号) [英訳]",
"uploader": "dankestdungeon"
}
]

0 comments on commit ee003e3

Please sign in to comment.