Changed MergeBranch.bjsMergeBranch.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                 ANYBODY,
56                 ME
57         }
58         public enum Status {
59                 ALL,
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, Who who, Status status)
275         {
276                 RooTicket.singleton().tickets = new Gee.ArrayList<RooTicket>();
277          
278                 
279                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
280
281                 table.insert("_developer", who.to_string().down().substring(15));
282                 
283                 table.insert("query[viewtype]", status.to_string().down().substring(18));
284
285                 table.insert("limit","200");
286                 table.insert("sort","summary");
287                 table.insert("dir","ASC");
288                 
289                 if (project_id != "") {
290                         table.insert("project_id",project_id);
291                 }
292
293
294                 var params = Soup.Form.encode_hash(table);
295                 
296                 var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
297                 
298                 GLib.debug("request %s", url);
299                 
300                 var session = new Soup.Session ();
301                 session.timeout = 0;
302                 var message = new Soup.Message ("GET", url);
303                 
304                 
305                 RooTicket.setAuth(message);
306                 
307                 session.send_message (message);
308                 
309                 var data = (string) message.response_body.flatten().data;
310                 //GLib.debug("got %s", data);
311                 try {
312                         var parser = new Json.Parser ();
313                         parser.load_from_data (data, -1);
314
315                         var response = parser.get_root().get_object();
316                         var success = response.get_boolean_member("success");
317                 
318                         if(!success){
319                                 GLib.error(response.get_string_member("errorMsg"));
320                                 return;
321                         }
322                         var rd = response.get_array_member ("data");
323                         
324                         // got a valid result...
325                         var _this = RooTicket.singleton();
326                         for(var i = 0; i < rd.get_length(); i++) {
327                                 _this.addTicket(rd.get_object_element(i));
328                         }
329                          
330                 
331                 } catch (Error e) {
332                         GLib.error(e.message);
333                         return;
334                 }
335                 
336         }
337         
338         
339         public void loadProjects()
340         {
341                 RooTicket.singleton().projects = new Gee.ArrayList<RooProject>();
342          
343                 
344                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
345          
346                 table.insert("query[project_filter]","P,N,U");
347                 table.insert("limit","200");
348                 table.insert("sort","name");
349                 table.insert("dir","ASC");
350
351                 var params = Soup.Form.encode_hash(table);
352                 
353                 var url = "%s/%s?%s" . printf(roourl, "core_project", params);
354                 
355                 GLib.debug("request %s", url);
356                 
357                 var session = new Soup.Session ();
358                 session.timeout = 0;
359                 var message = new Soup.Message ("GET", url);
360                 
361                 
362                 RooTicket.setAuth(message);
363                 
364                 session.send_message (message);
365                 
366                 var data = (string) message.response_body.flatten().data;
367                 //GLib.debug("got %s", data);
368                 try {
369                         var parser = new Json.Parser ();
370                         parser.load_from_data (data, -1);
371
372                         var response = parser.get_root().get_object();
373                         var status = response.get_boolean_member("success");
374                 
375                         if(!status){
376                                 GLib.error(response.get_string_member("errorMsg"));
377                                 return;
378                         }
379                         var rd = response.get_array_member ("data");
380                         
381                         // got a valid result...
382                         var _this = RooTicket.singleton();
383                         for(var i = 0; i < rd.get_length(); i++) {
384                                 _this.addProject(rd.get_object_element(i));
385                         }
386                          
387                 
388                 } catch (Error e) {
389                         GLib.error(e.message);
390                         return;
391                 }
392                 
393         }
394         public void loadRepos()
395         {
396                 RooTicket.singleton().repos = new Gee.ArrayList<RooRepo>();
397          
398                 
399                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
400          
401
402                 table.insert("limit","200");
403                 table.insert("sort","shortname");
404                 table.insert("dir","ASC");
405
406                 var params = Soup.Form.encode_hash(table);
407                 
408                 var url = "%s/%s?%s" . printf(roourl, "mtrack_repos", params);
409                 
410                 GLib.debug("request %s", url);
411                 
412                 var session = new Soup.Session ();
413                 session.timeout = 0;
414                 var message = new Soup.Message ("GET", url);
415                 
416                 
417                 RooTicket.setAuth(message);
418                 
419                 session.send_message (message);
420                 
421                 var data = (string) message.response_body.flatten().data;
422                 //GLib.debug("got %s", data);
423                 try {
424                         var parser = new Json.Parser ();
425                         parser.load_from_data (data, -1);
426
427                         var response = parser.get_root().get_object();
428                         var status = response.get_boolean_member("success");
429                 
430                         if(!status){
431                                 GLib.error(response.get_string_member("errorMsg"));
432                                 return;
433                         }
434                         var rd = response.get_array_member ("data");
435                         
436                         // got a valid result...
437                         var _this = RooTicket.singleton();
438                         for(var i = 0; i < rd.get_length(); i++) {
439                                 _this.addRepo(rd.get_object_element(i));
440                         }
441                          
442                 
443                 } catch (Error e) {
444                         GLib.error(e.message);
445                         return;
446                 }
447                 
448         }
449         public void loadProjectOptions(string pid)
450         {
451                 var rt = RooTicket.singleton();
452                 rt.milestones = new Gee.ArrayList<RooOption>();
453                 rt.priorities =  new Gee.ArrayList<RooOption>();
454                 rt.serverities =  new Gee.ArrayList<RooOption>();
455                 rt.classifications  =  new Gee.ArrayList<RooOption>();
456                 rt.developers =  new Gee.ArrayList<RooOption>();
457  
458                 if (pid == "") {
459                         return;
460                 }
461                 
462
463
464                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
465          
466                 table.insert("_options_for",pid);
467
468                 var params = Soup.Form.encode_hash(table);
469                 
470                 var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
471                 
472                 GLib.debug("request %s", url);
473                 
474                 var session = new Soup.Session ();
475                 session.timeout = 0;
476                 var message = new Soup.Message ("GET", url);
477                 
478                 
479                 RooTicket.setAuth(message);
480                 
481                 session.send_message (message);
482                 
483                 var data = (string) message.response_body.flatten().data;
484                 //GLib.debug("got %s", data);
485                 try {
486                         var parser = new Json.Parser ();
487                         parser.load_from_data (data, -1);
488
489                         var response = parser.get_root().get_object();
490                         var status = response.get_boolean_member("success");
491                 
492                         if(!status){
493                                 GLib.error(response.get_string_member("errorMsg"));
494                                 return;
495                         }
496                         var rd = response.get_object_member ("data");
497                         
498                         rt.milestones = this.readJsonArray( rd.get_array_member("milestone"));
499                         rt.priorities = this.readJsonArray( rd.get_array_member("priority"));
500                         rt.serverities = this.readJsonArray( rd.get_array_member("severity"));
501                         rt.classifications  = this.readJsonArray( rd.get_array_member("classification"));
502                         rt.developers = this.readJsonArray( rd.get_array_member("developer"));
503  
504                         
505                         
506                         
507                         // got a valid result...
508                          
509                 
510                 } catch (Error e) {
511                         GLib.error(e.message);
512                         return;
513                 }
514                 
515         }
516         
517         public  static void setAuth(Soup.Message message) 
518         {
519                 var rs =  RooTicket.singleton();                
520                 if (rs.username.length < 1) {
521                         string str;
522                         GLib.FileUtils.get_contents(GLib.Environment.get_home_dir() + "/.netrc", out str);
523                         var lines = str.split("\n");
524                         for(var i=0; i< lines.length; i++) {
525                         // assumes one line per entry.. if not we are buggered...
526                                         GLib.debug("got %s" , lines[i]);
527                         
528                                 var bits =  Regex.split_simple ("[ \t]+", lines[i].strip());
529                                 if (bits.length < 6 || bits[0] != "machine" || bits[1] != "git.roojs.com") {
530                                         continue;
531                                 }
532                                         GLib.debug("found password?");
533                                 // we are gussing.... 
534
535                                 RooTicket.singleton().username  = bits[3];
536                                 RooTicket.singleton().password  = bits[5];              
537                         }
538                 }
539
540
541                 var authCode = Base64.encode ("%s:%s".printf(rs.username, rs.password).data);
542                 message.request_headers.append("Authorization", "Basic %s".printf(authCode));
543         
544         
545         }
546
547
548         public void close(string commits)
549     {
550                 if (this.id == "-1") {
551                         return;
552                 }
553                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
554                 table.insert("id",id);
555                 table.insert("status_name","resolved");
556                 table.insert("reason","fixed by Commits: %s".printf(commits));  
557                 var params = Soup.Form.encode_hash(table);              
558
559                 GLib.debug("request POST %s / %s", roourl, id);
560
561                 var session = new Soup.Session ();
562                 session.timeout = 0;
563                 var message = new Soup.Message ("POST", roourl + "/mtrack_ticket");
564                 RooTicket.setAuth(message);
565
566                 message.set_request ("application/x-www-form-urlencoded", Soup.MemoryUse.STATIC, params.data);
567                 session.send_message (message);
568
569
570                 var data = (string) message.response_body.flatten().data;
571                 GLib.debug("got %s", data);
572                 try {
573                            var parser = new Json.Parser ();
574                            parser.load_from_data (data, -1);
575
576                            var response = parser.get_root().get_object();
577                            var status = response.get_boolean_member("success");
578
579                            if(!status){
580                                            GLib.error(response.get_string_member("errorMsg"));
581                                            return ;
582                            }
583                                 
584                            
585                                 
586
587                 } catch (Error e) {
588                            GLib.error(e.message);
589                            return ;
590                 }
591
592    }
593         public string createTicket(     
594                         string project_id,
595                         string milestone_id,
596                         string priority_id,
597                         string classification_id,
598                         string developer_id,
599                         string summary,
600                         string description
601                 ) 
602         {
603                  
604                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
605                  
606                 table.insert("project_id", project_id);
607                 table.insert("milestone_id", milestone_id);
608                 table.insert("priority_id", priority_id);
609                 table.insert("classification_id", classification_id);
610                 table.insert("developer_id", developer_id);
611                 table.insert("summary", summary);
612                 table.insert("description", description);
613                  
614                 var params = Soup.Form.encode_hash(table);              
615
616                 GLib.debug("request POST %s / %s", roourl, id);
617
618                 var session = new Soup.Session ();
619                 session.timeout = 0;
620                 var message = new Soup.Message ("POST", roourl + "/mtrack_ticket");
621                 RooTicket.setAuth(message);
622
623                 message.set_request ("application/x-www-form-urlencoded", Soup.MemoryUse.STATIC, params.data);
624                 session.send_message (message);
625
626
627                 var data = (string) message.response_body.flatten().data;
628                 GLib.debug("got %s", data);
629                 try {
630                            var parser = new Json.Parser ();
631                            parser.load_from_data (data, -1);
632
633                            var response = parser.get_root().get_object();
634                            var status = response.get_boolean_member("success");
635
636                            if(!status){
637                                            GLib.error(response.get_string_member("errorMsg"));
638                                            return "" ;
639                            }
640                                 var rd = response.get_object_member ("data");
641                                 return rd.get_string_member("id");
642                            
643                                 
644
645                 } catch (Error e) {
646                            GLib.error(e.message);
647                            return "";
648                 }
649    
650         }
651         
652 }
653