changelog updated
[stockthis] / stockthis.py
index 40aef5c..0fa9352 100644 (file)
@@ -27,13 +27,13 @@ try:
     HILDON = True
 except:
     HILDON = False
-    
+
 try:
     import osso
     OSSO = True
-    osso_c = osso.Context("net.yerga.stockthis", "0.1", False)
+#    osso_c = osso.Context("net.yerga.stockthis", "0.2", False)
 except:
-    OSSO = False    
+    OSSO = False
 
 from marketdata import markets, idmarket, localmarkets, localids
 
@@ -48,7 +48,7 @@ if '/usr/share' in runningpath:
     running_locally = False
 else:
     running_locally = True
-    
+
 if running_locally:
     imgdir = 'pixmaps/'
 else:
@@ -68,71 +68,72 @@ class StocksPy:
             if FREMANTLE:
                 self.window = hildon.StackableWindow()
             else:
-                self.window = hildon.Window()                
-            self.program.add_window(self.window) 
+                self.window = hildon.Window()
+            self.program.add_window(self.window)
         else:
             self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
 
-        self.window.set_default_size(800, 480)  
-        self.window.set_title('StocksPy')
+        self.window.set_default_size(800, 480)
+        self.window.set_title('StockThis')
         self.window.connect("destroy", gtk.main_quit)
         self.window.connect("key-press-event", self.on_key_press)
         self.window.connect("window-state-event", self.on_window_state_change)
         self.window_in_fullscreen = False
-        
+
         if HILDON:
             if FREMANTLE:
                 menu = hildon.AppMenu()
-                self.window.set_main_menu(menu)
+                self.window.set_app_menu(menu)
                 about_menu = gtk.Button("About")
+                about_menu.connect("clicked", self.on_about)
             else:
                 menu = gtk.Menu()
                 self.window.set_menu(menu)
                 about_menu = gtk.MenuItem("About")
                 about_menu.set_size_request(-1, 55)
-            
-            about_menu.connect("activate", self.on_about)
-            menu.append(about_menu)            
+                about_menu.connect("activate", self.on_about)
+
+            menu.append(about_menu)
             menu.show_all()
         else:
             #TODO: create a gtk.menubar
             pass
-        
-        
+
+
         vbox = gtk.VBox()
-        
+
         self.toolbar = gtk.HBox()
         self.toolbar.set_property("no-show-all", True)
         self.toolbar.hide()
         self.toolbar.set_homogeneous(True)
         self.toolbar.set_size_request(-1, 55)
-        
+
         self.markets_btn = gtk.Button('Markets')
         self.markets_btn.connect("clicked", self.create_markets_view)
         self.markets_btn.set_property("can_focus", False)
-        
-        self.components_btn = gtk.Button('Components')
+
+        self.components_btn = gtk.Button('Instruments')
         self.components_btn.connect("clicked", self.show_components_view)
-        self.components_btn.set_property("can_focus", False)          
-        
-        self.graph_btn = gtk.Button('Graphs')
+        self.components_btn.set_property("can_focus", False)
+
+        self.graph_btn = gtk.Button('Graph')
         self.graph_btn.connect("clicked", self.create_graphs_view)
         self.graph_btn.set_property("can_focus", False)
-        
+
         self.refresh_btn = gtk.Button('Refresh')
         self.refresh_btn.connect("clicked", self.refresh_stock_data)
         self.refresh_btn.set_property("can_focus", False)
-        
-        self.quotes_btn = gtk.Button('Quotes')
+
+        self.quotes_btn = gtk.Button('Quote')
         self.quotes_btn.connect("clicked", self.show_quotes_view)
-        self.quotes_btn.set_property("can_focus", False)        
-        
-        self.toolbar.pack_start(self.markets_btn)        
+        self.quotes_btn.set_property("can_focus", False)
+
+        self.toolbar.pack_start(self.markets_btn)
         self.toolbar.pack_start(self.components_btn)
         self.toolbar.pack_start(self.graph_btn)
-        self.toolbar.pack_start(self.quotes_btn) 
-        self.toolbar.pack_start(self.refresh_btn)        
-        
+        self.toolbar.pack_start(self.quotes_btn)
+        self.toolbar.pack_start(self.refresh_btn)
+
         self.mainbox = gtk.VBox()
 
 
@@ -154,26 +155,26 @@ class StocksPy:
 
         self.window.show_all()
 
