unity-scope-yahoostock-0.1+13.10.20130723/0000755000015700001700000000000012173421352020343 5ustar pbuserpbgroup00000000000000unity-scope-yahoostock-0.1+13.10.20130723/po/0000755000015700001700000000000012173421352020761 5ustar pbuserpbgroup00000000000000unity-scope-yahoostock-0.1+13.10.20130723/po/unity-scope-yahoostock.pot0000644000015700001700000000263512173420334026152 0ustar pbuserpbgroup00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-02-21 02:00+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../src/unity_yahoostock_daemon.py:33 msgid "Search Yahoostock" msgstr "" #: ../src/unity_yahoostock_daemon.py:34 msgid "Sorry, there are no Stock Quotes that match your search." msgstr "" #: ../src/unity_yahoostock_daemon.py:35 msgid "Powered by Yahoo! Finance" msgstr "" #: ../src/unity_yahoostock_daemon.py:43 msgid "Quotes" msgstr "" #: ../src/unity_yahoostock_daemon.py:47 msgid "Headlines" msgstr "" #: ../src/unity_yahoostock_daemon.py:256 ../src/unity_yahoostock_daemon.py:258 #: ../src/unity_yahoostock_daemon.py:260 msgid "Vol: " msgstr "" #: ../data/yahoostock.scope.in.h:1 msgid "yahoo;stock;market;price;" msgstr "" #: ../data/yahoostock.scope.in.h:2 msgid "Yahoo Stock" msgstr "" #: ../data/yahoostock.scope.in.h:3 msgid "Find Yahoo Stock Quotes" msgstr "" #: ../data/yahoostock.scope.in.h:4 msgid "Search Yahoo Stock" msgstr "" unity-scope-yahoostock-0.1+13.10.20130723/po/POTFILES.in0000644000015700001700000000013512173420334022534 0ustar pbuserpbgroup00000000000000[encoding: UTF-8] src/unity_yahoostock_daemon.py [type: gettext/ini]data/yahoostock.scope.in unity-scope-yahoostock-0.1+13.10.20130723/MANIFEST.in0000644000015700001700000000007612173420334022103 0ustar pbuserpbgroup00000000000000include MANIFEST.in include src/* include data/* include po/* unity-scope-yahoostock-0.1+13.10.20130723/tests/0000755000015700001700000000000012173421352021505 5ustar pbuserpbgroup00000000000000unity-scope-yahoostock-0.1+13.10.20130723/tests/data/0000755000015700001700000000000012173421352022416 5ustar pbuserpbgroup00000000000000unity-scope-yahoostock-0.1+13.10.20130723/tests/data/mock_yahoostocknews_GOOG_pass0000644000015700001700000002323612173420334030300 0ustar pbuserpbgroup00000000000000 Yahoo! Finance: GOOG NewsCopyright (c) 2012 Yahoo! Inc. All rights reserved.http://finance.yahoo.com/q/h?s=googLatest Financial News for Google Inc.en-USThu, 20 Dec 2012 13:50:31 GMThttp://l.yimg.com/a/i/brand/purplelogo/uh/us/fin.gifYahoo! Finance: GOOG Newshttp://finance.yahoo.com/q/h?s=goog14445Apple Dodges Google Bullethttp://us.rd.yahoo.com/finance/external/xwscheats/rss/SIG=1251vu4ir/*http://wallstcheatsheet.com/stocks/apple-dodges-google-bullet.html/[at Wall St. Cheat Sheet] - The U.S. International Trade Commission determined on Tuesday that Apple did not infringed on Motorola Mobility’s patent that prevents accidental hang-ups...yahoo_finance/1673636042Thu, 20 Dec 2012 13:50:31 GMTStock futures flat amid "fiscal cliff" uncertaintyhttp://us.rd.yahoo.com/finance/news/rss/story/*http://finance.yahoo.com/news/stock-index-futures-point-flat-103702375.html[Reuters] - Stock futures were flat on Thursday amid uncertainty over U.S. fiscal negotiations, as President Barack Obama threatened to veto a controversial Republican plan, suggesting a deal wouldn't come as soon ...yahoo_finance/456300920Thu, 20 Dec 2012 13:44:45 GMTApple on the Backfoothttp://us.rd.yahoo.com/finance/news/rss/story/*http://finance.yahoo.com/news/apple-backfoot-133900950.html[Zacks] - Reportedly, Apple Inc. was dealt a major blow as its request to ban Samsung's smartphones in the U.S. was turned down by U.S. District Judge Lucy H. Koh.yahoo_finance/3322604083Thu, 20 Dec 2012 13:39:00 GMTOne Kendall Square listed for $360M; Hungry Mother reported moving inhttp://us.rd.yahoo.com/finance/external/bizj/rss/SIG=131hshddu/*http://www.bizjournals.com/boston/blog/mass_roundup/2012/12/one-kendall-sq-listed-for-360m.html?ana=yfcpcyahoo_finance/203073392Thu, 20 Dec 2012 13:35:01 GMTIs Apple’s iPhone Better for Business Than Google’s Android?http://us.rd.yahoo.com/finance/external/xwscheats/rss/SIG=134nooe60/*http://wallstcheatsheet.com/stocks/is-apples-iphone-better-for-business-than-googles-android.html/yahoo_finance/1010576185Thu, 20 Dec 2012 13:34:43 GMTGeorgia company buys Horsham Google planthttp://us.rd.yahoo.com/finance/external/bizj/rss/SIG=13a7t4tpe/*http://www.bizjournals.com/philadelphia/morning_roundup/2012/12/georgia-company-buys-horsham-google.html?ana=yfcpcyahoo_finance/1597356008Thu, 20 Dec 2012 13:22:50 GMTU.S. Stock Futures Flat as Fiscal Talks Stallhttp://us.rd.yahoo.com/finance/external/wsj/rss/SIG=12gah944t/*http://online.wsj.com/article/SB10001424127887324461604578190891898992214.html?ru=yahoo&mod=yahoo_hsyahoo_finance/2243411841Thu, 20 Dec 2012 13:19:56 GMTInstagram Taking Cues From Facebook: For Better or Worse?http://us.rd.yahoo.com/finance/external/xwscheats/rss/SIG=132lnr1op/*http://wallstcheatsheet.com/stocks/instagram-taking-cues-from-facebook-for-better-or-worse.html/[at Wall St. Cheat Sheet] - Instagram chief executive Kevin Systrom stated in a blog post on Wednesday that user fears prompted by an updated Terms of Service were unfounded...yahoo_finance/3565387807Thu, 20 Dec 2012 13:15:06 GMTMicrosoft Set to Face Possible EU Fines on Browser Violationhttp://us.rd.yahoo.com/finance/external/bloomberg/rss/SIG=13g8m6h6o/*http://www.bloomberg.com/news/2012-12-20/microsoft-set-to-face-eu-decision-on-browser-antitrust-violation.html?cmpid=yhoo[at Bloomberg] - Microsoft Set to Face Possible EU Fines on Browser Violationyahoo_finance/2647207045Thu, 20 Dec 2012 13:08:58 GMTWhich Company Is Microsoft Betting On To Reverse Its Fortunes?http://us.rd.yahoo.com/finance/external/xwscheats/rss/SIG=1384car0n/*http://wallstcheatsheet.com/stocks/which-company-is-microsoft-betting-on-to-reverse-its-fortunes.html/yahoo_finance/73142085Thu, 20 Dec 2012 13:07:53 GMTGoogle sells Motorola cable box unit for $2.4 billionhttp://us.rd.yahoo.com/finance/external/cnnm/rss/SIG=12hb2sr4k/*http://money.cnn.com/2012/12/20/technology/google-cable-box-motorola/index.html?source=yahoo_quote[at CNNMoney.com] - Google sells Motorola cable box unit for $2.4 billionyahoo_finance/2596040135Thu, 20 Dec 2012 13:04:00 GMTEquities, New Tech, and Emerging Market Debt Is The Way To Go in 2013: Josh Brownhttp://us.rd.yahoo.com/finance/news/rss/story/*http://finance.yahoo.com/blogs/daily-ticker/equities-tech-emerging-market-debt-way-2013-josh-125822019.html[The Daily Ticker] - http://d.yimg.com/hn/p/i/bcst/yp/yahoofinance/21464/133343889.jpgyahoo_finance/1183373710Thu, 20 Dec 2012 12:58:22 GMTUS STOCKS-Futures flat amid 'fiscal cliff' uncertainty, data on taphttp://us.rd.yahoo.com/finance/external/reuters/rss/SIG=12k1bls2i/*http://www.reuters.com/article/2012/12/20/markets-usa-stocks-idUSL1E8NK1HL20121220?feedType=RSS&feedName=technologySector&rpc=43yahoo_finance/3662074308Thu, 20 Dec 2012 12:57:52 GMTUS STOCKS-Futures flat amid 'fiscal cliff' uncertainty, data on taphttp://us.rd.yahoo.com/finance/news/rss/story/*http://uk.finance.yahoo.com/news/us-stocks-futures-flat-amid-125752975.html[Reuters - UK Focus] - U.S. stock index futures wereflat on Thursday amid uncertainty over U.S. fiscal negotiations,as President Barack Obama threatened to veto a controversialRepublican plan, suggesting a deal wouldn't come ...yahoo_finance/166287057Thu, 20 Dec 2012 12:57:50 GMTEarly Movers: NYX, ICE, CAG & Morehttp://us.rd.yahoo.com/finance/external/cnbc/rss/SIG=112avbped/*http://www.cnbc.com/id/100330635?__source=yahoo|headline|quote|text|&par=yahooyahoo_finance/2878619084Thu, 20 Dec 2012 12:46:14 GMTThe Morning Download: Bad Day for Applehttp://us.rd.yahoo.com/finance/external/wsj/rss/SIG=12dkolor5/*http://blogs.wsj.com/cio/2012/12/20/the-morning-download-bad-day-for-apple/?mod=yahoo_hsyahoo_finance/3886035675Thu, 20 Dec 2012 12:44:29 GMTU.S. agency rejects Apple 'pinch-to-zoom' patent in initial rulinghttp://us.rd.yahoo.com/finance/news/rss/story/*http://sg.finance.yahoo.com/news/u-agency-rejects-apple-pinch-123648541.htmlyahoo_finance/3943558309Thu, 20 Dec 2012 12:36:48 GMTGoogle, Apple Buying Kodak's Digital Photo Patentshttp://us.rd.yahoo.com/finance/external/bloomberg/rss/SIG=13eghvi19/*http://www.bloomberg.com/video/google-apple-buying-kodak-s-digital-photo-patents-xIr6E4lbS16LAFOIJtjcUQ.html?cmpid=yhooyahoo_finance/3654355460Thu, 20 Dec 2012 12:36:46 GMTEricsson to take $1.2 billion charge on ST-Ericsson stakehttp://us.rd.yahoo.com/finance/news/rss/story/*http://sg.finance.yahoo.com/news/ericsson-1-2-billion-charge-075748976.html[Reuters] - By Simon Johnson and Olof Swahnberg STOCKHOLM (Reuters) - Ericsson is taking a $1.2 billion charge in a bid to write off its exposure to ST-Ericsson, adding to doubts over the future of the loss-making ...yahoo_finance/1707921808Thu, 20 Dec 2012 12:36:28 GMTEricsson to take $1.2 billion charge on ST-Ericsson stakehttp://us.rd.yahoo.com/finance/news/rss/story/*http://finance.yahoo.com/news/ericsson-1-2-billion-charge-075748791.html[Reuters] - Ericsson is taking a $1.2 billion charge in a bid to write off its exposure to ST-Ericsson, adding to doubts over the future of the loss-making joint venture after partner STMicroelectronics said it was ...yahoo_finance/553445319Thu, 20 Dec 2012 12:36:28 GMT unity-scope-yahoostock-0.1+13.10.20130723/tests/data/mock_yahoostock_GOOG_fail0000644000015700001700000000000612173420334027336 0ustar pbuserpbgroup00000000000000 unity-scope-yahoostock-0.1+13.10.20130723/tests/data/mock_yahoostock_INVALIDSYMBOL0000644000015700001700000000010312173420334027622 0ustar pbuserpbgroup00000000000000"Invalid Symbol","",0.00,"12/19/2012","4:00pm",1200,"0.00 - 0.00%" unity-scope-yahoostock-0.1+13.10.20130723/tests/data/mock_yahoostock_GOOG_pass0000644000015700001700000000010712173420334027373 0ustar pbuserpbgroup00000000000000"GOOG","Google Inc.",720.11,"12/19/2012","4:00pm",1200,"0.00 - 0.00%" unity-scope-yahoostock-0.1+13.10.20130723/tests/test_yahoostock.py0000644000015700001700000000503212173420334025300 0ustar pbuserpbgroup00000000000000#! /usr/bin/python3 # -*- coding: utf-8 -*- from gi.repository import Unity from unittest import TestCase import imp class ResultSet(Unity.ResultSet): def __init__(self): Unity.ResultSet.__init__(self) self.results = [] def do_add_result(self, result): self.results.append({'uri':result.uri, 'title':result.title, 'comment':result.comment, 'icon':result.icon_hint}) class ScopeTestCase(TestCase): def init_scope(self, scope_path): self.scope_module = imp.load_source('scope', scope_path) self.scope = self.scope_module.load_scope() def perform_query(self, query, filter_set = Unity.FilterSet.new()): result_set = ResultSet() ctx = Unity.SearchContext.create(query, 0, filter_set, None, result_set, None) s = self.scope.create_search_for_query(ctx) s.run() return result_set class TestYahoostock(ScopeTestCase): def setUp(self): self.init_scope('src/unity_yahoostock_daemon.py') def tearDown(self): self.scope = None self.scope_module = None def test_valid_searches(self): self.scope_module.QUOTE_URL = 'file:tests/data/mock_yahoostock_%s_pass' self.scope_module.NEWS_URL = 'file:tests/data/mock_yahoostocknews_%s_pass' self.scope_module.FAKE_CALL = True expected_results = ['Google Inc.\n720.11@4:00pm\nVol: 1200\n'] results = [] for s in ['GOOG']: result_set = self.perform_query(s) results.append(result_set.results[0]['comment']) self.assertEqual(results, expected_results) def test_invalid_symbol(self): self.scope_module.QUOTE_URL = 'file:tests/data/mock_yahoostock_%s' self.scope_module.NEWS_URL = 'file:tests/data/mock_yahoostocknews_GOOG_fail#%s' self.scope_module.FAKE_CALL = True results = [] for s in ['INVALIDSYMBOL']: result_set = self.perform_query(s) print (result_set.results) self.assertEqual(len(result_set.results), 0) def test_failing_search(self): self.scope_module.QUOTE_URL = 'file:tests/data/mock_yahoostock_%s_fail' self.scope_module.NEWS_URL = 'file:tests/data/mock_yahoostock_%s_fail' self.scope_module.FAKE_CALL = True for s in ['GOOG']: result_set = self.perform_query(s) self.assertEqual(len(result_set.results), 0) if __name__ == '__main__': unittest.main() unity-scope-yahoostock-0.1+13.10.20130723/src/0000755000015700001700000000000012173421352021132 5ustar pbuserpbgroup00000000000000unity-scope-yahoostock-0.1+13.10.20130723/src/unity_yahoostock_daemon.py0000644000015700001700000003453512173420334026453 0ustar pbuserpbgroup00000000000000#! /usr/bin/python3 # -*- coding: utf-8 -*- # Copyright (C) 2013 David Callé # Copyright (C) 2012 Matt Fischer # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranties of # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . from gi.repository import Unity, UnityExtras from gi.repository import Gio, GLib import urllib.parse import urllib.request import feedparser import gettext from datetime import datetime APP_NAME = 'unity-scope-yahoostock' LOCAL_PATH = '/usr/share/locale/' gettext.bindtextdomain(APP_NAME, LOCAL_PATH) gettext.textdomain(APP_NAME) _ = gettext.gettext GROUP_NAME = 'com.canonical.Unity.Scope.News.Yahoostock' UNIQUE_PATH = '/com/canonical/unity/scope/news/yahoostock' SEARCH_HINT = _('Search Yahoostock') NO_RESULTS_HINT = _('Sorry, there are no Stock Quotes that match your search.') PROVIDER_CREDITS = _('Powered by Yahoo! Finance') SVG_DIR = '/usr/share/icons/unity-icon-theme/places/svg/' PROVIDER_ICON = SVG_DIR+'service-yahoofinance.svg' DEFAULT_RESULT_ICON = SVG_DIR+'result-news.svg' DEFAULT_RESULT_MIMETYPE = 'text/html' DEFAULT_RESULT_TYPE = Unity.ResultType.DEFAULT ICON_SIZE_RESULT = 133 ICON_SIZE_PREVIEW = 380 c1 = {'id' :'recent', 'name' :_('Quotes'), 'icon' :SVG_DIR+'group-installed.svg', 'renderer':Unity.CategoryRenderer.HORIZONTAL_TILE} c2 = {'id' :'top', 'name' :_('Headlines'), 'icon' :SVG_DIR+'group-installed.svg', 'renderer':Unity.CategoryRenderer.HORIZONTAL_TILE} CATEGORIES = [c1, c2] FILTERS = [] m1 = {'id' :'stock', 'type' :'s', 'field':Unity.SchemaFieldType.OPTIONAL} EXTRA_METADATA = [m1] # source for how this API works: http://www.gummy-stuff.org/Yahoo-data.htm QUOTE_URL = "http://finance.yahoo.com/d/quotes.csv?s=%s&f=snl1d1t1vc" # source for the news NEWS_URL = "http://finance.yahoo.com/rss/headline?s=%s" # callback URL, this loads the webpage for a ticker CALLBACK_URL = "http://finance.yahoo.com/q?s=%s&ql=1" # Test injection FAKE_CALL = False def search(search, filters): ''' Any search method returning results as a list of tuples. Available tuple fields: uri (string) icon (string) title (string) comment (string) dnd_uri (string) mimetype (string) category (int) result_type (Unity ResultType) extras metadata fields (variant) ''' results = [] if not search: return results ys = Yahoostock() quotes = ys.getQuotes(urllib.parse.quote(search)) for quote in quotes: volume_str = ys.getVolumeStr(quote['volume']) change_str = ys.getChangeStr(quote['change']) comment = "%s\n%s@%s\n%s\n%s" % (quote['name'], quote['lastVal'], quote['lastTime'], volume_str, change_str) print (quote['symbol']) if quote['name'] == 'Invalid Symbol' or quote['lastVal'] == '0.00': return results results.append({'uri':ys.getQuoteUrl(quote['symbol']), 'icon':'http://chart.finance.yahoo.com/t?s=%s&lang=en-US®ion=US&width=%i&height=%i' % (quote['symbol'], ICON_SIZE_RESULT, ICON_SIZE_RESULT), 'title':quote['symbol'], 'comment':comment, 'stock':quote['symbol'], 'last_date':quote['lastDate'], 'evolution':quote['change']}) return results class Yahoostock: # splits a string by splitChar, but if splitChar is inside a quote, # it doesn't split. This is required to fix companies which annoyingly # have commas in their name, for example: # "RHT","Red Hat, Inc. Com",47.40,"1/26/2012","4:01pm",47.82,48.49,47.08 def _quotedSplit(self, line, splitChar): vals = [] entry = "" insideQuote = False for char in line: entry += char if char == splitChar and insideQuote is False: # when we append, skip the comma vals.append(entry[:-1]) entry = "" elif char == "\"": if insideQuote is True: insideQuote = False else: insideQuote = True #don't forget the last one, the line has no trailing comma! vals.append(entry) return vals def _isValid(self, quote): """Returns True if the quote is valid, False if not""" if quote["symbol"] == quote["name"]\ and quote["lastVal"] == '0.00'\ and quote["lastDate"] == quote["lastTime"]\ and quote["lastDate"] == "N/A"\ and quote["change"] == "N/A - N/A": return False return True def _parseLine(self, line): quote = {} vals = [] vals = self._quotedSplit(line, ',') quote["symbol"] = vals[0].replace('\"', '') quote["name"] = vals[1].replace('\"', '') quote["lastVal"] = vals[2] quote["lastDate"] = vals[3].replace('\"', '') quote["lastTime"] = vals[4].replace('\"', '') quote["volume"] = vals[5] quote["change"] = vals[6].strip().replace('\"', '') if not self._isValid(quote): quote["name"] = "Invalid Symbol" return quote def _parseData(self, stream): quotes = [] for line in stream.readlines(): try: quote = self._parseLine(line.decode('utf-8')) quotes.append(quote) except Exception as error: print(error) return quotes # this expects to be passed in a string like this: # HPQ+A+RHT+GM no spaces! def getQuotes(self, symbols): url = QUOTE_URL % (symbols) print(url) stream = urllib.request.urlopen(url) if stream is not None: if stream.getcode() is 200 or FAKE_CALL is True: return self._parseData(stream) else: print ("error: http returned %d" % (stream.getcode())) stream.close() return [] def getQuoteUrl(self, symbol): return CALLBACK_URL % (symbol) def getNewsForSymbol(self, symbol, maxitems): stories = [] url = NEWS_URL % (symbol) d = feedparser.parse(url) if d: count = 0 for entry in d.entries: try: if "title" not in entry.keys(): continue if "link" not in entry.keys(): continue ## skip all pay stories which start with "[$$]" in the title if entry.title.startswith("[$$]") or entry.link is None: continue story = {} story["title"] = entry.title story["link"] = entry.link if "published" in entry.keys(): story["date"] = entry.published elif "updated" in entry.keys(): story["date"] = entry.updated else: story["date"] = "" if "description" in entry.keys(): story["description"] = entry.description else: story["description"] = "" stories.append(story) count = count + 1 except Exception as e: print ("Exception: ", e) if count >= maxitems: break return stories def getChangeStr(self, change): if change is None or change is "" or change is "N/A" or change is "N/A - N/A": return "" change = change.replace("\"", "").strip() changeAmt, changePct = change.split(" - ", 2) try: changeFlt = round(float(changeAmt), 2) # hooray for unicode symbols # http://www.alanwood.net/unicode/arrows.html if changeFlt < 0: # down arrow = chr(8600) elif changeAmt > 0: # up arrow = chr(8599) else: # unch arrow = chr(8594) except Exception as e: print ("Exception: ", e) return "" return "%s %s (%s)" % (arrow, changeFlt, changePct) def getVolumeStr(self, volume): if volume is None or volume is "" or volume is "N/A": return "" try: fVol = float(volume) if fVol > 1000000: return _("Vol: ") + str(round(fVol / 1000000, 3)) + "M" elif fVol > 10000: return _("Vol: ") + str(round(fVol / 1000, 3)) + "k" else: return _("Vol: ") + volume except Exception as e: print ("Exception: ", e) return "" # Classes below this point establish communication # with Unity, you probably shouldn't modify them. class MySearch (Unity.ScopeSearchBase): def __init__(self, search_context): super (MySearch, self).__init__() self.set_search_context (search_context) def do_run (self): ''' Adds results to the model ''' try: result_set = self.search_context.result_set for i in search(self.search_context.search_query, self.search_context.filter_state): if not 'uri' in i or not i['uri'] or i['uri'] == '': continue if not 'icon' in i or not i['icon'] or i['icon'] == '': i['icon'] = DEFAULT_RESULT_ICON if not 'mimetype' in i or not i['mimetype'] or i['mimetype'] == '': i['mimetype'] = DEFAULT_RESULT_MIMETYPE if not 'result_type' in i or not i['result_type'] or i['result_type'] == '': i['result_type'] = DEFAULT_RESULT_TYPE if not 'category' in i or not i['category'] or i['category'] == '': i['category'] = 0 if not 'title' in i or not i['title']: i['title'] = '' if not 'comment' in i or not i['comment']: i['comment'] = '' if not 'dnd_uri' in i or not i['dnd_uri'] or i['dnd_uri'] == '': i['dnd_uri'] = i['uri'] result_set.add_result(**i) except Exception as error: print (error) class Preview (Unity.ResultPreviewer): def do_run(self): graph = Gio.FileIcon.new(Gio.file_new_for_uri(self.result.icon_hint.replace('=%i' % ICON_SIZE_RESULT, '=%i'% ICON_SIZE_PREVIEW))) corp = self.result.comment.split('\n')[0] value = self.result.comment.split('\n')[1].split('@')[0] time = self.result.comment.split('\n')[1].split('@')[1] volume = self.result.comment.split('\n')[2].split("Vol: ")[1] trend = self.result.metadata['evolution'].get_string() trends = trend.split(' ') date = self.result.metadata['last_date'].get_string() delta = datetime.today() - datetime.strptime(date, '%m/%d/%Y') if delta.days == 1: date = _('Yesterday') elif delta.days > 1: date = _('%i days ago' % delta.days) else: date = None preview = Unity.GenericPreview.new(corp, '', graph) if date: preview.props.subtitle = '%s, %s' % (date, time) else: preview.props.subtitle = time if len(trends) > 1: if trends[0] != trends[-1]: trend = '%s (%s)' % (trends[0], trends[-1]) else: trend = trends[0] if trend.startswith('-'): change_arrow = "\u2B0A" trend = '%s %s' % (change_arrow, trend[1:]) else: change_arrow = "\u2B08" trend = '%s %s' % (change_arrow, trend[1:]) preview.add_info(Unity.InfoHint.new("evolution", _("Evolution"), None, trend)) preview.add_info(Unity.InfoHint.new("value", _("Value"), None, value)) preview.add_info(Unity.InfoHint.new("volume", _("Volume"), None, volume)) preview.add_info(Unity.InfoHint.new("symbol", _("Symbol"), None, self.result.title)) icon = Gio.FileIcon.new (Gio.file_new_for_path(PROVIDER_ICON)) view_action = Unity.PreviewAction.new("open", _("View"), icon) preview.add_action(view_action) return preview class Scope (Unity.AbstractScope): def __init__(self): Unity.AbstractScope.__init__(self) def do_get_search_hint (self): return SEARCH_HINT def do_get_schema (self): ''' Adds specific metadata fields ''' schema = Unity.Schema.new () if EXTRA_METADATA: for m in EXTRA_METADATA: schema.add_field(m['id'], m['type'], m['field']) #FIXME should be REQUIRED for credits schema.add_field('provider_credits', 's', Unity.SchemaFieldType.OPTIONAL) return schema def do_get_categories (self): ''' Adds categories ''' cs = Unity.CategorySet.new () if CATEGORIES: for c in CATEGORIES: cat = Unity.Category.new (c['id'], c['name'], Gio.ThemedIcon.new(c['icon']), c['renderer']) cs.add (cat) return cs def do_get_filters (self): ''' Adds filters ''' fs = Unity.FilterSet.new () # if FILTERS: # return fs def do_get_group_name (self): return GROUP_NAME def do_get_unique_name (self): return UNIQUE_PATH def do_create_search_for_query (self, search_context): se = MySearch (search_context) return se def do_create_previewer(self, result, metadata): rp = Preview() rp.set_scope_result(result) rp.set_search_metadata(metadata) return rp def load_scope(): return Scope() unity-scope-yahoostock-0.1+13.10.20130723/src/__init__.py0000644000015700001700000000000012173420334023230 0ustar pbuserpbgroup00000000000000unity-scope-yahoostock-0.1+13.10.20130723/setup.py0000644000015700001700000000124412173420334022055 0ustar pbuserpbgroup00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- from distutils.core import setup from DistUtilsExtra.command import * setup(name='unity-scope-yahoostock', version='0.1', author='David Callé', author_email='davidc@framli.eu', url='http://launchpad.net/ubuntu-scopes', license='GNU General Public License (GPL)', data_files=[ ('share/dbus-1/services', ['data/unity-scope-yahoostock.service']), ('share/unity-scopes/yahoostock', ['src/unity_yahoostock_daemon.py']), ('share/unity-scopes/yahoostock', ['src/__init__.py']), ], cmdclass={'build': build_extra.build_extra, 'build_i18n': build_i18n.build_i18n,}) unity-scope-yahoostock-0.1+13.10.20130723/setup.cfg0000644000015700001700000000021112173420334022155 0ustar pbuserpbgroup00000000000000[build] i18n=True [build_i18n] domain=unity-scope-yahoostock desktop_files=[('share/unity/scopes/news', ('data/yahoostock.scope.in',))] unity-scope-yahoostock-0.1+13.10.20130723/data/0000755000015700001700000000000012173421352021254 5ustar pbuserpbgroup00000000000000unity-scope-yahoostock-0.1+13.10.20130723/data/unity-scope-yahoostock.service0000644000015700001700000000023312173420334027273 0ustar pbuserpbgroup00000000000000[D-BUS Service] Name=com.canonical.Unity.Scope.News.Yahoostock Exec=/usr/bin/python3 /usr/share/unity-scopes/scope-runner-dbus.py -s news/yahoostock.scope unity-scope-yahoostock-0.1+13.10.20130723/data/yahoostock.scope.in0000644000015700001700000000142312173420334025076 0ustar pbuserpbgroup00000000000000[Scope] DBusName=com.canonical.Unity.Scope.News.Yahoostock DBusPath=/com/canonical/unity/scope/news/yahoostock Icon=/usr/share/icons/unity-icon-theme/places/svg/service-yahoofinance.svg _Keywords=yahoo;stock;market;price; RequiredMetadata= OptionalMetadata=stock[s]; Loader=/usr/share/unity-scopes/yahoostock/unity_yahoostock_daemon.py Module=yahoostock.unity_yahoostock_daemon ModuleType=python3 RemoteContent=true Type=news _Name=Yahoo Finance _Description=This is an Ubuntu search plugin that enables information from Yahoo Finance to be searched and displayed in the Dash underneath the News header. If you do not wish to search this content source, you can disable this search plugin. _SearchHint=Search Yahoo Finance [Desktop Entry] X-Ubuntu-Gettext-Domain=unity-scope-yahoostock unity-scope-yahoostock-0.1+13.10.20130723/data/icons/0000755000015700001700000000000012173421352022367 5ustar pbuserpbgroup00000000000000unity-scope-yahoostock-0.1+13.10.20130723/data/icons/service-yahoostock.svg0000644000015700001700000001046512173420334026736 0ustar pbuserpbgroup00000000000000 image/svg+xml