1 //<Script type="text/javascript">
2 //var Gio = imports.gi.Gio;
3 //var GLib = imports.gi.GLib;
5 //var XObject = imports.XObject.XObject;
6 //var File = imports.File.File;
8 /// # valac --pkg gio-2.0 --pkg posix Monitor.vala -o /tmp/Monitor
11 //using Gee; // for array list?
13 static int main (string[] args) {
14 // A reference to our file
15 //var file = File.new_for_path ("data.txt");
16 MainLoop loop = new MainLoop ();
18 var m = new Monitor();
20 m.add("/home/alan/gitlive");
29 public class MonitorNamePathDir {
35 public MonitorNamePathDir(string name, string path, string dir)
47 public delegate void onEventHander (FileMonitor fm, File f_orig, File of_orig, FileMonitorEvent event_type);
51 * Monitor class - handles monitor managment for a large tree...
58 change : function () {
63 * x.stop() // stops all scanning.
64 * x.play(); // starts the scanning
71 public abstract class gitMonitorBase : Object
73 public abstract void monitor(string path, int depth = 0);
76 public class Monitor : gitMonitorBase
80 static int total_monitors = 0;
85 this.monitors = new Array<FileMonitor> ();
86 this.top = new Array<string> ();
90 public Array<FileMonitor> monitors;// Array of MonitorNamePathDirileMonitors
91 public Array<string> top; // list of top level directories..
94 * add a directory or file to monitor
96 public void add (string add)
99 print("Monitor.add: " + add);
100 this.top.append_val(add);
107 for(int i = 0; i < this.top.length ; i++) {
108 this.monitor(this.top.index(i));
112 * stop / pause monitoring
118 for(int i = 0; i < this.monitors.length ; i++) {
119 this.monitors.index(i).cancel();
121 this.monitors = new Array<FileMonitor>(); // clean /destroy/ kill old?
124 * pause monitoring - without changing what's monitored
131 * resume monitoring - without changing what's monitored
138 * monitor a file or directory (privatish)
140 * initially called with ~/gitlive null 0 (effectvely)
144 public override void monitor(string path, int depth = 0)
147 //GLib.debug("ADD: (%d): %s\n", depth, path);
149 //depth = typeof(depth) == 'number' ? depth *1 : 0;
150 depth = depth > 0 ? depth *1 : 0;
153 //fn = fn || function (fm, f, of, event_type, uh) {
154 // _this.onEvent(fm, f, of, event_type, uh);
157 var f = File.new_for_path(path);
158 //var cancel = new Gio.Cancellable ();
162 var fm = f.monitor(FileMonitorFlags.SEND_MOVED + FileMonitorFlags.WATCH_MOVES,null);
163 //var fm = f.monitor(FileMonitorFlags.WATCH_MOVES,null);
165 fm.changed.connect( this.onEvent );
166 this.monitors.append_val(fm);
170 GLib.debug("Total Monitors this: %d, All:%d: %s", (int)this.monitors.length, total_monitors, path);
174 GLib.debug("Error adding monitor: %s\n", e.message);
175 GLib.debug("Try: \n\nsudo su\necho 512 > /proc/sys/fs/inotify/max_user_instances\n");
176 // FIXME -- show error? do nothing..
178 // print("ADD path " + depth + ' ' + path);
181 // - this is not used.
182 //if (GLib.file_test(path + '/.git' , GLib.FileTest.IS_DIR) && this.initRepo) {
184 // this.initRepo(path);
186 FileEnumerator file_enum;
187 var cancellable = new Cancellable ();
189 file_enum = f.enumerate_children(
190 FileAttribute.STANDARD_DISPLAY_NAME + "," + FileAttribute.STANDARD_TYPE,
191 FileQueryInfoFlags.NOFOLLOW_SYMLINKS, // FileQueryInfoFlags.NONE,
194 // FIXME - show error..
199 while (cancellable.is_cancelled () == false ) {
201 next_file = file_enum .next_file (cancellable);
207 if (next_file == null) {
211 //print("got a file " + next_file.sudo () + '?=' + Gio.FileType.DIRECTORY);
213 if (next_file.get_file_type() != FileType.DIRECTORY) {
219 //stdout.printf("Monitor.monitor: got file %s : type :%u\n",
220 // next_file.get_display_name(), next_file.get_file_type());
223 if (next_file.get_is_symlink()) {
228 if (next_file.get_display_name()[0] == '.') {
232 var sp = path+"/"+next_file.get_display_name();
234 //print("got a file : " + sp);
240 this.monitor(sp, depth + 1);
244 file_enum.close(null);
252 public File realpath(File file)
258 if (FileUtils.test(file.get_path(), FileTest.EXISTS)) {
259 var rp = Posix.realpath(file.get_path());
260 return File.new_for_path(rp);
263 // file does not currently exist..
266 // FIX ME - string split?/?
267 var bn = file.get_basename();
268 var ar = file.get_path().split("/");
269 ar.resize(ar.length-1);
270 var dirname = string.joinv("/",ar );
271 var rp = Posix.realpath(dirname);
272 return File.new_for_path(rp + "/" + bn);
279 public void onEvent(File f_orig, File? of_orig, FileMonitorEvent event_type)
284 // print("onEvent\n");
285 var f = this.realpath(f_orig);
288 MonitorNamePathDir src = new MonitorNamePathDir( f.get_basename(), f.get_path() , Path.get_dirname(f.get_path()));
290 GLib.debug("onEvent src: %s", f.get_path());
296 case FileMonitorEvent.CHANGED:
297 src.action = "changed";
299 return; // ingore thise?? -wait for changes_done_htin?
301 case FileMonitorEvent.CHANGES_DONE_HINT:
302 src.action = "changed";
303 this.onChangesDoneHint(src);
306 case FileMonitorEvent.DELETED:
311 case FileMonitorEvent.CREATED:
312 src.action = "created";
316 case FileMonitorEvent.ATTRIBUTE_CHANGED: // eg. chmod/chatt
317 src.action = "attrib";
318 this.onAttributeChanged(src);
321 case FileMonitorEvent.MOVED: // eg. chmod/chatt
322 case FileMonitorEvent.MOVED_IN: // eg. chmod/chatt
323 case FileMonitorEvent.MOVED_OUT: // eg. chmod/chatt
324 case FileMonitorEvent.RENAMED: // eg. chmod/chatt
325 if (of_orig == null) { // move from outside of monitoring?
331 var of = this.realpath(of_orig);
332 var dest = new MonitorNamePathDir(
335 Path.get_dirname(of.get_path())
342 src.action = "moved";
343 dest.action = "moved";
344 this.onMoved(src,dest);
349 stdout.printf("event type not handled %u", event_type);
351 // rest are mount related - not really relivant.. maybe add later..
360 /** override these to do stuff.. */
361 //public void initRepo(MonitorNamePathDir src) { } // called on startup at the top level repo dir.
362 public virtual void onChanged(MonitorNamePathDir src) { }
363 public virtual void onChangesDoneHint(MonitorNamePathDir src) { }
364 public virtual void onDeleted(MonitorNamePathDir src) { }
365 public virtual void onCreated(MonitorNamePathDir src) { }
366 public virtual void onAttributeChanged(MonitorNamePathDir src) { }
367 public virtual void onMoved(MonitorNamePathDir src,MonitorNamePathDir dest) { }