-    def create_markets_view(self, widget): 
+    def create_markets_view(self, widget):
         names = markets
         ids = idmarket
         self.toolbar.hide()
-        
+
         actual_view = self.mainbox.get_children()
         if len(actual_view) > 0:
             for a_widget in actual_view:
                 a_widget.destroy()
 
-        self.marketsbox = gtk.VBox()        
+        self.marketsbox = gtk.VBox()
         lnames = len(names)
-        
+
         for i in range(lnames):
             button = gtk.Button(names[i])
             button.connect("clicked", self.create_components_view, ids[i])
             button.set_size_request(-1, 65)
             button.set_property("can_focus", False)
             self.marketsbox.pack_start(button, True, True, 2)
-        
+
         self.mainbox.pack_start(self.marketsbox, True, True, 2)
         self.mainbox.show_all()
 
@@ -181,11 +182,11 @@ class StocksPy:
         kind = self.market_id
         self.create_components_view(widget, kind)
 
-    def create_components_view(self, widget, kind):    
+    def create_components_view(self, widget, kind):
         actual_view = self.mainbox.get_children()
         for i in actual_view:
             i.destroy()
-    
+
         self.market_id = kind
         self.toolbar.show()
         self.components_btn.hide()
@@ -193,54 +194,63 @@ class StocksPy:
         self.refresh_btn.hide()
         self.graph_btn.hide()
         self.quotes_btn.hide()
-        
+
         names = localmarkets[idmarket.index(kind)]
         ids = localids[idmarket.index(kind)]
-        
+
         self.compbox = gtk.VBox()
-        
+
         self.components_trv = gtk.TreeView()
-        selection = self.components_trv.get_selection()
-        selection.connect("changed", self.changed_selection, ids)
+        self.components_trv.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_HORIZONTAL)
+
+        if not FREMANTLE:
+            selection = self.components_trv.get_selection()
+            selection.connect("changed", self.changed_selection, ids)
+        else:
+            self.components_trv.connect("row-activated", self.select_component, ids)
+
         self.components_trv.set_rubber_banding(True)
-        self.components_trv.set_headers_visible(False)        
+        self.components_trv.set_headers_visible(False)
         self.components_model = self.__create_components_model()
         self.components_trv.set_model(self.components_model)
-        self._components_trv_columns(self.components_trv)   
+        self._components_trv_columns(self.components_trv)
         self.add_initial_components(names, ids)
-        
-        self.compbox.pack_start(self.components_trv, True, True, 0) 
+
+        self.compbox.pack_start(self.components_trv, True, True, 0)
 
         self.mainbox.pack_start(self.compbox, True, True, 0)
         self.mainbox.show_all()
-    
+
+    def select_component(self, widget, path, column, ids):
+        self.create_quotes_view(widget,self.components_model[path][1] )
+
     def changed_selection(self, widget, ids):
         n, i, m = self.get_selected_from_treeview(self.components_trv, self.components_model, 1)
         if n is not None:
             self.create_quotes_view(widget, n)
-            
+
     def __create_components_model(self):
         lstore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
         return lstore
 
-    def _components_trv_columns(self, treeview): 
+    def _components_trv_columns(self, treeview):
         renderer = gtk.CellRendererText()
-        renderer.set_property('scale', 1.6)
+        renderer.set_property('scale', 1.3)
         #renderer.set_property("background", 'lightgray')
         renderer.set_property("xpad", 15)
         column = gtk.TreeViewColumn('Name', renderer, text=0)
         column.set_expand(True)
-        treeview.append_column(column) 
-        
+        treeview.append_column(column)
+
         renderer = gtk.CellRendererText()
         column = gtk.TreeViewColumn('IDS', renderer, text=1)
         column.set_visible(False)
-        treeview.append_column(column)         
-        
+        treeview.append_column(column)
+
     def add_initial_components(self, kind, ids):
         for i in range(len(kind)):
-            niter = self.components_model.append() 
-            self.components_model.set(niter, 0, kind[i], 1, ids[i])    
+            niter = self.components_model.append()
+            self.components_model.set(niter, 0, kind[i], 1, ids[i])
 
     def get_selected_from_treeview(self, treeview, model, setting):
         selection = treeview.get_selection()
@@ -261,93 +271,93 @@ class StocksPy:
         self.components_btn.show()
         self.markets_btn.show()
         self.refresh_btn.show()
