App-YTDL
view release on metacpan or search on metacpan
lib/App/YTDL/History.pm view on Meta::CPAN
sub read_history_files {
my ( $set, $opt ) = @_;
$set->{sticky} = {};
$set->{history} = {};
if ( $opt->{max_size_history} ) {
if ( -e $set->{sticky_file} ) {
$set->{sticky} = read_json( $set->{sticky_file} ) // {};
# ### ############################################################ ### # remove that after a while
my @keys = keys %{$set->{sticky}}; # added 0.401
if ( @keys && $keys[0] =~ /^https?:/ ) {
$set->{sticky} = _old_file_fmt_to_new_file_fmt( $set->{sticky} );
write_json( $set->{sticky_file}, $set->{sticky} );
}
# ### ############################################################ ### #
}
if ( -e $set->{history_file} ) {
$set->{history} = read_json( $set->{history_file} ) // {};
# ### ############################################################ ### # remove that after a while
my @keys = keys %{$set->{history}}; # added 0.401
if ( @keys && $keys[0] =~ /^https?:/ ) {
$set->{history} = _old_file_fmt_to_new_file_fmt( $set->{history} );
write_json( $set->{history_file}, $set->{history} );
}
# ### ############################################################ ### #
}
}
}
sub _old_file_fmt_to_new_file_fmt { # ### # remove that after a while # added 0.401
my ( $h_ref ) = @_;
my $new_h_ref = {};
for my $key ( keys %$h_ref ) {
my $uploader_url = $key;
my $uploader_id = $h_ref->{$uploader_url}{uploader_id};
my $uploader = $h_ref->{$uploader_url}{uploader};
my $extractor_key = $h_ref->{$uploader_url}{extractor};
my $timestamp = $h_ref->{$uploader_url}{timestamp};
$new_h_ref->{$uploader_id} = {
uploader_url => $uploader_url,
uploader => $uploader,
extractor_key => $extractor_key,
timestamp => $timestamp,
};
}
return $new_h_ref;
}
sub choose_videos_from_saved_uploaders {
my ( $set, $opt ) = @_;
my $truncated = _to_history_size_limit( $set, $opt );
if ( $truncated ) {
write_json( $set->{history_file}, $set->{history} );
}
my $prompt = 'Chosen:' . "\n";
my @urls;
my $sticky = _get_sorted_sticky( $set->{sticky} );
my $history = _get_sorted_history( $opt, $set->{history} );
CHANNEL: while ( 1 ) {
my $mark = '*';
my $confirm = ' CONFIRM';
my $hidden = 'Your choice:' . $mark;
my @pre = ( $hidden, undef, $confirm );
my $available_uploader = _available_uploader( $set, $opt, $sticky, $history );
my $menu = [ @pre, @$available_uploader ];
# Choose
my @indexes = choose(
$menu,
{ prompt => $prompt, layout => 3, index => 1, default => 1,
undef => ' BACK', meta_items => [ 0 .. $#pre ], include_highlighted => 2 }
);
if ( ! defined $indexes[0] || ! defined $menu->[$indexes[0]] ) {
if ( @urls ) {
$prompt = 'Channels:' . "\n";
@urls = ();
$sticky = _get_sorted_sticky( $set->{sticky} );
$history = _get_sorted_history( $opt, $set->{history} );
$mark = '*';
next CHANNEL;
}
else {
return;
}
}
elsif ( $menu->[$indexes[0]] eq $hidden ) {
for my $i ( 0 .. $#$sticky ) {
$prompt .= sprintf "= %s (%s)\n", $sticky->[$i]{uploader}, $sticky->[$i]{uploader_id};
push @urls, $sticky->[$i]{uploader_url};
}
@$sticky = ();
$mark = '';
next CHANNEL;
}
my $confirmed;
if ( $menu->[$indexes[0]] eq $confirm ) {
shift @indexes;
$confirmed = 1;
}
my $count = 0;
for my $i ( @indexes ) {
$i -= @pre + $count;
if ( $i <= $#$sticky ) {
$prompt .= sprintf "= %s (%s)\n", $sticky->[$i]{uploader}, $sticky->[$i]{uploader_id};
push @urls, $sticky->[$i]{uploader_url};
splice @$sticky, $i, 1;
}
else {
$i -= @$sticky;
$prompt .= sprintf "= %s (%s)\n", $history->[$i]{uploader}, $history->[$i]{uploader_id};
push @urls, $history->[$i]{uploader_url};
splice @$history, $i, 1;
}
$count++;
}
$mark = '*';
if ( $confirmed ) {
return @urls;
}
}
}
sub edit_sticky_file {
my ( $set, $opt ) = @_;
my $sticky = _get_sorted_sticky( $set->{sticky} );
my $history = _get_sorted_history( $opt, $set->{history} );
my $changed = 0;
STICKY: while ( 1 ) {
my @pre = ( undef );
my $menu = [ @pre, map( "+ $_->{uploader}", @$sticky ), map( "- $_->{uploader}", @$history ) ];
# Choose
my $idx = choose(
$menu,
{ prompt => 'Stickify:', layout => 3, index => 1, undef => ' <<' }
);
if ( ! defined $idx || ! defined $menu->[$idx] ) {
if ( $changed ) {
write_json( $set->{sticky_file}, $set->{sticky} );
write_json( $set->{history_file}, $set->{history} );
}
return;
}
else {
$changed++;
$idx-= @pre;
if ( $idx > $#$sticky ) {
$idx -= @$sticky;
my $up = $history->[$idx]{uploader_id};
$set->{sticky}{$up} = delete $set->{history}{$up};
}
else {
my $up = $sticky->[$idx]{uploader_id};
$set->{history}{$up} = delete $set->{sticky}{$up};
$set->{history}{$up}{timestamp} = time();
}
$sticky = _get_sorted_sticky( $set->{sticky} );
$history = _get_sorted_history( $opt, $set->{history} );
}
}
}
sub _uploader_id_removed_next {
my ( $set, $opt ) = @_;
my $amount = 3;
if ( ! $opt->{max_size_history} || $opt->{max_size_history} - $amount > keys %{$set->{history}} ) {
return;
}
my $removed_next = [];
my $last_added = [];
my $count = 0;
for my $key ( sort { $set->{history}{$b}{timestamp} <=> $set->{history}{$a}{timestamp} } keys %{$set->{history}} ) {
$count++;
if ( $count > $opt->{max_size_history} - $amount ) {
push @$removed_next, $key;
}
}
return $removed_next;
}
sub _available_uploader {
my ( $set, $opt, $sticky, $history ) = @_;
my $choices = [ map( "* $_->{uploader}", @$sticky ) ];
my $removed_next = _uploader_id_removed_next( $set, $opt );
for my $i ( 0 .. $#$history ) {
if ( any { $history->[$i]{uploader_id} eq $_ } @$removed_next ) {
push @$choices, "| $history->[$i]{uploader}";
}
else {
push @$choices, " $history->[$i]{uploader}";
}
}
return $choices;
( run in 0.674 second using v1.01-cache-2.11-cpan-0b5f733616e )