Re: Epiphany History Dashboard backend



Dashboard folks, I received this straight from Thomas, it looks a good
patch at first glance, and in the comments below I think there are some
interesting points, so I've CCd the list with my reply.

On Thu, 2003-12-18 at 21:14, Thomas Sutton wrote:
> I've modified your code to use XPath to grab only children of the
> correct Epiphany History version 1.0 format document (<ephy_history
> version="1.0">) and to grab the children (using XPath to grab only the
> ones we want is quicker (or maybe not being XML) than running through
> them all).
> 

Yep - I was learning (By reading the code that was there) c# at the time
and didn't realise you could do this - I'd worked it out by the time I
did the rhythmbox backend but hadn't had chance to go back and fix the
ephy history one ...

> I've also included the code I stole from backend-ephybookmarks.cs to
> grab the favicons from Epiphany and am attempting to modify the
> compositing to give less tiny renditions of the favicons.

Cool.

> I've also moved a few things to that should give a very slight speedup
> in general and worse cases: only grabbing the URL if the current node
> has matched and such like.

Ok

> I am planning on adding filtering at load time to kill as much noise
> (banner farms, possibly search engines, etc) as possible to speed loads
> and searches engines. At the moment, it just stops after it has found
> ten matches (many of which will be banners and junk on many searches)

Hmmm - one of the reasons that I didn't do this limiting was that I
wanted to make sure it was returning the most recent 10 matches, can we
guarantee that based on order in the XML and order that xPath pulls out
the items? I suspected not (Or at least that it probably wasn't a good
idea to rely on it!) so ideally I would have got all matches into an
array/XML document, sorted by date and then returned the last ten but I
couldn't quite work that out ...

> but I think it would probably be useful to do some nicer filtering.
> Perhaps by collapsing very similar matches into one (though this would
> probably be rather processor intensive). It would also be nice if we
> could see all matches somehow...

Yeah - I've also had some ideas about this. Especially the rhythmbox
backend needs something like this. Ideally I'd like a backend to be able
to pass XML back to dashboard representing a structure, where items
could have actions associated with them. In this case we'd probably want
the hierarchy to be based on website, e.g.

- Pages on google.com
   Foo wins the world cup
   Health scare for Foo
+ Pages on finance.yahoo.com
+ Pages on news.bbc.co.uk

In this case it's trivial to see that you *could* do this by spitting
back some javascript/dhtml stuff and get the desired effect, however in
the rhythmbox backend I'd really like to return some XML representing:

+ Greatest Hits - "Artist Foo"
   1 - Introduction
   2 - Some other song
   3 - Yet another song
   4 - Fade Out
- My First album - "Artist Foo"
- Second album - "Artist Foo"

So you'd get a nice set of information, *but* where HTML falls short is
that you should also be able to tie system actions into each item, so
that you could present a PLAY button next to "Greatest Hits - Artist
Foo" and spawn rhythmbox --album "Greatest Hits" --artist "Artist
Foo"[1]

At this point you need some kind of XML schema generated by the backend
and understood by the frontend ... I'm not sure if this is on the
roadmap or not?[2]

> It also needs to have some form of compression for long titles and
> (especially) URLs to prevent really nasty
> running-off-the-edge-of-the-window and not-lining-up-properly display
> errors.

Yep, I think there's probably no point showing the URL (If we go with
grouping by "website" as I discussed above) Then you're just left with
titles to sort out, and we should be able to wrap them intelligently.

> A patch is attached modifying your with my changes.

>From what I can see it looks good - but I don't have:

a) CVS access to commit it
b) Time to test it right now [Or this weekend, I have Christmas family
visiting plans!]
c) A propensity for reading straight diffs [I prefer diff -u]

Hence the CC to the dashboard list - hopefully someone can review,
commit and  comment on some of the points I've made ...