-        self.graph_btn.show() 
-        self.quotes_btn.hide() 
-    
+        self.graph_btn.show()
+        self.quotes_btn.hide()
+
         #actual_view = self.mainbox.get_children()
         #actual_view[0].destroy()
-        
+
         try:
             self.graphbox.destroy()
         except:
             pass
-        
+
         for i in range(len(localids)):
             if kind in localids[i]:
-                ind1, ind2 = i, localids[i].index(kind)  
+                ind1, ind2 = i, localids[i].index(kind)
 
         self.quotesbox = gtk.VBox()
 
-        label1 = gtk.Label('')
-        label1.set_markup('<b><big>'+localmarkets[ind1][ind2]+'</big></b>')
-        color = gtk.gdk.color_parse("#03A5FF")          
-        label1.modify_fg(gtk.STATE_NORMAL, color)
+        self.titlelbl = gtk.Label('')
+        self.titlelbl.set_markup('<b><big>'+localmarkets[ind1][ind2].replace('&', '')+'</big></b>')
+        color = gtk.gdk.color_parse("#03A5FF")
+        self.titlelbl.modify_fg(gtk.STATE_NORMAL, color)
 
         self.databox = gtk.VBox()
-        
+
         self.imagebox = gtk.VBox()
-        self.dataimg = gtk.Image()        
+        self.dataimg = gtk.Image()
         self.imagebox.pack_start(self.dataimg)
-        
-        self.show_data(kind)        
-        
+
+        self.show_data(kind)
+
         hbox1 = gtk.HBox()
-        
+
         label2 = gtk.Label('')
         label2.set_markup('<b><big>Price:</big></b>')
         self.lprice = gtk.Label('')
-        
+
         hbox1.pack_start(label2, False, False, 50)
         hbox1.pack_start(self.lprice, False, False, 185)
-        
+
         hbox2 = gtk.HBox()
 
         label4 = gtk.Label('')
         label4.set_markup('<b><big>Change:</big></b>')
         self.lchange = gtk.Label('')
         self.lpercent = gtk.Label('')
-        
+
         hbox2.pack_start(label4, False, False, 50)
-        hbox2.pack_start(self.lchange  , False, False, 145)             
+        hbox2.pack_start(self.lchange  , False, False, 145)
         hbox2.pack_start(self.lpercent, False, False, 0)
-                
+
         hbox3 = gtk.HBox()
-        
+
         label7 = gtk.Label('')
         label7.set_markup('<b><big>Volume:</big></b>')
         self.lvolume = gtk.Label('')
-        
+
         hbox3.pack_start(label7, False, False, 50)
-        hbox3.pack_start(self.lvolume  , False, False, 145)    
-        
+        hbox3.pack_start(self.lvolume  , False, False, 145)
+
         hbox4 = gtk.HBox()
-        
+
         label9 = gtk.Label('')
         label9.set_markup('<b><big>52 week high:</big></b>')
         self.l52whigh = gtk.Label('')
-        
+
         hbox4.pack_start(label9, False, False, 50)
-        hbox4.pack_start(self.l52whigh , False, False, 55)             
-        
+        hbox4.pack_start(self.l52whigh , False, False, 55)
+
         hbox5 = gtk.HBox()
-        
+
         label11 = gtk.Label('')
         label11.set_markup('<b><big>52 week low:</big></b>')
         self.l52wlow = gtk.Label('')
-        
+
         hbox5.pack_start(label11, False, False, 50)
         hbox5.pack_start(self.l52wlow , False, False, 70)
-    
+
         self.databox.pack_start(hbox1, True, True, 0)
         self.databox.pack_start(hbox2, True, True, 0)
         self.databox.pack_start(hbox3, True, True, 0)
         self.databox.pack_start(hbox4, True, True, 0)
         self.databox.pack_start(hbox5, True, True, 0)
-               
-        self.quotesbox.pack_start(label1, False, False, 0)
-        self.quotesbox.pack_start(gtk.HSeparator(), False, False, 0)     
-        self.quotesbox.pack_start(self.databox, True, True, 0)     
-        self.quotesbox.pack_start(self.imagebox, True, True, 0)    
+
+        self.quotesbox.pack_start(self.titlelbl, False, False, 0)
+        self.quotesbox.pack_start(gtk.HSeparator(), False, False, 0)
+        self.quotesbox.pack_start(self.databox, True, True, 0)
+        self.quotesbox.pack_start(self.imagebox, True, True, 0)
 
         self.mainbox.pack_start(self.quotesbox, True, True, 0)
         self.mainbox.show_all()
