Claire Hernandez 9 years ago
committed by Paul Poulain
parent
commit
f0f3c9b4bf
  1. 12
      README
  2. 2
      koct/chrome.manifest
  3. BIN
      koct/chrome/content/koct-window.png
  4. 6
      koct/chrome/content/koct.xul
  5. 84
      koct/chrome/content/main.xul
  6. BIN
      koct/chrome/content/module-icon.png
  7. 187
      koct/chrome/content/script.js
  8. BIN
      koct/chrome/icons/default/koct-window.ico
  9. 72
      koct/chrome/icons/default/koct-window.xpm
  10. 29
      koct/install.rdf

12
README

@ -1,2 +1,10 @@
This repository is for general contributions
to Koha.
This repository is for general contributions to Koha.
- sandbox:
The sandbox system has been developed with the goal to lower the barrier for librarian to test patches and improvements of Koha.
http://wiki.koha-community.org/wiki/Sandboxes
- koct:
Koha Offline Circulation Firefox addon
http://wiki.koha-community.org/wiki/Offline_circulation_firefox_plugin
https://addons.mozilla.org/fr/firefox/addon/koct/

2
koct/chrome.manifest

@ -0,0 +1,2 @@
content koct chrome/content/
overlay chrome://browser/content/browser.xul chrome://koct/content/koct.xul

BIN
koct/chrome/content/koct-window.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

6
koct/chrome/content/koct.xul

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<overlay id="koct" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<statusbar id="status-bar">
<statusbarpanel image="chrome://koct/content/koct-window.png" class="statusbarpanel-iconic" onclick="window.open('chrome://koct/content/main.xul','main','centerscreen,chrome,resizable');"/>
</statusbar>
</overlay>

84
koct/chrome/content/main.xul

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<window
id="koct-window"
title="Koha Offline Circulation Tool"
persist="screenX screenY"
width="500"
height="400"
onload="onReady()"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="script.js" />
<tabbox flex="1">
<tabs>
<tab label="Check Out" accesskey="o" />
<tab label="Check In" accesskey="i" />
<tab label="Log" accesskey="l" onclick="updateTree()" />
<tab label="Param" />
</tabs>
<tabpanels flex="1">
<tabpanel id="issuetab">
<vbox flex="1">
<hbox flex="1">
<vbox flex="1">
<label control="issuepatronbarcode" value="Patron Barcode:" />
<textbox id="issuepatronbarcode" tabindex="1" onkeypress="checkReturn(event,'issueitembarcode', false)" />
<label control="issueitembarcode" value="Item Barcode:" />
<textbox id="issueitembarcode" tabindex="2" onkeypress="checkReturn(event,'issuesave', 'issue')" />
</vbox>
<!--<vbox>
<label control="issuedate" value="Expected Return:" />
<datepicker id="issuedate" type="grid" />
</vbox>-->
</hbox>
<button id="issuesave" label="Save" tabindex="3" oncommand="save('issue')" />
</vbox>
</tabpanel>
<tabpanel id="returntab">
<vbox flex="1">
<vbox flex="1">
<label control="returnitembarcode" value="Item Barcode:" />
<textbox id="returnitembarcode" tabindex="1" onkeypress="checkReturn(event,'returnsave', 'return')" />
</vbox>
<button id="returnsave" tabindex="2" label="Save" oncommand="save('return')" />
</vbox>
</tabpanel>
<tabpanel id="logtab">
<vbox flex="1">
<tree id="tree1" flex="1" hidecolumnpicker="true" seltype="single" onselect="setText('tree1','value1');" >
<treecols>
<treecol flex="1" label="Timestamp" />
<treecol flex="1" label="Action" />
<treecol flex="1" label="Card Number" />
<treecol flex="1" label="Barcode" />
<treecol flex="1" label="Status" />
</treecols>
<treechildren id="treechildren">
</treechildren>
</tree>
<hbox>
<button label="Commit to Koha" oncommand="commit(true)" />
<button label="Apply directly" oncommand="commit(false)" />
<button label="Clear" oncommand="clear()" />
</hbox>
</vbox>
</tabpanel>
<tabpanel id="paramtab">
<vbox onkeyup="savePreferences()" onchange="savePreferences()" oncommand="savePreferences()">
<label control="server" value="Server:" />
<textbox id="server" />
<label control="branchcode" value="Branch Code:" />
<textbox id="branchcode" />
<label control="username" value="Username:" />
<textbox id="username" />
<label control="password" value="Password:" />
<textbox id="password" type="password" />
</vbox>
</tabpanel>
</tabpanels>
</tabbox>
<statusbar>
<statusbarpanel flex="1" />
<statusbarpanel id="status" />
</statusbar>
</window>

