Control vagalume last.fm client with DBus from python

As I have been experimenting with the docky python bindings, I created a small media control helper for Vagalume, a lightweight last.fm client. I found the vagalume DBus methods and signals to be mostly undocumented, but I found them lurking around after a quick look at some of the source code.

I created a smallish class with the help of the excellent PyGtk Notebook.

import dbus, gtk, gobject
from dbus.mainloop.glib import DBusGMainLoop

class vagalume:
    def __init__(self):
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        self.bus = dbus.SessionBus()

        self.player = self.bus.get_object("com.igalia.vagalume", "/com/igalia/vagalume")

        self.bus.add_signal_receiver(self.song_changed,
        dbus_interface="com.igalia.vagalume",
        signal_name="notify")

    def song_changed(self, *args):
        self.state = args[0]
        if state == 'stopped':
            #do something when the player is stopped
        elif state == 'playing':
            self.artist = args [1]
            self.title = args [2]
            self.album = args [3]
            #do something with the data here...

if __name__ == "__main__":
    app = vagalume()
    gtk.main()

I used the gtk mainloop for simplicity, but you could use

mainloop = gobject.MainLoop(is_running=True)
mainloop.run()

If you want to use the signals for change of song etc, it would be best to modify vagalume() to do what you want.

To interact with vagalume do something like:

    vagalume = vagalume()

    #do anything you want with dbus.
    #take a look at http://gitorious.org/vagalume/vagalume/blobs/master/src/dbus.h
    #for all of the functions available
    vagalume.player.Play()
    vagalume.player.Skip()
    vagalume.player.LoveTrack()
    vagalume.player.BanTrack()
    vagalume.player.Stop()

How to take a screenshot using pyGTK

I needed to capture my screen very quickly from python, and needed to save these images into a Python Image Library (PIL) Image. I wrote a small python class to do the work, keeping as little processing as possible in the screenshot.take() function.

import Image, gtk
class screenshot:
    def __init__(self):
        self.img_width = gtk.gdk.screen_width()
        self.img_height = gtk.gdk.screen_height()

        self.screengrab = gtk.gdk.Pixbuf(
            gtk.gdk.COLORSPACE_RGB,
            False,
            8,
            self.img_width,
            self.img_height)

    def take(self):
        self.screengrab.get_from_drawable(
            gtk.gdk.get_default_root_window(),
            gtk.gdk.colormap_get_system(),
            0, 0, 0, 0,
            self.img_width,
            self.img_height)

        final_screengrab = Image.frombuffer(
          "RGB",
          (self.img_width, self.img_height),
          self.screengrab.get_pixels(),
          "raw",
          "RGB",
          self.screengrab.get_rowstride(),
          1)
        return final_screengrab

if __name__ == '__main__':
    import time
    screenshot = screenshot()
    while True:
        ti = time.time()
        im = screenshot.take()
        tii = time.time()
        print tii-ti

TaylorType alpha testing needed!

TaylorType is a small program written in python which will compile any LaTeX document you give it with a single click. The emphasis is on a very lightweight and simple gui, the only interaction happens in the system tray, with two file selectors and a checkbox.

All it is is a small icon in the system tray, which can be configured to compile any LaTeX document.
It has some simple preferences, an option for different pdf viewers will be added soon.
It currently supports error messages for both LaTeX and BibTeX.

It uses gtk for the frontend and pure python for the backend.
It depends on LaTeX, BibTeX and common gnome components. including pynotify and gconf.

Main code is hosted here: https://launchpad.net/taylortype

Download from https://launchpad.net/taylortype/+download

Report all bugs to https://bugs.launchpad.net/taylortype

Main website (small): http://taylortype.sourceforge.net/

Using LaTeX with python.

