From 49904dabed83a6eef6e266bdf5bb23162145c055 Mon Sep 17 00:00:00 2001 From: apb Date: Sun, 23 Sep 2012 17:21:48 +0100 Subject: [PATCH] config --- src/graphxq/graphxq.xqm | 17 ++- src/graphxq/lib/config.xqm | 33 +++++ src/graphxq/lib/oauth.xqy | 238 ++++++++++++++++++++++++++++++++++ src/graphxq/static/app.js | 30 +++-- src/graphxq/views/about.xml | 4 +- src/graphxq/views/dotform.xml | 30 ++--- src/graphxq/views/layout.xml | 17 ++- src/graphxq/views/twitter.xml | 5 + 8 files changed, 341 insertions(+), 33 deletions(-) create mode 100644 src/graphxq/lib/config.xqm create mode 100644 src/graphxq/lib/oauth.xqy create mode 100644 src/graphxq/views/twitter.xml diff --git a/src/graphxq/graphxq.xqm b/src/graphxq/graphxq.xqm index 8f8334e..62c2927 100644 --- a/src/graphxq/graphxq.xqm +++ b/src/graphxq/graphxq.xqm @@ -7,12 +7,16 @@ module namespace grxq = 'apb.graphviz.web'; declare default function namespace 'apb.graphviz.web'; -import module namespace gr = 'apb.graphviz' at "lib/graphviz.xqm"; import module namespace dotui = 'apb.graphxq.dotui' at "dotui.xqm"; + import module namespace txq = 'apb.txq' at "lib/txq.xqm"; +import module namespace gr = 'apb.graphviz' at "lib/graphviz.xqm"; +import module namespace oa="http://basex.org/ns/oauth" at "lib/oauth.xqy"; +import module namespace config="apb.config" at "lib/config.xqm"; import module namespace request = "http://exquery.org/ns/request"; declare namespace rest = 'http://exquery.org/ns/restxq'; + declare variable $grxq:layout:=fn:resolve-uri("views/layout.xml"); declare @@ -102,6 +106,14 @@ declare return render("views/library.xml",$map) }; +declare +%rest:GET %rest:path("graphxq/twitter") +%output:method("html5") + function twitter( ) { + let $d:=$config:config + let $map:=map{"data":=fn:serialize($d) } + return render("views/twitter.xml",$map) +}; (:~ use dot or url :) declare %private function getdot($dot,$url) as xs:string{ @@ -131,7 +143,8 @@ declare function render($template,$locals){ "usermenu":=
users
, "title":=request:path(), "messages":=(), - "libserver":="//cdnjs.cloudflare.com/ajax/libs"} + "libserver":=$config:libserver, + "aceserver":=$config:aceserver} let $locals:=map:new(($default,$locals)) return txq:render(fn:resolve-uri($template),$locals,$grxq:layout) }; \ No newline at end of file diff --git a/src/graphxq/lib/config.xqm b/src/graphxq/lib/config.xqm new file mode 100644 index 0000000..b840c4f --- /dev/null +++ b/src/graphxq/lib/config.xqm @@ -0,0 +1,33 @@ +(:~ +: configuration access +: looks in WEB-INF/site-config.xml for actual values +: +: @author andy bunce +: @since sept 2012 +:) + +module namespace config = 'apb.config'; +declare default function namespace 'apb.config'; +declare variable $config:default:= + + //cdnjs.cloudflare.com/ajax/libs + http://d1n0x3qji82z53.cloudfront.net + + CONSUMER-KEY + CONSUMER-SECRET + your token + your secret + + +; +declare variable $config:config:= + fn:doc(fn:resolve-uri("../../WEB-INF/site-config.xml"))/config + ; + +(: +: /twitter-bootstrap/2.1.1/.. +: /jquery/1.8.1/jquery.min.js +:) +declare variable $config:libserver as xs:string:=$config:config/libserver/fn:string(); + +declare variable $config:aceserver as xs:string:=$config:config/aceserver/fn:string(); \ No newline at end of file diff --git a/src/graphxq/lib/oauth.xqy b/src/graphxq/lib/oauth.xqy new file mode 100644 index 0000000..a953672 --- /dev/null +++ b/src/graphxq/lib/oauth.xqy @@ -0,0 +1,238 @@ +(: +: an OAuth implementation written in XQuery for BaseX 7.4 +: based on http://norman.walsh.name/2010/09/25/oauth +:) +module namespace oa="http://basex.org/ns/oauth"; +import module namespace crypto="http://expath.org/ns/crypto"; + +declare function oa:twitter-service($CONSUMER-KEY as xs:string, + $CONSUMER-SECRET as xs:string){ + + + + http://twitter.com/oauth/request_token + GET + + + http://twitter.com/oauth/authorize + + + http://twitter.com/oauth/authenticate + force_login=true + + + http://twitter.com/oauth/access_token + POST + + + HMAC-SHA1 + + 1.0 + + {$CONSUMER-KEY} + {$CONSUMER-SECRET} + + +}; + +declare function oa:timestamp() as xs:unsignedLong { + let $epoch := xs:dateTime('1970-01-01T00:00:00Z') + let $now := current-dateTime() + let $d := $now - $epoch + let $seconds + := 86400 * days-from-duration($d) + + 3600 * hours-from-duration($d) + + 60 * minutes-from-duration($d) + + seconds-from-duration($d) + return + xs:unsignedLong($seconds) +}; + +declare function oa:sign($key as xs:string, $data as xs:string) as xs:string { + crypto:hmac($data,$key,'SHA1','base64') +}; + +declare function oa:signature-method( + $service as element(oa:service-provider) +) as xs:string +{ + if ($service/oa:signature-methods/oa:method = "HMAC-SHA1") + then "HMAC-SHA1" + else error(xs:QName("oa:BADSIGMETHOD"), + "Service must support 'HMAC-SHA1' signatures.") +}; + +declare function oa:http-method( + $proposed-method as xs:string +) as xs:string +{ + if (upper-case($proposed-method) = "GET") + then "GET" + else if (upper-case($proposed-method) = "POST") + then "POST" + else error(xs:QName("oa:BADHTTPMETHOD"), + "Service must use HTTP GET or POST.") +}; + +declare function oa:request-token( + $service as element(oa:service-provider), + $callback as xs:string?) +as element(oa:request-token) +{ + let $options := if (empty($callback)) + then () + else + + {$callback} + + let $data + := oa:signed-request($service, + $service/oa:request-token/oa:method, + $service/oa:request-token/oa:uri, + $options, (), ()) + return + + { if ($data/oa:error) + then + $data/* + else + for $pair in tokenize($data, "&") + return + element { concat("oa:", substring-before($pair, '=')) } + { substring-after($pair, '=') } + } + +}; + +declare function oa:access-token( + $service as element(oa:service-provider), + $request as element(oa:request-token), + $verifier as xs:string) +as element(oa:access-token) +{ + let $options := {$verifier} + let $data + := oa:signed-request($service, + $service/oa:access-token/oa:method, + $service/oa:access-token/oa:uri, + $options, + $request/oa:oauth_token, + $request/oa:oaauth_token_secret) + return + + { if ($data/oa:error) + then + $data/* + else + for $pair in tokenize($data, "&") + return + element { concat("oa:", substring-before($pair, '=')) } + { substring-after($pair, '=') } + } + +}; + +declare function oa:signed-request( + $service as element(oa:service-provider), + $method as xs:string, + $serviceuri as xs:string, + $options as element(oa:options)?, + $token as xs:string?, + $secret as xs:string?) +as element(oa:response) +{ + let $realm := string($service/@realm) + + let $nonce :=convert:integer-to-base(random:integer(),16) + let $stamp := oa:timestamp() + let $key := string($service/oa:authentication/oa:consumer-key) + let $sigkey := concat($service/oa:authentication/oa:consumer-key-secret, + "&", if (empty($secret)) then "" else $secret) + let $version := string($service/oa:oauth-version) + let $sigmethod := oa:signature-method($service) + let $httpmethod := oa:http-method($method) + + let $sigstruct + := + {$key} + {$nonce} + {$sigmethod} + {$stamp} + {$version} + { if (not(empty($token))) + then {$token} + else () + } + { if (not(empty($options))) + then $options/* + else () + } + + + let $encparams + := for $field in $sigstruct/* + order by local-name($field) + return + concat(local-name($field), "=", encode-for-uri(string($field))) + + let $sigbase := string-join(($httpmethod, encode-for-uri($serviceuri), + encode-for-uri(string-join($encparams,"&"))), "&") + + let $signature := encode-for-uri(oa:sign($sigkey, $sigbase)) + + (: This is a bit of a pragmatic hack, what's the real answer? :) + let $authfields := $sigstruct/*[starts-with(local-name(.), "oauth_") + and not(self::oauth_callback)] + + let $authheader := concat("OAuth realm="", $service/@realm, "", ", + "oauth_signature="", $signature, "", ", + string-join( + for $field in $authfields + return + concat(local-name($field),"="", encode-for-uri($field), """), + ", ")) + + let $uriparam := for $field in $options/* + return + concat(local-name($field),"=",encode-for-uri($field)) + + (: This strikes me as slightly weird. Twitter wants the parameters passed + encoded in the URI even for a POST. I don't know if that's a Twitter + quirk or the natural way that OAuth apps work. Anyway, if you find + this library isn't working for some other OAuth'd API, you might want + to play with this bit. + + let $requri := if ($httpmethod = "GET") + then concat($serviceuri, + if (empty($uriparam)) then '' + else concat("?",string-join($uriparam,"&"))) + else $serviceuri + + let $data := if ($httpmethod = "POST" and not(empty($uriparam))) + then {string-join($uriparam,"&")} + else () + :) + + let $requri := concat($serviceuri, + if (empty($uriparam)) then '' + else concat("?",string-join($uriparam,"&"))) + + + + let $request := + + + + let $tokenreq :=http:send-request($request,$requri) + + return + + { if (string($tokenreq[1]/@status) != "200") + then + ({$tokenreq[1]}, + {$tokenreq[2]}) + else + $tokenreq[2] + } + +}; diff --git a/src/graphxq/static/app.js b/src/graphxq/static/app.js index 8fdb8a2..ab58d74 100644 --- a/src/graphxq/static/app.js +++ b/src/graphxq/static/app.js @@ -48,10 +48,12 @@ jQuery(function($) { $.extend({ $(document).ready(function(){ $("#bnup").on("click",getsvg); - $("#bnsvg").on("click",function(){ $("#dotForm").submit()}); - $("#bndn").on("click",function(){getsvg(true)}); + $("#bnsvg").on("click",function(){ submit(false)}); + $("#bndn").on("click",function(){submit(true)}); $("#dot").on("keyup",getsvg); $('.colorpicker').colorPicker(); + + // set height where extend class var resize=function(){ var h=$(window).height(); $('.extend').each(function(){ @@ -64,6 +66,11 @@ $(document).ready(function(){ resize(); }); +function submit(dl){ + $("#ckdnload").prop("checked",dl); + $("#dotForm").submit() +} + function getsvg(dl){ var f=$("#dotForm").serializeArray() var d=$("#frm-defaults").serializeArray() @@ -74,20 +81,21 @@ function getsvg(dl){ url:"svg", data:f, dataType: "text", - success: function(str){ - // console.log(data) - var oParser = new DOMParser(); - var data = oParser.parseFromString(str, "text/xml"); - // http://stackoverflow.com/questions/3346106/accessing-a-dom-object-defined-in-an-external-svg-file - var n = document.importNode(data.documentElement,true); - $("#cuthere").empty().append(n); - $("#svgsrc").empty().text(str); - }, + success: updateSvg, error:function(jqXHR, textStatus, errorThrown){ console.log("ajax error: "+textStatus + errorThrown); } }); }; +function updateSvg(str){ + // console.log(data) + var oParser = new DOMParser(); + var data = oParser.parseFromString(str, "text/xml"); + // http://stackoverflow.com/questions/3346106/accessing-a-dom-object-defined-in-an-external-svg-file + var n = document.importNode(data.documentElement,true); + $("#cuthere").empty().append(n); + $("#svgsrc").empty().text(str); +}; function dotit(){ // xsvg.innerText=""; diff --git a/src/graphxq/views/about.xml b/src/graphxq/views/about.xml index cc211ce..1904480 100644 --- a/src/graphxq/views/about.xml +++ b/src/graphxq/views/about.xml @@ -37,12 +37,12 @@ -->
  • \ No newline at end of file diff --git a/src/graphxq/views/dotform.xml b/src/graphxq/views/dotform.xml index 720c94b..5fb0f9e 100644 --- a/src/graphxq/views/dotform.xml +++ b/src/graphxq/views/dotform.xml @@ -4,7 +4,7 @@ -
    -
    +
    +
    -
    - - {{ - }} - + + + + + +
    @@ -63,13 +60,16 @@
    -
    {$svgwidget}
    +
    {$svgwidget}
    - +
    \ No newline at end of file diff --git a/src/graphxq/views/layout.xml b/src/graphxq/views/layout.xml index dc78623..1d1571b 100644 --- a/src/graphxq/views/layout.xml +++ b/src/graphxq/views/layout.xml @@ -18,7 +18,7 @@ - + @@ -68,8 +68,19 @@ -