Work in progress
authorJason Skomorowski <jason@indexdata.com>
Mon, 15 Nov 2010 05:53:17 +0000 (06:53 +0100)
committerJason Skomorowski <jason@indexdata.com>
Mon, 15 Nov 2010 05:53:17 +0000 (06:53 +0100)
mkdru-block-facet.tpl.php [new file with mode: 0644]
mkdru-page.tpl.php [new file with mode: 0644]
mkdru.admin.inc [new file with mode: 0644]
mkdru.client.js [new file with mode: 0644]
mkdru.info [new file with mode: 0644]
mkdru.install [new file with mode: 0644]
mkdru.module [new file with mode: 0644]
mkdru.theme.js [new file with mode: 0644]

diff --git a/mkdru-block-facet.tpl.php b/mkdru-block-facet.tpl.php
new file mode 100644 (file)
index 0000000..61a6c24
--- /dev/null
@@ -0,0 +1 @@
+<div id="<?php print $divId ?>"> </div>
diff --git a/mkdru-page.tpl.php b/mkdru-page.tpl.php
new file mode 100644 (file)
index 0000000..0595341
--- /dev/null
@@ -0,0 +1,45 @@
+  <div id="mkdru">
+   <table width="100%" border="0" cellpadding="6" cellspacing="0">
+    <tr>
+     <td width="250" height="100" align="center"><b>PAZPAR2</b></td>
+     <td>
+      <form class="mkdru-search">
+       <input type="text" size="50"/>
+       <input id="button" type="button" value="Search"/>
+      </form>
+     </td>
+     <td>
+      <a href="http://www.indexdata.com"><img border="0" title="IndexData home page" src="id.gif" align="right" alt="" /></a>
+     </td>
+    </tr>
+   </table>
+
+  </div>
+
+  <div id="recordview">
+
+      <div id="ranking">
+
+       <form>
+        Sort by
+        <select id="mkdru-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 id="mkdru-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.
+       </form>
+      </div>
+      <div id="mkdru-pager"></div>
+      <div id="mkdru-navi"></div>
+      <div id="mkdru-results"></div>
+  </div>
diff --git a/mkdru.admin.inc b/mkdru.admin.inc
new file mode 100644 (file)
index 0000000..c07ac31
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+function jsdemo2_admin_settings() {
+  $form['jsdemo2_author_max']=array(
+    '#type' => 'textfield',
+    '#title' => t('Maximum authors to display'),
+    '#default_value' => variable_get('jsdemo2_author_max', 10),
+    '#size' => 3,
+    '#maxlength' => 3,
+  );
+  
+  $form['jsdemo2_source_max']=array(
+    '#type' => 'textfield',
+    '#title' => t('Maximum sources to display'),
+    '#default_value' => variable_get('jsdemo2_source_max', 16),
+    '#size' => 3,
+    '#maxlength' => 3,
+  );
+
+  $form['jsdemo2_subject_max']=array(
+    '#type' => 'textfield',
+    '#title' => t('Maximum subjects to display'),
+    '#default_value' => variable_get('jsdemo2_subject_max', 10),
+    '#size' => 3,
+    '#maxlength' => 3,
+  );
+
+  return system_settings_form($form);
+}
+
+function jsdemo2_admin_settings_validate($form, $form_state) {
+  if (!is_numeric($form_state['values']['jsdemo2_source_max'])) {
+    form_set_error('jsdemo2_source_max', t('Please enter a number.'));
+  }
+  if (!is_numeric($form_state['values']['jsdemo2_author_max'])) {
+    form_set_error('jsdemo2_author_max', t('Please enter a number.'));
+  }
+  if (!is_numeric($form_state['values']['jsdemo2_subject_max'])) {
+    form_set_error('jsdemo2_subject_max', t('Please enter a number.'));
+  }
+}
diff --git a/mkdru.client.js b/mkdru.client.js
new file mode 100644 (file)
index 0000000..1787621
--- /dev/null
@@ -0,0 +1,143 @@
+// Set up namespace and some state.
+var mkdru = {
+  // Settings to pass to pz2.js
+  usesessions: true,
+  showResponseType: '',
+  // Variables
+  curPage: 1,
+  recPerPage: 20,
+  totalRec: 0,
+  curSort: 'relevance',
+  curFilter: null,
+  submitted: false,
+  sourceMax: 16, // facets
+  subjectMax: 10,
+  authorMax: 10,
+  pz2: null,
+  pazpar2Path: '/pazpar2/search.pz2',
+};
+
+
+
+// pz2.js event handlers:
+mkdru.pz2Init = function () {
+  mkdru.pz2.stat();
+  mkdru.pz2.bytarget();
+};
+
+mkdru.pz2Show = function (data) {
+  mkdru.totalRec = data.merged;
+  $('#mkdru-pager').html(Drupal.theme('mkdruPager', data, mkdru.curPage,
+                                      Math.ceil(mkdru.totalRec / mkdru.recPerPage)));
+  $('.mkdru-next').bind('click', mkdru.nextPage);
+  $('.mkdru-prev').bind('click', mkdru.prevPage);
+
+  var html = "";
+  for (var i = 0; i < data.hits.length; i++) {
+    html += Drupal.theme('mkdruResult', data.hits[i], 
+                         i + 1 + mkdru.recPerPage * 
+                         (mkdru.curPage - 1));
+  }
+  $('#mkdru-results').html(html);
+};
+
+mkdru.pz2Status = function (data) {
+};
+
+mkdru.pz2Term = function (data) {
+    var html = "";
+    for (var i = 0; i < data.xtargets.length && i < mkdru.SourceMax; i++ ) {
+      html += Drupal.theme('mkdruTerm', data.xtargets[i].name, data.xtargets[i].freq, 
+                           'mkdru-facet-link-source', data.xtargets[i].id);
+    }
+    $('#mkdru-sources').html(html);
+
+    html = "";
+    for (var i = 0; i < data.subject.length && i < mkdru.SubjectMax; i++ ) {
+      html += Drupal.theme('mkdruTerm', data.subject[i].name, data.subject[i].freq, 
+                           'mkdru-facet-link-subject', data.subject[i].id);
+    }
+    $('#mkdru-subjects').html(html);
+
+    html = "";
+    for (var i = 0; i < data.author.length && i < mkdru.AuthorMax; i++ ) {
+      html += Drupal.theme('mkdruTerm', data.author[i].name, data.author[i].freq, 
+                           'mkdru-facet-link-author', data.author[i].id);
+    }
+    $('#mkdru-authors').html(html);
+};
+
+mkdru.pz2ByTarget = function (data) {
+  
+};
+
+
+
+// UI functions:
+mkdru.submitQuery = function () {
+  mkdru.submitted = true;
+//   mkdru.resetPage();
+//   mkdru.pollDropDowns();
+  mkdru.search();
+};
+
+mkdru.search = function () {
+  mkdru.pz2.search($('.mkdru-search input:text').attr('value'),
+                   mkdru.recPerPage, mkdru.curSort, mkdru.curFilter);
+};
+
+mkdru.pollDropDowns = function () {
+  mkdru.recPerPage = $('#mkdru-perpage').value;
+  mkdru.curSort = $('#mkdru-sort').value;
+  if (!mkdru.submitted) return false;
+  mkdru.resetPage();
+  mkdru.pz2.show(0, mkdru.recPerPage, mkdru.curSort);
+};
+
+mkdru.limitQuery = function (field, value) {
+  
+};
+
+mkdru.resetPage = function () {
+  mkdru.curPage = 1;
+  mkdru.totalRec = 0;
+};
+
+mkdru.showPage = function (pageNum) {
+  mkdru.curPage = pageNum;
+  mkdru.pz2.showPage(pageNum-1);
+};
+
+mkdru.nextPage = function () {
+  if (mkdru.totalRec - mkdru.recPerPage * mkdru.curPage > 0) {
+    mkdru.pz2.showNext();
+    mkdru.curPage++;
+  }
+};
+
+mkdru.prevPage = function () {
+  if (mkdru.pz2.showPrev() != false) {
+    mkdru.curPage--;
+  }
+};
+
+
+// wait until the DOM is ready, bind events
+// and instantiate pz2 library
+$(document).ready(function () {
+  $('.mkdru-search input:button').bind('click', mkdru.submitQuery);
+  $('.mkdru-search input:text').attr('value', '');
+  $('#mkdru-perpage').bind('change', function () { mkdru.pollDropDowns() });
+  $('#mkdru-sort').bind('change', function () { mkdru.pollDropDowns() });
+  mkdru.pz2 = new pz2( { "onshow": mkdru.pz2Show,
+              "showtime": 500, //each timer (show, stat, term, bytarget) can be specified this way
+              "pazpar2path": mkdru.pazpar2path,
+              "oninit": mkdru.pz2Init,
+              "onstat": mkdru.pz2Status,
+              "onterm": mkdru.pz2Term,
+              "termlist": "xtargets,subject,author",
+              "onbytarget": mkdru.pz2ByTarget,
+              "usesessions" : mkdru.usesessions,
+              "showResponseType": mkdru.showResponseType,
+              "onrecord": mkdru.pz2Record } );
+});
\ No newline at end of file
diff --git a/mkdru.info b/mkdru.info
new file mode 100644 (file)
index 0000000..119b00d
--- /dev/null
@@ -0,0 +1,3 @@
+name = Z39.50 metasearch
+description = Metasearching of Z39.50 and other targets via Index Data's Pazpar2 and associated tool stack.
+core = 6.x
diff --git a/mkdru.install b/mkdru.install
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mkdru.module b/mkdru.module
new file mode 100644 (file)
index 0000000..1ffb195
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+
+/**
+* Implementation of hook_node_info().
+*/
+function mkdru_node_info() {
+  return array(
+    'mkdru' => array(
+      'name' => t("Z39.50/SRU metasearch interface"),
+      'module' => 'mkdru',
+      'description' => t("Metasearch interface for Z39.50/SRU and other targets via a Pazpar2/Service Proxy backend"),
+
+    )
+  );
+}
+
+/**
+* Implementation of hook_perm().
+*/
+function mkdru_perm() {
+  return array('create metasearch interface', 'edit any metasearch interface', 'edit own metasearch interface');
+}
+
+/**
+* Implementation of hook_access().
+*/
+function mkdru_access($op, $node, $account) {
+
+  if ($op == 'create') {
+    // Only users with permission to do so may create this node type.
+    return user_access('create metasearch interface', $account);
+  }
+
+  // Users who create a node may edit or delete it later, assuming they have the
+  // necessary permissions.
+  if ($op == 'update' || $op == 'delete') {
+    if (user_access('edit own metasearch interface', $account) && ($account->uid == $node->uid)) {
+      return TRUE;
+    } else if (user_access('edit any metasearch interface', $account)) {
+      return TRUE;
+    }
+  }
+}
+
+/**
+* Implementation of hook_form().
+*/
+function mkdru_form(&$node, $form_state) {
+  $type = node_get_types('type', $node);
+
+  $form['title'] = array(
+    '#type' => 'textfield',
+    '#title' => check_plain($type->title_label),
+    '#required' => TRUE,
+    '#default_value' => $node->title,
+    '#weight' => -5
+  );
+
+  return $form;
+}
+
+/**
+* Implementation of hook_theme().
+*/
+function mkdru_theme() {
+  return array(
+    'mkdru_page' => array(
+      'template' => 'mkdru-page',
+      'arguments' => array(),
+    ),
+    'mkdru_page_js' => array(
+      'arguments' => array(),
+    ),
+//     'mkdru_block_facet' => array(
+//       'template' => 'mkdru-block-facet',
+//       'arguments' => array('divId' => NULL),
+//     ),
+  );
+}
+
+/**
+* Theme function to include Javascript search client and deps
+*/
+function theme_mkdru_page_js() {
+  $path = drupal_get_path('module', 'mkdru');
+  drupal_add_js('pazpar2/js/pz2.js', 'module', 'footer');
+  drupal_add_js($path . '/mkdru.theme.js', 'module', 'footer');
+  drupal_add_js($path . '/mkdru.client.js', 'module', 'footer');
+}
+
+/** 
+* Implementation of hook_view()
+*/
+function mkdru_view($node, $teaser = FALSE, $page = FALSE) {
+  $node->content['mkdru_page_js'] = array(
+    '#value' => theme('mkdru_page_js'), 
+    '#weight' => 0,
+  );
+  $node->content['mkdru_page'] = array(
+    '#value' => theme('mkdru_page'), 
+    '#weight' => 1,
+  );
+  return $node;
+}
+
+/** 
+* Implementation of hook_block()
+*/
+function mkdru_block($op='list', $delta='sources', $edit=array()) {
+  switch ($op) {
+    case 'list':
+      $blocks['mkdru_sources']['info'] = t('mkdru - source facets');
+      $blocks['mkdru_sources']['cache'] = BLOCK_NO_CACHE;
+      $blocks['mkdru_subjects']['info'] = t('mkdru - subject facets');
+      $blocks['mkdru_subjects']['cache'] = BLOCK_NO_CACHE;
+      $blocks['mkdru_authors']['info'] = t('mkdru - author facets');
+      $blocks['mkdru_authors']['cache'] = BLOCK_NO_CACHE;
+      return $blocks;
+
+    case 'view':
+      switch ($delta) {
+        // TODO: make the facet themable, I have no clue why this won't work
+//         case 'mkdru_sources':
+//           $block['subject'] = t('Source');
+//           $block['content'] = theme('mkdru_block_facet', 'mkdru-sources');
+//           return $block;
+//         case 'mkdru_subjects':
+//           $block['subject'] = t('Subject');
+//           $block['content'] = theme('mkdru_block_facet', 'mkdru-subjects');
+//           return $block;
+//         case 'mkdru_authors':
+//           $block['subject'] = t('Author');
+//           $block['content'] = theme('mkdru_block_facet', 'mkdru-authors');
+//           return $block;
+        case 'mkdru_sources':
+          $block['subject'] = t('Source');
+          $block['content'] = '<div id="mkdru-sources"> </div>';
+          return $block;
+        case 'mkdru_subjects':
+          $block['subject'] = t('Subject');
+          $block['content'] = '<div id="mkdru-subjects"> </div>';
+          return $block;
+        case 'mkdru_authors':
+          $block['subject'] = t('Author');
+          $block['content'] = '<div id="mkdru-authors"> </div>';
+          return $block;
+    }
+  }
+}
\ No newline at end of file
diff --git a/mkdru.theme.js b/mkdru.theme.js
new file mode 100644 (file)
index 0000000..2183e1c
--- /dev/null
@@ -0,0 +1,72 @@
+Drupal.theme.prototype.mkdruResult = function(hit, num) {
+  var html = [];
+  html.push('<div class="record" id="recdiv_' + hit.recid + '" >'
+      + '<span>' + num + '. </span>'
+      + '<a href="#" id="rec_' + hit.recid
+      + '"><b>' 
+      + hit["md-title"] + ' </b></a>');
+  if (hit["md-title-remainder"] !== undefined) {
+    html.push('<span>' + hit["md-title-remainder"] + ' </span>');
+  }
+  if (hit["md-title-responsibility"] !== undefined) {
+    html.push('<span><i>'+hit["md-title-responsibility"]+'</i></span>');
+  }
+  html.push('</div>');
+  return (html.join(''));
+};
+
+Drupal.theme.prototype.mkdruPager = function (data, curPage, pages) {
+    var caption = '<hr/><div style="float: right">Displaying: ' 
+                    + (data.start + 1) + ' to ' + (data.start + data.num) +
+                     ' of ' + data.merged + ' (found: ' 
+                     + data.total + ')</div>';
+
+    var onsides = 6;
+
+    var firstClkbl = ( curPage - onsides > 0 ) 
+        ? curPage - onsides
+        : 1;
+
+    var lastClkbl = firstClkbl + 2*onsides < pages
+        ? firstClkbl + 2*onsides
+        : pages;
+
+    var prev = '<span id="prev">&#60;&#60; Prev</span><b> | </b>';
+    if (curPage > 1)
+        var prev = '<a href="#" class="mkdru-prev">'
+        +'&#60;&#60; Prev</a><b> | </b>';
+
+    var middle = '';
+    for(var i = firstClkbl; i <= lastClkbl; i++) {
+        var numLabel = i;
+        if(i == curPage)
+            numLabel = '<b>' + i + '</b>';
+
+        middle += '<a href="#" onclick="mkdru.showPage(' + i + ')"> '
+            + numLabel + ' </a>';
+    }
+
+    var next = '<b> | </b><span id="next">Next &#62;&#62;</span>';
+    if (pages - curPage > 0)
+    var next = '<b> | </b><a href="#" class="mkdru-next">'
+        +'Next &#62;&#62;</a>';
+
+    predots = '';
+    if (firstClkbl > 1)
+        predots = '...';
+
+    postdots = '';
+    if (lastClkbl < pages)
+        postdots = '...';
+
+    return ('<div style="float: clear">' +
+        caption + prev + predots + middle + postdots + next + '</div><hr/>');
+};
+
+Drupal.theme.prototype.mkdruTerm = function (term, freq, linkClass, id) {
+  var html = '<a href="#"';
+  if (id)
+    html += ' target_id="' + id + '"';
+  html += ' class="' + linkClass + '">' + term + '</a><span> (' + freq + ')</span><br/>';
+  return html;
+};
\ No newline at end of file