X-Git-Url: http://git.roojs.org/?p=gitlive;a=blobdiff_plain;f=Monitor.vala;h=5b12963d5972dd94f8f87a77fa2f0f8bf7d3d1fb;hp=daf79d0d1ea2adf9327c5f263d1cd57c40b5683f;hb=refs%2Fheads%2Fwip_alan_T5632_cache_project_listing;hpb=accd5e9c739f8d96741c73cfc35625e9f9d519ca diff --git a/Monitor.vala b/Monitor.vala index daf79d0d..5b12963d 100644 --- a/Monitor.vala +++ b/Monitor.vala @@ -5,21 +5,29 @@ //var XObject = imports.XObject.XObject; //var File = imports.File.File; - +/// # valac --pkg gio-2.0 --pkg posix Monitor.vala -o /tmp/Monitor -using Gee; // for array list? - +//using Gee; // for array list? +/* static int main (string[] args) { // A reference to our file - var file = File.new_for_path ("data.txt"); + //var file = File.new_for_path ("data.txt"); + MainLoop loop = new MainLoop (); + print("starting"); + var m = new Monitor(); + + m.add("/home/alan/gitlive"); + m.start(); + loop.run (); + return 0; } +*/ - -class MonitorNamePathDir { - +public class MonitorNamePathDir { + public string action; public string name; public string path; public string dir; @@ -29,10 +37,16 @@ class MonitorNamePathDir { this.name = name; this.path = path; this.dir = dir; + this.action = "?"; } } + + +public delegate void onEventHander (FileMonitor fm, File f_orig, File of_orig, FileMonitorEvent event_type); + + /** * Monitor class - handles monitor managment for a large tree... * @@ -54,7 +68,12 @@ class MonitorNamePathDir { * */ -public class Monitor : Object +public abstract class gitMonitorBase : Object +{ + public abstract void monitor(string path, int depth = 0); +} + +public class Monitor : gitMonitorBase { @@ -63,28 +82,30 @@ public class Monitor : Object { - this.monitors = new ArrayList (); - this.top = new ArrayList (); + this.monitors = new Array (); + this.top = new Array (); this.paused = false; } - public ArrayList monitors;// Array of GioFileMonitors - public ArrayList top; // list of top level directories.. + public Array monitors;// Array of MonitorNamePathDirileMonitors + public Array top; // list of top level directories.. public bool paused; /** * add a directory or file to monitor */ public void add (string add) { - this.top.add(add); + + print("Monitor.add: " + add); + this.top.append_val(add); } /** * start monitoring */ public void start() { - foreach(var in in this.top) { - this.monitor(this.top[i]); + for(int i = 0; i < this.top.length ; i++) { + this.monitor(this.top.index(i)); } } /** @@ -94,10 +115,10 @@ public class Monitor : Object public void stop() { - foreach(var i in this.monitors) { - this.monitors[i].cancel(); + for(int i = 0; i < this.monitors.length ; i++) { + this.monitors.index(i).cancel(); } - this.monitors = new ArrayList(); // clean /destroy/ kill old? + this.monitors = new Array(); // clean /destroy/ kill old? } /** * pause monitoring - without changing what's monitored @@ -120,10 +141,10 @@ public class Monitor : Object * * */ - public void monitor(string path, string fn, int depth) + public override void monitor(string path, int depth = 0) { - // print("ADD: " + path) + //GLib.debug("ADD: (%d): %s\n", depth, path); //depth = typeof(depth) == 'number' ? depth *1 : 0; depth = depth > 0 ? depth *1 : 0; @@ -132,15 +153,23 @@ public class Monitor : Object //fn = fn || function (fm, f, of, event_type, uh) { // _this.onEvent(fm, f, of, event_type, uh); //} - - + var f = File.new_for_path(path); //var cancel = new Gio.Cancellable (); - if (depth > 0) { - var fm = f.monitor(FileMonitorFlags.SEND_MOVED,null); //Gio.FileMonitorFlags.SEND_MOVED - - fm.changed.connect(onEvent); - this.monitors.add(fm); + if (depth > 0) { + + try { + var fm = f.monitor(FileMonitorFlags.SEND_MOVED + FileMonitorFlags.WATCH_MOVES,null); + //var fm = f.monitor(FileMonitorFlags.WATCH_MOVES,null); + + fm.changed.connect( this.onEvent ); + this.monitors.append_val(fm); + + } catch (Error e) { + GLib.debug("Error adding monitor: %s\n", e.message); + GLib.debug("Try: \n\nsudo su\necho 512 > /proc/sys/fs/inotify/max_user_instances\n"); + // FIXME -- show error? do nothing.. + } // print("ADD path " + depth + ' ' + path); } // iterate children? @@ -149,27 +178,44 @@ public class Monitor : Object // this.initRepo(path); //} - - var enumerator = directory.enumerate_children (FILE_ATTRIBUTE_STANDARD_NAME, 0, null); - - - var file_enum = f.enumerate_children( - FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME + ','+ FILE_ATTRIBUTE_STANDARD_TYPE, - 0, // FileQueryInfoFlags.NONE, - null); - + FileEnumerator file_enum; + var cancellable = new Cancellable (); + try { + file_enum = f.enumerate_children( + FileAttribute.STANDARD_DISPLAY_NAME + "," + FileAttribute.STANDARD_TYPE, + FileQueryInfoFlags.NOFOLLOW_SYMLINKS, // FileQueryInfoFlags.NONE, + cancellable); + } catch (Error e) { + // FIXME - show error.. + return; + } FileInfo next_file; - while ((next_file = file_enum.next_file(null)) != null) { - + while (cancellable.is_cancelled () == false ) { + try { + next_file = file_enum .next_file (cancellable); + } catch(Error e) { + print(e.message); + break; + } + + if (next_file == null) { + break; + } + //print("got a file " + next_file.sudo () + '?=' + Gio.FileType.DIRECTORY); - - if (next_file.get_file_type() != FILETYPE_DIRECTORY) { + + if (next_file.get_file_type() != FileType.DIRECTORY) { next_file = null; continue; } - - if (next_file.get_file_type() == FILETYPE_SYMBOLIC_LINK) { + + + //stdout.printf("Monitor.monitor: got file %s : type :%u\n", + // next_file.get_display_name(), next_file.get_file_type()); + + + if (next_file.get_is_symlink()) { next_file = null; continue; } @@ -178,7 +224,7 @@ public class Monitor : Object next_file = null; continue; } - var sp = path+'/'+next_file.get_display_name(); + var sp = path+"/"+next_file.get_display_name(); // skip modules. //print("got a file : " + sp); @@ -186,11 +232,14 @@ public class Monitor : Object - this.monitor(sp, fn, depth + 1); + this.monitor(sp, depth + 1); } - - file_enum.close(null); + try { + file_enum.close(null); + } catch(Error e) { + // ignore? + } } @@ -211,37 +260,31 @@ public class Monitor : Object // FIX ME - string split?/? var bn = file.get_basename(); - var ar = file.get_path()).to_string().split('/'); - ar.pop(); - var dirname = ar.join('/'); + var ar = file.get_path().split("/"); + ar.resize(ar.length-1); + var dirname = string.joinv("/",ar ); var rp = Posix.realpath(dirname); - return File.new_for_path(rp + '/' + bn); + return File.new_for_path(rp + "/" + bn); } - public void onEvent(FileMonitor fm, File f_orig, File of_orig, FileMonitorEvent event_type) + public void onEvent(File f_orig, File? of_orig, FileMonitorEvent event_type) { if (this.paused) { return; } - + // print("onEvent\n"); var f = this.realpath(f_orig); - var of = this.realpath(of_orig); - + MonitorNamePathDir src = new MonitorNamePathDir( f.get_basename(), f.get_path() , Path.get_dirname(f.get_path())); - MonitorNamePathDir src = new MonitorNamePathDir( f.get_basename(), f.get_path() , GLib.path_get_dirname(f.get_path())); - MonitorNamePathDir dest = null; - if (of) { - dest = new MonitorNamePathDir( of.get_basename(), of.get_path(), GLib.path_get_dirname(of.get_path())); - - } - string event_name = "UKNOWN"; + + //string event_name = "UKNOWN"; // extract the event names ... - not sure if introspection is feasible in vala.. @@ -251,36 +294,62 @@ public class Monitor : Object // } //} + + + //print (JSON.stringify([event_name , f.get_path(), of ? of.get_path() : false ] )); //print ("got src: " + src.toString()); //print ("got event: " + src.toString()); try { + switch(event_type) { - case Gio.FileMonitorEvent.CHANGED: + case FileMonitorEvent.CHANGED: + src.action = "changed"; this.onChanged(src); return; // ingore thise?? -wait for changes_done_htin? - case Gio.FileMonitorEvent.CHANGES_DONE_HINT: + case FileMonitorEvent.CHANGES_DONE_HINT: + src.action = "changed"; this.onChangesDoneHint(src); return; - case Gio.FileMonitorEvent.DELETED: + case FileMonitorEvent.DELETED: + src.action = "rm"; this.onDeleted(src); return; - case Gio.FileMonitorEvent.CREATED: + case FileMonitorEvent.CREATED: + src.action = "created"; this.onCreated(src); return; - case Gio.FileMonitorEvent.ATTRIBUTE_CHANGED: // eg. chmod/chatt + case FileMonitorEvent.ATTRIBUTE_CHANGED: // eg. chmod/chatt + src.action = "attrib"; this.onAttributeChanged(src); return; - case Gio.FileMonitorEvent.MOVED: // eg. chmod/chatt + case FileMonitorEvent.MOVED: // eg. chmod/chatt + case FileMonitorEvent.MOVED_IN: // eg. chmod/chatt + case FileMonitorEvent.MOVED_OUT: // eg. chmod/chatt + case FileMonitorEvent.RENAMED: // eg. chmod/chatt + + var of = this.realpath(of_orig); + var dest = new MonitorNamePathDir( + of.get_basename(), + of.get_path(), + Path.get_dirname(of.get_path()) + ); + + src.action = "moved"; + dest.action = "moved"; this.onMoved(src,dest); return; - + + + default: + stdout.printf("event type not handled %u", event_type); + break; // rest are mount related - not really relivant.. maybe add later.. } } catch(Error e) { @@ -289,14 +358,15 @@ public class Monitor : Object } + /** override these to do stuff.. */ - public void initRepo(MonitorNamePathDir src) { } // called on startup at the top level repo dir. - public void onChanged(MonitorNamePathDir src) { } - public void onChangesDoneHint(MonitorNamePathDir src) { } - public void onDeleted(MonitorNamePathDir src) { } - public void onCreated(MonitorNamePathDir src) { } - public void onAttributeChanged(MonitorNamePathDir src) { } - public void onMoved(MonitorNamePathDir src) { } + //public void initRepo(MonitorNamePathDir src) { } // called on startup at the top level repo dir. + public virtual void onChanged(MonitorNamePathDir src) { } + public virtual void onChangesDoneHint(MonitorNamePathDir src) { } + public virtual void onDeleted(MonitorNamePathDir src) { } + public virtual void onCreated(MonitorNamePathDir src) { } + public virtual void onAttributeChanged(MonitorNamePathDir src) { } + public virtual void onMoved(MonitorNamePathDir src,MonitorNamePathDir dest) { } }