diff --git a/cgi-bin/download.cgi b/cgi-bin/download.cgi new file mode 100755 index 0000000..b412043 --- /dev/null +++ b/cgi-bin/download.cgi @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import cgitb; cgitb.enable() +import os, sys, cgi +from project import Project +from zipfile import ZipFile + + +method = os.environ.get("REQUEST_METHOD", "") +fs = cgi.FieldStorage() +project = fs.getvalue("p", "") +paths = fs.getlist("f[]") + +if paths: + proj = Project(project) + zippath = os.path.join(proj.fullpath, "{0}.zip".format(project)) + with ZipFile(zippath, 'w') as zzip: + for p in paths: + fp = os.path.join(proj.fullpath, p) + # print >> sys.stderr, "*** rm", fp + _, base = os.path.split(fp) + zzip.write(fp, project+"/"+base) + # serve zippath + print "Content-type: application/zip" + print "Content-disposition: attachment; filename={0}.zip".format(project) + print "Content-length: {0}".format(os.path.getsize(zippath)) + print + with open(zippath) as f: + while True: + data = f.read() + if data == "": + break + sys.stdout.write(data) + os.unlink(zippath) + diff --git a/cgi-bin/hype.cgi b/cgi-bin/hype.cgi index c27db96..801844e 100755 --- a/cgi-bin/hype.cgi +++ b/cgi-bin/hype.cgi @@ -1,4 +1,12 @@ #!/usr/bin/env python +# +# (c) 2014 Michael Murtaugh and contributors to the Digital Publishing Toolkit + +# License: GPL3 + +# This code has been developed as part of the [Digital Publishing Toolkit](http://digitalpublishingtoolkit.org). +# with the support of Institute for [Network Cultures](http://networkcultures.org) +# and [Creating 010](http://creating010.com). import cgitb; cgitb.enable() import os, sys, cgi, mimetypes @@ -33,11 +41,13 @@ print """
+ + diff --git a/editor.css b/editor.css index 6dd95a7..a446531 100644 --- a/editor.css +++ b/editor.css @@ -101,6 +101,23 @@ a:hover { width: auto; } +#listing div.item a { + text-decoration: none; +} + +#listing div.item.active a { + font-weight: bold; +} + +#listing div.item.active a::after { + content: " \2192"; + font-weight: bold; +} + +#listing div.item a:hover { + text-decoration: underline; +} + #listing div.item a.normal { color: black; } @@ -126,6 +143,10 @@ a:hover { display: none; } +#listing button, #listing select { + margin-right: 2px; +} + /* *** */ #editor { @@ -158,6 +179,10 @@ a:hover { font-size: 12px; } +.editorfoot button, .editorfoot select { + margin-right: 6px; +} + #editor .preview { position: absolute; left: 0; right: 0; diff --git a/editor.js b/editor.js index 0a819e3..5dafc6a 100644 --- a/editor.js +++ b/editor.js @@ -1,3 +1,16 @@ +/* + +(c) 2014 Michael Murtaugh and contributors to the Digital Publishing Toolkit + +License: GPL3 + +This code has been developed as part of the [Digital Publishing Toolkit](http://digitalpublishingtoolkit.org). +with the support of Institute for [Network Cultures](http://networkcultures.org) +and [Creating 010](http://creating010.com). + +*/ + + var editor_factory = aa_aceeditor(window.ace), editor = editor_factory.get_editor(), editor_elt = d3.select(editor.elt), @@ -21,6 +34,7 @@ var editor_factory = aa_aceeditor(window.ace), .append("div") .attr("class", "gear"); + function url_for (script) { return cgi_url+script+"?p=" + encodeURIComponent(project); } @@ -92,17 +106,30 @@ aa_frames(document.getElementById("split")); document.getElementById("editor").appendChild(editor.elt); -function edit (url) { - editor.href(url); +var activeURL; + +function updateActiveItem () { + var item = d3.selectAll("#listing div.item") + .classed("active", function (d) { + return d.url == activeURL; + }); +} + +function edit (url, done, forceReload) { + activeURL = url; + editor.href(url, done, forceReload); + editor.aceeditor.focus(); editor_elt .style("display", "block"); preview_div .style("display", "none"); close_make(); + updateActiveItem(); // make_div.style("display", "none"); } function preview (url) { + activeURL = url; preview_div .style("display", "block"); editor_elt @@ -110,6 +137,7 @@ function preview (url) { preview_iframe .attr("src", url); close_make(); + updateActiveItem(); // make_div.style("display", "none"); } @@ -143,18 +171,11 @@ function make (path, done) { function make_busy (val) { make_div.classed("busy", val); } -/* + function select_all () { - var checkboxes = d3.selectAll(".itemcheckbox"), - checked = d3.selectAll(".itemcheckbox:checked"); - if (checkboxes.size() == checked.size()) { - checkboxes.property("checked", false); - } else { - checkboxes.property("checked", true); - } + d3.selectAll("#listing div.item").each(item_select); update_selection(); } -*/ function delete_selection () { var items_selected = d3.selectAll("#listing div.selected"), @@ -181,6 +202,25 @@ function delete_selection () { } } +function download_selection () { + var items_selected = d3.selectAll("#listing div.selected"), + num_selected = items_selected.size(), + paths = items_selected.data().map(function (d) { return d.path }); + + if (num_selected == 0) return; + var ok = true; //confirm("Download "+num_selected+" selected file"+((num_selected==1)?"":"s") + "?"); + if (ok) { + var url = url_for("download.cgi"); + url += paths.map(function(x) { return "&f[]="+encodeURIComponent(x); }).join(""); + // console.log("download", url); + preview_iframe + .attr("src", url); + + items_selected.each(item_deselect); + update_selection(); + } +} + var longclick_begin; function item_select (d) { @@ -256,7 +296,7 @@ function rename () { $("#listing .listing_rename_buttons").hide(); return; } - var ok = confirm("Rename "+ss.size()+" file"+((ss==1)?"":"s") + "?"); + var ok = true; // confirm("Rename "+ss.size()+" file"+((ss==1)?"":"s") + "?"); if (ok) { ss.each(function (d) { var newpath = d3.select(this.parentNode).select("input.rename").property("value"); @@ -320,12 +360,16 @@ function refresh_listing(done) { } if (d.remake) { // alert("make"); + activeURL = d.url; + updateActiveItem(); make(d.path, function () { // re-get the d in case of change! var d = d3.select(that).datum(); // console.log("d", d, d.binary, d.url); if (!d.binary) { - edit(d.url); + // force reload! + console.log("force reload") + edit(d.url, null, true); } else { preview(d.url); } @@ -364,8 +408,10 @@ refresh_listing(); $("#listing .body").niceScroll({cursorcolor:"#0F0"}); $("#editor .make .body").niceScroll({cursorcolor:"#0F0"}); +$("#listing_select_all").click(select_all); $("#listing_refresh").click(refresh_listing); $("#listing_delete").click(delete_selection); +$("#listing_download").click(download_selection); $("#listing_rename").click(rename); $("#listing_cancel").click(listing_cancel); // $("#listing_select_all").click(select_all); diff --git a/lib/aa/ace-editor.js b/lib/aa/ace-editor.js index 1378b7a..bda8e20 100644 --- a/lib/aa/ace-editor.js +++ b/lib/aa/ace-editor.js @@ -26,7 +26,7 @@ function aa_aceeditor (ace) { current_href, highlightLineStart, highlightLineEnd, - _save; + _save, _reload; editor.elt = document.createElement("div"); @@ -42,6 +42,9 @@ function aa_aceeditor (ace) { editor.save = function (callback) { _save = callback; } + editor.reload = function (callback) { + _reload = callback; + } // a bit of a brutal solution but... $(document).bind("resize", function (e) { @@ -79,6 +82,24 @@ function aa_aceeditor (ace) { } }); + var reload = foot + .append("button") + .text("reload") + .on("click", function () { + var text; + if (_reload) { + text = editor.aceeditor.getValue(); + _reload.call(editor, { + text: text, + href: current_href + }); + } else { + editor.href(current_href, null, true); + aceeditor.focus(); + } + }); + + function highlight(s, e) { var session = editor.aceeditor.getSession(); if (highlightLineStart) { @@ -111,9 +132,9 @@ function aa_aceeditor (ace) { if (session == "loading") { return false; } - /* - todo, improve this.. now commented out to force reload - if (session != undefined) { + + // todo, improve this.. now commented out to force reload + if (!forceReload && (session != undefined)) { if (done) { window.setTimeout(function () { done.call(session); @@ -128,7 +149,6 @@ function aa_aceeditor (ace) { return true; } - */ sessionsByHref[href.nofrag] = "loading"; $.ajax({ url: href.nofrag,