SHARE
TWEET

cyberpython

a guest Feb 11th, 2010 110 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. '''
  5. *   Copyright 2010 Georgios Migdos <cyberpython@gmail.com>
  6. *
  7. *   Licensed under the Apache License, Version 2.0 (the "License");
  8. *   you may not use this file except in compliance with the License.
  9. *   You may obtain a copy of the License at
  10. *
  11. *       http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. *   Unless required by applicable law or agreed to in writing, software
  14. *   distributed under the License is distributed on an "AS IS" BASIS,
  15. *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. *   See the License for the specific language governing permissions and
  17. *   limitations under the License.
  18. *  
  19. *
  20. '''
  21.  
  22. import sys
  23. import time
  24. import threading
  25. import tempfile
  26. import os
  27. import webbrowser
  28.  
  29. from xml.dom.minidom import parse
  30. import urllib2
  31. import socket
  32.  
  33. import pygtk
  34. pygtk.require('2.0')
  35. import gtk
  36. from gtk import gdk
  37. import gobject
  38. import pango
  39. import cairo
  40. import webkit
  41.  
  42. class feedRetriever:
  43.  
  44.         def __init__(self, configuration):
  45.                 self.feeds = []
  46.                 self.rssItems = {}
  47.                 self.configuration = configuration
  48.        
  49.         def addFeed(self, feedTitle, feedUrl)
  50.                 feed = (feedTitle, feedUrl)
  51.                 self.feeds.append(feed)
  52.        
  53.         def setFeed(self, feedTitle, feedUrl):
  54.                 self.feeds = []
  55.                 if(feed!=None):
  56.                         feed = (feedTitle, feedUrl)
  57.                         self.feeds.append(feed)
  58.        
  59.         def setFeed(self, feed):               
  60.                 self.feeds = []
  61.                 if(feed!=None):
  62.                         self.feeds.append(feed)
  63.        
  64.         def getRssItems(self):
  65.                 return self.rssItems
  66.        
  67.         def update(self):
  68.                 error = False
  69.                 self.rssItems = {}
  70.                 for feed in self.feeds:        
  71.                         try:
  72.                                 feedUrl = feed[1]
  73.                                 feedTitle = feed[0]
  74.                                 socket.setdefaulttimeout(5)
  75.                                 feedXML = urllib2.urlopen(feedUrl)
  76.                                 self.parseXML(feedTitle, feedXML)
  77.                                 feedXML.close()
  78.                         except urllib2.URLError:
  79.                                 error = True
  80.                                 break
  81.                 if(error):
  82.                         print "Error retrieving RSS feed: ", feedUrl
  83.                         return self.getErrorMessage(feedUrl)
  84.                 return self.getContent()
  85.  
  86.         def parseXML(self, feedTitle, rssXML):
  87.                 dom = parse(rssXML)
  88.                 for item in dom.getElementsByTagName('item'):
  89.                         title = ""
  90.                         description = ""
  91.                         link = ""
  92.                         for rssTitle in item.getElementsByTagName('title'):
  93.                                 if(len(rssTitle.childNodes)>0):
  94.                                         title = rssTitle.childNodes[0].nodeValue
  95.                         for rssDescription in item.getElementsByTagName('description'):
  96.                                 if(len(rssDescription.childNodes)>0):
  97.                                         description = rssDescription.childNodes[0].nodeValue
  98.                         for rssLink in item.getElementsByTagName('link'):
  99.                                 if(len(rssLink.childNodes)>0):
  100.                                         link = rssLink.childNodes[0].nodeValue
  101.                         rssItem = (title, description, link)                   
  102.                         try:
  103.                                 items = self.rssItems[feedTitle]
  104.                                 items.append(rssItem)
  105.                         except KeyError:
  106.                                 self.rssItems[feedTitle] = []                          
  107.                                 self.rssItems[feedTitle].append(rssItem)
  108.        
  109.         def getErrorMessage(self, feedUrl):
  110.                 data = '''<html>
  111.         <head>
  112.                 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  113.                 <title>RssWidget</title>
  114.                
  115.                 <style type="text/css">
  116.                         body{
  117.                                 background-color: '''+self.configuration.getBackgroundColor()+''';
  118.                                 color: '''+self.configuration.getTextColor()+''';
  119.                                 font-size: 10px;                               
  120.                         }
  121.                 </style>
  122.         </head>
  123.         <body>
  124.                 <span style="'''+self.configuration.getTextColor()+'''; font-weight: bold;">''' + feedUrl + ''':</span><br>
  125.                 An error occured while loading the feed contents...
  126.         </body>
  127. </html>'''
  128.                 return data
  129.                
  130.        
  131.         def getContent(self):
  132.                 data = '''<html>
  133.         <head>
  134.                 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  135.                 <title>RssWidget</title>               
  136.        
  137.                 <style type="text/css">
  138.                         body{
  139.                                 background-color: '''+self.configuration.getBackgroundColor()+''';
  140.                                 color: '''+self.configuration.getTextColor()+''';
  141.                                 font-size: 10px;                               
  142.                         }
  143.                
  144.                         a{                             
  145.                                 color: '''+self.configuration.getTextColor()+''';
  146.                                 font-size: 10px;
  147.                                 text-decoration: underline;
  148.                         }
  149.                
  150.                         a:hover{                               
  151.                                 color: '''+self.configuration.getTextHoverColor()+''';
  152.                         }
  153.                
  154.                         a.heading{                             
  155.                                 color: '''+self.configuration.getTextColor()+''';
  156.                                 font-size: 10px;
  157.                                 text-decoration: underline;
  158.                                 font-weight: bold;                             
  159.                         }
  160.                
  161.                         a.heading:hover{                               
  162.                                 color: '''+self.configuration.getTextHoverColor()+''';
  163.                         }
  164.                        
  165.                         li{
  166.                                 padding-top: 5px;
  167.                         }
  168.                
  169.                         div.main_container{                                    
  170.                                 position:absolute;
  171.                                 top: 40px;
  172.                                 bottom: 5px;
  173.                                 left: 5px;
  174.                                 right: 5px;
  175.                                 overflow-y: auto;                              
  176.                                 overflow-x: hidden;
  177.                         }                      
  178.                         div.rss_content{
  179.                                 width: 90%;
  180.                                 font-size: 10px;
  181.                         }
  182.                         h2{
  183.                                 text-decoration: none;
  184.                                 font-weight: bold;
  185.                                 font-size: 12px;
  186.                         }
  187.                 </style>
  188.         </head>
  189.         <body>
  190.           <div class="main_container">
  191.                 <div class="rss_content">\n'''
  192.                 items = self.getRssItems()             
  193.                 for feedTitle,rssItems in items.iteritems():
  194.                         data = data + "<h2 style='position:fixed; top: 10px; left: 10px;'> "+feedTitle+"</h2>\n<ul>"
  195.                         for item in rssItems:
  196.                                 data = data + "\t\t\t<li>\n\t\t\t\t<a class='heading' href='"+ item[2] +"'> "+ item[0] +"</a>\n\t\t\t\t" + item[1] + "\n\t\t\t</li>\n"
  197.                         data = data + "</ul>"
  198.                 data = data + '''\t\t</div>
  199.           </div>
  200.         </body>
  201. </html>'''
  202.                 return data
  203.  
  204. class Updater(threading.Thread):
  205.  
  206.         def __init__(self, app, interval):
  207.                 self.interval = interval
  208.                 self.counter = self.interval
  209.                 self.app = app
  210.                 self.halt = False
  211.                 threading.Thread.__init__(self)
  212.        
  213.         def run(self):
  214.                 self.halt = False
  215.                 while(not self.halt):                  
  216.                         while(self.counter>0):
  217.                                 if(self.halt):
  218.                                         break;
  219.                                 time.sleep(1)
  220.                                 self.counter = self.counter - 1
  221.                         if(self.halt):
  222.                                         break;
  223.                         self.app.updateContent()
  224.                         self.counter = self.interval;
  225.                
  226.         def stop(self):
  227.                 self.halt = True
  228.        
  229.         def reset(self):
  230.                 self.counter = 0
  231.        
  232.         def setInterval(self, interval):
  233.                 self.interval = interval
  234.  
  235. class RssWidget:
  236.  
  237.         def __init__(self):
  238.                
  239.                 self.configuration = ConfigOptions()
  240.                 self.configuration.loadFromFile()
  241.                                        
  242.                 self.window_width = self.configuration.getWindowWidth()
  243.                 self.window_height = self.configuration.getWindowHeight()
  244.                 self.window_left = self.configuration.getWindowLeft()
  245.                 self.window_top = self.configuration.getWindowTop()
  246.                
  247.                 self.background_color = HTMLColorToRGB(self.configuration.getBackgroundColor())
  248.                 self.background_opacity = self.configuration.getBackgroundOpacity()
  249.                
  250.                 self.label_text_color = self.configuration.getTextColor()
  251.                 self.label_text_hover_color = self.configuration.getTextHoverColor()
  252.                 self.update_interval = self.configuration.getUpdateInterval()
  253.                
  254.                 self.border_size = 20
  255.                 self.vgap = 5
  256.                 self.label_width = 50          
  257.                 self.label_height = 25
  258.                 self.renderer_height =  self.window_height  - 2 * self.border_size - self.vgap - self.label_height
  259.                 self.tmp_file = tempfile.mkstemp()[1]
  260.                 self.updater = Updater(self, self.update_interval)
  261.                 self.createWindow()
  262.                 self.createOptionsWindow()
  263.                 self.updater.reset()
  264.                 self.updater.start()
  265.                
  266.         def createWindow(self):
  267.                 self.win = gtk.Window()
  268.                 screen = self.win.get_screen();
  269.                
  270.                 self.win.set_title('RSS-Thingy')
  271.                
  272.                 self.win.set_default_size(self.window_width, self.window_height)        #Window Size
  273.                 self.win.move(self.window_left,self.window_top) #Start position
  274.                 self.win.stick() #All desktops
  275.                 self.win.set_keep_below(True)   #Keep the window below the others
  276.                 self.win.set_decorated(False)   #No Decoration
  277.                 self.win.set_skip_taskbar_hint(True)
  278.                 self.win.set_skip_pager_hint(True)
  279.  
  280.                 self.win.connect('delete-event', gtk.main_quit)
  281.                 self.win.set_app_paintable(True)
  282.                 self.win.connect('expose-event', self.expose)
  283.                 self.win.set_colormap(screen.get_rgba_colormap())       #Set Alpha Screen
  284.                
  285.                 self.fixed = gtk.Fixed();
  286.                 self.win.add(self.fixed);
  287.                
  288.                 self.cursorHand = gtk.gdk.Cursor(gtk.gdk.HAND2)
  289.                
  290.                 self.retriever = feedRetriever(self.configuration)
  291.                
  292.                 self.createRendererWidget()
  293.                 self.createOptionsLabel()
  294.                 self.createCloseLabel()
  295.                 self.createRefreshLabel()
  296.                 self.createFeedSelectionLabel()
  297.  
  298.                 self.win.show_all()
  299.        
  300.         def createOptionsWindow(self):
  301.                 builder = gtk.Builder()
  302.                 builder.add_from_string(glade_xml_string)
  303.                 self.options_window = builder.get_object("window1")
  304.                 self.options_window.set_position(gtk.WIN_POS_CENTER)
  305.                 self.options_window.stick()
  306.                 self.options_window.connect('delete_event', self.on_options_window_close)
  307.                 self.options_add_feed_button = builder.get_object("button1")
  308.                 self.options_add_feed_button.connect("clicked", self.on_options_window_add_feed_clicked)
  309.                 self.options_remove_feed_button = builder.get_object("button2")
  310.                 self.options_remove_feed_button.connect("clicked", self.on_options_window_remove_feed_clicked)
  311.                 self.options_ok_button = builder.get_object("button3")
  312.                 self.options_ok_button.connect("clicked", self.on_options_window_ok_clicked)
  313.                 self.options_cancel_button = builder.get_object("button4")
  314.                 self.options_cancel_button.connect("clicked", self.on_options_window_cancel_clicked)
  315.                 self.options_adj1 = builder.get_object("adjustment1")
  316.                 self.options_adj2 = builder.get_object("adjustment2")
  317.                 self.options_adj3 = builder.get_object("adjustment3")
  318.                 self.options_adj4 = builder.get_object("adjustment4")
  319.                 self.options_adj5 = builder.get_object("adjustment5")
  320.                 self.options_adj6 = builder.get_object("adjustment6")
  321.                 self.options_clrb1 = builder.get_object("colorbutton1")
  322.                 self.options_clrb2 = builder.get_object("colorbutton2")
  323.                 self.options_clrb3 = builder.get_object("colorbutton3")
  324.                 self.options_treeview1 = builder.get_object("treeview1")
  325.                 self.createOptionsFeedsListView()
  326.        
  327.         def updateOptionsValues(self):
  328.                 x, y = self.win.get_position()
  329.                 self.configuration.setWindowLeft(x)
  330.                 self.configuration.setWindowTop(y)
  331.                 self.options_adj1.set_value(self.configuration.getWindowWidth())
  332.                 self.options_adj2.set_value(self.configuration.getWindowHeight())
  333.                 self.options_adj3.set_value(self.configuration.getWindowLeft())
  334.                 self.options_adj4.set_value(self.configuration.getWindowTop())
  335.                 self.options_adj5.set_value(int(self.configuration.getBackgroundOpacity()*100))
  336.                 self.options_adj6.set_value(self.configuration.getUpdateInterval())
  337.                 self.options_clrb1.set_color(gtk.gdk.Color(self.configuration.getBackgroundColor()))
  338.                 self.options_clrb2.set_color(gtk.gdk.Color(self.configuration.getTextColor()))
  339.                 self.options_clrb3.set_color(gtk.gdk.Color(self.configuration.getTextHoverColor()))
  340.                 self.updateOptionsFeedsListView()
  341.        
  342.         def updateConfigurationValues(self):
  343.                 self.configuration.setWindowWidth(int(self.options_adj1.get_value()))
  344.                 self.configuration.setWindowHeight(int(self.options_adj2.get_value()))
  345.                 self.configuration.setWindowLeft(int(self.options_adj3.get_value()))
  346.                 self.configuration.setWindowTop(int(self.options_adj4.get_value()))            
  347.                 self.configuration.setBackgroundOpacity( self.options_adj5.get_value() / 100.0)
  348.                 self.configuration.setUpdateInterval(int(self.options_adj6.get_value()))
  349.                 cl1 = self.options_clrb1.get_color()
  350.                 cl2 = self.options_clrb2.get_color()
  351.                 cl3 = self.options_clrb3.get_color()           
  352.                 clr1 = RGBToHTMLColor( (cl1.red, cl1.green, cl1.blue) )
  353.                 clr2 = RGBToHTMLColor( (cl2.red, cl2.green, cl2.blue) )
  354.                 clr3 = RGBToHTMLColor( (cl3.red, cl3.green, cl3.blue) )
  355.                 self.configuration.setBackgroundColor(clr1)
  356.                 self.configuration.setTextColor(clr2)
  357.                 self.configuration.setTextHoverColor(clr3)
  358.        
  359.         def applyConfiguration(self):
  360.                 self.window_width = self.configuration.getWindowWidth()
  361.                 self.window_height = self.configuration.getWindowHeight()
  362.                 self.window_left = self.configuration.getWindowLeft()
  363.                 self.window_top = self.configuration.getWindowTop()
  364.                
  365.                 self.background_color = HTMLColorToRGB(self.configuration.getBackgroundColor())
  366.                 self.background_opacity = self.configuration.getBackgroundOpacity()
  367.                
  368.                 self.label_text_color = self.configuration.getTextColor()
  369.                 self.label_text_hover_color = self.configuration.getTextHoverColor()
  370.                 self.update_interval = self.configuration.getUpdateInterval()
  371.                
  372.                 self.renderer_height =  self.window_height  - 2 * self.border_size - self.vgap - self.label_height
  373.        
  374.                 self.win.move(self.configuration.getWindowLeft(), self.configuration.getWindowTop())
  375.                 self.resize(self.configuration.getWindowWidth(), self.configuration.getWindowHeight())
  376.                 self.optionsLabel.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>Options</span>")
  377.                 self.closeLabel.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>Close</span>")
  378.                 self.refreshLabel.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>Refresh</span>")
  379.                 self.feedSelectionLabel.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>Select feed</span>")            
  380.                 if(self.updater!=None):
  381.                         self.updater.setInterval(self.configuration.getUpdateInterval())
  382.                         self.updater.reset()
  383.                
  384.        
  385.         def resize(self, w, h):
  386.                 self.win.resize(w, h)
  387.                
  388.                 width = self.window_width - 2 * self.border_size
  389.                 height = self.window_height  - 2 * self.border_size - self.vgap - self.label_height
  390.                 self.renderer.set_size_request(width,height)           
  391.                 self.fixed.move(self.renderer, self.border_size, self.border_size)
  392.                
  393.                 width = self.label_width
  394.                 height = self.label_height
  395.                
  396.                 self.options_eventBox.set_size_request(width,self.label_height)
  397.                 self.fixed.move(self.options_eventBox, self.border_size, self.border_size+self.renderer_height+self.vgap)
  398.                 self.close_eventBox.set_size_request(width,self.label_height)
  399.                 self.fixed.move(self.close_eventBox, self.window_width - self.border_size - width, self.border_size+self.renderer_height+self.vgap)
  400.                 width = 100
  401.                 self.refresh_eventBox.set_size_request(width,self.label_height)
  402.                 self.fixed.move(self.refresh_eventBox, (self.window_width - 2*self.border_size) / 2 - 25, self.border_size+self.renderer_height+self.vgap)
  403.                 width = 80
  404.                 self.feed_eventBox.set_size_request(width,self.label_height)
  405.                 self.fixed.move(self.feed_eventBox, self.window_width - self.border_size - width, 0)
  406.                
  407.        
  408.         def quit(self):
  409.                 gtk.main_quit()        
  410.                 if(self.updater!=None):
  411.                         self.updater.stop()
  412.                 os.remove(self.tmp_file)
  413.                 x, y = self.win.get_position()
  414.                 self.configuration.setWindowLeft(x)
  415.                 self.configuration.setWindowTop(y)
  416.                 self.configuration.saveToFile()
  417.        
  418.         def hideOptionsWindow(self):
  419.                 self.options_window.hide_all()
  420.                
  421.         def showOptionsWindow(self):
  422.                 self.updateOptionsValues()
  423.                 self.options_window.show_all()
  424.        
  425.         def createOptionsLabel(self):
  426.                 width = self.label_width
  427.                 height = self.label_height
  428.                                
  429.                 self.options_eventBox = gtk.EventBox()
  430.                 self.options_eventBox.set_size_request(width,self.label_height)
  431.                 self.options_eventBox.set_visible_window(False)
  432.                 self.fixed.put(self.options_eventBox, self.border_size, self.border_size+self.renderer_height+self.vgap)
  433.                
  434.                 self.optionsLabel = gtk.Label()
  435.                 self.optionsLabel.set_justify(gtk.JUSTIFY_LEFT)
  436.                 self.optionsLabel.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>Options</span>")
  437.                 self.options_eventBox.connect("enter-notify-event", self.mouse_enter, self.optionsLabel, "Options")
  438.                 self.options_eventBox.connect("leave-notify-event", self.mouse_leave, self.optionsLabel, "Options")
  439.                 self.options_eventBox.connect("button-press-event", self.on_options_label_clicked)
  440.                 self.options_eventBox.add(self.optionsLabel)
  441.                
  442.        
  443.         def createCloseLabel(self):
  444.                 width = self.label_width
  445.                 height = self.label_height
  446.                
  447.                 self.close_eventBox = gtk.EventBox()
  448.                 self.close_eventBox.set_size_request(width,self.label_height)
  449.                 self.close_eventBox.set_visible_window(False)          
  450.                 self.fixed.put(self.close_eventBox, self.window_width - self.border_size - width, self.border_size+self.renderer_height+self.vgap)
  451.                
  452.                 self.closeLabel = gtk.Label()
  453.                 self.closeLabel.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>Close</span>")
  454.                 self.closeLabel.set_justify(gtk.JUSTIFY_RIGHT)
  455.                 self.close_eventBox.connect("enter-notify-event", self.mouse_enter, self.closeLabel, "Close")
  456.                 self.close_eventBox.connect("leave-notify-event", self.mouse_leave, self.closeLabel, "Close")
  457.                 self.close_eventBox.connect("button-press-event", self.on_close_label_clicked)
  458.                 self.close_eventBox.add(self.closeLabel)
  459.                
  460.         def createRefreshLabel(self):
  461.                 width = 100
  462.                 height = self.label_height
  463.                
  464.                 self.refresh_eventBox = gtk.EventBox()
  465.                 self.refresh_eventBox.set_size_request(width,self.label_height)
  466.                 self.refresh_eventBox.set_visible_window(False)        
  467.                 self.fixed.put(self.refresh_eventBox, (self.window_width - 2*self.border_size) / 2 - 25, self.border_size+self.renderer_height+self.vgap)
  468.                
  469.                 self.refreshLabel = gtk.Label()
  470.                 self.refreshLabel.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>Refresh</span>")
  471.                 self.refreshLabel.set_justify(gtk.JUSTIFY_CENTER)
  472.                 self.refresh_eventBox.connect("enter-notify-event", self.mouse_enter, self.refreshLabel, "Refresh")
  473.                 self.refresh_eventBox.connect("leave-notify-event", self.mouse_leave, self.refreshLabel, "Refresh")
  474.                 self.refresh_eventBox.connect("button-press-event", self.on_refresh_label_clicked)
  475.                 self.refresh_eventBox.add(self.refreshLabel)
  476.                
  477.         def createFeedSelectionLabel(self):
  478.                 width = 80
  479.                 height = self.label_height
  480.                
  481.                 self.feed_eventBox = gtk.EventBox()
  482.                 self.feed_eventBox.set_size_request(width,self.label_height)
  483.                 self.feed_eventBox.set_visible_window(False)           
  484.                 self.fixed.put(self.feed_eventBox, self.window_width - self.border_size - width, 0)
  485.                
  486.                 self.feedSelectionLabel = gtk.Label()
  487.                 self.feedSelectionLabel.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>Select feed</span>")
  488.                 self.feedSelectionLabel.set_justify(gtk.JUSTIFY_RIGHT)
  489.                 self.feed_eventBox.connect("enter-notify-event", self.mouse_enter, self.feedSelectionLabel, "Select feed")
  490.                 self.feed_eventBox.connect("leave-notify-event", self.mouse_leave, self.feedSelectionLabel, "Select feed")
  491.                 self.feed_eventBox.connect("button-press-event", self.on_select_label_clicked)
  492.                 self.feed_eventBox.add(self.feedSelectionLabel)
  493.        
  494.         def createFeedsPopupMenu(self, event):
  495.                 menu = gtk.Menu()
  496.                 feeds = self.configuration.getFeeds()
  497.                 for feed in feeds:
  498.                         menu_item = gtk.MenuItem(feed[0])
  499.                         menu_item.connect("button-press-event", self.on_popupmenu_item_clicked, feed)
  500.                         menu.append(menu_item)                 
  501.                         menu_item.show()
  502.                 menu.popup(None, None, None, event.button, event.time)
  503.        
  504.        
  505.         def createRendererWidget(self):
  506.                
  507.                 width = self.window_width - 2 * self.border_size
  508.                 height = self.renderer_height
  509.                                
  510.                 self.renderer = webkit.WebView()
  511.                 self.renderer.connect("navigation-requested", self._navigation_requested_cb)
  512.                
  513.                 self.renderer.set_size_request(width,height)
  514.                 self.fixed.put(self.renderer, self.border_size, self.border_size)
  515.                
  516.                 data = '''<html>
  517.         <head>
  518.                 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  519.                 <title>RssWidget</title>
  520.                
  521.                 <style type="text/css">
  522.                         body{
  523.                                 background-color: '''+self.configuration.getBackgroundColor()+''';
  524.                                 text-decoration: none;
  525.                                 color: '''+self.configuration.getTextColor()+''';
  526.                                 font-size: 10px;                               
  527.                         }
  528.                 </style>
  529.         </head>
  530.         <body>'''
  531.                 feed = self.configuration.getCurrentFeed()
  532.                 if(feed!=None):
  533.                         data = data + "\t\t<span style='"+self.configuration.getTextColor()+"; font-size: 12px; font-weight: bold;'>" + self.configuration.getCurrentFeed()[0] + ":</span><br>\n\t\t\tLoading feed contents...\n"
  534.                 else:
  535.                         data = data + "Click on &quot;Options&quot; to add new RSS feeds and on &quot;Select feed&quot; to select the one to be displayed."
  536.                 data = data + "\t</body>\n</html>"
  537.                 self.renderer.load_html_string(data.encode('utf-8'), 'file:///')
  538.                
  539.         def _navigation_requested_cb(self, view, frame, networkRequest):
  540.                 # get uri from request object
  541.                 uri=networkRequest.get_uri()
  542.                 if(uri.startswith("file://")):                 
  543.                         return 0 #use default handler
  544.                 elif(uri.startswith('http://') or uri.startswith('https://')):
  545.                         webbrowser.open_new(uri)
  546.                         return 1
  547.                 else:
  548.                         return 1
  549.        
  550.         def updateContent(self):
  551.                 rssFeed = self.configuration.getCurrentFeed()
  552.                 if(rssFeed!=None):
  553.                         self.retriever.setFeed(rssFeed);
  554.                         data = self.retriever.update()
  555.                         f = open(self.tmp_file, "w")
  556.                         f.write(data.encode('utf-8'))
  557.                         f.close()
  558.                         self.renderer.open("file://"+self.tmp_file)
  559.        
  560.         def createOptionsFeedsListView(self):
  561.                 self.liststore = self.createModel()            
  562.                 self.options_treeview1.set_model(self.liststore)
  563.                 self.createColumns(self.options_treeview1)
  564.        
  565.         def createModel(self):
  566.                 store = gtk.ListStore(str, str)
  567.                 return store
  568.        
  569.         def createColumns(self, treeView):
  570.                 rendererText = gtk.CellRendererText()
  571.                 column = gtk.TreeViewColumn("Feed Name", rendererText, text=0)
  572.                 column.set_sort_column_id(0)    
  573.                 treeView.append_column(column)
  574.                
  575.                 rendererText = gtk.CellRendererText()
  576.                 column = gtk.TreeViewColumn("URL", rendererText, text=1)
  577.                 column.set_sort_column_id(1)
  578.                 treeView.append_column(column)
  579.                
  580.         def updateOptionsFeedsListView(self):
  581.                 self.liststore.clear()
  582.                 for feed in self.configuration.getFeeds():
  583.                     self.liststore.append(feed)
  584.        
  585.         def addRssFeed(self):
  586.                 result = self.showAddFeedDialog()
  587.                 response = result[0]
  588.                 feed = (result[1], result[2])
  589.                 if(response == gtk.RESPONSE_OK):
  590.                         self.configuration.addFeed(feed)
  591.                         self.updateOptionsFeedsListView()
  592.        
  593.         def removeSelectedFeed(self):
  594.                 '''selectedItemIter = self.getSelectedListviewItemIter(self.options_treeview1)
  595.                 if(selectedItemIter!=None):
  596.                         self.liststore.remove(selectedItemIter)
  597.                         self.configuration.addFeed(feed)'''
  598.                 selection = self.options_treeview1.get_selection()
  599.                 if (selection !=None):
  600.                         model, iter = selection.get_selected()
  601.                         if iter!=None:
  602.                                 index = model.get_path(iter)[0]
  603.                                 self.configuration.removeFeed(index)
  604.                                 self.updateOptionsFeedsListView()
  605.        
  606.         def getSelectedListviewItemIter(self, listview):
  607.                 treeSelection = listview.get_selection()
  608.                 treeIter = treeSelection.get_selected()[1]
  609.                 return treeIter
  610.        
  611.         def showAddFeedDialog(self):
  612.                 dialog = gtk.MessageDialog(
  613.                         self.options_window,
  614.                         gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
  615.                         gtk.MESSAGE_QUESTION,
  616.                         gtk.BUTTONS_OK_CANCEL,
  617.                         None)
  618.                 dialog.set_markup('\n<b>Please enter the following RSS feed properties:</b>')
  619.        
  620.                 feed_title_entry = gtk.Entry()
  621.                 feed_title_entry.set_text("RSS feed name")
  622.                 hbox1 = gtk.HBox()
  623.                 hbox1.pack_start(gtk.Label("Name:"))
  624.                 hbox1.pack_end(feed_title_entry)
  625.        
  626.                 feed_url_entry = gtk.Entry()
  627.                 feed_url_entry.set_text("RSS feed url")
  628.                 hbox2 = gtk.HBox()
  629.                 hbox2.pack_start(gtk.Label("URL:"))
  630.                 hbox2.pack_end(feed_url_entry)
  631.                
  632.                
  633.                 dialog.vbox.pack_start(hbox1)
  634.                 dialog.vbox.pack_start(hbox2)
  635.                 dialog.show_all()
  636.                
  637.                 response = dialog.run()
  638.                 feed_name = feed_title_entry.get_text()
  639.                 feed_url = feed_url_entry.get_text()
  640.                 dialog.destroy()
  641.                 return (response, feed_name, feed_url)
  642.        
  643.         def on_options_window_close(self, widget, event):
  644.                 self.hideOptionsWindow()
  645.                 return True
  646.                
  647.         def on_popupmenu_item_clicked(self, widget, event, feed):
  648.                 self.configuration.setCurrentFeed(feed)
  649.                 if(self.updater!=None):
  650.                         self.updater.reset()
  651.                        
  652.        
  653.         def mouse_enter(self, widget, event, label, text):
  654.                 label.set_markup("<span font_weight='bold' color='"+self.label_text_hover_color+"'>"+text+"</span>")
  655.                 widget.window.set_cursor(self.cursorHand)
  656.        
  657.         def mouse_leave(self, widget, event, label, text):
  658.                 label.set_markup("<span font_weight='bold' color='"+self.label_text_color+"'>"+text+"</span>")
  659.                 widget.window.set_cursor(None)
  660.        
  661.         def on_close_label_clicked(self, widget, event):               
  662.                 self.quit()
  663.                
  664.         def on_refresh_label_clicked(self, widget, event):
  665.                 if(self.updater!=None):
  666.                         self.updater.reset()
  667.        
  668.         def on_options_label_clicked(self, widget, event):             
  669.                 self.showOptionsWindow()
  670.        
  671.         def on_select_label_clicked(self, widget, event):              
  672.                 self.createFeedsPopupMenu(event)
  673.        
  674.         def on_options_window_ok_clicked(self, widget):        
  675.                 self.hideOptionsWindow()
  676.                 self.updateConfigurationValues()
  677.                 self.applyConfiguration()
  678.        
  679.         def on_options_window_cancel_clicked(self, widget):            
  680.                 self.hideOptionsWindow()
  681.                
  682.         def on_options_window_add_feed_clicked(self, widget):
  683.                 self.addRssFeed()
  684.                
  685.         def on_options_window_remove_feed_clicked(self, widget):
  686.                 self.removeSelectedFeed()
  687.  
  688.         def expose(self, widget, event):
  689.        
  690.                 (width, height) = widget.get_size()                             #Get window size
  691.                 cr = widget.window.cairo_create()                               #Get a cairo context
  692.                
  693.            
  694.                 cr.set_source_rgba(1.0, 1.0, 1.0, 0.0)          #Make the window transparent
  695.                 cr.set_operator(cairo.OPERATOR_SOURCE)          #Make the window transparent
  696.                 cr.paint()                                      #Make the window transparent
  697.                 cr.set_operator(cairo.OPERATOR_OVER);
  698.  
  699.                 self.draw_background(cr,width,height)
  700.        
  701.                 return False
  702.        
  703.         def draw_background(self,cr,w,h):
  704.                 x = 0
  705.                 y = 0
  706.                 r = 15
  707.        
  708.                 cr.set_operator(cairo.OPERATOR_SOURCE);                
  709.                 cr.set_source_rgba (self.background_color[0], self.background_color[1], self.background_color[2], self.background_opacity); # Background opacity
  710.                
  711.                 cr.move_to      ( x+r,y )                       # Move to A
  712.                 cr.line_to      ( x+w-r,y )                     # Straight line to B
  713.                 cr.curve_to     ( x+w-r,y,x+w,y,x+w,y+r )       # Curve to C
  714.                 cr.line_to      ( x+w,y+h-r )                   # Move to D
  715.                 cr.curve_to     ( x+w,y+h-r,x+w,y+h,x+w-r,y+h ) # Curve to E
  716.                 cr.line_to      ( x+r,y+h )                     # Line to F
  717.                 cr.curve_to     ( x+r,y+h,x,y+h,x,y+h-r )       # Curve to G
  718.                 cr.line_to      ( x,y+r )                       # Line to H
  719.                 cr.curve_to     ( x,y+r,x,y,x+r,y)              # Curve to G
  720.                 cr.fill         ( )
  721.                
  722.        
  723.         def main(self):
  724.                 gtk.main()     
  725.                 return True
  726.                
  727.  
  728. class ConfigOptions:
  729.        
  730.         def __init__(self):
  731.                 self.checkForConfigDir()
  732.                 self.configFile = os.path.join(self.configPath, "config.xml")
  733.        
  734.                 self.window_width = 640
  735.                 self.window_height = 400
  736.                 self.window_left = 100
  737.                 self.window_top = 100
  738.                
  739.                 self.background_color = "#000000"
  740.                 self.background_opacity = 0.75
  741.                 self.text_color = "#FFFFFF"
  742.                 self.text_hover_color = "#DEFE00"
  743.                 self.update_interval = 300
  744.                
  745.                 self.current_feed = None
  746.                 self.feeds=[]
  747.        
  748.         def checkForConfigDir(self):
  749.                 tmp_path = os.path.join('~', '.config', 'rssWidget')           
  750.                 self.configPath = os.path.expanduser(tmp_path)
  751.                 if(not os.path.exists(self.configPath)):
  752.                         os.makedirs(self.configPath)
  753.                         print "Created dir: "+self.configPath
  754.        
  755.         def getWindowWidth(self):
  756.                 return self.window_width
  757.        
  758.         def setWindowWidth(self, width):
  759.                 self.window_width = width
  760.        
  761.         def getWindowHeight(self):
  762.                 return self.window_height
  763.        
  764.         def setWindowHeight(self, height):
  765.                 self.window_height = height
  766.                
  767.         def getWindowLeft(self):
  768.                 return self.window_left
  769.        
  770.         def setWindowLeft(self, left):
  771.                 self.window_left = left
  772.                
  773.         def getWindowTop(self):
  774.                 return self.window_top
  775.        
  776.         def setWindowTop(self, top):
  777.                 self.window_top = top
  778.                
  779.         def getBackgroundColor(self):
  780.                 return self.background_color
  781.        
  782.         def setBackgroundColor(self, bg):
  783.                 self.background_color = bg
  784.        
  785.         def getBackgroundOpacity(self):
  786.                 return self.background_opacity
  787.        
  788.         def setBackgroundOpacity(self, opacity):
  789.                 self.background_opacity = opacity
  790.                
  791.         def getTextColor(self):
  792.                 return self.text_color
  793.        
  794.         def setTextColor(self, color):
  795.                 self.text_color = color
  796.        
  797.         def getTextHoverColor(self):
  798.                 return self.text_hover_color
  799.        
  800.         def setTextHoverColor(self, color):
  801.                 self.text_hover_color = color
  802.                
  803.         def getUpdateInterval(self):
  804.                 return self.update_interval
  805.        
  806.         def setUpdateInterval(self, interval):
  807.                 self.update_interval = interval
  808.        
  809.         def getCurrentFeed(self):
  810.                 return self.current_feed
  811.                
  812.         def setCurrentFeed(self, feed):
  813.                 self.current_feed = feed
  814.        
  815.         def getFeeds(self):
  816.                 return self.feeds
  817.        
  818.         def addFeed(self, feed):
  819.                 self.feeds.append(feed)
  820.        
  821.         def removeFeed(self, index):
  822.                 self.feeds.pop(index)
  823.        
  824.         def saveToFile(self):
  825.                 self.checkForConfigDir()
  826.                 data = "<configuration>\n"
  827.                 data = data +  "\t<window-width>" + str(self.window_width) + "</window-width>\n"
  828.                 data = data +  "\t" + "<window-height>" + str(self.window_height) + "</window-height>" + "\n"
  829.                 data = data +  "\t" + "<window-left>" + str(self.window_left) + "</window-left>" + "\n"
  830.                 data = data +  "\t" + "<window-top>" + str(self.window_top) + "</window-top>" + "\n"
  831.                 data = data +  "\t" + "<background-color>" + self.background_color + "</background-color>" + "\n"
  832.                 data = data +  "\t" + "<background-opacity>" + str(self.background_opacity) + "</background-opacity>" + "\n"
  833.                 data = data +  "\t" + "<text-color>" + self.text_color + "</text-color>" + "\n"
  834.                 data = data +  "\t" + "<text-hover-color>" + self.text_hover_color + "</text-hover-color>" + "\n"
  835.                 data = data +  "\t" + "<update-interval>" + str(self.update_interval) + "</update-interval>" + "\n"
  836.                 if(self.current_feed!=None):
  837.                         data = data +  "\t" + "<current-feed>" + "\n"          
  838.                         data = data +  "\t\t" + "<title>" + self.current_feed[0] + "</title>" + "\n"
  839.                         data = data +  "\t\t" + "<url>" + self.current_feed[1] + "</url>" + "\n"
  840.                         data = data +  "\t" + "</current-feed>" + "\n"
  841.                 for feed in self.feeds:
  842.                         data = data +  "\t" + "<feed>" + "\n"
  843.                         data = data +  "\t\t" + "<title>" + feed[0] + "</title>" + "\n"
  844.                         data = data +  "\t\t" + "<url>" + feed[1] + "</url>" + "\n"
  845.                         data = data +  "\t" + "</feed>" + "\n"
  846.                 data = data +  "</configuration>\n"
  847.                 f = open(self.configFile, 'w')
  848.                 f.write(data.encode('utf-8'))          
  849.                 f.close()
  850.        
  851.         def loadFromFile(self):
  852.                 if (os.path.exists(self.configFile)):
  853.                         f =  open(self.configFile, 'r')
  854.                         dom = parse(f)
  855.                         f.close()
  856.                         for item in dom.getElementsByTagName('window-width'):
  857.                                 if(len(item.childNodes)>0):
  858.                                         self.window_width = int(item.childNodes[0].nodeValue)
  859.                         #print "window-width : ", self.window_width
  860.                         for item in dom.getElementsByTagName('window-height'):
  861.                                 if(len(item.childNodes)>0):
  862.                                         self.window_height = int(item.childNodes[0].nodeValue)
  863.                         #print "window-height : ", self.window_height
  864.                         for item in dom.getElementsByTagName('window-left'):
  865.                                 if(len(item.childNodes)>0):
  866.                                         self.window_left = int(item.childNodes[0].nodeValue)
  867.                         #print "window-left : ", self.window_left
  868.                         for item in dom.getElementsByTagName('window-top'):
  869.                                 if(len(item.childNodes)>0):
  870.                                         self.window_top = int(item.childNodes[0].nodeValue)
  871.                         #print "window-top : ", self.window_top
  872.                         for item in dom.getElementsByTagName('background-color'):
  873.                                 if(len(item.childNodes)>0):
  874.                                         self.background_color = item.childNodes[0].nodeValue
  875.                         #print "background-color : ", self.background_color
  876.                         for item in dom.getElementsByTagName('background-opacity'):
  877.                                 if(len(item.childNodes)>0):
  878.                                         self.background_opacity = float(item.childNodes[0].nodeValue)
  879.                         #print "background-opacity : ", self.background_opacity
  880.                         for item in dom.getElementsByTagName('text-color'):
  881.                                 if(len(item.childNodes)>0):
  882.                                         self.text_color = item.childNodes[0].nodeValue
  883.                         #print "text-color : ", self.text_color
  884.                         for item in dom.getElementsByTagName('text-hover-color'):
  885.                                 if(len(item.childNodes)>0):
  886.                                         self.text_hover_color = item.childNodes[0].nodeValue
  887.                         #print "text-hover-color : ", self.text_hover_color
  888.                         for item in dom.getElementsByTagName('update-interval'):
  889.                                 if(len(item.childNodes)>0):
  890.                                         self.update_interval = int(item.childNodes[0].nodeValue)
  891.                         #print "update-interval : ", self.update_interval
  892.                         for item in dom.getElementsByTagName('current-feed'):
  893.                                 title = ""
  894.                                 url = ""
  895.                                 for rssTitle in item.getElementsByTagName('title'):
  896.                                         if(len(rssTitle.childNodes)>0):
  897.                                                 title = rssTitle.childNodes[0].nodeValue
  898.                                 for rssUrl in item.getElementsByTagName('url'):
  899.                                         if(len(rssUrl.childNodes)>0):
  900.                                                 url = rssUrl.childNodes[0].nodeValue
  901.                                 self.current_feed = (title, url)
  902.                         #print "current-feed: ", self.current_feed
  903.                         for item in dom.getElementsByTagName('feed'):
  904.                                 title = ""
  905.                                 url = ""
  906.                                 for rssTitle in item.getElementsByTagName('title'):
  907.                                         if(len(rssTitle.childNodes)>0):
  908.                                                 title = rssTitle.childNodes[0].nodeValue
  909.                                 for rssUrl in item.getElementsByTagName('url'):
  910.                                         if(len(rssUrl.childNodes)>0):
  911.                                                 url = rssUrl.childNodes[0].nodeValue
  912.                                 feedItem = (title, url)
  913.                                 self.feeds.append(feedItem)
  914.                         #print "feeds: ", self.feeds
  915.  
  916.                
  917. def HTMLColorToRGB(colorstring):
  918.         colorstring = colorstring.strip()
  919.         if colorstring[0] == '#':
  920.                 colorstring = colorstring[1:]
  921.         if len(colorstring) != 6:
  922.                 raise ValueError, "#" + colorstring + "is not in #RRGGBB format"
  923.         r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:]
  924.         r, g, b = [int(n, 16) for n in (r, g, b)]
  925.         return (r, g, b)
  926.            
  927. def RGBToHTMLColor(rgb_tuple):
  928.         r = hex(rgb_tuple[0]*255 / 65535)[2:]
  929.         g = hex(rgb_tuple[1]*255 / 65535)[2:]
  930.         b = hex(rgb_tuple[2]*255 / 65535)[2:]
  931.         if(len(r)==1): r = '0'+r
  932.         if(len(g)==1): g = '0'+g
  933.         if(len(b)==1): b = '0'+b
  934.         hexcolor = '#' + r + g + b
  935.         return hexcolor
  936.  
  937. def setProcessName(processName):
  938.         #The following has been "borrowed" from exaile :)
  939.         if sys.platform == 'linux2':
  940.             # Set process name.  Only works on Linux >= 2.1.57.
  941.             try:
  942.                 import ctypes
  943.                 libc = ctypes.CDLL('libc.so.6')
  944.                 libc.prctl(15, processName, 0, 0, 0)
  945.             except:
  946.                 try:
  947.                      import dl
  948.                      libc = dl.open('/lib/libc.so.6')
  949.                      libc.call('prctl', 15, (processName+'\0'), 0, 0, 0) # 15 is PR_SET_NAME
  950.                 except:
  951.                     pass
  952.  
  953.  
  954. glade_xml_string = '''<?xml version="1.0"?>
  955. <interface>
  956.  <requires lib="gtk+" version="2.16"/>
  957.  <!-- interface-naming-policy project-wide -->
  958.  <object class="GtkWindow" id="window1">
  959.    <property name="width_request">500</property>
  960.    <property name="height_request">500</property>
  961.    <property name="default_width">500</property>
  962.    <property name="default_height">500</property>
  963.    <child>
  964.      <object class="GtkHBox" id="hbox1">
  965.        <property name="visible">True</property>
  966.        <child>
  967.          <object class="GtkVBox" id="vbox1">
  968.            <property name="visible">True</property>
  969.            <property name="orientation">vertical</property>
  970.            <child>
  971.              <object class="GtkHBox" id="hbox2">
  972.                <property name="visible">True</property>
  973.                <child>
  974.                  <object class="GtkLabel" id="label1">
  975.                    <property name="visible">True</property>
  976.                    <property name="label" translatable="yes">&lt;b&gt;WIndow size:&lt;/b&gt;</property>
  977.                    <property name="use_markup">True</property>
  978.                  </object>
  979.                  <packing>
  980.                    <property name="expand">False</property>
  981.                    <property name="position">0</property>
  982.                  </packing>
  983.                </child>
  984.              </object>
  985.              <packing>
  986.                <property name="expand">False</property>
  987.                <property name="position">0</property>
  988.              </packing>
  989.            </child>
  990.            <child>
  991.              <object class="GtkHBox" id="hbox7">
  992.                <property name="visible">True</property>
  993.                <child>
  994.                  <object class="GtkHBox" id="hbox11">
  995.                    <property name="visible">True</property>
  996.                    <child>
  997.                      <object class="GtkLabel" id="label6">
  998.                        <property name="visible">True</property>
  999.                        <property name="label" translatable="yes">width : </property>
  1000.                        <property name="use_markup">True</property>
  1001.                      </object>
  1002.                      <packing>
  1003.                        <property name="expand">False</property>
  1004.                        <property name="position">0</property>
  1005.                      </packing>
  1006.                    </child>
  1007.                    <child>
  1008.                      <object class="GtkSpinButton" id="spinbutton1">
  1009.                        <property name="visible">True</property>
  1010.                        <property name="can_focus">True</property>
  1011.                        <property name="invisible_char">&#x25CF;</property>
  1012.                        <property name="adjustment">adjustment1</property>
  1013.                      </object>
  1014.                      <packing>
  1015.                        <property name="expand">False</property>
  1016.                        <property name="position">1</property>
  1017.                      </packing>
  1018.                    </child>
  1019.                    <child>
  1020.                      <object class="GtkLabel" id="label7">
  1021.                        <property name="visible">True</property>
  1022.                        <property name="label" translatable="yes"> pixels    </property>
  1023.                      </object>
  1024.                      <packing>
  1025.                        <property name="expand">False</property>
  1026.                        <property name="position">2</property>
  1027.                      </packing>
  1028.                    </child>
  1029.                    <child>
  1030.                      <object class="GtkLabel" id="label8">
  1031.                        <property name="visible">True</property>
  1032.                        <property name="label" translatable="yes">height : </property>
  1033.                        <property name="use_markup">True</property>
  1034.                      </object>
  1035.                      <packing>
  1036.                        <property name="expand">False</property>
  1037.                        <property name="position">3</property>
  1038.                      </packing>
  1039.                    </child>
  1040.                    <child>
  1041.                      <object class="GtkSpinButton" id="spinbutton2">
  1042.                        <property name="visible">True</property>
  1043.                        <property name="can_focus">True</property>
  1044.                        <property name="invisible_char">&#x25CF;</property>
  1045.                        <property name="adjustment">adjustment2</property>
  1046.                      </object>
  1047.                      <packing>
  1048.                        <property name="expand">False</property>
  1049.                        <property name="position">4</property>
  1050.                      </packing>
  1051.                    </child>
  1052.                    <child>
  1053.                      <object class="GtkLabel" id="label9">
  1054.                        <property name="visible">True</property>
  1055.                        <property name="label" translatable="yes"> pixels</property>
  1056.                      </object>
  1057.                      <packing>
  1058.                        <property name="expand">False</property>
  1059.                        <property name="position">5</property>
  1060.                      </packing>
  1061.                    </child>
  1062.                  </object>
  1063.                  <packing>
  1064.                    <property name="expand">False</property>
  1065.                    <property name="padding">10</property>
  1066.                    <property name="position">0</property>
  1067.                  </packing>
  1068.                </child>
  1069.              </object>
  1070.              <packing>
  1071.                <property name="expand">False</property>
  1072.                <property name="position">1</property>
  1073.              </packing>
  1074.            </child>
  1075.            <child>
  1076.              <object class="GtkHBox" id="hbox3">
  1077.                <property name="visible">True</property>
  1078.                <child>
  1079.                  <object class="GtkLabel" id="label2">
  1080.                    <property name="visible">True</property>
  1081.                    <property name="label" translatable="yes">&lt;b&gt;WIndow position:&lt;/b&gt;</property>
  1082.                    <property name="use_markup">True</property>
  1083.                  </object>
  1084.                  <packing>
  1085.                    <property name="expand">False</property>
  1086.                    <property name="position">0</property>
  1087.                  </packing>
  1088.                </child>
  1089.              </object>
  1090.              <packing>
  1091.                <property name="expand">False</property>
  1092.                <property name="position">2</property>
  1093.              </packing>
  1094.            </child>
  1095.            <child>
  1096.              <object class="GtkHBox" id="hbox8">
  1097.                <property name="visible">True</property>
  1098.                <child>
  1099.                  <object class="GtkHBox" id="hbox12">
  1100.                    <property name="visible">True</property>
  1101.                    <child>
  1102.                      <object class="GtkLabel" id="label10">
  1103.                        <property name="visible">True</property>
  1104.                        <property name="label" translatable="yes">left : </property>
  1105.                        <property name="use_markup">True</property>
  1106.                      </object>
  1107.                      <packing>
  1108.                        <property name="expand">False</property>
  1109.                        <property name="position">0</property>
  1110.                      </packing>
  1111.                    </child>
  1112.                    <child>
  1113.                      <object class="GtkSpinButton" id="spinbutton3">
  1114.                        <property name="visible">True</property>
  1115.                        <property name="can_focus">True</property>
  1116.                        <property name="invisible_char">&#x25CF;</property>
  1117.                        <property name="adjustment">adjustment3</property>
  1118.                      </object>
  1119.                      <packing>
  1120.                        <property name="expand">False</property>
  1121.                        <property name="position">1</property>
  1122.                      </packing>
  1123.                    </child>
  1124.                    <child>
  1125.                      <object class="GtkLabel" id="label11">
  1126.                        <property name="visible">True</property>
  1127.                        <property name="label" translatable="yes"> pixels    </property>
  1128.                      </object>
  1129.                      <packing>
  1130.                        <property name="expand">False</property>
  1131.                        <property name="position">2</property>
  1132.                      </packing>
  1133.                    </child>
  1134.                    <child>
  1135.                      <object class="GtkLabel" id="label12">
  1136.                        <property name="visible">True</property>
  1137.                        <property name="label" translatable="yes">top : </property>
  1138.                        <property name="use_markup">True</property>
  1139.                      </object>
  1140.                      <packing>
  1141.                        <property name="expand">False</property>
  1142.                        <property name="position">3</property>
  1143.                      </packing>
  1144.                    </child>
  1145.                    <child>
  1146.                      <object class="GtkSpinButton" id="spinbutton4">
  1147.                        <property name="visible">True</property>
  1148.                        <property name="can_focus">True</property>
  1149.                        <property name="invisible_char">&#x25CF;</property>
  1150.                        <property name="adjustment">adjustment4</property>
  1151.                      </object>
  1152.                      <packing>
  1153.                        <property name="expand">False</property>
  1154.                        <property name="position">4</property>
  1155.                      </packing>
  1156.                    </child>
  1157.                    <child>
  1158.                      <object class="GtkLabel" id="label13">
  1159.                        <property name="visible">True</property>
  1160.                        <property name="label" translatable="yes"> pixels</property>
  1161.                      </object>
  1162.                      <packing>
  1163.                        <property name="expand">False</property>
  1164.                        <property name="position">5</property>
  1165.                      </packing>
  1166.                    </child>
  1167.                  </object>
  1168.                  <packing>
  1169.                    <property name="expand">False</property>
  1170.                    <property name="padding">10</property>
  1171.                    <property name="position">0</property>
  1172.                  </packing>
  1173.                </child>
  1174.              </object>
  1175.              <packing>
  1176.                <property name="expand">False</property>
  1177.                <property name="position">3</property>
  1178.              </packing>
  1179.            </child>
  1180.            <child>
  1181.              <object class="GtkHBox" id="hbox4">
  1182.                <property name="visible">True</property>
  1183.                <child>
  1184.                  <object class="GtkLabel" id="label3">
  1185.                    <property name="visible">True</property>
  1186.                    <property name="label" translatable="yes">&lt;b&gt;WIndow background:&lt;/b&gt;</property>
  1187.                    <property name="use_markup">True</property>
  1188.                  </object>
  1189.                  <packing>
  1190.                    <property name="expand">False</property>
  1191.                    <property name="position">0</property>
  1192.                  </packing>
  1193.                </child>
  1194.              </object>
  1195.              <packing>
  1196.                <property name="expand">False</property>
  1197.                <property name="position">4</property>
  1198.              </packing>
  1199.            </child>
  1200.            <child>
  1201.              <object class="GtkHBox" id="hbox9">
  1202.                <property name="visible">True</property>
  1203.                <child>
  1204.                  <object class="GtkHBox" id="hbox10">
  1205.                    <property name="visible">True</property>
  1206.                    <child>
  1207.                      <object class="GtkLabel" id="label14">
  1208.                        <property name="visible">True</property>
  1209.                        <property name="label" translatable="yes">background  color : </property>
  1210.                        <property name="use_markup">True</property>
  1211.                      </object>
  1212.                      <packing>
  1213.                        <property name="expand">False</property>
  1214.                        <property name="position">0</property>
  1215.                      </packing>
  1216.                    </child>
  1217.                    <child>
  1218.                      <object class="GtkColorButton" id="colorbutton1">
  1219.                        <property name="visible">True</property>
  1220.                        <property name="can_focus">True</property>
  1221.                        <property name="receives_default">True</property>
  1222.                        <property name="color">#000000000000</property>
  1223.                      </object>
  1224.                      <packing>
  1225.                        <property name="expand">False</property>
  1226.                        <property name="position">1</property>
  1227.                      </packing>
  1228.                    </child>
  1229.                    <child>
  1230.                      <object class="GtkLabel" id="label15">
  1231.                        <property name="visible">True</property>
  1232.                        <property name="label" translatable="yes"> </property>
  1233.                      </object>
  1234.                      <packing>
  1235.                        <property name="expand">False</property>
  1236.                        <property name="position">2</property>
  1237.                      </packing>
  1238.                    </child>
  1239.                    <child>
  1240.                      <object class="GtkLabel" id="label16">
  1241.                        <property name="visible">True</property>
  1242.                        <property name="label" translatable="yes">opacity : </property>
  1243.                        <property name="use_markup">True</property>
  1244.                      </object>
  1245.                      <packing>
  1246.                        <property name="expand">False</property>
  1247.                        <property name="position">3</property>
  1248.                      </packing>
  1249.                    </child>
  1250.                    <child>
  1251.                      <object class="GtkSpinButton" id="spinbutton6">
  1252.                        <property name="visible">True</property>
  1253.                        <property name="can_focus">True</property>
  1254.                        <property name="invisible_char">&#x25CF;</property>
  1255.                        <property name="adjustment">adjustment5</property>
  1256.                      </object>
  1257.                      <packing>
  1258.                        <property name="expand">False</property>
  1259.                        <property name="position">4</property>
  1260.                      </packing>
  1261.                    </child>
  1262.                    <child>
  1263.                      <object class="GtkLabel" id="label17">
  1264.                        <property name="visible">True</property>
  1265.                        <property name="label" translatable="yes"> %</property>
  1266.                      </object>
  1267.                      <packing>
  1268.                        <property name="expand">False</property>
  1269.                        <property name="position">5</property>
  1270.                      </packing>
  1271.                    </child>
  1272.                  </object>
  1273.                  <packing>
  1274.                    <property name="expand">False</property>
  1275.                    <property name="padding">10</property>
  1276.                    <property name="position">0</property>
  1277.                  </packing>
  1278.                </child>
  1279.              </object>
  1280.              <packing>
  1281.                <property name="expand">False</property>
  1282.                <property name="position">5</property>
  1283.              </packing>
  1284.            </child>
  1285.            <child>
  1286.              <object class="GtkHBox" id="hbox5">
  1287.                <property name="visible">True</property>
  1288.                <child>
  1289.                  <object class="GtkLabel" id="label4">
  1290.                    <property name="visible">True</property>
  1291.                    <property name="label" translatable="yes">&lt;b&gt;Text properties:&lt;/b&gt;</property>
  1292.                    <property name="use_markup">True</property>
  1293.                  </object>
  1294.                  <packing>
  1295.                    <property name="expand">False</property>
  1296.                    <property name="position">0</property>
  1297.                  </packing>
  1298.                </child>
  1299.              </object>
  1300.              <packing>
  1301.                <property name="expand">False</property>
  1302.                <property name="position">6</property>
  1303.              </packing>
  1304.            </child>
  1305.            <child>
  1306.              <object class="GtkHBox" id="hbox13">
  1307.                <property name="visible">True</property>
  1308.                <child>
  1309.                  <object class="GtkHBox" id="hbox14">
  1310.                    <property name="visible">True</property>
  1311.                    <child>
  1312.                      <object class="GtkLabel" id="label18">
  1313.                        <property name="visible">True</property>
  1314.                        <property name="label" translatable="yes">text  color : </property>
  1315.                        <property name="use_markup">True</property>
  1316.                      </object>
  1317.                      <packing>
  1318.                        <property name="expand">False</property>
  1319.                        <property name="position">0</property>
  1320.                      </packing>
  1321.                    </child>
  1322.                    <child>
  1323.                      <object class="GtkColorButton" id="colorbutton2">
  1324.                        <property name="visible">True</property>
  1325.                        <property name="can_focus">True</property>
  1326.                        <property name="receives_default">True</property>
  1327.                        <property name="color">#000000000000</property>
  1328.                      </object>
  1329.                      <packing>
  1330.                        <property name="expand">False</property>
  1331.                        <property name="position">1</property>
  1332.                      </packing>
  1333.                    </child>
  1334.                    <child>
  1335.                      <object class="GtkLabel" id="label19">
  1336.                        <property name="visible">True</property>
  1337.                        <property name="label" translatable="yes"> </property>
  1338.                      </object>
  1339.                      <packing>
  1340.                        <property name="expand">False</property>
  1341.                        <property name="position">2</property>
  1342.                      </packing>
  1343.                    </child>
  1344.                    <child>
  1345.                      <object class="GtkLabel" id="label21">
  1346.                        <property name="visible">True</property>
  1347.                        <property name="label" translatable="yes"> </property>
  1348.                      </object>
  1349.                      <packing>
  1350.                        <property name="expand">False</property>
  1351.                        <property name="position">3</property>
  1352.                      </packing>
  1353.                    </child>
  1354.                    <child>
  1355.                      <object class="GtkLabel" id="label20">
  1356.                        <property name="visible">True</property>
  1357.                        <property name="label" translatable="yes">links color : </property>
  1358.                        <property name="use_markup">True</property>
  1359.                      </object>
  1360.                      <packing>
  1361.                        <property name="expand">False</property>
  1362.                        <property name="position">4</property>
  1363.                      </packing>
  1364.                    </child>
  1365.                    <child>
  1366.                      <object class="GtkColorButton" id="colorbutton3">
  1367.                        <property name="visible">True</property>
  1368.                        <property name="can_focus">True</property>
  1369.                        <property name="receives_default">True</property>
  1370.                        <property name="color">#000000000000</property>
  1371.                      </object>
  1372.                      <packing>
  1373.                        <property name="expand">False</property>
  1374.                        <property name="position">5</property>
  1375.                      </packing>
  1376.                    </child>
  1377.                  </object>
  1378.                  <packing>
  1379.                    <property name="expand">False</property>
  1380.                    <property name="padding">10</property>
  1381.                    <property name="position">0</property>
  1382.                  </packing>
  1383.                </child>
  1384.              </object>
  1385.              <packing>
  1386.                <property name="expand">False</property>
  1387.                <property name="position">7</property>
  1388.              </packing>
  1389.            </child>
  1390.            <child>
  1391.              <object class="GtkHBox" id="hbox16">
  1392.                <property name="visible">True</property>
  1393.                <child>
  1394.                  <object class="GtkLabel" id="label22">
  1395.                    <property name="visible">True</property>
  1396.                    <property name="label" translatable="yes">&lt;b&gt;Update every: &lt;/b&gt;</property>
  1397.                    <property name="use_markup">True</property>
  1398.                  </object>
  1399.                  <packing>
  1400.                    <property name="expand">False</property>
  1401.                    <property name="position">0</property>
  1402.                  </packing>
  1403.                </child>
  1404.              </object>
  1405.              <packing>
  1406.                <property name="expand">False</property>
  1407.                <property name="position">8</property>
  1408.              </packing>
  1409.            </child>
  1410.            <child>
  1411.              <object class="GtkHBox" id="hbox17">
  1412.                <property name="visible">True</property>
  1413.                <child>
  1414.                  <object class="GtkHBox" id="hbox18">
  1415.                    <property name="visible">True</property>
  1416.                    <child>
  1417.                      <object class="GtkSpinButton" id="spinbutton5">
  1418.                        <property name="visible">True</property>
  1419.                        <property name="can_focus">True</property>
  1420.                        <property name="invisible_char">&#x25CF;</property>
  1421.                        <property name="adjustment">adjustment6</property>
  1422.                      </object>
  1423.                      <packing>
  1424.                        <property name="position">0</property>
  1425.                      </packing>
  1426.                    </child>
  1427.                    <child>
  1428.                      <object class="GtkLabel" id="label23">
  1429.                        <property name="visible">True</property>
  1430.                        <property name="label" translatable="yes"> seconds</property>
  1431.                      </object>
  1432.                      <packing>
  1433.                        <property name="position">1</property>
  1434.                      </packing>
  1435.                    </child>
  1436.                  </object>
  1437.                  <packing>
  1438.                    <property name="expand">False</property>
  1439.                    <property name="padding">10</property>
  1440.                    <property name="position">0</property>
  1441.                  </packing>
  1442.                </child>
  1443.              </object>
  1444.              <packing>
  1445.                <property name="expand">False</property>
  1446.                <property name="position">9</property>
  1447.              </packing>
  1448.            </child>
  1449.            <child>
  1450.              <object class="GtkHBox" id="hbox6">
  1451.                <property name="visible">True</property>
  1452.                <child>
  1453.                  <object class="GtkLabel" id="label5">
  1454.                    <property name="visible">True</property>
  1455.                    <property name="label" translatable="yes">&lt;b&gt;RSS Feeds:&lt;/b&gt;</property>
  1456.                    <property name="use_markup">True</property>
  1457.                  </object>
  1458.                  <packing>
  1459.                    <property name="expand">False</property>
  1460.                    <property name="position">0</property>
  1461.                  </packing>
  1462.                </child>
  1463.              </object>
  1464.              <packing>
  1465.                <property name="expand">False</property>
  1466.                <property name="position">10</property>
  1467.              </packing>
  1468.            </child>
  1469.            <child>
  1470.              <object class="GtkHBox" id="hbox15">
  1471.                <property name="visible">True</property>
  1472.                <child>
  1473.                  <object class="GtkVBox" id="vbox2">
  1474.                    <property name="visible">True</property>
  1475.                    <property name="orientation">vertical</property>
  1476.                    <child>
  1477.                      <object class="GtkScrolledWindow" id="scrolledwindow1">
  1478.                        <property name="visible">True</property>
  1479.                        <property name="can_focus">True</property>
  1480.                        <property name="hscrollbar_policy">automatic</property>
  1481.                        <property name="vscrollbar_policy">automatic</property>
  1482.                        <property name="shadow_type">in</property>
  1483.                        <child>
  1484.                          <object class="GtkTreeView" id="treeview1">
  1485.                            <property name="visible">True</property>
  1486.                            <property name="can_focus">True</property>
  1487.                          </object>
  1488.                        </child>
  1489.                      </object>
  1490.                      <packing>
  1491.                        <property name="position">0</property>
  1492.                      </packing>
  1493.                    </child>
  1494.                    <child>
  1495.                      <object class="GtkHButtonBox" id="hbuttonbox1">
  1496.                        <property name="visible">True</property>
  1497.                        <property name="layout_style">start</property>
  1498.                        <child>
  1499.                          <object class="GtkButton" id="button1">
  1500.                            <property name="label">gtk-add</property>
  1501.                            <property name="visible">True</property>
  1502.                            <property name="can_focus">True</property>
  1503.                            <property name="receives_default">True</property>
  1504.                            <property name="use_stock">True</property>
  1505.                          </object>
  1506.                          <packing>
  1507.                            <property name="expand">False</property>
  1508.                            <property name="fill">False</property>
  1509.                            <property name="position">0</property>
  1510.                          </packing>
  1511.                        </child>
  1512.                        <child>
  1513.                          <object class="GtkButton" id="button2">
  1514.                            <property name="label">gtk-remove</property>
  1515.                            <property name="visible">True</property>
  1516.                            <property name="can_focus">True</property>
  1517.                            <property name="receives_default">True</property>
  1518.                            <property name="use_stock">True</property>
  1519.                          </object>
  1520.                          <packing>
  1521.                            <property name="expand">False</property>
  1522.                            <property name="fill">False</property>
  1523.                            <property name="position">1</property>
  1524.                          </packing>
  1525.                        </child>
  1526.                      </object>
  1527.                      <packing>
  1528.                        <property name="expand">False</property>
  1529.                        <property name="position">1</property>
  1530.                      </packing>
  1531.                    </child>
  1532.                  </object>
  1533.                  <packing>
  1534.                    <property name="padding">10</property>
  1535.                    <property name="position">0</property>
  1536.                  </packing>
  1537.                </child>
  1538.              </object>
  1539.              <packing>
  1540.                <property name="position">11</property>
  1541.              </packing>
  1542.            </child>
  1543.            <child>
  1544.              <object class="GtkHButtonBox" id="hbuttonbox2">
  1545.                <property name="visible">True</property>
  1546.                <property name="layout_style">end</property>
  1547.                <child>
  1548.                  <object class="GtkButton" id="button4">
  1549.                    <property name="label">gtk-cancel</property>
  1550.                    <property name="visible">True</property>
  1551.                    <property name="can_focus">True</property>
  1552.                    <property name="receives_default">True</property>
  1553.                    <property name="use_stock">True</property>
  1554.                  </object>
  1555.                  <packing>
  1556.                    <property name="expand">False</property>
  1557.                    <property name="fill">False</property>
  1558.                    <property name="position">0</property>
  1559.                  </packing>
  1560.                </child>
  1561.                <child>
  1562.                  <object class="GtkButton" id="button3">
  1563.                    <property name="label">gtk-ok</property>
  1564.                    <property name="visible">True</property>
  1565.                    <property name="can_focus">True</property>
  1566.                    <property name="receives_default">True</property>
  1567.                    <property name="use_stock">True</property>
  1568.                  </object>
  1569.                  <packing>
  1570.                    <property name="expand">False</property>
  1571.                    <property name="fill">False</property>
  1572.                    <property name="position">1</property>
  1573.                  </packing>
  1574.                </child>
  1575.              </object>
  1576.              <packing>
  1577.                <property name="expand">False</property>
  1578.                <property name="position">12</property>
  1579.              </packing>
  1580.            </child>
  1581.          </object>
  1582.          <packing>
  1583.            <property name="padding">5</property>
  1584.            <property name="position">0</property>
  1585.          </packing>
  1586.        </child>
  1587.      </object>
  1588.    </child>
  1589.  </object>
  1590.  <object class="GtkAdjustment" id="adjustment1">
  1591.    <property name="value">640</property>
  1592.    <property name="lower">100</property>
  1593.    <property name="upper">10000</property>
  1594.    <property name="step_increment">10</property>
  1595.    <property name="page_increment">100</property>
  1596.  </object>
  1597.  <object class="GtkAdjustment" id="adjustment2">
  1598.    <property name="value">400</property>
  1599.    <property name="lower">100</property>
  1600.    <property name="upper">10000</property>
  1601.    <property name="step_increment">10</property>
  1602.    <property name="page_increment">100</property>
  1603.  </object>
  1604.  <object class="GtkAdjustment" id="adjustment3">
  1605.    <property name="value">100</property>
  1606.    <property name="upper">10000</property>
  1607.    <property name="step_increment">1</property>
  1608.    <property name="page_increment">10</property>
  1609.  </object>
  1610.  <object class="GtkAdjustment" id="adjustment4">
  1611.    <property name="value">100</property>
  1612.    <property name="upper">10000</property>
  1613.    <property name="step_increment">1</property>
  1614.    <property name="page_increment">10</property>
  1615.  </object>
  1616.  <object class="GtkAdjustment" id="adjustment5">
  1617.    <property name="value">75</property>
  1618.    <property name="upper">100</property>
  1619.    <property name="step_increment">1</property>
  1620.    <property name="page_increment">10</property>
  1621.  </object>
  1622.  <object class="GtkAdjustment" id="adjustment6">
  1623.    <property name="upper">3600</property>
  1624.    <property name="lower">10</property>
  1625.    <property name="value">120</property>
  1626.    <property name="step_increment">1</property>
  1627.    <property name="page_increment">60</property>
  1628.  </object>
  1629. </interface>'''
  1630.  
  1631. setProcessName('rsswidget')
  1632. if __name__ == '__main__':     
  1633.         gtk.gdk.threads_init()
  1634.         rss_thingy = RssWidget()
  1635.         rss_thingy.main()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top