You are not logged in.

#1 2010-02-21 19:01:46

FSX
Member
Registered: 2009-08-06
Posts: 57

ChangeWP (random wallpaper setter)

Link23 on #gimptalk gave me the idea for this. It shows an icon in the systemtray and it sets a random wallpaper from a directory. Only feh is supported at the moment, because I don't know how Gnome/KDE etc. do this.

The dependencies are Python, PyGTK and xdg-utils.

The code:

#!/usr/bin/env python

"""
ChangeWP sets a random wallpaper.

Licensed under the MIT License.
"""


__author__ = 'Frank Smit <61924.nl>'
__version__ = '0.1'


import os
import sys
import subprocess
from random import randint
from ConfigParser import SafeConfigParser

import pygtk
pygtk.require('2.0')
import gtk
import gobject


_xdg_config_home = os.getenv('XDG_CONFIG_HOME',
    os.path.join(os.path.expanduser('~'), '.config'))
_default_config_path = os.path.join(_xdg_config_home, 'changewp.conf')


class Config:
    """A class for loading writing and changing configuration files."""

    def __init__(self, default_config):

        self.parser = SafeConfigParser(default_config)
        self.parser.read(_default_config_path)

    def __getitem__(self, option):
        return self.parser.get('DEFAULT', option)

    def __setitem__(self, option, value):
        self.parser.set('DEFAULT', option, str(value))

    def getint(self, option):
        """A convenience method for retrieving an integer option."""

        return int(self.parser.get('DEFAULT', option))

    def getbool(self, option):
        """A convenience method for retrieving a boolean option."""

        return self.parser.get('DEFAULT', option) == 'True'

    def save(self):
        """Write all the settings to the config file."""

        with open(_default_config_path, 'w') as f:
            self.parser.write(f)


class ChangeWP(gtk.StatusIcon):
    """The main class."""

    last_index = None
    wallpapers = []

    def __init__(self, arguments):
        """Load configuration, read wallpaper directory, restores the last
           wallpaper create widgets and enter GTK the main loop."""

        # Load config
        self.cfg = Config({
            'wallpaper_dir': os.path.expanduser('~/'),
            'last_wallpaper': ''
            })

        # Read wallpaper directory
        gobject.idle_add(self.read_directory)

        # Restore last wallpaper
        if self.cfg['last_wallpaper']:
            self.set_wallpaper()

        # Popup menu
        self.menu = gtk.Menu()

        menu_open = gtk.ImageMenuItem(gtk.STOCK_OPEN)
        menu_about = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
        menu_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)

        menu_open.connect('button-press-event', self._open)
        menu_about.connect('button-press-event', self._about)
        menu_quit.connect('button-press-event', self._quit)

        self.menu.append(menu_open)
        self.menu.append(menu_about)
        self.menu.append(menu_quit)

        # Systemtray icon
        gtk.StatusIcon.__init__(self)
        self.set_from_stock(gtk.STOCK_REFRESH)
        self.set_tooltip('ChangeWP')

        self.connect('activate', self._activate_icon)
        self.connect('popup-menu', self._popup_menu)

        self.set_visible(True)

        gtk.main()

    def read_directory(self):
        """Read all image files from the wallpaper directory."""

        self.wallpapers = [filename for filename in os.listdir(
            self.cfg['wallpaper_dir'])
            if (filename.lower().endswith('jpg')
            or filename.lower().endswith('png')
            or filename.lower().endswith('gif'))]

    def set_wallpaper(self):
        """Set a wallpaper."""

        subprocess.call(['feh', '--bg-tile', self.cfg['last_wallpaper']])

    def _activate_icon(self, widget):
        """Change the current wallpaper to a random wallpaper."""

        if not self.wallpapers:
            return

        # Count wallpapers and choose an index
        wallpaper_count = len(self.wallpapers)-1
        index = randint(0, wallpaper_count)

        # If the randint chooses the same index as the last one we run it again
        if wallpaper_count > 0 and index == self.last_index:
            index = randint(0, wallpaper_count)

        # Save the index
        self.last_index = index

        # Set 'last_wallpaper'
        self.cfg['last_wallpaper'] = os.path.join(
            self.cfg['wallpaper_dir'],
            self.wallpapers[self.last_index])

        # Change current wallpaper
        self.set_wallpaper()

    def _popup_menu(self, widget, button, time):
        """Show a popup menu."""

        # Only show the menu when the righ mouse button is clicked
        if button == 3:
            if self.menu:
                self.menu.show_all()
                self.menu.popup(None, None, None, 3, time)

    def _open(self, widget, event):
        """Choose and set the wallpaper directory."""

        dialog = gtk.FileChooserDialog(
            title='Choose your wallpaper directory...',
            action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                     gtk.STOCK_OPEN, gtk.RESPONSE_OK))

        dialog.set_current_folder(self.cfg['wallpaper_dir'])
        dialog.set_default_response(gtk.RESPONSE_OK)

        response = dialog.run()
        if response == gtk.RESPONSE_OK:
            self.cfg['wallpaper_dir'] = dialog.get_filename()
            gobject.idle_add(self.read_directory)

        dialog.destroy()

    def _about(self, widget, event):
        """Show the about window."""

        def _open_url(url):
            subprocess.call(['xdg-open', url])

        dialog = gtk.AboutDialog()
        gtk.about_dialog_set_url_hook(_open_url)

        dialog.set_name('ChangeWP')
        dialog.set_version(__version__)
        dialog.set_authors([__author__])
        dialog.set_website('http://61924.nl/')
        dialog.set_comments('ChangeWP sets a random wallpaper.')

        dialog.run()
        dialog.destroy()

    def _quit(self, widget, event):
        """Save the configuration and quit the program."""

        self.cfg.save()
        gtk.main_quit()

