unity-scope-chromiumbookmarks-0.1+13.10.20130723/0000755000015700001700000000000012173421105021710 5ustar pbuserpbgroup00000000000000unity-scope-chromiumbookmarks-0.1+13.10.20130723/po/0000755000015700001700000000000012173421105022326 5ustar pbuserpbgroup00000000000000unity-scope-chromiumbookmarks-0.1+13.10.20130723/po/unity-scope-chromiumbookmarks.pot0000644000015700001700000000233312173420135031066 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. # #: ../src/unity_chromiumbookmarks_daemon.py:36 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-02-21 01:59+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_chromiumbookmarks_daemon.py:34 msgid "Search Bookmarks" msgstr "" #: ../src/unity_chromiumbookmarks_daemon.py:35 msgid "Sorry, there are no Bookmarks that match your search." msgstr "" #: ../src/unity_chromiumbookmarks_daemon.py:45 msgid "Bookmarks" msgstr "" #: ../data/chromiumbookmarks.scope.in.h:1 msgid "chromiumbookmarks;" msgstr "" #: ../data/chromiumbookmarks.scope.in.h:2 msgid "Chromiumbookmarks" msgstr "" #: ../data/chromiumbookmarks.scope.in.h:3 msgid "Find Chromiumbookmarks items" msgstr "" #: ../data/chromiumbookmarks.scope.in.h:4 msgid "Search Chromiumbookmarks" msgstr "" unity-scope-chromiumbookmarks-0.1+13.10.20130723/po/POTFILES.in0000644000015700001700000000015312173420135024104 0ustar pbuserpbgroup00000000000000[encoding: UTF-8] src/unity_chromiumbookmarks_daemon.py [type: gettext/ini]data/chromiumbookmarks.scope.in unity-scope-chromiumbookmarks-0.1+13.10.20130723/MANIFEST.in0000644000015700001700000000007612173420135023453 0ustar pbuserpbgroup00000000000000include MANIFEST.in include src/* include data/* include po/* unity-scope-chromiumbookmarks-0.1+13.10.20130723/tests/0000755000015700001700000000000012173421105023052 5ustar pbuserpbgroup00000000000000unity-scope-chromiumbookmarks-0.1+13.10.20130723/tests/test_chromiumbookmarks.py0000644000015700001700000000433312173420135030224 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 TestAskUbuntu(ScopeTestCase): def setUp(self): self.init_scope('src/unity_chromiumbookmarks_daemon.py') def tearDown(self): self.scope = None self.scope_module = None def test_questions_search(self): self.scope_module.DEFAULT_BOOKMARKS = 'tests/data/mock_chromiumbookmarks_pass' self.scope_module.DEFAULT_TOP_SITES = 'tests/data/Top Sites' self.scope_module.PARSE_ALL_PROFILES = False expected_results = ["http://www.ubuntu.com/", "Test Bookmark"] results = [] for s in ['ubuntu']: result_set = self.perform_query(s) results.append(result_set.results[0]['uri']) results.append(result_set.results[0]['title']) self.assertEqual(results, expected_results) def test_questions_failing_search(self): self.scope_module.DEFAULT_BOOKMARKS = 'tests/data/mock_chromiumbookmarks_fail' self.scope_module.DEFAULT_TOP_SITES = 'tests/data/Top Sites' self.scope_module.PARSE_ALL_PROFILES = False for s in ['ubuntu']: result_set = self.perform_query(s) self.assertEqual(len(result_set.results), 0) if __name__ == '__main__': unittest.main() unity-scope-chromiumbookmarks-0.1+13.10.20130723/tests/__init__.py0000644000015700001700000000000012173420135025153 0ustar pbuserpbgroup00000000000000unity-scope-chromiumbookmarks-0.1+13.10.20130723/tests/data/0000755000015700001700000000000012173421105023763 5ustar pbuserpbgroup00000000000000unity-scope-chromiumbookmarks-0.1+13.10.20130723/tests/data/mock_chromiumbookmarks_fail0000644000015700001700000000000612173420135031444 0ustar pbuserpbgroup00000000000000 unity-scope-chromiumbookmarks-0.1+13.10.20130723/tests/data/mock_chromiumbookmarks_pass0000644000015700001700000000223112173420135031501 0ustar pbuserpbgroup00000000000000{ "checksum": "dd2b4a3b6c1e009f1c3ff444b9885ed7", "roots": { "bookmark_bar": { "children": [ { "children": [ { "date_added": "12946776668000000", "id": "1", "name": "Test Bookmark", "type": "url", "url": "http://www.ubuntu.com/" } ], "date_added": "12964667310451607", "date_modified": "12990414256547950", "id": "4", "name": "Test Folder", "type": "folder" } ], "date_added": "12964667271957138", "date_modified": "12990414256541428", "id": "1", "name": "Bookmarks Bar", "type": "folder" }, "other": { "children": [ ], "date_added": "12964667271957147", "date_modified": "0", "id": "2", "name": "Other Bookmarks", "type": "folder" }, "synced": { "children": [ ], "date_added": "12964667271957148", "date_modified": "0", "id": "3", "name": "Mobile Bookmarks", "type": "folder" } }, "version": 1 } unity-scope-chromiumbookmarks-0.1+13.10.20130723/tests/data/Top Sites0000644000015700001700000005000012173420135025515 0ustar pbuserpbgroup00000000000000SQLite format 3@ 99-'  l 7<!!CtablethumbnailsthumbnailsCREATE TABLE thumbnails (url LONGVARCHAR PRIMARY KEY,url_rank INTEGER ,title LONGVARCHAR,thumbnail BLOB,redirects LONGVARCHAR,boring_score DOUBLE DEFAULT 1.0, good_clipping INTEGER DEFAULT 0, at_top INTEGER DEFAULT 0, last_updated INTEGER DEFAULT 0, load_completed INTEGER DEFAULT 0)3G!indexsqlite_autoindex_thumbnails_1thumbnailse-tablemetametaCREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR)';indexsqlite_autoindex_meta_1meta ;last_compatible_version2 version2  version;last_compatible_version  unity-scope-chromiumbookmarks-0.1+13.10.20130723/src/0000755000015700001700000000000012173421105022477 5ustar pbuserpbgroup00000000000000unity-scope-chromiumbookmarks-0.1+13.10.20130723/src/unity_chromiumbookmarks_daemon.py0000644000015700001700000002475312173420135031375 0ustar pbuserpbgroup00000000000000#! /usr/bin/python3 # -*- coding: utf-8 -*- # Copyright(C) 2013 Mark Tully # 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 GLib, Gio from gi.repository import Unity import gettext import os import webbrowser import json import re import sqlite3 import tempfile APP_NAME = 'unity-scope-chromiumbookmarks' LOCAL_PATH = '/usr/share/locale/' gettext.bindtextdomain(APP_NAME, LOCAL_PATH) gettext.textdomain(APP_NAME) _ = gettext.gettext GROUP_NAME = 'com.canonical.Unity.Scope.Webhistory.Chromiumbookmarks' UNIQUE_PATH = '/com/canonical/unity/scope/webhistory/chromiumbookmarks' SEARCH_HINT = _('Search Bookmarks') NO_RESULTS_HINT = _('Sorry, there are no Bookmarks that match your search.') PROVIDER_CREDITS = _('') SVG_DIR = '/usr/share/icons/unity-icon-theme/places/svg/' PROVIDER_ICON = SVG_DIR + 'group-browserbookmarks.svg' DEFAULT_RESULT_ICON = SVG_DIR + 'group-browserbookmarks.svg' DEFAULT_RESULT_MIMETYPE = 'text/html' DEFAULT_RESULT_TYPE = Unity.ResultType.DEFAULT DEFAULT_BOOKMARKS = os.getenv("HOME") + "/.config/chromium/Default/Bookmarks" DEFAULT_TOP_SITES = '' PARSE_ALL_PROFILES = True CHROMIUM_EXECUTABLE = '/usr/bin/chromium-browser' TMP = tempfile.mkdtemp() c1 = {'id': 'bookmarks', 'name': _('Bookmarks'), 'icon': SVG_DIR + 'group-installed.svg', 'renderer': Unity.CategoryRenderer.VERTICAL_TILE} CATEGORIES = [c1] FILTERS = [] EXTRA_METADATA = [] def get_chromium_profiles(): BOOKMARKS_PATH = [DEFAULT_BOOKMARKS] if not PARSE_ALL_PROFILES: return BOOKMARKS_PATH try: for f in os.listdir(os.getenv("HOME") + "/.config/chromium/"): if f == "Default" or f.startswith('Profile '): profile_path = os.getenv("HOME") + "/.config/chromium/"+f+"/Bookmarks" if not profile_path in BOOKMARKS_PATH: BOOKMARKS_PATH.append(profile_path) except Exception as error: print(error) return BOOKMARKS_PATH def get_bookmarks_from_chromium(path): ''' Gets a list of bookmarks from the user's chromium profile Args: path: the path to Chromium's bookmarks file Returns: An array of bookmarks in the format [url, name] ''' bookmarks = [] if os.path.exists(path): bookmark_file = open(path) try: bookmark_json = json.load(bookmark_file) except ValueError: bookmark_json = "{}" def html_for_node(node): ''' For a node in the section, decide whether it's a folder or a bookmark ''' if 'url' in node: return html_for_url_node(node) elif 'children' in node: return html_for_parent_node(node) else: return '' def html_for_url_node(node): ''' For a bookmark, add the details ''' if not re.match("javascript:", node['url']): bookmark = [] bookmark.append(node['name']) bookmark.append(node['url']) bookmarks.append(bookmark) return else: return def html_for_parent_node(node): ''' For a folder, pass that node to html_for_node ''' for childnode in node['children']: html_for_node(childnode) return try: html_for_node(bookmark_json['roots']['bookmark_bar']) html_for_node(bookmark_json['roots']['other']) except TypeError: pass return bookmarks def search(search, filters): ''' Search for help documents matching the search string ''' results = [] global TMP if not os.path.exists(TMP): tmp_folder = tempfile.mkdtemp() TMP = tmp_folder else: tmp_folder = TMP for path in get_chromium_profiles(): user = path.split('/')[-2] bookmarks = get_bookmarks_from_chromium(path) if DEFAULT_TOP_SITES: thumbnail_path = DEFAULT_TOP_SITES else: thumbnail_path = path.replace('Bookmarks', 'Top Sites') conn = sqlite3.connect(thumbnail_path) connection = conn.cursor() for bookmark in bookmarks: # Search bookmark names for matches if search.lower() in bookmark[0].lower() or search.lower() in bookmark[1].lower(): sqlite_query = '''SELECT thumbnail FROM thumbnails WHERE url = "%s"''' % bookmark[1] icon = None connection.execute(sqlite_query) thumb = connection.fetchall() thumbname = bookmark[1].replace('/', '') if thumb: imageinfo = thumb[0][0] if imageinfo: open('%s/%s' % (tmp_folder, thumbname) , 'wb').write(imageinfo) icon = '%s/%s' % (tmp_folder, thumbname) else: if os.path.exists('%s/%s' % (tmp_folder, thumbname)): os.remove('%s/%s' % (tmp_folder, thumbname)) results.append({'uri': bookmark[1], 'icon': icon, 'category': 0, 'title': bookmark[0], 'user':user}) connection.close() return results def activate(result, metadata, id): """ Open the url in the default webbrowser Args: uri: The url to be opened """ parameters = [CHROMIUM_EXECUTABLE, result.uri] GLib.spawn_async(parameters) return Unity.ActivationResponse(handled=Unity.HandledType.HIDE_DASH, goto_uri=None) class Preview(Unity.ResultPreviewer): ''' Creates the preview for the result ''' def do_run(self): ''' Create a preview and return it ''' preview = Unity.GenericPreview.new(self.result.title, '', None) preview.props.subtitle = self.result.uri if os.path.exists(self.result.icon_hint): preview.props.image_source_uri = 'file://' + self.result.icon_hint else: preview.props.image = Gio.ThemedIcon.new('gtk-about') show_action = Unity.PreviewAction.new("show", _("Open"), None) preview.add_action(show_action) return preview # 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'] i['metadata'] = {} if EXTRA_METADATA: for e in i: for m in EXTRA_METADATA: if m['id'] == e: i['metadata'][e] = i[e] i['metadata']['provider_credits'] = GLib.Variant('s', PROVIDER_CREDITS) result_set.add_result(**i) except Exception as error: print(error) 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_activate(self, result, metadata, id): return activate(result, metadata, id) def do_create_previewer(self, result, metadata): ''' Creates a preview when a resut is right-clicked ''' result_preview = Preview() result_preview.set_scope_result(result) result_preview.set_search_metadata(metadata) return result_preview def load_scope(): return Scope() unity-scope-chromiumbookmarks-0.1+13.10.20130723/src/__init__.py0000644000015700001700000000000012173420135024600 0ustar pbuserpbgroup00000000000000unity-scope-chromiumbookmarks-0.1+13.10.20130723/setup.py0000644000015700001700000000167612173420135023436 0ustar pbuserpbgroup00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' Setup file for chromiumbookmarks dash plugin ''' from distutils.core import setup from DistUtilsExtra.command import build_extra from DistUtilsExtra.command import build_i18n setup(name='unity-scope-chromiumbookmarks', version='0.1', author='Mark Tully', author_email='markjtully@gmail.com', url='http://launchpad.net/ubuntu-scopes', license='GNU General Public License (GPL)', data_files=[('share/dbus-1/services', ['data/unity-scope-chromiumbookmarks.service']), #('share/icons/unity-icon-theme/places/svg', ['data/icons/service-chromiumbookmarks.svg']), ('share/unity-scopes/chromiumbookmarks', ['src/unity_chromiumbookmarks_daemon.py']), ('share/unity-scopes/chromiumbookmarks', ['src/__init__.py']), ], cmdclass={'build': build_extra.build_extra, 'build_i18n': build_i18n.build_i18n, }) unity-scope-chromiumbookmarks-0.1+13.10.20130723/setup.cfg0000644000015700001700000000022612173420135023533 0ustar pbuserpbgroup00000000000000[build] i18n=True [build_i18n] domain=unity-scope-chromiumbookmarks desktop_files=[('share/unity/scopes/web', ('data/chromiumbookmarks.scope.in',))] unity-scope-chromiumbookmarks-0.1+13.10.20130723/data/0000755000015700001700000000000012173421105022621 5ustar pbuserpbgroup00000000000000unity-scope-chromiumbookmarks-0.1+13.10.20130723/data/chromiumbookmarks.scope.in0000644000015700001700000000157112173420135030023 0ustar pbuserpbgroup00000000000000[Scope] DBusName=com.canonical.Unity.Scope.Webhistory.Chromiumbookmarks DBusPath=/com/canonical/unity/scope/webhistory/chromiumbookmarks Icon=/usr/share/icons/unity-icon-theme/places/svg/group-browserbookmarks.svg QueryBinary=chromium-browser _Keywords=chromiumbookmarks;chromium;web;bookmarks; RequiredMetadata= OptionalMetadata= Loader=/usr/share/unity-scopes/chromiumbookmarks/unity_chromiumbookmarks_daemon.py Module=chromiumbookmarks.unity_chromiumbookmarks_daemon ModuleType=python3 RemoteContent=false Type=web _Name=Chromium Bookmarks _Description=This is an Ubuntu search plugin that enables information from Chromium to be searched and displayed in the Dash underneath the Web header. If you do not wish to search this content source, you can disable this search plugin. _SearchHint=Search Chromiumbookmarks [Desktop Entry] X-Ubuntu-Gettext-Domain=unity-scope-chromiumbookmarks unity-scope-chromiumbookmarks-0.1+13.10.20130723/data/unity-scope-chromiumbookmarks.service0000644000015700001700000000025612173420135032221 0ustar pbuserpbgroup00000000000000[D-BUS Service] Name=com.canonical.Unity.Scope.Webhistory.Chromiumbookmarks Exec=/usr/bin/python3 /usr/share/unity-scopes/scope-runner-dbus.py -s web/chromiumbookmarks.scope unity-scope-chromiumbookmarks-0.1+13.10.20130723/data/icons/0000755000015700001700000000000012173421105023734 5ustar pbuserpbgroup00000000000000