added sources
[xkcdha] / xkcdha.py
1 #!/usr/bin/python -tt
2
3 import os
4 import sys
5 import re
6 import urllib
7
8 import gtk
9 import hildondesktop
10
11 MAX_HEIGHT = 370. 
12 MAX_WIDTH = 700.
13
14 class XKCDha(hildondesktop.HomeItem):
15         
16     image_dir = "/home/user/MyDocs/.images/xkcdha/"
17     icons_dir = "/usr/share/xkcdha/icons/"
18
19     def __init__(self, max_height, max_width):
20         def controls():
21             hbox = gtk.HBox()
22             hbox.pack_start(gtk.Alignment())
23             for name in ("prev", "random", "next"):
24                 box = gtk.EventBox()
25                 image  = gtk.Image()
26                 image.set_from_file(self.icons_dir + "%s.png" % name)
27                 box.add(image)
28                 box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
29                 box.connect("button-press-event", getattr(self, "cb_%s" % name))
30                 hbox.pack_start(box, False, False)
31                 hbox.pack_start(gtk.Alignment(), False, False, 5)
32             hbox.pack_start(gtk.Alignment())
33             return hbox
34
35         hildondesktop.HomeItem.__init__(self)
36         self.max_height, self.max_width = max_height, max_width
37         self.number = None
38         self.prev = None
39         self.next = None
40         self.image = gtk.Image()
41                 
42         self.set_image()
43
44         image_box = gtk.EventBox()
45         image_box.add(self.image)
46         image_box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
47         image_box.connect("button-press-event", self.cb_random)
48                 
49         vbox = gtk.VBox()
50         vbox.pack_start(controls())
51         vbox.pack_start(image_box)
52         vbox.pack_start(controls())
53         vbox.show_all()
54
55         self.add(vbox)
56
57     def set_image(self, number=""):
58         def get_image(number=""):
59             
60             if self.number and number != "random":
61                 if not number:
62                     number = self.number
63                 elif number == "next" and self.next:
64                     number = self.next
65                 if number == "prev" and self.prev:
66                     number = self.prev
67
68             print 'number=', number, self.number
69
70             url = "http://xkcd.com/"
71             if number == 'random':
72                 url = "http://dynamic.xkcd.com/comic/random/"
73             elif number:
74                 url = "http://xkcd.com/%s/" % number
75             
76             print 'url:', url
77
78             content = urllib.urlopen(url).read()
79             img_url = re.search('(http://imgs.xkcd.com/comics/[^"]+)" title="[^"]+"', 
80                     content).group(1)
81             next = re.search('<a href="([^"]+)" accesskey="n">Next', content).group(1)
82             prev = re.search('<a href="([^"]+)" accesskey="p">&lt; Prev', content).group(1)
83             self.number = re.search(\
84                     '<h3>Permanent link to this comic: http://xkcd.com/([^/]+)/</h3>', 
85                     content).group(1)
86             self.next = self.number
87             if next != '#':
88                 self.next = next[1:-1]
89
90             self.prev = self.number
91             if prev != '#':
92                 self.prev = prev[1:-1]
93
94             filename = os.path.join(self.image_dir, self.number + '.png')
95             if not os.path.exists(filename):
96                 print 'getting url', img_url, 'to', filename
97                 urllib.urlretrieve(img_url, filename)
98             else:
99                 print 'already exists', filename
100             
101             print 'filename:', filename, 'img_url:', img_url
102             print 'next:', next, self.next
103             print 'prev:', prev, self.prev
104             print 'number:', self.number
105             return filename
106
107         pixbuf = gtk.gdk.pixbuf_new_from_file(get_image(number))
108         scale_y = self.max_height / pixbuf.props.height
109         scale_x = self.max_width / pixbuf.props.width
110         if scale_x > scale_y:
111             newx = int(pixbuf.props.width * scale_y)
112             newy = int(self.max_height)
113         else:
114             newx = int(self.max_width)
115             newy = int(pixbuf.props.height * scale_x)
116         
117         self.image.set_from_pixbuf(pixbuf.scale_simple(newx, newy, gtk.gdk.INTERP_BILINEAR))
118         self.image.show()
119
120     def cb_random(self, widget, data = None):      
121         self.set_image('random')
122
123     def cb_next(self, widget, data = None):
124         self.set_image('next')
125
126     def cb_prev(self, widget, data = None):
127          self.set_image('prev')
128
129 def hd_plugin_get_objects():
130     return [XKCDha(MAX_HEIGHT, MAX_WIDTH)]
131
132 def run_in_window():
133     main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
134     main_window.set_title("XKCD Home Applet")
135     main_window.connect("destroy", gtk.main_quit)
136     main_window.add(XKCDha(MAX_HEIGHT, MAX_WIDTH))                            
137     main_window.show_all()
138     gtk.main()
139
140 if __name__ == "__main__":
141     run_in_window()
142     sys.exit()
143