@@ -118,6 +118,9 @@ my @VIDEO_QUEUE;
118118# Keep track of watched videos
119119my %WATCHED_VIDEOS ;
120120
121+ # Saved channels
122+ my %channels ;
123+
121124sub which_command {
122125 my ($cmd ) = @_ ;
123126
@@ -2076,217 +2079,188 @@ sub set_local_playlists {
20762079
20772080set_local_playlists();
20782081
2079- {
2080- my %channels ;
2081- my %removed_channels ;
2082-
2083- # ------------ Usernames list window ------------ #
2084- sub set_usernames {
2085- if (-e $CONFIG {youtube_users_file }) {
2086- if (open my $fh , ' <:utf8' , $CONFIG {youtube_users_file }) {
2087- while (defined (my $entry = <$fh >)) {
2088-
2089- $entry = unpack (' A*' , $entry );
2090- my ($channel , $label ) = split (' ' , $entry , 2);
2091-
2092- if (defined ($channel ) and $channel =~ / $valid_channel_id_re / ) {
2093- $channel = $+ {channel_id };
2094- if (defined ($label ) and $label =~ / \S / ) {
2095- $channels {$channel } = $label ;
2096- }
2097- else {
2098- $channels {$channel } = undef ;
2099- }
2100- }
2101- }
2102- close $fh ;
2103- }
2104- }
2105- else {
2106- # Default channels
2107- %channels = (
2108- ' UC1_uAIS3r8Vu6JjXWvastJg' => ' Mathologer' ,
2109- ' UCSju5G2aFaWMqn-_0YBtq5A' => ' Stand-Up Maths' ,
2110- ' UC-WICcSW1k3HsScuXxDrp0w' => ' Curry On!' ,
2111- ' UCShHFwKyhcDo3g7hr4f1R8A' => ' World Science Festival' ,
2112- ' UCYO_jab_esuFRV4b17AJtAw' => ' 3Blue1Brown' ,
2113- ' UCWnPjmqvljcafA0z2U1fwKQ' => ' Confreaks' ,
2114- ' UC_QIfHvN9auy2CoOdSfMWDw' => ' Strange Loop' ,
2115- ' UCseUQK4kC3x2x543nHtGpzw' => ' Brian Will' ,
2116- ' UC9-y-6csu5WGm29I7JiwpnA' => ' Computerphile' ,
2117- ' UCoxcjq-8xIDTYp3uz647V5A' => ' Numberphile' ,
2118- ' UCvBqzzvUBLCs8Y7Axb-jZew' => ' Sixty Symbols' ,
2119- ' UC6107grRI4m0o2-emgoDnAA' => ' SmarterEveryDay' ,
2120- ' UCF6F8LdCSWlRwQm_hfA2bcQ' => ' Coding Math' ,
2121- ' UC1znqKFL3jeR0eoA0pHpzvw' => ' SpaceRip' ,
2122- ' UCvjgXvBlbQiydffZU7m1_aw' => ' The Coding Train' ,
2123- ' UC0wbcfzV-bHhABbWGXKHwdg' => ' Utah Open Source' ,
2124- ' UCotwjyJnb-4KW7bmsOoLfkg' => ' Art of the Problem' ,
2125- ' UC7y4qaRSb5w2O8cCHOsKZDw' => ' YAPC NA' ,
2126- ' UCGHZpIpAWJQ-Jy_CeCdXhMA' => ' Cool Worlds' ,
2127- ' UCmG6gHgD8JaEZVxuHWJijGQ' => ' UConn Mathematics' ,
2128- ' UC81mayGa63QaJE1SjKIYp0w' => ' metaRising' ,
2129- ' UCSHZKyawb77ixDdsGog4iWA' => ' Lex Fridman' ,
2130- ' UCBa659QWEk1AI4Tg--mrJ2A' => ' Tom Scott' ,
2131- );
2132- }
2082+ # ------------ Usernames list window ------------ #
2083+ sub set_usernames {
21332084
2134- foreach my $channel (sort { CORE::fc($channels {$a } // $a ) cmp CORE::fc($channels {$b } // $b ) } keys %channels ) {
2135- my $iter = $users_liststore -> append;
2085+ if (-e $CONFIG {youtube_users_file }) {
2086+ %channels = ((map { @$_ } $yv_utils -> read_channels_from_file($CONFIG {youtube_users_file })), %channels ,);
2087+ }
2088+ else {
2089+ # Default channels
2090+ %channels = (
2091+ ' UC1_uAIS3r8Vu6JjXWvastJg' => ' Mathologer' ,
2092+ ' UCSju5G2aFaWMqn-_0YBtq5A' => ' Stand-Up Maths' ,
2093+ ' UC-WICcSW1k3HsScuXxDrp0w' => ' Curry On!' ,
2094+ ' UCShHFwKyhcDo3g7hr4f1R8A' => ' World Science Festival' ,
2095+ ' UCYO_jab_esuFRV4b17AJtAw' => ' 3Blue1Brown' ,
2096+ ' UCWnPjmqvljcafA0z2U1fwKQ' => ' Confreaks' ,
2097+ ' UC_QIfHvN9auy2CoOdSfMWDw' => ' Strange Loop' ,
2098+ ' UCseUQK4kC3x2x543nHtGpzw' => ' Brian Will' ,
2099+ ' UC9-y-6csu5WGm29I7JiwpnA' => ' Computerphile' ,
2100+ ' UCoxcjq-8xIDTYp3uz647V5A' => ' Numberphile' ,
2101+ ' UCvBqzzvUBLCs8Y7Axb-jZew' => ' Sixty Symbols' ,
2102+ ' UC6107grRI4m0o2-emgoDnAA' => ' SmarterEveryDay' ,
2103+ ' UCF6F8LdCSWlRwQm_hfA2bcQ' => ' Coding Math' ,
2104+ ' UC1znqKFL3jeR0eoA0pHpzvw' => ' SpaceRip' ,
2105+ ' UCvjgXvBlbQiydffZU7m1_aw' => ' The Coding Train' ,
2106+ ' UC0wbcfzV-bHhABbWGXKHwdg' => ' Utah Open Source' ,
2107+ ' UCotwjyJnb-4KW7bmsOoLfkg' => ' Art of the Problem' ,
2108+ ' UC7y4qaRSb5w2O8cCHOsKZDw' => ' YAPC NA' ,
2109+ ' UCGHZpIpAWJQ-Jy_CeCdXhMA' => ' Cool Worlds' ,
2110+ ' UCmG6gHgD8JaEZVxuHWJijGQ' => ' UConn Mathematics' ,
2111+ ' UC81mayGa63QaJE1SjKIYp0w' => ' metaRising' ,
2112+ ' UCSHZKyawb77ixDdsGog4iWA' => ' Lex Fridman' ,
2113+ ' UCBa659QWEk1AI4Tg--mrJ2A' => ' Tom Scott' ,
2114+ );
2115+ }
2116+
2117+ $users_liststore -> clear; # clear the list
2118+
2119+ foreach my $channel (sort { CORE::fc($channels {$a } // $a ) cmp CORE::fc($channels {$b } // $b ) } keys %channels ) {
2120+ my $iter = $users_liststore -> append;
21362121
2137- if (defined $channels {$channel }) {
2138- $users_liststore -> set(
2139- $iter ,
2140- 0 => $channel ,
2141- 1 => $channels {$channel },
2142- 2 => ' channel' ,
2143- );
2144- }
2145- else {
2146- $users_liststore -> set(
2147- $iter ,
2148- 0 => $channel ,
2149- 1 => $channel ,
2150- 2 => ' username' ,
2151- );
2152- }
2122+ $channels {$channel } // next ;
21532123
2154- $users_liststore -> set($iter , [3], [$user_icon_pixbuf ]);
2155- }
2124+ $users_liststore -> set(
2125+ $iter ,
2126+ 0 => $channel ,
2127+ 1 => $channels {$channel },
2128+ 2 => ' channel' ,
2129+ 3 => $user_icon_pixbuf ,
2130+ );
21562131 }
2132+ }
21572133
2158- sub save_channel {
2159- my $channel_name = $save_channel_name_entry -> get_text;
2160- my $channel_id = $save_channel_id_entry -> get_text;
2134+ sub save_channel {
2135+ my $channel_name = $save_channel_name_entry -> get_text;
2136+ my $channel_id = $save_channel_id_entry -> get_text;
21612137
2162- # Validate the channel id
2163- if (defined ($channel_id ) and $channel_id =~ / $valid_channel_id_re / ) {
2138+ # Validate the channel id
2139+ if (defined ($channel_id ) and $channel_id =~ / $valid_channel_id_re / ) {
21642140
2165- $channel_id = $+ {channel_id };
2141+ $channel_id = $+ {channel_id };
21662142
2167- # Get the channel name when empty
2168- if (not defined ($channel_name ) or not $channel_name =~ / \S / ) {
2169- $channel_name = $yv_obj -> channel_title_from_id($channel_id ) // die " Invalid channel ID: <<$channel_id >>" ;
2170- }
2143+ # Get the channel name when empty
2144+ if (not defined ($channel_name ) or not $channel_name =~ / \S / ) {
2145+ $channel_name = $yv_obj -> channel_title_from_id($channel_id ) // die " Invalid channel ID: <<$channel_id >>" ;
21712146 }
2172- elsif (defined ($channel_name ) and $channel_name =~ / $valid_channel_id_re / ) {
2147+ }
2148+ elsif (defined ($channel_name ) and $channel_name =~ / $valid_channel_id_re / ) {
21732149
2174- $channel_name = $+ {channel_id };
2175- $channel_id = $yv_obj -> channel_id_from_username($channel_name );
2150+ $channel_name = $+ {channel_id };
2151+ $channel_id = $yv_obj -> channel_id_from_username($channel_name );
21762152
2177- if (not defined $channel_id ) {
2178- die " Can't get channel ID from username: <<$channel_name >>" ;
2179- }
2180- }
2181- elsif (defined ($channel_id ) and $channel_id =~ / \S / ) {
2182- die " Invalid channel ID: <<$channel_id >>" ;
2183- }
2184- else {
2185- return ;
2153+ if (not defined $channel_id ) {
2154+ die " Can't get channel ID from username: <<$channel_name >>" ;
21862155 }
2156+ }
2157+ elsif (defined ($channel_id ) and $channel_id =~ / \S / ) {
2158+ die " Invalid channel ID: <<$channel_id >>" ;
2159+ }
2160+ else {
2161+ return ;
2162+ }
2163+
2164+ save_channel_by_id($channel_id , $channel_name );
2165+ }
21872166
2188- save_channel_by_id($channel_id , $channel_name );
2167+ sub save_channel_by_id {
2168+ my ($channel_id , $channel_name ) = @_ ;
2169+
2170+ # Validate the channel ID
2171+ if (not defined ($channel_id ) or not $channel_id =~ / $valid_channel_id_re / ) {
2172+ return ;
21892173 }
21902174
2191- sub save_channel_by_id {
2192- my ($channel_id , $channel_name ) = @_ ;
2175+ if ($channel_id =~ / $valid_channel_id_re / ) {
2176+ $channel_id = $+ {channel_id };
2177+ }
21932178
2194- # Validate the channel ID
2195- if (not defined ( $channel_id ) or not $channel_id =~ / $valid_channel_id_re / ) {
2196- return ;
2197- }
2179+ # Channel ID already exists in the list
2180+ if (exists ( $channels { $channel_id }) ) {
2181+ return ;
2182+ }
21982183
2199- if ($channel_id =~ / $valid_channel_id_re / ) {
2200- $channel_id = $+ {channel_id };
2201- }
2184+ # Get the channel name
2185+ if (not defined ($channel_name ) or not $channel_name =~ / \S / ) {
2186+ $channel_name = $yv_obj -> channel_title_from_id($channel_id ) // $channel_id ;
2187+ }
22022188
2203- # Channel ID already exists in the list
2204- if (exists ($channels {$channel_id })) {
2205- return ;
2206- }
2189+ # Save channel to file
2190+ say " :: Saving channel: $channel_name " if $yv_obj -> get_debug;
2191+ $channels {$channel_id } = $channel_name ;
2192+ write_channels_to_file(\%channels , $CONFIG {youtube_users_file });
2193+ set_usernames();
2194+ }
22072195
2208- # Get the channel name
2209- if ( not defined ( $channel_name ) or not $channel_name =~ / \S / ) {
2210- $channel_name = $yv_obj -> channel_title_from_id ($channel_id ) // $channel_id ;
2211- }
2196+ sub add_user_to_favorites {
2197+ my $channel_id = get_channel_id_for_selected_video() // return ;
2198+ save_channel_by_id ($channel_id );
2199+ }
22122200
2213- # Store it internally
2214- $channels {$channel_id } = $channel_name ;
2201+ sub remove_selected_username {
22152202
2216- # Append it to the list
2217- my $iter = $users_liststore -> append;
2203+ my $selection = $users_treeview -> get_selection // return ;
2204+ my $iter = $selection -> get_selected // return ;
2205+ my $channel_id = $users_liststore -> get($iter , 0);
22182206
2219- $users_liststore -> set(
2220- $iter ,
2221- 0 => $channel_id ,
2222- 1 => $channel_name ,
2223- 2 => ' channel' ,
2224- 3 => $user_icon_pixbuf ,
2225- );
2226- }
2207+ delete $channels {$channel_id };
2208+ $users_liststore -> remove($iter );
22272209
2228- sub add_user_to_favorites {
2229- my $channel_id = get_channel_id_for_selected_video() // return ;
2230- save_channel_by_id($channel_id );
2231- }
2210+ write_channels_to_file(\%channels , $CONFIG {youtube_users_file });
2211+ }
22322212
2233- sub remove_selected_user {
2234- my $selection = $users_treeview -> get_selection // return ;
2235- my $iter = $selection -> get_selected // return ;
2236- my $channel_id = $users_liststore -> get($iter , 0);
2237- delete $channels {$channel_id };
2238- $removed_channels {$channel_id } = 1;
2239- $users_liststore -> remove($iter );
2240- }
2213+ sub write_channels_to_file {
2214+ my ($channels , $file ) = @_ ;
22412215
2242- sub save_usernames_to_file {
2216+ my %new_channels = %$channels ;
22432217
2244- set_usernames(); # update %channels
2218+ open ( my $fh , ' >:utf8 ' , $file ) or return ;
22452219
2246- foreach my $id (keys %removed_channels ) {
2247- delete $channels {$id };
2220+ foreach my $channel (
2221+ sort { CORE::fc($new_channels {$a } // $a ) cmp CORE::fc($new_channels {$b } // $b ) }
2222+ keys %new_channels
2223+ ) {
2224+ if (defined ($new_channels {$channel })) {
2225+ say $fh " $channel $new_channels {$channel }" ;
22482226 }
2249-
2250- open (my $fh , ' >:utf8' , $CONFIG {youtube_users_file }) or return ;
2251- foreach my $channel (
2252- sort { CORE::fc($channels {$a } // $a ) cmp CORE::fc($channels {$b } // $b ) }
2253- keys %channels
2254- ) {
2255- if (defined ($channels {$channel })) {
2256- say $fh " $channel $channels {$channel }" ;
2257- }
2258- else {
2259- say $fh $channel ;
2260- }
2227+ else {
2228+ say $fh " $channel $channel " ;
22612229 }
2262- close $fh ;
22632230 }
22642231
2265- # Get playlists from username
2266- sub playlists_from_selected_username {
2267- my $selection = $users_treeview -> get_selection() // return ;
2268- my $iter = $selection -> get_selected() // return ;
2232+ close $fh ;
2233+ }
22692234
2270- my $type = $users_liststore -> get($iter , 2);
2271- my $channel = $users_liststore -> get($iter , 0);
2235+ sub save_usernames_to_file {
2236+ set_usernames(); # update channels
2237+ write_channels_to_file(\%channels , $CONFIG {youtube_users_file });
2238+ }
22722239
2273- playlists($type , $channel );
2274- }
2240+ # Get playlists from username
2241+ sub playlists_from_selected_username {
2242+ my $selection = $users_treeview -> get_selection() // return ;
2243+ my $iter = $selection -> get_selected() // return ;
2244+
2245+ my $type = $users_liststore -> get($iter , 2);
2246+ my $channel = $users_liststore -> get($iter , 0);
22752247
2276- sub videos_from_selected_username {
2277- my $selection = $users_treeview -> get_selection() // return ;
2278- my $iter = $selection -> get_selected() // return ;
2248+ playlists($type , $channel );
2249+ }
22792250
2280- my $type = $users_liststore -> get($iter , 2);
2281- my $channel = $users_liststore -> get($iter , 0);
2251+ sub videos_from_selected_username {
2252+ my $selection = $users_treeview -> get_selection() // return ;
2253+ my $iter = $selection -> get_selected() // return ;
22822254
2283- uploads( $type , $channel );
2284- }
2255+ my $type = $users_liststore -> get( $iter , 2 );
2256+ my $channel = $users_liststore -> get( $iter , 0);
22852257
2286- sub videos_from_saved_channel {
2287- hide_users_list_window();
2288- videos_from_selected_username();
2289- }
2258+ uploads($type , $channel );
2259+ }
2260+
2261+ sub videos_from_saved_channel {
2262+ hide_users_list_window();
2263+ videos_from_selected_username();
22902264}
22912265
22922266# ----- My panel settings ----- #
0 commit comments