gnome-applets r10777 - in trunk/invest-applet: . data invest



Author: callum
Date: Thu Apr  3 05:54:18 2008
New Revision: 10777
URL: http://svn.gnome.org/viewvc/gnome-applets?rev=10777&view=rev

Log:
Add sparklines support to the invest applet.

Modified:
   trunk/invest-applet/ChangeLog
   trunk/invest-applet/data/financialchart.ui
   trunk/invest-applet/data/prefs-dialog.ui
   trunk/invest-applet/invest/__init__.py
   trunk/invest-applet/invest/applet.py
   trunk/invest-applet/invest/chart.py
   trunk/invest-applet/invest/preferences.py
   trunk/invest-applet/invest/quotes.py
   trunk/invest-applet/invest/widgets.py

Modified: trunk/invest-applet/data/financialchart.ui
==============================================================================
--- trunk/invest-applet/data/financialchart.ui	(original)
+++ trunk/invest-applet/data/financialchart.ui	Thu Apr  3 05:54:18 2008
@@ -103,7 +103,7 @@
                 <property name="editable">True</property>
                 <property name="visibility">True</property>
                 <property name="max_length">0</property>
-                <property name="text" translatable="yes"/>
+                <property name="text" translatable="yes"></property>
                 <property name="has_frame">True</property>
                 <property name="invisible_char">*</property>
                 <property name="activates_default">False</property>

Modified: trunk/invest-applet/data/prefs-dialog.ui
==============================================================================
--- trunk/invest-applet/data/prefs-dialog.ui	(original)
+++ trunk/invest-applet/data/prefs-dialog.ui	Thu Apr  3 05:54:18 2008
@@ -10,7 +10,7 @@
     <property name="default_height">450</property>
     <property name="resizable">True</property>
     <property name="destroy_with_parent">True</property>
-    <property name="icon_name"/>
+    <property name="icon_name"></property>
     <property name="decorated">True</property>
     <property name="skip_taskbar_hint">False</property>
     <property name="skip_pager_hint">False</property>

Modified: trunk/invest-applet/invest/__init__.py
==============================================================================
--- trunk/invest-applet/invest/__init__.py	(original)
+++ trunk/invest-applet/invest/__init__.py	Thu Apr  3 05:54:18 2008
@@ -20,10 +20,12 @@
 # Shared data dir is most the time /usr/share/invest-applet
 if UNINSTALLED_INVEST:
 	SHARED_DATA_DIR = abspath(join(dirname(__file__), '..', 'data'))
-	GLADE_DATA_DIR = SHARED_DATA_DIR
+	BUILDER_DATA_DIR = SHARED_DATA_DIR
+	ART_DATA_DIR = join(SHARED_DATA_DIR, 'art')
 else:
 	SHARED_DATA_DIR = join(DATA_DIR, "gnome-applets", "invest-applet")
 	BUILDER_DATA_DIR = BUILDERDIR
+	ART_DATA_DIR = SHARED_DATA_DIR
 print "Data Dir: %s" % SHARED_DATA_DIR
 
 USER_INVEST_DIR = expanduser("~/.gnome2/invest-applet")
@@ -38,9 +40,6 @@
 # when presenting save/open dialogs
 os.chdir(expanduser("~"))
 
-# Path to images, icons
-ART_DATA_DIR = SHARED_DATA_DIR
-
 #Gconf client
 GCONF_CLIENT = gconf.client_get_default()
 
@@ -60,7 +59,6 @@
 AUTOREFRESH_TIMEOUT = 20*60*1000 # 15 minutes
 TICKER_TIMEOUT = 10000#3*60*1000#
 
-CHART_BASE_URL = "http://ichart.finance.yahoo.com/z?s=%(s)s&t=%(t)s&q=%(q)s&l=%(l)s&z=%(z)s&p=%(p)s&a=%(a)s%(opt)s"
 QUOTES_URL="http://finance.yahoo.com/d/quotes.csv?s=%(s)s&f=sl1d1t1c1ohgv&e=.csv"
 
 # Sample: "APPL",76.05,"1/9/2006","4:00pm",0.00,N/A,N/A,N/A,500

Modified: trunk/invest-applet/invest/applet.py
==============================================================================
--- trunk/invest-applet/invest/applet.py	(original)
+++ trunk/invest-applet/invest/applet.py	Thu Apr  3 05:54:18 2008
@@ -5,44 +5,18 @@
 import gconf
 
 import invest, invest.about, invest.chart, invest.preferences