if __name__ == '__main__':

    # Create a changewp dir in ~/.config if it doesn't exist
    if not os.path.isdir(_xdg_config_home):
        os.makedirs(_xdg_config_home, mode=0700)

    try:
        ChangeWP(sys.argv[1:])
    except KeyboardInterrupt:
        print ' Exiting ChangeWP...'
        sys.exit(0)

The README:

ChangeWP
========

ChangeWP sets a random wallpaper.

Installation
============

Install Python, PyGTK and xdg-utils.

Make the script executable and execute it. Then click with the right mouse button on
the icon that appeared in your systemtray and click on "Open" and choose a
directory that contains your wallpapers. Done.

To do
=====

 - Support for more wallpaper setters, e.g. KDE, Gnome/Gconf, Xubuntu/Xfconf
   and other commandline wallpaper setters.
   Only feh is supported at the moment.
 - "Change wallpaper each ?? minutes" option.

Resources
=========

 - Changing a wallpaper with Gconf:
   http://library.gnome.org/admin/system-admin-guide/stable/gconf-9.html.en#gconf-20
 - Change wallpaper with Xfconf:
   http://ubuntuforums.org/showpost.php?p=8046115&postcount=2
 - Change wallpaper in KDE:
   http://usalug.org/phpBB2/viewtopic.php?t=9821

License
=======

Copyright (c) 2010 Frank Smit

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Offline

#2 2010-02-21 21:02:33

JohannesSM64
Member
From: Norway
Registered: 2009-10-11
Posts: 623
Website

Re: ChangeWP (random wallpaper setter)

This can also be realized this way (.xinitrc):

while :; do
    feh --bg-center "$(find /path/to/dir -type f | shuf -n1)"
    sleep 15m
done &

Offline

#3 2010-02-21 21:11:27

FSX
Member
Registered: 2009-08-06
Posts: 57

Re: ChangeWP (random wallpaper setter)

Heh, nice. That's much simpler. I always directly try to make something in Python. smile

My script only changes the wallpaper when you click on the systray icon. I didn't add the interval stuff yet.

Offline

Board footer

Powered by FluxBB