You are not logged in.

#1 2008-08-19 17:28:55

Xyne
Moderator/TU
Registered: 2008-08-03
Posts: 5,632
Website

Conky: scrolling package notifier using perl

This post looks bigger than it actually is. tongue Anyway, I hope this is clear... if not, just ask.

Majkhii's update notifier in python made me wonder if it would be possible to create a scrolling notifier in conky to display upgradable packages.  A scrolling notifier would be able to display all the packages within a defined space without having your conky layout stretched across the screen if the package list gets too long.

I did this mostly as a programming exercise but thought that someone might find it useful, so here it is. If nothing else, you have a little client-server script pair to play with. wink

The best way that I came up with to do this (read: least overhead without patching conky) is to run a server script in the background that keeps track of upgradable packages and then to let conky exec a client script to get info from the server script. This avoids invoking pacman with "pacman -Qu" each time the scrolling text updates.


Automatically Syncing Pacman
First, you need to automatically sync pacman at regular intervals. Save this script...

#!/bin/sh
/usr/bin/pacman -Sy

...as "sync_pacman" or whatever you want to call it. Then do this:

chmod 744 sync_pacman
mv sync_pacman /etc/cron.hourly/

Everything in the cron.hourly directory will get run automatically every hour (unless you've killed cron).


The Server
Save the server as "conkyPkgListServer" (or whatever), make it executable, then start it in the background by passing it a port and, optionally*, an update interval (in minutes). E.g.

conkyPkgListServer 64564 15 &

Add this to your autostart list if you have one.
This starts the server on port 64564 and tells it to update every 15 minutes (this server is running on localhost and should only be accessible on your computer, i.e. not to anyone else on your network).


The Client
Save the client as "conkyPkgListClient", make it executable, then put it where conky can find it.
To get the number of upgradable packages, add a line like this to your conky config:

${execi 900 conkyPkgListClient 64564}

Conky will execute the client every 15 minutes, connect to the server script on port 64564, and get the number of packages.

Now, the interesting part... the scrolling package list. There are 2 different styles: horizontal and vertical.

Vertical Scroll

----        ----        ----
pkgA        pkgB        pkgC
pkgB   ->   pkgC   ->
pkgC                    pkgA
            pkgA        pkgB
----        ----        ----

Horizontal Scroll/

----------        ----------        ----------
pkgA pkgB   ->    gA pkgB pk   ->    pkgB pkgC
----------        ----------        ----------

Add this to conky:

${execi <interval> conkyPkgListClient <port> <interval> <direction> <size>}

Replace "<port>" with the port number that you started the server on (64564 in the example above).
Replace "<interval>" with the update interval, in seconds.
Replace "<direction>" with "n","e","s", or "w" (for north, east, south, west, respectively). North and south create a vertical scroll moving up or down, resp., and east and west a horizontal scroll moving right or left, resp.
Replace "<size>" with either the number of lines to display for a vertical scroll or the number of characters to display for a horizontal scroll.

e.g.
7 lines showing a vertically scrolling package list that moves up 1 line every 2 seconds:

${execi 2 conkyPkgListClient 64564 2 n 7}

A single horizontally scrolling field 25 characters wide that moves left 1 character every 2 seconds:

${execi 2 conkyPkgListClient 64564 2 e 25}

SERVER SCRIPT

#!/usr/bin/perl
use strict;
use IO::Socket;

my ($port,$update_interval) = @ARGV;

my $n = 0;
my @pkgs;

my $sock = new IO::Socket::INET(
    LocalPort => $port,
    Listen => 1,
    Reuse => 1,
    Proto => 'tcp')
|| die "Error creating socket: $!";



sub receive ($)
{
    my ($client) = @_;
    my $received = '';
    READ: while(1)
    {
        my ($data, $output);
        while(sysread( $client, $data, 1 ))
        {
            $received .= $data;
            if ($received =~ m/\n$/)
            {
                chomp $received;
                last READ;
            }
        }
    }
    return $received;
}

sub send ($ $)
{
    my ($client,$data) = @_;
    print $client "$data\r\n";
    $client->flush;
    close($client);
}

sub getPkgList
{
    my $pkgs = `pacman -Qu`;
    my @lines = split "\n\n", $pkgs;
    if (scalar @lines > 1)
    {
        $pkgs = $lines[-2];
        $pkgs =~ s/\s*\n\s*/ /g;
        ($n,$pkgs) = $pkgs =~ m/^\S+\s\((\d+)\):\s(.+)$/;
        @pkgs = split /\s+/,$pkgs;
    }
}

sub getMarquee ($ $ $)
{
    my ($interval,$direction,$size) = @_;
    my $marquee = '';

    if ($direction eq 'n' or $direction eq 's')
    {
        if ($size > $n)
        {
            push @pkgs, ('') x ($size-$n);
            $n = $size;
        }

        if ($n > 0)
        {
            my $t = time;
            $t = int($t/$interval);
            my $i = $t % $n;
            for (1..$size)
            {
                $i = ($direction eq 'n' ? $i + 1 : $i - 1);
                if ($i >= $n or $i < 0)
                {
                    $i = $i % $n;
                }
                $marquee .= $pkgs[$i]."\n";
            }
        }
    }

    elsif ($direction eq 'e' or $direction eq 'w')
    {
        my $pkg_str = "@pkgs ";
        $n = length($pkg_str);
        if ($size > $n)
        {
            $pkg_str .= ' ' x ($size - $n);
            $n = $size;
        }

        if ($n > 0)
        {
            my $t = time;
            $t = int($t/$interval);
            $t = -$t if ($direction eq 'e');
            my $i = $t % $n;
            if ($i >= $n or $i < 0)
            {
                $i = $i % $n;
            }
            $marquee .= substr( substr($pkg_str,$i).substr($pkg_str,0,($i-length($pkg_str))), 0, $size);
        }
    }

    return $marquee;
}

&getPkgList;
$update_interval *= 60 if (defined($update_interval));
my $last_update = time;
while ( defined($sock) )
{
    my $client = $sock->accept();
    if (defined($update_interval) and (time-$last_update) > $update_interval)
    {
        &getPkgList;
        $last_update = time;
    }
    my $received = &receive($client);
    if ($received eq 'update')
    {
        &getPkgList;
        &send($client,$n);
    }
    if ($received =~ m/(\d+) ([nesw]) (\d+)/)
    {
        &send($client,&getMarquee($1,$2,$3));
    }
    else
    {
        &send($client,$n);
    }
}

CLIENT SCRIPT

#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;

my $port = shift;
my $message = "@ARGV\n";

my $sock = new IO::Socket::INET(PeerAddr => 'localhost',PeerPort => $port,Proto => 'tcp') || die "Error creating socket: $!";
print $sock $message;
$sock->flush;

sub receive ($)
{
    my ($client) = @_;
    my $received = '';
    READ: while(1)
    {
        my ($data, $output);
        while(sysread( $client, $data, 1 ))
        {
            $received .= $data;
            if ($received =~ m/\r\n$/)
            {
                $received =~ s/\r\n$//;
                last READ;
            }
        }
    }
    return $received;
}

print &receive($sock);
close($sock);

*If you skip the update interval, replace "${execi 900 conkyPkgListClient 64564}" with "${execi 900 conkyPkgListClient 64564 update}" to update the server script's package list each time conky execs the client.

Last edited by Xyne (2008-12-16 03:48:45)

Offline

#2 2008-08-19 18:05:05

Daenyth
Forum Fellow
From: Boston, MA
Registered: 2008-02-24
Posts: 1,244

Re: Conky: scrolling package notifier using perl

Wow, excellent work! Put in on the AUR! (And update your sig)

Offline

#3 2008-08-21 07:55:05

LeoSolaris
Member
From: South Carolina
Registered: 2008-03-30
Posts: 354

Re: Conky: scrolling package notifier using perl

Impressive!  I am still learning Arch, and appearently, Linux. I will get around to cron'ing pacman -Sy at some point. (hey it is only day two)

I will look forward to testing this out at some time other than 4 am.

Spent too much time setting Arch up....   must sleep....   class in morning...   grrr


I keep getting distracted from my webserver project...

huh? oooh...  shiny!

Offline

#4 2008-08-21 10:10:27

Xyne
Moderator/TU
Registered: 2008-08-03
Posts: 5,632
Website

Re: Conky: scrolling package notifier using perl

Daenyth wrote:

Wow, excellent work! Put in on the AUR! (And update your sig)

Thanks smile
I actually hadn't even considered sticking this one on the AUR. I'll put it up once I've decided on the final names for the scripts (and a package name), plus I'll need to figure out how to include instructions in the PKGBUILD (I have an idea, just need to test it).

LeoSolaris wrote:

Impressive!  I am still learning Arch, and appearently, Linux. I will get around to cron'ing pacman -Sy at some point. (hey it is only day two)
I will look forward to testing this out at some time other than 4 am.
Spent too much time setting Arch up....   must sleep....   class in morning...   grrr

And thanks smile

I added the part about cronifying sync (realized that there was no reason not to). I'm still a Linux/Arch noob too, so I only figured out how to cronify things when I was writing the scripts. tongue

Welcome to Arch!

Offline

#5 2008-08-22 16:46:35

LeoSolaris
Member
From: South Carolina
Registered: 2008-03-30
Posts: 354

Re: Conky: scrolling package notifier using perl

Thanks for the welcome! I really do like the community here, feels like Ubuntu's. (Ubuntu's strongest point)