-from invest.quotes import get_quotes_updater
+from invest.quotes import QuoteUpdater
 from invest.widgets import *
 
-		
-class InvestAppletPreferences:
-	def __init__(self, applet):
-		# Default values
-		self.GCONF_APPLET_DIR = invest.GCONF_DIR
-		self.GCONF_CLIENT = gconf.client_get_default ()
-		
-		# Retrieve this applet's pref folder
-		path = applet.get_preferences_key()
-		if path != None:
-			self.GCONF_APPLET_DIR = path			
-			print 'Using per-applet gconf key:', self.GCONF_APPLET_DIR
-			gtik_settings = self.GCONF_CLIENT.get_string(self.GCONF_APPLET_DIR+"/prefs/tik_syms")
-			if gtik_settings != None and gtik_settings != "":
-				# Import old settings
-				self.GCONF_CLIENT.set_string(self.GCONF_APPLET_DIR+"/prefs/tik_syms", "")
-				for sym in gtik_settings.split('+'):
-					invest.STOCKS[sym].append({
-						"amount": 0,
-						"bought": 0,
-						"comission": 0,
-					})
-						
 class InvestApplet:
 	def __init__(self, applet):
 		self.applet = applet
-		self.prefs = InvestAppletPreferences(applet)
-		
-		self.investwidget = InvestWidget()
-
-		get_quotes_updater().connect('quotes-updated', self._on_quotes_updated)
-
 		self.applet.setup_menu_from_file (
-			invest.SHARED_DATA_DIR, "Invest_Applet.xml",
-			None, [("About", self.on_about), ("Prefs", self.on_preferences), ("Refresh", self.on_refresh)])
+			None, "Invest_Applet.xml",
+			None, [("About", self.on_about), 
+					("Prefs", self.on_preferences),
+					("Refresh", self.on_refresh)
+					])
 
 		evbox = gtk.HBox()
 		applet_icon = gtk.Image()
@@ -51,16 +25,18 @@
 			applet_icon.set_from_pixbuf(pixbuf)
 		except Exception, msg:
 			applet_icon.set_from_icon_name("stock_chart-autoformat", gtk.ICON_SIZE_BUTTON)
-		
+	
 		applet_icon.show()
 		evbox.add(applet_icon)
-
-		self.ilw = InvestmentsListWindow(self.applet, self.investwidget)
-
 		self.applet.add(evbox)
 		self.applet.connect("button-press-event",self.button_clicked)
 		self.applet.show_all()
-		get_quotes_updater().refresh()
+		self.new_ilw()
+
+	def new_ilw(self):
+		self.quotes_updater = QuoteUpdater()
+		self.investwidget = InvestWidget(self.quotes_updater)
+		self.ilw = InvestmentsListWindow(self.applet, self.investwidget)
 
 	def button_clicked(self, widget,event):
 		if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
@@ -71,27 +47,19 @@
 	
 	def on_preferences(self, component, verb):
 		invest.preferences.show_preferences(self)
-		get_quotes_updater().refresh()
+		self.quotes_updater.refresh()
 	
 	def on_refresh(self, component, verb):
-		get_quotes_updater().refresh()
-		
-	def _on_quotes_updated(self, updater):
-		pass
-		#invest.dbusnotification.notify(
-		#	_("Financial Report"),
-		#	"stock_chart",
-		#	_("Financial Report"),
-		#	_("Quotes updated"),
-		#	3000)
+		self.quotes_updater.refresh()
 
 class InvestmentsListWindow(gtk.Window):
 	def __init__(self, applet, list):
 		gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
 		self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK)
 		self.stick()
+		self.set_resizable(False)
 		
-		self.applet = applet
+		self.applet = applet # this is the widget we want to align with
 		self.alignment = self.applet.get_orient ()
 		
 		self.add(list)
@@ -114,6 +82,7 @@
 		"""
 		Calculates the position and moves the window to it.
 		"""
+		self.realize()
 
 		# Get our own dimensions & position
 		#(wx, wy) = self.get_origin()

Modified: trunk/invest-applet/invest/chart.py
==============================================================================
--- trunk/invest-applet/invest/chart.py	(original)
+++ trunk/invest-applet/invest/chart.py	Thu Apr  3 05:54:18 2008
@@ -152,7 +152,8 @@
 				a += "%s%s," % (name[1:], param)
 		
 		# Create the image URL -----------------------------------------------------