BIN
koct/chrome/content/module-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

187
koct/chrome/content/script.js

@ -0,0 +1,187 @@
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var dbCon;
var rowsadded;
function onReady() {
rowsadded = 0;
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
restorePreferences();
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("ProfD", Components.interfaces.nsIFile);
file.append("offlinecirc.sqlite");
var storageService = Components.classes["@mozilla.org/storage/service;1"]
.getService(Components.interfaces.mozIStorageService);
dbConn = storageService.openDatabase(file);
dbConn.executeSimpleSQL("CREATE TABLE IF NOT EXISTS offlinecirc (timestamp TIMESTAMP, action VARCHAR, cardnumber VARCHAR, barcode VARCHAR, status VARCHAR)");
var statement = Components.classes['@mozilla.org/storage/statement-wrapper;1'].createInstance(Components.interfaces.mozIStorageStatementWrapper);
var query = dbConn.createStatement("SELECT COUNT(*) AS numrow FROM offlinecirc");
statement.initialize(query);
statement.step();
if(statement.row.numrow) {
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
var deleteRows = {value: null};
if(prompts.confirmCheck(window, "WARNING", "The local database contains "+statement.row.numrow+" entrie(s), do you want to remove them ?", "I want to delete rows", deleteRows)){
if (deleteRows.value){
dbConn.executeSimpleSQL("DELETE FROM offlinecirc");
}
}
}
}
function updateTree() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var treechildren = document.getElementById("treechildren");
while (treechildren.firstChild) {
treechildren.removeChild(treechildren.firstChild);
}
var statement = Components.classes['@mozilla.org/storage/statement-wrapper;1'].createInstance(Components.interfaces.mozIStorageStatementWrapper);
var query = dbConn.createStatement("SELECT * FROM offlinecirc");
statement.initialize(query);
while (statement.step()) {
var treeitem = document.createElementNS(XUL_NS, "treeitem");
var treerow = document.createElementNS(XUL_NS, "treerow");
treeitem.appendChild(treerow);
for each( column in ['timestamp','action','cardnumber','barcode','status'] ) {
var treecell = document.createElementNS(XUL_NS, "treecell");
treecell.setAttribute("label", eval('statement.row.'+column));
treerow.appendChild(treecell);
}
treechildren.appendChild(treeitem);
}
}
function save(attr) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
switch(attr) {
case 'issue':
var patronbarcode = document.getElementById('issuepatronbarcode').value;
var itembarcode = document.getElementById('issueitembarcode').value;
dbConn.executeSimpleSQL("INSERT INTO offlinecirc VALUES(CURRENT_TIMESTAMP,'issue','"+patronbarcode+"','"+itembarcode+"','Local.')");
rowsadded++;
document.getElementById('issuepatronbarcode').value = '';
document.getElementById('issueitembarcode').value = '';
document.getElementById('issuepatronbarcode').focus();
document.getElementById('status').setAttribute("label",rowsadded+" Row(s) Added");
break;
case 'return':
var itembarcode = document.getElementById('returnitembarcode').value;
dbConn.executeSimpleSQL("INSERT INTO offlinecirc VALUES(CURRENT_TIMESTAMP,'return',NULL,'"+itembarcode+"','Local.')");
rowsadded++;
document.getElementById('returnitembarcode').value = '';
document.getElementById('returnitembarcode').focus();
document.getElementById('status').setAttribute("label",rowsadded+" Row(s) Added");
break;
}
}
function checkReturn(e, nextFieldName, attr) {
var event;
var key
var cChar
var retCheck = /\r/;
if (window.event) {
event = window.event;
key = window.event.keyCode;
target = event.srcElement;
} else if (e) {
event = e;
key = event.which;
target = event.target;
}
cChar= String.fromCharCode(key)
if(retCheck.test(cChar)) {
document.getElementById(nextFieldName).focus();
if(attr) {
save(attr);
}
}
}
function restorePreferences() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
prefs = prefs.getBranch("extensions.koct.");
for each( pref in ['server','branchcode','username','password'] ) {
document.getElementById(pref).value = prefs.getComplexValue("preference."+pref,
Components.interfaces.nsISupportsString).data;
}
}
function savePreferences() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
prefs = prefs.getBranch("extensions.koct.");
var str = Components.classes["@mozilla.org/supports-string;1"]
.createInstance(Components.interfaces.nsISupportsString);
for each( pref in ['server','branchcode','username','password'] ) {
str.data = document.getElementById(pref).value;
prefs.setComplexValue("preference."+pref,
Components.interfaces.nsISupportsString, str);
}
}
function commit( pending ) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var statement = Components.classes['@mozilla.org/storage/statement-wrapper;1'].createInstance(Components.interfaces.mozIStorageStatementWrapper);
var query = dbConn.createStatement("SELECT * FROM offlinecirc WHERE status='Local.' OR status='Authentication failed.'");
statement.initialize(query);
var url = document.getElementById('server').value+"/cgi-bin/koha/offline_circ/service.pl";
while ( statement.step() ) {
var params = "userid=" + document.getElementById('username').value;
params += "&password=" + document.getElementById('password').value;
params += "&branchcode=" + document.getElementById('branchcode').value;
params += "&pending=" + pending;
params += "&action=" + statement.row.action;
params += "&timestamp=" + statement.row.timestamp;
params += statement.row.cardnumber ? "&cardnumber=" + statement.row.cardnumber : "";
params += "&barcode=" + statement.row.barcode;
var req = new XMLHttpRequest();
req.open("POST", url, false);
req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", params.length);
//req.setRequestHeader("Connection", "close");
req.send(params);
if ( req.status == 200 ) {
dbConn.executeSimpleSQL("UPDATE offlinecirc SET status='"+req.responseText+"' WHERE timestamp='"+statement.row.timestamp+"'");
updateTree();
}
}
}
function clear() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var statement = Components.classes['@mozilla.org/storage/statement-wrapper;1'].createInstance(Components.interfaces.mozIStorageStatementWrapper);
var query = dbConn.createStatement("SELECT * FROM offlinecirc");
statement.initialize(query);
dbConn.executeSimpleSQL("DELETE FROM offlinecirc");
updateTree();
}