I learned about it a month or so ago, and read up on it, but never used it.

I am definitely going to borrow that for my conky script.

Ya know, I just took a moment to read it over and about the end, I realized that you could add a 'u' to the end of the cron and have it update every hour....   only downside is it would leave ya kinda wondering what went wrong if something breaks your system.

Sticking it in conky does make more sense. I may like to keep my comp bleeding edge, but I would really like a fighting chance at unbreaking it.

Last edited by LeoSolaris (2008-08-22 16:47:56)


I keep getting distracted from my webserver project...

huh? oooh...  shiny!

Offline

#6 2008-08-23 01:45:06

ltpl4y3r
Member
Registered: 2008-08-23
Posts: 28

Re: Conky: scrolling package notifier using perl

Great script!

I've been hoping to find something like this, especially for conky!

Thanks!

Offline

#7 2008-12-09 09:46:53

intrados
Member
Registered: 2008-08-01
Posts: 12

Re: Conky: scrolling package notifier using perl

I don't know if it's just me but the script seems to only show a few of the packages that can be updated. The rest is just filled with spaces were packages should be. Any suggestions?

Offline

#8 2008-12-09 19:01:37

Xyne
Moderator/TU
Registered: 2008-08-03
Posts: 5,632
Website

Re: Conky: scrolling package notifier using perl

