[gnome-applets: 1/2] invest-applet: Allow labels instead of stock symbols



commit fb6862e5540f59491a64917e61cc870d4652286c
Author: Callum McKenzie <callum spooky-possum org>
Date:   Fri Jul 24 21:17:05 2009 +1200

    invest-applet: Allow labels instead of stock symbols
    
    A contribution from Enrico Minack to allow user-supplied labels
    to be used instead of the stock symbol.

 invest-applet/invest/__init__.py    |   28 ++++++++++++++++++++++++++++
 invest-applet/invest/preferences.py |   32 ++++++++++++++++++--------------
 invest-applet/invest/quotes.py      |   27 +++++++++++++++++----------
 invest-applet/invest/test.py        |    2 +-
 invest-applet/invest/widgets.py     |   22 +++++++++++++++-------
 5 files changed, 79 insertions(+), 32 deletions(-)
---
diff --git a/invest-applet/invest/__init__.py b/invest-applet/invest/__init__.py
index bc8105a..9d3eccd 100644
--- a/invest-applet/invest/__init__.py
+++ b/invest-applet/invest/__init__.py
@@ -1,5 +1,6 @@
 import os, sys
 from os.path import join, exists, isdir, isfile, dirname, abspath, expanduser
+from types import ListType
 
 import gtk, gtk.gdk, gconf, gobject
 import cPickle
@@ -56,10 +57,37 @@ GCONF_DIR = "/apps/invest"
 # Preload gconf directories
 #GCONF_CLIENT.add_dir(GCONF_DIR, gconf.CLIENT_PRELOAD_RECURSIVE)
 
+# tests whether the given stocks are in the old format
+def old_stock_format(stocks):
+	if len(stocks) == 0:
+		return False
+
+	# take the first element of the dict and check if its value is a list
+	if type(stocks[stocks.keys()[0]]) is ListType:
+		return True
+
+	# there is no list, so it is already the new stock file format
+	return False
+
+# converts the given stocks from the old format into the new one
+def update_stock_format(stocks):
+	new = {}
+	
+	for k, l in stocks.items():
+		d = {'label':"", 'purchases':l}
+		new[k] = d
+		
+	return new
+
 STOCKS_FILE = join(USER_INVEST_DIR, "stocks.pickle")
 
 try:
 	STOCKS = cPickle.load(file(STOCKS_FILE))
+	
+	# if the stocks file is in the old stocks format,
+	# then we need to convert it into the new format
+	if old_stock_format(STOCKS):
+		STOCKS = update_stock_format(STOCKS);
 except Exception, msg:
 	STOCKS = {}
 
diff --git a/invest-applet/invest/preferences.py b/invest-applet/invest/preferences.py
index a73d5bf..94ed23a 100644
--- a/invest-applet/invest/preferences.py
+++ b/invest-applet/invest/preferences.py
@@ -20,9 +20,10 @@ class PrefsDialog:
 		self.ui.get_object("remove").connect('activate', self.on_remove_stock)
 		self.treeview.connect('key-press-event', self.on_tree_keypress)
 
-		self.typs = (str, float, float, float)
-		self.names = (_("Symbol"), _("Amount"), _("Price"), _("Commission"))
+		self.typs = (str, str, float, float, float)
+		self.names = (_("Symbol"), _("Label"), _("Amount"), _("Price"), _("Commission"))
 		store = gtk.ListStore(*self.typs)
+		store.set_sort_column_id(0, gtk.SORT_ASCENDING)
 		self.treeview.set_model(store)
 		self.model = store
 
@@ -49,19 +50,22 @@ class PrefsDialog:
 			cell_description.connect("edited", on_cell_edited, column, typ)
 			column_description = gtk.TreeViewColumn (name, cell_description)
 			if typ == str:
-				column_description.set_attributes (cell_description, text=0)
+				column_description.set_attributes (cell_description, text=column)
+				column_description.set_sort_column_id(column)
 			if typ == float:
 				column_description.set_cell_data_func(cell_description, get_cell_data, (float, column))
 			view.append_column(column_description)
 
 
-		for n in xrange (0, 4):
-			create_cell (self.treeview, n, self.names[n], self.typs[n])
+		for n in xrange (0, 5):
+			create_cell (self.treeview, n, self.names[n], self.typs[n])		
 		stock_items = invest.STOCKS.items ()
 		stock_items.sort ()
-		for key, purchases in stock_items:
+		for key, data in stock_items:
+			label = data["label"]
+			purchases = data["purchases"]
 			for purchase in purchases:
