Merge remote branch 'origin/master' into wosch
authorWolfram Schneider <wosch@indexdata.dk>
Fri, 21 Jun 2013 09:04:26 +0000 (09:04 +0000)
committerWolfram Schneider <wosch@indexdata.dk>
Fri, 21 Jun 2013 09:04:26 +0000 (09:04 +0000)
etc/apache2/spclient-dev [new file with mode: 0644]
etc/apache2/spdemo-px
experiments/spclient/README
experiments/spclient/index.html
experiments/spclient/mkws.js
experiments/spclient/mkwsStyle.css

diff --git a/etc/apache2/spclient-dev b/etc/apache2/spclient-dev
new file mode 100644 (file)
index 0000000..b4a7e8a
--- /dev/null
@@ -0,0 +1,26 @@
+# Configuration for the apache web server                 -*- apache -*-
+
+# pazpar2 / service proxy config
+<VirtualHost *:80>
+    ServerName spclient.example.com
+    ServerAlias spclient-dev.indexdata.com
+    ServerAdmin webmaster@example.com
+    ErrorLog /var/log/apache2/spdemo-error.log
+    CustomLog /var/log/apache2/spdemo-access.log combined
+
+    RewriteEngine on
+    RewriteLogLevel 1
+    RewriteLog /var/log/apache2/spdemo-rewrite.log 
+
+    DocumentRoot /home/indexdata/mkws/experiments/spclient
+
+    RewriteRule /service-proxy-auth  /service-proxy/?command=auth&action=login&username=guest&password=guest [P] # [NE,P]
+
+    ProxyPass        /service-proxy/ http://mkc.indexdata.com:9009/service-proxy/
+    ProxyPassReverse /service-proxy/ http://mkc.indexdata.com:9009/service-proxy/
+
+    ProxyPass        /pazpar2/         http://localhost:8004/pazpar2/
+    ProxyPassReverse /pazpar2/         http://localhost:8004/pazpar2/
+
+</VirtualHost>
+
index 77f8f67..7f28300 100644 (file)
@@ -1,6 +1,6 @@
 <VirtualHost *:80> 
    ServerName spdemo.indexdata.com
-   ServerAlias spdemo-dev.indexdata.com spdemo-devel.indexdata.com spdemo-sp.indexdata.com spdemo-pp2.indexdata.com
+   ServerAlias spdemo-dev.indexdata.com spdemo-devel.indexdata.com spdemo-sp.indexdata.com spdemo-pp2.indexdata.com spclient-dev.indexdata.com
    
    ErrorLog /var/log/apache2/spdemo-error.log
    CustomLog /var/log/apache2/spdemo-access.log combined
index 16b3bc3..912f5c3 100644 (file)
@@ -18,7 +18,7 @@ can have MasterKey searching with minimal effort.
 The following files must be hosted on mkws.indexdata.com:
        mkws.js
        mkwsStyle.css
-       /libjs-pz2/pz2api.1.js
+       /libjs-pz2/pz2api.1.js (*)
 
 The following files make up the application:
        index.html
@@ -29,6 +29,9 @@ The following files make up the application:
 Alias for /service-proxy/, to avoid cross-site scripting issues. We
 will fix this.)
 
+(*) if you don't have already installed libjs-pz2 on the machine, you can
+do it by installing a debian package or check it out from GIT:
+$ git clone ssh://git.indexdata.com:222/home/git/pub/libjs-pz2
 
 Configuring a client
 --------------------
@@ -38,6 +41,9 @@ whatever makes up the application itself:
 
 Prerequisites:
     <link rel="stylesheet" href="mkwsStyle.css" />
+    <script type="text/javascript">
+       var mkws_config = { };
+    </script>
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="/libjs-pz2/pz2api.1.js"></script>
     <script type="text/javascript" src="mkws.js"></script>
@@ -59,6 +65,24 @@ missing. One of the TODOs is to fix it so that it doesn't try to use
 whatever is not there, and just uses what is.
 
 
+You can configure and control the client with the JavaScript mkws_config object.
+
+Here is an example of all possible options
+    <script type="text/javascript">
+        var mkws_config = {
+                use_service_proxy: false,   /* true, flase */
+                switch: true,              /* true, false */
+                sort_default: "relevance",  /* "relevance", "title:1", "date:0", "date:1" */
+               query_width: 50,            /* 5..50 */
+                perpage_default: 20,       /* 10, 20, 30, 50 */
+                lang: "en",                 /* "en", "de", "da" */
+
+               pazpar2_url: "/pazpar2/search.pz2",        /* URL */
+               service_proxy_url: "/service-proxy/",      /* URL */
+               service_proxy_auth: "/service-proxy-auth", /* URL */
+         };
+    </script>
+
 What next?
 ----------
 
