X-Git-Url: http://git.roojs.org/?p=app.Builder.js;a=blobdiff_plain;f=src%2FResources.vala;h=f35b38972fc9799cfbd3515fa3ca2886af21cc0c;hp=fde9471c3ff142205f6c9162f3c033b34c3c7ff5;hb=HEAD;hpb=67717e58090705b4e464e9443ff3d3e56cee37a0 diff --git a/src/Resources.vala b/src/Resources.vala index fde9471c3..f35b38972 100644 --- a/src/Resources.vala +++ b/src/Resources.vala @@ -14,25 +14,114 @@ * overload... so sequentially may be best... */ +public class ResourcesItem : Object { + public string target; + public string src; + public string new_sha; + public string cur_sha; + public ResourcesItem(string src, string target, string new_sha) + { + this.target = target; + this.src = src; + this.new_sha = new_sha; + this.cur_sha = ""; + this.update_cur_sha(); + print("New ResourcesItem %s (%s) => (%s) %s\n", target , this.cur_sha , new_sha, src); + } + public void update_cur_sha() + { + if (this.target.contains("*")) { + return; + } + var tfn = BuilderApplication.configDirectory() + "/resources/" + this.target; + if (!GLib.FileUtils.test (tfn, FileTest.IS_REGULAR)) { + return; + } + uint8[] data; + uint8[] zero = { 0 }; + GLib.FileUtils.get_data(tfn, out data); + + var file = File.new_for_path (tfn); + + var info = file.query_info( + "standard::*", + FileQueryInfoFlags.NONE + ); + var csdata = new GLib.ByteArray.take("blob %s".printf(info.get_size().to_string()).data); + csdata.append(zero); + csdata.append(data); + + // git method... blob %d\0...string... + this.cur_sha = GLib.Checksum.compute_for_data(GLib.ChecksumType.SHA1, csdata.data ); + } + +} + + public class Resources : Object { - public signal void updateProgress(uint cur_pos); + public signal void updateProgress(uint cur_pos, uint total); static Resources singleton_val; - static Resources singleton() + + + Gee.ArrayList fetch_files; + + public static Resources singleton() { - if (singleton_val != null) { + if (singleton_val == null) { singleton_val = new Resources(); + singleton_val.ref(); } return singleton_val; } - + public Resources () + { + this.initFiles(); + } + + + public void initFiles() + { + string[] avail_files = { + "roodata.json", + "*", + "Editors/*.js", + "vapi/*" + + }; + this.fetch_files = new Gee.ArrayList(); + for (var i=0;i < avail_files.length; i++) { + var target = avail_files[i]; + var src = "https://raw.githubusercontent.com/roojs/app.Builder.js/master/resources/" + target; + + if (target == "roodata.json") { + src = "https://raw.githubusercontent.com/roojs/roojs1/master/docs/json/roodata.json"; + //src = "http://git.roojs.org/?p=roojs1;a=blob_plain;f=docs/json/roodata.json"; + } + if (target.contains("*")) { + var split = target.split("*"); + + src = "https://api.github.com/repos/roojs/app.Builder.js/contents/resources/" + split[0]; + if (split[0] == "vapi/") { + src = "https://api.github.com/repos/roojs/app.Builder.js/contents/src/vapi"; + + } + + } + + this.fetch_files.add(new ResourcesItem(src,target, "")); + } + + } + - uint fetch_pos = 0; + int fetch_pos = 0; public void fetchStart() { + this.initFiles(); if (this.fetch_pos > 0) { // only fetch one at a time... return; } @@ -44,102 +133,44 @@ public class Resources : Object { var cur = this.fetch_pos; this.fetch_pos++; - this.updateProgress(this.fetch_pos); // min=0; - switch (cur) { - case 0: // html for rendering Bootstrap apps. - this.fetchResourceFrom ( - "http://git.roojs.org/?p=app.Builder.js;a=blob_plain;f=resources/bootstrap.builder.html", - "bootstrap.builder.html", - (sess,msg) => { - this.fetchNext(); - }); - break; - case 1:// html for rendering Roo apps. - this.fetchResourceFrom ( - "http://git.roojs.org/?p=app.Builder.js;a=blob_plain;f=resources/roo.builder.html", - "roo.builder.html", - (sess,msg) => { - this.fetchNext(); - }); - break; - case 2: // generic javascript - this.fetchResourceFrom ( - "http://git.roojs.org/?p=app.Builder.js;a=blob_plain;f=resources/roo.builder.js", - "roo.builder.js", - (sess,msg) => { - // should trigger a redraw on a the webkit if it's live... - this.fetchNext(); - }); - break; - - case 3: // Gir overrides - used to handle the fact we are not querying valadoc yet....and gir does - // not map that well to vala... - this.fetchResourceFrom ( - "http://git.roojs.org/?p=app.Builder.js;a=blob_plain;f=resources/Gir.overides", - "Gir.overides", - (sess,msg) => { - (new Palete.GirObject()).loadOverides(true); - - this.fetchNext(); - }); - break; - - case 4: // The main gtk tree rules - this.fetchResourceFrom ( - "http://git.roojs.org/?p=app.Builder.js;a=blob_plain;f=resources/GtkUsage.txt", - "GtkUsage.txt", - (sess,msg) => { - Palete.factory("Gtk").load(); - this.fetchNext(); - }); - break; - case 5: // The main roo tree rules - this.fetchResourceFrom ( - "http://git.roojs.org/?p=app.Builder.js;a=blob_plain;f=resources/RooUsage.txt", - "RooUsage.txt", - (sess,msg) => { - // next step triggers the - this.fetchNext(); - }); - break; - case 6: // The docs / types for Roojs - it's already in roojs if checked out..?? - // we might be better just checking if roojs is set up configured. - - this.fetchResourceFrom ( - "http://git.roojs.org/?p=roojs1;a=blob_plain;f=docs/json/roodata.json", - "roodata.json", - (sess,msg) => { - // See Palete.Roo - Palete.factory("Roo").classes = null; - Palete.factory("Roo").load(); - this.updateProgress(0); - this.fetch_pos = 0; - }); - break; - } - - - - - + this.updateProgress(this.fetch_pos, this.fetch_files.size); // min=0; + + + if (this.fetch_pos > this.fetch_files.size) { + this.updateProgress(0,0); + this.fetch_pos = 0; + return; + + } + + this.fetchResourceFrom ( this.fetch_files.get(cur) ); + } + /** + * called on start to check we have all the required files.. + */ public void checkResources() { - bool needsload = false; - string[] res = { - "bootstrap.builder.html", - "roo.builder.html", - "roo.builder.js", - "Gir.overides", - "RooUsage.txt", - "GtkUsage.txt" - }; - - for (var i = 0; i < res.length; i++ ) { + bool needsload = false; + + // this has to check the required files, not the list... + string[] required = { + "bootstrap.builder.html", + "Gir.overides", + "GtkUsage.txt", + "mailer.builder.html", + "roo.builder.html", + "roo.builder.js", + "roodata.json", + "RooUsage.txt" + }; + + for (var i = 0; i < required.length; i++ ) { if (!FileUtils.test( - Application.configDirectory() + "/resources/" + res[i], FileTest.EXISTS + BuilderApplication.configDirectory() + "/resources/" + required[i], + FileTest.EXISTS )) { needsload = true; } @@ -150,26 +181,120 @@ public class Resources : Object this.fetchStart(); } + public void parseDirectory(string json, string target) + { + print("%s\n", json); + var pa = new Json.Parser(); + pa.load_from_data(json); + var node = pa.get_root(); + if (node.get_node_type () != Json.NodeType.ARRAY) { + return; + //throw new Error.INVALID_FORMAT ("Unexpected element type %s", node.type_name ()); + } + + var split = target.split("*"); + var ar = node.get_array (); + for(var i = 0; i < ar.get_length(); i++) { + var ob = ar.get_object_element(i); + var n = ob.get_string_member("name"); + if (ob.get_string_member("type") == "dir") { + continue; + } + if (split.length > 1 && !n.has_suffix(split[1])) { + // not needed.. + continue; + } + if (this.files_has_target(split[0] + n)) { + continue; + } + + + var src = ob.get_string_member("download_url"); + // "https://raw.githubusercontent.com/roojs/app.Builder.js/master/resources/" + split[0] + n; + var add = new ResourcesItem(src, split[0] + n, ob.get_string_member("sha") ); + //add.new_sha = ob.get_string_member("sha"); + this.fetch_files.add(add); + + } + } + public bool files_has_target(string target) + { + for (var i = 0; i < this.fetch_files.size; i++ ) { + if (this.fetch_files.get(i).target == target) { + return true; + } + } + return false; + + } + - public void fetchResourceFrom(string src, string target, Soup.SessionCallback? callback) + public void fetchResourceFrom(ResourcesItem item) { + if (item.new_sha != "" && item.new_sha == item.cur_sha) { + this.fetchNext(); + return; + } // fetch... - print("downloading %s \nto : %s\n", src,res); + print("downloading %s \nto : %s\n", item.src,item.target); var session = new Soup.Session (); session.user_agent = "App Builder "; - var message = new Soup.Message ("GET", src ); + var message = new Soup.Message ("GET", item.src ); session.queue_message (message, (sess, mess) => { - - FileUtils.set_contents( - Application.configDirectory() + "/resources/" + res, - (string) message.response_body.data - ); - - callback(sess,mess); + + if (item.target.contains("*")) { + // then it's a directory listing in JSON, and we need to add any new items to our list.. + // it's used to fetch Editors (and maybe other stuff..) + this.parseDirectory((string) message.response_body.data,item.target ); + this.fetchNext(); + return; + } + + + var tfn = BuilderApplication.configDirectory() + "/resources/" + item.target; + + + // create parent directory if needed + if (!GLib.FileUtils.test (GLib.Path.get_dirname(tfn), FileTest.IS_DIR)) { + var f = GLib.File.new_for_path(GLib.Path.get_dirname(tfn)); + f.make_directory_with_parents (); + } + + + + + // set data??? - if it's binary? + FileUtils.set_contents( tfn, (string) message.response_body.data ); + + switch (item.target) { + case "Gir.overides": + Palete.Gir.factory("Gtk").loadOverrides(true); + break; + + case "GtkUsage.txt": + Palete.factory("Gtk").load(); + break; + + case "roodata.json": + Palete.factory("Roo").classes = null; + Palete.factory("Roo").load(); + break; + + default: + break; + } + + + + + + + this.fetchNext(); + });