
##
# GNOME Desktop Decorator
#
# Download New Nature Artwork from art.gnome.org
# Thomas Perl <thp@thpinfo.com> 2007-03-22 01:08
##

import gtk
import gtk.gdk
import gobject
import os
import os.path
import urllib2
import shutil
import sys
import threading

import random
import re
import xml.dom
import xml.dom.minidom

sections = ('gnome', 'nature', 'abstract', 'other')

class ArtGnomeSource:
    text_types = ( xml.dom.Node.TEXT_NODE, xml.dom.Node.CDATA_SECTION_NODE )
    img_regex = re.compile( '(http:\/\/art.gnome.org\/images\/thumbnails\/backgrounds\/.*\.jpg)')

    def __init__( self, sect = 'nature'):
        self.feed_url = 'http://art.gnome.org/backgrounds/%s/?format=rss' % sect
        self.download_regex = re.compile( '(/download/backgrounds/%s/[^"]*\.jpg)' % sect)
        dom = xml.dom.minidom.parseString( urllib2.urlopen( self.feed_url).read())
        self.items = []
        for item in dom.getElementsByTagName( 'item'):
            new_item = {
                    'title': self.get_text( item.getElementsByTagName('title')[0]),
                    'link': self.get_text( item.getElementsByTagName('link')[0]),
                    'description': self.get_text( item.getElementsByTagName('description')[0]),
            }
            for img in self.img_regex.finditer( new_item['description']):
                new_item['thumb'] = img.group(0).strip()
            link_data = urllib2.urlopen(new_item['link']).read()
            for url in self.download_regex.finditer( link_data):
                new_item['download'] = 'http://art.gnome.org'+url.group(0).strip()
            if 'download' in new_item:
                self.items.append( new_item)

    def get_text( self, dom_node):
        return ''.join( [ n.data for n in dom_node.childNodes if n.nodeType in self.text_types ])


class DesktopDecorator( gtk.Window):
    setter_command = 'gconftool-2 -t str -s /desktop/gnome/background/picture_filename "%s"'

    def load_to_img( self, img, url):
        print url
        pixbuf = gtk.gdk.PixbufLoader()
        fp = urllib2.urlopen(url)
        for data in fp:
            pixbuf.write( data)
            if pixbuf.get_pixbuf() != None:
                gobject.idle_add( self.status_label.pulse)
                gobject.idle_add( img.set_from_pixbuf, pixbuf.get_pixbuf())
        pixbuf.close()
        gobject.idle_add( img.set_from_pixbuf, pixbuf.get_pixbuf())

        self.images_to_load -= 1
        if self.images_to_load == 0:
            gobject.idle_add( self.status_label.hide)
            self.set_title( 'Choose your new wallpaper (%s)' % self.section)
            for button in self.image_buttons:
                gobject.idle_add( button.set_sensitive, True)
        else:
            gobject.idle_add( self.status_label.set_text, 'Loading %s.. (%d remaining)' % ( self.section, self.images_to_load, ))

        return False

    def __init__( self, sect = 'nature'):
        gtk.Window.__init__( self)
        self.set_title('Desktop Decorator (thpinfo.com)')
        self.connect( 'destroy', lambda w: gtk.main_quit())
        self.set_resizable( False)
        self.set_position( gtk.WIN_POS_CENTER)
        self.set_icon_name('preferences-desktop-wallpaper')

        self.section = sect
        self.source = ArtGnomeSource( sect)
        
        self.vbox = gtk.VBox( spacing = 5)
        self.vbox.set_border_width( 10)
        self.add( self.vbox)
        self.main_table = gtk.Table( rows = int((len(self.source.items)-1)/3)+1, columns = 3, homogeneous = True)
        self.vbox.add( self.main_table)

        self.images_to_load = 0
        self.image_buttons = []
        for i in range(len(self.source.items)):
            img = gtk.Image()
            self.images_to_load += 1
            threading.Thread( target = self.load_to_img, args = ( img, self.source.items[i]['thumb'])).start()
            button = gtk.Button()
            button.add( img)
            button.download_uri = self.source.items[i]['download']
            button.connect( 'clicked', lambda w: self.set_desktop( w))
            button.set_sensitive( False)
            self.main_table.attach( button, i%3, i%3+1, int(i/3), int(i/3)+1, xpadding = 5, ypadding = 5)
            self.image_buttons.append( button)
        
        self.status_label = gtk.ProgressBar()
        self.set_title( 'Downloading previews for %s' % self.section)
        self.status_label.set_text('Loading images..')
        self.vbox.add( self.status_label)

        self.show_all()
    
    def download_file( self, uri, filename):
        if not os.path.exists( filename):
            fp = urllib2.urlopen(uri)
            fl = open( filename, 'w')

            b = 0
            size = 0

            if 'content-length' in fp.info():
                try:
                    size = int(fp.info()['content-length'])
                except:
                    pass

            for data in urllib2.urlopen(uri):
                b += len(data)
                gobject.idle_add( self.status_label.set_text, '%s (%d kb)' % ( os.path.basename(filename), int(b/1024), ))
                if size == 0:
                    gobject.idle_add( self.status_label.pulse)
                else:
                    gobject.idle_add( self.status_label.set_fraction, 1.0*b/size)
                fl.write( data)

        os.system( self.setter_command % filename)
        gobject.idle_add( self.destroy)

    def set_desktop( self, widget):
        for button in self.image_buttons:
            gobject.idle_add( button.set_sensitive, False)
        filename = os.path.basename( widget.download_uri)
        self.wallpaper_filename = os.path.expanduser( '~/.wallpapers/%s' % filename)
        d = os.path.dirname( self.wallpaper_filename)
        if not os.path.exists( d):
            os.makedirs( d)
        self.set_title('Downloading wallpaper')
        self.status_label.set_text( 'Please wait')
        self.status_label.show()
        threading.Thread( target = self.download_file, args = [ widget.download_uri, self.wallpaper_filename ]).start()


if __name__ == '__main__':
    if sys.argv[-1] in sections:
        section = sys.argv[-1]
    else:
        section = sections[random.randint(0,len(sections)-1)]
    print "using section %s" % section
    dd = DesktopDecorator( section)
    gobject.threads_init()
    gtk.main()

