Monitor.vala
[gitlive] / Monitor.vala
1 //<Script type="text/javascript">
2 //var Gio     = imports.gi.Gio;
3 //var GLib    = imports.gi.GLib;
4
5 //var XObject = imports.XObject.XObject;
6 //var File    = imports.File.File;
7
8  
9 using Gee; // for array list?
10
11 static int main (string[] args) {
12     // A reference to our file
13     var file = File.new_for_path ("data.txt");
14
15
16 }
17
18
19 class  MonitorNamePathDir {
20     
21     public string name;
22     public string path;
23     public string dir;
24     
25     public MonitorNamePathDir(string name, string path, string dir)
26     {
27         this.name = name;
28         this.path = path;
29         this.dir = dir;
30         
31     }
32 }
33
34 /**
35  * Monitor class - handles monitor managment for a large tree...
36  *
37  *
38  * This 
39  * 
40  * usage : 
41  * x = new Monitor({
42      change : function () {
43          * ....
44          *}
45   }
46  * x.add('/somepath')
47  * x.stop() // stops all scanning.
48  * x.play(); // starts the scanning
49  * 
50  * 
51  * 
52  * 
53  */
54  
55 public class Monitor : Object
56 {
57
58
59
60     public Monitor()
61     {
62        
63      
64         this.monitors = new ArrayList<FileMonitor> ();
65         this.top = new ArrayList<string> ();
66         this.paused = false;
67     }
68      
69     public ArrayList<FileMonitor> monitors;// Array of GioFileMonitors
70     public ArrayList<string> top; // list of top level directories..
71     public bool paused;
72     /**
73      * add a directory or file to monitor
74      */
75     public void add (string add)
76     {
77         this.top.add(add);
78     }
79     /**
80      * start monitoring
81      */
82     public void start()
83     {
84         foreach(var in in this.top) {
85             this.monitor(this.top[i]);
86         }
87     }
88     /**
89      * stop / pause monitoring
90      * 
91      */
92     public void stop()
93     {
94         
95         foreach(var i in  this.monitors) {
96             this.monitors[i].cancel();
97         } 
98         this.monitors = new ArrayList<FileMonitor>(); // clean /destroy/ kill old?
99     }
100     /**
101      * pause monitoring - without changing what's monitored 
102      */
103     public void pause()
104     {
105         this.paused = true;
106     }
107     /**
108      * resume monitoring - without changing what's monitored 
109      */
110     public void resume()
111     {
112         this.paused = false;
113     }
114     /**
115      * monitor a file or directory (privatish)
116      *
117      * initially called with ~/gitlive  null 0 (effectvely)
118      * 
119      * 
120      */
121     public void monitor(string path, string fn, int depth)
122     {
123          
124        // print("ADD: " + path)
125         
126         //depth = typeof(depth) == 'number'  ? depth *1 : 0;
127         depth = depth > 0  ? depth *1 : 0;
128         
129         
130         //fn = fn || function (fm, f, of, event_type, uh) {
131         //    _this.onEvent(fm, f, of, event_type, uh);
132         //}
133        
134           
135         var f = File.new_for_path(path);
136             //var cancel = new Gio.Cancellable ();
137         if (depth > 0) {     
138             var fm = f.monitor(FileMonitorFlags.SEND_MOVED,null); //Gio.FileMonitorFlags.SEND_MOVED
139             
140             fm.changed.connect(onEvent);
141             this.monitors.add(fm);
142             // print("ADD path " + depth + ' ' + path);
143         }
144         // iterate children?
145         // - this is not used.
146         //if (GLib.file_test(path + '/.git' , GLib.FileTest.IS_DIR) && this.initRepo) {
147             
148         //    this.initRepo(path);
149         //}
150         
151         var enumerator = directory.enumerate_children (FILE_ATTRIBUTE_STANDARD_NAME, 0, null);
152
153  
154          var file_enum = f.enumerate_children(
155             FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME + ','+    FILE_ATTRIBUTE_STANDARD_TYPE,
156             0, // FileQueryInfoFlags.NONE,
157             null);
158         
159         FileInfo next_file;
160         
161         while ((next_file = file_enum.next_file(null)) != null) {
162          
163             //print("got a file " + next_file.sudo () + '?=' + Gio.FileType.DIRECTORY);
164             
165             if (next_file.get_file_type() != FILETYPE_DIRECTORY) {
166                 next_file = null;
167                 continue;
168             }
169             
170             if (next_file.get_file_type() == FILETYPE_SYMBOLIC_LINK) {
171                 next_file = null;
172                 continue;
173             }
174             
175             if (next_file.get_display_name()[0] == '.') {
176                 next_file = null;
177                 continue;
178             }
179             var sp = path+'/'+next_file.get_display_name();
180             // skip modules.
181             //print("got a file : " + sp);
182          
183             next_file = null;
184             
185             
186             
187             this.monitor(sp, fn, depth + 1);
188             
189         }
190     
191         file_enum.close(null);
192     }
193     
194     
195     
196     public File realpath(File file)
197     {
198         if (file != null) {
199             return file;
200         }
201         
202         if (FileUtils.test(file.get_path(), FileTest.EXISTS)) {
203             var rp = Posix.realpath(file.get_path());
204             return File.new_for_path(rp);  
205             
206         }
207         // file does not currently exist..
208         // check parent.
209         
210 // FIX ME - string split?/? 
211         var bn = file.get_basename();
212         var ar = file.get_path().split('/');
213         ar.pop();
214         var dirname = ar.join('/');
215         var rp = Posix.realpath(dirname);
216         return File.new_for_path(rp + '/' + bn);
217         
218     }
219    
220     
221     
222      
223     public void onEvent(FileMonitor fm, File f_orig, File of_orig, FileMonitorEvent event_type)
224     {
225         if (this.paused) {
226             return;
227         }
228         
229         var f = this.realpath(f_orig);
230         
231         var of = this.realpath(of_orig);
232  
233         
234  
235         MonitorNamePathDir src = new MonitorNamePathDir( f.get_basename(), f.get_path() , GLib.path_get_dirname(f.get_path()));
236         MonitorNamePathDir dest = null;
237         
238         if (of) {
239             dest = new MonitorNamePathDir( of.get_basename(), of.get_path(),  GLib.path_get_dirname(of.get_path()));
240             
241         }
242         string event_name = "UKNOWN";
243         
244         
245         // extract the event names ... - not sure if introspection is feasible in vala..
246         //for(var i in Gio.FileMonitorEvent) {
247          //    if (Gio.FileMonitorEvent[i] == event_type) {
248          //        event_name = i;
249          //    }
250          //}
251         
252         //print (JSON.stringify([event_name , f.get_path(), of ? of.get_path() : false ] ));
253         //print ("got src: " + src.toString());
254         //print ("got event: " + src.toString());
255         try {
256                 
257             switch(event_type) {
258                 case Gio.FileMonitorEvent.CHANGED:
259                     this.onChanged(src);
260                     return; // ingore thise?? -wait for changes_done_htin?
261                     
262                 case Gio.FileMonitorEvent.CHANGES_DONE_HINT:
263                     this.onChangesDoneHint(src);
264                     return;
265                     
266                 case Gio.FileMonitorEvent.DELETED:
267                     this.onDeleted(src);
268                     return;
269                     
270                 case Gio.FileMonitorEvent.CREATED:
271                     this.onCreated(src);
272                     return;
273                 
274                 case Gio.FileMonitorEvent.ATTRIBUTE_CHANGED: // eg. chmod/chatt
275                     this.onAttributeChanged(src);
276                     return;
277                 
278                 case Gio.FileMonitorEvent.MOVED: // eg. chmod/chatt
279                     this.onMoved(src,dest);
280                     return; 
281                 
282                 // rest are mount related - not really relivant.. maybe add later..
283             } 
284         } catch(Error e) {
285             print(e.message);
286         }
287         
288     }
289     
290     /** override these to do stuff.. */
291     public void initRepo(MonitorNamePathDir src) { } // called on startup at the top level repo dir.
292     public void onChanged(MonitorNamePathDir src) { }
293     public void onChangesDoneHint(MonitorNamePathDir src) { }
294     public void onDeleted(MonitorNamePathDir src) { }
295     public void onCreated(MonitorNamePathDir src) { }
296     public void onAttributeChanged(MonitorNamePathDir src) { }
297     public void onMoved(MonitorNamePathDir src) { }
298           
299     
300 }
301  
302  
303
304
305
306
307