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