From 01b2d368595a17bbf11f94465860703280ffb823 Mon Sep 17 00:00:00 2001
From: difegue
Date: Tue, 7 Dec 2021 21:12:52 +0100
Subject: [PATCH 10/42] Fix is_file_in_archive and matching plugins to work
with the new extraction logic
---
lib/LANraragi/Plugin/Metadata/Eze.pm | 5 ++-
lib/LANraragi/Plugin/Metadata/Hdoujin.pm | 37 ++++++++++---------
lib/LANraragi/Plugin/Metadata/Koromo.pm | 5 ++-
lib/LANraragi/Plugin/Metadata/RegexParse.pm | 3 +-
lib/LANraragi/Utils/Archive.pm | 29 ++++++++-------
.../plugin-docs/code-examples.md | 7 ++--
6 files changed, 47 insertions(+), 39 deletions(-)
diff --git a/lib/LANraragi/Plugin/Metadata/Eze.pm b/lib/LANraragi/Plugin/Metadata/Eze.pm
index e18822800..4eea946fd 100644
--- a/lib/LANraragi/Plugin/Metadata/Eze.pm
+++ b/lib/LANraragi/Plugin/Metadata/Eze.pm
@@ -40,10 +40,11 @@ sub get_tags {
my ($savetitle) = @_; # Plugin parameters
my $logger = get_plugin_logger();
- if ( is_file_in_archive( $lrr_info->{file_path}, "info.json" ) ) {
+ my $path_in_archive = is_file_in_archive( $lrr_info->{file_path}, "info.json" );
+ if ($path_in_archive) {
#Extract info.json
- my $filepath = extract_file_from_archive( $lrr_info->{file_path}, "info.json" );
+ my $filepath = extract_file_from_archive( $lrr_info->{file_path}, $path_in_archive );
#Open it
my $stringjson = "";
diff --git a/lib/LANraragi/Plugin/Metadata/Hdoujin.pm b/lib/LANraragi/Plugin/Metadata/Hdoujin.pm
index 5c888b305..4e46ed41a 100644
--- a/lib/LANraragi/Plugin/Metadata/Hdoujin.pm
+++ b/lib/LANraragi/Plugin/Metadata/Hdoujin.pm
@@ -39,10 +39,11 @@ sub get_tags {
my $logger = get_plugin_logger();
my $file = $lrr_info->{file_path};
- if ( is_file_in_archive( $file, "info.json" ) ) {
+ my $path_in_archive = is_file_in_archive( $file, "info.json" );
+ if ($path_in_archive) {
#Extract info.json
- my $filepath = extract_file_from_archive( $file, "info.json" );
+ my $filepath = extract_file_from_archive( $file, $path_in_archive );
#Open it
my $stringjson = "";
@@ -70,28 +71,30 @@ sub get_tags {
$logger->info("Sending the following tags to LRR: $tags");
return ( tags => $tags );
- } elsif ( is_file_in_archive( $file, "info.txt" ) ) {
+ } else {
+ $path_in_archive = is_file_in_archive( $file, "info.txt" );
+ if ($path_in_archive) {
- # Extract info.txt
- my $filepath = extract_file_from_archive( $file, "info.txt" );
+ # Extract info.txt
+ my $filepath = extract_file_from_archive( $file, $path_in_archive );
- # Open it
- open( my $fh, '<:encoding(UTF-8)', $filepath )
- or return ( error => "Could not open $filepath!" );
+ # Open it
+ open( my $fh, '<:encoding(UTF-8)', $filepath )
+ or return ( error => "Could not open $filepath!" );
- while ( my $line = <$fh> ) {
+ while ( my $line = <$fh> ) {
- # Check if the line starts with TAGS:
- if ( $line =~ m/TAGS: (.*)/ ) {
- return ( tags => $1 );
+ # Check if the line starts with TAGS:
+ if ( $line =~ m/TAGS: (.*)/ ) {
+ return ( tags => $1 );
+ }
}
- }
- return ( error => "No tags were found in info.txt!" );
+ return ( error => "No tags were found in info.txt!" );
- } else {
- return ( error => "No Hdoujin info.json or info.txt file found in this archive!" );
+ } else {
+ return ( error => "No Hdoujin info.json or info.txt file found in this archive!" );
+ }
}
-
}
#tags_from_Hdoujin_json(decodedjson)
diff --git a/lib/LANraragi/Plugin/Metadata/Koromo.pm b/lib/LANraragi/Plugin/Metadata/Koromo.pm
index 1923f5e4f..daa86afb6 100644
--- a/lib/LANraragi/Plugin/Metadata/Koromo.pm
+++ b/lib/LANraragi/Plugin/Metadata/Koromo.pm
@@ -39,10 +39,11 @@ sub get_tags {
my $logger = get_plugin_logger();
my $file = $lrr_info->{file_path};
- if ( is_file_in_archive( $file, "Info.json" ) ) {
+ my $path_in_archive = is_file_in_archive( $file, "Info.json" );
+ if ($path_in_archive) {
#Extract info.json
- my $filepath = extract_file_from_archive( $file, "Info.json" );
+ my $filepath = extract_file_from_archive( $file, $path_in_archive );
#Open it
my $stringjson = "";
diff --git a/lib/LANraragi/Plugin/Metadata/RegexParse.pm b/lib/LANraragi/Plugin/Metadata/RegexParse.pm
index 33abaec4c..fd9a4f0ed 100644
--- a/lib/LANraragi/Plugin/Metadata/RegexParse.pm
+++ b/lib/LANraragi/Plugin/Metadata/RegexParse.pm
@@ -14,7 +14,6 @@ use LANraragi::Model::Plugins;
use LANraragi::Utils::Database qw(redis_encode redis_decode);
use LANraragi::Utils::Logging qw(get_logger);
use LANraragi::Utils::Generic qw(remove_spaces);
-use LANraragi::Utils::Archive qw(is_file_in_archive extract_file_from_archive);
#Meta-information about your plugin.
sub plugin_info {
@@ -43,7 +42,7 @@ sub get_tags {
my ($savetitle) = @_; # Plugin parameters
my $logger = get_logger( "regexparse", "plugins" );
- my $file = $lrr_info->{file_path};
+ my $file = $lrr_info->{file_path};
# lrr_info's file_path is taken straight from the filesystem, which might not be proper UTF-8.
# Run a decode to make sure we can derive tags with the proper encoding.
diff --git a/lib/LANraragi/Utils/Archive.pm b/lib/LANraragi/Utils/Archive.pm
index 655ce815b..491a1fe59 100644
--- a/lib/LANraragi/Utils/Archive.pm
+++ b/lib/LANraragi/Utils/Archive.pm
@@ -140,7 +140,7 @@ sub extract_thumbnail {
make_path("$thumbdir/$subfolder");
my $redis = LANraragi::Model::Config->get_redis;
- my $file = $redis->hget( $id, "file" );
+ my $file = $redis->hget( $id, "file" );
my $temppath = get_temp . "/thumb/$id";
# Make sure the thumb temp dir exists
@@ -231,7 +231,7 @@ sub get_filelist {
# is_file_in_archive($archive, $file)
# Uses libarchive::peek to figure out if $archive contains $file.
-# Returns 1 if it does exist, 0 otherwise.
+# Returns the exact in-archive path of the file if it exists, undef otherwise.
sub is_file_in_archive {
my ( $archive, $wantedname ) = @_;
@@ -239,24 +239,27 @@ sub is_file_in_archive {
if ( is_pdf($archive) ) {
$logger->debug("$archive is a pdf, no sense looking for specific files");
- return 0;
+ return undef;
}
$logger->debug("Iterating files of archive $archive, looking for '$wantedname'");
$Data::Dumper::Useqq = 1;
- my $peek = Archive::Libarchive::Peek->new( filename => $archive );
- my $found = 0;
- $peek->iterate(
- sub {
- my $name = $_[0];
- $logger->debug( "Found file " . Dumper($name) );
+ my $peek = Archive::Libarchive::Peek->new( filename => $archive );
+ my $found;
+ my @files = $peek->files;
- if ( $name =~ /$wantedname$/ ) {
- $found = 1;
- }
+ for my $file (@files) {
+ $logger->debug( "Found file " . Dumper($file) );
+ my ( $name, $path, $suffix ) = fileparse( $file, qr/\.[^.]*/ );
+
+ # If the end of the file contains $wantedname we're good
+ if ( "$name$suffix" =~ /$wantedname$/ ) {
+ $logger->debug("OK!");
+ $found = $file;
+ last;
}
- );
+ }
return $found;
}
diff --git a/tools/Documentation/plugin-docs/code-examples.md b/tools/Documentation/plugin-docs/code-examples.md
index d9c2262ad..32579911a 100644
--- a/tools/Documentation/plugin-docs/code-examples.md
+++ b/tools/Documentation/plugin-docs/code-examples.md
@@ -63,11 +63,12 @@ If you're running 0.5.2 or later:
```perl
use LANraragi::Utils::Archive qw(is_file_in_archive extract_file_from_archive);
-#Check if info.json is in the archive located at $file
-if (is_file_in_archive($file,"info.json")) {
+# Check if info.json is in the archive located at $file and get its precise path
+my $info_path = is_file_in_archive($file, "info.json");
+if ($info_path) {
#Extract info.json
- my $filepath = extract_file_from_archive($file, "info.json");
+ my $filepath = extract_file_from_archive($file, $info_path);
#Do whatever you need with the extracted file
open( my $fh, '<:encoding(UTF-8)', $filepath )
From 756517d80aab18ed241a3d30ef513bb4e1054d4a Mon Sep 17 00:00:00 2001
From: difegue
Date: Tue, 7 Dec 2021 21:13:11 +0100
Subject: [PATCH 11/42] Small modern theme fix on metadata edit
---
public/themes/modern.css | 2 --
1 file changed, 2 deletions(-)
diff --git a/public/themes/modern.css b/public/themes/modern.css
index b8dce202c..bb68254c2 100644
--- a/public/themes/modern.css
+++ b/public/themes/modern.css
@@ -257,8 +257,6 @@ tr.gtr1 {
height: 21px;
margin: 4px 1px 0;
padding: 2px 7px;
- max-width: 450px;
- width: 80%;
border-radius: 3px;
}
From 4d40291466d61313deaf2d91a6711bb23e1f725b Mon Sep 17 00:00:00 2001
From: difegue
Date: Tue, 7 Dec 2021 21:14:21 +0100
Subject: [PATCH 12/42] (#559) Add a default robots.txt file
---
public/robots.txt | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 public/robots.txt
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 000000000..77470cb39
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
\ No newline at end of file
From 322266088ed42310dff159f93fd0c619df7359b5 Mon Sep 17 00:00:00 2001
From: difegue
Date: Wed, 8 Dec 2021 14:22:27 +0100
Subject: [PATCH 13/42] Fix pbp violation
---
lib/LANraragi/Utils/Archive.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/LANraragi/Utils/Archive.pm b/lib/LANraragi/Utils/Archive.pm
index 491a1fe59..3f948d551 100644
--- a/lib/LANraragi/Utils/Archive.pm
+++ b/lib/LANraragi/Utils/Archive.pm
@@ -239,7 +239,7 @@ sub is_file_in_archive {
if ( is_pdf($archive) ) {
$logger->debug("$archive is a pdf, no sense looking for specific files");
- return undef;
+ return;
}
$logger->debug("Iterating files of archive $archive, looking for '$wantedname'");
From 74095f364be5e7175a027a36a0b5f4d2a5ddba96 Mon Sep 17 00:00:00 2001
From: difegue
Date: Mon, 13 Dec 2021 17:34:44 +0100
Subject: [PATCH 14/42] Add installation steps for windows LTSC users I was too
lazy to write those but someone on 4chan did it so credits to 'em
---
.../installing-lanraragi/methods.md | 3 ++-
.../installing-lanraragi/windows.md | 22 +++++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/tools/Documentation/installing-lanraragi/methods.md b/tools/Documentation/installing-lanraragi/methods.md
index 2e24d72af..4942e9508 100644
--- a/tools/Documentation/installing-lanraragi/methods.md
+++ b/tools/Documentation/installing-lanraragi/methods.md
@@ -24,7 +24,8 @@ Look at the methods below for something that fits your OS and usage.
{% hint style="warning" %}
This method works on **64-bit** editions of Windows 10 only.
-Since LRR 0.8.0, you need Windows 10 version _1903_ at least. 0.7.9 will work with version _1809_ if you're on an LTSC channel.
+Since LRR 0.8.0, you need Windows 10 version _1903_ at least. 0.7.9 will work with version _1809_ if you're on an LTSC channel.
+If you still want to use further server versions on 1809, a step-by-step workaround is available on the Windows documentation page below.
{% endhint %}

diff --git a/tools/Documentation/installing-lanraragi/windows.md b/tools/Documentation/installing-lanraragi/windows.md
index 46f414726..b3775e5a8 100644
--- a/tools/Documentation/installing-lanraragi/windows.md
+++ b/tools/Documentation/installing-lanraragi/windows.md
@@ -39,6 +39,28 @@ Once the install completes properly, you'll be able to launch the GUI from the s

+## Installation on Windows 10 1809 (LTSC)
+
+Recent MSI packages don't install on 1809 anymore due to underlying changes to make the installer lighter, but you can still sideload the latest server version on top of an old 0.7.9 install.
+
+{% hint style="warning" %}
+This method shouldn't break in the foreseeable future, but as the Win32 bootstrapper will still be the 0.7.9 version, you might lose out on future functionalities later on.
+You might want to consider switching to a [source install](./source.md) on top of a Debian WSL distro you'd maintain yourself.
+{% endhint %}
+
+1. Install 0.7.9 like normal, this is mostly done to get the Win32 UI application installed on to your taskbar, we'll install the updated Linux image next.
+2. If you started the service and the Windows application, make sure to close BOTH.
+3. Download the [MSI installer for the latest version](https://github.com/Difegue/LANraragi/releases/latest)
+4. Open the MSI file in 7zip, and extract the "package.tar" file, which is the underlying Linux image
+5. Download [LxRunOffline](https://github.com/DDoSolitary/LxRunOffline/releases) and put it in the same directory as the "package.tar" file you just extracted
+6. Uninstall the old Linux image from 0.7.9 with the following command, make sure to have your command window opened as administrator:
+ `lxrunoffline ui -n lanraragi`
+7. install the new image:
+ `lxrunoffline i -n lanraragi -d "C:\Users\*your user name*\AppData\Roaming\LANraragi\Distro\rootfs" -f LANraragi.tar`
+Note: the name of the install HAS to be "lanraragi", do not change this on the -n argument
+8. Start the application again, and you should see that it now shows the newest version of the server
+
+
## Configuration
Starting the GUI for the first time will prompt you to setup your content folder and the port you want the server to listen on. The main GUI is always available from your Taskbar.
From f1281f76153e4a62124f3a953065d0e41f2b2176 Mon Sep 17 00:00:00 2001
From: difegue
Date: Mon, 13 Dec 2021 17:50:24 +0100
Subject: [PATCH 15/42] (#563) Add warning text to the F! plugin description
Being able to slap HTML in plugin desc text is convenient but likely to slap me in the face one day
---
lib/LANraragi/Plugin/Metadata/Fakku.pm | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/lib/LANraragi/Plugin/Metadata/Fakku.pm b/lib/LANraragi/Plugin/Metadata/Fakku.pm
index aa290a58e..0ed1440cb 100644
--- a/lib/LANraragi/Plugin/Metadata/Fakku.pm
+++ b/lib/LANraragi/Plugin/Metadata/Fakku.pm
@@ -27,7 +27,8 @@ sub plugin_info {
author => "Difegue, Nodja",
version => "0.8",
description =>
- "Searches FAKKU for tags matching your archive. If you have an account, don't forget to enter the matching cookie in the login plugin to be able to access controversial content.",
+ "Searches FAKKU for tags matching your archive. If you have an account, don't forget to enter the matching cookie in the login plugin to be able to access controversial content.
+ This plugin can and will return invalid results depending on what you're searching for! The FAKKU search API isn't very precise and I recommend you use the Chaika.moe plugin when possible.",
icon =>
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAACZSURBVDhPlY+xDYQwDEWvZgRGYA22Y4frqJDSZhFugiuuo4cqPGT0iTjAYL3C+fGzktc3hEcsQvJq6HtjE2Jdv4viH4a4pWnL8q4A6g+ET9P8YhS2/kqwIZXWnwqChDxPfCFfD76wOzJ2IOR/0DSwnuRKYAKUW3gq2OsJTYM0jr7QVRVwlabJEaw3ARYBcmFXeomxphIeEMIMmh3lOLQR+QQAAAAASUVORK5CYII=",
parameters => [ { type => "bool", desc => "Save archive title" } ],
@@ -113,13 +114,13 @@ sub get_search_result_dom {
my $logger = get_plugin_logger();
- # Strip away (some) characters that break search
- # Note: The F! search backend sometimes fails to match you anyway. :/ The autosuggest API would work better but then again, CF issues
- # * Changed the ' filter to '\w*, meaning instead of just stripping the apostrophe, we also strip whatever is after it ("we're" > "we" instead of "we're" > "were").
- # This is because just removing the apostrophe will return wrong (or no) results (to give an example "Were in love" would not return anything, whereas "we in love" would)
- # * Added @ to the filters, because it's not supported by F*'s search engine either
- # * Added a space ahead of the - (hyphen) filter, to only remove hyphens directly prepended to something else (those are the only ones that break searches, probably because the search engine treats them as exclusions as most engines would).
- $title =~ s/ -|'\w*|~|!|@//g;
+# Strip away (some) characters that break search
+# Note: The F! search backend sometimes fails to match you anyway. :/ The autosuggest API would work better but then again, CF issues
+# * Changed the ' filter to '\w*, meaning instead of just stripping the apostrophe, we also strip whatever is after it ("we're" > "we" instead of "we're" > "were").
+# This is because just removing the apostrophe will return wrong (or no) results (to give an example "Were in love" would not return anything, whereas "we in love" would)
+# * Added @ to the filters, because it's not supported by F*'s search engine either
+# * Added a space ahead of the - (hyphen) filter, to only remove hyphens directly prepended to something else (those are the only ones that break searches, probably because the search engine treats them as exclusions as most engines would).
+ $title =~ s/ -|'\w*|~|!|@//g;
# Visit the base host once to set cloudflare cookies and jank
$ua->max_redirects(5)->get($fakku_host);
From 030a4c09d3aa125cb0b6c9d25eeba938025b9e33 Mon Sep 17 00:00:00 2001
From: difegue
Date: Wed, 15 Dec 2021 18:14:59 +0100
Subject: [PATCH 16/42] Update koromo plugin so it can also accept those weird
fakku torrent files, as the format is similar enough
+ rework tests for eze
---
lib/LANraragi/Plugin/Metadata/Eze.pm | 19 +++----
lib/LANraragi/Plugin/Metadata/Koromo.pm | 66 ++++++++++++------------
tests/LANraragi/Plugin/Metadata/Eze.t | 49 ++++++++++++++++++
tests/LANraragi/Plugin/Metadata/Koromo.t | 46 +++++++++++++++++
tests/mocks.pl | 16 ------
tests/plugins.t | 47 +++++------------
tests/samples/koromo/koromo_sample.json | 41 +++++++++++++++
7 files changed, 193 insertions(+), 91 deletions(-)
create mode 100644 tests/LANraragi/Plugin/Metadata/Eze.t
create mode 100644 tests/LANraragi/Plugin/Metadata/Koromo.t
create mode 100644 tests/samples/koromo/koromo_sample.json
diff --git a/lib/LANraragi/Plugin/Metadata/Eze.pm b/lib/LANraragi/Plugin/Metadata/Eze.pm
index 4eea946fd..bb78c373d 100644
--- a/lib/LANraragi/Plugin/Metadata/Eze.pm
+++ b/lib/LANraragi/Plugin/Metadata/Eze.pm
@@ -19,12 +19,13 @@ sub plugin_info {
return (
#Standard metadata
- name => "eze",
- type => "metadata",
- namespace => "ezeplugin",
- author => "Difegue",
- version => "2.2",
- description => "Collects metadata embedded into your archives by the eze userscript. (info.json files)",
+ name => "eze",
+ type => "metadata",
+ namespace => "ezeplugin",
+ author => "Difegue",
+ version => "2.2",
+ description =>
+ "Collects metadata embedded into your archives as eze-style info.json files. ({'gallery_info': {xxx} } syntax)",
icon =>
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA\nB3RJTUUH4wYCFDYBnHlU6AAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUH\nAAAETUlEQVQ4y22UTWhTWRTHf/d9JHmNJLFpShMcKoRIqxXE4sKpjgthYLCLggU/wI1CUWRUxlmU\nWblw20WZMlJc1yKKKCjCdDdYuqgRiygq2mL8aJpmQot5uabv3XdnUftG0bu593AOv3M45/yvGBgY\n4OrVqwRBgG3bGIaBbduhDSClxPM8tNZMTEwwMTGB53lYloXWmkgkwqdPnygUCljZbJbW1lYqlQqG\nYYRBjuNw9+5dHj16RD6fJ51O09bWxt69e5mammJ5eZm1tTXi8Tiu6xKNRrlx4wZWNBqlXq8Tj8cx\nTRMhBJZlMT4+zuXLlxFCEIvFqFarBEFAKpXCcRzq9TrpdJparcbIyAiHDh1icXERyzAMhBB4nofv\n+5imiWmavHr1inQ6jeM4ZLNZDMMglUqxuLiIlBLXdfn48SNKKXp6eqhUKiQSCaxkMsna2hqe52Hb\nNsMdec3n8+Pn2+vpETt37qSlpYVyucz8/DzT09Ns3bqVYrEIgOM4RCIRrI1MiUQCz/P43vE8jxcv\nXqCUwvM8Zmdn2bJlC6lUitHRUdrb2zFNE9/3sd6/f4/jOLiuSzKZDCH1wV/EzMwM3d3dNN69o729\nnXK5jFKKPXv2sLS0RF9fHydOnMD3fZRSaK0xtNYEQYBpmtTr9RC4b98+LMsCwLZtHj9+TCwWI5/P\nI6Xk5MmTXLhwAaUUG3MA4M6dOzQaDd68eYOUkqHIZj0U2ay11mzfvp1du3YhhGBgYIDjx4/T3d1N\nvV4nCAKklCilcF2XZrOJlBIBcOnSJc6ePYsQgj9yBf1l//7OJcXPH1Y1wK/Ff8SfvT995R9d/SA8\nzyMaja5Xq7Xm1q1bLCwssLS09M1Atm3bFr67urq+8W8oRUqJlBJLCMHNmze5d+8e2Ww2DPyrsSxq\ntRqZTAattZibm6PZbHJFVoUQgtOxtAbwfR8A13WJxWIYANVqFd/36e/v/ypzIpEgCAKEEMzNzYXN\n34CN/FsSvu+jtSaTyeC67jrw4cOHdHZ2kslkQmCz2SQSiYT269evMU0zhF2RVaH1ejt932dlZYXh\n4eF14MLCArZtI6UMAb+1/qBPx9L6jNOmAY4dO/b/agBnnDb9e1un3vhQzp8/z/Xr19eBQgjevn3L\n1NTUd5WilKJQKGAYxje+lpYWrl27xuTk5PqKARSLRfr6+hgaGiKbzfLy5UvGx8dRSqGUwnEcDMNA\nKYUQIlRGNBplZmaGw4cPE4/HOXDgAMbs7Cy9vb1cvHiR+fl5Hjx4QC6XwzAMYrEYz549Y3p6mufP\nn4d6NU0Tx3GYnJzk6NGjNJtNduzYQUdHB+LL8mu1Gv39/WitGRsb4/79+3R1dbF7925yuVw4/Uaj\nwalTpzhy5AhjY2P4vs/BgwdJp9OYG7ByuUwmk6FUKgFw7tw5SqUSlUqFp0+fkkgk2LRpEysrKzx5\n8oTBwUG01ty+fZv9+/eTz+dZXV3lP31rAEu+yXjEAAAAAElFTkSuQmCC",
parameters => [ { type => "bool", desc => "Save archive title" } ]
@@ -36,8 +37,8 @@ sub plugin_info {
sub get_tags {
shift;
- my $lrr_info = shift; # Global info hash
- my ($savetitle) = @_; # Plugin parameters
+ my $lrr_info = shift; # Global info hash
+ my ($save_title) = @_; # Plugin parameters
my $logger = get_plugin_logger();
my $path_in_archive = is_file_in_archive( $lrr_info->{file_path}, "info.json" );
@@ -71,7 +72,7 @@ sub get_tags {
#Return tags
$logger->info("Sending the following tags to LRR: $tags");
- if ($savetitle) {
+ if ( $save_title && $title ) {
$logger->info("Parsed title is $title");
return ( tags => $tags, title => $title );
} else {
diff --git a/lib/LANraragi/Plugin/Metadata/Koromo.pm b/lib/LANraragi/Plugin/Metadata/Koromo.pm
index daa86afb6..a46c369f8 100644
--- a/lib/LANraragi/Plugin/Metadata/Koromo.pm
+++ b/lib/LANraragi/Plugin/Metadata/Koromo.pm
@@ -20,12 +20,12 @@ sub plugin_info {
name => "koromo",
type => "metadata",
namespace => "koromoplugin",
- author => "CirnoT",
- version => "1.1",
- description => "Collects metadata embedded into your archives by the Koromo Copy downloader. (Info.json files)",
+ author => "CirnoT, Difegue",
+ version => "2.0",
+ description => "Collects metadata embedded into your archives as Koromo-style Info.json files. ( {'Tags': [xxx] } syntax)",
icon =>
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw1AUhU9TpVoqDmYQcchQnSyIijhKFYtgobQVWnUweekfNDEkKS6OgmvBwZ/FqoOLs64OroIg+APi4uqk6CIl3pcUWsR44fE+zrvn8N59gNCoMs3qGgc03TbTibiUy69IoVeE0QsRAYgys4xkZiEL3/q6pz6quxjP8u/7s/rUgsWAgEQ8ywzTJl4nnt60Dc77xCIryyrxOfGYSRckfuS64vEb55LLAs8UzWx6jlgklkodrHQwK5sa8RRxVNV0yhdyHquctzhr1Rpr3ZO/MFLQlzNcpzWMBBaRRAoSFNRQQRU2YrTrpFhI03ncxz/k+lPkUshVASPHPDagQXb94H/we7ZWcXLCS4rEge4Xx/kYAUK7QLPuON/HjtM8AYLPwJXe9m80gJlP0uttLXoE9G8DF9dtTdkDLneAwSdDNmVXCtISikXg/Yy+KQ8M3ALhVW9urXOcPgBZmtXSDXBwCIyWKHvN5909nXP7t6c1vx8dzXKFeWpUawAAAAZiS0dEAOwAEABqpSa6lwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+MKCRQBJSKMeg0AAAGVSURBVDjLpZMxa9tQFIXPeaiyhxiZzKFjBme1JFfYgYAe9Bd0yA8JIaQhkJLBP6T/wh3qpZYzm2I8dyilJJMTW7yTIVGRFasE8uAt93K+d+5991IS8Ybj1SVIer24ty8Jk2wyl5S/GkDSi+O4s9PaOYOQh91wSHK2DeLViVut1pmkTwAQtAPUQcz/xCRBEpKOg3ZwEnbDDklvK6AQ+77fds4tSJbBcM7Nm83GbhXiVcXj8fiHpO/WWgfgHAAkXYxGoy8k/UG/nzxDnsqRxF7cO0iS5AhAQxKLm6bpVZqmn8sxAI3kQ2KjKDqQ9GRFEqDNfpQcukrMkDRF3ADAJJvM1+v1n0G/n5D0AcBaew3gFMCFtfbyuVT/cHCYrFarX1mWLQCgsAWSXtgNO81mY/ed7380xpyUn3XOXefr/Ntyufw9vZn+LL7zn21J+fRmOru/f/hrjNmThFLOGWPeV8UvBklSTnIWdsNh0A4g6RiAI/n17vZuWBVvncQNSBAYEK5OvNGDbSMdRdE+AJdl2aJumfjWdX4EIwDvDt7UjSEAAAAASUVORK5CYII=",
- parameters => []
+ parameters => [ { type => "bool", desc => "Save archive title" } ]
);
}
@@ -34,7 +34,8 @@ sub plugin_info {
sub get_tags {
shift;
- my $lrr_info = shift; # Global info hash
+ my $lrr_info = shift; # Global info hash
+ my ($save_title) = @_; # Plugin parameter
my $logger = get_plugin_logger();
my $file = $lrr_info->{file_path};
@@ -62,14 +63,19 @@ sub get_tags {
$logger->debug("Found and loaded the following JSON: $stringjson");
#Parse it
- my $tags = tags_from_koromo_json($hashjson);
+ my ( $tags, $title ) = tags_from_koromo_json($hashjson);
#Delete it
unlink $filepath;
#Return tags
$logger->info("Sending the following tags to LRR: $tags");
- return ( tags => $tags );
+ if ( $save_title && $title ) {
+ $logger->info("Parsed title is $title");
+ return ( tags => $tags, title => $title );
+ } else {
+ return ( tags => $tags );
+ }
} else {
@@ -79,59 +85,53 @@ sub get_tags {
}
#tags_from_koromo_json(decodedjson)
-#Goes through the JSON hash obtained from an Info.json file and return the contained tags.
+#Goes through the JSON hash obtained from an Info.json file and return the contained tags (and title if found).
sub tags_from_koromo_json {
- my $hash = $_[0];
- my $return = "";
+ my $hash = $_[0];
+ my @found_tags;
+ my $title = $hash->{"Title"};
my $tags = $hash->{"Tags"};
my $characters = $hash->{"Characters"};
my $series = $hash->{"Series"};
+ my $parody = $hash->{"Parody"};
my $groups = $hash->{"Groups"};
+ my $artist = $hash->{"Artist"};
my $artists = $hash->{"Artists"};
+ my $language = $hash->{"Language"};
my $type = $hash->{"Types"};
+ my $url = $hash->{"URL"};
foreach my $tag (@$tags) {
-
- $return .= ", " unless $return eq "";
- $return .= $tag;
-
+ push( @found_tags, $tag );
}
foreach my $tag (@$characters) {
-
- $return .= ", " unless $return eq "";
- $return .= "character:" . $tag;
-
+ push( @found_tags, "character:" . $tag );
}
foreach my $tag (@$series) {
-
- $return .= ", " unless $return eq "";
- $return .= "series:" . $tag;
-
+ push( @found_tags, "series:" . $tag );
}
foreach my $tag (@$groups) {
-
- $return .= ", " unless $return eq "";
- $return .= "group:" . $tag;
-
+ push( @found_tags, "group:" . $tag );
}
foreach my $tag (@$artists) {
-
- $return .= ", " unless $return eq "";
- $return .= "artist:" . $tag;
-
+ push( @found_tags, "artist:" . $tag );
}
- $return .= ", " unless $return eq "";
- $return .= ( "category:" . $type ) unless !$type;
+ push( @found_tags, "series:" . $parody ) unless !$parody;
+ push( @found_tags, "artist:" . $artist ) unless !$artist;
+ push( @found_tags, "language:" . $language ) unless !$language;
+ push( @found_tags, "category:" . $type ) unless !$type;
+ push( @found_tags, "source:" . $url ) unless !$url;
#Done-o
- return $return;
+ my $concat_tags = join( ", ", @found_tags );
+ return ( $concat_tags, $title );
}
diff --git a/tests/LANraragi/Plugin/Metadata/Eze.t b/tests/LANraragi/Plugin/Metadata/Eze.t
new file mode 100644
index 000000000..32566d10a
--- /dev/null
+++ b/tests/LANraragi/Plugin/Metadata/Eze.t
@@ -0,0 +1,49 @@
+# LANraragi::Plugin::Metadata::Eze
+use strict;
+use warnings;
+use utf8;
+use Data::Dumper;
+use File::Temp qw(tempfile);
+use File::Copy "cp";
+
+use Cwd qw( getcwd );
+
+use Test::Trap;
+use Test::More;
+use Test::Deep;
+
+my $cwd = getcwd();
+my $SAMPLES = "$cwd/tests/samples";
+require "$cwd/tests/mocks.pl";
+
+use_ok('LANraragi::Plugin::Metadata::Eze');
+
+note("eze Tests");
+{
+ # Copy the eze sample json to a temporary directory as it's deleted once parsed
+ my ( $fh, $filename ) = tempfile();
+ cp( $SAMPLES . "/eze/eze_sample.json", $fh );
+
+ # Mock LANraragi::Utils::Archive's subs to return the temporary sample JSON
+ # Since we're using exports, the methods are under the plugin's namespace.
+ no warnings 'once', 'redefine';
+ local *LANraragi::Plugin::Metadata::Eze::get_plugin_logger = sub { return get_logger_mock(); };
+ local *LANraragi::Plugin::Metadata::Eze::extract_file_from_archive = sub { $filename };
+ local *LANraragi::Plugin::Metadata::Eze::is_file_in_archive = sub { 1 };
+
+ my %dummyhash = ( something => 22, file_path => "test" );
+
+ # Since this is calling the sub directly and not in an object context,
+ # we pass a dummy string as first parameter to replace the object.
+ my %ezetags = trap { LANraragi::Plugin::Metadata::Eze::get_tags( "", \%dummyhash, 1 ); };
+
+ my $ezetags =
+ "artist:mitarashi kousei, character:akiko minase, character:yuuichi aizawa, female:aunt, female:lingerie, female:sole female, group:mitarashi club, language:english, language:translated, male:sole male, misc:multi-work series, parody:kanon, source: website.org/g/1179590/7c5815c77b";
+ is( $ezetags{title},
+ "(C72) [Mitarashi Club (Mitarashi Kousei)] Akiko-san to Issho (Kanon) [English] [Belldandy100] [Decensored]",
+ "eze parsing test 1/2"
+ );
+ is( $ezetags{tags}, $ezetags, "eze parsing test 2/2" );
+}
+
+done_testing();
diff --git a/tests/LANraragi/Plugin/Metadata/Koromo.t b/tests/LANraragi/Plugin/Metadata/Koromo.t
new file mode 100644
index 000000000..ca0774c8b
--- /dev/null
+++ b/tests/LANraragi/Plugin/Metadata/Koromo.t
@@ -0,0 +1,46 @@
+# LANraragi::Plugin::Metadata::Koromo
+use strict;
+use warnings;
+use utf8;
+use Data::Dumper;
+use File::Temp qw(tempfile);
+use File::Copy "cp";
+
+use Cwd qw( getcwd );
+
+use Test::Trap;
+use Test::More;
+use Test::Deep;
+
+my $cwd = getcwd();
+my $SAMPLES = "$cwd/tests/samples";
+require "$cwd/tests/mocks.pl";
+
+use_ok('LANraragi::Plugin::Metadata::Koromo');
+
+note("Koromo Tests");
+{
+ # Copy the koromo sample json to a temporary directory as it's deleted once parsed
+ my ( $fh, $filename ) = tempfile();
+ cp( $SAMPLES . "/koromo/koromo_sample.json", $fh );
+
+ # Mock LANraragi::Utils::Archive's subs to return the temporary sample JSON
+ # Since we're using exports, the methods are under the plugin's namespace.
+ no warnings 'once', 'redefine';
+ local *LANraragi::Plugin::Metadata::Koromo::get_plugin_logger = sub { return get_logger_mock(); };
+ local *LANraragi::Plugin::Metadata::Koromo::extract_file_from_archive = sub { $filename };
+ local *LANraragi::Plugin::Metadata::Koromo::is_file_in_archive = sub { 1 };
+
+ my %dummyhash = ( something => 22, file_path => "test" );
+
+ # Since this is calling the sub directly and not in an object context,
+ # we pass a dummy string as first parameter to replace the object.
+ my %ko_tags = trap { LANraragi::Plugin::Metadata::Koromo::get_tags( "", \%dummyhash, 1 ); };
+
+ my $expected_tags =
+ "Teacher, Schoolgirl Outfit, Cheating, Hentai, Ahegao, Creampie, Uncensored, Condom, Unlimited, Heart Pupils, Love Hotel, series:Original Work, artist:β² Chimaki, language:English, source:https://www.fakku.net/hentai/after-school-english_1632947200";
+ is( $ko_tags{title}, "After School", "Koromo parsing test 1/2" );
+ is( $ko_tags{tags}, $expected_tags, "Koromo parsing test 2/2" );
+}
+
+done_testing();
diff --git a/tests/mocks.pl b/tests/mocks.pl
index 992964247..1e656fc0c 100644
--- a/tests/mocks.pl
+++ b/tests/mocks.pl
@@ -2,27 +2,11 @@
use warnings;
use utf8;
use Cwd;
-use File::Temp qw(tempfile);
-use File::Copy "cp";
use Data::Dumper;
use Test::MockObject;
use Mojo::JSON qw (decode_json);
-sub setup_eze_mock {
-
- # Copy the eze sample json to a temporary directory as it's deleted once parsed
- my $cwd = getcwd;
- my ( $fh, $filename ) = tempfile();
- cp( $cwd . "/tests/samples/eze/eze_sample.json", $fh );
-
- # Mock LANraragi::Utils::Archive's subs to return the temporary sample JSON
- # Since we're using exports, the methods are under the plugin's namespace.
- no warnings 'once', 'redefine';
- *LANraragi::Plugin::Metadata::Eze::extract_file_from_archive = sub { $filename };
- *LANraragi::Plugin::Metadata::Eze::is_file_in_archive = sub { 1 };
-}
-
sub setup_redis_mock {
# DataModel for searches
diff --git a/tests/plugins.t b/tests/plugins.t
index baeb04ba3..6e5f7c99f 100644
--- a/tests/plugins.t
+++ b/tests/plugins.t
@@ -25,27 +25,7 @@ my $cwd = getcwd;
require $cwd . "/tests/mocks.pl";
setup_redis_mock();
-# Mock Utils::Archive
-setup_eze_mock();
-
-note ( "eze Tests" );
-
-{
- my %dummyhash = ( something => 22, file_path => "test" );
-
- # Since this is calling the sub directly and not in an object context, we pass a dummy string as first parameter to replace the object.
- my %ezetags = trap { LANraragi::Plugin::Metadata::Eze::get_tags( "", \%dummyhash, 1 ); };
-
- my $ezetags =
- "artist:mitarashi kousei, character:akiko minase, character:yuuichi aizawa, female:aunt, female:lingerie, female:sole female, group:mitarashi club, language:english, language:translated, male:sole male, misc:multi-work series, parody:kanon, source: website.org/g/1179590/7c5815c77b";
- is( $ezetags{title},
- "(C72) [Mitarashi Club (Mitarashi Kousei)] Akiko-san to Issho (Kanon) [English] [Belldandy100] [Decensored]",
- "eze parsing test 1/2"
- );
- is( $ezetags{tags}, $ezetags, "eze parsing test 2/2" );
-}
-
-note ( "E-Hentai Tests" );
+note("E-Hentai Tests");
{
my $ua = trap { LANraragi::Plugin::Login::EHentai::do_login( "", "", "" ); };
@@ -54,7 +34,7 @@ note ( "E-Hentai Tests" );
my $eH_gToken = "0439fa3666";
my ( $test_eH_gID, $test_eH_gToken ) =
- trap { LANraragi::Plugin::Metadata::EHentai::lookup_gallery( "TOUHOU GUNMANIA", "", "", $ua, $domain, "", 0, 0 ); };
+ trap { LANraragi::Plugin::Metadata::EHentai::lookup_gallery( "TOUHOU GUNMANIA", "", "", $ua, $domain, "", 0, 0 ); };
is( $test_eH_gID, $eH_gID, 'eHentai search test 1/2' );
is( $test_eH_gToken, $eH_gToken, 'eHentai search test 2/2' );
@@ -63,42 +43,43 @@ note ( "E-Hentai Tests" );
ok( exists $test_eH_json->{gmetadata}, 'gmetadata exists' );
isa_ok( $test_eH_json->{gmetadata}, 'ARRAY', 'type of gmetadata' );
- ok( length ( $test_eH_json->{gmetadata}[0]{title} ) > 0, "eHentai title test 1" );
+ ok( length( $test_eH_json->{gmetadata}[0]{title} ) > 0, "eHentai title test 1" );
isa_ok( $test_eH_json->{gmetadata}[0]{tags}, 'ARRAY', 'type of tags' );
}
-note ( "nHentai Tests" );
+note("nHentai Tests");
{
- my $nH_gID = "52249";
+ my $nH_gID = "52249";
my $test_nH_gID = trap { LANraragi::Plugin::Metadata::nHentai::get_gallery_id_from_title("\"Pieces 1\" shirow"); };
is( $test_nH_gID, $nH_gID, 'nHentai search test' );
- my %nH_hashdata = trap { LANraragi::Plugin::Metadata::nHentai::get_tags_from_NH($nH_gID, 1) };
+ my %nH_hashdata = trap { LANraragi::Plugin::Metadata::nHentai::get_tags_from_NH( $nH_gID, 1 ) };
- ok( length $nH_hashdata{tags} > 0, 'nHentai API Tag retrieval test' );
+ ok( length $nH_hashdata{tags} > 0, 'nHentai API Tag retrieval test' );
ok( length $nH_hashdata{title} > 0, 'nHentai title test' );
}
-note ( "Chaika Tests" );
+note("Chaika Tests");
{
my ( $tags_jsearch, $title_jsearch ) =
- trap { LANraragi::Plugin::Metadata::Chaika::search_for_archive( "Zettai Seikou Keikaku", "artist:kemuri haku" ); };
- ok( length $tags_jsearch > 0, 'chaika.moe search test' );
+ trap { LANraragi::Plugin::Metadata::Chaika::search_for_archive( "Zettai Seikou Keikaku", "artist:kemuri haku" ); };
+ ok( length $tags_jsearch > 0, 'chaika.moe search test' );
ok( length $title_jsearch > 0, 'chaika.moe title test' );
my ( $tags_by_id, $title_by_id ) = trap { LANraragi::Plugin::Metadata::Chaika::tags_from_chaika_id( "archive", "27240" ); };
ok( length $tags_by_id > 0, 'chaika.moe API Tag retrieval test' );
ok( length $title_by_id > 0, 'chaika.moe ID title test ' );
- my ( $tags_by_sha1, $title_by_sha1 ) = trap { LANraragi::Plugin::Metadata::Chaika::tags_from_sha1("276601a0e5dae9427940ed17ac470c9945b47073"); };
+ my ( $tags_by_sha1, $title_by_sha1 ) =
+ trap { LANraragi::Plugin::Metadata::Chaika::tags_from_sha1("276601a0e5dae9427940ed17ac470c9945b47073"); };
ok( length $tags_jsearch > 0, 'chaika.moe SHA-1 reverse search test' );
- ok( length $title_by_id > 0, 'chaika.moe SHA-1 title test' );
+ ok( length $title_by_id > 0, 'chaika.moe SHA-1 title test' );
}
-note ( "FAKKU Tests : Disabled due to cloudflare being used on FAKKU" );
+note("FAKKU Tests : Disabled due to cloudflare being used on FAKKU");
# {
# my $f_title = "Kairakuten Cover Girl's Episode 009: Hamao";
diff --git a/tests/samples/koromo/koromo_sample.json b/tests/samples/koromo/koromo_sample.json
new file mode 100644
index 000000000..1c6a2764f
--- /dev/null
+++ b/tests/samples/koromo/koromo_sample.json
@@ -0,0 +1,41 @@
+{
+ "Artist": "β² Chimaki",
+ "Description": "Naughty things feel so good! β€",
+ "Favorites": 713,
+ "Language": "English",
+ "Magazine": "Comic Bavel 2021-11",
+ "Pages": 20,
+ "Parody": "Original Work",
+ "Publisher": "FAKKU",
+ "Related": [
+ "https://www.fakku.net/hentai/after-school-encounter-english",
+ "https://www.fakku.net/hentai/after-school-thrills-english",
+ "https://www.fakku.net/hentai/after-school-goddess-2-english",
+ "https://www.fakku.net/hentai/mark-of-the-saint-5-english",
+ "https://www.fakku.net/hentai/after-school-with-a-pushover-gal-english",
+ "https://www.fakku.net/hentai/killing-time-after-school-english",
+ "https://www.fakku.net/hentai/after-school-revenge-time-english",
+ "https://www.fakku.net/hentai/after-school-service-time-english",
+ "https://www.fakku.net/hentai/after-school-temptation-english-1485463915",
+ "https://www.fakku.net/hentai/after-school-activities-english",
+ "https://www.fakku.net/hentai/after-school-humiliation-english",
+ "https://www.fakku.net/hentai/after-school-disclosure-english"
+ ],
+ "Tags": [
+ "Teacher",
+ "Schoolgirl Outfit",
+ "Cheating",
+ "Hentai",
+ "Ahegao",
+ "Creampie",
+ "Uncensored",
+ "Condom",
+ "Unlimited",
+ "Heart Pupils",
+ "Love Hotel"
+ ],
+ "Thumb": "https://t.fakku.net/images/manga/a/after-school-english_1632947200_1632947200/thumbs/001.thumb.jpg",
+ "Title": "After School",
+ "URL": "https://www.fakku.net/hentai/after-school-english_1632947200",
+ "Released": "2021-10-12 16:00:03 UTC"
+}
\ No newline at end of file
From ce28aa07927d43bbcac5a23bb11c7a5f9252c665 Mon Sep 17 00:00:00 2001
From: difegue
Date: Tue, 21 Dec 2021 23:37:32 +0100
Subject: [PATCH 17/42] (#517) Add no_fallback to the thumbnail API
---
lib/LANraragi/Controller/Api/Archive.pm | 6 +--
lib/LANraragi/Model/Archive.pm | 21 +++++++-
.../api-documentation/archive-api.md | 16 +++++-
.../miscellaneous-other-api.md | 52 +++----------------
4 files changed, 43 insertions(+), 52 deletions(-)
diff --git a/lib/LANraragi/Controller/Api/Archive.pm b/lib/LANraragi/Controller/Api/Archive.pm
index 2aaba5da8..3ed22e144 100644
--- a/lib/LANraragi/Controller/Api/Archive.pm
+++ b/lib/LANraragi/Controller/Api/Archive.pm
@@ -88,15 +88,15 @@ sub get_categories {
sub serve_thumbnail {
my $self = shift;
- my $id = check_id_parameter( $self, "thumbnail" ) || return;
- LANraragi::Model::Archive::serve_thumbnail( $self, $id );
+ my $id = check_id_parameter( $self, "serve_thumbnail" ) || return;
+ LANraragi::Model::Archive::serve_thumbnail( $self, $id, $no_fallback );
}
# Use RenderFile to get the file of the provided id to the client.
sub serve_file {
my $self = shift;
- my $id = check_id_parameter( $self, "servefile" ) || return;
+ my $id = check_id_parameter( $self, "serve_file" ) || return;
my $redis = $self->LRR_CONF->get_redis();
my $file = $redis->hget( $id, "file" );
diff --git a/lib/LANraragi/Model/Archive.pm b/lib/LANraragi/Model/Archive.pm
index 81205735f..073d14015 100644
--- a/lib/LANraragi/Model/Archive.pm
+++ b/lib/LANraragi/Model/Archive.pm
@@ -142,6 +142,7 @@ sub find_untagged_archives {
sub serve_thumbnail {
my ( $self, $id ) = @_;
+ my $no_fallback = $self->req->param('no_fallback') eq "true" || "0";
my $thumbdir = LANraragi::Model::Config->get_thumbdir;
# Thumbnails are stored in the content directory, thumb subfolder.
@@ -151,9 +152,25 @@ sub serve_thumbnail {
# Queue a minion job to generate the thumbnail. Thumbnail jobs have the lowest priority.
unless ( -e $thumbname ) {
- $self->minion->enqueue( thumbnail_task => [ $thumbdir, $id ] => { priority => 0 } );
- $self->render_file( filepath => "./public/img/noThumb.png" );
+ my $job_id = $self->minion->enqueue( thumbnail_task => [ $thumbdir, $id ] => { priority => 0 } );
+
+ if ($no_fallback) {
+
+ $self->render(
+ json => {
+ operation => "serve_thumbnail",
+ success => 1,
+ job => $job_id
+ },
+ status => 202 # 202 Accepted
+ );
+ } else {
+
+ # If the thumbnail doesn't exist, serve the default thumbnail.
+ $self->render_file( filepath => "./public/img/noThumb.png" );
+ }
return;
+
} else {
# Simply serve the thumbnail.
diff --git a/tools/Documentation/api-documentation/archive-api.md b/tools/Documentation/api-documentation/archive-api.md
index 5614abaf2..062464153 100644
--- a/tools/Documentation/api-documentation/archive-api.md
+++ b/tools/Documentation/api-documentation/archive-api.md
@@ -149,12 +149,26 @@ ID of the Archive to process.
{% swagger baseUrl="http://lrr.tvc-16.science" path="/api/archives/:id/thumbnail" method="get" summary="Get Archive Thumbnail" %}
{% swagger-description %}
-Get the Thumbnail image for a given Archive.
+Get the Thumbnail image for a given Archive. This endpoint will queue generation of the thumbnail in the background if it doesn't already exist, and return a placeholder image.
+If you want to get the background job ID instead of the placeholder, you can use the `no_fallback` query parameter.
{% endswagger-description %}
{% swagger-parameter name="id" type="string" required="true" in="path" %}
ID of the Archive to process.
{% endswagger-parameter %}
+{% swagger-parameter name="no_fallback" type="boolean" required="false" in="query" %}
+Disables the placeholder image and returns a JSON if the thumbnail is queued for extraction. This parameter does nothing if the image already exists.
+{% endswagger-parameter %}
+
+{% swagger-response status="202" description="The thumbnail is queued for extraction. Use `/api/minion/:jobid` to track when your thumbnail is ready." %}
+```javascript
+{
+ "operation": "______",
+ "error": "No archive ID specified.",
+ "success": 0
+}
+```
+{% endswagger-response %}
{% swagger-response status="200" description="" %}
{% tabs %}
diff --git a/tools/Documentation/api-documentation/miscellaneous-other-api.md b/tools/Documentation/api-documentation/miscellaneous-other-api.md
index 8da02322f..53582a27a 100644
--- a/tools/Documentation/api-documentation/miscellaneous-other-api.md
+++ b/tools/Documentation/api-documentation/miscellaneous-other-api.md
@@ -222,28 +222,8 @@ Get a list of the available plugins on the server, filtered by type.
{% endswagger-description %}
{% swagger-parameter name="type" type="string" required="true" in="path" %}
-Type of plugins you want to list.
-
-\
-
-
-You can either use
-
-`login`
-
-,
-
-`metadata`
-
-,
-
-`script`
-
-, or
-
-`all`
-
- to get all previous types at once.
+Type of plugins you want to list.
+You can either use `login`, `metadata`, `script`, or `all` to get all previous types at once.
{% endswagger-parameter %}
{% swagger-response status="200" description="" %}
@@ -348,20 +328,8 @@ You can either use
{% swagger baseUrl="http://lrr.tvc-16.science" path="/api/plugins/use" method="post" summary="πUse a Plugin" %}
{% swagger-description %}
-Uses a Plugin and returns the result.
-
-\
-
-
-If using a metadata plugin, the matching archive will
-
-**not**
-
- be modified in the database.
-
-\
-
-
+Uses a Plugin and returns the result.
+If using a metadata plugin, the matching archive will **not** be modified in the database.
See more info on Plugins in the matching section of the Docs.
{% endswagger-description %}
@@ -397,11 +365,7 @@ Optional One-Shot argument to use when executing this Plugin.
{% swagger baseUrl="http://lrr.tvc-16.science" path="/api/plugins/queue" method="post" summary="πUse a Plugin Asynchronously" %}
{% swagger-description %}
-Uses a Plugin and returns a Minion Job ID matching the Plugin run.
-
-\
-
-
+Uses a Plugin and returns a Minion Job ID matching the Plugin run.
This endpoint is useful if you want to run longer-lived plugins which might timeout if ran with the standard endpoint.
{% endswagger-description %}
@@ -496,11 +460,7 @@ Whether to generate all thumbnails, or only the missing ones.
{% swagger baseUrl="http://lrr.tvc-16.science" path="/api/minion/:jobid" method="get" summary="πGet the status of a Minion Job" %}
{% swagger-description %}
-Get the status of a Minion Job. Minions jobs are ran for various occasions like thumbnails, cache warmup and handling incoming files.
-
-\
-
-
+Get the status of a Minion Job. Minions jobs are ran for various occasions like thumbnails, cache warmup and handling incoming files.
Usually stuff you don't need to care about as a client, but the API is there for internal usage mostly.
{% endswagger-description %}
From 2fe180c6668127181b82988e1445e6a1f7a68cc6 Mon Sep 17 00:00:00 2001
From: difegue
Date: Wed, 22 Dec 2021 14:48:46 +0100
Subject: [PATCH 18/42] Add default value for isnew
---
lib/LANraragi/Controller/Api/Archive.pm | 2 +-
lib/LANraragi/Utils/Database.pm | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/LANraragi/Controller/Api/Archive.pm b/lib/LANraragi/Controller/Api/Archive.pm
index 3ed22e144..3cf3ce249 100644
--- a/lib/LANraragi/Controller/Api/Archive.pm
+++ b/lib/LANraragi/Controller/Api/Archive.pm
@@ -89,7 +89,7 @@ sub get_categories {
sub serve_thumbnail {
my $self = shift;
my $id = check_id_parameter( $self, "serve_thumbnail" ) || return;
- LANraragi::Model::Archive::serve_thumbnail( $self, $id, $no_fallback );
+ LANraragi::Model::Archive::serve_thumbnail( $self, $id );
}
# Use RenderFile to get the file of the provided id to the client.
diff --git a/lib/LANraragi/Utils/Database.pm b/lib/LANraragi/Utils/Database.pm
index 889b81c94..da20c8061 100644
--- a/lib/LANraragi/Utils/Database.pm
+++ b/lib/LANraragi/Utils/Database.pm
@@ -128,7 +128,7 @@ sub build_json {
arcid => $id,
title => $title,
tags => $tags,
- isnew => $isnew,
+ isnew => $isnew ? $isnew : "false",
extension => lc( ( split( /\./, $file ) )[-1] ),
progress => $progress ? int($progress) : 0,
pagecount => $pagecount ? int($pagecount) : 0
From ff9ffb80d3a8ec111c210587873c5ff00d20c3d7 Mon Sep 17 00:00:00 2001
From: difegue
Date: Wed, 22 Dec 2021 16:16:05 +0100
Subject: [PATCH 19/42] (#567) Hiding the carousel now sets a pref so it
doesn't re-open on reloads
+ the matching API endpoints won't be called if the carousel is closed
---
public/js/index.js | 105 +++++++++++++++++++++-------------
public/js/index_datatables.js | 2 -
templates/index.html.tt2 | 7 ++-
3 files changed, 69 insertions(+), 45 deletions(-)
diff --git a/public/js/index.js b/public/js/index.js
index c01f5b9c5..4bb66a90c 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -5,6 +5,7 @@
const Index = {};
Index.selectedCategory = "";
Index.awesomplete = {};
+Index.carouselInitialized = false;
Index.swiper = {};
Index.serverVersion = "";
Index.debugMode = false;
@@ -23,40 +24,10 @@ Index.initializeAll = function () {
$(document).on("change.thumbnail-crop", "#thumbnail-crop", Index.toggleCrop);
$(document).on("change.namespace-sortby", "#namespace-sortby", Index.handleCustomSort);
$(document).on("click.order-sortby", "#order-sortby", Index.toggleOrder);
+ $(document).on("click.open_carousel", ".collapsible-title", Index.toggleCarousel);
$(document).on("click.reload-carousel", "#reload-carousel", Index.updateCarousel);
$(document).on("click.close_overlay", "#overlay-shade", LRR.closeOverlay);
- // hack: force-open the collapsible
- $(".collapsible-title").click();
- Index.swiper = new Swiper(".index-carousel-container", {
- slidesPerView: "auto",
- spaceBetween: 8,
- navigation: {
- nextEl: ".carousel-next",
- prevEl: ".carousel-prev",
- },
- mousewheel: true,
- freeMode: true,
- });
-
- // Initialize carousel mode menu
- $.contextMenu({
- selector: "#carousel-mode-menu",
- trigger: "left",
- build: () => ({
- callback(key) {
- localStorage.carouselType = key;
- Index.updateCarousel();
- },
- items: {
- random: { name: "Randomly Picked", icon: "fas fa-random" },
- inbox: { name: "New Archives", icon: "fas fa-envelope-open-text" },
- untagged: { name: "Untagged Archives", icon: "fas fa-edit" },
- // ondeck: { name: "On Deck", icon: "fas fa-book-reader" },
- },
- }),
- });
-
// 0 = List view
// 1 = Thumbnail view
// List view is at 0 but became the non-default state later so here's some legacy weirdness
@@ -80,6 +51,36 @@ Index.initializeAll = function () {
localStorage.carouselType = "random";
}
+ // Default to opened carousel
+ if (localStorage.getItem("carouselOpen") === null) {
+ localStorage.carouselOpen = 1;
+ }
+
+ // Force-open the collapsible if carouselOpen = true
+ if (localStorage.carouselOpen === "1") {
+ localStorage.carouselOpen = "0"; // Bad hack since clicking collapsible-title will trigger toggleCarousel and modify this
+ $(".collapsible-title").click();
+ }
+ Index.updateCarousel();
+
+ // Initialize carousel mode menu
+ $.contextMenu({
+ selector: "#carousel-mode-menu",
+ trigger: "left",
+ build: () => ({
+ callback(key) {
+ localStorage.carouselType = key;
+ Index.updateCarousel();
+ },
+ items: {
+ random: { name: "Randomly Picked", icon: "fas fa-random" },
+ inbox: { name: "New Archives", icon: "fas fa-envelope-open-text" },
+ untagged: { name: "Untagged Archives", icon: "fas fa-edit" },
+ // ondeck: { name: "On Deck", icon: "fas fa-book-reader" },
+ },
+ }),
+ });
+
// Tell user about the context menu
if (localStorage.getItem("sawContextMenuToast") === null) {
localStorage.sawContextMenuToast = true;
@@ -130,6 +131,28 @@ Index.toggleMode = function () {
IndexTable.dataTable.draw();
};
+Index.toggleCarousel = function () {
+ localStorage.carouselOpen = (localStorage.carouselOpen === "1") ? "0" : "1";
+
+ if (!Index.carouselInitialized) {
+ Index.carouselInitialized = true;
+ $("#reload-carousel").show();
+
+ Index.swiper = new Swiper(".index-carousel-container", {
+ slidesPerView: "auto",
+ spaceBetween: 8,
+ navigation: {
+ nextEl: ".carousel-next",
+ prevEl: ".carousel-prev",
+ },
+ mousewheel: true,
+ freeMode: true,
+ });
+
+ Index.updateCarousel();
+ }
+};
+
Index.toggleCrop = function () {
localStorage.cropthumbs = $("#thumbnail-crop")[0].checked;
IndexTable.dataTable.draw();
@@ -274,16 +297,18 @@ Index.updateCarousel = function (e) {
break;
}
- Server.callAPI(endpoint,
- "GET", null, "Error getting carousel data!",
- (results) => {
- results.data.forEach((archive) => {
- carousel.append(LRR.buildThumbnailDiv(archive));
- });
+ if (Index.carouselInitialized) {
+ Server.callAPI(endpoint,
+ "GET", null, "Error getting carousel data!",
+ (results) => {
+ results.data.forEach((archive) => {
+ carousel.append(LRR.buildThumbnailDiv(archive));
+ });
- Index.swiper.update();
- $("#carousel-loading").hide();
- });
+ Index.swiper.update();
+ $("#carousel-loading").hide();
+ });
+ }
};
/**
diff --git a/public/js/index_datatables.js b/public/js/index_datatables.js
index 848a52238..921c71be3 100644
--- a/public/js/index_datatables.js
+++ b/public/js/index_datatables.js
@@ -106,8 +106,6 @@ IndexTable.doSearch = function (page) {
// Re-load categories so the most recently selected/created ones appear first
Index.loadCategories();
-
- Index.updateCarousel();
};
// #region Compact View
diff --git a/templates/index.html.tt2 b/templates/index.html.tt2
index 9a299867e..a06473b2c 100644
--- a/templates/index.html.tt2
+++ b/templates/index.html.tt2
@@ -85,11 +85,12 @@
-
...
+
...
-
+
From 32cc991e8c5bae3bbd57d163278048c50159ae9f Mon Sep 17 00:00:00 2001
From: difegue
Date: Wed, 22 Dec 2021 16:37:02 +0100
Subject: [PATCH 20/42] Add option to use file modified time for the builtin
date_added feature
This fully deprecates the DateAdded plugin.
---
lib/LANraragi/Controller/Config.pm | 72 ++++++++++---------
lib/LANraragi/Model/Archive.pm | 1 -
lib/LANraragi/Model/Config.pm | 30 ++++----
lib/LANraragi/Plugin/Metadata/DateAdded.pm | 62 ----------------
lib/LANraragi/Utils/Database.pm | 16 ++++-
templates/config.html.tt2 | 21 ++++--
.../templates_config/config_tags.html.tt2 | 31 ++++++++
tests/modules.t | 57 ++++++++-------
.../advanced-usage/external-readers.md | 2 +-
9 files changed, 143 insertions(+), 149 deletions(-)
delete mode 100644 lib/LANraragi/Plugin/Metadata/DateAdded.pm
diff --git a/lib/LANraragi/Controller/Config.pm b/lib/LANraragi/Controller/Config.pm
index 5fab376d3..c4c430ae0 100644
--- a/lib/LANraragi/Controller/Config.pm
+++ b/lib/LANraragi/Controller/Config.pm
@@ -15,33 +15,35 @@ sub index {
my $self = shift;
$self->render(
- template => "config",
- version => $self->LRR_VERSION,
- vername => $self->LRR_VERNAME,
- descstr => $self->LRR_DESC,
- motd => $self->LRR_CONF->get_motd,
- dirname => $self->LRR_CONF->get_userdir,
- thumbdir => $self->LRR_CONF->get_thumbdir,
- forceddirname => ( defined $ENV{LRR_DATA_DIRECTORY} ? 1 : 0 ),
- forcedthumbdir => ( defined $ENV{LRR_THUMB_DIRECTORY} ? 1 : 0 ),
- pagesize => $self->LRR_CONF->get_pagesize,
- enablepass => $self->LRR_CONF->enable_pass,
- password => $self->LRR_CONF->get_password,
- tagruleson => $self->LRR_CONF->enable_tagrules,
- tagrules => restore_CRLF( $self->LRR_CONF->get_tagrules ),
- title => $self->LRR_CONF->get_htmltitle,
- tempmaxsize => $self->LRR_CONF->get_tempmaxsize,
- localprogress => $self->LRR_CONF->enable_localprogress,
- devmode => $self->LRR_CONF->enable_devmode,
- nofunmode => $self->LRR_CONF->enable_nofun,
- apikey => $self->LRR_CONF->get_apikey,
- enablecors => $self->LRR_CONF->enable_cors,
- enableresize => $self->LRR_CONF->enable_resize,
- sizethreshold => $self->LRR_CONF->get_threshold,
- readerquality => $self->LRR_CONF->get_readquality,
- theme => $self->LRR_CONF->get_style,
- csshead => generate_themes_header($self),
- tempsize => get_tempsize
+ template => "config",
+ version => $self->LRR_VERSION,
+ vername => $self->LRR_VERNAME,
+ descstr => $self->LRR_DESC,
+ motd => $self->LRR_CONF->get_motd,
+ dirname => $self->LRR_CONF->get_userdir,
+ thumbdir => $self->LRR_CONF->get_thumbdir,
+ forceddirname => ( defined $ENV{LRR_DATA_DIRECTORY} ? 1 : 0 ),
+ forcedthumbdir => ( defined $ENV{LRR_THUMB_DIRECTORY} ? 1 : 0 ),
+ pagesize => $self->LRR_CONF->get_pagesize,
+ enablepass => $self->LRR_CONF->enable_pass,
+ password => $self->LRR_CONF->get_password,
+ tagruleson => $self->LRR_CONF->enable_tagrules,
+ tagrules => restore_CRLF( $self->LRR_CONF->get_tagrules ),
+ title => $self->LRR_CONF->get_htmltitle,
+ tempmaxsize => $self->LRR_CONF->get_tempmaxsize,
+ localprogress => $self->LRR_CONF->enable_localprogress,
+ devmode => $self->LRR_CONF->enable_devmode,
+ nofunmode => $self->LRR_CONF->enable_nofun,
+ apikey => $self->LRR_CONF->get_apikey,
+ enablecors => $self->LRR_CONF->enable_cors,
+ enableresize => $self->LRR_CONF->enable_resize,
+ sizethreshold => $self->LRR_CONF->get_threshold,
+ readerquality => $self->LRR_CONF->get_readquality,
+ theme => $self->LRR_CONF->get_style,
+ usedateadded => $self->LRR_CONF->enable_dateadded,
+ usedatemodified => $self->LRR_CONF->use_lastmodified,
+ csshead => generate_themes_header($self),
+ tempsize => get_tempsize
);
}
@@ -69,13 +71,15 @@ sub save_config {
# For checkboxes,
# we check if the parameter exists in the POST to return either 1 or 0.
- enablepass => ( scalar $self->req->param('enablepass') ? '1' : '0' ),
- enablecors => ( scalar $self->req->param('enablecors') ? '1' : '0' ),
- localprogress => ( scalar $self->req->param('localprogress') ? '1' : '0' ),
- devmode => ( scalar $self->req->param('devmode') ? '1' : '0' ),
- enableresize => ( scalar $self->req->param('enableresize') ? '1' : '0' ),
- tagruleson => ( scalar $self->req->param('tagruleson') ? '1' : '0' ),
- nofunmode => ( scalar $self->req->param('nofunmode') ? '1' : '0' )
+ enablepass => ( scalar $self->req->param('enablepass') ? '1' : '0' ),
+ enablecors => ( scalar $self->req->param('enablecors') ? '1' : '0' ),
+ localprogress => ( scalar $self->req->param('localprogress') ? '1' : '0' ),
+ devmode => ( scalar $self->req->param('devmode') ? '1' : '0' ),
+ enableresize => ( scalar $self->req->param('enableresize') ? '1' : '0' ),
+ tagruleson => ( scalar $self->req->param('tagruleson') ? '1' : '0' ),
+ nofunmode => ( scalar $self->req->param('nofunmode') ? '1' : '0' ),
+ usedateadded => ( scalar $self->req->param('usedateadded') ? '1' : '0' ),
+ usedatemodified => ( scalar $self->req->param('usedatemodified') ? '1' : '0' )
);
# Only add newpassword field as password if enablepass = 1
diff --git a/lib/LANraragi/Model/Archive.pm b/lib/LANraragi/Model/Archive.pm
index 073d14015..fd8bebca4 100644
--- a/lib/LANraragi/Model/Archive.pm
+++ b/lib/LANraragi/Model/Archive.pm
@@ -124,7 +124,6 @@ sub find_untagged_archives {
remove_newlines($t);
# The following are basic and therefore don't count as "tagged"
- # date_added added for convenience as running the matching plugin doesn't really count as tagging
$nondefaulttags += 1 unless $t =~ /(artist|parody|series|language|event|group|date_added):.*/;
}
diff --git a/lib/LANraragi/Model/Config.pm b/lib/LANraragi/Model/Config.pm
index 162b7d152..8ef364d01 100644
--- a/lib/LANraragi/Model/Config.pm
+++ b/lib/LANraragi/Model/Config.pm
@@ -131,19 +131,21 @@ sub get_tagrules {
);
}
-sub get_htmltitle { return &get_redis_conf( "htmltitle", "LANraragi" ) }
-sub get_motd { return &get_redis_conf( "motd", "Welcome to this Library running LANraragi!" ) }
-sub get_tempmaxsize { return &get_redis_conf( "tempmaxsize", "500" ) }
-sub get_pagesize { return &get_redis_conf( "pagesize", "100" ) }
-sub enable_pass { return &get_redis_conf( "enablepass", "1" ) }
-sub enable_nofun { return &get_redis_conf( "nofunmode", "0" ) }
-sub enable_cors { return &get_redis_conf( "enablecors", "0" ) }
-sub get_apikey { return &get_redis_conf( "apikey", "" ) }
-sub enable_localprogress { return &get_redis_conf( "localprogress", "0" ) }
-sub enable_tagrules { return &get_redis_conf( "tagruleson", "1" ) }
-sub enable_resize { return &get_redis_conf( "enableresize", "0" ) }
-sub get_threshold { return &get_redis_conf( "sizethreshold", "1000" ) }
-sub get_readquality { return &get_redis_conf( "readerquality", "50" ) }
-sub get_style { return &get_redis_conf( "theme", "modern.css" ) }
+sub get_htmltitle { return &get_redis_conf( "htmltitle", "LANraragi" ) }
+sub get_motd { return &get_redis_conf( "motd", "Welcome to this Library running LANraragi!" ) }
+sub get_tempmaxsize { return &get_redis_conf( "tempmaxsize", "500" ) }
+sub get_pagesize { return &get_redis_conf( "pagesize", "100" ) }
+sub enable_pass { return &get_redis_conf( "enablepass", "1" ) }
+sub enable_nofun { return &get_redis_conf( "nofunmode", "0" ) }
+sub enable_cors { return &get_redis_conf( "enablecors", "0" ) }
+sub get_apikey { return &get_redis_conf( "apikey", "" ) }
+sub enable_localprogress { return &get_redis_conf( "localprogress", "0" ) }
+sub enable_tagrules { return &get_redis_conf( "tagruleson", "1" ) }
+sub enable_resize { return &get_redis_conf( "enableresize", "0" ) }
+sub get_threshold { return &get_redis_conf( "sizethreshold", "1000" ) }
+sub get_readquality { return &get_redis_conf( "readerquality", "50" ) }
+sub get_style { return &get_redis_conf( "theme", "modern.css" ) }
+sub enable_dateadded { return &get_redis_conf( "usedateadded", "1" ) }
+sub use_lastmodified { return &get_redis_conf( "usedatemodified", "0" ) }
1;
diff --git a/lib/LANraragi/Plugin/Metadata/DateAdded.pm b/lib/LANraragi/Plugin/Metadata/DateAdded.pm
deleted file mode 100644
index 2f4a88a41..000000000
--- a/lib/LANraragi/Plugin/Metadata/DateAdded.pm
+++ /dev/null
@@ -1,62 +0,0 @@
-package LANraragi::Plugin::Metadata::DateAdded;
-
-use strict;
-use warnings;
-
-#Plugins can freely use all Perl packages already installed on the system
-#Try however to restrain yourself to the ones already installed for LRR (see tools/cpanfile) to avoid extra installations by the end-user.
-use Mojo::UserAgent;
-
-use LANraragi::Model::Plugins;
-use LANraragi::Utils::Logging qw(get_logger);
-
-#Meta-information about your plugin.
-sub plugin_info {
-
- return (
- #Standard metadata
- name => "Date Added",
- type => "metadata",
- namespace => "DateAddedPlugin",
- author => "Utazukin",
- version => "0.3",
- description => "Adds the unix time stamp of the date the archive was added as a tag under the \"date_added\" namespace.",
- icon =>
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA\nB3RJTUUH4wYCFQY4HfiAJAAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUH\nAAADKUlEQVQ4y6WVsUtrVxzHP+fmkkiqJr2CQWKkvCTwJgkJDpmyVAR1cVOhdq04tHNB7BD8A97S\nXYkO3dRRsMSlFoIOLYFEohiDiiTNNeaGpLn5dRDv06ev75V+4SyH8/2c3/n+zuEoEeFTqtfrb5RS\nJZ/P98m1iMirI5fLMT8/L+FwWEKhkIRCIXn79q2srKxIpVL5qE/7cINms8ny8rIkEgkpl8skk0lm\nZ2eZmZkhHo+TzWYJBoOyvr4u7Xb7RYHq6ZEvLi6Ynp6WVqvFwsIC4+PjRCIRDMNAKcXNzQ2lUols\nNsvOzg6xWIxMJqOeRuEAq9UqqVRKhoaGmJubY2pqCl3XiUajXF5e0t/fz+DgIIVCAbfbzdbWFtvb\n24yMjLC/v6+eZWjbNqurq5JIJGRtbU0syxLbtsU0TXmqXq8njUZDRERubm4knU6LYRiSyWScDBER\nGo0G4XBYFhcX5fz8XP4yTbGLf0hnd0s+plqtJru7u7K0tCSRSEQ6nc77ppycnFCv10kmk4yOjoII\n2kiIv3//lfbGu1dvh1KKVCrF2NgYmqaRy+UAHoCHh4f4fD4mJiZwuVz4fT74YhDvTz/TPv2TX378\ngWKx+Azo9/sZGBhAKYVhGBSLxa8doGmaABiGQT6fp9VqPbg0jcr897w7+I3FxUVs23aAlmVxe3tL\nPB7n/v6eWq22D6A/lq+UotlsEo1G8Xg8jvFNOMzCN99iGF/icrmc+b6+PrxeL6enp7hcLpR6aLT+\nuEDTNEqlErFYDMuy8Hq9AHg8HpaXv3uRYbfbRdM0TNNE096/Dweo6zoHBwfE43F0XXeAjyf4UJVK\nhUql8iwGJ8NHeb1e9vb2CAaDADQajRcgy7IACAQCHB0d/TtQ0zQuLi7Y3Nzk+vqacrkMwNXVFXd3\nd7Tbbc7Ozuh0OmxsbHB1dfViQ/21+3V8fIxpmkxOTmKaJrZt0263sW0b27ZJp9M0m010XX8RhwN8\nNPV6PQCKxSL5fB7DMAgEAnS7XarVKtVqFbfbjVIK27ZRSjkeB9jtdikUChQKBf6vlIg4Gb3Wzc/V\n8PDwV36//1x9zhfwX/QPryPQMvGWTdEAAAAASUVORK5CYII=",
- parameters => [ { type => "bool", desc => "Use file modified time instead of current time." } ],
- oneshot_arg =>
- "Use file modified time (yes/true), or use current time (no/false). Leaving blank uses the global setting (default: current time)"
- );
-
-}
-
-#Mandatory function to be implemented by your plugin
-sub get_tags {
-
- shift;
- my $lrr_info = shift; # Global info hash
- my ($use_filetime) = @_; # Plugin parameters
-
- #Use the logger to output status - they'll be passed to a specialized logfile and written to STDOUT.
- my $logger = get_logger( "Date Added Plugin", "plugins" );
-
- #Work your magic here - You can create subroutines below to organize the code better
-
- $logger->debug( "Processing file: " . $lrr_info->{file_path} );
- my $newtags = "";
- my $oneshotarg = $lrr_info->{oneshot_param};
- my $oneshot_file_time = $oneshotarg =~ /^(yes|true)$/i;
- my $oneshot_current_time = $oneshotarg =~ /^(no|false)$/i;
-
- if ( $oneshot_file_time || ( $use_filetime && !$oneshot_current_time ) ) {
- $logger->info("Using file date");
- $newtags = "date_added:" . ( stat( $lrr_info->{file_path} ) )[9]; #9 is the unix time stamp for date modified.
- } else {
- $logger->info("Using current date");
- $newtags = "date_added:" . time();
- }
- return ( tags => $newtags );
-}
-
-1;
-
diff --git a/lib/LANraragi/Utils/Database.pm b/lib/LANraragi/Utils/Database.pm
index da20c8061..3b5a83651 100644
--- a/lib/LANraragi/Utils/Database.pm
+++ b/lib/LANraragi/Utils/Database.pm
@@ -13,6 +13,7 @@ use Cwd;
use Unicode::Normalize;
use LANraragi::Model::Plugins;
+use LANraragi::Model::Config;
use LANraragi::Utils::Generic qw(flat remove_spaces);
use LANraragi::Utils::Tags qw(unflat_tagrules tags_rules_to_array restore_CRLF);
use LANraragi::Utils::Logging qw(get_logger);
@@ -38,8 +39,19 @@ sub add_archive_to_redis {
$redis->hset( $id, "name", redis_encode($name) );
$redis->hset( $id, "title", redis_encode($name) );
- # Initialize tags to the current date
- $redis->hset( $id, "tags", "date_added:" . time() );
+ # Initialize tags to the current date if the matching pref is enabled
+ if ( LANraragi::Model::Config->enable_dateadded eq "1" ) {
+
+ if ( LANraragi::Model::Config->use_lastmodified eq "1" ) {
+ $logger->info("Using file date");
+ $redis->hset( $id, "tags", "date_added:" . ( stat($file) )[9] ); #9 is the unix time stamp for date modified.
+ } else {
+ $logger->info("Using current date");
+ $redis->hset( $id, "tags", "date_added:" . time() );
+ }
+ } else {
+ $redis->hset( $id, "tags", "" );
+ }
# Don't encode filenames.
$redis->hset( $id, "file", $file );
diff --git a/templates/config.html.tt2 b/templates/config.html.tt2
index 74818cf71..f83bbbce8 100644
--- a/templates/config.html.tt2
+++ b/templates/config.html.tt2
@@ -47,8 +47,8 @@