Merge lp://qastaging/~neal-s/do-plugins/firefoxawesomebar into lp://qastaging/do-plugins

Proposed by Alex Launi
Status: Merged
Merged at revision: not available
Proposed branch: lp://qastaging/~neal-s/do-plugins/firefoxawesomebar
Merge into: lp://qastaging/do-plugins
Diff against target: None lines
To merge this branch: bzr merge lp://qastaging/~neal-s/do-plugins/firefoxawesomebar
Reviewer Review Type Date Requested Status
Alex Launi (community) Needs Fixing
Review via email: mp+5689@code.qastaging.launchpad.net

This proposal supersedes a proposal from 2009-04-11.

To post a comment you must log in.
Revision history for this message
Neal Stewart (neal-s) wrote : Posted in a previous version of this proposal

Another try!

This version allows you to search through your Firefox Bookmarks from Gnome Do directly.

Bookmarks and History are both provided as children of the Firefox Application.

Revision history for this message
Neal Stewart (neal-s) wrote : Posted in a previous version of this proposal

Code reverted to old version somehow? Will fix in a few hours. Delay review, please.

> Another try!
>
> This version allows you to search through your Firefox Bookmarks from Gnome Do
> directly.
>
> Bookmarks and History are both provided as children of the Firefox
> Application.

Revision history for this message
Neal Stewart (neal-s) wrote : Posted in a previous version of this proposal

And now it's back to where it was this afternoon.

Revision history for this message
Alex Launi (alexlauni) wrote :

Usability: Arrowing into the firefox application should have two meta-items, bookmarks and history. You should then arrow into one. Currently if I arrow into firefox i am given 1000s of results just called url. This renders the window manager plugin useless since finding my window becomes impossible. Organizing these into subcategories will make this much more sane.

Fix namespaces, just use Firefox, not Mozilla.Firefox.
Fix some other mono guidelines issues, you've got a few places where your method calls are not seperated from their parameters. ex)
     Foo(bar) ;
should be
     Foo (bar);

Youve got an extra space between your const delcarations in FABarItemSource.cs, and are missing one between your global variable declarations and your constructor. You've got a few places with extra newlines, keep these to single blank lines.

You should not be calling UpdateItems in ChildrenOfItem that's bad news.

Do prefix Services calls with Do.Platform, it's not needed and is overly verbose.

you've got a while (null != (line = r.ReadLine ())), reverse that.
while ((line = r.ReadLine ()) != null)

Try and avoid one line conditionals, unless it makes the code more readable, use a newline for the predicate. Examples in your code:
in FABarItemSource.cs/ProfilePath() you do
     if (!String.IsNullOrEmpty (storedProfilePath)) return storedProfilePath;
this would be better on two lines like
     if (!String.IsNullOrEmpty (storedProfilePath))
          return storedProfilePath;

assign profile before home, do your assignments like this in order of line length. It makes the code prettier.

tempDatabasePath property should be TempDatabasePath
in this property the else if should be on the same line as the ending if bracket, and the else if's starting bracket should be on the same line as the else if.

Your declarations of static vars should all be together at the top.

There are some serious formatting issues in LoadFoldeItems, i'm going to blame monodevelop, but you still need to clean them up. You dont need to call dbcon.Close (), that's the point of the using statements. Can you document why you're using the parameters to GetString and GetInt32? the 0s, 1s, and 2s seem arbitrary. Make them meaningful. LoadPlaceItems () has similar criticisms to LoadFolderItems.

FABarItem's class bracket should be on the line below
organize your variable declarations by length, same for their initializations in the constructor.

review: Needs Fixing
594. By Neal Stewart <email address hidden>

FUNCTION CHANGES -----

Created BrowseBookmarkItem and BrowseHistoryItem.
ChildrenOfItems given for both. Provide what you'd expect.

Feeding Main Firefox application those items.

Firefox Awesome Bar item provides those items, as well as Bookmarks, to
the main list.

See ChildrenOfItem in FABarItemSource for details.

FORMAT CHANGES -----

Now complying to Mono standards in method calls and parameters.

Instantiated SQlite search results to provide code clarity.

Changed connection string creation from string literal to concatenated
string.

595. By Neal Stewart <email address hidden>

Hopefully fixed the SQL formatting problems with Loggerhead...hopefully.

596. By Neal Stewart <email address hidden>

Changed some method names.

597. By Neal Stewart <email address hidden>