Do you mean that you have more packages waiting to be updated than displayed in the list? This is probably what's happening:

The server updates the pkg list: 3 new packages
The client is set to display 5 lines: 3 packages + 2 empty lines
2 new packages are released but don't show up immediately because the server is set to update the list at 15 minute intervals.
*a few minutes later*
The server updates the pkg list: 5 new packages
The client now displays 5 pkgs across 5 lines

You can reduce the server update interval if you think this is a problem.

Offline

#9 2008-12-09 23:19:53

intrados
Member
Registered: 2008-08-01
Posts: 12

Re: Conky: scrolling package notifier using perl

No. This is the list of packages I need updated: 
              asciidoc-8.3.0-1  clucene-0.9.21b-1  docbook-xsl-1.74.0-1  fftw-3.2-1  git-1.6.0.5-1  htop-0.8.1-1  hunspell-1.2.8-1  imlib2-1.4.2-2 
              jdk-6u11-1  jre-6u11-1  lesstif-0.95.0-3  libv4l-0.5.7-1  libxi-1.1.4-1  mutagen-1.15-1  pango-1.22.3-2  pciutils-3.0.3-1 
              perl-xml-libxml-1.69-1  perl-xml-libxslt-1.68-1  perl-xml-sax-0.96-1  picard-0.11-1  pm-utils-1.2.3-3  python-2.6.1-1  sqlite3-3.6.6.2-1 
              ttf-dejavu-2.27-1  vlc-0.9.8a-1  wavpack-4.50.1-1  wpa_supplicant-0.5.11-1  xorg-server-1.5.3-3  xvidcore-1.2.1-1 
But regardless of which direction I tell it to scroll, settings, etc: it only shows the first 3 and the rest is filled with empty space.

2008-12-09-182622_3040x1200_scrot.jpg

Offline

#10 2008-12-09 23:28:39