@@ -69,5 +93,3 @@ Main areas of work:
 * Make CSS prettier
 * Embed in a real, existing, site
 * Clean up the code
-
-
index f1d0982..fd9699d 100644 (file)
@@ -3,9 +3,19 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="copyright" content="(c) 1999-2013 IndexData ApS, http://indexdata.com">
     <title>MKWS demo client</title>
     <!-- Next four lines required by MKWS -->
     <link rel="stylesheet" href="mkwsStyle.css" />
+    <script type="text/javascript">
+       var mkws_config = { 
+               lang: "da",
+               use_service_proxy: true,
+               switch: true, 
+               sort_default: "relevance",
+               perpage_default: 20
+        }; 
+    </script>
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="/libjs-pz2/pz2api.1.js"></script>
     <script type="text/javascript" src="mkws.js"></script>
     <div id="mkwsSearch"></div>
     <div id="mkwsRecords"></div>
     <div id="mkwsTargets"></div>
-    <div id="mkwsStat"></div>
+
+    <div id="footer">
+      <div id="mkwsStat"></div>
+      <span>Copyright &copy; 1999-2013 by <a href="http://www.indexdata.com">Index Data</a></span> 
+    </div>
   </body>
 </html>
index 3c8d76e..9b339fa 100644 (file)
@@ -1,18 +1,69 @@
 /* A very simple client that shows a basic usage of the pz2.js
 */
 
+"use strict"; // HTML5
+
+if (!mkws_config)
+    var mkws_config = {}; // for the guys who forgot to define mkws_config...
+
+var pazpar2_url = mkws_config.pazpar2_url ? mkws_config.pazpar2_url : "/pazpar2/search.pz2";
+var service_proxy_url = mkws_config.service_proxy_url ? mkws_config.service_proxy_url : "/service-proxy/";
+
+var pazpar2path = mkws_config.use_service_proxy ? service_proxy_url : pazpar2_url;
+var usesessions = mkws_config.use_service_proxy ? false : true;
+
+var mkws_locale_lang = {
+    "de": {
+       "Authors": "Autoren",
+       "Subjects": "Schlagw&ouml;rter",
+       "Sources": "Daten und Quellen",
+       "TERMLISTS": "Termlisten",
+       "Next": "Weiter",
+       "Prev": "Zur&uuml;ck",
+       "Search": "Suche",
+       "Sort by": "Sortieren nach",
+       "and show": "und zeige",
+       "per page": "pro Seite",
+       "Displaying": "Zeige",
+       "to": "von",
+       "of": "aus",
+       "found": "gefunden",
+
+       "dummy": "dummy"
+    },
+
+    "da": {
+       "Authors": "Forfattere",
+       "Subjects": "Emner",
+       "Sources": "Kilder",
+       "TERMLISTS": "TERMLISTS",
+       "Next": "N&aelig;ste",
+       "Prev": "Forrige",
+       "Search": "S&oslash;g",
+       "Sort by": "Sorter efter",
+       "and show": "og vis",
+       "per page": "per side",
+       "Displaying": "Viser",
+       "to": "til",
+       "of": "ud af",
+       "found": "fandt",
+
+       "dummy": "dummy"
+    }
+};
+
 // create a parameters array and pass it to the pz2's constructor
 // then register the form submit event with the pz2.search function
 // autoInit is set to true on default
 var my_paz = new pz2( { "onshow": my_onshow,
                     "showtime": 500,            //each timer (show, stat, term, bytarget) can be specified this way
-                    "pazpar2path": '/service-proxy/',
+                    "pazpar2path": pazpar2path,
                     "oninit": my_oninit,
                     "onstat": my_onstat,
                     "onterm": my_onterm,
                     "termlist": "xtargets,subject,author",
                     "onbytarget": my_onbytarget,
-                   "usesessions" : false,
+                   "usesessions" : usesessions,
                     "showResponseType": '', // or "json" (for debugging?)
                     "onrecord": my_onrecord } );
 // some state vars
