36
35
PROVIDER_CREDITS = _('')
37
36
SVG_DIR = '/usr/share/icons/unity-icon-theme/places/svg/'
38
37
PROVIDER_ICON = SVG_DIR + 'service-firefoxbookmarks.svg'
39
DEFAULT_RESULT_ICON = 'gtk-about'
38
DEFAULT_RESULT_ICON = SVG_DIR + 'result-help.svg'
40
39
DEFAULT_RESULT_MIMETYPE = 'text/html'
41
40
DEFAULT_RESULT_TYPE = Unity.ResultType.DEFAULT
42
FIREFOX_EXECUTABLE = '/usr/bin/firefox'
43
41
BOOKMARKS_PATH = os.getenv("HOME") + "/.mozilla/firefox/"
44
BOOKMARKS_QUERY = '''SELECT moz_bookmarks.title, moz_places.url, moz_favicons.url, '%s', '%s'
45
FROM moz_bookmarks, moz_places, moz_favicons
46
WHERE moz_places.id = moz_bookmarks.fk
47
AND moz_places.favicon_id = moz_favicons.id
48
AND moz_bookmarks.title is not null
49
AND moz_places.favicon_id is not null
50
AND moz_bookmarks.type = 1
51
AND (moz_bookmarks.title LIKE '%%%s%%' OR moz_places.url LIKE '%%%s%%')
52
ORDER BY moz_bookmarks.lastModified;'''
54
43
c1 = {'id': 'bookmarks',
55
44
'name': _('Bookmarks'),
62
51
EXTRA_METADATA = []
65
def get_bookmarks_from_firefox(path, search):
67
Gets a list of bookmarks from the user's firefox profiles
69
# Build Firefox's profile paths
54
def get_bookmarks_from_firefox(path):
56
Gets a list of bookmarks from the user's firefox profile
58
# Build Firefox's profile path
72
61
for folder in os.listdir(path):
74
firefox_dbfiles.append(path + folder + "/places.sqlite")
76
for dbfile in firefox_dbfiles:
77
if os.path.exists(dbfile):
79
filename = dbfile.replace('/places.sqlite', '')
80
file_name, profile_name = os.path.splitext(filename)
81
profile_name = profile_name[1:]
82
sqlite_query = BOOKMARKS_QUERY % (profile_name, dbfile, search, search)
84
conn = sqlite3.connect(dbfile)
85
connection = conn.cursor()
86
connection.execute(sqlite_query)
87
profile_bookmarks = connection.fetchall()
88
for bookmark in profile_bookmarks:
89
bookmarks.append(bookmark)
91
except sqlite3.DatabaseError:
62
if folder.endswith(".default"):
63
firefox_dbfile = path + folder + "/places.sqlite"
65
if os.path.exists(firefox_dbfile):
67
sqlite_query = '''SELECT moz_bookmarks.title, moz_places.url, moz_favicons.url
68
FROM moz_bookmarks, moz_places, moz_favicons
69
WHERE moz_places.id = moz_bookmarks.fk
70
AND moz_places.favicon_id = moz_favicons.id
71
AND moz_bookmarks.title is not null
72
AND moz_places.favicon_id is not null
73
AND moz_bookmarks.type = 1
74
ORDER BY moz_bookmarks.lastModified;'''
76
conn = sqlite3.connect(firefox_dbfile)
77
connection = conn.cursor()
78
connection.execute(sqlite_query)
79
bookmarks = connection.fetchall()
98
88
Search for help documents matching the search string
101
bookmarks = get_bookmarks_from_firefox(BOOKMARKS_PATH, search)
91
bookmarks = get_bookmarks_from_firefox(BOOKMARKS_PATH)
103
93
for bookmark in bookmarks:
104
94
# Stop Firefox's smart bookmark folders from showing up
105
95
if not bookmark[1].find("place:") == -1:
107
path = bookmark[4].replace('places.sqlite', 'thumbnails/')
108
icon = '%s%s.png' % (path, hashlib.md5(bookmark[1].encode()).hexdigest())
109
if not os.path.exists(icon):
111
results.append({'uri': bookmark[1],
114
'title': bookmark[0],
115
'user': GLib.Variant('s', bookmark[3])})
98
if bookmark[2].startswith("chrome:"):
99
icon = Gio.ThemedIcon.new("firefox").to_string()
103
# Search bookmark names for matches
104
if not bookmark[0].lower().find(search.lower()) == -1:
105
results.append({'uri': bookmark[1],
108
'title': bookmark[0],
109
'comment': bookmark[1]})
112
# Search bookmark urls for matches
113
if not bookmark[1].lower().find(search.lower()) == -1:
114
results.append({'uri': bookmark[1],
117
'title': bookmark[0],
118
'comment': bookmark[1]})
119
def activate(result, metadata, id):
122
def activate(scope, uri):
121
124
Open the url in the default webbrowser
123
126
uri: The url to be opened
125
parameters = [FIREFOX_EXECUTABLE, result.uri]
126
GLib.spawn_async(parameters)
127
return Unity.ActivationResponse(handled=Unity.HandledType.HIDE_DASH, goto_uri=None)
130
class Preview(Unity.ResultPreviewer):
132
Creates the preview for the result
136
Create a preview and return it
138
preview = Unity.GenericPreview.new(self.result.title, '', None)
139
preview.props.subtitle = self.result.uri
141
if os.path.exists(self.result.icon_hint):
142
preview.props.image_source_uri = 'file://' + self.result.icon_hint
144
preview.props.image = Gio.ThemedIcon.new('gtk-about')
145
show_action = Unity.PreviewAction.new("show", _("Show"), None)
146
preview.add_action(show_action)
129
return Unity.ActivationResponse(handled=Unity.HandledType.HIDE_DASH, goto_uri='')
149
132
# Classes below this point establish communication
150
133
# with Unity, you probably shouldn't modify them.
179
162
i['comment'] = ''
180
163
if not 'dnd_uri' in i or not i['dnd_uri'] or i['dnd_uri'] == '':
181
164
i['dnd_uri'] = i['uri']
182
i['provider_credits'] = GLib.Variant('s', PROVIDER_CREDITS)
183
result_set.add_result(**i)
168
for m in EXTRA_METADATA:
170
i['metadata'][e] = i[e]
171
i['metadata']['provider_credits'] = GLib.Variant('s', PROVIDER_CREDITS)
172
result = Unity.ScopeResult.create(str(i['uri']), str(i['icon']),
173
i['category'], i['result_type'],
174
str(i['mimetype']), str(i['title']),
175
str(i['comment']), str(i['dnd_uri']),
177
result_set.add_result(result)
184
178
except Exception as error:
236
230
se = MySearch(search_context)
239
def do_activate(self, result, metadata, id):
240
return activate(result, metadata, id)
242
def do_create_previewer(self, result, metadata):
244
Creates a preview when a resut is right-clicked
246
result_preview = Preview()
247
result_preview.set_scope_result(result)
248
result_preview.set_search_metadata(metadata)
249
return result_preview
252
234
def load_scope():