Open Source im professionellen Einsatz
Linux-Magazin 03/2009
©Claudia35, Pixelio.de

©Claudia35, Pixelio.de

Perl-Applets erweitern plattformunabhängiges Desktop-Panel

Hingucker für Spekulanten

Das eine Panel bringt pfiffige Applets mit, das andere hat eine spektakuläre Optik - aber alles Gute ist selten beisammen. Als Abhilfe bietet sich Perlpanel an. Plattformunabhängig ist es ganz nach dem eigenen Geschmack mit selbst geschriebenen Perl-Applets erweiterbar. Als Beispiel dient ein Börsenticker.

932

Ob Gnome oder KDE, jeder Desktop bietet so genannte Panels an. Sie schmiegen sich oben oder unten an den Bildschirmrand, beherbergen Menüs und Icons zum Starten von Programmen, zeigen laufende Applikationen mit Task-Bars an oder schalten zwischen virtuellen Desktops hin und her. Ziel des Projekts Perlpanel ist es, ein solches Panel plattformunabhängig bereitzustellen. Außerdem soll der Anwender es mit ein paar schnell zusammengeklopften Skripten um eigene Applets erweitern können.

Unter Ubuntu installiert der User dieses Panel mit »apt-get install perlpanel« und startet es probeweise mit dem Aufruf »/usr/bin/perlpanel«. Abbildung 1 zeigt am unteren Rand des Desktops das Panel-GUI. Belegt den Platz an der Bildschirmunterkante bereits ein anderes Panel, dann verlegt es der Anwender entweder an den rechten oder an den linken Rand oder er löscht es gleich ganz - falls er tatsächlich die Brücken hinter sich abbrechen möchte.

Abbildung 1: Perlpanel bietet die üblichen Funktionen wie virtuelle Desktops und Task-Bars, erlaubt aber auch selbst geschriebene Applets.

Aktien stets im Blick

Wer die Kurse seiner Aktien oder geplanter Erwerbungen laufend im Blick behalten möchte, ist womöglich mit einer einschlägigen Applikation nicht optimal bedient, weil andere Anwendungen deren Fenster im Zweifel verdecken. Stattdessen könnte ein Panel-Applet ideal für den Spekulanten sein, das es erlaubt, die aktuellen Kurse nie aus den Augen zu verlieren. Dafür könnte es etwa alle 5 Minuten die fraglichen Aktienwerte von Yahoo Finance abholen und anzeigen. (Ihre Namen entnimmt es einer lokalen Konfigurationsdatei »~/.ticker-rc« im Homeverzeichnis). Wie in Abbildung 2 demonstriert, ignoriert das Applet Kommentar- und Leerzeilen im Konfigurationsfile und erwartet pro Zeile ein Aktienkürzel. Abbildung 1 zeigt, wie es die vier ausgewählten Kurse im Panel auf den Desktop bringt.

Abbildung 2: Die Kurse der in »~/.ticker-rc« eingetragenen Aktien holt das Applet in regelmäßigen Abständen vom Yahoo-Server.

Das Einholen der Kurse vom Yahoo-Server erledigt das Skript »getquote« in Listing 1, das auf der Kommandozeile eine Reihe von Aktienkürzeln entgegennimmt und deren letzte Kurswerte zeilenweise ausgibt. Der eigentliche Applet-Code »Ticker.pm« ist in Listing 2 zu sehen. Das Applet liest einfach die Konfigurationsdatei ein, ruft im 5-Minuten-Rhythmus das Skript »getquote« auf und frischt mit den zurückgegebenen Werten seine Anzeige im Perlpanel auf. Falls der User mit der Maus auf das Applet klickt, ist er offensichtlich ungeduldig und möchte die neuesten Kurse, also fragt das Applet den Yahoo-Server dann sofort wieder an und frischt die Anzeige im Panel auf.

Listing 1:
»getquote«

01 #!/usr/local/bin/perl -w
02 use strict;
03 use Finance::YahooQuote;
04
05 $Finance::YahooQuote::TIMEOUT = 60;
06
07 exit 0 unless @ARGV;
08
09 my @quotes = getcustomquote(
10 [@ARGV],
11 ["Symbol", "Last Trade (Price Only)"]);
12
13 if(! exists $quotes[0][1]) {
14 die "Fetching quote failedn";
15 }
16
17 for my $quote (@quotes) {
18 print "@$quoten";
19 }

Listing 2:
»Ticker.pm«

