package AmphetaDesk::ChannelsList; ############################################################################### # AmphetaDesk (c) 2000-2002 Disobey # # morbus@disobey.com http://www.disobey.com/amphetadesk/ # ############################################################################### # ABOUT THIS PACKAGE: # # This package controls the listing in the "Add a Channel" portion, from # # parsing through the OPML file (gleaned from syndic8.com) to actually # # turning it into something suitable for HTML display. # # # # LIST OF ROUTINES BELOW: # # get_sorted_channels_list - get arrays of various sorted channel options. # # load_channel_list_letter - loads channels that start with the $letter. # ############################################################################### # "16x or 4x? 5 minutes or 20 minutes? I just don't know, Mr. Bond." # ############################################################################### use strict; $|++; use AmphetaDesk::Settings; use AmphetaDesk::Utilities; use AmphetaDesk::WWW; use XML::Parser; require Exporter; use vars qw( @ISA @EXPORT ); @ISA = qw( Exporter ); @EXPORT = qw( get_sorted_channels_list load_channels_by_letter ); # yadda, yadda. my $letter = ''; my $total_count = 0; my $letter_count = 0; # where we store our # in-memory channel letter. my %CHANNELS; ############################################################################### # get_sorted_channels_list - get arrays of various sorted channel options. # ############################################################################### # USAGE: # # # returns our channel list data, sorted by title. # # my @array = get_sorted_channels_list("title", "data"); # # # # # returns 'l' data, reversed sorted by title. # # my @array = get_sorted_channels_list("title", "reversed_data"); # # # # NOTES: # # This routine goes through our currently stored syndic8 channel list in # # %CHANNELS, and returns an array based on how the data should be sorted # # as well as how the data is returned. Sorting can be done on ANY # # attribute stored in %CHANNELS, and the returned array could be sorted # # normally or reversed. # # # # RETURNS: # # @array; the sorted array of channel ids. # ############################################################################### sub get_sorted_channels_list { my ($sort_by, $return) = @_; # prepare our various arrays # and return the format requested. my @names = sort { uc( $CHANNELS{$a}{$sort_by} ) cmp uc ( $CHANNELS{$b}{$sort_by} ) } keys %CHANNELS; my @names_r = sort { uc( $CHANNELS{$b}{$sort_by} ) cmp uc ( $CHANNELS{$a}{$sort_by} ) } keys %CHANNELS; my @data; foreach (@names) { push(@data, $CHANNELS{$_}); } my @data_r; foreach (@names_r) { push(@data_r, $CHANNELS{$_}); } return @data if $return eq "data"; return @data_r if $return eq "reversed_data"; } ############################################################################### # load_channels_by_letter - loads channels that start with the $letter. # ############################################################################### # USAGE: # # $channel_list = load_channels_by_letter( $letter ); # # # # NOTES: # # This channel uses XML::Parser to load our channel list opml and then # # returns a data structure of all the channels that match said letter. # # # # RETURNS: # # $channel_list; a data structure of matching letters. # ############################################################################### sub load_channels_by_letter { ($letter, my $language) = @_; # if our letter isn't defined, or # else, is a number, rewrite to # be \d so that our regexp will get 'em. $letter = '\d' unless $letter; $letter = '\d' if $letter =~ /\d/; # start over with # our letter carrier # and our counts. undef %CHANNELS; $total_count = 0; $letter_count = 0; # my logfile is aroused. note("Loading our channel list from " . get_setting("names_file_services_channels") . "."); # fetch updated version if none exists locally if (! -e (get_setting("files_services_channels")) ) { my $l = new AmphetaDesk::WWW; $l->getstore( "http://www.disobey.com/amphetadesk/lists/services-channels-recent.xml", (get_setting("files_services_channels")) ); } # get an new instance of the parser, # register handlers, then parse. my $p = new XML::Parser; $p->setHandlers( Start => \&_start ); $p->parsefile( get_setting("files_services_channels") ); # creates the # data struct. sub _start { my ($p, $tag_name, %attrs) = @_; # if there are no text attributes, return, # else, return if the letter doesn't match. return unless $attrs{text}; $total_count++; return if $attrs{text} !~ /^$letter/i; $letter_count++; while ( my ($key,$value) = each(%attrs) ) { # change syndic8.com's "text" to "title". this just allows # us to match the similar attribute from the myChannels.opml. $CHANNELS{$attrs{text}}{title} = $value if $key eq "text"; next if $key eq "text"; # assign other attributes normally. note # that we lowercase the attribute name. this # is another syndic8 to ampheta change. $CHANNELS{$attrs{text}}{lc($key)} = $value; } return 1; } # silly blurbage to the log file. $letter = "0-9" if $letter eq '\d'; note("There was a total of $total_count channels, with $letter_count matches for '$letter'."); return 1; } 1;