diff --git a/README b/README index 38791ec..6d6cb66 100644 --- a/README +++ b/README @@ -16,4 +16,10 @@ b) offline annotations(something like speedtrans) with ability to sync/upload to since there might be no dns lookup for local.pad.ma possible +after checkout make sure a version of oxjs is available at static/oxjs +i.e. +cd pandoralocal/static +bzr branch http://code.0x2620.org/oxjs +cd oxjs +./tools/build/build.py diff --git a/pandoralocal/server.py b/pandoralocal/server.py index 305cd44..ba11a14 100644 --- a/pandoralocal/server.py +++ b/pandoralocal/server.py @@ -189,7 +189,8 @@ class Server(Resource): def render_GET(self, request): print 'render_GET' request.headers['Server'] = 'pandoralocal/%s' % __version__ - f = open('static/index.html') + path = self.static_path('api.html') + f = open(path) data = f.read() f.close() request.headers['Content-Type'] = 'text/html' diff --git a/pandoralocal/static/api.html b/pandoralocal/static/api.html new file mode 100644 index 0000000..53c4fc6 --- /dev/null +++ b/pandoralocal/static/api.html @@ -0,0 +1,14 @@ + + + + + pandoralocal API + + + + + + + + + diff --git a/pandoralocal/static/css/highlight.css b/pandoralocal/static/css/highlight.css new file mode 100644 index 0000000..39be6f7 --- /dev/null +++ b/pandoralocal/static/css/highlight.css @@ -0,0 +1,67 @@ +pre code { + display: block; + background: #F0F0F0; +} + +pre code, +.xml .title { + color: black; +} + +.string, +.title, +.parent, +.tag .attribute .value, +.rules .value, +.rules .value .number, +.preprocessor, +.instancevar, +.aggregate, +.template_tag, +.django .variable, +.addition, +.flow, +.stream { + color: #800; +} + +.comment, +.annotation, +.template_comment, +.diff .header, +.chunk { + color: #888; +} + +.number, +.regexp, +.literal, +.change { + color: #080; +} + +.decorator, +.filter .argument, +.localvars, +.array, +.attr_selector, +.pi, +.doctype, +.deletion, +.envvar, +.shebang { + color: #88F; +} + +.keyword, +.id, +.title, +.aggregate { + font-weight: bold; +} + +.html .css, +.html .javascript, +.html .vbscript { + opacity: 0.5; +} diff --git a/pandoralocal/static/js/api/highlight.pack.js b/pandoralocal/static/js/api/highlight.pack.js new file mode 100644 index 0000000..d2aa563 --- /dev/null +++ b/pandoralocal/static/js/api/highlight.pack.js @@ -0,0 +1 @@ +var hljs=new function(){var p={};var a={};function n(c){return c.replace(/&/gm,"&").replace(//gm,">")}function k(s,r){if(!s){return false}for(var c=0;c"}function B(C){return""}while(z.length||A.length){var w=v().splice(0,1)[0];x+=n(y.substr(s,w.offset-s));s=w.offset;if(w.event=="start"){x+=t(w.node);u.push(w.node)}else{if(w.event=="stop"){var r=u.length;do{r--;var c=u[r];x+=B(c)}while(c!=w.node);u.splice(r,1);while(r'+n(M[0])+""}else{O+=n(M[0])}R=Q.lR.lastIndex;M=Q.lR.exec(N)}O+=n(N.substr(R,N.length-R));return O}function L(r,N){if(N.subLanguage&&a[N.subLanguage]){var M=g(N.subLanguage,r);u+=M.keyword_count;C+=M.r;return M.value}else{return G(r,N)}}function J(N,r){var M=N.nM?"":'';if(N.rB){s+=M;N.buffer=""}else{if(N.eB){s+=n(r)+M;N.buffer=""}else{s+=M;N.buffer=r}}D[D.length]=N}function F(M,O,R){var P=D[D.length-1];if(R){s+=L(P.buffer+M,P);return false}var S=A(O,P);if(S){s+=L(P.buffer+M,P);J(S,O);C+=S.r;return S.rB}var r=x(D.length-1,O);if(r){var T=P.nM?"":"";if(P.rE){s+=L(P.buffer+M,P)+T}else{if(P.eE){s+=L(P.buffer+M,P)+T+n(O)}else{s+=L(P.buffer+M+O,P)+T}}while(r>1){T=D[D.length-2].nM?"":"";s+=T;r--;D.length--}var Q=D[D.length-1];D.length--;D[D.length-1].buffer="";if(Q.starts){for(var N=0;N1){throw"Illegal"}return{language:K,r:C,keyword_count:u,value:s}}catch(H){if(H=="Illegal"){return{language:null,r:0,keyword_count:0,value:n(E)}}else{throw H}}}function i(){function r(y,x){if(y.compiled){return}if(y.b){y.bR=e(x,"^"+y.b)}if(y.e){y.eR=e(x,"^"+y.e)}if(y.i){y.iR=e(x,"^(?:"+y.i+")")}if(y.r==undefined){y.r=1}if(!y.displayClassName){y.displayClassName=y.cN}if(!y.cN){y.nM=true}for(var w in y.k){if(!y.k.hasOwnProperty(w)){continue}if(y.k[w] instanceof Object){y.keywordGroups=y.k}else{y.keywordGroups={keyword:y.k}}break}y.sm=[];if(y.c){for(var v=0;vz.keyword_count+z.r){z=w}if(w.keyword_count+w.r>y.keyword_count+y.r){z=y;y=w}}}var u=v.className;if(!u.match(y.language)){u=u?(u+" "+y.language):y.language}var c=d(v);if(c.length){var s=document.createElement("pre");s.innerHTML=y.value;y.value=m(c,d(s),C)}if(A){y.value=y.value.replace(/^((<[^>]+>|\t)+)/gm,function(D,G,F,E){return G.replace(/\t/g,A)})}if(r){y.value=y.value.replace(/\n/g,"
")}if(/MSIE [678]/.test(navigator.userAgent)&&v.tagName=="CODE"&&v.parentNode.tagName=="PRE"){var s=v.parentNode;var x=document.createElement("div");x.innerHTML="
"+y.value+"
";v=x.firstChild.firstChild;x.firstChild.cN=s.cN;s.parentNode.replaceChild(x.firstChild,s)}else{v.innerHTML=y.value}v.className=u;v.dataset={};v.dataset.result={language:y.language,kw:y.keyword_count,re:y.r};if(z&&z.language){v.dataset.second_best={language:z.language,kw:z.keyword_count,re:z.r}}}function l(){if(l.called){return}l.called=true;f();if(arguments.length){for(var c=0;c|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:["escape"],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:["escape"],r:0};this.BE={cN:"escape",b:"\\\\.",e:this.IMR,nM:true,r:0};this.CLCM={cN:"comment",b:"//",e:"$",r:0};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NUMBER_MODE={cN:"number",b:this.NR,e:this.IMR,r:0};this.CNM={cN:"number",b:this.CNR,e:this.IMR,r:0};this.inherit=function(c,t){var s={};for(var r in c){s[r]=c[r]}if(t){for(var r in t){s[r]=t[r]}}return s}}();var initHighlightingOnLoad=hljs.initHighlightingOnLoad;hljs.LANGUAGES.javascript={dM:{l:[hljs.UIR],c:["string","comment","number","regexp_container","function"],k:{keyword:{"in":1,"if":1,"for":1,"while":1,"finally":1,"var":1,"new":1,"function":1,"do":1,"return":1,"void":1,"else":1,"break":1,"catch":1,"instanceof":1,"with":1,"throw":1,"case":1,"default":1,"try":1,"this":1,"switch":1,"continue":1,"typeof":1,"delete":1},literal:{"true":1,"false":1,"null":1}}},m:[hljs.CLCM,hljs.CBLCLM,hljs.CNM,hljs.ASM,hljs.QSM,hljs.BE,{cN:"regexp_container",b:"("+hljs.RSR+"|case|return|throw)\\s*",e:hljs.IMR,nM:true,l:[hljs.IR],k:{"return":1,"throw":1,"case":1},c:["comment",{cN:"regexp",b:"/.*?[^\\\\/]/[gim]*",e:hljs.IMR}],r:0},{cN:"function",b:"\\bfunction\\b",e:"{",l:[hljs.UIR],k:{"function":1},c:[{cN:"title",b:"[A-Za-z$_][0-9A-Za-z$_]*",e:hljs.IMR},{cN:"params",b:"\\(",e:"\\)",c:["string","comment"]}]}]};hljs.LANGUAGES.python={dM:{l:[hljs.UIR],i:"(|\\?)",c:["comment","string","function","class","number","decorator"],k:{keyword:{and:1,elif:1,is:1,global:1,as:1,"in":1,"if":1,from:1,raise:1,"for":1,except:1,"finally":1,print:1,"import":1,pass:1,"return":1,exec:1,"else":1,"break":1,not:1,"with":1,"class":1,assert:1,yield:1,"try":1,"while":1,"continue":1,del:1,or:1,def:1,lambda:1,nonlocal:10},built_in:{None:1,True:1,False:1,Ellipsis:1,NotImplemented:1}}},m:[{cN:"function",l:[hljs.UIR],b:"\\bdef ",e:":",i:"$",k:{def:1},c:["title","params"],r:10},{cN:"class",l:[hljs.UIR],b:"\\bclass ",e:":",i:"[${]",k:{"class":1},c:["title","params"],r:10},{cN:"title",b:hljs.UIR,e:hljs.IMR},{cN:"params",b:"\\(",e:"\\)",c:["string"]},hljs.HCM,hljs.CNM,{cN:"string",b:"u?r?'''",e:"'''",r:10},{cN:"string",b:'u?r?"""',e:'"""',r:10},hljs.ASM,hljs.QSM,hljs.BE,{cN:"string",b:"(u|r|ur)'",e:"'",c:["escape"],r:10},{cN:"string",b:'(u|r|ur)"',e:'"',c:["escape"],r:10},{cN:"decorator",b:"@",e:"$"}]}; \ No newline at end of file diff --git a/pandoralocal/static/js/api/pandora.js b/pandoralocal/static/js/api/pandora.js new file mode 100755 index 0000000..6dab620 --- /dev/null +++ b/pandoralocal/static/js/api/pandora.js @@ -0,0 +1,155 @@ +/*** + Pandora API +***/ +Ox.load('UI', { + hideScreen: false, + showScreen: true, + theme: 'classic' +}, function() { + +var app = new Ox.App({ + apiURL: '/api/', + init: 'init', +}).bindEvent('load', function(data) { + app.site = { + }; + app.site.default_info = '

