RooTicket.vala
[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 public class RooProject  : Object 
38 {
39         public string  id; // not really important that they are numbers..
40         public string code;
41         public string name;
42         public string type;
43  
44 }
45
46
47 static RooTicket  _RooTicket;
48
49
50
51 public class RooTicket : Object
52 {
53         
54          public enum Who {
55                 ANY,
56                 ME
57         }
58         public enum Status {
59                 ANY,
60                 ACTIVE
61         }
62         
63    //const string baseurl = "https://roojs.com/admin.php/Ro/mtrack_ticket"; 
64         const string roourl = "https://roojs.com/admin.php/Roo";        
65         public static RooTicket singleton()
66     {
67         if (_RooTicket == null) {
68             _RooTicket = new RooTicket();
69             _RooTicket.tickets = new Gee.ArrayList<RooTicket>();
70             _RooTicket.projects = new Gee.ArrayList<RooProject>();
71             _RooTicket.repos = new Gee.ArrayList<RooRepo>();
72             _RooTicket.loadRepos(); // initalize it..        
73         }
74         return _RooTicket;
75     }
76         public Gee.ArrayList<RooTicket> tickets; // only available for singletonn.
77         public Gee.ArrayList<RooProject> projects; // only available for singletonn.    
78         public Gee.ArrayList<RooRepo> repos; // only available for singletonn.          
79         
80         public Gee.ArrayList<RooOption> milestones;
81         public Gee.ArrayList<RooOption> priorities;
82         public Gee.ArrayList<RooOption> serverities;
83         public Gee.ArrayList<RooOption> classifications;
84         public Gee.ArrayList<RooOption> developers;
85                  
86         
87         public string username = ""; // only available for singletonn.
88         public string password = ""; // only available for singletonn.
89
90
91         public string  id; // not really important that they are numbers..
92         public string summary;
93         public string description;
94         public string project_id_name;
95
96
97         public string summaryToBranchName()
98         {
99                 // first 5 words of summary..
100                 var  regex = new Regex ("[^A-Za-z0-9 ]+");
101                 var str = regex.replace(this.summary, this.summary.length,0, "");
102                 string[] words = Regex.split_simple ("[ \t]+", str);
103                 var ret = "";
104                 for (var i =0; i< (words.length > 5 ? 5 : words.length); i++) {
105                         ret += ret.length > 0 ? "_" : "";
106                         ret += words[i];
107                 }
108                 return ret;
109         }
110         public string usernameLocal()
111         {
112                 // git username is an email addres... - so this reutrns the local part..
113                 //?? assumes that all members are under the same domain... normally the case......
114                 return RooTicket.singleton().username.split("@")[0];
115         
116         }
117
118         public Gee.ArrayList<RooOption> readJsonArray(Json.Array a)
119         {
120                 var ret = new Gee.ArrayList<RooOption>();
121                 for(var i = 0; i < a.get_length(); i++) {
122                         var t = a.get_object_element(i);
123                         ret.add(new RooOption(
124                                 t.get_string_member("id"),
125                                 t.get_string_member("name"),                            
126                                 t.get_string_member("display_name")
127                         ));
128                 }
129                 return ret;
130                          
131         }
132
133         public RooTicket addTicket(Json.Object t)
134         {
135                 var add = new RooTicket();
136                 add.id = t.get_string_member("id");
137                 add.summary = t.get_string_member("summary");
138                 add.description = t.get_string_member("description");
139                 add.project_id_name = t.get_string_member("project_id_name");                                           
140                 this.tickets.add(add);
141                 GLib.debug("ADD ticket  %s : %s : %s", add.id, add.summary, add.project_id_name);
142                 return add;
143         }
144         public RooProject addProject(Json.Object t)
145         {
146                 var add = new RooProject();
147                 add.id = t.get_string_member("id");
148                 add.name = t.get_string_member("name");
149                 add.type = t.get_string_member("type");
150                 add.code = t.get_string_member("code");                                         
151                 this.projects.add(add);
152                 GLib.debug("ADD project  %s : %s : %s", add.id, add.code, add.name);
153                 return add;
154         }
155         
156         public RooRepo addRepo(Json.Object t)
157         {
158                 var add = new RooRepo();
159                 add.id = t.get_string_member("id");
160                 add.shortname = t.get_string_member("shortname");
161                 add.description = t.get_string_member("description");           
162                 add.project_id = t.get_string_member("project_id");                                             
163                 this.repos.add(add);
164                 GLib.debug("ADD project  %s : %s : %s", add.id, add.shortname, add.project_id);
165                 return add;
166         }
167         
168         public RooProject? getProjectByRepo(GitRepo repo)
169         {
170                 var rt = RooTicket.singleton();
171                 
172                 if (rt.repos.size < 1) {
173                         rt.loadRepos();
174                 }
175                 if (rt.projects.size < 1) {
176                         rt.loadProjects();
177                 }
178                 
179                 var pid = "";
180                 foreach(var roo_repo in rt.repos) {
181                         if (roo_repo.shortname == repo.name) {
182                                 pid = roo_repo.project_id;
183                                 break;
184                         }
185                 }
186                 if (pid == "") {
187                         GLib.debug("getProjectByRepo: repo has no project");            
188                         return null;
189                 }
190                 // get project by id...
191                 foreach(var roo_project in rt.projects) {
192                         if (roo_project.id == pid) {
193                                 GLib.debug("getProjectByRepo: project_id = %s", pid);
194                                 return roo_project;
195                         }
196                 }
197                 GLib.debug("getProjectByRepo: can not find project");                           
198                 return null;
199         
200         }
201         
202         
203         public static RooTicket fakeTicket()
204         {
205                 var t = new RooTicket();
206                 t.id = "-1";
207                 t.summary = "";
208                 t.description = "";
209                 t.project_id_name = "";
210                 RooTicket.singleton().tickets.add(t);
211                 return t;
212         }
213         
214  
215         public RooTicket? getById(string id)
216         {
217                 foreach(var t in this.tickets) {
218                         if (t.id == id) {
219                                 return t;
220                         }
221                 }
222                 if (id == "-1") {
223                         return RooTicket.fakeTicket();
224                 }
225                 
226         return this.loadTicket(id);
227
228  
229         }
230
231
232         public RooTicket? loadTicket(string id)
233         {
234
235                    var table = new GLib.HashTable<string, string>(str_hash, str_equal);
236                    table.insert("_id",id);         
237                    
238                    var params = Soup.Form.encode_hash(table);              
239                    var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
240                    GLib.debug("request %s", url);
241                    
242                    var session = new Soup.Session ();
243                    session.timeout = 0;
244                    var message = new Soup.Message ("GET", url);
245                    RooTicket.setAuth(message);
246                    session.send_message (message);
247                    
248                    
249                    var data = (string) message.response_body.flatten().data;
250                    GLib.debug("got %s", data);
251                    try {
252                            var parser = new Json.Parser ();
253                            parser.load_from_data (data, -1);
254
255                            var response = parser.get_root().get_object();
256                            var status = response.get_boolean_member("success");
257                    
258                            if(!status){
259                                    GLib.error(response.get_string_member("errorMsg"));
260                                    return null;
261                            }
262                            var rd = response.get_object_member ("data");
263                            
264                            return this.addTicket(rd);
265                            
266                             
267                    
268                    } catch (Error e) {
269                            GLib.error(e.message);
270                            return null;
271                    }
272         }
273
274         public void loadTickets(string project_id, NotMe not_me, Closed closed)
275         {
276                 RooTicket.singleton().tickets = new Gee.ArrayList<RooTicket>();
277          
278                 
279                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
280                 if (not_me  == NotMe.FALSE) {
281                         table.insert("query[viewtype]","me");
282                 } else {
283                 
284                 }               
285                 if (closed  == Closed.TRUE) {
286                         table.insert("query[viewtype]","me");
287                 } else {
288                 
289                 }
290
291                 table.insert("limit","999");
292                 table.insert("sort","summary");
293                 table.insert("dir","ASC");
294                 
295                 if (project_id != "") {
296                         table.insert("project_id",project_id);
297                 }
298
299
300                 var params = Soup.Form.encode_hash(table);
301                 
302                 var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
303                 
304                 GLib.debug("request %s", url);
305                 
306                 var session = new Soup.Session ();
307                 session.timeout = 0;
308                 var message = new Soup.Message ("GET", url);
309                 
310                 
311                 RooTicket.setAuth(message);
312                 
313                 session.send_message (message);
314                 
315                 var data = (string) message.response_body.flatten().data;
316                 //GLib.debug("got %s", data);
317                 try {
318                         var parser = new Json.Parser ();
319                         parser.load_from_data (data, -1);
320
321                         var response = parser.get_root().get_object();
322                         var status = response.get_boolean_member("success");
323                 
324                         if(!status){
325                                 GLib.error(response.get_string_member("errorMsg"));
326                                 return;
327                         }
328                         var rd = response.get_array_member ("data");
329                         
330                         // got a valid result...
331                         var _this = RooTicket.singleton();
332                         for(var i = 0; i < rd.get_length(); i++) {
333                                 _this.addTicket(rd.get_object_element(i));
334                         }
335                          
336                 
337                 } catch (Error e) {
338                         GLib.error(e.message);
339                         return;
340                 }
341                 
342         }
343         
344         
345         public void loadProjects()
346         {
347                 RooTicket.singleton().projects = new Gee.ArrayList<RooProject>();
348          
349                 
350                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
351          
352                 table.insert("query[project_filter]","P,N,U");
353                 table.insert("limit","999");
354                 table.insert("sort","name");
355                 table.insert("dir","ASC");
356
357                 var params = Soup.Form.encode_hash(table);
358                 
359                 var url = "%s/%s?%s" . printf(roourl, "core_project", params);
360                 
361                 GLib.debug("request %s", url);
362                 
363                 var session = new Soup.Session ();
364                 session.timeout = 0;
365                 var message = new Soup.Message ("GET", url);
366                 
367                 
368                 RooTicket.setAuth(message);
369                 
370                 session.send_message (message);
371                 
372                 var data = (string) message.response_body.flatten().data;
373                 //GLib.debug("got %s", data);
374                 try {
375                         var parser = new Json.Parser ();
376                         parser.load_from_data (data, -1);
377
378                         var response = parser.get_root().get_object();
379                         var status = response.get_boolean_member("success");
380                 
381                         if(!status){
382                                 GLib.error(response.get_string_member("errorMsg"));
383                                 return;
384                         }
385                         var rd = response.get_array_member ("data");
386                         
387                         // got a valid result...
388                         var _this = RooTicket.singleton();
389                         for(var i = 0; i < rd.get_length(); i++) {
390                                 _this.addProject(rd.get_object_element(i));
391                         }
392                          
393                 
394                 } catch (Error e) {
395                         GLib.error(e.message);
396                         return;
397                 }
398                 
399         }
400         public void loadRepos()
401         {
402                 RooTicket.singleton().repos = new Gee.ArrayList<RooRepo>();
403          
404                 
405                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
406          
407
408                 table.insert("limit","999");
409                 table.insert("sort","shortname");
410                 table.insert("dir","ASC");
411
412                 var params = Soup.Form.encode_hash(table);
413                 
414                 var url = "%s/%s?%s" . printf(roourl, "mtrack_repos", params);
415                 
416                 GLib.debug("request %s", url);
417                 
418                 var session = new Soup.Session ();
419                 session.timeout = 0;
420                 var message = new Soup.Message ("GET", url);
421                 
422                 
423                 RooTicket.setAuth(message);
424                 
425                 session.send_message (message);
426                 
427                 var data = (string) message.response_body.flatten().data;
428                 //GLib.debug("got %s", data);
429                 try {
430                         var parser = new Json.Parser ();
431                         parser.load_from_data (data, -1);
432
433                         var response = parser.get_root().get_object();
434                         var status = response.get_boolean_member("success");
435                 
436                         if(!status){
437                                 GLib.error(response.get_string_member("errorMsg"));
438                                 return;
439                         }
440                         var rd = response.get_array_member ("data");
441                         
442                         // got a valid result...
443                         var _this = RooTicket.singleton();
444                         for(var i = 0; i < rd.get_length(); i++) {
445                                 _this.addRepo(rd.get_object_element(i));
446                         }
447                          
448                 
449                 } catch (Error e) {
450                         GLib.error(e.message);
451                         return;
452                 }
453                 
454         }
455         public void loadProjectOptions(string pid)
456         {
457                 var rt = RooTicket.singleton();
458                 rt.milestones = new Gee.ArrayList<RooOption>();
459                 rt.priorities =  new Gee.ArrayList<RooOption>();
460                 rt.serverities =  new Gee.ArrayList<RooOption>();
461                 rt.classifications  =  new Gee.ArrayList<RooOption>();
462                 rt.developers =  new Gee.ArrayList<RooOption>();
463  
464                 if (pid == "") {
465                         return;
466                 }
467                 
468
469
470                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
471          
472                 table.insert("_options_for",pid);
473
474                 var params = Soup.Form.encode_hash(table);
475                 
476                 var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
477                 
478                 GLib.debug("request %s", url);
479                 
480                 var session = new Soup.Session ();
481                 session.timeout = 0;
482                 var message = new Soup.Message ("GET", url);
483                 
484                 
485                 RooTicket.setAuth(message);
486                 
487                 session.send_message (message);
488                 
489                 var data = (string) message.response_body.flatten().data;
490                 //GLib.debug("got %s", data);
491                 try {
492                         var parser = new Json.Parser ();
493                         parser.load_from_data (data, -1);
494
495                         var response = parser.get_root().get_object();
496                         var status = response.get_boolean_member("success");
497                 
498                         if(!status){
499                                 GLib.error(response.get_string_member("errorMsg"));
500                                 return;
501                         }
502                         var rd = response.get_object_member ("data");
503                         
504                         rt.milestones = this.readJsonArray( rd.get_array_member("milestone"));
505                         rt.priorities = this.readJsonArray( rd.get_array_member("priority"));
506                         rt.serverities = this.readJsonArray( rd.get_array_member("severity"));
507                         rt.classifications  = this.readJsonArray( rd.get_array_member("classification"));
508                         rt.developers = this.readJsonArray( rd.get_array_member("developer"));
509  
510                         
511                         
512                         
513                         // got a valid result...
514                          
515                 
516                 } catch (Error e) {
517                         GLib.error(e.message);
518                         return;
519                 }
520                 
521         }
522         
523         public  static void setAuth(Soup.Message message) 
524         {
525                 var rs =  RooTicket.singleton();                
526                 if (rs.username.length < 1) {
527                         string str;
528                         GLib.FileUtils.get_contents(GLib.Environment.get_home_dir() + "/.netrc", out str);
529                         var lines = str.split("\n");
530                         for(var i=0; i< lines.length; i++) {
531                         // assumes one line per entry.. if not we are buggered...
532                                         GLib.debug("got %s" , lines[i]);
533                         
534                                 var bits =  Regex.split_simple ("[ \t]+", lines[i].strip());
535                                 if (bits.length < 6 || bits[0] != "machine" || bits[1] != "git.roojs.com") {
536                                         continue;
537                                 }
538                                         GLib.debug("found password?");
539                                 // we are gussing.... 
540
541                                 RooTicket.singleton().username  = bits[3];
542                                 RooTicket.singleton().password  = bits[5];              
543                         }
544                 }
545
546
547                 var authCode = Base64.encode ("%s:%s".printf(rs.username, rs.password).data);
548                 message.request_headers.append("Authorization", "Basic %s".printf(authCode));
549         
550         
551         }
552
553
554         public void close(string commits)
555     {
556                 if (this.id == "-1") {
557                         return;
558                 }
559                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
560                 table.insert("id",id);
561                 table.insert("status_name","resolved");
562                 table.insert("reason","fixed by Commits: %s".printf(commits));  
563                 var params = Soup.Form.encode_hash(table);              
564
565                 GLib.debug("request POST %s / %s", roourl, id);
566
567                 var session = new Soup.Session ();
568                 session.timeout = 0;
569                 var message = new Soup.Message ("POST", roourl + "/mtrack_ticket");
570                 RooTicket.setAuth(message);
571
572                 message.set_request ("application/x-www-form-urlencoded", Soup.MemoryUse.STATIC, params.data);
573                 session.send_message (message);
574
575
576                 var data = (string) message.response_body.flatten().data;
577                 GLib.debug("got %s", data);
578                 try {
579                            var parser = new Json.Parser ();
580                            parser.load_from_data (data, -1);
581
582                            var response = parser.get_root().get_object();
583                            var status = response.get_boolean_member("success");
584
585                            if(!status){
586                                            GLib.error(response.get_string_member("errorMsg"));
587                                            return ;
588                            }
589                                 
590                            
591                                 
592
593                 } catch (Error e) {
594                            GLib.error(e.message);
595                            return ;
596                 }
597
598    }
599         public string createTicket(     
600                         string project_id,
601                         string milestone_id,
602                         string priority_id,
603                         string classification_id,
604                         string developer_id,
605                         string summary,
606                         string description
607                 ) 
608         {
609                  
610                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
611                  
612                 table.insert("project_id", project_id);
613                 table.insert("milestone_id", milestone_id);
614                 table.insert("priority_id", priority_id);
615                 table.insert("classification_id", classification_id);
616                 table.insert("developer_id", developer_id);
617                 table.insert("summary", summary);
618                 table.insert("description", description);
619                  
620                 var params = Soup.Form.encode_hash(table);              
621
622                 GLib.debug("request POST %s / %s", roourl, id);
623
624                 var session = new Soup.Session ();
625                 session.timeout = 0;
626                 var message = new Soup.Message ("POST", roourl + "/mtrack_ticket");
627                 RooTicket.setAuth(message);
628
629                 message.set_request ("application/x-www-form-urlencoded", Soup.MemoryUse.STATIC, params.data);
630                 session.send_message (message);
631
632
633                 var data = (string) message.response_body.flatten().data;
634                 GLib.debug("got %s", data);
635                 try {
636                            var parser = new Json.Parser ();
637                            parser.load_from_data (data, -1);
638
639                            var response = parser.get_root().get_object();
640                            var status = response.get_boolean_member("success");
641
642                            if(!status){
643                                            GLib.error(response.get_string_member("errorMsg"));
644                                            return "" ;
645                            }
646                                 var rd = response.get_object_member ("data");
647                                 return rd.get_string_member("id");
648                            
649                                 
650
651                 } catch (Error e) {
652                            GLib.error(e.message);
653                            return "";
654                 }
655    
656         }
657         
658 }
659