summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2016-10-18 18:26:49 +0100
committerdakkar <dakkar@thenautilus.net>2016-10-18 18:26:49 +0100
commitb51533bf1461e8487018dc51a890309441fc51d4 (patch)
treecdd59e0faef02200ac8a5ca42e91289bd68a661d
parentmore rough pieces (diff)
downloadanidb-renamer-b51533bf1461e8487018dc51a890309441fc51d4.tar.gz
anidb-renamer-b51533bf1461e8487018dc51a890309441fc51d4.tar.bz2
anidb-renamer-b51533bf1461e8487018dc51a890309441fc51d4.zip
this may make sense
-rw-r--r--lib/AniDB/Datastore.pm108
-rw-r--r--lib/AniDB/Manager.pm48
2 files changed, 134 insertions, 22 deletions
diff --git a/lib/AniDB/Datastore.pm b/lib/AniDB/Datastore.pm
index 8db4e16..41602e6 100644
--- a/lib/AniDB/Datastore.pm
+++ b/lib/AniDB/Datastore.pm
@@ -3,7 +3,8 @@ use 5.024;
use experimental 'signatures';
use Moo;
use Path::Tiny;
-use AniDB::Hashing;
+use Try::Tiny;
+use JSON::MaybeXS qw(encode_json decode_json);
use namespace::clean;
has database => ( is => 'ro', required => 1 );
@@ -22,23 +23,25 @@ sub _build_dbh($self) {
);
}
-sub update($self,$path) {
- my $stat = $path->stat;
-
- return 0 unless $self->_has_changed($path,$stat);
- my $hash = AniDB::Hashing::hash_fd($path->openr_raw);
- $self->_update_path_info(
- $path => {
- size => $stat->size,
- mtime => $stat->mtime,
- hash => $hash,
- },
- );
- return 1;
+sub BUILD($self) {
+ try {
+ $self->dbh->selectall_arrayref('SELECT * FROM path_info LIMIT 1');
+ } catch {
+ if (/\bno such table\b/) {
+ my @sql = do { local $/ = ";\n\n"; <DATA> };
+ $self->dbh->do($_) for @sql;
+ }
+ else {
+ die $_;
+ }
+ };
}
-sub _has_changed($self,$path,$stat) {
+sub has_changed($self,$path,$stat) {
my $path_info = $self->path_info_for($path);
+ # if we don't know about the file, it's definitely changed!
+ return 1 unless $path_info;
+
return (
$path_info->{size} == $stat->size
&& $path_info->{mtime} == $stat->mtime
@@ -76,22 +79,85 @@ sub path_info_for($self,$path) {
return $ret->[0];
}
+sub update_path_info($self,$path,$path_info) {
+ my @binds = (@{$path_info}{qw(size mtime hash)}, $path->stringify);
+ return $self->dbh->do(
+ qr{UPDATE path_info SET size=?, mtime=?, hash=? WHERE name=?},
+ {},
+ @binds,
+ ) or $self->dbh->do(
+ qr{INSERT INTO path_info(size,mtime,hash,name) VALUES (?,?,?,?)},
+ {},
+ @binds,
+ );
+}
+
sub episode_info_for($self,$args) {
my $ret = $self->dbh->selectall_arrayref(
- qr{SELECT * FROM episode_info WHERE hash=? AND size=?},
- { Slice => {} },
+ qr{SELECT json FROM episode_info WHERE hash=? AND size=?},
+ { },
@{$args}{qw(hash size)},
);
- return $ret->[0];
+ return unless $ret && $ret->[0];
+ return decode_json($ret->[0][0]);
+}
+
+sub update_episode_info($self,$path_info, $episode_info) {
+ my $json = encode_json($episode_info);
+ my @binds = ($json, @{$path_info}{qw(size hash)});
+ return $self->dbh->do(
+ qr{UPDATE episode_info SET json=? WHERE size=? AND hash=?},
+ {},
+ @binds,
+ ) or $self->dbh->do(
+ qr{INSERT INTO episode_info(json,size,hash) VALUES (?,?,?)},
+ {},
+ @binds,
+ );
}
sub anime_info_for($self,$args) {
my $ret = $self->dbh->selectall_arrayref(
- qr{SELECT * FROM anime_info WHERE aid=?},
- { Slice => {} },
+ qr{SELECT json FROM anime_info WHERE aid=?},
+ { },
@{$args}{qw(aid)},
);
- return $ret->[0];
+ return unless $ret && $ret->[0];
+ return decode_json($ret->[0][0]);
+}
+
+sub update_anime_info($self,$episode_info, $anime_info) {
+ my $json = encode_json($anime_info);
+ my @binds = ($json, $episode_info->{eid});
+ return $self->dbh->do(
+ qr{UPDATE anime_info SET json=? WHERE eid=?},
+ {},
+ @binds,
+ ) or $self->dbh->do(
+ qr{INSERT INTO anime_info(json,eid) VALUES (?,?)},
+ {},
+ @binds,
+ );
}
1;
+
+__DATA__
+CREATE TABLE path_info (
+ name TEXT PRIMARY KEY,
+ mtime INT NOT NULL,
+ size INT NOT NULL,
+ hash TEXT NOT NULL
+);
+
+CREATE TABLE episode_info (
+ size INT NOT NULL,
+ hash TEXT NOT NULL,
+ json TEST NOT NULL,
+ PRIMARY KEY (size,hash)
+);
+
+CREATE TABLE anime_info (
+ eid INT PRIMARY KEY,
+ json TEST NOT NULL
+);
diff --git a/lib/AniDB/Manager.pm b/lib/AniDB/Manager.pm
index eeb724f..0539c07 100644
--- a/lib/AniDB/Manager.pm
+++ b/lib/AniDB/Manager.pm
@@ -4,12 +4,17 @@ use experimental 'signatures';
use Moo;
use Log::Any '$log';
use Path::Tiny;
+use AniDB::Hashing;
use namespace::clean;
has datastore => (
is => 'ro',
required => 1,
- handles => [qw(update)],
+);
+
+has api_client => (
+ is => 'ro',
+ required => 1,
);
around BUILDARGS => sub($orig,$class,@args) {
@@ -20,6 +25,12 @@ around BUILDARGS => sub($orig,$class,@args) {
database => $db_name,
});
}
+ if (my $username = $args->{username}) {
+ require AniDB::APIClient;;
+ $args->{api_client} = AniDB::APIClient->new({
+ %{$args}{qw(username password)},
+ });
+ }
return $args;
};
@@ -35,6 +46,7 @@ sub _build_renamer {
sub new_name_for($self,$path) {
$path = path($path)->realpath;
+ $self->update($path);
my $full_info = $self->datastore->full_info_for($path);
return $self->renamer->new_name_for($path,$full_info);
}
@@ -61,4 +73,38 @@ sub rename($self,$path,$new_path) {
}
}
+sub update($self,$path) {
+ $path = path($path)->realpath;
+
+ my $stat = $path->stat;
+
+ return unless $self->datastore->has_changed($path,$stat);
+
+ my $hash = AniDB::Hashing::hash_fd($path->openr_raw);
+
+ $self->datastore->update_path_info(
+ $path => my $path_info = {
+ size => $stat->size,
+ mtime => $stat->mtime,
+ hash => $hash,
+ },
+ );
+
+ my $episode_info = $self->datastore->episode_info_for($path_info);
+ unless ($episode_info) {
+ $episode_info = $self->api_client->episode_info_for($path_info);
+ $self->datastore->update_episode_info(
+ $path_info, $episode_info,
+ );
+ }
+
+ my $anime_info = $self->datastore->anime_info_for($episode_info);
+ unless ($anime_info) {
+ $anime_info = $self->api_client->anime_info_for($episode_info);
+ $self->datastore->update_anime_info(
+ $episode_info, $anime_info,
+ );
+ }
+}
+
1;