Pan.do/ra API Overview

use this api in the browser with Ox.app or use pandora_client it in python. Further description of the api can be found on the wiki
'; + app.$body = $('body'); + app.$document = $(document); + app.$window = $(window); + //app.$body.html(''); + Ox.UI.hideLoadingScreen(); + + app.$ui = {}; + app.$ui.actionList = constructList(); + app.$ui.actionInfo = Ox.Container().css({padding: '16px'}).html(app.site.default_info); + + app.api.api({docs: true, code: true}, function(results) { + app.actions = results.data.actions; + + if(document.location.hash) { + app.$ui.actionList.triggerEvent('select', {ids: document.location.hash.substring(1).split(',')}); + } + }); + + var $left = new Ox.SplitPanel({ + elements: [ + { + element: new Ox.Element().append(new Ox.Element() + .html('Pandoralocal API').css({ + 'padding': '4px', + })).css({ + 'background-color': '#ddd', + 'font-weight': 'bold', + }), + size: 24 + }, + { + element: app.$ui.actionList + } + ], + orientation: 'vertical' + }); + var $main = new Ox.SplitPanel({ + elements: [ + { + element: $left, + size: 160 + }, + { + element: app.$ui.actionInfo, + } + ], + orientation: 'horizontal' + }); + + $main.appendTo(app.$body); +}); + +function constructList() { + return new Ox.TextList({ + columns: [ + { + align: "left", + id: "name", + operator: "+", + title: "Name", + unique: true, + visible: true, + width: 140 + }, + ], + columnsMovable: false, + columnsRemovable: false, + id: 'actionList', + items: function(data, callback) { + function _sort(a, b) { + if(a.name > b.name) + return 1; + else if(a.name == b.name) + return 0; + return -1; + } + if (!data.keys) { + app.api.api(function(results) { + var items = []; + Ox.forEach(results.data.actions, function(v, k) { + items.push({'name': k}) + }); + items.sort(_sort); + var result = {'data': {'items': items.length}}; + callback(result); + }); + } else { + app.api.api(function(results) { + var items = []; + Ox.forEach(results.data.actions, function(v, k) { + items.push({'name': k}) + }); + items.sort(_sort); + var result = {'data': {'items': items}}; + callback(result); + }); + } + }, + scrollbarVisible: true, + sort: [ + { + key: "name", + operator: "+" + } + ] + }).bindEvent({ + select: function(data) { + var info = $('
').addClass('OxSelectable'), + hash = '#'; + if(data.ids.length) { + data.ids.forEach(function(id) { + info.append($("

").html(id)); + var $doc =$('
')
+                           .html(app.actions[id].doc.replace('/\n/
\n/g')) + .appendTo(info); + var $code = $('') + .html(app.actions[id].code[1].replace('/\n/
\n/g')) + .hide(); + var f = app.actions[id].code[0]; + $('') + .html(' View Source ('+f+')') + .click(function() { $code.toggle();}) + .appendTo(info); + $('
').append($code).appendTo(info);
+                hljs.highlightBlock($code[0], '    ');
+
+                hash += id + ',';
+              });
+          } else {
+            info.html(app.site.default_info);
+          }
+
+            document.location.hash = hash.substring(0, hash.length-1);
+            app.$ui.actionInfo.html(info);
+       }
+    });
+}
+});
+