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