Uncommited changes synced
[gitlive] / RooTicket.vala
1 /** 
2
3 code to fetch ticket info...
4
5 */
6
7 public class RooRepo : Object 
8 {
9  
10  
11
12         public string  id; // not really important that they are numbers..
13         public string project_id;
14         public string description;
15         public string shortname;
16         
17
18 }
19
20 public class RooOption : Object 
21 {
22         
23         public string id; // not really important that they are numbers..
24         public string name;     
25         public string display_name;
26  
27         public RooOption (string id, string name, string display_name)
28         {
29                 this.id = id;
30                 this.name = name;
31                 this.display_name = name;
32         }
33
34 }
35
36
37 static RooTicket  _RooTicket;
38
39
40
41 public class RooTicket : Object
42 {
43         
44          public enum Who {
45                 ANYBODY,
46                 ME
47         }
48         public enum Status {
49                 ALL,
50                 ACTIVE
51         }
52         
53    //const string baseurl = "https://roojs.com/admin.php/Ro/mtrack_ticket"; 
54         const string roourl = "https://roojs.com/admin.php/Roo";        
55         public static RooTicket singleton()
56     {
57         if (_RooTicket == null) {
58             _RooTicket = new RooTicket();
59             _RooTicket.tickets = new Gee.ArrayList<RooTicket>();
60  
61             _RooTicket.repos = new Gee.ArrayList<RooRepo>();
62             _RooTicket.loadRepos(); // initalize it..        
63         }
64         return _RooTicket;
65     }
66         public Gee.ArrayList<RooTicket> tickets; // only available for singletonn.
67  
68         public Gee.ArrayList<RooRepo> repos; // only available for singletonn.          
69         
70         public Gee.ArrayList<RooOption> milestones;
71         public Gee.ArrayList<RooOption> priorities;
72         public Gee.ArrayList<RooOption> serverities;
73         public Gee.ArrayList<RooOption> classifications;
74         public Gee.ArrayList<RooOption> developers;
75                  
76         
77         public string username = ""; // only available for singletonn.
78         public string password = ""; // only available for singletonn.
79
80
81         public string  id; // not really important that they are numbers..
82         public string summary;
83         public string description;
84         public string project_id_name;
85
86
87         public string summaryToBranchName()
88         {
89                 // first 5 words of summary..
90                 var  regex = new Regex ("[^A-Za-z0-9 ]+");
91                 var str = regex.replace(this.summary, this.summary.length,0, "");
92                 string[] words = Regex.split_simple ("[ \t]+", str);
93                 var ret = "";
94                 for (var i =0; i< (words.length > 5 ? 5 : words.length); i++) {
95                         ret += ret.length > 0 ? "_" : "";
96                         ret += words[i];
97                 }
98                 return ret;
99         }
100         public string usernameLocal()
101         {
102                 // git username is an email addres... - so this reutrns the local part..
103                 //?? assumes that all members are under the same domain... normally the case......
104                 return RooTicket.singleton().username.split("@")[0];
105         
106         }
107
108         public Gee.ArrayList<RooOption> readJsonArray(Json.Array a)
109         {
110                 var ret = new Gee.ArrayList<RooOption>();
111                 for(var i = 0; i < a.get_length(); i++) {
112                         var t = a.get_object_element(i);
113                         ret.add(new RooOption(
114                                 t.get_string_member("id"),
115                                 t.get_string_member("name"),                            
116                                 t.get_string_member("display_name")
117                         ));
118                 }
119                 return ret;
120                          
121         }
122
123         public RooTicket addTicket(Json.Object t)
124         {
125                 var add = new RooTicket();
126                 add.id = t.get_string_member("id");
127                 add.summary = t.get_string_member("summary");
128                 add.description = t.get_string_member("description");
129                 add.project_id_name = t.get_string_member("project_id_name");                                           
130                 this.tickets.add(add);
131                 GLib.debug("ADD ticket  %s : %s : %s", add.id, add.summary, add.project_id_name);
132                 return add;
133         }
134          
135         public RooRepo addRepo(Json.Object t)
136         {
137                 var add = new RooRepo();
138                 add.id = t.get_string_member("id");
139                 add.shortname = t.get_string_member("shortname");
140                 add.description = t.get_string_member("description");           
141                 add.project_id = t.get_string_member("project_id");                                             
142                 this.repos.add(add);
143                 GLib.debug("ADD project  %s : %s : %s", add.id, add.shortname, add.project_id);
144                 return add;
145         }
146         
147  
148         
149         
150         public static RooTicket fakeTicket()
151         {
152                 var t = new RooTicket();
153                 t.id = "-1";
154                 t.summary = "";
155                 t.description = "";
156                 t.project_id_name = "";
157                 RooTicket.singleton().tickets.add(t);
158                 return t;
159         }
160         
161  
162         public RooTicket? getById(string id)
163         {
164                 foreach(var t in this.tickets) {
165                         if (t.id == id) {
166                                 return t;
167                         }
168                 }
169                 if (id == "-1") {
170                         return RooTicket.fakeTicket();
171                 }
172                 
173         return this.loadTicket(id);
174
175  
176         }
177
178
179         public RooTicket? loadTicket(string id)
180         {
181
182                    var table = new GLib.HashTable<string, string>(str_hash, str_equal);
183                    table.insert("_id",id);         
184                    
185                    var params = Soup.Form.encode_hash(table);              
186                    var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
187                    GLib.debug("request %s", url);
188                    
189                    var session = new Soup.Session ();
190                    session.timeout = 0;
191                    var message = new Soup.Message ("GET", url);
192                    RooTicket.setAuth(message);
193                    session.send_message (message);
194                    
195                    
196                    var data = (string) message.response_body.flatten().data;
197                    GLib.debug("got %s", data);
198                    try {
199                            var parser = new Json.Parser ();
200                            parser.load_from_data (data, -1);
201
202                            var response = parser.get_root().get_object();
203                            var status = response.get_boolean_member("success");
204                    
205                            if(!status){
206                                    GLib.error(response.get_string_member("errorMsg"));
207                                    return null;
208                            }
209                            var rd = response.get_object_member ("data");
210                            
211                            return this.addTicket(rd);
212                            
213                             
214                    
215                    } catch (Error e) {
216                            GLib.error(e.message);
217                            return null;
218                    }
219         }
220
221         public void loadTickets(string project_id, Who who, Status status)
222         {
223                 RooTicket.singleton().tickets = new Gee.ArrayList<RooTicket>();
224          
225                 
226                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
227
228                 table.insert("_developer", who.to_string().down().substring(15));
229                 
230                 table.insert("query[viewtype]", status.to_string().down().substring(18));
231
232                 table.insert("limit","200");
233                 table.insert("sort","summary");
234                 table.insert("dir","ASC");
235                 
236                 if (project_id != "") {
237                         table.insert("project_id",project_id);
238                 }
239
240
241                 var params = Soup.Form.encode_hash(table);
242                 
243                 var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
244                 
245                 GLib.debug("request %s", url);
246                 
247                 var session = new Soup.Session ();
248                 session.timeout = 0;
249                 var message = new Soup.Message ("GET", url);
250                 
251                 
252                 RooTicket.setAuth(message);
253                 
254                 session.send_message (message);
255                 
256                 var data = (string) message.response_body.flatten().data;
257                 //GLib.debug("got %s", data);
258                 try {
259                         var parser = new Json.Parser ();
260                         parser.load_from_data (data, -1);
261
262                         var response = parser.get_root().get_object();
263                         var success = response.get_boolean_member("success");
264                 
265                         if(!success){
266                                 GLib.error(response.get_string_member("errorMsg"));
267                                 return;
268                         }
269                         var rd = response.get_array_member ("data");
270                         
271                         // got a valid result...
272                         var _this = RooTicket.singleton();
273                         for(var i = 0; i < rd.get_length(); i++) {
274                                 _this.addTicket(rd.get_object_element(i));
275                         }
276                          
277                 
278                 } catch (Error e) {
279                         GLib.error(e.message);
280                         return;
281                 }
282                 
283         }
284         
285          
286         public void loadRepos()
287         {
288                 RooTicket.singleton().repos = new Gee.ArrayList<RooRepo>();
289          
290                 
291                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
292          
293
294                 table.insert("limit","200");
295                 table.insert("sort","shortname");
296                 table.insert("dir","ASC");
297
298                 var params = Soup.Form.encode_hash(table);
299                 
300                 var url = "%s/%s?%s" . printf(roourl, "mtrack_repos", params);
301                 
302                 GLib.debug("request %s", url);
303                 
304                 var session = new Soup.Session ();
305                 session.timeout = 0;
306                 var message = new Soup.Message ("GET", url);
307                 
308                 
309                 RooTicket.setAuth(message);
310                 
311                 session.send_message (message);
312                 
313                 var data = (string) message.response_body.flatten().data;
314                 //GLib.debug("got %s", data);
315                 try {
316                         var parser = new Json.Parser ();
317                         parser.load_from_data (data, -1);
318
319                         var response = parser.get_root().get_object();
320                         var status = response.get_boolean_member("success");
321                 
322                         if(!status){
323                                 GLib.error(response.get_string_member("errorMsg"));
324                                 return;
325                         }
326                         var rd = response.get_array_member ("data");
327                         
328                         // got a valid result...
329                         var _this = RooTicket.singleton();
330                         for(var i = 0; i < rd.get_length(); i++) {
331                                 _this.addRepo(rd.get_object_element(i));
332                         }
333                          
334                 
335                 } catch (Error e) {
336                         GLib.error(e.message);
337                         return;
338                 }
339                 
340         }
341         public void loadProjectOptions(string pid)
342         {
343                 var rt = RooTicket.singleton();
344                 rt.milestones = new Gee.ArrayList<RooOption>();
345                 rt.priorities =  new Gee.ArrayList<RooOption>();
346                 rt.serverities =  new Gee.ArrayList<RooOption>();
347                 rt.classifications  =  new Gee.ArrayList<RooOption>();
348                 rt.developers =  new Gee.ArrayList<RooOption>();
349  
350                 if (pid == "") {
351                         return;
352                 }
353                 
354
355
356                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
357          
358                 table.insert("_options_for",pid);
359
360                 var params = Soup.Form.encode_hash(table);
361                 
362                 var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
363                 
364                 GLib.debug("request %s", url);
365                 
366                 var session = new Soup.Session ();
367                 session.timeout = 0;
368                 var message = new Soup.Message ("GET", url);
369                 
370                 
371                 RooTicket.setAuth(message);
372                 
373                 session.send_message (message);
374                 
375                 var data = (string) message.response_body.flatten().data;
376                 //GLib.debug("got %s", data);
377                 try {
378                         var parser = new Json.Parser ();
379                         parser.load_from_data (data, -1);
380
381                         var response = parser.get_root().get_object();
382                         var status = response.get_boolean_member("success");
383                 
384                         if(!status){
385                                 GLib.error(response.get_string_member("errorMsg"));
386                                 return;
387                         }
388                         var rd = response.get_object_member ("data");
389                         
390                         rt.milestones = this.readJsonArray( rd.get_array_member("milestone"));
391                         rt.priorities = this.readJsonArray( rd.get_array_member("priority"));
392                         rt.serverities = this.readJsonArray( rd.get_array_member("severity"));
393                         rt.classifications  = this.readJsonArray( rd.get_array_member("classification"));
394                         rt.developers = this.readJsonArray( rd.get_array_member("developer"));
395  
396                         
397                         
398                         
399                         // got a valid result...
400                          
401                 
402                 } catch (Error e) {
403                         GLib.error(e.message);
404                         return;
405                 }
406                 
407         }
408         
409         public  static void setAuth(Soup.Message message) 
410         {
411                 var rs =  RooTicket.singleton();                
412                 if (rs.username.length < 1) {
413                         string str;
414                         GLib.FileUtils.get_contents(GLib.Environment.get_home_dir() + "/.netrc", out str);
415                         var lines = str.split("\n");
416                         for(var i=0; i< lines.length; i++) {
417                         // assumes one line per entry.. if not we are buggered...
418                                         GLib.debug("got %s" , lines[i]);
419                         
420                                 var bits =  Regex.split_simple ("[ \t]+", lines[i].strip());
421                                 if (bits.length < 6 || bits[0] != "machine" || bits[1] != "git.roojs.com") {
422                                         continue;
423                                 }
424                                         GLib.debug("found password?");
425                                 // we are gussing.... 
426
427                                 RooTicket.singleton().username  = bits[3];
428                                 RooTicket.singleton().password  = bits[5];              
429                         }
430                 }
431
432
433                 var authCode = Base64.encode ("%s:%s".printf(rs.username, rs.password).data);
434                 message.request_headers.append("Authorization", "Basic %s".printf(authCode));
435         
436         
437         }
438
439
440         public void close(string commits)
441     {
442                 if (this.id == "-1") {
443                         return;
444                 }
445                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
446                 table.insert("id",id);
447                 table.insert("status_name","resolved");
448                 table.insert("reason","fixed by Commits: %s".printf(commits));  
449                 var params = Soup.Form.encode_hash(table);              
450
451                 GLib.debug("request POST %s / %s", roourl, id);
452
453                 var session = new Soup.Session ();
454                 session.timeout = 0;
455                 var message = new Soup.Message ("POST", roourl + "/mtrack_ticket");
456                 RooTicket.setAuth(message);
457
458                 message.set_request ("application/x-www-form-urlencoded", Soup.MemoryUse.STATIC, params.data);
459                 session.send_message (message);
460
461
462                 var data = (string) message.response_body.flatten().data;
463                 GLib.debug("got %s", data);
464                 try {
465                            var parser = new Json.Parser ();
466                            parser.load_from_data (data, -1);
467
468                            var response = parser.get_root().get_object();
469                            var status = response.get_boolean_member("success");
470
471                            if(!status){
472                                            GLib.error(response.get_string_member("errorMsg"));
473                                            return ;
474                            }
475                                 
476                            
477                                 
478
479                 } catch (Error e) {
480                            GLib.error(e.message);
481                            return ;
482                 }
483
484    }
485         public string createTicket(     
486                         string project_id,
487                         string milestone_id,
488                         string priority_id,
489                         string classification_id,
490                         string developer_id,
491                         string summary,
492                         string description
493                 ) 
494         {
495                  
496                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
497                  
498                 table.insert("project_id", project_id);
499                 table.insert("milestone_id", milestone_id);
500                 table.insert("priority_id", priority_id);
501                 table.insert("classification_id", classification_id);
502                 table.insert("developer_id", developer_id);
503                 table.insert("summary", summary);
504                 table.insert("description", description);
505                  
506                 var params = Soup.Form.encode_hash(table);              
507
508                 GLib.debug("request POST %s / %s", roourl, id);
509
510                 var session = new Soup.Session ();
511                 session.timeout = 0;
512                 var message = new Soup.Message ("POST", roourl + "/mtrack_ticket");
513                 RooTicket.setAuth(message);
514
515                 message.set_request ("application/x-www-form-urlencoded", Soup.MemoryUse.STATIC, params.data);
516                 session.send_message (message);
517
518
519                 var data = (string) message.response_body.flatten().data;
520                 GLib.debug("got %s", data);
521                 try {
522                            var parser = new Json.Parser ();
523                            parser.load_from_data (data, -1);
524
525                            var response = parser.get_root().get_object();
526                            var status = response.get_boolean_member("success");
527
528                            if(!status){
529                                            GLib.error(response.get_string_member("errorMsg"));
530                                            return "" ;
531                            }
532                                 var rd = response.get_object_member ("data");
533                                 return rd.get_string_member("id");
534                            
535                                 
536
537                 } catch (Error e) {
538                            GLib.error(e.message);
539                            return "";
540                 }
541    
542         }
543         
544 }
545