1 //<Script type="text/javascript">
6 * Projects can only contain one directory... - it can import other projects..(later)
8 * we need to sort out that - paths is currently a key/value array..
14 public errordomain Error {
22 // static array of all projects.
23 public Gee.HashMap<string,Project> projects;
27 public bool projects_loaded = false;
31 public class Project : Object {
33 public signal void on_changed ();
36 public string fn = ""; // just a md5...
37 public string name = "";
38 public string runhtml = "";
39 public string base_template = "";
40 public string rootURL = "";
41 public string html_gen = "";
43 public Gee.HashMap<string,string> paths;
44 public Gee.HashMap<string,JsRender.JsRender> files ;
48 public Json.Object json_project_data;
49 public Palete.RooDatabase roo_database;
50 public Palete.Palete palete;
55 public Project (string path) {
57 this.name = GLib.Path.get_basename(path); // default..
58 this.json_project_data = new Json.Object();
60 this.is_scanned = false;
61 this.paths = new Gee.HashMap<string,string>();
62 this.files = new Gee.HashMap<string,JsRender.JsRender>();
63 //XObject.extend(this, cfg);
65 if (path.length > 0) {
66 this.paths.set(path, "dir");
68 // dummy roo database...
69 this.initRooDatabase();
74 public void initRooDatabase()
77 this.roo_database = new Palete.RooDatabase.from_project(this);
82 public static void loadAll(bool force = false)
84 if (projects_loaded && !force) {
88 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
89 var dir = File.new_for_path(dirname);
90 if (!dir.query_exists()) {
94 projects = new Gee.HashMap<string,Project>();
98 var file_enum = dir.enumerate_children(
99 GLib.FileAttribute.STANDARD_DISPLAY_NAME,
100 GLib.FileQueryInfoFlags.NONE,
106 while ((next_file = file_enum.next_file(null)) != null) {
107 var fn = next_file.get_display_name();
108 if (!Regex.match_simple("\\.json$", fn)) {
111 factoryFromFile(dirname + "/" + fn);
114 GLib.warning("oops - something went wrong scanning the projects\n");
120 public static Gee.ArrayList<Project> allProjectsByName()
122 var ret = new Gee.ArrayList<Project>();
123 var iter = projects.map_iterator();
124 while (iter.next()) {
125 ret.add(iter.get_value());
132 public static Project getProject(string name)
135 var iter = projects.map_iterator();
136 while (iter.next()) {
137 if (iter.get_value().name == name) {
138 return iter.get_value();
147 public static string listAllToString()
149 var all = new Gee.ArrayList<Project>();
151 var fiter = projects.map_iterator();
153 while(fiter.next()) {
154 all.add(fiter.get_value());
157 all.sort((fa,fb) => {
158 return ((Project)fa).name.collate(((Project)fb).name);
162 var iter = all.list_iterator();
163 var ret = "ID\tName\tDirectory\n";
164 while (iter.next()) {
165 ret += "%s\t%s\t%s\n".printf(
168 iter.get().firstPath()
180 public static Project getProjectByHash(string fn)
183 var iter = projects.map_iterator();
184 while (iter.next()) {
185 if (iter.get_value().fn == fn) {
186 return iter.get_value();
195 // load project data from project file.
196 public static void factoryFromFile(string jsonfile)
199 GLib.debug("parse %s", jsonfile);
201 var pa = new Json.Parser();
202 pa.load_from_file(jsonfile);
203 var node = pa.get_root();
206 if (node == null || node.get_node_type () != Json.NodeType.OBJECT) {
207 GLib.debug("SKIP " + jsonfile + " - invalid format?");
211 var obj = node.get_object ();
212 var xtype = obj.get_string_member("xtype");
215 var paths = obj.get_object_member("paths");
218 paths.foreach_member((sobj, key, val) => {
226 var proj = factory(xtype, fpath);
228 proj.json_project_data = obj; // store the original object...
230 proj.fn = Path.get_basename(jsonfile).split(".")[0];
234 if (obj.has_member("runhtml")) {
235 proj.runhtml = obj.get_string_member("runhtml");
238 if (obj.has_member("base_template")) {
239 proj.base_template = obj.get_string_member("base_template");
242 if (obj.has_member("rootURL")) {
243 proj.rootURL = obj.get_string_member("rootURL");
246 if (obj.has_member("html_gen")) {
247 proj.html_gen = obj.get_string_member("html_gen");
250 proj.name = obj.get_string_member("name");
253 paths.foreach_member((sobj, key, val) => {
254 proj.paths.set(key, "dir");
256 proj.initRooDatabase();
258 GLib.debug("Add Project %s", proj.id);
260 projects.set(proj.id,proj);
268 public static Project factory(string xtype, string path)
271 // check to see if it's already loaded..
274 var iter = projects.map_iterator();
275 while (iter.next()) {
276 if (iter.get_value().hasPath( path)) {
277 return iter.get_value();
284 return new Gtk(path);
286 return new Roo(path);
288 return new Flutter(path);
290 throw new Error.INVALID_TYPE("invalid project type");
296 public static void remove(Project project)
299 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
301 FileUtils.unlink(dirname + "/" + project.fn + ".json");
302 projects.unset(project.id,null);
312 if (this.fn.length < 1) {
313 // make the filename..
314 //var t = new DateTime.now_local ();
316 //t.to_timeval(out tv);
317 //var str = "%l:%l".printf(tv.tv_sec,tv.tv_usec);
318 var str = this.firstPath();
320 this.fn = GLib.Checksum.compute_for_string(GLib.ChecksumType.MD5, str, str.length);
323 var dirname = GLib.Environment.get_home_dir() + "/.Builder";
324 var s = this.toJSON(false);
325 FileUtils.set_contents(dirname + "/" + this.fn + ".json", s, s.length);
332 public string toJSON(bool show_all)
336 this.json_project_data.set_string_member("name", this.name);
337 this.json_project_data.set_string_member("fn", this.fn);
338 this.json_project_data.set_string_member("xtype", this.xtype);
339 this.json_project_data.set_string_member("runhtml", this.runhtml);
340 this.json_project_data.set_string_member("rootURL", this.rootURL);
341 this.json_project_data.set_string_member("base_template", this.base_template);
342 this.json_project_data.set_string_member("rootURL", this.rootURL);
343 this.json_project_data.set_string_member("html_gen", this.html_gen);
345 var paths = new Json.Object();
348 var iter = this.paths.map_iterator();
349 while (iter.next()) {
350 paths.set_string_member(iter.get_key(), "path");
352 this.json_project_data.set_object_member("paths", paths);
356 var files = new Json.Array();
359 var fiter = this.files.map_iterator();
360 while (fiter.next()) {
361 files.add_string_element (fiter.get_key());
363 this.json_project_data.set_array_member("files", files);
368 var generator = new Json.Generator ();
369 var root = new Json.Node(Json.NodeType.OBJECT);
370 root.init_object(this.json_project_data);
371 generator.set_root (root);
373 generator.pretty = true;
374 generator.indent = 4;
377 return generator.to_data (null);
381 public string firstPath()
383 var iter = this.paths.map_iterator();
384 while (iter.next()) {
385 return iter.get_key();
391 public bool hasPath(string path)
393 var iter = this.paths.map_iterator();
394 while (iter.next()) {
395 if (iter.get_key() == path) {
404 // returns the first path
405 public string getName()
407 var iter = this.paths.map_iterator();
408 while (iter.next()) {
409 return GLib.Path.get_basename(iter.get_key());
415 public Gee.ArrayList<JsRender.JsRender> sortedFiles()
417 var files = new Gee.ArrayList<JsRender.JsRender>();
419 var fiter = this.files.map_iterator();
420 while(fiter.next()) {
421 files.add(fiter.get_value());
423 files.sort((fa,fb) => {
424 return ((JsRender.JsRender)fa).name.collate(((JsRender.JsRender)fb).name);
433 public string listAllFilesToString()
436 var iter = this.sortedFiles().list_iterator();
437 var ret = "ID\tName\tDirectory\n";
438 while (iter.next()) {
439 ret += "%s\n".printf(
455 public JsRender.JsRender? getByName(string name)
458 var fiter = files.map_iterator();
459 while(fiter.next()) {
461 var f = fiter.get_value();
464 GLib.debug ("Project.getByName: %s ?= %s" ,f.name , name);
465 if (f.name == name) {
471 public JsRender.JsRender? getByPath(string path)
474 var fiter = files.map_iterator();
475 while(fiter.next()) {
477 var f = fiter.get_value();
480 //GLib.debug ("Project.getByName: %s ?= %s" ,f.name , name);
481 if (f.path == path) {
488 public JsRender.JsRender? getById(string id)
491 var fiter = files.map_iterator();
492 while(fiter.next()) {
494 var f = fiter.get_value();
497 //console.log(f.id + '?=' + id);
505 public JsRender.JsRender newFile (string name)
507 var ret = JsRender.JsRender.factory(this.xtype,
509 this.firstPath() + "/" + name + ".bjs");
514 public JsRender.JsRender loadFileOnly (string path)
517 return JsRender.JsRender.factory(xt, this, path);
521 public JsRender.JsRender create(string filename)
523 var ret = this.loadFileOnly(filename);
531 public void addFile(JsRender.JsRender pfile) { // add a single file, and trigger changed.
534 this.files.set(pfile.path, pfile); // duplicate check?
538 public void add(string path, string type)
540 this.paths.set(path,type);
541 //Seed.print(" type is '" + type + "'");
544 // console.dump(this.files);
546 if (type == "file" ) {
548 this.files.set(path,this.loadFileOnly( path ));
554 public void scanDirs() // cached version
556 if (this.is_scanned) {
559 this.scanDirsForce();
560 //console.dump(this.files);
564 public void scanDirsForce()
566 this.is_scanned = true;
567 var iter = this.paths.map_iterator();
568 while (iter.next()) {
569 //print("path: " + iter.get_key() + " : " + iter.get_value() +"\n");
570 if (iter.get_value() != "dir") {
573 this.scanDir(iter.get_key());
575 //console.dump(this.files);
579 public void scanDir(string dir, int dp =0 )
582 //print("Project.Base: Running scandir on " + dir +"\n");
583 if (dp > 5) { // no more than 5 deep?
586 // this should be done async -- but since we are getting the proto up ...
587 var other_files = new Gee.ArrayList<string>();
588 var bjs_files = new Gee.ArrayList<string>();
590 var subs = new GLib.List<string>();;
591 var f = File.new_for_path(dir);
593 var file_enum = f.enumerate_children(GLib.FileAttribute.STANDARD_DISPLAY_NAME, GLib.FileQueryInfoFlags.NONE, null);
597 while ((next_file = file_enum.next_file(null)) != null) {
598 var fn = next_file.get_display_name();
601 //print("trying" + dir + "/" + fn +"\n");
603 if (fn[0] == '.') { // skip hidden
607 if (FileUtils.test(dir + "/" + fn, GLib.FileTest.IS_DIR)) {
608 subs.append(dir + "/" + fn);
612 if (!Regex.match_simple("\\.bjs$", fn)) {
614 //print("no a bjs\n");
617 bjs_files.add(fn.substring(0, fn.length-4));
620 var el = JsRender.JsRender.factory(xt,this, dir + "/" + fn);
621 this.files.set( dir + "/" + fn, el);
627 GLib.warning("Project::scanDirs failed : " + e.message + "\n");
628 } catch (GLib.Error e) {
629 GLib.warning("Project::scanDirs failed : " + e.message + "\n");
631 foreach(var fn in other_files) {
632 var dpos = fn.last_index_of(".");
633 var without_ext = fn.substring(0, dpos);
634 if (bjs_files.contains(without_ext)) {
637 GLib.debug("Could have added %s/%s", dir, fn);
638 //var el = JsRender.JsRender.factory("plain",this, dir + "/" + fn);
639 //this.files.set( dir + "/" + fn, el);
642 for (var i = 0; i < subs.length(); i++) {
643 this.scanDir(subs.nth_data(i), dp+1);
647 // wrapper around the javascript data...
648 public string get_string_member(string key) {
650 if (!this.json_project_data.has_member(key)) {
653 var ret = this.json_project_data.get_string_member(key);