diff options
Diffstat (limited to 'knewsticker-scripts')
-rw-r--r-- | knewsticker-scripts/GENERAL | 23 | ||||
-rw-r--r-- | knewsticker-scripts/Generic.Newsticker.Error | 134 | ||||
-rw-r--r-- | knewsticker-scripts/Makefile.am | 7 | ||||
-rw-r--r-- | knewsticker-scripts/README.kataribe | 44 | ||||
-rw-r--r-- | knewsticker-scripts/Readme.ErrorHandling | 19 | ||||
-rw-r--r-- | knewsticker-scripts/Readme.newsrss | 48 | ||||
-rw-r--r-- | knewsticker-scripts/Readme.stock | 36 | ||||
-rwxr-xr-x | knewsticker-scripts/bbc.pl | 54 | ||||
-rwxr-xr-x | knewsticker-scripts/fyensget.py | bin | 0 -> 3312 bytes | |||
-rwxr-xr-x | knewsticker-scripts/kataribe.pl | 96 | ||||
-rw-r--r-- | knewsticker-scripts/newsrss.pl | 100 | ||||
-rwxr-xr-x | knewsticker-scripts/sportscores.py | 241 | ||||
-rwxr-xr-x | knewsticker-scripts/stock.pl | 276 |
13 files changed, 1078 insertions, 0 deletions
diff --git a/knewsticker-scripts/GENERAL b/knewsticker-scripts/GENERAL new file mode 100644 index 0000000..df80c73 --- /dev/null +++ b/knewsticker-scripts/GENERAL @@ -0,0 +1,23 @@ +All scripts surrendered to the knewsticker scripts section which are +distributed WITH KDE are subject to the licensing restrictions of the KDE +project. Should you use any of those scripts in conjuction with any KDE +product you are also subject to their licensing. If the script is used +without a KDE affiliation , if not other stated within the script, or if no +co author is present, those scripts are believed to be in the public domain. + +Please ensure, that you implement proper error handling within your scripts. +The error handling is important for those, who might be using your script, +but have no real understanding of the underlying structure. Since +Knewsticker is a graphical application it relies on the error codes it gets +from your script to display proper error messages to the end user. + +The current set of error messages and how to use them can be found in the +documenation. You can find the documentation at: +http://spoon.pkl.net/~backpane/knews/ + +If you have questions concerning the precommands or if you want to have +certain features implemented into Knewsticker, please contact the +Knewsticker precommand scripts maintainer at dlanx@kde.org, who will talk to +the Knewsticker author for you, or contact him directly at raabe@kde.org. + +Thank you. diff --git a/knewsticker-scripts/Generic.Newsticker.Error b/knewsticker-scripts/Generic.Newsticker.Error new file mode 100644 index 0000000..b6d1341 --- /dev/null +++ b/knewsticker-scripts/Generic.Newsticker.Error @@ -0,0 +1,134 @@ +This file is roughly based on your systems errno.h. +Many perl errors can be exported as errors defined in errno.h by doing the + following: +use Errno qw(EINTR EIO :POSIX); +or simply use Errno. + +The semantics of this file are as follows: + A numerical error code followed by a human readable upper case short definition, which is followed by an +explanation of the actual error code. +We assume, that the interpreter you use returns an +error code of 1 upon failing to execute your script and an error code of 0 if +the execution is successful. This does NOT include any data passed from +the script or any errors which might occur during runtime, it is simply a +way for us to determine wheter your script started at all and if any more +output should be expected. +Some of the errors described below can be categorized, those categories range +from warning over critical to fatal. +An error which would terminate your script and therefore close the running +process, would be considered as fatal. +An error which would prevent your script from sending valid output, yet +not terminate its process would be considered as critical. Any other +error is considered as warning. A warning is always +OPTIONAL, critical errors and fatal errors MUST be implemented + +Depending on which script language or programming language you use it is +up to you, to determine wheter an error is fatal, critical or just a warning, +some suggestions have been made in the list below. +Generic and system error section: +0 NOERR No error has been detected +1 EPERM The operation is not permitted by the executing program. + Which means, that some fatal error occurred and + your script could not even be started. +2 ENOENT A file or directory your script wanted to read or write + could not be found and the scripts operation was + hampered by that. +5 EIO There has been an error while your script + attempted to read or write data +7 E2BIG If your scripts accepts arguments at the command + line, this error means, that too many arguments + were entered. This error code is not in + effect yet. +8 ENOEXEC If your script relies on system level programs and that + program could not be executed, use this + error code to report that to + knewsticker. This is an informational + error code and not necessarily a fatal + one +13 EACCESS permission to a resource or file has been denied to + your script, which does not allow it to + properly function, this error is fatal + and should be followed at once by + and exit code of 1 +19 ENODEV A device you are trying to write to is not + available, as above this error code is + fatal, it should be followed by an exit + code of 1 to terminate your scripts + operation. +28 ENOSPC There is no more space left on the device you are + trying to write a temporary file to. +30 EROFS You are trying to write a temporary file to an + read only file system +38 ENOSYS Your script tried to call a function which was not + implemented or it is trying to access an + external resource which does not exist. + You can also use this error code when + you are writing a perl script and the + modules functions you are trying to + access is not present. +61 ENODATA Your script has not been able to retrieve any data. + Thus no XML can be returned. This error + is critical, yet not necessarily fatal. +--------------------------------------------------------- +Network related errors. +64 ENONET The machine you are using is not connected to a + network. This error is fatal +71 EPROTO Your script tried to access a protocol which is not + implemented. This would mean, that you + are trying to use SNMP on a system that + does not understand it +89 EDESTADDRREQ Your script requires for the user to enter a destination + address to retrieve data from. + This error is used when that has + not been done. It is + informational yet fatal + to the script +94 ESOCKTNOSUPPORT Your script is trying to use a socket type not supported + by the system, for + example trying to open a + unix socket of a + system where this is not + supported +101 ENETUNREACH The network you are trying to access is + unreachable +102 ENETRESET The network you were trying to access dropped the + connection with a reset +104 ECONNRESET The connection you had has been reset by your peer +110 ETIMEDOUT The connection you were trying to establish timed out +111 ECONNREFUSED The connection you were trying to established has been refused +112 EHOSTDOWN The host you are trying to reach is down +113 EHOSTUNREACH The host you are trying to reach is unreachable, no route + to host +Please NOTE that above error codes ONLY correspond to the error numbers defined +on Linux i386 machines if you wish to use the Perl method mentioned. +The error codes which are mentioned above are _reserved_ for newsticker internal +use and have not necessarily anything to do with the error codes returned by +your system. + +---------------- +Since we are possibly dealing often with HTTP error codes this is a specialized +section you may use to return errors based on that protocol. +These error codes correspond to the actual HTTP error codes, thus enabling +you to handle them easier when passing them on to Knewsticker. +Client errors: +400 EBADREQ Bad Request. Your script sent a bad request, not + understood by the server, which is + reporting this back to you. +401 ENOAUTH No authorization has been issued for an area that needs + some form of authorization before it can + be accessed +402 EMUSTPAY You cannot access the data without paying for it, this + is not a bogus error, it is defined as + such in the http protocol +403 EFORBIDDEN You are forbidden to access the source you requested +404 ENOTFOUND The data you tried to access could not be found. +408 ETIMEOUT Your HTTP request timed out, this is an error which + reflects timeouts for the HTTP protocol + ONLY. Generic time outs are handled in + the above paragraph +Server errors: +500 ESERVERE A server error has been encountered. +505 EHTTPNOSUP The HTTP protocol version you attempted to use was not + understood by the http server or source + you were trying to access +------------------- diff --git a/knewsticker-scripts/Makefile.am b/knewsticker-scripts/Makefile.am new file mode 100644 index 0000000..7fb55f1 --- /dev/null +++ b/knewsticker-scripts/Makefile.am @@ -0,0 +1,7 @@ +scriptdir = $(kde_datadir)/knewsticker/scripts +script_DATA = Generic.Newsticker.Error Readme.ErrorHandling \ + fyensget.py \ + stock.pl Readme.stock \ + newsrss.pl Readme.newsrss \ + bbc.pl \ + sportscores.py diff --git a/knewsticker-scripts/README.kataribe b/knewsticker-scripts/README.kataribe new file mode 100644 index 0000000..eb3a281 --- /dev/null +++ b/knewsticker-scripts/README.kataribe @@ -0,0 +1,44 @@ +Kataribe Readme + +Kataribe is a more or less simple script to turn your Mbox into an RSS file, +so that you may display the subject and from in your Knewsticker. This +script uses a set of Perl modules to access the mail box. The standard mail +box format which I assume is the classic UNIX Mbox format. The script is +rather flexible though and if you wish to adjust the script to fit your +mailbox's needs, please be my guest. You can find a list of classes, which +are supported by the module here: +http://search.cpan.org/search?mode=module&query=Mail%3A%3ABox + +The following list of modules must be installed in order for this script to +work: + +Data::Dumper; +Date::Format; +Mail::Box; +Mail::Box::Manager; +MIME::Words + +Make sure, that you set the $limit variable in the top section of the +script. Parsing a Mbox file is not highly efficient and parsing a huge Mbox +file over and over can be very time consuming. This might cause the script +to time out and not report any data back to KNewsticker. By default only the +_newest_ ten messages are read and displayed as RSS. + +This script tries to be smart about the From header, yet might not always +guess right. The script assumes to find a from in the form of: + +A name <a@email.de> + +It will try to display the A name part in Knewsticker along with the subject +of the mail messages. If the script cannot find a name, it will try to use +the email address instead. + +I realize, that there are still several issues, which could be adressed and +the script surely is not 100% feature complete, but it is operational for +those, who wish to have a quick overview about the new mail, which might +have been dumped into their local account using fetchmail or any other +delivering service. + +This IS a work in progress, it has been tested by the author but not by any +other, so please make sure to do so and report back to bio@gmx.de. Thank +you. diff --git a/knewsticker-scripts/Readme.ErrorHandling b/knewsticker-scripts/Readme.ErrorHandling new file mode 100644 index 0000000..f8d2999 --- /dev/null +++ b/knewsticker-scripts/Readme.ErrorHandling @@ -0,0 +1,19 @@ +Error Handling for Knewsticker Pre commands + +Error handling might not be a prerequisite for writing Knewsticker scripts, +yet it would be nice if you tried to introduce some comprehensive error +handling in your scripts. Knewsticker is a graphical application and as such +the user is not able to read any error output your program might produce. +Knewsticker knows a variety of error codes and each is handled in a +different way. You may look those codes up in the table provided. + +Please make sure to return those error codes properly for the development +language you are trying to use. If you are trying to use Perl, please make +sure you understand an have read the top most part of the error handling +document. It will explain to you, how it is fairly easy to catch errors and +report them back to Knewsticker. + +If you are still unsure how to do it on a system level, simply implement +your own error handling and make sure, that your return codes match the +event(s) described in the error handling document you will find in CVS as +well. diff --git a/knewsticker-scripts/Readme.newsrss b/knewsticker-scripts/Readme.newsrss new file mode 100644 index 0000000..bb434e0 --- /dev/null +++ b/knewsticker-scripts/Readme.newsrss @@ -0,0 +1,48 @@ +This Readme is meant to describe how you should go about using the news to +RSS script. Please keep in mind, that all software retrieved from CVS is in +a constant change; your script might work now, but it might not work a +moment later. + +Even though the script can handle multiple newsgroups at once, Knewsticker +has not been adjusted to handle such a behavior on its own, therefore please +poll only one newsgroup per executed script. + +You need to customize each executed script to fit your needs, yet before you +can do so, you must be sure, that the version of perl you are running is +providing all the necessary modules for this script to function. You need to +have the following modules installed: + +News::NNTPClient; +MIME::Words + +If you are not sure wheter those are installed, simply execute the script at +the command line and watch for possible errors. Right now the script has no +error handling whatsoever, which might be corrected in future versions. You +can either go and retrieve the modules from www.cpan.org and install them by +hand or run the following command as root, while you are connected to the +Internet: + +perl -MCPAN -e "install module::name" + +Executing this command at the prompt will automatically download and install +the requested module, eventual dependencies will be resolved automatically. + +Once you have installed all the necessary tools, you can start customizing +your script, this means, that you should open it with your favourite editor +and read the comments above each variable you must set carefully. + +Most scripts are commented rather precisely, as it is the case with this +one. Of course you may set which nntp host we are connecting to within the +script, but if you have a host set in /etc/nntpserver the script will ALWAYS +default to that server, this has been implemented for systems, where the +administrator might not wish you to use a different nntp server. Of course +it can be evaded, but we urge you to be polite and use what is offered to +you by the system. + +Once you are sure you have set all the variables as requested in the scripts +upper part, you may now store it anywhere on your hard disk. Make sure you +have read knewstickers help on executing pre commands. + +Enjoy this script. + +anonymous coder. diff --git a/knewsticker-scripts/Readme.stock b/knewsticker-scripts/Readme.stock new file mode 100644 index 0000000..06b3d8d --- /dev/null +++ b/knewsticker-scripts/Readme.stock @@ -0,0 +1,36 @@ +This Readme is meant to describe how you should go about using the +Stockticker to RSS script. Please keep in mind, that all software retrieved +from CVS is in a constant change; your script might work now, but it might +not work a moment later. + +You need to customize each executed script to fit your needs, yet before you +can do so, you must be sure, that the version of perl you are running is +providing all the necessary modules for this script to function. You need to +have the following module(s) installed: + +Finance::Quote + +If you are not sure wheter those are installed, simply execute the script at +the command line and watch for possible errors. Right now the script has no +error handling what so ever, which might be corrected in future versions. +You can either go and retrieve the modules from www.cpan.org and install +them by hand or run the following command as root, while you are connected +to the Internet: + +perl -MCPAN -e "install module::name" + +Executing this command at the prompt will automatically download and install +the requested module, eventual dependencies will be resolved automatically. + +Once you have installed all the necessary tools, you can start customizing +your script, this means, that you should open it with your favourite editor +and read the comments above each variable you must set carefully. Most +scripts are commented rather precisely, as it is the case with this one. + +Once you are sure you have set all the variables as requested in the scripts +upper part, you may now store it anywhere on your hard disk. Make sure you +have read knewstickers help on executing pre commands. + +Enjoy this script and READ the commentary within it.. + +anonymous coder. diff --git a/knewsticker-scripts/bbc.pl b/knewsticker-scripts/bbc.pl new file mode 100755 index 0000000..78cb4e3 --- /dev/null +++ b/knewsticker-scripts/bbc.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl +=cut + +Copyright (c) 2001 Malte Starostik <malte@kde.org> + +Unlimited use, modification and distribution granted as long as the above +copyright statement and this sentence remain intact. + +=cut + +use strict; +use LWP::Simple; + +print <<'EOT'; +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" + "http://my.netscape.com/publish/formats/rss-0.91.dtd"> +<rss version="0.91"> +<channel> +<title>BBC News Headlines</title> +<description>News from the BBC</description> +<language>en-gb</language> +EOT + +my ($secnum, $section, $headline, $url); +foreach (split /\r?\n/, get "http://tickers.bbc.co.uk/tickerdata/story2.dat") +{ + $secnum = $1, $section = '' if (/^STORY ([\d+])/ && $1 != $secnum); + if (/^HEADLINE (.+)/) + { + next if $1 =~ /Last update/; + $headline = $1; + $headline =~ s/&/&/g; + $headline =~ s/</</g; + $headline =~ s/>/>/g; + $headline =~ s/"/"/g; + $section = $headline, $section =~ s/\s*\d+ (Ja|Fe|Ma|Ap|Ju|Au|Se|Oc|No|De)\S+ \d+$// unless $section; + } + if (/^URL (.+)/) + { + $url = $1, $url =~ s/&/&/g; + print <<EOT +<item> +<title>$headline ($section)</title> +<link>$url</link> +</item> +EOT + } +} + +print <<'EOT'; +</channel> +</rss> +EOT diff --git a/knewsticker-scripts/fyensget.py b/knewsticker-scripts/fyensget.py Binary files differnew file mode 100755 index 0000000..3f60a0b --- /dev/null +++ b/knewsticker-scripts/fyensget.py diff --git a/knewsticker-scripts/kataribe.pl b/knewsticker-scripts/kataribe.pl new file mode 100755 index 0000000..5cd483c --- /dev/null +++ b/knewsticker-scripts/kataribe.pl @@ -0,0 +1,96 @@ +#!/usr/local/bin/perl -w +use Data::Dumper; +use Date::Format; +use Mail::Box; +use Mail::Box::Manager; +use MIME::Words qw(:all); + +use constant TIMEZONE => 'MEST'; +#Set your mailbox's FULL path within the "" right here +$mbox = "/var/mail/codexx"; +#Set the amount of emails you wish to read. If you set this +# value to 5, the script will try to read the 5 most CURRENT +# messages from your INBOX. +# I advise you NOT to use more than 25 here, since parsing a huge +# inbox can take a very long time! +my $limit = 5; + +#STOPSTOPSTOPSTOPSTOPSTOP +#if the maiblox file is not existant return ENOENT +if (!-e $mbox) { +exit 2; +} +#if we do not have access to read from that mailbox return EACCESS +if (!-r $mbox) { +exit 13; +} + + + +my $mgr = Mail::Box::Manager->new; +my $folder = $mgr->open( + folder => $mbox, + ) or exit 61; #if we cannot open the mailbox we will not be able to + #return any data, so exit with ENODATA + +$mgr->registerType( + mbox => 'Mail::Box::Mbox' + ); + +my $number_of_emails = $folder->messages; +if ($number_of_emails < $limit) { +$boundary = ($number_of_emails+10)-$number_of_emails; +} +else { +$boundary = 0; +} + + +print "<?xml version=\"1.0\"?>\n<\!DOCTYPE rss PUBLIC \"-//Netscape + Communications//DTD RSS 0.91//EN\" + \"http://my.netscape.com/publish/formats/rss-0.91.dtd\">\n<rss + version=\"0.91\">\n"; +print "<title> RSS file </title>\n<link>http://www.kde.org</link>\n<description>This +is an automatically generated file using the NNTP to RSS generator for +Knewsticker.</description>\n<language>en-us</language>\n"; +print "<channel>\n"; + +my (@from, @time, @subject, @size, @from_email); + +foreach ($boundary .. $number_of_emails - 1) { + + chomp($subject[$_] = $folder->message($_)->head->get('subject')); +# $size[$_] = $folder->message($_)->size; +# $size[$_] = $size[$_] / 1024; +# $size[$_] = substr($size[$_],0,5) ."kb"; + chomp($from[$_] = $folder->message($_)->head->get('from')); + $time[$_] = time2str('%a %b %e', $folder->message($_)->timestamp, TIMEZONE); + + ($from_email[$_]) = ($from[$_] =~ /([^<]*)/); + ($from[$_]) = ($from[$_] =~ /<([^>]*?)>/); + defined($from_email[$_]) or $from_email[$_] = $from[$_]; +for ($subject[$_], $from[$_]) { + + s{&}{&}g; + s{\(}{(}g; + s{\)}{)}g; + #s{@}{@}g; + s{<}{<}g; + s{>}{>}g; + + }; +for ($subject[$_]) { +decode_mimewords($_); +} + + print<<EOT; + +<item> +<title> Mail from: $from_email[$_] concerning $subject[$_] sent at $time[$_]</title> +<link>mailto://$from[$_]</link> +<description></descrition> +</item> +EOT + +}; +print "</channel>\n</rss>\n"; diff --git a/knewsticker-scripts/newsrss.pl b/knewsticker-scripts/newsrss.pl new file mode 100644 index 0000000..7bfade3 --- /dev/null +++ b/knewsticker-scripts/newsrss.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl -w + +# This file is not released under any specific License. All Licenses, which +# might be requirered by knewsticker are explicitly accepted by the author +# whenver this file comes with knewsticker. +# Commonly this file simply underlies the regulations of international +# copyright. This file is copyrighted by anonymous coder .< bio@gmx.net>, A lot +# of help has been offered to me by malte, so thank him as well + + +use News::NNTPClient; +use POSIX qw(strftime); +use MIME::Words qw(:all); + +# Enter your newsserver here, or set it in your /etc/nntpserver +$host = "news.chello.at"; + +#set EVERY group you wish to check here. Make sure you seperate them by one +#whitespace only. At present Knewsticker only handles ONE group per file, so +#please DO NOT SET MORE THAN 1 GROUP. It will break this scripts functionality +@groups = qw(at.linux); + +#Specify here how many articles should be checked for EACH group you entered. +#The default value is 10. which means the newest 10 subjects are displayed +$get=10; + +# STOP do NOT continue unless you KNOW what you are doing +# STOP STOP STOP STOP STOP STOP STOP STOP STOP +for my $group (@groups) { +$head ="<?xml version=\"1.0\"?>\n<\!DOCTYPE rss PUBLIC \"-//Netscape + Communications//DTD RSS 0.91//EN\" + \"http://my.netscape.com/publish/formats/rss-0.91.dtd\">\n<rss + version=\"0.91\">\n"; +$static="<title> " . $group . " RSS file + </title>\n<link>http://www.kde.org</link>\n<description>This +is an automatically generated file using the NNTP to RSS generator for +Knewsticker.</description>\n<language>en-us</language>\n"; + +print $head; +print "<channel>\n"; +print $static; +$now_string = strftime "%a, %d %b %Y %H:%M:%S %z", localtime; +print "<pubDate>" . $now_string . "</pubDate>\n"; + +sub read_etc_nntpserver { +my $rc; + open(FH, '</etc/nntpserver') || return undef; + $rc = scalar(<FH>); + close(FH); + $rc =~ s/\s*$//; + return $rc || undef; +} +$t = read_etc_nntpserver(); +if(!defined $t) { +$t = $host; +} + +$c = new News::NNTPClient($t); + +(undef, $last) = ($c->group($group)); +$thislast = ($last-$get); + +@b = map { $_ = decode_mimewords $_ } $c->xhdr("Subject", $thislast, $last); +@c= map { s/&/&/g; s/\(/(/g; s/\)/)/g; s/@/@/g; s/</</g; + s/>/>/g; $_ } @b; +foreach (@c) { /(\d+)\s*(.*)\s*/ and $postings{$1} = {'subject' => $2}; } + +@b = map { $_ = decode_mimewords $_ } $c->xhdr("From", $thislast, $last); +@c= map { s/&/&/g; s/\(/(/g; s/\)/)/g; s/@/@/g; s/</</g; + s/>/>/g; $_ } @b; +foreach (@c) { /(\d+)\s*(.*)\s*/ and $postings{$1}->{'from'} = $2; } + +@b = $c->xhdr("Message-ID", $thislast, $last); +@c= map { s/&/&/g; s/\(/(/g; s/\)/)/g; s/</</g; s/>/>/g; $_ } + @b; +foreach (@c) { /(\d+)\s*(.*)\s*/ and $postings{$1}->{'message-id'} = $2; } + +for ($i = $thislast; $i != $last+1; $i++) { +@b = $c->body($i); +@c= map { s/&/&/g; s/\(/(/g; s/\)/)/g; s/</</g; s/>/>/g; $_ } + @b; +@d= (grep !/^$/, @c)[0..3]; +foreach (@d) { $postings{$i}->{'body'} .= $_ ; } + +} + +foreach my $id (sort keys %postings) +{ + print "<item>\n"; + print "<title>" . $postings{$id}->{'subject'} . + "</title>\n"; + print "<link>nntp://" . $t ."/" . $group ."/" . + $postings{$id}->{'message-id'} ."</link>\n"; + print "<description> This article has been posted by " . +$postings{$id}->{'from'} . " containing:\n " . $postings{$id}->{'body'} +. "</description>\n</item>\n"; +} +print "</channel>\n</rss>\n"; +%postings =(); +} diff --git a/knewsticker-scripts/sportscores.py b/knewsticker-scripts/sportscores.py new file mode 100755 index 0000000..ce9d04d --- /dev/null +++ b/knewsticker-scripts/sportscores.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python +import string, urllib, sys + +if len(sys.argv) > 1: + sport = sys.argv[1] +else: + sport = "NHL" # Must be one of NHL, NBA, MLB + +class SportsParser: + def __init__(self): + print "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>" + print "<rdf:RDF" + print "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"" + print "xmlns=\"http://my.netscape.com/rdf/simple/0.9/\">" + print "<channel>" + print "<title>%s</title>" %self.title() + print "<description>%s</description>" %self.description() + print "<link>%s</link>" %self.link() + print "</channel>" + self.processScores(self.inputFile()) + print "</rdf:RDF>" + + def processScores(self, inputFile): + try: + input = urllib.urlopen(self.inputFile()) + lines = input.readlines() + except: + sys.exit(5) + + for line in lines: + if self.isScoreLine(line): + self.handleScoreLine(line) + + def handleGame(self, headline, link): + print "<item>" + print "<title>%s</title>" %headline + print "<link>%s</link>" %link + print "</item>" + +class NHLParser(SportsParser): + def isScoreLine(self, line): + if line.startswith("nhl_scores_current[") or line.startswith("nhl_scores_previous["): + return 1 + else: + return 0 + + def handleScoreLine(self, line): + __line = string.strip(line) + __line = string.split(__line, "|") + __date = __line[1] + __dayOfWeek = __line[3] + __teamA = __line[4] + __teamB = __line[5] + __teamAAbbr = __line[7] + __teamBAbbr = __line[8] + __gameState = __line[9] + __hour = int(__line[10]) + __minutes = int(__line[11]) + __timeZone = __line[12] + __scoreA = __line[13] + __scoreB = __line[15] + if __gameState == "pre-game": + self.handleGame("%s at %s (%i:%02i %s)" %(__teamAAbbr, __teamBAbbr, __hour, __minutes, __timeZone), self.link()) + elif __gameState == "Final": + self.handleGame("%s %s %s %s (Final)" %(__teamBAbbr, __scoreB, __teamAAbbr, __scoreA), self.link()) + # I'm tired of wget'ing the HTML file just to wait for an in-progress + # entry. Moo. + + def inputFile(self): + return "http://sports.excite.com/nhl/index.html" + + def title(self): + return "NHL Scores" + + def description(self): + return "Official scores from the National Hockey League" + + def link(self): + return "http://sports.excite.com/nhl" + +class NBAParser(SportsParser): + def isScoreLine(self, line): + if line.startswith("nba_scores_current[") or line.startswith("nba_scores_previous["): + return 1 + else: + return 0 + + def period(self, period): + if period > 5: + return "%sOT" %(period - 4) + elif period == 5: + return "OT" + elif period == 4: + return "4th" + elif period == 3: + return "3rd" + elif period == 2: + return "2nd" + elif period == 1: + return "1st" + + def handleScoreLine(self, line): + __line = string.strip(line) + __line = string.split(__line, "|") + + date = __line[1] + dayOfWeek = __line[3] + homeTeam = __line[4] + awayTeam = __line[5] + homeTeamAbbrev = __line[7] + awayTeamAbbrev = __line[8] + hourUpdated = int(__line[10]) + minuteUpdated = int(__line[11]) + timeZoneUpdated = __line[12] + homeTeamScore = __line[13] + try: + period = int(__line[14]) + except: + period = 0 + awayTeamScore = __line[15] + minutesRemaining = __line[16] + secondsRemaining = __line[17] + + headline = "" + if __line[9].count("pre") > 0: + # game hasn't started yet, print time it starts + headline = "%s at %s (%s:%02i %s)" %(awayTeamAbbrev, homeTeamAbbrev, hourUpdated, minuteUpdated, timeZoneUpdated) + elif __line[9].count("inal") > 0: + # game over + headline = "%s %s %s %s" %(awayTeamAbbrev, awayTeamScore, homeTeamAbbrev, homeTeamScore) + if period > 4: + headline += " (%s)" %self.period(period) + else: + headline += " (Final)" + else: + # game in progress + minutesRemaining = int(minutesRemaining) + secondsRemaining = int(secondsRemaining) + headline += " %s %s %s %s" %(awayTeamAbbrev, awayTeamScore, homeTeamAbbrev, homeTeamScore) + headline += " (%i:%02i %s)" %(minutesRemaining, secondsRemaining, self.period(period)) + + self.handleGame(headline, self.link()) + + def inputFile(self): + return "http://sports.excite.com/nba/index.html" + + def title(self): + return "NBA Scores" + + def description(self): + return "Official scores from the National Basketball Association" + + def link(self): + return "http://sports.excite.com/nba" + +class MLBParser(SportsParser): + def isScoreLine(self, line): + if line.startswith("mlb_scores_current[") or line.startswith("mlb_scores_previous["): + return 1 + else: + return 0 + + def inning(self, inning): + # I wonder if there's some nice i18n-friendly way to do this + if inning > 3: + return "%sth" %(inning) + elif inning == 3: + return "3rd" + elif inning == 2: + return "2nd" + elif inning == 1: + return "1st" + + def handleScoreLine(self, line): + __line = string.strip(line) + __line = string.split(__line, "|") + + date = __line[1] + dayOfWeek = __line[3] + homeTeam = __line[4] + awayTeam = __line[5] + homeTeamAbbrev = __line[7] + awayTeamAbbrev = __line[8] + try: + hourUpdated = int(__line[10]) + except: + hourUpdated = 0 + try: + minuteUpdated = int(__line[11]) + except: + minuteUpdated = 0 + timeZoneUpdated = __line[12] + homeTeamScore = __line[13] + try: + inning = int(__line[14]) + except: + inning = 0 + awayTeamScore = __line[15] + minutesRemaining = __line[16] + secondsRemaining = __line[17] + + headline = "" + if __line[9].count("pre") > 0: + # game hasn't started yet, print time it starts + headline = "%s at %s (%s:%02i %s)" %(awayTeamAbbrev, homeTeamAbbrev, hourUpdated, minuteUpdated, timeZoneUpdated) + elif __line[9].count("inal") > 0: + # game over + headline = "%s %s %s %s" %(awayTeamAbbrev, awayTeamScore, homeTeamAbbrev, homeTeamScore) + if inning > 4: + headline += " (%s)" %self.inning(inning) + else: + headline += " (Final)" + else: + # Game in progress + # TODO: find out if it's the top or bottom of the inning + # Need to wget while a game's in progress to see. + headline += " %s %s %s %s" %(awayTeamAbbrev, awayTeamScore, homeTeamAbbrev, homeTeamScore) + headline += " (%s)" %(self.inning(inning)) + + self.handleGame(headline, self.link()) + + def inputFile(self): + return "http://sports.excite.com/mlb/index.html" + + def title(self): + return "MLB Scores" + + def description(self): + return "Official scores from Major League Baseball" + + def link(self): + return "http://sports.excite.com/mlb" + +try: + parser = globals()["%sParser" %(sport)]() + +except: + print "Invalid sport type '%s' selected." %sport + sys.exit(2) + +sys.exit(0) diff --git a/knewsticker-scripts/stock.pl b/knewsticker-scripts/stock.pl new file mode 100755 index 0000000..9e07adf --- /dev/null +++ b/knewsticker-scripts/stock.pl @@ -0,0 +1,276 @@ +#!/usr/bin/perl +############################################################################### +# getstockquote.pl - Retrieves stock data for given ticker symbol(s) +# +# Purpose: This script returns a nicely formatted HTML table containing stock +# data for ticker symbols given as command line arguments. This +# script can be used from a server-side exec (it's orginal use) or +# via a call from a regular CGI script. It could also be called from +# PHP, but I haven't tested this. The script prints its results on +# STDOUT. +# Usage: READ AT THE VERY END OF THIS COMMENT BLOCK +# The "quote_source" value can can any of the following: +# yahoo: NYSE quotes +# yahoo_europe: Europe quotes +# fidelity: Fidelity Investments Quotes +# troweprice: Quotes from T. Rowe Price +# vanguard: Quotes from Vanguard Group +# asx: Australian quotes from ASX +# tiaacref: Annuities from TIAA-CREF. +# Requires: Script requires at least perl 5.005, patch 3. +# Script must have the Finance::Quote module installed. This module +# in turn requires the LWP modules (which in turn have their own +# reqs). See CPAN for exact requirements for LWP: +# http://www.perl.com/CPAN-local//modules/by-module/LWP/ +# Or you can simply type as root user +# perl -MCPAN -e "install Finance::Quote" +# All dependancies will be resolved automatically then +# Origina Author: William Rhodes <wrhodes@27.org> +# Copyright (C) 2000 William Rhodes <wrhodes@27.org>. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# The information that you obtain with this script may be copyrighted by Yahoo! +# Inc., and is governed by their usage license. See +# http://www.yahoo.com/docs/info/gen_disclaimer.html for more information. +# +# The information that you obtain with this script may be copyrighted by the +# ASX, and is governed by its usage license. See +# http://www3.asx.com.au/Fdis.htm for more information. +# +# The information that you obtain with this script may be copyrighted by +# TIAA-CREF, and is governed by its usage license. +# +# Other copyrights and conditions may apply to data fetched via this script. +# +# Submitting changes back to the author is not required but certainly +# encouraged. Bug fixes are also greatly appreciated. +# +# +# This script has been altered by an anonymous coder to fit the Knewsticker +# needs. +# Please set your stock symbols and the ticker you wish to retrieve them from +# as follows: +# Locate the Variable that is named 'my @tickers' +# within the parenthesis put as the FIRST values you ticker, for example yahoo +# or yahoo_europe or any of the others mentioned above +# any subsequent value seperated by a whitespace is a ticker symbol +# such as MSFT or IBM or LNUX +# Make sure all data is set correctly then call this script from Knewsticker +############################################################################### + + +use Finance::Quote; +use POSIX qw(strftime); +# Set this to 1 if you wish to have VERY detailed stock quotes it is greatly +# encouraged, that you only use this when you have 1 stock symbol and not more. +my $verbose = 0; + +#Make sure you set the first value within the parenthesis to match the ticker +#you wish to retrieve data from, such as yahoo or yahoo_europe. Each following +#entry, seperated by a whitespace, represnts a stock symbol to the script +my @tickers = qw(yahoo_europe IBM MSFT LNUX); + +#------------------------------------------------------------------------------- +#STOP STOP STOP STOP only go on if you know what you are doing!! + +# Get rid of puncuation in @ARGV. This will filter out metacharacters and +# such, which makes the script marginally more safe +# +foreach (@tickers) { s/[^a-zA-Z0-9\-=_\.\^]//; } + +# Check the input to make sure we can look stuff up +# +@tickers = CheckInput(@tickers); + +# Get a new Finance::Quote object +# +my $quote_src = $tickers[0]; +my $quote = Finance::Quote->new; +# Override LWP's 120 second timeout, throw error if we time out +# Set this pretty short if using as a server-side exec +# +exit 110 unless ($quote->timeout(10)); + + +# Load the quotes hash for getting data +# +my %quotes = $quote->$quote_src(@tickers); + +# Start our RSS table output; get the ticker data, print it out +# +$head ="<?xml version=\"1.0\"?>\n<\!DOCTYPE rss PUBLIC \"-//Netscape + Communications//DTD RSS 0.91//EN\" + \"http://my.netscape.com/publish/formats/rss-0.91.dtd\">\n<rss + version=\"0.91\">\n"; + +$static="<title> " . $group . " RSS file + </title>\n<link>http://www.kde.org</link>\n<description>This +is an automatically generated file using the STOCK to RSS generator for +Knewsticker.</description>\n<language>en-us</language>\n"; + +shift(@tickers); +print $head; +print "<channel>\n"; +print $static; +$now_string = strftime "%a, %d %b %Y %H:%M:%S %z", localtime; +print "<pubDate>" . $now_string . "</pubDate>\n"; +for (@tickers) { print PrintData($_); } +print "</channel>\n</rss>\n"; + + +############################################################################### +# SUBROUTINES +############################################################################### + +# You have to specify a valid quote source and at least one ticker symbol +# If this script was a stand-alone CGI, it probably ought to use CGI::CARP to +# send errors to the browser. +# +sub CheckInput { + my @input = @_; + my ($src_name, $src_val, $src_err, $src_found); + my %ticker_src; + + $ticker_src{yahoo} = "NYSE quotes"; + $ticker_src{yahoo_europe} = "Europe quotes"; + $ticker_src{fidelity} = "Fidelity Investments Quotes"; + $ticker_src{troweprice} = "Quotes from T. Rowe Price"; + $ticker_src{vanguard} = "Quotes from Vanguard Group"; + $ticker_src{asx} = "Australian quotes from ASX"; + $ticker_src{tiaacref} = "Annuities from TIAA-CREF"; + + # Check for font size option + # + if ($input[0] =~ /\-\-fontsize=[1-6]/) { + $input[0] =~ s/\-\-fontsize=(\d)//; + $font_size = $1; + shift(@input); + } + + # Check for verbose, shift @input anyway + # + if ($input[0] =~ /\-\-verbose=yes/i) { + $verbose = 1; + shift(@input); + } elsif ($input[0] =~ /\-\-verbose=no/i) { + $verbose = 0; + shift(@input); + } + + # No quote source or symbols + # + if (!$input[0]) { + $src_err .= "$0: Error: No quote source given. Quote source must be one + of the following:<br>\n"; + while (($src_name, $src_val) = each(%ticker_src)) { + $src_err .= " $src_name - $src_val<br>\n"; + } + ReturnError("$src_err\n"); + } elsif (!$input[1]) { + ReturnError("$0: Error: No symbols given."); + } + + # Check for invalid quote source + # + $src_found = 0; + foreach $src_name (keys %ticker_src) { + if ($src_name eq lc($input[0])) { + $src_found = 1; + } + } + + # Throw an error unless we had a valid quote source + # + unless ($src_found) { + $src_err .= "$0: Error: Invalid quote source \"$input[0]\". "; + $src_err .= "Quote source must be one of the following:<br>\n"; + while (($src_name, $src_val) = each(%ticker_src)) { + $src_err .= " $src_name - $src_val<br>\n"; + } + ReturnError($src_err); + } + + # So everything matched, send out args back + # + return(@input); + +} # End CheckInput + + +# Return each ticker data in HTML table rows +# +sub PrintData { + my ($key, $value, $name, $output); + my %data; + my $ticker = shift || die "No ticker data given! $!\n"; + if ($quote_src ne "tiaacref") { + $ticker = uc($ticker); + } + + # Our hash of stuff that we want to return as table rows + # We have our default, and then add to it if $verbose is set + # + $data{a_Last_Price} = $quotes{"$ticker", "last"}; + $data{b_High} = $quotes{"$ticker", "high"}; + $data{c_Low} = $quotes{"$ticker", "low"}; + $data{g_Open} = $quotes{"$ticker", "open"}; + $data{h_Close} = $quotes{"$ticker", "close"}; + if ($verbose) { + $data{d_Change} = $quotes{"$ticker", "change"}; + $data{e_Last_Trade} = $quotes{"$ticker", "date"} . " at " . + $quotes{"$ticker", "time"}; + $data{b_High} = $quotes{"$ticker", "high"}; + $data{c_Low} = $quotes{"$ticker", "low"}; + $data{f_Volume} = $quotes{"$ticker", "volume"} . " shares"; + $data{i_Bid} = $quotes{"$ticker", "bid"}; + $data{j_Ask} = $quotes{"$ticker", "ask"}; + + # Volume needs commas to look good + # + $data{f_Volume} = reverse($data{f_Volume}); + $data{f_Volume} =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; + $data{f_Volume} = reverse($data{f_Volume}); + + } + $output = "<item>\n<title>\n $ticker Stock Symbol"; + foreach $key (sort keys %data) { + $name = $key; # Need to save $key for hash lookups + $name =~ s/^[a-z]_//; # Get rid of sorting characters + $name =~ s/_/ /g; # Get rid of underscores + $data{$key} = "N/A" if ($data{$key} eq ""); # Don't show empty values + + # We want at least two decimal places in some fields + # + if ($name =~ /Last|High|Low|Open|Close|Bid|Ask/i) { + $data{$key} =~ s/^(\d+$)$/$1\.00/; + $data{$key} =~ s/^(\d+\.\d)$/$1\0/; + } + + $output .= " $name $data{$key} "; + } + $output .= "\n"; + $output .="</title>\n<link>http://www.kde.org</link>\n</item>\n"; + return($output); +} # End GetData + + +# Prints a usage and error message to STDOUT, exits with -1 +# +sub ReturnError { + my $error = shift; + my $usage = "Usage: + Add the following options to \@tickers at the top of the script:<br> + [--fontsize=1..6] [--verbose=yes|no] + <quote_source> <ticker1> [ticker2] ...\n"; + print $error . "<br>" . $usage; + exit; +} # End ReturnError |