@@ -41,9 +92,9 @@ function my_onshow(data) {
     // move it out
     var pager = document.getElementById("pager");
     pager.innerHTML = "";
-    pager.innerHTML +='<hr/><div style="float: right">Displaying: '
-                    + (data.start + 1) + ' to ' + (data.start + data.num) +
-                     ' of ' + data.merged + ' (found: '
+    pager.innerHTML +='<hr/><div style="float: right">' + M('Displaying') + ': '
+                    + (data.start + 1) + ' ' + M('to') + ' ' + (data.start + data.num) +
+                     ' ' + M('of') + ' ' + data.merged + ' (' + M('found') + ': '
                      + data.total + ')</div>';
     drawPager(pager);
     // navi
@@ -85,20 +136,20 @@ function my_onstat(data) {
 
 function my_onterm(data) {
     var termlists = [];
-    termlists.push('<hr/><b>TERMLISTS:</b><hr/><div class="termtitle">Sources</div>');
+    termlists.push('<hr/><b>' + M('TERMLISTS') + ':</b><hr/><div class="termtitle">' + M('Sources') + '</div>');
     for (var i = 0; i < data.xtargets.length && i < SourceMax; i++ ) {
         termlists.push('<a href="#" target_id='+data.xtargets[i].id
             + ' onclick="limitTarget(this.getAttribute(\'target_id\'), this.firstChild.nodeValue);return false;">' + data.xtargets[i].name
         + ' </a><span> (' + data.xtargets[i].freq + ')</span><br/>');
     }
 
-    termlists.push('<hr/><div class="termtitle">Subjects</div>');
+    termlists.push('<hr/><div class="termtitle">' + M('Subjects') + '</div>');
     for (var i = 0; i < data.subject.length && i < SubjectMax; i++ ) {
         termlists.push('<a href="#" onclick="limitQuery(\'su\', this.firstChild.nodeValue);return false;">' + data.subject[i].name + '</a><span>  ('
               + data.subject[i].freq + ')</span><br/>');
     }
 
-    termlists.push('<hr/><div class="termtitle">Authors</div>');
+    termlists.push('<hr/><div class="termtitle">' + M('Authors') + '</div>');
     for (var i = 0; i < data.author.length && i < AuthorMax; i++ ) {
         termlists.push('<a href="#" onclick="limitQuery(\'au\', this.firstChild.nodeValue);return false;">'
                             + data.author[i].name
@@ -234,10 +285,10 @@ function drawPager (pagerDiv)
         ? firstClkbl + 2*onsides
         : pages;
 
-    var prev = '<span id="prev">&#60;&#60; Prev</span><b> | </b>';
+    var prev = '<span id="prev">&#60;&#60; ' + M('Prev') + '</span><b> | </b>';
     if (curPage > 1)
         prev = '<a href="#" id="prev" onclick="pagerPrev();">'
-        +'&#60;&#60; Prev</a><b> | </b>';
+        +'&#60;&#60; ' + M('Prev') + '</a><b> | </b>';
 
     var middle = '';
     for(var i = firstClkbl; i <= lastClkbl; i++) {
@@ -249,10 +300,10 @@ function drawPager (pagerDiv)
             + numLabel + ' </a>';
     }
 
-    var next = '<b> | </b><span id="next">Next &#62;&#62;</span>';
+    var next = '<b> | </b><span id="next">' + M('Next') + ' &#62;&#62;</span>';
     if (pages - curPage > 0)
         next = '<b> | </b><a href="#" id="next" onclick="pagerNext()">'
-        +'Next &#62;&#62;</a>';
+        + M('Next') + ' &#62;&#62;</a>';
 
     var predots = '';
     if (firstClkbl > 1)
@@ -371,26 +422,35 @@ function renderDetails(data, marker)
     return details;
 }
 
-
-$(document).ready(function() {
-    $("#mkwsSwitch").html($("<a/>", {
-       href: '#',
-       onclick: "switchView(\'records\')",
-       text: "Records",
-    }));
-    $("#mkwsSwitch").append($("<span/>", { text: " | " }));
-    $("#mkwsSwitch").append($("<a/>", {
-       href: '#',
-       onclick: "switchView(\'targets\')",
-       text: "Targets",
-    }));
+/*
+ * All the HTML stuff to render the search forms and
+ * result pages.
+ */
+function mkws_html_all(data) {
+
+    /* default config */
+    var config = {
+       sort: [["relevance"], ["title:1", "title"], ["date:0", "newest"], ["date:1", "oldest"]],
+       perpage: [10, 20, 30, 50],
+       sort_default: "relevance",
+       perpage_default: 20,
+       query_width: 50,
+       switch: true, /* show/hide Records|Targets menu */
+
+       dummy: "dummy"
+    };
+
+    /* override standard config values by function parameters */
+    for (var k in data) {
+       config[k] = data[k];
+    }
 
     // For some reason, doing this programmatically results in
     // document.search.query being undefined, hence the raw HTML.
     $("#mkwsSearch").html('\
     <form id="searchForm" name="search">\
       <input id="query" type="text" size="50" />\
-      <input id="button" type="submit" value="Search" />\
+      <input id="button" type="submit" value="' + M('Search') + '" />\
     </form>');
 
     $("#mkwsRecords").html('\
@@ -402,11 +462,9 @@ $(document).ready(function() {
           <td valign="top">\
             <div id="ranking">\
               <form name="select" id="select">\
-        Sort by\
-        <select name="sort" id="sort"><option value="relevance" selected="selected">relevance</option><option value="title:1">title</option><option value="date:0">newest</option><option value="date:1">oldest</option></select>\
-        and show \
-        <select name="perpage" id="perpage"><option value="10">10</option><option value="20" selected="selected">20</option><option value="30">30</option><option value="50">50</option></select>\
-        per page.\
+        ' + M('Sort by') + mkws_html_sort(config) + '\
+        ' + M('and show') + ' ' + mkws_html_perpage(config) + '\
+        ' + M('per page') + '.\
        </form>\
             </div>\
             <div id="pager"></div>\
@@ -417,19 +475,84 @@ $(document).ready(function() {
       </table>\
     </div>');
 
+    mkws_html_switch(config);
+    if (mkws_config.use_service_proxy)
+       mkws_service_proxy_auth(config.service_proxy_auth);
+
+    domReady();
+}
+
+function mkws_html_switch(config) {
+    $("#mkwsSwitch").html($("<a/>", {
+       href: '#',
+       onclick: "switchView(\'records\')",
+       text: "Records"
+    }));
+    $("#mkwsSwitch").append($("<span/>", { text: " | " }));
+    $("#mkwsSwitch").append($("<a/>", {
+       href: '#',
+       onclick: "switchView(\'targets\')",
+       text: "Targets"
+    }));
+
     $("#mkwsTargets").html('\
       <div id="bytarget">\
        No information available yet.\
       </div>');
     $("#mkwsTargets").css("display", "none");
 
-    domReady();
-});
+    if (!config.switch) {
+        $("#mkwsSwitch").css("display", "none");
+    }
+}
+
+function mkws_html_sort(config) {
+    var sort_html = '<select name="sort" id="sort">';
+
+    for(var i = 0; i < config.sort.length; i++) {
+       var key = config.sort[i][0];
+       var val = config.sort[i].length == 1 ? config.sort[i][0] : config.sort[i][1];
+
+       sort_html += '<option value="' + key + '"';
+       if (key == config.sort_default) {
+           sort_html += ' selected="selected"';
+       }
+       sort_html += '>' + val + '</option>';
+    }
+    sort_html += '</select>';
+
+    return sort_html;
+}
+
+function mkws_html_perpage(config) {
+    var perpage_html = '<select name="perpage" id="perpage">';
 
-$(document).ready(function() {
-    var jqxhr = jQuery.get("/service-proxy-auth")
+    for(var i = 0; i < config.perpage.length; i++) {
+       var key = config.perpage[i];
+
+       perpage_html += '<option value="' + key + '"';
+       if (key == config.perpage_default) {
+           perpage_html += ' selected="selected"';
+       }
+       perpage_html += '>' + key + '</option>';
+    }
+    perpage_html += '</select>';
+
+    return perpage_html;
+}
+
+/*
+ * Run service-proxy authentication in background (after page load).
+ * The username/password is configured in the apache config file
+ * for the site.
+ */
+function mkws_service_proxy_auth(auth_url) {
+    if (!auth_url)
+       auth_url = "/service-proxy-auth";
+
+    var jqxhr = jQuery.get(auth_url)
        .fail(function() {
-           alert("service proxy authentification failed, give up!");
+           alert("service proxy authentication failed, give up!");
        })
        .success(function(data) {
            if (!jQuery.isXMLDoc(data)) {
@@ -442,4 +565,29 @@ $(document).ready(function() {
                return;
            }
        });
-});
+}
+
+/* locale */
+function M(word) {
+    var lang = jQuery.parseQuerystring().lang || mkws_config.lang;
+
+    if (!lang || !mkws_locale_lang[lang])
+       return word;
+
+    return mkws_locale_lang[lang][word] ? mkws_locale_lang[lang][word] : word;
+}
+
+jQuery.extend({
+    parseQuerystring: function() {
+    var nvpair = {};
+    var qs = window.location.search.replace('?', '');
+    var pairs = qs.split('&');
+    $.each(pairs, function(i, v){
+       var pair = v.split('=');
+       nvpair[pair[0]] = pair[1];
+    });
+    return nvpair;
+} });
+
+/* magic */
+$(document).ready(function() { mkws_html_all(mkws_config) });
index f17c546..3920487 100644 (file)
@@ -69,3 +69,15 @@ div.details {
     background-color: #fafafa;
     border-bottom: 1px solid  #156a16;
 }
+
+#mkwsStat {
+    font-weight: bold;
+    font-size: small;
+}
+
+#footer {
+    padding-top: 4px;
+    text-align: center;
+    font-size: small;
+}
+