Lee
[1] Assuming that we can patch rhythmbox to support that, but I imagine
it would be reasonably trivial and sensible
[2] It may even be already possible for all I know!
-- 
Lee Willis <lee leewillis co uk>
14a15,16
> using System.Reflection;
> using Gdk;
20c22
< 		XmlNodeList         titles;
---
> 		XmlNodeList         items;
25c27
< 			Name = "Web Browser History";
---
> 			this.Name = "Web Browser History";
37,38c39,40
< 				doc = new XmlDocument ();
< 				doc.Load (path);
---
> 				this.doc = new XmlDocument ();
> 				this.doc.Load (path);
40c42
< 				titles = doc.SelectNodes ("//node");
---
> 				items = this.doc.SelectNodes ("/ephy_history[ version=\"1.0\"]/node");
46a49,59
> 				Console.WriteLine ("Epiphany history backend loaded {0} items.",
>                           items.Count);
> 
> 		        path = Path.Combine (home_dir,
>                              ".gnome2/epiphany/ephy-favicon-cache.xml");
> 		        if (File.Exists (path))
> 		        {
> 		        	this.favicondoc = new XmlDocument ();
> 					this.favicondoc.Load (path);
> 		        }
> 
57d69
< 
67c79,81
< 			string html = String.Format("<table width=\"100%\" bgcolor=\"#003366\" border=0 cellpadding=0 cellspacing=0><tr><td>");
---
> 			string html = String.Format(
> 				"<table width=\"100%\" bgcolor=\"#003366\" border=0 " +
> 				"cellpadding=0 cellspacing=0><tr><td>");
69c83,85
< 			html += String.Format ("<table bgcolor=\"#003366\" cellpadding=4 cellspacing=0 width=100%>");
---
> 			html += String.Format (
> 				"<table bgcolor=\"#003366\" cellpadding=4 cellspacing=0 " +
> 				"width=100%>");
71,72c87,96
< 			html += String.Format ("<tr><td align=\"center\" valign=\"center\" bgcolor=\"#003366\"><img heiight=36 width=36 src=\"internal:bookmark.png\" border=0></td><td width=\"100%\" valign=\"center\" bgcolor=\"#003366\"><font color=#ffffff size=+2>Epiphany Recently Visited</font></td></tr></table>");
< 			html += String.Format ("<tr><td><table bgcolor=\"#003366\" cellpadding=3 cellspacing=1 width=100%>");
---
> 			html += String.Format (
> 				"<tr><td align=\"center\" valign=\"center\" " +
> 				"bgcolor=\"#003366\"><img heiight=36 width=36 " +
> 				"src=\"internal:bookmark.png\" border=0></td><td " +
> 				"width=\"100%\" valign=\"center\" bgcolor=\"#003366\">" +
> 				"<font color=#ffffff size=+2>Epiphany History</font></td>"+
> 				"</tr></table>");
> 			html += String.Format (
> 				"<tr><td><table bgcolor=\"#003366\" cellpadding=3 " +
> 				"cellspacing=1 width=100%>");
78c102
< 			foreach (XmlNode node in titles) {
---
> 			foreach (XmlNode node in this.items) {
83,94c107,110
< 
< 				foreach (XmlNode property in node.ChildNodes) {
< 
< 					string property_id = (property.Attributes["id"].Value).ToString();
< 					
< 					// Only match on page title, or URL - should this only match on title?
< 					if (property_id == "2") {
< 						PageTitle = property.InnerText.ToString();
< 					} else if (property_id == "3") {
< 						PageURL = property.InnerText.ToString();
< 					}
< 				}
---
> 				string PageIcon = "";
>         
> 				// XXX: Use XPath to grab correct children...
> 				PageTitle  = node.SelectSingleNode("property[ id=2]").InnerText;
96a113,117
> 				
> 					// Only grab this stuff if we will need it...
>         			PageURL = 
> 						node.SelectSingleNode("property[ id=3]").InnerText;
> 					PageIcon = this.GetIconPath (PageURL);
99a121
> 					//FIXED - <thsutton utas edu au>
101,117c123,140
< "<tr>" +
< "<td align=\"center\" bgcolor=\"{2}\">" +
< "<a href=\"{1}\">" +
< "<img  border=0 width=24 height=24 src=\"internal:bookmark.png\"></a></td>" +
< "<td width=\"100%\" valign=top bgcolor=\"{2}\">" +
< "<a href=\"{1}\" style=\"text-decoration: none;\">{0}<br>" +
< "<font size=-1 color=#666666>{1}</font></a>" +
< "</td>" +
< "</tr>",  PageTitle, PageURL, bgcolor);
< 
< 				match_count ++;
< 
< 				if (bgcolor == "#dddddd")
< 					bgcolor = "#ffffff";
< 				else
< 					bgcolor = "#dddddd";
< 
---
> 						"<tr>" +
> 						"<td align=\"center\" bgcolor=\"{2}\">" +
> 						"<a href=\"{1}\">" +
> 						"<img  border=0 width=24 height=24 src=\"{3}\"></a>" +
> 						"</td>" +
> 						"<td width=\"100%\" valign=top bgcolor=\"{2}\">" +
> 						"<a href=\"{1}\" style=\"text-decoration: none;\">" +
> 						"{0}<br>" +
> 						"<font size=-1 color=#666666>{1}</font></a>" +
> 						"</td>" +
> 						"</tr>",  PageTitle, PageURL, bgcolor, PageIcon);
> 
> 					match_count ++;
> 
> 					if (bgcolor == "#dddddd")
> 						bgcolor = "#ffffff";
> 					else
> 						bgcolor = "#dddddd";
119a143,153
> 				if (match_count == 10){
> 					html += String.Format (
> 						"<tr>" +
> 						"<td align=\"center\" bgcolor=\"{0}\" colspan=\"2\">" +
> 						"<span>...</span>" +
> 						"</td>" +
> 						"</tr>",  bgcolor);
> 					break;
> 				}
> 				
> 			} //foreach
121,123c155
< 			}
< 
<       html += String.Format ("</table></td></tr></table><br>");
---
>       		html += String.Format ("</table></td></tr></table><br>");
128,129c160,161
< 			return new Match (this, html, 0, String.Format ("history:{0}", clue_text));
< 		}
---
> 			return new Match (this, html, 0, 
> 				String.Format ("history:{0}", clue_text));
130a163,250
> 	
> // Below was grabbed from backend-ephybookmarks.cs and modified a bit by 
> // <thsutton utas edu au>
> 		private Stream GetImage (string name)
> 		{
> 			Assembly assembly = System.Reflection.Assembly.GetEntryAssembly ();
> 			//Console.WriteLine ("ASSEMBLY NAMED " + assembly.FullName);
> 			System.IO.Stream s = assembly.GetManifestResourceStream (name);
> 			
> 			return s;
> 		}
> 
> 		private string GetIconPath (string url)
> 		{
> 			if (favicondoc == null)
> 			        return "internal:bookmark.png";
> 
> 			int index = url.IndexOf ("/", 7);
> 			//Console.WriteLine (String.Format ("url is {0}; index is {1}", url, index));
> 			if (index > -1)
> 			   url = url.Substring (0, index);
> 			//Console.WriteLine ("url base: " + url);
> 
> 			string xpath = "descendant::node[starts-with(child::property[1]/child::text(), '" + url + "')]";
> 			//Console.WriteLine ("xpath expression: " + xpath);
> 			XmlNode fav_node = favicondoc.SelectSingleNode (xpath);
> 
> 			if (fav_node != null) {
> 				xpath = "child::property[position()=2]";
> 				XmlNode favicon = fav_node.SelectSingleNode (xpath);
> 				string home_dir = Environment.GetEnvironmentVariable ("HOME");
> 				string path = Path.Combine (home_dir, ".gnome2/epiphany/favicon_cache");
> 				string iconfile = Path.Combine (path, favicon.InnerText);
> 
> 				// Fixes bug #128935
> 				if (! File.Exists (iconfile)) {
> 					iconfile = "internal:bookmark.png";
> 				} 
> 				// XXX: Need to look at Gdk.Pixbuf to make scaling nicer.
> 				//      This will do till then...
> 				return iconfile;
> 
> 				// Composite an icon...
> 				Gdk.Pixbuf icon = new Pixbuf (iconfile);
> 				Gdk.Pixbuf bookmark =
> 					new Pixbuf (GetImage ("bookmark.png"));
> 				Gdk.Pixbuf white =
> 					new Pixbuf (GetImage ("white.png"));
> 
> 				white = white.ScaleSimple (
> 					72, 30, //dest x,y
> 					Gdk.InterpType.Bilinear);
> 					
> 				white.Composite (bookmark,
> 					 0,  0, // dest x,y
> 					72, 30, // width, height
> 					20,  0, // offset x,y
> 					 1,  1, // scaling x,y
> 					Gdk.InterpType.Bilinear,
> 					127); //Alpha
> 
> 				// I just want to make the icon be 16x16.
> 				// This does it for me!
> 				Gdk.Pixbuf small_icon = icon.ScaleSimple (
> 					28, 28, //dest x,y
> 					Gdk.InterpType.Bilinear);
> 
> 				small_icon.Composite(bookmark,
> 					 0,  0, // dest x,y
> 					28, 28, // width, height
> 					 0,  0, // offset x,y
> 					 1,  1, // scaling x,y
> 					Gdk.InterpType.Bilinear,
> 					255);   //Alpha
> 
> 				iconfile = Path.GetFileName (iconfile);
> 				string home = Environment.GetEnvironmentVariable ("HOME");
> 				iconfile = Path.Combine( Path.Combine (home,
> 				String.Format (".dashboard/tmp/")),
> 				"ephyhist-"+iconfile.ToString());
> 
> 				bookmark.Savev (iconfile, "png", null, null);
> 				return iconfile;
> 			}
> 
> 			return "internal:bookmark.png";
> 		}
> }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]