Busy Day: Nautilus Metadata and Open With Menu
- From: "Kevin Kubasik" <kevin kubasik net>
- To: Dashboard <dashboard-hackers gnome org>
- Subject: Busy Day: Nautilus Metadata and Open With Menu
- Date: Wed, 10 May 2006 15:59:31 -0400
Hey, I've been coding away today, and wanted to share what I had
finished, primarily in hopes of soliciting some code review.
- Open With Menu Stuff: I got some simple configure hackery to work
and let anyone running gtk-sharp 2.8 or above use the handy "Open
With" menu.
Bug: http://bugzilla.gnome.org/show_bug.cgi?id=330682
Patch: http://bugzilla.gnome.org/attachment.cgi?id=65175&action=diff
- Nautilus Notes : I have a system together that indexes the 'Notes'
that a user can enter in nautilus. It also has some basic
inotifyification, but that is probably going to need some looking at.
Bug: http://bugzilla.gnome.org/show_bug.cgi?id=307812
Patch: http://bugzilla.gnome.org/attachment.cgi?id=65193&action=diff
If you can spare a minute, please try them out and let me know what
you think. (I also attached both patches)
--
Cheers,
Kevin Kubasik
http://kubasik.net/blog
Index: ./beagled/FileSystemQueryable/FileSystemQueryable.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/FileSystemQueryable/FileSystemQueryable.cs,v
retrieving revision 1.106
diff -u -1 -2 -r1.106 FileSystemQueryable.cs
--- ./beagled/FileSystemQueryable/FileSystemQueryable.cs 29 Apr 2006 15:44:25 -0000 1.106
+++ ./beagled/FileSystemQueryable/FileSystemQueryable.cs 10 May 2006 19:22:14 -0000
@@ -95,24 +95,26 @@
event_backend = new InotifyBackend ();
} else {
Logger.Log.Debug ("Creating null file event backend");
event_backend = new NullFileEventBackend ();
}
tree_crawl_task = new TreeCrawlTask (new TreeCrawlTask.Handler (AddDirectory));
tree_crawl_task.Source = this;
file_crawl_task = new FileCrawlTask (this);
file_crawl_task.Source = this;
+ event_backend.CreateWatch(Environment.GetEnvironmentVariable ("HOME") +
+ "/.nautilus/metafiles");
name_resolver = (LuceneNameResolver) Driver;
PreloadDirectoryNameInfo ();
// Setup our file-name filter
filter = new FileNameFilter (this);
// Do the right thing when paths expire
DirectoryModel.ExpireEvent +=
new DirectoryModel.ExpireHandler (ExpireDirectoryPath);
}
@@ -389,34 +391,41 @@
return unique_id;
}
//////////////////////////////////////////////////////////////////////////
//
// Directory-related methods
//
private Hashtable dir_models_by_path = new Hashtable ();
- private DirectoryModel GetDirectoryModelByPath (string path)
+ public DirectoryModel GetDirectoryModelByPath (string path)
{
DirectoryModel dir;
lock (dir_models_by_path) {
dir = dir_models_by_path [path] as DirectoryModel;
if (dir != null)
return dir;
}
-
+ /*
+ if (!(roots.Contains (new DirectoryModel (path)))){
+ Console.WriteLine("Add DirModel: " + Path.GetPathRoot (path) +Path.GetFileName(path));
+ AddDirectory ( new DirectoryModel (Path.GetPathRoot (path)),
+ Path.GetFileName(path));
+
+ }
+ */
// Walk each root until we find the correct path
foreach (DirectoryModel root in roots) {
dir = root.WalkTree (path);
if (dir != null) {
lock (dir_models_by_path)
dir_models_by_path [path] = dir;
break;
}
}
return dir;
}
Index: ./beagled/FileSystemQueryable/InotifyBackend.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/FileSystemQueryable/InotifyBackend.cs,v
retrieving revision 1.14
diff -u -1 -2 -r1.14 InotifyBackend.cs
--- ./beagled/FileSystemQueryable/InotifyBackend.cs 10 Aug 2005 19:22:41 -0000 1.14
+++ ./beagled/FileSystemQueryable/InotifyBackend.cs 10 May 2006 19:22:15 -0000
@@ -71,25 +71,29 @@
{
this.queryable = queryable;
}
private void OnInotifyEvent (Inotify.Watch watch,
string path,
string subitem,
string srcpath,
Inotify.EventType type)
{
bool is_directory;
is_directory = (type & Inotify.EventType.IsDirectory) != 0;
-
+ if ( path.StartsWith (Environment.GetEnvironmentVariable ("HOME") +
+ "/.nautilus/metafiles")) {
+ NautilusEvent(path, subitem);
+ return;
+ }
queryable.ReportEventInDirectory (path);
// The case of matched move events
if ((type & Inotify.EventType.MovedTo) != 0 && srcpath != null) {
queryable.HandleMoveEvent (Path.GetDirectoryName (srcpath),
Path.GetFileName (srcpath),
path, subitem, is_directory);
return;
}
// Then this must be an unmatched moveto
// An unmatched MovedTo is like a create
@@ -122,15 +126,34 @@
}
if ((type & Inotify.EventType.CloseWrite) != 0) {
queryable.HandleAddEvent (path, subitem, is_directory);
return;
}
if ((type & Inotify.EventType.QueueOverflow) != 0) {
Logger.Log.Warn ("Inotify queue overflowed: file system is in an unknown state");
queryable.HandleOverflowEvent ();
return;
}
+ }
+
+ private void NautilusEvent(string path, string subitem)
+ {
+ if ( !(File.Exists (path+"/"+subitem)))
+ return;
+ /*
+ string directory = Path.GetFileNameWithoutExtension (subitem);
+ directory = directory.Replace ("%2F","/" );
+ if (directory.StartsWith ("file://"))
+ directory = directory.Substring ("file://".Length);
+ queryable.Recrawl (directory);
+ */
+ foreach (string s in NautilusTools.AllFiles (path+"/"+subitem)){
+ DirectoryModel dir;
+ dir = queryable.GetDirectoryModelByPath (Path.GetDirectoryName (s.Substring ("file://".Length)));
+ queryable.AddFile (dir, Path.GetFileName (s));
+ }
+
}
}
}
Index: ./Util/NautilusTools.cs
===================================================================
RCS file: /cvs/gnome/beagle/Util/NautilusTools.cs,v
retrieving revision 1.5
diff -u -1 -2 -r1.5 NautilusTools.cs
--- ./Util/NautilusTools.cs 10 Mar 2005 02:02:33 -0000 1.5
+++ ./Util/NautilusTools.cs 10 May 2006 19:22:15 -0000
@@ -38,25 +38,25 @@
public class NautilusTools {
private class XmlDocCacheItem {
public XmlDocument doc;
public DateTime timestamp;
}
static private Hashtable cache = new Hashtable ();
private NautilusTools () { } // This class is static
- static private string GetMetaFileName (string path)
+ static public string GetMetaFileName (string path)
{
string nautilusDir = Environment.GetEnvironmentVariable ("HOME") +
"/.nautilus/metafiles/file:%2F%2F";
if (path.StartsWith ("file://"))
path = path.Substring ("file://".Length);
path = Path.GetDirectoryName (Path.GetFullPath (path));
path = path.Replace ("/", "%2F");
string name = nautilusDir + path + ".xml";
// If the filename is too long, ignore it.
@@ -112,15 +112,79 @@
XmlNode attr = subnode.Attributes.GetNamedItem ("name");
return attr != null ? attr.Value : null;
}
static public string GetNotes (string path)
{
XmlNode node = GetMetaFileNode (path);
if (node == null)
return null;
XmlNode attr = node.Attributes.GetNamedItem ("annotation");
return attr != null ? attr.Value : null;
+ }
+ static public void AddNote (string path, string note)
+ {
+ XmlNode node = GetMetaFileNode (path);
+ if (node == null)
+ return;
+ XmlNode attr = node.Attributes.GetNamedItem ("annotation");
+ attr.Value= attr.Value+" "+note;
+
+ }
+ static public bool HasMetaData(string path)
+ {
+ XmlNode node = GetMetaFileNode (path);
+ if (node == null)
+ return false;
+ return true;
+ }
+
+ static public string[] AllFiles(string path)
+ {
+ //int endIndex = path.LastIndexOf(".xml");
+ //string metaFile = path.Remove(endIndex+4, path.Length-(endIndex+4));
+ //string metaFile = Path.GetFileNameWithoutExtention(path);
+
+ if (path == null)
+ return null;
+ if (!(File.Exists (path)))
+ return null;
+ XmlDocCacheItem cached = (XmlDocCacheItem) cache [path];
+ XmlDocument doc;
+ DateTime lastWrite = System.DateTime.Now;
+ try{
+ lastWrite = File.GetLastWriteTime (path);
+ }catch(System.IO.IOException e){
+ Console.WriteLine(e.Message);
+ }
+
+
+ if (cached == null || lastWrite > cached.timestamp) {
+ doc = new XmlDocument ();
+ doc.Load (new StreamReader (path));
+
+ cached = new XmlDocCacheItem ();
+ cached.doc = doc;
+ cached.timestamp = lastWrite;
+ cache [path] = cached;
+
+ } else {
+ doc = cached.doc;
+ }
+ string xpath = "/directory/file[ name]";
+ XmlNodeList xnl = doc.SelectNodes(xpath);
+ string[] files = new string[xnl.Count];
+ int i = 0;
+ string directory = Path.GetFileNameWithoutExtension (path);
+ directory = directory.Replace ("%2F","/" );
+ //Console.WriteLine("Directory: " + directory);
+ foreach (XmlNode node in xnl){
+ files[i] = Path.Combine( directory , node.Attributes.GetNamedItem("name").Value.ToString());
+ i++;
+ }
+ //foreach (string s in files)
+ // Console.WriteLine("Files: " + s);
+ return files;
}
}
}
Index: ./beagled/Filter.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Filter.cs,v
retrieving revision 1.45
diff -u -1 -2 -r1.45 Filter.cs
--- ./beagled/Filter.cs 3 Apr 2006 16:51:03 -0000 1.45
+++ ./beagled/Filter.cs 10 May 2006 19:22:15 -0000
@@ -505,25 +505,25 @@
// file soon.
FileAdvise.PreLoad (currentStream);
}
}
try {
DoOpen (info);
if (IsFinished)
return true;
else if (HasError)
return false;
-
+ DoPullPropertiesNautilus();
DoPullProperties ();
if (IsFinished)
return true;
else if (HasError)
return false;
// Close and reset our TextReader
if (currentReader != null) {
currentReader.Close ();
currentReader = null;
}
@@ -705,15 +705,28 @@
protected void AddChildIndexable (Indexable indexable)
{
this.child_indexables.Add (indexable);
}
protected void AddChildIndexables (ICollection indexables)
{
this.child_indexables.AddRange (indexables);
}
public ArrayList ChildIndexables {
get { return this.child_indexables; }
+ }
+
+ private void DoPullPropertiesNautilus()
+ {
+ FileInfo info = this.FileInfo;
+ if ( info == null )
+ return;
+ string path = info.FullName;
+ if ( NautilusTools.HasMetaData (path)) {
+ this.AddProperty ( Beagle.Property.New ("beagle:notes" ,
+ NautilusTools.GetNotes (path)));
+ }
+
}
}
}
Index: configure.in
===================================================================
RCS file: /cvs/gnome/beagle/configure.in,v
retrieving revision 1.243
diff -u -1 -2 -r1.243 configure.in
--- configure.in 1 May 2006 19:36:30 -0000 1.243
+++ configure.in 10 May 2006 16:33:50 -0000
@@ -206,24 +206,32 @@
PKG_CHECK_MODULES(LIBTRAYICON,
[
gdk-2.0 >= $GDK20_MINIMUM_VERSION
atk >= $ATK_MINIMUM_VERSION
])
AC_SUBST(LIBTRAYICON_CFLAGS)
AC_SUBST(LIBTRAYICON_LIBS)
fi
dnl ----------------------------------------------
+dnl OpenWith Menu (Requires GTK 2.8)
+ PKG_CHECK_MODULES(OPEN_WITH,
+[
+ gtk-sharp-2.0 >= 2.8
+])
+AM_CONDITIONAL(ENABLE_OPEN_WITH, test "x$OPEN_WITH" != "xno")
+dnl ----------------------------------------------
+
dnl evolution support
AC_ARG_ENABLE([evolution],
AC_HELP_STRING([--disable-evolution], [Disable evolution support (default auto)]),
enable_evo=$enableval,
enable_evo_sharp=auto)
EVO_SHARP_PREFIX=`$PKG_CONFIG --variable=prefix evolution-sharp`
EVO_LIBDIR=`$PKG_CONFIG --variable=evolibdir evolution-sharp`
AC_SUBST(EVO_LIBDIR)
@@ -671,20 +679,21 @@
Mozilla Extension? yes
Epiphany Extension? ${enable_epiphany_extension}
Local SqliteClient? ${use_local_sqlite}
Sqlite version: ${SQLITE_MAJ_VER}.x
Enable WebServices no (WebServices are deprecated)
Enable libbeagle ${enable_libbeagle}
Enable python bindings ${have_python}
Enable beagle-search GUI ${enable_gui}
+ Enable OpenWithMenu ${ENABLE_OPEN_WITH}
"
echo
if test "x$enable_epiphany_extension" = "xyes"; then
echo "NOTE: The Beagle Epiphany Extension Is Totally Insecure!"
echo " Use it at your own risk!"
echo
fi
Index: ./search/Makefile.am
===================================================================
RCS file: /cvs/gnome/beagle/search/Makefile.am,v
retrieving revision 1.16
diff -u -1 -2 -r1.16 Makefile.am
--- ./search/Makefile.am 26 Apr 2006 17:59:17 -0000 1.16
+++ ./search/Makefile.am 10 May 2006 16:33:50 -0000
@@ -1,19 +1,23 @@
CSC = mcs -debug
CSFLAGS = -target:exe
if ENABLE_DESKTOP_LAUNCH
CSFLAGS += -define:ENABLE_DESKTOP_LAUNCH
endif
+if ENABLE_OPEN_WITH
+CSFLAGS += -define:ENABLE_OPEN_WITH
+endif
+
pkglib_DATA = Search.exe Search.exe.mdb
BIN_WRAPPERS = beagle-search
beagle-search: beagle-search.in
sed -e "s:@pkglibdir@:${pkglibdir}:" < $(srcdir)/beagle-search.in > beagle-search
chmod a+x beagle-search
CSFILES = \
$(srcdir)/Category.cs \
$(srcdir)/ConversationCategory.cs \
$(srcdir)/Entry.cs \
@@ -47,26 +51,29 @@
$(srcdir)/Tiles/Spreadsheet.cs \
$(srcdir)/Tiles/TextDocument.cs \
$(srcdir)/Tiles/ThumbnailFactory.cs \
$(srcdir)/Tiles/Tile.cs \
$(srcdir)/Tiles/TileAction.cs \
$(srcdir)/Tiles/TileActivator.cs \
$(srcdir)/Tiles/TileFlat.cs \
$(srcdir)/Tiles/TileGroup.cs \
$(srcdir)/Tiles/TileTemplate.cs \
$(srcdir)/Tiles/Utils.cs \
$(srcdir)/Tiles/Video.cs \
$(srcdir)/Tiles/WebHistory.cs \
- $(srcdir)/Tiles/WidgetFu.cs
+ $(srcdir)/Tiles/WidgetFu.cs
+if ENABLE_OPEN_WITH
+TILES += $(srcdir)/Tiles/OpenWithMenu.cs
+endif
PAGES = \
$(srcdir)/Pages/Base.cs \
$(srcdir)/Pages/NoMatch.cs \
$(srcdir)/Pages/QuickTips.cs \
$(srcdir)/Pages/RootUser.cs \
$(srcdir)/Pages/StartDaemon.cs
TRAY = \
$(srcdir)/Tray/NotificationArea.cs \
$(srcdir)/Tray/TrayIcon.cs
Index: ./search/Tiles/Tile.cs
===================================================================
RCS file: /cvs/gnome/beagle/search/Tiles/Tile.cs,v
retrieving revision 1.17
diff -u -1 -2 -r1.17 Tile.cs
--- ./search/Tiles/Tile.cs 25 Apr 2006 13:05:03 -0000 1.17
+++ ./search/Tiles/Tile.cs 10 May 2006 16:33:50 -0000
@@ -170,25 +170,25 @@
protected void AddAction (TileAction action)
{
actions.Add (action);
}
private void ShowPopupMenu ()
{
Gtk.Menu menu = new Gtk.Menu ();
ActionMenuItem mi = new ActionMenuItem (new TileAction (Catalog.GetString ("Open"), Stock.Open, Open));
menu.Append (mi);
-#if NOT_YET
+#if ENABLE_OPEN_WITH
// FIXME: Disabled until we have a reasonable workaround
// for lower gtk# versions.
if (EnableOpenWith) {
OpenWithMenu owm = new OpenWithMenu (Hit ["beagle:MimeType"]);
owm.ApplicationActivated += OpenWith;
owm.AppendToMenu (menu);
}
#endif
if (Actions.Count > 0) {
SeparatorMenuItem si = new SeparatorMenuItem ();
menu.Append (si);
@@ -306,25 +306,25 @@
details.Show ();
}
}
return details;
}
}
public virtual void Open ()
{
System.Console.WriteLine ("Warning: Open method not implemented for this tile type");
}
-#if NOT_YET
+#if ENABLE_OPEN_WITH
private void OpenWith (Gnome.Vfs.MimeApplication mime_application)
{
GLib.List uri_list = new GLib.List (typeof (string));
uri_list.Append (Hit.UriAsString);
mime_application.Launch (uri_list);
}
#endif
protected void OpenFromMime (Hit hit)
{
string command = null, item;
bool expects_uris = false;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]