-#!/usr/bin/env python2.5
+#!/usr/bin/env python
# -*- coding: UTF8 -*-
# Copyright (C) 2008 by Daniel Martin Yerga
# <dyerga@gmail.com>
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-# StocksPy: Application to get stocks data from Yahoo Finance.
-# Version 0.1
+# StocksThis: Application to get stocks data from Yahoo Finance.
#
+_version = "StockThis 0.4 rev1"
+VERSION = "0.4"
+
import urllib2
import gtk, gobject
-try:
- import hildon
- HILDON = True
-except:
- HILDON = False
-
-try:
- import osso
- OSSO = True
-# osso_c = osso.Context("net.yerga.stockthis", "0.2", False)
-except:
- OSSO = False
+import os
+import hildon
+import marketdata
+import settings
+import logging
+import sys
-from marketdata import markets, idmarket, localmarkets, localids
+from portrait import FremantleRotation
-#TODO: detect if running in Fremantle
-FREMANTLE=True
+import osso
+osso_c = osso.Context("net.yerga.stockthis", "0.3", False)
#detect if is ran locally or not
-import sys
runningpath = sys.path[0]
-if '/usr/share' in runningpath:
- running_locally = False
+if '/opt/' in runningpath:
+ runninglocally = False
else:
- running_locally = True
+ runninglocally = True
-if running_locally:
- imgdir = 'pixmaps/'
-else:
- imgdir = '/usr/share/stockthis/pixmaps/'
+HOME = os.path.expanduser("~")
+
+settingsdb, imgdir, configdir, logfile = \
+ settings.define_paths(runninglocally, HOME)
+
+logger = logging.getLogger('st')
+logging.basicConfig(filename=logfile,level=logging.ERROR, filemode='w')
+
+DEBUG = True
+
+if DEBUG:
+ #set the main logger to DEBUG
+ logger.setLevel(logging.DEBUG)
+
+ #Create a handler for console debug
+ console = logging.StreamHandler()
+ console.setLevel(logging.DEBUG)
+ # set a format which is simpler for console use
+ formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
+ # tell the handler to use this format
+ console.setFormatter(formatter)
+ logging.getLogger('').addHandler(console)
-loading_img = imgdir + 'loading.gif'
+fhsize = gtk.HILDON_SIZE_FINGER_HEIGHT
+horbtn = hildon.BUTTON_ARRANGEMENT_HORIZONTAL
+ui_normal = gtk.HILDON_UI_MODE_NORMAL
+ui_edit = gtk.HILDON_UI_MODE_EDIT
+winprogind = hildon.hildon_gtk_window_set_progress_indicator
+
+allnames = []
+allsymbols = []
gtk.gdk.threads_init()
class StocksPy:
def __init__(self):
- if HILDON:
- self.program = hildon.Program()
- self.program.__init__()
- gtk.set_application_name('')
- if FREMANTLE:
- self.window = hildon.StackableWindow()
- else:
- self.window = hildon.Window()
- self.program.add_window(self.window)
- else:
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
-
+ self.program = hildon.Program()
+ self.program.__init__()
+ gtk.set_application_name("StockThis")
+ self.window = hildon.StackableWindow()
self.window.set_default_size(800, 480)
- self.window.set_title('StockThis')
+ self.program.add_window(self.window)
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_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)
- menu.show_all()
- else:
- #TODO: create a gtk.menubar
- pass
-
- vbox = gtk.VBox()
+ FremantleRotation('StockThis', None, "0.3", 0)
- 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.create_menu(self.window)
- self.markets_btn = gtk.Button('Markets')
- self.markets_btn.connect("clicked", self.create_markets_view)
- self.markets_btn.set_property("can_focus", False)
+ vbox = gtk.VBox()
+ toolbar = self.main_toolbar(False, False, None, '', '', True)
+
+ parea = hildon.PannableArea()
+ tv = hildon.GtkTreeView(ui_normal)
+ inmodel = self.__create_model(marketdata.main, marketdata.idmain)
+ tv.connect("row-activated", self.show_instrument_view, inmodel,
+ marketdata.localmarkets, marketdata.localids,
+ marketdata.idmain)
+ tv.set_model(inmodel)
+ self._tv_columns(tv)
+ parea.add(tv)
+
+ vbox.pack_start(parea, True, True, 0)
+ vbox.pack_start(gtk.HSeparator(), False, False, 5)
+ vbox.pack_start(toolbar, False, False, 0)
- self.components_btn = gtk.Button('Instruments')
- self.components_btn.connect("clicked", self.show_components_view)
- self.components_btn.set_property("can_focus", False)
+ self.window.add(vbox)
+ self.window.show_all()
- self.graph_btn = gtk.Button('Graph')
- self.graph_btn.connect("clicked", self.create_graphs_view)
- self.graph_btn.set_property("can_focus", False)
+ self.show_info_banner(self.window,
+ ("StockThis uses your network connection to get data.\n"
+ "Be aware of the high costs that your network provider may apply."))
- self.refresh_btn = gtk.Button('Refresh')
- self.refresh_btn.connect("clicked", self.refresh_stock_data)
- self.refresh_btn.set_property("can_focus", False)
+ def create_menu(self, window):
+ menu = hildon.AppMenu()
+ window.set_app_menu(menu)
+ button = gtk.Button("About")
+ button.connect("clicked", About)
+ menu.append(button)
+ menu.show_all()
- self.quotes_btn = gtk.Button('Quote')
- self.quotes_btn.connect("clicked", self.show_quotes_view)
- self.quotes_btn.set_property("can_focus", False)
+ def show_instrument_view(self, widget, path, column, inmodel, names,
+ ids, mindex):
+ market = inmodel[path][0]
+ names = names[mindex.index(market)]
+ ids = ids[mindex.index(market)]
- 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)
+ window = hildon.StackableWindow()
+ self.create_menu(window)
+ window.set_title(inmodel[path][1])
- self.mainbox = gtk.VBox()
+ vbox = gtk.VBox()
+ toolbar = self.main_toolbar(False, False, None, '', '', False)
+ parea = hildon.PannableArea()
+ parea.connect("horizontal-movement", self.horizontal_mov)
+ tv = hildon.GtkTreeView(ui_normal)
+ model = self.__create_model(names, ids)
- if FREMANTLE:
- self.swin = hildon.PannableArea()
+ if market == 'metals':
+ tv.connect("row-activated", self.show_metal_graphs, model)
else:
- self.swin = gtk.ScrolledWindow()
- if HILDON:
- hildon.hildon_helper_set_thumb_scrollbar(self.swin, True)
- self.swin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- self.swin.add_with_viewport(self.mainbox)
+ tv.connect("row-activated", self.show_quotes_view, model, False)
+
+ tv.set_model(model)
+ self._tv_columns(tv)
+ parea.add(tv)
- vbox.pack_start(self.swin, True, True, 0)
+ vbox.pack_start(parea, True, True, 0)
vbox.pack_start(gtk.HSeparator(), False, False, 5)
- vbox.pack_start(self.toolbar, False, False, 0)
+ vbox.pack_start(toolbar, False, False, 0)
- self.create_markets_view(self.mainbox)
- self.window.add(vbox)
+ window.add(vbox)
+ window.show_all()
- self.window.show_all()
+ def horizontal_mov(self, parea, direction, initial_x, initial_y):
+ #direction = 2 right-to-left
+ #direction = 3 lefto-to-right
- 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()
- 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()
-
- def show_components_view(self, widget):
- kind = self.market_id
- self.create_components_view(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()
- self.markets_btn.show()
- 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()
- 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)
+ vadj = parea.get_vadjustment()
+ val = vadj.get_value()
- self.components_trv.set_rubber_banding(True)
- 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.add_initial_components(names, ids)
+ if direction == 2:
+ if int(val)-2500 < 0:
+ parea.scroll_to(-1, 0)
+ else:
+ parea.scroll_to(-1, int(val)-2500)
+ elif direction == 3:
+ parea.scroll_to(-1, int(val)+3500)
+
+ #print val
+
+ def show_quotes_view(self, widget, path, column, model, portfolio):
+ quote = model[path][0], model[path][1]
+ #print "quote:", quote[0]
+ #('EURUSD=X', 'EUR/USD')
+
+ #Currencies and ETFs should show the list now -> view = True
+ #Other items show a new list with options
+ view = False
+ for i in marketdata.localids[(len(marketdata.localids)-2):]:
+ for j in i:
+ if quote[0] == j:
+ #print j
+ view = True
+
+ if not view:
+ if quote[0] in marketdata.idindexes:
+ self.show_instrument_view(widget, path, column, model,
+ marketdata.wnamesindexes,
+ marketdata.widsindexes,
+ marketdata.idindexes)
+ return
+ if quote[0] in marketdata.idotmarkets:
+ self.show_instrument_view(widget, path, column, model,
+ marketdata.omnames,
+ marketdata.omsymbols,
+ marketdata.idotmarkets)
+ return
+ if quote[0] in marketdata.ideumarkets:
+ self.show_instrument_view(widget, path, column, model,
+ marketdata.eunames,
+ marketdata.eusymbols,
+ marketdata.ideumarkets)
+ return
+ if quote[0] in marketdata.idusmarkets:
+ self.show_instrument_view(widget, path, column, model,
+ marketdata.usnames,
+ marketdata.ussymbols,
+ marketdata.idusmarkets)
+ return
+
+
+ win = hildon.StackableWindow()
+ self.create_menu(win)
+ win.set_title(quote[1])
- self.compbox.pack_start(self.components_trv, True, True, 0)
+ vbox = gtk.VBox()
- self.mainbox.pack_start(self.compbox, True, True, 0)
- self.mainbox.show_all()
+ ltitle = gtk.Label('')
+ ltitle.set_markup('<b><big>' + quote[1].replace('&', '') +
+ '</big></b>')
+ color = gtk.gdk.color_parse("#03A5FF")
+ ltitle.modify_fg(gtk.STATE_NORMAL, color)
+
+ parea = hildon.PannableArea()
+ parea.set_property("mov-mode", hildon.MOVEMENT_MODE_BOTH)
+
+ vbox1 = gtk.VBox()
+
+ hbox = gtk.HBox()
+ label = gtk.Label('')
+ label.set_markup('<b><big>%39s:</big></b>' % '<u>Price</u>')
+ lprice = gtk.Label('')
+ hbox.pack_start(label, False, False, 0)
+ #if self.is_portrait():
+ hbox.pack_start(lprice, False, False, 25)
+ #else:
+ # hbox.pack_start(lprice, False, False, 245)
+
+ vbox1.pack_start(hbox, True, True, 0)
+
+ hbox = gtk.HBox()
+ label = gtk.Label('')
+ label.set_markup('<b><big>%35s:</big></b>' % '<u>Change</u>')
+ lchange = gtk.Label('')
+ lpercent = gtk.Label('')
+ hbox.pack_start(label, False, False, 0)
+ #if self.is_portrait():
+ hbox.pack_start(lchange, False, False, 25)
+ hbox.pack_start(lpercent, False, False, 0)
+ #else:
+ # hbox.pack_start(lchange, False, False, 205)
+ # hbox.pack_start(lpercent, False, False, 0)
+
+ vbox1.pack_start(hbox, True, True, 0)
+
+ hbox = gtk.HBox()
+ label = gtk.Label('')
+ label.set_markup('<b><big>%35s:</big></b>' % '<u>Volume</u>')
+ lvolume = gtk.Label('')
+ hbox.pack_start(label, False, False, 0)
+ #if self.is_portrait():
+ hbox.pack_start(lvolume, False, False, 25)
+ #else:
+ # hbox.pack_start(lvolume, False, False, 207)
+
+ vbox1.pack_start(hbox, True, True, 0)
+
+ hbox = gtk.HBox()
+ label = gtk.Label('')
+ label.set_markup('<b><big>%30s:</big></b>' % '<u>52 week high</u>')
+ l52whigh = gtk.Label('')
+ hbox.pack_start(label, False, False, 0)
+ #if self.is_portrait():
+ hbox.pack_start(l52whigh, False, False, 25)
+ #else:
+ # hbox.pack_start(l52whigh, False, False, 125)
+
+ vbox1.pack_start(hbox, True, True, 0)
+
+ hbox = gtk.HBox()
+ label = gtk.Label('')
+ label.set_markup('<b><big>%30s:</big></b>' % '<u>52 week low</u>')
+ l52wlow = gtk.Label('')
+ hbox.pack_start(label, False, False, 0)
+ #if self.is_portrait():
+ hbox.pack_start(l52wlow, False, False, 26)
+ #else:
+ # hbox.pack_start(l52wlow, False, False, 140)
+ vbox1.pack_start(hbox, True, True, 0)
+
+ #if self.is_portrait():
+ # hbox = gtk.VBox()
+ #else:
+ hbox = gtk.HBox()
+ button1 = hildon.PickerButton(fhsize, horbtn)
+ data = ["50", "100", "200", "300", "400", "500", "600", "700", "800",
+ "900", "1000"]
+ selector = self.create_selector(data, True)
+ button1.set_selector(selector)
+ button1.set_title("Your shares")
+ shares = self.get_shares_from_symbol(quote[0])
+ button1.set_value(shares)
+ hbox.pack_start(button1, True, True, 0)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_title("Add to Portfolio")
+ button.connect("clicked", self.add_to_portfolio, button1, quote[0], quote[1])
+ hbox.pack_start(button, True, True, 0)
- def select_component(self, widget, path, column, ids):
- self.create_quotes_view(widget,self.components_model[path][1] )
+ hbox1 = gtk.HBox()
+ label = gtk.Label('')
+ label.set_markup('<b><big>%37s:</big></b>' % '<u>Shares</u>')
+ lshares = gtk.Label(shares)
+ hbox1.pack_start(label, False, False, 0)
+ #if self.is_portrait():
+ hbox1.pack_start(lshares, False, False, 25)
+ #else:
+ # hbox1.pack_start(lshares, False, False, 220)
- 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)
+ hbox2 = gtk.HBox()
+ label = gtk.Label('')
+ label.set_markup('<b><big>%29s:</big></b>' % '<u>Holdings Value</u>')
+ holdingsvalue = gtk.Label("")
+ hbox2.pack_start(label, False, False, 0)
+ #if self.is_portrait():
+ hbox2.pack_start(holdingsvalue, False, False, 25)
+ #else:
+ # hbox2.pack_start(holdingsvalue, False, False, 105)
- def __create_components_model(self):
- lstore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- return lstore
+ hbox3 = gtk.HBox()
+ label = gtk.Label('')
+ label.set_markup("<b><big>%25s:</big></b>" % "<u>Day's Value Change</u>")
+ dayvaluechange = gtk.Label("")
+ hbox3.pack_start(label, False, False, 0)
+ #if self.is_portrait():
+ hbox3.pack_start(dayvaluechange, False, False, 25)
+ #else:
+ # hbox3.pack_start(dayvaluechange, False, False, 45)
+
+ if not portfolio:
+ vbox1.pack_start(hbox, False, False, 0)
+ else:
+ vbox1.pack_start(hbox1, True, True, 0)
+ vbox1.pack_start(hbox2, True, True, 0)
+ vbox1.pack_start(hbox3, True, True, 0)
- def _components_trv_columns(self, treeview):
- renderer = gtk.CellRendererText()
- 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)
+ parea.add_with_viewport(vbox1)
- renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn('IDS', renderer, text=1)
- column.set_visible(False)
- treeview.append_column(column)
+ widgets = [win, ltitle, lprice, lchange, lpercent, lvolume, l52whigh,
+ l52wlow, lshares, holdingsvalue, dayvaluechange]
- 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])
+ toolbar = self.main_toolbar(True, portfolio, widgets, quote[0], quote[1], False)
- def get_selected_from_treeview(self, treeview, model, setting):
- selection = treeview.get_selection()
- selected_model, selected_iter = selection.get_selected()
- if selected_iter:
- selected_name = model.get_value(selected_iter, setting)
- else:
- selected_name = None
- return selected_name, selected_iter, selected_model
+ vbox.pack_start(ltitle, False, False, 0)
+ vbox.pack_start(gtk.HSeparator(), False, False, 0)
+ vbox.pack_start(parea, True, True, 0)
+ vbox.pack_start(gtk.HSeparator(), False, False, 5)
+ vbox.pack_start(toolbar, False, False, 0)
- def show_quotes_view(self, widget):
- kind = self.stocks_id
- self.create_quotes_view(widget, kind)
- def create_quotes_view(self, widget, kind):
- self.stocks_id = kind
- self.toolbar.show()
- self.components_btn.show()
- self.markets_btn.show()
- self.refresh_btn.show()
- self.graph_btn.show()
- self.quotes_btn.hide()
+ win.add(vbox)
+ win.show_all()
+ self.show_data(quote[0], widgets, shares)
- #actual_view = self.mainbox.get_children()
- #actual_view[0].destroy()
+ def is_portrait(self):
+ width = gtk.gdk.screen_width()
+ height = gtk.gdk.screen_height()
+ if width > height:
+ return False
+ else:
+ return True
+ def get_shares_from_symbol(self, symbol):
+ shares = "0"
try:
- self.graphbox.destroy()
+ portfolio_data = settings.load_portfolio(settingsdb)
+ for item in portfolio_data :
+ if symbol in item:
+ shares = item[2]
+ return shares
except:
- pass
-
- for i in range(len(localids)):
- if kind in localids[i]:
- ind1, ind2 = i, localids[i].index(kind)
+ logger.exception("Getting shares from symbol: %s" % symbol)
+ return shares
- self.quotesbox = gtk.VBox()
+ def add_to_portfolio(self, widget, button, symbol, name):
+ shares = button.get_value()
- 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)
+ try:
+ portfolio = settings.load_portfolio(settingsdb)
+ index = "None"
+ for item in portfolio:
+ if symbol in item:
+ index = portfolio.index(item)
- self.databox = gtk.VBox()
+ item = [symbol, name, shares, '-']
- self.imagebox = gtk.VBox()
- self.dataimg = gtk.Image()
- self.imagebox.pack_start(self.dataimg)
+ if index is "None":
+ settings.insert_new_item_to_portfolio(settingsdb, item)
+ else:
+ settings.delete_item_from_portfolio(settingsdb, symbol)
+ settings.insert_new_item_to_portfolio(settingsdb, item)
- self.show_data(kind)
+ self.show_info_banner(widget, "Added to portfolio")
+ except:
+ logger.exception("Adding to portfolio: %s, %s" % (symbol, name))
+ self.show_info_banner(widget, "Error adding to portfolio")
- hbox1 = gtk.HBox()
- label2 = gtk.Label('')
- label2.set_markup('<b><big>Price:</big></b>')
- self.lprice = gtk.Label('')
+ def create_selector(self, data, entry):
+ if entry:
+ selector = hildon.TouchSelectorEntry(text=True)
+ else:
+ selector = hildon.TouchSelector(text=True)
+ for i in range(len(data)):
+ selector.append_text(data[i])
- hbox1.pack_start(label2, False, False, 50)
- hbox1.pack_start(self.lprice, False, False, 185)
+ return selector
- hbox2 = gtk.HBox()
+ def show_data(self, symbol, widgets, shares):
+ import thread
+ winprogind(widgets[0], 1)
+ thread.start_new_thread(self.get_data, (symbol, widgets, shares))
- label4 = gtk.Label('')
- label4.set_markup('<b><big>Change:</big></b>')
- self.lchange = gtk.Label('')
- self.lpercent = gtk.Label('')
+ def get_data(self, symbol, widgets, shares):
+ from ystockquote import ystockquote as yt
+ win, ltitle, lprice, lchange, lpercent, lvolume, l52whigh, l52wlow, lshares, holdingsvalue, dayvaluechange = widgets
- hbox2.pack_start(label4, False, False, 50)
- hbox2.pack_start(self.lchange , False, False, 145)
- hbox2.pack_start(self.lpercent, False, False, 0)
+ try:
+ data = yt.get_all(symbol)
+ except:
+ logger.exception("Getting data from Yahoo: %s" % symbol)
+ data = {'price': 'N/A', 'change': 'N/A', 'volume':'N/A',
+ '52_week_high': 'N/A', '52_week_low': 'N/A'}
+ ltitle.set_markup('<b><big>Failed to get data</big></b>')
- hbox3 = gtk.HBox()
+ try:
+ ch_percent = \
+ 100.0 * float(data['change'])/(float(data['price']) - \
+ float(data['change']))
+ except ValueError:
+ ch_percent = 0.0
- label7 = gtk.Label('')
- label7.set_markup('<b><big>Volume:</big></b>')
- self.lvolume = gtk.Label('')
+ lprice.set_label(data['price'])
+ lchange.set_label(data['change'])
+ lpercent.set_label('%6.2f %%' % ch_percent)
- hbox3.pack_start(label7, False, False, 50)
- hbox3.pack_start(self.lvolume , False, False, 145)
+ if '-' in data['change']:
+ color = gtk.gdk.color_parse("#FF0000")
+ else:
+ color = gtk.gdk.color_parse("#16EB78")
- hbox4 = gtk.HBox()
+ lpercent.modify_fg(gtk.STATE_NORMAL, color)
+ lchange.modify_fg(gtk.STATE_NORMAL, color)
- label9 = gtk.Label('')
- label9.set_markup('<b><big>52 week high:</big></b>')
- self.l52whigh = gtk.Label('')
+ lvolume.set_label(data['volume'])
+ l52whigh.set_label(data['52_week_high'])
+ l52wlow.set_label(data['52_week_low'])
- hbox4.pack_start(label9, False, False, 50)
- hbox4.pack_start(self.l52whigh , False, False, 55)
+ try:
+ daychange = float(shares)*float(data['change'])
+ except ValueError:
+ daychange = 'N/A'
+ try:
+ holdvalue = float(shares)*float(data['price'])
+ except ValueError:
+ holdvalue = 'N/A'
- hbox5 = gtk.HBox()
+ dayvaluechange.set_label(str(daychange))
+ holdingsvalue.set_label(str(holdvalue))
- label11 = gtk.Label('')
- label11.set_markup('<b><big>52 week low:</big></b>')
- self.l52wlow = gtk.Label('')
+ winprogind(win, 0)
- hbox5.pack_start(label11, False, False, 50)
- hbox5.pack_start(self.l52wlow , False, False, 70)
+ def refresh_stock_data(self, widget, portfolio, widgets, symbol):
+ if portfolio:
+ shares = self.get_shares_from_symbol(symbol)
+ else:
+ shares = "0"
- 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.show_data(symbol, widgets, shares)
- 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)
+ def show_graph_view(self, widget, symbol, name):
+ win = hildon.StackableWindow()
+ self.create_menu(win)
+ win.set_title(name)
- self.mainbox.pack_start(self.quotesbox, True, True, 0)
- self.mainbox.show_all()
- self.compbox.hide()
- self.databox.hide()
+ vbox = gtk.VBox()
+ toolbar = self.main_toolbar(False, True, None, '', '', False)
- def show_data(self, kind):
- import thread
- self.dataimg.set_from_file(loading_img)
- self.imagebox.show()
- self.databox.hide()
- thread.start_new_thread(self.get_data, (kind,))
+ self.graphs_title = gtk.Label(name)
+ color = gtk.gdk.color_parse("#03A5FF")
+ self.graphs_title.modify_fg(gtk.STATE_NORMAL, color)
- def get_data(self, kind):
- self.graph_btn.show()
- self.refresh_btn.show()
- self.quotes_btn.hide()
+ parea = hildon.PannableArea()
+ parea.set_property("mov-mode", hildon.MOVEMENT_MODE_BOTH)
- from ystockquote import ystockquote as yt
- try:
- 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>')
+ vbox1 = gtk.VBox()
- try:
- ch_percent = 100.0 * float(data['change'])/(float(data['price'])-float(data['change']))
- except ValueError:
- ch_percent = 0.0
+ hbox = gtk.HBox()
+ hbox.set_homogeneous(True)
- self.lprice.set_label(data['price'])
- self.lchange.set_label(data['change'])
- self.lpercent.set_label('%6.2f %%' % ch_percent)
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('1d')
+ button.connect("clicked", self.show_graph, '1d', win, symbol)
+ hbox.pack_start(button)
- if '-' in data['change']:
- color = gtk.gdk.color_parse("#FF0000")
- else:
- color = gtk.gdk.color_parse("#16EB78")
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('5d')
+ button.connect("clicked", self.show_graph, '5d', win, symbol)
+ hbox.pack_start(button)
- self.lpercent.modify_fg(gtk.STATE_NORMAL, color)
- self.lchange.modify_fg(gtk.STATE_NORMAL, color)
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('3m')
+ button.connect("clicked", self.show_graph, '3m', win, symbol)
+ hbox.pack_start(button)
- self.lvolume.set_label(data['volume'])
- self.l52whigh.set_label(data['52_week_high'])
- self.l52wlow.set_label(data['52_week_low'])
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('6m')
+ button.connect("clicked", self.show_graph, '6m', win, symbol)
+ hbox.pack_start(button)
- self.databox.show_all()
- self.imagebox.hide()
+ vbox1.pack_start(hbox, False, False, 0)
+ hbox = gtk.HBox()
+ hbox.set_homogeneous(True)
- def refresh_stock_data(self, widget):
- self.show_data(self.stocks_id)
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('1y')
+ button.connect("clicked", self.show_graph, '1y', win, symbol)
+ hbox.pack_start(button)
- def create_graphs_view(self, widget):
- self.graph_btn.hide()
- self.refresh_btn.hide()
- self.quotes_btn.show()
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('2y')
+ button.connect("clicked", self.show_graph, '2y', win, symbol)
+ hbox.pack_start(button)
- self.graph = gtk.Image()
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('5y')
+ button.connect("clicked", self.show_graph, '5y', win, symbol)
+ hbox.pack_start(button)
- kind = self.stocks_id
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('Max')
+ button.connect("clicked", self.show_graph, 'max', win, symbol)
+ hbox.pack_start(button)
- self.show_graph(None, '1d', kind)
+ vbox1.pack_start(hbox, False, False, 0)
- for i in range(len(localids)):
- if kind in localids[i]:
- ind1, ind2 = i, localids[i].index(kind)
+ self.graph = gtk.Image()
+ vbox1.pack_start(self.graph, True, True, 0)
- #self.mainbox.destroy()
- #self.mainbox = gtk.VBox()
- #self.swin.add_with_viewport(self.mainbox)
+ parea.add_with_viewport(vbox1)
- actual_view = self.mainbox.get_children()
- for a_widget in actual_view:
- a_widget.destroy()
+ vbox.pack_start(self.graphs_title, False, False, 0)
+ vbox.pack_start(gtk.HSeparator(), False, False, 0)
+ vbox.pack_start(parea, True, True, 0)
+ vbox.pack_start(gtk.HSeparator(), False, False, 5)
+ vbox.pack_start(toolbar, False, False, 0)
- self.graphbox = gtk.VBox()
+ win.add(vbox)
+ win.show_all()
- self.graphs_title = gtk.Label(localmarkets[ind1][ind2])
- color = gtk.gdk.color_parse("#03A5FF")
- self.graphs_title.modify_fg(gtk.STATE_NORMAL, color)
+ self.show_graph(None, '1d', win, symbol)
- 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)
- self.btn5d = gtk.Button('5d')
- self.btn5d.set_property("can_focus", False)
- self.btn5d.connect("clicked", self.show_graph, '5d', kind)
- self.btn3m = gtk.Button('3m')
- self.btn3m.set_property("can_focus", False)
- self.btn3m.connect("clicked", self.show_graph, '3m', kind)
- self.btn6m = gtk.Button('6m')
- self.btn6m.set_property("can_focus", False)
- self.btn6m.connect("clicked", self.show_graph, '6m', kind)
- self.btn1y = gtk.Button('1y')
- self.btn1y.set_property("can_focus", False)
- self.btn1y.connect("clicked", self.show_graph, '1y', kind)
- self.btn2y = gtk.Button('2y')
- self.btn2y.set_property("can_focus", False)
- self.btn2y.connect("clicked", self.show_graph, '2y', kind)
- self.btn5y = gtk.Button('5y')
- self.btn5y.set_property("can_focus", False)
- self.btn5y.connect("clicked", self.show_graph, '5y', kind)
- 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(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()
-
- def show_graph(self, widget, option, kind):
+ def show_graph(self, widget, option, win, symbol):
import thread
- self.graph.set_from_file(loading_img)
- thread.start_new_thread(self.get_graph_data, (option, kind))
+ winprogind(win, 1)
+ thread.start_new_thread(self.get_graph_data, (option, win, symbol))
- def get_graph_data(self, option, kind):
+ def get_graph_data(self, option, win, symbol):
if option == '1d':
- url = 'http://uk.ichart.yahoo.com/b?s=%s' % kind
+ url = 'http://uk.ichart.yahoo.com/b?s=%s' % symbol
elif option == '5d':
- url = 'http://uk.ichart.yahoo.com/w?s=%s' % kind
+ url = 'http://uk.ichart.yahoo.com/w?s=%s' % symbol
elif option == '3m':
- url = 'http://chart.finance.yahoo.com/c/3m/s/%s' % kind.lower()
+ url = 'http://chart.finance.yahoo.com/c/3m/s/%s' % symbol.lower()
elif option == '6m':
- url = 'http://chart.finance.yahoo.com/c/6m/s/%s' % kind.lower()
+ url = 'http://chart.finance.yahoo.com/c/6m/s/%s' % symbol.lower()
elif option == '1y':
- url = 'http://chart.finance.yahoo.com/c/1y/s/%s' % kind.lower()
+ url = 'http://chart.finance.yahoo.com/c/1y/s/%s' % symbol.lower()
elif option == '2y':
- url = 'http://chart.finance.yahoo.com/c/2y/s/%s' % kind.lower()
+ url = 'http://chart.finance.yahoo.com/c/2y/s/%s' % symbol.lower()
elif option == '5y':
- url = 'http://chart.finance.yahoo.com/c/5y/s/%s' % kind.lower()
+ url = 'http://chart.finance.yahoo.com/c/5y/s/%s' % symbol.lower()
elif option == 'max':
- url = 'http://chart.finance.yahoo.com/c/my/s/%s' % kind.lower()
+ url = 'http://chart.finance.yahoo.com/c/my/s/%s' % symbol.lower()
try:
myimg = urllib2.urlopen(url)
- imgdata=myimg.read()
+ imgdata = myimg.read()
pbl = gtk.gdk.PixbufLoader()
pbl.write(imgdata)
pbuf = pbl.get_pixbuf()
+ pbuf = pbuf.scale_simple(475, 235, gtk.gdk.INTERP_TILES)
pbl.close()
self.graph.set_from_pixbuf(pbuf)
+ winprogind(win, 0)
except:
- print 'no internet data'
+ logger.exception("Getting graph data: %s" % url)
+ winprogind(win, 0)
self.graphs_title.set_label('Failed to get data')
self.graph.destroy()
+ def show_metal_graphs(self, widget, path, column, model):
+ metal = model[path][1]
+ metal_urls = self.get_metal_graphs_urls(metal)
+ options = []
+ for i in metal_urls:
+ options.append(i[0])
+
+ win = hildon.StackableWindow()
+ #self.create_menu(win)
+ win.set_title(metal)
+
+ vbox = gtk.VBox()
+ #toolbar = self.main_toolbar(False, True, None, '', '', False)
+
+ self.metalgraph_title = gtk.Label(metal)
+ color = gtk.gdk.color_parse("#03A5FF")
+ self.metalgraph_title.modify_fg(gtk.STATE_NORMAL, color)
+
+ parea = hildon.PannableArea()
+ parea.set_property("mov-mode", hildon.MOVEMENT_MODE_BOTH)
+
+ vbox1 = gtk.VBox()
+
+ hbox = gtk.HBox()
+ hbox.set_homogeneous(True)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('live')
+ button.connect("clicked", self.show_metalgraph, 'live', win, metal_urls)
+ if 'live' in options:
+ hbox.pack_start(button)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('30d')
+ button.connect("clicked", self.show_metalgraph, '30d', win, metal_urls)
+ if '30d' in options:
+ hbox.pack_start(button)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('60d')
+ button.connect("clicked", self.show_metalgraph, '60d', win, metal_urls)
+ if '60d' in options:
+ hbox.pack_start(button)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('6m')
+ button.connect("clicked", self.show_metalgraph, '6m', win, metal_urls)
+ if '6m' in options:
+ hbox.pack_start(button)
+
+ vbox1.pack_start(hbox, False, False, 0)
+ hbox = gtk.HBox()
+ hbox.set_homogeneous(True)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('1y')
+ button.connect("clicked", self.show_metalgraph, '1y', win, metal_urls)
+ if '1y' in options:
+ hbox.pack_start(button)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('5y')
+ button.connect("clicked", self.show_metalgraph, '5y', win, metal_urls)
+ if '5y' in options:
+ hbox.pack_start(button)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label('10y')
+ button.connect("clicked", self.show_metalgraph, '10y', win, metal_urls)
+ if '10y' in options:
+ hbox.pack_start(button)
+
+ vbox1.pack_start(hbox, False, False, 0)
+
+ self.metalgraph = gtk.Image()
+ vbox1.pack_start(self.metalgraph, True, True, 0)
+
+ parea.add_with_viewport(vbox1)
+
+ vbox.pack_start(self.metalgraph_title, False, False, 0)
+ vbox.pack_start(gtk.HSeparator(), False, False, 0)
+ vbox.pack_start(parea, True, True, 0)
+ vbox.pack_start(gtk.HSeparator(), False, False, 5)
+ #vbox.pack_start(toolbar, False, False, 0)
+
+ win.add(vbox)
+ win.show_all()
+
+ self.show_metalgraph(None, options[0], win, metal_urls)
+
+ def show_metalgraph(self, widget, option, win, metal_urls):
+ import thread
+ winprogind(win, 1)
+ thread.start_new_thread(self.get_metalgraph_data, (option, win, metal_urls))
+
+ def get_metalgraph_data(self, option, win, metal_urls):
+ for i in metal_urls:
+ if i[0] == option:
+ print i[1]
+ url = i[1]
+
+ try:
+ myimg = urllib2.urlopen(url)
+ imgdata = myimg.read()
+
+ pbl = gtk.gdk.PixbufLoader()
+ pbl.write(imgdata)
+
+
+ pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, 475, 235)
+ pixbuf.fill(0xffffffff)
+
+
+ pbuf = pbl.get_pixbuf()
+ pbuf = pbuf.scale_simple(475, 235, gtk.gdk.INTERP_TILES)
+
+ pixbuf.composite(pbuf, 0, 0, pixbuf.props.width, pixbuf.props.height, 0, 0, 1.0, 1.0, gtk.gdk.INTERP_HYPER, 55)
+
+
+ pbl.close()
+ self.metalgraph.set_from_pixbuf(pbuf)
+ winprogind(win, 0)
+ except:
+ logger.exception("Getting graph data: %s" % url)
+ winprogind(win, 0)
+ self.metalgraph_title.set_label('Failed to get data')
+ self.metalgraph.destroy()
+
+ def get_metal_graphs_urls(self, metal):
+ metal_urls = []
+ liveurl = 'http://www.kitco.com/images/live/%s'
+ graphurl = 'http://www.kitco.com/LFgif/%s'
+ t24url = 'http://www.kitconet.com/charts/metals/base/%s'
+ if metal == 'Gold':
+ metal_urls.append(['live', liveurl % 'gold.gif'])
+ metal_urls.append(['30d', graphurl % 'au0030lnb.gif'])
+ metal_urls.append(['60d', graphurl % 'au0060lnb.gif'])
+ metal_urls.append(['6m', graphurl % 'au0182nyb.gif'])
+ metal_urls.append(['1y', graphurl % 'au0365nyb.gif'])
+ metal_urls.append(['5y', graphurl % 'au1825nyb.gif'])
+ metal_urls.append(['10y', graphurl % 'au3650nyb.gif'])
+ elif metal == 'Silver':
+ metal_urls.append(['live', liveurl % 'silver.gif'])
+ metal_urls.append(['30d', graphurl % 'ag0030lnb.gif'])
+ metal_urls.append(['60d', graphurl % 'ag0060lnb.gif'])
+ metal_urls.append(['6m', graphurl % 'ag0182nyb.gif'])
+ metal_urls.append(['1y', graphurl % 'ag0365nyb.gif'])
+ metal_urls.append(['5y', graphurl % 'ag1825nyb.gif'])
+ metal_urls.append(['10y', graphurl % 'ag3650nyb.gif'])
+ elif metal == 'Platinum':
+ metal_urls.append(['live', liveurl % 'plati.gif'])
+ metal_urls.append(['30d', graphurl % 'pt0030lnb.gif'])
+ metal_urls.append(['60d', graphurl % 'pt0060lnb.gif'])
+ metal_urls.append(['6m', graphurl % 'pt0182nyb.gif'])
+ metal_urls.append(['1y', graphurl % 'pt0365nyb.gif'])
+ metal_urls.append(['5y', graphurl % 'pt1825nyb.gif'])
+ elif metal == 'Palladium':
+ metal_urls.append(['live', liveurl % 'plad.gif'])
+ metal_urls.append(['30d', graphurl % 'pd0030lnb.gif'])
+ metal_urls.append(['60d', graphurl % 'pd0060lnb.gif'])
+ metal_urls.append(['6m', graphurl % 'pd0182nyb.gif'])
+ metal_urls.append(['1y', graphurl % 'pd0365nyb.gif'])
+ metal_urls.append(['5y', graphurl % 'pd1825nyb.gif'])
+ elif metal == 'Rhodium':
+ metal_urls.append(['30d', graphurl % 'rh0030lnb.gif'])
+ metal_urls.append(['60d', graphurl % 'rh0060lnb.gif'])
+ metal_urls.append(['6m', graphurl % 'rh0182lnb.gif'])
+ metal_urls.append(['1y', graphurl % 'rh0365lnb.gif'])
+ metal_urls.append(['5y', graphurl % 'rh1825lnb.gif'])
+ elif metal == 'Copper':
+ metal_urls.append(['live', t24url % 't24_cp450x275.gif'])
+ elif metal == 'Nickel':
+ metal_urls.append(['live', t24url % 't24_nk450x275.gif'])
+ elif metal == 'Aluminium':
+ metal_urls.append(['live', t24url % 't24_al450x275.gif'])
+ elif metal == 'Zinc':
+ metal_urls.append(['live', t24url % 't24_zc450x275.gif'])
+ elif metal == 'Lead':
+ metal_urls.append(['live', t24url % 't24_ld450x275.gif'])
+
+ return metal_urls
+
+ def _tv_columns(self, treeview):
+ column = gtk.TreeViewColumn('ID', gtk.CellRendererText(), text=0)
+ column.set_visible(False)
+ treeview.append_column(column)
+
+ column = gtk.TreeViewColumn('Name', gtk.CellRendererText(), text=1)
+ treeview.append_column(column)
+
+ def __create_model(self, names, ids):
+ lstore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+ for item in range(len(names)):
+ iter = lstore.append()
+ lstore.set(iter, 0, ids[item], 1, names[item])
+ return lstore
+
+ def main_toolbar(self, quotesview, portfolio, widgets, symbol, name, initial):
+ toolbar = gtk.HBox()
+ #toolbar.set_homogeneous(True)
+
+ portfolio_btn = hildon.Button(fhsize, horbtn)
+ portfolio_btn.set_title("Portfolio")
+ portfolio_btn.connect("clicked", self.show_portfolio_view)
+
+ graph_btn = hildon.Button(fhsize, horbtn)
+ graph_btn.set_title("Graph")
+ graph_btn.connect("clicked", self.show_graph_view, symbol, name)
+
+ refresh_btn = hildon.Button(fhsize, horbtn)
+ refresh_btn.set_title("Refresh")
+ refresh_btn.connect("clicked", self.refresh_stock_data, portfolio,
+ widgets, symbol)
+
+
+ info_btn = hildon.Button(fhsize, horbtn)
+ img = gtk.image_new_from_icon_name("general_information", gtk.ICON_SIZE_SMALL_TOOLBAR)
+ info_btn.set_image(img)
+ info_btn.connect("clicked", self.show_app_information)
+
+ search_btn = hildon.Button(fhsize, horbtn)
+ img = gtk.image_new_from_icon_name("general_search", gtk.ICON_SIZE_SMALL_TOOLBAR)
+ search_btn.set_image(img)
+ search_btn.connect("clicked", self.show_search_dialog)
+
+ if not portfolio:
+ toolbar.pack_start(portfolio_btn)
+ if not quotesview:
+ toolbar.pack_start(info_btn, False, False, 0)
+ if quotesview:
+ toolbar.pack_start(graph_btn)
+ toolbar.pack_start(refresh_btn)
+
+ if initial:
+ toolbar.pack_start(search_btn, False, False, 0)
+
+ toolbar.show_all()
+
+ return toolbar
+
+ def show_search_dialog(self, widget):
+ dlg = gtk.Dialog(title='Search company', parent=None, flags=0)
+ dlg.set_has_separator(False)
+
+ hbox = gtk.HBox()
+
+ entry = hildon.Entry(fhsize)
+ entry.connect("activate", self.do_search, entry, dlg)
+ hbox.pack_start(entry, True, True, 0)
+
+ button = hildon.Button(fhsize, horbtn)
+ img = gtk.image_new_from_icon_name("general_search", gtk.ICON_SIZE_SMALL_TOOLBAR)
+ button.set_image(img)
+ button.connect("clicked", self.do_search, entry, dlg)
+ hbox.pack_start(button, False, False, 0)
+
+ dlg.vbox.pack_start(hbox, False, False, 0)
+
+ dlg.show_all()
+ dlg.run()
+ dlg.destroy()
+
- #Functions for fullscreen
- def on_window_state_change(self, widget, event, *args):
- if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
- self.window_in_fullscreen = True
+ def do_search(self, widget, entry, dlg):
+ import thread
+ text = entry.get_text()
+ dlg.destroy()
+
+ winprogind(self.window, 1)
+ thread.start_new_thread(self._really_do_search, (text,))
+
+ def _really_do_search(self, text):
+
+ if allnames == []:
+ for market in marketdata.eunames:
+ for company in market:
+ allnames.append(company)
+
+ for market in marketdata.omnames:
+ for company in market:
+ allnames.append(company)
+
+ for market in marketdata.usnames:
+ for company in market:
+ allnames.append(company)
+
+ if allsymbols == []:
+ for market in marketdata.eusymbols:
+ for company in market:
+ allsymbols.append(company)
+
+ for market in marketdata.omsymbols:
+ for company in market:
+ allsymbols.append(company)
+
+ for market in marketdata.ussymbols:
+ for company in market:
+ allsymbols.append(company)
+
+ new_model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+ for i in range(len(allnames)):
+ if text.lower() in allnames[i].lower():
+ niter = new_model.append()
+ #print allsymbols[i], allnames[i]
+ #FIXME: repeated companies in the results list
+ #print if allnames[i]
+ #for j in new_model:
+ # if j[1] == allnames[i]:
+ new_model.set(niter, 0, allsymbols[i], 1, allnames[i])
+
+ if len(new_model) == 0:
+ winprogind(self.window, 0)
+ gtk.gdk.threads_enter()
+ self.show_info_banner(self.window, "No items found for this search")
+ gtk.gdk.threads_leave()
+ return
+
+ gtk.gdk.threads_enter()
+ self.show_search_screen(new_model, text)
+ gtk.gdk.threads_leave()
+ winprogind(self.window, 0)
+
+
+ def show_search_screen(self, model, text):
+ window = hildon.StackableWindow()
+ self.create_menu(window)
+ window.set_title("Search for " + text)
+
+ vbox = gtk.VBox()
+ toolbar = self.main_toolbar(False, False, None, '', '', False)
+
+ parea = hildon.PannableArea()
+ parea.connect("horizontal-movement", self.horizontal_mov)
+ tv = hildon.GtkTreeView(ui_normal)
+ tv.connect("row-activated", self.show_quotes_view, model, False)
+ tv.set_model(model)
+ self._tv_columns(tv)
+ parea.add(tv)
+
+ vbox.pack_start(parea, True, True, 0)
+ vbox.pack_start(gtk.HSeparator(), False, False, 5)
+ vbox.pack_start(toolbar, False, False, 0)
+
+ window.add(vbox)
+ window.show_all()
+
+ def show_app_information(self, widget):
+ self.show_information_note(self.window, (
+ "The data is got from Yahoo! Finance.\n"
+ "It could be delayed or even wrong.\n"
+ "The author doesn't validate in any way this data and therefore he is not responsible for any damage that may occur.\n\n"
+ "You can scroll large list with gestures:\n"
+ "Left-to-right gesture: scroll down.\n"
+ "Right-to-left gesture: scroll up."))
+
+ def show_portfolio_view(self, widget):
+ data = settings.load_portfolio(settingsdb)
+ for item in data:
+ item.append('-')
+ item.append('-')
+
+ win = hildon.StackableWindow()
+ self.create_menu(win)
+ win.set_title("Portfolio")
+
+ vbox = gtk.VBox()
+
+ parea = hildon.PannableArea()
+ parea.set_property("mov-mode", hildon.MOVEMENT_MODE_BOTH)
+ tv = hildon.GtkTreeView(ui_normal)
+ tv.set_headers_visible(True)
+ self.portfolio_model = self._create_portfolio_model(data)
+ self.quotes_id = tv.connect("row-activated", self.show_quotes_view,
+ self.portfolio_model, True)
+ tv.set_model(self.portfolio_model)
+ self._tv_portfolio_columns(tv)
+ parea.add(tv)
+
+ hbox = gtk.HBox()
+ button = hildon.Button(fhsize, horbtn)
+ button.set_title("Refresh All")
+ button.connect("clicked", self.refresh_portfolio, tv, win)
+ hbox.pack_start(button, True, True, 0)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_title("Add manually")
+ button.connect("clicked", self.add_item_dlg, None, None)
+ hbox.pack_start(button, True, True, 0)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_title("Remove")
+ button.connect("clicked", self.remove_item)
+ hbox.pack_start(button, True, True, 0)
+
+ button = hildon.CheckButton(fhsize)
+ button.set_label("Edit")
+
+ button.connect("toggled", self.edit_toggled, tv)
+ hbox.pack_start(button, True, True, 0)
+
+
+ vbox.pack_start(parea, True, True, 0)
+ vbox.pack_start(hbox, False, False, 0)
+ win.add(vbox)
+ win.show_all()
+
+ def edit_toggled(self, widget, tv):
+ if widget.get_active():
+ tv.disconnect(self.quotes_id)
+ self.edit_id = tv.connect("row-activated",
+ self.edit_portfolio_item, self.portfolio_model)
+ else:
+ tv.disconnect(self.edit_id)
+ self.quotes_id = tv.connect("row-activated",
+ self.show_quotes_view, self.portfolio_model, True)
+
+ def edit_portfolio_item(self, widget, path, column, model):
+ seliter = model.get_iter(path)
+
+ symbol = model[path][0]
+ name = model[path][1]
+ shares = model[path][2]
+
+ data = [shares, symbol, name]
+ self.add_item_dlg(widget, data, seliter)
+
+ def add_item_dlg(self, widget, data, seliter):
+ if data:
+ shares = data[0]
+ symbol = data[1]
+ name = data[2]
+ title = "Edit item from portfolio"
+ btntext = "Edit"
+ edit = True
else:
- self.window_in_fullscreen = False
+ shares = "0"
+ symbol = ""
+ name = ""
+ title = "Add to portfolio"
+ btntext = "Add"
+ edit = False
+
+ dlg = gtk.Dialog(title=title, parent=None, flags=0)
+ dlg.set_has_separator(False)
+
+ button1 = hildon.PickerButton(fhsize, horbtn)
+ data = ["50", "100", "200", "300", "400", "500", "600", "700", "800",
+ "900", "1000"]
+ selector = self.create_selector(data, True)
+ button1.set_selector(selector)
+ button1.set_title("Your shares")
+ button1.set_value(shares)
+ dlg.vbox.pack_start(button1, False, False, 0)
+
+ entry1 = hildon.Entry(fhsize)
+ entry1.set_text(name)
+ entry2 = hildon.Entry(fhsize)
+ entry2.set_text(symbol)
+
+ entry1.set_placeholder("Name")
+ entry1.connect("activate", self.add_item, dlg, button1, entry1,
+ entry2, edit, seliter)
+ dlg.vbox.pack_start(entry1, False, False, 0)
+
+ entry2.connect("activate", self.add_item, dlg, button1, entry1,
+ entry2, edit, seliter)
+ entry2.set_placeholder("Yahoo Finance symbol")
+ dlg.vbox.pack_start(entry2, False, False, 0)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_label(btntext)
+ button.connect("clicked", self.add_item, dlg, button1, entry1,
+ entry2, edit, seliter)
+ dlg.vbox.pack_start(button, False, False, 0)
+
+ dlg.show_all()
+ dlg.run()
+ dlg.destroy()
+
+ def add_item(self, widget, dlg, button, entry1, entry2, edit, seliter):
+ symbol = entry2.get_text()
+ name = entry1.get_text()
+ shares = button.get_value()
+
+ if name == '' or symbol == '':
+ self.show_info_banner(widget, "Must add the name and symbol")
+ return
+
+ self.add_to_portfolio(widget, button, symbol, name)
+ dlg.destroy()
+
+ if edit:
+ self.portfolio_model.set(seliter, 0, symbol, 1, name, 2, shares,
+ 3, "-", 4, "-", 5, "-", 6, "green")
+ else:
+ niter = self.portfolio_model.append()
+ self.portfolio_model.set(niter, 0, symbol, 1, name, 2, shares,
+ 3, "-", 4, "-", 5, "-", 6, "green")
+
+ def remove_item(self, widget):
+ win = hildon.StackableWindow()
+ win.fullscreen()
+ toolbar = hildon.EditToolbar("Choose items to delete", "Delete")
+ win.set_edit_toolbar(toolbar)
- #F6 fullscreen, F7 bigger font, F8 smaller font
- def on_key_press(self, widget, event, *args):
- if event.keyval == gtk.keysyms.F6:
- if self.window_in_fullscreen:
- self.window.unfullscreen ()
+ vbox = gtk.VBox()
+ parea = hildon.PannableArea()
+ tv = hildon.GtkTreeView(ui_edit)
+ selection = tv.get_selection()
+ selection.set_mode(gtk.SELECTION_MULTIPLE)
+ tv.set_model(self.portfolio_model)
+ self._tv_remove_portfolio_columns(tv)
+ parea.add(tv)
+
+ toolbar.connect("button-clicked", self.delete_from_portfolio, win, tv,
+ selection)
+ toolbar.connect_object("arrow-clicked", gtk.Window.destroy, win)
+
+ vbox.pack_start(parea, True, True, 0)
+ win.add(vbox)
+ win.show_all()
+
+ def delete_from_portfolio(self, widget, win, tv, selection):
+ if not self.is_treeview_selected(tv):
+ return
+
+ conf = self.show_confirmation(win, "Delete items?")
+
+ if conf:
+ try:
+ selmodel, selected = selection.get_selected_rows()
+ iters = [selmodel.get_iter(path) for path in selected]
+ for i in iters:
+ symbol = selmodel.get_value(i, 0)
+ settings.delete_item_from_portfolio(settingsdb, symbol)
+ selmodel.remove(i)
+ except:
+ logger.exception("Deleting item from portfolio")
+ self.info_banner(widget, "Error deleting item")
+
+ def _tv_remove_portfolio_columns(self, treeview):
+ column = gtk.TreeViewColumn('ID', gtk.CellRendererText(), text=0)
+ column.set_visible(False)
+ treeview.append_column(column)
+
+ column = gtk.TreeViewColumn('Name', gtk.CellRendererText(), text=1)
+ column.set_property("expand", True)
+ treeview.append_column(column)
+
+ column = gtk.TreeViewColumn('Shares', gtk.CellRendererText(), text=2)
+ column.set_visible(False)
+ treeview.append_column(column)
+
+ column = gtk.TreeViewColumn('Price', gtk.CellRendererText(), text=3)
+ column.set_visible(False)
+ treeview.append_column(column)
+
+ def refresh_portfolio(self, widget, tv, win):
+ data = settings.load_portfolio(settingsdb)
+ for item in data:
+ item.append('-')
+ item.append('-')
+ import thread
+ winprogind(win, 1)
+ thread.start_new_thread(self._do_refresh_portfolio, (data, tv, win))
+
+ def _do_refresh_portfolio(self, data, tv, win):
+ print data
+ for item in data:
+ item[3], item[4] = self.get_portfolio_data(item[0])
+ try:
+ ch_percent = \
+ 100.0 * float(item[4])/(float(item[3]) - \
+ float(item[4]))
+ except ValueError:
+ ch_percent = 0.0
+
+ item[5] = '%6.2f %%' % ch_percent
+
+
+ print data
+ self.portfolio_model = self._create_portfolio_model(data)
+ tv.set_model(self.portfolio_model)
+ winprogind(win, 0)
+
+ def get_portfolio_data(self, symbol):
+ from ystockquote import ystockquote as yt
+ try:
+ data = yt.get_all(symbol)
+ return data['price'], data['change']
+ except:
+ logger.exception("Getting price from Yahoo: %s" % symbol)
+ return "-", "-"
+
+ def _create_portfolio_model(self, data):
+ lstore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
+ gobject.TYPE_STRING, gobject.TYPE_STRING,
+ gobject.TYPE_STRING, gobject.TYPE_STRING,
+ gobject.TYPE_STRING)
+ for item in data:
+ iter = lstore.append()
+ if '+' in item[4]:
+ color = 'green'
else:
- self.window.fullscreen ()
-
- def on_about(self, widget):
- dialog = gtk.AboutDialog()
- dialog.set_name("StockThis")
- 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>"])
- logo = gtk.gdk.pixbuf_new_from_file(imgdir + "stockthis.png")
- dialog.set_logo(logo)
- dialog.set_license("This program is released under the GNU\nGeneral Public License. Please visit \nhttp://www.gnu.org/copyleft/gpl.html\nfor details.")
- dialog.set_artists(["Logo by Daniel Martin Yerga"])
+ color = 'red'
+ lstore.set(iter, 0, item[0], 1, item[1], 2, item[2], 3, item[3],
+ 4, item[4], 5, item[5], 6, color)
+ return lstore
+
+ def _tv_portfolio_columns(self, treeview):
+ column = gtk.TreeViewColumn('ID', gtk.CellRendererText(), text=0)
+ column.set_visible(False)
+ treeview.append_column(column)
+
+ column = gtk.TreeViewColumn('Name', gtk.CellRendererText(), text=1)
+ column.set_property("expand", True)
+ treeview.append_column(column)
+
+ column = gtk.TreeViewColumn('Shares', gtk.CellRendererText(), text=2)
+ treeview.append_column(column)
+
+ column = gtk.TreeViewColumn('Price', gtk.CellRendererText(), text=3)
+ treeview.append_column(column)
+
+ column = gtk.TreeViewColumn('Change', gtk.CellRendererText(), text=4)
+ treeview.append_column(column)
+
+
+ renderer = gtk.CellRendererText()
+ renderer.set_property("foreground-set", True)
+ column = gtk.TreeViewColumn('%', renderer, text=5, foreground=6)
+ treeview.append_column(column)
+
+ def show_confirmation(self, window, msg):
+ dialog = hildon.hildon_note_new_confirmation(window, msg)
+ dialog.show_all()
+ result = dialog.run()
+ if result == gtk.RESPONSE_OK:
+ dialog.destroy()
+ return True
+
+ dialog.destroy()
+ return False
+
+ def show_information_note(self, window, msg):
+ dialog = hildon.hildon_note_new_information(window, msg)
+ dialog.show_all()
+ result = dialog.run()
+ dialog.destroy()
+
+ def show_info_banner(self, widget, msg):
+ hildon.hildon_banner_show_information(widget, 'qgn_note_infoprint', msg)
+
+ def is_treeview_selected(self, treeview):
+ selection = treeview.get_selection()
+ if selection.count_selected_rows() == 0:
+ self.show_info_banner(treeview, 'No selected item')
+ return False
+ else:
+ return True
+
+class About:
+
+ def __init__(self, widget):
+ self.abdialog = gtk.Dialog()
+ self.abdialog.set_title("About StockThis")
+
+ notebook = gtk.Notebook()
+ notebook.set_show_tabs(False)
+ notebook.set_scrollable(False)
+ notebook.set_show_border(False)
+
+ # Description page #
+ vbox = gtk.VBox()
+
+ label = gtk.Label()
+ label.set_markup("<b><big>StockThis %s</big></b>" % VERSION)
+ vbox.pack_start(label, True, True, 0)
+
+ label = gtk.Label("Stocks application with big database")
+ vbox.pack_start(label, True, True, 0)
+
+ label = gtk.Label("GNU General Public License")
+ vbox.pack_start(label, True, True, 0)
+
+ url = "http://stockthis.garage.maemo.org"
+ webbtn = gtk.LinkButton(url, "Web")
+ vbox.pack_start(webbtn, True, True, 0)
+ gtk.link_button_set_uri_hook(self.launch_browser)
+
+ notebook.append_page(vbox, gtk.Label())
+
+ # Credits page #
+ vbox = gtk.VBox()
+ textview = hildon.TextView()
+ textview.set_cursor_visible(False)
+ textview.set_wrap_mode(gtk.WRAP_WORD)
+ text = "Written by Daniel Martin Yerga (dyerga@gmail.com)"
+ textview.get_buffer().set_text(text)
+
+ parea = hildon.PannableArea()
+ parea.add(textview)
+
+ vbox.pack_start(parea, True, True, 0)
+ notebook.append_page(vbox, gtk.Label())
+
+
+ # Donate page #
+ vbox = gtk.VBox()
+
+ textview = hildon.TextView()
+ textview.set_cursor_visible(False)
+ textview.set_wrap_mode(gtk.WRAP_WORD)
+ text = """StockThis is a free software application.
+Developing good software takes time and hard work.
+StockThis's author develops the program in his spare time.
+If you like the program and it's helpful, consider donating a small amount of money.
+Donations are a great incentive and help the developer feel that the hard work is appreciated.
+"""
+ textview.get_buffer().set_text(text)
+
+ parea = hildon.PannableArea()
+ parea.add(textview)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_title("Make donation")
+ url = "http://stockthis.garage.maemo.org/donate.html"
+ button.connect("clicked", self.launch_browser, url)
+ vbox.pack_start(button, False, False, 0)
+ vbox.pack_start(parea, True, True, 0)
+
+ notebook.append_page(vbox, gtk.Label())
+
+ # Report page #
+ vbox = gtk.VBox()
+
+ textview = hildon.TextView()
+ textview.set_cursor_visible(False)
+ textview.set_wrap_mode(gtk.WRAP_WORD)
+ text = """StockThis is being improved thanks to bug reports that users have submitted. The author appreciates these reports.
+If the application is having an error when you're using it, you have two choices to report this error:
+1) Send the log from the button above (if there's an error in the log).
+2) Press the button and read how to report a bug."""
+ textview.get_buffer().set_text(text)
+
+ parea = hildon.PannableArea()
+ parea.add(textview)
+
+ hbox = gtk.HBox()
+ hbox.set_homogeneous(True)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_title("Report error")
+ url = "http://stockthis.garage.maemo.org/reporting.html"
+ button.connect("clicked", self.launch_browser, url)
+ hbox.pack_start(button, True, True, 0)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_title("Log")
+ button.connect("clicked", self.on_show_log)
+ hbox.pack_start(button, True, True, 0)
+
+ vbox.pack_start(hbox, False, False, 0)
+ vbox.pack_start(parea, True, True, 0)
+
+ notebook.append_page(vbox, gtk.Label())
+
+ # Rate page #
+ vbox = gtk.VBox()
+
+ textview = hildon.TextView()
+ textview.set_cursor_visible(False)
+ textview.set_wrap_mode(gtk.WRAP_WORD)
+ text = """The downloads section in maemo.org has a nice system where you can rate applications.
+If you consider StockThis a good application (or a bad one too), you could rate it in maemo.org site."""
+ textview.get_buffer().set_text(text)
+
+ button = hildon.Button(fhsize, horbtn)
+ button.set_title("Rate StockThis")
+ url = "http://maemo.org/downloads/product/Maemo5/stockthis"
+ button.connect("clicked", self.launch_browser, url)
+ image = gtk.Image()
+ image.set_from_file(imgdir + "maemoorg.png")
+ vbox.pack_start(button, False, False, 0)
+ vbox.pack_start(image, False, False, 5)
+ vbox.pack_start(textview, True, True, 0)
+
+ notebook.append_page(vbox, gtk.Label())
+
+ # Buttons #
+ self.abdialog.vbox.pack_start(notebook, True, True, 0)
+
+ hbox = gtk.HBox()
+
+ descbutton = hildon.GtkRadioButton(fhsize)
+ descbutton.set_mode(False)
+ descbutton.set_active(True)
+ descbutton.set_label('Description')
+ descbutton.connect("toggled", self.change_tab, notebook, 0)
+ hbox.pack_start(descbutton, True, True, 0)
+
+ button = hildon.GtkRadioButton(fhsize)
+ button.set_mode(False)
+ button.set_active(True)
+ button.set_label('Credits')
+ button.set_group(descbutton)
+ button.connect("toggled", self.change_tab, notebook, 1)
+ hbox.pack_start(button, True, True, 0)
+
+ button = hildon.GtkRadioButton(fhsize)
+ button.set_mode(False)
+ button.set_label('Donate')
+ button.set_group(descbutton)
+ button.connect("clicked", self.change_tab, notebook, 2)
+ hbox.pack_start(button, True, True, 0)
+
+ button = hildon.GtkRadioButton(fhsize)
+ button.set_mode(False)
+ button.set_label('Report')
+ button.set_group(descbutton)
+ button.connect("clicked", self.change_tab, notebook, 3)
+ hbox.pack_start(button, True, True, 0)
+
+ button = hildon.GtkRadioButton(fhsize)
+ button.set_mode(False)
+ button.set_label('Rate')
+ button.set_group(descbutton)
+ button.connect("clicked", self.change_tab, notebook, 4)
+ hbox.pack_start(button, True, True, 0)
+
+ self.abdialog.vbox.pack_start(hbox, False, False, 0)
+
+ self.abdialog.show_all()
+ self.abdialog.run()
+ self.abdialog.destroy()
+
+ def change_tab(self, widget, notebook, number):
+ notebook.set_current_page(number)
+
+ def launch_browser(self, widget, url):
+ import dbus
+ bus = dbus.SystemBus()
+ proxy = bus.get_object("com.nokia.osso_browser", "/com/nokia/osso_browser/request")
+ iface = dbus.Interface(proxy, 'com.nokia.osso_browser')
+
+ self.abdialog.destroy()
+
+ iface.open_new_window(url)
+
+ def on_show_log(self, widget):
+ Log(widget, logfile)
+
+
+class Log:
+
+ def __init__(self, widget, logfile):
+ #Log dialog UI
+ dialog = gtk.Dialog(title='Log', parent=None)
+
+ dialog.set_size_request(600, 350)
+
+ parea = hildon.PannableArea()
+ parea.set_property("mov-mode", hildon.MOVEMENT_MODE_BOTH)
+
+ textview = hildon.TextView()
+ textview.set_property("editable", False)
+ textview.set_property("wrap-mode", gtk.WRAP_WORD)
+
+ log = open(logfile, 'r')
+ logtext = log.read()
+ log.close()
+
+ textview.get_buffer().set_text(logtext)
+ parea.add(textview)
+
+ dialog.vbox.pack_start(parea, True, True, 0)
+
+ hbox = gtk.HBox()
+
+ save_btn = hildon.Button(fhsize, horbtn)
+ save_btn.set_title("Save")
+ save_btn.connect('clicked', self.save, logfile, dialog)
+
+ clear_btn = hildon.Button(fhsize, horbtn)
+ clear_btn.set_title("Clear")
+ clear_btn.connect('clicked', self.clear, textview, logfile)
+
+ send_btn = hildon.Button(fhsize, horbtn)
+ send_btn.set_title('Send')
+ send_btn.connect('clicked', self.send, dialog, logfile)
+
+ hbox.pack_start(save_btn, True, True, 0)
+ hbox.pack_start(clear_btn, True, True, 0)
+ hbox.pack_start(send_btn, True, True, 0)
+
+ dialog.vbox.pack_start(hbox, False, False, 0)
+
+ dialog.show_all()
dialog.run()
dialog.destroy()
+ def show_filechooser(self, window, title, name, EXT):
+ action = gtk.FILE_CHOOSER_ACTION_SAVE
+
+ m = hildon.FileSystemModel()
+ file_dialog = hildon.FileChooserDialog(window, action, m)
+ file_dialog.set_title(title)
+
+ file_dialog.set_current_name(name)
+ HOME = os.path.expanduser("~")
+
+ if os.path.exists(HOME + '/MyDocs/.documents'):
+ file_dialog.set_current_folder(HOME + '/MyDocs/.documents')
+ else:
+ file_dialog.set_current_folder(HOME)
+
+ file_dialog.set_default_response(gtk.RESPONSE_CANCEL)
+
+ result = file_dialog.run()
+ if result == gtk.RESPONSE_OK:
+ namefile = file_dialog.get_filename()
+ namefile, extension = os.path.splitext(namefile)
+ namefile = namefile + "." + EXT
+ else:
+ namefile = None
+ file_dialog.destroy()
+
+ return namefile
+
+
+ def clear(self, widget, textview, logfile):
+ textview.get_buffer().set_text('')
+ f = open(logfile, 'w')
+ f.close()
+
+ def save(self, widget, logfile, dlg):
+ import shutil
+ filename = self.show_filechooser(dlg, "Save log file",
+ "stockthis-log", "txt")
+
+ if not filename:
+ return
+
+ try:
+ shutil.copyfile(logfile, filename)
+ stockspy.show_info_banner(widget, 'Log file saved')
+ except:
+ logger.exception("Saving log file")
+ stockspy.show_info_banner(widget, 'Error saving the log file')
+
+ def send(self, widget, dlg, logfile):
+ sendtxt = ("You are going to send the log to the developers.\n"
+ "This helps the developers to track problems with the application.\n"
+ "It doesn't send any personal information (like passwords or similar).")
+
+ dialog = hildon.hildon_note_new_confirmation(dlg, sendtxt)
+ dialog.set_button_texts("Send", "Cancel")
+ dialog.show_all()
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK:
+ self.do_pre_send(dlg, logfile)
+
+ dialog.destroy()
+
+ def do_pre_send(self, dlg, logfile):
+ import thread
+ hildon.hildon_gtk_window_set_progress_indicator(dlg, 1)
+ thread.start_new_thread(self._do_send, (dlg, logfile))
+
+ def _do_send(self, dlg, logfile):
+ import pycurl, shutil, random, commands
+ try:
+ rname = ''
+ for i in random.sample('abcdefghijkl123456789', 18):
+ rname += i
+
+ rnamepath = HOME + "/.stockthis/" + rname
+ shutil.copyfile(logfile, rnamepath)
+
+ gtkversion = "%s.%s.%s" % gtk.ver
+ if os.path.exists("/etc/maemo_version"):
+ mfile = open("/etc/maemo_version", 'r')
+ maemoversion = mfile.read()
+ mfile.close()
+ else:
+ maemoversion = ''
+
+ opsystem = ' '.join(os.uname())
+ pyversion = os.sys.version
+ pid = os.getpid()
+ comm = ("awk '/Private_Dirty/{sum+=$2}END{print sum \"kB\"}'"
+ " /proc/%s/smaps") % pid
+ status, dirtymem = commands.getstatusoutput(comm)
+
+ lfile = open(rnamepath, 'r')
+ log = lfile.read()
+ lfile.close()
+
+
+ log = ("%s\nPython version: %s\nGtk version: %s\n"
+ "Maemo version: %sOperating system: %s\n"
+ "Dirty Memory: %s\nLog:\n%s") % (_version, pyversion, gtkversion,
+ maemoversion, opsystem, dirtymem, log)
+
+ lfile = open(rnamepath, 'w')
+ lfile.write(log)
+ lfile.close()
+
+ url = "http://yerga.net/logs/uploader.php"
+ data = [('uploadedfile', (pycurl.FORM_FILE, rnamepath)),]
+ mycurl = pycurl.Curl()
+ mycurl.setopt(pycurl.URL, url)
+ mycurl.setopt(pycurl.HTTPPOST, data)
+
+ mycurl.perform()
+ mycurl.close()
+ os.remove(rnamepath)
+
+ gtk.gdk.threads_enter()
+ stockspy.show_info_banner(dlg, 'Log sent')
+ gtk.gdk.threads_leave()
+ hildon.hildon_gtk_window_set_progress_indicator(dlg, 0)
+ except:
+ logger.exception("Sending log file")
+ gtk.gdk.threads_enter()
+ stockspy.show_info_banner(dlg, 'Error sending the log file')
+ gtk.gdk.threads_leave()
+ hildon.hildon_gtk_window_set_progress_indicator(dlg, 0)
+
+
if __name__ == "__main__":
stockspy = StocksPy()
gtk.gdk.threads_enter()