package AniDB::Manager; use 5.024; use Moo; use experimental 'signatures'; use Log::Any '$log'; use Path::Tiny; use namespace::clean; has datastore => ( is => 'ro', required => 1, ); has api_client => ( is => 'ro', required => 1, ); around BUILDARGS => sub($orig,$class,@args) { my $args = $class->$orig(@args); if (my $db_name = $args->{database}) { require AniDB::Datastore; $args->{datastore} = AniDB::Datastore->new({ database => $db_name, }); } if (my $username = $args->{username}) { require AniDB::APIClient;; $args->{api_client} = AniDB::APIClient->new({ %{$args}{qw(username password)}, }); } return $args; }; has renamer => ( is => 'ro', lazy => 1, ); sub _build_renamer { require AniDB::Renamer; return AniDB::Renamer->new(); } has hash_function => ( is => 'ro', lazy => 1, ); sub _build_hash_function { require AniDB::Hashing; return \&AniDB::Hashing::hash_fd; } 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); } sub maybe_new_name_for($self,$path) { my $new_name = $self->new_name_for($path); return if $new_name eq $path; return $new_name; } sub rename($self,$path,$new_path) { $path = path($path)->realpath; $new_path ||= $self->new_name_for($path); if ($path->move($new_path)) { $self->datastore->rename($path,$new_path); return 1; } else { $log->errorf( 'failed to rename %s to %s', $path, $new_path, ); return; } } sub update($self,$path) { $path = path($path)->realpath; my $stat = $path->stat; return unless $self->datastore->has_changed($path,$stat); my $hash = $self->hash_function->($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;