Xyne
Moderator/TU
Registered: 2008-08-03
Posts: 5,632
Website

Re: Conky: scrolling package notifier using perl

EDIT 2
I've updated the server script. Try the new one and let me know if it fixes the problem.

Last edited by Xyne (2008-12-09 23:41:28)

Offline

#11 2008-12-10 00:51:03

intrados
Member
Registered: 2008-08-01
Posts: 12

Re: Conky: scrolling package notifier using perl

That fixed it. Thanks.

Offline

#12 2008-12-16 03:34:49

sabooky
Member
Registered: 2006-11-02
Posts: 89

Re: Conky: scrolling package notifier using perl

The way the script parses the output of `pacman -Qu` could cause some problems.

Here's my `pacman -Qu` output when I enable the testing repo.

# pacman -Qu
Checking for package upgrades... 
warning: emerald-themes-git: local (20080612-1) is newer than compiz-fusion (20080524-1)
warning: jdk: local (6-2) is newer than community (6u11-1)

Remove (1): bluez-libs-3.32-1  

Total Removed Size:   0.31 MB

Targets (73): bluez-4.1-1  audacity-1.3.6-2  bash-3.2.048-1  binutils-2.19-1  bison-2.4.1-1  ca-certificates-20080809-5  cheese-2.24.2-2  cups-1.3.9-3  
              cvs-1.11.23-3  devilspie-0.22-3  dhcpcd-4.0.7-1  dsniff-2.4b1-13  ettercap-NG_0.7.3-11  ettercap-gtk-NG_0.7.3-5  evince-2.24.2-2  
              evolution-data-server-2.24.2-2  flashplugin-10.0.12.36-4  gcc-4.3.2-2  gcc-libs-4.3.2-2  ghc-6.10.1-1  ghostscript-8.63-4  glibc-2.9-2  
              gnome-control-center-2.24.0.1-4  gnome-panel-2.24.2-2  gnome-python-desktop-2.24.0-3  gnome-vfs-2.24.0-2  gstreamer0.10-bad-plugins-0.10.9-2  
              gtk2-2.14.5-2  gvfs-1.0.3-2  hal-0.5.11-7  hdparm-9.3-1  heimdal-1.2.1-2  imagemagick-6.4.7.8-1  kdelibs-4.1.3-2  kdelibs3-3.5.10-2  
              kernel-headers-2.6.27.6-2  kernel26-2.6.27.9-1  lftp-3.7.7-1  libcups-1.3.9-2  libgnomecups-0.2.3-4  libgnomeprint-2.18.3-4  
              libnetworkmanager-0.7.0-1  libpcap-1.0.0-1  libspectre-0.2.2-2  libx86-1.1-2  live-media-2008.11.13-1  man-pages-3.15-1  mkinitcpio-0.5.19.1-2  
              module-init-tools-3.5-1  mplayer-1.0rc2-9  neon-0.28.3-2  nmap-4.76-3  openoffice-base-3.0.0-4  openssh-5.1p1-2  openssl-0.9.8i-3  
              pacman-3.2.1-2  ppp-2.4.4-7  python-clientform-0.2.10-1  python-mechanize-0.1.10-1  qemu-0.9.1-11  samba-3.2.5-2  smbclient-3.2.5-2  
              subversion-1.5.4-2  syslog-ng-2.1.3-2  tcpdump-4.0.0-2  totem-plparser-2.24.2-2  udev-132-1  vi-7.2.65-1  vim-7.2.65-1.1  wine-1.1.10-2  
              wireshark-1.0.4-3  xf86-input-evdev-2.1.0-1  xine-lib-1.1.15-4  

Total Download Size:    0.00 MB
Total Installed Size:   1611.16 MB

The getPkgList subroutine will parse "Remove (1): bluez-libs-3.32-1" Rather than targets in this case.

Something I noticed when I was working on a conkypac rewrite (that I never bothered to finish.. sigh..). I ended up doing the python equivalent of..

$pkgs = $lines[-2];

Anywho.. great script, pretty cool idea.

Offline

#13 2008-12-16 03:47:40

Xyne
Moderator/TU
Registered: 2008-08-03
Posts: 5,632
Website

Re: Conky: scrolling package notifier using perl

