[open-ils-commits] r18265 - in branches/rel_1_6/Open-ILS: examples src/perlmods/OpenILS/Application src/perlmods/OpenILS/Application/Actor src/perlmods/OpenILS/WWW src/sql/Pg src/sql/Pg/upgrade web/css/theme web/js/dojo web/js/dojo/MARC web/js/dojo/fieldmapper web/js/dojo/openils web/js/ui web/templates (miker)
svn at svn.open-ils.org
svn at svn.open-ils.org
Mon Oct 11 13:25:22 EDT 2010
Author: miker
Date: 2010-10-11 13:25:19 -0400 (Mon, 11 Oct 2010)
New Revision: 18265
Added:
branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/WWW/TemplateBatchBibUpdate.pm
branches/rel_1_6/Open-ILS/src/sql/Pg/upgrade/0434.data.merge_template_container_type.sql
branches/rel_1_6/Open-ILS/web/js/dojo/MARC/
branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Batch.js
branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Field.js
branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Record.js
Modified:
branches/rel_1_6/Open-ILS/examples/opensrf.xml.example
branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm
branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm
branches/rel_1_6/Open-ILS/src/sql/Pg/950.data.seed-values.sql
branches/rel_1_6/Open-ILS/web/css/theme/default.css
branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/AutoIDL.js
branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js
branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/IDL.js
branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/dojoData.js
branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/hash.js
branches/rel_1_6/Open-ILS/web/js/dojo/openils/User.js
branches/rel_1_6/Open-ILS/web/js/ui/base.js
branches/rel_1_6/Open-ILS/web/templates/login.tt2
Log:
Backporting batch update functionality for 1.6.2, along with some deps
Modified: branches/rel_1_6/Open-ILS/examples/opensrf.xml.example
===================================================================
--- branches/rel_1_6/Open-ILS/examples/opensrf.xml.example 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/examples/opensrf.xml.example 2010-10-11 17:25:19 UTC (rev 18265)
@@ -283,6 +283,15 @@
</servers>
<max_cache_time>86400</max_cache_time>
</global>
+ <anon>
+ <!-- anonymous cache. currently, primarily used for web session caching -->
+ <servers>
+ <server>localhost:11211</server>
+ </servers>
+ <max_cache_time>1800</max_cache_time>
+ <!-- maximum size of a single cache entry / default = 100k-->
+ <max_cache_size>102400</max_cache_size>
+ </anon>
</cache>
<apps>
Modified: branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm
===================================================================
--- branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm 2010-10-11 17:25:19 UTC (rev 18265)
@@ -7,6 +7,10 @@
use OpenSRF::EX qw(:try);
use OpenILS::Utils::Fieldmapper;
use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenSRF::Utils::SettingsClient;
+use OpenSRF::Utils::Cache;
+use Digest::MD5 qw(md5_hex);
+use OpenSRF::Utils::JSON;
my $apputils = "OpenILS::Application::AppUtils";
my $U = $apputils;
@@ -506,7 +510,101 @@
+__PACKAGE__->register_method(
+ method => "anon_cache",
+ api_name => "open-ils.actor.anon_cache.set_value",
+ signature => {
+ desc => q/
+ Sets a value in the anon web cache. If the session key is
+ undefined, one will be automatically generated.
+ /,
+ params => [
+ {desc => 'Session key', type => 'string'},
+ {
+ desc => q/Field name. The name of the field in this cache session whose value to set/,
+ type => 'string'
+ },
+ {
+ desc => q/The cached value. This can be any type of object (hash, array, string, etc.)/,
+ type => 'any'
+ },
+ ],
+ return => {
+ desc => 'session key on success, undef on error',
+ type => 'string'
+ }
+ }
+);
+__PACKAGE__->register_method(
+ method => "anon_cache",
+ api_name => "open-ils.actor.anon_cache.get_value",
+ signature => {
+ desc => q/
+ Returns the cached data at the specified field within the specified cache session.
+ /,
+ params => [
+ {desc => 'Session key', type => 'string'},
+ {
+ desc => q/Field name. The name of the field in this cache session whose value to set/,
+ type => 'string'
+ },
+ ],
+ return => {
+ desc => 'cached value on success, undef on error',
+ type => 'any'
+ }
+ }
+);
+
+__PACKAGE__->register_method(
+ method => "anon_cache",
+ api_name => "open-ils.actor.anon_cache.delete_session",
+ signature => {
+ desc => q/
+ Deletes a cache session.
+ /,
+ params => [
+ {desc => 'Session key', type => 'string'},
+ ],
+ return => {
+ desc => 'Session key',
+ type => 'string'
+ }
+ }
+);
+
+sub anon_cache {
+ my($self, $conn, $ses_key, $field_key, $value) = @_;
+
+ my $sc = OpenSRF::Utils::SettingsClient->new;
+ my $cache = OpenSRF::Utils::Cache->new('anon');
+ my $cache_timeout = $sc->config_value(cache => anon => 'max_cache_time') || 1800; # 30 minutes
+ my $cache_size = $sc->config_value(cache => anon => 'max_cache_size') || 102400; # 100k
+
+ if($self->api_name =~ /delete_session/) {
+
+ return $cache->delete_cache($ses_key);
+
+ } elsif( $self->api_name =~ /set_value/ ) {
+
+ $ses_key = md5_hex(time . rand($$)) unless $ses_key;
+ my $blob = $cache->get_cache($ses_key) || {};
+ $blob->{$field_key} = $value;
+ return undef if
+ length(OpenSRF::Utils::JSON->perl2JSON($blob)) > $cache_size; # bytes, characters, whatever ;)
+ $cache->put_cache($ses_key, $blob, $cache_timeout);
+ return $ses_key;
+
+ } else {
+
+ my $blob = $cache->get_cache($ses_key) or return undef;
+ return $blob->{$field_key};
+ }
+}
+
+
+
1;
Modified: branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm
===================================================================
--- branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm 2010-10-11 17:25:19 UTC (rev 18265)
@@ -175,6 +175,156 @@
}
__PACKAGE__->register_method(
+ method => "template_overlay_biblio_record_entry",
+ api_name => "open-ils.cat.biblio.record_entry.template_overlay",
+ stream => 1,
+ signature => q#
+ Overlays biblio.record_entry MARC values
+ @param auth The authtoken
+ @param records The record ids to be updated by the template
+ @param template The overlay template
+ @return Stream of hashes record id in the key "record" and t or f for the success of the overlay operation in key "success"
+ #
+);
+
+sub template_overlay_biblio_record_entry {
+ my($self, $conn, $auth, $records, $template) = @_;
+ my $e = new_editor(authtoken=>$auth, xact=>1);
+ return $e->die_event unless $e->checkauth;
+
+ $records = [$records] if (!ref($records));
+
+ for my $rid ( @$records ) {
+ my $rec = $e->retrieve_biblio_record_entry($rid);
+ next unless $rec;
+
+ unless ($e->allowed('UPDATE_RECORD', $rec->owner, $rec)) {
+ $conn->respond({ record => $rid, success => 'f' });
+ next;
+ }
+
+ my $success = $e->json_query(
+ { from => [ 'vandelay.template_overlay_bib_record', $template, $rid ] }
+ )->[0]->{'vandelay.template_overlay_bib_record'};
+
+ $conn->respond({ record => $rid, success => $success });
+ }
+
+ $e->commit;
+ return undef;
+}
+
+__PACKAGE__->register_method(
+ method => "template_overlay_container",
+ api_name => "open-ils.cat.container.template_overlay",
+ stream => 1,
+ signature => q#
+ Overlays biblio.record_entry MARC values
+ @param auth The authtoken
+ @param container The container, um, containing the records to be updated by the template
+ @param template The overlay template, or nothing and the method will look for a negative bib id in the container
+ @return Stream of hashes record id in the key "record" and t or f for the success of the overlay operation in key "success"
+ #
+);
+
+__PACKAGE__->register_method(
+ method => "template_overlay_container",
+ api_name => "open-ils.cat.container.template_overlay.background",
+ stream => 1,
+ signature => q#
+ Overlays biblio.record_entry MARC values
+ @param auth The authtoken
+ @param container The container, um, containing the records to be updated by the template
+ @param template The overlay template, or nothing and the method will look for a negative bib id in the container
+ @return Cache key to check for status of the container overlay
+ #
+);
+
+sub template_overlay_container {
+ my($self, $conn, $auth, $container, $template) = @_;
+ my $e = new_editor(authtoken=>$auth, xact=>1);
+ return $e->die_event unless $e->checkauth;
+
+ my $actor = OpenSRF::AppSession->create('open-ils.actor') if ($self->api_name =~ /background$/);
+
+ my $items = $e->search_container_biblio_record_entry_bucket_item({ bucket => $container });
+
+ my $titem;
+ if (!$template) {
+ ($titem) = grep { $_->target_biblio_record_entry < 0 } @$items;
+ if (!$titem) {
+ $e->rollback;
+ return undef;
+ }
+ $items = [grep { $_->target_biblio_record_entry > 0 } @$items];
+
+ $template = $e->retrieve_biblio_record_entry( $titem->target_biblio_record_entry )->marc;
+ }
+
+ my $responses = [];
+ my $some_failed = 0;
+
+ $self->respond_complete(
+ $actor->request('open-ils.actor.anon_cache.set_value', $auth, res_list => $responses)->gather(1)
+ ) if ($actor);
+
+ for my $item ( @$items ) {
+ my $rec = $e->retrieve_biblio_record_entry($item->target_biblio_record_entry);
+ next unless $rec;
+
+ my $success = 'f';
+ if ($e->allowed('UPDATE_RECORD', $rec->owner, $rec)) {
+ $success = $e->json_query(
+ { from => [ 'vandelay.template_overlay_bib_record', $template, $rec->id ] }
+ )->[0]->{'vandelay.template_overlay_bib_record'};
+ }
+
+ $some_failed++ if ($success eq 'f');
+
+ if ($actor) {
+ push @$responses, { record => $rec->id, success => $success };
+ $actor->request('open-ils.actor.anon_cache.set_value', $auth, res_list => $responses);
+ } else {
+ $conn->respond({ record => $rec->id, success => $success });
+ }
+
+ if ($success eq 't') {
+ unless ($e->delete_container_biblio_record_entry_bucket_item($item)) {
+ $e->rollback;
+ if ($actor) {
+ push @$responses, { complete => 1, success => 'f' };
+ $actor->request('open-ils.actor.anon_cache.set_value', $auth, res_list => $responses);
+ return undef;
+ } else {
+ return { complete => 1, success => 'f' };
+ }
+ }
+ }
+ }
+
+ if ($titem && !$some_failed) {
+ return $e->die_event unless ($e->delete_container_biblio_record_entry_bucket_item($titem));
+ }
+
+ if ($e->commit) {
+ if ($actor) {
+ push @$responses, { complete => 1, success => 't' };
+ $actor->request('open-ils.actor.anon_cache.set_value', $auth, res_list => $responses);
+ } else {
+ return { complete => 1, success => 't' };
+ }
+ } else {
+ if ($actor) {
+ push @$responses, { complete => 1, success => 'f' };
+ $actor->request('open-ils.actor.anon_cache.set_value', $auth, res_list => $responses);
+ } else {
+ return { complete => 1, success => 'f' };
+ }
+ }
+ return undef;
+}
+
+__PACKAGE__->register_method(
method => "update_biblio_record_entry",
api_name => "open-ils.cat.biblio.record_entry.update",
signature => q/
Added: branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/WWW/TemplateBatchBibUpdate.pm
===================================================================
--- branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/WWW/TemplateBatchBibUpdate.pm (rev 0)
+++ branches/rel_1_6/Open-ILS/src/perlmods/OpenILS/WWW/TemplateBatchBibUpdate.pm 2010-10-11 17:25:19 UTC (rev 18265)
@@ -0,0 +1,613 @@
+package OpenILS::WWW::TemplateBatchBibUpdate;
+use strict;
+use warnings;
+use bytes;
+
+use Apache2::Log;
+use Apache2::Const -compile => qw(OK REDIRECT DECLINED NOT_FOUND :log);
+use APR::Const -compile => qw(:error SUCCESS);
+use APR::Table;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil;
+use CGI;
+use Data::Dumper;
+use Text::CSV;
+
+use OpenSRF::EX qw(:try);
+use OpenSRF::Utils qw/:datetime/;
+use OpenSRF::Utils::Cache;
+use OpenSRF::System;
+use OpenSRF::AppSession;
+use XML::LibXML;
+use XML::LibXSLT;
+
+use Encode;
+use Unicode::Normalize;
+use OpenILS::Utils::Fieldmapper;
+use OpenSRF::Utils::Logger qw/$logger/;
+
+use MARC::Record;
+use MARC::File::XML;
+
+use UNIVERSAL::require;
+
+our @formats = qw/USMARC UNIMARC XML BRE/;
+
+# set the bootstrap config and template include directory when
+# this module is loaded
+my $bootstrap;
+
+sub import {
+ my $self = shift;
+ $bootstrap = shift;
+}
+
+
+sub child_init {
+ OpenSRF::System->bootstrap_client( config_file => $bootstrap );
+ Fieldmapper->import(IDL => OpenSRF::Utils::SettingsClient->new->config_value("IDL"));
+}
+
+sub handler {
+ my $r = shift;
+ my $cgi = new CGI;
+
+ my $authid = $cgi->cookie('ses') || $cgi->param('ses');
+ my $usr = verify_login($authid);
+ return show_template($r) unless ($usr);
+
+
+ my $template = $cgi->param('template');
+ return show_template($r) unless ($template);
+
+ # find some IDs ...
+ my @records;
+
+ @records = map { $_ ? ($_) : () } $cgi->param('recid');
+
+ if (!@records) { # try for a file
+ my $file = $cgi->param('idfile');
+ if ($file) {
+ my $col = $cgi->param('idcolumn') || 0;
+ my $csv = new Text::CSV;
+
+ while (<$file>) {
+ $csv->parse($_);
+ my @data = $csv->fields;
+ my $id = $data[$col];
+ $id =~ s/\D+//o;
+ next unless ($id);
+ push @records, $id;
+ }
+ }
+ }
+
+ my $e = OpenSRF::AppSession->connect('open-ils.cstore');
+ $e->request('open-ils.cstore.transaction.begin')->gather(1);
+
+ # still no records ...
+ my $container = $cgi->param('containerid');
+ if ($container) {
+ my $bucket = $e->request(
+ 'open-ils.cstore.direct.container.biblio_record_entry_bucket.retrieve',
+ $container
+ )->gather(1);
+ unless($bucket) {
+ $e->request('open-ils.cstore.transaction.rollback')->gather(1);
+ $e->disconnect;
+ $r->log->error("No such bucket $container");
+ $logger->error("No such bucket $container");
+ return Apache2::Const::NOT_FOUND;
+ }
+ my $recs = $e->request(
+ 'open-ils.cstore.direct.container.biblio_record_entry_bucket_item.search.atomic',
+ { bucket => $container }
+ )->gather(1);
+ @records = map { ($_->target_biblio_record_entry) } @$recs;
+ }
+
+ unless (@records) {
+ $e->request('open-ils.cstore.transaction.rollback')->gather(1);
+ $e->disconnect;
+ return show_template($r);
+ }
+
+ # we have a template and some record ids, so...
+
+ # insert the template record
+ my $min_id = $e->request(
+ 'open-ils.cstore.json_query',
+ { select => { bre => [{ column => 'id', transform => 'min', aggregate => 1}] }, from => 'bre' }
+ )->gather(1)->{id} - 1;
+
+ warn "new template bib id = $min_id\n";
+
+ my $tmpl_rec = Fieldmapper::biblio::record_entry->new;
+ $tmpl_rec->id($min_id);
+ $tmpl_rec->deleted('t');
+ $tmpl_rec->active('f');
+ $tmpl_rec->marc($template);
+ $tmpl_rec->creator($usr->id);
+ $tmpl_rec->editor($usr->id);
+
+ warn "about to create bib $min_id\n";
+ $e->request('open-ils.cstore.direct.biblio.record_entry.create', $tmpl_rec )->gather(1);
+
+ # create the new container for the records and the template
+ my $bucket = Fieldmapper::container::biblio_record_entry_bucket->new;
+ $bucket->owner($usr->id);
+ $bucket->btype('template_merge');
+
+ my $bname = $cgi->param('bname') || 'Temporary Merge Bucket '. localtime() . ' ' . $usr->id;
+ $bucket->name($bname);
+
+ $bucket = $e->request('open-ils.cstore.direct.container.biblio_record_entry_bucket.create', $bucket )->gather(1);
+
+ # create items in the bucket
+ my $item = Fieldmapper::container::biblio_record_entry_bucket_item->new;
+ $item->bucket($bucket->id);
+ $item->target_biblio_record_entry($min_id);
+
+ $e->request('open-ils.cstore.direct.container.biblio_record_entry_bucket_item.create', $item )->gather(1);
+
+ for my $r (@records) {
+ $item->target_biblio_record_entry($r);
+ $e->request('open-ils.cstore.direct.container.biblio_record_entry_bucket_item.create', $item )->gather(1);
+ }
+
+ $e->request('open-ils.cstore.transaction.commit')->gather(1);
+ $e->disconnect;
+
+ # fire the background bucket processor
+ my $cache_key = OpenSRF::AppSession
+ ->create('open-ils.cat')
+ ->request('open-ils.cat.container.template_overlay.background', $authid, $bucket->id)
+ ->gather(1);
+
+ return show_processing_template($r, $bucket->id, \@records, $cache_key);
+}
+
+sub verify_login {
+ my $auth_token = shift;
+ return undef unless $auth_token;
+
+ my $user = OpenSRF::AppSession
+ ->create("open-ils.auth")
+ ->request( "open-ils.auth.session.retrieve", $auth_token )
+ ->gather(1);
+
+ if (ref($user) eq 'HASH' && $user->{ilsevent} == 1001) {
+ return undef;
+ }
+
+ return $user if ref($user);
+ return undef;
+}
+
+sub show_processing_template {
+ my $r = shift;
+ my $bid = shift;
+ my $recs = shift;
+ my $cache_key = shift;
+
+ my $rec_string = @$recs;
+
+ $r->content_type('text/html');
+ $r->print(<<HTML);
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+ <head>
+ <title>Merging records...</title>
+ <style type="text/css">
+ \@import '/js/dojo/dojo/resources/dojo.css';
+ \@import '/js/dojo/dijit/themes/tundra/tundra.css';
+ .hide_me { display: none; visibility: hidden; }
+ th { font-weight: bold; }
+ </style>
+
+ <script type="text/javascript">
+ var djConfig= {
+ isDebug: false,
+ parseOnLoad: true,
+ AutoIDL: ['aou','aout','pgt','au','cbreb']
+ }
+ </script>
+
+ <script src='/js/dojo/dojo/dojo.js'></script>
+ <!-- <script src="/js/dojo/dojo/openils_dojo.js"></script> -->
+
+ <script type="text/javascript">
+
+ dojo.require('fieldmapper.AutoIDL');
+ dojo.require('fieldmapper.dojoData');
+ dojo.require('openils.User');
+ dojo.require('openils.CGI');
+ dojo.require('openils.widget.ProgressDialog');
+
+ var cgi = new openils.CGI();
+ var u = new openils.User({ authcookie : 'ses' });
+
+ dojo.addOnLoad(function () {
+ progress_dialog.show(true);
+ progress_dialog.update({maximum:$rec_string});
+
+ var interval;
+ interval = setInterval( function() {
+ fieldmapper.standardRequest(
+ ['open-ils.actor','open-ils.actor.anon_cache.get_value'],
+ { async : false,
+ params: [ u.authtoken, 'res_list' ],
+ onerror : function (r) { progress_dialog.hide(); },
+ onresponse : function (r) {
+ var counter = { success : 0, fail : 0, total : 0 };
+ dojo.forEach( openils.Util.readResponse(r), function(x) {
+ if (x.complete) {
+ clearInterval(interval);
+ progress_dialog.hide();
+ if (x.success == 't') dojo.byId('complete_msg').innerHTML = 'Overlay completed successfully';
+ else dojo.byId('complete_msg').innerHTML = 'Overlay did not complet successfully';
+ } else {
+ counter.total++;
+ switch (x.success) {
+ case 't':
+ counter.success++;
+ break;
+ default:
+ counter.fail++;
+ break;
+ }
+ }
+ });
+
+ // update the progress dialog
+ progress_dialog.update({progress:counter.total});
+ dojo.byId('success_count').innerHTML = counter.success;
+ dojo.byId('fail_count').innerHTML = counter.fail;
+ dojo.byId('total_count').innerHTML = counter.total;
+ }
+ }
+ );
+ }, 1000);
+
+ });
+ </script>
+ </head>
+
+ <body class='tundra'>
+ <div class="hide_me"><div dojoType="openils.widget.ProgressDialog" jsId="progress_dialog"></div></div>
+
+ <table style="width:100%; margin-top:100px;">
+ <th>
+ <td>Status</td>
+ <td>Record Count</td>
+ </th>
+ <tr>
+ <td>Success</td>
+ <td id='success_count'></td>
+ </tr>
+ <tr>
+ <td>Failure</td>
+ <td id='fail_count'></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td id='total_count'></td>
+ </tr>
+ </table>
+
+ <div id='complete_msg'></div>
+
+ </body>
+</html>
+HTML
+
+ return Apache2::Const::OK;
+}
+
+
+sub show_template {
+ my $r = shift;
+
+ $r->content_type('text/html');
+ $r->print(<<'HTML');
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+ <head>
+ <title>Merge Template Builder</title>
+ <style type="text/css">
+ @import '/js/dojo/dojo/resources/dojo.css';
+ @import '/js/dojo/dijit/themes/tundra/tundra.css';
+ .hide_me { display: none; visibility: hidden; }
+ th { font-weight: bold; }
+ </style>
+
+ <script type="text/javascript">
+ var djConfig= {
+ isDebug: false,
+ parseOnLoad: true,
+ AutoIDL: ['aou','aout','pgt','au','cbreb']
+ }
+ </script>
+
+ <script src='/js/dojo/dojo/dojo.js'></script>
+ <!-- <script src="/js/dojo/dojo/openils_dojo.js"></script> -->
+
+ <script type="text/javascript">
+
+ dojo.require('dojo.data.ItemFileReadStore');
+ dojo.require('dijit.form.Form');
+ dojo.require('dijit.form.NumberSpinner');
+ dojo.require('dijit.form.FilteringSelect');
+ dojo.require('dijit.form.TextBox');
+ dojo.require('dijit.form.Textarea');
+ dojo.require('dijit.form.Button');
+ dojo.require('MARC.Batch');
+ dojo.require('fieldmapper.AutoIDL');
+ dojo.require('fieldmapper.dojoData');
+ dojo.require('openils.User');
+ dojo.require('openils.CGI');
+
+ var cgi = new openils.CGI();
+ var u = new openils.User({ authcookie : 'ses' });
+
+ var bucketStore = new dojo.data.ItemFileReadStore(
+ { data : cbreb.toStoreData(
+ fieldmapper.standardRequest(
+ ['open-ils.actor','open-ils.actor.container.retrieve_by_class'],
+ [u.authtoken, u.user.id(), 'biblio', 'staff_client']
+ )
+ )
+ }
+ );
+
+ function render_preview () {
+ var rec = ruleset_to_record();
+ dojo.byId('marcPreview').innerHTML = rec.toBreaker();
+ }
+
+ function render_from_template () {
+ var kid_number = dojo.byId('ruleList').childNodes.length;
+ var clone = dojo.query('*[name=ruleTable]', dojo.byId('ruleTemplate'))[0].cloneNode(true);
+
+ var typeSelect = dojo.query('*[name=typeSelect]',clone).instantiate(dijit.form.FilteringSelect, {
+ onChange : function (val) {
+ switch (val) {
+ case 'a':
+ case 'r':
+ dijit.byNode(dojo.query('*[name=marcDataContainer] .dijit',clone)[0]).attr('disabled',false);
+ break;
+ default :
+ dijit.byNode(dojo.query('*[name=marcDataContainer] .dijit',clone)[0]).attr('disabled',true);
+ };
+ render_preview();
+ }
+ })[0];
+
+ var marcData = dojo.query('*[name=marcData]',clone).instantiate(dijit.form.TextBox, {
+ onChange : render_preview
+ })[0];
+
+
+ var tag = dojo.query('*[name=tag]',clone).instantiate(dijit.form.TextBox, {
+ onChange : function (newtag) {
+ var md = dijit.byNode(dojo.query('*[name=marcDataContainer] .dijit',clone)[0]);
+ var current_marc = md.attr('value');
+
+ if (newtag.length == 3) {
+ if (current_marc.length == 0) newtag += ' \\\\';
+ if (current_marc.substr(0,3) != newtag) current_marc = newtag + current_marc.substr(3);
+ }
+ md.attr('value', current_marc);
+ render_preview();
+ }
+ })[0];
+
+ var sf = dojo.query('*[name=sf]',clone).instantiate(dijit.form.TextBox, {
+ onChange : function (newsf) {
+ var md = dijit.byNode(dojo.query('*[name=marcDataContainer] .dijit',clone)[0]);
+ var current_marc = md.attr('value');
+ var sf_list = newsf.split('');
+
+ for (var i in sf_list) {
+ var re = '\\$' + sf_list[i];
+ if (current_marc.match(re)) continue;
+ current_marc += '$' + sf_list[i];
+ }
+
+ md.attr('value', current_marc);
+ render_preview();
+ }
+ })[0];
+
+ var matchSF = dojo.query('*[name=matchSF]',clone).instantiate(dijit.form.TextBox, {
+ onChange : render_preview
+ })[0];
+
+ var matchRE = dojo.query('*[name=matchRE]',clone).instantiate(dijit.form.TextBox, {
+ onChange : render_preview
+ })[0];
+
+ var removeButton = dojo.query('*[name=removeButton]',clone).instantiate(dijit.form.Button, {
+ onClick : function() {
+ dojo.addClass(
+ dojo.byId('ruleList').childNodes[kid_number],
+ 'hide_me'
+ );
+ render_preview();
+ }
+ })[0];
+
+ dojo.place(clone,'ruleList');
+ }
+
+ function ruleset_to_record () {
+ var rec = new MARC.Record ({ delimiter : '$' });
+
+ dojo.forEach(
+ dojo.query('#ruleList *[name=ruleTable]').filter( function (node) {
+ if (node.className.match(/hide_me/)) return false;
+ return true;
+ }),
+ function (tbl) {
+ var rule_tag = new MARC.Field ({
+ tag : '905',
+ ind1 : ' ',
+ ind2 : ' '
+ });
+ var rule_txt = dijit.byNode(dojo.query('*[name=tagContainer] .dijit',tbl)[0]).attr('value');
+ rule_txt += dijit.byNode(dojo.query('*[name=sfContainer] .dijit',tbl)[0]).attr('value');
+
+ var reSF = dijit.byNode(dojo.query('*[name=matchSFContainer] .dijit',tbl)[0]).attr('value');
+ if (reSF) {
+ var reRE = dijit.byNode(dojo.query('*[name=matchREContainer] .dijit',tbl)[0]).attr('value');
+ rule_txt += '[' + reSF + '~' + reRE + ']';
+ }
+
+ var rtype = dijit.byNode(dojo.query('*[name=typeSelectContainer] .dijit',tbl)[0]).attr('value');
+ rule_tag.addSubfields( rtype, rule_txt )
+ rec.appendFields( rule_tag );
+
+ if (rtype == 'a' || rtype == 'r') {
+ rec.appendFields(
+ new MARC.Record ({
+ delimiter : '$',
+ marcbreaker : dijit.byNode(dojo.query('*[name=marcDataContainer] .dijit',tbl)[0]).attr('value')
+ }).fields[0]
+ );
+ }
+ }
+ );
+
+ return rec;
+ }
+ </script>
+ </head>
+
+ <body class='tundra'>
+
+ <div dojoType="dijit.form.Form" id="myForm" jsId="myForm" encType="multipart/form-data" action="" method="POST">
+ <script type='dojo/method' event='onSubmit'>
+ var rec = ruleset_to_record();
+
+ // no-op to force replace mode
+ rec.appendFields(
+ new MARC.Field ({
+ tag : '905',
+ ind1 : ' ',
+ ind2 : ' ',
+ subfields : [['r','901c']]
+ })
+ );
+
+ dojo.byId('template_value').value = rec.toXmlString();
+ return true;
+ </script>
+
+ <input type='hidden' id='template_value' name='template'/>
+
+ <table>
+ <tr>
+ <th>Optional merge queue name:</th>
+ <td><input id='bucketName' type='text' dojoType='dijit.form.TextBox' name='bname' value=''/></td>
+ </tr>
+ <tr>
+ <th>Batch update records in Bucket:</th>
+ <td>
+ <div name='containerid' jsId='bucketList' dojoType='dijit.form.FilteringSelect' store='bucketStore' searchAttr='name' id='bucketList'>
+ <script type='dojo/method' event='postCreate'>
+ if (cgi.param('containerid')) this.attr('value',cgi.param('containerid'));
+ </script>
+ </div>
+ </td>
+ </tr>
+ <tr><th colspan='2'><div style='text-align: center;'>or</div></hd></tr>
+ <tr>
+ <th>Batch update records from CSV file:</th>
+ <td><input id='idfile' type="file" name="idfile"/><br/>Column <input style='width:75px;' type='text' dojoType='dijit.form.NumberSpinner' name='idcolumn' value='0' constraints='{min:0,max:100,places:0}' /> starting from 0</td>
+ </tr>
+ <tr><th colspan='2'><div style='text-align: center;'>or</div></th></tr>
+ <tr>
+ <th>Test Ruleset by applying to one record:</th>
+ <td><input name='recid' style='width:75px;' type='text' dojoType='dijit.form.NumberTextBox' name='id' value='' constraints='{min:0}' /></td>
+ </tr>
+ </table>
+
+ <button type="submit" dojoType='dijit.form.Button'>Apply Ruleset</button>
+
+ </div> <!-- end of the form -->
+
+ <hr/>
+ <table style='width: 100%'>
+ <tr>
+ <td style='width: 50%'><div id='ruleList'></div></td>
+ <td valign='top'>Update Template Preview:<br/><pre id='marcPreview'></pre></td>
+ </tr>
+ </table>
+
+ <button dojoType='dijit.form.Button'>Add Merge Rule
+ <script type='dojo/connect' event='onClick'>render_from_template()</script>
+ <script type='dojo/method' event='postCreate'>render_from_template()</script>
+ </button>
+
+ <div class='hide_me' id='ruleTemplate'>
+ <div name='ruleTable'>
+ <table>
+ <tbody>
+ <tr>
+ <th>Rule Type</th>
+ <td name='typeSelectContainer'>
+ <select name='typeSelect'>
+ <option value='r'>Replace</option>
+ <option value='a'>Add</option>
+ <option value='d'>Delete</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <th>MARC Tag</th>
+ <td name='tagContainer'><input style='with: 2em;' name='tag' type='text'></input</td>
+ </td>
+ <tr>
+ <th>Optional Subfields</th>
+ <td name='sfContainer'><input name='sf' type='text'/></td>
+ </tr>
+ <tr>
+ <th>MARC Data</th>
+ <td name='marcDataContainer'><input name='marcData' type='text'/></td>
+ </tr>
+ <tr>
+ <th colspan='2' style='padding-top: 10px; text-align: center;'>Optionally Restrict By</th>
+ </tr>
+ <tr>
+ <th>Subfield</th>
+ <td name='matchSFContainer'><input style='with: 2em;' name='matchSF' type='text'></input</td>
+ </td>
+ <tr>
+ <th>Regular Expression</th>
+ <td name='matchREContainer'><input name='matchRE' type='text'/></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>
+ <button name='removeButton'>Remove Merge Rule
+ </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <hr/>
+ </div>
+ </div>
+
+ </body>
+</html>
+HTML
+
+ return Apache2::Const::OK;
+}
+
+1;
+
+
Modified: branches/rel_1_6/Open-ILS/src/sql/Pg/950.data.seed-values.sql
===================================================================
--- branches/rel_1_6/Open-ILS/src/sql/Pg/950.data.seed-values.sql 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/src/sql/Pg/950.data.seed-values.sql 2010-10-11 17:25:19 UTC (rev 18265)
@@ -1780,6 +1780,7 @@
INSERT INTO container.biblio_record_entry_bucket_type (code,label) VALUES ('staff_client', oils_i18n_gettext('staff_client', 'General Staff Client container', 'cbrebt', 'label'));
INSERT INTO container.biblio_record_entry_bucket_type (code,label) VALUES ('bookbag', oils_i18n_gettext('bookbag', 'Book Bag', 'cbrebt', 'label'));
INSERT INTO container.biblio_record_entry_bucket_type (code,label) VALUES ('reading_list', oils_i18n_gettext('reading_list', 'Reading List', 'cbrebt', 'label'));
+INSERT INTO container.biblio_record_entry_bucket_type (code,label) VALUES ('template_merge',oils_i18n_gettext('template_merge','Template Merge Container', 'cbrebt', 'label'));
INSERT INTO container.user_bucket_type (code,label) VALUES ('misc', oils_i18n_gettext('misc', 'Miscellaneous', 'cubt', 'label'));
INSERT INTO container.user_bucket_type (code,label) VALUES ('folks', oils_i18n_gettext('folks', 'Friends', 'cubt', 'label'));
Copied: branches/rel_1_6/Open-ILS/src/sql/Pg/upgrade/0434.data.merge_template_container_type.sql (from rev 18264, trunk/Open-ILS/src/sql/Pg/upgrade/0434.data.merge_template_container_type.sql)
===================================================================
--- branches/rel_1_6/Open-ILS/src/sql/Pg/upgrade/0434.data.merge_template_container_type.sql (rev 0)
+++ branches/rel_1_6/Open-ILS/src/sql/Pg/upgrade/0434.data.merge_template_container_type.sql 2010-10-11 17:25:19 UTC (rev 18265)
@@ -0,0 +1,9 @@
+
+BEGIN;
+
+INSERT INTO config.upgrade_log (version) VALUES ('0434');
+
+INSERT INTO container.biblio_record_entry_bucket_type (code,label) VALUES ('template_merge','Template Merge Container');
+
+COMMIT;
+
Modified: branches/rel_1_6/Open-ILS/web/css/theme/default.css
===================================================================
--- branches/rel_1_6/Open-ILS/web/css/theme/default.css 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/css/theme/default.css 2010-10-11 17:25:19 UTC (rev 18265)
@@ -56,3 +56,4 @@
border-bottom:1px solid #ACA899;
}
+.oils-notify-text { color: red; font-weight:bold; }
Added: branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Batch.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Batch.js (rev 0)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Batch.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -0,0 +1,82 @@
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2009 Equinox Software, Inc.
+ * Mike Rylander <miker at esilibrary.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * ---------------------------------------------------------------------------
+ */
+
+if(!dojo._hasResource["MARC.Batch"]) {
+
+ dojo.require('dojox.xml.parser');
+ dojo.require('MARC.Record');
+
+ dojo._hasResource["MARC.Batch"] = true;
+ dojo.provide("MARC.Batch");
+ dojo.declare('MARC.Batch', null, {
+
+ constructor : function(kwargs) {
+ this.ready = false;
+ this.records = [];
+ this.source = kwargs.source;
+ this.delimiter = kwargs.delimiter
+ this.current_record = 0;
+
+ if (this.source) this.ready = true;
+ if (!this.ready && kwargs.url) this.fetchURL( kwargs.url );
+
+ if (this.ready) this.parse();
+ },
+
+ parse : function () {
+ if (dojo.isObject( this.source )) { // assume an xml collection document
+ this.source = dojo.query('record', this.source);
+ this.type = 'xml';
+ } else if (this.source.match(/^\s*</)) { // this is xml text
+ this.source = dojox.xml.parser.parse( this.source );
+ this.parse();
+ } else { // must be a marcbreaker doc. split on blank lines
+ this.source = this.source.split(/^$/);
+ this.type = 'marcbreaker';
+ }
+ },
+
+ fetchURL : function (u) {
+ var me = this;
+ dojo.xhrGet({
+ url : u,
+ sync : true,
+ handleAs: 'text',
+ load : function (mrc) {
+ me.source = mrc;
+ me.ready = true;
+ }
+ });
+ },
+
+ next : function () {
+ var chunk = this.source[this.current_record++];
+
+ if (chunk) {
+ var args = {};
+ args[this.type] = chunk;
+ if (this.delimiter) args.delimiter = this.delimiter;
+ return new MARC.Record(args);
+ }
+
+ return null;
+ }
+
+ });
+}
+
+
+
Added: branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Field.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Field.js (rev 0)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Field.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -0,0 +1,130 @@
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2009 Equinox Software, Inc.
+ * Mike Rylander <miker at esilibrary.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * ---------------------------------------------------------------------------
+ */
+
+if(!dojo._hasResource["MARC.Field"]) {
+
+ dojo._hasResource["MARC.Field"] = true;
+ dojo.provide("MARC.Field");
+ dojo.declare('MARC.Field', null, {
+
+ error : false, // MARC record pointer
+ record : null, // MARC record pointer
+ tag : '', // MARC tag
+ ind1 : '', // MARC indicator 1
+ ind2 : '', // MARC indicator 2
+ data : '', // MARC data for a controlfield element
+ subfields : [], // list of MARC subfields for a datafield element
+
+ constructor : function(kwargs) {
+ this.record = kwargs.record;
+ this.tag = kwargs.tag;
+ this.ind1 = kwargs.ind1;
+ this.ind2 = kwargs.ind2;
+ this.data = kwargs.data;
+ if (kwargs.subfields) this.subfields = kwargs.subfields;
+ else this.subfields = [];
+ },
+
+ subfield : function (code) {
+ var list = dojo.filter( this.subfields, function (s) {
+ if (s[0] == code) return true; return true;
+ });
+ if (list.length == 1) return list[0];
+ return list;
+ },
+
+ addSubfields : function () {
+ for (var i = 0; i < arguments.length; i++) {
+ var code = arguments[i];
+ var value = arguments[++i];
+ this.subfields.push( [ code, value ] );
+ }
+ },
+
+ deleteSubfields : function (c) {
+ return this.deleteSubfield( { code : c } );
+ },
+
+ deleteSubfield : function (args) {
+ var me = this;
+ if (!dojo.isArray( args.code )) {
+ args.code = [ args.code ];
+ }
+
+ if (args.pos && !dojo.isArray( args.pos )) {
+ args.pos = [ args.pos ];
+ }
+
+ for (var i = 0; i < args.code.length; i++) {
+ var sub_pos = {};
+ for (var j = 0; j < me.subfields; j++) {
+ if (me.subfields[j][0] == args.code[i]) {
+
+ if (!sub_pos[args.code[i]]) sub_pos[args.code[j]] = 0;
+ else sub_pos[args.code[i]]++;
+
+ if (args.pos) {
+ for (var k = 0; k < args.pos.length; k++) {
+ if (sub_pos[args.code[i]] == args.pos[k]) me.subfields.splice(j,1);
+ }
+ } else if (args.match && me.subfields[j][1].match( args.match )) {
+ me.subfields.splice(j,1);
+ } else {
+ me.subfields.splice(j,1);
+ }
+ }
+ }
+ }
+ },
+
+ update : function ( args ) {
+ if (this.isControlfield()) {
+ this.data = args;
+ } else {
+ if (args.ind1) this.ind1 = args.ind1;
+ if (args.ind2) this.ind2 = args.ind2;
+ if (args.tag) this.tag = args.tag;
+
+ for (var i in args) {
+ if (i == 'tag' || i == 'ind1' || i == 'ind2') continue;
+ var done = 0;
+ dojo.forEach( this.subfields, function (f) {
+ if (!done && f[0] == i) {
+ f[1] = args[i];
+ done = 1;
+ }
+ });
+ }
+ }
+ },
+
+ isControlfield : function () {
+ return this.tag < '010' ? true : false;
+ },
+
+ indicator : function (num, value) {
+ if (value) {
+ if (num == 1) this.ind1 = value;
+ else if (num == 2) this.ind2 = value;
+ else { this.error = true; return null; }
+ }
+ if (num == 1) return this.ind1;
+ else if (num == 2) return this.ind2;
+ else { this.error = true; return null; }
+ }
+
+ });
+}
Added: branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Record.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Record.js (rev 0)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/MARC/Record.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -0,0 +1,299 @@
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2009 Equinox Software, Inc.
+ * Mike Rylander <miker at esilibrary.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * ---------------------------------------------------------------------------
+ */
+
+if(!dojo._hasResource["MARC.Record"]) {
+
+ dojo.require('dojox.xml.parser');
+ dojo.require('MARC.Field');
+
+ dojo._hasResource["MARC.Record"] = true;
+ dojo.provide("MARC.Record");
+ dojo.declare('MARC.Record', null, {
+
+ delimiter : '\u2021', // default subfield delimiter
+
+ constructor : function(kwargs) {
+ this.fields = [];
+ this.leader = '00000cam a2200205Ka 4500';
+
+ if (kwargs.delimiter) this.delimiter = kwargs.delimiter;
+ if (kwargs.onLoad) this.onLoad = kwargs.onLoad;
+ if (kwargs.url) {
+ this.fromXmlURL(kwargs.url);
+ } else if (kwargs.marcxml) {
+ this.fromXmlString(kwargs.marcxml);
+ if (this.onLoad) this.onLoad();
+ } else if (kwargs.xml) {
+ this.fromXmlDocument(kwargs.xml);
+ if (this.onLoad) this.onLoad();
+ } else if (kwargs.marcbreaker) {
+ this.fromBreaker(kwargs.marcbreaker);
+ if (this.onLoad) this.onLoad();
+ }
+ },
+
+ title : function () { return this.subfield('245','a') },
+
+ field : function (spec) {
+ var list = dojo.filter( this.fields, function (f) {
+ if (f.tag.match(spec)) return true;
+ return false;
+ });
+
+ if (list.length == 1) return list[0];
+ return list;
+ },
+
+ subfield : function (spec, code) { return this.field(spec)[0].subfield(code) },
+
+ appendFields : function () {
+ var me = this;
+ dojo.forEach( arguments, function (f) { me.fields.push( f ) } );
+ },
+
+ deleteField : function (f) { return this.deleteFields(f) },
+
+ insertOrderedFields : function () {
+ var me = this;
+ for (var i = 0; i < arguments.length; i++) {
+ var f = arguments[i];
+ var done = false;
+ for (var j = 0; j < this.fields.length; j++) {
+ if (f.tag < this.fields[j].tag) {
+ this.insertFieldsBefore(this.fields[j], f);
+ done = true;
+ break;
+ }
+ }
+ if (!done) this.appendFields(f);
+ }
+ },
+
+ insertFieldsBefore : function (target) {
+ var args = Array.prototype.slice.call(arguments);
+ args.splice(0,1);
+ var me = this;
+ for (var j = 0; j < this.fields.length; j++) {
+ if (target === this.fields[j]) {
+ j--;
+ dojo.forEach( args, function (f) {
+ me.fields.splice(j++,0,f);
+ });
+ break;
+ }
+ }
+ },
+
+ insertFieldsAfter : function (target) {
+ var args = Array.prototype.slice.call(arguments);
+ args.splice(0,1);
+ var me = this;
+ for (var j = 0; j < this.fields.length; j++) {
+ if (target === this.fields[j]) {
+ dojo.forEach( args, function (f) {
+ me.fields.splice(j++,0,f);
+ });
+ break;
+ }
+ }
+ },
+
+ deleteFields : function () {
+ var me = this;
+ var counter = 0;
+ for ( var i in arguments ) {
+ var f = arguments[i];
+ for (var j = 0; j < me.fields.length; j++) {
+ if (f === me.fields[j]) {
+ me.fields[j].record = null;
+ me.fields.splice(j,0);
+ counter++
+ break;
+ }
+ }
+ }
+ return counter;
+ },
+
+ clone : function () { return dojo.clone(this) },
+
+ fromXmlURL : function (url) {
+ this.ready = false;
+ var me = this;
+ dojo.xhrGet({
+ url : url,
+ sync : true,
+ handleAs: 'xml',
+ load : function (mxml) {
+ me.fromXmlDocument(dojo.query('record', mxml)[0]);
+ me.ready = true;
+ if (me.onLoad) me.onLoad();
+ }
+ });
+ },
+
+ fromXmlString : function (mxml) {
+ return this.fromXmlDocument( dojox.xml.parser.parse( mxml ) );
+ },
+
+ fromXmlDocument : function (mxml) {
+ var me = this;
+ me.leader = dojox.xml.parser.textContent(dojo.query('leader', mxml)[0]) || '00000cam a2200205Ka 4500';
+
+ dojo.forEach( dojo.query('controlfield', mxml), function (cf) {
+ me.fields.push(
+ new MARC.Field({
+ record : me,
+ tag : cf.getAttribute('tag'),
+ data : dojox.xml.parser.textContent(cf)
+ })
+ )
+ });
+
+ dojo.forEach( dojo.query('datafield', mxml), function (df) {
+ me.fields.push(
+ new MARC.Field({
+ record : me,
+ tag : df.getAttribute('tag'),
+ ind1 : df.getAttribute('ind1'),
+ ind2 : df.getAttribute('ind2'),
+ subfields : dojo.map(
+ dojo.query('subfield', df),
+ function (sf) {
+ return [ sf.getAttribute('code'), dojox.xml.parser.textContent(sf) ];
+ }
+ )
+ })
+ )
+ });
+
+ return this;
+ },
+
+ toXmlDocument : function () {
+
+ var doc = dojox.xml.parser.parse('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
+ var rec_node = dojo.query('record', doc)[0];
+
+ var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
+ dojox.xml.parser.textContent(ldr, this.leader);
+ rec_node.appendChild( ldr );
+
+ dojo.forEach( this.fields, function (f) {
+ var element = f.isControlfield() ? 'controlfield' : 'datafield';
+ var f_node = doc.createElementNS( 'http://www.loc.gov/MARC21/slim', element );
+ f_node.setAttribute('tag', f.tag);
+
+ if (f.isControlfield() && f.data) {
+ dojox.xml.parser.textContent(f_node, f.data);
+ } else {
+ f_node.setAttribute('ind1', f.indicator(1));
+ f_node.setAttribute('ind2', f.indicator(2));
+ dojo.forEach( f.subfields, function (sf) {
+ var sf_node = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'subfield');
+ sf_node.setAttribute('code', sf[0]);
+ dojox.xml.parser.textContent(sf_node, sf[1]);
+ f_node.appendChild(sf_node);
+ });
+ }
+
+ rec_node.appendChild(f_node);
+ });
+
+ return doc;
+ },
+
+ toXmlString : function () {
+ return dojox.xml.parser.innerXML( this.toXmlDocument() );
+ },
+
+ fromBreaker : function (marctxt) {
+ var me = this;
+
+ function cf_line_data (l) { return l.substring(4) };
+ function df_line_data (l) { return l.substring(6) };
+ function line_tag (l) { return l.substring(0,3) };
+ function df_ind1 (l) { return l.substring(4,5).replace('\\',' ') };
+ function df_ind2 (l) { return l.substring(5,6).replace('\\',' ') };
+ function isControlField (l) {
+ var x = line_tag(l);
+ return (x == 'LDR' || x < '010') ? true : false;
+ }
+
+ var lines = marctxt.replace(/^=/gm,'').split('\n');
+ dojo.forEach(lines, function (current_line) {
+
+ if (current_line.match(/^#/)) {
+ // skip comment lines
+ } else if (isControlField(current_line)) {
+ if (line_tag(current_line) == 'LDR') {
+ me.leader = cf_line_data(current_line) || '00000cam a2200205Ka 4500';
+ } else {
+ me.fields.push(
+ new MARC.Field({
+ record : me,
+ tag : line_tag(current_line),
+ data : cf_line_data(current_line).replace('\\',' ','g')
+ })
+ );
+ }
+ } else {
+ var data = df_line_data(current_line);
+ if (!(data.substring(0,1) == me.delimiter)) data = me.delimiter + 'a' + data;
+
+ var sf_list = data.split(me.delimiter);
+ sf_list.shift();
+
+ me.fields.push(
+ new MARC.Field({
+ record : me,
+ tag : line_tag(current_line),
+ ind1 : df_ind1(current_line),
+ ind2 : df_ind2(current_line),
+ subfields : dojo.map(
+ sf_list,
+ function (sf) { return [ sf.substring(0,1), sf.substring(1) ] }
+ )
+ })
+ );
+ }
+ });
+
+ return this;
+ },
+
+ toBreaker : function () {
+
+ var me = this;
+ var mtxt = '=LDR ' + this.leader + '\n';
+
+ mtxt += dojo.map( this.fields, function (f) {
+ if (f.isControlfield() && f.data) {
+ return '=' + f.tag + ' ' + f.data.replace(' ','\\','g');
+ } else {
+ return '=' + f.tag + ' ' +
+ f.indicator(1).replace(' ','\\') +
+ f.indicator(2).replace(' ','\\') +
+ dojo.map( f.subfields, function (sf) {
+ return me.delimiter + sf.join('');
+ }).join('');
+ }
+ }).join('\n');
+
+ return mtxt;
+ }
+ });
+}
Modified: branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/AutoIDL.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/AutoIDL.js 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/AutoIDL.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -2,6 +2,14 @@
dojo.provide("fieldmapper.AutoIDL");
dojo.require("fieldmapper.IDL");
- fieldmapper.IDL.load();
+
+ var classlist = [];
+ try {
+ classlist = dojo.config.AutoIDL || [];
+ } catch(x) {
+ /* meh */
+ }
+
+ fieldmapper.IDL.load(classlist);
}
Modified: branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -53,7 +53,7 @@
obj.a[i] = thing.clone();
} else {
- if(instanceOf(thing, Array)) {
+ if(dojo.isArray(thing)) {
obj.a[i] = new Array();
for( var j in thing ) {
@@ -71,11 +71,103 @@
return obj;
},
+ RequiredField : function (f) {
+ if (!f) return;
+ if (fieldmapper.IDL && fieldmapper.IDL.loaded)
+ return this.Structure.fields[f].required;
+ return;
+ },
+
+ ValidateField : function (f) {
+ if (!f) return;
+ if (fieldmapper.IDL && fieldmapper.IDL.loaded) {
+ if (this.Structure.fields[f] && this.Structure.fields[f].validate) {
+ return this.Structure.fields[f].validate.test(this[f]());
+ }
+ return true;
+ }
+ return;
+ }
+
+
+
+/*
isnew : function(n) { if(arguments.length == 1) this.a[0] =n; return this.a[0]; },
ischanged : function(n) { if(arguments.length == 1) this.a[1] =n; return this.a[1]; },
isdeleted : function(n) { if(arguments.length == 1) this.a[2] =n; return this.a[2]; }
+*/
+
});
+ fieldmapper.vivicateClass = function (cl) {
+ dojo.provide( cl );
+ dojo.declare( cl , fieldmapper.Fieldmapper, {
+ constructor : function () {
+ if (!this.a) this.a = [];
+ this.classname = this.declaredClass;
+ this._fields = [];
+
+ if (fieldmapper.IDL && fieldmapper.IDL.loaded) {
+ this.Structure = fieldmapper.IDL.fmclasses[this.classname]
+
+ for (var f in fieldmapper.IDL.fmclasses[this.classname].fields) {
+ var field = fieldmapper.IDL.fmclasses[this.classname].fields[f];
+ var p = field.array_position;
+ this._fields.push( field.name );
+ this[field.name]=new Function('n', 'if(arguments.length==1)this.a['+p+']=n;return this.a['+p+'];');
+ }
+ } else {
+ this._fields = fmclasses[this.classname];
+
+ for( var pos = 0; pos < this._fields.length; pos++ ) {
+ var p = parseInt(pos);
+ var f = this._fields[pos];
+ this[f]=new Function('n', 'if(arguments.length==1)this.a['+p+']=n;return this.a['+p+'];');
+ }
+ }
+
+ }
+ });
+ fieldmapper[cl] = window[cl]; // alias into place
+ if (fieldmapper.IDL && fieldmapper.IDL.loaded) fieldmapper[cl].Identifier = fieldmapper.IDL.fmclasses[cl].pkey;
+ };
+
+ if (!window.fmclasses) dojo.require("fieldmapper.fmall", true);
+ for( var cl in fmclasses ) {
+ fieldmapper.vivicateClass(cl);
+ }
+
+ // if we were NOT called by the IDL loader ...
+ // XXX This is now deprecated in preference to fieldmapper.AutoIDL
+ if ( !(fieldmapper.IDL && fieldmapper.IDL.loaded) ) {
+
+ fieldmapper.cmsa.Identifier = 'alias';
+ fieldmapper.cmc.Identifier = 'name';
+ fieldmapper.i18n_l.Identifier = 'code';
+ fieldmapper.ccpbt.Identifier = 'code';
+ fieldmapper.ccnbt.Identifier = 'code';
+ fieldmapper.cbrebt.Identifier = 'code';
+ fieldmapper.cubt.Identifier = 'code';
+ fieldmapper.ccm.Identifier = 'code';
+ fieldmapper.cvrfm.Identifier = 'code';
+ fieldmapper.clm.Identifier = 'code';
+ fieldmapper.cam.Identifier = 'code';
+ fieldmapper.cifm.Identifier = 'code';
+ fieldmapper.citm.Identifier = 'code';
+ fieldmapper.cblvl.Identifier = 'code';
+ fieldmapper.clfm.Identifier = 'code';
+ fieldmapper.mous.Identifier = 'usr';
+ fieldmapper.moucs.Identifier = 'usr';
+ fieldmapper.mucs.Identifier = 'usr';
+ fieldmapper.mus.Identifier = 'usr';
+ fieldmapper.rxbt.Identifier = 'xact';
+ fieldmapper.rxpt.Identifier = 'xact';
+ fieldmapper.cxt.Identifier = 'name';
+ fieldmapper.amtr.Identifier = 'matchpoint';
+ fieldmapper.coust.Identifier = 'name';
+
+ }
+
fieldmapper._request = function ( meth, staff, params ) {
var ses = OpenSRF.CachedClientSession( meth[0] );
if (!ses) return null;
@@ -90,7 +182,7 @@
if (dojo.isObject(params)) {
args = params;
} else {
- args.params = [].splice.call(arguments, 1, arguments.length - 1);
+ args.params = [].splice.call(arguments, 2, arguments.length - 2);
}
}
@@ -136,76 +228,6 @@
fieldmapper.staffRequest = function (meth, params) { return fieldmapper._request(meth, true, params) };
fieldmapper.Fieldmapper.prototype.staffRequest = fieldmapper.staffRequest;
- // if we were called by the IDL loader ...
- if ( fieldmapper.IDL && fieldmapper.IDL.loaded ) {
- for( var cl in fieldmapper.IDL.fmclasses ) {
- dojo.provide( cl );
- dojo.declare( cl , fieldmapper.Fieldmapper, {
- constructor : function () {
- if (!this.a) this.a = [];
- this.classname = this.declaredClass;
- this._fields = [];
- this.Structure = fieldmapper.IDL.fmclasses[this.classname]
-
- for (var f in fieldmapper.IDL.fmclasses[this.classname].fields) {
- var field = fieldmapper.IDL.fmclasses[this.classname].fields[f];
- var p = field.array_position;
- this._fields.push( field.name );
- this[field.name]=new Function('n', 'if(arguments.length==1)this.a['+p+']=n;return this.a['+p+'];');
- }
- }
- });
- fieldmapper[cl] = window[cl]; // alias into place
- fieldmapper[cl].Identifier = fieldmapper.IDL.fmclasses[cl].pkey;
- }
-
- // ... otherwise we need to get the oldschool fmall.js stuff, which will lack .structure
- } else {
- if (!window.fmclasses)
- dojo.require("fieldmapper.fmall", true);
-
- for( var cl in fmclasses ) {
- dojo.provide( cl );
- dojo.declare( cl , fieldmapper.Fieldmapper, {
- constructor : function () {
- if (!this.a) this.a = [];
- this.classname = this.declaredClass;
- this._fields = fmclasses[this.classname];
- for( var pos = 0; pos < this._fields.length; pos++ ) {
- var p = parseInt(pos);
- var f = this._fields[pos];
- this[f]=new Function('n', 'if(arguments.length==1)this.a['+p+']=n;return this.a['+p+'];');
- }
- }
- });
- fieldmapper[cl] = window[cl]; // alias into place
- fieldmapper[cl].Identifier = 'id'; // alias into place
- }
-
- fieldmapper.i18n_l.Identifier = 'code';
- fieldmapper.ccpbt.Identifier = 'code';
- fieldmapper.ccnbt.Identifier = 'code';
- fieldmapper.cbrebt.Identifier = 'code';
- fieldmapper.cubt.Identifier = 'code';
- fieldmapper.ccm.Identifier = 'code';
- fieldmapper.cvrfm.Identifier = 'code';
- fieldmapper.clm.Identifier = 'code';
- fieldmapper.cam.Identifier = 'code';
- fieldmapper.cifm.Identifier = 'code';
- fieldmapper.citm.Identifier = 'code';
- fieldmapper.cblvl.Identifier = 'code';
- fieldmapper.clfm.Identifier = 'code';
- fieldmapper.mous.Identifier = 'usr';
- fieldmapper.moucs.Identifier = 'usr';
- fieldmapper.mucs.Identifier = 'usr';
- fieldmapper.mus.Identifier = 'usr';
- fieldmapper.rxbt.Identifier = 'xact';
- fieldmapper.rxpt.Identifier = 'xact';
- fieldmapper.cxt.Identifier = 'name';
- fieldmapper.amtr.Identifier = 'matchpoint';
-
- }
-
fieldmapper.OpenSRF = {};
/* Methods are defined as [ service, method, have_staff ]
@@ -291,7 +313,7 @@
FETCH_MR_DESCRIPTORS : ['open-ils.search','open-ils.search.metabib.record_to_descriptors'],
FETCH_HIGHEST_PERM_ORG : ['open-ils.actor','open-ils.actor.user.perm.highest_org.batch'],
FETCH_USER_NOTES : ['open-ils.actor','open-ils.actor.note.retrieve.all'],
- FETCH_ORG_BY_SHORTNAME : ['open-ils.actor','open-ils.actor.org_unit.retrieve_by_shorname'],
+ FETCH_ORG_BY_SHORTNAME : ['open-ils.actor','open-ils.actor.org_unit.retrieve_by_shortname'],
FETCH_BIB_ID_BY_BARCODE : ['open-ils.search','open-ils.search.bib_id.by_barcode'],
FETCH_ORG_SETTING : ['open-ils.actor','open-ils.actor.ou_setting.ancestor_default'],
FETCH_ORG_SETTING_BATCH : ['open-ils.actor','open-ils.actor.ou_setting.ancestor_default.batch']
Modified: branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/IDL.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/IDL.js 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/IDL.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -1,45 +1,62 @@
if(!dojo._hasResource["fieldmapper.IDL"]) {
+ dojo.require("DojoSRF");
dojo.provide("fieldmapper.IDL");
dojo.declare('fieldmapper.IDL', null, {
_URL_PATH : '/reports/fm_IDL.xml', // XXX locale?
- // -- just need to set up xmlent and use '/reports/'+dojo.locale+'/fm_IDL.xml'
+ // -- just need to set up xmlent and use '/reports/'+OpenSRF.locale+'/fm_IDL.xml'
NS_REPORTS : 'http://open-ils.org/spec/opensrf/IDL/reporter/v1',
NS_PERSIST : 'http://open-ils.org/spec/opensrf/IDL/persistence/v1',
NS_OBJ : 'http://open-ils.org/spec/opensrf/IDL/objects/v1',
- constructor : function(callback, force) {
- if(!fieldmapper.IDL.fmclasses || force) {
+ constructor : function(classlist) {
+
+ if(!fieldmapper.IDL.fmclasses || (classlist && classlist.length)) {
+ var idl_url = this._URL_PATH;
+
+ if (classlist.length) {
+ idl_url += '?';
+
+ for (var i = 0; i < classlist.length; i++) {
+ var trim_class = classlist[i];
+ if (!trim_class) continue;
+
+ if (i > 0) idl_url += '&';
+ idl_url += 'class=' + trim_class;
+ }
+ }
+
var self = this;
dojo.xhrGet({
- url : this._URL_PATH,
+ url : idl_url,
handleAs : 'xml',
sync : true,
timeout : 10000,
load : function (response) {
- self._parse(response, callback);
+ self._parse(response);
fieldmapper.IDL.loaded = true;
},
error : function (response) {
fieldmapper.IDL.loaded = false;
dojo.require('fieldmapper.fmall', true);
- if(callback)
- callback();
}
});
}
+ dojo.require('fieldmapper.Fieldmapper');
- return dojo.require('fieldmapper.Fieldmapper');
+ if (classlist && classlist.length)
+ dojo.forEach( classlist, function (c) { fieldmapper.vivicateClass(c); } );
},
- _parse : function(xmlNode, callback) {
- var classes = xmlNode.getElementsByTagName('class');
- var idl = fieldmapper.IDL.fmclasses = {};
-
+ _parse : function(xmlNode) {
+ var classes = dojo.query('class',xmlNode);
+ if (!fieldmapper.IDL || !fieldmapper.IDL.fmclasses)
+ fieldmapper.IDL.fmclasses = {};
+
for(var i = 0; i < classes.length; i++) {
var node = classes[i];
var id = node.getAttribute('id');
- var fields = node.getElementsByTagName('fields')[0];
+ var fields = dojo.query('fields',node)[0];
window.fmclasses[id] = [];
var fieldData = this._parseFields(node, id);
@@ -48,22 +65,25 @@
fields : fieldData.list,
field_map : fieldData.map,
name : node.getAttribute('id'),
- //table : node.getAttributeNS(this.NS_PERSIST, 'tablename'),
- //core : node.getAttributeNS(this.NS_REPORTS, 'core'),
- label : node.getAttributeNS(this.NS_REPORTS, 'label'),
- restrict_primary : node.getAttributeNS(this.NS_PERSIST, 'restrict_primary'),
- virtual : (node.getAttributeNS(this.NS_PERSIST, 'virtual') == 'true'),
- pkey : fields.getAttributeNS(this.NS_PERSIST, 'primary'),
- pkey_sequence : fields.getAttributeNS(this.NS_PERSIST, 'sequence')
+ //table : fieldmapper._getAttributeNS(node,this.NS_PERSIST, 'tablename'),
+ //core : fieldmapper._getAttributeNS(node,this.NS_REPORTS, 'core'),
+ label : fieldmapper._getAttributeNS(node,this.NS_REPORTS, 'label'),
+ restrict_primary : fieldmapper._getAttributeNS(node,this.NS_PERSIST, 'restrict_primary'),
+ virtual : (fieldmapper._getAttributeNS(node,this.NS_PERSIST, 'virtual') == 'true'),
+ pkey : fieldmapper._getAttributeNS(fields,this.NS_PERSIST, 'primary'),
+ pkey_sequence : fieldmapper._getAttributeNS(fields,this.NS_PERSIST, 'sequence')
};
- var permacrud = node.getElementsByTagName('permacrud')[0];
+ var valid = fieldmapper._getAttributeNS(node,this.NS_OBJ, 'validate');
+ if (valid) obj.validate = new RegExp( valid.replace(/\\/g, '\\\\') );
+
+ var permacrud = dojo.query('permacrud',node)[0];
if(permacrud) {
var actions = ['create', 'retrieve', 'update', 'delete'];
obj.permacrud = {};
for(var idx in actions) {
var action = actions[idx];
- var pnode = permacrud.getElementsByTagName(action)[0];
+ var pnode = dojo.query(action,permacrud)[0];
if(pnode) {
var permString = pnode.getAttribute('permission');
var permList = null;
@@ -85,11 +105,9 @@
obj.core = (obj.core == 'true');
obj.label = (obj.label) ? obj.label : obj.name;
- idl[id] = obj;
+ fieldmapper.IDL.fmclasses[id] = obj;
}
- if(callback)
- callback();
},
/* parses the links and fields portion of the IDL */
@@ -97,11 +115,11 @@
var data = [];
var map = {};
- var fields = node.getElementsByTagName('fields')[0];
- fields = fields.getElementsByTagName('field');
+ var fields = dojo.query('fields',node)[0];
+ fields = dojo.query('field',fields);
- var links = node.getElementsByTagName('links')[0];
- if( links ) links = links.getElementsByTagName('link');
+ var links = dojo.query('links',node)[0];
+ if( links ) links = dojo.query('link',links);
else links = [];
@@ -116,13 +134,15 @@
var obj = {
field : field,
name : name,
- label : field.getAttributeNS(this.NS_REPORTS,'label'),
- datatype : field.getAttributeNS(this.NS_REPORTS,'datatype'),
- primitive : field.getAttributeNS(this.NS_PERSIST,'primitive'),
- selector : field.getAttributeNS(this.NS_REPORTS,'selector'),
+ label : fieldmapper._getAttributeNS(field,this.NS_REPORTS,'label'),
+ datatype : fieldmapper._getAttributeNS(field,this.NS_REPORTS,'datatype'),
+ primitive : fieldmapper._getAttributeNS(field,this.NS_PERSIST,'primitive'),
+ selector : fieldmapper._getAttributeNS(field,this.NS_REPORTS,'selector'),
array_position : position++,
type : 'field',
- virtual : (fields[i].getAttributeNS(this.NS_PERSIST, 'virtual') == 'true')
+ virtual : (fieldmapper._getAttributeNS(fields[i],this.NS_PERSIST, 'virtual') == 'true'),
+ required : (fieldmapper._getAttributeNS(fields[i],this.NS_OBJ, 'required') == 'true'),
+ i18n : (fieldmapper._getAttributeNS(fields[i],this.NS_PERSIST, 'i18n') == 'true')
};
obj.label = obj.label || obj.name;
@@ -167,9 +187,20 @@
});
+ fieldmapper._getAttributeNS = function (node,ns,attr) {
+ if (node.getAttributeNS) return node.getAttributeNS(ns,attr);
+ return node.getAttribute(attr);
+ };
+
window.fmclasses = {};
- fieldmapper.IDL.load = function (callback, force) { return new fieldmapper.IDL(callback, force); };
+ fieldmapper.IDL.load = function (list) { if (!list) list = []; return new fieldmapper.IDL(list); };
fieldmapper.IDL.loaded = false;
+ JSON2js.fallbackObjectifier = function (arg, key_name, val_name) {
+ console.log("Firing IDL loader for " + arg[key_name]);
+ fieldmapper.IDL.load([arg[key_name]]);
+ return decodeJS(arg);
+ }
+
}
Modified: branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/dojoData.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/dojoData.js 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/dojoData.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -26,10 +26,10 @@
function _fromStoreItem (data) {
this.fromHash(data);
- for (var i in this._ignore_fields)
+ for (var i = 0; this._ignore_fields && i < this._ignore_fields.length; i++)
this[this._ignore_fields[i]](null);
- for ( var i=0; i < this._fields.length; i++) {
+ for (var i = 0; this._fields && i < this._fields.length; i++) {
if (dojo.isArray( this[this._fields[i]]() ))
this[this._fields[i]]( this[this._fields[i]]()[0] );
}
@@ -53,22 +53,22 @@
if (!params) params = {};
var data = this.initStoreData(label, params);
- for (var i in list) data.items.push( list[i].toHash(true, params.virtualFields) );
+ for (var i = 0; list && i < list.length; i++) data.items.push( list[i].toHash(true, params.virtualFields) );
if (params.children && params.parent) {
var _hash_list = data.items;
var _find_root = {};
- for (var i in _hash_list) {
+ for (var i = 0; _hash_list && i < _hash_list.length; i++) {
_find_root[_hash_list[i][params.identifier]] = _hash_list[i];
}
var item_data = [];
- for (var i in _hash_list) {
+ for (var i = 0; _hash_list && i < _hash_list.length; i++) {
var obj = _hash_list[i]
obj[params.children] = [];
- for (var j in _hash_list) {
+ for (var j = 0; _hash_list && j < _hash_list.length; j++) {
var kid = _hash_list[j];
if (kid[params.parent] == obj[params.identifier]) {
obj[params.children].push( { _reference : kid[params.identifier] } );
@@ -92,15 +92,18 @@
return data;
}
- for (var i in fmclasses) fieldmapper[i].prototype.fromStoreItem = _fromStoreItem;
- for (var i in fmclasses) fieldmapper[i].toStoreData = _toStoreData;
- for (var i in fmclasses) fieldmapper[i].toStoreItem = _toStoreItem;
- for (var i in fmclasses) fieldmapper[i].prototype.toStoreItem = function ( args ) { return _toStoreItem(this, args) };
- for (var i in fmclasses) fieldmapper[i].initStoreData = _initStoreData;
+ for (var i in fmclasses) {
+ fieldmapper[i].prototype.fromStoreItem = _fromStoreItem;
+ fieldmapper[i].prototype.fromStoreItem = _fromStoreItem;
+ fieldmapper[i].toStoreData = _toStoreData;
+ fieldmapper[i].toStoreItem = _toStoreItem;
+ fieldmapper[i].prototype.toStoreItem = function ( args ) { return _toStoreItem(this, args) };
+ fieldmapper[i].initStoreData = _initStoreData;
+ }
- fieldmapper.aou.prototype._ignore_fields = ['children'];
- fieldmapper.aout.prototype._ignore_fields = ['children'];
- fieldmapper.pgt.prototype._ignore_fields = ['children'];
+ if (fieldmapper.aou) fieldmapper.aou.prototype._ignore_fields = ['children'];
+ if (fieldmapper.aout) fieldmapper.aout.prototype._ignore_fields = ['children'];
+ if (fieldmapper.pgt) fieldmapper.pgt.prototype._ignore_fields = ['children'];
fieldmapper.aou.toStoreData = function (list, label) {
if (!label) label = 'shortname';
Modified: branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/hash.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/hash.js 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/fieldmapper/hash.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -41,7 +41,7 @@
}
if (virtFields && virtFields.length > 0) {
- for (var i in virtFields) {
+ for (var i = 0; i < virtFields.length; i++) {
if (!_hash[virtFields[i]])
_hash[virtFields[i]] = null;
}
Modified: branches/rel_1_6/Open-ILS/web/js/dojo/openils/User.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/dojo/openils/User.js 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/js/dojo/openils/User.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -24,6 +24,7 @@
dojo.require('fieldmapper.Fieldmapper');
dojo.require('fieldmapper.OrgUtils');
dojo.require('openils.Util');
+ dojo.require('dojo.cookie');
dojo.declare('openils.User', null, {
@@ -50,6 +51,7 @@
this.authcookie = kwargs.authcookie || openils.User.authcookie;
this.permOrgStoreCache = {}; /* permName => permOrgUnitStore map */
+ if (this.authcookie) this.authtoken = dojo.cookie(this.authcookie);
if (this.id && this.authtoken) this.user = this.getById( this.id );
else if (this.authtoken) this.getBySession();
else if (kwargs.login) this.login();
@@ -137,13 +139,16 @@
var authReq = OpenSRF.CachedClientSession('open-ils.auth').request('open-ils.auth.authenticate.complete', loginInfo);
authReq.oncomplete = function(rr) {
var data = rr.recv().content();
+
+ if(!data || !data.payload)
+ throw new Error("Login Failed: " + js2JSON(data));
+
_u.authtoken = data.payload.authtoken;
if (!openils.User.authtoken) openils.User.authtoken = _u.authtoken;
_u.authtime = data.payload.authtime;
if (!openils.User.authtime) openils.User.authtime = _u.authtime;
_u.getBySession(onComplete);
if(_u.authcookie) {
- dojo.require('dojo.cookie');
dojo.cookie(_u.authcookie, _u.authtoken, {path:'/'});
}
}
@@ -179,15 +184,18 @@
[loginInfo]
);
+ if(!data || !data.payload) return false;
+
_u.authtoken = data.payload.authtoken;
if (!openils.User.authtoken) openils.User.authtoken = _u.authtoken;
_u.authtime = data.payload.authtime;
if (!openils.User.authtime) openils.User.authtime = _u.authtime;
if(_u.authcookie) {
- dojo.require('dojo.cookie');
dojo.cookie(_u.authcookie, _u.authtoken, {path:'/'});
}
+
+ return true;
},
Modified: branches/rel_1_6/Open-ILS/web/js/ui/base.js
===================================================================
--- branches/rel_1_6/Open-ILS/web/js/ui/base.js 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/js/ui/base.js 2010-10-11 17:25:19 UTC (rev 18265)
@@ -31,6 +31,7 @@
}
function oilsDoLogin() {
+ openils.Util.hide('oils-login-failed');
var cgi = new openils.CGI();
var workstation = cgi.param('ws') || dojo.cookie('ws');
var user = new openils.User();
@@ -41,9 +42,14 @@
};
if(workstation)
args.workstation = workstation;
- user.login(args);
- dojo.cookie('ses', user.authtoken, {path : '/'});
- location.href = location.href;
+
+ if(user.login(args)) {
+ dojo.cookie('ses', user.authtoken, {path : '/'});
+ location.href = location.href;
+ } else {
+ openils.Util.show('oils-login-failed');
+ }
+
return false;
}
Modified: branches/rel_1_6/Open-ILS/web/templates/login.tt2
===================================================================
--- branches/rel_1_6/Open-ILS/web/templates/login.tt2 2010-10-11 16:07:47 UTC (rev 18264)
+++ branches/rel_1_6/Open-ILS/web/templates/login.tt2 2010-10-11 17:25:19 UTC (rev 18265)
@@ -2,6 +2,7 @@
<div style='display:none;' dojoType="dijit.Dialog" jsId='oilsLoginDialog' class='oils-login-dialog'>
<script>dojo.require('dijit.form.TextBox');</script>
<b>Please Login</b>
+ <div class='hidden oils-notify-text' id='oils-login-failed'>Login Failed</div>
<form>
<table>
<tr>
More information about the open-ils-commits
mailing list