fixins

598. By Neal Stewart <email address hidden>

Changed Collection searching to LINQ

Some housekeeping.

599. By Neal Stewart <email address hidden>

Removed Path.Combine(Path.Combine...

Now using Linq.

600. By Neal Stewart <email address hidden>

Changed from Community to Official.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Firefox/Firefox.mdp'
2--- Firefox/Firefox.mdp 2009-02-28 16:16:48 +0000
3+++ Firefox/Firefox.mdp 2009-04-11 21:58:01 +0000
4@@ -18,12 +18,19 @@
5 <File name="src" subtype="Directory" buildaction="Compile" />
6 <File name="src/BookmarkItemSource.cs" subtype="Code" buildaction="Compile" />
7 <File name="Resources/Firefox.addin.xml" subtype="Code" buildaction="EmbedAsResource" />
8+ <File name="src/FABarItemSource.cs" subtype="Code" buildaction="Compile" />
9+ <File name="src/FABarItems.cs" subtype="Code" buildaction="Compile" />
10 </Contents>
11 <References>
12 <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
13 <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
14- <ProjectReference type="Gac" localcopy="True" refto="Do.Platform, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null" />
15- <ProjectReference type="Gac" localcopy="True" refto="Do.Universe, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null" />
16 <ProjectReference type="Gac" localcopy="True" refto="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
17+ <ProjectReference type="Gac" localcopy="True" refto="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
18+ <ProjectReference type="Gac" localcopy="True" refto="Mono.Data.SqliteClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
19+ <ProjectReference type="Gac" localcopy="True" refto="Do.Platform, Version=0.9.0.0, Culture=neutral, PublicKeyToken=null" />
20+ <ProjectReference type="Gac" localcopy="True" refto="Do.Platform.Linux, Version=0.9.0.0, Culture=neutral, PublicKeyToken=null" />
21+ <ProjectReference type="Gac" localcopy="True" refto="Do.Universe, Version=0.9.0.0, Culture=neutral, PublicKeyToken=null" />
22+ <ProjectReference type="Gac" localcopy="True" refto="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
23+ <ProjectReference type="Gac" localcopy="True" refto="Mono.Data.SqliteClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
24 </References>
25-</Project>
26\ No newline at end of file
27+</Project>
28
29=== modified file 'Firefox/Makefile.am'
30--- Firefox/Makefile.am 2009-01-09 05:04:13 +0000
31+++ Firefox/Makefile.am 2009-04-11 21:58:01 +0000
32@@ -3,7 +3,8 @@
33 ASSEMBLY=Firefox
34
35 FILES = \
36- src/BookmarkItemSource.cs
37+ src/FABarItemSource.cs \
38+ src/FABarItems.cs
39
40 RESOURCES = \
41 Resources/Firefox.addin.xml
42@@ -12,5 +13,7 @@
43 Mono.Posix \
44 System \
45 System.Core \
46+ System.Data \
47+ Mono.Data.SqliteClient \
48 $(DO_PLATFORM_LIBS) \
49 $(DO_UNIVERSE_LIBS)
50
51=== modified file 'Firefox/Resources/Firefox.addin.xml'
52--- Firefox/Resources/Firefox.addin.xml 2009-01-16 23:29:46 +0000
53+++ Firefox/Resources/Firefox.addin.xml 2009-04-11 21:58:01 +0000
54@@ -1,11 +1,11 @@
55 <Addin
56 id="Firefox"
57 namespace="Do"
58- version="2.2"
59+ version="3"
60 name="Firefox"
61- description="Search Firefox 3 bookmarks."
62- author="David Siegel"
63- category="Official"
64+ description="Search Firefox 3 bookmarks, bookmark directories, and history."
65+ author="Neal Stewart"
66+ category="Community"
67 >
68
69 <Runtime>
70@@ -17,6 +17,6 @@
71 </Dependencies>
72
73 <Extension path="/Do/ItemSource">
74- <ItemSource type="Mozilla.Firefox.BookmarkItemSource" />
75+ <ItemSource type="Mozilla.Firefox.FABarItemSource" />
76 </Extension>
77 </Addin>
78
79=== added file 'Firefox/src/FABarItemSource.cs'
80--- Firefox/src/FABarItemSource.cs 1970-01-01 00:00:00 +0000
81+++ Firefox/src/FABarItemSource.cs 2009-04-12 15:14:14 +0000
82@@ -0,0 +1,285 @@
83+// FABarItemSource.cs -- Modification of BookmarkItemSource
84+//
85+// GNOME Do is the legal property of its developers. Please refer to the
86+// COPYRIGHT file distributed with this source distribution.
87+//
88+// This program is free software: you can redistribute it and/or modify
89+// it under the terms of the GNU General Public License as published by
90+// the Free Software Foundation, either version 3 of the License, or
91+// (at your option) any later version.
92+//
93+// This program is distributed in the hope that it will be useful,
94+// but WITHOUT ANY WARRANTY; without even the implied warranty of
95+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
96+// GNU General Public License for more details.
97+//
98+// You should have received a copy of the GNU General Public License
99+// along with this program. If not, see <http://www.gnu.org/licenses/>.
100+//
101+
102+using System;
103+using System.IO;
104+using System.Data;
105+using System.Linq;
106+using System.Collections.Generic;
107+
108+using Do.Universe;
109+using Do.Universe.Common;
110+
111+using Mono.Data.SqliteClient;
112+using Mono.Unix;
113+
114+namespace Mozilla.Firefox
115+{
116+ public class FABarItemSource : ItemSource
117+ {
118+ const string BeginProfileName = "Path=";
119+ const string BeginDefaultProfile = "Default=1";
120+
121+
122+ List<Item> items;
123+ IEnumerable<PlaceItem> places;
124+ IEnumerable<FolderItem> folders;
125+ public FABarItemSource ()
126+ {
127+ places = Enumerable.Empty<PlaceItem> ();
128+ folders = Enumerable.Empty<FolderItem> ();
129+ items = new List<Item> ();
130+ }
131+
132+ public override IEnumerable<Type> SupportedItemTypes {
133+ get {
134+ yield return typeof (PlaceItem);
135+ yield return typeof (FolderItem);
136+ yield return typeof (IApplicationItem);
137+ }
138+ }
139+
140+ public override string Name {
141+ get { return Catalog.GetString ("Firefox Bookmarks"); }
142+ }
143+
144+ public override string Description {
145+ get { return Catalog.GetString ("Search through your bookmarks."); }
146+ }
147+
148+ public override string Icon {
149+ get { return "firefox-3.0"; }
150+ }
151+
152+
153+ public override IEnumerable<Item> Items {
154+ get { return items; }
155+ }
156+
157+ public override void UpdateItems ()
158+ {
159+ this.places = LoadPlaceItems ();
160+ this.folders = LoadFolderItems ();
161+ items.Clear();
162+ // Feed the main itemsource only Bookmark places and directories.
163+ foreach (FolderItem folder in folders) items.Add((Item) folder);
164+ foreach (PlaceItem place in places)
165+ if (place.ParentId != null) items.Add((Item) place);
166+ }
167+
168+ public override IEnumerable<Item> ChildrenOfItem (Item item) {
169+ // If it's the Firefox Application Item, give them everything.
170+ if (isFirefox(item)) {
171+ UpdateItems();
172+ foreach (Item folder in folders) yield return folder;
173+ foreach (Item place in places) yield return place;
174+ }
175+
176+ // If it's a folder, give them its' children.
177+ if (isFolder(item)) {
178+ FolderItem parent = (FolderItem) item;
179+ foreach (FolderItem folder in folders) {
180+ if (parent.Id == folder.ParentId) yield return (Item) folder;
181+ }
182+ foreach (PlaceItem place in places) {
183+ if (parent.Id == place.ParentId) yield return (Item) place;
184+ }
185+ }
186+ }
187+
188+ bool isFirefox(Item item) {
189+ return item.Equals(Do.Platform.Services.UniverseFactory.MaybeApplicationItemFromCommand("firefox"));
190+ }
191+
192+ bool isFolder(Item item) {
193+ return item is FolderItem;
194+ }
195+
196+ /// <summary>
197+ /// Looks in the firefox profiles file (~/.mozilla/firefox/profiles.ini)
198+ /// for the name of the default profile, and returns the path to the
199+ /// default profile.
200+ /// </summary>
201+ /// <returns>
202+ /// A <see cref="System.String"/> containing the absolute path to the
203+ /// bookmarks.html file of the default firefox profile for the current
204+ /// user.
205+ /// </returns>
206+ static string storedProfilePath;
207+ static string ProfilePath {
208+ get {
209+ string line, profile, path, home;
210+
211+ if (!String.IsNullOrEmpty(storedProfilePath)) return storedProfilePath;
212+
213+ home = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
214+ profile = null;
215+ path = Path.Combine (home, ".mozilla/firefox/profiles.ini");
216+ using (StreamReader r = File.OpenText (path)) {
217+ while (null != (line = r.ReadLine ())) {
218+ if (line.StartsWith (BeginDefaultProfile)) break;
219+ if (line.StartsWith (BeginProfileName)) {
220+ line = line.Trim ();
221+ line = line.Substring (BeginProfileName.Length);
222+ profile = line;
223+ }
224+ }
225+ }
226+ return storedProfilePath =
227+ Path.Combine (Path.Combine (home, ".mozilla/firefox"), profile);
228+ }
229+ }
230+
231+ /// <summary>
232+ /// Looks at the file currently saved in the temp folder and sees if it
233+ /// needs to be updated.
234+ /// </summary>
235+ /// <returns>
236+ /// The path of the current database file in memory.
237+ /// </returns>
238+ static string storedTempDatabasePath;
239+ static string tempDatabasePath {
240+ get {
241+ // Create a reference to the current firefox file.
242+ string firefoxPath = Path.Combine (ProfilePath, "places.sqlite");
243+
244+ // Check if the stored temp file exists.
245+ if ((String.IsNullOrEmpty(storedTempDatabasePath)) || (!File.Exists(storedTempDatabasePath))) {
246+ // If it doesn't, make one.
247+ string copyPath = Path.GetTempFileName();
248+ System.IO.File.Copy(firefoxPath, copyPath, true);
249+ storedTempDatabasePath = copyPath;
250+ }
251+ else if (File.Exists(storedTempDatabasePath))
252+ {
253+ FileInfo currentFileInfo = new FileInfo(firefoxPath);
254+ FileInfo firefoxFileInfo = new FileInfo(storedTempDatabasePath);
255+
256+ if (currentFileInfo.Length != firefoxFileInfo.Length)
257+ System.IO.File.Copy(firefoxPath, storedTempDatabasePath, true);
258+ }
259+
260+ return storedTempDatabasePath;
261+ }
262+ }
263+
264+ /// <summary>
265+ /// Creates the current SQL connection string to the temporary database in use.
266+ /// </summary>
267+ /// <returns>
268+ /// The current SQL connection string to the temporary database in use.
269+ /// </returns>
270+ string connectionString {
271+ get { return String.Format ("URI=file:{0},version=3",tempDatabasePath); }
272+ }
273+
274+ /// <summary>
275+ /// Opens a connection to the current temporary database copy,
276+ /// and searches for bookmark directories, then adds those to
277+ /// the IEnumerable collection to be returned.
278+ /// </summary>
279+ /// <returns>
280+ /// A collection of bookmark directory Folder Items.
281+ /// </returns>
282+ IEnumerable<FolderItem> LoadFolderItems ()
283+ {
284+
285+ using (IDbConnection dbcon = (IDbConnection) new SqliteConnection(connectionString)) {
286+ dbcon.Open();
287+ using (IDbCommand dbcmd = dbcon.CreateCommand()) {
288+ dbcmd.CommandText = @"SELECT title,
289+ id,
290+ parent
291+ FROM moz_bookmarks
292+ WHERE type = 2";
293+ using (IDataReader reader = dbcmd.ExecuteReader()) {
294+ while(reader.Read()) {
295+ string title = reader.GetString(0);
296+ int id = reader.GetInt32(1);
297+ /* Firefox's parent system uses the field with ID 1 as a
298+ * parent for all other directories. It doesn't have a name,
299+ * so we'll give it one. */
300+ if (id == 1)
301+ yield return new FolderItem("Mozilla Bookmarks",
302+ reader.GetInt32(1),
303+ reader.GetInt32(2));
304+ /* Firefox uses another field that doesn't have a name.
305+ * It references portions of their menu that generate
306+ * information dynamically from History, Tags, etc.
307+ * Ignore it. */
308+ else if (title != "") {
309+ yield return new FolderItem(title,
310+ reader.GetInt32(1),
311+ reader.GetInt32(2));
312+ }
313+ }
314+ }
315+ }
316+ dbcon.Close();
317+ }
318+ }
319+
320+ /// <summary>
321+ /// Opens a connection to the current temporary database, and searches for all
322+ /// place entries then adds those to the IEnumerable collection to be returned.
323+ /// </summary>
324+ /// <returns>
325+ /// A collection of bookmarks and history Place Items.
326+ /// </returns>
327+ IEnumerable<PlaceItem> LoadPlaceItems ()
328+ {
329+ using (IDbConnection dbcon = (IDbConnection) new SqliteConnection(connectionString)) {
330+ dbcon.Open();
331+ using (IDbCommand dbcmd = dbcon.CreateCommand()) {
332+ dbcmd.CommandText = @"SELECT moz_places.title,
333+ moz_places.url,
334+ moz_bookmarks.parent,
335+ moz_bookmarks.title
336+ FROM moz_places LEFT OUTER JOIN moz_bookmarks
337+ ON moz_places.id=moz_bookmarks.fk
338+ ORDER BY moz_places.frecency DESC";
339+ using (IDataReader reader = dbcmd.ExecuteReader()) {
340+ while(reader.Read()) {
341+ string url = reader.GetString(1);
342+ // Firefox stores some interesting non-url places. Ignore them.
343+ if (url[0] != 'p') {
344+ string title = reader.GetString(0);
345+ // If the place is a bookmark, use the title stored in Bookmarks.
346+ if (!reader.IsDBNull(2))
347+ yield return new PlaceItem (reader.GetString(3),
348+ reader.GetString(1),
349+ reader.GetInt32(2));
350+ // If the place has no title, use the url as a title so it's searchable.
351+ else if (title == "")
352+ yield return new PlaceItem (reader.GetString(1),
353+ reader.GetString(1));
354+ else
355+ yield return new PlaceItem (title,
356+ reader.GetString(1));
357+ }
358+ }
359+ }
360+ }
361+ dbcon.Close();
362+ }
363+ }
364+ }
365+}
366+
367+
368
369=== added file 'Firefox/src/FABarItems.cs'
370--- Firefox/src/FABarItems.cs 1970-01-01 00:00:00 +0000
371+++ Firefox/src/FABarItems.cs 2009-04-11 21:58:01 +0000
372@@ -0,0 +1,79 @@
373+// FABarItems.cs
374+// GNOME Do is the legal property of its developers, whose names are too
375+// numerous to list here. Please refer to the COPYRIGHT file distributed with
376+// this source distribution.
377+//
378+// This program is free software: you can redistribute it and/or modify
379+// it under the terms of the GNU General Public License as published by
380+// the Free Software Foundation, either version 3 of the License, or
381+// (at your option) any later version.
382+//
383+// This program is distributed in the hope that it will be useful,
384+// but WITHOUT ANY WARRANTY; without even the implied warranty of
385+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
386+// GNU General Public License for more details.
387+//
388+// You should have received a copy of the GNU General Public License
389+// along with this program. If not, see <http://www.gnu.org/licenses/>.
390+
391+using System;
392+using Do.Universe;
393+using Do.Universe.Common;
394+
395+
396+namespace Mozilla.Firefox
397+{
398+ public class FolderItem : Item {
399+ string title;
400+ int id;
401+ int parentID;
402+
403+ public FolderItem (string title, int id)
404+ {
405+ this.title = title;
406+ this.id = id;
407+ }
408+
409+ public FolderItem (string title, int id, int parentID)
410+ {
411+ this.title = title;
412+ this.id = id;
413+ this.parentID = parentID;
414+ }
415+
416+ public override string Name { get { return title; } }
417+ public override string Description { get { return "Mozilla Firefox Bookmark Directory"; } }
418+ public override string Icon { get { return "folder"; } }
419+ public int Id { get { return id; } }
420+ public int ParentId {
421+ get { return parentID; }
422+ }
423+ }
424+
425+ public class PlaceItem : Item, IBookmarkItem
426+ {
427+ string title, url;
428+ int? parentID;
429+
430+ public PlaceItem (string title, string url)
431+ {
432+ this.title = title;
433+ this.url = url;
434+ }
435+
436+ public PlaceItem (string title, string url, int parentID)
437+ {
438+ this.title = title;
439+ this.url = url;
440+ this.parentID = parentID;
441+ }
442+
443+ public override string Name { get { return title; } }
444+ public override string Description { get { return url; } }
445+ public override string Icon { get { return "www"; } }
446+ public string Url { get { return url; } }
447+ public int? ParentId {
448+ get { return parentID; }
449+ }
450+ }
451+}

Subscribers

People subscribed via source and target branches