-				store.append([key, purchase["amount"], purchase["bought"], purchase["comission"]])
+				store.append([key, label, purchase["amount"], purchase["bought"], purchase["comission"]])
 
 		try:
 			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest-16.png"), -1,-1)
@@ -87,12 +91,12 @@ class PrefsDialog:
 			#	return
 
 			if not model[iter][0] in invest.STOCKS:
-				invest.STOCKS[model[iter][0]] = []
-
-			invest.STOCKS[model[iter][0]].append({
-				"amount": float(model[iter][1]),
-				"bought": float(model[iter][2]),
-				"comission": float(model[iter][3]),
+				invest.STOCKS[model[iter][0]] = { 'label': model[iter][1], 'purchases': [] }
+				
+			invest.STOCKS[model[iter][0]]["purchases"].append({
+				"amount": float(model[iter][2]),
+				"bought": float(model[iter][3]),
+				"comission": float(model[iter][4]),
 			})
 		self.model.foreach(save_symbol)
 		try:
@@ -106,7 +110,7 @@ class PrefsDialog:
 		pass
 
 	def on_add_stock(self, w):
-		iter = self.model.append(["GOOG", 0, 0, 0])
+		iter = self.model.append(["GOOG", "Google Inc.", 0, 0, 0])
 		path = self.model.get_path(iter)
 		self.treeview.set_cursor(path, self.treeview.get_column(0), True)
 
diff --git a/invest-applet/invest/quotes.py b/invest-applet/invest/quotes.py
index f32b2da..a2108db 100644
--- a/invest-applet/invest/quotes.py
+++ b/invest-applet/invest/quotes.py
@@ -66,12 +66,13 @@ class QuotesRetriever(Thread, _IdleObject):
 class QuoteUpdater(gtk.ListStore):
 	updated = False
 	last_updated = None
-	SYMBOL, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION_PCT, PB = range(7)
+	SYMBOL, LABEL, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION_PCT, PB = range(8)
 	def __init__ (self, change_icon_callback, set_tooltip_callback):
-		gtk.ListStore.__init__ (self, gobject.TYPE_STRING, bool, float, float, float, float, gtk.gdk.Pixbuf)
+		gtk.ListStore.__init__ (self, gobject.TYPE_STRING, gobject.TYPE_STRING, bool, float, float, float, float, gtk.gdk.Pixbuf)
 		gobject.timeout_add(AUTOREFRESH_TIMEOUT, self.refresh)
 		self.change_icon_callback = change_icon_callback
 		self.set_tooltip_callback = set_tooltip_callback
+		self.set_sort_column_id(1, gtk.SORT_ASCENDING)
 		self.refresh()
 		
 	def refresh(self):
@@ -151,27 +152,32 @@ class QuoteUpdater(gtk.ListStore):
 			for ticker, val in quote_items:
 				pb = None
 				
+				# get the label of this stock for later reuse
+				label = invest.STOCKS[ticker]["label"]
+				if len(label) == 0:
+					label = ticker
+
 				# Check whether the symbol is a simple quote, or a portfolio value
 				is_simple_quote = True
-				for purchase in invest.STOCKS[ticker]:
+				for purchase in invest.STOCKS[ticker]["purchases"]:
 					if purchase["amount"] != 0:
 						is_simple_quote = False
 						break
 				
 				if is_simple_quote:
 					self.simple_quotes_count += 1
-					row = self.insert(0, [ticker, True, 0, 0, val["trade"], val["variation_pct"], pb])
+					row = self.insert(0, [ticker, label, True, 0, 0, val["trade"], val["variation_pct"], pb])
 					simple_quotes_change += val['variation_pct']
 				else:
 					self.positions_count += 1
-					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])
+					current = sum([purchase["amount"]*val["trade"] for purchase in invest.STOCKS[ticker]["purchases"] if purchase["amount"] != 0])
+					paid = sum([purchase["amount"]*purchase["bought"] + purchase["comission"] for purchase in invest.STOCKS[ticker]["purchases"] if purchase["amount"] != 0])
 					balance = current - paid
 					if paid != 0:
 						change = 100*balance/paid
 					else:
 						change = 100 # Not technically correct, but it will look more intuitive than the real result of infinity.
-					row = self.insert(0, [ticker, False, balance, change, val["trade"], val["variation_pct"], pb])
+					row = self.insert(0, [ticker, label, False, balance, change, val["trade"], val["variation_pct"], pb])
 					self.positions_balance += balance
 	
 				if len(ticker.split('.')) == 2:
