--- /dev/null
+import hildon
+import hildondesktop
+import gtk
+import csv
+import urllib2
+import urllib
+import string
+import os
+import osso
+
+# constants. dbfile is the location of the csv
+# comiccache is the location of the images
+
+comiccache = "/home/user/MyDocs/comics/"
+comics = {"xkcd":{"name":"xkcd","link":"http://xkcd.org/","start":666,"dbfile":"/home/user/.comicdb.xkcd.csv"},
+ "sinfest":{"name":"Sinfest","link":"http://sinfest.com/","start":3400,"dbfile":"/home/user/.comicdb.sinfest.csv"}}
+imagedir = "/home/user/comic-widget/images/"
+# handling of the comics
+class ComicDb():
+ def __init__(self, comic):
+ #if no db, start from this comic id.
+ self.comic = comic
+ self.start = comics[self.comic]["start"]
+ self.dbfile = comics[self.comic]["dbfile"]
+
+ #if db file exist, read it
+ if os.path.isfile(self.dbfile) == True:
+ dbf = open(self.dbfile, 'r')
+ # if not, create it.
+ else:
+ dbf = open(self.dbfile, 'w')
+ dbf.write('comic,id,link,url,filename,title\n')
+ dbf.close()
+ dbf = open(self.dbfile, 'r')
+ self.fetch_latest_std(self.comic, self.start)
+
+ if not os.path.exists(comiccache + self.comic + "/"):
+ os.makedirs(comiccache + self.comic + "/")
+ dbr = csv.DictReader(dbf)
+ self.db = []
+ for row in dbr:
+ self.db.insert(0,row)
+ dbf.close()
+ self.currentcomic = 0
+
+ def get_comic(self):
+ print str(self.currentcomic)
+ if self.currentcomic < 0:
+ self.refresh()
+ self.currentcomic = 0
+ if len(self.db) < (self.currentcomic + 1):
+ self.currentcomic -= 1
+ self.refresh()
+ self.currentcomic = len(self.db) - 1
+
+ dbrow = self.db[self.currentcomic]
+ filename = comiccache + self.comic + "/" + dbrow['filename']
+ print filename + "\n"
+
+ if os.path.isfile(filename):
+ print "found, returning " + filename + "\n"
+ return filename
+ else:
+ #fetch file
+ print filename + " not found\nretrieving " + dbrow['url'] + "\n"
+ urllib.urlretrieve(dbrow['url'], filename)
+ print "success\n"
+ return filename
+
+ def get_current_row(self):
+ return self.db[self.currentcomic]
+
+ def get_link(self):
+ print str(self.currentcomic)
+ if self.currentcomic < 0:
+ self.refresh()
+ self.currentcomic = 0
+ if len(self.db) < (self.currentcomic + 1):
+ self.currentcomic -= 1
+ return self.db[self.currentcomic]['link']
+
+
+
+ def insert_row(self, irow):
+ dbf = open(self.dbfile, 'a')
+ dbw = csv.writer(dbf)
+ dbw.writerow(irow)
+ dbf.close()
+
+ def insert_row_first(self, irow):
+ dbf = open(self.dbfile, 'w')
+ dbf.write('comic,id,link,url,filename,title\n')
+ dbw = csv.writer(dbf)
+ dbw.writerow(irow)
+ dbf.close()
+ dbf = open(self.dbfile, 'a')
+ dbw = csv.DictWriter(dbf, ['comic','id','link','url','filename','title'])
+ tmpdb = self.db
+ tmpdb.reverse()
+ for row in tmpdb:
+ dbw.writerow(row)
+ dbf.close()
+
+ def refresh(self):
+ if len(self.db) < 1:
+ self.fetch_latest_std(self.comic, self.start)
+ elif self.currentcomic == 0 or self.currentcomic < 0:
+ self.fetch_latest_std(self.comic, self.db[0]['id'])
+ elif self.currentcomic == (len(self.db) - 1):
+ self.fetch_earlier(self.comic, self.db[self.currentcomic]['id'])
+ dbf = open(self.dbfile, 'r')
+ dbr = csv.DictReader(dbf)
+ self.db = []
+ for row in dbr:
+ self.db.insert(0,row)
+ dbf.close()
+
+ def fetch_earlier(self, comic, earliest):
+ number = int(earliest) - 1
+ if number < 0:
+ return False
+ print "number is now: " + str(number) + "\n"
+ if comic == 'xkcd':
+ link = "http://xkcd.org/" + str(number) + "/"
+ elif comic == 'sinfest':
+ link = "http://www.sinfest.net/archive_page.php?comicID=" + str(number)
+ else:
+ return False
+ print "link: " + link + "\n"
+ try:
+ f = urllib2.urlopen(link)
+ hcode = f.code
+ except:
+ hcode = 404
+ print "got hcode = " + str(hcode) + "\n"
+ if (hcode != 200):
+ return False
+ else:
+ # Build db entry.
+ # they look like: comic,id,link,url,filename,title
+ # We already have comic, number/id and link
+
+ if comic == 'xkcd':
+ s = f.read()
+ f.close()
+ splt = string.split(s, "<h3>Image URL (for hotlinking/embedding): ", 1)
+ splt2 = string.split(splt[1], "</h3>", 1)
+ url = splt2[0]
+ splt = string.split(splt[0], "<h1>", 1)
+ splt = string.split(splt[1], "</h1>", 1)
+ title = splt[0]
+
+ elif comic == 'sinfest':
+ s = f.read()
+ f.close()
+ splt = string.split(s, 'height="107"', 1)
+ splt = string.split(splt[1], '<img src="', 1)
+ splt = string.split(splt[1], '" alt="', 1)
+ url = splt[0]
+ if len(url) < 49:
+ print "Fake 404! Break break break!"
+ return False
+ splt = string.split(splt[1], '" border="0" />', 1)
+ title = splt[0]
+ splt2 = string.rsplit(url, "/", 1)
+ filename = splt2[1]
+ irow = [comic,number,link,url,filename,title]
+ print "got irow: "
+ print irow
+ print "\ninserting first...\n"
+ self.insert_row_first(irow)
+
+
+ def fetch_latest_std(self, comic, latest):
+
+ print "fetching new after " + str(comic) + " " + str(latest) + "\n"
+ hcode = 200
+ number = int(latest) + 1
+ while hcode == 200:
+ print "number is now: " + str(number) + "\n"
+ if comic == 'xkcd':
+ link = "http://xkcd.org/" + str(number) + "/"
+ elif comic == 'sinfest':
+ link = "http://www.sinfest.net/archive_page.php?comicID=" + str(number)
+ else:
+ break
+ print "link: " + link + "\n"
+ try:
+ f = urllib2.urlopen(link)
+ hcode = f.code
+ except:
+ hcode = 404
+ print "got hcode = " + str(hcode) + "\n"
+ if (hcode != 200):
+ break
+ else:
+ # Build db entry.
+ # they look like: comic,id,link,url,filename,title
+ # We already have comic, number/id and link
+
+ if comic == 'xkcd':
+ s = f.read()
+ f.close()
+ splt = string.split(s, "<h3>Image URL (for hotlinking/embedding): ", 1)
+ splt2 = string.split(splt[1], "</h3>", 1)
+ url = splt2[0]
+ splt = string.split(splt[0], "<h1>", 1)
+ splt = string.split(splt[1], "</h1>", 1)
+ title = splt[0]
+
+ elif comic == 'sinfest':
+ s = f.read()
+ f.close()
+ splt = string.split(s, 'height="107"', 1)
+ splt = string.split(splt[1], '<img src="', 1)
+ splt = string.split(splt[1], '" alt="', 1)
+ url = splt[0]
+ if len(url) < 49:
+ print "Fake 404! Break break break!"
+ break
+ splt = string.split(splt[1], '" border="0" />', 1)
+ title = splt[0]
+
+ splt2 = string.rsplit(url, "/", 1)
+ filename = splt2[1]
+ irow = [comic,number,link,url,filename,title]
+ print "got irow: "
+ print irow
+ print "\ninserting...\n"
+
+ self.insert_row(irow)
+
+ number += 1
+
+class ComicHomePlugin(hildondesktop.HomePluginItem):
+ def __init__(self):
+ hildondesktop.HomePluginItem.__init__(self)
+ self.osso_c = osso.Context("comic-widget", "0.0.1", False)
+ self.osso_rpc = osso.Rpc(self.osso_c)
+ self.keys = comics.keys()
+ self.keypointer = 1
+ self.db = ComicDb(self.keys[self.keypointer])
+ self.comicname = comics[self.keys[self.keypointer]]['name']
+ screen = self.get_screen()
+ colormap = screen.get_rgba_colormap()
+ self.set_colormap(colormap)
+ #setup internal area
+ self.set_size_request(480, 230)
+ self.imgvpos = 0;
+ self.vbox = gtk.VBox()
+ self.hbox = gtk.HBox()
+ self.label = gtk.Label(self.comicname + " " + str(self.db.db[self.db.currentcomic]['id']))
+ self.e_goweb = gtk.EventBox()
+ self.e_open = gtk.EventBox()
+ self.e_switch = gtk.EventBox()
+ self.e_next = gtk.EventBox()
+ self.e_prev = gtk.EventBox()
+ self.e_up = gtk.EventBox()
+ self.e_down = gtk.EventBox()
+ self.comic_image = self.get_resized_pixmap(self.db.get_comic(), self.imgvpos)
+ self.comic_image.show()
+ self.next = gtk.image_new_from_file(imagedir + "right.png")
+ self.prev = gtk.image_new_from_file(imagedir + "left.png")
+ self.up = gtk.image_new_from_file(imagedir + "up.png")
+ self.down = gtk.image_new_from_file(imagedir + "down.png")
+ self.switch = gtk.image_new_from_file(imagedir + "star.png")
+
+ self.e_goweb.add(self.label)
+ self.e_goweb.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.e_goweb.connect("button-press-event", self.view_comic)
+
+ self.e_open.add(self.comic_image)
+
+ self.e_switch.add(self.switch)
+ self.e_switch.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.e_switch.connect("button-press-event", self.switch_comic)
+
+
+ self.e_next.add(self.next)
+ self.e_next.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.e_next.connect("button-press-event", self.get_next)
+
+ self.e_prev.add(self.prev)
+ self.e_prev.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.e_prev.connect("button_press_event", self.get_prev)
+
+ self.e_up.add(self.up)
+ self.e_up.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.e_up.connect("button-press-event", self.scroll_up)
+
+ self.e_down.add(self.down)
+ self.e_down.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.e_down.connect("button-press-event", self.scroll_down)
+
+ self.vbox.pack_start(self.e_open,False,False,0)
+ self.vbox.pack_end(self.hbox,False,False,0)
+
+ self.hbox.pack_start(self.e_switch,False,False,5)
+ self.hbox.pack_start(self.e_goweb,False,False,5)
+ self.hbox.pack_end(self.e_next,False,False,5)
+ self.hbox.pack_end(self.e_down,False,False,5)
+ self.hbox.pack_end(self.e_up,False,False,5)
+ self.hbox.pack_end(self.e_prev,False,False,5)
+ self.vbox.show_all()
+ self.add(self.vbox)
+
+
+ def switch_comic(self, widget, event):
+ if not event.type == gtk.gdk.BUTTON_PRESS:
+ return False
+ self.keypointer = (self.keypointer + 1) % 2
+ self.imgvpos = 0
+ self.db = []
+ print "switching to " + self.keys[self.keypointer]
+ self.comicname = comics[self.keys[self.keypointer]]['name']
+ self.db = ComicDb(self.keys[self.keypointer])
+ self.e_goweb.remove(self.label)
+ self.label = gtk.Label(self.comicname + " " + str(self.db.db[self.db.currentcomic]['id']))
+ self.e_goweb.add(self.label)
+ self.e_goweb.show_all()
+ self.e_open.remove(self.comic_image)
+ self.comic_image = self.get_resized_pixmap(self.db.get_comic(), self.imgvpos)
+ self.e_open.add(self.comic_image)
+ self.e_open.show_all()
+
+ def switch_rel(self, widget, event):
+ if not event.type == gtk.gdk.BUTTON_RELEASE:
+ return False
+ widget.remove(self.switch)
+ self.switch = gtk.image_new_from_file(imagedir + "star.png")
+ widget.add(self.switch)
+ widget.show_all()
+
+ def view_comic(self, widget, event):
+ if not event.type == gtk.gdk.BUTTON_PRESS:
+ return False
+ link = self.db.get_link()
+ self.osso_rpc.rpc_run_with_defaults("osso_browser", "open_new_window", (link,))
+
+ def scroll_down(self, widget, event):
+ if not event.type == gtk.gdk.BUTTON_PRESS:
+ return False
+ self.e_open.remove(self.comic_image)
+ self.imgvpos = self.imgvpos + 50
+ self.comic_image = self.get_resized_pixmap(self.db.get_comic(), self.imgvpos)
+ self.e_open.add(self.comic_image)
+ self.e_open.show_all()
+
+ def scroll_up(self, widget, event):
+ if not event.type == gtk.gdk.BUTTON_PRESS:
+ return False
+ self.e_open.remove(self.comic_image)
+ self.imgvpos = self.imgvpos - 50
+ if self.imgvpos < 0:
+ self.imgvpos = 0
+ self.comic_image = self.get_resized_pixmap(self.db.get_comic(), self.imgvpos)
+ self.e_open.add(self.comic_image)
+ self.e_open.show_all()
+
+ def get_next(self, widget, event):
+ if not event.type == gtk.gdk.BUTTON_PRESS:
+ return False
+ self.db.currentcomic -= 1
+ self.imgvpos = 0
+ self.e_open.remove(self.comic_image)
+ self.comic_image = self.get_resized_pixmap(self.db.get_comic(), self.imgvpos)
+ self.e_open.add(self.comic_image)
+ self.e_open.show_all()
+ self.e_goweb.remove(self.label)
+ self.label = gtk.Label(self.comicname + " " + str(self.db.db[self.db.currentcomic]['id']))
+ self.e_goweb.add(self.label)
+ self.e_goweb.show_all()
+
+ def get_prev(self, widget, event):
+ if not event.type == gtk.gdk.BUTTON_PRESS:
+ return False
+ self.db.currentcomic += 1
+ self.imgvpos = 0
+ self.e_open.remove(self.comic_image)
+ self.comic_image = self.get_resized_pixmap(self.db.get_comic(), self.imgvpos)
+ self.e_open.add(self.comic_image)
+ self.e_open.show_all()
+ self.e_goweb.remove(self.label)
+ self.label = gtk.Label(self.comicname + " " + str(self.db.db[self.db.currentcomic]['id']))
+ self.e_goweb.add(self.label)
+ self.e_goweb.show_all()
+
+ def get_resized_pixmap(self, filename, vpos):
+ pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
+ parent_buf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, pixbuf.get_has_alpha(), 8, 478, 190)
+ parent_buf.fill(0x00000000)
+ retimg = gtk.Image()
+ # get correct width/height
+ new_width = 0
+ new_height = 1
+ new_width = 478
+ new_height = int((478.0 / pixbuf.get_width()) * pixbuf.get_height())
+ scaled_buf = pixbuf.scale_simple(new_width,new_height,gtk.gdk.INTERP_BILINEAR)
+
+ if scaled_buf.get_height() > 190:
+ if scaled_buf.get_height() - (vpos + 190) < 0:
+ vpos = scaled_buf.get_height() - 190
+ scaled_buf.copy_area(0,vpos,478,190,parent_buf,0,0)
+
+ else:
+ tmpy = 190 - scaled_buf.get_height()
+ if tmpy > 0:
+ tmpy = tmpy / 2
+
+ scaled_buf.copy_area(0,vpos,478,scaled_buf.get_height(),parent_buf,0,tmpy)
+
+ retimg.set_from_pixbuf(parent_buf)
+ return retimg
+
+
+hd_plugin_type = ComicHomePlugin
+
+
+if __name__ == "__main__":
+ import gobject
+ gobject.type_register(hd_plugin_type)
+ obj = gobject.new(hd_plugin_type, plugin_id="plugin_id")
+ obj.show_all()
+ gtk.main()