BIN
koct/chrome/icons/default/koct-window.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

72
koct/chrome/icons/default/koct-window.xpm

@ -0,0 +1,72 @@
/* XPM */
static char * koct_window_xpm[] = {
"16 16 53 1",
" c None",
". c #99CC33",
"+ c #92C825",
"@ c #92C826",
"# c #FFFFFF",
"$ c #DDDAE4",
"% c #9B98A2",
"& c #C7C4CD",
"* c #FEFEFE",
"= c #D4D4D4",
"- c #272727",
"; c #000000",
"> c #282828",
", c #F3F3F3",
"' c #FDFDFD",
") c #BDBDBD",
"! c #565656",
"~ c #DBDBDB",
"{ c #0C0C0C",
"] c #F2F2F2",
"^ c #2E2E2E",
"/ c #CECECE",
"( c #ACACAC",
"_ c #CACACA",
": c #414141",
"< c #F4F4F4",
"[ c #0F0F0F",
"} c #121212",
"| c #F6F6F6",
"1 c #D0D0D0",
"2 c #5A5A5A",
"3 c #BEBEBE",
"4 c #8D8D8D",
"5 c #060606",
"6 c #444444",
"7 c #C3C3C3",
"8 c #686868",
"9 c #CBCBCB",
"0 c #B1B1B1",
"a c #C5C5C5",
"b c #C9C9C9",
"c c #1A1A1A",
"d c #EBEBEB",
"e c #DDDDDD",
"f c #C8C8C8",
"g c #DCDCDC",
"h c #262626",
"i c #424242",
"j c #0B0B0B",
"k c #C7C7C7",
"l c #FFFEFF",
"m c #A7A4AD",
"n c #B7B4BE",
".+@@@@@@@@@@@@+.",
"+#######$%&####+",
"@##**#=-;;;>,'#@",
"@#**#);;;;;;!##@",
"@#**~;;;;;;;{]#@",
"@#*#^;;;;;;;;/#@",
"@##(;;;;;;;;;_#@",
"@##:;;;;;;;;;=#@",
"@#<[;;;;;;;;}|#@",
"@#1;23345;;;6##@",
"@#78#''#9;;;0##@",
"@#ab'***'c;-#'#@",
"@#dd*e##f;;~**#@",
"@#*'*ghi;jk#**#@",
"+#####lmn######+",
".+@@@@@@@@@@@@+."};

29
koct/install.rdf

@ -0,0 +1,29 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>koct@koha.fr</em:id>
<em:version>0.2.2</em:version>
<em:type>2</em:type>
<!-- Target Application this extension can install into,
with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>1.5</em:minVersion>
<em:maxVersion>3.6.*</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:iconURL>chrome://koct/content/module-icon.png</em:iconURL>
<em:name>KOCT</em:name>
<em:description>Koha Offline Circulation Tool</em:description>
<em:creator>BibLibre</em:creator>
<em:developer>Jean-André Santoni; Claire Hernandez</em:developer>
<em:homepageURL>http://www.biblibre.com/</em:homepageURL>
</Description>
</RDF>
Loading…
Cancel
Save