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 )