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 gee-0.8 --pkg gio-2.0 --pkg posix Monitor.val
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 var m = new Monitor();
17 var m.add("/home/alan/gitlive");
24 public class MonitorNamePathDir {
30 public MonitorNamePathDir(string name, string path, string dir)
39 public delegate void onEventHander (FileMonitor fm, File f_orig, File of_orig, FileMonitorEvent event_type);
43 * Monitor class - handles monitor managment for a large tree...
50 change : function () {
55 * x.stop() // stops all scanning.
56 * x.play(); // starts the scanning
63 public class Monitor : Object
72 this.monitors = new Array<FileMonitor> ();
73 this.top = new Array<string> ();
77 public Array<FileMonitor> monitors;// Array of MonitorNamePathDirileMonitors
78 public Array<string> top; // list of top level directories..
81 * add a directory or file to monitor
83 public void add (string add)
85 this.top.append_val(add);
92 for(int i = 0; i < this.monitors.length ; i++) {
93 this.monitor(this.top.index(i), ( fm, f_orig, of_orig, event_type) => {
94 this.onEvent (fm, f_orig, of_orig, event_type ) ;
99 * stop / pause monitoring
105 for(int i = 0; i < this.monitors.length ; i++) {
106 this.monitors.index(i).cancel();
108 this.monitors = new Array<FileMonitor>(); // clean /destroy/ kill old?
111 * pause monitoring - without changing what's monitored
118 * resume monitoring - without changing what's monitored
125 * monitor a file or directory (privatish)
127 * initially called with ~/gitlive null 0 (effectvely)
131 public void monitor(string path, onEventHander fn , int depth = 0)
134 // print("ADD: " + path)
136 //depth = typeof(depth) == 'number' ? depth *1 : 0;
137 depth = depth > 0 ? depth *1 : 0;
140 //fn = fn || function (fm, f, of, event_type, uh) {
141 // _this.onEvent(fm, f, of, event_type, uh);
145 var f = File.new_for_path(path);
146 //var cancel = new Gio.Cancellable ();
150 var fm = f.monitor(FileMonitorFlags.SEND_MOVED,null); //Gio.FileMonitorFlags.SEND_MOVED
152 fm.changed.connect( ( fm, f_orig, of_orig, event_type) => {
154 fn (fm, f_orig, of_orig, event_type ) ;
157 //this.onEvent (fm, f_orig, of_orig, event_type ) ;
159 this.monitors.append_val(fm);
162 // FIXME -- show error? do nothing..
164 // print("ADD path " + depth + ' ' + path);
167 // - this is not used.
168 //if (GLib.file_test(path + '/.git' , GLib.FileTest.IS_DIR) && this.initRepo) {
170 // this.initRepo(path);
172 FileEnumerator file_enum;
174 file_enum = f.enumerate_children(
175 FileAttribute.STANDARD_DISPLAY_NAME + "," + FileAttribute.STANDARD_TYPE,
176 0, // FileQueryInfoFlags.NONE,
179 // FIXME - show error..
186 next_file = file_enum.next_file(null);
190 if (next_file == null) {
193 //print("got a file " + next_file.sudo () + '?=' + Gio.FileType.DIRECTORY);
195 if (next_file.get_file_type() != FileType.DIRECTORY) {
200 if (next_file.get_file_type() ==FileType.SYMBOLIC_LINK) {
205 if (next_file.get_display_name()[0] == '.') {
209 var sp = path+"/"+next_file.get_display_name();
211 //print("got a file : " + sp);
217 this.monitor(sp, fn, depth + 1);
221 file_enum.close(null);
229 public File realpath(File file)
235 if (FileUtils.test(file.get_path(), FileTest.EXISTS)) {
236 var rp = Posix.realpath(file.get_path());
237 return File.new_for_path(rp);
240 // file does not currently exist..
243 // FIX ME - string split?/?
244 var bn = file.get_basename();
245 var ar = file.get_path().split("/");
246 ar.resize(ar.length-1);
247 var dirname = string.joinv("/",ar );
248 var rp = Posix.realpath(dirname);
249 return File.new_for_path(rp + "/" + bn);
256 public void onEvent(FileMonitor fm, File f_orig, File of_orig, FileMonitorEvent event_type)
262 var f = this.realpath(f_orig);
264 var of = this.realpath(of_orig);
268 MonitorNamePathDir src = new MonitorNamePathDir( f.get_basename(), f.get_path() , Path.get_dirname(f.get_path()));
269 MonitorNamePathDir dest = null;
272 dest = new MonitorNamePathDir( of.get_basename(), of.get_path(), Path.get_dirname(of.get_path()));
275 //string event_name = "UKNOWN";
278 // extract the event names ... - not sure if introspection is feasible in vala..
279 //for(var i in Gio.FileMonitorEvent) {
280 // if (Gio.FileMonitorEvent[i] == event_type) {
285 //print (JSON.stringify([event_name , f.get_path(), of ? of.get_path() : false ] ));
286 //print ("got src: " + src.toString());
287 //print ("got event: " + src.toString());
291 case FileMonitorEvent.CHANGED:
293 return; // ingore thise?? -wait for changes_done_htin?
295 case FileMonitorEvent.CHANGES_DONE_HINT:
296 this.onChangesDoneHint(src);
299 case FileMonitorEvent.DELETED:
303 case FileMonitorEvent.CREATED:
307 case FileMonitorEvent.ATTRIBUTE_CHANGED: // eg. chmod/chatt
308 this.onAttributeChanged(src);
311 case FileMonitorEvent.MOVED: // eg. chmod/chatt
312 this.onMoved(src,dest);
315 // rest are mount related - not really relivant.. maybe add later..
323 /** override these to do stuff.. */
324 public void initRepo(MonitorNamePathDir src) { } // called on startup at the top level repo dir.
325 public void onChanged(MonitorNamePathDir src) { }
326 public void onChangesDoneHint(MonitorNamePathDir src) { }
327 public void onDeleted(MonitorNamePathDir src) { }
328 public void onCreated(MonitorNamePathDir src) { }
329 public void onAttributeChanged(MonitorNamePathDir src) { }
330 public void onMoved(MonitorNamePathDir src,MonitorNamePathDir dest) { }