Thanks for pointing that out, sabooky. I really need to just get around to figuring out how alpm works so that I can try to write my own tools instead of wrapping pacman... it's just not that high up on the TODO list.

Offline

#14 2008-12-16 04:07:44

sabooky
Member
Registered: 2006-11-02
Posts: 89

Re: Conky: scrolling package notifier using perl

Xyne wrote:

Thanks for pointing that out, sabooky. I really need to just get around to figuring out how alpm works so that I can try to write my own tools instead of wrapping pacman... it's just not that high up on the TODO list.

Thanks for pointing out alpm, I was avoiding it since it was in C.. but now there seems to be a pyalpm project going on.. I'll wait for that to mature some.
and.. yea.. parsing pacman's output is a pain especially because the format changes from time to time..

Offline

#15 2008-12-16 05:39:10

Xyne
Moderator/TU
Registered: 2008-08-03
Posts: 5,632
Website

Re: Conky: scrolling package notifier using perl

There's also pyalpmm (2 "m"s)... someone started a new implementation because he thought the pyalpm project seemed dead (he posted a thread a day or two ago).

Offline

#16 2012-01-05 06:39:22

Chr|s
Member
From: New York State, USA
Registered: 2012-01-04
Posts: 14

Re: Conky: scrolling package notifier using perl

Sorry to bring up an old post but I was told by many people in #archlinux on FreeNode IRC that using pacman -Sy is a big no no, suppose to only use it when your updating your system when you do pacman -Syu.

I came across this post from the wiki for arch. Therefore I guess I shouldn't use this method...if anyone has any better ones, please let me know. Thanks

Offline

#17 2012-01-05 06:53:52

bernarcher
Forum Fellow
From: Germany
Registered: 2009-02-17
Posts: 2,271

Re: Conky: scrolling package notifier using perl

Hello Chr|s, welcome to the Arch forums.

As you state by yourself, this is a very old post. If you have a real issue with this please create a thread of your own and link back here if necessary.

And make sure to read our Forum Etiquette.

Closing this thread.


To know or not to know ...
... the questions remain forever.

Offline

#18 2012-01-05 06:59:33

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 12,421

Re: Conky: scrolling package notifier using perl

First, welcome to Arch Linux

Chr|s wrote:

I came across this post from the wiki for arch. Therefore I guess I shouldn't use this method...if anyone has any better ones, please let me know. Thanks

Boy, you are not just whistling Dixie.  Three years ?!?

Sorry to bring up an old post but I was told by many people in #archlinux on FreeNode IRC that using pacman -Sy is a big no no, suppose to only use it when your updating your system when you do pacman -Syu.

The point is, you do not want to put yourself in a situation where you selectively update a single package, but not update others.  This can cause breakage. 
This thread (with which I had not been familiar) does update the database on a periodic basis.  If you were to do this, when you do your next sync, you would have to do a pacman -Su prior to a pacman -S someNewPackage

Now, for my moderator alter ego.  Our policy on old threads is to keep new issues from being confused by ancient advice.  Things change fast, and it makes it impossible to find answers to contemporary problems.  Although that is not true in this case, I am going to close this ancient thread anyway.

If you wish to pursue this, feel free to open a new thread with a link back to this thread.  That is the preferred method of extending old threads.

Thanks.

edit: Hey Bernarcher, good Morning.  I see you beat me to it.  I'm off to bed soon -- The forums are yours smile

Last edited by ewaller (2012-01-05 07:01:10)


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Like you, I have no idea what you are doing, but I am pretty sure it is wrong...Jasonwryan
----
How to Ask Questions the Smart Way

Offline

#19 2012-01-06 18:29:06

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 12,421

Re: Conky: scrolling package notifier using perl

Posted on behalf of Xyne:

Paconky works around the automatic -Sy issues by downloading the databases to a separate directory. This approach should be adopted by any automatic update notifiers. The paconky code also provides a good starting point for writing your own update notifier using pyalpm. If pyalpm had existed when I wrote the scrolling package notifier, I would have used it.

Xyne: PM me if you want me to reopen the thread -- ewaller


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Like you, I have no idea what you are doing, but I am pretty sure it is wrong...Jasonwryan
----
How to Ask Questions the Smart Way

Offline

Board footer

Powered by FluxBB