-		url = CHART_BASE_URL % {
+		chart_base_url = "http://ichart.europe.yahoo.com/z?s=%(s)s&t=%(t)s&q=%(q)s&l=%(l)s&z=%(z)s&p=%(p)s&a=%(a)s%(opt)s"
+		url = chart_base_url % {
 			"s": tickers[0],
 			"t": self.ui.get_object("t").get_active_text(),
 			"q": self.ui.get_object("q").get_active_text(),
@@ -162,7 +163,7 @@
 			"a": a,
 			"opt": opt,
 		}
-		
+
 		# Download and display the image -------------------------------------------	
 		progress = self.ui.get_object("progress")
 		progress.set_text(_("Opening Chart"))
@@ -211,6 +212,31 @@
 		if autorefresh.get_active():
 			self.autorefresh_id = gobject.timeout_add(AUTOREFRESH_TIMEOUT, self.on_refresh_chart, True)
 
+def FinancialSparklineChartPixbuf(ticker, update_callback, userdata):
+	if len(ticker.split('.')) == 2:
+		url = 'http://ichart.europe.yahoo.com/h?s=%s' % ticker
+	else:
+		url = 'http://ichart.yahoo.com/h?s=%s' % ticker
+	
+	def read_cb(handle, buffer, result, size, loader):
+		if result:
+			loader.close()
+			handle.close(lambda *args: None)
+			update_callback(loader.get_pixbuf(), userdata)
+		else:
+			loader.write(buffer, size)
+			handle.read(GNOMEVFS_CHUNK_SIZE, read_cb, loader)
+
+	def open_cb(handle, result):
+		if result:
+			print "Open of sparkline chart for ticker %s failed:" % ticker, result
+		else:
+			loader = gtk.gdk.PixbufLoader()
+			handle.read(GNOMEVFS_CHUNK_SIZE, read_cb, loader)
+
+	gnomevfs.async.open(url, open_cb, gnomevfs.OPEN_READ,
+		gnomevfs.PRIORITY_DEFAULT)
+
 def show_chart(tickers):
 	ui = gtk.Builder();
 	ui.add_from_file(os.path.join(invest.BUILDER_DATA_DIR, "financialchart.ui"))

Modified: trunk/invest-applet/invest/preferences.py
==============================================================================
--- trunk/invest-applet/invest/preferences.py	(original)
+++ trunk/invest-applet/invest/preferences.py	Thu Apr  3 05:54:18 2008
@@ -9,7 +9,7 @@
 class PrefsDialog:
 	def __init__(self, applet):
 		self.ui = gtk.Builder()
-		self.ui.add_from_file(os.path.join(invest.BUILDER_DATA_DIR, "prefs-dialog.ui"))
+		self.ui.add_from_file(join(invest.BUILDER_DATA_DIR, "prefs-dialog.ui"))
 
 		self.dialog = self.ui.get_object("preferences")
 		self.treeview = self.ui.get_object("stocks")

Modified: trunk/invest-applet/invest/quotes.py
==============================================================================
--- trunk/invest-applet/invest/quotes.py	(original)
+++ trunk/invest-applet/invest/quotes.py	Thu Apr  3 05:54:18 2008
@@ -8,14 +8,11 @@
 import invest, invest.about, invest.chart
 
 class QuoteUpdater(gtk.ListStore):
-	__gsignals__ = {
-		"quotes-updated" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
-	}
-	
-	SYMBOL, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION = range(6)
+	SYMBOL, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION = range(6)	
 	def __init__ (self):
-		gtk.ListStore.__init__ (self, gobject.TYPE_STRING, bool, float, float, float, float)
+		gtk.ListStore.__init__ (self, gobject.TYPE_STRING, bool, float, float, float, float, gtk.gdk.Pixbuf)
 		gobject.timeout_add(invest.AUTOREFRESH_TIMEOUT, self.refresh)
+		self.refresh()
 		
 	def refresh(self):
 		if len(invest.STOCKS) == 0:
@@ -67,16 +64,19 @@
 		
 		quote_items = quotes.items ()
 		quote_items.sort ()
+
 		for ticker, val in quote_items:
+			pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, 1, 1)
+			
 			# Check whether the symbol is a simple quote, or a portfolio value
 			is_simple_quote = True
 			for purchase in invest.STOCKS[ticker]:
 				if purchase["amount"] != 0:
 					is_simple_quote = False
 					break
-
+			
 			if is_simple_quote:
-				self.append([ticker, True, 0, 0, val["trade"], val["variation"]])
+				row = self.insert(0, [ticker, True, 0, 0, val["trade"], val["variation"], pb])
 			else:
 				current = sum([purchase["amount"]*val["trade"] for purchase in invest.STOCKS[ticker] if purchase["amount"] != 0])
 				paid = sum([purchase["amount"]*purchase["bought"] + purchase["comission"] for purchase in invest.STOCKS[ticker] if purchase["amount"] != 0])
@@ -85,13 +85,23 @@
 					change = 100*balance/paid
 				else:
 					change = 100 # Not technically correct, but it will look more intuitive than the real result of infinity.
-				self.append([ticker, False, balance, change, val["trade"], val["variation"]])
+				row = self.insert(0, [ticker, False, balance, change, val["trade"], val["variation"], pb])
 				
-		self.emit("quotes-updated")
+			invest.chart.FinancialSparklineChartPixbuf(ticker, self.set_pb_callback, row)
+	
+	def set_pb_callback(self, pb, row):
+		self.set_value(row, 6, pb)
+	
+	# check if we have only simple quotes
+	def simple_quotes_only(self):
+		res = True
+		for entry, value in invest.STOCKS.iteritems():
+			for purchase in value:
+				if purchase["amount"] != 0:
+					res = False
+					break
+		return res
 
 if gtk.pygtk_version < (2,8,0):
 	gobject.type_register(QuoteUpdater)
 
-_updater = QuoteUpdater()
-def get_quotes_updater():
-	return _updater

Modified: trunk/invest-applet/invest/widgets.py
==============================================================================
--- trunk/invest-applet/invest/widgets.py	(original)
+++ trunk/invest-applet/invest/widgets.py	Thu Apr  3 05:54:18 2008
@@ -6,7 +6,6 @@
 import csv, os
 from gettext import gettext as _
 import invest, invest.about, invest.chart
-from invest.quotes import get_quotes_updater
 from invest import *
 
 COLORSCALE_POSITIVE = [
@@ -37,29 +36,46 @@
 RED = COLORSCALE_NEGATIVE[-1]
 
 class InvestWidget(gtk.TreeView):
-	def __init__(self):
+	def __init__(self, quotes_updater):
 		gtk.TreeView.__init__(self)
-
 		self.set_property("rules-hint", True)
 		self.set_reorderable(True)
 
+		simple_quotes_only = quotes_updater.simple_quotes_only()
+
 		# model: SYMBOL, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION
 		# old col_names = ['Symbol', 'Value/Balance', 'Variation/Balance PCT', 'Value']
 		# Translators: these words all refer to a stock. Last is short
 		# for "last price". Gain is referring to the gain since the 
 		# stock was purchased.
-		col_names = [_('Symbol'), _('Last'), _('Change'), _('Gain'), _('Gain %')]
+		col_names = [_('Ticker'), _('Last'), _('Change'), _('Chart'), _('Gain'), _('Gain %')]
 		col_cellgetdata_functions = [self._getcelldata_symbol, self._getcelldata_value,
-			self._getcelldata_variation, self._getcelldata_balance, self._getcelldata_balancepct]
+			self._getcelldata_variation, None, self._getcelldata_balance, 
+			self._getcelldata_balancepct]
 		for i, col_name in enumerate(col_names):
-			cell = gtk.CellRendererText ()
-			column = gtk.TreeViewColumn (col_name, cell)
-			column.set_cell_data_func(cell, col_cellgetdata_functions[i])
-			self.append_column(column)
+			if i < 3:
+				cell = gtk.CellRendererText()
+				column = gtk.TreeViewColumn (col_name, cell)
+				column.set_cell_data_func(cell, col_cellgetdata_functions[i])
+				self.append_column(column)
+			elif i == 3:
+				cell_pb = gtk.CellRendererPixbuf()
+				column = gtk.TreeViewColumn (col_name, cell_pb, pixbuf=6)
+				self.append_column(column)
+			else:
+				# add the last two column only if we have any positions
+				if simple_quotes_only == False:
+					cell = gtk.CellRendererText()
+					column = gtk.TreeViewColumn (col_name, cell)
+					column.set_cell_data_func(cell, col_cellgetdata_functions[i])
+					self.append_column(column)
 
-		self.connect('row-activated', self.on_row_activated)
-		self.set_model(get_quotes_updater())
+		if simple_quotes_only == True:
+			self.set_property('headers-visible', False)
 
+		self.connect('row-activated', self.on_row_activated)
+		self.set_model(quotes_updater)
+		
 	def _getcelldata_symbol(self, column, cell, model, iter):
 		cell.set_property('text', model[iter][model.SYMBOL])
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]