@@ -203,13 +209,14 @@ class QuoteUpdater(gtk.ListStore):
 			self.quotes_valid = False
 
 	def set_pb_callback(self, retriever, row):
-		self.set_value(row, 6, retriever.image.get_pixbuf())
+		self.set_value(row, self.PB, retriever.image.get_pixbuf())
 	
 	# 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:
+		for entry, data in invest.STOCKS.iteritems():
+			purchases = data["purchases"]
+			for purchase in purchases:
 				if purchase["amount"] != 0:
 					res = False
 					break
diff --git a/invest-applet/invest/test.py b/invest-applet/invest/test.py
index cacbc03..4a86a59 100755
--- a/invest-applet/invest/test.py
+++ b/invest-applet/invest/test.py
@@ -11,7 +11,7 @@ def null_function (*args):
 class TestQuotes (unittest.TestCase):
     def testQuoteUpdater_populate (self):
         qu = quotes.QuoteUpdater (null_function, null_function)
-        invest.STOCKS = {'GOGO': [{'amount' : 1, 'comission' : 0.0, 'bought': 0.0}], 'JAVA': [{'amount' : 1, 'comission' : 0.0, 'bought': 0.0}]}
+        invest.STOCKS = {'GOGO': {'label': "Google Inc.", 'purchases': [{'amount' : 1, 'comission' : 0.0, 'bought': 0.0}]}, 'JAVA': {'label':"Sun Microsystems Inc.", 'purchases': [{'amount' : 1, 'comission' : 0.0, 'bought': 0.0}]}}
         quote = { 'GOGO': { "ticker": 'GOGO', "trade": 386.91, "time": "10/3/2008", "date": "4.00pm", "variation": -3.58, "open": 397.14, "variation_pct": 10 }}
         qu.populate (quote)
         self.assertEqual (qu.quotes_valid, True)
diff --git a/invest-applet/invest/widgets.py b/invest-applet/invest/widgets.py
index 3cc99b2..967294a 100644
--- a/invest-applet/invest/widgets.py
+++ b/invest-applet/invest/widgets.py
@@ -46,29 +46,37 @@ class InvestWidget(gtk.TreeView):
 
 		simple_quotes_only = quotes_updater.simple_quotes_only()
 
-		# model: SYMBOL, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION_PCT, PB
+		# model: SYMBOL, LABEL, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION_PCT, PB
 		# 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 = [_('Ticker'), _('Last'), _('Change %'), _('Chart'), _('Gain'), _('Gain %')]
-		col_cellgetdata_functions = [self._getcelldata_symbol, self._getcelldata_value,
-			self._getcelldata_variation, None, self._getcelldata_balance,
+		col_cellgetdata_functions = [self._getcelldata_label, self._getcelldata_value,
+			self._getcelldata_variation, None, self._getcelldata_balance, 
 			self._getcelldata_balancepct]
 		for i, col_name in enumerate(col_names):
 			if i < 3:
 				cell = gtk.CellRendererText()
 				column = gtk.TreeViewColumn (col_name, cell)
+				if i == 0:
+					column.set_sort_column_id(quotes_updater.LABEL)
+				elif i == 2:
+					column.set_sort_column_id(quotes_updater.VARIATION_PCT)
 				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)
+				column = gtk.TreeViewColumn (col_name, cell_pb, pixbuf=quotes_updater.PB)
 				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)
+					if i == 4:
+						column.set_sort_column_id(quotes_updater.BALANCE)
+					elif i == 5:
+						column.set_sort_column_id(quotes_updater.BALANCE_PCT)
 					column.set_cell_data_func(cell, col_cellgetdata_functions[i])
 					self.append_column(column)
 
@@ -78,8 +86,8 @@ class InvestWidget(gtk.TreeView):
 		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])
+	def _getcelldata_label(self, column, cell, model, iter):
+		cell.set_property('text', model[iter][model.LABEL])
 
 	def _getcelldata_value(self, column, cell, model, iter):
 		cell.set_property('text', "%.5g" % model[iter][model.VALUE])
@@ -195,7 +203,7 @@ class InvestTrend(gtk.Image):
 
 			start = now / (1 + var)
 
-			portfolio_number = sum([purchase["amount"] for purchase in invest.STOCKS[row[updater.SYMBOL]]])
+			portfolio_number = sum([purchase["amount"] for purchase in invest.STOCKS[row[updater.SYMBOL]]["purchases"]])
 			start_total += start * portfolio_number
 			now_total += now * portfolio_number
 



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