App-DrivePlayer
view release on metacpan or search on metacpan
lib/App/DrivePlayer/GUI/SheetSync.pm view on Meta::CPAN
package App::DrivePlayer::GUI::SheetSync;
# Moo role: Google Sheet synchronisation.
use strict;
use warnings;
use utf8;
use Moo::Role;
use Glib qw( FALSE );
use Gtk3 '-init';
use App::DrivePlayer::SheetDB;
sub _sheet_db {
my ($self) = @_;
my $sid = $self->config->sheet_id() or do {
$self->_show_error(
"No spreadsheet configured.\n\n" .
"Open File â Settings, enter or create a Spreadsheet ID."
);
return;
};
return unless $self->_init_api();
return App::DrivePlayer::SheetDB->new(
api => $self->rest_api,
spreadsheet_id => $sid,
);
}
sub _clear_sheet_id {
my ($self) = @_;
$self->config->_data->{sheet_id} = '';
$self->config->save();
my $log = do { eval { require Log::Log4perl; Log::Log4perl->get_logger(__PACKAGE__) } };
$log->warn('Spreadsheet not found (deleted?); sheet ID cleared from config') if $log;
return;
}
sub _auto_sync_to_sheet {
my ($self) = @_;
return unless $self->config->sheet_id();
$self->_set_status('Auto-syncing to Sheetâ¦');
Gtk3::main_iteration_do(FALSE) while Gtk3::events_pending();
my $sheet = $self->_sheet_db() or return;
my $counts = eval { $sheet->push_to_sheet($self->db) };
if ($@) {
if ($@ =~ /^SHEET_NOT_FOUND:/) {
$self->_clear_sheet_id();
$self->_set_status('Spreadsheet not found (deleted?); sheet ID cleared.');
} else {
$self->_set_status("Sheet sync failed: $@");
}
} else {
$self->_set_status(
"Sheet synced: $counts->{scan_folders} folders, $counts->{tracks} tracks."
);
}
return;
}
# Targeted single-row sync used after a single-track edit. Avoids the
lib/App/DrivePlayer/GUI/SheetSync.pm view on Meta::CPAN
$self->drive->list(
filter => "name='DrivePlayer Library' and mimeType='application/vnd.google-apps.spreadsheet' and trashed=false",
params => { fields => 'files(id,name)', pageSize => 1 },
);
};
if ($@) {
$log->warn("New-device sheet restore: Drive search failed: $@") if $log;
return;
}
unless (@found) {
$log->info('New-device sheet restore: no DrivePlayer Library spreadsheet found') if $log;
return;
}
$sheet_id = $found[0]{id};
$self->config->_data->{sheet_id} = $sheet_id;
$self->config->save();
$log->info("New-device sheet restore: found spreadsheet $sheet_id") if $log;
}
my $sheet = App::DrivePlayer::SheetDB->new(
api => $api,
spreadsheet_id => $sheet_id,
);
my $counts = eval { $sheet->pull_from_sheet($self->db) };
if ($@) {
if ($@ =~ /^SHEET_NOT_FOUND:/) {
$self->_clear_sheet_id();
} else {
$log->warn("New-device sheet restore: pull_from_sheet failed: $@") if $log;
}
} else {
$log->info("New-device sheet restore: pulled $counts->{scan_folders} folders, $counts->{tracks} tracks") if $log;
}
return;
}
sub _prune_removed_folders {
my ($self) = @_;
my $log = do { eval { require Log::Log4perl; Log::Log4perl->get_logger(__PACKAGE__) } };
my @config_ids = map { $_->{id} } @{ $self->config->music_folders() };
return unless @config_ids; # no folders configured yet â nothing to prune
my %keep = map { $_ => 1 } @config_ids;
for my $sf ($self->db->all_scan_folders()) {
next if $keep{ $sf->{drive_id} };
$log->info("Pruning removed folder '$sf->{name}' from database") if $log;
$self->db->delete_scan_folder($sf->{drive_id});
}
return;
}
1;
__END__
=head1 NAME
App::DrivePlayer::GUI::SheetSync - Role for Google Sheet synchronisation
=head1 DESCRIPTION
A L<Moo::Role> consumed by L<App::DrivePlayer::GUI> that handles syncing the
local library to and from a Google Sheets spreadsheet.
=cut
( run in 1.949 second using v1.01-cache-2.11-cpan-140bd7fdf52 )