001 ###########################################
002 package PerlPanel::Applet::Ticker;
003 use strict;
004 use Log::Log4perl qw(:easy);
005
006 my $REFRESH = 5 * 30_000;
007 my($CFG_FILE)= glob "~/.ticker-rc";
008 my $GETQUOTE = "/usr/bin/getquote";
009
010 Log::Log4perl->easy_init({
011 level => $DEBUG,
012 file => ">>/tmp/ticker.log",
013 });
014
015 ###########################################
016 sub new {
017 ###########################################
018 my($package) = @_;
019
020 my $self = {};
021 bless($self, $package);
022 return $self;
023 }
024
025 ###########################################
026 sub configure {
027 ###########################################
028 my($self) = @_;
029
030 $self->{label} =
031  Gtk2::Label->new("Ticker");
032
033 $self->{widget} = Gtk2::Button->new();
034 $self->{widget}->signal_connect(
035 'clicked', sub {
036  $self->stocks_update() });
037
038 $self->{widget}->set_relief('none');
039 $self->{widget}->add($self->{label});
040
041 $self->{widget}->show_all;
042
043 $self->stocks_update();
044
045 PerlPanel::add_timeout(5 * 60_000,
046 sub { $self->stocks_update() ;
047  return 1 });
048
049 return 1;
050 }
051
052 ###########################################
053 sub symbols {
054 ###########################################
055 my @symbols = ();
056
057 if(! open(FILE, "<$CFG_FILE")) {
058 ERROR "Cannot open $CFG_FILE";
059 return ();
060 }
061
062 while(<FILE>) {
063 s/#.*//g;
064 s/[^w.]//g;
065 next if /^s*$/;
066 chomp;
067 push @symbols, $_;
068 }
069
070 return @symbols;
071 }
072
073 ###########################################
074 sub stocks_update {
075 ###########################################
076 my ($self) = @_;
077
078 my($tag, $buffer);
079 my $symbols = join " ", symbols();
080
081 DEBUG "Updating '$symbols'";
082
083 if($symbols eq "") {
084 $self->{label}->set_markup(
085   "No symbols defined");
086 return undef;
087 }
088
089 if (!open(COMMAND,
090  "$GETQUOTE $symbols |")) {
091 $self->{label}->set_markup(
092   "Fetch failed ($!)");
093 ERROR "Fetch failed ($!)";
094 return undef;
095 }
096
097 $tag = Gtk2::Helper->add_watch(
098 fileno(COMMAND), 'in',
099 sub {
100 if (eof(COMMAND)) {
101  DEBUG "Received data: $buffer";
102  close(COMMAND);
103  Gtk2::Helper->remove_watch($tag);
104  $buffer =~ s/n/ /g;
105  $self->{label}->set_markup(
106     $buffer);
107 } else {
108  $buffer .= <COMMAND>;
109 }
110 });
111
112 return 1;
113 }
114
115 ###########################################
116 sub expand { return 0; }
117 sub fill { return 0; }
118 sub widget { return $_[0]->{widget} }
119 sub get_default_config { return undef; }
120
121 1;

Schnapp die Kurse

Die an »getquote« auf der Kommandozeile übergebenen Aktienkürzel liegen wie in Perl üblich im Array »@ARGV«. Das Modul Finance::YahooQuote holt mit der Funktion »getcustomquote()« die Kurse vom Yahoo-Server und gibt an, dass es nur an den Spalten »Symbol« (dem vorher bei der Anfrage angegebene Aktienkürzel) und »Last Trade (Price Only)« (dem letzten Börsenkurs) interessiert ist. Yahoo liefert sonst mit der Funktion »getquote()« einen ganzen Rattenschwanz an Daten, die das Applet aber nicht braucht und daher von vornherein ablehnt.

Passiert ein Fehler bei der Übertragung, kommt ein einzelner Wert mit einer Fehlermeldung zurück, während Yahoo im Erfolgsfall ein Array zurückliefert, dessen Einträge wiederum Referenzen auf Arrays mit den Einträgen zu Aktienkürzel und Kurs sind. Zeile 13 prüft daher, ob tatsächlich ein zweispaltiger Eintrag zurückkam, und bricht andernfalls sofort ab. Zeile 5 setzt noch einen Time-out von 60 Sekunden, der bei Netzwerkstörungen dafür sorgt, dass das Skript nicht ewig wartet. Über die Leitung eingetrudelte Kurswerte gibt die »for«-Schleife ab Zeile 17 im Format »Kürzel Kurs« zeilenweise auf der Standardausgabe aus.

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Kleine Mahlzeit

    Es muss nicht immer ein ausgewachsenes Programm sein. Viele kleine Aufgaben lassen sich auch mit Applets erledigen, die im Panel residieren und nur darauf warten, aufgerufen zu werden.

  • Tierische Kurssprünge

    Ein in Perl geschriebenes Pidgin-Plugin ignoriert dröge Börsentage, an denen die Kurse stillstehen, aber schlägt per Instant Message Alarm, falls die Aktien anfangen Achterbahn zu fahren.

  • Seid umschlungen, Millionen!

    Das Perl-Skript »dagobert« zeigt auf Kommando die aktuellen Vermögensverhältnisse seines Besitzers an. Es rechnet den Inhalt mehrerer Konten und Aktiendepots zusammen und gestattet es dem Anwender, eigene Plugins einzuhängen.

  • KDE veröffentlicht Plasma 5.9

    Die KDE-Entwickler haben eine neue Version ihrer beliebten Desktop-Umgebung Plasma mit zahlreichen kleineren Neuerungen veröffentlicht. Unter anderem gibt es globale Menüs, einen verbesserten Taskmanager und ein leicht überarbeitetes Design.

  • KDE Plasma 5.10 veröffentlicht

    Das KDE-Projekt hat eine neue Version seiner Desktop-Umgebung veröffentlicht. Plasma 5.10 enthält viele kleine, aber nützliche Änderungen. So nutzt die Arbeitsfläche ab sofort standardmäßig die Ordner-Ansicht („Folder View“).

comments powered by Disqus

Ausgabe 09/2017

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.