I have written a small (and buggy) python module to drive latex. This can be used in larger programs (eg taylortype https://launchpad.net/taylortype)

All it does is execute the latex command, read the output and return a nicely formatted error message if something goes wrong.

Here is the code:

http://dl.dropbox.com/u/3746044/python-latex.py

http://www.pasteall.org/11691/python

#!/usr/bin/env python

##Copyright (C) 2010 Louis Taylor  
## _    ___ _____                                                              
##| |  | _ \_   _|                                                             
##| |__|  _/ | |                                                               
##|____|_|   |_| *programus optimus est*                                       
##                                                                             
##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 3 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.                                 
##                                                                            
##You should have received a copy of the GNU General Public License            
##along with this program.  If not, see http://www.gnu.org/licenses/gpl-3.0.txt  

import os, subprocess, time

def compile(latexfile, pdfdir='/tmp', rmlog=False, movepdf=False, usebibtex=True):
    '''compiles latex document, saves it to the directory
    specified in *pdfdir* and returns any error messages it can find'''
    path = os.path.split(latexfile)
    texfile = path[1]
    directory = path[0]

    rawname = os.path.splitext(texfile)[0]

    logfile = os.path.splitext(texfile)[0]+'.log'
    logpath = os.path.join(pdfdir, logfile)

    pdffile = os.path.splitext(texfile)[0]+'.pdf'
    pdfpath = os.path.join(pdfdir, pdffile)

    os.chdir(directory) #change cwd to the dir to place all latex files

    #os.system('bibtex %s' % rawname) #this will be replaced by the new function
    bibtex_error = False
    if usebibtex == True:
        print 'using bibtex'
        bib_err = bibtex(rawname, pdfdir)
        if bib_err != '':
            #get an error message
            bibtex_error = ['error', 'BibTeX error', '', bib_err]
        else:
            pass

    else:
        print 'not using bibtex'

    cmd = ['pdflatex', '--halt-on-error', '-output-directory', pdfdir, texfile]
    latex = subprocess.Popen(cmd, shell=False,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    message = latex.communicate()[0] #get the stdout, latex.communicate()[1] gives stderr
    #set the data to be returned on success
    returned = ['success', pdfpath]

    if '\n!' in message:
        name = False
        ln = False
        error_msg = ''
        error_ln = ''
        quote = ''

        for line in message.split('\n'):
            if line == '':
                pass #pass if the line is blank

            elif line[0] == '!' and not name:
                #find error message line
                name = True
                error_msg = line.replace('!', '').strip()
                                        #remove all whitespace around string

            elif line[0] == 'l' and name and not ln:
                #find line number and quote.
                #only come to this line if:
                #the-- first character is an 'l', there has just been an error
                #line and there has not been a line number before.
                ln = True
                string = line.split(' ')
                error_ln = string[0].replace('l.', '')
                quote = line.replace(string[0], '')

            else:
                pass

    #repeat the BibTeX command, as requested by Peter Flynn
    if usebibtex == True:
        print 'using bibtex'
        bib_err = bibtex(rawname, pdfdir)
        if bib_err != '':
            #get an error message
            bibtex_error = ['error', 'BibTeX error', '', bib_err]
        else:
            pass

    else:
        print 'not using bibtex'

        #set the data to be returned on error
        try:
            returned = ['error', error_msg, error_ln, quote, pdffile]
        except UnboundLocalError:
            returned = ['success', pdfpath]

    if rmlog:
        try:
            os.remove(logpath)
        except OSError:
            pass

    if movepdf != False:
        #bit of a quick hack, use cp to do the work:
            #use python to do this?
        os.system('cp "%s" "%s"' % (pdfpath, movepdf))

    if returned == ['success', pdfpath] and bibtex_error == False:
        '''return normal traceback if everything whent ok'''
        return returned
    if returned != ['success', pdfpath] and bibtex_error == False:
        '''return latex error message'''
        return returned
    if returned == ['success', pdfpath] and bibtex_error != False:
        '''return bibtex error'''
        return bibtex_error
    if returned != ['success', pdfpath] and bibtex_error != False:
        '''let the latex error have preference over bibtex error'''
        return returned

def bibtex(rawtexname, directory):
    #os.chdir(directory)

    cmd = ['bibtex', rawtexname]
    bibtex = subprocess.Popen(cmd, shell=False,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    message = bibtex.communicate()[0] #get the stdout, bibtex.communicate()[1] gives stderr
    print message

    error = ''
    for line in message.split('\n'):
        if error != '':
            #if we already have the first bibtex error message
            break
        else:
            #if we do not have an error message yet
            words = line.split()
            if line == '':
                break
            elif line[0] == 'I':
                #if line is one of the variations on "I couldn't..."
                if words[1] == 'found':
                    error = line.replace('I', '').replace('---', ' ').strip()
                elif words[1] == "couldn't":
                    error = line.replace('I', '').strip()

            elif 'Warning--' in line:
                error = line.replace('Warning--I ', '')
    return error

if __name__ == '__main__':
    #small self test
    error = compile('/home/louis/Desktop/tex/text.tex', '/home/louis/Desktop/tex', True, movepdf=False, usebibtex=True)
    print error

how to change the gnome wallpaper from python

here is a quick way to change the gnome wallpaper from python. The module is importable and can be used in another program.

Creative Commons License
This work is licensed under a Creative Commons GNU General Public License License.

download from: code on pasteall or code from dropbox

the indentation on wordpress is rubbish, so this is just the lines of code without indentation:


#!/usr/bin/env python
import os
def change_wallpaper(imagefile):
cmd = 'gconftool-2 -s /desktop/gnome/background/picture_filename -t string "%s"' % imagefile
os.system(cmd)


if __name__ == '__main__':
change_wallpaper ('background.jpg')

python class for looking at the connected machines on the network.

class for looking at the connected machines on the network.
Can give the same output available on the network router

Must be run under root, this is necessary because of nmap
depends on:
* nmap
* python 2.6
* ping

To use, you must call the function refresh()

again, the indentation on this website is non-existent, so get the code from:
http://www.pasteall.org/10698/python

download list-hosts.py

”’#!/usr/bin/env python
##Copyright (C) 2010 Louis Taylor
## _ ___ _____
##| | | _ \_ _|
##| |__| _/ | |
##|____|_| |_| *programus optimus est*
##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 3 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.
##
##You should have received a copy of the GNU General Public License
##along with this program. If not, see http://www.gnu.org/licenses/
import os, sys, re
class connected:
”’
class for looking at the connected machines on the network.
Can give the same output available on the network router
Must be run under root, this is necessary because of nmap
depends on:
* nmap
* python 2.6
* ping
”’
def __init__(self):
self.ipregex = re.compile(‘\(.*?\)’)
self.hostregex = re.compile(‘Host\.*is up’)
self.cmd = ‘nmap -sP 192.168.1.1-255’
self.peopleConnected = []
self.ipConnected = []
self.MACConnected = []
self.database = []
self.current = 0
if not os.getuid() == 0:
#raise Exception, ‘must be run as root’ #uncomment and use this if you want
#it to be run as part of a larger
#program
print ‘must be run as root’
sys.exit(1)
else:
pass
def output(self, cmd):
”’outputs the text from cmd”’
self.outputtext=os.popen(cmd).read().split(‘\n’)
return self.outputtext
def refresh(self):
”’refreshes the list of machines connected to the network
You must call this function every time you expect the values to change
and want to read these changes”’
ishost = False
hasMAC = True
for line in self.output(self.cmd):
splitline = line.split(‘ ‘)
if splitline[0] == ‘Host’:
if not hasMAC:
self.MACConnected += [‘unknown’]
self.peopleConnected += [splitline[1].replace(‘.home’, ”)]
ipAddress = self.ipregex.search(line)
self.ipConnected += [ipAddress.group().replace(‘(‘, ”).replace(‘)’, ”)]
ishost = True
hasMAC = False
#check if the line begins with ‘MAC’ and is after a host line
elif ishost and splitline[0] == ‘MAC’:
brackets = self.ipregex.search(line)
brackets = brackets.group()
line = line.replace(brackets, ”).replace(‘MAC Address: ‘, ”)
self.MACConnected += [line]
hasMAC = True
ishost = False
current = -1
self.database = []
for name in self.peopleConnected:
current += 1
self.database.append(name)
self.database.append([self.ipConnected[current], self.MACConnected[current]])
def ip(self, name):
”’returns the ip address of the given computer name
returns 000.000.000.000 if none found e.g. computer not connected”’
try:
index = self.database.index(name)+1 #get the index of the item
#add 1 to get to the next index
except ValueError:
return ‘000.000.000.000’
return self.database[index][0]
def mac(self, name):
”’returns the MAC address of the given computer name
returns 00:00:00:00:00:00 if none found e.g. computer not connected”’
try:
index = self.database.index(name)+1 #get the index of the item
#add 1 to get to the next index
except ValueError:
return ’00:00:00:00:00:00′
return self.database[index][1]
def os(self, name):
”’will try to find the name and version of the os that the ip is running.
v. slow, so run in multithreaded or prepare for a freeze
* name can be an ip address or the bssid
Warning! this function does not work, do not use”’
cmd = ‘sudo nmap -O %s’ % name
output = self.output(cmd)
def up(self, ip):
”’returns True if the ip address replies to a ping request”’
cmd = ‘ping -q -c 1 %s’ % ip
output = os.popen(cmd).read()
if ‘ping: unknown host’ in output:
#trys to see if the ip address entered is invalid.
return False
elif ‘1 received’ in output:
#try to see if the computer has receved any packets.
return True
else:
#return false because there is nothing else to do if the
#output is in a different format than usual.
return False
def names(self):
”’returns the names of the computers connected to the network”’
return self.peopleConnected
if __name__ == ‘__main__’:
”’small self test/example of use”’
people = connected()
people.refresh()
for name in people.names():
print name
print ‘… MAC:’, people.mac(name)
print ‘… ip:’, people.ip(name)”’

Some free wallpapers to download.

Here are some free wallpapers to download, all of these where taken by me and my wonderful camera🙂.

Creative Commons License
This work is licenced under a Creative Commons Licence.

This one was taken with a modified fixed-lens digital camera that allowed me to take detailed photographs of objects about 5mm away from the lens.