def parse_yahoo_csv(self, csvreader): result = {} for fields in csvreader: if len(fields) == 0: continue if len(fields) != len(QUOTES_CSV_FIELDS): invest.debug("CSV line has unexpected number of fields, expected %d, has %d: %s" % (len(QUOTES_CSV_FIELDS), len(fields), fields)) continue result[fields[0]] = {} for i, field in enumerate(QUOTES_CSV_FIELDS): if type(field) == tuple: try: result[fields[0]][field[0]] = field[1](fields[i]) except: result[fields[0]][field[0]] = 0 else: result[fields[0]][field] = fields[i] # calculated fields try: result[fields[0]]['variation_pct'] = result[fields[0]]['variation'] / float(result[fields[0]]['trade'] - result[fields[0]]['variation']) * 100 except ZeroDivisionError: result[fields[0]]['variation_pct'] = 0 return result
def __init__(self, applet): invest.debug("init applet"); self.applet = applet # name, stock_id, label, accellerator, tooltip, callback menu_actions = [("About", Gtk.STOCK_HELP, _("About"), None, None, self.on_about), ("Help", Gtk.STOCK_HELP, _("Help"), None, None, self.on_help), ("Prefs", Gtk.STOCK_PREFERENCES, _("Preferences"), None, None, self.on_preferences), ("Refresh", Gtk.STOCK_REFRESH, _("Refresh"), None, None, self.on_refresh) ] actiongroup = Gtk.ActionGroup.new("InvestAppletActions") actiongroup.set_translation_domain(invest.defs.GETTEXT_PACKAGE) actiongroup.add_actions(menu_actions, None) self.applet.setup_menu_from_file (join(invest.defs.PKGDATADIR, "ui/invest-applet-menu.xml"), actiongroup); evbox = Gtk.HBox() self.applet_icon = Gtk.Image() self.set_applet_icon(0) self.applet_icon.show() evbox.add(self.applet_icon) self.applet.add(evbox) self.applet.connect("button-press-event", self.button_clicked) self.applet.show_all() self.new_ilw()
def show_run_hide(self, explanation = ""): expl = self.ui.get_object("explanation") expl.set_markup(explanation) self.dialog.show_all() if explanation == "": expl.hide() self.dialog.run() self.dialog.destroy() invest.STOCKS = {} def save_symbol(model, path, iter): #if int(model[iter][1]) == 0 or float(model[iter][2]) < 0.0001: # return if not model[iter][0] in invest.STOCKS: 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: cPickle.dump(invest.STOCKS, file(invest.STOCKS_FILE, 'w')) invest.debug('Stocks written to file') except Exception, msg: invest.error('Could not save stocks file: %s' % msg)
def __init__(self): self.state = STATE_UNKNOWN self.statechange_callback = None try: # get an event loop loop = DBusGMainLoop() # get the NetworkManager object from D-Bus invest.debug("Connecting to Network Manager via D-Bus") bus = dbus.SystemBus(mainloop=loop) nmobj = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager') nm = dbus.Interface(nmobj, 'org.freedesktop.NetworkManager') # connect the signal handler to the bus bus.add_signal_receiver(self.handler, None, 'org.freedesktop.NetworkManager', 'org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager') # get the current status of the network manager self.state = nm.state() invest.debug("Current Network Manager status is %d" % self.state) except Exception, msg: invest.error("Could not connect to the Network Manager: %s" % msg )
def get_quote(self, quotes, ticker): # the data for this quote quote = quotes[ticker]; # make sure the currency field is upper case quote["currency"] = quote["currency"].upper(); # the currency of currency conversion rates like EURUSD=X is wrong in csv # this can be fixed easily by reusing the latter currency in the symbol if len(ticker) == 8 and ticker.endswith("=X"): quote["currency"] = ticker[3:6] # indices should not have a currency, though yahoo says so if ticker.startswith("^"): quote["currency"] = "" # sometimes, funny currencies are returned (special characters), only consider known currencies if len(quote["currency"]) > 0 and quote["currency"] not in currencies.Currencies.currencies: invest.debug("Currency '%s' is not known, dropping" % quote["currency"]) quote["currency"] = "" # if this is a currency not yet seen and different from the target currency, memorize it if quote["currency"] not in self.currencies and len(quote["currency"]) > 0: self.currencies.append(quote["currency"]) return quote
def save_currencies(self, data): invest.debug("Storing currencies to %s" % invest.CURRENCIES_FILE) try: f = open(invest.CURRENCIES_FILE, 'w') f.write(data) f.close() except Exception, msg: invest.error("Could not save the retrieved currencies to %s: %s" % (invest.CURRENCIES_FILE, msg) )
def set_update_interval(self, interval): if self.timeout_id != None: invest.debug("Canceling refresh timer") GObject.source_remove(self.timeout_id) self.timeout_id = None if interval > 0: invest.debug("Setting refresh timer to %s:%02d.%03d" % ( interval / 60000, interval % 60000 / 1000, interval % 1000) ) self.timeout_id = GObject.timeout_add(interval, self.refresh)
def save_quotes(self, data): invest.debug("Storing quotes") try: f = open(invest.QUOTES_FILE, 'w') f.write(data) f.close() except Exception, msg: invest.error("Could not save the retrieved quotes file to %s: %s" % (invest.QUOTES_FILE, msg) )
def run(self): quotes_url = QUOTES_URL % {"s": self.tickers} try: quotes_file = urlopen(quotes_url, proxies = invest.PROXY) self.data = quotes_file.readlines () quotes_file.close () except Exception, msg: invest.debug("Error while retrieving quotes data (url = %s): %s" % (quotes_url, msg))
def run(self): quotes_url = QUOTES_URL % {"s": self.tickers} try: quotes_file = urlopen(quotes_url, proxies=invest.PROXY) self.data = quotes_file.readlines() quotes_file.close() except Exception, msg: invest.debug("Error while retrieving quotes data (url = %s): %s" % (quotes_url, msg))
def handler(self,signal=None): if isinstance(signal, dict): state = signal.get('State') if state != None: invest.debug("Network Manager change state %d => %d" % (self.state, state) ); self.state = state # notify about state change if self.statechange_callback != None: self.statechange_callback()
def load_currencies(self): invest.debug("Loading currencies from %s" % invest.CURRENCIES_FILE) try: f = open(invest.CURRENCIES_FILE, 'r') data = f.readlines() f.close() self.convert_currencies(self.parse_yahoo_csv(csv.reader(data))) except Exception, msg: invest.error("Could not load the currencies from %s: %s" % (invest.CURRENCIES_FILE, msg) )
def on_retriever_completed(self, retriever): if retriever.retrieved == False: invest.debug("QuotesRetriever failed for tickers '%s'" % retriever.tickers); self.update_tooltip(_('Invest could not connect to Yahoo! Finance')) else: invest.debug("QuotesRetriever completed"); # cache the retrieved csv file self.save_quotes(retriever.data) # load the cache and parse it self.load_quotes() # expand index values if requested self.expand_indices()
def save_index_quotes(self, index, data): # store the index quotes invest.debug("Storing quotes of index %s" % index) try: filename = invest.INDEX_QUOTES_FILE_TEMPLATE.replace('#', index) filename = join(invest.USER_INVEST_DIR, filename) f = open(filename, 'w') f.write(data) f.close() except Exception, msg: invest.error("Could not save the retrieved index quotes file of %s to %s: %s" % (index, filename, msg) ) return
def load_quotes(self): invest.debug("Loading quotes"); try: f = open(invest.QUOTES_FILE, 'r') data = f.readlines() f.close() self.populate(self.parse_yahoo_csv(csv.reader(data))) self.updated = True self.last_updated = datetime.datetime.fromtimestamp(getmtime(invest.QUOTES_FILE)) self.update_tooltip() except Exception, msg: invest.error("Could not load the cached quotes file %s: %s" % (invest.QUOTES_FILE, msg) )
def __init__(self, ui): self.ui = ui # Window Properties win = ui.get_object("window") win.set_title(_("Financial Chart")) try: pixbuf = gtk.gdk.pixbuf_new_from_file_at_size( join(invest.ART_DATA_DIR, "invest_neutral.svg"), 96, 96) self.ui.get_object("plot").set_from_pixbuf(pixbuf) except Exception, msg: invest.debug("Could not load 'invest-neutral.svg' file: %s" % msg) pass
def expand_index(self, index, data): invest.debug("Expanding index %s" % index) quotes = self.parse_yahoo_csv(csv.reader(data)) nodes = self.find_stock(index) for node in nodes: for ticker in quotes.keys(): quote = self.get_quote(quotes, ticker) row = self.insert(self.get_iter(node), 0, [ticker, quote["label"], quote["currency"], True, 0.0, 0.0, float(quote["trade"]), float(quote["variation_pct"]), None]) self.retrieve_image(ticker, row) # indicate if index was found return len(nodes) > 0
def __init__(self, ui): self.ui = ui #Time ranges of the plot self.time_ranges = ["1d", "5d", "3m", "6m", "1y", "5y", "my"] # Window Properties win = ui.get_object("window") win.set_title(_("Financial Chart")) try: pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest_neutral.svg"), 96,96) self.ui.get_object("plot").set_from_pixbuf(pixbuf) except Exception, msg: invest.debug("Could not load 'invest-neutral.svg' file: %s" % msg) pass
def refresh(self): invest.debug("Refreshing") # when nm tells me I am offline, stop the update interval if invest.nm.offline(): invest.debug("We are offline, stopping update timer") self.set_update_interval(0) return False if len(invest.STOCKS) == 0: return True tickers = '+'.join(invest.STOCKS.keys()) quotes_retriever = QuotesRetriever(tickers) quotes_retriever.connect("completed", self.on_retriever_completed) quotes_retriever.start() return True
def retrieve_currencies(self): # start retrieving currency conversion rates if invest.CONFIG.has_key("currency"): target_currency = invest.CONFIG["currency"] symbols = [] invest.debug("These currencies occur: %s" % self.currencies) for currency in self.currencies: if currency == target_currency: continue invest.debug("%s will be converted to %s" % ( currency, target_currency )) symbol = currency + target_currency + "=X" symbols.append(symbol) if len(symbols) > 0: tickers = '+'.join(symbols) quotes_retriever = QuotesRetriever(tickers) quotes_retriever.connect("completed", self.on_currency_retriever_completed) quotes_retriever.start()
def show_run_hide(self, explanation = ""): expl = self.ui.get_object("explanation") expl.set_markup(explanation) self.dialog.show_all() if explanation == "": expl.hide() # returns 1 if help is clicked while self.dialog.run() == 1: pass self.dialog.destroy() # transform the stocks treestore into the STOCKS list invest.STOCKS = self.to_list(self.model.get_iter_first()) # store the STOCKS into the pickles file try: cPickle.dump(invest.STOCKS, file(invest.STOCKS_FILE, 'w')) invest.debug('Stocks written to file') except Exception, msg: invest.error('Could not save stocks file: %s' % msg)
def __init__(self, ui): self.ui = ui #Time ranges of the plot (parameter / combo-box t) self.time_ranges = ["1d", "5d", "3m", "6m", "1y", "5y", "my"] #plot types (parameter / combo-box q) self.plot_types = ["l", "b", "c"] #plot scales (parameter / combo-box l) self.plot_scales = ["off", "on"] # Window Properties win = ui.get_object("window") win.set_title(_("Financial Chart")) try: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(join(invest.ART_DATA_DIR, "invest_neutral.svg"), 96,96) self.ui.get_object("plot").set_from_pixbuf(pixbuf) except Exception, msg: invest.debug("Could not load 'invest-neutral.svg' file: %s" % msg) pass
def populate(self, quotes): if (len(quotes) == 0): return self.clear() self.currencies = [] try: quote_items = quotes.items () quote_items.sort () self.quotes_change = 0 self.quotes_count = 0 self.statistics = {} # iterate over the STOCKS tree and build up this treestore self.add_quotes(quotes, invest.STOCKS, None) # we can only compute an avg quote change if there are quotes if self.quotes_count > 0: self.avg_quotes_change = self.quotes_change/float(self.quotes_count) # change icon quotes_change_sign = 0 if self.avg_quotes_change != 0: quotes_change_sign = self.avg_quotes_change / abs(self.avg_quotes_change) self.change_icon_callback(quotes_change_sign) else: self.avg_quotes_change = 0 # mark quotes to finally be valid self.quotes_valid = True except Exception, msg: invest.debug("Failed to populate quotes: %s" % msg) invest.debug(quotes) self.quotes_valid = False
def show_run_hide(self, explanation=""): expl = self.ui.get_object("explanation") expl.set_markup(explanation) self.dialog.show_all() if explanation == "": expl.hide() self.dialog.run() self.dialog.destroy() invest.STOCKS = {} def save_symbol(model, path, iter): #if int(model[iter][1]) == 0 or float(model[iter][2]) < 0.0001: # return if not model[iter][0] in invest.STOCKS: 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: cPickle.dump(invest.STOCKS, file(invest.STOCKS_FILE, 'w')) invest.debug('Stocks written to file') except Exception, msg: invest.error('Could not save stocks file: %s' % msg)
def add_quotes(self, quotes, stocks, parent): for stock in stocks: if not stock.has_key('ticker'): name = stock['name'] list = stock['list'] # here, the stock group name is used as the label, # so in quotes, the key == None indicates a group # in preferences, the label == None indicates this try: row = self.insert(parent, 0, [None, name, None, True, None, None, None, None, None]) except Exception, msg: invest.debug("Failed to insert group %s: %s" % (name, msg)) self.add_quotes(quotes, list, row) # Todo: update the summary statistics of row else: ticker = stock['ticker']; if not quotes.has_key(ticker): invest.debug("no quote for %s retrieved" % ticker) continue # get the quote quote = self.get_quote(quotes, ticker) # get the label of this stock for later reuse label = stock["label"] if len(label) == 0: if len(quote["label"]) != 0: label = quote["label"] else: label = ticker # Check whether the symbol is a simple quote, or a portfolio value try: if self.is_simple_quote(stock): row = self.insert(parent, 0, [ticker, label, quote["currency"], True, 0.0, 0.0, float(quote["trade"]), float(quote["variation_pct"]), None]) else: (balance, change) = self.balance(stock["purchases"], quote["trade"]) row = self.insert(parent, 0, [ticker, label, quote["currency"], False, float(balance), float(change), float(quote["trade"]), float(quote["variation_pct"]), None]) self.add_balance_change(balance, change, quote["currency"]) except Exception, msg: invest.debug("Failed to insert stock %s: %s" % (stock, msg)) self.quotes_change += quote['variation_pct'] self.quotes_count += 1 self.retrieve_image(ticker, row)
def __init__(self, applet): self.ui = gtk.Builder() 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") self.ui.get_object("add").connect('clicked', self.on_add_stock) self.ui.get_object("add").connect('activate', self.on_add_stock) self.ui.get_object("remove").connect('clicked', self.on_remove_stock) self.ui.get_object("remove").connect('activate', self.on_remove_stock) self.treeview.connect('key-press-event', self.on_tree_keypress) 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 def on_cell_edited(cell, path, new_text, col, typ): try: if col == 0: # stock symbols must be uppercase new_text = str.upper(new_text) store[path][col] = typ(new_text) except: pass def get_cell_data(column, cell, model, iter, data): typ, col = data if typ == int: cell.set_property('text', "%d" % typ(model[iter][col])) elif typ == float: cell.set_property('text', "%.2f" % typ(model[iter][col])) else: cell.set_property('text', typ(model[iter][col])) def create_cell (view, column, name, typ): cell_description = gtk.CellRendererText () cell_description.set_property("editable", True) 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=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, 5): create_cell (self.treeview, n, self.names[n], self.typs[n]) stock_items = invest.STOCKS.items () stock_items.sort () for key, data in stock_items: label = data["label"] purchases = data["purchases"] for purchase in purchases: 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) self.dialog.set_icon(pixbuf) except Exception, msg: invest.debug("Could not load 'invest-16.png' file: %s" % msg) pass
def update_position (self): """ Calculates the position and moves the window to it. """ self.realize() # get information sources window = self.applet.get_window() screen = window.get_screen() monitor = screen.get_monitor_geometry (screen.get_monitor_at_window (window)) # Get applet position and dimensions ... (ret, ax, ay) = window.get_origin() (ignored, ignored, aw, ah) = window.get_geometry() # ... and widget dimensions size = self.list.size_request() ww = size.width + self.get_border_width() * 2 wh = size.height + self.get_border_width() * 2 invest.debug("applet has position (%d,%d) and size (%d,%d)" % (ax, ay, aw, ah)) invest.debug("applet widget has size (%d,%d)" % (ww, wh)) invest.debug("monitor has position (%d,%d) and size (%d,%d)" % (monitor.x, monitor.y, monitor.width, monitor.height)) if self.alignment == PanelApplet.AppletOrient.LEFT: invest.debug("applet orientation is LEFT") wx = ax - ww - WidgetPaddingSpace wy = ay if (wy + wh + WidgetPaddingSpace > monitor.y + monitor.height): wy = monitor.y + monitor.height - wh - WidgetPaddingSpace if (wy + wh + WidgetPaddingSpace > monitor.height): wh = wh - (wy + wh + WidgetPaddingSpace - monitor.height) wy = monitor.height - wh - WidgetPaddingSpace if (wy < WidgetPaddingSpace): wh = wh + (wy - WidgetPaddingSpace) wy = WidgetPaddingSpace if (wy + wh > monitor.height / 2): gravity = Gdk.Gravity.SOUTH_WEST else: gravity = Gdk.Gravity.NORTH_WEST elif self.alignment == PanelApplet.AppletOrient.RIGHT: invest.debug("applet orientation is RIGHT") wx = ax + aw wy = ay if (wy + wh + WidgetPaddingSpace > monitor.y + monitor.height): wy = monitor.y + monitor.height - wh - WidgetPaddingSpace if (wy + wh + WidgetPaddingSpace > monitor.height): wh = wh - (wy + wh + WidgetPaddingSpace - monitor.height) wy = monitor.height - wh - WidgetPaddingSpace if (wy < WidgetPaddingSpace): wh = wh + (wy - WidgetPaddingSpace) wy = WidgetPaddingSpace if (wy + wh > monitor.height / 2): gravity = Gdk.Gravity.SOUTH_EAST else: gravity = Gdk.Gravity.NORTH_EAST elif self.alignment == PanelApplet.AppletOrient.DOWN: invest.debug("applet orientation is DOWN") wx = ax wy = ay + ah if (wx + ww > monitor.x + monitor.width): wx = monitor.x + monitor.width - ww if (wx < 0): wx = 0 if (wy + wh + WidgetPaddingSpace > monitor.height): wh = wh - (wy + wh + WidgetPaddingSpace - monitor.height) wy = monitor.height - wh - WidgetPaddingSpace gravity = Gdk.Gravity.NORTH_WEST elif self.alignment == PanelApplet.AppletOrient.UP: invest.debug("applet orientation is UP") invest.debug("widget size is (%d,%d)" % (ww, wh)) wx = ax wy = ay - wh if (wx + ww > monitor.x + monitor.width): wx = monitor.x + monitor.width - ww if (wx < 0): wx = 0 invest.debug("current widget position is (%d,%d)" % (wx, wy)) if (wy < WidgetPaddingSpace): wy = WidgetPaddingSpace if (wy + wh + WidgetPaddingSpace > monitor.height): wh = monitor.height - wy - WidgetPaddingSpace gravity = Gdk.Gravity.SOUTH_WEST invest.debug("Set widget position to (%d,%d)" % (wx, wy)) self.move(wx, wy) invest.debug("Set widget size to (%d,%d)" % (ww, wh)) self.resize(ww, wh) invest.debug("Set widget gravity to %s" % gravity) self.set_gravity(gravity)
def run(self): self.image = gtk.Image() try: sock = urllib.urlopen(self.image_url, proxies=invest.PROXY) except Exception, msg: invest.debug("Error while opening %s: %s" % (self.image_url, msg))
def applet_factory(applet, iid, data): invest.debug('Starting invest instance: %s %s %s'% ( applet, iid, data )) invest.applet.InvestApplet(applet) return True
""" sys.exit() if __name__ == "__main__": try: opts, args = getopt.getopt(sys.argv[1:], "hdw", ["help", "debug", "window"]) except getopt.GetoptError: # Unknown args were passed, we fallback to behave as if # no options were passed opts = [] args = sys.argv[1:] for o, a in opts: if o in ("-h", "--help"): usage() elif o in ("-d", "--debug"): invest.DEBUGGING = True invest.debug("Debugging enabled") # these messages cannot be turned by invest.DEBUGGING at their originating location, # because that variable was set here to be True invest.debug("Data Dir: %s" % invest.SHARED_DATA_DIR) invest.debug("Detected PROXY: %s" % invest.PROXY) invest.debug("Found NetworkManager spec %s (%s)" % (invest.networkmanager.spec, invest.networkmanager.version)) invest.debug("Starting applet factory, waiting for gnome-panel to connect ...") PanelApplet.Applet.factory_main( "InvestAppletFactory", # id PanelApplet.Applet.__gtype__, # gtype applet_factory, # factory callback None) # factory data pointer
def run(self): self.image = Gtk.Image() try: sock = urllib.urlopen(self.image_url, proxies = invest.PROXY) except Exception, msg: invest.debug("Error while opening %s: %s" % (self.image_url, msg))
def populate(self, quotes): if (len(quotes) == 0): return self.clear() try: quote_items = quotes.items () quote_items.sort () simple_quotes_change = 0 self.simple_quotes_count = 0 self.positions_balance = 0 self.positions_count = 0 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]["purchases"]: if purchase["amount"] != 0: is_simple_quote = False break if is_simple_quote: self.simple_quotes_count += 1 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]["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, label, False, balance, change, val["trade"], val["variation_pct"], pb]) self.positions_balance += balance 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 image_retriever = invest.chart.ImageRetriever(url) image_retriever.connect("completed", self.set_pb_callback, row) image_retriever.start() if self.simple_quotes_count > 0: self.avg_simple_quotes_change = simple_quotes_change/float(self.simple_quotes_count) else: self.avg_simple_quotes_change = 0 if self.avg_simple_quotes_change != 0: simple_quotes_change_sign = self.avg_simple_quotes_change / abs(self.avg_simple_quotes_change) else: simple_quotes_change_sign = 0 # change icon if self.simple_quotes_count > 0: self.change_icon_callback(simple_quotes_change_sign) else: positions_balance_sign = self.positions_balance/abs(self.positions_balance) self.change_icon_callback(positions_balance_sign) # mark quotes to finally be valid self.quotes_valid = True except Exception, msg: invest.debug("Failed to populate quotes: %s" % msg) invest.debug(quotes) self.quotes_valid = False
def __init__(self, applet): self.ui = gtk.Builder() 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") self.ui.get_object("add").connect('clicked', self.on_add_stock) self.ui.get_object("add").connect('activate', self.on_add_stock) self.ui.get_object("remove").connect('clicked', self.on_remove_stock) self.ui.get_object("remove").connect('activate', self.on_remove_stock) self.treeview.connect('key-press-event', self.on_tree_keypress) 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 def on_cell_edited(cell, path, new_text, col, typ): try: if col == 0: # stock symbols must be uppercase new_text = str.upper(new_text) store[path][col] = typ(new_text) except: pass def get_cell_data(column, cell, model, iter, data): typ, col = data if typ == int: cell.set_property('text', "%d" % typ(model[iter][col])) elif typ == float: cell.set_property('text', "%.2f" % typ(model[iter][col])) else: cell.set_property('text', typ(model[iter][col])) def create_cell(view, column, name, typ): cell_description = gtk.CellRendererText() cell_description.set_property("editable", True) 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=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, 5): create_cell(self.treeview, n, self.names[n], self.typs[n]) stock_items = invest.STOCKS.items() stock_items.sort() for key, data in stock_items: label = data["label"] purchases = data["purchases"] for purchase in purchases: 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) self.dialog.set_icon(pixbuf) except Exception, msg: invest.debug("Could not load 'invest-16.png' file: %s" % msg) pass
def populate(self, quotes): if (len(quotes) == 0): return self.clear() try: quote_items = quotes.items() quote_items.sort() simple_quotes_change = 0 self.simple_quotes_count = 0 self.positions_balance = 0 self.positions_count = 0 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]["purchases"]: if purchase["amount"] != 0: is_simple_quote = False break if is_simple_quote: self.simple_quotes_count += 1 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]["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, label, False, balance, change, val["trade"], val["variation_pct"], pb ]) self.positions_balance += balance 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 image_retriever = invest.chart.ImageRetriever(url) image_retriever.connect("completed", self.set_pb_callback, row) image_retriever.start() if self.simple_quotes_count > 0: self.avg_simple_quotes_change = simple_quotes_change / float( self.simple_quotes_count) else: self.avg_simple_quotes_change = 0 if self.avg_simple_quotes_change != 0: simple_quotes_change_sign = self.avg_simple_quotes_change / abs( self.avg_simple_quotes_change) else: simple_quotes_change_sign = 0 # change icon if self.simple_quotes_count > 0: self.change_icon_callback(simple_quotes_change_sign) else: positions_balance_sign = self.positions_balance / abs( self.positions_balance) self.change_icon_callback(positions_balance_sign) # mark quotes to finally be valid self.quotes_valid = True except Exception, msg: invest.debug("Failed to populate quotes: %s" % msg) invest.debug(quotes) self.quotes_valid = False
# store the STOCKS into the pickles file try: cPickle.dump(invest.STOCKS, file(invest.STOCKS_FILE, 'w')) invest.debug('Stocks written to file') except Exception, msg: invest.error('Could not save stocks file: %s' % msg) # store the CONFIG (currency, index expansion) into the config file invest.CONFIG = {} if self.currency_code != None and len(self.currency_code) == 3: invest.CONFIG['currency'] = self.currency_code invest.CONFIG['indexexpansion'] = self.indexexpansion.get_active() invest.CONFIG['hidecharts'] = self.hidecharts.get_active() try: cPickle.dump(invest.CONFIG, file(invest.CONFIG_FILE, 'w')) invest.debug('Configuration written to file') except Exception, msg: invest.debug('Could not save configuration file: %s' % msg) def to_list(self, iter): stocks = {} groups = [] while iter != None: if self.is_stock(iter): ticker = self.model[iter][0] if not ticker in stocks: stocks[ticker] = { 'ticker': ticker, 'label': self.model[iter][1],