@@ -361,74 +371,80 @@ class StocksPy:
         self.databox.hide()
         thread.start_new_thread(self.get_data, (kind,))
 
-    def get_data(self, kind):    
+    def get_data(self, kind):
         self.graph_btn.show()
         self.refresh_btn.show()
-        self.quotes_btn.hide() 
-        
+        self.quotes_btn.hide()
+
         from ystockquote import ystockquote as yt
-        data = yt.get_all(kind)
-        
         try:
-            ch_percent = 100.0 * float(data['change'])/float(data['price'])
+            data = yt.get_all(kind)
+        except:
+            print 'Failed to get internet data'
+            data = {'price': 'N/A', 'change': 'N/A', 'volume':'N/A',
+                    '52_week_high': 'N/A', '52_week_low': 'N/A'}
+            self.titlelbl.set_markup('<b><big>Failed to get data</big></b>')
+
+        try:
+            ch_percent = 100.0 * float(data['change'])/(float(data['price'])-float(data['change']))
         except ValueError:
             ch_percent = 0.0
 
         self.lprice.set_label(data['price'])
         self.lchange.set_label(data['change'])
         self.lpercent.set_label('%6.2f %%' % ch_percent)
-        
+
         if '-' in data['change']:
             color = gtk.gdk.color_parse("#FF0000")
         else:
-            color = gtk.gdk.color_parse("#16EB78")   
-                     
+            color = gtk.gdk.color_parse("#16EB78")
+
         self.lpercent.modify_fg(gtk.STATE_NORMAL, color)
-        self.lchange.modify_fg(gtk.STATE_NORMAL, color) 
-                   
+        self.lchange.modify_fg(gtk.STATE_NORMAL, color)
+
         self.lvolume.set_label(data['volume'])
         self.l52whigh.set_label(data['52_week_high'])
         self.l52wlow.set_label(data['52_week_low'])
-               
-        self.databox.show_all()  
-        self.imagebox.hide()  
+
+        self.databox.show_all()
+        self.imagebox.hide()
 
     def refresh_stock_data(self, widget):
         self.show_data(self.stocks_id)
 
-    def create_graphs_view(self, widget):        
+    def create_graphs_view(self, widget):
         self.graph_btn.hide()
         self.refresh_btn.hide()
         self.quotes_btn.show()
-        
+
         self.graph = gtk.Image()
-        
+
         kind = self.stocks_id
-        
+
         self.show_graph(None, '1d', kind)
-        
+
         for i in range(len(localids)):
             if kind in localids[i]:
                 ind1, ind2 = i, localids[i].index(kind)
 
-        #self.mainbox.destroy()  
+        #self.mainbox.destroy()
         #self.mainbox = gtk.VBox()
-        #self.swin.add_with_viewport(self.mainbox) 
-        
+        #self.swin.add_with_viewport(self.mainbox)
+
         actual_view = self.mainbox.get_children()
         for a_widget in actual_view:
-            a_widget.destroy() 
+            a_widget.destroy()
 
         self.graphbox = gtk.VBox()
 
-        label1 = gtk.Label(localmarkets[ind1][ind2])
+        self.graphs_title = gtk.Label(localmarkets[ind1][ind2])
         color = gtk.gdk.color_parse("#03A5FF")
-        label1.modify_fg(gtk.STATE_NORMAL, color)
-        
+        self.graphs_title.modify_fg(gtk.STATE_NORMAL, color)
+
         hbox1 = gtk.HBox()
         hbox1.set_size_request(-1, 55)
         hbox1.set_homogeneous(True)
-        
+
         self.btn1d = gtk.Button('1d')
         self.btn1d.set_property("can_focus", False)
         self.btn1d.connect("clicked", self.show_graph, '1d', kind)
@@ -453,22 +469,22 @@ class StocksPy:
         self.btnmax = gtk.Button('max')
         self.btnmax.set_property("can_focus", False)
         self.btnmax.connect("clicked", self.show_graph, 'max', kind)
-        
+
         hbox1.pack_start(self.btn1d)
