NewBranch.bjs
[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         public RooProject? getProjectByRepo(GitRepo repo)
148         {
149                 var rt = RooTicket.singleton();
150                 
151                 if (rt.repos.size < 1) {
152                         rt.loadRepos();
153                 }
154                  
155                 
156                 var pid = "";
157                 foreach(var roo_repo in rt.repos) {
158                         if (roo_repo.shortname == repo.name) {
159                                 pid = roo_repo.project_id;
160                                 break;
161                         }
162                 }
163                 if (pid == "") {
164                         GLib.debug("getProjectByRepo: repo has no project");            
165                         return null;
166                 }
167                 // get project by id...
168                 foreach(var roo_project in RooProject.projects()) {
169                         if (roo_project.id == pid) {
170                                 GLib.debug("getProjectByRepo: project_id = %s", pid);
171                                 return roo_project;
172                         }
173                 }
174                 GLib.debug("getProjectByRepo: can not find project");                           
175                 return null;
176         
177         }
178         
179         
180         public static RooTicket fakeTicket()
181         {
182                 var t = new RooTicket();
183                 t.id = "-1";
184                 t.summary = "";
185                 t.description = "";
186                 t.project_id_name = "";
187                 RooTicket.singleton().tickets.add(t);
188                 return t;
189         }
190         
191  
192         public RooTicket? getById(string id)
193         {
194                 foreach(var t in this.tickets) {
195                         if (t.id == id) {
196                                 return t;
197                         }
198                 }
199                 if (id == "-1") {
200                         return RooTicket.fakeTicket();
201                 }
202                 
203         return this.loadTicket(id);
204
205  
206         }
207
208
209         public RooTicket? loadTicket(string id)
210         {
211
212                    var table = new GLib.HashTable<string, string>(str_hash, str_equal);
213                    table.insert("_id",id);         
214                    
215                    var params = Soup.Form.encode_hash(table);              
216                    var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
217                    GLib.debug("request %s", url);
218                    
219                    var session = new Soup.Session ();
220                    session.timeout = 0;
221                    var message = new Soup.Message ("GET", url);
222                    RooTicket.setAuth(message);
223                    session.send_message (message);
224                    
225                    
226                    var data = (string) message.response_body.flatten().data;
227                    GLib.debug("got %s", data);
228                    try {
229                            var parser = new Json.Parser ();
230                            parser.load_from_data (data, -1);
231
232                            var response = parser.get_root().get_object();
233                            var status = response.get_boolean_member("success");
234                    
235                            if(!status){
236                                    GLib.error(response.get_string_member("errorMsg"));
237                                    return null;
238                            }
239                            var rd = response.get_object_member ("data");
240                            
241                            return this.addTicket(rd);
242                            
243                             
244                    
245                    } catch (Error e) {
246                            GLib.error(e.message);
247                            return null;
248                    }
249         }
250
251         public void loadTickets(string project_id, Who who, Status status)
252         {
253                 RooTicket.singleton().tickets = new Gee.ArrayList<RooTicket>();
254          
255                 
256                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
257
258                 table.insert("_developer", who.to_string().down().substring(15));
259                 
260                 table.insert("query[viewtype]", status.to_string().down().substring(18));
261
262                 table.insert("limit","200");
263                 table.insert("sort","summary");
264                 table.insert("dir","ASC");
265                 
266                 if (project_id != "") {
267                         table.insert("project_id",project_id);
268                 }
269
270
271                 var params = Soup.Form.encode_hash(table);
272                 
273                 var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
274                 
275                 GLib.debug("request %s", url);
276                 
277                 var session = new Soup.Session ();
278                 session.timeout = 0;
279                 var message = new Soup.Message ("GET", url);
280                 
281                 
282                 RooTicket.setAuth(message);
283                 
284                 session.send_message (message);
285                 
286                 var data = (string) message.response_body.flatten().data;
287                 //GLib.debug("got %s", data);
288                 try {
289                         var parser = new Json.Parser ();
290                         parser.load_from_data (data, -1);
291
292                         var response = parser.get_root().get_object();
293                         var success = response.get_boolean_member("success");
294                 
295                         if(!success){
296                                 GLib.error(response.get_string_member("errorMsg"));
297                                 return;
298                         }
299                         var rd = response.get_array_member ("data");
300                         
301                         // got a valid result...
302                         var _this = RooTicket.singleton();
303                         for(var i = 0; i < rd.get_length(); i++) {
304                                 _this.addTicket(rd.get_object_element(i));
305                         }
306                          
307                 
308                 } catch (Error e) {
309                         GLib.error(e.message);
310                         return;
311                 }
312                 
313         }
314         
315          
316         public void loadRepos()
317         {
318                 RooTicket.singleton().repos = new Gee.ArrayList<RooRepo>();
319          
320                 
321                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
322          
323
324                 table.insert("limit","200");
325                 table.insert("sort","shortname");
326                 table.insert("dir","ASC");
327
328                 var params = Soup.Form.encode_hash(table);
329                 
330                 var url = "%s/%s?%s" . printf(roourl, "mtrack_repos", params);
331                 
332                 GLib.debug("request %s", url);
333                 
334                 var session = new Soup.Session ();
335                 session.timeout = 0;
336                 var message = new Soup.Message ("GET", url);
337                 
338                 
339                 RooTicket.setAuth(message);
340                 
341                 session.send_message (message);
342                 
343                 var data = (string) message.response_body.flatten().data;
344                 //GLib.debug("got %s", data);
345                 try {
346                         var parser = new Json.Parser ();
347                         parser.load_from_data (data, -1);
348
349                         var response = parser.get_root().get_object();
350                         var status = response.get_boolean_member("success");
351                 
352                         if(!status){
353                                 GLib.error(response.get_string_member("errorMsg"));
354                                 return;
355                         }
356                         var rd = response.get_array_member ("data");
357                         
358                         // got a valid result...
359                         var _this = RooTicket.singleton();
360                         for(var i = 0; i < rd.get_length(); i++) {
361                                 _this.addRepo(rd.get_object_element(i));
362                         }
363                          
364                 
365                 } catch (Error e) {
366                         GLib.error(e.message);
367                         return;
368                 }
369                 
370         }
371         public void loadProjectOptions(string pid)
372         {
373                 var rt = RooTicket.singleton();
374                 rt.milestones = new Gee.ArrayList<RooOption>();
375                 rt.priorities =  new Gee.ArrayList<RooOption>();
376                 rt.serverities =  new Gee.ArrayList<RooOption>();
377                 rt.classifications  =  new Gee.ArrayList<RooOption>();
378                 rt.developers =  new Gee.ArrayList<RooOption>();
379  
380                 if (pid == "") {
381                         return;
382                 }
383                 
384
385
386                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
387          
388                 table.insert("_options_for",pid);
389
390                 var params = Soup.Form.encode_hash(table);
391                 
392                 var url = "%s/%s?%s" . printf(roourl, "mtrack_ticket", params);
393                 
394                 GLib.debug("request %s", url);
395                 
396                 var session = new Soup.Session ();
397                 session.timeout = 0;
398                 var message = new Soup.Message ("GET", url);
399                 
400                 
401                 RooTicket.setAuth(message);
402                 
403                 session.send_message (message);
404                 
405                 var data = (string) message.response_body.flatten().data;
406                 //GLib.debug("got %s", data);
407                 try {
408                         var parser = new Json.Parser ();
409                         parser.load_from_data (data, -1);
410
411                         var response = parser.get_root().get_object();
412                         var status = response.get_boolean_member("success");
413                 
414                         if(!status){
415                                 GLib.error(response.get_string_member("errorMsg"));
416                                 return;
417                         }
418                         var rd = response.get_object_member ("data");
419                         
420                         rt.milestones = this.readJsonArray( rd.get_array_member("milestone"));
421                         rt.priorities = this.readJsonArray( rd.get_array_member("priority"));
422                         rt.serverities = this.readJsonArray( rd.get_array_member("severity"));
423                         rt.classifications  = this.readJsonArray( rd.get_array_member("classification"));
424                         rt.developers = this.readJsonArray( rd.get_array_member("developer"));
425  
426                         
427                         
428                         
429                         // got a valid result...
430                          
431                 
432                 } catch (Error e) {
433                         GLib.error(e.message);
434                         return;
435                 }
436                 
437         }
438         
439         public  static void setAuth(Soup.Message message) 
440         {
441                 var rs =  RooTicket.singleton();                
442                 if (rs.username.length < 1) {
443                         string str;
444                         GLib.FileUtils.get_contents(GLib.Environment.get_home_dir() + "/.netrc", out str);
445                         var lines = str.split("\n");
446                         for(var i=0; i< lines.length; i++) {
447                         // assumes one line per entry.. if not we are buggered...
448                                         GLib.debug("got %s" , lines[i]);
449                         
450                                 var bits =  Regex.split_simple ("[ \t]+", lines[i].strip());
451                                 if (bits.length < 6 || bits[0] != "machine" || bits[1] != "git.roojs.com") {
452                                         continue;
453                                 }
454                                         GLib.debug("found password?");
455                                 // we are gussing.... 
456
457                                 RooTicket.singleton().username  = bits[3];
458                                 RooTicket.singleton().password  = bits[5];              
459                         }
460                 }
461
462
463                 var authCode = Base64.encode ("%s:%s".printf(rs.username, rs.password).data);
464                 message.request_headers.append("Authorization", "Basic %s".printf(authCode));
465         
466         
467         }
468
469
470         public void close(string commits)
471     {
472                 if (this.id == "-1") {
473                         return;
474                 }
475                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
476                 table.insert("id",id);
477                 table.insert("status_name","resolved");
478                 table.insert("reason","fixed by Commits: %s".printf(commits));  
479                 var params = Soup.Form.encode_hash(table);              
480
481                 GLib.debug("request POST %s / %s", roourl, id);
482
483                 var session = new Soup.Session ();
484                 session.timeout = 0;
485                 var message = new Soup.Message ("POST", roourl + "/mtrack_ticket");
486                 RooTicket.setAuth(message);
487
488                 message.set_request ("application/x-www-form-urlencoded", Soup.MemoryUse.STATIC, params.data);
489                 session.send_message (message);
490
491
492                 var data = (string) message.response_body.flatten().data;
493                 GLib.debug("got %s", data);
494                 try {
495                            var parser = new Json.Parser ();
496                            parser.load_from_data (data, -1);
497
498                            var response = parser.get_root().get_object();
499                            var status = response.get_boolean_member("success");
500
501                            if(!status){
502                                            GLib.error(response.get_string_member("errorMsg"));
503                                            return ;
504                            }
505                                 
506                            
507                                 
508
509                 } catch (Error e) {
510                            GLib.error(e.message);
511                            return ;
512                 }
513
514    }
515         public string createTicket(     
516                         string project_id,
517                         string milestone_id,
518                         string priority_id,
519                         string classification_id,
520                         string developer_id,
521                         string summary,
522                         string description
523                 ) 
524         {
525                  
526                 var table = new GLib.HashTable<string, string>(str_hash, str_equal);
527                  
528                 table.insert("project_id", project_id);
529                 table.insert("milestone_id", milestone_id);
530                 table.insert("priority_id", priority_id);
531                 table.insert("classification_id", classification_id);
532                 table.insert("developer_id", developer_id);
533                 table.insert("summary", summary);
534                 table.insert("description", description);
535                  
536                 var params = Soup.Form.encode_hash(table);              
537
538                 GLib.debug("request POST %s / %s", roourl, id);
539
540                 var session = new Soup.Session ();
541                 session.timeout = 0;
542                 var message = new Soup.Message ("POST", roourl + "/mtrack_ticket");
543                 RooTicket.setAuth(message);
544
545                 message.set_request ("application/x-www-form-urlencoded", Soup.MemoryUse.STATIC, params.data);
546                 session.send_message (message);
547
548
549                 var data = (string) message.response_body.flatten().data;
550                 GLib.debug("got %s", data);
551                 try {
552                            var parser = new Json.Parser ();
553                            parser.load_from_data (data, -1);
554
555                            var response = parser.get_root().get_object();
556                            var status = response.get_boolean_member("success");
557
558                            if(!status){
559                                            GLib.error(response.get_string_member("errorMsg"));
560                                            return "" ;
561                            }
562                                 var rd = response.get_object_member ("data");
563                                 return rd.get_string_member("id");
564                            
565                                 
566
567                 } catch (Error e) {
568                            GLib.error(e.message);
569                            return "";
570                 }
571    
572         }
573         
574 }
575