-        hbox1.pack_start(self.btn5d)        
-        hbox1.pack_start(self.btn3m)        
-        hbox1.pack_start(self.btn6m)        
-        hbox1.pack_start(self.btn1y) 
-        hbox1.pack_start(self.btn2y)        
-        hbox1.pack_start(self.btn5y)        
-        hbox1.pack_start(self.btnmax)      
-           
-        self.graphbox.pack_start(label1, False, False, 2)
-        self.graphbox.pack_start(hbox1, False, False, 0)     
+        hbox1.pack_start(self.btn5d)
+        hbox1.pack_start(self.btn3m)
+        hbox1.pack_start(self.btn6m)
+        hbox1.pack_start(self.btn1y)
+        hbox1.pack_start(self.btn2y)
+        hbox1.pack_start(self.btn5y)
+        hbox1.pack_start(self.btnmax)
+
+        self.graphbox.pack_start(self.graphs_title, False, False, 2)
+        self.graphbox.pack_start(hbox1, False, False, 0)
         self.graphbox.pack_start(self.graph, True, True, 5)
-        
+
         self.mainbox.pack_start(self.graphbox, False, False, 2)
-        self.mainbox.show_all()   
+        self.mainbox.show_all()
 
     def show_graph(self, widget, option, kind):
         import thread
@@ -478,51 +494,56 @@ class StocksPy:
     def get_graph_data(self, option, kind):
         if option == '1d':
             url = 'http://uk.ichart.yahoo.com/b?s=%s' % kind
-        elif option == '5d':  
+        elif option == '5d':
             url = 'http://uk.ichart.yahoo.com/w?s=%s' % kind
-        elif option == '3m':  
+        elif option == '3m':
             url = 'http://chart.finance.yahoo.com/c/3m/s/%s' % kind.lower()
-        elif option == '6m':  
+        elif option == '6m':
             url = 'http://chart.finance.yahoo.com/c/6m/s/%s' % kind.lower()
-        elif option == '1y':  
+        elif option == '1y':
             url = 'http://chart.finance.yahoo.com/c/1y/s/%s' % kind.lower()
-        elif option == '2y':  
+        elif option == '2y':
             url = 'http://chart.finance.yahoo.com/c/2y/s/%s' % kind.lower()
-        elif option == '5y':  
+        elif option == '5y':
             url = 'http://chart.finance.yahoo.com/c/5y/s/%s' % kind.lower()
-        elif option == 'max':  
+        elif option == 'max':
             url = 'http://chart.finance.yahoo.com/c/my/s/%s' % kind.lower()
-                
-        myimg = urllib2.urlopen(url)
-        imgdata=myimg.read()
 
-        pbl = gtk.gdk.PixbufLoader()
-        pbl.write(imgdata)
+        try:
+            myimg = urllib2.urlopen(url)
+            imgdata=myimg.read()
+
+            pbl = gtk.gdk.PixbufLoader()
+            pbl.write(imgdata)
+
+            pbuf = pbl.get_pixbuf()
+            pbl.close()
+            self.graph.set_from_pixbuf(pbuf)
+        except:
+            print 'no internet data'
+            self.graphs_title.set_label('Failed to get data')
+            self.graph.destroy()
 
-        pbuf = pbl.get_pixbuf()
-        pbl.close()
-        
-        self.graph.set_from_pixbuf(pbuf)
 
     #Functions for fullscreen
-    def on_window_state_change(self, widget, event, *args):           
+    def on_window_state_change(self, widget, event, *args):
         if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
             self.window_in_fullscreen = True
         else:
             self.window_in_fullscreen = False
 
     #F6 fullscreen, F7 bigger font, F8 smaller font
-    def on_key_press(self, widget, event, *args):  
+    def on_key_press(self, widget, event, *args):
         if event.keyval == gtk.keysyms.F6:
             if self.window_in_fullscreen:
                 self.window.unfullscreen ()
             else:
-                self.window.fullscreen () 
+                self.window.fullscreen ()
 
     def on_about(self, widget):
         dialog = gtk.AboutDialog()
         dialog.set_name("StockThis")
-        dialog.set_version("0.1")
+        dialog.set_version("0.2")
         dialog.set_copyright("Copyright © 2009")
         dialog.set_website("http://stockthis.garage.maemo.org")
         dialog.set_authors(["Daniel Martin Yerga <dyerga@gmail.com>"])
@@ -532,10 +553,9 @@ class StocksPy:
         dialog.set_artists(["Logo by Daniel Martin Yerga"])
         dialog.run()
         dialog.destroy()
-          
+
 if __name__ == "__main__":
     stockspy = StocksPy()
     gtk.gdk.threads_enter()
     gtk.main()
     gtk.gdk.threads_leave()
-