From: erickson Date: Sat, 19 Apr 2008 12:45:17 +0000 (+0000) Subject: ------ X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=40275b85cd9c97ca5e30c58d2792485afbee96bc;p=Evergreen.git ------ Merged changes from trunk into the acq branch. Details below... ------ Merged revisions 8237,8245,8250,8253,8258-8259,8261-8264,8270,8272,8274-8275,8287,8293,8298-8299,8302,8304-8305,8308-8309,8311-8312,8314,8316,8322,8325,8327,8331,8336,8341,8347-8348,8352,8354,8361,8379-8384,8387,8389,8392,8398,8402-8403,8405,8414,8423,8426,8431-8450,8452,8455,8457,8459-8462,8464,8466,8468,8471-8475,8477,8481,8488-8489,8494,8496,8498-8499,8501-8503,8506-8509,8513-8516,8519-8520,8523-8526,8528-8530,8533,8537,8544,8546-8554,8557-8559,8562-8566,8570-8573,8575,8577,8580,8582-8592,8600,8602,8604,8606,8609-8611,8614-8616,8618-8619,8624-8628,8630,8632,8634,8636,8643,8645,8652-8656,8661,8663,8665-8667,8669,8674,8677,8679-8680,8689-8691,8693,8696,8699-8705,8707-8708,8711,8713,8721,8723,8725-8726,8731,8740-8741,8749,8752,8755,8759-8761,8765-8767,8771-8772,8788,8794,8798,8802,8808,8811,8818,8820,8823,8825,8829-8830,8835,8837,8840,8842,8844-8856,8858-8860,8863,8870-8875,8881,8883-8884,8886-8904,8906,8909-8911,8917,8920-8928,8930-8931,8933,8936,8942-8944,8948-8956,8959-8964,8966-8977,8985-8986,8990-8991,8993,8995,8999,9001-9002,9004,9007-9015,9017-9019,9021-9026,9028-9040,9043,9045-9059,9061,9065,9067,9069,9071,9073,9076-9077,9079,9081-9082,9085-9086,9088,9092,9094,9099,9102,9104,9108,9111-9116,9119,9121-9125,9127,9129-9133,9137,9140-9142,9144-9146,9148-9150,9152,9159,9165-9166,9175,9177,9180,9186-9187,9191-9193,9195-9196,9198,9200,9203-9204,9206-9210,9212-9217,9219-9223,9225-9226,9228-9229,9232-9236,9241,9243,9245,9247-9248,9253,9255-9256,9259-9261,9266,9269-9270,9272,9276,9279,9288-9289,9291-9295,9300,9304,9309-9314,9318-9323,9325,9327-9330,9333-9336,9338-9340,9342-9343,9345,9347,9349-9350,9352-9354,9356-9360,9362-9380 via svnmerge from svn://svn.open-ils.org/ILS/trunk ........ r8237 | miker | 2007-12-19 17:51:14 -0500 (Wed, 19 Dec 2007) | 1 line make z search more robust when using multi-target search ........ r8245 | dbs | 2007-12-19 21:08:57 -0500 (Wed, 19 Dec 2007) | 2 lines Add Armenian translation of OPAC (thanks to tigran.zargaryan@eifl.net) ........ r8250 | erickson | 2007-12-20 10:58:46 -0500 (Thu, 20 Dec 2007) | 1 line added search ........ r8253 | dbs | 2007-12-20 14:26:51 -0500 (Thu, 20 Dec 2007) | 4 lines Enable translation of ils_events.xml, roundtripping from XML to POT to PO to XML. Check in a current trunk version of the POT file. Still need to enable elements for each xml:lang to merge into the ultimate XML file. ........ r8258 | phasefx | 2007-12-20 17:25:25 -0500 (Thu, 20 Dec 2007) | 1 line multi-z-source functionality for staff client z39.50 client ........ r8259 | erickson | 2007-12-20 23:09:53 -0500 (Thu, 20 Dec 2007) | 1 line fixed atomic method re-naming ........ r8261 | dbs | 2007-12-20 23:29:19 -0500 (Thu, 20 Dec 2007) | 2 lines Add some documentation to this marvelous class ........ r8262 | phasefx | 2007-12-21 01:18:07 -0500 (Fri, 21 Dec 2007) | 1 line consider .auth for services ........ r8263 | phasefx | 2007-12-21 01:47:03 -0500 (Fri, 21 Dec 2007) | 1 line hardcode native evergreen catalog as a virtual z-source, and show 0 records found if no .count field ........ r8264 | phasefx | 2007-12-21 01:55:05 -0500 (Fri, 21 Dec 2007) | 1 line oops, disable these widgets until the native-evergreen-catalog virtual z-service is in trunk ........ r8270 | dbs | 2007-12-21 13:11:33 -0500 (Fri, 21 Dec 2007) | 2 lines Fix typo that prevents parsing virtual fields ........ r8272 | dbs | 2007-12-21 13:42:39 -0500 (Fri, 21 Dec 2007) | 2 lines Add a little bit of example usage to the docs for idl.pl ........ r8274 | erickson | 2007-12-21 17:43:58 -0500 (Fri, 21 Dec 2007) | 1 line added some documentation. sorry, dbs, if the format isn't right... more to come ........ r8275 | dbs | 2007-12-22 21:41:38 -0500 (Sat, 22 Dec 2007) | 2 lines Install Evergreen Python modules via distutils ........ r8287 | miker | 2007-12-28 11:34:04 -0500 (Fri, 28 Dec 2007) | 1 line adding fkey for actor.usr.profile -- Thanks to Jonh from AlphaG for spotting the missing definition ........ r8293 | phasefx | 2008-01-02 10:38:16 -0500 (Wed, 02 Jan 2008) | 1 line refactor the flattening of hold copies, and disallow editing the pickup locations for intransit or ready for pickup holds ........ r8298 | phasefx | 2008-01-03 11:36:22 -0500 (Thu, 03 Jan 2008) | 1 line experiment with svn:keywords ........ r8299 | phasefx | 2008-01-03 11:38:12 -0500 (Thu, 03 Jan 2008) | 1 line copy/paste-o, but keywords seem to work ........ r8302 | erickson | 2008-01-03 12:10:17 -0500 (Thu, 03 Jan 2008) | 1 line forward-porting move to cstore for bib create and replace calls ........ r8304 | phasefx | 2008-01-03 13:46:51 -0500 (Thu, 03 Jan 2008) | 1 line change Build ID to Target Server ID to match reality, and display the svn path the build came from ........ r8305 | phasefx | 2008-01-03 13:49:23 -0500 (Thu, 03 Jan 2008) | 1 line I'm not going to bother parsing the svn keyword for now, so this looks better like this ........ r8308 | erickson | 2008-01-03 14:13:16 -0500 (Thu, 03 Jan 2008) | 1 line fixed typo -- tiemstamp ........ r8309 | erickson | 2008-01-03 14:42:36 -0500 (Thu, 03 Jan 2008) | 1 line replaced unneccesary loop with API call ........ r8311 | erickson | 2008-01-03 15:59:14 -0500 (Thu, 03 Jan 2008) | 1 line showing last year closed dates in addition to this year and beyond ........ r8312 | erickson | 2008-01-04 09:01:02 -0500 (Fri, 04 Jan 2008) | 1 line parsing primary, sequence, and primitive settings from IDL ........ r8314 | erickson | 2008-01-04 14:19:49 -0500 (Fri, 04 Jan 2008) | 1 line added fields where links existed for nonexistant fields. fixed a typo ........ r8316 | erickson | 2008-01-04 15:35:44 -0500 (Fri, 04 Jan 2008) | 6 lines * added link parsing * added an abstraction layer over the IDL class, field, and link objects for class-based access * started (slowly) making the move to the more pythonic lower/underscore method names ........ r8322 | erickson | 2008-01-04 17:12:38 -0500 (Fri, 04 Jan 2008) | 1 line logging error for now instead of throwing exception ........ r8325 | miker | 2008-01-05 20:13:11 -0500 (Sat, 05 Jan 2008) | 1 line make the message about duplicate TCN avoidance more clear ........ r8327 | dbs | 2008-01-06 13:44:22 -0500 (Sun, 06 Jan 2008) | 2 lines Typo fix in Python IDL module (virtul -> virtual) ........ r8331 | erickson | 2008-01-06 14:32:55 -0500 (Sun, 06 Jan 2008) | 1 line more IDL api work. moving to more pythonic lower/underscore method names. moved global functions to class-level static method. updated docstring and dependent classes ........ r8336 | erickson | 2008-01-06 16:06:50 -0500 (Sun, 06 Jan 2008) | 1 line changed create_date to create_time to match column in db ........ r8341 | dbs | 2008-01-06 20:05:01 -0500 (Sun, 06 Jan 2008) | 2 lines Enable Python build with regular user to avoid perm problems at clean time. ........ r8347 | erickson | 2008-01-07 18:16:02 -0500 (Mon, 07 Jan 2008) | 1 line plugged in new permission checking call which uses cstore instead of storage ........ r8348 | phasefx | 2008-01-08 11:50:32 -0500 (Tue, 08 Jan 2008) | 1 line refactor and fix dedup of shelving locations, and fix regression when Copy Editor is in View-Only mode ........ r8352 | phasefx | 2008-01-08 14:28:15 -0500 (Tue, 08 Jan 2008) | 1 line refactor spawn_copy_editor and perm check ........ r8354 | phasefx | 2008-01-08 15:37:09 -0500 (Tue, 08 Jan 2008) | 1 line one hell of a typo ;) fixes a regression ........ r8361 | erickson | 2008-01-09 09:52:48 -0500 (Wed, 09 Jan 2008) | 1 line added an is_true function ........ r8379 | miker | 2008-01-11 20:02:23 -0500 (Fri, 11 Jan 2008) | 1 line force flushing of the apache/mod_perl buffer after each record ........ r8380 | miker | 2008-01-14 17:09:33 -0500 (Mon, 14 Jan 2008) | 1 line allow the exporter to accept a container id, for exporting buckets etc ........ r8381 | miker | 2008-01-14 17:29:13 -0500 (Mon, 14 Jan 2008) | 1 line allow cgi params instead of a cookie for auth token ........ r8382 | dbs | 2008-01-14 23:26:35 -0500 (Mon, 14 Jan 2008) | 2 lines Switch to setuptools for dependency handling ........ r8383 | erickson | 2008-01-15 09:48:34 -0500 (Tue, 15 Jan 2008) | 1 line removing deprecated code ........ r8384 | erickson | 2008-01-15 12:30:07 -0500 (Tue, 15 Jan 2008) | 1 line repaired typo ........ r8387 | erickson | 2008-01-15 18:26:10 -0500 (Tue, 15 Jan 2008) | 1 line updated to match opensrf changes, more move away from prefixed functions. ........ r8389 | dbs | 2008-01-15 22:37:47 -0500 (Tue, 15 Jan 2008) | 4 lines Backport from acq-experiment branch: Add a build flag for Python modules. Use setuptools for building and installing Python modules. ........ r8392 | erickson | 2008-01-16 12:27:00 -0500 (Wed, 16 Jan 2008) | 1 line added acq const ........ r8398 | erickson | 2008-01-17 12:11:51 -0500 (Thu, 17 Jan 2008) | 1 line added a generic event class to model ILS events, removed functional event code from the util class ........ r8402 | erickson | 2008-01-17 12:57:34 -0500 (Thu, 17 Jan 2008) | 1 line added a to_ex method to turn the event into an exception and a runtime raise_and_parse method for 1-line event handling ........ r8403 | erickson | 2008-01-17 13:00:46 -0500 (Thu, 17 Jan 2008) | 1 line repaired event test ........ r8405 | dbs | 2008-01-17 13:57:17 -0500 (Thu, 17 Jan 2008) | 4 lines Move POT files into en-US subdirectory (clutter BAD). Provide more granular file and directory handling. Repair some of the unit tests to match the reorged dirs. ........ r8414 | dbs | 2008-01-17 21:58:17 -0500 (Thu, 17 Jan 2008) | 2 lines Move hardcoded strings out of offline transaction mgmt interface ........ r8423 | erickson | 2008-01-18 15:17:47 -0500 (Fri, 18 Jan 2008) | 1 line added explicit disconnect ........ r8426 | erickson | 2008-01-18 17:02:19 -0500 (Fri, 18 Jan 2008) | 1 line repaired logic error in reading event status. assuming existance of code and textcode ........ r8431 | dbs | 2008-01-19 00:26:34 -0500 (Sat, 19 Jan 2008) | 4 lines Move strings out of font_settings.xul; shuffle logic to make i18n possible. Correct a typo in offline_manage_xacts.xul. Note: chrome/locale is the wrong place for these properties, we probably want to coalesce all JS message catalogs into a single directory, then copy it into both chrome and server XUL. ........ r8432 | dbs | 2008-01-19 14:33:39 -0500 (Sat, 19 Jan 2008) | 2 lines Correct SetEnv syntax for XUL locale ........ r8433 | dbs | 2008-01-19 15:33:26 -0500 (Sat, 19 Jan 2008) | 2 lines Just use one messagecatalog (offline.properties) in chrome ........ r8434 | dbs | 2008-01-19 15:35:15 -0500 (Sat, 19 Jan 2008) | 2 lines Server-side XUL uses server-side message catalogs ........ r8435 | dbs | 2008-01-19 15:37:46 -0500 (Sat, 19 Jan 2008) | 2 lines Define common strings for server-side messagecatalogs ........ r8436 | dbs | 2008-01-20 06:28:18 -0500 (Sun, 20 Jan 2008) | 4 lines Start using locale SSI env to pull in DTD for XUL/XHTML Add include and XML entity parsing to XHTML files in /xul/ Localize a few more admin files ........ r8437 | dbs | 2008-01-20 07:13:59 -0500 (Sun, 20 Jan 2008) | 2 lines Correct "temaplate" typo ........ r8438 | dbs | 2008-01-20 07:44:43 -0500 (Sun, 20 Jan 2008) | 3 lines Localize many of the strings in closed_dates.xhtml; Note: some of the forms need to be redesigned to support i18n. ........ r8439 | dbs | 2008-01-20 13:54:06 -0500 (Sun, 20 Jan 2008) | 2 lines The localization madness continues... ........ r8440 | dbs | 2008-01-20 16:48:37 -0500 (Sun, 20 Jan 2008) | 2 lines Restore regression spotted by miker (thanks!) ........ r8441 | miker | 2008-01-20 21:33:29 -0500 (Sun, 20 Jan 2008) | 1 line stylesheet that can turn the Library of Conference MARC data into a nice XML format ........ r8442 | dbs | 2008-01-20 21:43:57 -0500 (Sun, 20 Jan 2008) | 2 lines More staff client localization in server/admin ........ r8443 | dbs | 2008-01-20 21:49:29 -0500 (Sun, 20 Jan 2008) | 2 lines Teach dtd2js.pl to ignore comments. ........ r8444 | miker | 2008-01-20 21:50:02 -0500 (Sun, 20 Jan 2008) | 1 line adding copyright and docs ........ r8445 | miker | 2008-01-20 21:52:53 -0500 (Sun, 20 Jan 2008) | 1 line adding pointer to the original docs ........ r8446 | dbs | 2008-01-20 22:58:26 -0500 (Sun, 20 Jan 2008) | 3 lines Teach i18n Makefile about multiple property file locations. Update our POT files. ........ r8447 | dbs | 2008-01-21 10:08:35 -0500 (Mon, 21 Jan 2008) | 3 lines Merge circ.properties into offline.properties (missed it the first time around). Now we (truly) have just a single properties file for the offline interfaces. ........ r8448 | phasefx | 2008-01-21 10:18:47 -0500 (Mon, 21 Jan 2008) | 1 line some try/catch goodness for messagecatalog implementation, and throw exception on key not found ........ r8449 | dbs | 2008-01-21 10:20:39 -0500 (Mon, 21 Jan 2008) | 2 lines Clean up staff client 'make' output ........ r8450 | dbs | 2008-01-21 12:31:02 -0500 (Mon, 21 Jan 2008) | 3 lines Eliminate lang.js (old i18n approach). Load common.properties in util_overlay.xul so it is available globally. ........ r8452 | erickson | 2008-01-22 10:49:53 -0500 (Tue, 22 Jan 2008) | 1 line beginnings of general purpose org_unit utility functions ........ r8455 | erickson | 2008-01-22 11:24:42 -0500 (Tue, 22 Jan 2008) | 1 line added open-ils.actor app ........ r8457 | dbs | 2008-01-22 11:34:56 -0500 (Tue, 22 Jan 2008) | 2 lines Use the SHELL Makefile variable to set bash, rather than hash-bang ........ r8459 | dbs | 2008-01-22 12:35:18 -0500 (Tue, 22 Jan 2008) | 3 lines Enable build via relative header file and library locations within the build tree We had been depending on files existing in /openils/ - egg-and-chicken style ........ r8460 | dbs | 2008-01-22 12:41:29 -0500 (Tue, 22 Jan 2008) | 3 lines Restore Makefile.install to r8000. This experimental update was unintentionally included in my previous commit ........ r8461 | dbs | 2008-01-22 12:51:52 -0500 (Tue, 22 Jan 2008) | 2 lines Correct install rules for the c-app headers ........ r8462 | dbs | 2008-01-22 12:59:24 -0500 (Tue, 22 Jan 2008) | 2 lines This actually uses bash syntax; let's be explicit in the hash-bang ........ r8464 | phasefx | 2008-01-22 14:14:07 -0500 (Tue, 22 Jan 2008) | 1 line util.window was relying on xulG, but when called from the main.menu framework, there is no xulG. This fixes the Operator Change regression, and the chrome Perm Denied/Re-Auth regression ........ r8466 | erickson | 2008-01-22 15:03:18 -0500 (Tue, 22 Jan 2008) | 1 line more org utility code ........ r8468 | erickson | 2008-01-22 15:10:20 -0500 (Tue, 22 Jan 2008) | 1 line more org utility code ........ r8471 | dbs | 2008-01-22 22:17:07 -0500 (Tue, 22 Jan 2008) | 2 lines Reorder admin user insert statements to satisfy foreign key dependencies ........ r8472 | dbs | 2008-01-22 22:59:40 -0500 (Tue, 22 Jan 2008) | 2 lines Typo in debug output ........ r8473 | dbs | 2008-01-23 08:25:47 -0500 (Wed, 23 Jan 2008) | 2 lines We no longer need to call lang.js ........ r8474 | dbs | 2008-01-23 08:31:36 -0500 (Wed, 23 Jan 2008) | 2 lines Localize strings in circ checkin interface ........ r8475 | erickson | 2008-01-23 08:57:00 -0500 (Wed, 23 Jan 2008) | 1 line added method to return flat list of related orgs ........ r8477 | erickson | 2008-01-23 09:07:42 -0500 (Wed, 23 Jan 2008) | 1 line verifying existance of local tree before performing some functions ........ r8481 | erickson | 2008-01-23 11:30:52 -0500 (Wed, 23 Jan 2008) | 1 line added org name sorting to org list retrieval ........ r8488 | dbs | 2008-01-23 22:18:56 -0500 (Wed, 23 Jan 2008) | 2 lines Do not force application type of XHTML files to XUL (wreaks havoc with javascript) ........ r8489 | dbs | 2008-01-23 23:04:17 -0500 (Wed, 23 Jan 2008) | 2 lines Use a more explicit term than "Mult-date" for easier translation ........ r8494 | miker | 2008-01-24 13:29:44 -0500 (Thu, 24 Jan 2008) | 1 line added param sets for voided billing clauses ........ r8496 | miker | 2008-01-24 13:31:05 -0500 (Thu, 24 Jan 2008) | 1 line fixing authority validation with the new input/output methods for the gateway ........ r8498 | dbs | 2008-01-24 15:51:34 -0500 (Thu, 24 Jan 2008) | 2 lines Localize checkin and checkout interfaces ........ r8499 | miker | 2008-01-25 12:50:59 -0500 (Fri, 25 Jan 2008) | 1 line make flags accept 0/1 as well as false/true ........ r8501 | dbs | 2008-01-27 14:31:23 -0500 (Sun, 27 Jan 2008) | 2 lines Correct entity name ........ r8502 | dbs | 2008-01-27 17:04:03 -0500 (Sun, 27 Jan 2008) | 2 lines Correct a mod_xmlent complaint about invalid XML ........ r8503 | dbs | 2008-01-27 17:38:29 -0500 (Sun, 27 Jan 2008) | 3 lines Migrate opac.js over from strbundle to messagecatalog Make circ_brief.xul locale-aware ........ r8506 | miker | 2008-01-27 19:09:49 -0500 (Sun, 27 Jan 2008) | 1 line adding create_time column to match the IDL ........ r8507 | dbs | 2008-01-27 20:38:18 -0500 (Sun, 27 Jan 2008) | 3 lines Return null in the event the requested org setting doesn't exist, rather than erroring out. Credit berick for fixing this one. ........ r8508 | dbs | 2008-01-27 23:40:26 -0500 (Sun, 27 Jan 2008) | 2 lines Correct a regression introduced by i18n, and make jslint happy while we're at it. ........ r8509 | erickson | 2008-01-28 10:03:32 -0500 (Mon, 28 Jan 2008) | 1 line protecting against edge case where we run off the end of the org table before finding a place to insert the callnumber row ........ r8513 | miker | 2008-01-28 12:13:33 -0500 (Mon, 28 Jan 2008) | 1 line ignore deleted records within a metarecord ........ r8514 | dbs | 2008-01-28 13:18:39 -0500 (Mon, 28 Jan 2008) | 2 lines A bit more checkout.js code cleaning to comply with jslint standards ........ r8515 | miker | 2008-01-28 15:04:14 -0500 (Mon, 28 Jan 2008) | 1 line just use plperl and not plperlu ........ r8516 | miker | 2008-01-28 15:16:10 -0500 (Mon, 28 Jan 2008) | 1 line ok fine. use plperlu ........ r8519 | erickson | 2008-01-28 15:57:12 -0500 (Mon, 28 Jan 2008) | 1 line drastically up the timeout for these long-running transactions ........ r8520 | miker | 2008-01-28 17:04:02 -0500 (Mon, 28 Jan 2008) | 1 line spacing ........ r8523 | erickson | 2008-01-28 18:20:29 -0500 (Mon, 28 Jan 2008) | 11 lines created an external brick configuration file brick_ctl can now take disparate sets of IPs for the master and drones removed the linux-specific IP grepping in favor of the configured IPs made xul building more flexible general cleanup committing example config file ........ r8524 | dbs | 2008-01-28 22:10:55 -0500 (Mon, 28 Jan 2008) | 3 lines Correct logic error that prevented users from changing their usernames (res = '0' because the username isn't found, but '0' != their user ID so it was always failing) ........ r8525 | dbs | 2008-01-28 23:45:00 -0500 (Mon, 28 Jan 2008) | 2 lines Convert z39.50 client over to common.properties strings from lang.js ........ r8526 | erickson | 2008-01-29 13:21:08 -0500 (Tue, 29 Jan 2008) | 1 line added some hold permit exemptions for DCPL and LEE. this is a PINES thing ........ r8528 | dbs | 2008-01-29 14:14:29 -0500 (Tue, 29 Jan 2008) | 3 lines Return explicit nulls if no matching username / barcode is found (and modify tests accordingly). We suspect JSON::XS started returning '0' instead of 0, which threw off our logic. ........ r8529 | miker | 2008-01-29 16:13:32 -0500 (Tue, 29 Jan 2008) | 1 line make double extra sure that the namespace attribute is there! ........ r8530 | miker | 2008-01-29 16:30:03 -0500 (Tue, 29 Jan 2008) | 1 line use default namespaces ... easier to work with anyway, and newer libxmls avoid stripping them ........ r8533 | dbs | 2008-01-29 22:23:21 -0500 (Tue, 29 Jan 2008) | 2 lines We actually need to test for equality with '0' ........ r8537 | erickson | 2008-01-30 12:13:42 -0500 (Wed, 30 Jan 2008) | 1 line ensuring transactions are closed after a billing is applied against a negative balance transaction ........ r8544 | phasefx | 2008-01-30 14:00:38 -0500 (Wed, 30 Jan 2008) | 1 line change D_ALERT log level to D_WARN to avoid unneeded popups ........ r8546 | dbs | 2008-01-30 16:56:40 -0500 (Wed, 30 Jan 2008) | 2 lines Make "make clean" clean the staff_client directory as well ........ r8547 | miker | 2008-01-31 13:13:37 -0500 (Thu, 31 Jan 2008) | 1 line Patch from Scott McKellar plugging several pointer leaks ........ r8548 | miker | 2008-01-31 13:34:42 -0500 (Thu, 31 Jan 2008) | 27 lines Patch from Scott McKellar: 1. I added the const qualifier to a number of function parameters. 2. I moved the prototype for _oilsEventParseEvents() from the header into the implementation file, and made the function static. No other source file calls it, nor should it. 3. I removed an extra leading underscore from each of _oilsEventEvents and _oilsEventDescriptions, and made them static. 3. I removed an unhelpful cast from a call to safe_malloc(). 4. I made sure to initialize every member of a new oilsEvent. 5. In several spots where we update pointer members of an oilsEvent, I preceded the update with a free, in order to avoid potential memory leaks. 6. I replaced calls to oilsEventSetPermission() and oilsEventSetPayload() with the equivalent inline code. 7. In oilsEventFree(), the original code would free the json member or the payload member but not both. We now free both. We also free the event member, which we didn't do before. ........ r8549 | miker | 2008-01-31 13:56:38 -0500 (Thu, 31 Jan 2008) | 1 line Patch from Scott Mckellar to plug a few leaks ........ r8550 | miker | 2008-01-31 14:01:25 -0500 (Thu, 31 Jan 2008) | 15 lines 1. In main() we allocate a growing_buffer named "json". I added a line to free it. 2. In commitTransaction() and rollbackTransaction() I eliminated a layer of jsonObjectClone(), along with the associated jsonObjectFree(). Now we extract the string we want directly from the original object without making an unnecessary copy. 3. I renamed the four macros starting with "E" so as to start with "E_" instead. 4. All functions (other than main()) are now static, as are the three variables that had been declared at global scope. ........ r8551 | miker | 2008-01-31 14:53:27 -0500 (Thu, 31 Jan 2008) | 12 lines Patch from Scott McKellar: 1. In oilsInitIDL: I added the const qualifier to the input parameter. This change involved some juggling of a couple of extra variables. 2. Also in oilsInitIDL: I plugged a potential memory leak related to an early return. 3. In oilsUtilsFetchUserByBarcode we create a jsonObject named "card" but we weren't freeing it. Now we free it. ........ r8552 | miker | 2008-01-31 14:55:57 -0500 (Thu, 31 Jan 2008) | 1 line Missed the header in the last patch (from Scott McKellar) ........ r8553 | miker | 2008-01-31 14:59:04 -0500 (Thu, 31 Jan 2008) | 1 line Patch from Scott McKellar to plug a small leak in open-ils.auth ........ r8554 | miker | 2008-01-31 15:13:05 -0500 (Thu, 31 Jan 2008) | 1 line put source include files in front of installed, system include files in the -I list (avoids mis-matched definition errors when const, etc is corrected) ........ r8557 | erickson | 2008-01-31 15:52:21 -0500 (Thu, 31 Jan 2008) | 1 line disallow marking an item lost that is already marked lost ........ r8558 | miker | 2008-01-31 16:40:30 -0500 (Thu, 31 Jan 2008) | 1 line moving dedup to just where it is needed ........ r8559 | erickson | 2008-01-31 16:58:50 -0500 (Thu, 31 Jan 2008) | 1 line duping method_type before using it as a data in the hash, since method_type is later freed ........ r8562 | erickson | 2008-01-31 17:45:28 -0500 (Thu, 31 Jan 2008) | 1 line comitting initial authoritative auto-magic transactions for cstore ........ r8563 | miker | 2008-02-01 00:10:42 -0500 (Fri, 01 Feb 2008) | 1 line adding 610, 611 and 630 to the list of controlled fields ........ r8564 | miker | 2008-02-01 09:10:33 -0500 (Fri, 01 Feb 2008) | 1 line give cstore the ability to select a subcolumn from a complex datatype, using the transform syntax ........ r8565 | miker | 2008-02-01 09:20:32 -0500 (Fri, 01 Feb 2008) | 1 line subcolumn redux: need to wrap the function call in parens to delimit the subcolumn from the function ........ r8566 | miker | 2008-02-01 09:24:01 -0500 (Fri, 01 Feb 2008) | 1 line it's the little things that getcha .... typo ........ r8570 | phasefx | 2008-02-01 12:25:05 -0500 (Fri, 01 Feb 2008) | 1 line single-row refresh does not realize when an item needs to move between lists, as in the Item Outs interface with Mark Lost or Claimed Returned. This is a quick fix, needs testing ........ r8571 | phasefx | 2008-02-01 12:25:57 -0500 (Fri, 01 Feb 2008) | 1 line sidestep race condition with new volumes and db replication.. this should fix the Stat Cat popup errors, but we need to test on weezie ........ r8572 | erickson | 2008-02-01 15:03:45 -0500 (Fri, 01 Feb 2008) | 1 line added method to find the org tree segments where a user has a given permission, includes work orgs ........ r8573 | erickson | 2008-02-01 15:10:26 -0500 (Fri, 01 Feb 2008) | 1 line moved old-fashioned perm check to json_query for speed ........ r8575 | erickson | 2008-02-01 15:19:52 -0500 (Fri, 01 Feb 2008) | 1 line removed cstoreditor :funcs import, was causing circular import problems when apputils was imported by cstoreeditor. ........ r8577 | miker | 2008-02-01 15:38:03 -0500 (Fri, 01 Feb 2008) | 1 line adding the usr->barcode link ........ r8580 | erickson | 2008-02-01 17:25:53 -0500 (Fri, 01 Feb 2008) | 1 line created method to return the thinnest full tree which contains a list of org IDs ........ r8582 | dbs | 2008-02-02 14:48:13 -0500 (Sat, 02 Feb 2008) | 2 lines Revert revision 8546 - checked in the wrong file. ........ r8583 | dbs | 2008-02-02 14:48:53 -0500 (Sat, 02 Feb 2008) | 2 lines Make "make clean" clean the staff_client directory as well ........ r8584 | dbs | 2008-02-02 14:53:18 -0500 (Sat, 02 Feb 2008) | 2 lines i18n for checkout and circulation info interfaces ........ r8585 | dbs | 2008-02-02 16:15:51 -0500 (Sat, 02 Feb 2008) | 2 lines i18n for copy details and circulation summary screens ........ r8586 | miker | 2008-02-02 16:18:14 -0500 (Sat, 02 Feb 2008) | 1 line protect against null fingerprints (???) ........ r8587 | dbs | 2008-02-02 17:16:55 -0500 (Sat, 02 Feb 2008) | 2 lines i18n of copy status overlay ........ r8588 | miker | 2008-02-02 22:51:59 -0500 (Sat, 02 Feb 2008) | 1 line initial in-db circ and hold stuff. this codifies the circ_modifier, and requires that values be registered before importing items that use them. so, word to the wise, and the importer. there is some example SQL that will be useful for upgrading embedded in the script files right now. ........ r8589 | miker | 2008-02-03 14:08:44 -0500 (Sun, 03 Feb 2008) | 48 lines Patch from Scott McKellar: 1. In setSavepoint(), releaseSavepoint() and rollbackSavepoint() we were leaking spName. 2. Deep in doCreate() we were passing the return value of jsonObjectToSimpleString() directly to strcmp(), resulting in a leak. The strcmp() was inside a complex if condition. which I rearranged so as to capture the string and free it. Also: I captured and reused the return value from jsonObjectGetKeyConst() so as to avoid duplicated calls. Aso: I reversed the sense of the if condition and swapped the branches, so that it tests for equality rather than inequality. To my eyes this arrangement is more readable. 3. doRetrieve() was leaking id. 4. jsonNumberToDBString() was passing the return value of jsonObjectToSimpleString() directly to atol() and atof(), thereby leaking the memory. I captured the pointers and freed them. 5. searchFieldTransform() was leaking val. 6. In searchJOIN() we were leaking type and filter_op in the case of some early returns. I moved the allocations past the early returns so that we don't allocate them until we need them. I also free them as soon as we are done with them. As a side benefit, I was able to avoid allocating filter_op at all in some cases. I gave similar treatment to table, although that wasn't being leaked. As a result I could avoid having to free it in the early returns. A couple of the early returns would leak field or fkey. I plugged those leaks as well. I moved the declarations of filter and join_filter to their points of first use, in the interest of clarity. 7. In buildSELECT(): we were passing the return value of jsonObjectToSimpleString() directly to osrfHashGet(), thereby leaking the memory. I captured the pointer and freed it. 8. In doFieldmapperSearch() a do/while loop allocates pkey_val but in some cases wasn't freeing it. ........ r8590 | dbs | 2008-02-04 00:43:50 -0500 (Mon, 04 Feb 2008) | 2 lines Bring i18n to the main login window ........ r8591 | dbs | 2008-02-04 00:56:31 -0500 (Mon, 04 Feb 2008) | 2 lines Complete i18n of chrome/cat/opac.js ........ r8592 | erickson | 2008-02-04 10:36:28 -0500 (Mon, 04 Feb 2008) | 1 line repaired logic error in union-tree builder ........ r8600 | erickson | 2008-02-04 11:23:30 -0500 (Mon, 04 Feb 2008) | 1 line no longer clobbering client-provided array of orgs ........ r8602 | erickson | 2008-02-04 11:28:06 -0500 (Mon, 04 Feb 2008) | 1 line verifying existance of org tree before building union tree ........ r8604 | erickson | 2008-02-04 11:35:03 -0500 (Mon, 04 Feb 2008) | 1 line forcing int-ness on flat org keys for consistency ........ r8606 | erickson | 2008-02-04 11:45:51 -0500 (Mon, 04 Feb 2008) | 1 line added a min-depth function for a group of orgs, changed some variable names to be more explicit ........ r8609 | dbs | 2008-02-04 13:17:10 -0500 (Mon, 04 Feb 2008) | 2 lines Bring i18n to JSAN error messages ........ r8610 | miker | 2008-02-04 16:22:27 -0500 (Mon, 04 Feb 2008) | 1 line adding baseline circ matrix models ........ r8611 | erickson | 2008-02-04 16:52:33 -0500 (Mon, 04 Feb 2008) | 1 line repaired some copy/paste errors ........ r8614 | phasefx | 2008-02-04 17:01:39 -0500 (Mon, 04 Feb 2008) | 1 line clear "Red Items are circulating" hint on refresh in Patron Bills interface ........ r8615 | dbs | 2008-02-04 17:08:53 -0500 (Mon, 04 Feb 2008) | 2 lines Fix typo (getStrint->getString) ........ r8616 | erickson | 2008-02-04 17:14:58 -0500 (Mon, 04 Feb 2008) | 1 line added a .ids version of the work ou retrieval function. short circuiting the highest-work-org method if we hit an org with depth 0 ........ r8618 | dbs | 2008-02-04 17:33:11 -0500 (Mon, 04 Feb 2008) | 2 lines Bring more i18n love to chrome/main ........ r8619 | erickson | 2008-02-04 18:40:23 -0500 (Mon, 04 Feb 2008) | 1 line moved some of the work org and perm calls into apputils since they will be needed accross applications and they will be hit a lot ........ r8624 | dbs | 2008-02-04 22:22:51 -0500 (Mon, 04 Feb 2008) | 2 lines Bring i18n to main.js ........ r8625 | dbs | 2008-02-04 22:44:01 -0500 (Mon, 04 Feb 2008) | 2 lines Correct common.error vs. common.exception mistake, plus a bit more i18n ........ r8626 | dbs | 2008-02-04 23:30:59 -0500 (Mon, 04 Feb 2008) | 2 lines More i18n for chrome ........ r8627 | miker | 2008-02-05 08:21:10 -0500 (Tue, 05 Feb 2008) | 1 line updating models with (what should be) working display code ........ r8628 | erickson | 2008-02-05 09:59:55 -0500 (Tue, 05 Feb 2008) | 1 line added org descendant/ancestor/full_path utility methods ........ r8630 | erickson | 2008-02-05 10:05:34 -0500 (Tue, 05 Feb 2008) | 1 line fixed calls to new_editor, which will not work in apputils (circular ref) ........ r8632 | erickson | 2008-02-05 10:15:57 -0500 (Tue, 05 Feb 2008) | 1 line fixed some typos ........ r8634 | erickson | 2008-02-05 10:25:11 -0500 (Tue, 05 Feb 2008) | 1 line added a descendants option to the high work org retrieval function ........ r8636 | erickson | 2008-02-05 10:52:44 -0500 (Tue, 05 Feb 2008) | 1 line repaired descendant logic for initial high perm org ........ r8643 | phasefx | 2008-02-05 14:28:43 -0500 (Tue, 05 Feb 2008) | 1 line regression in dos.print kludge.. need to quote path for windows, and assure text is being passed and not objects ........ r8645 | miker | 2008-02-05 14:35:57 -0500 (Tue, 05 Feb 2008) | 1 line updating the exporter config to add the proxy for staff ........ r8652 | dbs | 2008-02-05 22:44:09 -0500 (Tue, 05 Feb 2008) | 2 lines i18n improvements as I go through updating status ........ r8653 | erickson | 2008-02-05 22:57:01 -0500 (Tue, 05 Feb 2008) | 9 lines getting closer on the circmatrixmatchpoint editing - using edit_inline on foreign keys to allow for up-front editing of objects which link to circmatrixmatchpoint - updated some of the __str__ methods to use gettext's unique brand of string interpolation - added some blank=False flags for non-required fields ........ r8654 | erickson | 2008-02-05 23:00:23 -0500 (Tue, 05 Feb 2008) | 1 line added example verbose name ........ r8655 | erickson | 2008-02-05 23:18:00 -0500 (Tue, 05 Feb 2008) | 1 line overriding save to force None-ness on the interval fields ........ r8656 | miker | 2008-02-06 01:24:56 -0500 (Wed, 06 Feb 2008) | 1 line use serial instead of plain INT for pkey on circ_mod_test table ........ r8661 | erickson | 2008-02-06 11:29:55 -0500 (Wed, 06 Feb 2008) | 1 line gave cstore editor the ability to check an array of permissions ........ r8663 | erickson | 2008-02-06 11:39:23 -0500 (Wed, 06 Feb 2008) | 1 line fixed variable declaration ........ r8665 | erickson | 2008-02-06 12:14:41 -0500 (Wed, 06 Feb 2008) | 1 line now using the find_highest_perm_org and get_org_tree methods provided in apputils ........ r8666 | erickson | 2008-02-06 12:33:51 -0500 (Wed, 06 Feb 2008) | 3 lines using shared build_org_tree in apputils ........ r8667 | erickson | 2008-02-06 12:53:33 -0500 (Wed, 06 Feb 2008) | 4 lines added vars to store permission error info ........ r8669 | erickson | 2008-02-06 13:03:15 -0500 (Wed, 06 Feb 2008) | 1 line logic bug in new perm checker. removed some dead code ........ r8674 | erickson | 2008-02-06 15:23:22 -0500 (Wed, 06 Feb 2008) | 1 line added explicit "return undef" ........ r8677 | miker | 2008-02-06 20:26:36 -0500 (Wed, 06 Feb 2008) | 1 line fixing readonly IDL logic ........ r8679 | dbs | 2008-02-06 23:24:31 -0500 (Wed, 06 Feb 2008) | 2 lines Bring copy_status to the world of i18n ........ r8680 | dbs | 2008-02-06 23:39:38 -0500 (Wed, 06 Feb 2008) | 2 lines Ensure ils_events.py is executable ........ r8689 | miker | 2008-02-07 14:36:16 -0500 (Thu, 07 Feb 2008) | 1 line cross-port the per-object perm scheme from the acq branch ........ r8690 | miker | 2008-02-07 14:48:17 -0500 (Thu, 07 Feb 2008) | 1 line adding index for object perms, and re-tabbing a bit ........ r8691 | miker | 2008-02-07 14:49:48 -0500 (Thu, 07 Feb 2008) | 1 line also bringing the permacrud.xsd from acq (thanks for the reminder, Dan!) ........ r8693 | dbs | 2008-02-07 16:41:17 -0500 (Thu, 07 Feb 2008) | 2 lines Typo: lenth -> length ........ r8696 | dbs | 2008-02-07 17:39:23 -0500 (Thu, 07 Feb 2008) | 2 lines Mostly finish off server/circ i18n work ........ r8699 | miker | 2008-02-08 10:38:30 -0500 (Fri, 08 Feb 2008) | 1 line adding subfield setting for idfield ........ r8700 | erickson | 2008-02-08 12:35:04 -0500 (Fri, 08 Feb 2008) | 1 line moving variable decl. until after config is loaded ........ r8701 | dbs | 2008-02-08 14:56:33 -0500 (Fri, 08 Feb 2008) | 2 lines Fix one little typo ........ r8702 | erickson | 2008-02-08 15:46:18 -0500 (Fri, 08 Feb 2008) | 4 lines calling copy_details directly to prevent any issues with the $self variable ........ r8703 | erickson | 2008-02-08 15:51:54 -0500 (Fri, 08 Feb 2008) | 1 line direct function calls to prevent any issues with $self ........ r8704 | erickson | 2008-02-08 15:57:29 -0500 (Fri, 08 Feb 2008) | 1 line direct function calls to prevent any issues with $self. removed some unused code ........ r8705 | miker | 2008-02-08 16:01:19 -0500 (Fri, 08 Feb 2008) | 1 line moving to direct call syntax instead of indirection based, since it is unsafe ........ r8707 | dbs | 2008-02-11 00:04:23 -0500 (Mon, 11 Feb 2008) | 2 lines Start tackling circ/util.js i18n ........ r8708 | miker | 2008-02-11 07:52:04 -0500 (Mon, 11 Feb 2008) | 32 lines Patch from Scott McKellar which plugs a couple of memory leaks, and applies some minor optimizations, as much for clarity as for performance. 1. In buildSELECT() we were leaking defaultselhash in the case of an early return. 2. In doFieldmapperSearch() we were leaking flesh_blob in the case of an early return. 3. In doFieldmapperSearch() I rearranged the logic a bit. First, I performed a single search of meta to get a method type and saved the result for reuse, instead of performing the identical search repeatedly. Second, I turned a series of ifs into a series of if/elses. That way we stop searching when we find a match. More importantly, the if/else structure makes it more clear to the reader that we're really just branching on method type in a case structure. This latter change requires that none of the branches changes the contents of ctx->method->userData. So far as I can tell by tracing out all the branches, this condition is satisfied, as one would intuitively expect. 4. Also in doFieldmapperSearch(): I increased the size of the growing_buffer sel_list from 16 characters to 64. Since the formatted string is at least 13 characters long, depending on the length of the class name and primary key, I suspect that 16 characters will almost never be big enough. Even 64 characters might be too short. I don't know how long the values typically are in practice. ........ r8711 | erickson | 2008-02-11 10:44:34 -0500 (Mon, 11 Feb 2008) | 1 line new lib IP ranges ........ r8713 | erickson | 2008-02-11 13:47:54 -0500 (Mon, 11 Feb 2008) | 1 line rolling back one change to oilsEventFree, which was causing a double-free. as noted in a new comment, if event->json is generated, it will contain a pointer to event->payload, which will cause event->payload to be automatically freed at ->payload free time ........ r8721 | erickson | 2008-02-11 15:37:58 -0500 (Mon, 11 Feb 2008) | 1 line augmented parse_and_raise to act as a pass-thru when the provided object is not an event ........ r8723 | miker | 2008-02-11 15:47:11 -0500 (Mon, 11 Feb 2008) | 1 line adde Parse::RecDescent stubbing for future use ........ r8725 | dbs | 2008-02-11 16:44:51 -0500 (Mon, 11 Feb 2008) | 2 lines Complete server/circ/util.js i18n (oh my aching fingers) ........ r8726 | dbs | 2008-02-11 21:41:11 -0500 (Mon, 11 Feb 2008) | 2 lines i18n for the server/main and server/OpenILS directories ........ r8731 | miker | 2008-02-12 11:13:11 -0500 (Tue, 12 Feb 2008) | 1 line arg! typo ........ r8740 | phasefx | 2008-02-12 23:00:28 -0500 (Tue, 12 Feb 2008) | 1 line removing dead code.. Hold Capture interface is a variant of Check In interface ........ r8741 | dbs | 2008-02-13 11:32:35 -0500 (Wed, 13 Feb 2008) | 2 lines Update copyright statement in catalogue footer ........ r8749 | phasefx | 2008-02-13 23:25:58 -0500 (Wed, 13 Feb 2008) | 1 line tweaked wording for Items Out interface to better match reality ........ r8752 | miker | 2008-02-14 16:39:19 -0500 (Thu, 14 Feb 2008) | 1 line in-DB circ matrix models (a couple more to go) ........ r8755 | erickson | 2008-02-14 21:41:35 -0500 (Thu, 14 Feb 2008) | 1 line defaulting selection_ou to the pickup lib instead of home_ou of the recipient ........ r8759 | miker | 2008-02-15 15:35:53 -0500 (Fri, 15 Feb 2008) | 1 line adding test result virtual class and fixing cut-n-paste error ........ r8760 | miker | 2008-02-15 15:56:40 -0500 (Fri, 15 Feb 2008) | 1 line adding hold matrix model data; adding permacrud validation hooks to main xsd ........ r8761 | phasefx | 2008-02-16 13:15:13 -0500 (Sat, 16 Feb 2008) | 1 line Holdings Maintenance interface. copy_browser.js uses circ/util.js and that needs these properties ........ r8765 | phasefx | 2008-02-18 16:33:13 -0500 (Mon, 18 Feb 2008) | 1 line This method returns 1 or 0. == appears to work whether res equals "1" or 1, is that what we want? ........ r8766 | phasefx | 2008-02-18 16:41:14 -0500 (Mon, 18 Feb 2008) | 1 line This method returns 1 or 0. == appears to work whether res equals "1" or 1, is that what we want? ........ r8767 | erickson | 2008-02-18 16:55:14 -0500 (Mon, 18 Feb 2008) | 1 line returning undef on not-found instead of 0 to prevent id=0 conflicts ........ r8771 | dbs | 2008-02-19 07:34:58 -0500 (Tue, 19 Feb 2008) | 4 lines Add explicit postgresql version dependencies Differentiate between Ubuntu Gutsy and Debian Etch postgresql versions Update SpiderMonkey version ........ r8772 | erickson | 2008-02-19 08:54:39 -0500 (Tue, 19 Feb 2008) | 6 lines Removing some dead code changed (wherever possible) references from objson to the new opensrf/osrf_json.h cstore is the last remaining legacy json (objson) client that needs updating ........ r8788 | erickson | 2008-02-19 18:38:18 -0500 (Tue, 19 Feb 2008) | 1 line using explicit namespace in addition to default namespace to account for differences in libxml2 handling ........ r8794 | dbs | 2008-02-19 23:38:35 -0500 (Tue, 19 Feb 2008) | 2 lines French MARC tooltip creator for the cataloging interface ........ r8798 | dbs | 2008-02-20 10:52:38 -0500 (Wed, 20 Feb 2008) | 3 lines Convert entity-ized hyphens back to regular hyphens for easy copy and pasting (but escape the second hyphen to avoid "invalid comment" warnings from xsltproc) ........ r8802 | dbs | 2008-02-20 12:33:33 -0500 (Wed, 20 Feb 2008) | 3 lines Update libdbi and libdbi-drivers to 0.8.3 to avoid recent compilation problems on Ubuntu Gutsy (Thanks to anarchivist for the heads-up!) ........ r8808 | miker | 2008-02-21 12:34:28 -0500 (Thu, 21 Feb 2008) | 1 line adding authoritative method varients ........ r8811 | erickson | 2008-02-21 19:09:41 -0500 (Thu, 21 Feb 2008) | 1 line added hold permit flag for new holds to prevent max-holds checks on existing holds ........ r8818 | erickson | 2008-02-22 10:20:05 -0500 (Fri, 22 Feb 2008) | 1 line added logic to migrate holds from the deleted records to the master record in title merging ........ r8820 | erickson | 2008-02-22 10:22:54 -0500 (Fri, 22 Feb 2008) | 1 line moved to die_events for in-transaction error handling ........ r8823 | dbs | 2008-02-22 13:34:56 -0500 (Fri, 22 Feb 2008) | 3 lines srfsh wants less, and it's not installed on minimal debian, so let's give it less. less is more ........ r8825 | erickson | 2008-02-22 13:51:26 -0500 (Fri, 22 Feb 2008) | 1 line added support for volume-level holds migration during volume merging ........ r8829 | dbs | 2008-02-22 19:32:45 -0500 (Fri, 22 Feb 2008) | 2 lines Enable custom specified ID to be retained in preprocess subroutine ........ r8830 | dbs | 2008-02-22 20:34:49 -0500 (Fri, 22 Feb 2008) | 2 lines And check for duplicate IDs in the main loop, just like miker asked ........ r8835 | erickson | 2008-02-26 16:04:19 -0500 (Tue, 26 Feb 2008) | 1 line changed error to warning to prevent stderr spewing ........ r8837 | erickson | 2008-02-26 16:08:02 -0500 (Tue, 26 Feb 2008) | 1 line changed the /right/ error to warning to prevent stderr spewing ........ r8840 | erickson | 2008-02-29 09:08:25 -0500 (Fri, 29 Feb 2008) | 1 line checking for xact instead of xact_id to verify session. at this point in the code, if the editor has not had a reason to create a session yet, xact_id will be undef ........ r8842 | erickson | 2008-02-29 09:16:22 -0500 (Fri, 29 Feb 2008) | 1 line added check for always_xact since xact flag may not be set in authoritative mode ........ r8844 | miker | 2008-03-01 00:43:04 -0500 (Sat, 01 Mar 2008) | 1 line adding initial sru support ........ r8845 | miker | 2008-03-01 11:13:02 -0500 (Sat, 01 Mar 2008) | 1 line moving default grammar to HEREDOC instead of DATA section ........ r8846 | miker | 2008-03-01 11:31:38 -0500 (Sat, 01 Mar 2008) | 1 line adjusting cql qualifier logic ........ r8847 | miker | 2008-03-01 11:36:54 -0500 (Sat, 01 Mar 2008) | 1 line more adjusting of the cql qualifier logic ........ r8848 | miker | 2008-03-01 11:37:27 -0500 (Sat, 01 Mar 2008) | 1 line more adjusting of the cql qualifier logic ........ r8849 | miker | 2008-03-01 11:41:30 -0500 (Sat, 01 Mar 2008) | 1 line use the correct access method for the id list ........ r8850 | miker | 2008-03-01 11:59:42 -0500 (Sat, 01 Mar 2008) | 1 line adding SRU exmple stanza ........ r8851 | miker | 2008-03-01 14:30:51 -0500 (Sat, 01 Mar 2008) | 1 line adding test for SRU perl module in settings tester support script ........ r8852 | miker | 2008-03-02 23:41:21 -0500 (Sun, 02 Mar 2008) | 1 line adding relation modifier support and making relations more strictly follow the cql guidlines ........ r8853 | miker | 2008-03-02 23:44:33 -0500 (Sun, 02 Mar 2008) | 1 line typo ........ r8854 | miker | 2008-03-03 00:01:59 -0500 (Mon, 03 Mar 2008) | 1 line fixing sort and sort_dir in the advanced query syntax ........ r8855 | miker | 2008-03-03 00:12:04 -0500 (Mon, 03 Mar 2008) | 1 line just a space ........ r8856 | miker | 2008-03-03 18:27:29 -0500 (Mon, 03 Mar 2008) | 1 line finally get rid of the diagnostics stuff ........ r8858 | miker | 2008-03-03 18:45:56 -0500 (Mon, 03 Mar 2008) | 1 line remove grouping -- causing some extranious search terms ........ r8859 | dbs | 2008-03-04 11:01:40 -0500 (Tue, 04 Mar 2008) | 2 lines Add SRU to the CPAN dependencies ........ r8860 | dbs | 2008-03-04 13:09:48 -0500 (Tue, 04 Mar 2008) | 2 lines Fix typos (thanks Mark Ellis for pointing these out) ........ r8863 | erickson | 2008-03-04 15:41:23 -0500 (Tue, 04 Mar 2008) | 1 line changed checks and Xs to yes/no to make IE happy. moved thaw date from prompt to form. added calendar widget to thaw date form. change UI terminology from freeze/thaw to activate/suspend ........ r8870 | erickson | 2008-03-05 12:57:12 -0500 (Wed, 05 Mar 2008) | 1 line added some circ rules for new circ mods video-mid and dvd-mid ........ r8871 | erickson | 2008-03-05 17:39:08 -0500 (Wed, 05 Mar 2008) | 1 line added a multidomain opensrf_core.xml example. updated the basic opensrf_core.xml to match opensrf changes (as of opensrf changeset 1253) ........ r8872 | dbs | 2008-03-05 21:38:03 -0500 (Wed, 05 Mar 2008) | 3 lines Whitespace consistency in XML files (plus modelines). Bump opensrf.xml.example version to 0.0.3. ........ r8873 | dbs | 2008-03-05 23:11:30 -0500 (Wed, 05 Mar 2008) | 2 lines Remove extraneous element; otherwise gateway is b0rk3n ........ r8874 | dbs | 2008-03-06 00:21:02 -0500 (Thu, 06 Mar 2008) | 3 lines Make the seed values work with PostgreSQL 8.1 and up... (PostgreSQL didn't grok multi-row INSERT statements until 8.2) ........ r8875 | erickson | 2008-03-06 07:38:01 -0500 (Thu, 06 Mar 2008) | 1 line added json::xs to cpan list ........ r8881 | erickson | 2008-03-06 10:41:21 -0500 (Thu, 06 Mar 2008) | 1 line added a common IDL fetching method ........ r8883 | erickson | 2008-03-06 11:26:58 -0500 (Thu, 06 Mar 2008) | 1 line added private client access to public router so error message from the private domain will be handled properly ........ r8884 | erickson | 2008-03-06 11:31:19 -0500 (Thu, 06 Mar 2008) | 1 line fetching IDL from new open-ils idl method. added a remote_connect option for clients who are not on the private network ........ r8886 | dbs | 2008-03-06 15:50:21 -0500 (Thu, 06 Mar 2008) | 2 lines circStrings, not commonStrings - thanks for finding this one, Bill Ott ........ r8887 | miker | 2008-03-06 16:03:04 -0500 (Thu, 06 Mar 2008) | 1 line v1 of staged search stored procedure(s) ........ r8888 | miker | 2008-03-06 20:46:42 -0500 (Thu, 06 Mar 2008) | 1 line adding alias qualifier to support more than one search class ........ r8889 | miker | 2008-03-06 20:59:40 -0500 (Thu, 06 Mar 2008) | 1 line cut-n-past gotcha ........ r8890 | miker | 2008-03-06 21:33:47 -0500 (Thu, 06 Mar 2008) | 1 line went too far with the aliasing ........ r8891 | miker | 2008-03-06 21:58:33 -0500 (Thu, 06 Mar 2008) | 1 line improve metarecord constituent record test ........ r8892 | miker | 2008-03-06 23:05:19 -0500 (Thu, 06 Mar 2008) | 1 line shiny new search method based on staged search stored proc ........ r8893 | miker | 2008-03-06 23:13:03 -0500 (Thu, 06 Mar 2008) | 1 line explicitly use the JSON module ........ r8894 | miker | 2008-03-07 10:19:01 -0500 (Fri, 07 Mar 2008) | 1 line add preferred language support ........ r8895 | miker | 2008-03-07 10:40:07 -0500 (Fri, 07 Mar 2008) | 1 line adding preferred lang support to the new perl, and adjusting the depth test logic ........ r8896 | miker | 2008-03-07 10:48:31 -0500 (Fri, 07 Mar 2008) | 1 line because Dan understands the importance of proper speeeling ........ r8897 | miker | 2008-03-07 11:27:16 -0500 (Fri, 07 Mar 2008) | 1 line thinkos ........ r8898 | miker | 2008-03-07 11:29:51 -0500 (Fri, 07 Mar 2008) | 1 line typos ........ r8899 | miker | 2008-03-07 11:48:28 -0500 (Fri, 07 Mar 2008) | 1 line typos ........ r8900 | miker | 2008-03-07 11:51:19 -0500 (Fri, 07 Mar 2008) | 1 line typos ........ r8901 | miker | 2008-03-07 11:54:43 -0500 (Fri, 07 Mar 2008) | 1 line remember kids, always execute your prepared queries before fetching from them ........ r8902 | miker | 2008-03-07 12:15:35 -0500 (Fri, 07 Mar 2008) | 1 line trimming the record hashes ........ r8903 | miker | 2008-03-07 12:18:31 -0500 (Fri, 07 Mar 2008) | 1 line actually trimming the record hashes ........ r8904 | miker | 2008-03-07 13:10:23 -0500 (Fri, 07 Mar 2008) | 1 line adding circ_item_list example reporter view; installing staged-search stuff ........ r8906 | phasefx | 2008-03-07 16:07:15 -0500 (Fri, 07 Mar 2008) | 1 line eliminate some redundancy before I try to i18n-ize this ........ r8909 | phasefx | 2008-03-07 16:44:59 -0500 (Fri, 07 Mar 2008) | 1 line Believe these have been replaced by ue.xhtml and family ........ r8910 | phasefx | 2008-03-07 16:50:08 -0500 (Fri, 07 Mar 2008) | 1 line The user perm editor was derived from a previous user editor so there might be some cruft here; for example, take_survey.js ........ r8911 | phasefx | 2008-03-07 17:34:51 -0500 (Fri, 07 Mar 2008) | 1 line bring a little sanity to blank tab labels ........ r8917 | phasefx | 2008-03-07 22:47:41 -0500 (Fri, 07 Mar 2008) | 1 line notify staff if no payments applied or no patron credit added, and do not print receipt. bug #609 ........ r8920 | phasefx | 2008-03-08 02:38:57 -0500 (Sat, 08 Mar 2008) | 1 line typos, and working around the fun JSON number/text casting issue ........ r8921 | phasefx | 2008-03-08 02:40:21 -0500 (Sat, 08 Mar 2008) | 1 line some i18n goodness and fixes. And an extra column for patron lists, and including the last name for staff who collected a payment ........ r8922 | phasefx | 2008-03-08 02:46:39 -0500 (Sat, 08 Mar 2008) | 1 line dead code ........ r8923 | phasefx | 2008-03-08 02:55:15 -0500 (Sat, 08 Mar 2008) | 1 line explicit number casting for JSON results ........ r8924 | phasefx | 2008-03-08 03:50:59 -0500 (Sat, 08 Mar 2008) | 1 line non-cat vs pre-cat labels. Stop throwing an error dialog if a pre-cat checkout is cancelled ........ r8925 | phasefx | 2008-03-08 04:02:30 -0500 (Sat, 08 Mar 2008) | 1 line Hrmm, global_utils.js gets copied and shared between chrome and remote xul, so not sure what's the best thing to do here for the properties files. Where do we want the redundancy? Or can we get rid of it? ........ r8926 | phasefx | 2008-03-08 04:18:41 -0500 (Sat, 08 Mar 2008) | 1 line added a testString binding to messagecat, since z3950.js is generating keys and getString throws an alert when a key is not found ........ r8927 | phasefx | 2008-03-08 18:57:15 -0500 (Sat, 08 Mar 2008) | 1 line this should be quoted ........ r8928 | phasefx | 2008-03-08 19:20:07 -0500 (Sat, 08 Mar 2008) | 1 line layout change for z39.50 client ........ r8930 | erickson | 2008-03-08 20:03:32 -0500 (Sat, 08 Mar 2008) | 1 line initial checkouts-by-circ-mods support ........ r8931 | phasefx | 2008-03-08 20:12:03 -0500 (Sat, 08 Mar 2008) | 1 line working around Number vs String from JSON again.. might be a better way to handle this ........ r8933 | erickson | 2008-03-08 20:22:02 -0500 (Sat, 08 Mar 2008) | 1 line using json true instead of 1 ........ r8936 | miker | 2008-03-09 13:24:11 -0400 (Sun, 09 Mar 2008) | 1 line only search where search_field is true ........ r8942 | miker | 2008-03-09 20:45:35 -0400 (Sun, 09 Mar 2008) | 1 line NACO normalization is handy to have around ........ r8943 | phasefx | 2008-03-09 21:03:32 -0400 (Sun, 09 Mar 2008) | 1 line we can't reliably use messagecat with scripts that run before the onload event ........ r8944 | miker | 2008-03-09 21:06:23 -0400 (Sun, 09 Mar 2008) | 1 line some normalization functions for use in in-DB ingest, when it happens ........ r8948 | erickson | 2008-03-09 22:35:40 -0400 (Sun, 09 Mar 2008) | 1 line added initial (basic) staged search support ........ r8949 | phasefx | 2008-03-09 22:49:04 -0400 (Sun, 09 Mar 2008) | 18 lines Switch to .authoritative version of some methods We're getting a 404 with these: open-ils.search.callnumber.retrieve.authoritative open-ils.search.asset.copy.fleshed.batch.retrieve.authoritative open-ils.search.biblio.record.copy_count.staff.authoritative open-ils.circ.copy_location.retrieve.authoritative open-ils.circ.hold.details.retrieve.authoritative open-ils.circ.holds.id_list.retrieve.authoritative open-ils.circ.open_non_cataloged_circulation.user.authoritative open-ils.actor.usergroup.members.retrieve.authoritative open-ils.circ.money.billing.retrieve.all.authoritative open-ils.circ.money.billable_xact_summary.retrieve.authoritative open-ils.circ.money.payment.retrieve.all.authoritative open-ils.search.biblio.record.mods_slim.retrieve.authoritative ........ r8950 | phasefx | 2008-03-09 22:55:21 -0400 (Sun, 09 Mar 2008) | 1 line disable .authoritative for these for the time being ........ r8951 | miker | 2008-03-10 00:04:44 -0400 (Mon, 10 Mar 2008) | 1 line making OpenILS::Application the base app so that authoritative works ........ r8952 | miker | 2008-03-10 00:25:35 -0400 (Mon, 10 Mar 2008) | 18 lines Patch from Scott McKellar: This patch is mostly a performance tweak. 1. I replaced all instances of "jsonParseString( "[]" )" with "jsonNewObjectType(JSON_ARRAY)", which produces the same result with less work. 2. Likewise I replaced all instances of "jsonParseString( "{}" )" with "jsonNewObjectType(JSON_HASH)". 3. In two spots I eliminated a memset() applied to _tmp_dt, a variable of type time_t. 4. In several calls to strftime() I used the sizeof operator to replace hard-coded buffer lengths. ........ r8953 | miker | 2008-03-10 00:30:59 -0400 (Mon, 10 Mar 2008) | 15 lines Patch from Scott McKellar: 1. The functions _rest_xml_output and _escape_xml are now static, and a couple of their parameters are now const. 2. In json_string_to_xml() we were leaking res_xml in the case of an early return. I moved the early return out of the way. 3. In _rest_xml_output() we were leaking tag in the case of an early return. I plugged that leak. 4. In a couple of spots I replaced buffer_data() with buffer_release(), and eliminated two intermediate variables that are no longer needed. ........ r8954 | miker | 2008-03-10 00:34:46 -0400 (Mon, 10 Mar 2008) | 9 lines Patch from Scott McKellar: In oilsAuthGetTimeout() we make three calls to osrf_settings_host_value_object(), which allocates a jsonObject. However we were passing the return values directly to another function, without capturing the pointers for freeing. As a result we were leaking the jsonObjects thus allocated. ........ r8955 | miker | 2008-03-10 08:22:53 -0400 (Mon, 10 Mar 2008) | 1 line typo and un-PINES-ifying language patch from Karen Collier ........ r8956 | phasefx | 2008-03-10 11:19:57 -0400 (Mon, 10 Mar 2008) | 1 line Flip back to .authoritative version. Thanks Mike! ........ r8959 | miker | 2008-03-11 08:26:58 -0400 (Tue, 11 Mar 2008) | 1 line initial permacrud application ........ r8960 | miker | 2008-03-11 08:39:02 -0400 (Tue, 11 Mar 2008) | 1 line permacrud for config.metabib_field ........ r8961 | miker | 2008-03-11 08:52:22 -0400 (Tue, 11 Mar 2008) | 1 line all_perms flag and ou-less checking ........ r8962 | miker | 2008-03-11 08:53:27 -0400 (Tue, 11 Mar 2008) | 1 line xsd update for all_perms flag ........ r8963 | miker | 2008-03-11 08:54:23 -0400 (Tue, 11 Mar 2008) | 1 line correction to transit perms ........ r8964 | erickson | 2008-03-11 11:15:25 -0400 (Tue, 11 Mar 2008) | 1 line ported object-specific perm checks from acq-experiment branch to trunk, since it is globally applicable ........ r8966 | erickson | 2008-03-11 11:46:47 -0400 (Tue, 11 Mar 2008) | 1 line added ability to pass an object ID and hint to allowed() for object perm checking ........ r8967 | miker | 2008-03-11 12:14:17 -0400 (Tue, 11 Mar 2008) | 1 line search method ........ r8968 | miker | 2008-03-11 12:26:45 -0400 (Tue, 11 Mar 2008) | 1 line typo; settings-tester update ........ r8969 | miker | 2008-03-11 12:36:32 -0400 (Tue, 11 Mar 2008) | 1 line use the correct context node, duh ........ r8970 | miker | 2008-03-11 12:49:55 -0400 (Tue, 11 Mar 2008) | 1 line generate methods after loading the IDL ........ r8971 | erickson | 2008-03-11 13:21:35 -0400 (Tue, 11 Mar 2008) | 1 line added the permacrud namespace, some log lines for debugging ........ r8972 | miker | 2008-03-11 13:27:41 -0400 (Tue, 11 Mar 2008) | 1 line only test type if we have an object ........ r8973 | miker | 2008-03-11 13:30:34 -0400 (Tue, 11 Mar 2008) | 1 line getAttribute is for elements, not xpath contexts ........ r8974 | miker | 2008-03-11 14:34:54 -0400 (Tue, 11 Mar 2008) | 1 line permacrud search works! ........ r8975 | miker | 2008-03-11 14:52:51 -0400 (Tue, 11 Mar 2008) | 1 line split on pipes, not between every character; also, commit after an update ........ r8976 | miker | 2008-03-11 14:55:37 -0400 (Tue, 11 Mar 2008) | 1 line and return the result of the cstore call ........ r8977 | miker | 2008-03-11 15:32:53 -0400 (Tue, 11 Mar 2008) | 1 line making based orgs work ........ r8985 | miker | 2008-03-11 21:17:32 -0400 (Tue, 11 Mar 2008) | 1 line adding real stylesheet data for mods 2, 3.0 and 3.2; allowing namespace URIs to be non-unique, since MODS reuses the same one ........ r8986 | miker | 2008-03-12 08:44:43 -0400 (Wed, 12 Mar 2008) | 1 line xml_transform class ........ r8990 | erickson | 2008-03-12 11:39:20 -0400 (Wed, 12 Mar 2008) | 1 line changed wording on place-hold-for-me button, moved it farther over to the right. disbled when any text is in the barcode field ........ r8991 | erickson | 2008-03-12 11:40:11 -0400 (Wed, 12 Mar 2008) | 1 line updated low-hit spellcheck and authority check to honor multi-class search calls ........ r8993 | erickson | 2008-03-12 12:04:21 -0400 (Wed, 12 Mar 2008) | 1 line gave oils_requestor the ability to find the IDL from the settings server based on hostname if none is specified in the path. passing hostname from the offline-blocked list generator ........ r8995 | erickson | 2008-03-12 15:16:50 -0400 (Wed, 12 Mar 2008) | 1 line repaired bug caused by parsing an empty date. added some style to the thaw-date form ........ r8999 | miker | 2008-03-13 01:20:23 -0400 (Thu, 13 Mar 2008) | 1 line lots of permacrud definition ... lots to go ........ r9001 | erickson | 2008-03-13 11:57:51 -0400 (Thu, 13 Mar 2008) | 1 line added selection_ou and depth enforcement to hold possibility check for metarecord, title, and volume holds ........ r9002 | miker | 2008-03-13 12:38:43 -0400 (Thu, 13 Mar 2008) | 1 line making old_best tests more explicit ........ r9004 | erickson | 2008-03-13 14:32:10 -0400 (Thu, 13 Mar 2008) | 1 line replaced old-style checkperm call with allowed() ........ r9007 | erickson | 2008-03-13 21:49:04 -0400 (Thu, 13 Mar 2008) | 1 line added basic caching layer for staged search. still need to do the number juggling to determine real limit/offset values ........ r9008 | miker | 2008-03-14 09:00:32 -0400 (Fri, 14 Mar 2008) | 1 line adding google books view to result pages ........ r9009 | miker | 2008-03-14 09:28:43 -0400 (Fri, 14 Mar 2008) | 1 line thinkos ... it seems to be working now ........ r9010 | miker | 2008-03-14 09:34:32 -0400 (Fri, 14 Mar 2008) | 1 line allow all books in google books to show up, not just previewable ones ........ r9011 | miker | 2008-03-14 09:35:48 -0400 (Fri, 14 Mar 2008) | 1 line correcting comment ........ r9012 | erickson | 2008-03-14 11:14:41 -0400 (Fri, 14 Mar 2008) | 1 line staged search caching and paging ........ r9013 | erickson | 2008-03-14 11:48:57 -0400 (Fri, 14 Mar 2008) | 1 line fixed assumption that available=0 implies no hits, some cleanup ........ r9014 | miker | 2008-03-14 12:47:52 -0400 (Fri, 14 Mar 2008) | 1 line protect against 0 checked ........ r9015 | phasefx | 2008-03-14 13:37:49 -0400 (Fri, 14 Mar 2008) | 1 line this is refactored code, and the environment where it came from had org ids, but I was passing org objects here by mistake in it's new location, so.. flattening the orgs ........ r9017 | erickson | 2008-03-14 15:03:06 -0400 (Fri, 14 Mar 2008) | 1 line stop looking when we have checked all of the possible hits for visibility. no longer calculating the average estimated hit count. using the initial estimated hit count ........ r9018 | miker | 2008-03-14 15:12:38 -0400 (Fri, 14 Mar 2008) | 1 line using opac event to fetch the google data once ........ r9019 | erickson | 2008-03-14 15:22:08 -0400 (Fri, 14 Mar 2008) | 1 line removed debugging alert ........ r9021 | miker | 2008-03-14 16:30:58 -0400 (Fri, 14 Mar 2008) | 1 line only using active adjustments ........ r9022 | miker | 2008-03-14 16:31:23 -0400 (Fri, 14 Mar 2008) | 1 line port the slimpac/opensearch to staged search via open-ils.search.biblio.multiclass.query ........ r9023 | erickson | 2008-03-14 16:32:45 -0400 (Fri, 14 Mar 2008) | 1 line output is now backwards compatibable with non-staged api call. added a config option for turning on staged search ........ r9024 | miker | 2008-03-14 16:59:28 -0400 (Fri, 14 Mar 2008) | 1 line returning the resulting $_ from map ........ r9025 | erickson | 2008-03-14 17:01:17 -0400 (Fri, 14 Mar 2008) | 1 line hiding "end" link with staged search, changed some terminology ........ r9026 | phasefx | 2008-03-14 17:20:10 -0400 (Fri, 14 Mar 2008) | 1 line json number vs string again ........ r9028 | phasefx | 2008-03-14 17:39:56 -0400 (Fri, 14 Mar 2008) | 1 line expose hold freeze/thaw options for staff ........ r9029 | phasefx | 2008-03-14 17:43:17 -0400 (Fri, 14 Mar 2008) | 1 line brain damage. These are hold focus/range options.. let's keep them hidden until we can tie it to a config option or somesuch ........ r9030 | miker | 2008-03-14 18:08:14 -0400 (Fri, 14 Mar 2008) | 1 line removing some dead code ........ r9031 | phasefx | 2008-03-14 19:24:52 -0400 (Fri, 14 Mar 2008) | 1 line speed up the copy bucket interface a little bit ........ r9032 | miker | 2008-03-14 21:29:21 -0400 (Fri, 14 Mar 2008) | 1 line fixing the slimpac ........ r9033 | miker | 2008-03-14 23:33:56 -0400 (Fri, 14 Mar 2008) | 1 line allow url-based sort/dir to work ........ r9034 | miker | 2008-03-14 23:50:41 -0400 (Fri, 14 Mar 2008) | 1 line minor cleanup; allow numeric OUs ........ r9035 | miker | 2008-03-14 23:55:18 -0400 (Fri, 14 Mar 2008) | 1 line removing relevance span population from metabib search ........ r9036 | miker | 2008-03-14 23:59:33 -0400 (Fri, 14 Mar 2008) | 1 line much more premacrud ........ r9037 | phasefx | 2008-03-15 00:39:49 -0400 (Sat, 15 Mar 2008) | 1 line this was left in from debugging ........ r9038 | phasefx | 2008-03-15 01:02:31 -0400 (Sat, 15 Mar 2008) | 1 line silence some of the debug chatter in the console ........ r9039 | phasefx | 2008-03-15 01:46:21 -0400 (Sat, 15 Mar 2008) | 1 line Sometimes the main window will lose focus and get lowered after clipboard actions... this will make sure the window stays raised (despite the action being called .focus), but we still need to figure out focus ........ r9040 | phasefx | 2008-03-15 01:46:51 -0400 (Sat, 15 Mar 2008) | 1 line tweaks to file picker ........ r9043 | phasefx | 2008-03-15 01:52:00 -0400 (Sat, 15 Mar 2008) | 1 line support empty params for these utility functions ........ r9045 | phasefx | 2008-03-15 02:52:12 -0400 (Sat, 15 Mar 2008) | 1 line more refactoring.. putting all the list CSV functions into list.js ........ r9046 | phasefx | 2008-03-15 02:53:22 -0400 (Sat, 15 Mar 2008) | 1 line interface tweaks: CSV to clipboard, printer, or file ........ r9047 | miker | 2008-03-15 12:45:21 -0400 (Sat, 15 Mar 2008) | 1 line cache the sru query results in the ML ........ r9048 | miker | 2008-03-16 00:46:29 -0400 (Sun, 16 Mar 2008) | 1 line improving relation mapping; adding automatically created explain doc ........ r9049 | phasefx | 2008-03-16 03:39:04 -0400 (Sun, 16 Mar 2008) | 1 line layout and source tweaks ........ r9050 | phasefx | 2008-03-16 04:43:28 -0400 (Sun, 16 Mar 2008) | 1 line new arrow images ........ r9051 | phasefx | 2008-03-16 04:51:04 -0400 (Sun, 16 Mar 2008) | 1 line rethinking record bucket interface ........ r9052 | phasefx | 2008-03-16 04:55:04 -0400 (Sun, 16 Mar 2008) | 1 line dedup Show All in Catalog ........ r9053 | phasefx | 2008-03-16 04:57:28 -0400 (Sun, 16 Mar 2008) | 1 line show last name of bucket owner ........ r9054 | phasefx | 2008-03-16 05:17:21 -0400 (Sun, 16 Mar 2008) | 1 line speed up record bucket display with async flesh on demand ........ r9055 | phasefx | 2008-03-16 05:30:57 -0400 (Sun, 16 Mar 2008) | 1 line bucket item count ........ r9056 | miker | 2008-03-16 13:58:53 -0400 (Sun, 16 Mar 2008) | 1 line Memory leak plugging from Scott McKellar ........ r9057 | phasefx | 2008-03-16 15:16:04 -0400 (Sun, 16 Mar 2008) | 1 line simple search for record bucket interface.. uses an OPAC method that can handle author: title: etc in the search string. Need to move it to staged search ........ r9058 | phasefx | 2008-03-16 16:52:06 -0400 (Sun, 16 Mar 2008) | 1 line Some focus/label tweaks. And a help button point to an html file. Dan and I need to revisit this and come up with a best practice and infrastructure ........ r9059 | dbs | 2008-03-16 21:16:09 -0400 (Sun, 16 Mar 2008) | 2 lines Clean up illegal trailing commas in object initializers ........ r9061 | dbs | 2008-03-16 22:31:52 -0400 (Sun, 16 Mar 2008) | 4 lines Use a table to map search keys to their definitions Add some semantic markup (kbd, yeah) Use XHTML because we're hep cats ........ r9065 | miker | 2008-03-18 00:02:21 -0400 (Tue, 18 Mar 2008) | 1 line actually test for transcendance, not just for a source ........ r9067 | erickson | 2008-03-18 09:46:17 -0400 (Tue, 18 Mar 2008) | 1 line added search filters and sorting to metarecord results page ........ r9069 | erickson | 2008-03-18 10:25:49 -0400 (Tue, 18 Mar 2008) | 1 line added config option for defining the downloaded record format for each Z source ........ r9071 | erickson | 2008-03-18 12:13:55 -0400 (Tue, 18 Mar 2008) | 1 line implemented hard hold ceilings and basis for soft ceilings ........ r9073 | erickson | 2008-03-18 12:35:05 -0400 (Tue, 18 Mar 2008) | 1 line implemented soft hold ceilings ........ r9076 | erickson | 2008-03-18 22:27:13 -0400 (Tue, 18 Mar 2008) | 1 line ported user prefs call to cstoreEditor, with finer grained perm checking ........ r9077 | erickson | 2008-03-18 22:27:16 -0400 (Tue, 18 Mar 2008) | 1 line fixed typo and repaired boolean test (to be safe) in opac init to enforce user depth preference setting ........ r9079 | erickson | 2008-03-19 09:46:25 -0400 (Wed, 19 Mar 2008) | 1 line ported org-settings update code to cstoreEditor ........ r9081 | erickson | 2008-03-19 09:53:19 -0400 (Wed, 19 Mar 2008) | 1 line coercing setting values that are pure space to nulls ........ r9082 | phasefx | 2008-03-19 11:34:49 -0400 (Wed, 19 Mar 2008) | 1 line make the authority pop-ups more readable ........ r9085 | erickson | 2008-03-19 11:51:51 -0400 (Wed, 19 Mar 2008) | 1 line changed terminology (ceiling to boundary) for clarity. updated logic to try soft boundary first if it is greater then hard boundary, up to the hard boundary ........ r9086 | miker | 2008-03-19 12:31:02 -0400 (Wed, 19 Mar 2008) | 1 line add the ability to turn off forced-https ........ r9088 | erickson | 2008-03-19 15:28:14 -0400 (Wed, 19 Mar 2008) | 1 line moved PREFIX def to top ........ r9092 | miker | 2008-03-19 21:40:07 -0400 (Wed, 19 Mar 2008) | 1 line fixing the freshmeat feed link; moving to rss v2 from atom for feeds, to make feed readers happier ........ r9094 | miker | 2008-03-19 22:50:12 -0400 (Wed, 19 Mar 2008) | 1 line adding extra staff checks for record visibility ........ r9099 | erickson | 2008-03-20 08:09:52 -0400 (Thu, 20 Mar 2008) | 1 line removed old comment. removed unnucessary grep call ........ r9102 | erickson | 2008-03-20 09:46:47 -0400 (Thu, 20 Mar 2008) | 1 line added some timing logs ........ r9104 | miker | 2008-03-21 00:06:34 -0400 (Fri, 21 Mar 2008) | 1 line remove fleshing capabilities inside permacrud -- may reimplement in a cruddy fashsion later ........ r9108 | erickson | 2008-03-21 15:24:22 -0400 (Fri, 21 Mar 2008) | 1 line protecting against undefined copy array ........ r9111 | dbs | 2008-03-23 21:49:14 -0400 (Sun, 23 Mar 2008) | 2 lines Localization for offline transaction management ........ r9112 | dbs | 2008-03-23 21:57:09 -0400 (Sun, 23 Mar 2008) | 2 lines Missed a few strings in offline transaction management ........ r9113 | miker | 2008-03-23 22:38:06 -0400 (Sun, 23 Mar 2008) | 1 line protect against null params to transforms in SQL ........ r9114 | miker | 2008-03-23 23:24:02 -0400 (Sun, 23 Mar 2008) | 1 line move the default proxy html into a heredoc ........ r9115 | miker | 2008-03-23 23:25:57 -0400 (Sun, 23 Mar 2008) | 1 line arg! typo ........ r9116 | dbs | 2008-03-23 23:33:30 -0400 (Sun, 23 Mar 2008) | 2 lines Move some more hardcoded strings to i18n. ........ r9119 | miker | 2008-03-24 00:42:43 -0400 (Mon, 24 Mar 2008) | 1 line removing unused (and broken) code ........ r9121 | dbs | 2008-03-24 10:33:48 -0400 (Mon, 24 Mar 2008) | 3 lines Tooltips now contain field names, thanks to miker's fancy XSL Now we can expose these in the cataloging interface ........ r9122 | dbs | 2008-03-24 11:41:09 -0400 (Mon, 24 Mar 2008) | 3 lines Generate fields just like miker's fancy XSL for LoC MARC Normalize linefeeds to be consistent with marcedit-tooltips.xml ........ r9123 | miker | 2008-03-24 13:47:25 -0400 (Mon, 24 Mar 2008) | 1 line add timezone info to times -- only used currently for hours of operation ........ r9124 | miker | 2008-03-24 13:59:52 -0400 (Mon, 24 Mar 2008) | 1 line add timezone info to times -- only used currently for hours of operation ........ r9125 | miker | 2008-03-24 14:24:52 -0400 (Mon, 24 Mar 2008) | 1 line use gmtime for time-only calc ........ r9127 | erickson | 2008-03-24 15:58:02 -0400 (Mon, 24 Mar 2008) | 1 line trimming null entries from end of results array ........ r9129 | dbs | 2008-03-24 16:38:59 -0400 (Mon, 24 Mar 2008) | 4 lines Make MARC editor tooltips localized resources Add fr-CA version of MARC editor tooltips (thanks to Library and Archives Canada for the permission to use their translation) Need to fix the dang locale preference lookup; we're just going with the default for now ........ r9130 | dbs | 2008-03-24 20:05:26 -0400 (Mon, 24 Mar 2008) | 3 lines Hmm. xulplanet.com appears to have better xul docs than mozilla.org Basic locale preferences for MARC editor tooltips are now working ........ r9131 | dbs | 2008-03-24 20:57:25 -0400 (Mon, 24 Mar 2008) | 2 lines i18n for bib_brief.xul ........ r9132 | dbs | 2008-03-24 21:18:41 -0400 (Mon, 24 Mar 2008) | 2 lines Duplicate IDs do not work for message catalogs ........ r9133 | dbs | 2008-03-24 23:22:42 -0400 (Mon, 24 Mar 2008) | 3 lines Start bringing i18n to the copy browser. Repair a typo in bib_brief.xul ........ r9137 | dbs | 2008-03-25 23:28:32 -0400 (Tue, 25 Mar 2008) | 2 lines Knock off a few more strings for i18n ........ r9140 | dbs | 2008-03-26 21:35:47 -0400 (Wed, 26 Mar 2008) | 2 lines Default to staged search (and avoid complaints in the logs about no value for use_staged_search) ........ r9141 | miker | 2008-03-26 22:29:20 -0400 (Wed, 26 Mar 2008) | 1 line adding org types to permacrud ........ r9142 | miker | 2008-03-26 23:52:16 -0400 (Wed, 26 Mar 2008) | 5 lines The advanced query syntax parser here was cribbed from the original implemenation inside the OpenSearch server. mod_perl, due to being too clever by half, required a call to decode_utf8 to shove raw octets into the correct shape. Becuase the data coming to this implementation comes from opensrf, which is unicode end-to-end via JSON, it's somebody else's job to make sure the characters are properly encoded, and once they get to us they're already proper UTF-8 character strings. Thus, no need for (and things broken by) the call to decode_utf8. Why is that explanation so long? So that we don't do it again ... :) ........ r9144 | miker | 2008-03-27 00:17:10 -0400 (Thu, 27 Mar 2008) | 1 line escape regexp-special characters ........ r9145 | miker | 2008-03-27 00:33:59 -0400 (Thu, 27 Mar 2008) | 1 line use POSIX regexp operator instead of ILIKE ........ r9146 | miker | 2008-03-27 00:36:16 -0400 (Thu, 27 Mar 2008) | 1 line comment out the debuging NOTICE ........ r9148 | miker | 2008-03-27 01:25:29 -0400 (Thu, 27 Mar 2008) | 1 line adding org_unit retrieve checks ........ r9149 | miker | 2008-03-27 01:26:22 -0400 (Thu, 27 Mar 2008) | 1 line procting permacrud search from failed retrieve ........ r9150 | miker | 2008-03-27 02:15:43 -0400 (Thu, 27 Mar 2008) | 1 line adding "at least one, please!" check to org types ........ r9152 | miker | 2008-03-27 21:01:40 -0400 (Thu, 27 Mar 2008) | 1 line adding permission group tree to permacrud ........ r9159 | miker | 2008-03-29 00:21:56 -0400 (Sat, 29 Mar 2008) | 1 line add cross-checks for perm creation; add perm assignment checks ........ r9165 | erickson | 2008-03-30 20:55:27 -0400 (Sun, 30 Mar 2008) | 1 line added new ip range ........ r9166 | erickson | 2008-03-31 16:51:39 -0400 (Mon, 31 Mar 2008) | 1 line added new freezethaw dep ........ r9175 | erickson | 2008-04-01 10:25:05 -0400 (Tue, 01 Apr 2008) | 1 line added style to indicate a hold thaw date is either invalid or <= today ........ r9177 | erickson | 2008-04-01 11:29:45 -0400 (Tue, 01 Apr 2008) | 1 line no longer allowing hold updates when date is invalid or <= today ........ r9180 | erickson | 2008-04-01 12:24:16 -0400 (Tue, 01 Apr 2008) | 1 line little more fine tuning of the thaw date handling; fixed post-create edit bug for thaw dates ........ r9186 | dbs | 2008-04-01 21:19:36 -0400 (Tue, 01 Apr 2008) | 2 lines Add non-default refresh of org_tree proximity, per 2008/02/28 discussion on open-ils-dev ........ r9187 | dbs | 2008-04-01 21:24:06 -0400 (Tue, 01 Apr 2008) | 2 lines We need to install the new org_tree proximity script if we're going to use it ........ r9191 | phasefx | 2008-04-02 13:04:36 -0400 (Wed, 02 Apr 2008) | 1 line Change some of the wording for hold freeze/thaw. Need to rethink fancy_prompt in light of i18n (maybe do away with it), so there are some lingering uses of freeze/thaw in the staff client ........ r9192 | miker | 2008-04-02 13:07:25 -0400 (Wed, 02 Apr 2008) | 1 line get the text value, then transform ........ r9193 | phasefx | 2008-04-02 13:35:56 -0400 (Wed, 02 Apr 2008) | 1 line Fix the Macros button for all template types. Remove a + + from some string concatenation that was putting NaN in the display ........ r9195 | phasefx | 2008-04-02 14:17:02 -0400 (Wed, 02 Apr 2008) | 1 line typo in properties name ........ r9196 | phasefx | 2008-04-02 14:26:56 -0400 (Wed, 02 Apr 2008) | 1 line some of the column definitions in the copy browser use circStrings ........ r9198 | erickson | 2008-04-02 15:52:09 -0400 (Wed, 02 Apr 2008) | 1 line using boolean test wrapper function ........ r9200 | erickson | 2008-04-02 16:02:31 -0400 (Wed, 02 Apr 2008) | 1 line added logic to run the hold targeter if a hold is un-frozen by the user ........ r9203 | dbs | 2008-04-02 22:22:15 -0400 (Wed, 02 Apr 2008) | 2 lines First cut at automated checks for problems with i18n string properties ........ r9204 | dbs | 2008-04-02 22:27:41 -0400 (Wed, 02 Apr 2008) | 2 lines Correct problems found by check_properties.py ........ r9206 | phasefx | 2008-04-03 01:06:57 -0400 (Thu, 03 Apr 2008) | 1 line fill in the missing entities between these two lang.dtd files. Will the POTS stuff do this for us Dan? ........ r9207 | dbs | 2008-04-03 10:10:22 -0400 (Thu, 03 Apr 2008) | 2 lines C&P error in internal instructions; might as well make'em right ........ r9208 | phasefx | 2008-04-03 12:57:43 -0400 (Thu, 03 Apr 2008) | 1 line some entities for hold interfaces ........ r9209 | phasefx | 2008-04-03 13:41:49 -0400 (Thu, 03 Apr 2008) | 1 line some i18n, fewer steps for freezing/thawing holds, and disabling editing of hold range/focus through css. Needs more testing ........ r9210 | erickson | 2008-04-03 14:01:36 -0400 (Thu, 03 Apr 2008) | 1 line merge error, forgot to pass orig_hold ........ r9212 | miker | 2008-04-03 20:43:23 -0400 (Thu, 03 Apr 2008) | 1 line use a safer test for bool grantable flag ........ r9213 | miker | 2008-04-03 22:11:04 -0400 (Thu, 03 Apr 2008) | 1 line adding backend support for system-supplied "search groups" -- user search groups to come later ........ r9214 | miker | 2008-04-03 22:23:13 -0400 (Thu, 03 Apr 2008) | 1 line make the row unique ........ r9215 | dbs | 2008-04-03 22:51:54 -0400 (Thu, 03 Apr 2008) | 2 lines Trivial - ensure "Done" gets placed on its own line. ........ r9216 | phasefx | 2008-04-03 23:41:02 -0400 (Thu, 03 Apr 2008) | 1 line prevent duplicate rows in patron holds interface ........ r9217 | miker | 2008-04-03 23:56:23 -0400 (Thu, 03 Apr 2008) | 1 line adding bib_level filter support ........ r9219 | miker | 2008-04-04 00:36:51 -0400 (Fri, 04 Apr 2008) | 1 line adding lasso support to copy count calls ........ r9220 | miker | 2008-04-04 00:44:47 -0400 (Fri, 04 Apr 2008) | 1 line adding base-line copy counting for lasso groups ........ r9221 | phasefx | 2008-04-04 00:57:59 -0400 (Fri, 04 Apr 2008) | 1 line more i18n, prevent hold activation date from being set to Today, and auto-suspend holds when activation date is set ........ r9222 | miker | 2008-04-04 07:58:26 -0400 (Fri, 04 Apr 2008) | 1 line adding lasso data support for use by the OPAC ........ r9223 | miker | 2008-04-04 08:06:52 -0400 (Fri, 04 Apr 2008) | 1 line use the fieldmapper objects ... ........ r9225 | erickson | 2008-04-04 09:17:13 -0400 (Fri, 04 Apr 2008) | 1 line patch from Brandon to avoid showing opac-invisible stat cats in public display: http://list.georgialibraries.org/pipermail/open-ils-dev/2008-March/002731.html ........ r9226 | phasefx | 2008-04-04 10:48:17 -0400 (Fri, 04 Apr 2008) | 1 line Forward-port a disallow for editing pickup lib for intransit holds. This may eventually need to become configurable based on policy, in which case we will need to handle the transits involved ........ r9228 | miker | 2008-04-04 11:07:36 -0400 (Fri, 04 Apr 2008) | 1 line adding bib_level mapping table ........ r9229 | miker | 2008-04-04 11:30:43 -0400 (Fri, 04 Apr 2008) | 1 line adding bib_level filter to the advanced search ........ r9232 | miker | 2008-04-04 14:53:01 -0400 (Fri, 04 Apr 2008) | 1 line begin exposing lassos in the OPAC ........ r9233 | miker | 2008-04-04 16:32:28 -0400 (Fri, 04 Apr 2008) | 1 line trying to move towards lassos ........ r9234 | miker | 2008-04-04 17:18:09 -0400 (Fri, 04 Apr 2008) | 1 line copy counts come back, but must be interpreted differently ........ r9235 | miker | 2008-04-04 17:18:48 -0400 (Fri, 04 Apr 2008) | 1 line copy counts come back, but must be interpreted differently ........ r9236 | miker | 2008-04-05 07:44:42 -0400 (Sat, 05 Apr 2008) | 1 line display the lasso name when appropriate ........ r9241 | miker | 2008-04-06 22:28:05 -0400 (Sun, 06 Apr 2008) | 1 line display consolidated copy counts on the result page, and hide the ou_type header bar ........ r9243 | miker | 2008-04-07 10:25:02 -0400 (Mon, 07 Apr 2008) | 1 line adding "first5" function to trim zip codes ........ r9245 | miker | 2008-04-07 10:57:20 -0400 (Mon, 07 Apr 2008) | 1 line add "first word" support -- use for callnumber prefix ........ r9247 | phasefx | 2008-04-07 12:27:53 -0400 (Mon, 07 Apr 2008) | 1 line prevent the viewing of foreign non-cats from polluting local non-cat dropdown lists ........ r9248 | miker | 2008-04-07 12:31:39 -0400 (Mon, 07 Apr 2008) | 1 line set some sequences after insertion ........ r9253 | erickson | 2008-04-07 13:27:16 -0400 (Mon, 07 Apr 2008) | 1 line repaired close tag ........ r9255 | erickson | 2008-04-07 13:52:23 -0400 (Mon, 07 Apr 2008) | 1 line returning home org in AQ field for patron info requests. Thanks for the SIP support, David ........ r9256 | miker | 2008-04-07 13:52:28 -0400 (Mon, 07 Apr 2008) | 1 line adding cross-check perms to "ccs" ........ r9259 | dbs | 2008-04-07 20:42:32 -0400 (Mon, 07 Apr 2008) | 2 lines When you hit an error, you want to see the entire error message ........ r9260 | dbs | 2008-04-07 21:11:35 -0400 (Mon, 07 Apr 2008) | 2 lines Back on that i18n horse ........ r9261 | dbs | 2008-04-07 22:38:32 -0400 (Mon, 07 Apr 2008) | 2 lines Bring copy_browser.xul to the i18n party ........ r9266 | dbs | 2008-04-08 11:06:30 -0400 (Tue, 08 Apr 2008) | 2 lines i18n for copy_buckets.js and copy_buckets.xul ........ r9269 | dbs | 2008-04-08 12:46:43 -0400 (Tue, 08 Apr 2008) | 2 lines Missing formatting flag for a common error message. ........ r9270 | dbs | 2008-04-08 12:52:54 -0400 (Tue, 08 Apr 2008) | 2 lines Finish the copy_buckets i18n. ........ r9272 | dbs | 2008-04-08 17:18:36 -0400 (Tue, 08 Apr 2008) | 2 lines 25% of the way through i18n of copy_editor.js ........ r9276 | dbs | 2008-04-08 21:29:35 -0400 (Tue, 08 Apr 2008) | 2 lines Finish i18n for the easy part of copy_editor.js ........ r9279 | dbs | 2008-04-08 22:33:09 -0400 (Tue, 08 Apr 2008) | 2 lines i18n for the strings in the copy_editor.xul ........ r9288 | phasefx | 2008-04-09 22:17:26 -0400 (Wed, 09 Apr 2008) | 1 line protect against empty list items ........ r9289 | dbs | 2008-04-09 22:18:34 -0400 (Wed, 09 Apr 2008) | 2 lines i18n for copy_notes.xul ........ r9291 | dbs | 2008-04-10 09:12:17 -0400 (Thu, 10 Apr 2008) | 2 lines Probably need to define our message catalogs ........ r9292 | dbs | 2008-04-10 09:12:49 -0400 (Thu, 10 Apr 2008) | 2 lines i18n for copy_summary ........ r9293 | dbs | 2008-04-10 09:59:09 -0400 (Thu, 10 Apr 2008) | 2 lines Initial stab at marcedit i18n ........ r9294 | dbs | 2008-04-10 10:42:17 -0400 (Thu, 10 Apr 2008) | 2 lines Make our i18n messagecatalog strings work (need global.css for binding xbl) ........ r9295 | dbs | 2008-04-10 12:11:11 -0400 (Thu, 10 Apr 2008) | 2 lines Syntax errors in copy_editor.js ........ r9300 | miker | 2008-04-10 21:15:37 -0400 (Thu, 10 Apr 2008) | 1 line adding permacrud app to the example config ........ r9304 | miker | 2008-04-10 21:59:08 -0400 (Thu, 10 Apr 2008) | 1 line copyright header ........ r9309 | miker | 2008-04-10 23:45:49 -0400 (Thu, 10 Apr 2008) | 1 line merging admin interface from the dojo-admin branch ........ r9310 | miker | 2008-04-10 23:50:01 -0400 (Thu, 10 Apr 2008) | 1 line merging dojo-ified fieldmapper from the dojo-admin branch ........ r9311 | dbs | 2008-04-11 11:37:25 -0400 (Fri, 11 Apr 2008) | 2 lines python-dev is required to build OpenSRF python packages ........ r9312 | miker | 2008-04-11 11:44:56 -0400 (Fri, 11 Apr 2008) | 7 lines Patch from Scott McKellar: These patches use the new function osrfHashIteratorKey() to fetch the current key from an osrfHashIterator, instead of accessing it directly. ........ r9313 | dbs | 2008-04-11 12:52:46 -0400 (Fri, 11 Apr 2008) | 2 lines web/js/opensrf directory has to exist before we can install into it ........ r9314 | erickson | 2008-04-11 14:14:13 -0400 (Fri, 11 Apr 2008) | 1 line putting OpenSRF.js into the dojo dir so dojo can find it ........ r9318 | miker | 2008-04-11 22:49:38 -0400 (Fri, 11 Apr 2008) | 1 line Patch from Scott McKellar to use new osrfHash iterator key function ........ r9319 | phasefx | 2008-04-12 12:15:34 -0400 (Sat, 12 Apr 2008) | 1 line differentiate entities for editing items and editing volumes ........ r9320 | phasefx | 2008-04-12 12:47:55 -0400 (Sat, 12 Apr 2008) | 1 line oy, extraneous quotation mark ........ r9321 | erickson | 2008-04-13 08:32:26 -0400 (Sun, 13 Apr 2008) | 1 line initial credit card and paypal processing code. this still needs some refactoring to accomodate the staff and patron workflows. ........ r9322 | erickson | 2008-04-13 08:32:54 -0400 (Sun, 13 Apr 2008) | 1 line added prereqs for credit card processing ........ r9323 | erickson | 2008-04-13 09:07:53 -0400 (Sun, 13 Apr 2008) | 1 line added initial Event handling code ........ r9325 | erickson | 2008-04-13 11:51:04 -0400 (Sun, 13 Apr 2008) | 1 line user and auth session management class ........ r9327 | dbs | 2008-04-13 14:17:49 -0400 (Sun, 13 Apr 2008) | 9 lines At various points in opac_utils.js, there are calls to doLogout() (no parms). However, Firefox complains that doLogout() is not defined. The only defined function is doLogout(noredirect) (one parm). As I can't find any instances of doLogout being called with a parameter, and I can't see noredirect being used anywhere in the function, the simplest patch appears to be to just remove the parameter from the prototype. ........ r9328 | dbs | 2008-04-13 14:23:17 -0400 (Sun, 13 Apr 2008) | 2 lines dbi_get_result_long is deprecated; using dbi_get_result_int instead ........ r9329 | dbs | 2008-04-13 19:46:53 -0400 (Sun, 13 Apr 2008) | 2 lines Clean up the problems I introduced during i18n-ization ........ r9330 | dbs | 2008-04-13 20:13:53 -0400 (Sun, 13 Apr 2008) | 3 lines Fix problems introduced during i18n-ization (JavaScript strings don't span multiple lines by default) ........ r9333 | erickson | 2008-04-13 22:52:50 -0400 (Sun, 13 Apr 2008) | 1 line added function to get the highest org list for a given permission ........ r9334 | miker | 2008-04-14 08:29:49 -0400 (Mon, 14 Apr 2008) | 1 line add support for async calls via an async kwarg ........ r9335 | miker | 2008-04-14 09:16:42 -0400 (Mon, 14 Apr 2008) | 1 line adding open-ils.fielder app ........ r9336 | miker | 2008-04-14 09:24:05 -0400 (Mon, 14 Apr 2008) | 1 line better name for the method ........ r9338 | miker | 2008-04-14 09:32:00 -0400 (Mon, 14 Apr 2008) | 1 line logging and simpler method call ........ r9339 | erickson | 2008-04-14 09:32:05 -0400 (Mon, 14 Apr 2008) | 1 line augmented the org descendants retrieval method to take an optional list of orgs ........ r9340 | miker | 2008-04-14 09:51:53 -0400 (Mon, 14 Apr 2008) | 1 line editor returns an array ........ r9342 | erickson | 2008-04-14 10:04:47 -0400 (Mon, 14 Apr 2008) | 1 line added a parallel method for perm_org_set which returns the sub-tree for each of the perm orgs ........ r9343 | miker | 2008-04-14 11:22:58 -0400 (Mon, 14 Apr 2008) | 1 line add new permacrud permissions to the base set ........ r9345 | erickson | 2008-04-14 13:38:59 -0400 (Mon, 14 Apr 2008) | 1 line added versions of work perm org fetcher to return flat list of all org units or org IDs. if no depth is provided to get_org_depth, do not default to 0 ........ r9347 | erickson | 2008-04-14 13:57:25 -0400 (Mon, 14 Apr 2008) | 1 line fixed method name typo ........ r9349 | erickson | 2008-04-14 14:29:35 -0400 (Mon, 14 Apr 2008) | 1 line org_unit_list and org_id_list now return sub-lists, segregated by branches of the org tree. the first item in each list is the highest perm or for that branch of the tree ........ r9350 | miker | 2008-04-14 14:39:08 -0400 (Mon, 14 Apr 2008) | 1 line moving seed data out of the schema files ........ r9352 | erickson | 2008-04-14 15:03:36 -0400 (Mon, 14 Apr 2008) | 1 line rolling back segregation by branch.. if that kind of pre-sorting is needed, just grab the tree ........ r9353 | erickson | 2008-04-14 16:21:49 -0400 (Mon, 14 Apr 2008) | 1 line added a synchronous option to user session fetching ........ r9354 | erickson | 2008-04-14 16:22:14 -0400 (Mon, 14 Apr 2008) | 1 line checking to make sure the potential event is actually an object before using the "in" operator ........ r9356 | dbs | 2008-04-14 20:23:18 -0400 (Mon, 14 Apr 2008) | 3 lines i18n for the MARC editor Note that marcedit.js doesn't like messagecatalog calls for some reason ........ r9357 | dbs | 2008-04-14 21:37:00 -0400 (Mon, 14 Apr 2008) | 2 lines Typo ........ r9358 | dbs | 2008-04-14 22:42:21 -0400 (Mon, 14 Apr 2008) | 3 lines Move inline calls into my_init(); messagecatalog isn't visible until after onload event Thanks to phasefx and miker for the assist! ........ r9359 | miker | 2008-04-15 07:59:51 -0400 (Tue, 15 Apr 2008) | 1 line dojo.require OpenSRF, since we use it herein. it will only be loaded if it has not been before ........ r9360 | dbs | 2008-04-15 08:18:51 -0400 (Tue, 15 Apr 2008) | 2 lines marc_view i18n ........ r9362 | miker | 2008-04-15 12:02:42 -0400 (Tue, 15 Apr 2008) | 1 line updating dewey extractor ........ r9363 | miker | 2008-04-15 12:42:11 -0400 (Tue, 15 Apr 2008) | 1 line default to pulling all fields from field_safe classes ........ r9364 | miker | 2008-04-15 13:09:40 -0400 (Tue, 15 Apr 2008) | 1 line fixing fielder with no fields ........ r9365 | miker | 2008-04-15 13:17:22 -0400 (Tue, 15 Apr 2008) | 1 line getting perl fieldmapper class name from idl ........ r9366 | miker | 2008-04-15 20:50:26 -0400 (Tue, 15 Apr 2008) | 1 line backend i18n dojo wrapper ........ r9367 | miker | 2008-04-15 20:50:56 -0400 (Tue, 15 Apr 2008) | 1 line default error handler typo ........ r9368 | dbs | 2008-04-15 21:38:49 -0400 (Tue, 15 Apr 2008) | 3 lines And so it is done. OpenSRF.js has been renamed to DojoSRF.js. Case-insensitive platforms of the world, rejoice. ........ r9369 | miker | 2008-04-16 13:48:34 -0400 (Wed, 16 Apr 2008) | 1 line arg! typo ........ r9370 | miker | 2008-04-17 01:21:21 -0400 (Thu, 17 Apr 2008) | 1 line in-db translation Digit widget ........ r9371 | miker | 2008-04-17 01:28:05 -0400 (Thu, 17 Apr 2008) | 1 line pull in my own requirements ........ r9372 | miker | 2008-04-17 14:04:26 -0400 (Thu, 17 Apr 2008) | 1 line use the class hint for the fully qualified field name, instead of the table (which is not always available) ........ r9373 | miker | 2008-04-17 14:54:50 -0400 (Thu, 17 Apr 2008) | 1 line locale parsing based on URL knowledge (because apache is not helping); aou.name translation support ........ r9374 | miker | 2008-04-17 15:21:56 -0400 (Thu, 17 Apr 2008) | 1 line move locale parsing out to a separate javascript file; translations of group names and descriptions ........ r9375 | miker | 2008-04-18 01:12:11 -0400 (Fri, 18 Apr 2008) | 1 line dojo-ify fmall.js ........ r9376 | miker | 2008-04-18 01:14:48 -0400 (Fri, 18 Apr 2008) | 1 line refactoring the translation widget some more -- happier with grids now, only slightly painful ........ r9377 | miker | 2008-04-18 01:15:51 -0400 (Fri, 18 Apr 2008) | 1 line put the translation widget into the status grid ........ r9378 | miker | 2008-04-18 01:16:33 -0400 (Fri, 18 Apr 2008) | 1 line load fmall.js via dojo in fieldmapper.Fieldmapper ........ r9379 | miker | 2008-04-18 10:08:31 -0400 (Fri, 18 Apr 2008) | 1 line adding Identifier to fieldmapper classes ........ r9380 | miker | 2008-04-18 10:17:37 -0400 (Fri, 18 Apr 2008) | 1 line typo in identifier setting ........ git-svn-id: svn://svn.open-ils.org/ILS/branches/acq-experiment@9385 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Evergreen/conf/lib_ips.txt b/Evergreen/conf/lib_ips.txt index 9721739bcb..75d571f195 100644 --- a/Evergreen/conf/lib_ips.txt +++ b/Evergreen/conf/lib_ips.txt @@ -428,3 +428,10 @@ WGRL-PC 168.12.204.1 168.12.204.254 WGRL-TA 168.12.205.1 168.12.205.254 WGRL-VR 168.12.206.1 168.12.206.254 WGRL-MZ 168.12.220.1 168.12.220.254 +WGRL-WB 168.12.224.1 168.12.224.255 +LBRLS-LB 168.13.31.1 168.13.31.255 +LBRLS-CORD 168.13.28.1 168.13.28.255 +LBRLS-DOOLY 168.13.29.1 168.13.29.255 +LBRLS-UNAD 168.13.30.1 168.13.30.255 +LBRLS-SCH 168.13.33.1 168.13.33.255 +LBRLS-BYRM 168.13.27.1 168.13.27.255 diff --git a/Evergreen/src/extras/import/import_holdings.pl b/Evergreen/src/extras/import/import_holdings.pl index b7ed45485e..cd7cf4b5eb 100755 --- a/Evergreen/src/extras/import/import_holdings.pl +++ b/Evergreen/src/extras/import/import_holdings.pl @@ -1,6 +1,9 @@ #!/usr/bin/perl -w use strict; -use XML::LibXML; +use UNIVERSAL::require; +use MARC::Charset; +use MARC::Batch; +use MARC::File::XML; use Time::HiRes qw/time/; use Getopt::Long; use Data::Dumper; @@ -36,16 +39,17 @@ my %status_map = ( $|=1; -my ($userid,$cn_id,$cp_id,$cp_file,$cn_file,$lib_map_field,$id_tag, $marc_file) = - (1, 1, 1, 'asset_copy.sql','asset_volume.sql','shortname','./controlfield[@tag="001"]'); +my ($userid,$cn_id,$cp_id,$cp_file,$cn_file,$lib_map_field,$id_tag,$id_field,$id_subfield, $marc_file) = + (1, 1, 1, 'asset_copy.sql','asset_volume.sql','shortname','001'); -my ($holding_tag,$bc,$lbl,$own,$pr,$cpn,$avail) = - ('./datafield[@tag="999"]','i','a','m','p','c','k'); +my ($skip,$enc,$marctype,$holding_tag,$bc,$lbl,$own,$pr,$cpn,$avail) = + (0,'utf-8','XML','999','i','a','m','p','c','k'); my ($db_driver,$db_host,$db_name,$db_user,$db_pw) = ('Pg','localhost','evergreen','postgres','postgres'); GetOptions ( + "encoding=s" => \$enc, "copy_file=s" => \$cp_file, "volume_file=s" => \$cn_file, "userid=i" => \$userid, @@ -57,18 +61,32 @@ GetOptions ( "db_user=s" => \$db_user, "db_pw=s" => \$db_pw, "lib_map_field=s" => \$lib_map_field, - "id_tag_xpath=s" => \$id_tag, - "holding_tag_xpath=s" => \$holding_tag, + "id_field=s" => \$id_field, + "id_subfield=s" => \$id_subfield, + "holding_field=s" => \$holding_tag, "item_barcode=s" => \$bc, "item_call_number=s" => \$lbl, "item_owning_lib=s" => \$own, "item_price=s" => \$pr, "item_copy_number=s" => \$cpn, "item_copy_status=s" => \$avail, - "marc_file=s" => \$marc_file, + "marc_file=s" => \$marc_file, + "marctype=s" => \$marctype, + "skip=i" => \$skip, ); +if ($marctype eq 'XML') { + 'open'->use(':utf8'); +} else { + bytes->use(); +} + +if ($enc) { + MARC::Charset->ignore_errors(1); + MARC::Charset->assume_encoding($enc); +} + my $dsn = "dbi:$db_driver:host=$db_host;dbname=$db_name"; my $dbh = DBI->connect($dsn,$db_user,$db_pw); @@ -87,67 +105,44 @@ while (my $lib = $sth->fetchrow_arrayref) { my $tcn_sth = $dbh->prepare("SELECT id FROM biblio.record_entry WHERE tcn_value = ?"); my $rec_id; -open CP, ">$cp_file" or die "Can't open $cp_file! $!\n"; -open CN, ">$cn_file" or die "Can't open $cn_file! $!\n"; +open CP, ">>$cp_file" or die "Can't open $cp_file! $!\n"; +open CN, ">>$cn_file" or die "Can't open $cn_file! $!\n"; - -print CP <new(); +my $batch = MARC::Batch->new( $marctype => $marc_file ); +$batch->strict_off(); +$batch->warnings_off(); my $cn_map; -my $doc; - -$doc = $parser->parse_file( $marc_file ); -my $xc = XML::LibXML::XPathContext->new($doc); -my @records = $xc->findnodes('//record'); -foreach my $record (@records) { - - my $tcn; - my $success = 0; - try { - $tcn = $xc->findvalue( $id_tag, $record ); - $success = 1; - } catch Error with { - my $e = shift; - warn $e; - }; - next unless $success; - - $tcn =~ s/^\s*(\.+)\s*/$1/o; - $tcn =~ s/\s+/_/go; - - unless ($tcn) { - warn "\nNo TCN found in rec!!\n"; - next; - } +my $count = 0; +my $record; +while ( try { $record = $batch->next } otherwise { $record = -1 } ) { + next if ($record == -1); + $count++; + next if ($count <= $skip); - $tcn_sth->execute($tcn); - $tcn_sth->bind_col(1, \$rec_id); - $tcn_sth->fetch; + $rec_id = $record->subfield( $id_field => $id_subfield ); - unless ($rec_id) { - warn "\n !! TCN $tcn not in the map!\n"; - next; - } + next unless ($rec_id); - for my $node ($xc->findnodes($holding_tag, $record)) { - my $barcode = $xc->findvalue( "./*[\@code=\"$bc\"]", $node ); - my $label = $xc->findvalue( "./*[\@code=\"$lbl\"]", $node ); - my $owning_lib = $$lib_map{ $xc->findvalue( "./*[\@code=\"$own\"]", $node ) }; - my $price = $xc->findvalue( "./*[\@code=\"$pr\"]", $node ); - my $copy_number = $xc->findvalue( "./*[\@code=\"$cpn\"]", $node ) || 0; - my $available = $xc->findvalue( "./*[\@code=\"$avail\"]", $node ) || ''; + for my $field ($record->field($holding_tag)) { + my $barcode = $field->subfield( $bc ); + my $label = $field->subfield( $lbl ); + my $owning_lib = $$lib_map{ $field->subfield( $own ) }; + my $price = $field->subfield( $pr ); + my $copy_number = $field->subfield( $cpn ) || '\N'; + my $available = $field->subfield( $avail ) || ''; my $status = $status_map{$available} || 0; @@ -157,8 +152,8 @@ foreach my $record (@records) { $barcode =~ s/\\/\\\\/og; $label =~ s/\\/\\\\/og; - $price =~ s/\$//og; - if ($price !~ /^\s*\d{1,6}\.\d{2}\s*$/o) { + $price =~ s/\$//og if($price); + if (!defined($price) || $price !~ /^\s*\d{1,6}\.\d{2}\s*$/o) { $price = '0.00'; } diff --git a/Evergreen/src/extras/import/quick_metarecord_map.sql b/Evergreen/src/extras/import/quick_metarecord_map.sql index a402c8668b..89a8364d8a 100644 --- a/Evergreen/src/extras/import/quick_metarecord_map.sql +++ b/Evergreen/src/extras/import/quick_metarecord_map.sql @@ -10,7 +10,8 @@ INSERT INTO metabib.metarecord (fingerprint,master_record) FROM (SELECT DISTINCT ON (fingerprint) fingerprint, id, quality FROM biblio.record_entry - ORDER BY fingerprint, quality desc) AS x; + ORDER BY fingerprint, quality desc) AS x + WHERE fingerprint IS NOT NULL; INSERT INTO metabib.metarecord_source_map (metarecord,source) SELECT m.id, b.id diff --git a/Evergreen/src/javascript/backend/circ/circ_item_config.js b/Evergreen/src/javascript/backend/circ/circ_item_config.js index ec1f5186bc..d98f762393 100644 --- a/Evergreen/src/javascript/backend/circ/circ_item_config.js +++ b/Evergreen/src/javascript/backend/circ/circ_item_config.js @@ -230,6 +230,14 @@ var CIRC_MOD_MAP = { maxFine : 'overdue_mid' }, + 'dvd-mid' : { + SIPMediaType : '006', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + 'e-book' : { SIPMediaType : '001', magneticMedia : 'f', @@ -356,6 +364,15 @@ var CIRC_MOD_MAP = { maxFine : 'overdue_mid' }, + 'video-mid' : { + SIPMediaType : '005', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'facbestslr' : { SIPMediaType : '001', magneticMedia : 'f', diff --git a/Evergreen/src/javascript/backend/circ/circ_permit_hold.js b/Evergreen/src/javascript/backend/circ/circ_permit_hold.js index 80b36b8592..c40e88561e 100644 --- a/Evergreen/src/javascript/backend/circ/circ_permit_hold.js +++ b/Evergreen/src/javascript/backend/circ/circ_permit_hold.js @@ -10,10 +10,12 @@ var isStaffHold = isGroupDescendantId('Staff', requestor.profile); /* non-staff members are allowed 50 open holds at most */ if( ! isStaffHold ) { - var count = userHoldCount(patron.id); - log_info("patron has " + count + " open holds"); - if( count >= 50 ) - result.events.push('MAX_HOLDS'); + if(newHold) { + var count = userHoldCount(patron.id); + log_info("patron has " + count + " open holds"); + if( count >= 50 ) + result.events.push('MAX_HOLDS'); + } } else { log_info("This is a staff-placed hold"); } @@ -70,6 +72,26 @@ if( ( marcItemType == 'g' || log_info("this is a range-protected item..."); + /* ------------------------------------------------------------------------ */ + /** This patch allows DCPL and LEE patrons to place + holds on protected items accross their systems. In short, if the pickup lib, + owning lib, and patron home (or request lib) are all within either of the two + systems, allow the hold */ + if( + /* DCPL=33, LEE=115 */ + (hasCommonAncestor(holdPickupLib, 33, 1) || hasCommonAncestor(holdPickupLib, 115, 1)) && + (hasCommonAncestor(volume.owning_lib, 33, 1) || hasCommonAncestor(volume.owning_lib, 115, 1)) && + ( + hasCommonAncestor(patron.home_ou.id, 33, 1) || hasCommonAncestor(patron.home_ou.id, 115, 1) || + hasCommonAncestor(holdRequestLib.id, 33, 1) || hasCommonAncestor(holdRequestLib.id, 115, 1) + )) { + + log_info("DCPL and LEE are allowed to place holds on protected items accross the two systems"); + return; + } + /* ------------------------------------------------------------------------ */ + + if( ! hasCommonAncestor( volume.owning_lib, holdPickupLib, 1 ) ) { /* we don't want these items to transit to the pickup lib */ diff --git a/Evergreen/xul/staff_client/server/patron/ue_config.js b/Evergreen/xul/staff_client/server/patron/ue_config.js index e540314ac9..917efdcba0 100644 --- a/Evergreen/xul/staff_client/server/patron/ue_config.js +++ b/Evergreen/xul/staff_client/server/patron/ue_config.js @@ -37,12 +37,12 @@ var barredAlerted = false; function uEditUsrnameBlur(field) { var usrname = uEditNodeVal(field); - if(!usrname) return; + if (!usrname) { return; } var req = new Request(CHECK_USERNAME, SESSION, usrname); req.callback( function(r) { var res = r.getResultObject(); - if( res && res != patron.id() ) { + if( res !== null && res != patron.id() ) { field.widget.onblur = null; /* prevent alert storm */ alertId('ue_dup_username'); field.widget.onblur = uEditUsrnameBlur; @@ -67,7 +67,7 @@ function uEditBarcodeBlur(field) { req.callback( function(r) { var res = r.getResultObject(); - if( res && res != patron.id() ) { + if( res == 1 ) { field.widget.onblur = null; /* prevent alert storm */ alertId('ue_dup_barcode'); field.widget.onblur = uEditBarcodeBlur; diff --git a/Open-ILS/admin/ils_admin/setup/ils_data/models.py b/Open-ILS/admin/ils_admin/setup/ils_data/models.py index 42e4ba2c3d..ea19cec87b 100644 --- a/Open-ILS/admin/ils_admin/setup/ils_data/models.py +++ b/Open-ILS/admin/ils_admin/setup/ils_data/models.py @@ -2,6 +2,7 @@ from django.db import models from django.db.models import signals from django.dispatch import dispatcher import datetime +from gettext import gettext as _ INTERVAL_HELP_TEXT = _('examples: "1 hour", "14 days", "3 months", "DD:HH:MM:SS.ms"') CHAR_MAXLEN=200 # just provide a sane default @@ -220,6 +221,36 @@ class HoursOfOperation(models.Model): Config tables -------------------------------------------------------------- """ +class CircModifier(models.Model): + code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True) + name = models.CharField(maxlength=CHAR_MAXLEN) + description = models.CharField(maxlength=CHAR_MAXLEN); + sip2_media_type = models.CharField(maxlength=CHAR_MAXLEN); + magnetic_media = models.BooleanField() + class Admin: + search_fields = ['name','code'] + list_display = ('code','name','description','sip2_media_type','magnetic_media') + class Meta: + db_table = 'circ_modifier' + ordering = ['name'] + verbose_name = _('Circulation Modifier') + def __str__(self): + return self.name + + +class VideoRecordingFormat(models.Model): + code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True) + value = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT); + class Admin: + search_fields = ['value','code'] + list_display = ('value','code') + class Meta: + db_table = 'videorecording_format_map' + ordering = ['code'] + verbose_name = _('Video Recording Format') + def __str__(self): + return self.value + class RuleCircDuration(models.Model): name = models.CharField(maxlength=CHAR_MAXLEN) extended = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT); @@ -236,6 +267,89 @@ class RuleCircDuration(models.Model): def __str__(self): return self.name +class CircMatrixMatchpoint(models.Model): + active = models.BooleanField(blank=False, default=True) + org_unit_id = models.ForeignKey(OrgUnit, db_column='org_unit', blank=False) + grp_id = models.ForeignKey(GrpTree, db_column='grp', blank=False, verbose_name=_("User Group")) + circ_modifier_id = models.ForeignKey(CircModifier, db_column='circ_modifier', null=True,blank=True) + marc_type_id = models.ForeignKey('ItemTypeMap', db_column='marc_type', null=True,blank=True) + marc_form_id = models.ForeignKey('ItemFormMap', db_column='marc_form', null=True,blank=True) + marc_vr_format_id = models.ForeignKey('VideoRecordingFormat', db_column='marc_vr_format', null=True,blank=True) + ref_flag = models.BooleanField(null=True) + usr_age_lower_bound = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT, null=True, blank=True) + usr_age_upper_bound = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT, null=True, blank=True) + + def save(self): + ''' Override to force None-ness on the interval fields ''' + if self.usr_age_lower_bound == "": + self.usr_age_lower_bound = None + if self.usr_age_upper_bound == "": + self.usr_age_upper_bound = None + return models.Model.save(self) + + class Admin: + search_fields = ['grp_id','org_unit_id','circ_modifier_id','marc_type_id','marc_form_id', + 'marc_vr_format_id','usr_age_lower_bound','usr_age_upper_bound'] + + list_display = ('grp_id','org_unit_id','circ_modifier_id','marc_type_id','marc_form_id', + 'marc_vr_format_id','ref_flag','usr_age_lower_bound','usr_age_upper_bound') + + list_filter = ['grp_id','org_unit_id','circ_modifier_id','marc_type_id','marc_form_id','marc_vr_format_id'] + class Meta: + db_table = 'circ_matrix_matchpoint' + ordering = ['id'] + verbose_name = _('Circulation Matrix Matchpoint') + def __str__(self): + return _("OrgUnit: %(orgid)s, Group: %(grpid)s, Circ Modifier: %(modid)s") % { + 'orgid':self.org_unit_id, 'grpid':self.grp_id, 'modid':self.circ_modifier_id} + +class CircMatrixTest(models.Model): + matchpoint_id = models.ForeignKey(CircMatrixMatchpoint, db_column='matchpoint', blank=False, primary_key=True, + edit_inline=models.TABULAR, core=True, num_in_admin=1) + max_items_out = models.IntegerField(null=True, blank=True) + max_overdue = models.IntegerField(null=True, blank=True) + max_fines = models.FloatField(max_digits=8, decimal_places=2, null=True, blank=True) + script_test = models.CharField(maxlength=CHAR_MAXLEN, null=True, blank=True) + class Admin: + list_display = ('matchpoint_id','max_items_out','max_overdue','max_fines','script_test') + class Meta: + db_table = 'circ_matrix_test' + ordering = ['matchpoint_id'] + verbose_name = _('Circ Matrix Test') + def __str__(self): + return _("%(mid)s, Max Items Out: %(iout)s, Max Overdue: %(odue)s, Max Fines: %(fines)s") % { + 'mid': self.matchpoint_id, 'iout' : self.max_items_out, 'odue':self.max_overdue, 'fines':self.max_fines} + +class CircMatrixCircModTest(models.Model): + matchpoint_id = models.ForeignKey(CircMatrixMatchpoint, db_column='matchpoint', blank=False, edit_inline=True,core=True, num_in_admin=1) + items_out = models.IntegerField(blank=False) + circ_mod_id = models.ForeignKey(CircModifier, db_column='circ_mod', blank=False) + class Admin: + search_fields = ['circ_mod_id'] + list_display = ('matchpoint_id','circ_mod_id','items_out') + class Meta: + db_table = 'circ_matrix_circ_mod_test' + ordering = ['matchpoint_id'] + verbose_name = _('Circ Matrix Items Out Cirulation Modifier Subtest') + def __str__(self): + return _("%(mid)s, Restriction: %(mod)s") % {'mid': self.matchpoint_id,'mod':self.circ_mod_id} + +class CircMatrixRuleSet(models.Model): + matchpoint_id = models.ForeignKey(CircMatrixMatchpoint, db_column='matchpoint', + blank=False, primary_key=True, edit_inline=True,core=True, num_in_admin=1) + duration_rule_id = models.ForeignKey(RuleCircDuration, db_column='duration_rule', blank=False) + recurring_fine_rule_id = models.ForeignKey('RuleRecurringFine', db_column='recurring_fine_rule', blank=False) + max_fine_rule_id = models.ForeignKey('RuleMaxFine', db_column='max_fine_rule', blank=False) + class Admin: + search_fields = ['matchoint_id'] + list_display = ('matchpoint_id','duration_rule_id','recurring_fine_rule_id','max_fine_rule_id') + class Meta: + db_table = 'circ_matrix_ruleset' + ordering = ['matchpoint_id'] + verbose_name = _('Circ Matrix Rule Set') + def __str__(self): + return _("Duration: %(dur)s, Recurring Fine: %(rfine)s, Max Fine: %(mfine)s") % { + 'dur':self.duration_rule_id, 'rfine':self.recurring_fine_rule_id, 'mfine':self.max_fine_rule_id} class RuleMaxFine(models.Model): name = models.CharField(maxlength=CHAR_MAXLEN) diff --git a/Open-ILS/examples/apache/eg_vhost.conf b/Open-ILS/examples/apache/eg_vhost.conf index d6838fe3f3..7716719b24 100644 --- a/Open-ILS/examples/apache/eg_vhost.conf +++ b/Open-ILS/examples/apache/eg_vhost.conf @@ -99,8 +99,17 @@ OSRFGatewayConfig /openils/conf/opensrf_core.xml # ---------------------------------------------------------------------------------- -# Run server-side XUL through xmlent to load the correct XML entities +# Run server-side XUL and XHTML through xmlent to load the correct XML entities # ---------------------------------------------------------------------------------- + + Options +Includes + AddOutputFilter INCLUDES;XMLENT .xhtml + allow from all + + # We only support one locale (en-US) for the time being + SetEnv locale en-US + + Options +Includes XMLEntContentType "application/vnd.mozilla.xul+xml" @@ -108,9 +117,10 @@ OSRFGatewayConfig /openils/conf/opensrf_core.xml allow from all # We only support one locale (en-US) for the time being - SetEnv locale=en-US + SetEnv locale en-US + # ---------------------------------------------------------------------------------- # Supercat feeds # ---------------------------------------------------------------------------------- @@ -149,6 +159,13 @@ OSRFGatewayConfig /openils/conf/opensrf_core.xml PerlSendHeader On allow from all + + SetHandler perl-script + PerlHandler OpenILS::WWW::SuperCat::sru_search + Options +ExecCGI + PerlSendHeader On + allow from all + SetHandler perl-script PerlHandler OpenILS::WWW::SuperCat::changes_feed @@ -202,7 +219,10 @@ OSRFGatewayConfig /openils/conf/opensrf_core.xml # ---------------------------------------------------------------------------------- SetHandler perl-script - PerlHandler OpenILS::WWW::Exporter + PerlSetVar OILSProxyTitle "Exporter Login" + PerlSetVar OILSProxyDescription "Please log in to export records" + PerlSetVar OILSProxyPermissions "STAFF_LOGIN" + PerlHandler OpenILS::WWW::Proxy OpenILS::WWW::Exporter Options +ExecCGI allow from all diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml index aada4298ff..2f216bef3e 100644 --- a/Open-ILS/examples/fm_IDL.xml +++ b/Open-ILS/examples/fm_IDL.xml @@ -1,4 +1,28 @@ - + + + + + @@ -96,6 +120,20 @@ + + + + + + + + + + + + + + @@ -167,6 +205,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -177,6 +390,7 @@ + @@ -324,9 +538,7 @@ - - - + @@ -419,6 +631,14 @@ + + + + + + + + @@ -448,6 +668,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -463,6 +704,14 @@ + + + + + + + + @@ -474,6 +723,14 @@ + + + + + + + + @@ -484,6 +741,14 @@ + + + + + + + + @@ -510,6 +775,14 @@ + + + + + + + + @@ -549,6 +822,13 @@ + + + + + + + @@ -598,6 +878,13 @@ + + + + + + + @@ -624,6 +911,14 @@ + + + + + + + + @@ -639,6 +934,14 @@ + + + + + + + + @@ -654,6 +957,14 @@ + + + + + + + + @@ -806,6 +1117,22 @@ + + + + + + + + + + + + + + + + @@ -849,6 +1176,14 @@ + + + + + + + + @@ -860,6 +1195,14 @@ + + + + + + + + @@ -959,6 +1302,7 @@ + @@ -974,6 +1318,14 @@ + + + + + + + + @@ -1026,6 +1378,22 @@ + + + + + + + + + + + + + + + + @@ -1178,6 +1546,14 @@ + + + + + + + + @@ -1196,7 +1572,7 @@ - + @@ -1204,6 +1580,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1220,6 +1685,22 @@ + + + + + + + + + + + + + + + + @@ -1243,6 +1724,14 @@ + + + + + + + + @@ -1264,6 +1753,14 @@ + + + + + + + + @@ -1316,7 +1813,7 @@ - + @@ -1358,6 +1855,17 @@ + + + + + + + + + + + @@ -1529,6 +2037,14 @@ + + + + + + + + @@ -1683,6 +2199,14 @@ + + + + + + + + @@ -1925,6 +2449,14 @@ + + + + + + + + @@ -2036,6 +2568,14 @@ + + + + + + + + @@ -2314,8 +2854,8 @@ - - + + @@ -2326,6 +2866,14 @@ + + + + + + + + @@ -3310,6 +3858,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Open-ILS/examples/oils_sip.xml.example b/Open-ILS/examples/oils_sip.xml.example index 9e807c03e8..e1a2c65474 100644 --- a/Open-ILS/examples/oils_sip.xml.example +++ b/Open-ILS/examples/oils_sip.xml.example @@ -82,7 +82,7 @@ /openils/var/ circ/circ_item_config.js - + diff --git a/Open-ILS/examples/opensrf.xml.example b/Open-ILS/examples/opensrf.xml.example index 87accd92dc..f3d8d30196 100644 --- a/Open-ILS/examples/opensrf.xml.example +++ b/Open-ILS/examples/opensrf.xml.example @@ -2,12 +2,13 @@ - + - + /openils/var/log /openils/var/sock @@ -17,34 +18,36 @@ Example opensrf config file for OpenILS /openils/var - + - - - false - - + + + false + + /openils/conf/fm_IDL.xml prefork /openils/var/data/ils_events.xml - + localhost - + evergreen@localhost https://localhost/reporter/ @@ -93,6 +96,8 @@ Example opensrf config file for OpenILS z3950.loc.gov 7090 Voyager + + FI 121 76 @@ -113,10 +118,10 @@ Example opensrf config file for OpenILS OLUCWorldCat 121 76 @@ -140,31 +145,39 @@ Example opensrf config file for OpenILS OpenILS::WWW::AddedContent::Amazon - + http://images.amazon.com/images/P/ - + 4 - + 600 - + 4 MY_USER_ID @@ -173,7 +186,7 @@ Example opensrf config file for OpenILS - + @@ -204,16 +217,20 @@ Example opensrf config file for OpenILS 93 - + 1000 1 15 - + 1 @@ -256,6 +273,8 @@ Example opensrf config file for OpenILS oilsMARC21slim2HTML.xsl + + true @@ -500,8 +519,8 @@ Example opensrf config file for OpenILS /openils/var/catalog/ /openils/var/web/opac/common/js/ - biblio_fingerprint.js - biblio_descriptor.js + biblio_fingerprint.js + biblio_descriptor.js @@ -658,6 +677,41 @@ Example opensrf config file for OpenILS + + 3 + 1 + perl + OpenILS::Application::PermaCrud + 17 + + open-ils.permacrud_unix.sock + open-ils.permacrud_unix.pid + 1000 + open-ils.permacrud_unix.log + 5 + 15 + 3 + 5 + + + + + 3 + 1 + perl + OpenILS::Application::Fielder + 17 + + open-ils.fielder_unix.sock + open-ils.fielder_unix.pid + 1000 + open-ils.fielder_unix.log + 5 + 15 + 3 + 5 + + @@ -666,12 +720,12 @@ Example opensrf config file for OpenILS @@ -692,6 +746,8 @@ Example opensrf config file for OpenILS open-ils.ingest open-ils.reporter open-ils.reporter-store + open-ils.permacrud + open-ils.fielder diff --git a/Open-ILS/examples/opensrf_core.xml.example b/Open-ILS/examples/opensrf_core.xml.example index d5b3530c68..8d91d99fcf 100644 --- a/Open-ILS/examples/opensrf_core.xml.example +++ b/Open-ILS/examples/opensrf_core.xml.example @@ -1,4 +1,7 @@ + @@ -7,20 +10,12 @@ router - - - localhost - - - - - localhost - + + localhost client mypass 5222 @@ -29,12 +24,12 @@ /openils/var/log/osrfsys.log - + + --> 3 @@ -63,21 +58,19 @@ + which means we define the log XID string for log traces --> true router - - localhost - + localhost - + opensrf.math open-ils.cat @@ -99,43 +92,45 @@ - + + - - 0 + + 0 - + - - localhost + + localhost - - localhost + + localhost - + - + - - localhost - 5222 + + localhost + 5222 - - router - mypassword + + router + mypassword - - - router - 10 - 5 + + + router + 10 + 5 - - /openils/var/log/router.log - 3 + + /openils/var/log/router.log + 3 + - + diff --git a/Open-ILS/examples/opensrf_core.xml.example.multidomain b/Open-ILS/examples/opensrf_core.xml.example.multidomain new file mode 100644 index 0000000000..5c8050fffe --- /dev/null +++ b/Open-ILS/examples/opensrf_core.xml.example.multidomain @@ -0,0 +1,142 @@ + + + + + + + + + + + + router + public.localhost + + opensrf.math + open-ils.cat + open-ils.supercat + open-ils.search + open-ils.circ + open-ils.actor + open-ils.auth + open-ils.collections + open-ils.reporter + + + + + + router + private.localhost + + + + + + private.localhost + osrf + osrf + 5222 + + /openils/var/log/osrfsys.log + + 3 + /openils/conf/opensrf.xml + + + + + + + true + router + + + public.localhost + + + + opensrf.math + opensrf.dbmath + open-ils.cat + open-ils.search + open-ils.circ + open-ils.actor + open-ils.auth + open-ils.collections + open-ils.reporter + + + + osrf + osrf + 5222 + 3 + /openils/var/log/gateway.log + + + + + + + + + + private.localhost + + private.localhost + public.localhost + + + public.localhost + 5222 + /openils/var/sock/unix_sock + router + osrf + router + 10 + 5 + + syslog + local2 + 5 + + + + private.localhost + + private.localhost + + + private.localhost + 5222 + router + osrf + router + 10 + 5 + + syslog + local2 + 4 + + + + + + + + + + diff --git a/Open-ILS/examples/permacrud.xsd b/Open-ILS/examples/permacrud.xsd index 8ddcf0afed..ded4f017f4 100644 --- a/Open-ILS/examples/permacrud.xsd +++ b/Open-ILS/examples/permacrud.xsd @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + @@ -46,6 +47,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + @@ -56,6 +59,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + @@ -66,6 +71,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + @@ -76,6 +83,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + diff --git a/Open-ILS/src/Makefile b/Open-ILS/src/Makefile index ec7082cc69..130e24e6ec 100644 --- a/Open-ILS/src/Makefile +++ b/Open-ILS/src/Makefile @@ -1,7 +1,7 @@ # vim:noet:ts=4 export LDFLAGS += -L . -L$(TMP) -L $(OPENSRF_LIBS) -export CFLAGS += -pipe -g -Wall -O2 -fPIC -I$(LIBXML2_HEADERS) -I$(APACHE2_HEADERS) -I$(APR_HEADERS) \ +export CFLAGS += -pipe -g -Wall -O2 -fPIC -I../../include -I$(LIBXML2_HEADERS) -I$(APACHE2_HEADERS) -I$(APR_HEADERS) \ -D_LARGEFILE64_SOURCE -I$(LIBXML2_HEADERS)/libxml -I$(TMP) -I$(OPENSRF_HEADERS) export INCDIR = "$(INCLUDEDIR)/openils/" @@ -69,9 +69,13 @@ webcore-install: mkdir -p $(ADMINDIR) cp -r ../admin/* $(ADMINDIR) mkdir -p $(WEBDIR) + mkdir -p $(WEBDIR)/js/opensrf/ mkdir -p $(WEBDIR)/opac/extras/xsl/ cp -r ../web/* $(WEBDIR) cp $(OPENSRF_LIBS)/javascript/* $(WEBDIR)/opac/common/js/ + # dojo-ified opensrf libs + cp $(OPENSRF_LIBS)/javascript/opensrf*js $(WEBDIR)/js/opensrf/ + cp $(OPENSRF_LIBS)/javascript/DojoSRF.js $(WEBDIR)/js/dojo/ ln -sf $(WEBDIR)/opac/skin/default/xml/index.xml $(WEBDIR)/opac/skin/default/xml/mresult.xml ln -sf $(WEBDIR)/opac/skin/default/xml/index.xml $(WEBDIR)/opac/skin/default/xml/rresult.xml ln -sf $(WEBDIR)/opac/skin/default/xml/index.xml $(WEBDIR)/opac/skin/default/xml/rdetail.xml @@ -105,7 +109,9 @@ autojs-install: @echo $@ cp extras/fieldmapper.pl $(BINDIR) cp extras/org_tree_js.pl $(BINDIR) + cp extras/org_lasso_js.pl $(BINDIR) cp extras/org_tree_html_options.pl $(BINDIR) + cp extras/org_tree_proximity.pl $(BINDIR) cp extras/autogen.sh $(BINDIR) cp support-scripts/offline-blocked-list.pl $(BINDIR) # this should probably be somewhere else # ----------------------------------------------------------------------------------- diff --git a/Open-ILS/src/apachemods/json_xml.c b/Open-ILS/src/apachemods/json_xml.c index e7c11b6d16..8b2195137b 100644 --- a/Open-ILS/src/apachemods/json_xml.c +++ b/Open-ILS/src/apachemods/json_xml.c @@ -1,21 +1,20 @@ #include "json_xml.h" #include "fieldmapper_lookup.h" -void _rest_xml_output(growing_buffer*, jsonObject*, char*, int, int); -char* _escape_xml (char*); +static void _rest_xml_output(growing_buffer*, const jsonObject*, char*, int, int); +static char* _escape_xml (const char*); char* json_string_to_xml(char* content) { jsonObject * obj; growing_buffer * res_xml; - char * output; int i; obj = json_parse_string( content ); - res_xml = buffer_init(1024); if (!obj) return NULL; + res_xml = buffer_init(1024); buffer_add(res_xml, ""); if(obj->type == JSON_ARRAY ) { @@ -28,15 +27,11 @@ char* json_string_to_xml(char* content) { buffer_add(res_xml, ""); - output = buffer_data(res_xml); - buffer_free(res_xml); jsonObjectFree(obj); - - return output; + return buffer_release(res_xml); } -char* _escape_xml (char* text) { - char* out; +char* _escape_xml (const char* text) { growing_buffer* b = buffer_init(256); int len = strlen(text); int i; @@ -50,12 +45,11 @@ char* _escape_xml (char* text) { else buffer_add_char(b,text[i]); } - out = buffer_data(b); - buffer_free(b); - return out; + return buffer_release(b); } -void _rest_xml_output(growing_buffer* buf, jsonObject* obj, char * obj_class, int arr_index, int notag) { +static void _rest_xml_output(growing_buffer* buf, const jsonObject* obj, + char * obj_class, int arr_index, int notag) { char * tag; int i; @@ -77,6 +71,7 @@ void _rest_xml_output(growing_buffer* buf, jsonObject* obj, char * obj_class, in if(obj->classname) { if(obj->type == JSON_NULL) { buffer_fadd(buf,"<%s>", tag, obj->classname, tag); + free(tag); return; } else { buffer_fadd(buf,"<%s>", tag, obj->classname); diff --git a/Open-ILS/src/apachemods/json_xml.h b/Open-ILS/src/apachemods/json_xml.h index 2752fd0492..e59996b1de 100644 --- a/Open-ILS/src/apachemods/json_xml.h +++ b/Open-ILS/src/apachemods/json_xml.h @@ -3,8 +3,7 @@ #include /* the JSON parser, so we can read the response we're XMLizing */ -#include "objson/object.h" -#include "objson/json_parser.h" -#include "utils.h" +#include +#include char* json_string_to_xml(char*); diff --git a/Open-ILS/src/apachemods/mod_rest_gateway.c b/Open-ILS/src/apachemods/mod_rest_gateway.c deleted file mode 100644 index 8adff62e7d..0000000000 --- a/Open-ILS/src/apachemods/mod_rest_gateway.c +++ /dev/null @@ -1,217 +0,0 @@ -#include "mod_rest_gateway.h" -#include "http_log.h" - -char* ils_rest_gateway_config_file; - -static const char* ils_gateway_set_config(cmd_parms *parms, void *config, const char *arg) { - ils_gateway_config *cfg; - - cfg = ap_get_module_config(parms->server->module_config, &ils_rest_gateway_module); - - cfg->configfile = (char*) arg; - ils_rest_gateway_config_file = (char*) arg; - - return NULL; -} - -/* tell apache about our commands */ -static const command_rec ils_gateway_cmds[] = { - AP_INIT_TAKE1( GATEWAY_CONFIG, ils_gateway_set_config, NULL, RSRC_CONF, "gateway config file"), - {NULL} -}; - -/* build the config object */ -static void* ils_gateway_create_config( apr_pool_t* p, server_rec* s) { - ils_gateway_config* cfg = (ils_gateway_config*) apr_palloc(p, sizeof(ils_gateway_config)); - cfg->configfile = GATEWAY_DEFAULT_CONFIG; - return (void*) cfg; -} - - -static void mod_ils_gateway_child_init(apr_pool_t *p, server_rec *s) { - - char* cfg = ils_rest_gateway_config_file; - - if( ! osrf_system_bootstrap_client( cfg, CONFIG_CONTEXT) ) { - osrfLogError( OSRF_LOG_MARK, "Unable to load gateway config file..."); - return; - } - fprintf(stderr, "Bootstrapping %ld\n", (long) getpid() ); - fflush(stderr); -} - -static int mod_ils_gateway_method_handler (request_rec *r) { - - /* make sure we're needed first thing*/ - if (strcmp(r->handler, MODULE_NAME )) - return DECLINED; - - osrfLogSetAppname("oils_rest_gw"); - - apr_pool_t *p = r->pool; /* memory pool */ - char* arg = r->args; /* url query string */ - - char* service = NULL; /* service to connect to */ - char* method = NULL; /* method to perform */ - - //json* exception = NULL; /* returned in error conditions */ - //jsonObject* exception = NULL; /* returned in error conditions */ - string_array* sarray = init_string_array(12); /* method parameters */ - - growing_buffer* buffer = NULL; /* POST data */ - growing_buffer* tmp_buf = NULL; /* temp buffer */ - - char* key = NULL; /* query item name */ - char* val = NULL; /* query item value */ - - jsonObject* response = jsonParseString("{\"status\":0,\"debug\":\"\"}"); - jsonObject* payload = jsonParseString("[]"); - jsonObjectSetKey(response, "payload", payload ); - - /* verify we are connected */ - if(!osrfSystemGetTransportClient()) { - osrfLogError( OSRF_LOG_MARK, "Bootstrap Failed, no transport client"); - return HTTP_INTERNAL_SERVER_ERROR; - } - - - /* gather the post args and append them to the url query string */ - if( !strcmp(r->method,"POST") ) { - - ap_setup_client_block(r,REQUEST_CHUNKED_DECHUNK); - - if(! ap_should_client_block(r)) { - osrfLogWarning( OSRF_LOG_MARK, "No Post Body"); - } - - char body[1025]; - memset(body, '\0', sizeof(body)); - buffer = buffer_init(1025); - - while(ap_get_client_block(r, body, 1024)) { - buffer_add( buffer, body ); - memset(body, '\0', sizeof(body)); - } - - if(arg && arg[0]) { - tmp_buf = buffer_init(1024); - buffer_add(tmp_buf,arg); - buffer_add(tmp_buf,buffer->buf); - arg = (char*) apr_pstrdup(p, tmp_buf->buf); - buffer_free(tmp_buf); - } else { - arg = (char*) apr_pstrdup(p, buffer->buf); - } - buffer_free(buffer); - - } - - ap_log_rerror( APLOG_MARK, APLOG_DEBUG, 0, r, "URL: %s", arg ); - - - if( ! arg || !arg[0] ) { /* we received no request */ - osrfLogWarning( OSRF_LOG_MARK, "No Args"); - return OK; - } - - r->allowed |= (AP_METHOD_BIT << M_GET); - r->allowed |= (AP_METHOD_BIT << M_POST); - - - while( arg && (val = ap_getword(p, (const char**) &arg, '&'))) { - - key = ap_getword(r->pool, (const char**) &val, '='); - if(!key || !key[0]) - break; - - ap_unescape_url((char*)key); - ap_unescape_url((char*)val); - - if(!strcmp(key,"service")) - service = val; - - if(!strcmp(key,"method")) - method = val; - - if(!strcmp(key,"param")) - string_array_add(sarray, val); - - } - - osrfLogInfo( OSRF_LOG_MARK, "Performing(%ld): service %s | method %s | \n", - (long) getpid(), service, method ); - - int k; - for( k = 0; k!= sarray->size; k++ ) { - osrfLogInfo( OSRF_LOG_MARK, "param %s", string_array_get_string(sarray,k)); - } - - osrf_app_session* session = osrf_app_client_session_init(service); - - osrfLogDebug( OSRF_LOG_MARK, "MOD session service: %s", session->remote_service ); - - int req_id = osrfAppSessionMakeRequest( session, NULL, method, 1, sarray ); - string_array_destroy(sarray); - - osrf_message* omsg = NULL; - - while((omsg = osrfAppSessionRequestRecv( session, req_id, 60 ))) { - - jsonObjectSetKey(response, "status", jsonNewNumberObject(omsg->status_code)); - - if( omsg->_result_content ) { - jsonObjectPush( payload, jsonObjectClone(omsg->_result_content)); - - } else { - - char* s = omsg->status_name ? omsg->status_name : "Unknown Error"; - char* t = omsg->status_text ? omsg->status_text : "No Error Message"; - jsonObjectSetKey(response, "debug", jsonNewObject("\n\n%s:\n%s\n", s, t)); - osrfLogError( OSRF_LOG_MARK, "Gateway received error: %s", - jsonObjectGetString(jsonObjectGetKeyConst(response, "debug"))); - break; - } - - osrf_message_free(omsg); - omsg = NULL; - } - - char* content = jsonObjectToJSON(response); - char* xml = json_string_to_xml( content ); - - free(content); - jsonObjectFree(response); - - - /* set content type to text/xml for passing around XML objects */ - ap_set_content_type(r, "text/xml"); - ap_rputs(xml,r); - free(xml); - - osrf_app_session_request_finish( session, req_id ); - osrfLogDebug( OSRF_LOG_MARK, "gateway process message successfully"); - - - osrfAppSessionFree(session); - - - return OK; - -} - -static void mod_ils_gateway_register_hooks (apr_pool_t *p) { - ap_hook_handler(mod_ils_gateway_method_handler, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_child_init(mod_ils_gateway_child_init,NULL,NULL,APR_HOOK_MIDDLE); -} - - -module AP_MODULE_DECLARE_DATA ils_rest_gateway_module = { - STANDARD20_MODULE_STUFF, - NULL, - NULL, - ils_gateway_create_config, - NULL, - ils_gateway_cmds, - mod_ils_gateway_register_hooks, -}; - diff --git a/Open-ILS/src/apachemods/mod_rest_gateway.h b/Open-ILS/src/apachemods/mod_rest_gateway.h deleted file mode 100644 index 571e3d6d16..0000000000 --- a/Open-ILS/src/apachemods/mod_rest_gateway.h +++ /dev/null @@ -1,31 +0,0 @@ -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_protocol.h" -//#include "apr_compat.h" -#include "apr_strings.h" - -/* our stuff */ -#include "opensrf/transport_client.h" -#include "opensrf/osrf_message.h" -#include "opensrf/osrf_app_session.h" -#include "string_array.h" -#include "md5.h" -#include "objson/object.h" -#include "objson/json_parser.h" - -#include "json_xml.h" -#define GATEWAY_CONFIG "ILSRestGatewayConfig" -#define MODULE_NAME "ils_rest_gateway_module" -#define CONFIG_CONTEXT "gateway" - -#define GATEWAY_DEFAULT_CONFIG "/openils/conf/opensrf_core.xml" - - -/* our config structure */ -typedef struct { - char* configfile; /* our bootstrap config file */ -} ils_gateway_config; - -module AP_MODULE_DECLARE_DATA ils_rest_gateway_module; - diff --git a/Open-ILS/src/apachemods/mod_xmlbuilder.c b/Open-ILS/src/apachemods/mod_xmlbuilder.c deleted file mode 100644 index 7c316ff39b..0000000000 --- a/Open-ILS/src/apachemods/mod_xmlbuilder.c +++ /dev/null @@ -1,439 +0,0 @@ -#include "mod_xmlbuilder.h" - -char* __xmlBuilderDynamicLocale = NULL; -request_rec* currentRec = NULL; - - -/* set the base DTD directory */ -static const char* xmlBuilderSetBaseDir(cmd_parms *params, void *cfg, const char *arg) { - xmlBuilderConfig* config = ap_get_module_config( - params->server->module_config, &xmlbuilder_module ); - config->baseDir = (char*) arg; - return NULL; -} - -static const char* xmlBuilderSetDefaultLocale( - cmd_parms* params, void* cfg, const char* arg ) { - xmlBuilderConfig* config = ap_get_module_config( - params->server->module_config, &xmlbuilder_module ); - config->defaultLocale = (char*) arg; - return NULL; -} - -static const char* xmlBuilderSetDefaultDtd( - cmd_parms* params, void* cfg, const char* arg ) { - xmlBuilderConfig* config = ap_get_module_config( - params->server->module_config, &xmlbuilder_module ); - config->defaultDtd = (char*) arg; - if( config->defaultDtd ) { - if(!strcmp(config->defaultDtd,"NULL")) - config->defaultDtd = NULL; - } - return NULL; -} - - -static const char* xmlBuilderSetLocaleParam( - cmd_parms* params, void* cfg, const char* arg ) { - xmlBuilderConfig* config = ap_get_module_config( - params->server->module_config, &xmlbuilder_module ); - config->localeParam = (char*) arg; - return NULL; -} - - -static const char* xmlBuilderSetPostXSL( - cmd_parms* params, void* cfg, const char* arg ) { - xmlBuilderConfig* config = ap_get_module_config( - params->server->module_config, &xmlbuilder_module ); - config->postXSL = xsltParseStylesheetFile((xmlChar*) arg); - if( config->postXSL == NULL ) - apacheDebug("Unable to parse postXSL stylesheet: %s. No postXSL will be performed", arg); - return NULL; -} - -static const char* xmlBuilderSetContentType( - cmd_parms* params, void* cfg, const char* arg ) { - xmlBuilderConfig* config = ap_get_module_config( - params->server->module_config, &xmlbuilder_module ); - config->contentType = (char*) arg; - return NULL; -} - -// ACCESS_CONF - OR_ALL ? -static const command_rec xmlBuilderCommands[] = { - AP_INIT_TAKE1( MODXMLB_CONFIG_LOCALE, - xmlBuilderSetDefaultLocale, NULL, RSRC_CONF, "Default Locale"), - AP_INIT_TAKE1( MODXMLB_CONFIG_BASE_DIR, - xmlBuilderSetBaseDir, NULL, RSRC_CONF, "Base Directory"), - AP_INIT_TAKE1( MODXMLB_CONFIG_POST_XSL, - xmlBuilderSetPostXSL, NULL, RSRC_CONF, "Post XSL"), - AP_INIT_TAKE1( MODXMLB_CONFIG_DEFAULT_DTD, - xmlBuilderSetDefaultDtd, NULL, RSRC_CONF, "Default DTD"), - AP_INIT_TAKE1( MODXMLB_CONFIG_LOCALE_PARAM, - xmlBuilderSetLocaleParam, NULL, RSRC_CONF, "Locale URL param name"), - AP_INIT_TAKE1( MODXMLB_CONFIG_CONTENT_TYPE, - xmlBuilderSetContentType, NULL, RSRC_CONF, "Content Type"), - {NULL} -}; - -static void* xmlBuilderCreateConfig( apr_pool_t* p, server_rec* s ) { - xmlBuilderConfig* config = - (xmlBuilderConfig*) apr_palloc( p, sizeof(xmlBuilderConfig) ); - config->baseDir = MODXMLB_DEFAULT_BASE_DIR; - config->defaultLocale = MODXMLB_DEFAULT_LOCALE; - config->defaultDtd = NULL; - config->postXSL = NULL; - config->contentType = NULL; - config->localeParam = MODXMLB_DEFAULT_LOCALE_PARAM; - return (void*) config; -} - - -/* Child Init handler ----------------------------------------------------------- */ -static void xmlBuilderChildInit( apr_pool_t *p, server_rec *s ) { -} - -static int xmlBuilderHandler( request_rec* r ) { - - if( strcmp(r->handler, MODULE_NAME ) ) return DECLINED; - currentRec = r; - - xmlBuilderConfig* config = ap_get_module_config( - r->server->module_config, &xmlbuilder_module ); - - /* - xmlBuilderConfig* config = ap_get_module_config( - r->per_dir_config, &xmlbuilder_module ); - */ - - if(config == NULL) { - ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, currentRec, - "config is nulll..."); - return HTTP_INTERNAL_SERVER_ERROR; - } - - r->allowed |= (AP_METHOD_BIT << M_GET); - r->allowed |= (AP_METHOD_BIT << M_POST); - char* ct = config->contentType; - - - if(!config->contentType) ct = "text/html; charset=utf-8"; - /* ---------------------------------- */ - // Hack to force XUL mime type (until config is fixed) - char* f = r->filename; - if(f) { - int l = strlen(f); - if(l > 4) { - if( !strcmp( f + (l - 4), ".xul")) - ct = "application/vnd.mozilla.xul+xml"; - } - } - /* ---------------------------------- */ - - ap_set_content_type(r, ct); - - //ap_table_set(r->headers_out, "Cache-Control", "max-age=15552000"); - - char* dates = apr_pcalloc(r->pool, MAX_STRING_LEN); - apr_rfc822_date(dates, apr_time_now() + 604800000000); /* cache for one week */ - ap_table_set(r->headers_out, "Expires", dates); - - apr_rfc822_date(dates, apr_time_now()); /* cache for one week */ - ap_table_set(r->headers_out, "Date", dates); - - - /* - char expire_hdr[APR_RFC822_DATE_LEN]; - apr_rfc822_date(expire_hdr, (apr_time_t)(time(NULL) + 15552000)); - ap_table_set(r->headers_out, "Expires", expire_hdr); - */ - - string_array* params = apacheParseParms(r); - char* locale = apacheGetFirstParamValue(params, config->localeParam); - if(locale) __xmlBuilderDynamicLocale = locale; - char* XMLFile = r->filename; - - xmlDocPtr doc = xmlBuilderProcessFile( XMLFile, config ); - if(!doc) return apacheError( "Unable to parse XML file %s", XMLFile ); - - /* apply the post XSL */ - if(config->postXSL) { - xmlDocPtr newdoc; - newdoc = xsltApplyStylesheet(config->postXSL, doc, NULL ); - - if(newdoc == NULL) { - apacheDebug("Error applying postXSL... skipping."); - } else { - xmlFreeDoc(doc); - doc = newdoc; - } - } - - char* docXML = xmlDocToString( doc, 1 ); - //apacheDebug("DOC:\n%s\n%s", docXML); - ap_rputs(docXML, r); - free(docXML); - xmlFreeDoc( doc ); - doc = NULL; - //xmlCleanupCharEncodingHandlers(); - //xmlCleanupParser(); - - return OK; -} - - -/* frees the collected DTD's */ -static void __xmlBuilderFreeDtdHash( char* key, void* item ) { - if(!item) return; - xmlFreeDtd( item ); -} - - -xmlDocPtr xmlBuilderProcessFile( char* filename, xmlBuilderConfig* config ) { - if(!filename) { - apacheError( "No XML file provided" ); return NULL; } - - xmlBuilderContext context; - context.config = config; - context.doc = xmlNewDoc( BAD_CAST "1.0" ); - context.dtdHash = osrfNewHash(); - context.entHash = osrfNewHash(); - context.nodeList = osrfNewList(); - context.xmlError = 0; - context.xmlFile = filename; - context.dtdHash->freeItem = &__xmlBuilderFreeDtdHash; - - - /* - ap_log_rerror( APLOG_MARK, APLOG_DEBUG, 0, currentRec, - "xmlBuilderProcessFile() Options: " - "XMLBuilderDefaultLocale : %s | XMLBuilderBaseDir : %s | " - "XMLBuilderDefaultDTD : %s | XMLBuilderLocaleParam : %s", - config->defaultLocale, config->baseDir, config->defaultDtd, config->localeParam ); - */ - - /* pre-parse the default dtd if defined */ - if( config->defaultDtd ) - xmlBuilderAddDtd( config->defaultDtd, &context ); - - xmlParserCtxtPtr parserCtx; - - parserCtx = xmlCreatePushParserCtxt(xmlBuilderSaxHandler, &context, "", 0, NULL); - xmlCtxtReadFile( parserCtx, filename, NULL, XML_PARSE_RECOVER ); - - xmlFreeParserCtxt( parserCtx ); - osrfListFree(context.nodeList); - osrfHashFree(context.entHash); - osrfHashFree(context.dtdHash); - return context.doc; -} - - -void xmlBuilderStartElement( void* context, const xmlChar *name, const xmlChar **atts ) { - xmlBuilderContext* ctx = (xmlBuilderContext*) context; - - xmlNodePtr node = NULL; - - /* process xincludes as a sub-doc */ - if( !strcmp( name, "xi:include" ) ) { - - char* href = strdup(xmlSaxAttr( atts, "href" )); - if(href) { - - /* find the relative path for the xinclude */ - if(href[0] != '/') { - int len = strlen(ctx->xmlFile) + strlen(href) + 1; - char buf[len]; - memset( buf, '\0', sizeof(len) ); - strcpy( buf, ctx->xmlFile ); - int i; - for( i = strlen(buf); i != 0; i-- ) { - if( buf[i] == '/' ) break; - buf[i] = '\0'; - } - strcat( buf, href ); - free(href); - href = strdup(buf); - } - - - xmlDocPtr subDoc = xmlBuilderProcessFile( href, ctx->config ); - node = xmlDocGetRootElement( subDoc ); - } - - if(!node) { - apacheError("Unable to parse xinclude: %s", href ); - free(href); - return; - } - free(href); - - } else { - node = xmlNewNode(NULL, name); - xmlBuilderAddAtts( ctx, node, atts ); - } - - - xmlNodePtr parent = osrfListGetIndex( - ctx->nodeList, ctx->nodeList->size - 1 ); - - if( parent ) xmlAddChild( parent, node ); - else xmlDocSetRootElement(ctx->doc, node); - - osrfListPush( ctx->nodeList, node ); -} - - -void xmlBuilderAddAtts( xmlBuilderContext* ctx, xmlNodePtr node, const xmlChar** atts ) { - if(!(ctx && node && atts)) return; - int i; - - for(i = 0; (atts[i] != NULL); i++) { - - if(atts[i+1]) { - - const xmlChar* name = atts[i]; - const xmlChar* prop = atts[i+1]; - int nl = strlen(prop); - char* _prop = NULL; - - if( prop[0] == '&' && prop[nl-1] == ';' ) { /* replace the entity if we are one */ - char buf[nl+1]; - memset( buf, '\0', sizeof(buf) ); - strncat(buf, prop + 1, nl - 2); - xmlEntityPtr ent = osrfHashGet( ctx->entHash, buf ); - if(ent && ent->content) _prop = ent->content; - } else { _prop = (char*) prop; } - - xmlSetProp( node, name, _prop ); - i++; - } - } -} - -void xmlBuilderEndElement( void* context, const xmlChar* name ) { - xmlBuilderContext* ctx = (xmlBuilderContext*) context; - osrfListPop( ctx->nodeList ); -} - - -void xmlBuilderHandleCharacter(void* context, const xmlChar *ch, int len) { - xmlBuilderContext* ctx = (xmlBuilderContext*) context; - xmlNodePtr node = osrfListGetIndex( - ctx->nodeList, ctx->nodeList->size - 1 ); - - if(node) { - xmlNodePtr txt = xmlNewTextLen(ch, len); - xmlAddChild( node, txt ); - } - -} - - -void xmlBuilderParseError( void* context, const char* msg, ... ) { - xmlBuilderContext* ctx = (xmlBuilderContext*) context; - VA_LIST_TO_STRING(msg); - apacheDebug( "Parser Error Occurred: %s", VA_BUF); - ctx->xmlError = 1; -} - - -xmlEntityPtr xmlBuilderGetEntity( void* context, const xmlChar* name ) { - xmlBuilderContext* ctx = (xmlBuilderContext*) context; - xmlEntityPtr ent = osrfHashGet( ctx->entHash, name ); - return ent; -} - - -void xmlBuilderExtSubset( void* blob, - const xmlChar* name, const xmlChar* extId, const xmlChar* sysId ) { - - xmlBuilderContext* context = (xmlBuilderContext*) blob; - if( context->config->defaultDtd ) { - apacheDebug("Ignoring DTD [%s] because default DTD is set...", sysId); - return; - } - - xmlBuilderAddDtd( sysId, context ); -} - -void xmlBuilderComment( void* blob, const xmlChar* data ) { - xmlBuilderContext* ctx = (xmlBuilderContext*) blob; - xmlNodePtr comment = xmlNewComment( data ); - xmlNodePtr parent = osrfListGetIndex( - ctx->nodeList, ctx->nodeList->size - 1 ); - if( parent ) xmlAddChild( parent, comment ); -} - - - -void xmlBuilderProcInstruction( - void* blob, const xmlChar* name, const xmlChar* data ) { - xmlBuilderContext* ctx = (xmlBuilderContext*) blob; - //xmlNodePtr node = xmlNewDocPI( ctx->doc, name, data ); - xmlNodePtr pi = xmlNewDocPI( ctx->doc, name, data ); - xmlAddChild( (xmlNodePtr) ctx->doc, pi ); -} - - - -void xmlBuilderAddDtd( const char* sysId, xmlBuilderContext* context ) { - - if(!sysId) return; - if( osrfHashGet( context->dtdHash, sysId ) ) return; /* already parsed this hash */ - - //apacheDebug("Adding new DTD file to the entity hash: %s", sysId); - - /* use the dynamic locale if defined... default locale instead */ - char* locale; - if(__xmlBuilderDynamicLocale) locale = __xmlBuilderDynamicLocale; - else locale = context->config->defaultLocale; - - /* determine the path to the DTD file and load it */ - int len = strlen(context->config->baseDir) + strlen(locale) + strlen(sysId) + 4; - char buf[len]; - snprintf( buf, sizeof(buf), "%s/%s/%s", context->config->baseDir, locale, sysId ); - - xmlDtdPtr dtd = xmlParseDTD(NULL, buf); - if(!dtd) return; - - /* cycle through entities and push them into the entity hash */ - xmlNodePtr node = dtd->children; - while( node ) { - if( node->type == XML_ENTITY_DECL ) { /* shove the entities into the hash */ - xmlEntityPtr ent = (xmlEntityPtr) node; - osrfHashSet( context->entHash, ent, (char*) ent->name ); - } - node = node->next; - } - - /* cache the DTD so we can free it later */ - osrfHashSet( context->dtdHash, dtd, sysId ); -} - - -/* ------------------------------------------------------------------------ */ - -/* register callbacks */ -static void xmlBuilderRegisterHooks (apr_pool_t *p) { - ap_hook_handler(xmlBuilderHandler, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_child_init(xmlBuilderChildInit,NULL,NULL,APR_HOOK_MIDDLE); -} - - -/* finally, flesh the module */ -module AP_MODULE_DECLARE_DATA xmlbuilder_module = { - STANDARD20_MODULE_STUFF, - NULL, - NULL, - xmlBuilderCreateConfig, - NULL, - xmlBuilderCommands, - xmlBuilderRegisterHooks, -}; - - - - - diff --git a/Open-ILS/src/c-apps/Makefile b/Open-ILS/src/c-apps/Makefile index 0ac65fca4b..01973561f9 100644 --- a/Open-ILS/src/c-apps/Makefile +++ b/Open-ILS/src/c-apps/Makefile @@ -1,4 +1,4 @@ -LDLIBS += -lobjson -lopensrf #-lfieldmapper +LDLIBS += -lopensrf #-lfieldmapper LDFLAGS += -Wl,-rpath=$(LIBDIR) -L$(DBI_LIBS) CFLAGS += -DOSRF_LOG_PARAMS -I../../include diff --git a/Open-ILS/src/c-apps/oils_auth.c b/Open-ILS/src/c-apps/oils_auth.c index 07e71ad169..59ff65d06f 100644 --- a/Open-ILS/src/c-apps/oils_auth.c +++ b/Open-ILS/src/c-apps/oils_auth.c @@ -1,7 +1,7 @@ #include "opensrf/osrf_app_session.h" #include "opensrf/osrf_application.h" #include "opensrf/osrf_settings.h" -#include "objson/object.h" +#include "opensrf/osrf_json.h" #include "opensrf/log.h" #include "openils/oils_utils.h" #include "openils/oils_constants.h" @@ -172,6 +172,7 @@ static int oilsAuthVerifyPassword( const osrfMethodContext* ctx, char* seed = osrfCacheGetString( "%s%s", OILS_AUTH_CACHE_PRFX, uname ); /**/ if(!seed) { + free(realPassword); return osrfAppRequestRespondException( ctx->session, ctx->request, "No authentication seed found. " "open-ils.auth.authenticate.init must be called first"); @@ -209,20 +210,22 @@ static double oilsAuthGetTimeout( const jsonObject* userObj, const char* type, d if(!_oilsAuthOPACTimeout) { /* Load the default timeouts */ - _oilsAuthOPACTimeout = - jsonObjectGetNumber( - osrf_settings_host_value_object( - "/apps/open-ils.auth/app_settings/default_timeout/opac")); + jsonObject* value_obj; + + value_obj = osrf_settings_host_value_object( + "/apps/open-ils.auth/app_settings/default_timeout/opac" ); + _oilsAuthOPACTimeout = jsonObjectGetNumber(value_obj); + jsonObjectFree(value_obj); - _oilsAuthStaffTimeout = - jsonObjectGetNumber( - osrf_settings_host_value_object( - "/apps/open-ils.auth/app_settings/default_timeout/staff" )); + value_obj = osrf_settings_host_value_object( + "/apps/open-ils.auth/app_settings/default_timeout/staff" ); + _oilsAuthStaffTimeout = jsonObjectGetNumber(value_obj); + jsonObjectFree(value_obj); - _oilsAuthOverrideTimeout = - jsonObjectGetNumber( - osrf_settings_host_value_object( - "/apps/open-ils.auth/app_settings/default_timeout/temp" )); + value_obj = osrf_settings_host_value_object( + "/apps/open-ils.auth/app_settings/default_timeout/temp" ); + _oilsAuthOverrideTimeout = jsonObjectGetNumber(value_obj); + jsonObjectFree(value_obj); osrfLogInfo(OSRF_LOG_MARK, "Set default auth timetouts: opac => %d : staff => %d : temp => %d", diff --git a/Open-ILS/src/c-apps/oils_cstore.c b/Open-ILS/src/c-apps/oils_cstore.c index bc619f5c62..ce5dbdc25e 100644 --- a/Open-ILS/src/c-apps/oils_cstore.c +++ b/Open-ILS/src/c-apps/oils_cstore.c @@ -2,10 +2,11 @@ #include "opensrf/osrf_settings.h" #include "opensrf/osrf_message.h" #include "opensrf/utils.h" -#include "objson/object.h" +#include "opensrf/osrf_json.h" #include "opensrf/log.h" #include "openils/oils_idl.h" #include +#include #include #include @@ -70,7 +71,7 @@ static char* getSourceDefinition( osrfHash* ); static dbi_conn writehandle; /* our MASTER db connection */ static dbi_conn dbhandle; /* our CURRENT db connection */ -osrfHash readHandles; +//static osrfHash * readHandles; static jsonObject* jsonNULL = NULL; // static int max_flesh_depth = 100; @@ -450,7 +451,7 @@ int beginTransaction ( osrfMethodContext* ctx ) { if (!ctx->session->userData) { ctx->session->userData = osrfNewHash(); - ((osrfHash*)ctx->session->userData)->freeItem = &sessionDataFree; + osrfHashSetCallback((osrfHash*)ctx->session->userData, &sessionDataFree); } osrfHashSet( (osrfHash*)ctx->session->userData, strdup( ctx->session->session_id ), "xact_id" ); @@ -623,20 +624,26 @@ int dispatchCRUDMethod ( osrfMethodContext* ctx ) { int err = 0; + const char* methodtype = osrfHashGet(meta, "methodtype"); jsonObject * obj = NULL; - if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "create")) - obj = doCreate(ctx, &err); - if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "retrieve")) + if (!strcmp(methodtype, "create")) { + obj = doCreate(ctx, &err); + osrfAppRespondComplete( ctx, obj ); + } + else if (!strcmp(methodtype, "retrieve")) { obj = doRetrieve(ctx, &err); - - if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "update")) + osrfAppRespondComplete( ctx, obj ); + } + else if (!strcmp(methodtype, "update")) { obj = doUpdate(ctx, &err); - - if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "delete")) + osrfAppRespondComplete( ctx, obj ); + } + else if (!strcmp(methodtype, "delete")) { obj = doDelete(ctx, &err); - - if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "search")) { + osrfAppRespondComplete( ctx, obj ); + } + else if (!strcmp(methodtype, "search")) { obj = doFieldmapperSearch(ctx, class_obj, ctx->params, &err); if(err) return err; @@ -649,17 +656,17 @@ int dispatchCRUDMethod ( osrfMethodContext* ctx ) { jsonObjectIteratorFree(itr); osrfAppRespondComplete( ctx, NULL ); - } else if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "id_list")) { + } else if (!strcmp(methodtype, "id_list")) { jsonObject* _p = jsonObjectClone( ctx->params ); if (jsonObjectGetIndex( _p, 1 )) { jsonObjectRemoveKey( jsonObjectGetIndex( _p, 1 ), "flesh" ); jsonObjectRemoveKey( jsonObjectGetIndex( _p, 1 ), "flesh_columns" ); } else { - jsonObjectSetIndex( _p, 1, jsonParseString("{}") ); + jsonObjectSetIndex( _p, 1, jsonNewObjectType(JSON_HASH) ); } - growing_buffer* sel_list = buffer_init(16); + growing_buffer* sel_list = buffer_init(64); buffer_fadd(sel_list, "{ \"%s\":[\"%s\"] }", osrfHashGet( class_obj, "classname" ), osrfHashGet( class_obj, "primarykey" )); char* _s = buffer_release(sel_list); @@ -941,8 +948,8 @@ static jsonObject* doCreate(osrfMethodContext* ctx, int* err ) { } else { - jsonObject* fake_params = jsonParseString("[]"); - jsonObjectPush(fake_params, jsonParseString("{}")); + jsonObject* fake_params = jsonNewObjectType(JSON_ARRAY); + jsonObjectPush(fake_params, jsonNewObjectType(JSON_HASH)); jsonObjectSetKey( jsonObjectGetIndex(fake_params, 0), @@ -991,8 +998,8 @@ static jsonObject* doRetrieve(osrfMethodContext* ctx, int* err ) { id ); - jsonObject* fake_params = jsonParseString("[]"); - jsonObjectPush(fake_params, jsonParseString("{}")); + jsonObject* fake_params = jsonNewObjectType(JSON_ARRAY); + jsonObjectPush(fake_params, jsonNewObjectType(JSON_HASH)); jsonObjectSetKey( jsonObjectGetIndex(fake_params, 0), @@ -1177,7 +1184,9 @@ static char* searchFieldTransform (const char* class, osrfHash* field, const jso char* val = jsonObjectToSimpleString(func_item); - if ( dbi_conn_quote_string(dbhandle, &val) ) { + if ( !val ) { + buffer_add( sql_buf, ",NULL" ); + } else if ( dbi_conn_quote_string(dbhandle, &val) ) { buffer_fadd( sql_buf, ",%s", val ); } else { osrfLogError(OSRF_LOG_MARK, "%s: Error quoting key string [%s]", MODULENAME, val); @@ -1417,7 +1426,7 @@ static char* searchJOIN ( const jsonObject* join_hash, osrfHash* leftmeta ) { if (join_hash->type == JSON_STRING) { // create a wrapper around a copy of the original char* _tmp = jsonObjectToSimpleString( join_hash ); - freeable_hash = jsonParseString("{}"); + freeable_hash = jsonNewObjectType(JSON_HASH); jsonObjectSetKey(freeable_hash, _tmp, NULL); free(_tmp); working_hash = freeable_hash; @@ -1454,6 +1463,7 @@ static char* searchJOIN ( const jsonObject* join_hash, osrfHash* leftmeta ) { ); buffer_free(join_buf); free(field); + jsonObjectIteratorFree(search_itr); return NULL; } fkey = strdup( fkey ); @@ -1471,6 +1481,7 @@ static char* searchJOIN ( const jsonObject* join_hash, osrfHash* leftmeta ) { ); buffer_free(join_buf); free(fkey); + jsonObjectIteratorFree(search_itr); return NULL; } field = strdup( field ); @@ -1517,6 +1528,7 @@ static char* searchJOIN ( const jsonObject* join_hash, osrfHash* leftmeta ) { class ); buffer_free(join_buf); + jsonObjectIteratorFree(search_itr); return NULL; } @@ -1657,7 +1669,8 @@ static char* searchWHERE ( const jsonObject* search_hash, osrfHash* meta, int op ); buffer_free(sql_buf); free(table); - return NULL; + jsonObjectIteratorFree(search_itr); + return NULL; } char* subpred = searchPredicate( class, field, node->item ); @@ -1753,13 +1766,13 @@ static char* SELECT ( // if the select list is empty, or the core class field list is '*', // build the default select list ... if (!selhash) { - selhash = defaultselhash = jsonParseString( "{}" ); - jsonObjectSetKey( selhash, core_class, jsonParseString( "[]" ) ); + selhash = defaultselhash = jsonNewObjectType(JSON_HASH); + jsonObjectSetKey( selhash, core_class, jsonNewObjectType(JSON_ARRAY) ); } else if ( (tmp_const = jsonObjectGetKeyConst( selhash, core_class )) && tmp_const->type == JSON_STRING ) { char* _x = jsonObjectToSimpleString( tmp_const ); if (!strncmp( "*", _x, 1 )) { jsonObjectRemoveKey( selhash, core_class ); - jsonObjectSetKey( selhash, core_class, jsonParseString( "[]" ) ); + jsonObjectSetKey( selhash, core_class, jsonNewObjectType(JSON_ARRAY) ); } free(_x); } @@ -1855,7 +1868,7 @@ static char* SELECT ( char* pkey = osrfHashGet(idlClass, "primarykey"); char* tname = osrfHashGet(idlClass, "tablename"); - buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, __column, pkey, cname, pkey, locale, __column); + buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, cname, __column, pkey, cname, pkey, locale, __column); } else { buffer_fadd(select_buf, " \"%s\".%s AS \"%s\"", cname, __column, __column); } @@ -1899,7 +1912,7 @@ static char* SELECT ( char* pkey = osrfHashGet(idlClass, "primarykey"); char* tname = osrfHashGet(idlClass, "tablename"); - buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, fname, pkey, cname, pkey, locale, __alias); + buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, cname, fname, pkey, cname, pkey, locale, __alias); } else { buffer_fadd(select_buf, " \"%s\".%s AS \"%s\"", cname, fname, __alias); } @@ -2124,6 +2137,7 @@ static char* SELECT ( buffer_free(order_buf); buffer_free(sql_buf); if (defaultselhash) jsonObjectFree(defaultselhash); + jsonObjectIteratorFree(class_itr); return NULL; } @@ -2208,12 +2222,12 @@ static char* buildSELECT ( jsonObject* search_hash, jsonObject* order_hash, osrf growing_buffer* select_buf = buffer_init(128); if ( !(selhash = jsonObjectGetKey( order_hash, "select" )) ) { - defaultselhash = jsonParseString( "{}" ); + defaultselhash = jsonNewObjectType(JSON_HASH); selhash = defaultselhash; } if ( !jsonObjectGetKeyConst(selhash,core_class) ) { - jsonObjectSetKey( selhash, core_class, jsonParseString( "[]" ) ); + jsonObjectSetKey( selhash, core_class, jsonNewObjectType(JSON_ARRAY) ); jsonObject* flist = jsonObjectGetKey( selhash, core_class ); int i = 0; @@ -2271,7 +2285,7 @@ static char* buildSELECT ( jsonObject* search_hash, jsonObject* order_hash, osrf char* pkey = osrfHashGet(idlClass, "primarykey"); char* tname = osrfHashGet(idlClass, "tablename"); - buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, fname, pkey, cname, pkey, locale, fname); + buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, cname, fname, pkey, cname, pkey, locale, fname); } else { buffer_fadd(select_buf, " \"%s\".%s", cname, fname); } @@ -2314,6 +2328,7 @@ static char* buildSELECT ( jsonObject* search_hash, jsonObject* order_hash, osrf "Severe query error -- see error log for more details" ); buffer_free(sql_buf); + if(defaultselhash) jsonObjectFree(defaultselhash); return NULL; } else { buffer_add(sql_buf, pred); @@ -2556,7 +2571,7 @@ static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* meta, osrfLogDebug(OSRF_LOG_MARK, "%s SQL = %s", MODULENAME, sql); dbi_result result = dbi_conn_query(dbhandle, sql); - jsonObject* res_list = jsonParseString("[]"); + jsonObject* res_list = jsonNewObjectType(JSON_ARRAY); if(result) { osrfLogDebug(OSRF_LOG_MARK, "Query returned with no errors"); osrfHash* dedup = osrfNewHash(); @@ -2668,7 +2683,7 @@ static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* meta, osrfStringArray* link_map = osrfHashGet( kid_link, "map" ); if (link_map->size > 0) { - jsonObject* _kid_key = jsonParseString("[]"); + jsonObject* _kid_key = jsonNewObjectType(JSON_ARRAY); jsonObjectPush( _kid_key, jsonNewObject( osrfStringArrayGetString( link_map, 0 ) ) @@ -2690,9 +2705,9 @@ static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* meta, osrfHashGet(kid_link, "reltype") ); - jsonObject* fake_params = jsonParseString("[]"); - jsonObjectPush(fake_params, jsonParseString("{}")); // search hash - jsonObjectPush(fake_params, jsonParseString("{}")); // order/flesh hash + jsonObject* fake_params = jsonNewObjectType(JSON_ARRAY); + jsonObjectPush(fake_params, jsonNewObjectType(JSON_HASH)); // search hash + jsonObjectPush(fake_params, jsonNewObjectType(JSON_HASH)); // order/flesh hash osrfLogDebug(OSRF_LOG_MARK, "Creating dummy params object..."); @@ -2750,6 +2765,7 @@ static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* meta, osrfStringArrayFree(link_fields); jsonObjectIteratorFree(itr); jsonObjectFree(res_list); + jsonObjectFree(flesh_blob); return jsonNULL; } @@ -2758,7 +2774,7 @@ static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* meta, jsonObject* X = NULL; if ( link_map->size > 0 && kids->size > 0 ) { X = kids; - kids = jsonParseString("[]"); + kids = jsonNewObjectType(JSON_ARRAY); jsonObjectNode* _k_node; jsonObjectIterator* _k = jsonNewObjectIterator( X ); @@ -2787,6 +2803,7 @@ static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* meta, ) ); } + jsonObjectIteratorFree(_k); } if (!(strcmp( osrfHashGet(kid_link, "reltype"), "has_a" )) || !(strcmp( osrfHashGet(kid_link, "reltype"), "might_have" ))) { @@ -3158,7 +3175,7 @@ static jsonObject* oilsMakeFieldmapperFromResult( dbi_result result, osrfHash* m jsonNewNumberObject(dbi_result_get_longlong(result, columnName))); else jsonObjectSetIndex( object, fmIndex, - jsonNewNumberObject(dbi_result_get_long(result, columnName))); + jsonNewNumberObject(dbi_result_get_int(result, columnName))); break; @@ -3182,18 +3199,19 @@ static jsonObject* oilsMakeFieldmapperFromResult( dbi_result result, osrfHash* m memset(dt_string, '\0', sizeof(dt_string)); memset(&gmdt, '\0', sizeof(gmdt)); - memset(&_tmp_dt, '\0', sizeof(_tmp_dt)); _tmp_dt = dbi_result_get_datetime(result, columnName); - localtime_r( &_tmp_dt, &gmdt ); if (!(attr & DBI_DATETIME_DATE)) { - strftime(dt_string, 255, "%T", &gmdt); + gmtime_r( &_tmp_dt, &gmdt ); + strftime(dt_string, sizeof(dt_string), "%T", &gmdt); } else if (!(attr & DBI_DATETIME_TIME)) { - strftime(dt_string, 255, "%F", &gmdt); + localtime_r( &_tmp_dt, &gmdt ); + strftime(dt_string, sizeof(dt_string), "%F", &gmdt); } else { - strftime(dt_string, 255, "%FT%T%z", &gmdt); + localtime_r( &_tmp_dt, &gmdt ); + strftime(dt_string, sizeof(dt_string), "%FT%T%z", &gmdt); } jsonObjectSetIndex( object, fmIndex, jsonNewObject(dt_string) ); @@ -3247,7 +3265,7 @@ static jsonObject* oilsMakeJSONFromResult( dbi_result result ) { if( attr & DBI_INTEGER_SIZE8 ) jsonObjectSetKey( object, columnName, jsonNewNumberObject(dbi_result_get_longlong(result, columnName)) ); else - jsonObjectSetKey( object, columnName, jsonNewNumberObject(dbi_result_get_long(result, columnName)) ); + jsonObjectSetKey( object, columnName, jsonNewNumberObject(dbi_result_get_int(result, columnName)) ); break; case DBI_TYPE_DECIMAL : @@ -3262,18 +3280,19 @@ static jsonObject* oilsMakeJSONFromResult( dbi_result result ) { memset(dt_string, '\0', sizeof(dt_string)); memset(&gmdt, '\0', sizeof(gmdt)); - memset(&_tmp_dt, '\0', sizeof(_tmp_dt)); _tmp_dt = dbi_result_get_datetime(result, columnName); - localtime_r( &_tmp_dt, &gmdt ); if (!(attr & DBI_DATETIME_DATE)) { - strftime(dt_string, 255, "%T", &gmdt); + gmtime_r( &_tmp_dt, &gmdt ); + strftime(dt_string, sizeof(dt_string), "%T", &gmdt); } else if (!(attr & DBI_DATETIME_TIME)) { - strftime(dt_string, 255, "%F", &gmdt); + localtime_r( &_tmp_dt, &gmdt ); + strftime(dt_string, sizeof(dt_string), "%F", &gmdt); } else { - strftime(dt_string, 255, "%FT%T%z", &gmdt); + localtime_r( &_tmp_dt, &gmdt ); + strftime(dt_string, sizeof(dt_string), "%FT%T%z", &gmdt); } jsonObjectSetKey( object, columnName, jsonNewObject(dt_string) ); diff --git a/Open-ILS/src/c-apps/oils_event.c b/Open-ILS/src/c-apps/oils_event.c index bc9b737c77..fe9894b243 100644 --- a/Open-ILS/src/c-apps/oils_event.c +++ b/Open-ILS/src/c-apps/oils_event.c @@ -71,7 +71,8 @@ void oilsEventFree( oilsEvent* event ) { free(event->perm); free(event->file); if(event->json) jsonObjectFree(event->json); - if(event->payload) jsonObjectFree(event->payload); + /* event->json will contain a pointer to event->payload */ + else jsonObjectFree(event->payload); free(event); } diff --git a/Open-ILS/src/c-apps/oils_fetch.c b/Open-ILS/src/c-apps/oils_fetch.c deleted file mode 100644 index 4babd2569e..0000000000 --- a/Open-ILS/src/c-apps/oils_fetch.c +++ /dev/null @@ -1,228 +0,0 @@ -#include "opensrf/osrf_app_session.h" -#include "opensrf/osrf_application.h" -#include "opensrf/osrf_settings.h" -#include "objson/object.h" -#include "opensrf/log.h" -#include "openils/oils_utils.h" -#include "openils/oils_constants.h" -#include "openils/oils_event.h" -#include -#include - -#define OILS_AUTH_CACHE_PRFX "oils_fetch_" - -#define MODULENAME "open-ils.fetch" -dbi_conn dbhandle; /* our db connection */ - -/* handy NULL json object to have around */ -static jsonObject* oilsFetchNULL = NULL; - -int osrfAppChildInit(); - -/* turns a singal db result row into a jsonObject */ -jsonObject* oilsFetchMakeJSON( dbi_result result, char* hint ); - -osrfHash* fmClassMap = NULL; - - -int osrfAppInitialize() { - osrfLogInfo(OSRF_LOG_MARK, "Initializing Fetch Server..."); - - oilsFetchNULL = jsonNewObject(NULL); - fmClassMap = osrfNewHash(); - - int i; - char* hint; - char* apiname; - - osrfList* keys = fm_classes(); - if(!keys) return 0; - - /* cycle through all of the classes and register a - * retrieve method for each */ - for( i = 0; i < keys->size; i++ ) { - - hint = OSRF_LIST_GET_INDEX(keys, i); - i++; - apiname = OSRF_LIST_GET_INDEX(keys, i); - if(!(hint && apiname)) break; - - osrfHashSet( fmClassMap, hint, apiname ); - - char method[256]; - snprintf(method, sizeof(method), "open-ils.fetch.%s.retrieve", apiname); - - osrfAppRegisterMethod( MODULENAME, - method, "oilsFetchDoRetrieve", "", 1, 0 ); - } - - return 0; -} - - -/** - * Connects to the database - */ -int osrfAppChildInit() { - - dbi_initialize(NULL); - - char* driver = osrf_settings_host_value("/apps/%s/app_settings/databases/driver", MODULENAME); - char* user = osrf_settings_host_value("/apps/%s/app_settings/databases/database/user", MODULENAME); - char* host = osrf_settings_host_value("/apps/%s/app_settings/databases/database/host", MODULENAME); - char* port = osrf_settings_host_value("/apps/%s/app_settings/databases/database/port", MODULENAME); - char* db = osrf_settings_host_value("/apps/%s/app_settings/databases/database/db", MODULENAME); - char* pw = osrf_settings_host_value("/apps/%s/app_settings/databases/database/pw", MODULENAME); - - dbhandle = dbi_conn_new(driver); - - if(!dbhandle) { - osrfLogError(OSRF_LOG_MARK, "Error creating database driver %s", driver); - return -1; - } - - osrfLogInfo(OSRF_LOG_MARK, "oils_fetch connecting to database. host=%s, " - "port=%s, user=%s, pw=%s, db=%s", host, port, user, pw, db ); - - if(host) dbi_conn_set_option(dbhandle, "host", host ); - if(port) dbi_conn_set_option_numeric( dbhandle, "port", atoi(port) ); - if(user) dbi_conn_set_option(dbhandle, "username", user); - if(pw) dbi_conn_set_option(dbhandle, "password", pw ); - if(db) dbi_conn_set_option(dbhandle, "dbname", db ); - - free(user); - free(host); - free(port); - free(db); - free(pw); - - if (dbi_conn_connect(dbhandle) < 0) { - const char* err; - dbi_conn_error(dbhandle, &err); - osrfLogError( OSRF_LOG_MARK, "Error connecting to database: %s", err); - return -1; - } - - osrfLogInfo(OSRF_LOG_MARK, "%s successfully connected to the database", MODULENAME); - - return 0; -} - - - -int oilsFetchDoRetrieve( osrfMethodContext* ctx ) { - - OSRF_METHOD_VERIFY_CONTEXT(ctx); - - char* id = jsonObjectToSimpleString(jsonObjectGetIndex(ctx->params, 0)); - char* meth = strdup(ctx->method->name); - char* strtk; - - strtok_r(meth, ".", &strtk); /* open-ils */ - strtok_r(NULL, ".", &strtk); /* fetch */ - char* schema = strtok_r(NULL, ".", &strtk); - char* object = strtok_r(NULL, ".", &strtk); - - osrfLogDebug(OSRF_LOG_MARK, "%s retrieving %s.%s " - "object with id %s", MODULENAME, schema, object, id ); - - /* construct the SQL */ - char sql[256]; - snprintf( sql, sizeof(sql), "select * from %s.%s where id = %s;", schema, object, id ); - - /* find the object hint from the api name */ - char hintbuf[256]; - snprintf(hintbuf, sizeof(hintbuf), "%s.%s", schema, object ); - char* hint = osrfHashGet( fmClassMap, hintbuf ); - - osrfLogDebug(OSRF_LOG_MARK, "%s SQL = %s", MODULENAME, sql); - - dbi_result result = dbi_conn_queryf(dbhandle, sql); - - if(result) { - - /* there should be one row at the most */ - dbi_result_next_row(result); - - /* JSONify the result */ - jsonObject* obj = oilsFetchMakeJSON( result, hint ); - - /* clean up the query */ - dbi_result_free(result); - - osrfAppRespondComplete( ctx, obj ); - jsonObjectFree(obj); - - } else { - - osrfLogDebug(OSRF_LOG_MARK, "%s returned no results for query %s", MODULENAME, sql); - osrfAppRespondComplete( ctx, oilsFetchNULL ); - } - - free(id); - free(meth); - return 0; -} - - -jsonObject* oilsFetchMakeJSON( dbi_result result, char* hint ) { - if(!(result && hint)) return NULL; - - jsonObject* object = jsonParseString("[]"); - jsonObjectSetClass(object, hint); - - int attr; - int fmIndex; - int columnIndex = 1; - unsigned short type; - const char* columnName; - - /* cycle through the column list */ - while( (columnName = dbi_result_get_field_name(result, columnIndex++)) ) { - - /* determine the field type and storage attributes */ - type = dbi_result_get_field_type(result, columnName); - attr = dbi_result_get_field_attribs(result, columnName); - - /* fetch the fieldmapper index */ - if( (fmIndex = fm_ntop(hint, (char*) columnName)) < 0 ) continue; - - switch( type ) { - - case DBI_TYPE_INTEGER : - - if( attr & DBI_INTEGER_SIZE8 ) - jsonObjectSetIndex( object, fmIndex, - jsonNewNumberObject(dbi_result_get_longlong(result, columnName))); - else - jsonObjectSetIndex( object, fmIndex, - jsonNewNumberObject(dbi_result_get_long(result, columnName))); - - break; - - case DBI_TYPE_DECIMAL : - jsonObjectSetIndex( object, fmIndex, - jsonNewNumberObject(dbi_result_get_double(result, columnName))); - break; - - case DBI_TYPE_STRING : - jsonObjectSetIndex( object, fmIndex, - jsonNewObject(dbi_result_get_string(result, columnName))); - break; - - case DBI_TYPE_DATETIME : - jsonObjectSetIndex( object, fmIndex, - jsonNewNumberObject(dbi_result_get_datetime(result, columnName))); - break; - - case DBI_TYPE_BINARY : - osrfLogError( OSRF_LOG_MARK, - "Can't do binary at column %s : index %d", columnName, columnIndex - 1); - } - } - - return object; -} - - - diff --git a/Open-ILS/src/c-apps/oils_idl-core.c b/Open-ILS/src/c-apps/oils_idl-core.c index 8b8184daac..bf6c9afb13 100644 --- a/Open-ILS/src/c-apps/oils_idl-core.c +++ b/Open-ILS/src/c-apps/oils_idl-core.c @@ -346,7 +346,7 @@ char * oilsIDL_pton (const char* classname, int pos) { while ( (f = osrfHashIteratorNext( itr )) ) { if ( atoi(osrfHashGet(f, "array_position")) == pos ) { - ret = strdup(itr->current); + ret = strdup(osrfHashIteratorKey(itr)); break; } } diff --git a/Open-ILS/src/cgi-bin/lib-setup.cgi b/Open-ILS/src/cgi-bin/lib-setup.cgi index 71b949aa4a..502d26a861 100755 --- a/Open-ILS/src/cgi-bin/lib-setup.cgi +++ b/Open-ILS/src/cgi-bin/lib-setup.cgi @@ -298,7 +298,7 @@ if (my $action = $cgi->param('action')) { print Tr( "" ); print "*". - "You must hide every OU you want hidden, not just an anscestor!"; + "You must hide every OU you want hidden, not just an ancestor!"; #------------------------------------------------------------------------- # Hours of operation form @@ -349,7 +349,7 @@ if (my $action = $cgi->param('action')) { # Address edit form #------------------------------------------------------------------------- - print "

Adresses for ".$node->name."

"; + print "

Addresses for ".$node->name."

"; print ""; my %addrs = ( ill_address => 'ILL Address', holds_address => 'Consortial Holds Address', diff --git a/Open-ILS/src/extras/Makefile.install b/Open-ILS/src/extras/Makefile.install index bfc3b48a0a..245ced7481 100644 --- a/Open-ILS/src/extras/Makefile.install +++ b/Open-ILS/src/extras/Makefile.install @@ -3,12 +3,14 @@ # # Makefile to install prerequisites for OpenSRF and Evergreen # -# Currently supports Debian (etch) and Gentoo. Installs Perl prereqs, +# Currently supports Debian (etch), Ubuntu (gutsy) and Gentoo. Installs Perl prereqs, # libjs with Perl wrapper, libdbi, libdbi-drivers, and libyaz # # usage: # make -f Makefile.install debian # - or - +# make -f Makefile.install ubuntu +# - or - # make -f Makefile.install gentoo # # Notes: @@ -38,9 +40,9 @@ JS_INSTALL_PREFIX=/usr/ # The libdbi sources can be fetched from sourceforge.net. They are stored on # the open-ils.org site now for ease of direct linking -LIBDBI=libdbi-0.8.2 -LIBDBI_DRIVERS=libdbi-drivers-0.8.2-1 -LIBDBI_HOST=http://open-ils.org/~erickson/evergreen +LIBDBI=libdbi-0.8.3 +LIBDBI_DRIVERS=libdbi-drivers-0.8.3 +LIBDBI_HOST=http://open-ils.org/~denials/evergreen YAZ=yaz-2.1.56 YAZ_HOST=http://ftp.indexdata.dk/pub/yaz @@ -51,8 +53,8 @@ DEBS = \ syslog-ng\ psmisc\ ntpdate\ + less\ memcached\ - postgresql-client\ libxml2-dev\ libmodule-build-perl\ libexpat1-dev\ @@ -96,8 +98,27 @@ DEBS = \ libtext-csv-perl\ libspreadsheet-writeexcel-perl\ libtie-ixhash-perl\ - python-setuptools - + python-dev\ + python-setuptools\ + libfreezethaw-perl\ + libbusiness-creditcard-perl\ + libbusiness-onlinepayment-perl\ + libbusiness-onlinepayment-authorizenet-perl + + +PGSQL_DEBIAN = \ + postgresql-8.1\ + postgresql-client-8.1\ + postgresql-contrib-8.1\ + postgresql-plperl-8.1\ + postgresql-server-dev-8.1 + +PGSQL_UBUNTU = \ + postgresql-8.2\ + postgresql-client-8.2\ + postgresql-contrib-8.2\ + postgresql-plperl-8.2\ + postgresql-server-dev-8.2 GENTOOS = \ vim\ @@ -132,9 +153,10 @@ GENTOOS = \ dev-perl/libwww-perl\ dev-perl/Template-Toolkit\ dev-perl/Error\ - dev-perl/Text-CSV_XS\ - dev-perl/Spreadsheet-WriteExcel\ - dev-perl/Tie-IxHash + dev-perl/Text-CSV_XS\ + dev-perl/Spreadsheet-WriteExcel\ + dev-perl/Tie-IxHash\ + dev-perl/FreezeThaw GENTOO_RC = \ ejabberd\ @@ -146,7 +168,7 @@ GENTOO_PERL = \ Class::DBI::AbstractSearch\ MARC::Record \ Net::Z3950::ZOOM \ - Text::CSV + Text::CSV DEB_APACHE_MODS = \ expires\ @@ -163,7 +185,10 @@ CPAN_MODULES = \ TMTM/Class-DBI-0.96.tar.gz \ RHANDOM/Net-Server-0.90.tar.gz \ MARC::Charset MARC::File::XML\ - Net::Z3950::ZOOM + JSON::XS\ + SRU \ + Net::Z3950::ZOOM \ + Business::CreditCard::Object # ---------------------------------------------------------------------------- @@ -175,10 +200,12 @@ all: # these should be the same for any distro install: install_yaz install_cpan install_js_sm install_libdbi -debian: install_debs install debian_sys_config +debian: install_pgsql_debian install_debs install debian_sys_config gentoo: install_gentoos install_gentoo_rc install_gentoo_perl install +ubuntu: install_pgsql_ubuntu install_debs install debian_sys_config + # - COMMON TARGETS --------------------------------------------------------- @@ -242,7 +269,11 @@ debian_sys_config: install_debs: apt-get install $(DEBS) +install_pgsql_debian: + apt-get install $(PGSQL_DEBIAN) +install_pgsql_ubuntu: + apt-get install $(PGSQL_UBUNTU) # ------------------------------------------------------------------ # - GENTOO --------------------------------------------------------- @@ -259,4 +290,3 @@ install_gentoo_perl: # ------------------------------------------------------------------ - diff --git a/Open-ILS/src/extras/autogen.sh b/Open-ILS/src/extras/autogen.sh index 8804b2b693..cb266b46e1 100755 --- a/Open-ILS/src/extras/autogen.sh +++ b/Open-ILS/src/extras/autogen.sh @@ -1,6 +1,49 @@ #!/bin/bash +# ----------------------------------------------------------------------- +# Copyright (C) 2005-2008 Georgia Public Library Service +# Bill Erickson +# +# 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. +# ----------------------------------------------------------------------- + # vim:noet:ts=4 +# --------------------------------------------------------------------------- +# Make sure we're running as the correct user +# --------------------------------------------------------------------------- +[ $(whoami) != 'opensrf' ] && echo 'Must run as user "opensrf"' && exit; + +function usage { + echo ""; + echo "usage: $0 [-u] -c "; + echo ""; + echo "Mandatory parameters:"; + echo -e " -c\t\tfull path to C configuration file (opensrf_core.xml)"; + echo ""; + echo "Optional parameters:"; + echo -e " -u\t\tupdate proximity of library sites in organization tree"; + echo -e " \t\t(this is expensive for a large organization tree)"; + echo ""; + echo "Examples:"; + echo ""; + echo " Update organization tree:"; + echo " $0 -c /openils/conf/opensrf_core.xml"; + echo " $0 /openils/conf/opensrf_core.xml"; + echo ""; + echo " Update organization tree and refresh proximity:"; + echo " $0 -u -c /openils/conf/opensrf_core.xml"; + echo ""; + exit; +} + ( BASEDIR=${0%/*} @@ -13,13 +56,26 @@ cd "$BASEDIR" CONFIG="$1"; -[ -z "$CONFIG" ] && echo "usage: $0 " && exit; +# --------------------------------------------------------------------------- +# Load the command line options and set the global vars +# --------------------------------------------------------------------------- +while getopts "c:u h" flag; do + case $flag in + "c") CONFIG="$OPTARG";; + "u") PROXIMITY="REFRESH";; + "h") usage;; + esac; +done + +[ -z "$CONFIG" ] && usage; JSDIR="/openils/var/web/opac/common/js/"; +FMDOJODIR="/openils/var/web/js/dojo/fieldmapper/"; SLIMPACDIR="/openils/var/web/opac/extras/slimpac/"; echo "Updating fieldmapper"; perl fieldmapper.pl "$CONFIG" > "$JSDIR/fmall.js"; +cp "$JSDIR/fmall.js" "$FMDOJODIR/" echo "Updating web_fieldmapper"; perl fieldmapper.pl "$CONFIG" "web_core" > "$JSDIR/fmcore.js"; @@ -29,7 +85,19 @@ perl org_tree_js.pl "$CONFIG" > "$JSDIR/OrgTree.js"; echo "Updating OrgTree HTML"; perl org_tree_html_options.pl "$CONFIG" "$SLIMPACDIR/lib_list.inc"; +cp "$JSDIR/OrgTree.js" "$FMDOJODIR/" + +echo "Updating Search Groups"; +perl org_lasso_js.pl "$CONFIG" > "$JSDIR/OrgLasso.js"; +cp "$JSDIR/OrgLasso.js" "$FMDOJODIR/" + +if [ "$PROXIMITY" ] +then + echo "Refreshing proximity of org units"; + perl org_tree_proximity.pl "$CONFIG"; +fi +echo ""; echo "Done"; ) diff --git a/Open-ILS/src/extras/ils_events.xml b/Open-ILS/src/extras/ils_events.xml index a2b315d311..68845df213 100644 --- a/Open-ILS/src/extras/ils_events.xml +++ b/Open-ILS/src/extras/ils_events.xml @@ -734,6 +734,12 @@ + + The requested item is already marked as lost + + + + diff --git a/Open-ILS/src/extras/import/build-oils-db.sh b/Open-ILS/src/extras/import/build-oils-db.sh index b6aa3281cf..691ce9fe95 100755 --- a/Open-ILS/src/extras/import/build-oils-db.sh +++ b/Open-ILS/src/extras/import/build-oils-db.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash if [ "_$4" == "_" ]; then echo "Usage:" echo " $0 {Open-ILS-driver} {db-host} {db-port} {db-name} {db-user} {db-password} [db-version]" diff --git a/Open-ILS/src/extras/import/marc2bre.pl b/Open-ILS/src/extras/import/marc2bre.pl index 7f8323de60..b6c658b3d7 100755 --- a/Open-ILS/src/extras/import/marc2bre.pl +++ b/Open-ILS/src/extras/import/marc2bre.pl @@ -22,8 +22,8 @@ use DBI; #MARC::Charset->ignore_errors(1); -my ($id_field, $recid, $user, $config, $idlfile, $marctype, $keyfile, $dontuse_file, $enc, $force_enc, @files, @trash_fields, $quiet) = - ('', 0, 1, '/openils/conf/opensrf_core.xml', '/openils/conf/fm_IDL.xml', 'USMARC'); +my ($id_field, $id_subfield, $recid, $user, $config, $idlfile, $marctype, $keyfile, $dontuse_file, $enc, $force_enc, @files, @trash_fields, $quiet) = + ('', 'a', 0, 1, '/openils/conf/opensrf_core.xml', '/openils/conf/fm_IDL.xml', 'USMARC'); my ($db_driver,$db_host,$db_name,$db_user,$db_pw) = ('Pg','localhost','evergreen','postgres','postgres'); @@ -32,6 +32,7 @@ GetOptions( 'marctype=s' => \$marctype, 'startid=i' => \$recid, 'idfield=s' => \$id_field, + 'idsubfield=s' => \$id_subfield, 'user=s' => \$user, 'encoding=s' => \$enc, 'hard_encoding' => \$force_enc, @@ -143,11 +144,12 @@ while ( try { $rec = $batch->next } otherwise { $rec = -1 } ) { if ($field->is_control_field) { $id = $field->data; } else { - $id = $field->subfield('a'); + $id = $field->subfield($id_subfield); } $id =~ s/\D+//gso; } + $id = '' if (exists $dontuse_id{$id}); } if (!$id) { @@ -157,7 +159,7 @@ while ( try { $rec = $batch->next } otherwise { $rec = -1 } ) { if ($keyfile) { if (my $tcn = $keymap{$id}) { $rec->delete_field( $_ ) for ($rec->field($id_field)); - $rec->append_fields( MARC::Field->new( $id_field, '', '', 'a', $tcn ) ); + $rec->append_fields( MARC::Field->new( $id_field, '', '', $id_subfield, $tcn ) ); } else { $count++; next; @@ -165,9 +167,9 @@ while ( try { $rec = $batch->next } otherwise { $rec = -1 } ) { } my $tcn; - ($rec, $tcn) = preprocess($rec); + ($rec, $tcn) = preprocess($rec, $id); - $tcn->add_subfields(c => $id); + $tcn->add_subfields(c => $id); $rec->delete_field( $_ ) for ($rec->field($id_field)); $rec->append_fields( $tcn ); @@ -211,13 +213,16 @@ while ( try { $rec = $batch->next } otherwise { $rec = -1 } ) { sub preprocess { my $rec = shift; + my $id = shift; - my ($id, $source, $value) = ('','',''); + my ($source, $value) = ('',''); + + $id = '' if (exists $dontuse_id{$id}); if (!$id) { my $f = $rec->field('001'); $id = $f->data if ($f); - $id = '' if (exists $dontuse_id{$id}); + $id = '' if (exists $dontuse_id{$id}); } if (!$id || exists $dontuse_id{$source.$id}) { @@ -261,7 +266,7 @@ sub preprocess { } if ($id && exists $dontuse_id{$id}) { - warn "\n!!! ID $id is already in use\n"; + warn "\n!!! TCN $id is already in use. Using the record ID ($recid) as a system-generated TCN.\n"; $id = ''; } diff --git a/Open-ILS/src/extras/oils_requestor.c b/Open-ILS/src/extras/oils_requestor.c index bacbf5677f..53effc2632 100644 --- a/Open-ILS/src/extras/oils_requestor.c +++ b/Open-ILS/src/extras/oils_requestor.c @@ -22,9 +22,10 @@ int main( int argc, char* argv[] ) { char* config = NULL; char* context = NULL; char* idl_filename = NULL; + char* hostname = NULL; char* request; - while( (c = getopt( argc, argv, "f:u:p:s:c:i:" )) != -1 ) { + while( (c = getopt( argc, argv, "f:u:p:s:c:i:h:" )) != -1 ) { switch(c) { case '?': return -1; case 'f': config = strdup(optarg); break; @@ -33,19 +34,10 @@ int main( int argc, char* argv[] ) { case 'p': password = strdup(optarg); break; case 's': script = strdup(optarg); break; case 'i': idl_filename = strdup(optarg); break; + case 'h': hostname = strdup(optarg); break; } } - if (!idl_filename) { - fprintf(stderr, "IDL file not provided. Exiting...\n"); - return -1; - } - - if (!oilsInitIDL( idl_filename )) { - fprintf(stderr, "IDL file could not be loaded. Exiting...\n"); - return -1; - } - if(!(config && context)) { fprintf(stderr, "Config or config context not provided. Exiting...\n"); return -1; @@ -56,6 +48,19 @@ int main( int argc, char* argv[] ) { return 1; } + if(!idl_filename) { + if(!hostname) { + fprintf(stderr, "We need an IDL file name or a settings server hostname...\n"); + return 1; + } + osrf_settings_retrieve(hostname); + } + + if (!oilsInitIDL( idl_filename )) { + fprintf(stderr, "IDL file could not be loaded. Exiting...\n"); + return -1; + } + printf("Connected to OpenSRF network...\n"); if( username && password && @@ -76,6 +81,7 @@ int main( int argc, char* argv[] ) { free(script); free(authtoken); free(idl_filename); + osrf_settings_free_host_config(NULL); return 1; } diff --git a/Open-ILS/src/extras/org_lasso_js.pl b/Open-ILS/src/extras/org_lasso_js.pl new file mode 100644 index 0000000000..e99d1241b8 --- /dev/null +++ b/Open-ILS/src/extras/org_lasso_js.pl @@ -0,0 +1,34 @@ +#!/usr/bin/perl +use strict; use warnings; + +# ------------------------------------------------------------ +# turns the actor.org_lasso table into a js file +# ------------------------------------------------------------ + +use OpenSRF::System; +use OpenILS::Utils::Fieldmapper; +use OpenSRF::Utils::SettingsClient; +use OpenSRF::Utils::JSON; + +die "usage: perl org_tree_js.pl " unless $ARGV[0]; +OpenSRF::System->bootstrap_client(config_file => $ARGV[0]); + +Fieldmapper->import(IDL => OpenSRF::Utils::SettingsClient->new->config_value("IDL")); + +# must be loaded after the IDL is parsed +require OpenILS::Utils::CStoreEditor; + +# fetch the org_unit's and org_unit_type's +my $e = OpenILS::Utils::CStoreEditor->new; +my $lassos = $e->request( + 'open-ils.cstore.direct.actor.org_lasso.search.atomic', + {id => {"!=" => undef}}, + {order_by => {lasso => 'name'}} +); + +print + "var _lasso = [\n new lasso(" . + join( "),\n new lasso(", map { OpenSRF::Utils::JSON->perl2JSON( bless($_, 'ARRAY') ) } @$lassos ) . + ")\n]; /* Org Search Groups (Lassos) */ \n"; + + diff --git a/Open-ILS/src/extras/org_tree_js.pl b/Open-ILS/src/extras/org_tree_js.pl index fab85fa7e9..a867650dfa 100644 --- a/Open-ILS/src/extras/org_tree_js.pl +++ b/Open-ILS/src/extras/org_tree_js.pl @@ -24,8 +24,12 @@ $cache->delete_cache('orgtree'); # fetch the org_unit's and org_unit_type's my $e = OpenILS::Utils::CStoreEditor->new; -my $tree = $e->retrieve_all_actor_org_unit; my $types = $e->retrieve_all_actor_org_unit_type; +my $tree = $e->request( + 'open-ils.cstore.direct.actor.org_unit.search.atomic', + {id => {"!=" => undef}}, + {order_by => {aou => 'name'}} +); sub val { diff --git a/Open-ILS/src/extras/org_tree_proximity.pl b/Open-ILS/src/extras/org_tree_proximity.pl new file mode 100644 index 0000000000..97a435f505 --- /dev/null +++ b/Open-ILS/src/extras/org_tree_proximity.pl @@ -0,0 +1,40 @@ +#!/usr/bin/perl +# ----------------------------------------------------------------------- +# Copyright (C) 2008 Laurentian University +# Dan Scott +# +# 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. +# ----------------------------------------------------------------------- + +# calculate the proximity of organizations in the organization tree + +# vim:noet:ts=4:sw=4 + +use OpenSRF::AppSession; +use OpenSRF::System; +use OpenILS::Utils::Fieldmapper; +use OpenSRF::Utils::SettingsClient; + +die "usage: perl org_tree_proximity.pl " unless $ARGV[0]; +OpenSRF::System->bootstrap_client(config_file => $ARGV[0]); + +Fieldmapper->import(IDL => OpenSRF::Utils::SettingsClient->new->config_value("IDL")); + +my $ses = OpenSRF::AppSession->create("open-ils.storage"); +my $result = $ses->request("open-ils.storage.actor.org_unit.refresh_proximity"); + +if ($result) { + print "Successfully updated the organization proximity"; +} else { + print "Failed to update the organiziation proximity"; +} + +$ses->disconnect(); diff --git a/Open-ILS/src/javascript/backend/circ/circ_lib.js b/Open-ILS/src/javascript/backend/circ/circ_lib.js index 5cad8b40c9..621e45363e 100644 --- a/Open-ILS/src/javascript/backend/circ/circ_lib.js +++ b/Open-ILS/src/javascript/backend/circ/circ_lib.js @@ -43,6 +43,7 @@ var currentLocation = environment.location; var holdRequestLib = environment.requestLib; var holdPickupLib = environment.pickupLib; /* hold pickup lib */ var requestor = environment.requestor || patron; +var newHold = environment.newHold; @@ -204,7 +205,12 @@ function hasCommonAncestor( org1, org2, depth ) { return false; } - +/* returns a dictionary of circmod : count for checked out items */ +function checkoutsByCircModifier(userid) { + var key = scratchKey(); + __OILS_FUNC_userCircsByCircmod(scratchPad(key), userid); + return getScratch(key); +} /* useful for testing */ function die(msg) { diff --git a/Open-ILS/src/javascript/backend/circ/circ_permit_hold.js b/Open-ILS/src/javascript/backend/circ/circ_permit_hold.js index 142c0527bb..942aacedd4 100644 --- a/Open-ILS/src/javascript/backend/circ/circ_permit_hold.js +++ b/Open-ILS/src/javascript/backend/circ/circ_permit_hold.js @@ -18,14 +18,20 @@ if( !isTrue(copy.circulate) ) var config = findGroupConfig(patronProfile); + if( config ) { /* see if they have too many items out */ - var limit = config.maxHolds; - var count = userHoldCount(patron.id); - if( limit >= 0 && count >= limit ) { - log_info("patron has " + count + " open holds"); - result.events.push('MAX_HOLDS'); + if(newHold) { + log_info("This is a new hold, checking maxHolds..."); + var limit = config.maxHolds; + var count = userHoldCount(patron.id); + if( limit >= 0 && count >= limit ) { + log_info("patron has " + count + " open holds"); + result.events.push('MAX_HOLDS'); + } + } else { + log_info("Ignoring maxHolds on existing hold..."); } } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm b/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm index eda27d68ab..a38ad7e005 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm @@ -78,39 +78,42 @@ sub set_user_settings { } - __PACKAGE__->register_method( method => "set_ou_settings", api_name => "open-ils.actor.org_unit.settings.update", ); sub set_ou_settings { - my( $self, $client, $user_session, $ouid, $settings ) = @_; - - my( $staff, $evt ) = $apputils->checkses( $user_session ); - return $evt if $evt; - $evt = $apputils->check_perms( $staff->id, $ouid, 'UPDATE_ORG_SETTING' ); - return $evt if $evt; + my( $self, $client, $auth, $org_id, $settings ) = @_; - my @params; - for my $set (keys %$settings) { - - my $json = OpenSRF::Utils::JSON->perl2JSON($$settings{$set}); - $logger->activity("updating org_unit.setting: $ouid : $set : $json"); + my $e = new_editor(authtoken => $auth, xact => 1); + return $e->die_event unless $e->checkauth; + return $e->die_event unless $e->allowed('UPDATE_ORG_SETTING', $org_id); - push( @params, - { org_unit => $ouid, name => $set }, - { value => $json } ); - } + for my $name (keys %$settings) { + my $val = $$settings{$name}; + my $set = $e->search_actor_org_unit_setting({org_unit => $org_id, name => $name})->[0]; - my $ses = $U->start_db_session(); - my $stat = $ses->request( - 'open-ils.storage.direct.actor.org_unit_setting.merge', @params )->gather(1); - $U->commit_db_session($ses); + if(defined $val) { + $val = OpenSRF::Utils::JSON->perl2JSON($val); + if($set) { + $set->value($val); + $e->update_actor_org_unit_setting($set) or return $e->die_event; + } else { + $set = Fieldmapper::actor::org_unit_setting->new; + $set->org_unit($org_id); + $set->name($name); + $set->value($val); + $e->create_actor_org_unit_setting($set) or return $e->die_event; + } + } elsif($set) { + $e->delete_actor_org_unit_setting($set) or return $e->die_event; + } + } - return $stat; + $e->commit; + return 1; } - my $fetch_user_settings; my $fetch_ou_settings; @@ -119,21 +122,21 @@ __PACKAGE__->register_method( api_name => "open-ils.actor.patron.settings.retrieve", ); sub user_settings { - my( $self, $client, $user_session, $uid, $setting ) = @_; - - my( $staff, $user, $evt ) = - $apputils->checkses_requestor( $user_session, $uid, 'VIEW_USER' ); - return $evt if $evt; + my( $self, $client, $auth, $user_id, $setting ) = @_; - $logger->debug("User " . $staff->id . " fetching user $uid\n"); - my $s = $apputils->simplereq( - 'open-ils.cstore', - 'open-ils.cstore.direct.actor.user_setting.search.atomic', { usr => $uid } ); + my $e = new_editor(authtoken => $auth); + return $e->event unless $e->checkauth; + + my $patron = $e->retrieve_actor_user($user_id) or return $e->event; + if($e->requestor->id != $user_id) { + return $e->event unless $e->allowed('VIEW_USER', $patron->home_ou); + } + my $s = $e->search_actor_user_setting({usr => $user_id}); my $settings = { map { ( $_->name => OpenSRF::Utils::JSON->JSON2perl($_->value) ) } @$s }; - return $$settings{$setting} if $setting; - return $settings; + return $$settings{$setting} if $setting; + return $settings; } @@ -852,7 +855,7 @@ sub set_user_perms { $map->clear_id; } - next if (!$all || !grep { $_->perm eq $map->perm and $_->grantable == 1 and $_->depth <= $map->depth } @$perms); + next if (!$all || !grep { $_->perm eq $map->perm and $U->is_true($_->grantable) and $_->depth <= $map->depth } @$perms); #warn( "Updating permissions with method $method and session $ses and map $map" ); $logger->info( "Updating permissions with method $method and map $map" ); @@ -3041,9 +3044,5 @@ sub create_user_opt_in_at_org { } - - - - 1; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Actor/ClosedDates.pm b/Open-ILS/src/perlmods/OpenILS/Application/Actor/ClosedDates.pm index 5bf5c92029..e7601dfc5b 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Actor/ClosedDates.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Actor/ClosedDates.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Actor::ClosedDates; -use base 'OpenSRF::Application'; +use base 'OpenILS::Application'; use strict; use warnings; use OpenSRF::EX qw(:try); use OpenILS::Utils::Editor q/:funcs/; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm b/Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm index b93004a383..74ef5122ad 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Actor/Container.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Actor::Container; -use base 'OpenSRF::Application'; +use base 'OpenILS::Application'; use strict; use warnings; use OpenILS::Application::AppUtils; use OpenILS::Perm; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Actor/UserGroups.pm b/Open-ILS/src/perlmods/OpenILS/Application/Actor/UserGroups.pm index b2ec498521..2ca5965698 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Actor/UserGroups.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Actor/UserGroups.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Actor::UserGroups; -use base 'OpenSRF::Application'; +use base 'OpenILS::Application'; use strict; use warnings; use OpenILS::Application::AppUtils; use OpenILS::Utils::CStoreEditor q/:funcs/; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm b/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm index 326c1c3eb9..d3eeb1f562 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm @@ -769,8 +769,7 @@ __PACKAGE__->register_method( signature => q/ Merges a group of records @param auth The login session key - @param master The id of the record all other r - ecords should be merged into + @param master The id of the record all other records should be merged into @param records Array of records to be merged into the master record @return 1 on success, Event on error. / @@ -783,8 +782,44 @@ sub merge { my $editor = new_editor( requestor => $reqr, xact => 1 ); my $v = OpenILS::Application::Cat::Merge::merge_records($editor, $master, $records); return $v if $v; - $editor->finish; - return 1; + $editor->commit; + # tell the client the merge is complete, then merge the holds + $conn->respond_complete(1); + merge_holds($master, $records); + return undef; +} + +sub merge_holds { + my($master, $records) = @_; + return unless $master and @$records; + return if @$records == 1 and $master == $$records[0]; + + my $e = new_editor(xact=>1); + my $holds = $e->search_action_hold_request( + { cancel_time => undef, + fulfillment_time => undef, + hold_type => 'T', + target => $records + }, + {idlist=>1} + ); + + for my $hold_id (@$holds) { + + my $hold = $e->retrieve_action_hold_request($hold_id); + + $logger->info("Changing hold ".$hold->id. + " target from ".$hold->target." to $master in record merge"); + + $hold->target($master); + unless($e->update_action_hold_request($hold)) { + my $evt = $e->event; + $logger->error("Error updating hold ". $evt->textcode .":". $evt->desc .":". $evt->stacktrace); + } + } + + $e->commit; + return undef; } @@ -870,7 +905,7 @@ sub fleshed_volume_update { } # now update any attached copies - if( @$copies and !$vol->isdeleted ) { + if( $copies and @$copies and !$vol->isdeleted ) { $_->call_number($vol->id) for @$copies; $evt = update_fleshed_copies( $editor, $override, $vol, $copies, $delete_stats ); return $evt if $evt; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Cat/Merge.pm b/Open-ILS/src/perlmods/OpenILS/Application/Cat/Merge.pm index 77e596cba9..0c54a50598 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Cat/Merge.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Cat/Merge.pm @@ -1,6 +1,6 @@ use strict; use warnings; package OpenILS::Application::Cat::Merge; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use OpenSRF::Application; use OpenILS::Application::AppUtils; use OpenILS::Application::Cat::Utils; @@ -114,16 +114,15 @@ sub merge_records { $vol->edit_date('now'); $vol->record( $master ); $editor->update_asset_call_number($vol) - or return $editor->event; + or return $editor->die_event; } } # cycle through and delete the non-master records for my $rec (@recs) { - my ($record, $evt) = - $editor->retrieve_biblio_record_entry($rec); - return $evt if $evt; + my $record = $editor->retrieve_biblio_record_entry($rec) + or return $editor->die_event; $logger->debug("merge: seeing if record $rec needs to be deleted or un-deleted"); @@ -135,7 +134,7 @@ sub merge_records { $record->editor($reqr->id); $record->edit_date('now'); $editor->update_biblio_record_entry($record, {checkperm => 1}) - or return $editor->event; + or return $editor->die_event; } } else { @@ -144,7 +143,7 @@ sub merge_records { $record->editor($reqr->id); $record->edit_date('now'); $editor->update_biblio_record_entry($record, {checkperm => 1}) - or return $editor->event; + or return $editor->die_event; } } @@ -207,7 +206,7 @@ sub merge_volumes { $copy->call_number($bigcn); $copy->editor($editor->requestor->id); $copy->edit_date('now'); - $editor->update_asset_copy($copy) or return (undef, $editor->event); + $editor->update_asset_copy($copy) or return (undef, $editor->die_event); } } @@ -217,8 +216,9 @@ sub merge_volumes { $_->deleted('t'); $_->editor($editor->requestor->id); $_->edit_date('now'); - return (undef,$editor->event) unless $editor->allowed('UPDATE_VOLUME', $_->owning_lib); - $editor->update_asset_call_number($_) or return (undef, $editor->event); + return (undef,$editor->die_event) unless $editor->allowed('UPDATE_VOLUME', $_->owning_lib); + $editor->update_asset_call_number($_) or return (undef, $editor->die_event); + merge_volume_holds($editor, $bigcn, $_->id); } my ($mvol) = grep { $_->id == $bigcn } @$volumes; @@ -226,6 +226,32 @@ sub merge_volumes { return ($mvol); } +sub merge_volume_holds { + my($e, $master_id, $vol_id) = @_; + + my $holds = $e->search_action_hold_request( + { cancel_time => undef, + fulfillment_time => undef, + hold_type => 'V', + target => $vol_id + } + ); + + for my $hold (@$holds) { + + $logger->info("Changing hold ".$hold->id. + " target from ".$hold->target." to $master_id in volume merge"); + + $hold->target($master_id); + unless($e->update_action_hold_request($hold)) { + my $evt = $e->event; + $logger->error("Error updating hold ". $evt->textcode .":". $evt->desc .":". $evt->stacktrace); + } + } + + return undef; +} + 1; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm index 3bf9ff1ead..2076337490 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm @@ -257,6 +257,9 @@ sub new_set_circ_lost { $e->allowed('SET_CIRC_LOST', $circ->circ_lib) or return $e->die_event; + return OpenILS::Event->new('COPY_MARKED_LOST') + if $copy->status == OILS_COPY_STATUS_LOST; + # --------------------------------------------------------------------- # fetch the related org settings my $default_price = $U->ou_ancestor_setting_value( @@ -273,12 +276,10 @@ sub new_set_circ_lost { # --------------------------------------------------------------------- # move the copy into LOST status - unless( $copy->status == OILS_COPY_STATUS_LOST ) { - $copy->status(OILS_COPY_STATUS_LOST); - $copy->editor($e->requestor->id); - $copy->edit_date('now'); - $e->update_asset_copy($copy) or return $e->die_event; - } + $copy->status(OILS_COPY_STATUS_LOST); + $copy->editor($e->requestor->id); + $copy->edit_date('now'); + $e->update_asset_copy($copy) or return $e->die_event; # --------------------------------------------------------------------- # determine the appropriate item price to charge and create the billing @@ -336,6 +337,8 @@ sub reopen_xact { or return $e->die_event; } } + + return undef; } @@ -888,7 +891,7 @@ sub copy_details_barcode { my $e = new_editor(); my $cid = $e->search_asset_copy({barcode=>$barcode, deleted=>'f'}, {idlist=>1})->[0]; return $e->event unless $cid; - return $self->copy_details( $conn, $auth, $cid ); + return copy_details( $self, $conn, $auth, $cid ); } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm index f6383fbb43..d1109b49c9 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm @@ -1,6 +1,6 @@ package OpenILS::Application::Circ::Circulate; use strict; use warnings; -use base 'OpenSRF::Application'; +use base 'OpenILS::Application'; use OpenSRF::EX qw(:try); use OpenSRF::Utils::SettingsClient; use OpenSRF::Utils::Logger qw(:logger); diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/CopyLocations.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/CopyLocations.pm index f5c5dd259c..2952d2b9db 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/CopyLocations.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/CopyLocations.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Circ::CopyLocations; -use base 'OpenSRF::Application'; +use base 'OpenILS::Application'; use strict; use warnings; use Data::Dumper; $Data::Dumper::Indent = 0; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/HoldNotify.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/HoldNotify.pm index c78cfbaff7..7cb32831c2 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/HoldNotify.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/HoldNotify.pm @@ -15,7 +15,7 @@ package OpenILS::Application::Circ::HoldNotify; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; use OpenSRF::EX qw(:try); use vars q/$AUTOLOAD/; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm index 608d993a8d..97bf16f8ab 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm @@ -15,7 +15,7 @@ package OpenILS::Application::Circ::Holds; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; use OpenILS::Application::AppUtils; use Data::Dumper; @@ -113,16 +113,16 @@ sub create_hold { push( @events, OpenILS::Event->new('HOLD_EXISTS')) if @$existing; if( $t eq OILS_HOLD_TYPE_METARECORD ) - { $pevt = $e->event unless $e->checkperm($rid, $porg, 'MR_HOLDS'); } + { $pevt = $e->event unless $e->allowed('MR_HOLDS', $porg); } if( $t eq OILS_HOLD_TYPE_TITLE ) - { $pevt = $e->event unless $e->checkperm($rid, $porg, 'TITLE_HOLDS'); } + { $pevt = $e->event unless $e->allowed('TITLE_HOLDS', $porg); } if( $t eq OILS_HOLD_TYPE_VOLUME ) - { $pevt = $e->event unless $e->checkperm($rid, $porg, 'VOLUME_HOLDS'); } + { $pevt = $e->event unless $e->allowed('VOLUME_HOLDS', $porg); } if( $t eq OILS_HOLD_TYPE_COPY ) - { $pevt = $e->event unless $e->checkperm($rid, $porg, 'COPY_HOLDS'); } + { $pevt = $e->event unless $e->allowed('COPY_HOLDS', $porg); } return $pevt if $pevt; @@ -140,7 +140,7 @@ sub create_hold { $hold->requestor($e->requestor->id); $hold->request_lib($e->requestor->ws_ou); - $hold->selection_ou($recipient->home_ou) unless $hold->selection_ou; + $hold->selection_ou($hold->pickup_lib) unless $hold->selection_ou; $hold = $e->create_action_hold_request($hold) or return $e->event; } @@ -149,7 +149,7 @@ sub create_hold { $conn->respond_complete(1); for(@holds) { - next if $_->frozen; + next if $U->is_true($_->frozen); $U->storagereq( 'open-ils.storage.action.hold_request.copy_targeter', undef, $_->id ); @@ -359,7 +359,7 @@ sub user_hold_count { my $patron = $e->retrieve_actor_user($userid) or return $e->event; return $e->event unless $e->allowed('VIEW_HOLD', $patron->home_ou); - return $self->__user_hold_count($e, $userid); + return __user_hold_count($self, $e, $userid); } sub __user_hold_count { @@ -483,7 +483,7 @@ sub cancel_hold { $e->update_action_hold_request($hold) or return $e->event; - $self->delete_hold_copy_maps($e, $hold->id); + delete_hold_copy_maps($self, $e, $hold->id); $e->commit; return 1; @@ -518,6 +518,12 @@ sub update_hold { my $e = new_editor(authtoken=>$auth, xact=>1); return $e->die_event unless $e->checkauth; + my $orig_hold = $e->retrieve_action_hold_request($hold->id) + or return $e->die_event; + + # don't allow the user to be changed + return OpenILS::Event->new('BAD_PARAMS') if $hold->usr != $orig_hold->usr; + if($hold->usr ne $e->requestor->id) { # if the hold is for a different user, make sure the # requestor has the appropriate permissions @@ -526,12 +532,8 @@ sub update_hold { return $e->die_event unless $e->allowed('UPDATE_HOLD', $usr->home_ou); } - my $evt = $self->update_hold_if_frozen($e, $hold); - return $evt if $evt; - - $e->update_action_hold_request($hold) - or return $e->die_event; - + update_hold_if_frozen($self, $e, $hold, $orig_hold); + $e->update_action_hold_request($hold) or return $e->die_event; $e->commit; return $hold->id; } @@ -539,17 +541,22 @@ sub update_hold { # if the hold is frozen, this method ensures that the hold is not "targeted", # that is, it clears the current_copy and prev_check_time to essentiallly -# reset the hold +# reset the hold. If it is being activated, it runs the targeter in the background sub update_hold_if_frozen { - my($self, $e, $hold) = @_; - return undef if $hold->capture_time; - if($hold->frozen and ($hold->current_copy or $hold->prev_check_time)) { - $logger->info("clearing current_copy and check_time for frozen hold"); + my($self, $e, $hold, $orig_hold) = @_; + return if $hold->capture_time; + + if($U->is_true($hold->frozen)) { + $logger->info("clearing current_copy and check_time for frozen hold ".$hold->id); $hold->clear_current_copy; $hold->clear_prev_check_time; - $e->update_action_hold_request($hold) or return $e->die_event; + + } else { + if($U->is_true($orig_hold->frozen)) { + $logger->info("Running targeter on activated hold ".$hold->id); + $U->storagereq( 'open-ils.storage.action.hold_request.copy_targeter', undef, $hold->id ); + } } - return undef; } @@ -774,7 +781,7 @@ sub reset_hold { return $evt if $evt; ($reqr, $evt) = $U->checksesperm($auth, 'UPDATE_HOLD'); # XXX stronger permission return $evt if $evt; - $evt = $self->_reset_hold($reqr, $hold); + $evt = _reset_hold($self, $reqr, $hold); return $evt if $evt; return 1; } @@ -967,7 +974,6 @@ sub fetch_captured_holds { } } - __PACKAGE__->register_method( method => "check_title_hold", api_name => "open-ils.circ.title_hold.is_possible", @@ -989,10 +995,11 @@ sub check_title_hold { my $titleid = $params{titleid} ||""; my $volid = $params{volume_id}; my $copyid = $params{copy_id}; - my $mrid = $params{mrid} ||""; + my $mrid = $params{mrid} ||""; my $depth = $params{depth} || 0; my $pickup_lib = $params{pickup_lib}; my $hold_type = $params{hold_type} || 'T'; + my $selection_ou = $params{selection_ou} || $pickup_lib; my $e = new_editor(authtoken=>$authtoken); return $e->event unless $e->checkauth; @@ -1006,12 +1013,60 @@ sub check_title_hold { return OpenILS::Event->new('PATRON_BARRED') if $U->is_true($patron->barred); - my $rangelib = $params{range_lib} || $patron->home_ou; - my $request_lib = $e->retrieve_actor_org_unit($e->requestor->ws_ou) or return $e->event; - $logger->info("checking hold possibility with type $hold_type"); + my $soft_boundary = $U->ou_ancestor_setting_value($selection_ou, OILS_SETTING_HOLD_SOFT_BOUNDARY); + my $hard_boundary = $U->ou_ancestor_setting_value($selection_ou, OILS_SETTING_HOLD_HARD_BOUNDARY); + + if(defined $soft_boundary and $$params{depth} < $soft_boundary) { + # work up the tree and as soon as we find a potential copy, use that depth + # also, make sure we don't go past the hard boundary if it exists + + # our min boundary is the greater of user-specified boundary or hard boundary + my $min_depth = (defined $hard_boundary and $hard_boundary > $$params{depth}) ? + $hard_boundary : $$params{depth}; + + my $depth = $soft_boundary; + while($depth >= $min_depth) { + $logger->info("performing hold possibility check with soft boundary $depth"); + return {success => 1, depth => $depth} + if do_possibility_checks($e, $patron, $request_lib, $depth, %params); + $depth--; + } + return {success => 0}; + + } elsif(defined $hard_boundary and $$params{depth} < $hard_boundary) { + # there is no soft boundary, enforce the hard boundary if it exists + $logger->info("performing hold possibility check with hard boundary $hard_boundary"); + if(do_possibility_checks($e, $patron, $request_lib, $hard_boundary, %params)) { + return {success => 1, depth => $hard_boundary} + } else { + return {success => 0}; + } + + } else { + # no boundaries defined, fall back to user specifed boundary or no boundary + $logger->info("performing hold possibility check with no boundary"); + if(do_possibility_checks($e, $patron, $request_lib, $params{depth}, %params)) { + return {success => 1, depth => $hard_boundary}; + } else { + return {success => 0}; + } + } +} + +sub do_possibility_checks { + my($e, $patron, $request_lib, $depth, %params) = @_; + + my $titleid = $params{titleid} ||""; + my $volid = $params{volume_id}; + my $copyid = $params{copy_id}; + my $mrid = $params{mrid} ||""; + my $pickup_lib = $params{pickup_lib}; + my $hold_type = $params{hold_type} || 'T'; + my $selection_ou = $params{selection_ou} || $pickup_lib; + my $copy; my $volume; @@ -1035,12 +1090,12 @@ sub check_title_hold { or return $e->event; return _check_volume_hold_is_possible( - $volume, $title, $rangelib, $depth, $request_lib, $patron, $e->requestor, $pickup_lib); + $volume, $title, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou); } elsif( $hold_type eq OILS_HOLD_TYPE_TITLE ) { return _check_title_hold_is_possible( - $titleid, $rangelib, $depth, $request_lib, $patron, $e->requestor, $pickup_lib); + $titleid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou); } elsif( $hold_type eq OILS_HOLD_TYPE_METARECORD ) { @@ -1048,49 +1103,12 @@ sub check_title_hold { my @recs = map { $_->source } @$maps; for my $rec (@recs) { return 1 if (_check_title_hold_is_possible( - $rec, $rangelib, $depth, $request_lib, $patron, $e->requestor, $pickup_lib)); + $rec, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou)); } return 0; } } - - -sub ___check_title_hold_is_possible { - my( $titleid, $rangelib, $depth, $request_lib, $patron, $requestor, $pickup_lib ) = @_; - - my $limit = 10; - my $offset = 0; - my $title; - - $logger->debug("Fetching ranged title tree for title $titleid, org $rangelib, depth $depth"); - - while( $title = $U->storagereq( - 'open-ils.storage.biblio.record_entry.ranged_tree', - $titleid, $rangelib, $depth, $limit, $offset ) ) { - - last unless - ref($title) and - ref($title->call_numbers) and - @{$title->call_numbers}; - - for my $cn (@{$title->call_numbers}) { - - $logger->debug("Checking callnumber ".$cn->id." for hold fulfillment possibility"); - - for my $copy (@{$cn->copies}) { - $logger->debug("Checking copy ".$copy->id." for hold fulfillment possibility"); - return 1 if verify_copy_for_hold( - $patron, $requestor, $title, $copy, $pickup_lib, $request_lib ); - $logger->debug("Copy ".$copy->id." for hold fulfillment possibility failed..."); - } - } - - $offset += $limit; - } - return 0; -} - my %prox_cache; sub _check_metarecord_hold_is_possible { @@ -1200,10 +1218,35 @@ sub _check_metarecord_hold_is_possible { return 0; } +sub create_ranged_org_filter { + my($e, $selection_ou, $depth) = @_; + + # find the orgs from which this hold may be fulfilled, + # based on the selection_ou and depth + + my $top_org = $e->search_actor_org_unit([ + {parent_ou => undef}, + {flesh=>1, flesh_fields=>{aou=>['ou_type']}}])->[0]; + my %org_filter; + + return () if $depth == $top_org->ou_type->depth; + + my $org_list = $U->storagereq('open-ils.storage.actor.org_unit.descendants.atomic', $selection_ou, $depth); + %org_filter = (circ_lib => []); + push(@{$org_filter{circ_lib}}, $_->id) for @$org_list; + + $logger->info("hold org filter at depth $depth and selection_ou ". + "$selection_ou created list of @{$org_filter{circ_lib}}"); + + return %org_filter; +} + + sub _check_title_hold_is_possible { - my( $titleid, $rangelib, $depth, $request_lib, $patron, $requestor, $pickup_lib ) = @_; + my( $titleid, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou ) = @_; - my $e = new_editor(); + my $e = new_editor(); + my %org_filter = create_ranged_org_filter($e, $selection_ou, $depth); # this monster will grab the id and circ_lib of all of the "holdable" copies for the given record my $copies = $e->json_query( @@ -1227,7 +1270,7 @@ sub _check_title_hold_is_possible { } }, where => { - '+acp' => { circulate => 't', deleted => 'f', holdable => 't' } + '+acp' => { circulate => 't', deleted => 'f', holdable => 't', %org_filter } } } ); @@ -1313,8 +1356,9 @@ sub _check_title_hold_is_possible { sub _check_volume_hold_is_possible { - my( $vol, $title, $rangelib, $depth, $request_lib, $patron, $requestor, $pickup_lib ) = @_; - my $copies = new_editor->search_asset_copy({call_number => $vol->id}); + my( $vol, $title, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou ) = @_; + my %org_filter = create_ranged_org_filter(new_editor(), $selection_ou, $depth); + my $copies = new_editor->search_asset_copy({call_number => $vol->id, %org_filter}); $logger->info("checking possibility of volume hold for volume ".$vol->id); for my $copy ( @$copies ) { return 1 if verify_copy_for_hold( @@ -1335,7 +1379,8 @@ sub verify_copy_for_hold { title => $title, title_descriptor => $title->fixed_fields, # this is fleshed into the title object pickup_lib => $pickup_lib, - request_lib => $request_lib + request_lib => $request_lib, + new_hold => 1 } ); return 0; @@ -1366,7 +1411,7 @@ sub find_nearest_permitted_hold { for my $h (@$old_holds) { return ($h) if $h->hold_type eq 'R'; } - my $hold_stall_interval = $U->ou_ancestor_setting_value($user->ws_ou, 'circ.hold_stalling.soft'); + my $hold_stall_interval = $U->ou_ancestor_setting_value($user->ws_ou, OILS_SETTING_HOLD_SOFT_STALL); $logger->info("circulator: searching for best hold at org ".$user->ws_ou. " and copy $bc with a hold stalling interval of ". ($hold_stall_interval || "(none)")); diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm index a0525b2194..c8a1129317 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm @@ -15,7 +15,7 @@ package OpenILS::Application::Circ::Money; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; use OpenILS::Application::AppUtils; my $apputils = "OpenILS::Application::AppUtils"; @@ -86,7 +86,7 @@ sub make_payments { $total_paid += $amount; - $trans = $self->fetch_mbts($client, $login, $transid); + $trans = fetch_mbts($self, $client, $login, $transid); return $trans if $U->event_code($trans); $logger->info("payment: processing transaction [$transid] with balance_owed = ". @@ -316,6 +316,11 @@ sub create_grocery_bill { $apputils->commit_db_session($session); + my $e = new_editor(xact=>1); + $evt = _check_open_xact($e, $transid); + return $evt if $evt; + $e->commit; + return $transid; } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/NonCat.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/NonCat.pm index ea3b8f0b56..4c1226b129 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/NonCat.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/NonCat.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Circ::NonCat; -use base 'OpenSRF::Application'; +use base 'OpenILS::Application'; use strict; use warnings; use OpenSRF::EX qw(:try); use Data::Dumper; @@ -58,39 +58,6 @@ __PACKAGE__->register_method( event on failure /); -sub __create_noncat_type { - my( $self, $client, $authtoken, $name, $orgId, $interval, $inhouse ) = @_; - my( $staff, $evt ) = $U->checkses($authtoken); - return $evt if $evt; - - # grab all of "my" non-cat types and see if one with - # the requested name already exists - my $types = $self->retrieve_noncat_types_all($client, $orgId); - for(@$types) { - if( $_->name eq $name ) { - return OpenILS::Event->new('NON_CAT_TYPE_EXISTS', payload => $name); - } - } - - $evt = $U->check_perms( $staff->id, $orgId, 'CREATE_NON_CAT_TYPE' ); - return $evt if $evt; - - my $type = Fieldmapper::config::non_cataloged_type->new; - $type->name($name); - $type->owning_lib($orgId); - $type->circ_duration($interval); - $type->in_house( ($inhouse) ? 't' : 'f' ); - - my $id = $U->simplereq( - 'open-ils.storage', - 'open-ils.storage.direct.config.non_cataloged_type.create', $type ); - - return $U->DB_UPDATE_FAILED($type) unless $id; - $type->id($id); - return $type; -} - - sub create_noncat_type { my( $self, $client, $authtoken, $name, $orgId, $interval, $inhouse ) = @_; @@ -100,7 +67,7 @@ sub create_noncat_type { # grab all of "my" non-cat types and see if one with # the requested name already exists - my $types = $self->retrieve_noncat_types_all($client, $orgId); + my $types = retrieve_noncat_types_all($self, $client, $orgId); for(@$types) { if( $_->name eq $name ) { $e->rollback; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm index 41ab511ee0..af8ead5b97 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm @@ -390,6 +390,45 @@ sub insert_user_funcs { return $val; } ); + + $runner->insert(__OILS_FUNC_userCircsByCircmod => + sub { + my( $write_key, $userid ) = @_; + use OpenSRF::Utils::JSON; + + # this bug ugly thing generates a count of checkouts by circ_modifier + my $query = { + "select" => { + "acp" => ["circ_modifier"], + "circ"=>[{ + "aggregate"=> OpenSRF::Utils::JSON->true, + "transform"=>"count", + "alias"=>"count", + "column"=>"id" + }], + }, + "from"=>{"acp"=>{"circ"=>{"field"=>"target_copy","fkey"=>"id"}}}, + "where"=>{ + "+circ"=>{ + "checkin_time"=>undef, + "usr"=>$userid, + "-or"=>[ + {"stop_fines"=>["LOST","LONGOVERDUE","CLAIMSRETURNED"]}, + {"stop_fines"=>undef} + ] + } + } + }; + + my $mods = $e->json_query($query); + my $breakdown = {}; + $breakdown->{$_->{circ_modifier}} = $_->{count} for @$mods; + $logger->info("script_runner: Loaded checkouts by circ_modifier breakdown:". + OpenSRF::Utils::JSON->perl2JSON($breakdown)); + $runner->insert($write_key, $breakdown, 1) if (keys %$breakdown); + } + ); + } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/StatCat.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/StatCat.pm index 8155c6186b..57e20dd5b8 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/StatCat.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/StatCat.pm @@ -14,7 +14,7 @@ # --------------------------------------------------------------- package OpenILS::Application::Circ::StatCat; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; use OpenSRF::Utils::Logger qw($logger); diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Survey.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Survey.pm index 096c7ca8bd..643d5e6d1a 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Survey.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Survey.pm @@ -14,7 +14,7 @@ # --------------------------------------------------------------- package OpenILS::Application::Circ::Survey; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; use OpenSRF::EX qw/:try/; use OpenILS::Application::AppUtils; @@ -55,7 +55,7 @@ sub add_survey { if($err) { throw OpenSRF::EX::ERROR ($err); } # re-retrieve the survey from the db and return it - return $self->get_fleshed_survey( $client, $survey->id() ); + return get_fleshed_survey($self, $client, $survey->id() ); } @@ -161,7 +161,7 @@ sub get_required_surveys { my @fleshed; for my $survey (@$surveys) { - push(@fleshed, $self->get_fleshed_survey($client, $survey)); + push(@fleshed, get_fleshed_survey($self, $client, $survey)); } return \@fleshed; @@ -210,7 +210,7 @@ sub get_all_surveys { my @fleshed; for my $survey (@$surveys) { - push(@fleshed, $self->get_fleshed_survey($client, $survey)); + push(@fleshed, get_fleshed_survey($self, $client, $survey)); } return \@fleshed; } @@ -368,7 +368,7 @@ sub get_random_survey { warn "Random survey index for process $$ is $random\n"; my $surv = $surveys->[$random]; - return $self->get_fleshed_survey($client, $surv); + return get_fleshed_survey($self, $client, $surv); } @@ -390,7 +390,7 @@ sub get_random_survey_global { warn "Random survey index for process $$ is $random\n"; my $surv = $surveys->[$random]; - return $self->get_fleshed_survey($client, $surv); + return get_fleshed_survey($self, $client, $surv); } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm index ff3ad4eca8..dd6fea7a2a 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Circ::Transit; -use base 'OpenSRF::Application'; +use base 'OpenILS::Application'; use strict; use warnings; use OpenSRF::EX qw(:try); use Data::Dumper; @@ -44,7 +44,7 @@ sub copy_transit_receive { ($copy, $evt) = $U->fetch_copy_by_barcode($params{barcode}) unless $copy; return $evt if $evt; my $session = $U->start_db_session(); - $evt = $self->transit_receive( $copy, $requestor, $session ); + $evt = transit_receive( $self, $copy, $requestor, $session ); $U->commit_db_session($session) if $U->event_equals($evt,'SUCCESS'); return $evt; } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Collections.pm b/Open-ILS/src/perlmods/OpenILS/Application/Collections.pm index e1cd9b4c7c..e558c0fe93 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Collections.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Collections.pm @@ -129,7 +129,7 @@ sub process_users_of_interest_results { my($self, $conn, $e, $req, $starttime, @params) = @_; my $total; - while( my $resp = $req->recv(timeout => 600) ) { + while( my $resp = $req->recv(timeout => 7200) ) { return $req->failed if $req->failed; my $hash = $resp->content; @@ -304,7 +304,7 @@ sub users_with_activity { $conn->status( new OpenSRF::DomainObject::oilsContinueStatus ); my $total; - while( my $resp = $req->recv(timeout => 600) ) { + while( my $resp = $req->recv(timeout => 7200) ) { unless($total) { $total = time - $start; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm b/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm new file mode 100644 index 0000000000..0289f955c8 --- /dev/null +++ b/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm @@ -0,0 +1,304 @@ +# -------------------------------------------------------------------- +# Copyright (C) 2008 Niles Ingalls +# Niles Ingalls +# Bill Erickson +# +# 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. +# -------------------------------------------------------------------- +package OpenILS::Application::CreditCard; +use base qw/OpenSRF::Application/; +use strict; use warnings; + +use DateTime; +use DateTime::Format::ISO8601; +use OpenILS::Application::AppUtils; +use OpenSRF::Utils qw/:datetime/; +use OpenILS::Event; +use OpenSRF::EX qw(:try); +use OpenSRF::Utils::Logger qw(:logger); +use OpenILS::Utils::Fieldmapper; +use OpenILS::Utils::CStoreEditor q/:funcs/; +use OpenILS::Const qw/:const/; +use OpenSRF::Utils::SettingsClient; +use Business::CreditCard; +use Business::CreditCard::Object; +use Business::OnlinePayment; + + +__PACKAGE__->register_method( + method => 'process_payment', + api_name => 'open-ils.credit.process', + signature => { + desc => 'Creates a new provider', + params => [ + { desc => 'Authentication token', type => 'string' }, + { desc => q/Hash of arguments. Options include: + XXX add docs as API stablilizes... + /, type => 'hash' } + ], + return => { desc => 'Hash of status information', type=>'hash' } + } +); + +sub process_payment { + my $self = shift; + my $client = shift; + my $argshash = shift; + + my $e = new_editor(); + my $patron = $e->retrieve_actor_user( + [ + $argshash->{patron_id}, + { + flesh => 1, + flesh_fields => { au => ["mailing_address"] } + } + ] + ) or return $e->event; + + return OpenILS::Event->new('BAD_PARAMS') + unless $argshash->{login} + and $argshash->{password} + and $argshash->{action}; + + if ( $argshash->{processor} eq 'PayPal' ) { + # XXX not ready for prime time + return handle_paypal($e, $argshash, $patron); + + } elsif ( $argshash->{processor} eq 'AuthorizeNet' ) { + return handle_authorizenet($e, $argshash, $patron); + } +} + +sub handle_paypal { + my($e, $argshash, $patron) = @_; + + require Business::PayPal::API; + require Business::OnlinePayment::PayPal; + my $card = Business::CreditCard::Object->new( $argshash->{cc} ); + + $logger->debug("applying paypal payment"); + + if ( !$card->is_valid ) { + return { + statusText => "should return address:(patron_id):", + processor => $argshash->{processor}, + testmode => $argshash->{testmode}, + card => $card->number(), + expiration => $argshash->{expiration}, + name => $patron->first_given_name, + patron_id => $patron->id, + patron_patron_id => $patron->mailing_address, + statusCode => 500 + }; + } + + my $type = $card->type(); + + if ( substr( $type, -5, 5 ) =~ / card/ ) { + $type = substr( $type, 0, -5 ); + } + + my $transaction = Business::OnlinePayment->new( + $argshash->{processor}, + "Username" => $argshash->{PayPal_Username}, + "Password" => $argshash->{PayPal_Password}, + "Signature" => $argshash->{PayPal_Signature} + ); + + $transaction->content( + action => $argshash->{action}, + amount => $argshash->{amount}, + type => "$type", + card_number => $card->number(), + expiration => $argshash->{expiration}, + cvv2 => $argshash->{cvv2}, + name => $patron->first_given_name . ' ' . $patron->family_name, + address => $patron->mailing_address->street1, + city => $patron->mailing_address->city, + state => $patron->mailing_address->state, + zip => $patron->mailing_address->post_code + ); + + $transaction->test_transaction(1); # XXX + $transaction->submit; + + if ( $transaction->is_success ) { + return { + statusText => "Card approved: ".$transaction->authorization, + statusCode => 200, + approvalCode => $transaction->authorization, + CorrelationID => $transaction->correlationid + }; + + } else { + return { + statusText => "Card declined: " . $transaction->error_message, + statusCode => 500 + + }; + } +} + +sub handle_authorizenet { + my($e, $argshash, $patron) = @_; + + require Business::OnlinePayment::AuthorizeNet; + my $card = Business::CreditCard::Object->new( $argshash->{cc} ); + + $logger->debug("applying authorize.net payment"); + + if ( ! $card->is_valid ) { + $logger->warn("authorize.net card number is invalid"); + + return { + statusText => "should return address:(patron_id):", + processor => $argshash->{processor}, + testmode => $argshash->{testmode}, + card => $card->number(), + expiration => $argshash->{expiration}, + name => $patron->first_given_name, + patron_id => $patron->id, + patron_patron_id => $patron->mailing_address, + statusCode => 500 + }; + } + + my $type = $card->type(); + + if ( substr( $type, -5, 5 ) =~ / card/ ) { + $type = substr( $type, 0, -5 ); + } + + my $transaction = new Business::OnlinePayment( + $argshash->{processor}, 'test_transaction' => $argshash->{testmode}); + + $transaction->content( + type => "$type", #'American Express', 'VISA', 'MasterCard' + login => $argshash->{login}, + password => $argshash->{password}, + action => $argshash->{action}, + description => $argshash->{description}, + amount => $argshash->{amount}, + card_number => $card->number(), + expiration => $argshash->{expiration}, + cvv2 => $argshash->{cvv2}, + first_name => $patron->first_given_name, + last_name => $patron->family_name, + address => $patron->mailing_address->street1, + city => $patron->mailing_address->city, + state => $patron->mailing_address->state, + zip => $patron->mailing_address->post_code, + customer_id => $patron->id + ); + + $transaction->submit(); + + if ( $transaction->is_success() ) { + $logger->info("authorize.net payment succeeded"); + return { + statusText => "Card approved: " + . $transaction->authorization, + statusCode => 200, + approvalCode => $transaction->authorization, + server_response => $transaction->server_response + + }; + + } else { + $logger->info("authorize.net card declined"); + return { + statusText => "Card decliined: " . $transaction->error_message, + statusCode => 500, + approvalCode => $transaction->error_message, + server_response => $transaction->server_response + }; + } +} + + +__PACKAGE__->register_method( + method => 'retrieve_payable_balance', + api_name => 'open-ils.credit.payable_balance.retrieve', + signature => { + desc => '', + params => [ + { desc => 'Authentication token', type => 'string' }, + { desc => 'Authentication token', type => 'string' }, + { desc => 'User id', type => 'number' } + ], + return => { desc => 'The ID of the new provider' } + } +); + +sub retrieve_payable_balance { + my ( $self, $conn, $auth, $user_id ) = @_; + my $e = new_editor( authtoken => $auth ); + return $e->event unless $e->checkauth; + + if ( $e->requestor->id != $user_id ) { + # XXX check perm + } + + my $circ_orgs = $e->json_query({ + "select" => { "circ" => ["circ_lib"] }, + from => "circ", + "where" => { "usr" => $user_id, xact_finish => undef }, + distinct => 1 + }); + + my $groc_orgs = $e->json_query({ + "select" => { "mg" => ["billing_location"] }, + from => "mg", + "where" => { "usr" => $user_id, xact_finish => undef }, + distinct => 1 + }); + + my %hash; + my @orgs; + for my $org ( @$circ_orgs, @$groc_orgs ) { + my $o = $org->{billing_location}; + $o = $org->{circ_lib} unless $o; + next if $hash{$org}; + $hash{$o} = + OpenILS::Application::AppUtils->simplereq( 'open-ils.actor', + 'open-ils.actor.ou_setting.ancestor_default', + $o, 'credit.allow' ); + } + + my @credit_orgs = map { $hash{$_} ? ($_) : () } keys %hash; + + my $xact_summaries = + OpenILS::Application::AppUtils->simplereq( 'open-ils.actor', + 'open-ils.actor.user.transactions.have_charge', + $auth, $user_id ); + + my $sum = 0.0; + + for my $xact (@$xact_summaries) { + + # make two lists and grab them in batch XXX + if ( $xact->xact_type eq 'circulation' ) { + my $circ = + $e->search_action_circulation( { id => $xact->id } )->[0]; + next unless grep { $_ == $circ->circ_lib } @credit_orgs; + } + else { + my $bill = $e->search_money_grocery( { id => $xact } )->[0]; + next unless grep { $_ == $bill->billing_location } @credit_orgs; + } + $sum += $xact->ballance_owed(); + } + + return $sum; +} + +1; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Fielder.pm b/Open-ILS/src/perlmods/OpenILS/Application/Fielder.pm new file mode 100644 index 0000000000..c541345dd5 --- /dev/null +++ b/Open-ILS/src/perlmods/OpenILS/Application/Fielder.pm @@ -0,0 +1,120 @@ +# vim:et:ts=4:sw=4: + +package OpenILS::Application::Fielder; +use OpenILS::Application; +use base qw/OpenILS::Application/; + +use Unicode::Normalize; +use OpenSRF::EX qw/:try/; + +use OpenSRF::AppSession; +use OpenSRF::Utils::SettingsClient; +use OpenSRF::Utils::Logger qw/:level/; + +use OpenILS::Utils::Fieldmapper; +use OpenSRF::Utils::JSON; + +use OpenILS::Utils::CStoreEditor qw/:funcs/; + +use XML::LibXML; +use XML::LibXML::XPathContext; +use XML::LibXSLT; + +our %namespace_map = ( + oils_persist=> {ns => 'http://open-ils.org/spec/opensrf/IDL/persistence/v1'}, + oils_obj => {ns => 'http://open-ils.org/spec/opensrf/IDL/objects/v1'}, + idl => {ns => 'http://opensrf.org/spec/IDL/base/v1'}, + reporter => {ns => 'http://open-ils.org/spec/opensrf/IDL/reporter/v1'}, + perm => {ns => 'http://open-ils.org/spec/opensrf/IDL/permacrud/v1'}, +); + + +my $log = 'OpenSRF::Utils::Logger'; + +my $parser = XML::LibXML->new(); +my $xslt = XML::LibXSLT->new(); + +my $xpc = XML::LibXML::XPathContext->new(); +$xpc->registerNs($_, $namespace_map{$_}{ns}) for ( keys %namespace_map ); + +my $idl; + +sub initialize { + + my $conf = OpenSRF::Utils::SettingsClient->new; + my $idl_file = $conf->config_value( 'IDL' ); + + $idl = $parser->parse_file( $idl_file ); + + $log->debug( 'IDL XML file loaded' ); + + generate_methods(); + +} +sub child_init {} + +sub fielder_fetch { + my $self = shift; + my $client = shift; + my $obj = shift; + + my $query = $obj->{query}; + my $fields = $obj->{fields}; + + my $obj_class = $self->{class_hint}; + my $fm_class = $self->{class_name}; + + if (!$fields) { + $fields = [ $fm_class->real_fields ]; + } + + $log->debug( 'Field list: '. OpenSRF::Utils::JSON->perl2JSON( $fields ) ); + $log->debug( 'Query: '. OpenSRF::Utils::JSON->perl2JSON( $query ) ); + + return undef unless $fields; + return undef unless $query; + + $fields = [$fields] if (!ref($fields)); + + + $log->debug( 'Query Class: '. $obj_class ); + + my $res = new_editor()->json_query({ + select => { $obj_class => $fields }, + from => $obj_class, + where => $query + }); + + for my $value (@$res) { + $client->respond($value); + } + + return undef; + +} + +sub generate_methods { + try { + for my $class_node ( $xpc->findnodes( '//idl:class[@oils_persist:field_safe="true"]', $idl->documentElement ) ) { + my $hint = $class_node->getAttribute('id'); + my $fm = $class_node->getAttributeNS('http://open-ils.org/spec/opensrf/IDL/objects/v1','fieldmapper'); + $log->debug("Fielder class_node $hint"); + + __PACKAGE__->register_method( + method => 'fielder_fetch', + api_name => 'open-ils.fielder.' . $hint, + class_hint => $hint, + class_name => "Fieldmapper::$fm", + stream => 1, + argc => 1 + ); + } + } catch Error with { + my $e = shift; + $log->error("error generating Fielder methods: $e"); + }; +} + + +1; + diff --git a/Open-ILS/src/perlmods/OpenILS/Application/PermaCrud.pm b/Open-ILS/src/perlmods/OpenILS/Application/PermaCrud.pm new file mode 100644 index 0000000000..5011d9e91e --- /dev/null +++ b/Open-ILS/src/perlmods/OpenILS/Application/PermaCrud.pm @@ -0,0 +1,272 @@ +# vim:et:ts=4:sw=4: + +package OpenILS::Application::PermaCrud; +use OpenILS::Application; +use base qw/OpenILS::Application/; + +use Unicode::Normalize; +use OpenSRF::EX qw/:try/; + +use OpenSRF::AppSession; +use OpenSRF::Utils::SettingsClient; +use OpenSRF::Utils::Logger qw/:level/; + +use OpenILS::Utils::Fieldmapper; +use OpenSRF::Utils::JSON; + +use OpenILS::Utils::CStoreEditor qw/:funcs/; + +use XML::LibXML; +use XML::LibXML::XPathContext; +use XML::LibXSLT; + +our %namespace_map = ( + oils_persist=> {ns => 'http://open-ils.org/spec/opensrf/IDL/persistence/v1'}, + oils_obj => {ns => 'http://open-ils.org/spec/opensrf/IDL/objects/v1'}, + idl => {ns => 'http://opensrf.org/spec/IDL/base/v1'}, + reporter => {ns => 'http://open-ils.org/spec/opensrf/IDL/reporter/v1'}, + perm => {ns => 'http://open-ils.org/spec/opensrf/IDL/permacrud/v1'}, +); + + +my $log = 'OpenSRF::Utils::Logger'; + +my $parser = XML::LibXML->new(); +my $xslt = XML::LibXSLT->new(); + +my $xpc = XML::LibXML::XPathContext->new(); +$xpc->registerNs($_, $namespace_map{$_}{ns}) for ( keys %namespace_map ); + +my $idl; + +sub initialize { + + my $conf = OpenSRF::Utils::SettingsClient->new; + my $idl_file = $conf->config_value( 'IDL' ); + + $idl = $parser->parse_file( $idl_file ); + + $log->debug( 'IDL XML file loaded' ); + + generate_methods(); + +} +sub child_init {} + +sub CRUD_action_object_permcheck { + my $self = shift; + my $client = shift; + my $auth = shift; + my $obj = shift; + + my $e = shift || new_editor(authtoken => $auth, xact => 1); + return $e->event unless $e->checkauth; + + if (ref($obj) && $obj->json_hint ne $self->{class_hint}) { + throw OpenSRF::DomainObject::oilsException->new( + statusCode => 500, + status => "Class missmatch: $self->{class_hint} method called with " . $obj->json_hint, + ); + } + + my $class_node; + try { + ($class_node) = $xpc->findnodes( "//idl:class[\@id='$self->{class_hint}']", $idl->documentElement ); + } catch Error with { + my $error = shift; + $log->error("Error finding class node: $error [//idl:class[\@id='$self->{class_hint}']]"); + throw OpenSRF::DomainObject::oilsException->new( + statusCode => 500, + status => "Error finding class node: $error [//idl:class[\@id='$self->{class_hint}']]" + ); + }; + + if (!$class_node) { + $log->error("Error finding class node: $error [//idl:class[\@id='$self->{class_hint}']]"); + throw OpenSRF::DomainObject::oilsException->new( + statusCode => 500, + status => "Error finding class node: $error [//idl:class[\@id='$self->{class_hint}']]" + ); + } + + my $action_node; + try { + ($action_node) = $xpc->findnodes( "perm:permacrud/perm:actions/perm:$self->{action}", $class_node ); + } catch Error with { + my $error = shift; + $log->error("Error finding action node: $error [perm:permacrud/perm:actions/perm:$self->{action}]"); + throw OpenSRF::DomainObject::oilsException->new( + statusCode => 500, + status => "Error finding action node: $error [perm:permacrud/perm:actions/perm:$self->{action}]" + ); + }; + + if (!$action_node) { + $log->error("Error finding action node: $error [perm:permacrud/perm:actions/perm:$self->{action}]"); + throw OpenSRF::DomainObject::oilsException->new( + statusCode => 500, + status => "Error finding action node: $error [perm:permacrud/perm:actions/perm:$self->{action}]" + ); + } + + my $all_perms = $action_node->getAttribute( 'all_perms' ); + + my $fm_class = $xpc->findvalue( '@oils_obj:fieldmapper', $class_node ); + if (!ref($obj)) { + my $retrieve_method = 'retrieve_' . $fm_class; + $retrieve_method =~ s/::/_/go; + $obj = $e->$retrieve_method( $obj ); + } + + (my $o_type = $fm_class) =~ s/::/./go; + + my $perm_field_value = $action_node->getAttribute('permission'); + + if ($perm_field_value) { + my @perms = split '\|', $perm_field_value; + + my @context_ous; + if ($action_node->getAttribute('global_required')) { + push @context_ous, $e->search_actor_org_unit( { parent_ou => undef } )->[0]->id; + + } else { + my $context_field_value = $action_node->getAttribute('context_field'); + + if ($context_field_value) { + push @context_ous, $obj->$_ for ( split '\|', $context_field_value ); + } else { + for my $context_node ( $xpc->findnodes( "perm:context", $action_node ) ) { + my $context_field = $context_node->getAttribute('field'); + my $link_field = $context_node->getAttribute('link'); + + if ($link_field) { + + my ($link_node) = $xpc->findnodes( "idl:links/idl:link[\@field='$link_field']", $class_node ); + my $link_class_hint = $link_node->getAttribute('class'); + my $remote_field = $link_node->getAttribute('key'); + + my ($remote_class_node) = $xpc->findnodes( "//idl:class[\@id='$link_class_hint']", $idl->documentElement ); + my $search_method = 'search_' . $xpc->findvalue( '@oils_obj:fieldmapper', $remote_class_node ); + $search_method =~ s/::/_/go; + + for my $remote_object ( @{$e->$search_method( { $remote_field => $obj->$link_field } )} ) { + push @context_ous, $remote_object->$context_field; + } + } else { + push @context_ous, $obj->$_ for ( split '\|', $context_field ); + } + } + } + } + + my $pok = 0; + for my $perm (@perms) { + if (@context_ous) { + for my $c_ou (@context_ous) { + if ($e->allowed($perm => $c_ou => $obj)) { + $pok++; + last; + } + } + } else { + $pok++ if ($e->allowed($perm => undef => $obj)); + } + } + + if ((lc($all_perms) eq 'true' && @perms != $pok) or !$pok) { + throw OpenSRF::DomainObject::oilsException->new( + statusCode => 403, + status => "Perm failure -- action: $self->{action}, object type: $self->{json_hint}", + ); + } + } + + return $obj if ($self->{action} eq 'retrieve'); + + my $val = $e->session->request("open-ils.cstore.direct.$o_type.$self->{action}" => $obj )->gather(1); + $e->commit; + + return $val; +} + +sub search_permacrud { + my $self = shift; + my $client = shift; + my $auth = shift; + my @args = @_; + + if (@args > 1) { + delete $args[1]{flesh}; + delete $args[1]{flesh_fields}; + } + + my $e = new_editor(authtoken => $auth, xact => 1); + return $e->event unless $e->checkauth; + + my $class_node; + try { + ($class_node) = $xpc->findnodes( "//idl:class[\@id='$self->{class_hint}']", $idl->documentElement ); + } catch Error with { + my $error = shift; + $log->error("Error finding class node: $error [//idl:class[\@id='$self->{class_hint}']]"); + throw OpenSRF::DomainObject::oilsException->new( + statusCode => 500, + status => "Error finding class node: $error [//idl:class[\@id='$self->{class_hint}']]" + ); + }; + + my $search_method = 'search_' . $xpc->findvalue( '@oils_obj:fieldmapper', $class_node ); + $search_method =~ s/::/_/go; + + $log->debug("Calling CStoreEditor search method: $search_method"); + + my $obj_list = $e->$search_method( \@args ); + + my $retriever = $self->method_lookup( $self->{retriever} ); + for my $o ( @$obj_list ) { + try { + ($o) = $retriever->run( $auth, $o, $e ); + $client->respond( $o ) if ($o); + }; + } + + return undef; +} + +sub generate_methods { + try { + for my $class_node ( $xpc->findnodes( '//idl:class[perm:permacrud]', $idl->documentElement ) ) { + my $hint = $class_node->getAttribute('id'); + $log->debug("permacrud class_node $hint"); + + for my $action_node ( $xpc->findnodes( "perm:permacrud/perm:actions/perm:*", $class_node ) ) { + (my $method = $action_node->localname) =~ s/^.+:(.+)$/$1/o; + $log->internal("permacrud method = $method"); + + __PACKAGE__->register_method( + method => 'CRUD_action_object_permcheck', + api_name => 'open-ils.permacrud.' . $method . '.' . $hint, + class_hint => $hint, + action => $method, + ); + + if ($method eq 'retrieve') { + __PACKAGE__->register_method( + method => 'search_permacrud', + api_name => 'open-ils.permacrud.search.' . $hint, + class_hint => $hint, + retriever => 'open-ils.permacrud.retrieve.' . $hint, + stream => 1 + ); + } + } + } + } catch Error with { + my $e = shift; + $log->error("error generating permacrud methods: $e"); + }; +} + + +1; + diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search/AddedContent.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search/AddedContent.pm index 1e27f879bf..0538deab8b 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search/AddedContent.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search/AddedContent.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Search::AddedContent; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; sub initialize { return 1; } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search/Authority.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search/Authority.pm index 94b5fe7eb0..fa5eac47d3 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search/Authority.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search/Authority.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Search::Authority; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; use OpenILS::Utils::Fieldmapper; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm index 61baf74509..d28f5cc26f 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Search::Biblio; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; @@ -273,7 +273,7 @@ sub fleshed_by_barcode { my $copyid = $e->search_asset_copy( {barcode => $barcode, deleted => 'f'}, {idlist=>1})->[0] or return $e->event; - return $self->fleshed_copy_retrieve2($conn, $copyid); + return fleshed_copy_retrieve2( $self, $conn, $copyid); } @@ -431,7 +431,7 @@ __PACKAGE__->register_method( subclasses, specified with a "|". For example, "title|proper:gone with the wind" For more, see config.metabib_field - @param nocache @see open-ils.search.biblio.multiclass + @param docache @see open-ils.search.biblio.multiclass # ); __PACKAGE__->register_method( @@ -451,8 +451,8 @@ sub multiclass_query { my($self, $conn, $arghash, $query, $docache) = @_; $logger->debug("initial search query => $query"); + my $orig_query = $query; - $query = decode_utf8($query); $query =~ s/\+/ /go; $query =~ s/'//go; $query =~ s/^\s+//go; @@ -496,6 +496,10 @@ sub multiclass_query { $arghash->{language} = [] unless $arghash->{language}; push(@{$arghash->{language}}, $value); + } elsif($type =~ /^sort/o) { + # sort and sort_dir modifiers + $arghash->{$type} = $value; + } else { # append the search term to the term under construction $search->{$type} = {} unless $search->{$type}; @@ -516,12 +520,21 @@ sub multiclass_query { # capture the original limit because the search method alters the limit internally my $ol = $arghash->{limit}; + my $sclient = OpenSRF::Utils::SettingsClient->new; + (my $method = $self->api_name) =~ s/\.query//o; + + $method =~ s/multiclass/multiclass.staged/ + if $sclient->config_value(apps => 'open-ils.search', + app_settings => 'use_staged_search') =~ /true/i; + + $method = $self->method_lookup($method); my ($data) = $method->run($arghash, $docache); $arghash->{limit} = $ol if $ol; $data->{compiled_search} = $arghash; + $data->{query} = $orig_query; $logger->info("compiled search is " . OpenSRF::Utils::JSON->perl2JSON($arghash)); @@ -532,7 +545,8 @@ __PACKAGE__->register_method( method => 'cat_search_z_style_wrapper', api_name => 'open-ils.search.biblio.zstyle', stream => 1, -); + signature => q/@see open-ils.search.biblio.multiclass/); + sub cat_search_z_style_wrapper { my $self = shift; my $client = shift; @@ -561,7 +575,7 @@ sub cat_search_z_style_wrapper { $$searchhash{searches}{keyword}{term} .= join ' ', $$searchhash{searches}{keyword}{term}, $$args{search}{pubdate} if $$args{search}{pubdate}; $$searchhash{searches}{keyword}{term} .= join ' ', $$searchhash{searches}{keyword}{term}, $$args{search}{item_type} if $$args{search}{item_type}; - my ($list) = $self->method_lookup('open-ils.search.biblio.multiclass.staff')->run( $searchhash ); + my $list = the_quest_for_knowledge( $self, $client, $searchhash ); if ($list->{count} > 0) { $result->{count} = $list->{count}; @@ -714,6 +728,147 @@ sub the_quest_for_knowledge { } +__PACKAGE__->register_method( + method => 'staged_search', + api_name => 'open-ils.search.biblio.multiclass.staged'); +__PACKAGE__->register_method( + method => 'staged_search', + api_name => 'open-ils.search.biblio.multiclass.staged.staff', + signature => q/@see open-ils.search.biblio.multiclass.staged/); +__PACKAGE__->register_method( + method => 'staged_search', + api_name => 'open-ils.search.metabib.multiclass.staged', + signature => q/@see open-ils.search.biblio.multiclass.staged/); +__PACKAGE__->register_method( + method => 'staged_search', + api_name => 'open-ils.search.metabib.multiclass.staged.staff', + signature => q/@see open-ils.search.biblio.multiclass.staged/); + +my $PAGE_SIZE = 1000; +my $SEARCH_PAGES = 25; +sub staged_search { + my($self, $conn, $search_hash, $docache) = @_; + + my $method = ($self->api_name =~ /metabib/) ? + 'open-ils.storage.metabib.multiclass.staged.search_fts': + 'open-ils.storage.biblio.multiclass.staged.search_fts'; + + $method .= '.staff' if $self->api_name =~ /staff$/; + $method .= '.atomic'; + + my $user_offset = $search_hash->{offset} || 0; # user-specified offset + my $user_limit = $search_hash->{limit} || 10; + + # we're grabbing results on a per-superpage basis, which means the + # limit and offset should coincide with superpage boundaries + $search_hash->{offset} = 0; + $search_hash->{limit} = $PAGE_SIZE; + $search_hash->{check_limit} = $PAGE_SIZE; # force a well-known check_limit + + # pull any existing results from the cache + my $key = search_cache_key($method, $search_hash); + my $cache_data = $cache->get_cache($key) || {}; + + # keep retrieving results until we find enough to + # fulfill the user-specified limit and offset + my $all_results = []; + my $page; # current superpage + my $est_hit_count; + + for($page = 0; $page < $SEARCH_PAGES; $page++) { + + my $data = $cache_data->{$page}; + my $results; + my $summary; + + $logger->debug("staged search: analyzing superpage $page"); + + if($data) { + # this window of results is already cached + $logger->debug("staged search: found cached results"); + $summary = $data->{summary}; + $results = $data->{results}; + + } else { + # retrieve the window of results from the database + $logger->debug("staged search: fetching results from the database"); + $search_hash->{skip_check} = $page * $PAGE_SIZE; + my $start = time; + $results = $U->storagereq($method, %$search_hash); + $logger->info("staged search: DB call took ".(time - $start)." seconds"); + $summary = shift(@$results); + + # Create backwards-compatible result structures + if($self->api_name =~ /biblio/) { + $results = [map {[$_->{id}]} @$results]; + } else { + $results = [map {[$_->{id}, $_->{rel}, $_->{record}]} @$results]; + } + + $results = [grep {defined $_->[0]} @$results]; + cache_staged_search_page($key, $page, $summary, $results) if $docache; + } + + # add the new set of results to the set under construction + push(@$all_results, @$results); + + my $current_count = scalar(@$all_results); + + $est_hit_count = $summary->{estimated_hit_count} || $summary->{visible} + if $page == 0; + + $logger->debug("staged search: located $current_count, with estimated hits=". + $summary->{estimated_hit_count}." : visible=".$summary->{visible}.", checked=".$summary->{checked}); + + # we've found all the possible hits + last if $current_count == $summary->{visible} + and not defined $summary->{estimated_hit_count}; + + # we've found enough results to satisfy the requested limit/offset + last if $current_count >= ($user_limit + $user_offset); + + # we've scanned all possible hits + last if $summary->{checked} < $PAGE_SIZE; + } + + my @results = grep {defined $_} @$all_results[$user_offset..($user_offset + $user_limit - 1)]; + + return { + count => $est_hit_count, + ids => \@results + }; +} + +# creates a unique token to represent the query in the cache +sub search_cache_key { + my $method = shift; + my $search_hash = shift; + my @sorted; + for my $key (sort keys %$search_hash) { + push(@sorted, ($key => $$search_hash{$key})) + unless $key eq 'limit' or + $key eq 'offset' or + $key eq 'skip_check'; + } + my $s = OpenSRF::Utils::JSON->perl2JSON(\@sorted); + return $pfx . md5_hex($method . $s); +} + +sub cache_staged_search_page { + # puts this set of results into the cache + my($key, $page, $summary, $results) = @_; + my $data = $cache->get_cache($key); + $data ||= {}; + $data->{$page} = { + summary => $summary, + results => $results + }; + + $logger->info("staged search: cached with key=$key, superpage=$page, estimated=". + $summary->{estimated_hit_count}.", visible=".$summary->{visible}); + + $cache->put_cache($key, $data); +} sub search_cache { @@ -735,7 +890,6 @@ sub search_cache { return undef unless $offset < $count; - my @result; for( my $i = $offset; $i <= $end; $i++ ) { last unless my $d = $$data[$i]; @@ -803,8 +957,8 @@ sub biblio_mrid_to_modsbatch { my ($mr, $evt) = _grab_metarecord($mrid); return $evt unless $mr; - my $mvr = $self->biblio_mrid_check_mvr($client, $mr); - $mvr = $self->biblio_mrid_make_modsbatch( $client, $mr ) unless $mvr; + my $mvr = biblio_mrid_check_mvr($self, $client, $mr); + $mvr = biblio_mrid_make_modsbatch( $self, $client, $mr ) unless $mvr; return $mvr unless ref($args); @@ -1389,6 +1543,9 @@ __PACKAGE__->register_method ( api_name => 'open-ils.search.biblio.item_type_map.retrieve.all'); __PACKAGE__->register_method ( method => 'bib_extras', + api_name => 'open-ils.search.biblio.bib_level_map.retrieve.all'); +__PACKAGE__->register_method ( + method => 'bib_extras', api_name => 'open-ils.search.biblio.audience_map.retrieve.all'); sub bib_extras { @@ -1405,6 +1562,9 @@ sub bib_extras { return $e->retrieve_all_config_item_type_map() if( $self->api_name =~ /item_type_map/ ); + return $e->retrieve_all_config_bib_level_map() + if( $self->api_name =~ /bib_level_map/ ); + return $e->retrieve_all_config_audience_map() if( $self->api_name =~ /audience_map/ ); diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search/CNBrowse.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search/CNBrowse.pm index 0f2beb4c48..fd901f71de 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search/CNBrowse.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search/CNBrowse.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Search::CNBrowse; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; use OpenSRF::EX qw(:try); diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search/Z3950.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search/Z3950.pm index 520ed6a0b4..9d84c1872e 100755 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search/Z3950.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search/Z3950.pm @@ -1,6 +1,6 @@ package OpenILS::Application::Search::Z3950; use strict; use warnings; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use OpenILS::Utils::ZClient; use MARC::Record; @@ -15,10 +15,9 @@ use OpenILS::Utils::ModsParser; use OpenSRF::Utils::SettingsClient; use OpenILS::Application::AppUtils; use OpenSRF::Utils::Logger qw/$logger/; -use OpenILS::Utils::CStoreEditor q/:funcs/; +use OpenILS::Utils::Editor q/:funcs/; my $output = "USMARC"; -my $U = 'OpenILS::Application::AppUtils'; my $sclient; my %services; @@ -85,35 +84,7 @@ sub query_services { my $e = new_editor(authtoken=>$auth); return $e->event unless $e->checkauth; return $e->event unless $e->allowed('REMOTE_Z3950_QUERY'); - - my $sources = $e->search_config_z3950_source( - [ { name => { '!=' => undef } }, - { flesh => 1, flesh_fields => { czs => ['attrs'] } }] - ); - - my %hash = (); - for my $s ( @$sources ) { - $hash{ $s->name } = { - name => $s->name, - label => $s->label, - host => $s->host, - port => $s->port, - db => $s->db, - auth => $s->auth, - }; - - for my $a ( @{ $s->attrs } ) { - $hash{ $a->source }{attrs}{ $a->name } = { - name => $a->name, - label => $a->label, - code => $a->code, - format => $a->format, - source => $a->source, - }; - } - } - - return \%hash; + return $sclient->config_value('z3950', 'services'); } @@ -149,9 +120,7 @@ sub do_class_search { my @connections; my @results; - my @services; for (my $i = 0; $i < @{$$args{service}}; $i++) { - my %tmp_args = %$args; $tmp_args{service} = $$args{service}[$i]; $tmp_args{username} = $$args{username}[$i]; @@ -159,46 +128,30 @@ sub do_class_search { $logger->debug("z3950: service: $tmp_args{service}, async: $tmp_args{async}"); - if ($tmp_args{service} eq 'native-evergreen-catalog') { - my $method = $self->method_lookup('open-ils.search.biblio.zstyle'); - $conn->respond( - $self->method_lookup( - 'open-ils.search.biblio.zstyle' - )->run($auth, \%tmp_args) - ); - } else { + $tmp_args{query} = compile_query('and', $tmp_args{service}, $tmp_args{search}); - $tmp_args{query} = compile_query('and', $tmp_args{service}, $tmp_args{search}); + my $res = do_service_search( $self, $conn, $auth, \%tmp_args ); - my $res = $self->do_service_search( $conn, $auth, \%tmp_args ); + push @results, $res->{result}; + push @connections, $res->{connection}; - if ($U->event_code($res)) { - $conn->respond($res) if $U->event_code($res); - } else { - - push @services, $tmp_args{service}; - push @results, $res->{result}; - push @connections, $res->{connection}; - } - } + $logger->debug("z3950: Result object: $results[$i], Connection object: $connections[$i]"); } $logger->debug("z3950: Connections created"); - return undef unless (@connections); + my @records; while ((my $index = OpenILS::Utils::ZClient::event( \@connections )) != 0) { my $ev = $connections[$index - 1]->last_event(); $logger->debug("z3950: Received event $ev"); if ($ev == OpenILS::Utils::ZClient::EVENT_END()) { - my $munged = process_results( $results[$index - 1], $$args{limit}, $$args{offset} ); - $$munged{service} = $services[$index - 1]; + my $munged = process_results( $results[$index - 1], $$args{limit}, $$args{offset}, $$args{service}[$index -1] ); + $$munged{service} = $$args{service}[$index - 1]; $conn->respond($munged); } } $logger->debug("z3950: Search Complete"); - - return undef; } @@ -214,11 +167,11 @@ sub do_service_search { my $info = $services{$$args{service}}; - $$args{host} = $$info{host}, - $$args{port} = $$info{port}, - $$args{db} = $$info{db}, + $$args{host} = $$info{host}; + $$args{port} = $$info{port}; + $$args{db} = $$info{db}; - return $self->do_search( $conn, $auth, $args ); + return do_search( $self, $conn, $auth, $args ); } @@ -285,7 +238,7 @@ sub do_search { return {result => $results, connection => $connection} if ($async); - my $munged = process_results($results, $limit, $offset); + my $munged = process_results($results, $limit, $offset, $$args{service}); $munged->{query} = $query; return $munged; @@ -300,8 +253,11 @@ sub process_results { my $results = shift; my $limit = shift || 10; my $offset = shift || 0; + my $service = shift; - $results->option(elementSetName => "FI"); # full records with no holdings + my $rformat = $services{$service}->{record_format} || 'FI'; + $results->option(elementSetName => $rformat); + $logger->info("z3950: using record format '$rformat'"); my @records; my $res = {}; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search/Zips.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search/Zips.pm index f4f2c8e10e..ff133627c1 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search/Zips.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search/Zips.pm @@ -1,5 +1,5 @@ package OpenILS::Application::Search::Zips; -use base qw/OpenSRF::Application/; +use base qw/OpenILS::Application/; use strict; use warnings; use OpenSRF::EX qw(:try); diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Storage/FTS.pm b/Open-ILS/src/perlmods/OpenILS/Application/Storage/FTS.pm index c20edf2f6e..6dd03c0382 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Storage/FTS.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Storage/FTS.pm @@ -4,6 +4,71 @@ my $log = 'OpenSRF::Utils::Logger'; #------------------------------------------------------------------------------- package OpenILS::Application::Storage::FTS; use OpenSRF::Utils::Logger qw/:level/; +use Parse::RecDescent; +use Unicode::Normalize; + +my $_default_grammar_parser = new Parse::RecDescent ( <<'GRAMMAR' ); + + + +search_expression: or_expr(s) | and_expr(s) | expr(s) +or_expr: lexpr '||' rexpr +and_expr: lexpr '&&' rexpr +lexpr: expr +rexpr: expr +expr: phrase(s) | group(s) | word(s) +joiner: '||' | '&&' +phrase: '"' token(s) '"' +group : '(' search_expression ')' +word: numeric_range | negative_token | token +negative_token: '-' .../\D+/ token +token: /[-\w]+/ +numeric_range: /\d+-\d*/ + +GRAMMAR + +sub naco_normalize { + + my $txt = lc(shift); + my $sf = shift; + + $txt = NFD($txt); + $txt =~ s/\pM+//go; # Remove diacritics + + $txt =~ s/\xE6/AE/go; # Convert ae digraph + $txt =~ s/\x{153}/OE/go;# Convert oe digraph + $txt =~ s/\xFE/TH/go; # Convert Icelandic thorn + + $txt =~ tr/\x{2070}\x{2071}\x{2072}\x{2073}\x{2074}\x{2075}\x{2076}\x{2077}\x{2078}\x{2079}\x{207A}\x{207B}/0123456789+-/;# Convert superscript numbers + $txt =~ tr/\x{2080}\x{2081}\x{2082}\x{2083}\x{2084}\x{2085}\x{2086}\x{2087}\x{2088}\x{2089}\x{208A}\x{208B}/0123456889+-/;# Convert subscript numbers + + $txt =~ tr/\x{0251}\x{03B1}\x{03B2}\x{0262}\x{03B3}/AABGG/; # Convert Latin and Greek + $txt =~ tr/\x{2113}\xF0\!\"\(\)\-\{\}\<\>\;\:\.\?\xA1\xBF\/\\\@\*\%\=\xB1\+\xAE\xA9\x{2117}\$\xA3\x{FFE1}\xB0\^\_\~\`/LD /; # Convert Misc + $txt =~ tr/\'\[\]\|//d; # Remove Misc + + if ($sf && $sf =~ /^a/o) { + my $commapos = index($txt,','); + if ($commapos > -1) { + if ($commapos != length($txt) - 1) { + my @list = split /,/, $txt; + my $first = shift @list; + $txt = $first . ',' . join(' ', @list); + } else { + $txt =~ s/,/ /go; + } + } + } else { + $txt =~ s/,/ /go; + } + + $txt =~ s/\s+/ /go; # Compress multiple spaces + $txt =~ s/^\s+//o; # Remove leading space + $txt =~ s/\s+$//o; # Remove trailing space + + return $txt; +} + +#' stupid vim syntax highlighting ... sub compile { @@ -32,6 +97,7 @@ sub compile { sub decompose { my $self = shift; my $term = shift; + my $parser = shift || $_default_grammar_parser; $term =~ s/:/ /go; $term =~ s/\s+--\s+/ /go; @@ -44,6 +110,7 @@ sub decompose { $log->debug("Stripped search term string is [$term]",DEBUG); + my $parsetree = $parser->search_expression( $term ); my @words = $term =~ /\b((?{ fts_op } = 'ILIKE'; $self->{ fts_col } = $self->{ text_col } = 'value'; $self->{ raw } = $term; + $self->{ parsetree } = $parsetree; $self->{ words } = \@words; $self->{ nots } = \@nots; $self->{ phrases } = \@parts; @@ -89,6 +157,11 @@ sub raw { return $self->{raw}; } +sub parse_tree { + my $self = shift; + return $self->{parsetree}; +} + sub fts_col { my $self = shift; return $self->{fts_col}; @@ -215,3 +288,4 @@ package Class::DBI; } 1; + diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm index 65e0eebcb5..cb6b06a8ee 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm @@ -818,7 +818,7 @@ sub new_hold_copy_targeter { $log->info("Processing hold ".$hold->id."...\n"); #first, re-fetch the hold, to make sure it's not captured already - $hold->remove_from_object_index(); + $hold->remove_from_object_index(); $hold = action::hold_request->retrieve( $hold->id ); die "OK\n" if (!$hold or $hold->capture_time); @@ -838,7 +838,11 @@ sub new_hold_copy_targeter { {$_->record} metabib::record_descriptor ->search( - record => [ map { $_->id } metabib::metarecord->retrieve($hold->target)->source_records ], + record => [ + map { + isTrue($_->deleted) ? () : ($_->id) + } metabib::metarecord->retrieve($hold->target)->source_records + ], ( $types ? (item_type => [split '', $types]) : () ), ( $formats ? (item_form => [split '', $formats]) : () ), ( $lang ? (item_lang => $lang) : () ), @@ -947,11 +951,7 @@ sub new_hold_copy_targeter { if (!scalar(@good_copies)) { $log->info("\tNo (non-current) copies eligible to fill the hold."); - if ( - $old_best && - grep { $old_best eq $_ } @$all_copies && - !action::hold_request->search_where({ current_copy => $old_best->id, capture_time => undef, cancel_time => undef }) - ) { + if ( $old_best && grep { ''.$old_best->id eq ''.$_->id } @$all_copies ) { # the old copy is still available $log->debug("\tPushing current_copy back onto the targeting list"); push @good_copies, $old_best; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/biblio.pm b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/biblio.pm index b73dcad689..cb5a66c56c 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/biblio.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/biblio.pm @@ -23,7 +23,12 @@ sub record_copy_count { my $out_table = actor::org_unit_type->table; my $descendants = "actor.org_unit_descendants(u.id)"; - my $ancestors = "actor.org_unit_ancestors(?)"; + my $ancestors = "actor.org_unit_ancestors(?) u JOIN $out_table t ON (u.ou_type = t.id)"; + + if ($args{org_unit} < 0) { + $args{org_unit} *= -1; + $ancestors = "(select org_unit as id from actor.org_lasso_map where lasso = ?) u CROSS JOIN (SELECT -1 AS depth) t"; + } my $visible = 'AND a.opac_visible = TRUE AND st.holdable = TRUE AND loc.opac_visible = TRUE AND cp.opac_visible = TRUE'; if ($self->api_name =~ /staff/o) { @@ -79,8 +84,7 @@ sub record_copy_count { AND src.transcendant IS TRUE ) ) AS transcendant - FROM $ancestors u - JOIN $out_table t ON (u.ou_type = t.id) + FROM $ancestors GROUP BY 1,2 SQL diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm index 2b54ac49f6..21bff43162 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm @@ -6,6 +6,7 @@ use OpenILS::Application::Storage::FTS; use OpenILS::Utils::Fieldmapper; use OpenSRF::Utils::Logger qw/:level/; use OpenSRF::Utils::Cache; +use OpenSRF::Utils::JSON; use Data::Dumper; use Digest::MD5 qw/md5_hex/; @@ -22,12 +23,13 @@ sub ordered_records_from_metarecord { my $org = shift || 1; my $depth = shift; - my (@types,@forms); + my (@types,@forms,@blvl); if ($formats) { - my ($t, $f) = split '-', $formats; + my ($t, $f, $b) = split '-', $formats; @types = split '', $t; @forms = split '', $f; + @blvl = split '', $b; } my $descendants = @@ -139,6 +141,10 @@ sub ordered_records_from_metarecord { $sql .= ' AND rd.item_form IN ('.join(',',map{'?'}@forms).')'; } + if (@blvl) { + $sql .= ' AND rd.bib_level IN ('.join(',',map{'?'}@blvl).')'; + } + $sql .= <<" SQL"; @@ -176,7 +182,7 @@ sub ordered_records_from_metarecord { quality DESC SQL - my $ids = metabib::metarecord_source_map->db_Main->selectcol_arrayref($sql, {}, "$mr", @types, @forms); + my $ids = metabib::metarecord_source_map->db_Main->selectcol_arrayref($sql, {}, "$mr", @types, @forms, @blvl); return $ids if ($self->api_name =~ /atomic$/o); $client->respond( $_ ) for ( @$ids ); @@ -264,19 +270,27 @@ sub metarecord_copy_count { my $cl_table = asset::copy_location->table; my $cs_table = config::copy_status->table; my $out_table = actor::org_unit_type->table; + my $descendants = "actor.org_unit_descendants(u.id)"; - my $ancestors = "actor.org_unit_ancestors(?)"; + my $ancestors = "actor.org_unit_ancestors(?) u JOIN $out_table t ON (u.ou_type = t.id)"; + + if ($args{org_unit} < 0) { + $args{org_unit} *= -1; + $ancestors = "(select org_unit as id from actor.org_lasso_map where lasso = ?) u CROSS JOIN (SELECT -1 AS depth) t"; + } my $copies_visible = 'AND a.opac_visible IS TRUE AND cp.opac_visible IS TRUE AND cs.holdable IS TRUE AND cl.opac_visible IS TRUE'; $copies_visible = '' if ($self->api_name =~ /staff/o); - my (@types,@forms); - my ($t_filter, $f_filter) = ('',''); + my (@types,@forms,@blvl); + my ($t_filter, $f_filter, $b_filter) = ('','',''); if ($args{format}) { - my ($t, $f) = split '-', $args{format}; + my ($t, $f, $b) = split '-', $args{format}; @types = split '', $t; @forms = split '', $f; + @blvl = split '', $b; + if (@types) { $t_filter = ' AND rd.item_type IN ('.join(',',map{'?'}@types).')'; } @@ -284,6 +298,10 @@ sub metarecord_copy_count { if (@forms) { $f_filter .= ' AND rd.item_form IN ('.join(',',map{'?'}@forms).')'; } + + if (@blvl) { + $b_filter .= ' AND rd.bib_level IN ('.join(',',map{'?'}@blvl).')'; + } } my $sql = <<" SQL"; @@ -304,6 +322,7 @@ sub metarecord_copy_count { $copies_visible $t_filter $f_filter + $b_filter ) ) AS count, sum( @@ -322,6 +341,7 @@ sub metarecord_copy_count { $copies_visible $t_filter $f_filter + $b_filter ) ) AS available, sum( @@ -340,6 +360,7 @@ sub metarecord_copy_count { AND cl.opac_visible IS TRUE $t_filter $f_filter + $b_filter ) ) AS unshadow, sum( @@ -352,8 +373,7 @@ sub metarecord_copy_count { ) ) AS transcendant - FROM $ancestors u - JOIN $out_table t ON (u.ou_type = t.id) + FROM $ancestors GROUP BY 1,2 SQL @@ -361,12 +381,15 @@ sub metarecord_copy_count { $sth->execute( ''.$args{metarecord}, @types, @forms, + @blvl, ''.$args{metarecord}, @types, @forms, + @blvl, ''.$args{metarecord}, @types, @forms, + @blvl, ''.$args{metarecord}, ''.$args{org_unit}, ); @@ -1915,10 +1938,6 @@ sub biblio_search_multi_class_fts { $ou = actor::org_unit->search( { parent_ou => undef } )->next->id; } - if (!defined($args{org_unit})) { - die "No target organizational unit passed to ".$self->api_name; - } - if (! scalar( keys %{$args{searches}} )) { die "No search arguments were passed to ".$self->api_name; } @@ -2309,6 +2328,235 @@ __PACKAGE__->register_method( cachable => 1, ); +# XXX factored most of the PG dependant stuff out of here... need to find a way to do "dependants". +sub staged_fts { + my $self = shift; + my $client = shift; + my %args = @_; + + my $ou = $args{org_unit}; + my $limit = $args{limit} || 10; + my $offset = $args{offset} || 0; + + if (!$ou) { + $ou = actor::org_unit->search( { parent_ou => undef } )->next->id; + } + + if (! scalar( keys %{$args{searches}} )) { + die "No search arguments were passed to ".$self->api_name; + } + + my (@statuses,@types,@forms,@lang,@aud,@lit_form,@vformats,@bib_level); + + if ($args{available}) { + @statuses = (0,7); + } + + if (my $s = $args{statuses}) { + $s = [$s] if (!ref($s)); + @statuses = @$s; + } + + if (my $a = $args{audience}) { + $a = [$a] if (!ref($a)); + @aud = @$a; + } + + if (my $l = $args{language}) { + $l = [$l] if (!ref($l)); + @lang = @$l; + } + + if (my $f = $args{lit_form}) { + $f = [$f] if (!ref($f)); + @lit_form = @$f; + } + + if (my $f = $args{item_form}) { + $f = [$f] if (!ref($f)); + @forms = @$f; + } + + if (my $t = $args{item_type}) { + $t = [$t] if (!ref($t)); + @types = @$t; + } + + if (my $b = $args{bib_level}) { + $b = [$b] if (!ref($b)); + @bib_level = @$b; + } + + if (my $v = $args{vr_format}) { + $v = [$v] if (!ref($v)); + @vformats = @$v; + } + + # XXX legacy format and item type support + if ($args{format}) { + my ($t, $f) = split '-', $args{format}; + @types = split '', $t; + @forms = split '', $f; + } + + my %stored_proc_search_args; + for my $search_group (sort keys %{$args{searches}}) { + (my $search_group_name = $search_group) =~ s/\|/_/gso; + my ($search_class,$search_field) = split /\|/, $search_group; + $log->debug("Searching class [$search_class] and field [$search_field]",DEBUG); + + if ($search_field) { + unless ( config::metabib_field->search( field_class => $search_class, name => $search_field )->next ) { + $log->warn("Requested class [$search_class] or field [$search_field] does not exist!"); + return undef; + } + } + + my $class = $_cdbi->{$search_class}; + my $search_table = $class->table; + + my ($index_col) = $class->columns('FTS'); + $index_col ||= 'value'; + + + my $fts = OpenILS::Application::Storage::FTS->compile( + $search_class => $args{searches}{$search_group}{term}, + $search_group_name.'.value', + "$search_group_name.$index_col" + ); + $fts->sql_where_clause; # this builds the ranks for us + + my @fts_ranks = $fts->fts_rank; + my @fts_queries = $fts->fts_query; + my @phrases = map { lc($_) } $fts->phrases; + my @words = map { lc($_) } $fts->words; + + $stored_proc_search_args{$search_group} = { + fts_rank => \@fts_ranks, + fts_query => \@fts_queries, + phrase => \@phrases, + word => \@words, + }; + + } + + my $param_search_ou = $ou; + my $param_depth = $args{depth}; $param_depth = 'NULL' unless (defined($param_depth) and length($param_depth) > 0 ); + my $param_searches = OpenSRF::Utils::JSON->perl2JSON( \%stored_proc_search_args ); $param_searches =~ s/\$//go; $param_searches = '$$'.$param_searches.'$$'; + my $param_statuses = '$${' . join(',', map { s/\$//go; $_ } @statuses) . '}$$'; + my $param_audience = '$${' . join(',', map { s/\$//go; $_ } @aud) . '}$$'; + my $param_language = '$${' . join(',', map { s/\$//go; $_ } @lang) . '}$$'; + my $param_lit_form = '$${' . join(',', map { s/\$//go; $_ } @lit_form) . '}$$'; + my $param_types = '$${' . join(',', map { s/\$//go; $_ } @types) . '}$$'; + my $param_forms = '$${' . join(',', map { s/\$//go; $_ } @forms) . '}$$'; + my $param_vformats = '$${' . join(',', map { s/\$//go; $_ } @vformats) . '}$$'; + my $param_bib_level = '$${' . join(',', map { s/\$//go; $_ } @bib_level) . '}$$'; + my $param_pref_lang = $args{preferred_language}; $param_pref_lang =~ s/\$//go; $param_pref_lang = '$$'.$param_pref_lang.'$$'; + my $param_pref_lang_multiplier = $args{preferred_language_weight}; $param_pref_lang_multiplier ||= 'NULL'; + my $param_sort = $args{'sort'}; $param_sort =~ s/\$//go; $param_sort = '$$'.$param_sort.'$$'; + my $param_sort_desc = defined($args{sort_dir}) && $args{sort_dir} =~ /^d/io ? "'t'" : "'f'"; + my $metarecord = $self->api_name =~ /metabib/o ? "'t'" : "'f'"; + my $staff = $self->api_name =~ /staff/o ? "'t'" : "'f'"; + my $param_rel_limit = $args{core_limit}; $param_rel_limit ||= 'NULL'; + my $param_chk_limit = $args{check_limit}; $param_chk_limit ||= 'NULL'; + my $param_skip_chk = $args{skip_check}; $param_skip_chk ||= 'NULL'; + + my $sth = metabib::metarecord_source_map->db_Main->prepare(<<" SQL"); + SELECT * + FROM search.staged_fts( + $param_search_ou, + $param_depth, + $param_searches, + $param_statuses, + $param_audience, + $param_language, + $param_lit_form, + $param_types, + $param_forms, + $param_vformats, + $param_bib_level, + $param_pref_lang, + $param_pref_lang_multiplier, + $param_sort, + $param_sort_desc, + $metarecord, + $staff, + $param_rel_limit, + $param_chk_limit, + $param_skip_chk + ); + SQL + + $sth->execute; + + my $recs = $sth->fetchall_arrayref({}); + my $summary_row = pop @$recs; + + my $total = $$summary_row{total}; + my $checked = $$summary_row{checked}; + my $visible = $$summary_row{visible}; + my $deleted = $$summary_row{deleted}; + my $excluded = $$summary_row{excluded}; + + my $estimate = $visible; + if ( $total > $checked && $checked ) { + my $deleted_ratio = $deleted / $checked; + my $exclution_ratio = $excluded / $checked; + my $delete_adjusted_total = $total - ( $total * $deleted_ratio ); + + $estimate = $$summary_row{estimated_hit_count} = int($delete_adjusted_total - ( $delete_adjusted_total * $exclution_ratio )); + } + + delete $$summary_row{id}; + delete $$summary_row{rel}; + delete $$summary_row{record}; + + $client->respond( $summary_row ); + + $log->debug("Search yielded ".scalar(@$recs)." checked, visible results with an approximate visible total of $estimate.",DEBUG); + + for my $rec (@$recs[$offset .. $offset + $limit - 1]) { + delete $$rec{checked}; + delete $$rec{visible}; + delete $$rec{excluded}; + delete $$rec{deleted}; + delete $$rec{total}; + $$rec{rel} = sprintf('%0.3f',$$rec{rel}); + + $client->respond( $rec ); + } + return undef; +} +__PACKAGE__->register_method( + api_name => "open-ils.storage.biblio.multiclass.staged.search_fts", + method => 'staged_fts', + api_level => 1, + stream => 1, + cachable => 1, +); +__PACKAGE__->register_method( + api_name => "open-ils.storage.biblio.multiclass.staged.search_fts.staff", + method => 'staged_fts', + api_level => 1, + stream => 1, + cachable => 1, +); +__PACKAGE__->register_method( + api_name => "open-ils.storage.metabib.multiclass.staged.search_fts", + method => 'staged_fts', + api_level => 1, + stream => 1, + cachable => 1, +); +__PACKAGE__->register_method( + api_name => "open-ils.storage.metabib.multiclass.staged.search_fts.staff", + method => 'staged_fts', + api_level => 1, + stream => 1, + cachable => 1, +); + + sub xref_count { my $self = shift; my $client = shift; diff --git a/Open-ILS/src/perlmods/OpenILS/Const.pm b/Open-ILS/src/perlmods/OpenILS/Const.pm index cf5f16bfcf..79268979aa 100644 --- a/Open-ILS/src/perlmods/OpenILS/Const.pm +++ b/Open-ILS/src/perlmods/OpenILS/Const.pm @@ -77,6 +77,10 @@ econst OILS_SETTING_DEF_ITEM_PRICE => 'cat.default_item_price'; econst OILS_SETTING_ORG_BOUNCED_EMAIL => 'org.bounced_emails'; econst OILS_SETTING_CHARGE_LOST_ON_ZERO => 'circ.charge_lost_on_zero'; econst OILS_SETTING_VOID_OVERDUE_ON_LOST => 'circ.void_overdue_on_lost'; +econst OILS_SETTING_HOLD_SOFT_STALL => 'circ.hold_stalling.soft'; +econst OILS_SETTING_HOLD_HARD_STALL => 'circ.hold_stalling.hard'; +econst OILS_SETTING_HOLD_SOFT_BOUNDARY => 'circ.hold_boundary.soft'; +econst OILS_SETTING_HOLD_HARD_BOUNDARY => 'circ.hold_boundary.hard'; diff --git a/Open-ILS/src/perlmods/OpenILS/Reporter/SQLBuilder.pm b/Open-ILS/src/perlmods/OpenILS/Reporter/SQLBuilder.pm index c12bab96a8..f5307ef425 100644 --- a/Open-ILS/src/perlmods/OpenILS/Reporter/SQLBuilder.pm +++ b/Open-ILS/src/perlmods/OpenILS/Reporter/SQLBuilder.pm @@ -949,12 +949,14 @@ sub toSQL { $sql .= " NOT BETWEEN ". join(" AND ", map { $_->toSQL } @$val); } elsif (lc($op) eq 'like') { $val = $$val[0] if (ref($val) eq 'ARRAY'); + $val = $val->toSQL; $val =~ s/^'(.*)'$/$1/o; $val =~ s/%/\\\\%/o; $val =~ s/_/\\\\_/o; $sql .= " LIKE '\%$val\%'"; } elsif (lc($op) eq 'ilike') { $val = $$val[0] if (ref($val) eq 'ARRAY'); + $val = $val->toSQL; $val =~ s/^'(.*)'$/$1/o; $val =~ s/%/\\\\%/o; $val =~ s/_/\\\\_/o; diff --git a/Open-ILS/src/perlmods/OpenILS/SIP/Patron.pm b/Open-ILS/src/perlmods/OpenILS/SIP/Patron.pm index 8f609b2a29..a780b7e69c 100644 --- a/Open-ILS/src/perlmods/OpenILS/SIP/Patron.pm +++ b/Open-ILS/src/perlmods/OpenILS/SIP/Patron.pm @@ -96,6 +96,13 @@ sub name { $u->second_given_name . ' ' . $u->family_name; } +sub home_library { + my $self = shift; + my $lib = $self->{editor}->retrieve_actor_org_unit($self->{user}->home_ou)->shortname; + syslog('LOG_DEBUG', "OILS: Patron home library is $lib"); + return $lib; +} + sub __addr_string { my $addr = shift; return "" unless $addr; diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm b/Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm index d8a05dd70d..b625f4cb55 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm @@ -52,7 +52,7 @@ sub import { next unless ($idl->{$c}{'oils_obj:fieldmapper'}); my $n = 'Fieldmapper::'.$idl->{$c}{'oils_obj:fieldmapper'}; - $log->debug("Building Fieldmapper clas for [$n] from IDL"); + $log->debug("Building Fieldmapper class for [$n] from IDL"); $$fieldmap{$n}{hint} = $c; $$fieldmap{$n}{virtual} = ($idl->{$c}{'oils_persist:virtual'} eq 'true') ? 1 : 0; diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm b/Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm index 5f69de9dff..fcef298dc6 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm @@ -34,6 +34,7 @@ sub permit_copy_hold { _direct => { requestLib => $$params{request_lib}, pickupLib => $$params{pickup_lib}, + newHold => $$params{new_hold}, } }; diff --git a/Open-ILS/src/perlmods/OpenILS/WWW/Exporter.pm b/Open-ILS/src/perlmods/OpenILS/WWW/Exporter.pm index 3c38cd1129..d02d4ff623 100644 --- a/Open-ILS/src/perlmods/OpenILS/WWW/Exporter.pm +++ b/Open-ILS/src/perlmods/OpenILS/WWW/Exporter.pm @@ -83,11 +83,25 @@ sub handler { } } + my $ses = OpenSRF::AppSession->create('open-ils.cstore'); + + # still no records ... + my $container = $cgi->param('containerid'); + if ($container) { + my $authid = $cgi->cookie('ses') || $cgi->param('ses'); + my $auth = verify_login($authid); + if (!$auth) { + return 403; + } + my $recs = $ses->request( 'open-ils.cstore.direct.container.biblio_record_entry_bucket_item.search.atomic', { bucket => $container } )->gather(1); + @records = map { ($_->target_biblio_record_entry) } @$recs; + } + return show_template($r) unless (@records); my $type = $cgi->param('rectype') || 'biblio'; if ($type ne 'biblio' && $type ne 'authority') { - die "Bad record type: $type"; + return 400; } my $tcn_v = 'tcn_value'; @@ -113,9 +127,7 @@ sub handler { binmode(STDOUT, ':utf8') if ($encoding eq 'UTF-8'); if (!grep { uc($format) eq $_ } @formats) { - die "Please select a supported format. ". - "Right now that means one of [". - join('|',@formats). "]\n"; + return 400; } if ($format ne 'XML') { @@ -123,7 +135,6 @@ sub handler { $ftype->require; } - my $ses = OpenSRF::AppSession->create('open-ils.cstore'); $r->headers_out->set("Content-Disposition" => "inline; filename=$filename"); @@ -147,7 +158,7 @@ sub handler { my $req = $ses->request( 'open-ils.cstore.direct.actor.org_unit.search', { id => { '!=' => undef } } ); while (my $o = $req->recv) { - die $req->failed->stringify if ($req->failed); + next if ($req->failed); $o = $o->content; last unless ($o); $orgs{$o->id} = $o; @@ -157,7 +168,7 @@ sub handler { $req = $ses->request( 'open-ils.cstore.direct.asset.copy_location.search', { id => { '!=' => undef } } ); while (my $s = $req->recv) { - die $req->failed->stringify if ($req->failed); + next if ($req->failed); $s = $s->content; last unless ($s); $shelves{$s->id} = $s; @@ -251,6 +262,8 @@ sub handler { $r->print($req->as_usmarc); } + $r->rflush(); + } otherwise { my $e = shift; warn "\n$e\n"; @@ -264,6 +277,23 @@ sub handler { } +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_template { my $r = shift; diff --git a/Open-ILS/src/perlmods/OpenILS/WWW/Proxy.pm b/Open-ILS/src/perlmods/OpenILS/WWW/Proxy.pm index b9ad7dfd06..84c8f4d1eb 100644 --- a/Open-ILS/src/perlmods/OpenILS/WWW/Proxy.pm +++ b/Open-ILS/src/perlmods/OpenILS/WWW/Proxy.pm @@ -15,10 +15,41 @@ use OpenSRF::System; # set the bootstrap config and template include directory when # this module is loaded my $bootstrap; +my $ssl_off; + +my $default_template = < + + TITLE + + +


+
+
+
+ + + + + + + + + + + +
DESCRIPTION
Username or barcode:
Password:
+ + + + + +HTML sub import { my $self = shift; $bootstrap = shift; + $ssl_off = shift; } @@ -39,13 +70,13 @@ sub handler { return Apache2::Const::NOT_FOUND unless (@$perms); my $cgi = new CGI; - my $auth_ses = $cgi->cookie('ses'); - my $ws_ou = $cgi->cookie('ws_ou'); + my $auth_ses = $cgi->cookie('ses') || $cgi->param('ses'); + my $ws_ou = $cgi->cookie('ws_ou') || $cgi->param('ws_ou'); my $url = $cgi->url; # push everyone to the secure site - if ($url =~ /^http:/o) { + if (!$ssl_off && $url =~ /^http:/o) { $url =~ s/^http:/https:/o; print "Location: $url\n\n"; return Apache2::Const::OK; @@ -59,7 +90,7 @@ sub handler { print $cgi->header(-type=>'text/html', -expires=>'-1d'); if (!$proxyhtml) { - $proxyhtml = join '', ; + $proxyhtml = $default_template; $proxyhtml =~ s/TITLE/$title/gso; $proxyhtml =~ s/DESCRIPTION/$desc/gso; } else { @@ -147,35 +178,5 @@ sub oils_login { return $response->{payload}->{authtoken}; } - - 1; -__DATA__ - - - TITLE - - -


-
-
- - - - - - - - - - - - -
DESCRIPTION
Username or barcode:
Password:
- -
-
- - - diff --git a/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm b/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm index 34d0a12f5e..4c2368a02d 100644 --- a/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm +++ b/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm @@ -9,6 +9,8 @@ use Apache2::RequestIO (); use Apache2::RequestUtil; use CGI; use Data::Dumper; +use SRU::Request; +use SRU::Response; use OpenSRF::EX qw(:try); use OpenSRF::Utils qw/:datetime/; @@ -27,6 +29,8 @@ use OpenSRF::Utils::Logger qw/$logger/; use MARC::Record; use MARC::File::XML; +my $log = 'OpenSRF::Utils::Logger'; + # set the bootstrap config when this module is loaded my ($bootstrap, $cstore, $supercat, $actor, $parser, $search, $xslt, $cn_browse_xslt, %browse_types); @@ -742,8 +746,8 @@ sub bookbag_feed { $feed->creator($host); $feed->update_ts(gmtime_ISO8601()); - $feed->link(rss => $base . "/rss2-full/$id" => 'application/rss+xml'); - $feed->link(alternate => $base . "/atom-full/$id" => 'application/atom+xml'); + $feed->link(alternate => $base . "/rss2-full/$id" => 'application/rss+xml'); + $feed->link(atom => $base . "/atom-full/$id" => 'application/atom+xml'); $feed->link(html => $base . "/html-full/$id" => 'text/html'); $feed->link(unapi => $unapi); @@ -778,7 +782,7 @@ sub changes_feed { my $url = $cgi->url(-path_info=>$add_path); my $root = (split 'feed', $url)[0]; - my $base = (split 'freshmeat', $url)[0] . 'freshmeat'; + my $base = (split 'freshmeat', $url)[0] . '/freshmeat'; my $unapi = (split 'feed', $url)[0] . 'unapi'; my $path = $cgi->path_info; @@ -811,8 +815,8 @@ sub changes_feed { $feed->creator($host); $feed->update_ts(gmtime_ISO8601()); - $feed->link(rss => $base . "/rss2-full/$rtype/$axis/$limit/$date" => 'application/rss+xml'); - $feed->link(alternate => $base . "/atom-full/$rtype/$axis/$limit/$date" => 'application/atom+xml'); + $feed->link(alternate => $base . "/rss2-full/$rtype/$axis/$limit/$date" => 'application/rss+xml'); + $feed->link(atom => $base . "/atom-full/$rtype/$axis/$limit/$date" => 'application/atom+xml'); $feed->link(html => $base . "/html-full/$rtype/$axis/$limit/$date" => 'text/html'); $feed->link(unapi => $unapi); @@ -956,8 +960,12 @@ sub opensearch_feed { $lang = '' if ($lang eq '*'); $sort = $cgi->param('searchSort') if $cgi->param('searchSort'); + $sort ||= ''; $sortdir = $cgi->param('searchSortDir') if $cgi->param('searchSortDir'); - $terms .= " " . $cgi->param('searchTerms') if $cgi->param('searchTerms'); + $sortdir ||= ''; + + $terms .= " " if ($terms && $cgi->param('searchTerms')); + $terms .= $cgi->param('searchTerms') if $cgi->param('searchTerms'); $class = $cgi->param('searchClass') if $cgi->param('searchClass'); $class ||= '-'; @@ -975,11 +983,16 @@ sub opensearch_feed { my $sut = $cgi->param('su'); my $set = $cgi->param('se'); - $terms .= " keyword: $kwt" if ($kwt); - $terms .= " title: $tit" if ($tit); - $terms .= " author: $aut" if ($aut); - $terms .= " subject: $sut" if ($sut); - $terms .= " series: $set" if ($set); + $terms .= " " if ($terms && $kwt); + $terms .= "keyword: $kwt" if ($kwt); + $terms .= " " if ($terms && $tit); + $terms .= "title: $tit" if ($tit); + $terms .= " " if ($terms && $aut); + $terms .= "author: $aut" if ($aut); + $terms .= " " if ($terms && $sut); + $terms .= "subject: $sut" if ($sut); + $terms .= " " if ($terms && $set); + $terms .= "series: $set" if ($set); if ($version eq '1.0') { $type = 'rss2'; @@ -988,13 +1001,6 @@ sub opensearch_feed { } my $flesh_feed = ($type =~ /-full$/o) ? 1 : 0; - $terms = decode_utf8($terms); - $terms =~ s/\+/ /go; - $terms =~ s/'//go; - $terms =~ s/^\s+//go; - my $term_copy = $terms; - - my $complex_terms = 0; if ($terms eq 'help') { print $cgi->header(-type => 'text/html'); print <<" HTML"; @@ -1008,95 +1014,58 @@ sub opensearch_feed { HTML return Apache2::Const::OK; - } - - my $cache_key = ''; - my $searches = {}; - while ($term_copy =~ s/((?:keyword(?:\|\w+)?|title(?:\|\w+)?|author(?:\|\w+)?|subject(?:\|\w+)?|series(?:\|\w+)?|site|dir|sort|lang):[^:]+)$//so) { - my ($c,$t) = split ':' => $1; - if ($c eq 'site') { - $org = $t; - $org =~ s/^\s*//o; - $org =~ s/\s*$//o; - } elsif ($c eq 'sort') { - ($sort = lc($t)) =~ s/^\s*(\w+)\s*$/$1/go; - } elsif ($c eq 'dir') { - ($sortdir = lc($t)) =~ s/^\s*(\w+)\s*$/$1/go; - } elsif ($c eq 'lang') { - ($lang = lc($t)) =~ s/^\s*(\w+)\s*$/$1/go; - } else { - $$searches{$c}{term} .= ' '.$t; - $cache_key .= $c . $t; - $complex_terms = 1; - } - } - + } + + $terms = decode_utf8($terms); $lang = 'eng' if ($lang eq 'en-US'); - if ($term_copy) { - no warnings; - $class = 'keyword' if ($class eq '-'); - $$searches{$class}{term} .= " $term_copy"; - $cache_key .= $class . $term_copy; - } + $log->debug("OpenSearch terms: $terms"); my $org_unit; if ($org eq '-') { $org_unit = $actor->request( 'open-ils.actor.org_unit_list.search' => parent_ou => undef )->gather(1); - } else { + } elsif ($org !~ /^\d+$/o) { $org_unit = $actor->request( 'open-ils.actor.org_unit_list.search' => shortname => uc($org) )->gather(1); - } - - { no warnings; $cache_key .= $org.$sort.$sortdir.$lang; } - - my $rs_name = $cgi->cookie('os_session'); - my $cached_res = OpenSRF::Utils::Cache->new->get_cache( "os_session:$rs_name" ) if ($rs_name); - - my $recs; - if (!($recs = $$cached_res{os_results}{$cache_key})) { - $rs_name = $cgi->remote_host . '::' . rand(time); - $recs = $search->request( - 'open-ils.search.biblio.multiclass' => { - searches => $searches, - org_unit => $org_unit->[0]->id, - offset => 0, - limit => 5000, - ($sort ? ( 'sort' => $sort ) : ()), - ($sortdir ? ( 'sort_dir' => $sortdir ) : ($sort ? (sort_dir => 'asc') : (sort_dir => 'desc') )), - ($lang ? ( 'language' => $lang ) : ()), - } + } else { + $org_unit = $actor->request( + 'open-ils.actor.org_unit_list.search' => id => $org )->gather(1); - try { - $$cached_res{os_results}{$cache_key} = $recs; - OpenSRF::Utils::Cache->new->put_cache( "os_session:$rs_name", $cached_res, 1800 ); - } catch Error with { - warn "supercat unable to store IDs in memcache server\n"; - $logger->error("supercat unable to store IDs in memcache server"); - }; } + my $recs = $search->request( + 'open-ils.search.biblio.multiclass.query' => { + org_unit => $org_unit->[0]->id, + offset => $offset - 1, + limit => $limit, + sort => $sort, + sort_dir => $sortdir, + ($lang ? ( 'language' => $lang ) : ()), + } => $terms => 1 + )->gather(1); + + $log->debug("Hits for [$terms]: $recs->{count}"); + my $feed = create_record_feed( 'record', $type, - [ map { $_->[0] } @{$recs->{ids}}[$offset .. $offset + $limit - 1] ], + [ map { $_->[0] } @{$recs->{ids}} ], $unapi, $org, $flesh_feed ); + + $log->debug("Feed created..."); + $feed->root($root); $feed->lib($org); $feed->search($terms); $feed->class($class); - if ($complex_terms) { - $feed->title("Search results for [$terms] at ".$org_unit->[0]->name); - } else { - $feed->title("Search results for [$class => $terms] at ".$org_unit->[0]->name); - } + $feed->title("Search results for [$terms] at ".$org_unit->[0]->name); $feed->creator($host); $feed->update_ts(gmtime_ISO8601()); @@ -1122,6 +1091,8 @@ sub opensearch_feed { $limit, ); + $log->debug("...basic feed data added..."); + $feed->link( next => $base . "/$version/$org/$type/$class?searchTerms=$terms&searchSort=$sort&searchSortDir=$sortdir&searchLang=$lang&startIndex=" . int($offset + $limit + 1) . "&count=" . $limit => @@ -1141,13 +1112,13 @@ sub opensearch_feed { ); $feed->link( - rss => + alternate => $base . "/$version/$org/rss2-full/$class?searchTerms=$terms&searchSort=$sort&searchSortDir=$sortdir&searchLang=$lang" => 'application/rss+xml' ); $feed->link( - alternate => + atom => $base . "/$version/$org/atom-full/$class?searchTerms=$terms&searchSort=$sort&searchSortDir=$sortdir&searchLang=$lang" => 'application/atom+xml' ); @@ -1166,6 +1137,8 @@ sub opensearch_feed { $feed->link( 'unapi-server' => $unapi); + $log->debug("...feed links added..."); + # $feed->link( # opac => # $root . "../$lang/skin/default/xml/rresult.xml?rt=list&" . @@ -1173,13 +1146,9 @@ sub opensearch_feed { # 'text/html' # ); - print $cgi->header( - -type => $feed->type, - -charset => 'UTF-8', - -cookie => $cgi->cookie( -name => 'os_session', -value => $rs_name, -expires => '+30m' ), - ); + print $cgi->header( -type => $feed->type, -charset => 'UTF-8') . entityize($feed->toString) . "\n"; - print entityize($feed->toString) . "\n"; + $log->debug("...and feed returned."); return Apache2::Const::OK; } @@ -1316,4 +1285,397 @@ sub string_browse { return Apache2::Const::OK; } +our %qualifier_map = ( + + # Som EG qualifiers + 'eg.site' => 'site', + 'eg.sort' => 'sort', + 'eg.direction' => 'dir', + 'eg.available' => 'available', + + # Title class: + 'eg.title' => 'title', + 'dc.title' => 'title', + 'bib.titleabbreviated' => 'title|abbreviated', + 'bib.titleuniform' => 'title|uniform', + 'bib.titletranslated' => 'title|translated', + 'bib.titlealternative' => 'title', + 'bib.titleseries' => 'series', + 'eg.series' => 'title', + + # Author/Name class: + 'eg.author' => 'title', + 'eg.name' => 'title', + 'creator' => 'author', + 'dc.creator' => 'author', + 'dc.contributer' => 'author', + 'dc.publisher' => 'keyword', + 'bib.name' => 'author', + 'bib.namepersonal' => 'author|personal', + 'bib.namepersonalfamily'=> 'author|personal', + 'bib.namepersonalgiven' => 'author|personal', + 'bib.namecorporate' => 'author|corporate', + 'bib.nameconference' => 'author|conference', + + # Subject class: + 'eg.subject' => 'subject', + 'dc.subject' => 'subject', + 'bib.subjectplace' => 'subject|geographic', + 'bib.subjecttitle' => 'keyword', + 'bib.subjectname' => 'subject|name', + 'bib.subjectoccupation' => 'keyword', + + # Keyword class: + 'eg.keyword' => 'keyword', + 'srw.serverchoice' => 'keyword', + + # Identifiers: + 'dc.identifier' => 'keyword', + + # Dates: + 'bib.dateissued' => undef, + 'bib.datecreated' => undef, + 'bib.datevalid' => undef, + 'bib.datemodified' => undef, + 'bib.datecopyright' => undef, + + # Resource Type: + 'dc.type' => undef, + + # Format: + 'dc.format' => undef, + + # Genre: + 'bib.genre' => 'keyword', + + # Target Audience: + 'bib.audience' => undef, + + # Place of Origin: + 'bib.originplace' => undef, + + # Language + 'dc.language' => 'lang', + + # Edition + 'bib.edition' => 'keyword', + + # Part: + 'bib.volume' => 'keyword', + 'bib.issue' => 'keyword', + 'bib.startpage' => 'keyword', + 'bib.endpage' => 'keyword', + + # Issuance: + 'bib.issuance' => 'keyword', +); + +our %qualifier_ids = ( + eg => 'http://open-ils.org/spec/SRU/context-set/evergreen/v1', + dc => 'info:srw/cql-context-set/1/dc-v1.1', + bib => 'info:srw/cql-context-set/1/bib-v1.0', + srw => '' +); + +our %nested_qualifier_map = ( + eg => { + site => ['site','Evergreen Site Code (shortname)'], + sort => ['sort','Sort on relevance, title, author, pubdate, create_date or edit_date'], + direction => ['dir','Sort direction (asc|desc)'], + available => ['available','Filter to availble (true|false)'], + title => ['title'], + author => ['author'], + name => ['author'], + subject => ['subject'], + keyword => ['keyword'], + series => ['series'], + }, + dc => { + title => ['title'], + creator => ['author'], + contributor => ['author'], + publisher => ['keyword'], + subject => ['subject'], + identifier => ['keyword'], + type => [undef], + format => [undef], + language => ['lang'], + }, + bib => { + # Title class: + titleAbbreviated => ['title'], + titleUniform => ['title'], + titleTranslated => ['title'], + titleAlternative => ['title'], + titleSeries => ['series'], + + # Author/Name class: + name => ['author'], + namePersonal => ['author'], + namePersonalFamily => ['author'], + namePersonalGiven => ['author'], + nameCorporate => ['author'], + nameConference => ['author'], + + # Subject class: + subjectPlace => ['subject'], + subjectTitle => ['keyword'], + subjectName => ['subject|name'], + subjectOccupation => ['keyword'], + + # Keyword class: + + # Dates: + dateIssued => [undef], + dateCreated => [undef], + dateValid => [undef], + dateModified => [undef], + dateCopyright => [undef], + + # Genre: + genre => ['keyword'], + + # Target Audience: + audience => [undef], + + # Place of Origin: + originPlace => [undef], + + # Edition + edition => ['keyword'], + + # Part: + volume => ['keyword'], + issue => ['keyword'], + startPage => ['keyword'], + endPage => ['keyword'], + + # Issuance: + issuance => ['keyword'], + }, + srw => { + serverChoice => ['keyword'], + }, +); + + +my $base_explain = < + + + + + + + + + <description primary="true"/> + </databaseInfo> + + <indexInfo> + <set identifier="info:srw/cql-context-set/1/cql-v1.2" name="cql"/> + </indexInfo> + + <schemaInfo> + <schema + identifier="info:srw/schema/1/marcxml-v1.1" + location="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd" + sort="true" + retrieve="true" + name="marcxml"> + <title>MARC21Slim (marcxml) + + + + + 10 + eg + keyword + all + marcxml + marcxml + 10 + relevant + stem + fuzzy + word + + + +XML + + +my $ex_doc; +sub sru_search { + my $cgi = new CGI; + + my $req = SRU::Request->newFromCGI( $cgi ); + my $resp = SRU::Response->newFromRequest( $req ); + + if ( $resp->type eq 'searchRetrieve' ) { + my $cql_query = $req->query; + my $search_string = $req->cql->toEvergreen; + + my $offset = $req->startRecord; + $offset-- if ($offset); + $offset ||= 0; + + my $limit = $req->maximumRecords; + $limit ||= 10; + + warn "SRU search string [$cql_query] converted to [$search_string]\n"; + + my $recs = $search->request( + 'open-ils.search.biblio.multiclass.query' => {offset => $offset, limit => $limit} => $search_string => 1 + )->gather(1); + + my $bre = $supercat->request( 'open-ils.supercat.record.object.retrieve' => [ map { $_->[0] } @{$recs->{ids}} ] )->gather(1); + + $resp->addRecord( + SRU::Response::Record->new( + recordSchema => 'info:srw/schema/1/marcxml-v1.1', + recordData => $_->marc + ) + ) for @$bre; + + $resp->numberOfRecords($recs->{count}); + + } elsif ( $resp->type eq 'explain' ) { + if (!$ex_doc) { + my $host = $cgi->virtual_host || $cgi->server_name; + + my $add_path = 0; + if ( $cgi->server_software !~ m|^Apache/2.2| ) { + my $rel_name = $cgi->url(-relative=>1); + $add_path = 1 if ($cgi->url(-path_info=>1) !~ /$rel_name$/); + } + my $base = $cgi->url(-base=>1); + my $url = $cgi->url(-path_info=>$add_path); + $url =~ s/^$base\///o; + + my $doc = $parser->parse_string($base_explain); + my $e = $doc->documentElement; + $e->findnodes('/z:explain/z:serverInfo/z:host')->shift->appendText( $host ); + $e->findnodes('/z:explain/z:serverInfo/z:port')->shift->appendText( $cgi->server_port ); + $e->findnodes('/z:explain/z:serverInfo/z:database')->shift->appendText( $url ); + + for my $name ( keys %OpenILS::WWW::SuperCat::nested_qualifier_map ) { + + my $identifier = $OpenILS::WWW::SuperCat::qualifier_ids{ $name }; + + next unless $identifier; + + my $set_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'set' ); + $set_node->setAttribute( identifier => $identifier ); + $set_node->setAttribute( name => $name ); + + $e->findnodes('/z:explain/z:indexInfo')->shift->appendChild( $set_node ); + + for my $index ( keys %{ $OpenILS::WWW::SuperCat::nested_qualifier_map{$name} } ) { + my $desc = $OpenILS::WWW::SuperCat::nested_qualifier_map{$name}{$index}[1] || $index; + + my $name_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'name' ); + + my $map_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'map' ); + $map_node->appendChild( $name_node ); + + my $title_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'title' ); + + my $index_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'index' ); + $index_node->appendChild( $title_node ); + $index_node->appendChild( $map_node ); + + $index_node->setAttribute( id => $name . '.' . $index ); + $title_node->appendText( $desc ); + $name_node->setAttribute( set => $name ); + $name_node->appendText($index ); + + $e->findnodes('/z:explain/z:indexInfo')->shift->appendChild( $index_node ); + } + } + + $ex_doc = $e->toString; + } + + $resp->record( + SRU::Response::Record->new( + recordSchema => 'info:srw/cql-context-set/2/zeerex-1.1', + recordData => $ex_doc + ) + ); + } + + print $cgi->header( -type => 'application/xml' ); + print entityize($resp->asXML) . "\n"; + return Apache2::Const::OK; +} + + +{ + package CQL::BooleanNode; + + sub toEvergreen { + my $self = shift; + my $left = $self->left(); + my $right = $self->right(); + my $leftStr = $left->toEvergreen; + my $rightStr = $right->toEvergreen(); + + my $op = '||' if uc $self->op() eq 'OR'; + $op ||= '&&'; + + return "$leftStr $rightStr"; + } + + package CQL::TermNode; + + sub toEvergreen { + my $self = shift; + my $qualifier = $self->getQualifier(); + my $term = $self->getTerm(); + my $relation = $self->getRelation(); + + my $query; + if ( $qualifier ) { + my ($qset, $qname) = split(/\./, $qualifier); + + warn "!!! $qset, $qname $OpenILS::WWW::SuperCat::nested_qualifier_map{$qset}{$qname}[0]\n"; + + if ( exists($OpenILS::WWW::SuperCat::nested_qualifier_map{$qset}{$qname}) ) { + $qualifier = $OpenILS::WWW::SuperCat::nested_qualifier_map{$qset}{$qname}[0] || 'kw'; + } + + my @modifiers = $relation->getModifiers(); + + my $base = $relation->getBase(); + if ( grep { $base eq $_ } qw/= scr exact all/ ) { + + my $quote_it = 1; + foreach my $m ( @modifiers ) { + if( grep { $m->[ 1 ] eq $_ } qw/cql.fuzzy cql.stem cql.relevant cql.word/ ) { + $quote_it = 0; + last; + } + } + + $quote_it = 0 if ( $base eq 'all' ); + $term = maybeQuote($term) if $quote_it; + + } else { + croak( "Evergreen doesn't support the $base relations" ); + } + + + } else { + $qualifier = "kw"; + } + + return "$qualifier:$term"; + } +} + 1; diff --git a/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm b/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm index 76f8a6a09f..9ad6c2c3ca 100644 --- a/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm +++ b/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm @@ -5,8 +5,11 @@ use OpenSRF::EX qw(:try); use XML::LibXML; use XML::LibXSLT; use OpenSRF::Utils::SettingsClient; +use OpenSRF::Utils::Logger qw/$logger/; use CGI; +my $log = 'OpenSRF::Utils::Logger'; + sub exists { my $class = shift; my $type = shift; @@ -212,6 +215,7 @@ sub composeDoc { sub toString { my $self = shift; $self->composeDoc; + $log->debug("Document composed"); return $self->{doc}->toString(1); } @@ -230,7 +234,8 @@ sub new { my $class = shift; my $self = $class->SUPER::build(''); $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef); - $self->{type} = 'application/xml'; + $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom'); + $self->{type} = 'application/atom+xml'; $self->{item_xpath} = '/atom:feed'; return $self; } @@ -290,10 +295,11 @@ sub new { my $class = shift; my $xml = shift; my $self = $class->SUPER::build($xml); + $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef); $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom'); $self->{item_xpath} = '/atom:entry'; $self->{holdings_xpath} = '/atom:entry'; - $self->{type} = 'application/xml'; + $self->{type} = 'application/atom+xml'; return $self; } @@ -306,7 +312,7 @@ use base 'OpenILS::WWW::SuperCat::Feed'; sub new { my $class = shift; my $self = $class->SUPER::build(''); - $self->{type} = 'application/xml'; + $self->{type} = 'application/rss+xml'; $self->{item_xpath} = '/rss/channel'; return $self; } @@ -355,7 +361,7 @@ sub new { my $class = shift; my $xml = shift; my $self = $class->SUPER::build($xml); - $self->{type} = 'application/xml'; + $self->{type} = 'application/rss+xml'; $self->{item_xpath} = '/item'; $self->{holdings_xpath} = '/item'; return $self; @@ -389,6 +395,7 @@ sub new { my $class = shift; my $xml = shift; my $self = $class->SUPER::build($xml); + $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', undef); $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', 'mods'); $self->{type} = 'application/xml'; $self->{holdings_xpath} = '/mods:mods'; @@ -441,6 +448,7 @@ sub new { my $class = shift; my $xml = shift; my $self = $class->SUPER::build($xml); + $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', undef); $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', 'mods'); $self->{type} = 'application/xml'; $self->{holdings_xpath} = '/mods:mods'; @@ -509,6 +517,7 @@ sub new { my $xml = shift; my $self = $class->SUPER::build($xml); return undef unless $self; + $self->{doc}->documentElement->setNamespace('http://www.loc.gov/MARC21/slim', undef); $self->{doc}->documentElement->setNamespace('http://www.loc.gov/MARC21/slim', 'marc'); $self->{type} = 'application/xml'; $self->{holdings_xpath} = '/marc:record'; diff --git a/Open-ILS/src/python/oils/utils/idl.py b/Open-ILS/src/python/oils/utils/idl.py index 870b86c75c..5a2eae7359 100644 --- a/Open-ILS/src/python/oils/utils/idl.py +++ b/Open-ILS/src/python/oils/utils/idl.py @@ -182,14 +182,6 @@ class IDLClass(object): else: self.virtual = False - def __getitem__(self, member): - """ - Returns the requested member using dictionary syntax. - """ - if hasattr(self, member): - exec("result = self.%s" % member) - return result - def get_field(self, field_name): try: return [f for f in self.fields if f.name == field_name][0] @@ -217,13 +209,6 @@ class IDLField(object): else: self.virtual = False - def __getitem__(self, member): - """ - Returns the requested member using dictionary syntax. - """ - if hasattr(self, member): - exec("result = self.%s" % member) - return result class IDLLink(object): def __init__(self, field, **kwargs): diff --git a/Open-ILS/src/reporter/clark-kent.pl b/Open-ILS/src/reporter/clark-kent.pl index d05f46bd1d..0be667691f 100755 --- a/Open-ILS/src/reporter/clark-kent.pl +++ b/Open-ILS/src/reporter/clark-kent.pl @@ -1,8 +1,7 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # vim:ts=4:noet: use strict; -use diagnostics; use DBI; use FileHandle; use XML::LibXML; diff --git a/Open-ILS/src/sql/Pg/002.functions.config.sql b/Open-ILS/src/sql/Pg/002.functions.config.sql index d13a4f56e7..ded3995cb0 100644 --- a/Open-ILS/src/sql/Pg/002.functions.config.sql +++ b/Open-ILS/src/sql/Pg/002.functions.config.sql @@ -40,13 +40,13 @@ $_$ LANGUAGE SQL; */ -CREATE OR REPLACE FUNCTION oils_i18n_xlate ( keytable TEXT, keycol TEXT, identcol TEXT, keyvalue TEXT, raw_locale TEXT ) RETURNS TEXT AS $func$ +CREATE OR REPLACE FUNCTION oils_i18n_xlate ( keytable TEXT, keyclass TEXT, keycol TEXT, identcol TEXT, keyvalue TEXT, raw_locale TEXT ) RETURNS TEXT AS $func$ DECLARE locale TEXT := LOWER( REGEXP_REPLACE( REGEXP_REPLACE( raw_locale, E'[;, ].+$', '' ), E'-', '_', 'g' ) ); language TEXT := REGEXP_REPLACE( locale, E'_.+$', '' ); result config.i18n_core%ROWTYPE; fallback TEXT; - keyfield TEXT := keytable || '.' || keycol; + keyfield TEXT := keyclass || '.' || keycol; BEGIN -- Try the full locale @@ -85,5 +85,9 @@ CREATE OR REPLACE FUNCTION oils_i18n_gettext( TEXT ) RETURNS TEXT AS $$ SELECT $1; $$ LANGUAGE SQL; +CREATE OR REPLACE FUNCTION public.first_word ( TEXT ) RETURNS TEXT AS $$ + SELECT SUBSTRING( $1 FROM $_$^\S+$_$); +$$ LANGUAGE SQL; + COMMIT; diff --git a/Open-ILS/src/sql/Pg/005.schema.actors.sql b/Open-ILS/src/sql/Pg/005.schema.actors.sql index 745435ce64..596135c3f2 100644 --- a/Open-ILS/src/sql/Pg/005.schema.actors.sql +++ b/Open-ILS/src/sql/Pg/005.schema.actors.sql @@ -4,7 +4,7 @@ BEGIN; CREATE SCHEMA actor; COMMENT ON SCHEMA actor IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * Schema: actor @@ -66,7 +66,7 @@ CREATE TABLE actor.usr ( ); COMMENT ON TABLE actor.usr IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * User objects @@ -150,7 +150,7 @@ CREATE TABLE actor.usr_standing_penalty ( ); COMMENT ON TABLE actor.usr_standing_penalty IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * User standing penalties @@ -180,7 +180,7 @@ CREATE TABLE actor.usr_setting ( ); COMMENT ON TABLE actor.usr_setting IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * User settings @@ -214,7 +214,7 @@ CREATE TABLE actor.stat_cat ( ); COMMENT ON TABLE actor.stat_cat IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * User Statistical Catagories @@ -246,7 +246,7 @@ CREATE TABLE actor.stat_cat_entry ( ); COMMENT ON TABLE actor.stat_cat_entry IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * User Statistical Catagory Entries @@ -280,7 +280,7 @@ CREATE TABLE actor.stat_cat_entry_usr_map ( ); COMMENT ON TABLE actor.stat_cat_entry_usr_map IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * Statistical Catagory Entry to User map @@ -312,7 +312,7 @@ CREATE TABLE actor.card ( ); COMMENT ON TABLE actor.card IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * Library Cards @@ -371,6 +371,19 @@ CREATE INDEX actor_org_unit_billing_address_idx ON actor.org_unit (billing_addre CREATE INDEX actor_org_unit_mailing_address_idx ON actor.org_unit (mailing_address); CREATE INDEX actor_org_unit_holds_address_idx ON actor.org_unit (holds_address); +CREATE TABLE actor.org_lasso ( + id SERIAL PRIMARY KEY, + name TEXT UNIQUE +); + +CREATE TABLE actor.org_lasso_map ( + id SERIAL PRIMARY KEY, + lasso INT NOT NULL REFERENCES actor.org_lasso (id) ON DELETE CASCADE, + org_unit INT NOT NULL REFERENCES actor.org_unit (id) ON DELETE CASCADE +); +CREATE UNIQUE INDEX ou_lasso_lasso_ou_idx ON actor.org_lasso_map (lasso, org_unit); +CREATE INDEX ou_lasso_org_unit_idx ON actor.org_lasso_map (org_unit); + CREATE TABLE actor.org_unit_proximity ( id BIGSERIAL PRIMARY KEY, from_org INT, @@ -431,7 +444,7 @@ CREATE TABLE actor.org_unit_setting ( ); COMMENT ON TABLE actor.org_unit_setting IS $$ /* - * Copyright (C) 2005 Georgia Public Library Service + * Copyright (C) 2005-2008 Equinox Software, Inc. / Georgia Public Library Service * Mike Rylander * * Org Unit settings @@ -497,4 +510,8 @@ CREATE TABLE actor.org_address ( CREATE INDEX actor_org_address_org_unit_idx ON actor.org_address (org_unit); +CREATE OR REPLACE FUNCTION public.first5 ( TEXT ) RETURNS TEXT AS $$ + SELECT SUBSTRING( $1, 1, 5); +$$ LANGUAGE SQL; + COMMIT; diff --git a/Open-ILS/src/sql/Pg/020.schema.functions.sql b/Open-ILS/src/sql/Pg/020.schema.functions.sql index c2a85bd4f5..0ba1add6e4 100644 --- a/Open-ILS/src/sql/Pg/020.schema.functions.sql +++ b/Open-ILS/src/sql/Pg/020.schema.functions.sql @@ -17,9 +17,12 @@ CREATE OR REPLACE FUNCTION public.non_filing_normalize ( TEXT, "char" ) RETURNS $$ LANGUAGE SQL STRICT IMMUTABLE; CREATE OR REPLACE FUNCTION public.naco_normalize( TEXT, TEXT ) RETURNS TEXT AS $func$ + use Unicode::Normalize; + my $txt = lc(shift); my $sf = shift; + $txt = NFD($txt); $txt =~ s/\pM+//go; # Remove diacritics $txt =~ s/\xE6/AE/go; # Convert ae digraph @@ -33,7 +36,7 @@ CREATE OR REPLACE FUNCTION public.naco_normalize( TEXT, TEXT ) RETURNS TEXT AS $ $txt =~ tr/\x{2113}\xF0\!\"\(\)\-\{\}\<\>\;\:\.\?\xA1\xBF\/\\\@\*\%\=\xB1\+\xAE\xA9\x{2117}\$\xA3\x{FFE1}\xB0\^\_\~\`/LD /; # Convert Misc $txt =~ tr/\'\[\]\|//d; # Remove Misc - if ($sf =~ /^a/o) { + if ($sf && $sf =~ /^a/o) { my $commapos = index($txt,','); if ($commapos > -1) { if ($commapos != length($txt) - 1) { @@ -59,17 +62,47 @@ CREATE OR REPLACE FUNCTION public.naco_normalize( TEXT ) RETURNS TEXT AS $func$ SELECT public.naco_normalize($1,''); $func$ LANGUAGE 'sql' STRICT IMMUTABLE; +CREATE OR REPLACE FUNCTION public.normalize_space( TEXT ) RETURNS TEXT AS $$ + SELECT regexp_replace(regexp_replace(regexp_replace($1, E'\\n', ' ', 'g'), E'(?:^\\s+)|(\\s+$)', '', 'g'), E'\\s+', ' ', 'g'); +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION public.lowercase( TEXT ) RETURNS TEXT AS $$ + return lc(shift); +$$ LANGUAGE PLPERLU; + +CREATE OR REPLACE FUNCTION public.uppercase( TEXT ) RETURNS TEXT AS $$ + return uc(shift); +$$ LANGUAGE PLPERLU; + +CREATE OR REPLACE FUNCTION public.remove_diacritics( TEXT ) RETURNS TEXT AS $$ + use Unicode::Normalize; + + my $x = NFD(shift); + $x =~ s/\pM+//go; + return $x; + +$$ LANGUAGE PLPERLU; + +CREATE OR REPLACE FUNCTION public.entityize( TEXT ) RETURNS TEXT AS $$ + use Unicode::Normalize; + + my $x = NFC(shift); + $x =~ s/([\x{0080}-\x{fffd}])/sprintf('&#x%X;',ord($1))/sgoe; + return $x; + +$$ LANGUAGE PLPERLU; + CREATE OR REPLACE FUNCTION public.call_number_dewey( TEXT ) RETURNS TEXT AS $$ my $txt = shift; $txt =~ s/^\s+//o; $txt =~ s/[\[\]\{\}\(\)`'"#<>\*\?\-\+\$\\]+//o; $txt =~ s/\s+$//o; - if (/(\d{3}(?:\.\d+)?)/o) { + if ($txt =~ /(\d{3}(?:\.\d+)?)/o) { return $1; } else { return (split /\s+/, $txt)[0]; } -$$ LANGUAGE 'plperl' STRICT IMMUTABLE; +$$ LANGUAGE 'plperlu' STRICT IMMUTABLE; CREATE OR REPLACE FUNCTION public.call_number_dewey( TEXT, INT ) RETURNS TEXT AS $$ SELECT SUBSTRING(call_number_dewey($1) FROM 1 FOR $2); diff --git a/Open-ILS/src/sql/Pg/090.schema.action.sql b/Open-ILS/src/sql/Pg/090.schema.action.sql index 0e06d3b43a..e54287782d 100644 --- a/Open-ILS/src/sql/Pg/090.schema.action.sql +++ b/Open-ILS/src/sql/Pg/090.schema.action.sql @@ -89,6 +89,7 @@ CREATE TABLE action.circulation ( due_date TIMESTAMP WITH TIME ZONE, stop_fines_time TIMESTAMP WITH TIME ZONE, checkin_time TIMESTAMP WITH TIME ZONE, + create_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), duration INTERVAL, -- derived from "circ duration" rule fine_interval INTERVAL NOT NULL DEFAULT '1 day'::INTERVAL, -- derived from "circ fine" rule recuring_fine NUMERIC(6,2), -- derived from "circ fine" rule diff --git a/Open-ILS/src/sql/Pg/100.circ_matrix.sql b/Open-ILS/src/sql/Pg/100.circ_matrix.sql new file mode 100644 index 0000000000..321e697f27 --- /dev/null +++ b/Open-ILS/src/sql/Pg/100.circ_matrix.sql @@ -0,0 +1,389 @@ + +BEGIN; + +-- NOTE: current config.item_type should get sip2_media_type and magnetic_media columns + +-- New table needed to handle circ modifiers inside the DB. Will still require +-- central admin. The circ_modifier column on asset.copy will become an fkey to this table. +CREATE TABLE config.circ_modifier ( + code TEXT PRIMARY KEY, + name TEXT UNIQUE NOT NULL, + description TEXT NOT NULL, + sip2_media_type TEXT NOT NULL, + magnetic_media BOOL NOT NULL DEFAULT TRUE +); + +/* +-- for instance ... +INSERT INTO config.circ_modifier VALUES ( 'DVD', 'DVD', 'um ... DVDs', '001', FALSE ); +INSERT INTO config.circ_modifier VALUES ( 'VIDEO', 'VIDEO', 'Tapes', '001', TRUE ); +INSERT INTO config.circ_modifier VALUES ( 'BOOK', 'BOOK', 'Dead tree', '001', FALSE ); +INSERT INTO config.circ_modifier VALUES ( 'CRAZY_ARL-ATH_SETTING', 'R2R_TAPE', 'reel2reel tape', '007', TRUE ); +*/ + +-- But, just to get us started, use this +/* + +UPDATE asset.copy SET circ_modifier = UPPER(circ_modifier) WHERE circ_modifier IS NOT NULL AND circ_modifier <> ''; +UPDATE asset.copy SET circ_modifier = NULL WHERE circ_modifier = ''; + +INSERT INTO config.circ_modifier (code, name, description, sip2_media_type ) + SELECT DISTINCT + UPPER(circ_modifier), + UPPER(circ_modifier), + LOWER(circ_modifier), + '001' + FROM asset.copy + WHERE circ_modifier IS NOT NULL; + +*/ + +-- add an fkey pointing to the new circ mod table +ALTER TABLE asset.copy ADD CONSTRAINT circ_mod_fkey FOREIGN KEY (circ_modifier) REFERENCES config.circ_modifier (code) ON UPDATE CASCADE ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; + +-- config table to hold the vr_format names +CREATE TABLE config.videorecording_format_map ( + code TEXT PRIMARY KEY, + value TEXT NOT NULL +); + +INSERT INTO config.videorecording_format_map VALUES ('a','Beta'); +INSERT INTO config.videorecording_format_map VALUES ('b','VHS'); +INSERT INTO config.videorecording_format_map VALUES ('c','U-matic'); +INSERT INTO config.videorecording_format_map VALUES ('d','EIAJ'); +INSERT INTO config.videorecording_format_map VALUES ('e','Type C'); +INSERT INTO config.videorecording_format_map VALUES ('f','Quadruplex'); +INSERT INTO config.videorecording_format_map VALUES ('g','Laserdisc'); +INSERT INTO config.videorecording_format_map VALUES ('h','CED'); +INSERT INTO config.videorecording_format_map VALUES ('i','Betacam'); +INSERT INTO config.videorecording_format_map VALUES ('j','Betacam SP'); +INSERT INTO config.videorecording_format_map VALUES ('k','Super-VHS'); +INSERT INTO config.videorecording_format_map VALUES ('m','M-II'); +INSERT INTO config.videorecording_format_map VALUES ('o','D-2'); +INSERT INTO config.videorecording_format_map VALUES ('p','8 mm.'); +INSERT INTO config.videorecording_format_map VALUES ('q','Hi-8 mm.'); +INSERT INTO config.videorecording_format_map VALUES ('u','Unknown'); +INSERT INTO config.videorecording_format_map VALUES ('v','DVD'); +INSERT INTO config.videorecording_format_map VALUES ('z','Other'); + + + +/** + ** Here we define the tables that make up the circ matrix. Conceptually, this implements + ** the "sparse matrix" that everyone talks about, instead of using traditional rules logic. + ** Physically, we cut the matrix up into separate tables (almost 3rd normal form!) that handle + ** different portions of the matrix. This wil simplify creation of the UI (I hope), and help the + ** developers focus on specific parts of the matrix. + **/ + + +-- +-- ****** Which ruleset and tests to use ******* +-- +-- * Most specific range for org_unit and grp wins. +-- +-- * circ_modifier match takes precidence over marc_type match, if circ_modifier is set here +-- +-- * marc_type is first checked against the circ_as_type from the copy, then the item type from the marc record +-- +-- * If neither circ_modifier nor marc_type is set (both are NULLABLE) then the entry defines the default +-- ruleset and tests for the OU + group (like BOOK in PINES) +-- + +CREATE TABLE config.circ_matrix_matchpoint ( + id SERIAL PRIMARY KEY, + active BOOL NOT NULL DEFAULT TRUE, + org_unit INT NOT NULL REFERENCES actor.org_unit (id), -- Set to the top OU for the matchpoint applicability range; we can use org_unit_prox to choose the "best" + grp INT NOT NULL REFERENCES permission.grp_tree (id), -- Set to the top applicable group from the group tree; will need decendents and prox functions for filtering + circ_modifier TEXT REFERENCES config.circ_modifier (code), + marc_type TEXT REFERENCES config.item_type_map (code), + marc_form TEXT REFERENCES config.item_form_map (code), + marc_vr_format TEXT REFERENCES config.videorecording_format_map (code), + ref_flag BOOL, + usr_age_lower_bound INTERVAL, + usr_age_upper_bound INTERVAL, + CONSTRAINT ep_once_per_grp_loc_mod_marc UNIQUE (grp, org_unit, circ_modifier, marc_type, marc_form, marc_vr_format, ref_flag, usr_age_lower_bound, usr_age_upper_bound) +); + + +-- Tests to determine if circ can occur for this item at this location for this patron +CREATE TABLE config.circ_matrix_test ( + matchpoint INT PRIMARY KEY NOT NULL REFERENCES config.circ_matrix_matchpoint (id) ON DELETE CASCADE, + circulate BOOL NOT NULL DEFAULT TRUE, -- Hard "can't circ" flag requiring an override + max_items_out INT, -- Total current active circulations must be less than this, NULL means skip (always pass) + max_overdue INT, -- Total overdue active circulations must be less than this, NULL means skip (always pass) + max_fines NUMERIC(8,2), -- Total fines owed must be less than this, NULL means skip (always pass) + script_test TEXT -- filename or javascript source ?? +); + +-- Tests for max items out by circ_modifier +CREATE TABLE config.circ_matrix_circ_mod_test ( + id SERIAL PRIMARY KEY, + matchpoint INT NOT NULL REFERENCES config.circ_matrix_matchpoint (id) ON DELETE CASCADE, + items_out INT NOT NULL, -- Total current active circulations must be less than this, NULL means skip (always pass) + circ_mod TEXT NOT NULL REFERENCES config.circ_modifier (code) ON DELETE CASCADE ON UPDATE CASCADE -- circ_modifier type that the max out applies to +); + + +-- How to circ, assuming tests pass +CREATE TABLE config.circ_matrix_ruleset ( + matchpoint INT PRIMARY KEY REFERENCES config.circ_matrix_matchpoint (id), + duration_rule INT NOT NULL REFERENCES config.rule_circ_duration (id), + recurring_fine_rule INT NOT NULL REFERENCES config.rule_recuring_fine (id), + max_fine_rule INT NOT NULL REFERENCES config.rule_max_fine (id) +); + +CREATE OR REPLACE FUNCTION action.find_circ_matrix_matchpoint( context_ou INT, match_item BIGINT, match_user INT ) RETURNS INT AS $func$ +DECLARE + current_group permission.grp_tree%ROWTYPE; + user_object actor.usr%ROWTYPE; + item_object asset.copy%ROWTYPE; + rec_descriptor metabib.rec_descriptor%ROWTYPE; + current_mp config.circ_matrix_matchpoint%ROWTYPE; + matchpoint config.circ_matrix_matchpoint%ROWTYPE; +BEGIN + SELECT INTO user_object * FROM actor.usr WHERE id = match_user; + SELECT INTO item_object * FROM asset.copy WHERE id = match_item; + SELECT INTO rec_descriptor r.* FROM metabib.rec_descriptor r JOIN asset.call_number c USING (record) WHERE c.id = item_object.call_number; + SELECT INTO current_group * FROM permission.grp_tree WHERE id = user_object.profile; + + LOOP + -- for each potential matchpoint for this ou and group ... + FOR current_mp IN + SELECT m.* + FROM config.circ_matrix_matchpoint m + JOIN actor.org_unit_ancestors( context_ou ) d ON (m.org_unit = d.id) + LEFT JOIN actor.org_unit_proximity p ON (p.from_org = context_ou AND p.to_org = d.id) + WHERE m.grp = current_group.id AND m.active + ORDER BY CASE WHEN p.prox IS NULL THEN 999 ELSE p.prox END, + CASE WHEN m.circ_modifier IS NOT NULL THEN 32 ELSE 0 END + + CASE WHEN m.marc_type IS NOT NULL THEN 16 ELSE 0 END + + CASE WHEN m.marc_form IS NOT NULL THEN 8 ELSE 0 END + + CASE WHEN m.marc_vr_format IS NOT NULL THEN 4 ELSE 0 END + + CASE WHEN m.ref_flag IS NOT NULL THEN 2 ELSE 0 END + + CASE WHEN m.usr_age_lower_bound IS NOT NULL THEN 0.5 ELSE 0 END + + CASE WHEN m.usr_age_upper_bound IS NOT NULL THEN 0.5 ELSE 0 END DESC LOOP + + IF current_mp.circ_modifier IS NOT NULL THEN + CONTINUE WHEN current_mp.circ_modifier <> item_object.circ_modifier; + END IF; + + IF current_mp.marc_type IS NOT NULL THEN + IF item_object.circ_as_type IS NOT NULL THEN + CONTINUE WHEN current_mp.marc_type <> item_object.circ_as_type; + ELSE + CONTINUE WHEN current_mp.marc_type <> rec_descriptor.item_type; + END IF; + END IF; + + IF current_mp.marc_form IS NOT NULL THEN + CONTINUE WHEN current_mp.marc_form <> rec_descriptor.item_form; + END IF; + + IF current_mp.marc_vr_format IS NOT NULL THEN + CONTINUE WHEN current_mp.marc_vr_format <> rec_descriptor.vr_format; + END IF; + + IF current_mp.ref_flag IS NOT NULL THEN + CONTINUE WHEN current_mp.ref_flag <> item_object.ref; + END IF; + + IF current_mp.usr_age_lower_bound IS NOT NULL THEN + CONTINUE WHEN user_object.dob IS NULL OR current_mp.usr_age_lower_bound < age(user_object.dob); + END IF; + + IF current_mp.usr_age_upper_bound IS NOT NULL THEN + CONTINUE WHEN user_object.dob IS NULL OR current_mp.usr_age_upper_bound > age(user_object.dob); + END IF; + + + -- everything was undefined or matched + matchpoint = current_mp; + + EXIT WHEN matchpoint.id IS NOT NULL; + END LOOP; + + EXIT WHEN current_group.parent IS NULL OR matchpoint.id IS NOT NULL; + + SELECT INTO current_group * FROM permission.grp_tree WHERE id = current_group.parent; + END LOOP; + + RETURN matchpoint.id; +END; +$func$ LANGUAGE plpgsql; + + +CREATE TYPE action.matrix_test_result AS ( success BOOL, matchpoint INT, fail_part TEXT ); +CREATE OR REPLACE FUNCTION action.item_user_circ_test( circ_ou INT, match_item BIGINT, match_user INT, renewal BOOL ) RETURNS SETOF action.matrix_test_result AS $func$ +DECLARE + matchpoint_id INT; + user_object actor.usr%ROWTYPE; + item_object asset.copy%ROWTYPE; + item_status_object config.copy_status%ROWTYPE; + item_location_object asset.copy_location%ROWTYPE; + result action.matrix_test_result; + circ_test config.circ_matrix_test%ROWTYPE; + out_by_circ_mod config.circ_matrix_circ_mod_test%ROWTYPE; + items_out INT; + items_overdue INT; + current_fines NUMERIC(8,2) := 0.0; + tmp_fines NUMERIC(8,2); + tmp_xact BIGINT; + done BOOL := FALSE; +BEGIN + result.success := TRUE; + + -- Fail if the user is BARRED + SELECT INTO user_object * FROM actor.usr WHERE id = match_user; + + -- Fail if we couldn't find a set of tests + IF user_object.id IS NULL THEN + result.fail_part := 'no_user'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + RETURN; + END IF; + + IF user_object.barred IS TRUE THEN + result.fail_part := 'actor.usr.barred'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + + -- Fail if the item can't circulate + SELECT INTO item_object * FROM asset.copy WHERE id = match_item; + IF item_object.circulate IS FALSE THEN + result.fail_part := 'asset.copy.circulate'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + + -- Fail if the item isn't in a circulateable status on a non-renewal + IF NOT renewal AND item_object.status NOT IN ( 0, 7, 8 ) THEN + result.fail_part := 'asset.copy.status'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + ELSIF renewal AND item_object.status <> 1 THEN + result.fail_part := 'asset.copy.status'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + + -- Fail if the item can't circulate because of the shelving location + SELECT INTO item_location_object * FROM asset.copy_location WHERE id = item_object.location; + IF item_location_object.circulate IS FALSE THEN + result.fail_part := 'asset.copy_location.circulate'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + + SELECT INTO matchpoint_id action.find_circ_matrix_matchpoint(circ_ou, match_item, match_user); + result.matchpoint := matchpoint_id; + + -- Fail if we couldn't find a set of tests + IF result.matchpoint IS NULL THEN + result.fail_part := 'no_matchpoint'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + + -- Fail if the test is set to hard non-circulating + IF circ_test.circulate IS FALSE THEN + result.fail_part := 'config.circ_matrix_test.circulate'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + + -- Fail if the user has too many items checked out + IF circ_test.max_items_out IS NOT NULL THEN + SELECT INTO items_out COUNT(*) + FROM action.circulation + WHERE usr = match_user + AND checkin_time IS NULL + AND (stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE') OR stop_fines IS NULL); + IF items_out >= circ_test.max_items_out THEN + result.fail_part := 'config.circ_matrix_test.max_items_out'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + END IF; + + -- Fail if the user has too many items with specific circ_modifiers checked out + FOR out_by_circ_mod IN SELECT * FROM config.circ_matrix_circ_mod_test WHERE matchpoint = matchpoint_id LOOP + SELECT INTO items_out COUNT(*) + FROM action.circulation circ + JOIN asset.copy cp ON (cp.id = circ.target_copy) + WHERE circ.usr = match_user + AND circ.checkin_time IS NULL + AND (circ.stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE') OR circ.stop_fines IS NULL) + AND cp.circ_modifier = out_by_circ_mod.circ_mod; + IF items_out >= out_by_circ_mod.items_out THEN + result.fail_part := 'config.circ_matrix_circ_mod_test'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + END LOOP; + + -- Fail if the user has too many overdue items + IF circ_test.max_overdue IS NOT NULL THEN + SELECT INTO items_overdue COUNT(*) + FROM action.circulation + WHERE usr = match_user + AND checkin_time IS NULL + AND due_date < NOW() + AND (stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE') OR stop_fines IS NULL); + IF items_overdue >= circ_test.max_overdue THEN + result.fail_part := 'config.circ_matrix_test.max_overdue'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + END IF; + + -- Fail if the user has a high fine balance + IF circ_test.max_fines IS NOT NULL THEN + FOR tmp_xact IN SELECT id FROM money.billable_xact WHERE usr = match_usr AND xact_finish IS NULL LOOP + SELECT INTO tmp_fines SUM( amount ) FROM money.billing WHERE xact = tmp_xact AND NOT voided; + current_fines = current_fines + COALESCE(tmp_fines, 0.0); + SELECT INTO tmp_fines SUM( amount ) FROM money.payment WHERE xact = tmp_xact AND NOT voided; + current_fines = current_fines - COALESCE(tmp_fines, 0.0); + END LOOP; + + IF current_fines >= circ_test.max_overdue THEN + result.fail_part := 'config.circ_matrix_test.max_fines'; + result.success := FALSE; + RETURN NEXT result; + done := TRUE; + END IF; + END IF; + + -- If we passed everything, return the successful matchpoint id + IF NOT done THEN + RETURN NEXT result; + END IF; + + RETURN; +END; +$func$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION action.item_user_circ_test( INT, BIGINT, INT ) RETURNS SETOF action.matrix_test_result AS $func$ + SELECT * FROM action.item_user_circ_test( $1, $2, $3, FALSE ); +$func$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION action.item_user_renew_test( INT, BIGINT, INT ) RETURNS SETOF action.matrix_test_result AS $func$ + SELECT * FROM action.item_user_circ_test( $1, $2, $3, TRUE ); +$func$ LANGUAGE SQL; + + +COMMIT; + diff --git a/Open-ILS/src/sql/Pg/110.hold_matrix.sql b/Open-ILS/src/sql/Pg/110.hold_matrix.sql new file mode 100644 index 0000000000..ac34949f9c --- /dev/null +++ b/Open-ILS/src/sql/Pg/110.hold_matrix.sql @@ -0,0 +1,278 @@ +BEGIN; + + +-- +-- ****** Which ruleset and tests to use ******* +-- +-- * Most specific range for org_unit and grp wins. +-- +-- * circ_modifier match takes precidence over marc_type match, if circ_modifier is set here +-- +-- * marc_type is first checked against the circ_as_type from the copy, then the item type from the marc record +-- +-- * If neither circ_modifier nor marc_type is set (both are NULLABLE) then the entry defines the default +-- ruleset and tests for the OU + group (like BOOK in PINES) +-- + + + +CREATE TABLE config.hold_matrix_matchpoint ( + id SERIAL PRIMARY KEY, + active BOOL NOT NULL DEFAULT TRUE, + user_home_ou INT REFERENCES actor.org_unit (id), -- Set to the top OU for the matchpoint applicability range; we can use org_unit_prox to choose the "best" + request_ou INT REFERENCES actor.org_unit (id), -- Set to the top OU for the matchpoint applicability range; we can use org_unit_prox to choose the "best" + pickup_ou INT REFERENCES actor.org_unit (id), -- Set to the top OU for the matchpoint applicability range; we can use org_unit_prox to choose the "best" + item_owning_ou INT REFERENCES actor.org_unit (id), -- Set to the top OU for the matchpoint applicability range; we can use org_unit_prox to choose the "best" + item_circ_ou INT REFERENCES actor.org_unit (id), -- Set to the top OU for the matchpoint applicability range; we can use org_unit_prox to choose the "best" + usr_grp INT REFERENCES permission.grp_tree (id), -- Set to the top applicable group from the group tree; will need decendents and prox functions for filtering + requestor_grp INT NOT NULL REFERENCES permission.grp_tree (id), -- Set to the top applicable group from the group tree; will need decendents and prox functions for filtering + circ_modifier TEXT REFERENCES config.circ_modifier (code), + marc_type TEXT REFERENCES config.item_type_map (code), + marc_form TEXT REFERENCES config.item_form_map (code), + marc_vr_format TEXT REFERENCES config.videorecording_format_map (code), + ref_flag BOOL, + CONSTRAINT hous_once_per_grp_loc_mod_marc UNIQUE (user_home_ou, request_ou, pickup_ou, item_owning_ou, item_circ_ou, requestor_grp, usr_grp, circ_modifier, marc_type, marc_form, marc_vr_format) +); + +INSERT INTO config.hold_matrix_matchpoint (requestor_grp) VALUES (1); + +-- Tests to determine if hold against a specific copy is possible for a user at (and from) a location +CREATE TABLE config.hold_matrix_test ( + matchpoint INT PRIMARY KEY REFERENCES config.hold_matrix_matchpoint (id), + holdable BOOL NOT NULL DEFAULT TRUE, -- Hard "can't hold" flag requiring an override + distance_is_from_owner BOOL NOT NULL DEFAULT FALSE, -- How to calculate transit_range. True means owning lib, false means copy circ lib + transit_range INT REFERENCES actor.org_unit_type (id), -- Can circ inside range of cn.owner/cp.circ_lib at depth of the org_unit_type specified here + max_holds INT, -- Total hold requests must be less than this, NULL means skip (always pass) + include_frozen_holds BOOL NOT NULL DEFAULT TRUE, -- Include frozen hold requests in the count for max_holds test + age_hold_protect_rule INT REFERENCES config.rule_age_hold_protect (id) -- still not sure we want to move this off the copy +); + +CREATE OR REPLACE FUNCTION action.find_hold_matrix_matchpoint( pickup_ou INT, request_ou INT, match_item BIGINT, match_user INT, match_requestor INT ) RETURNS INT AS $func$ +DECLARE + current_requestor_group permission.grp_tree%ROWTYPE; + root_ou actor.org_unit%ROWTYPE; + requestor_object actor.usr%ROWTYPE; + user_object actor.usr%ROWTYPE; + item_object asset.copy%ROWTYPE; + item_cn_object asset.call_number%ROWTYPE; + rec_descriptor metabib.rec_descriptor%ROWTYPE; + current_mp_weight FLOAT; + matchpoint_weight FLOAT; + tmp_weight FLOAT; + current_mp config.hold_matrix_matchpoint%ROWTYPE; + matchpoint config.hold_matrix_matchpoint%ROWTYPE; +BEGIN + SELECT INTO root_ou * FROM actor.org_unit WHERE parent_ou IS NULL; + SELECT INTO user_object * FROM actor.usr WHERE id = match_user; + SELECT INTO requestor_object * FROM actor.usr WHERE id = match_requestor; + SELECT INTO item_object * FROM asset.copy WHERE id = match_item; + SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number; + SELECT INTO rec_descriptor r.* FROM metabib.rec_descriptor r WHERE r.record = item_cn_object.record; + SELECT INTO current_requestor_group * FROM permission.grp_tree WHERE id = requestor_object.profile; + + LOOP + -- for each potential matchpoint for this ou and group ... + FOR current_mp IN + SELECT m.* + FROM config.hold_matrix_matchpoint m + WHERE m.requestor_grp = current_requestor_group.id AND m.active + ORDER BY CASE WHEN m.circ_modifier IS NOT NULL THEN 16 ELSE 0 END + + CASE WHEN m.marc_type IS NOT NULL THEN 8 ELSE 0 END + + CASE WHEN m.marc_form IS NOT NULL THEN 4 ELSE 0 END + + CASE WHEN m.marc_vr_format IS NOT NULL THEN 2 ELSE 0 END + + CASE WHEN m.ref_flag IS NOT NULL THEN 1 ELSE 0 END DESC LOOP + + current_mp_weight := 5.0; + + IF current_mp.circ_modifier IS NOT NULL THEN + CONTINUE WHEN current_mp.circ_modifier <> item_object.circ_modifier; + END IF; + + IF current_mp.marc_type IS NOT NULL THEN + IF item_object.circ_as_type IS NOT NULL THEN + CONTINUE WHEN current_mp.marc_type <> item_object.circ_as_type; + ELSE + CONTINUE WHEN current_mp.marc_type <> rec_descriptor.item_type; + END IF; + END IF; + + IF current_mp.marc_form IS NOT NULL THEN + CONTINUE WHEN current_mp.marc_form <> rec_descriptor.item_form; + END IF; + + IF current_mp.marc_vr_format IS NOT NULL THEN + CONTINUE WHEN current_mp.marc_vr_format <> rec_descriptor.vr_format; + END IF; + + IF current_mp.ref_flag IS NOT NULL THEN + CONTINUE WHEN current_mp.ref_flag <> item_object.ref; + END IF; + + + -- caclulate the rule match weight + IF current_mp.item_owning_ou IS NOT NULL AND current_mp.item_owning_ou <> root_ou.id THEN + SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.item_owning_ou, item_cn_object.owning_lib)::FLOAT + 1.0)::FLOAT; + current_mp_weight := current_mp_weight - tmp_weight; + END IF; + + IF current_mp.item_circ_ou IS NOT NULL AND current_mp.item_circ_ou <> root_ou.id THEN + SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.item_circ_ou, item_object.circ_lib)::FLOAT + 1.0)::FLOAT; + current_mp_weight := current_mp_weight - tmp_weight; + END IF; + + IF current_mp.pickup_ou IS NOT NULL AND current_mp.pickup_ou <> root_ou.id THEN + SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.pickup_ou, pickup_ou)::FLOAT + 1.0)::FLOAT; + current_mp_weight := current_mp_weight - tmp_weight; + END IF; + + IF current_mp.request_ou IS NOT NULL AND current_mp.request_ou <> root_ou.id THEN + SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.request_ou, request_ou)::FLOAT + 1.0)::FLOAT; + current_mp_weight := current_mp_weight - tmp_weight; + END IF; + + IF current_mp.user_home_ou IS NOT NULL AND current_mp.user_home_ou <> root_ou.id THEN + SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.user_home_ou, user_object.home_ou)::FLOAT + 1.0)::FLOAT; + current_mp_weight := current_mp_weight - tmp_weight; + END IF; + + -- set the matchpoint if we found the best one + IF matchpoint_weight IS NULL OR matchpoint_weight > current_mp_weight THEN + matchpoint = current_mp; + matchpoint_weight = current_mp_weight; + END IF; + + END LOOP; + + EXIT WHEN current_requestor_group.parent IS NULL OR matchpoint.id IS NOT NULL; + + SELECT INTO current_requestor_group * FROM permission.grp_tree WHERE id = current_requestor_group.parent; + END LOOP; + + RETURN matchpoint.id; +END; +$func$ LANGUAGE plpgsql; + + +CREATE OR REPLACE FUNCTION action.hold_request_permit_test( pickup_ou INT, request_ou INT, match_item BIGINT, match_user INT, match_requestor INT ) RETURNS SETOF action.matrix_test_result AS $func$ +DECLARE + matchpoint_id INT; + user_object actor.usr%ROWTYPE; + age_protect_object config.rule_age_hold_protect%ROWTYPE; + transit_range_ou_type actor.org_unit_type%ROWTYPE; + transit_source actor.org_unit%ROWTYPE; + item_object asset.copy%ROWTYPE; + result action.matrix_test_result; + hold_test config.hold_matrix_test%ROWTYPE; + hold_count INT; + hold_transit_prox INT; + frozen_hold_count INT; + done BOOL := FALSE; +BEGIN + SELECT INTO user_object * FROM actor.usr WHERE id = match_user; + + -- Fail if we couldn't find a user + IF user_object.id IS NULL THEN + result.fail_part := 'no_user'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + RETURN; + END IF; + + SELECT INTO item_object * FROM asset.copy WHERE id = match_item; + + -- Fail if we couldn't find a copy + IF item_object.id IS NULL THEN + result.fail_part := 'no_item'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + RETURN; + END IF; + + SELECT INTO matchpoint_id action.find_hold_matrix_matchpoint(pickup_ou, request_ou, match_item, match_user, match_requestor); + + -- Fail if we couldn't find any matchpoint (requires a default) + IF matchpoint_id IS NULL THEN + result.fail_part := 'no_matchpoint'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + RETURN; + END IF; + + SELECT INTO hold_test * FROM config.hold_matrix_test WHERE matchpoint = matchpoint_id; + + result.matchpoint := matchpoint_id; + result.success := TRUE; + + IF hold_test.holdable IS FALSE THEN + result.fail_part := 'config.hold_matrix_test.holdable'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + + IF hold_test.transit_range IS NOT NULL THEN + SELECT INTO transit_range_ou_type * FROM actor.org_unit_type WHERE id = hold_test.transit_range; + IF hold_test.distance_is_from_owner THEN + SELECT INTO transit_source ou.* FROM actor.org_unit ou JOIN asset.call_number cn ON (cn.owning_lib = ou.id) WHERE cn.id = item_object.call_number; + ELSE + SELECT INTO transit_source * FROM actor.org_unit WHERE id = item_object.circ_lib; + END IF; + + PERFORM * FROM actor.org_unit_descendants( transit_source.id, transit_range_ou_type.depth ) WHERE id = pickup_ou; + + IF NOT FOUND THEN + result.fail_part := 'transit_range'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + END IF; + + IF hold_test.max_holds IS NOT NULL THEN + SELECT INTO hold_count COUNT(*) + FROM action.hold_request + WHERE usr = match_user + AND fulfillment_time IS NULL + AND cancel_time IS NULL + AND CASE WHEN hold_test.include_frozen_holds THEN TRUE ELSE frozen IS FALSE END; + + IF items_out >= hold_test.max_holds THEN + result.fail_part := 'config.hold_matrix_test.max_holds'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + END IF; + + IF item_object.age_protect IS NOT NULL THEN + SELECT INTO age_protect_object * FROM config.rule_age_hold_protect WHERE id = item_object.age_protect; + + IF item_object.create_date + age_protect_object.age > NOW() THEN + IF hold_test.distance_is_from_owner THEN + SELECT INTO hold_transit_prox prox FROM actor.org_unit_prox WHERE from_org = item_cn_object.owning_lib AND to_org = pickup_ou; + ELSE + SELECT INTO hold_transit_prox prox FROM actor.org_unit_prox WHERE from_org = item_object.circ_lib AND to_org = pickup_ou; + END IF; + + IF hold_transit_prox > age_protect_object.prox THEN + result.fail_part := 'config.rule_age_hold_protect.prox'; + result.success := FALSE; + done := TRUE; + RETURN NEXT result; + END IF; + END IF; + END IF; + + IF NOT done THEN + RETURN NEXT result; + END IF; + + RETURN; +END; +$func$ LANGUAGE plpgsql; + +COMMIT; + diff --git a/Open-ILS/src/sql/Pg/300.schema.staged_search.sql b/Open-ILS/src/sql/Pg/300.schema.staged_search.sql new file mode 100644 index 0000000000..bbfb291a93 --- /dev/null +++ b/Open-ILS/src/sql/Pg/300.schema.staged_search.sql @@ -0,0 +1,562 @@ + +DROP SCHEMA search CASCADE; + +BEGIN; + +CREATE SCHEMA search; + +CREATE TABLE search.relevance_adjustment ( + id SERIAL PRIMARY KEY, + active BOOL NOT NULL DEFAULT TRUE, + field INT NOT NULL REFERENCES config.metabib_field (id), + bump_type TEXT NOT NULL CHECK (bump_type IN ('word_order','first_word','full_match')), + multiplier NUMERIC NOT NULL DEFAULT 1.0 +); +CREATE UNIQUE INDEX bump_once_per_field_idx ON search.relevance_adjustment ( field, bump_type ); + +CREATE OR REPLACE FUNCTION search.pick_table (TEXT) RETURNS TEXT AS $$ + SELECT CASE + WHEN $1 = 'author' THEN 'metabib.author_field_entry' + WHEN $1 = 'title' THEN 'metabib.title_field_entry' + WHEN $1 = 'subject' THEN 'metabib.subject_field_entry' + WHEN $1 = 'keyword' THEN 'metabib.keyword_field_entry' + WHEN $1 = 'series' THEN 'metabib.series_field_entry' + END; +$$ LANGUAGE SQL; + +CREATE TYPE search.search_result AS ( id BIGINT, rel NUMERIC, record INT, total INT, checked INT, visible INT, deleted INT, excluded INT ); +CREATE TYPE search.search_args AS ( id INT, field_class TEXT, field_name TEXT, table_alias TEXT, term TEXT, term_type TEXT ); + +CREATE OR REPLACE FUNCTION search.staged_fts ( + + param_search_ou INT, + param_depth INT, + param_searches TEXT, -- JSON hash, to be turned into a resultset via search.parse_search_args + param_statuses INT[], + param_audience TEXT[], + param_language TEXT[], + param_lit_form TEXT[], + param_types TEXT[], + param_forms TEXT[], + param_vformats TEXT[], + param_bib_level TEXT[], + param_pref_lang TEXT, + param_pref_lang_multiplier REAL, + param_sort TEXT, + param_sort_desc BOOL, + metarecord BOOL, + staff BOOL, + param_rel_limit INT, + param_chk_limit INT, + param_skip_chk INT + +) RETURNS SETOF search.search_result AS $func$ +DECLARE + + current_res search.search_result%ROWTYPE; + query_part search.search_args%ROWTYPE; + phrase_query_part search.search_args%ROWTYPE; + rank_adjust_id INT; + core_rel_limit INT; + core_chk_limit INT; + core_skip_chk INT; + rank_adjust search.relevance_adjustment%ROWTYPE; + query_table TEXT; + tmp_text TEXT; + tmp_int INT; + current_rank TEXT; + ranks TEXT[] := '{}'; + query_table_alias TEXT; + from_alias_array TEXT[] := '{}'; + used_ranks TEXT[] := '{}'; + mb_field INT; + mb_field_list INT[]; + search_org_list INT[]; + select_clause TEXT := 'SELECT'; + from_clause TEXT := ' FROM metabib.metarecord_source_map m JOIN metabib.rec_descriptor mrd ON (m.source = mrd.record) '; + where_clause TEXT := ' WHERE 1=1 '; + mrd_used BOOL := FALSE; + sort_desc BOOL := FALSE; + + core_result RECORD; + core_cursor REFCURSOR; + core_rel_query TEXT; + vis_limit_query TEXT; + inner_where_clause TEXT; + + total_count INT := 0; + check_count INT := 0; + deleted_count INT := 0; + visible_count INT := 0; + excluded_count INT := 0; + +BEGIN + + core_rel_limit := COALESCE( param_rel_limit, 25000 ); + core_chk_limit := COALESCE( param_chk_limit, 1000 ); + core_skip_chk := COALESCE( param_skip_chk, 1 ); + + IF metarecord THEN + select_clause := select_clause || ' m.metarecord as id, array_accum(distinct m.source) as records,'; + ELSE + select_clause := select_clause || ' m.source as id, array_accum(distinct m.source) as records,'; + END IF; + + -- first we need to construct the base query + FOR query_part IN SELECT * FROM search.parse_search_args(param_searches) WHERE term_type = 'fts_query' LOOP + + inner_where_clause := 'index_vector @@ ' || query_part.term; + + IF query_part.field_name IS NOT NULL THEN + + SELECT id INTO mb_field + FROM config.metabib_field + WHERE field_class = query_part.field_class + AND name = query_part.field_name; + + IF FOUND THEN + inner_where_clause := inner_where_clause || + ' AND ' || 'field = ' || mb_field; + END IF; + + END IF; + + -- moving on to the rank ... + SELECT * INTO query_part + FROM search.parse_search_args(param_searches) + WHERE term_type = 'fts_rank' + AND table_alias = query_part.table_alias; + + current_rank := query_part.term || ' * ' || query_part.table_alias || '_weight.weight'; + + IF query_part.field_name IS NOT NULL THEN + + SELECT array_accum(distinct id) INTO mb_field_list + FROM config.metabib_field + WHERE field_class = query_part.field_class + AND name = query_part.field_name; + + ELSE + + SELECT array_accum(distinct id) INTO mb_field_list + FROM config.metabib_field + WHERE field_class = query_part.field_class; + + END IF; + + FOR rank_adjust IN SELECT * FROM search.relevance_adjustment WHERE active AND field IN ( SELECT * FROM search.explode_array( mb_field_list ) ) LOOP + + IF NOT rank_adjust.bump_type = ANY (used_ranks) THEN + + IF rank_adjust.bump_type = 'first_word' THEN + SELECT term INTO tmp_text + FROM search.parse_search_args(param_searches) + WHERE table_alias = query_part.table_alias AND term_type = 'word' + ORDER BY id + LIMIT 1; + + tmp_text := query_part.table_alias || '.value ILIKE ' || quote_literal( tmp_text || '%' ); + + ELSIF rank_adjust.bump_type = 'word_order' THEN + SELECT array_to_string( array_accum( term ), '%' ) INTO tmp_text + FROM search.parse_search_args(param_searches) + WHERE table_alias = query_part.table_alias AND term_type = 'word'; + + tmp_text := query_part.table_alias || '.value ILIKE ' || quote_literal( '%' || tmp_text || '%' ); + + ELSIF rank_adjust.bump_type = 'full_match' THEN + SELECT array_to_string( array_accum( term ), E'\\s+' ) INTO tmp_text + FROM search.parse_search_args(param_searches) + WHERE table_alias = query_part.table_alias AND term_type = 'word'; + + tmp_text := query_part.table_alias || '.value ~ ' || quote_literal( '^' || tmp_text || E'\\W*$' ); + + END IF; + + + current_rank := current_rank || ' * ( CASE WHEN ' || tmp_text || + ' THEN ' || rank_adjust.multiplier || '::REAL ELSE 1.0 END )'; + + used_ranks := array_append( used_ranks, rank_adjust.bump_type ); + + END IF; + + END LOOP; + + ranks := array_append( ranks, current_rank ); + used_ranks := '{}'; + + FOR phrase_query_part IN + SELECT * + FROM search.parse_search_args(param_searches) + WHERE term_type = 'phrase' + AND table_alias = query_part.table_alias LOOP + + tmp_text := replace( phrase_query_part.term, '*', E'\\*' ); + tmp_text := replace( tmp_text, '?', E'\\?' ); + tmp_text := replace( tmp_text, '+', E'\\+' ); + tmp_text := replace( tmp_text, '|', E'\\|' ); + tmp_text := replace( tmp_text, '(', E'\\(' ); + tmp_text := replace( tmp_text, ')', E'\\)' ); + tmp_text := replace( tmp_text, '[', E'\\[' ); + tmp_text := replace( tmp_text, ']', E'\\]' ); + + inner_where_clause := inner_where_clause || ' AND ' || 'value ~* ' || quote_literal( E'(^|\\W+)' || regexp_replace(tmp_text, E'\\s+',E'\\\\s+','g') || E'(\\W+|\$)' ); + + END LOOP; + + query_table := search.pick_table(query_part.field_class); + + from_clause := from_clause || + ' JOIN ( SELECT * FROM ' || query_table || ' WHERE ' || inner_where_clause || + CASE WHEN core_rel_limit > 0 THEN ' LIMIT ' || core_rel_limit::TEXT ELSE '' END || ' ) AS ' || query_part.table_alias || + ' ON ( m.source = ' || query_part.table_alias || '.source )' || + ' JOIN config.metabib_field AS ' || query_part.table_alias || '_weight' || + ' ON ( ' || query_part.table_alias || '.field = ' || query_part.table_alias || '_weight.id AND ' || query_part.table_alias || '_weight.search_field)'; + + from_alias_array := array_append(from_alias_array, query_part.table_alias); + + END LOOP; + + IF param_pref_lang IS NOT NULL AND param_pref_lang_multiplier IS NOT NULL THEN + current_rank := ' CASE WHEN mrd.item_lang = ' || quote_literal( param_pref_lang ) || + ' THEN ' || param_pref_lang_multiplier || '::REAL ELSE 1.0 END '; + + --ranks := array_append( ranks, current_rank ); + END IF; + + current_rank := ' AVG( ( (' || array_to_string( ranks, ') + (' ) || ') ) * ' || current_rank || ' ) '; + select_clause := select_clause || current_rank || ' AS rel,'; + + sort_desc = param_sort_desc; + + IF param_sort = 'pubdate' THEN + + tmp_text := '999999'; + IF param_sort_desc THEN tmp_text := '0'; END IF; + + current_rank := $$ + ( COALESCE( FIRST (( + SELECT SUBSTRING(frp.value FROM E'\\d{4}') + FROM metabib.full_rec frp + WHERE frp.record = m.source + AND frp.tag = '260' + AND frp.subfield = 'c' + LIMIT 1 + )), $$ || quote_literal(tmp_text) || $$ )::INT ) + $$; + + ELSIF param_sort = 'title' THEN + + tmp_text := 'zzzzzz'; + IF param_sort_desc THEN tmp_text := ' '; END IF; + + current_rank := $$ + ( COALESCE( FIRST (( + SELECT LTRIM(SUBSTR( frt.value, COALESCE(SUBSTRING(frt.ind2 FROM E'\\d+'),'0')::INT + 1 )) + FROM metabib.full_rec frt + WHERE frt.record = m.source + AND frt.tag = '245' + AND frt.subfield = 'a' + LIMIT 1 + )),$$ || quote_literal(tmp_text) || $$)) + $$; + + ELSIF param_sort = 'author' THEN + + tmp_text := 'zzzzzz'; + IF param_sort_desc THEN tmp_text := ' '; END IF; + + current_rank := $$ + ( COALESCE( FIRST (( + SELECT LTRIM(fra.value) + FROM metabib.full_rec fra + WHERE fra.record = m.source + AND fra.tag LIKE '1%' + AND fra.subfield = 'a' + ORDER BY fra.tag::text::int + LIMIT 1 + )),$$ || quote_literal(tmp_text) || $$)) + $$; + + ELSIF param_sort = 'create_date' THEN + current_rank := $$( FIRST (( SELECT create_date FROM biblio.record_entry rbr WHERE rbr.id = m.source)) )$$; + ELSIF param_sort = 'edit_date' THEN + current_rank := $$( FIRST (( SELECT edit_date FROM biblio.record_entry rbr WHERE rbr.id = m.source)) )$$; + ELSE + sort_desc := NOT COALESCE(param_sort_desc, FALSE); + END IF; + + select_clause := select_clause || current_rank || ' AS rank'; + + -- now add the other qualifiers + IF param_audience IS NOT NULL AND array_upper(param_audience, 1) > 0 THEN + where_clause = where_clause || $$ AND mrd.audience IN ('$$ || array_to_string(param_audience, $$','$$) || $$') $$; + END IF; + + IF param_language IS NOT NULL AND array_upper(param_language, 1) > 0 THEN + where_clause = where_clause || $$ AND mrd.item_lang IN ('$$ || array_to_string(param_language, $$','$$) || $$') $$; + END IF; + + IF param_lit_form IS NOT NULL AND array_upper(param_lit_form, 1) > 0 THEN + where_clause = where_clause || $$ AND mrd.lit_form IN ('$$ || array_to_string(param_lit_form, $$','$$) || $$') $$; + END IF; + + IF param_types IS NOT NULL AND array_upper(param_types, 1) > 0 THEN + where_clause = where_clause || $$ AND mrd.item_type IN ('$$ || array_to_string(param_types, $$','$$) || $$') $$; + END IF; + + IF param_forms IS NOT NULL AND array_upper(param_forms, 1) > 0 THEN + where_clause = where_clause || $$ AND mrd.item_form IN ('$$ || array_to_string(param_forms, $$','$$) || $$') $$; + END IF; + + IF param_vformats IS NOT NULL AND array_upper(param_vformats, 1) > 0 THEN + where_clause = where_clause || $$ AND mrd.vr_format IN ('$$ || array_to_string(param_vformats, $$','$$) || $$') $$; + END IF; + + IF param_bib_level IS NOT NULL AND array_upper(param_bib_level, 1) > 0 THEN + where_clause = where_clause || $$ AND mrd.bib_level IN ('$$ || array_to_string(param_bib_level, $$','$$) || $$') $$; + END IF; + + core_rel_query := select_clause || from_clause || where_clause || + ' GROUP BY 1 ORDER BY 4' || CASE WHEN sort_desc THEN ' DESC' ELSE ' ASC' END || ';'; + --RAISE NOTICE 'Base Query: %', core_rel_query; + + IF param_search_ou > 0 THEN + IF param_depth IS NOT NULL THEN + SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou, param_depth ); + ELSE + SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou ); + END IF; + ELSIF param_search_ou < 0 THEN + SELECT array_accum(distinct org_unit) INTO search_org_list FROM actor.org_lasso_map WHERE lasso = -param_search_ou; + ELSIF param_search_ou = 0 THEN + -- reserved for user lassos (ou_buckets/type='lasso') with ID passed in depth ... hack? sure. + END IF; + + OPEN core_cursor FOR EXECUTE core_rel_query; + + LOOP + + FETCH core_cursor INTO core_result; + EXIT WHEN NOT FOUND; + + + IF total_count % 1000 = 0 THEN + -- RAISE NOTICE ' % total, % checked so far ... ', total_count, check_count; + END IF; + + IF core_chk_limit > 0 AND total_count - core_skip_chk + 1 >= core_chk_limit THEN + total_count := total_count + 1; + CONTINUE; + END IF; + + total_count := total_count + 1; + + CONTINUE WHEN param_skip_chk IS NOT NULL and total_count < param_skip_chk; + + check_count := check_count + 1; + + PERFORM 1 FROM biblio.record_entry b WHERE NOT b.deleted AND b.id IN ( SELECT * FROM search.explode_array( core_result.records ) ); + IF NOT FOUND THEN + -- RAISE NOTICE ' % were all deleted ... ', core_result.records; + deleted_count := deleted_count + 1; + CONTINUE; + END IF; + + PERFORM 1 + FROM biblio.record_entry b + JOIN config.bib_source s ON (b.source = s.id) + WHERE s.transcendant + AND b.id IN ( SELECT * FROM search.explode_array( core_result.records ) ); + + IF FOUND THEN + -- RAISE NOTICE ' % were all transcendant ... ', core_result.records; + visible_count := visible_count + 1; + + current_res.id = core_result.id; + current_res.rel = core_result.rel; + + tmp_int := 1; + IF metarecord THEN + SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id; + END IF; + + IF tmp_int = 1 THEN + current_res.record = core_result.records[1]; + ELSE + current_res.record = NULL; + END IF; + + RETURN NEXT current_res; + + CONTINUE; + END IF; + + IF param_statuses IS NOT NULL AND array_upper(param_statuses, 1) > 0 THEN + + PERFORM 1 + FROM asset.call_number cn + JOIN asset.copy cp ON (cp.call_number = cn.id) + WHERE NOT cn.deleted + AND NOT cp.deleted + AND cp.status IN ( SELECT * FROM search.explode_array( param_statuses ) ) + AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) ) + AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) ) + LIMIT 1; + + IF NOT FOUND THEN + -- RAISE NOTICE ' % were all status-excluded ... ', core_result.records; + excluded_count := excluded_count + 1; + CONTINUE; + END IF; + + END IF; + + IF staff IS NULL OR NOT staff THEN + + PERFORM 1 + FROM asset.call_number cn + JOIN asset.copy cp ON (cp.call_number = cn.id) + JOIN actor.org_unit a ON (cp.circ_lib = a.id) + JOIN asset.copy_location cl ON (cp.location = cl.id) + JOIN config.copy_status cs ON (cp.status = cs.id) + WHERE NOT cn.deleted + AND NOT cp.deleted + AND cs.holdable + AND cl.opac_visible + AND cp.opac_visible + AND a.opac_visible + AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) ) + AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) ) + LIMIT 1; + + IF NOT FOUND THEN + -- RAISE NOTICE ' % were all visibility-excluded ... ', core_result.records; + excluded_count := excluded_count + 1; + CONTINUE; + END IF; + + ELSE + + PERFORM 1 + FROM asset.call_number cn + JOIN asset.copy cp ON (cp.call_number = cn.id) + JOIN actor.org_unit a ON (cp.circ_lib = a.id) + JOIN asset.copy_location cl ON (cp.location = cl.id) + JOIN config.copy_status cs ON (cp.status = cs.id) + WHERE NOT cn.deleted + AND NOT cp.deleted + AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) ) + AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) ) + LIMIT 1; + + IF NOT FOUND THEN + + PERFORM 1 + FROM asset.call_number cn + WHERE cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) ) + LIMIT 1; + + IF FOUND THEN + -- RAISE NOTICE ' % were all visibility-excluded ... ', core_result.records; + excluded_count := excluded_count + 1; + CONTINUE; + END IF; + + END IF; + + END IF; + + visible_count := visible_count + 1; + + current_res.id = core_result.id; + current_res.rel = core_result.rel; + + tmp_int := 1; + IF metarecord THEN + SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id; + END IF; + + IF tmp_int = 1 THEN + current_res.record = core_result.records[1]; + ELSE + current_res.record = NULL; + END IF; + + RETURN NEXT current_res; + + IF visible_count % 1000 = 0 THEN + -- RAISE NOTICE ' % visible so far ... ', visible_count; + END IF; + + END LOOP; + + current_res.id = NULL; + current_res.rel = NULL; + current_res.record = NULL; + current_res.total = total_count; + current_res.checked = check_count; + current_res.deleted = deleted_count; + current_res.visible = visible_count; + current_res.excluded = excluded_count; + + CLOSE core_cursor; + + RETURN NEXT current_res; + +END; +$func$ LANGUAGE PLPGSQL; + +/* + param_statuses INT[], + param_audience TEXT[], x + param_language TEXT[], x + param_lit_form TEXT[], x + param_types TEXT[], x + param_forms TEXT[], x + param_vformats TEXT[], x +*/ + +CREATE OR REPLACE FUNCTION search.explode_array(anyarray) RETURNS SETOF anyelement AS $BODY$ + SELECT ($1)[s] FROM generate_series(1, array_upper($1, 1)) AS s; +$BODY$ +LANGUAGE 'sql' IMMUTABLE; + +CREATE OR REPLACE FUNCTION search.parse_search_args (TEXT) RETURNS SETOF search.search_args AS $perlcode$ + use JSON::XS; + my $json = shift; + + my $args = decode_json( $json ); + + my $id = 1; + + for my $k ( keys %$args ) { + (my $alias = $k) =~ s/\|/_/gso; + my ($class, $field) = split /\|/, $k; + my $part = $args->{$k}; + for my $p ( keys %$part ) { + my $data = $part->{$p}; + $data = [$data] if (!ref($data)); + for my $datum ( @$data ) { + return_next( + { field_class => $class, + field_name => $field, + term => $datum, + table_alias => $alias, + term_type => $p, + id => $id, + } + ); + $id++; + } + } + } + + return undef; + +$perlcode$ LANGUAGE PLPERLU; + + +COMMIT; + diff --git a/Open-ILS/src/sql/Pg/800.fkeys.sql b/Open-ILS/src/sql/Pg/800.fkeys.sql index e241bf7b48..e0309841df 100644 --- a/Open-ILS/src/sql/Pg/800.fkeys.sql +++ b/Open-ILS/src/sql/Pg/800.fkeys.sql @@ -3,6 +3,7 @@ BEGIN; ALTER TABLE actor.usr ADD CONSTRAINT actor_usr_mailing_address_fkey FOREIGN KEY (mailing_address) REFERENCES actor.usr_address (id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE actor.usr ADD CONSTRAINT actor_usr_billining_address_fkey FOREIGN KEY (billing_address) REFERENCES actor.usr_address (id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE actor.usr ADD CONSTRAINT actor_usr_home_ou_fkey FOREIGN KEY (home_ou) REFERENCES actor.org_unit (id) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE actor.usr ADD CONSTRAINT actor_usr_profile_fkey FOREIGN KEY (profile) REFERENCES permission.grp_tree (id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE actor.stat_cat ADD CONSTRAINT actor_stat_cat_owner_fkey FOREIGN KEY (owner) REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql index 9c52b0715b..484c101287 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -1,64 +1,97 @@ --002.schema.config.sql: INSERT INTO config.bib_source (quality, source, transcendant) VALUES - (90, oils_i18n_gettext('oclc'), FALSE), - (10, oils_i18n_gettext('System Local'), FALSE), + (90, oils_i18n_gettext('oclc'), FALSE); +INSERT INTO config.bib_source (quality, source, transcendant) VALUES + (10, oils_i18n_gettext('System Local'), FALSE); +INSERT INTO config.bib_source (quality, source, transcendant) VALUES (1, oils_i18n_gettext('Project Gutenberg'), TRUE); INSERT INTO config.standing (value) VALUES (oils_i18n_gettext('Good')); INSERT INTO config.standing (value) VALUES (oils_i18n_gettext('Barred')); -INSERT INTO config.xml_transform VALUES ( 'marcxml', 'http://www.loc.gov/MARC21/slim', 'marc', '---' ); -INSERT INTO config.xml_transform VALUES ( 'mods', 'http://www.loc.gov/mods/', 'mods', '/home/miker/MARC21slim2MODS.xsl' ); - INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES - ( 'series', 'seriestitle', $$//mods:mods/mods:relatedItem[@type="series"]/mods:titleInfo$$ ), - ( 'title', 'abbreviated', $$//mods:mods/mods:titleInfo[mods:title and (@type='abbreviated')]$$ ), - ( 'title', 'translated', $$//mods:mods/mods:titleInfo[mods:title and (@type='translated')]$$ ), - ( 'title', 'uniform', $$//mods:mods/mods:titleInfo[mods:title and (@type='uniform')]$$ ), - ( 'title', 'proper', $$//mods:mods/mods:titleInfo[mods:title and not (@type)]$$ ), - ( 'author', 'corporate', $$//mods:mods/mods:name[@type='corporate']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ), - ( 'author', 'personal', $$//mods:mods/mods:name[@type='personal']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ), - ( 'author', 'conference', $$//mods:mods/mods:name[@type='conference']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ), - ( 'author', 'other', $$//mods:mods/mods:name[@type='personal']/mods:namePart[not(../mods:role)]$$ ), - ( 'subject', 'geographic', $$//mods:mods/mods:subject/mods:geographic$$ ), - ( 'subject', 'name', $$//mods:mods/mods:subject/mods:name$$ ), - ( 'subject', 'temporal', $$//mods:mods/mods:subject/mods:temporal$$ ), - ( 'subject', 'topic', $$//mods:mods/mods:subject/mods:topic$$ ), --- ( field_class, name, xpath ) VALUES ( 'subject', 'genre', $$//mods:mods/mods:genre$$ ), - ( 'keyword', 'keyword', $$//mods:mods/*[not(local-name()='originInfo')]$$ ); -- /* to fool vim */ + ( 'series', 'seriestitle', $$//mods:mods/mods:relatedItem[@type="series"]/mods:titleInfo$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'title', 'abbreviated', $$//mods:mods/mods:titleInfo[mods:title and (@type='abbreviated')]$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'title', 'translated', $$//mods:mods/mods:titleInfo[mods:title and (@type='translated')]$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'title', 'uniform', $$//mods:mods/mods:titleInfo[mods:title and (@type='uniform')]$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'title', 'proper', $$//mods:mods/mods:titleInfo[mods:title and not (@type)]$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'author', 'corporate', $$//mods:mods/mods:name[@type='corporate']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'author', 'personal', $$//mods:mods/mods:name[@type='personal']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'author', 'conference', $$//mods:mods/mods:name[@type='conference']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'author', 'other', $$//mods:mods/mods:name[@type='personal']/mods:namePart[not(../mods:role)]$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'subject', 'geographic', $$//mods:mods/mods:subject/mods:geographic$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'subject', 'name', $$//mods:mods/mods:subject/mods:name$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'subject', 'temporal', $$//mods:mods/mods:subject/mods:temporal$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'subject', 'topic', $$//mods:mods/mods:subject/mods:topic$$ ); +--INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES +-- ( field_class, name, xpath ) VALUES ( 'subject', 'genre', $$//mods:mods/mods:genre$$ ); +INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES + ( 'keyword', 'keyword', $$//mods:mods/*[not(local-name()='originInfo')]$$ ); -- /* to fool vim */; INSERT INTO config.non_cataloged_type ( owning_lib, name ) VALUES ( 1, oils_i18n_gettext('Paperback Book') ); INSERT INTO config.identification_type ( name ) VALUES - ( oils_i18n_gettext('Drivers License') ), - ( oils_i18n_gettext('SSN') ), + ( oils_i18n_gettext('Drivers License') ); +INSERT INTO config.identification_type ( name ) VALUES + ( oils_i18n_gettext('SSN') ); +INSERT INTO config.identification_type ( name ) VALUES ( oils_i18n_gettext('Other') ); INSERT INTO config.rule_circ_duration VALUES - (DEFAULT, oils_i18n_gettext('7_days_0_renew'), '7 days', '7 days', '7 days', 0), - (DEFAULT, oils_i18n_gettext('28_days_2_renew'), '28 days', '28 days', '28 days', 2), - (DEFAULT, oils_i18n_gettext('3_months_0_renew'), '3 months', '3 months', '3 months', 0), - (DEFAULT, oils_i18n_gettext('3_days_1_renew'), '3 days', '3 days', '3 days', 1), - (DEFAULT, oils_i18n_gettext('2_months_2_renew'), '2 months', '2 months', '2 months', 2), - (DEFAULT, oils_i18n_gettext('35_days_1_renew'), '35 days', '35 days', '35 days', 1), - (DEFAULT, oils_i18n_gettext('7_days_2_renew'), '7 days', '7 days', '7 days', 2), - (DEFAULT, oils_i18n_gettext('1_hour_2_renew'), '1 hour', '1 hour', '1 hour', 2), - (DEFAULT, oils_i18n_gettext('28_days_0_renew'), '28 days', '28 days', '28 days', 0), - (DEFAULT, oils_i18n_gettext('14_days_2_renew'), '14 days', '14 days', '14 days', 2), + (DEFAULT, oils_i18n_gettext('7_days_0_renew'), '7 days', '7 days', '7 days', 0); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('28_days_2_renew'), '28 days', '28 days', '28 days', 2); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('3_months_0_renew'), '3 months', '3 months', '3 months', 0); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('3_days_1_renew'), '3 days', '3 days', '3 days', 1); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('2_months_2_renew'), '2 months', '2 months', '2 months', 2); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('35_days_1_renew'), '35 days', '35 days', '35 days', 1); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('7_days_2_renew'), '7 days', '7 days', '7 days', 2); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('1_hour_2_renew'), '1 hour', '1 hour', '1 hour', 2); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('28_days_0_renew'), '28 days', '28 days', '28 days', 0); +INSERT INTO config.rule_circ_duration VALUES + (DEFAULT, oils_i18n_gettext('14_days_2_renew'), '14 days', '14 days', '14 days', 2); +INSERT INTO config.rule_circ_duration VALUES (DEFAULT, oils_i18n_gettext('default'), '21 days', '14 days', '7 days', 2); INSERT INTO config.rule_max_fine VALUES - (DEFAULT, oils_i18n_gettext('default'), 5.00), - (DEFAULT, oils_i18n_gettext('overdue_min'), 5.00), - (DEFAULT, oils_i18n_gettext('overdue_mid'), 10.00), - (DEFAULT, oils_i18n_gettext('overdue_max'), 100.00), - (DEFAULT, oils_i18n_gettext('overdue_equip_min'), 25.00), - (DEFAULT, oils_i18n_gettext('overdue_equip_mid'), 25.00), + (DEFAULT, oils_i18n_gettext('default'), 5.00); +INSERT INTO config.rule_max_fine VALUES + (DEFAULT, oils_i18n_gettext('overdue_min'), 5.00); +INSERT INTO config.rule_max_fine VALUES + (DEFAULT, oils_i18n_gettext('overdue_mid'), 10.00); +INSERT INTO config.rule_max_fine VALUES + (DEFAULT, oils_i18n_gettext('overdue_max'), 100.00); +INSERT INTO config.rule_max_fine VALUES + (DEFAULT, oils_i18n_gettext('overdue_equip_min'), 25.00); +INSERT INTO config.rule_max_fine VALUES + (DEFAULT, oils_i18n_gettext('overdue_equip_mid'), 25.00); +INSERT INTO config.rule_max_fine VALUES (DEFAULT, oils_i18n_gettext('overdue_equip_max'), 100.00); INSERT INTO config.rule_recuring_fine VALUES - (DEFAULT, oils_i18n_gettext('default'), 0.50, 0.10, 0.05, '1 day'), - (DEFAULT, oils_i18n_gettext('10_cent_per_day'), 0.50, 0.10, 0.10, '1 day'), + (DEFAULT, oils_i18n_gettext('default'), 0.50, 0.10, 0.05, '1 day'); +INSERT INTO config.rule_recuring_fine VALUES + (DEFAULT, oils_i18n_gettext('10_cent_per_day'), 0.50, 0.10, 0.10, '1 day'); +INSERT INTO config.rule_recuring_fine VALUES (DEFAULT, oils_i18n_gettext('50_cent_per_day'), 0.50, 0.50, 0.50, '1 day'); INSERT INTO config.rule_age_hold_protect VALUES (DEFAULT, oils_i18n_gettext('3month'), '3 months', 0); @@ -87,730 +120,908 @@ INSERT INTO config.copy_status (id,name) VALUES (14,oils_i18n_gettext('Damaged SELECT SETVAL('config.copy_status_id_seq'::TEXT, 100); INSERT INTO config.net_access_level (name) VALUES - (oils_i18n_gettext('Filtered')), - (oils_i18n_gettext('Unfiltered')), + (oils_i18n_gettext('Filtered')); +INSERT INTO config.net_access_level (name) VALUES + (oils_i18n_gettext('Unfiltered')); +INSERT INTO config.net_access_level (name) VALUES (oils_i18n_gettext('No Access')); INSERT INTO config.audience_map (code, value, description) VALUES - ('', oils_i18n_gettext('Unknown or unspecified'), oils_i18n_gettext('The target audience for the item not known or not specified.')), - ('a', oils_i18n_gettext('Preschool'), oils_i18n_gettext('The item is intended for children, approximate ages 0-5 years.')), - ('b', oils_i18n_gettext('Primary'), oils_i18n_gettext('The item is intended for children, approximate ages 6-8 years.')), - ('c', oils_i18n_gettext('Pre-adolescent'), oils_i18n_gettext('The item is intended for young people, approximate ages 9-13 years.')), - ('d', oils_i18n_gettext('Adolescent'), oils_i18n_gettext('The item is intended for young people, approximate ages 14-17 years.')), - ('e', oils_i18n_gettext('Adult'), oils_i18n_gettext('The item is intended for adults.')), - ('f', oils_i18n_gettext('Specialized'), oils_i18n_gettext('The item is aimed at a particular audience and the nature of the presentation makes the item of little interest to another audience.')), - ('g', oils_i18n_gettext('General'), oils_i18n_gettext('The item is of general interest and not aimed at an audience of a particular intellectual level.')), + ('', oils_i18n_gettext('Unknown or unspecified'), oils_i18n_gettext('The target audience for the item not known or not specified.')); +INSERT INTO config.audience_map (code, value, description) VALUES + ('a', oils_i18n_gettext('Preschool'), oils_i18n_gettext('The item is intended for children, approximate ages 0-5 years.')); +INSERT INTO config.audience_map (code, value, description) VALUES + ('b', oils_i18n_gettext('Primary'), oils_i18n_gettext('The item is intended for children, approximate ages 6-8 years.')); +INSERT INTO config.audience_map (code, value, description) VALUES + ('c', oils_i18n_gettext('Pre-adolescent'), oils_i18n_gettext('The item is intended for young people, approximate ages 9-13 years.')); +INSERT INTO config.audience_map (code, value, description) VALUES + ('d', oils_i18n_gettext('Adolescent'), oils_i18n_gettext('The item is intended for young people, approximate ages 14-17 years.')); +INSERT INTO config.audience_map (code, value, description) VALUES + ('e', oils_i18n_gettext('Adult'), oils_i18n_gettext('The item is intended for adults.')); +INSERT INTO config.audience_map (code, value, description) VALUES + ('f', oils_i18n_gettext('Specialized'), oils_i18n_gettext('The item is aimed at a particular audience and the nature of the presentation makes the item of little interest to another audience.')); +INSERT INTO config.audience_map (code, value, description) VALUES + ('g', oils_i18n_gettext('General'), oils_i18n_gettext('The item is of general interest and not aimed at an audience of a particular intellectual level.')); +INSERT INTO config.audience_map (code, value, description) VALUES ('j', oils_i18n_gettext('Juvenile'), oils_i18n_gettext('The item is intended for children and young people, approximate ages 0-15 years.')); INSERT INTO config.lit_form_map (code, value, description) VALUES - ('0', oils_i18n_gettext('Not fiction (not further specified)'), oils_i18n_gettext('The item is not a work of fiction and no further identification of the literary form is desired')), - ('1', oils_i18n_gettext('Fiction (not further specified)'), oils_i18n_gettext('The item is a work of fiction and no further identification of the literary form is desired')), - ('c', oils_i18n_gettext('Comic strips'), NULL), - ('d', oils_i18n_gettext('Dramas'), NULL), - ('e', oils_i18n_gettext('Essays'), NULL), - ('f', oils_i18n_gettext('Novels'), NULL), - ('h', oils_i18n_gettext('Humor, satires, etc.'), oils_i18n_gettext('The item is a humorous work, satire or of similar literary form.')), - ('i', oils_i18n_gettext('Letters'), oils_i18n_gettext('The item is a single letter or collection of correspondence.')), - ('j', oils_i18n_gettext('Short stories'), oils_i18n_gettext('The item is a short story or collection of short stories.')), - ('m', oils_i18n_gettext('Mixed forms'), oils_i18n_gettext('The item is a variety of literary forms (e.g., poetry and short stories).')), - ('p', oils_i18n_gettext('Poetry'), oils_i18n_gettext('The item is a poem or collection of poems.')), - ('s', oils_i18n_gettext('Speeches'), oils_i18n_gettext('The item is a speech or collection of speeches.')), + ('0', oils_i18n_gettext('Not fiction (not further specified)'), oils_i18n_gettext('The item is not a work of fiction and no further identification of the literary form is desired')); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('1', oils_i18n_gettext('Fiction (not further specified)'), oils_i18n_gettext('The item is a work of fiction and no further identification of the literary form is desired')); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('c', oils_i18n_gettext('Comic strips'), NULL); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('d', oils_i18n_gettext('Dramas'), NULL); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('e', oils_i18n_gettext('Essays'), NULL); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('f', oils_i18n_gettext('Novels'), NULL); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('h', oils_i18n_gettext('Humor, satires, etc.'), oils_i18n_gettext('The item is a humorous work, satire or of similar literary form.')); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('i', oils_i18n_gettext('Letters'), oils_i18n_gettext('The item is a single letter or collection of correspondence.')); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('j', oils_i18n_gettext('Short stories'), oils_i18n_gettext('The item is a short story or collection of short stories.')); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('m', oils_i18n_gettext('Mixed forms'), oils_i18n_gettext('The item is a variety of literary forms (e.g., poetry and short stories).')); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('p', oils_i18n_gettext('Poetry'), oils_i18n_gettext('The item is a poem or collection of poems.')); +INSERT INTO config.lit_form_map (code, value, description) VALUES + ('s', oils_i18n_gettext('Speeches'), oils_i18n_gettext('The item is a speech or collection of speeches.')); +INSERT INTO config.lit_form_map (code, value, description) VALUES ('u', oils_i18n_gettext('Unknown'), oils_i18n_gettext('The literary form of the item is unknown.')); -- TO-DO: Auto-generate these values from CLDR -INSERT INTO config.language_map (code, value) VALUES - ('aar', oils_i18n_gettext('Afar')), - ('abk', oils_i18n_gettext('Abkhaz')), - ('ace', oils_i18n_gettext('Achinese')), - ('ach', oils_i18n_gettext('Acoli')), - ('ada', oils_i18n_gettext('Adangme')), - ('ady', oils_i18n_gettext('Adygei')), - ('afa', oils_i18n_gettext('Afroasiatic (Other)')), - ('afh', oils_i18n_gettext('Afrihili (Artificial language)')), - ('afr', oils_i18n_gettext('Afrikaans')), - ('-ajm', oils_i18n_gettext('Aljamía')), - ('aka', oils_i18n_gettext('Akan')), - ('akk', oils_i18n_gettext('Akkadian')), - ('alb', oils_i18n_gettext('Albanian')), - ('ale', oils_i18n_gettext('Aleut')), - ('alg', oils_i18n_gettext('Algonquian (Other)')), - ('amh', oils_i18n_gettext('Amharic')), - ('ang', oils_i18n_gettext('English, Old (ca. 450-1100)')), - ('apa', oils_i18n_gettext('Apache languages')), - ('ara', oils_i18n_gettext('Arabic')), - ('arc', oils_i18n_gettext('Aramaic')), - ('arg', oils_i18n_gettext('Aragonese Spanish')), - ('arm', oils_i18n_gettext('Armenian')), - ('arn', oils_i18n_gettext('Mapuche')), - ('arp', oils_i18n_gettext('Arapaho')), - ('art', oils_i18n_gettext('Artificial (Other)')), - ('arw', oils_i18n_gettext('Arawak')), - ('asm', oils_i18n_gettext('Assamese')), - ('ast', oils_i18n_gettext('Bable')), - ('ath', oils_i18n_gettext('Athapascan (Other)')), - ('aus', oils_i18n_gettext('Australian languages')), - ('ava', oils_i18n_gettext('Avaric')), - ('ave', oils_i18n_gettext('Avestan')), - ('awa', oils_i18n_gettext('Awadhi')), - ('aym', oils_i18n_gettext('Aymara')), - ('aze', oils_i18n_gettext('Azerbaijani')), - ('bad', oils_i18n_gettext('Banda')), - ('bai', oils_i18n_gettext('Bamileke languages')), - ('bak', oils_i18n_gettext('Bashkir')), - ('bal', oils_i18n_gettext('Baluchi')), - ('bam', oils_i18n_gettext('Bambara')), - ('ban', oils_i18n_gettext('Balinese')), - ('baq', oils_i18n_gettext('Basque')), - ('bas', oils_i18n_gettext('Basa')), - ('bat', oils_i18n_gettext('Baltic (Other)')), - ('bej', oils_i18n_gettext('Beja')), - ('bel', oils_i18n_gettext('Belarusian')), - ('bem', oils_i18n_gettext('Bemba')), - ('ben', oils_i18n_gettext('Bengali')), - ('ber', oils_i18n_gettext('Berber (Other)')), - ('bho', oils_i18n_gettext('Bhojpuri')), - ('bih', oils_i18n_gettext('Bihari')), - ('bik', oils_i18n_gettext('Bikol')), - ('bin', oils_i18n_gettext('Edo')), - ('bis', oils_i18n_gettext('Bislama')), - ('bla', oils_i18n_gettext('Siksika')), - ('bnt', oils_i18n_gettext('Bantu (Other)')), - ('bos', oils_i18n_gettext('Bosnian')), - ('bra', oils_i18n_gettext('Braj')), - ('bre', oils_i18n_gettext('Breton')), - ('btk', oils_i18n_gettext('Batak')), - ('bua', oils_i18n_gettext('Buriat')), - ('bug', oils_i18n_gettext('Bugis')), - ('bul', oils_i18n_gettext('Bulgarian')), - ('bur', oils_i18n_gettext('Burmese')), - ('cad', oils_i18n_gettext('Caddo')), - ('cai', oils_i18n_gettext('Central American Indian (Other)')), - ('-cam', oils_i18n_gettext('Khmer')), - ('car', oils_i18n_gettext('Carib')), - ('cat', oils_i18n_gettext('Catalan')), - ('cau', oils_i18n_gettext('Caucasian (Other)')), - ('ceb', oils_i18n_gettext('Cebuano')), - ('cel', oils_i18n_gettext('Celtic (Other)')), - ('cha', oils_i18n_gettext('Chamorro')), - ('chb', oils_i18n_gettext('Chibcha')), - ('che', oils_i18n_gettext('Chechen')), - ('chg', oils_i18n_gettext('Chagatai')), - ('chi', oils_i18n_gettext('Chinese')), - ('chk', oils_i18n_gettext('Truk')), - ('chm', oils_i18n_gettext('Mari')), - ('chn', oils_i18n_gettext('Chinook jargon')), - ('cho', oils_i18n_gettext('Choctaw')), - ('chp', oils_i18n_gettext('Chipewyan')), - ('chr', oils_i18n_gettext('Cherokee')), - ('chu', oils_i18n_gettext('Church Slavic')), - ('chv', oils_i18n_gettext('Chuvash')), - ('chy', oils_i18n_gettext('Cheyenne')), - ('cmc', oils_i18n_gettext('Chamic languages')), - ('cop', oils_i18n_gettext('Coptic')), - ('cor', oils_i18n_gettext('Cornish')), - ('cos', oils_i18n_gettext('Corsican')), - ('cpe', oils_i18n_gettext('Creoles and Pidgins, English-based (Other)')), - ('cpf', oils_i18n_gettext('Creoles and Pidgins, French-based (Other)')), - ('cpp', oils_i18n_gettext('Creoles and Pidgins, Portuguese-based (Other)')), - ('cre', oils_i18n_gettext('Cree')), - ('crh', oils_i18n_gettext('Crimean Tatar')), - ('crp', oils_i18n_gettext('Creoles and Pidgins (Other)')), - ('cus', oils_i18n_gettext('Cushitic (Other)')), - ('cze', oils_i18n_gettext('Czech')), - ('dak', oils_i18n_gettext('Dakota')), - ('dan', oils_i18n_gettext('Danish')), - ('dar', oils_i18n_gettext('Dargwa')), - ('day', oils_i18n_gettext('Dayak')), - ('del', oils_i18n_gettext('Delaware')), - ('den', oils_i18n_gettext('Slave')), - ('dgr', oils_i18n_gettext('Dogrib')), - ('din', oils_i18n_gettext('Dinka')), - ('div', oils_i18n_gettext('Divehi')), - ('doi', oils_i18n_gettext('Dogri')), - ('dra', oils_i18n_gettext('Dravidian (Other)')), - ('dua', oils_i18n_gettext('Duala')), - ('dum', oils_i18n_gettext('Dutch, Middle (ca. 1050-1350)')), - ('dut', oils_i18n_gettext('Dutch')), - ('dyu', oils_i18n_gettext('Dyula')), - ('dzo', oils_i18n_gettext('Dzongkha')), - ('efi', oils_i18n_gettext('Efik')), - ('egy', oils_i18n_gettext('Egyptian')), - ('eka', oils_i18n_gettext('Ekajuk')), - ('elx', oils_i18n_gettext('Elamite')), - ('eng', oils_i18n_gettext('English')), - ('enm', oils_i18n_gettext('English, Middle (1100-1500)')), - ('epo', oils_i18n_gettext('Esperanto')), - ('-esk', oils_i18n_gettext('Eskimo languages')), - ('-esp', oils_i18n_gettext('Esperanto')), - ('est', oils_i18n_gettext('Estonian')), - ('-eth', oils_i18n_gettext('Ethiopic')), - ('ewe', oils_i18n_gettext('Ewe')), - ('ewo', oils_i18n_gettext('Ewondo')), - ('fan', oils_i18n_gettext('Fang')), - ('fao', oils_i18n_gettext('Faroese')), - ('-far', oils_i18n_gettext('Faroese')), - ('fat', oils_i18n_gettext('Fanti')), - ('fij', oils_i18n_gettext('Fijian')), - ('fin', oils_i18n_gettext('Finnish')), - ('fiu', oils_i18n_gettext('Finno-Ugrian (Other)')), - ('fon', oils_i18n_gettext('Fon')), - ('fre', oils_i18n_gettext('French')), - ('-fri', oils_i18n_gettext('Frisian')), - ('frm', oils_i18n_gettext('French, Middle (ca. 1400-1600)')), - ('fro', oils_i18n_gettext('French, Old (ca. 842-1400)')), - ('fry', oils_i18n_gettext('Frisian')), - ('ful', oils_i18n_gettext('Fula')), - ('fur', oils_i18n_gettext('Friulian')), - ('gaa', oils_i18n_gettext('Gã')), - ('-gae', oils_i18n_gettext('Scottish Gaelic')), - ('-gag', oils_i18n_gettext('Galician')), - ('-gal', oils_i18n_gettext('Oromo')), - ('gay', oils_i18n_gettext('Gayo')), - ('gba', oils_i18n_gettext('Gbaya')), - ('gem', oils_i18n_gettext('Germanic (Other)')), - ('geo', oils_i18n_gettext('Georgian')), - ('ger', oils_i18n_gettext('German')), - ('gez', oils_i18n_gettext('Ethiopic')), - ('gil', oils_i18n_gettext('Gilbertese')), - ('gla', oils_i18n_gettext('Scottish Gaelic')), - ('gle', oils_i18n_gettext('Irish')), - ('glg', oils_i18n_gettext('Galician')), - ('glv', oils_i18n_gettext('Manx')), - ('gmh', oils_i18n_gettext('German, Middle High (ca. 1050-1500)')), - ('goh', oils_i18n_gettext('German, Old High (ca. 750-1050)')), - ('gon', oils_i18n_gettext('Gondi')), - ('gor', oils_i18n_gettext('Gorontalo')), - ('got', oils_i18n_gettext('Gothic')), - ('grb', oils_i18n_gettext('Grebo')), - ('grc', oils_i18n_gettext('Greek, Ancient (to 1453)')), - ('gre', oils_i18n_gettext('Greek, Modern (1453- )')), - ('grn', oils_i18n_gettext('Guarani')), - ('-gua', oils_i18n_gettext('Guarani')), - ('guj', oils_i18n_gettext('Gujarati')), - ('gwi', oils_i18n_gettext('Gwich''in')), - ('hai', oils_i18n_gettext('Haida')), - ('hat', oils_i18n_gettext('Haitian French Creole')), - ('hau', oils_i18n_gettext('Hausa')), - ('haw', oils_i18n_gettext('Hawaiian')), - ('heb', oils_i18n_gettext('Hebrew')), - ('her', oils_i18n_gettext('Herero')), - ('hil', oils_i18n_gettext('Hiligaynon')), - ('him', oils_i18n_gettext('Himachali')), - ('hin', oils_i18n_gettext('Hindi')), - ('hit', oils_i18n_gettext('Hittite')), - ('hmn', oils_i18n_gettext('Hmong')), - ('hmo', oils_i18n_gettext('Hiri Motu')), - ('hun', oils_i18n_gettext('Hungarian')), - ('hup', oils_i18n_gettext('Hupa')), - ('iba', oils_i18n_gettext('Iban')), - ('ibo', oils_i18n_gettext('Igbo')), - ('ice', oils_i18n_gettext('Icelandic')), - ('ido', oils_i18n_gettext('Ido')), - ('iii', oils_i18n_gettext('Sichuan Yi')), - ('ijo', oils_i18n_gettext('Ijo')), - ('iku', oils_i18n_gettext('Inuktitut')), - ('ile', oils_i18n_gettext('Interlingue')), - ('ilo', oils_i18n_gettext('Iloko')), - ('ina', oils_i18n_gettext('Interlingua (International Auxiliary Language Association)')), - ('inc', oils_i18n_gettext('Indic (Other)')), - ('ind', oils_i18n_gettext('Indonesian')), - ('ine', oils_i18n_gettext('Indo-European (Other)')), - ('inh', oils_i18n_gettext('Ingush')), - ('-int', oils_i18n_gettext('Interlingua (International Auxiliary Language Association)')), - ('ipk', oils_i18n_gettext('Inupiaq')), - ('ira', oils_i18n_gettext('Iranian (Other)')), - ('-iri', oils_i18n_gettext('Irish')), - ('iro', oils_i18n_gettext('Iroquoian (Other)')), - ('ita', oils_i18n_gettext('Italian')), - ('jav', oils_i18n_gettext('Javanese')), - ('jpn', oils_i18n_gettext('Japanese')), - ('jpr', oils_i18n_gettext('Judeo-Persian')), - ('jrb', oils_i18n_gettext('Judeo-Arabic')), - ('kaa', oils_i18n_gettext('Kara-Kalpak')), - ('kab', oils_i18n_gettext('Kabyle')), - ('kac', oils_i18n_gettext('Kachin')), - ('kal', oils_i18n_gettext('Kalâtdlisut')), - ('kam', oils_i18n_gettext('Kamba')), - ('kan', oils_i18n_gettext('Kannada')), - ('kar', oils_i18n_gettext('Karen')), - ('kas', oils_i18n_gettext('Kashmiri')), - ('kau', oils_i18n_gettext('Kanuri')), - ('kaw', oils_i18n_gettext('Kawi')), - ('kaz', oils_i18n_gettext('Kazakh')), - ('kbd', oils_i18n_gettext('Kabardian')), - ('kha', oils_i18n_gettext('Khasi')), - ('khi', oils_i18n_gettext('Khoisan (Other)')), - ('khm', oils_i18n_gettext('Khmer')), - ('kho', oils_i18n_gettext('Khotanese')), - ('kik', oils_i18n_gettext('Kikuyu')), - ('kin', oils_i18n_gettext('Kinyarwanda')), - ('kir', oils_i18n_gettext('Kyrgyz')), - ('kmb', oils_i18n_gettext('Kimbundu')), - ('kok', oils_i18n_gettext('Konkani')), - ('kom', oils_i18n_gettext('Komi')), - ('kon', oils_i18n_gettext('Kongo')), - ('kor', oils_i18n_gettext('Korean')), - ('kos', oils_i18n_gettext('Kusaie')), - ('kpe', oils_i18n_gettext('Kpelle')), - ('kro', oils_i18n_gettext('Kru')), - ('kru', oils_i18n_gettext('Kurukh')), - ('kua', oils_i18n_gettext('Kuanyama')), - ('kum', oils_i18n_gettext('Kumyk')), - ('kur', oils_i18n_gettext('Kurdish')), - ('-kus', oils_i18n_gettext('Kusaie')), - ('kut', oils_i18n_gettext('Kutenai')), - ('lad', oils_i18n_gettext('Ladino')), - ('lah', oils_i18n_gettext('Lahnda')), - ('lam', oils_i18n_gettext('Lamba')), - ('-lan', oils_i18n_gettext('Occitan (post-1500)')), - ('lao', oils_i18n_gettext('Lao')), - ('-lap', oils_i18n_gettext('Sami')), - ('lat', oils_i18n_gettext('Latin')), - ('lav', oils_i18n_gettext('Latvian')), - ('lez', oils_i18n_gettext('Lezgian')), - ('lim', oils_i18n_gettext('Limburgish')), - ('lin', oils_i18n_gettext('Lingala')), - ('lit', oils_i18n_gettext('Lithuanian')), - ('lol', oils_i18n_gettext('Mongo-Nkundu')), - ('loz', oils_i18n_gettext('Lozi')), - ('ltz', oils_i18n_gettext('Letzeburgesch')), - ('lua', oils_i18n_gettext('Luba-Lulua')), - ('lub', oils_i18n_gettext('Luba-Katanga')), - ('lug', oils_i18n_gettext('Ganda')), - ('lui', oils_i18n_gettext('Luiseño')), - ('lun', oils_i18n_gettext('Lunda')), - ('luo', oils_i18n_gettext('Luo (Kenya and Tanzania)')), - ('lus', oils_i18n_gettext('Lushai')), - ('mac', oils_i18n_gettext('Macedonian')), - ('mad', oils_i18n_gettext('Madurese')), - ('mag', oils_i18n_gettext('Magahi')), - ('mah', oils_i18n_gettext('Marshallese')), - ('mai', oils_i18n_gettext('Maithili')), - ('mak', oils_i18n_gettext('Makasar')), - ('mal', oils_i18n_gettext('Malayalam')), - ('man', oils_i18n_gettext('Mandingo')), - ('mao', oils_i18n_gettext('Maori')), - ('map', oils_i18n_gettext('Austronesian (Other)')), - ('mar', oils_i18n_gettext('Marathi')), - ('mas', oils_i18n_gettext('Masai')), - ('-max', oils_i18n_gettext('Manx')), - ('may', oils_i18n_gettext('Malay')), - ('mdr', oils_i18n_gettext('Mandar')), - ('men', oils_i18n_gettext('Mende')), - ('mga', oils_i18n_gettext('Irish, Middle (ca. 1100-1550)')), - ('mic', oils_i18n_gettext('Micmac')), - ('min', oils_i18n_gettext('Minangkabau')), - ('mis', oils_i18n_gettext('Miscellaneous languages')), - ('mkh', oils_i18n_gettext('Mon-Khmer (Other)')), - ('-mla', oils_i18n_gettext('Malagasy')), - ('mlg', oils_i18n_gettext('Malagasy')), - ('mlt', oils_i18n_gettext('Maltese')), - ('mnc', oils_i18n_gettext('Manchu')), - ('mni', oils_i18n_gettext('Manipuri')), - ('mno', oils_i18n_gettext('Manobo languages')), - ('moh', oils_i18n_gettext('Mohawk')), - ('mol', oils_i18n_gettext('Moldavian')), - ('mon', oils_i18n_gettext('Mongolian')), - ('mos', oils_i18n_gettext('Mooré')), - ('mul', oils_i18n_gettext('Multiple languages')), - ('mun', oils_i18n_gettext('Munda (Other)')), - ('mus', oils_i18n_gettext('Creek')), - ('mwr', oils_i18n_gettext('Marwari')), - ('myn', oils_i18n_gettext('Mayan languages')), - ('nah', oils_i18n_gettext('Nahuatl')), - ('nai', oils_i18n_gettext('North American Indian (Other)')), - ('nap', oils_i18n_gettext('Neapolitan Italian')), - ('nau', oils_i18n_gettext('Nauru')), - ('nav', oils_i18n_gettext('Navajo')), - ('nbl', oils_i18n_gettext('Ndebele (South Africa)')), - ('nde', oils_i18n_gettext('Ndebele (Zimbabwe) ')), - ('ndo', oils_i18n_gettext('Ndonga')), - ('nds', oils_i18n_gettext('Low German')), - ('nep', oils_i18n_gettext('Nepali')), - ('new', oils_i18n_gettext('Newari')), - ('nia', oils_i18n_gettext('Nias')), - ('nic', oils_i18n_gettext('Niger-Kordofanian (Other)')), - ('niu', oils_i18n_gettext('Niuean')), - ('nno', oils_i18n_gettext('Norwegian (Nynorsk)')), - ('nob', oils_i18n_gettext('Norwegian (Bokmål)')), - ('nog', oils_i18n_gettext('Nogai')), - ('non', oils_i18n_gettext('Old Norse')), - ('nor', oils_i18n_gettext('Norwegian')), - ('nso', oils_i18n_gettext('Northern Sotho')), - ('nub', oils_i18n_gettext('Nubian languages')), - ('nya', oils_i18n_gettext('Nyanja')), - ('nym', oils_i18n_gettext('Nyamwezi')), - ('nyn', oils_i18n_gettext('Nyankole')), - ('nyo', oils_i18n_gettext('Nyoro')), - ('nzi', oils_i18n_gettext('Nzima')), - ('oci', oils_i18n_gettext('Occitan (post-1500)')), - ('oji', oils_i18n_gettext('Ojibwa')), - ('ori', oils_i18n_gettext('Oriya')), - ('orm', oils_i18n_gettext('Oromo')), - ('osa', oils_i18n_gettext('Osage')), - ('oss', oils_i18n_gettext('Ossetic')), - ('ota', oils_i18n_gettext('Turkish, Ottoman')), - ('oto', oils_i18n_gettext('Otomian languages')), - ('paa', oils_i18n_gettext('Papuan (Other)')), - ('pag', oils_i18n_gettext('Pangasinan')), - ('pal', oils_i18n_gettext('Pahlavi')), - ('pam', oils_i18n_gettext('Pampanga')), - ('pan', oils_i18n_gettext('Panjabi')), - ('pap', oils_i18n_gettext('Papiamento')), - ('pau', oils_i18n_gettext('Palauan')), - ('peo', oils_i18n_gettext('Old Persian (ca. 600-400 B.C.)')), - ('per', oils_i18n_gettext('Persian')), - ('phi', oils_i18n_gettext('Philippine (Other)')), - ('phn', oils_i18n_gettext('Phoenician')), - ('pli', oils_i18n_gettext('Pali')), - ('pol', oils_i18n_gettext('Polish')), - ('pon', oils_i18n_gettext('Ponape')), - ('por', oils_i18n_gettext('Portuguese')), - ('pra', oils_i18n_gettext('Prakrit languages')), - ('pro', oils_i18n_gettext('Provençal (to 1500)')), - ('pus', oils_i18n_gettext('Pushto')), - ('que', oils_i18n_gettext('Quechua')), - ('raj', oils_i18n_gettext('Rajasthani')), - ('rap', oils_i18n_gettext('Rapanui')), - ('rar', oils_i18n_gettext('Rarotongan')), - ('roa', oils_i18n_gettext('Romance (Other)')), - ('roh', oils_i18n_gettext('Raeto-Romance')), - ('rom', oils_i18n_gettext('Romani')), - ('rum', oils_i18n_gettext('Romanian')), - ('run', oils_i18n_gettext('Rundi')), - ('rus', oils_i18n_gettext('Russian')), - ('sad', oils_i18n_gettext('Sandawe')), - ('sag', oils_i18n_gettext('Sango (Ubangi Creole)')), - ('sah', oils_i18n_gettext('Yakut')), - ('sai', oils_i18n_gettext('South American Indian (Other)')), - ('sal', oils_i18n_gettext('Salishan languages')), - ('sam', oils_i18n_gettext('Samaritan Aramaic')), - ('san', oils_i18n_gettext('Sanskrit')), - ('-sao', oils_i18n_gettext('Samoan')), - ('sas', oils_i18n_gettext('Sasak')), - ('sat', oils_i18n_gettext('Santali')), - ('scc', oils_i18n_gettext('Serbian')), - ('sco', oils_i18n_gettext('Scots')), - ('scr', oils_i18n_gettext('Croatian')), - ('sel', oils_i18n_gettext('Selkup')), - ('sem', oils_i18n_gettext('Semitic (Other)')), - ('sga', oils_i18n_gettext('Irish, Old (to 1100)')), - ('sgn', oils_i18n_gettext('Sign languages')), - ('shn', oils_i18n_gettext('Shan')), - ('-sho', oils_i18n_gettext('Shona')), - ('sid', oils_i18n_gettext('Sidamo')), - ('sin', oils_i18n_gettext('Sinhalese')), - ('sio', oils_i18n_gettext('Siouan (Other)')), - ('sit', oils_i18n_gettext('Sino-Tibetan (Other)')), - ('sla', oils_i18n_gettext('Slavic (Other)')), - ('slo', oils_i18n_gettext('Slovak')), - ('slv', oils_i18n_gettext('Slovenian')), - ('sma', oils_i18n_gettext('Southern Sami')), - ('sme', oils_i18n_gettext('Northern Sami')), - ('smi', oils_i18n_gettext('Sami')), - ('smj', oils_i18n_gettext('Lule Sami')), - ('smn', oils_i18n_gettext('Inari Sami')), - ('smo', oils_i18n_gettext('Samoan')), - ('sms', oils_i18n_gettext('Skolt Sami')), - ('sna', oils_i18n_gettext('Shona')), - ('snd', oils_i18n_gettext('Sindhi')), - ('-snh', oils_i18n_gettext('Sinhalese')), - ('snk', oils_i18n_gettext('Soninke')), - ('sog', oils_i18n_gettext('Sogdian')), - ('som', oils_i18n_gettext('Somali')), - ('son', oils_i18n_gettext('Songhai')), - ('sot', oils_i18n_gettext('Sotho')), - ('spa', oils_i18n_gettext('Spanish')), - ('srd', oils_i18n_gettext('Sardinian')), - ('srr', oils_i18n_gettext('Serer')), - ('ssa', oils_i18n_gettext('Nilo-Saharan (Other)')), - ('-sso', oils_i18n_gettext('Sotho')), - ('ssw', oils_i18n_gettext('Swazi')), - ('suk', oils_i18n_gettext('Sukuma')), - ('sun', oils_i18n_gettext('Sundanese')), - ('sus', oils_i18n_gettext('Susu')), - ('sux', oils_i18n_gettext('Sumerian')), - ('swa', oils_i18n_gettext('Swahili')), - ('swe', oils_i18n_gettext('Swedish')), - ('-swz', oils_i18n_gettext('Swazi')), - ('syr', oils_i18n_gettext('Syriac')), - ('-tag', oils_i18n_gettext('Tagalog')), - ('tah', oils_i18n_gettext('Tahitian')), - ('tai', oils_i18n_gettext('Tai (Other)')), - ('-taj', oils_i18n_gettext('Tajik')), - ('tam', oils_i18n_gettext('Tamil')), - ('-tar', oils_i18n_gettext('Tatar')), - ('tat', oils_i18n_gettext('Tatar')), - ('tel', oils_i18n_gettext('Telugu')), - ('tem', oils_i18n_gettext('Temne')), - ('ter', oils_i18n_gettext('Terena')), - ('tet', oils_i18n_gettext('Tetum')), - ('tgk', oils_i18n_gettext('Tajik')), - ('tgl', oils_i18n_gettext('Tagalog')), - ('tha', oils_i18n_gettext('Thai')), - ('tib', oils_i18n_gettext('Tibetan')), - ('tig', oils_i18n_gettext('Tigré')), - ('tir', oils_i18n_gettext('Tigrinya')), - ('tiv', oils_i18n_gettext('Tiv')), - ('tkl', oils_i18n_gettext('Tokelauan')), - ('tli', oils_i18n_gettext('Tlingit')), - ('tmh', oils_i18n_gettext('Tamashek')), - ('tog', oils_i18n_gettext('Tonga (Nyasa)')), - ('ton', oils_i18n_gettext('Tongan')), - ('tpi', oils_i18n_gettext('Tok Pisin')), - ('-tru', oils_i18n_gettext('Truk')), - ('tsi', oils_i18n_gettext('Tsimshian')), - ('tsn', oils_i18n_gettext('Tswana')), - ('tso', oils_i18n_gettext('Tsonga')), - ('-tsw', oils_i18n_gettext('Tswana')), - ('tuk', oils_i18n_gettext('Turkmen')), - ('tum', oils_i18n_gettext('Tumbuka')), - ('tup', oils_i18n_gettext('Tupi languages')), - ('tur', oils_i18n_gettext('Turkish')), - ('tut', oils_i18n_gettext('Altaic (Other)')), - ('tvl', oils_i18n_gettext('Tuvaluan')), - ('twi', oils_i18n_gettext('Twi')), - ('tyv', oils_i18n_gettext('Tuvinian')), - ('udm', oils_i18n_gettext('Udmurt')), - ('uga', oils_i18n_gettext('Ugaritic')), - ('uig', oils_i18n_gettext('Uighur')), - ('ukr', oils_i18n_gettext('Ukrainian')), - ('umb', oils_i18n_gettext('Umbundu')), - ('und', oils_i18n_gettext('Undetermined')), - ('urd', oils_i18n_gettext('Urdu')), - ('uzb', oils_i18n_gettext('Uzbek')), - ('vai', oils_i18n_gettext('Vai')), - ('ven', oils_i18n_gettext('Venda')), - ('vie', oils_i18n_gettext('Vietnamese')), - ('vol', oils_i18n_gettext('Volapük')), - ('vot', oils_i18n_gettext('Votic')), - ('wak', oils_i18n_gettext('Wakashan languages')), - ('wal', oils_i18n_gettext('Walamo')), - ('war', oils_i18n_gettext('Waray')), - ('was', oils_i18n_gettext('Washo')), - ('wel', oils_i18n_gettext('Welsh')), - ('wen', oils_i18n_gettext('Sorbian languages')), - ('wln', oils_i18n_gettext('Walloon')), - ('wol', oils_i18n_gettext('Wolof')), - ('xal', oils_i18n_gettext('Kalmyk')), - ('xho', oils_i18n_gettext('Xhosa')), - ('yao', oils_i18n_gettext('Yao (Africa)')), - ('yap', oils_i18n_gettext('Yapese')), - ('yid', oils_i18n_gettext('Yiddish')), - ('yor', oils_i18n_gettext('Yoruba')), - ('ypk', oils_i18n_gettext('Yupik languages')), - ('zap', oils_i18n_gettext('Zapotec')), - ('zen', oils_i18n_gettext('Zenaga')), - ('zha', oils_i18n_gettext('Zhuang')), - ('znd', oils_i18n_gettext('Zande')), - ('zul', oils_i18n_gettext('Zulu')), - ('zun', oils_i18n_gettext('Zuni')); - -INSERT INTO config.item_form_map (code, value) VALUES - ('a', oils_i18n_gettext('Microfilm')), - ('b', oils_i18n_gettext('Microfiche')), - ('c', oils_i18n_gettext('Microopaque')), - ('d', oils_i18n_gettext('Large print')), - ('f', oils_i18n_gettext('Braille')), - ('r', oils_i18n_gettext('Regular print reproduction')), - ('s', oils_i18n_gettext('Electronic')); - -INSERT INTO config.item_type_map (code, value) VALUES - ('a', oils_i18n_gettext('Language material')), - ('t', oils_i18n_gettext('Manuscript language material')), - ('g', oils_i18n_gettext('Projected medium')), - ('k', oils_i18n_gettext('Two-dimensional nonprojectable graphic')), - ('r', oils_i18n_gettext('Three-dimensional artifact or naturally occurring object')), - ('o', oils_i18n_gettext('Kit')), - ('p', oils_i18n_gettext('Mixed materials')), - ('e', oils_i18n_gettext('Cartographic material')), - ('f', oils_i18n_gettext('Manuscript cartographic material')), - ('c', oils_i18n_gettext('Notated music')), - ('d', oils_i18n_gettext('Manuscript notated music')), - ('i', oils_i18n_gettext('Nonmusical sound recording')), - ('j', oils_i18n_gettext('Musical sound recording')), - ('m', oils_i18n_gettext('Computer file')); +INSERT INTO config.language_map (code, value) VALUES ('aar', oils_i18n_gettext('Afar')); +INSERT INTO config.language_map (code, value) VALUES ('abk', oils_i18n_gettext('Abkhaz')); +INSERT INTO config.language_map (code, value) VALUES ('ace', oils_i18n_gettext('Achinese')); +INSERT INTO config.language_map (code, value) VALUES ('ach', oils_i18n_gettext('Acoli')); +INSERT INTO config.language_map (code, value) VALUES ('ada', oils_i18n_gettext('Adangme')); +INSERT INTO config.language_map (code, value) VALUES ('ady', oils_i18n_gettext('Adygei')); +INSERT INTO config.language_map (code, value) VALUES ('afa', oils_i18n_gettext('Afroasiatic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('afh', oils_i18n_gettext('Afrihili (Artificial language)')); +INSERT INTO config.language_map (code, value) VALUES ('afr', oils_i18n_gettext('Afrikaans')); +INSERT INTO config.language_map (code, value) VALUES ('-ajm', oils_i18n_gettext('Aljamía')); +INSERT INTO config.language_map (code, value) VALUES ('aka', oils_i18n_gettext('Akan')); +INSERT INTO config.language_map (code, value) VALUES ('akk', oils_i18n_gettext('Akkadian')); +INSERT INTO config.language_map (code, value) VALUES ('alb', oils_i18n_gettext('Albanian')); +INSERT INTO config.language_map (code, value) VALUES ('ale', oils_i18n_gettext('Aleut')); +INSERT INTO config.language_map (code, value) VALUES ('alg', oils_i18n_gettext('Algonquian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('amh', oils_i18n_gettext('Amharic')); +INSERT INTO config.language_map (code, value) VALUES ('ang', oils_i18n_gettext('English, Old (ca. 450-1100)')); +INSERT INTO config.language_map (code, value) VALUES ('apa', oils_i18n_gettext('Apache languages')); +INSERT INTO config.language_map (code, value) VALUES ('ara', oils_i18n_gettext('Arabic')); +INSERT INTO config.language_map (code, value) VALUES ('arc', oils_i18n_gettext('Aramaic')); +INSERT INTO config.language_map (code, value) VALUES ('arg', oils_i18n_gettext('Aragonese Spanish')); +INSERT INTO config.language_map (code, value) VALUES ('arm', oils_i18n_gettext('Armenian')); +INSERT INTO config.language_map (code, value) VALUES ('arn', oils_i18n_gettext('Mapuche')); +INSERT INTO config.language_map (code, value) VALUES ('arp', oils_i18n_gettext('Arapaho')); +INSERT INTO config.language_map (code, value) VALUES ('art', oils_i18n_gettext('Artificial (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('arw', oils_i18n_gettext('Arawak')); +INSERT INTO config.language_map (code, value) VALUES ('asm', oils_i18n_gettext('Assamese')); +INSERT INTO config.language_map (code, value) VALUES ('ast', oils_i18n_gettext('Bable')); +INSERT INTO config.language_map (code, value) VALUES ('ath', oils_i18n_gettext('Athapascan (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('aus', oils_i18n_gettext('Australian languages')); +INSERT INTO config.language_map (code, value) VALUES ('ava', oils_i18n_gettext('Avaric')); +INSERT INTO config.language_map (code, value) VALUES ('ave', oils_i18n_gettext('Avestan')); +INSERT INTO config.language_map (code, value) VALUES ('awa', oils_i18n_gettext('Awadhi')); +INSERT INTO config.language_map (code, value) VALUES ('aym', oils_i18n_gettext('Aymara')); +INSERT INTO config.language_map (code, value) VALUES ('aze', oils_i18n_gettext('Azerbaijani')); +INSERT INTO config.language_map (code, value) VALUES ('bad', oils_i18n_gettext('Banda')); +INSERT INTO config.language_map (code, value) VALUES ('bai', oils_i18n_gettext('Bamileke languages')); +INSERT INTO config.language_map (code, value) VALUES ('bak', oils_i18n_gettext('Bashkir')); +INSERT INTO config.language_map (code, value) VALUES ('bal', oils_i18n_gettext('Baluchi')); +INSERT INTO config.language_map (code, value) VALUES ('bam', oils_i18n_gettext('Bambara')); +INSERT INTO config.language_map (code, value) VALUES ('ban', oils_i18n_gettext('Balinese')); +INSERT INTO config.language_map (code, value) VALUES ('baq', oils_i18n_gettext('Basque')); +INSERT INTO config.language_map (code, value) VALUES ('bas', oils_i18n_gettext('Basa')); +INSERT INTO config.language_map (code, value) VALUES ('bat', oils_i18n_gettext('Baltic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('bej', oils_i18n_gettext('Beja')); +INSERT INTO config.language_map (code, value) VALUES ('bel', oils_i18n_gettext('Belarusian')); +INSERT INTO config.language_map (code, value) VALUES ('bem', oils_i18n_gettext('Bemba')); +INSERT INTO config.language_map (code, value) VALUES ('ben', oils_i18n_gettext('Bengali')); +INSERT INTO config.language_map (code, value) VALUES ('ber', oils_i18n_gettext('Berber (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('bho', oils_i18n_gettext('Bhojpuri')); +INSERT INTO config.language_map (code, value) VALUES ('bih', oils_i18n_gettext('Bihari')); +INSERT INTO config.language_map (code, value) VALUES ('bik', oils_i18n_gettext('Bikol')); +INSERT INTO config.language_map (code, value) VALUES ('bin', oils_i18n_gettext('Edo')); +INSERT INTO config.language_map (code, value) VALUES ('bis', oils_i18n_gettext('Bislama')); +INSERT INTO config.language_map (code, value) VALUES ('bla', oils_i18n_gettext('Siksika')); +INSERT INTO config.language_map (code, value) VALUES ('bnt', oils_i18n_gettext('Bantu (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('bos', oils_i18n_gettext('Bosnian')); +INSERT INTO config.language_map (code, value) VALUES ('bra', oils_i18n_gettext('Braj')); +INSERT INTO config.language_map (code, value) VALUES ('bre', oils_i18n_gettext('Breton')); +INSERT INTO config.language_map (code, value) VALUES ('btk', oils_i18n_gettext('Batak')); +INSERT INTO config.language_map (code, value) VALUES ('bua', oils_i18n_gettext('Buriat')); +INSERT INTO config.language_map (code, value) VALUES ('bug', oils_i18n_gettext('Bugis')); +INSERT INTO config.language_map (code, value) VALUES ('bul', oils_i18n_gettext('Bulgarian')); +INSERT INTO config.language_map (code, value) VALUES ('bur', oils_i18n_gettext('Burmese')); +INSERT INTO config.language_map (code, value) VALUES ('cad', oils_i18n_gettext('Caddo')); +INSERT INTO config.language_map (code, value) VALUES ('cai', oils_i18n_gettext('Central American Indian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('-cam', oils_i18n_gettext('Khmer')); +INSERT INTO config.language_map (code, value) VALUES ('car', oils_i18n_gettext('Carib')); +INSERT INTO config.language_map (code, value) VALUES ('cat', oils_i18n_gettext('Catalan')); +INSERT INTO config.language_map (code, value) VALUES ('cau', oils_i18n_gettext('Caucasian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('ceb', oils_i18n_gettext('Cebuano')); +INSERT INTO config.language_map (code, value) VALUES ('cel', oils_i18n_gettext('Celtic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('cha', oils_i18n_gettext('Chamorro')); +INSERT INTO config.language_map (code, value) VALUES ('chb', oils_i18n_gettext('Chibcha')); +INSERT INTO config.language_map (code, value) VALUES ('che', oils_i18n_gettext('Chechen')); +INSERT INTO config.language_map (code, value) VALUES ('chg', oils_i18n_gettext('Chagatai')); +INSERT INTO config.language_map (code, value) VALUES ('chi', oils_i18n_gettext('Chinese')); +INSERT INTO config.language_map (code, value) VALUES ('chk', oils_i18n_gettext('Truk')); +INSERT INTO config.language_map (code, value) VALUES ('chm', oils_i18n_gettext('Mari')); +INSERT INTO config.language_map (code, value) VALUES ('chn', oils_i18n_gettext('Chinook jargon')); +INSERT INTO config.language_map (code, value) VALUES ('cho', oils_i18n_gettext('Choctaw')); +INSERT INTO config.language_map (code, value) VALUES ('chp', oils_i18n_gettext('Chipewyan')); +INSERT INTO config.language_map (code, value) VALUES ('chr', oils_i18n_gettext('Cherokee')); +INSERT INTO config.language_map (code, value) VALUES ('chu', oils_i18n_gettext('Church Slavic')); +INSERT INTO config.language_map (code, value) VALUES ('chv', oils_i18n_gettext('Chuvash')); +INSERT INTO config.language_map (code, value) VALUES ('chy', oils_i18n_gettext('Cheyenne')); +INSERT INTO config.language_map (code, value) VALUES ('cmc', oils_i18n_gettext('Chamic languages')); +INSERT INTO config.language_map (code, value) VALUES ('cop', oils_i18n_gettext('Coptic')); +INSERT INTO config.language_map (code, value) VALUES ('cor', oils_i18n_gettext('Cornish')); +INSERT INTO config.language_map (code, value) VALUES ('cos', oils_i18n_gettext('Corsican')); +INSERT INTO config.language_map (code, value) VALUES ('cpe', oils_i18n_gettext('Creoles and Pidgins, English-based (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('cpf', oils_i18n_gettext('Creoles and Pidgins, French-based (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('cpp', oils_i18n_gettext('Creoles and Pidgins, Portuguese-based (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('cre', oils_i18n_gettext('Cree')); +INSERT INTO config.language_map (code, value) VALUES ('crh', oils_i18n_gettext('Crimean Tatar')); +INSERT INTO config.language_map (code, value) VALUES ('crp', oils_i18n_gettext('Creoles and Pidgins (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('cus', oils_i18n_gettext('Cushitic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('cze', oils_i18n_gettext('Czech')); +INSERT INTO config.language_map (code, value) VALUES ('dak', oils_i18n_gettext('Dakota')); +INSERT INTO config.language_map (code, value) VALUES ('dan', oils_i18n_gettext('Danish')); +INSERT INTO config.language_map (code, value) VALUES ('dar', oils_i18n_gettext('Dargwa')); +INSERT INTO config.language_map (code, value) VALUES ('day', oils_i18n_gettext('Dayak')); +INSERT INTO config.language_map (code, value) VALUES ('del', oils_i18n_gettext('Delaware')); +INSERT INTO config.language_map (code, value) VALUES ('den', oils_i18n_gettext('Slave')); +INSERT INTO config.language_map (code, value) VALUES ('dgr', oils_i18n_gettext('Dogrib')); +INSERT INTO config.language_map (code, value) VALUES ('din', oils_i18n_gettext('Dinka')); +INSERT INTO config.language_map (code, value) VALUES ('div', oils_i18n_gettext('Divehi')); +INSERT INTO config.language_map (code, value) VALUES ('doi', oils_i18n_gettext('Dogri')); +INSERT INTO config.language_map (code, value) VALUES ('dra', oils_i18n_gettext('Dravidian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('dua', oils_i18n_gettext('Duala')); +INSERT INTO config.language_map (code, value) VALUES ('dum', oils_i18n_gettext('Dutch, Middle (ca. 1050-1350)')); +INSERT INTO config.language_map (code, value) VALUES ('dut', oils_i18n_gettext('Dutch')); +INSERT INTO config.language_map (code, value) VALUES ('dyu', oils_i18n_gettext('Dyula')); +INSERT INTO config.language_map (code, value) VALUES ('dzo', oils_i18n_gettext('Dzongkha')); +INSERT INTO config.language_map (code, value) VALUES ('efi', oils_i18n_gettext('Efik')); +INSERT INTO config.language_map (code, value) VALUES ('egy', oils_i18n_gettext('Egyptian')); +INSERT INTO config.language_map (code, value) VALUES ('eka', oils_i18n_gettext('Ekajuk')); +INSERT INTO config.language_map (code, value) VALUES ('elx', oils_i18n_gettext('Elamite')); +INSERT INTO config.language_map (code, value) VALUES ('eng', oils_i18n_gettext('English')); +INSERT INTO config.language_map (code, value) VALUES ('enm', oils_i18n_gettext('English, Middle (1100-1500)')); +INSERT INTO config.language_map (code, value) VALUES ('epo', oils_i18n_gettext('Esperanto')); +INSERT INTO config.language_map (code, value) VALUES ('-esk', oils_i18n_gettext('Eskimo languages')); +INSERT INTO config.language_map (code, value) VALUES ('-esp', oils_i18n_gettext('Esperanto')); +INSERT INTO config.language_map (code, value) VALUES ('est', oils_i18n_gettext('Estonian')); +INSERT INTO config.language_map (code, value) VALUES ('-eth', oils_i18n_gettext('Ethiopic')); +INSERT INTO config.language_map (code, value) VALUES ('ewe', oils_i18n_gettext('Ewe')); +INSERT INTO config.language_map (code, value) VALUES ('ewo', oils_i18n_gettext('Ewondo')); +INSERT INTO config.language_map (code, value) VALUES ('fan', oils_i18n_gettext('Fang')); +INSERT INTO config.language_map (code, value) VALUES ('fao', oils_i18n_gettext('Faroese')); +INSERT INTO config.language_map (code, value) VALUES ('-far', oils_i18n_gettext('Faroese')); +INSERT INTO config.language_map (code, value) VALUES ('fat', oils_i18n_gettext('Fanti')); +INSERT INTO config.language_map (code, value) VALUES ('fij', oils_i18n_gettext('Fijian')); +INSERT INTO config.language_map (code, value) VALUES ('fin', oils_i18n_gettext('Finnish')); +INSERT INTO config.language_map (code, value) VALUES ('fiu', oils_i18n_gettext('Finno-Ugrian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('fon', oils_i18n_gettext('Fon')); +INSERT INTO config.language_map (code, value) VALUES ('fre', oils_i18n_gettext('French')); +INSERT INTO config.language_map (code, value) VALUES ('-fri', oils_i18n_gettext('Frisian')); +INSERT INTO config.language_map (code, value) VALUES ('frm', oils_i18n_gettext('French, Middle (ca. 1400-1600)')); +INSERT INTO config.language_map (code, value) VALUES ('fro', oils_i18n_gettext('French, Old (ca. 842-1400)')); +INSERT INTO config.language_map (code, value) VALUES ('fry', oils_i18n_gettext('Frisian')); +INSERT INTO config.language_map (code, value) VALUES ('ful', oils_i18n_gettext('Fula')); +INSERT INTO config.language_map (code, value) VALUES ('fur', oils_i18n_gettext('Friulian')); +INSERT INTO config.language_map (code, value) VALUES ('gaa', oils_i18n_gettext('Gã')); +INSERT INTO config.language_map (code, value) VALUES ('-gae', oils_i18n_gettext('Scottish Gaelic')); +INSERT INTO config.language_map (code, value) VALUES ('-gag', oils_i18n_gettext('Galician')); +INSERT INTO config.language_map (code, value) VALUES ('-gal', oils_i18n_gettext('Oromo')); +INSERT INTO config.language_map (code, value) VALUES ('gay', oils_i18n_gettext('Gayo')); +INSERT INTO config.language_map (code, value) VALUES ('gba', oils_i18n_gettext('Gbaya')); +INSERT INTO config.language_map (code, value) VALUES ('gem', oils_i18n_gettext('Germanic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('geo', oils_i18n_gettext('Georgian')); +INSERT INTO config.language_map (code, value) VALUES ('ger', oils_i18n_gettext('German')); +INSERT INTO config.language_map (code, value) VALUES ('gez', oils_i18n_gettext('Ethiopic')); +INSERT INTO config.language_map (code, value) VALUES ('gil', oils_i18n_gettext('Gilbertese')); +INSERT INTO config.language_map (code, value) VALUES ('gla', oils_i18n_gettext('Scottish Gaelic')); +INSERT INTO config.language_map (code, value) VALUES ('gle', oils_i18n_gettext('Irish')); +INSERT INTO config.language_map (code, value) VALUES ('glg', oils_i18n_gettext('Galician')); +INSERT INTO config.language_map (code, value) VALUES ('glv', oils_i18n_gettext('Manx')); +INSERT INTO config.language_map (code, value) VALUES ('gmh', oils_i18n_gettext('German, Middle High (ca. 1050-1500)')); +INSERT INTO config.language_map (code, value) VALUES ('goh', oils_i18n_gettext('German, Old High (ca. 750-1050)')); +INSERT INTO config.language_map (code, value) VALUES ('gon', oils_i18n_gettext('Gondi')); +INSERT INTO config.language_map (code, value) VALUES ('gor', oils_i18n_gettext('Gorontalo')); +INSERT INTO config.language_map (code, value) VALUES ('got', oils_i18n_gettext('Gothic')); +INSERT INTO config.language_map (code, value) VALUES ('grb', oils_i18n_gettext('Grebo')); +INSERT INTO config.language_map (code, value) VALUES ('grc', oils_i18n_gettext('Greek, Ancient (to 1453)')); +INSERT INTO config.language_map (code, value) VALUES ('gre', oils_i18n_gettext('Greek, Modern (1453- )')); +INSERT INTO config.language_map (code, value) VALUES ('grn', oils_i18n_gettext('Guarani')); +INSERT INTO config.language_map (code, value) VALUES ('-gua', oils_i18n_gettext('Guarani')); +INSERT INTO config.language_map (code, value) VALUES ('guj', oils_i18n_gettext('Gujarati')); +INSERT INTO config.language_map (code, value) VALUES ('gwi', oils_i18n_gettext('Gwich''in')); +INSERT INTO config.language_map (code, value) VALUES ('hai', oils_i18n_gettext('Haida')); +INSERT INTO config.language_map (code, value) VALUES ('hat', oils_i18n_gettext('Haitian French Creole')); +INSERT INTO config.language_map (code, value) VALUES ('hau', oils_i18n_gettext('Hausa')); +INSERT INTO config.language_map (code, value) VALUES ('haw', oils_i18n_gettext('Hawaiian')); +INSERT INTO config.language_map (code, value) VALUES ('heb', oils_i18n_gettext('Hebrew')); +INSERT INTO config.language_map (code, value) VALUES ('her', oils_i18n_gettext('Herero')); +INSERT INTO config.language_map (code, value) VALUES ('hil', oils_i18n_gettext('Hiligaynon')); +INSERT INTO config.language_map (code, value) VALUES ('him', oils_i18n_gettext('Himachali')); +INSERT INTO config.language_map (code, value) VALUES ('hin', oils_i18n_gettext('Hindi')); +INSERT INTO config.language_map (code, value) VALUES ('hit', oils_i18n_gettext('Hittite')); +INSERT INTO config.language_map (code, value) VALUES ('hmn', oils_i18n_gettext('Hmong')); +INSERT INTO config.language_map (code, value) VALUES ('hmo', oils_i18n_gettext('Hiri Motu')); +INSERT INTO config.language_map (code, value) VALUES ('hun', oils_i18n_gettext('Hungarian')); +INSERT INTO config.language_map (code, value) VALUES ('hup', oils_i18n_gettext('Hupa')); +INSERT INTO config.language_map (code, value) VALUES ('iba', oils_i18n_gettext('Iban')); +INSERT INTO config.language_map (code, value) VALUES ('ibo', oils_i18n_gettext('Igbo')); +INSERT INTO config.language_map (code, value) VALUES ('ice', oils_i18n_gettext('Icelandic')); +INSERT INTO config.language_map (code, value) VALUES ('ido', oils_i18n_gettext('Ido')); +INSERT INTO config.language_map (code, value) VALUES ('iii', oils_i18n_gettext('Sichuan Yi')); +INSERT INTO config.language_map (code, value) VALUES ('ijo', oils_i18n_gettext('Ijo')); +INSERT INTO config.language_map (code, value) VALUES ('iku', oils_i18n_gettext('Inuktitut')); +INSERT INTO config.language_map (code, value) VALUES ('ile', oils_i18n_gettext('Interlingue')); +INSERT INTO config.language_map (code, value) VALUES ('ilo', oils_i18n_gettext('Iloko')); +INSERT INTO config.language_map (code, value) VALUES ('ina', oils_i18n_gettext('Interlingua (International Auxiliary Language Association)')); +INSERT INTO config.language_map (code, value) VALUES ('inc', oils_i18n_gettext('Indic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('ind', oils_i18n_gettext('Indonesian')); +INSERT INTO config.language_map (code, value) VALUES ('ine', oils_i18n_gettext('Indo-European (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('inh', oils_i18n_gettext('Ingush')); +INSERT INTO config.language_map (code, value) VALUES ('-int', oils_i18n_gettext('Interlingua (International Auxiliary Language Association)')); +INSERT INTO config.language_map (code, value) VALUES ('ipk', oils_i18n_gettext('Inupiaq')); +INSERT INTO config.language_map (code, value) VALUES ('ira', oils_i18n_gettext('Iranian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('-iri', oils_i18n_gettext('Irish')); +INSERT INTO config.language_map (code, value) VALUES ('iro', oils_i18n_gettext('Iroquoian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('ita', oils_i18n_gettext('Italian')); +INSERT INTO config.language_map (code, value) VALUES ('jav', oils_i18n_gettext('Javanese')); +INSERT INTO config.language_map (code, value) VALUES ('jpn', oils_i18n_gettext('Japanese')); +INSERT INTO config.language_map (code, value) VALUES ('jpr', oils_i18n_gettext('Judeo-Persian')); +INSERT INTO config.language_map (code, value) VALUES ('jrb', oils_i18n_gettext('Judeo-Arabic')); +INSERT INTO config.language_map (code, value) VALUES ('kaa', oils_i18n_gettext('Kara-Kalpak')); +INSERT INTO config.language_map (code, value) VALUES ('kab', oils_i18n_gettext('Kabyle')); +INSERT INTO config.language_map (code, value) VALUES ('kac', oils_i18n_gettext('Kachin')); +INSERT INTO config.language_map (code, value) VALUES ('kal', oils_i18n_gettext('Kalâtdlisut')); +INSERT INTO config.language_map (code, value) VALUES ('kam', oils_i18n_gettext('Kamba')); +INSERT INTO config.language_map (code, value) VALUES ('kan', oils_i18n_gettext('Kannada')); +INSERT INTO config.language_map (code, value) VALUES ('kar', oils_i18n_gettext('Karen')); +INSERT INTO config.language_map (code, value) VALUES ('kas', oils_i18n_gettext('Kashmiri')); +INSERT INTO config.language_map (code, value) VALUES ('kau', oils_i18n_gettext('Kanuri')); +INSERT INTO config.language_map (code, value) VALUES ('kaw', oils_i18n_gettext('Kawi')); +INSERT INTO config.language_map (code, value) VALUES ('kaz', oils_i18n_gettext('Kazakh')); +INSERT INTO config.language_map (code, value) VALUES ('kbd', oils_i18n_gettext('Kabardian')); +INSERT INTO config.language_map (code, value) VALUES ('kha', oils_i18n_gettext('Khasi')); +INSERT INTO config.language_map (code, value) VALUES ('khi', oils_i18n_gettext('Khoisan (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('khm', oils_i18n_gettext('Khmer')); +INSERT INTO config.language_map (code, value) VALUES ('kho', oils_i18n_gettext('Khotanese')); +INSERT INTO config.language_map (code, value) VALUES ('kik', oils_i18n_gettext('Kikuyu')); +INSERT INTO config.language_map (code, value) VALUES ('kin', oils_i18n_gettext('Kinyarwanda')); +INSERT INTO config.language_map (code, value) VALUES ('kir', oils_i18n_gettext('Kyrgyz')); +INSERT INTO config.language_map (code, value) VALUES ('kmb', oils_i18n_gettext('Kimbundu')); +INSERT INTO config.language_map (code, value) VALUES ('kok', oils_i18n_gettext('Konkani')); +INSERT INTO config.language_map (code, value) VALUES ('kom', oils_i18n_gettext('Komi')); +INSERT INTO config.language_map (code, value) VALUES ('kon', oils_i18n_gettext('Kongo')); +INSERT INTO config.language_map (code, value) VALUES ('kor', oils_i18n_gettext('Korean')); +INSERT INTO config.language_map (code, value) VALUES ('kos', oils_i18n_gettext('Kusaie')); +INSERT INTO config.language_map (code, value) VALUES ('kpe', oils_i18n_gettext('Kpelle')); +INSERT INTO config.language_map (code, value) VALUES ('kro', oils_i18n_gettext('Kru')); +INSERT INTO config.language_map (code, value) VALUES ('kru', oils_i18n_gettext('Kurukh')); +INSERT INTO config.language_map (code, value) VALUES ('kua', oils_i18n_gettext('Kuanyama')); +INSERT INTO config.language_map (code, value) VALUES ('kum', oils_i18n_gettext('Kumyk')); +INSERT INTO config.language_map (code, value) VALUES ('kur', oils_i18n_gettext('Kurdish')); +INSERT INTO config.language_map (code, value) VALUES ('-kus', oils_i18n_gettext('Kusaie')); +INSERT INTO config.language_map (code, value) VALUES ('kut', oils_i18n_gettext('Kutenai')); +INSERT INTO config.language_map (code, value) VALUES ('lad', oils_i18n_gettext('Ladino')); +INSERT INTO config.language_map (code, value) VALUES ('lah', oils_i18n_gettext('Lahnda')); +INSERT INTO config.language_map (code, value) VALUES ('lam', oils_i18n_gettext('Lamba')); +INSERT INTO config.language_map (code, value) VALUES ('-lan', oils_i18n_gettext('Occitan (post-1500)')); +INSERT INTO config.language_map (code, value) VALUES ('lao', oils_i18n_gettext('Lao')); +INSERT INTO config.language_map (code, value) VALUES ('-lap', oils_i18n_gettext('Sami')); +INSERT INTO config.language_map (code, value) VALUES ('lat', oils_i18n_gettext('Latin')); +INSERT INTO config.language_map (code, value) VALUES ('lav', oils_i18n_gettext('Latvian')); +INSERT INTO config.language_map (code, value) VALUES ('lez', oils_i18n_gettext('Lezgian')); +INSERT INTO config.language_map (code, value) VALUES ('lim', oils_i18n_gettext('Limburgish')); +INSERT INTO config.language_map (code, value) VALUES ('lin', oils_i18n_gettext('Lingala')); +INSERT INTO config.language_map (code, value) VALUES ('lit', oils_i18n_gettext('Lithuanian')); +INSERT INTO config.language_map (code, value) VALUES ('lol', oils_i18n_gettext('Mongo-Nkundu')); +INSERT INTO config.language_map (code, value) VALUES ('loz', oils_i18n_gettext('Lozi')); +INSERT INTO config.language_map (code, value) VALUES ('ltz', oils_i18n_gettext('Letzeburgesch')); +INSERT INTO config.language_map (code, value) VALUES ('lua', oils_i18n_gettext('Luba-Lulua')); +INSERT INTO config.language_map (code, value) VALUES ('lub', oils_i18n_gettext('Luba-Katanga')); +INSERT INTO config.language_map (code, value) VALUES ('lug', oils_i18n_gettext('Ganda')); +INSERT INTO config.language_map (code, value) VALUES ('lui', oils_i18n_gettext('Luiseño')); +INSERT INTO config.language_map (code, value) VALUES ('lun', oils_i18n_gettext('Lunda')); +INSERT INTO config.language_map (code, value) VALUES ('luo', oils_i18n_gettext('Luo (Kenya and Tanzania)')); +INSERT INTO config.language_map (code, value) VALUES ('lus', oils_i18n_gettext('Lushai')); +INSERT INTO config.language_map (code, value) VALUES ('mac', oils_i18n_gettext('Macedonian')); +INSERT INTO config.language_map (code, value) VALUES ('mad', oils_i18n_gettext('Madurese')); +INSERT INTO config.language_map (code, value) VALUES ('mag', oils_i18n_gettext('Magahi')); +INSERT INTO config.language_map (code, value) VALUES ('mah', oils_i18n_gettext('Marshallese')); +INSERT INTO config.language_map (code, value) VALUES ('mai', oils_i18n_gettext('Maithili')); +INSERT INTO config.language_map (code, value) VALUES ('mak', oils_i18n_gettext('Makasar')); +INSERT INTO config.language_map (code, value) VALUES ('mal', oils_i18n_gettext('Malayalam')); +INSERT INTO config.language_map (code, value) VALUES ('man', oils_i18n_gettext('Mandingo')); +INSERT INTO config.language_map (code, value) VALUES ('mao', oils_i18n_gettext('Maori')); +INSERT INTO config.language_map (code, value) VALUES ('map', oils_i18n_gettext('Austronesian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('mar', oils_i18n_gettext('Marathi')); +INSERT INTO config.language_map (code, value) VALUES ('mas', oils_i18n_gettext('Masai')); +INSERT INTO config.language_map (code, value) VALUES ('-max', oils_i18n_gettext('Manx')); +INSERT INTO config.language_map (code, value) VALUES ('may', oils_i18n_gettext('Malay')); +INSERT INTO config.language_map (code, value) VALUES ('mdr', oils_i18n_gettext('Mandar')); +INSERT INTO config.language_map (code, value) VALUES ('men', oils_i18n_gettext('Mende')); +INSERT INTO config.language_map (code, value) VALUES ('mga', oils_i18n_gettext('Irish, Middle (ca. 1100-1550)')); +INSERT INTO config.language_map (code, value) VALUES ('mic', oils_i18n_gettext('Micmac')); +INSERT INTO config.language_map (code, value) VALUES ('min', oils_i18n_gettext('Minangkabau')); +INSERT INTO config.language_map (code, value) VALUES ('mis', oils_i18n_gettext('Miscellaneous languages')); +INSERT INTO config.language_map (code, value) VALUES ('mkh', oils_i18n_gettext('Mon-Khmer (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('-mla', oils_i18n_gettext('Malagasy')); +INSERT INTO config.language_map (code, value) VALUES ('mlg', oils_i18n_gettext('Malagasy')); +INSERT INTO config.language_map (code, value) VALUES ('mlt', oils_i18n_gettext('Maltese')); +INSERT INTO config.language_map (code, value) VALUES ('mnc', oils_i18n_gettext('Manchu')); +INSERT INTO config.language_map (code, value) VALUES ('mni', oils_i18n_gettext('Manipuri')); +INSERT INTO config.language_map (code, value) VALUES ('mno', oils_i18n_gettext('Manobo languages')); +INSERT INTO config.language_map (code, value) VALUES ('moh', oils_i18n_gettext('Mohawk')); +INSERT INTO config.language_map (code, value) VALUES ('mol', oils_i18n_gettext('Moldavian')); +INSERT INTO config.language_map (code, value) VALUES ('mon', oils_i18n_gettext('Mongolian')); +INSERT INTO config.language_map (code, value) VALUES ('mos', oils_i18n_gettext('Mooré')); +INSERT INTO config.language_map (code, value) VALUES ('mul', oils_i18n_gettext('Multiple languages')); +INSERT INTO config.language_map (code, value) VALUES ('mun', oils_i18n_gettext('Munda (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('mus', oils_i18n_gettext('Creek')); +INSERT INTO config.language_map (code, value) VALUES ('mwr', oils_i18n_gettext('Marwari')); +INSERT INTO config.language_map (code, value) VALUES ('myn', oils_i18n_gettext('Mayan languages')); +INSERT INTO config.language_map (code, value) VALUES ('nah', oils_i18n_gettext('Nahuatl')); +INSERT INTO config.language_map (code, value) VALUES ('nai', oils_i18n_gettext('North American Indian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('nap', oils_i18n_gettext('Neapolitan Italian')); +INSERT INTO config.language_map (code, value) VALUES ('nau', oils_i18n_gettext('Nauru')); +INSERT INTO config.language_map (code, value) VALUES ('nav', oils_i18n_gettext('Navajo')); +INSERT INTO config.language_map (code, value) VALUES ('nbl', oils_i18n_gettext('Ndebele (South Africa)')); +INSERT INTO config.language_map (code, value) VALUES ('nde', oils_i18n_gettext('Ndebele (Zimbabwe) ')); +INSERT INTO config.language_map (code, value) VALUES ('ndo', oils_i18n_gettext('Ndonga')); +INSERT INTO config.language_map (code, value) VALUES ('nds', oils_i18n_gettext('Low German')); +INSERT INTO config.language_map (code, value) VALUES ('nep', oils_i18n_gettext('Nepali')); +INSERT INTO config.language_map (code, value) VALUES ('new', oils_i18n_gettext('Newari')); +INSERT INTO config.language_map (code, value) VALUES ('nia', oils_i18n_gettext('Nias')); +INSERT INTO config.language_map (code, value) VALUES ('nic', oils_i18n_gettext('Niger-Kordofanian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('niu', oils_i18n_gettext('Niuean')); +INSERT INTO config.language_map (code, value) VALUES ('nno', oils_i18n_gettext('Norwegian (Nynorsk)')); +INSERT INTO config.language_map (code, value) VALUES ('nob', oils_i18n_gettext('Norwegian (Bokmål)')); +INSERT INTO config.language_map (code, value) VALUES ('nog', oils_i18n_gettext('Nogai')); +INSERT INTO config.language_map (code, value) VALUES ('non', oils_i18n_gettext('Old Norse')); +INSERT INTO config.language_map (code, value) VALUES ('nor', oils_i18n_gettext('Norwegian')); +INSERT INTO config.language_map (code, value) VALUES ('nso', oils_i18n_gettext('Northern Sotho')); +INSERT INTO config.language_map (code, value) VALUES ('nub', oils_i18n_gettext('Nubian languages')); +INSERT INTO config.language_map (code, value) VALUES ('nya', oils_i18n_gettext('Nyanja')); +INSERT INTO config.language_map (code, value) VALUES ('nym', oils_i18n_gettext('Nyamwezi')); +INSERT INTO config.language_map (code, value) VALUES ('nyn', oils_i18n_gettext('Nyankole')); +INSERT INTO config.language_map (code, value) VALUES ('nyo', oils_i18n_gettext('Nyoro')); +INSERT INTO config.language_map (code, value) VALUES ('nzi', oils_i18n_gettext('Nzima')); +INSERT INTO config.language_map (code, value) VALUES ('oci', oils_i18n_gettext('Occitan (post-1500)')); +INSERT INTO config.language_map (code, value) VALUES ('oji', oils_i18n_gettext('Ojibwa')); +INSERT INTO config.language_map (code, value) VALUES ('ori', oils_i18n_gettext('Oriya')); +INSERT INTO config.language_map (code, value) VALUES ('orm', oils_i18n_gettext('Oromo')); +INSERT INTO config.language_map (code, value) VALUES ('osa', oils_i18n_gettext('Osage')); +INSERT INTO config.language_map (code, value) VALUES ('oss', oils_i18n_gettext('Ossetic')); +INSERT INTO config.language_map (code, value) VALUES ('ota', oils_i18n_gettext('Turkish, Ottoman')); +INSERT INTO config.language_map (code, value) VALUES ('oto', oils_i18n_gettext('Otomian languages')); +INSERT INTO config.language_map (code, value) VALUES ('paa', oils_i18n_gettext('Papuan (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('pag', oils_i18n_gettext('Pangasinan')); +INSERT INTO config.language_map (code, value) VALUES ('pal', oils_i18n_gettext('Pahlavi')); +INSERT INTO config.language_map (code, value) VALUES ('pam', oils_i18n_gettext('Pampanga')); +INSERT INTO config.language_map (code, value) VALUES ('pan', oils_i18n_gettext('Panjabi')); +INSERT INTO config.language_map (code, value) VALUES ('pap', oils_i18n_gettext('Papiamento')); +INSERT INTO config.language_map (code, value) VALUES ('pau', oils_i18n_gettext('Palauan')); +INSERT INTO config.language_map (code, value) VALUES ('peo', oils_i18n_gettext('Old Persian (ca. 600-400 B.C.)')); +INSERT INTO config.language_map (code, value) VALUES ('per', oils_i18n_gettext('Persian')); +INSERT INTO config.language_map (code, value) VALUES ('phi', oils_i18n_gettext('Philippine (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('phn', oils_i18n_gettext('Phoenician')); +INSERT INTO config.language_map (code, value) VALUES ('pli', oils_i18n_gettext('Pali')); +INSERT INTO config.language_map (code, value) VALUES ('pol', oils_i18n_gettext('Polish')); +INSERT INTO config.language_map (code, value) VALUES ('pon', oils_i18n_gettext('Ponape')); +INSERT INTO config.language_map (code, value) VALUES ('por', oils_i18n_gettext('Portuguese')); +INSERT INTO config.language_map (code, value) VALUES ('pra', oils_i18n_gettext('Prakrit languages')); +INSERT INTO config.language_map (code, value) VALUES ('pro', oils_i18n_gettext('Provençal (to 1500)')); +INSERT INTO config.language_map (code, value) VALUES ('pus', oils_i18n_gettext('Pushto')); +INSERT INTO config.language_map (code, value) VALUES ('que', oils_i18n_gettext('Quechua')); +INSERT INTO config.language_map (code, value) VALUES ('raj', oils_i18n_gettext('Rajasthani')); +INSERT INTO config.language_map (code, value) VALUES ('rap', oils_i18n_gettext('Rapanui')); +INSERT INTO config.language_map (code, value) VALUES ('rar', oils_i18n_gettext('Rarotongan')); +INSERT INTO config.language_map (code, value) VALUES ('roa', oils_i18n_gettext('Romance (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('roh', oils_i18n_gettext('Raeto-Romance')); +INSERT INTO config.language_map (code, value) VALUES ('rom', oils_i18n_gettext('Romani')); +INSERT INTO config.language_map (code, value) VALUES ('rum', oils_i18n_gettext('Romanian')); +INSERT INTO config.language_map (code, value) VALUES ('run', oils_i18n_gettext('Rundi')); +INSERT INTO config.language_map (code, value) VALUES ('rus', oils_i18n_gettext('Russian')); +INSERT INTO config.language_map (code, value) VALUES ('sad', oils_i18n_gettext('Sandawe')); +INSERT INTO config.language_map (code, value) VALUES ('sag', oils_i18n_gettext('Sango (Ubangi Creole)')); +INSERT INTO config.language_map (code, value) VALUES ('sah', oils_i18n_gettext('Yakut')); +INSERT INTO config.language_map (code, value) VALUES ('sai', oils_i18n_gettext('South American Indian (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('sal', oils_i18n_gettext('Salishan languages')); +INSERT INTO config.language_map (code, value) VALUES ('sam', oils_i18n_gettext('Samaritan Aramaic')); +INSERT INTO config.language_map (code, value) VALUES ('san', oils_i18n_gettext('Sanskrit')); +INSERT INTO config.language_map (code, value) VALUES ('-sao', oils_i18n_gettext('Samoan')); +INSERT INTO config.language_map (code, value) VALUES ('sas', oils_i18n_gettext('Sasak')); +INSERT INTO config.language_map (code, value) VALUES ('sat', oils_i18n_gettext('Santali')); +INSERT INTO config.language_map (code, value) VALUES ('scc', oils_i18n_gettext('Serbian')); +INSERT INTO config.language_map (code, value) VALUES ('sco', oils_i18n_gettext('Scots')); +INSERT INTO config.language_map (code, value) VALUES ('scr', oils_i18n_gettext('Croatian')); +INSERT INTO config.language_map (code, value) VALUES ('sel', oils_i18n_gettext('Selkup')); +INSERT INTO config.language_map (code, value) VALUES ('sem', oils_i18n_gettext('Semitic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('sga', oils_i18n_gettext('Irish, Old (to 1100)')); +INSERT INTO config.language_map (code, value) VALUES ('sgn', oils_i18n_gettext('Sign languages')); +INSERT INTO config.language_map (code, value) VALUES ('shn', oils_i18n_gettext('Shan')); +INSERT INTO config.language_map (code, value) VALUES ('-sho', oils_i18n_gettext('Shona')); +INSERT INTO config.language_map (code, value) VALUES ('sid', oils_i18n_gettext('Sidamo')); +INSERT INTO config.language_map (code, value) VALUES ('sin', oils_i18n_gettext('Sinhalese')); +INSERT INTO config.language_map (code, value) VALUES ('sio', oils_i18n_gettext('Siouan (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('sit', oils_i18n_gettext('Sino-Tibetan (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('sla', oils_i18n_gettext('Slavic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('slo', oils_i18n_gettext('Slovak')); +INSERT INTO config.language_map (code, value) VALUES ('slv', oils_i18n_gettext('Slovenian')); +INSERT INTO config.language_map (code, value) VALUES ('sma', oils_i18n_gettext('Southern Sami')); +INSERT INTO config.language_map (code, value) VALUES ('sme', oils_i18n_gettext('Northern Sami')); +INSERT INTO config.language_map (code, value) VALUES ('smi', oils_i18n_gettext('Sami')); +INSERT INTO config.language_map (code, value) VALUES ('smj', oils_i18n_gettext('Lule Sami')); +INSERT INTO config.language_map (code, value) VALUES ('smn', oils_i18n_gettext('Inari Sami')); +INSERT INTO config.language_map (code, value) VALUES ('smo', oils_i18n_gettext('Samoan')); +INSERT INTO config.language_map (code, value) VALUES ('sms', oils_i18n_gettext('Skolt Sami')); +INSERT INTO config.language_map (code, value) VALUES ('sna', oils_i18n_gettext('Shona')); +INSERT INTO config.language_map (code, value) VALUES ('snd', oils_i18n_gettext('Sindhi')); +INSERT INTO config.language_map (code, value) VALUES ('-snh', oils_i18n_gettext('Sinhalese')); +INSERT INTO config.language_map (code, value) VALUES ('snk', oils_i18n_gettext('Soninke')); +INSERT INTO config.language_map (code, value) VALUES ('sog', oils_i18n_gettext('Sogdian')); +INSERT INTO config.language_map (code, value) VALUES ('som', oils_i18n_gettext('Somali')); +INSERT INTO config.language_map (code, value) VALUES ('son', oils_i18n_gettext('Songhai')); +INSERT INTO config.language_map (code, value) VALUES ('sot', oils_i18n_gettext('Sotho')); +INSERT INTO config.language_map (code, value) VALUES ('spa', oils_i18n_gettext('Spanish')); +INSERT INTO config.language_map (code, value) VALUES ('srd', oils_i18n_gettext('Sardinian')); +INSERT INTO config.language_map (code, value) VALUES ('srr', oils_i18n_gettext('Serer')); +INSERT INTO config.language_map (code, value) VALUES ('ssa', oils_i18n_gettext('Nilo-Saharan (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('-sso', oils_i18n_gettext('Sotho')); +INSERT INTO config.language_map (code, value) VALUES ('ssw', oils_i18n_gettext('Swazi')); +INSERT INTO config.language_map (code, value) VALUES ('suk', oils_i18n_gettext('Sukuma')); +INSERT INTO config.language_map (code, value) VALUES ('sun', oils_i18n_gettext('Sundanese')); +INSERT INTO config.language_map (code, value) VALUES ('sus', oils_i18n_gettext('Susu')); +INSERT INTO config.language_map (code, value) VALUES ('sux', oils_i18n_gettext('Sumerian')); +INSERT INTO config.language_map (code, value) VALUES ('swa', oils_i18n_gettext('Swahili')); +INSERT INTO config.language_map (code, value) VALUES ('swe', oils_i18n_gettext('Swedish')); +INSERT INTO config.language_map (code, value) VALUES ('-swz', oils_i18n_gettext('Swazi')); +INSERT INTO config.language_map (code, value) VALUES ('syr', oils_i18n_gettext('Syriac')); +INSERT INTO config.language_map (code, value) VALUES ('-tag', oils_i18n_gettext('Tagalog')); +INSERT INTO config.language_map (code, value) VALUES ('tah', oils_i18n_gettext('Tahitian')); +INSERT INTO config.language_map (code, value) VALUES ('tai', oils_i18n_gettext('Tai (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('-taj', oils_i18n_gettext('Tajik')); +INSERT INTO config.language_map (code, value) VALUES ('tam', oils_i18n_gettext('Tamil')); +INSERT INTO config.language_map (code, value) VALUES ('-tar', oils_i18n_gettext('Tatar')); +INSERT INTO config.language_map (code, value) VALUES ('tat', oils_i18n_gettext('Tatar')); +INSERT INTO config.language_map (code, value) VALUES ('tel', oils_i18n_gettext('Telugu')); +INSERT INTO config.language_map (code, value) VALUES ('tem', oils_i18n_gettext('Temne')); +INSERT INTO config.language_map (code, value) VALUES ('ter', oils_i18n_gettext('Terena')); +INSERT INTO config.language_map (code, value) VALUES ('tet', oils_i18n_gettext('Tetum')); +INSERT INTO config.language_map (code, value) VALUES ('tgk', oils_i18n_gettext('Tajik')); +INSERT INTO config.language_map (code, value) VALUES ('tgl', oils_i18n_gettext('Tagalog')); +INSERT INTO config.language_map (code, value) VALUES ('tha', oils_i18n_gettext('Thai')); +INSERT INTO config.language_map (code, value) VALUES ('tib', oils_i18n_gettext('Tibetan')); +INSERT INTO config.language_map (code, value) VALUES ('tig', oils_i18n_gettext('Tigré')); +INSERT INTO config.language_map (code, value) VALUES ('tir', oils_i18n_gettext('Tigrinya')); +INSERT INTO config.language_map (code, value) VALUES ('tiv', oils_i18n_gettext('Tiv')); +INSERT INTO config.language_map (code, value) VALUES ('tkl', oils_i18n_gettext('Tokelauan')); +INSERT INTO config.language_map (code, value) VALUES ('tli', oils_i18n_gettext('Tlingit')); +INSERT INTO config.language_map (code, value) VALUES ('tmh', oils_i18n_gettext('Tamashek')); +INSERT INTO config.language_map (code, value) VALUES ('tog', oils_i18n_gettext('Tonga (Nyasa)')); +INSERT INTO config.language_map (code, value) VALUES ('ton', oils_i18n_gettext('Tongan')); +INSERT INTO config.language_map (code, value) VALUES ('tpi', oils_i18n_gettext('Tok Pisin')); +INSERT INTO config.language_map (code, value) VALUES ('-tru', oils_i18n_gettext('Truk')); +INSERT INTO config.language_map (code, value) VALUES ('tsi', oils_i18n_gettext('Tsimshian')); +INSERT INTO config.language_map (code, value) VALUES ('tsn', oils_i18n_gettext('Tswana')); +INSERT INTO config.language_map (code, value) VALUES ('tso', oils_i18n_gettext('Tsonga')); +INSERT INTO config.language_map (code, value) VALUES ('-tsw', oils_i18n_gettext('Tswana')); +INSERT INTO config.language_map (code, value) VALUES ('tuk', oils_i18n_gettext('Turkmen')); +INSERT INTO config.language_map (code, value) VALUES ('tum', oils_i18n_gettext('Tumbuka')); +INSERT INTO config.language_map (code, value) VALUES ('tup', oils_i18n_gettext('Tupi languages')); +INSERT INTO config.language_map (code, value) VALUES ('tur', oils_i18n_gettext('Turkish')); +INSERT INTO config.language_map (code, value) VALUES ('tut', oils_i18n_gettext('Altaic (Other)')); +INSERT INTO config.language_map (code, value) VALUES ('tvl', oils_i18n_gettext('Tuvaluan')); +INSERT INTO config.language_map (code, value) VALUES ('twi', oils_i18n_gettext('Twi')); +INSERT INTO config.language_map (code, value) VALUES ('tyv', oils_i18n_gettext('Tuvinian')); +INSERT INTO config.language_map (code, value) VALUES ('udm', oils_i18n_gettext('Udmurt')); +INSERT INTO config.language_map (code, value) VALUES ('uga', oils_i18n_gettext('Ugaritic')); +INSERT INTO config.language_map (code, value) VALUES ('uig', oils_i18n_gettext('Uighur')); +INSERT INTO config.language_map (code, value) VALUES ('ukr', oils_i18n_gettext('Ukrainian')); +INSERT INTO config.language_map (code, value) VALUES ('umb', oils_i18n_gettext('Umbundu')); +INSERT INTO config.language_map (code, value) VALUES ('und', oils_i18n_gettext('Undetermined')); +INSERT INTO config.language_map (code, value) VALUES ('urd', oils_i18n_gettext('Urdu')); +INSERT INTO config.language_map (code, value) VALUES ('uzb', oils_i18n_gettext('Uzbek')); +INSERT INTO config.language_map (code, value) VALUES ('vai', oils_i18n_gettext('Vai')); +INSERT INTO config.language_map (code, value) VALUES ('ven', oils_i18n_gettext('Venda')); +INSERT INTO config.language_map (code, value) VALUES ('vie', oils_i18n_gettext('Vietnamese')); +INSERT INTO config.language_map (code, value) VALUES ('vol', oils_i18n_gettext('Volapük')); +INSERT INTO config.language_map (code, value) VALUES ('vot', oils_i18n_gettext('Votic')); +INSERT INTO config.language_map (code, value) VALUES ('wak', oils_i18n_gettext('Wakashan languages')); +INSERT INTO config.language_map (code, value) VALUES ('wal', oils_i18n_gettext('Walamo')); +INSERT INTO config.language_map (code, value) VALUES ('war', oils_i18n_gettext('Waray')); +INSERT INTO config.language_map (code, value) VALUES ('was', oils_i18n_gettext('Washo')); +INSERT INTO config.language_map (code, value) VALUES ('wel', oils_i18n_gettext('Welsh')); +INSERT INTO config.language_map (code, value) VALUES ('wen', oils_i18n_gettext('Sorbian languages')); +INSERT INTO config.language_map (code, value) VALUES ('wln', oils_i18n_gettext('Walloon')); +INSERT INTO config.language_map (code, value) VALUES ('wol', oils_i18n_gettext('Wolof')); +INSERT INTO config.language_map (code, value) VALUES ('xal', oils_i18n_gettext('Kalmyk')); +INSERT INTO config.language_map (code, value) VALUES ('xho', oils_i18n_gettext('Xhosa')); +INSERT INTO config.language_map (code, value) VALUES ('yao', oils_i18n_gettext('Yao (Africa)')); +INSERT INTO config.language_map (code, value) VALUES ('yap', oils_i18n_gettext('Yapese')); +INSERT INTO config.language_map (code, value) VALUES ('yid', oils_i18n_gettext('Yiddish')); +INSERT INTO config.language_map (code, value) VALUES ('yor', oils_i18n_gettext('Yoruba')); +INSERT INTO config.language_map (code, value) VALUES ('ypk', oils_i18n_gettext('Yupik languages')); +INSERT INTO config.language_map (code, value) VALUES ('zap', oils_i18n_gettext('Zapotec')); +INSERT INTO config.language_map (code, value) VALUES ('zen', oils_i18n_gettext('Zenaga')); +INSERT INTO config.language_map (code, value) VALUES ('zha', oils_i18n_gettext('Zhuang')); +INSERT INTO config.language_map (code, value) VALUES ('znd', oils_i18n_gettext('Zande')); +INSERT INTO config.language_map (code, value) VALUES ('zul', oils_i18n_gettext('Zulu')); +INSERT INTO config.language_map (code, value) VALUES ('zun', oils_i18n_gettext('Zuni')); + +INSERT INTO config.item_form_map (code, value) VALUES ('a', oils_i18n_gettext('Microfilm')); +INSERT INTO config.item_form_map (code, value) VALUES ('b', oils_i18n_gettext('Microfiche')); +INSERT INTO config.item_form_map (code, value) VALUES ('c', oils_i18n_gettext('Microopaque')); +INSERT INTO config.item_form_map (code, value) VALUES ('d', oils_i18n_gettext('Large print')); +INSERT INTO config.item_form_map (code, value) VALUES ('f', oils_i18n_gettext('Braille')); +INSERT INTO config.item_form_map (code, value) VALUES ('r', oils_i18n_gettext('Regular print reproduction')); +INSERT INTO config.item_form_map (code, value) VALUES ('s', oils_i18n_gettext('Electronic')); + +INSERT INTO config.item_type_map (code, value) VALUES ('a', oils_i18n_gettext('Language material')); +INSERT INTO config.item_type_map (code, value) VALUES ('t', oils_i18n_gettext('Manuscript language material')); +INSERT INTO config.item_type_map (code, value) VALUES ('g', oils_i18n_gettext('Projected medium')); +INSERT INTO config.item_type_map (code, value) VALUES ('k', oils_i18n_gettext('Two-dimensional nonprojectable graphic')); +INSERT INTO config.item_type_map (code, value) VALUES ('r', oils_i18n_gettext('Three-dimensional artifact or naturally occurring object')); +INSERT INTO config.item_type_map (code, value) VALUES ('o', oils_i18n_gettext('Kit')); +INSERT INTO config.item_type_map (code, value) VALUES ('p', oils_i18n_gettext('Mixed materials')); +INSERT INTO config.item_type_map (code, value) VALUES ('e', oils_i18n_gettext('Cartographic material')); +INSERT INTO config.item_type_map (code, value) VALUES ('f', oils_i18n_gettext('Manuscript cartographic material')); +INSERT INTO config.item_type_map (code, value) VALUES ('c', oils_i18n_gettext('Notated music')); +INSERT INTO config.item_type_map (code, value) VALUES ('d', oils_i18n_gettext('Manuscript notated music')); +INSERT INTO config.item_type_map (code, value) VALUES ('i', oils_i18n_gettext('Nonmusical sound recording')); +INSERT INTO config.item_type_map (code, value) VALUES ('j', oils_i18n_gettext('Musical sound recording')); +INSERT INTO config.item_type_map (code, value) VALUES ('m', oils_i18n_gettext('Computer file')); + +INSERT INTO config.bib_level_map (code, value) VALUES ('a', oils_i18n_gettext('Monographic component part')); +INSERT INTO config.bib_level_map (code, value) VALUES ('b', oils_i18n_gettext('Serial component part')); +INSERT INTO config.bib_level_map (code, value) VALUES ('c', oils_i18n_gettext('Collection')); +INSERT INTO config.bib_level_map (code, value) VALUES ('d', oils_i18n_gettext('Subunit')); +INSERT INTO config.bib_level_map (code, value) VALUES ('i', oils_i18n_gettext('Integrating resource')); +INSERT INTO config.bib_level_map (code, value) VALUES ('m', oils_i18n_gettext('Monograph/Item')); +INSERT INTO config.bib_level_map (code, value) VALUES ('s', oils_i18n_gettext('Serial')); --005.schema.actors.sql: -- The PINES levels INSERT INTO actor.org_unit_type (name, opac_label, depth, parent, can_have_users, can_have_vols) VALUES - ( oils_i18n_gettext('Consortium'),oils_i18n_gettext('Everywhere'), 0, NULL, FALSE, FALSE ), + ( oils_i18n_gettext('Consortium'),oils_i18n_gettext('Everywhere'), 0, NULL, FALSE, FALSE ); +INSERT INTO actor.org_unit_type (name, opac_label, depth, parent, can_have_users, can_have_vols) VALUES ( oils_i18n_gettext('System'),oils_i18n_gettext('Local Library System'), 1, 1, FALSE, FALSE ); INSERT INTO actor.org_unit_type (name, opac_label, depth, parent) VALUES - ( oils_i18n_gettext('Branch'),oils_i18n_gettext('This Branch'), 2, 2 ), - ( oils_i18n_gettext('Sub-lib'),oils_i18n_gettext('This Specialized Library'), 3, 3 ), + ( oils_i18n_gettext('Branch'),oils_i18n_gettext('This Branch'), 2, 2 ); +INSERT INTO actor.org_unit_type (name, opac_label, depth, parent) VALUES + ( oils_i18n_gettext('Sub-lib'),oils_i18n_gettext('This Specialized Library'), 3, 3 ); +INSERT INTO actor.org_unit_type (name, opac_label, depth, parent) VALUES ( oils_i18n_gettext('Bookmobile'),oils_i18n_gettext('Your Bookmobile'), 3, 3 ); INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES - (NULL, 1, 'CONS', oils_i18n_gettext('Example Consortium')), - (1, 2, 'SYS1', oils_i18n_gettext('Example System 1')), - (1, 2, 'SYS2', oils_i18n_gettext('Example System 2')), - (2, 3, 'BR1', oils_i18n_gettext('Example Branch 1')), - (2, 3, 'BR2', oils_i18n_gettext('Example Branch 2')), - (3, 3, 'BR3', oils_i18n_gettext('Example Branch 3')), - (3, 3, 'BR4', oils_i18n_gettext('Example Branch 4')), - (4, 4, 'SL1', oils_i18n_gettext('Example Sub-lib 1')), + (NULL, 1, 'CONS', oils_i18n_gettext('Example Consortium')); +INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES + (1, 2, 'SYS1', oils_i18n_gettext('Example System 1')); +INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES + (1, 2, 'SYS2', oils_i18n_gettext('Example System 2')); +INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES + (2, 3, 'BR1', oils_i18n_gettext('Example Branch 1')); +INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES + (2, 3, 'BR2', oils_i18n_gettext('Example Branch 2')); +INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES + (3, 3, 'BR3', oils_i18n_gettext('Example Branch 3')); +INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES + (3, 3, 'BR4', oils_i18n_gettext('Example Branch 4')); +INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES + (4, 4, 'SL1', oils_i18n_gettext('Example Sub-lib 1')); +INSERT INTO actor.org_unit (parent_ou, ou_type, shortname, name) VALUES (6, 5, 'BM1', oils_i18n_gettext('Example Bookmobile 1')); INSERT INTO actor.org_address VALUES (DEFAULT,DEFAULT,DEFAULT,1,oils_i18n_gettext('123 Main St.'),NULL,oils_i18n_gettext('Anywhere'),NULL,oils_i18n_gettext('GA'),oils_i18n_gettext('US'),oils_i18n_gettext('30303')); UPDATE actor.org_unit SET holds_address = 1, ill_address = 1, billing_address = 1, mailing_address = 1; --- Just so that there is a user... -INSERT INTO actor.usr ( profile, card, usrname, passwd, first_given_name, family_name, dob, master_account, super_user, ident_type, ident_value, home_ou ) VALUES ( 1, 1, 'admin', 'open-ils', oils_i18n_gettext('Administrator'), oils_i18n_gettext('System Account'), '1979-01-22', TRUE, TRUE, 1, 'identification', 1 ); - -INSERT INTO actor.card (usr, barcode) VALUES (1,'101010101010101'); - - --006.data.permissions.sql: INSERT INTO permission.perm_list VALUES - (-1, 'EVERYTHING', NULL), - (2, 'OPAC_LOGIN', NULL), - (4, 'STAFF_LOGIN', NULL), - (5, 'MR_HOLDS', NULL), - (6, 'TITLE_HOLDS', NULL), - (7, 'VOLUME_HOLDS', NULL), - (8, 'COPY_HOLDS', oils_i18n_gettext('User is allowed to place a hold on a specific copy')), - (9, 'REQUEST_HOLDS', NULL), - (10, 'REQUEST_HOLDS_OVERRIDE', NULL), - (11, 'VIEW_HOLD', oils_i18n_gettext('Allows a user to view another user''s holds')), - (13, 'DELETE_HOLDS', NULL), - (14, 'UPDATE_HOLD', oils_i18n_gettext('Allows a user to update another user''s hold')), - (15, 'RENEW_CIRC', NULL), - (16, 'VIEW_USER_FINES_SUMMARY', NULL), - (17, 'VIEW_USER_TRANSACTIONS', NULL), - (18, 'UPDATE_MARC', NULL), - (19, 'CREATE_MARC', oils_i18n_gettext('User is allowed to create new MARC records')), - (20, 'IMPORT_MARC', NULL), - (21, 'CREATE_VOLUME', NULL), - (22, 'UPDATE_VOLUME', NULL), - (23, 'DELETE_VOLUME', NULL), - (25, 'UPDATE_COPY', NULL), - (26, 'DELETE_COPY', NULL), - (27, 'RENEW_HOLD_OVERRIDE', NULL), - (28, 'CREATE_USER', NULL), - (29, 'UPDATE_USER', NULL), - (30, 'DELETE_USER', NULL), - (31, 'VIEW_USER', NULL), - (32, 'COPY_CHECKIN', NULL), - (33, 'CREATE_TRANSIT', NULL), - (34, 'VIEW_PERMISSION', NULL), - (35, 'CHECKIN_BYPASS_HOLD_FULFILL', NULL), - (36, 'CREATE_PAYMENT', NULL), - (37, 'SET_CIRC_LOST', NULL), - (38, 'SET_CIRC_MISSING', NULL), - (39, 'SET_CIRC_CLAIMS_RETURNED', NULL), - (41, 'CREATE_TRANSACTION', oils_i18n_gettext('User may create new billable transactions')), - (43, 'CREATE_BILL', oils_i18n_gettext('Allows a user to create a new bill on a transaction')), - (44, 'VIEW_CONTAINER', oils_i18n_gettext('Allows a user to view another user''s containers (buckets)')), - (45, 'CREATE_CONTAINER', oils_i18n_gettext('Allows a user to create a new container for another user')), - (24, 'CREATE_COPY', oils_i18n_gettext('User is allowed to create a new copy object')), - (47, 'UPDATE_ORG_UNIT', oils_i18n_gettext('Allows a user to change org unit settings')), - (48, 'VIEW_CIRCULATIONS', oils_i18n_gettext('Allows a user to see what another use has checked out')), - (42, 'VIEW_TRANSACTION', oils_i18n_gettext('User may view another user''s transactions')), - (49, 'DELETE_CONTAINER', oils_i18n_gettext('Allows a user to delete another user container')), - (50, 'CREATE_CONTAINER_ITEM', oils_i18n_gettext('Create a container item for another user')), - (51, 'CREATE_USER_GROUP_LINK', oils_i18n_gettext('User can add other users to permission groups')), - (52, 'REMOVE_USER_GROUP_LINK', oils_i18n_gettext('User can remove other users from permission groups')), - (53, 'VIEW_PERM_GROUPS', oils_i18n_gettext('Allow user to view others'' permission groups')), - (54, 'VIEW_PERMIT_CHECKOUT', oils_i18n_gettext('Allows a user to determine of another user can checkout an item')), - (55, 'UPDATE_BATCH_COPY', oils_i18n_gettext('Allows a user to edit copies in batch')), - (56, 'CREATE_PATRON_STAT_CAT', oils_i18n_gettext('User may create a new patron statistical category')), - (57, 'CREATE_COPY_STAT_CAT', oils_i18n_gettext('User may create a copy stat cat')), - (58, 'CREATE_PATRON_STAT_CAT_ENTRY', oils_i18n_gettext('User may create a new patron stat cat entry')), - (59, 'CREATE_COPY_STAT_CAT_ENTRY', oils_i18n_gettext('User may create a new copy stat cat entry')), - (60, 'UPDATE_PATRON_STAT_CAT', oils_i18n_gettext('User may update a patron stat cat')), - (61, 'UPDATE_COPY_STAT_CAT', oils_i18n_gettext('User may update a copy stat cat')), - (62, 'UPDATE_PATRON_STAT_CAT_ENTRY', oils_i18n_gettext('User may update a patron stat cat entry')), - (63, 'UPDATE_COPY_STAT_CAT_ENTRY', oils_i18n_gettext('User may update a copy stat cat entry')), - (65, 'CREATE_COPY_STAT_CAT_ENTRY_MAP', oils_i18n_gettext('User may link a copy to a stat cat entry')), - (64, 'CREATE_PATRON_STAT_CAT_ENTRY_MAP', oils_i18n_gettext('User may link another user to a stat cat entry')), - (66, 'DELETE_PATRON_STAT_CAT', oils_i18n_gettext('User may delete a patron stat cat')), - (67, 'DELETE_COPY_STAT_CAT', oils_i18n_gettext('User may delete a copy stat cat')), - (68, 'DELETE_PATRON_STAT_CAT_ENTRY', oils_i18n_gettext('User may delete a patron stat cat entry')), - (69, 'DELETE_COPY_STAT_CAT_ENTRY', oils_i18n_gettext('User may delete a copy stat cat entry')), - (70, 'DELETE_PATRON_STAT_CAT_ENTRY_MAP', oils_i18n_gettext('User may delete a patron stat cat entry map')), - (71, 'DELETE_COPY_STAT_CAT_ENTRY_MAP', oils_i18n_gettext('User may delete a copy stat cat entry map')), - (72, 'CREATE_NON_CAT_TYPE', oils_i18n_gettext('Allows a user to create a new non-cataloged item type')), - (73, 'UPDATE_NON_CAT_TYPE', oils_i18n_gettext('Allows a user to update a non cataloged type')), - (74, 'CREATE_IN_HOUSE_USE', oils_i18n_gettext('Allows a user to create a new in-house-use ')), - (75, 'COPY_CHECKOUT', oils_i18n_gettext('Allows a user to check out a copy')), - (76, 'CREATE_COPY_LOCATION', oils_i18n_gettext('Allows a user to create a new copy location')), - (77, 'UPDATE_COPY_LOCATION', oils_i18n_gettext('Allows a user to update a copy location')), - (78, 'DELETE_COPY_LOCATION', oils_i18n_gettext('Allows a user to delete a copy location')), - (79, 'CREATE_COPY_TRANSIT', oils_i18n_gettext('Allows a user to create a transit_copy object for transiting a copy')), - (80, 'COPY_TRANSIT_RECEIVE', oils_i18n_gettext('Allows a user to close out a transit on a copy')), - (81, 'VIEW_HOLD_PERMIT', oils_i18n_gettext('Allows a user to see if another user has permission to place a hold on a given copy')), - (82, 'VIEW_COPY_CHECKOUT_HISTORY', oils_i18n_gettext('Allows a user to view which users have checked out a given copy')), - (83, 'REMOTE_Z3950_QUERY', oils_i18n_gettext('Allows a user to perform z3950 queries against remote servers')), - (84, 'REGISTER_WORKSTATION', oils_i18n_gettext('Allows a user to register a new workstation')), - (85, 'VIEW_COPY_NOTES', oils_i18n_gettext('Allows a user to view all notes attached to a copy')), - (86, 'VIEW_VOLUME_NOTES', oils_i18n_gettext('Allows a user to view all notes attached to a volume')), - (87, 'VIEW_TITLE_NOTES', oils_i18n_gettext('Allows a user to view all notes attached to a title')), - (89, 'CREATE_VOLUME_NOTE', oils_i18n_gettext('Allows a user to create a new volume note')), - (88, 'CREATE_COPY_NOTE', oils_i18n_gettext('Allows a user to create a new copy note')), - (90, 'CREATE_TITLE_NOTE', oils_i18n_gettext('Allows a user to create a new title note')), - (91, 'DELETE_COPY_NOTE', oils_i18n_gettext('Allows a user to delete someone elses copy notes')), - (92, 'DELETE_VOLUME_NOTE', oils_i18n_gettext('Allows a user to delete someone elses volume note')), - (93, 'DELETE_TITLE_NOTE', oils_i18n_gettext('Allows a user to delete someone elses title note')), - (94, 'UPDATE_CONTAINER', oils_i18n_gettext('Allows a user to update another users container')), - (95, 'CREATE_MY_CONTAINER', oils_i18n_gettext('Allows a user to create a container for themselves')), - (96, 'VIEW_HOLD_NOTIFICATION', oils_i18n_gettext('Allows a user to view notifications attached to a hold')), - (97, 'CREATE_HOLD_NOTIFICATION', oils_i18n_gettext('Allows a user to create new hold notifications')), - (98, 'UPDATE_ORG_SETTING', oils_i18n_gettext('Allows a user to update an org unit setting')), - (99, 'OFFLINE_UPLOAD', oils_i18n_gettext('Allows a user to upload an offline script')), - (100, 'OFFLINE_VIEW', oils_i18n_gettext('Allows a user to view uploaded offline script information')), - (101, 'OFFLINE_EXECUTE', oils_i18n_gettext('Allows a user to execute an offline script batch')), - (102, 'CIRC_OVERRIDE_DUE_DATE', oils_i18n_gettext('Allows a user to change set the due date on an item to any date')), - (103, 'CIRC_PERMIT_OVERRIDE', oils_i18n_gettext('Allows a user to bypass the circ permit call for checkout')), - (104, 'COPY_IS_REFERENCE.override', oils_i18n_gettext('Allows a user to override the copy_is_reference event')), - (105, 'VOID_BILLING', oils_i18n_gettext('Allows a user to void a bill')), - (106, 'CIRC_CLAIMS_RETURNED.override', oils_i18n_gettext('Allows a person to check in/out an item that is claims returned')), - (107, 'COPY_BAD_STATUS.override', oils_i18n_gettext('Allows a user to check out an item in a non-circulatable status')), - (108, 'COPY_ALERT_MESSAGE.override', oils_i18n_gettext('Allows a user to check in/out an item that has an alert message')), - (109, 'COPY_STATUS_LOST.override', oils_i18n_gettext('Allows a user to remove the lost status from a copy')), - (110, 'COPY_STATUS_MISSING.override', oils_i18n_gettext('Allows a user to change the missing status on a copy')), - (111, 'ABORT_TRANSIT', oils_i18n_gettext('Allows a user to abort a copy transit if the user is at the transit destination or source')), - (112, 'ABORT_REMOTE_TRANIST', oils_i18n_gettext('Allows a user to abort a copy transit if the user is not at the transit source or dest')), - (113, 'VIEW_ZIP_DATA', oils_i18n_gettext('Allowsa user to query the zip code data method')), - (114, 'CANCEL_HOLDS', oils_i18n_gettext('')), - (115, 'CREATE_DUPLICATE_HOLDS', oils_i18n_gettext('Allows a user to create duplicate holds (e.g. two holds on the same title)')), - (117, 'actor.org_unit.closed_date.update', oils_i18n_gettext('Allows a user to update a closed date interval for a given location')), - (116, 'actor.org_unit.closed_date.delete', oils_i18n_gettext('Allows a user to remove a closed date interval for a given location')), - (118, 'actor.org_unit.closed_date.create', oils_i18n_gettext('Allows a user to create a new closed date for a location')), - (119, 'DELETE_NON_CAT_TYPE', oils_i18n_gettext('Allows a user to delete a non cataloged type')), - (120, 'money.collections_tracker.create', oils_i18n_gettext('Allows a user to put someone into collections')), - (121, 'money.collections_tracker.delete', oils_i18n_gettext('Allows a user to remove someone from collections')), - (122, 'BAR_PATRON', oils_i18n_gettext('Allows a user to bar a patron')), - (123, 'UNBAR_PATRON', oils_i18n_gettext('Allows a user to un-bar a patron')), - (124, 'DELETE_WORKSTATION', oils_i18n_gettext('Allows a user to remove an existing workstation so a new one can replace it')), - (125, 'group_application.user', oils_i18n_gettext('Allows a user to add/remove users to/from the "User" group')), - (126, 'group_application.user.patron', oils_i18n_gettext('Allows a user to add/remove users to/from the "Patron" group')), - (127, 'group_application.user.staff', oils_i18n_gettext('Allows a user to add/remove users to/from the "Staff" group')), - (128, 'group_application.user.staff.circ', oils_i18n_gettext('Allows a user to add/remove users to/from the "Circulator" group')), - (129, 'group_application.user.staff.cat', oils_i18n_gettext('Allows a user to add/remove users to/from the "Cataloger" group')), - (130, 'group_application.user.staff.admin.global_admin', oils_i18n_gettext('Allows a user to add/remove users to/from the "GlobalAdmin" group')), - (131, 'group_application.user.staff.admin.local_admin', oils_i18n_gettext('Allows a user to add/remove users to/from the "LocalAdmin" group')), - (132, 'group_application.user.staff.admin.lib_manager', oils_i18n_gettext('Allows a user to add/remove users to/from the "LibraryManager" group')), - (133, 'group_application.user.staff.cat.cat1', oils_i18n_gettext('Allows a user to add/remove users to/from the "Cat1" group')), - (134, 'group_application.user.staff.supercat', oils_i18n_gettext('Allows a user to add/remove users to/from the "Supercat" group')), - (135, 'group_application.user.sip_client', oils_i18n_gettext('Allows a user to add/remove users to/from the "SIP-Client" group')), - (136, 'group_application.user.vendor', oils_i18n_gettext('Allows a user to add/remove users to/from the "Vendor" group')), - (137, 'ITEM_AGE_PROTECTED.override', oils_i18n_gettext('Allows a user to place a hold on an age-protected item')), - (138, 'MAX_RENEWALS_REACHED.override', oils_i18n_gettext('Allows a user to renew an item past the maximun renewal count')), - (139, 'PATRON_EXCEEDS_CHECKOUT_COUNT.override', oils_i18n_gettext('Allow staff to override checkout count failure')), - (140, 'PATRON_EXCEEDS_OVERDUE_COUNT.override', oils_i18n_gettext('Allow staff to override overdue count failure')), - (141, 'PATRON_EXCEEDS_FINES.override', oils_i18n_gettext('Allow staff to override fine amount checkout failure')), - (142, 'CIRC_EXCEEDS_COPY_RANGE.override', oils_i18n_gettext('')), - (143, 'ITEM_ON_HOLDS_SHELF.override', oils_i18n_gettext('')), - (144, 'COPY_NOT_AVAILABLE.override', oils_i18n_gettext('Allow staff to force checkout of Missing/Lost type items')), - (146, 'HOLD_EXISTS.override', oils_i18n_gettext('allows users to place multiple holds on a single title')), - (147, 'RUN_REPORTS', oils_i18n_gettext('Allows a users to run reports')), - (148, 'SHARE_REPORT_FOLDER', oils_i18n_gettext('Allows a user to share report his own folders')), - (149, 'VIEW_REPORT_OUTPUT', oils_i18n_gettext('Allow user to view report output')), - (150, 'COPY_CIRC_NOT_ALLOWED.override', oils_i18n_gettext('Allows a user to checkout an item that is marked as non-circ')), - (151, 'DELETE_CONTAINER_ITEM', oils_i18n_gettext('Allows a user to delete an item out of another user''s container')), + (-1, 'EVERYTHING', NULL); +INSERT INTO permission.perm_list VALUES + (2, 'OPAC_LOGIN', NULL); +INSERT INTO permission.perm_list VALUES + (4, 'STAFF_LOGIN', NULL); +INSERT INTO permission.perm_list VALUES + (5, 'MR_HOLDS', NULL); +INSERT INTO permission.perm_list VALUES + (6, 'TITLE_HOLDS', NULL); +INSERT INTO permission.perm_list VALUES + (7, 'VOLUME_HOLDS', NULL); +INSERT INTO permission.perm_list VALUES + (8, 'COPY_HOLDS', oils_i18n_gettext('User is allowed to place a hold on a specific copy')); +INSERT INTO permission.perm_list VALUES + (9, 'REQUEST_HOLDS', NULL); +INSERT INTO permission.perm_list VALUES + (10, 'REQUEST_HOLDS_OVERRIDE', NULL); +INSERT INTO permission.perm_list VALUES + (11, 'VIEW_HOLD', oils_i18n_gettext('Allows a user to view another user''s holds')); +INSERT INTO permission.perm_list VALUES + (13, 'DELETE_HOLDS', NULL); +INSERT INTO permission.perm_list VALUES + (14, 'UPDATE_HOLD', oils_i18n_gettext('Allows a user to update another user''s hold')); +INSERT INTO permission.perm_list VALUES + (15, 'RENEW_CIRC', NULL); +INSERT INTO permission.perm_list VALUES + (16, 'VIEW_USER_FINES_SUMMARY', NULL); +INSERT INTO permission.perm_list VALUES + (17, 'VIEW_USER_TRANSACTIONS', NULL); +INSERT INTO permission.perm_list VALUES + (18, 'UPDATE_MARC', NULL); +INSERT INTO permission.perm_list VALUES + (19, 'CREATE_MARC', oils_i18n_gettext('User is allowed to create new MARC records')); +INSERT INTO permission.perm_list VALUES + (20, 'IMPORT_MARC', NULL); +INSERT INTO permission.perm_list VALUES + (21, 'CREATE_VOLUME', NULL); +INSERT INTO permission.perm_list VALUES + (22, 'UPDATE_VOLUME', NULL); +INSERT INTO permission.perm_list VALUES + (23, 'DELETE_VOLUME', NULL); +INSERT INTO permission.perm_list VALUES + (25, 'UPDATE_COPY', NULL); +INSERT INTO permission.perm_list VALUES + (26, 'DELETE_COPY', NULL); +INSERT INTO permission.perm_list VALUES + (27, 'RENEW_HOLD_OVERRIDE', NULL); +INSERT INTO permission.perm_list VALUES + (28, 'CREATE_USER', NULL); +INSERT INTO permission.perm_list VALUES + (29, 'UPDATE_USER', NULL); +INSERT INTO permission.perm_list VALUES + (30, 'DELETE_USER', NULL); +INSERT INTO permission.perm_list VALUES + (31, 'VIEW_USER', NULL); +INSERT INTO permission.perm_list VALUES + (32, 'COPY_CHECKIN', NULL); +INSERT INTO permission.perm_list VALUES + (33, 'CREATE_TRANSIT', NULL); +INSERT INTO permission.perm_list VALUES + (34, 'VIEW_PERMISSION', NULL); +INSERT INTO permission.perm_list VALUES + (35, 'CHECKIN_BYPASS_HOLD_FULFILL', NULL); +INSERT INTO permission.perm_list VALUES + (36, 'CREATE_PAYMENT', NULL); +INSERT INTO permission.perm_list VALUES + (37, 'SET_CIRC_LOST', NULL); +INSERT INTO permission.perm_list VALUES + (38, 'SET_CIRC_MISSING', NULL); +INSERT INTO permission.perm_list VALUES + (39, 'SET_CIRC_CLAIMS_RETURNED', NULL); +INSERT INTO permission.perm_list VALUES + (41, 'CREATE_TRANSACTION', oils_i18n_gettext('User may create new billable transactions')); +INSERT INTO permission.perm_list VALUES + (43, 'CREATE_BILL', oils_i18n_gettext('Allows a user to create a new bill on a transaction')); +INSERT INTO permission.perm_list VALUES + (44, 'VIEW_CONTAINER', oils_i18n_gettext('Allows a user to view another user''s containers (buckets)')); +INSERT INTO permission.perm_list VALUES + (45, 'CREATE_CONTAINER', oils_i18n_gettext('Allows a user to create a new container for another user')); +INSERT INTO permission.perm_list VALUES + (24, 'CREATE_COPY', oils_i18n_gettext('User is allowed to create a new copy object')); +INSERT INTO permission.perm_list VALUES + (47, 'UPDATE_ORG_UNIT', oils_i18n_gettext('Allows a user to change org unit settings')); +INSERT INTO permission.perm_list VALUES + (48, 'VIEW_CIRCULATIONS', oils_i18n_gettext('Allows a user to see what another use has checked out')); +INSERT INTO permission.perm_list VALUES + (42, 'VIEW_TRANSACTION', oils_i18n_gettext('User may view another user''s transactions')); +INSERT INTO permission.perm_list VALUES + (49, 'DELETE_CONTAINER', oils_i18n_gettext('Allows a user to delete another user container')); +INSERT INTO permission.perm_list VALUES + (50, 'CREATE_CONTAINER_ITEM', oils_i18n_gettext('Create a container item for another user')); +INSERT INTO permission.perm_list VALUES + (51, 'CREATE_USER_GROUP_LINK', oils_i18n_gettext('User can add other users to permission groups')); +INSERT INTO permission.perm_list VALUES + (52, 'REMOVE_USER_GROUP_LINK', oils_i18n_gettext('User can remove other users from permission groups')); +INSERT INTO permission.perm_list VALUES + (53, 'VIEW_PERM_GROUPS', oils_i18n_gettext('Allow user to view others'' permission groups')); +INSERT INTO permission.perm_list VALUES + (54, 'VIEW_PERMIT_CHECKOUT', oils_i18n_gettext('Allows a user to determine of another user can checkout an item')); +INSERT INTO permission.perm_list VALUES + (55, 'UPDATE_BATCH_COPY', oils_i18n_gettext('Allows a user to edit copies in batch')); +INSERT INTO permission.perm_list VALUES + (56, 'CREATE_PATRON_STAT_CAT', oils_i18n_gettext('User may create a new patron statistical category')); +INSERT INTO permission.perm_list VALUES + (57, 'CREATE_COPY_STAT_CAT', oils_i18n_gettext('User may create a copy stat cat')); +INSERT INTO permission.perm_list VALUES + (58, 'CREATE_PATRON_STAT_CAT_ENTRY', oils_i18n_gettext('User may create a new patron stat cat entry')); +INSERT INTO permission.perm_list VALUES + (59, 'CREATE_COPY_STAT_CAT_ENTRY', oils_i18n_gettext('User may create a new copy stat cat entry')); +INSERT INTO permission.perm_list VALUES + (60, 'UPDATE_PATRON_STAT_CAT', oils_i18n_gettext('User may update a patron stat cat')); +INSERT INTO permission.perm_list VALUES + (61, 'UPDATE_COPY_STAT_CAT', oils_i18n_gettext('User may update a copy stat cat')); +INSERT INTO permission.perm_list VALUES + (62, 'UPDATE_PATRON_STAT_CAT_ENTRY', oils_i18n_gettext('User may update a patron stat cat entry')); +INSERT INTO permission.perm_list VALUES + (63, 'UPDATE_COPY_STAT_CAT_ENTRY', oils_i18n_gettext('User may update a copy stat cat entry')); +INSERT INTO permission.perm_list VALUES + (65, 'CREATE_COPY_STAT_CAT_ENTRY_MAP', oils_i18n_gettext('User may link a copy to a stat cat entry')); +INSERT INTO permission.perm_list VALUES + (64, 'CREATE_PATRON_STAT_CAT_ENTRY_MAP', oils_i18n_gettext('User may link another user to a stat cat entry')); +INSERT INTO permission.perm_list VALUES + (66, 'DELETE_PATRON_STAT_CAT', oils_i18n_gettext('User may delete a patron stat cat')); +INSERT INTO permission.perm_list VALUES + (67, 'DELETE_COPY_STAT_CAT', oils_i18n_gettext('User may delete a copy stat cat')); +INSERT INTO permission.perm_list VALUES + (68, 'DELETE_PATRON_STAT_CAT_ENTRY', oils_i18n_gettext('User may delete a patron stat cat entry')); +INSERT INTO permission.perm_list VALUES + (69, 'DELETE_COPY_STAT_CAT_ENTRY', oils_i18n_gettext('User may delete a copy stat cat entry')); +INSERT INTO permission.perm_list VALUES + (70, 'DELETE_PATRON_STAT_CAT_ENTRY_MAP', oils_i18n_gettext('User may delete a patron stat cat entry map')); +INSERT INTO permission.perm_list VALUES + (71, 'DELETE_COPY_STAT_CAT_ENTRY_MAP', oils_i18n_gettext('User may delete a copy stat cat entry map')); +INSERT INTO permission.perm_list VALUES + (72, 'CREATE_NON_CAT_TYPE', oils_i18n_gettext('Allows a user to create a new non-cataloged item type')); +INSERT INTO permission.perm_list VALUES + (73, 'UPDATE_NON_CAT_TYPE', oils_i18n_gettext('Allows a user to update a non cataloged type')); +INSERT INTO permission.perm_list VALUES + (74, 'CREATE_IN_HOUSE_USE', oils_i18n_gettext('Allows a user to create a new in-house-use ')); +INSERT INTO permission.perm_list VALUES + (75, 'COPY_CHECKOUT', oils_i18n_gettext('Allows a user to check out a copy')); +INSERT INTO permission.perm_list VALUES + (76, 'CREATE_COPY_LOCATION', oils_i18n_gettext('Allows a user to create a new copy location')); +INSERT INTO permission.perm_list VALUES + (77, 'UPDATE_COPY_LOCATION', oils_i18n_gettext('Allows a user to update a copy location')); +INSERT INTO permission.perm_list VALUES + (78, 'DELETE_COPY_LOCATION', oils_i18n_gettext('Allows a user to delete a copy location')); +INSERT INTO permission.perm_list VALUES + (79, 'CREATE_COPY_TRANSIT', oils_i18n_gettext('Allows a user to create a transit_copy object for transiting a copy')); +INSERT INTO permission.perm_list VALUES + (80, 'COPY_TRANSIT_RECEIVE', oils_i18n_gettext('Allows a user to close out a transit on a copy')); +INSERT INTO permission.perm_list VALUES + (81, 'VIEW_HOLD_PERMIT', oils_i18n_gettext('Allows a user to see if another user has permission to place a hold on a given copy')); +INSERT INTO permission.perm_list VALUES + (82, 'VIEW_COPY_CHECKOUT_HISTORY', oils_i18n_gettext('Allows a user to view which users have checked out a given copy')); +INSERT INTO permission.perm_list VALUES + (83, 'REMOTE_Z3950_QUERY', oils_i18n_gettext('Allows a user to perform z3950 queries against remote servers')); +INSERT INTO permission.perm_list VALUES + (84, 'REGISTER_WORKSTATION', oils_i18n_gettext('Allows a user to register a new workstation')); +INSERT INTO permission.perm_list VALUES + (85, 'VIEW_COPY_NOTES', oils_i18n_gettext('Allows a user to view all notes attached to a copy')); +INSERT INTO permission.perm_list VALUES + (86, 'VIEW_VOLUME_NOTES', oils_i18n_gettext('Allows a user to view all notes attached to a volume')); +INSERT INTO permission.perm_list VALUES + (87, 'VIEW_TITLE_NOTES', oils_i18n_gettext('Allows a user to view all notes attached to a title')); +INSERT INTO permission.perm_list VALUES + (89, 'CREATE_VOLUME_NOTE', oils_i18n_gettext('Allows a user to create a new volume note')); +INSERT INTO permission.perm_list VALUES + (88, 'CREATE_COPY_NOTE', oils_i18n_gettext('Allows a user to create a new copy note')); +INSERT INTO permission.perm_list VALUES + (90, 'CREATE_TITLE_NOTE', oils_i18n_gettext('Allows a user to create a new title note')); +INSERT INTO permission.perm_list VALUES + (91, 'DELETE_COPY_NOTE', oils_i18n_gettext('Allows a user to delete someone elses copy notes')); +INSERT INTO permission.perm_list VALUES + (92, 'DELETE_VOLUME_NOTE', oils_i18n_gettext('Allows a user to delete someone elses volume note')); +INSERT INTO permission.perm_list VALUES + (93, 'DELETE_TITLE_NOTE', oils_i18n_gettext('Allows a user to delete someone elses title note')); +INSERT INTO permission.perm_list VALUES + (94, 'UPDATE_CONTAINER', oils_i18n_gettext('Allows a user to update another users container')); +INSERT INTO permission.perm_list VALUES + (95, 'CREATE_MY_CONTAINER', oils_i18n_gettext('Allows a user to create a container for themselves')); +INSERT INTO permission.perm_list VALUES + (96, 'VIEW_HOLD_NOTIFICATION', oils_i18n_gettext('Allows a user to view notifications attached to a hold')); +INSERT INTO permission.perm_list VALUES + (97, 'CREATE_HOLD_NOTIFICATION', oils_i18n_gettext('Allows a user to create new hold notifications')); +INSERT INTO permission.perm_list VALUES + (98, 'UPDATE_ORG_SETTING', oils_i18n_gettext('Allows a user to update an org unit setting')); +INSERT INTO permission.perm_list VALUES + (99, 'OFFLINE_UPLOAD', oils_i18n_gettext('Allows a user to upload an offline script')); +INSERT INTO permission.perm_list VALUES + (100, 'OFFLINE_VIEW', oils_i18n_gettext('Allows a user to view uploaded offline script information')); +INSERT INTO permission.perm_list VALUES + (101, 'OFFLINE_EXECUTE', oils_i18n_gettext('Allows a user to execute an offline script batch')); +INSERT INTO permission.perm_list VALUES + (102, 'CIRC_OVERRIDE_DUE_DATE', oils_i18n_gettext('Allows a user to change set the due date on an item to any date')); +INSERT INTO permission.perm_list VALUES + (103, 'CIRC_PERMIT_OVERRIDE', oils_i18n_gettext('Allows a user to bypass the circ permit call for checkout')); +INSERT INTO permission.perm_list VALUES + (104, 'COPY_IS_REFERENCE.override', oils_i18n_gettext('Allows a user to override the copy_is_reference event')); +INSERT INTO permission.perm_list VALUES + (105, 'VOID_BILLING', oils_i18n_gettext('Allows a user to void a bill')); +INSERT INTO permission.perm_list VALUES + (106, 'CIRC_CLAIMS_RETURNED.override', oils_i18n_gettext('Allows a person to check in/out an item that is claims returned')); +INSERT INTO permission.perm_list VALUES + (107, 'COPY_BAD_STATUS.override', oils_i18n_gettext('Allows a user to check out an item in a non-circulatable status')); +INSERT INTO permission.perm_list VALUES + (108, 'COPY_ALERT_MESSAGE.override', oils_i18n_gettext('Allows a user to check in/out an item that has an alert message')); +INSERT INTO permission.perm_list VALUES + (109, 'COPY_STATUS_LOST.override', oils_i18n_gettext('Allows a user to remove the lost status from a copy')); +INSERT INTO permission.perm_list VALUES + (110, 'COPY_STATUS_MISSING.override', oils_i18n_gettext('Allows a user to change the missing status on a copy')); +INSERT INTO permission.perm_list VALUES + (111, 'ABORT_TRANSIT', oils_i18n_gettext('Allows a user to abort a copy transit if the user is at the transit destination or source')); +INSERT INTO permission.perm_list VALUES + (112, 'ABORT_REMOTE_TRANIST', oils_i18n_gettext('Allows a user to abort a copy transit if the user is not at the transit source or dest')); +INSERT INTO permission.perm_list VALUES + (113, 'VIEW_ZIP_DATA', oils_i18n_gettext('Allowsa user to query the zip code data method')); +INSERT INTO permission.perm_list VALUES + (114, 'CANCEL_HOLDS', oils_i18n_gettext('')); +INSERT INTO permission.perm_list VALUES + (115, 'CREATE_DUPLICATE_HOLDS', oils_i18n_gettext('Allows a user to create duplicate holds (e.g. two holds on the same title)')); +INSERT INTO permission.perm_list VALUES + (117, 'actor.org_unit.closed_date.update', oils_i18n_gettext('Allows a user to update a closed date interval for a given location')); +INSERT INTO permission.perm_list VALUES + (116, 'actor.org_unit.closed_date.delete', oils_i18n_gettext('Allows a user to remove a closed date interval for a given location')); +INSERT INTO permission.perm_list VALUES + (118, 'actor.org_unit.closed_date.create', oils_i18n_gettext('Allows a user to create a new closed date for a location')); +INSERT INTO permission.perm_list VALUES + (119, 'DELETE_NON_CAT_TYPE', oils_i18n_gettext('Allows a user to delete a non cataloged type')); +INSERT INTO permission.perm_list VALUES + (120, 'money.collections_tracker.create', oils_i18n_gettext('Allows a user to put someone into collections')); +INSERT INTO permission.perm_list VALUES + (121, 'money.collections_tracker.delete', oils_i18n_gettext('Allows a user to remove someone from collections')); +INSERT INTO permission.perm_list VALUES + (122, 'BAR_PATRON', oils_i18n_gettext('Allows a user to bar a patron')); +INSERT INTO permission.perm_list VALUES + (123, 'UNBAR_PATRON', oils_i18n_gettext('Allows a user to un-bar a patron')); +INSERT INTO permission.perm_list VALUES + (124, 'DELETE_WORKSTATION', oils_i18n_gettext('Allows a user to remove an existing workstation so a new one can replace it')); +INSERT INTO permission.perm_list VALUES + (125, 'group_application.user', oils_i18n_gettext('Allows a user to add/remove users to/from the "User" group')); +INSERT INTO permission.perm_list VALUES + (126, 'group_application.user.patron', oils_i18n_gettext('Allows a user to add/remove users to/from the "Patron" group')); +INSERT INTO permission.perm_list VALUES + (127, 'group_application.user.staff', oils_i18n_gettext('Allows a user to add/remove users to/from the "Staff" group')); +INSERT INTO permission.perm_list VALUES + (128, 'group_application.user.staff.circ', oils_i18n_gettext('Allows a user to add/remove users to/from the "Circulator" group')); +INSERT INTO permission.perm_list VALUES + (129, 'group_application.user.staff.cat', oils_i18n_gettext('Allows a user to add/remove users to/from the "Cataloger" group')); +INSERT INTO permission.perm_list VALUES + (130, 'group_application.user.staff.admin.global_admin', oils_i18n_gettext('Allows a user to add/remove users to/from the "GlobalAdmin" group')); +INSERT INTO permission.perm_list VALUES + (131, 'group_application.user.staff.admin.local_admin', oils_i18n_gettext('Allows a user to add/remove users to/from the "LocalAdmin" group')); +INSERT INTO permission.perm_list VALUES + (132, 'group_application.user.staff.admin.lib_manager', oils_i18n_gettext('Allows a user to add/remove users to/from the "LibraryManager" group')); +INSERT INTO permission.perm_list VALUES + (133, 'group_application.user.staff.cat.cat1', oils_i18n_gettext('Allows a user to add/remove users to/from the "Cat1" group')); +INSERT INTO permission.perm_list VALUES + (134, 'group_application.user.staff.supercat', oils_i18n_gettext('Allows a user to add/remove users to/from the "Supercat" group')); +INSERT INTO permission.perm_list VALUES + (135, 'group_application.user.sip_client', oils_i18n_gettext('Allows a user to add/remove users to/from the "SIP-Client" group')); +INSERT INTO permission.perm_list VALUES + (136, 'group_application.user.vendor', oils_i18n_gettext('Allows a user to add/remove users to/from the "Vendor" group')); +INSERT INTO permission.perm_list VALUES + (137, 'ITEM_AGE_PROTECTED.override', oils_i18n_gettext('Allows a user to place a hold on an age-protected item')); +INSERT INTO permission.perm_list VALUES + (138, 'MAX_RENEWALS_REACHED.override', oils_i18n_gettext('Allows a user to renew an item past the maximun renewal count')); +INSERT INTO permission.perm_list VALUES + (139, 'PATRON_EXCEEDS_CHECKOUT_COUNT.override', oils_i18n_gettext('Allow staff to override checkout count failure')); +INSERT INTO permission.perm_list VALUES + (140, 'PATRON_EXCEEDS_OVERDUE_COUNT.override', oils_i18n_gettext('Allow staff to override overdue count failure')); +INSERT INTO permission.perm_list VALUES + (141, 'PATRON_EXCEEDS_FINES.override', oils_i18n_gettext('Allow staff to override fine amount checkout failure')); +INSERT INTO permission.perm_list VALUES + (142, 'CIRC_EXCEEDS_COPY_RANGE.override', oils_i18n_gettext('')); +INSERT INTO permission.perm_list VALUES + (143, 'ITEM_ON_HOLDS_SHELF.override', oils_i18n_gettext('')); +INSERT INTO permission.perm_list VALUES + (144, 'COPY_NOT_AVAILABLE.override', oils_i18n_gettext('Allow staff to force checkout of Missing/Lost type items')); +INSERT INTO permission.perm_list VALUES + (146, 'HOLD_EXISTS.override', oils_i18n_gettext('allows users to place multiple holds on a single title')); +INSERT INTO permission.perm_list VALUES + (147, 'RUN_REPORTS', oils_i18n_gettext('Allows a users to run reports')); +INSERT INTO permission.perm_list VALUES + (148, 'SHARE_REPORT_FOLDER', oils_i18n_gettext('Allows a user to share report his own folders')); +INSERT INTO permission.perm_list VALUES + (149, 'VIEW_REPORT_OUTPUT', oils_i18n_gettext('Allow user to view report output')); +INSERT INTO permission.perm_list VALUES + (150, 'COPY_CIRC_NOT_ALLOWED.override', oils_i18n_gettext('Allows a user to checkout an item that is marked as non-circ')); +INSERT INTO permission.perm_list VALUES + (151, 'DELETE_CONTAINER_ITEM', oils_i18n_gettext('Allows a user to delete an item out of another user''s container')); +INSERT INTO permission.perm_list VALUES (152, 'ASSIGN_WORK_ORG_UNIT', oils_i18n_gettext('Allow a staff member to define where another staff member has their permissions')), (153, 'CREATE_FUNDING_SOURCE', oils_i18n_gettext('Allow a user to create a new funding source')), (154, 'DELETE_FUNDING_SOURCE', oils_i18n_gettext('Allow a user to delete a funding source')), @@ -838,128 +1049,222 @@ INSERT INTO permission.perm_list VALUES (176, 'MANAGE_PROVIDER', oils_i18n_gettext('Allow a user to view and purchase from a provider')), (177, 'VIEW_PICKLIST', oils_i18n_gettext('Allow a user to view another users picklist')); +SELECT SETVAL('permission.perm_list_id_seq'::TEXT, (SELECT MAX(id) FROM permission.perm_list)); + +INSERT INTO permission.perm_list (code) VALUES ('ASSIGN_GROUP_PERM'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_AUDIENCE'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_BIB_LEVEL'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_CIRC_DURATION'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_CIRC_MOD'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_COPY_STATUS'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_HOURS_OF_OPERATION'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_ITEM_FORM'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_ITEM_TYPE'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_LANGUAGE'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_LASSO'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_LASSO_MAP'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_LIT_FORM'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_METABIB_FIELD'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_NET_ACCESS_LEVEL'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_ORG_ADDRESS'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_ORG_TYPE'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_ORG_UNIT'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_ORG_UNIT_CLOSING'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_PERM'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_RELEVANCE_ADJUSTMENT'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_SURVEY'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_VR_FORMAT'); +INSERT INTO permission.perm_list (code) VALUES ('CREATE_XML_TRANSFORM'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_AUDIENCE'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_BIB_LEVEL'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_CIRC_DURATION'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_CIRC_MOD'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_COPY_STATUS'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_HOURS_OF_OPERATION'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_ITEM_FORM'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_ITEM_TYPE'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_LANGUAGE'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_LASSO'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_LASSO_MAP'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_LIT_FORM'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_METABIB_FIELD'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_NET_ACCESS_LEVEL'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_ORG_ADDRESS'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_ORG_TYPE'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_ORG_UNIT'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_ORG_UNIT_CLOSING'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_PERM'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_RELEVANCE_ADJUSTMENT'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_SURVEY'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_TRANSIT'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_VR_FORMAT'); +INSERT INTO permission.perm_list (code) VALUES ('DELETE_XML_TRANSFORM'); +INSERT INTO permission.perm_list (code) VALUES ('REMOVE_GROUP_PERM'); +INSERT INTO permission.perm_list (code) VALUES ('TRANSIT_COPY'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_AUDIENCE'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_BIB_LEVEL'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_CIRC_DURATION'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_CIRC_MOD'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_COPY_NOTE'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_COPY_STATUS'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_GROUP_PERM'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_HOURS_OF_OPERATION'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_ITEM_FORM'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_ITEM_TYPE'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_LANGUAGE'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_LASSO'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_LASSO_MAP'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_LIT_FORM'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_METABIB_FIELD'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_NET_ACCESS_LEVEL'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_ORG_ADDRESS'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_ORG_TYPE'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_ORG_UNIT_CLOSING'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_PERM'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_RELEVANCE_ADJUSTMENT'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_SURVEY'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_TRANSIT'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_VOLUME_NOTE'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_VR_FORMAT'); +INSERT INTO permission.perm_list (code) VALUES ('UPDATE_XML_TRANSFORM'); + + +INSERT INTO permission.grp_tree (id, name, parent, description, perm_interval, usergroup, application_perm) VALUES + (1, 'Users', NULL, NULL, '3 years', FALSE, 'group_application.user'); +INSERT INTO permission.grp_tree (id, name, parent, description, perm_interval, usergroup, application_perm) VALUES + (2, 'Patrons', 1, NULL, '3 years', TRUE, 'group_application.user.patron'); +INSERT INTO permission.grp_tree (id, name, parent, description, perm_interval, usergroup, application_perm) VALUES + (3, 'Staff', 1, NULL, '3 years', FALSE, 'group_application.user.staff'); +INSERT INTO permission.grp_tree (id, name, parent, description, perm_interval, usergroup, application_perm) VALUES + (4, 'Catalogers', 3, NULL, '3 years', TRUE, 'group_application.user.staff.cat'); +INSERT INTO permission.grp_tree (id, name, parent, description, perm_interval, usergroup, application_perm) VALUES + (5, 'Circulators', 3, NULL, '3 years', TRUE, 'group_application.user.staff.circ'); INSERT INTO permission.grp_tree (id, name, parent, description, perm_interval, usergroup, application_perm) VALUES - (1, 'Users', NULL, NULL, '3 years', FALSE, 'group_application.user'), - (2, 'Patrons', 1, NULL, '3 years', TRUE, 'group_application.user.patron'), - (3, 'Staff', 1, NULL, '3 years', FALSE, 'group_application.user.staff'), - (4, 'Catalogers', 3, NULL, '3 years', TRUE, 'group_application.user.staff.cat'), - (5, 'Circulators', 3, NULL, '3 years', TRUE, 'group_application.user.staff.circ'), (10, 'Local System Administrator', 3, 'System maintenance, configuration, etc.', '3 years', TRUE, 'group_application.user.staff.admin.local_admin'); +SELECT SETVAL('permission.grp_tree_id_seq'::TEXT, (SELECT MAX(id) FROM permission.grp_tree)); -- XXX Incomplete base permission setup. A patch would be appreciated. -INSERT INTO permission.grp_perm_map VALUES - (57, 2, 15, 0, false), - (109, 2, 95, 0, false), - (1, 1, 2, 0, false), - (12, 1, 5, 0, false), - (13, 1, 6, 0, false), - (51, 1, 32, 0, false), - (111, 1, 95, 0, false), - (11, 3, 4, 0, false), - (14, 3, 7, 2, false), - (16, 3, 9, 0, false), - (19, 3, 15, 0, false), - (20, 3, 16, 0, false), - (21, 3, 17, 0, false), - (116, 3, 18, 0, false), - (117, 3, 20, 0, false), - (118, 3, 21, 2, false), - (119, 3, 22, 2, false), - (120, 3, 23, 2, false), - (121, 3, 25, 2, false), - (26, 3, 27, 0, false), - (27, 3, 28, 0, false), - (28, 3, 29, 0, false), - (29, 3, 30, 0, false), - (44, 3, 31, 0, false), - (31, 3, 33, 0, false), - (32, 3, 34, 0, false), - (33, 3, 35, 0, false), - (41, 3, 36, 0, false), - (45, 3, 37, 0, false), - (46, 3, 38, 0, false), - (47, 3, 39, 0, false), - (122, 3, 41, 0, false), - (123, 3, 43, 0, false), - (60, 3, 44, 0, false), - (110, 3, 45, 0, false), - (124, 3, 8, 2, false), - (125, 3, 24, 2, false), - (126, 3, 19, 0, false), - (61, 3, 47, 2, false), - (95, 3, 48, 0, false), - (17, 3, 11, 0, false), - (62, 3, 42, 0, false), - (63, 3, 49, 0, false), - (64, 3, 50, 0, false), - (127, 3, 53, 0, false), - (65, 3, 54, 0, false), - (128, 3, 55, 2, false), - (67, 3, 56, 2, false), - (68, 3, 57, 2, false), - (69, 3, 58, 2, false), - (70, 3, 59, 2, false), - (71, 3, 60, 2, false), - (72, 3, 61, 2, false), - (73, 3, 62, 2, false), - (74, 3, 63, 2, false), - (81, 3, 72, 2, false), - (82, 3, 73, 2, false), - (83, 3, 74, 2, false), - (84, 3, 75, 0, false), - (85, 3, 76, 2, false), - (86, 3, 77, 2, false), - (89, 3, 79, 0, false), - (90, 3, 80, 0, false), - (91, 3, 81, 0, false), - (92, 3, 82, 0, false), - (98, 3, 83, 0, false), - (115, 3, 84, 0, false), - (100, 3, 85, 0, false), - (101, 3, 86, 0, false), - (102, 3, 87, 0, false), - (103, 3, 89, 2, false), - (104, 3, 88, 2, false), - (108, 3, 94, 0, false), - (112, 3, 96, 0, false), - (113, 3, 97, 0, false), - (130, 3, 99, 1, false), - (131, 3, 100, 1, false), - (22, 4, 18, 0, false), - (24, 4, 20, 0, false), - (38, 4, 21, 2, false), - (34, 4, 22, 2, false), - (39, 4, 23, 2, false), - (35, 4, 25, 2, false), - (129, 4, 26, 2, false), - (15, 4, 8, 2, false), - (40, 4, 24, 2, false), - (23, 4, 19, 0, false), - (66, 4, 55, 2, false), - (134, 10, 51, 1, false), - (75, 10, 66, 2, false), - (76, 10, 67, 2, false), - (77, 10, 68, 2, false), - (78, 10, 69, 2, false), - (79, 10, 70, 2, false), - (80, 10, 71, 2, false), - (87, 10, 78, 2, false), - (105, 10, 91, 1, false), - (106, 10, 92, 1, false), - (107, 10, 93, 0, false), - (114, 10, 98, 1, false), - (132, 10, 101, 1, true), - (136, 10, 102, 1, false), - (137, 10, 103, 1, false), - (97, 5, 41, 0, false), - (96, 5, 43, 0, false), - (93, 5, 48, 0, false), - (94, 5, 53, 0, false), - (133, 5, 102, 0, false), - (138, 5, 104, 1, false); - --- Admin user +INSERT INTO permission.grp_perm_map VALUES (57, 2, 15, 0, false); +INSERT INTO permission.grp_perm_map VALUES (109, 2, 95, 0, false); +INSERT INTO permission.grp_perm_map VALUES (1, 1, 2, 0, false); +INSERT INTO permission.grp_perm_map VALUES (12, 1, 5, 0, false); +INSERT INTO permission.grp_perm_map VALUES (13, 1, 6, 0, false); +INSERT INTO permission.grp_perm_map VALUES (51, 1, 32, 0, false); +INSERT INTO permission.grp_perm_map VALUES (111, 1, 95, 0, false); +INSERT INTO permission.grp_perm_map VALUES (11, 3, 4, 0, false); +INSERT INTO permission.grp_perm_map VALUES (14, 3, 7, 2, false); +INSERT INTO permission.grp_perm_map VALUES (16, 3, 9, 0, false); +INSERT INTO permission.grp_perm_map VALUES (19, 3, 15, 0, false); +INSERT INTO permission.grp_perm_map VALUES (20, 3, 16, 0, false); +INSERT INTO permission.grp_perm_map VALUES (21, 3, 17, 0, false); +INSERT INTO permission.grp_perm_map VALUES (116, 3, 18, 0, false); +INSERT INTO permission.grp_perm_map VALUES (117, 3, 20, 0, false); +INSERT INTO permission.grp_perm_map VALUES (118, 3, 21, 2, false); +INSERT INTO permission.grp_perm_map VALUES (119, 3, 22, 2, false); +INSERT INTO permission.grp_perm_map VALUES (120, 3, 23, 2, false); +INSERT INTO permission.grp_perm_map VALUES (121, 3, 25, 2, false); +INSERT INTO permission.grp_perm_map VALUES (26, 3, 27, 0, false); +INSERT INTO permission.grp_perm_map VALUES (27, 3, 28, 0, false); +INSERT INTO permission.grp_perm_map VALUES (28, 3, 29, 0, false); +INSERT INTO permission.grp_perm_map VALUES (29, 3, 30, 0, false); +INSERT INTO permission.grp_perm_map VALUES (44, 3, 31, 0, false); +INSERT INTO permission.grp_perm_map VALUES (31, 3, 33, 0, false); +INSERT INTO permission.grp_perm_map VALUES (32, 3, 34, 0, false); +INSERT INTO permission.grp_perm_map VALUES (33, 3, 35, 0, false); +INSERT INTO permission.grp_perm_map VALUES (41, 3, 36, 0, false); +INSERT INTO permission.grp_perm_map VALUES (45, 3, 37, 0, false); +INSERT INTO permission.grp_perm_map VALUES (46, 3, 38, 0, false); +INSERT INTO permission.grp_perm_map VALUES (47, 3, 39, 0, false); +INSERT INTO permission.grp_perm_map VALUES (122, 3, 41, 0, false); +INSERT INTO permission.grp_perm_map VALUES (123, 3, 43, 0, false); +INSERT INTO permission.grp_perm_map VALUES (60, 3, 44, 0, false); +INSERT INTO permission.grp_perm_map VALUES (110, 3, 45, 0, false); +INSERT INTO permission.grp_perm_map VALUES (124, 3, 8, 2, false); +INSERT INTO permission.grp_perm_map VALUES (125, 3, 24, 2, false); +INSERT INTO permission.grp_perm_map VALUES (126, 3, 19, 0, false); +INSERT INTO permission.grp_perm_map VALUES (61, 3, 47, 2, false); +INSERT INTO permission.grp_perm_map VALUES (95, 3, 48, 0, false); +INSERT INTO permission.grp_perm_map VALUES (17, 3, 11, 0, false); +INSERT INTO permission.grp_perm_map VALUES (62, 3, 42, 0, false); +INSERT INTO permission.grp_perm_map VALUES (63, 3, 49, 0, false); +INSERT INTO permission.grp_perm_map VALUES (64, 3, 50, 0, false); +INSERT INTO permission.grp_perm_map VALUES (127, 3, 53, 0, false); +INSERT INTO permission.grp_perm_map VALUES (65, 3, 54, 0, false); +INSERT INTO permission.grp_perm_map VALUES (128, 3, 55, 2, false); +INSERT INTO permission.grp_perm_map VALUES (67, 3, 56, 2, false); +INSERT INTO permission.grp_perm_map VALUES (68, 3, 57, 2, false); +INSERT INTO permission.grp_perm_map VALUES (69, 3, 58, 2, false); +INSERT INTO permission.grp_perm_map VALUES (70, 3, 59, 2, false); +INSERT INTO permission.grp_perm_map VALUES (71, 3, 60, 2, false); +INSERT INTO permission.grp_perm_map VALUES (72, 3, 61, 2, false); +INSERT INTO permission.grp_perm_map VALUES (73, 3, 62, 2, false); +INSERT INTO permission.grp_perm_map VALUES (74, 3, 63, 2, false); +INSERT INTO permission.grp_perm_map VALUES (81, 3, 72, 2, false); +INSERT INTO permission.grp_perm_map VALUES (82, 3, 73, 2, false); +INSERT INTO permission.grp_perm_map VALUES (83, 3, 74, 2, false); +INSERT INTO permission.grp_perm_map VALUES (84, 3, 75, 0, false); +INSERT INTO permission.grp_perm_map VALUES (85, 3, 76, 2, false); +INSERT INTO permission.grp_perm_map VALUES (86, 3, 77, 2, false); +INSERT INTO permission.grp_perm_map VALUES (89, 3, 79, 0, false); +INSERT INTO permission.grp_perm_map VALUES (90, 3, 80, 0, false); +INSERT INTO permission.grp_perm_map VALUES (91, 3, 81, 0, false); +INSERT INTO permission.grp_perm_map VALUES (92, 3, 82, 0, false); +INSERT INTO permission.grp_perm_map VALUES (98, 3, 83, 0, false); +INSERT INTO permission.grp_perm_map VALUES (115, 3, 84, 0, false); +INSERT INTO permission.grp_perm_map VALUES (100, 3, 85, 0, false); +INSERT INTO permission.grp_perm_map VALUES (101, 3, 86, 0, false); +INSERT INTO permission.grp_perm_map VALUES (102, 3, 87, 0, false); +INSERT INTO permission.grp_perm_map VALUES (103, 3, 89, 2, false); +INSERT INTO permission.grp_perm_map VALUES (104, 3, 88, 2, false); +INSERT INTO permission.grp_perm_map VALUES (108, 3, 94, 0, false); +INSERT INTO permission.grp_perm_map VALUES (112, 3, 96, 0, false); +INSERT INTO permission.grp_perm_map VALUES (113, 3, 97, 0, false); +INSERT INTO permission.grp_perm_map VALUES (130, 3, 99, 1, false); +INSERT INTO permission.grp_perm_map VALUES (131, 3, 100, 1, false); +INSERT INTO permission.grp_perm_map VALUES (22, 4, 18, 0, false); +INSERT INTO permission.grp_perm_map VALUES (24, 4, 20, 0, false); +INSERT INTO permission.grp_perm_map VALUES (38, 4, 21, 2, false); +INSERT INTO permission.grp_perm_map VALUES (34, 4, 22, 2, false); +INSERT INTO permission.grp_perm_map VALUES (39, 4, 23, 2, false); +INSERT INTO permission.grp_perm_map VALUES (35, 4, 25, 2, false); +INSERT INTO permission.grp_perm_map VALUES (129, 4, 26, 2, false); +INSERT INTO permission.grp_perm_map VALUES (15, 4, 8, 2, false); +INSERT INTO permission.grp_perm_map VALUES (40, 4, 24, 2, false); +INSERT INTO permission.grp_perm_map VALUES (23, 4, 19, 0, false); +INSERT INTO permission.grp_perm_map VALUES (66, 4, 55, 2, false); +INSERT INTO permission.grp_perm_map VALUES (134, 10, 51, 1, false); +INSERT INTO permission.grp_perm_map VALUES (75, 10, 66, 2, false); +INSERT INTO permission.grp_perm_map VALUES (76, 10, 67, 2, false); +INSERT INTO permission.grp_perm_map VALUES (77, 10, 68, 2, false); +INSERT INTO permission.grp_perm_map VALUES (78, 10, 69, 2, false); +INSERT INTO permission.grp_perm_map VALUES (79, 10, 70, 2, false); +INSERT INTO permission.grp_perm_map VALUES (80, 10, 71, 2, false); +INSERT INTO permission.grp_perm_map VALUES (87, 10, 78, 2, false); +INSERT INTO permission.grp_perm_map VALUES (105, 10, 91, 1, false); +INSERT INTO permission.grp_perm_map VALUES (106, 10, 92, 1, false); +INSERT INTO permission.grp_perm_map VALUES (107, 10, 93, 0, false); +INSERT INTO permission.grp_perm_map VALUES (114, 10, 98, 1, false); +INSERT INTO permission.grp_perm_map VALUES (132, 10, 101, 1, true); +INSERT INTO permission.grp_perm_map VALUES (136, 10, 102, 1, false); +INSERT INTO permission.grp_perm_map VALUES (137, 10, 103, 1, false); +INSERT INTO permission.grp_perm_map VALUES (97, 5, 41, 0, false); +INSERT INTO permission.grp_perm_map VALUES (96, 5, 43, 0, false); +INSERT INTO permission.grp_perm_map VALUES (93, 5, 48, 0, false); +INSERT INTO permission.grp_perm_map VALUES (94, 5, 53, 0, false); +INSERT INTO permission.grp_perm_map VALUES (133, 5, 102, 0, false); +INSERT INTO permission.grp_perm_map VALUES (138, 5, 104, 1, false); + +SELECT SETVAL('permission.grp_perm_map_id_seq'::TEXT, (SELECT MAX(id) FROM permission.grp_perm_map)); + +-- Admin user account +INSERT INTO actor.usr ( profile, card, usrname, passwd, first_given_name, family_name, dob, master_account, super_user, ident_type, ident_value, home_ou ) VALUES ( 1, 1, 'admin', 'open-ils', oils_i18n_gettext('Administrator'), oils_i18n_gettext('System Account'), '1979-01-22', TRUE, TRUE, 1, 'identification', 1 ); + +-- Admin user barcode +INSERT INTO actor.card (usr, barcode) VALUES (1,'101010101010101'); +UPDATE actor.usr SET card = (SELECT id FROM actor.card WHERE barcode = '101010101010101') WHERE id = 1; + +-- Admin user permissions INSERT INTO permission.usr_perm_map (usr,perm,depth) VALUES (1,-1,0); --010.schema.biblio.sql: @@ -968,3 +1273,35 @@ INSERT INTO biblio.record_entry VALUES (-1,1,1,1,-1,NOW(),NOW(),FALSE,FALSE,'',' --040.schema.asset.sql: INSERT INTO asset.copy_location (name,owning_lib) VALUES (oils_i18n_gettext('Stacks'),1); INSERT INTO asset.call_number VALUES (-1,1,NOW(),1,NOW(),-1,1,'UNCATALOGED'); + +-- some more from 002.schema.config.sql: +INSERT INTO config.xml_transform VALUES ( 'marcxml', 'http://www.loc.gov/MARC21/slim', 'marc', '---' ); +INSERT INTO config.xml_transform VALUES ( 'mods', 'http://www.loc.gov/mods/', 'mods', ''); +INSERT INTO config.xml_transform VALUES ( 'mods3', 'http://www.loc.gov/mods/v3', 'mods3', ''); +INSERT INTO config.xml_transform VALUES ( 'mods32', 'http://www.loc.gov/mods/v3', 'mods32', ''); + +-- circ matrix +INSERT INTO config.circ_matrix_matchpoint (org_unit,grp) VALUES (1,1); +INSERT INTO config.circ_matrix_ruleset (matchpoint,duration_rule,recurring_fine_rule,max_fine_rule) VALUES (1,11,1,1); + +-- Staged Search (for default matchpoints) +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(1, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(1, 'full_match', 20); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(2, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(2, 'word_order', 10); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(2, 'full_match', 20); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(3, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(3, 'word_order', 10); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(3, 'full_match', 20); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(4, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(4, 'word_order', 10); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(4, 'full_match', 20); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(5, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(5, 'word_order', 10); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(5, 'full_match', 20); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(6, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(7, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(8, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(9, 'first_word', 1.5); +INSERT INTO search.relevance_adjustment (field, bump_type, multiplier) VALUES(14, 'word_order', 10); + diff --git a/Open-ILS/src/sql/Pg/951.data.MODS-xsl.sql b/Open-ILS/src/sql/Pg/951.data.MODS-xsl.sql new file mode 100644 index 0000000000..9f610c44c4 --- /dev/null +++ b/Open-ILS/src/sql/Pg/951.data.MODS-xsl.sql @@ -0,0 +1,2143 @@ +UPDATE config.xml_transform SET xslt=$$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BK + SE + + + BK + MM + CF + MP + VM + MU + + + + + + + + + + + + + b + afghk + + + + + abfghk + + + + + + + + + + + <xsl:value-of select="substring($title,@ind2+1)"/> + + + + + <xsl:value-of select="$title"/> + + + + + + + + + b + b + afghk + + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">ab</xsl:with-param> + </xsl:call-template> + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">abh</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">abfh</xsl:with-param> + </xsl:call-template> + + + + + + + + + <xsl:variable name="str"> + <xsl:for-each select="marc:subfield"> + <xsl:if test="(contains('adfkmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))"> + <xsl:value-of select="text()"/> + <xsl:text> </xsl:text> + </xsl:if> + </xsl:for-each> + </xsl:variable> + <xsl:value-of select="substring($str,1,string-length($str)-1)"/> + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">ah</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + creator + + + + + + + + + + + creator + + + + + + + + + + creator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + personal + + + + + + + + + + + yes + + + yes + + + + text + cartographic + notated music + sound recording + still image + moving image + three dimensional object + software, multimedia + mixed material + + + + + globe + + + + remote sensing image + + + + + + + map + + + atlas + + + + + + + + + database + + + loose-leaf + + + series + + + newspaper + + + periodical + + + web site + + + + + + + + + abstract or summary + + + bibliography + + + catalog + + + dictionary + + + encyclopedia + + + handbook + + + legal article + + + index + + + discography + + + legislation + + + theses + + + survey of literature + + + review + + + programmed text + + + filmography + + + directory + + + statistics + + + technical report + + + legal case and case notes + + + law report or digest + + + treaty + + + + + + conference publication + + + + + + + + + numeric data + + + database + + + font + + + game + + + + + + + patent + + + festschrift + + + + + biography + + + + + + essay + + + drama + + + comic strip + + + fiction + + + humor, satire + + + letter + + + novel + + + short story + + + speech + + + + + + + + biography + + + conference publication + + + drama + + + essay + + + fiction + + + folktale + + + history + + + humor, satire + + + memoir + + + poetry + + + rehersal + + + reporting + + + sound + + + speech + + + + + + + + art original + + + kit + + + art reproduction + + + diorama + + + filmstrip + + + legal article + + + picture + + + graphic + + + technical drawing + + + motion picture + + + chart + + + flash card + + + microscope slide + + + model + + + realia + + + slide + + + transparency + + + videorecording + + + toy + + + + + + + + + + + abvxyz + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + monographic + continuing + + + + + + + + ab + + + + + + + + + + + + rfc3066 + + + iso639-2b + + + + + + + + + + + + + + + + + reformatted digital + + + + + + + + + + + + + + + + + + + +
braille
+
+ +
print
+
+ +
electronic
+
+ +
microfiche
+
+ +
microfilm
+
+
+ + + + + access + + + preservation + + + replacement + + + + + + + + + + + +
+
+ + + + + abce + + + +
+ + + + + + + + + + + + ab + + + + + + + + + agrt + + + + + + + + ab + + + + + + + + + adolescent + + + adult + + + general + + + juvenile + + + preschool + + + specialized + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + defg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + + + + abx + + + + + + + + ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">av</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">av</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + + + + + + + abcq + t + g + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">dg</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + c + t + dgn + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + + + + + + + aqdc + t + gn + + + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfgklmorsv</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + <xsl:value-of select="marc:subfield[@code='a']"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + + + + + + + + + abcq + t + g + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">dg</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + c + t + dgn + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + + + + + + + aqdc + t + gn + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfgklmorsv</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + issue number + matrix number + music plate + music publisher + videorecording identifier + + + + ab + + + + + + + + + ab + + + + + + + + + ab + + + + + + + + + + doi + uri + + + + + + + + + + + + + + + + + + abj + + + + + + + + abcd35 + + + + + + + + abcde35 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n + n + fghkdlmor + + + + + p + p + fghkdlmor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cdn + + + + + + + + + + + abcq + + + + + + + + + + + acdeq + + + + + + + + constituent + related + + + + + + + + + <xsl:value-of select="."/> + + + + + + + + + + <xsl:value-of select="."/> + + + + + + + + + + + + + + + + + + + + + + + + lcsh + lcshac + mesh + + nal + csh + rvm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + abcq + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cdnp + + + + + + + + + + + + + + + + abcdeqnp + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfhklor</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + abcd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + yes + + + + + + + + Arabic + Latin + Chinese, Japanese, Korean + Cyrillic + Hebrew + Greek + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .:,;/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+$$ WHERE name = 'mods'; + diff --git a/Open-ILS/src/sql/Pg/952.data.MODS3-xsl.sql b/Open-ILS/src/sql/Pg/952.data.MODS3-xsl.sql new file mode 100644 index 0000000000..ee6d1b7125 --- /dev/null +++ b/Open-ILS/src/sql/Pg/952.data.MODS3-xsl.sql @@ -0,0 +1,2863 @@ +UPDATE config.xml_transform SET xslt=$$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BK + SE + + + BK + MM + CF + MP + VM + MU + + + + + + + + + + b + afghk + + + + + abfgk + + + + + + + + + + + + + + + + + + + <xsl:value-of select="substring($titleChop,@ind2+1)"/> + + + + + <xsl:value-of select="$titleChop"/> + + + + + + + + + b + b + afghk + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">a</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <!-- 1/04 removed $h, b --> + <xsl:with-param name="codes">a</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <!-- 1/04 removed $h, $b --> + <xsl:with-param name="codes">af</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + <xsl:variable name="str"> + <xsl:for-each select="marc:subfield"> + <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))"> + <xsl:value-of select="text()"/> + <xsl:text> </xsl:text> + </xsl:if> + </xsl:for-each> + </xsl:variable> + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="substring($str,1,string-length($str)-1)"/> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">ah</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + creator + + + + + + + + + + creator + + + + + + + + + + creator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + personal + + + + + + + + + + + + yes + + + yes + + + text + cartographic + notated music + sound recording-nonmusical + sound recording-musical + still image + moving image + three dimensional object + software, multimedia + mixed material + + + + + globe + + + + remote sensing image + + + + + + + map + + + atlas + + + + + + + + + database + + + loose-leaf + + + series + + + newspaper + + + periodical + + + web site + + + + + + + + + abstract or summary + + + bibliography + + + catalog + + + dictionary + + + encyclopedia + + + handbook + + + legal article + + + index + + + discography + + + legislation + + + theses + + + survey of literature + + + review + + + programmed text + + + filmography + + + directory + + + statistics + + + technical report + + + legal case and case notes + + + law report or digest + + + treaty + + + + + + conference publication + + + + + + + + + numeric data + + + database + + + font + + + game + + + + + + + patent + + + festschrift + + + + + biography + + + + + + essay + + + drama + + + comic strip + + + fiction + + + humor, satire + + + letter + + + novel + + + short story + + + speech + + + + + + + + biography + + + conference publication + + + drama + + + essay + + + fiction + + + folktale + + + history + + + humor, satire + + + memoir + + + poetry + + + rehearsal + + + reporting + + + sound + + + speech + + + + + + + + art original + + + kit + + + art reproduction + + + diorama + + + filmstrip + + + legal article + + + picture + + + graphic + + + technical drawing + + + motion picture + + + chart + + + flash card + + + microscope slide + + + model + + + realia + + + slide + + + transparency + + + videorecording + + + toy + + + + + + + + + + + abvxyz + - + + + + + + + + + + + code + marccountry + + + + + + + + + code + iso3166 + + + + + + + + + text + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :,;/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + monographic + continuing + + + + + + + + ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + reformatted digital + + + + + + + + + + + + + + + + + + + +
braille
+
+ +
print
+
+ +
electronic
+
+ +
microfiche
+
+ +
microfilm
+
+
+ + +
+ + + + + +
+
+ + +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ + +
+ + + + + access + + + preservation + + + replacement + + + + + + + + + + + + + + abce + + + +
+ + + + + + + + + + + + ab + + + + + + + + + agrt + + + + + + + + ab + + + + + + + + + + adolescent + + + adult + + + general + + + juvenile + + + preschool + + + specialized + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + defg + + + + + + + + + + + + + marcgac + + + + + + iso3166 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + + + + abx + + + + + + + + ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">av</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">av</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + abcx3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + aq + t + g + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">dg</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + c + t + dgn + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + aqdc + t + gn + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfgklmorsv</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="marc:subfield[@code='a']"/> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + aq + t + g + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">dg</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + + c + t + dgn + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + aqdc + t + gn + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfgklmorsv</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + issue number + matrix number + music plate + music publisher + videorecording identifier + + + + + + ba + ab + + + + + + + + + + + ab + + + + + + + + + ab + + + + + + + + + doi + hdl + uri + + + + + + + + + + + + + + + + + y3z + + + + + + + + + + + + + + + + + + + + + + y3 + + + + + + + + + + + + + + abje + + + + + + + + + abcd35 + + + + + + + + abcde35 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n + n + fghkdlmor + + + + + p + p + fghkdlmor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + g + g + pst + + + + + p + p + fghkdlmor + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cdn + + + + + + + + + + + aq + + + + :,;/ + + + + + + + + + + + acdeq + + + + + + + constituent + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="."/> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="."/> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="."/> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="."/> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + code + marcgac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lcsh + lcshac + mesh + + nal + csh + rvm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + aq + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cdnp + + + + + + + + + + + + + + + + abcdeqnp + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfhklor</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="part"/> + + + + + + + + + + + + + + abcd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bc + + + + + + + + + + + + + + + + + + + + + + + yes + + + + + + + + + + + + + + + + + + + + + + Arabic + Latin + Chinese, Japanese, Korean + Cyrillic + Hebrew + Greek + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .:,;/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$$ WHERE name = 'mods3'; diff --git a/Open-ILS/src/sql/Pg/953.data.MODS32-xsl.sql b/Open-ILS/src/sql/Pg/953.data.MODS32-xsl.sql new file mode 100644 index 0000000000..b0f3e4eaac --- /dev/null +++ b/Open-ILS/src/sql/Pg/953.data.MODS32-xsl.sql @@ -0,0 +1,3082 @@ +UPDATE config.xml_transform SET xslt=$$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BK + SE + + + BK + MM + CF + MP + VM + MU + + + + + + + + + b + afgk + + + + + abfgk + + + + + + + + + + + + + + + + + + <xsl:value-of select="substring($titleChop,@ind2+1)"/> + + + + + <xsl:value-of select="$titleChop"/> + + + + + + + + + b + b + afgk + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">a</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <!-- 1/04 removed $h, b --> + <xsl:with-param name="codes">a</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <!-- 1/04 removed $h, $b --> + <xsl:with-param name="codes">af</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + <xsl:variable name="str"> + <xsl:for-each select="marc:subfield"> + <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))"> + <xsl:value-of select="text()"/> + <xsl:text> </xsl:text> + </xsl:if> + </xsl:for-each> + </xsl:variable> + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="substring($str,1,string-length($str)-1)"/> + </xsl:with-param> + </xsl:call-template> + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">ah</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + creator + + + + + + + + + creator + + + + + + + + + creator + + + + + + + + + + + + + + + + + + + + + + + + + + + + personal + + + + + + + + + + + yes + + + yes + + + text + cartographic + notated music + sound recording-nonmusical + sound recording-musical + still image + moving image + three dimensional object + software, multimedia + mixed material + + + + globe + + + remote sensing image + + + + + + map + + + atlas + + + + + + + + database + + + loose-leaf + + + series + + + newspaper + + + periodical + + + web site + + + + + + + + abstract or summary + + + bibliography + + + catalog + + + dictionary + + + encyclopedia + + + handbook + + + legal article + + + index + + + discography + + + legislation + + + theses + + + survey of literature + + + review + + + programmed text + + + filmography + + + directory + + + statistics + + + technical report + + + legal case and case notes + + + law report or digest + + + treaty + + + + + + conference publication + + + + + + + + numeric data + + + database + + + font + + + game + + + + + + patent + + + festschrift + + + + biography + + + + + essay + + + drama + + + comic strip + + + fiction + + + humor, satire + + + letter + + + novel + + + short story + + + speech + + + + + + + biography + + + conference publication + + + drama + + + essay + + + fiction + + + folktale + + + history + + + humor, satire + + + memoir + + + poetry + + + rehearsal + + + reporting + + + sound + + + speech + + + + + + + art original + + + kit + + + art reproduction + + + diorama + + + filmstrip + + + legal article + + + picture + + + graphic + + + technical drawing + + + motion picture + + + chart + + + flash card + + + microscope slide + + + model + + + realia + + + slide + + + transparency + + + videorecording + + + toy + + + + + + + + + + abvxyz + - + + + + + + + + + code + marccountry + + + + + + + + code + iso3166 + + + + + + + + text + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :,;/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + monographic + continuing + + + + + + + ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + reformatted digital + + + digitized microfilm + + + digitized other analog + + + + + + + + + + + + + + + +
braille
+
+ +
print
+
+ +
electronic
+
+ +
microfiche
+
+ +
microfilm
+
+
+ + +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ + + + + +
+
+ +
+ +
+
+ + + + access + + + preservation + + + replacement + + + + + +
chip cartridge
+
+ +
computer optical disc cartridge
+
+ +
magnetic disc
+
+ +
magneto-optical disc
+
+ +
optical disc
+
+ +
remote
+
+ +
tape cartridge
+
+ +
tape cassette
+
+ +
tape reel
+
+ + +
celestial globe
+
+ +
earth moon globe
+
+ +
planetary or lunar globe
+
+ +
terrestrial globe
+
+ + +
kit
+
+ + +
atlas
+
+ +
diagram
+
+ +
map
+
+ +
model
+
+ +
profile
+
+ +
remote-sensing image
+
+ +
section
+
+ +
view
+
+ + +
aperture card
+
+ +
microfiche
+
+ +
microfiche cassette
+
+ +
microfilm cartridge
+
+ +
microfilm cassette
+
+ +
microfilm reel
+
+ +
microopaque
+
+ + +
film cartridge
+
+ +
film cassette
+
+ +
film reel
+
+ + +
chart
+
+ +
collage
+
+ +
drawing
+
+ +
flash card
+
+ +
painting
+
+ +
photomechanical print
+
+ +
photonegative
+
+ +
photoprint
+
+ +
picture
+
+ +
print
+
+ +
technical drawing
+
+ + +
notated music
+
+ + +
filmslip
+
+ +
filmstrip cartridge
+
+ +
filmstrip roll
+
+ +
other filmstrip type
+
+ +
slide
+
+ +
transparency
+
+ +
remote-sensing image
+
+ +
cylinder
+
+ +
roll
+
+ +
sound cartridge
+
+ +
sound cassette
+
+ +
sound disc
+
+ +
sound-tape reel
+
+ +
sound-track film
+
+ +
wire recording
+
+ + +
braille
+
+ +
combination
+
+ +
moon
+
+ +
tactile, with no writing system
+
+ + +
braille
+
+ +
large print
+
+ +
regular print
+
+ +
text in looseleaf binder
+
+ + +
videocartridge
+
+ +
videocassette
+
+ +
videodisc
+
+ +
videoreel
+
+ + + + + + + + + + abce + + + +
+ + + + + + + + + + ab + + + + + + + + agrt + + + + + + + ab + + + + + + + + + adolescent + + + adult + + + general + + + juvenile + + + preschool + + + specialized + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + defg + + + + + + + + + + + + marcgac + + + + + + iso3166 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + + + abx + + + + + + + ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">av</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">av</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + abcx3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + aq + t + g + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">dg</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + c + t + dgn + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + aqdc + t + gn + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfgklmorsv</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + aq + t + g + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">dg</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + c + t + dgn + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + aqdc + t + gn + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfgklmorsv</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + isbn + + + + + + + + + + isrc + + + + + + + + + + ismn + + + + + + + + + + sici + + + + ab + + + + + + issn + + + + + + + + lccn + + + + + + + + + + issue number + matrix number + music plate + music publisher + videorecording identifier + + + + + + + ba + ab + + + + + + + + + + ab + + + + + + + + doi + hdl + uri + + + + + + + + + + + + + + + + + y3z + + + + + + + + + + + + + + + + + + + + + y3 + + + + + + + z + + + + + + + + + + + + + + + + + + abje + + + + + + + + abcd35 + + + + + + + abcde35 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n + n + fgkdlmor + + + + + p + p + fgkdlmor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + g + g + pst + + + + + p + p + fgkdlmor + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cdn + + + + + + + + + + aq + + + + :,;/ + + + + + + + + + + acdeq + + + + + + constituent + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="."></xsl:value-of> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="."></xsl:value-of> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="."></xsl:value-of> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:value-of select="."></xsl:value-of> + </xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + code + marcgac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lcsh + lcshac + mesh + + nal + csh + rvm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + aq + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cdnp + + + + + + + + + + + + + + + abcdeqnp + + + + + + + + + + + + + + + + + + + <xsl:call-template name="chopPunctuation"> + <xsl:with-param name="chopString"> + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfhklor</xsl:with-param> + </xsl:call-template> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="part"></xsl:call-template> + + + + + + + + + + + + + abcd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bc + + + + + + + + + + + + + + + + + + + + + + + + + + + yes + + + + + + + + + + + + + + + + + + + + + + + + + + + Arabic + Latin + Chinese, Japanese, Korean + Cyrillic + Hebrew + Greek + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + summary or subtitle + sung or spoken text + libretto + table of contents + accompanying material + translation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + summary or subtitle + sung or spoken text + libretto + table of contents + accompanying material + translation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .:,;/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$$ WHERE name = 'mods32'; diff --git a/Open-ILS/src/sql/Pg/build-db.sh b/Open-ILS/src/sql/Pg/build-db.sh index 276b3f1078..cf738be1d2 100755 --- a/Open-ILS/src/sql/Pg/build-db.sh +++ b/Open-ILS/src/sql/Pg/build-db.sh @@ -19,11 +19,19 @@ PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 080.schema.mon PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 090.schema.action.sql PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 200.schema.acq.sql +PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 100.circ_matrix.sql +PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 110.hold_matrix.sql + +PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 300.schema.staged_search.sql + PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 500.view.cross-schema.sql PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 800.fkeys.sql PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 900.audit-functions.sql PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 901.audit-tables.sql PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 950.data.seed-values.sql +PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 951.data.MODS-xsl.sql +PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 952.data.MODS3-xsl.sql +PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f 953.data.MODS32-xsl.sql PGPASSWORD=$5 PGUSER=$4 PGHOST=$1 PGPORT=$2 PGDATABASE=$3 psql -f reporter-schema.sql diff --git a/Open-ILS/src/sql/Pg/example.reporter-extension.sql b/Open-ILS/src/sql/Pg/example.reporter-extension.sql index 88d310e2ac..c359d911be 100644 --- a/Open-ILS/src/sql/Pg/example.reporter-extension.sql +++ b/Open-ILS/src/sql/Pg/example.reporter-extension.sql @@ -154,6 +154,75 @@ SELECT x.id AS id, JOIN reporter.demographic dem ON (dem.id = u.id) JOIN actor.usr_address paddr ON (paddr.id = u.billing_address); +CREATE OR REPLACE VIEW reporter.classic_item_list AS +SELECT t.value as title, + a.value as author, + p.value as pubdate, + cp.id, + cp.price, + cp.barcode, + cn.label as call_number_label, + CASE + WHEN call_number_dewey(cn.label) ~ E'^[0-9.]+$' + THEN + btrim( + to_char( + 10 * floor((call_number_dewey(cn.label)::float) / 10), '000' + ) + ) + ELSE NULL + END AS dewey_block_tens, + CASE + WHEN call_number_dewey(cn.label) ~ E'^[0-9.]+$' + THEN + btrim( + to_char( + 100 * floor((call_number_dewey(cn.label)::float) / 100), '000' + ) + ) + ELSE NULL + END AS dewey_block_hundreds, + (SELECT COUNT(*) FROM action.circulation WHERE target_copy = cp.id) as use_count, + cp.circ_modifier, + sl.name AS shelving_location, + sc1.stat_cat_entry AS stat_cat_1, + sc2.stat_cat_entry AS stat_cat_2, + sce1.value AS stat_cat_1_value, + sce2.value AS stat_cat_2_value, + cp.edit_date, + cp.create_date, + ol.shortname AS owning_lib_name, + cn.owning_lib, + cl.shortname AS circ_lib_name, + cl.id AS circ_lib, + cp.creator, + cp.age_protect, + cp.opac_visible, + cp.ref, + cp.deposit_amount, + cp.deleted, + b.tcn_value, + cp.status, + circ.stop_fines, + circ.due_date, + circ_card.barcode as patron_barcode, + circ_u.first_given_name || ' ' || circ_u.family_name as patron_name + FROM asset.copy cp + JOIN asset.copy_location sl ON (cp.location = sl.id) + JOIN asset.call_number cn ON (cp.call_number = cn.id) + JOIN biblio.record_entry b ON (cn.record = b.id) + JOIN actor.org_unit ol ON (cn.owning_lib = ol.id) + JOIN actor.org_unit cl ON (cp.circ_lib = cl.id) + LEFT JOIN metabib.full_rec t ON (cn.record = t.record AND t.tag = '245' and t.subfield = 'a') + LEFT JOIN metabib.full_rec a ON (cn.record = a.record AND a.tag = '100' and a.subfield = 'a') + LEFT JOIN metabib.full_rec p ON (cn.record = p.record AND p.tag = '260' and p.subfield = 'c') + LEFT JOIN action.circulation circ ON (circ.target_copy = cp .id AND circ.checkin_time IS NULL) + LEFT JOIN actor.usr circ_u ON (circ_u.id = circ.usr) + LEFT JOIN actor.card circ_card ON (circ_u.id = circ_card.usr) + LEFT JOIN asset.stat_cat_entry_copy_map sc1 ON (sc1.owning_copy = cp.id AND sc1.stat_cat = 1) + LEFT JOIN asset.stat_cat_entry sce1 ON (sce1.id = sc1.stat_cat_entry) + LEFT JOIN asset.stat_cat_entry_copy_map sc2 ON (sc2.owning_copy = cp.id AND sc2.stat_cat = 2) + LEFT JOIN asset.stat_cat_entry sce2 ON (sce2.id = sc2.stat_cat_entry); COMMIT; diff --git a/Open-ILS/src/support-scripts/brick_ctl.sh b/Open-ILS/src/support-scripts/brick_ctl.sh index e64674b589..f42c7a307f 100755 --- a/Open-ILS/src/support-scripts/brick_ctl.sh +++ b/Open-ILS/src/support-scripts/brick_ctl.sh @@ -1,42 +1,32 @@ #!/bin/bash -# ------------------------------------------------------------------- -# -# XXX This probably only works on Linux for now... +# --------------------------------------------------------------- +# Copyright (C) 2007-2008 Georgia Public Library Service # +# 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. +# --------------------------------------------------------------- + +# ------------------------------------------------------------------- # This script is used to manage "bricks", which are collections of # servers all serving a single OpenSRF domain. There will be 1 -# lead machine, which will typcically run this script, and 1 or more +# master machine, which will typcically run this script, and 1 or more # drones, which respond to this script. -# -# XXX The fetching and build commands need to be updated to work -# with the now-separated OpenSRF 0.9 and Evergreen 1.2 # ------------------------------------------------------------------- -[ -f /etc/profile ] && . /etc/profile -[ -f ~/.bashrc ] && . ~/.bashrc - -DRONE_COUNT=2; # how many drones are in this brick -ETH_DEV="eth0" # ethernet device -PREFIX="/openils" # the installed ILS files prefix -# this is useful if you are using ldirector. we can -# "detach" a brick by removing the ldirector ping file -LDIRECTOR_FILE="/$PREFIX/var/web/ldirectorping.txt" +# TODO finish the download and build functionality -# XXX needs work -SRC_DIR="/home/opensrf/ILS"; -STAFF_CLIENT_BUILD_ID="sc_v100_rc2"; -XUL_BASE="/$PREFIX/var/web/xul"; - -IP_PREFIX=$(/sbin/ifconfig | grep -A1 $ETH_DEV | grep inet | cut -d'.' -f1,2,3 | cut -d':' -f2); -IP=$(/sbin/ifconfig | grep -A1 $ETH_DEV | grep inet | cut -d'.' -f 4 | cut -d' ' -f1); -FIRST=$(expr $IP + 1); -LAST=$(expr $IP + $DRONE_COUNT); +[ -f /etc/profile ] && . /etc/profile +[ -f ~/.bashrc ] && . ~/.bashrc -OSRF_PID_DIR="/tmp/"; -OSRF_CONFIG="/$PREFIX/conf/opensrf_core.xml"; -LOCAL_BASE="osrf_ctl.sh -d $OSRF_PID_DIR -c $OSRF_CONFIG"; -DRONE_BASE=". /etc/profile && osrf_ctl.sh -d $OSRF_PID_DIR -c $OSRF_CONFIG"; +DEFAULT_CONFIG=~/.oils_brick.cfg # ------------------------------------------------------------------- @@ -44,175 +34,188 @@ DRONE_BASE=". /etc/profile && osrf_ctl.sh -d $OSRF_PID_DIR -c $OSRF_CONFIG"; # ------------------------------------------------------------------- [ $(whoami) != 'opensrf' ] && echo 'Must run as user "opensrf"' && exit; + function usage { - echo ""; - echo "usage: $0 -a " - echo " -u : host + path URL where the download file lives"; - echo " -f : the name of the bundle to fetch"; - echo " -x : the destination xul directory"; - echo "Actions:"; - echo " fetch"; - echo " start_perl"; - echo " start_c"; - echo " start_perl_c"; - echo " start_all"; - echo " stop_perl"; - echo " stop_c"; - echo " stop_perl_c"; - echo " stop_all"; - echo " restart_perl"; - echo " restart_c"; - echo " restart_perl_c"; - echo " restart_all"; - echo " build"; - echo " build_xul"; - echo " detach_brick"; - echo " attach_brick"; - exit 0; + echo ""; + echo "usage: $0 -a " + echo " -u : host + path URL where the download file lives"; + echo " -f : the name of the bundle to fetch"; + echo " -x : staff client build directory"; + echo " -i : staff client build ID"; + echo "Actions:"; + echo " fetch"; + echo " start_perl"; + echo " start_c"; + echo " start_osrf"; + echo " start_all"; + echo " stop_perl"; + echo " stop_c"; + echo " stop_osrf"; + echo " stop_all"; + echo " restart_perl"; + echo " restart_c"; + echo " restart_osrf"; + echo " restart_all"; + echo " build"; + echo " build_xul"; + echo " detach_brick"; + echo " attach_brick"; + exit 0; } # ------------------------------------------------------------------- # Load the config opts # ------------------------------------------------------------------- -while getopts "a:x:bf:hu:" flag; do - case $flag in - "a") OPT_ACTION="$OPTARG";; - "x") OPT_XUL_DIR="$OPTARG";; - "u") OPT_FETCH_BASE_URL="$OPTARG";; - "f") OPT_FETCH_FILE="$OPTARG";; - "h"|*) usage;; - esac; +while getopts "a:x:bf:hu:c:i:" flag; do + case $flag in + "a") OPT_ACTION="$OPTARG";; + "u") OPT_FETCH_BASE_URL="$OPTARG";; + "f") OPT_FETCH_FILE="$OPTARG";; + "x") OPT_XUL_BUILD_DIR="$OPTARG";; + "i") OPT_XUL_BUILD_ID="$OPTARG";; + "c") OPT_CONFIG_FILE="$OPTARG";; + "h"|*) usage;; + esac; done - - +# ------------------------------------------------------------------- +# Load the config file +# ------------------------------------------------------------------- +if [ -e "$OPT_CONFIG_FILE" ]; then + . $OPT_CONFIG_FILE; +else + if [ -e ~/.oils_brick.cfg ]; then + . $DEFAULT_CONFIG; + else + echo "Please specify a valid config file or create one at $DEFAULT_CONFIG"; + fi; +fi; + + +# make sure an action was specified [ -z "$OPT_ACTION" ] && usage; +LOCAL_BASE="osrf_ctl.sh -d $OSRF_PID_DIR -c $OSRF_CONFIG"; +DRONE_BASE=". /etc/profile && osrf_ctl.sh -d $OSRF_PID_DIR -c $OSRF_CONFIG"; # ------------------------------------------------------------------- -# Runs DRONE_ACT on the drones, the LOCAL_ACT on the local machine +# Runs DRONE_ACT on the drones, then LOCAL_ACT on the local machine # ------------------------------------------------------------------- function drone_first { - LOCAL_ACT=$1 - DRONE_ACT=$2 - SLEEP=$3; - echo -e "\ndrone_first() $LOCAL_ACT\n"; - for(( i = $FIRST; i <= $LAST; i++ )) { - echo -e "\n$IP_PREFIX.$i\n" - ssh $OPT_SSH_BACKGROUND "$IP_PREFIX.$i" "$DRONE_ACT"; - [ -n "$SLEEP" -a -n "$OPT_SSH_BACKGROUND" ] && sleep $SLEEP; - } - $LOCAL_ACT; + LOCAL_ACT=$1 + DRONE_ACT=$2 + echo "drone_first(): $LOCAL_ACT"; + for drone in ${DRONES[@]:0}; do + echo "* $drone" + ssh "$drone" "$DRONE_ACT"; + done; + $LOCAL_ACT; } # ------------------------------------------------------------------- -# Runs LOCAL_ACT on the local machine and DRONE_ACT on the drones +# Runs LOCAL_ACT on the local machine then DRONE_ACT on the drones # ------------------------------------------------------------------- function local_first { - LOCAL_ACT=$1 - DRONE_ACT=$2 - SLEEP=$3; - echo -e "\nlocal_first() $LOCAL_ACT\n"; - $LOCAL_ACT; - for(( i = $FIRST; i <= $LAST; i++ )) { - echo -e "\n$IP_PREFIX.$i\n" - ssh $OPT_SSH_BACKGROUND "$IP_PREFIX.$i" "$DRONE_ACT"; - [ -n "$SLEEP" -a -n "$OPT_SSH_BACKGROUND" ] && sleep $SLEEP; - } + LOCAL_ACT=$1 + DRONE_ACT=$2 + echo "local_first(): $LOCAL_ACT"; + $LOCAL_ACT; + for drone in ${DRONES[@]:0}; do + echo "* $drone" + ssh "$drone" "$DRONE_ACT"; + done; } function make_xul { - [ -z "$OPT_XUL_DIR" ] && echo "Try again with -x to specify xul directory" && exit; - DIR="$XUL_BASE/$OPT_XUL_DIR"; - echo "Building XUL and copying to $DIR"; - cd "$SRC_DIR/Open-ILS/xul/staff_client" - make clean; - make STAFF_CLIENT_BUILD_ID="$STAFF_CLIENT_BUILD_ID"; - cd /$PREFIX/var/web/xul/ - mkdir -p "$DIR"; - cd "$DIR"; - cp -r "$SRC_DIR/Open-ILS/xul/staff_client/build/server" "$DIR"; - #cp /$PREFIX/var/web/xul/*.jpg "$DIR/server/"; - #cp /$PREFIX/var/web/xul/index.html "$DIR/server/"; - #cd /$PREFIX/var/web/xul/; - echo -e "\n[pwd=$PWD] Linking to new build directory: $STAFF_CLIENT_BUILD_ID -> $DIR\n"; - rm "$STAFF_CLIENT_BUILD_ID"; - ln -s "$OPT_XUL_DIR" "$STAFF_CLIENT_BUILD_ID"; + DIR="$XUL_BASE/$OPT_XUL_BUILD_DIR"; + echo "Building XUL and copying to $DIR"; + cd "$OILS_SRC_DIR/Open-ILS/xul/staff_client" + make clean; + make STAFF_CLIENT_BUILD_ID="$OPT_XUL_BUILD_ID"; + cd "$XUL_BASE"; + mkdir -p "$DIR"; + cd "$DIR/.."; + cp -r "$OILS_SRC_DIR/Open-ILS/xul/staff_client/build/server" "$DIR"; + echo -e "\nLinking to new build directory: $OPT_XUL_BUILD_ID -> $DIR\n"; + rm -f "$OPT_XUL_BUILD_ID"; + rm -f current; + ln -s "$OPT_XUL_BUILD_DIR" current; + ln -s current "$OPT_XUL_BUILD_ID"; } function detach_brick { - echo -n "Detaching brick..."; - - [ ! -f "$LDIRECTOR_FILE" ] && \ - echo "ping file already moved, skipping ..." && return 0; - - mv -f "$LDIRECTOR_FILE" "$LDIRECTOR_FILE.x" - x=10; - while(sleep 1); do - x=$(expr $x - 1); - echo -n " $x "; - [ $x == 0 ] && break; - done; - echo ""; + echo -n "Detaching brick..."; + + [ ! -f "$LDIRECTOR_FILE" ] && \ + echo "ping file already moved, skipping ..." && return 0; + + mv -f "$LDIRECTOR_FILE" "$LDIRECTOR_FILE-" + x=10; + while(sleep 1); do + x=$(expr $x - 1); + echo -n " $x "; + [ $x == 0 ] && break; + done; + echo ""; } function fetch_build { - [ -z "$OPT_FETCH_BASE_URL" -o -z "$OPT_FETCH_FILE" ] && \ - echo "I need a build URL and a bundle file..." && exit; - - NEW_DIR=${OPT_FETCH_FILE:0:$(expr ${#OPT_FETCH_FILE} - 7)}; - - if [ ! -d "$NEW_DIR" ]; then - - echo "Fetching archive... $OPT_FETCH_BASE_URL$OPT_FETCH_FILE"; - wget -q "$OPT_FETCH_BASE_URL$OPT_FETCH_FILE"; - - [ ! -f "$OPT_FETCH_FILE" ] && \ - echo "Unable to fetch $OPT_FETCH_FILE!" && exit; - - # unpack the new build - echo "Unpacking archive..." - tar -zxf $OPT_FETCH_FILE; - cp "ILS/install.conf" "$NEW_DIR/" - rm $OPT_FETCH_FILE; - fi; - - rm ILS; - ln -s $NEW_DIR ILS + [ -z "$OPT_FETCH_BASE_URL" -o -z "$OPT_FETCH_FILE" ] && \ + echo "I need a build URL and a bundle file..." && exit; + + NEW_DIR=${OPT_FETCH_FILE:0:$(expr ${#OPT_FETCH_FILE} - 7)}; + + if [ ! -d "$NEW_DIR" ]; then + + echo "Fetching archive... $OPT_FETCH_BASE_URL$OPT_FETCH_FILE"; + wget -q "$OPT_FETCH_BASE_URL$OPT_FETCH_FILE"; + + [ ! -f "$OPT_FETCH_FILE" ] && \ + echo "Unable to fetch $OPT_FETCH_FILE!" && exit; + + # unpack the new build + echo "Unpacking archive..." + tar -zxf $OPT_FETCH_FILE; + cp "current/install.conf" "$NEW_DIR/" + rm $OPT_FETCH_FILE; + fi; + + rm current; + ln -s $NEW_DIR current; } case $OPT_ACTION in - "start_perl_c") local_first "$LOCAL_BASE -a start_perl && $LOCAL_BASE -a start_c" \ - "$DRONE_BASE -a start_perl && $DRONE_BASE -a start_c" 4;; + "start_osrf") local_first "$LOCAL_BASE -a start_perl && $LOCAL_BASE -a start_c" \ + "$DRONE_BASE -a start_perl && $DRONE_BASE -a start_c";; - "stop_perl_c") drone_first "$LOCAL_BASE -a stop_perl && $LOCAL_BASE -a stop_c" \ - "$DRONE_BASE -a stop_perl && $DRONE_BASE -a stop_c" 2;; + "stop_osrf") drone_first "$LOCAL_BASE -a stop_perl && $LOCAL_BASE -a stop_c" \ + "$DRONE_BASE -a stop_perl && $DRONE_BASE -a stop_c";; - "restart_perl_c") local_first "$LOCAL_BASE -a restart_perl && $LOCAL_BASE -a restart_c" \ - "$DRONE_BASE -a restart_perl && $DRONE_BASE -a restart_c" 4;; + "restart_osrf") local_first "$LOCAL_BASE -a restart_perl && $LOCAL_BASE -a restart_c" \ + "$DRONE_BASE -a restart_perl && $DRONE_BASE -a restart_c";; - "start_perl") local_first "$LOCAL_BASE -a start_perl" "$DRONE_BASE -a start_perl" 4;; - "stop_perl") drone_first "$LOCAL_BASE -a stop_perl" "$DRONE_BASE -a stop_perl" 2;; - "restart_perl") local_first "$LOCAL_BASE -a restart_perl" "$DRONE_BASE -a restart_perl" 4;; - "start_c") local_first "$LOCAL_BASE -a start_c" "$DRONE_BASE -a start_c" 2;; - "stop_c") drone_first "$LOCAL_BASE -a stop_c" "$DRONE_BASE -a stop_c" 2;; - "restart_c") local_first "$LOCAL_BASE -a restart_c" "$DRONE_BASE -a restart_c" 2;; + "start_perl") local_first "$LOCAL_BASE -a start_perl" "$DRONE_BASE -a start_perl";; + "stop_perl") drone_first "$LOCAL_BASE -a stop_perl" "$DRONE_BASE -a stop_perl";; + "restart_perl") local_first "$LOCAL_BASE -a restart_perl" "$DRONE_BASE -a restart_perl";; + "start_c") local_first "$LOCAL_BASE -a start_c" "$DRONE_BASE -a start_c";; + "stop_c") drone_first "$LOCAL_BASE -a stop_c" "$DRONE_BASE -a stop_c";; + "restart_c") local_first "$LOCAL_BASE -a restart_c" "$DRONE_BASE -a restart_c";; - "start_all") local_first "$LOCAL_BASE -a start_all" \ - "$DRONE_BASE -a start_perl && $DRONE_BASE -a start_c" 4;; + "start_all") local_first "$LOCAL_BASE -a start_all" \ + "$DRONE_BASE -a start_perl && $DRONE_BASE -a start_c";; - "stop_all") drone_first "$LOCAL_BASE -a stop_all" \ - "$DRONE_BASE -a stop_perl && $DRONE_BASE -a stop_c" 2;; + "stop_all") drone_first "$LOCAL_BASE -a stop_all" \ + "$DRONE_BASE -a stop_perl && $DRONE_BASE -a stop_c";; - "restart_all") $0 -a stop_all; $0 -a start_all;; - "build") cd ~/ILS/ && make clean default_config all;; - "build_xul") make_xul;; - "detach_brick") detach_brick;; - "attach_brick") mv "$LDIRECTOR_FILE.x" "$LDIRECTOR_FILE";; - "fetch") fetch_build;; + "restart_all") $0 -a stop_all; $0 -a start_all;; + "build") cd ~/ILS/ && make clean default_config all;; + "build_xul") make_xul;; + "detach_brick") detach_brick;; + "attach_brick") mv "$LDIRECTOR_FILE-" "$LDIRECTOR_FILE";; + "fetch") fetch_build;; esac; diff --git a/Open-ILS/src/support-scripts/offline-blocked-list.pl b/Open-ILS/src/support-scripts/offline-blocked-list.pl index e2714e3a00..42327d01bf 100755 --- a/Open-ILS/src/support-scripts/offline-blocked-list.pl +++ b/Open-ILS/src/support-scripts/offline-blocked-list.pl @@ -16,11 +16,13 @@ if(1) { # XXX command line param use OpenSRF::Utils::JSON; use IPC::Open2 qw/open2/; + use Net::Domain qw/hostfqdn/; sub runmethod { my $method = shift; my $flag = shift; - my $command = "echo \"open-ils.storage $method\" | $oils_reqr -f $config -c $context"; + my $hostname = hostfqdn(); + my $command = "echo \"open-ils.storage $method\" | $oils_reqr -f $config -c $context -h $hostname"; warn "-> $command\n"; my ($child_stdout, $child_stdin); diff --git a/Open-ILS/src/support-scripts/oils_brick.cfg.example b/Open-ILS/src/support-scripts/oils_brick.cfg.example new file mode 100644 index 0000000000..68c69e5368 --- /dev/null +++ b/Open-ILS/src/support-scripts/oils_brick.cfg.example @@ -0,0 +1,18 @@ +# install prefix +export PREFIX=/openils +# this is the lead machine +export MASTER="10.1.0.10" +# array of drone machines +export DRONES=("10.1.0.11" "10.1.0.12" "10.1.0.13" "10.1.0.14") +# if you use ldirector (or similar), this is the ping file +export LDIRECTOR_FILE="/$PREFIX/var/web/ldirectorping.txt" +# ILS sources directory +export OILS_SRC_DIR=/home/opensrf/current +# OpenSRF sources directory +export OSRF_SRC_DIR=/home/opensrf/OpenSRF-0.9 +# XUL install prefix +export XUL_BASE="/$PREFIX/var/web/xul" +# OpenSRF bootstrap config +export OSRF_CONFIG="/$PREFIX/conf/opensrf_core.xml" +# ILS PID directory +export OSRF_PID_DIR=/var/run/evergreen diff --git a/Open-ILS/src/support-scripts/settings-tester.pl b/Open-ILS/src/support-scripts/settings-tester.pl index 90c4e5317a..7b9d8aa28b 100755 --- a/Open-ILS/src/support-scripts/settings-tester.pl +++ b/Open-ILS/src/support-scripts/settings-tester.pl @@ -306,6 +306,7 @@ sub get_debug_info { __DATA__ LWP::UserAgent XML::LibXML +XML::LibXML::XPathContext XML::LibXSLT Net::Server::PreFork Cache::Memcached @@ -331,3 +332,5 @@ Text::CSV Text::CSV_XS Spreadsheet::WriteExcel::Big Tie::IxHash +Parse::RecDescent +SRU diff --git a/Open-ILS/web/conify/global/actor/org_unit.html b/Open-ILS/web/conify/global/actor/org_unit.html new file mode 100644 index 0000000000..7077479dc9 --- /dev/null +++ b/Open-ILS/web/conify/global/actor/org_unit.html @@ -0,0 +1,815 @@ + + + + Confiy :: Global :: Actor :: Org Units + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + +
+
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Org Unit Name + + + + +
Org Unit Policy Code + + + +
Main Email Address + + + +
Main Phone Number + + + +
Org Unit Type +
+ +
+
Parent Org Unit +
+ +
+
OPAC Visible + +
+ +
+ + + + + +
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Open timeClose time
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
+ + + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + +
Type + + Valid + +
Street 1
Street 2
CityStateZip
CountryCounty
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
TypeValid + +
Street 1
Street 2
CityStateZip
CountryCounty
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
TypeValid + +
Street 1
Street 2
CityStateZip
CountryCounty
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
TypeValid + +
Street 1
Street 2
CityStateZip
CountryCounty
+ + +
+
+
+
+
+
+ +
Now editing:
+ + diff --git a/Open-ILS/web/conify/global/actor/org_unit.js b/Open-ILS/web/conify/global/actor/org_unit.js new file mode 100644 index 0000000000..ad00205e8b --- /dev/null +++ b/Open-ILS/web/conify/global/actor/org_unit.js @@ -0,0 +1,257 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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. +# --------------------------------------------------------------------------- +*/ + +dojo.require('fieldmapper.dojoData'); +dojo.require('openils.I18N'); +dojo.require('dojo.parser'); +dojo.require('dojo.data.ItemFileWriteStore'); +dojo.require('dojo.date.stamp'); +dojo.require('dijit.form.TextBox'); +dojo.require('dijit.form.TimeTextBox'); +dojo.require('dijit.form.ValidationTextBox'); +dojo.require('dijit.form.CheckBox'); +dojo.require('dijit.form.FilteringSelect'); +dojo.require('dijit.Tree'); +dojo.require('dijit.layout.ContentPane'); +dojo.require('dijit.layout.TabContainer'); +dojo.require('dijit.layout.LayoutContainer'); +dojo.require('dijit.layout.SplitContainer'); +dojo.require('dojox.widget.Toaster'); +dojo.require('dojox.fx'); + +// some handy globals +var cgi = new CGI(); +var cookieManager = new HTTP.Cookies(); +var ses = cookieManager.read('ses') || cgi.param('ses'); +var pCRUD = new OpenSRF.ClientSession('open-ils.permacrud'); + +var current_ou, current_ou_hoo; +var virgin_ou_id = -1; + +//var ou_type_store = new dojo.data.ItemFileWriteStore({ data : aout.toStoreData( globalOrgTypes ) }); + +var highlighter = {}; + +function status_update (markup) { + if (parent !== window && parent.status_update) parent.status_update( markup ); +} + +function save_org () { + var modified_ou = new aou().fromStoreItem( current_ou ); + modified_ou.ischanged( 1 ); + + new_kid_button.disabled = false; + save_ou_button.disabled = false; + delete_ou_button.disabled = false; + + pCRUD.request({ + method : 'open-ils.permacrud.update.aou', + timeout : 10, + params : [ ses, modified_ou ], + onerror : function (r) { + highlighter.editor_pane.red.play(); + status_update( 'Problem saving data for ' + ou_list_store.getValue( current_ou, 'name' ) ); + }, + oncomplete : function (r) { + var res = r.recv(); + if ( res && res.content() ) { + ou_list_store.setValue( current_ou, 'ischanged', 0 ); + highlighter.editor_pane.green.play(); + status_update( 'Saved changes to ' + ou_list_store.getValue( current_ou, 'name' ) ); + } else { + highlighter.editor_pane.red.play(); + status_update( 'Problem saving data for ' + ou_list_store.getValue( current_ou, 'name' ) ); + } + }, + }).send(); +} + +function hoo_load () { + // empty result not coming through ... + current_ou_hoo = new aouhoo().fromHash({id:ou_list_store.getValue( current_ou, 'id' )}); + current_ou_hoo.isnew(1); + + pCRUD.request({ + method : 'open-ils.permacrud.retrieve.aouhoo', + params : [ ses, ou_list_store.getValue( current_ou, 'id' ) ], + onerror : function (r) { throw 'Problem fetching hours of operation for ' + ou_list_store.getValue( current_ou, 'name' );}, + oncomplete : function (r) { + current_ou_hoo = null; + + var res = r.recv(); + if (res) { + if (res.content()) current_ou_hoo = res.content(); + } + + if (!current_ou_hoo) { + current_ou_hoo = new aouhoo().fromHash({id:ou_list_store.getValue( current_ou, 'id' )}); + current_ou_hoo.isnew(1); + for (var i = 0; i < 7; i++) { + current_ou_hoo['dow_' + i + '_open']('09:00:00'); + current_ou_hoo['dow_' + i + '_close']('17:00:00'); + } + } + + for (var i = 0; i < 7; i++) { + window['dow_' + i + '_open'].setValue( + dojo.date.stamp.fromISOString( 'T' + current_ou_hoo['dow_' + i + '_open']() ) + ); + window['dow_' + i + '_close'].setValue( + dojo.date.stamp.fromISOString( 'T' + current_ou_hoo['dow_' + i + '_close']() ) + ); + } + + highlighter.hoo_pane.green.play(); + } + }).send(); + +} + +function addr_load () { + // empty result not coming through ... + + save_ill_address.disabled = false; + save_holds_address.disabled = false; + save_mailing_address.disabled = false; + save_billing_address.disabled = false; + + if (ou_list_store.getValue( current_ou, 'billing_address' )) { + pCRUD.request({ + method : 'open-ils.permacrud.retrieve.aoa', + params : [ ses, ou_list_store.getValue( current_ou, 'billing_address' ) ], + onerror : function (r) { throw 'Problem fetching Physical Address for ' + ou_list_store.getValue( current_ou, 'name' );}, + oncomplete : function (r) { + current_billing_address = null; + + var res = r.recv(); + if (res) { + if (res.content()) current_billing_address = res.content(); + } + + if (!current_billing_address) { + current_billing_address = new aoa().fromHash({org_unit:ou_list_store.getValue( current_ou, 'id' )}); + current_billing_address.isnew(1); + } + + set_addr_inputs('billing'); + highlighter.addresses_pane.green.play(); + } + }).send(); + } else { + current_billing_address = new aoa().fromHash({org_unit:ou_list_store.getValue( current_ou, 'id' )}); + current_billing_address.isnew(1); + set_addr_inputs('billing'); + } + + if (ou_list_store.getValue( current_ou, 'mailing_address' )) { + pCRUD.request({ + method : 'open-ils.permacrud.retrieve.aoa', + params : [ ses, ou_list_store.getValue( current_ou, 'mailing_address' ) ], + onerror : function (r) { throw 'Problem fetching Physical Address for ' + ou_list_store.getValue( current_ou, 'name' );}, + oncomplete : function (r) { + current_mailing_address = null; + + var res = r.recv(); + if (res) { + if (res.content()) current_mailing_address = res.content(); + } + + if (!current_mailing_address) { + current_mailing_address = new aoa().fromHash({org_unit:ou_list_store.getValue( current_ou, 'id' )}); + current_mailing_address.isnew(1); + } + + set_addr_inputs('mailing'); + highlighter.addresses_pane.green.play(); + } + }).send(); + } else { + current_mailing_address = new aoa().fromHash({org_unit:ou_list_store.getValue( current_ou, 'id' )}); + current_mailing_address.isnew(1); + set_addr_inputs('mailing'); + } + + if (ou_list_store.getValue( current_ou, 'holds_address' )) { + pCRUD.request({ + method : 'open-ils.permacrud.retrieve.aoa', + params : [ ses, ou_list_store.getValue( current_ou, 'holds_address' ) ], + onerror : function (r) { throw 'Problem fetching Physical Address for ' + ou_list_store.getValue( current_ou, 'name' );}, + oncomplete : function (r) { + current_holds_address = null; + + var res = r.recv(); + if (res) { + if (res.content()) current_holds_address = res.content(); + } + + if (!current_holds_address) { + current_holds_address = new aoa().fromHash({org_unit:ou_list_store.getValue( current_ou, 'id' )}); + current_holds_address.isnew(1); + } + + set_addr_inputs('holds'); + highlighter.addresses_pane.green.play(); + } + }).send(); + } else { + current_holds_address = new aoa().fromHash({org_unit:ou_list_store.getValue( current_ou, 'id' )}); + current_holds_address.isnew(1); + set_addr_inputs('holds'); + } + + if (ou_list_store.getValue( current_ou, 'ill_address' )) { + pCRUD.request({ + method : 'open-ils.permacrud.retrieve.aoa', + params : [ ses, ou_list_store.getValue( current_ou, 'ill_address' ) ], + onerror : function (r) { throw 'Problem fetching Physical Address for ' + ou_list_store.getValue( current_ou, 'name' );}, + oncomplete : function (r) { + current_ill_address = null; + + var res = r.recv(); + if (res) { + if (res.content()) current_ill_address = res.content(); + } + + if (!current_ill_address) { + current_ill_address = new aoa().fromHash({org_unit:ou_list_store.getValue( current_ou, 'id' )}); + current_ill_address.isnew(1); + } + + set_addr_inputs('ill'); + highlighter.addresses_pane.green.play(); + } + }).send(); + } else { + current_ill_address = new aoa().fromHash({org_unit:ou_list_store.getValue( current_ou, 'id' )}); + current_ill_address.isnew(1); + set_addr_inputs('ill'); + } + +} + +function set_addr_inputs (type) { + window[type + '_addr_valid'].setChecked( window['current_' + type + '_address'].valid() == 't' ? true : false ); + window[type + '_addr_type'].setValue( window['current_' + type + '_address'].address_type() || '' ); + window[type + '_addr_street1'].setValue( window['current_' + type + '_address'].street1() || '' ); + window[type + '_addr_street2'].setValue( window['current_' + type + '_address'].street2() || '' ); + window[type + '_addr_city'].setValue( window['current_' + type + '_address'].city() || '' ); + window[type + '_addr_county'].setValue( window['current_' + type + '_address'].county() || '' ); + window[type + '_addr_country'].setValue( window['current_' + type + '_address'].country() || '' ); + window[type + '_addr_state'].setValue( window['current_' + type + '_address'].state() || '' ); + window[type + '_addr_post_code'].setValue( window['current_' + type + '_address'].post_code() || '' ); +} + diff --git a/Open-ILS/web/conify/global/actor/org_unit_type.html b/Open-ILS/web/conify/global/actor/org_unit_type.html new file mode 100644 index 0000000000..b9b111d694 --- /dev/null +++ b/Open-ILS/web/conify/global/actor/org_unit_type.html @@ -0,0 +1,413 @@ + + + + Confiy :: Global :: Actor :: Org Unit Types + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + +
+
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
Type Name + + + + +
OPAC Label + + + + +
Parent Type +
+ +
+
Can have Volumes/Copies + +
Can have Users + +
+ +
+ + + + + +
+ + + +
+
+
+ + + diff --git a/Open-ILS/web/conify/global/actor/org_unit_type.js b/Open-ILS/web/conify/global/actor/org_unit_type.js new file mode 100644 index 0000000000..dcb7d7d969 --- /dev/null +++ b/Open-ILS/web/conify/global/actor/org_unit_type.js @@ -0,0 +1,83 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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. +# --------------------------------------------------------------------------- +*/ + +dojo.require('fieldmapper.dojoData'); +dojo.require('openils.I18N'); +dojo.require('dojo.parser'); +dojo.require('dojo.data.ItemFileWriteStore'); +dojo.require('dojo.date.stamp'); +dojo.require('dijit.form.NumberSpinner'); +dojo.require('dijit.form.TextBox'); +dojo.require('dijit.form.TimeTextBox'); +dojo.require('dijit.form.ValidationTextBox'); +dojo.require('dijit.form.CheckBox'); +dojo.require('dijit.form.FilteringSelect'); +dojo.require('dijit.Tree'); +dojo.require('dijit.layout.ContentPane'); +dojo.require('dijit.layout.TabContainer'); +dojo.require('dijit.layout.LayoutContainer'); +dojo.require('dijit.layout.SplitContainer'); +dojo.require('dojox.widget.Toaster'); +dojo.require('dojox.fx'); + +// some handy globals +var cgi = new CGI(); +var cookieManager = new HTTP.Cookies(); +var ses = cookieManager.read('ses') || cgi.param('ses'); +var pCRUD = new OpenSRF.ClientSession('open-ils.permacrud'); + +var current_type; +var current_fm_type; +var virgin_out_id = -1; + +var highlighter = {}; + +function status_update (markup) { + if (parent !== window && parent.status_update) parent.status_update( markup ); +} + +function save_type () { + + var modified_aout = new aout().fromStoreItem( current_type ); + modified_aout.ischanged( 1 ); + + new_kid_button.disabled = false; + save_out_button.disabled = false; + delete_out_button.disabled = false; + + pCRUD.request({ + method : 'open-ils.permacrud.update.aout', + timeout : 10, + params : [ ses, modified_aout ], + onerror : function (r) { + highlighter.editor_pane.red.play(); + status_update( 'Problem saving data for ' + ou_type_store.getValue( current_type, 'name' ) ); + }, + oncomplete : function (r) { + var res = r.recv(); + if ( res && res.content() ) { + ou_type_store.setValue( current_type, 'ischanged', 0 ); + highlighter.editor_pane.green.play(); + status_update( 'Saved changes to ' + ou_type_store.getValue( current_type, 'name' ) ); + } else { + highlighter.editor_pane.red.play(); + status_update( 'Problem saving data for ' + ou_type_store.getValue( current_type, 'name' ) ); + } + }, + }).send(); +} + diff --git a/Open-ILS/web/conify/global/admin.html b/Open-ILS/web/conify/global/admin.html new file mode 100644 index 0000000000..8a4ff3f868 --- /dev/null +++ b/Open-ILS/web/conify/global/admin.html @@ -0,0 +1,77 @@ + + + + Conify :: Global :: Admin + + + + + + + + + + + + + +
+
+ + Configure your ILS +
+ +
+ +
+
+ +
+
+ + + diff --git a/Open-ILS/web/conify/global/admin.js b/Open-ILS/web/conify/global/admin.js new file mode 100644 index 0000000000..e3b4ae2be9 --- /dev/null +++ b/Open-ILS/web/conify/global/admin.js @@ -0,0 +1,6 @@ +var djConfig = { parseOnLoad : true }; + +var _url_locale = location.href.replace(/^.*conify\/(.+)\/global.*$/, "$1").toLowerCase().replace(/-/,'_'); +if (_url_locale) djConfig.locale = _url_locale; +else djConfig.locale = ''; + diff --git a/Open-ILS/web/conify/global/config/copy_status.html b/Open-ILS/web/conify/global/config/copy_status.html new file mode 100644 index 0000000000..3efa3c2105 --- /dev/null +++ b/Open-ILS/web/conify/global/config/copy_status.html @@ -0,0 +1,295 @@ + + + + Confiy :: Global :: Config :: Copy Status + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ New Status: +
+ +
+ +
+
+
+ +
+
+ +
+ + + + + +
+
+ + + diff --git a/Open-ILS/web/conify/global/config/copy_status.js b/Open-ILS/web/conify/global/config/copy_status.js new file mode 100644 index 0000000000..bfa91742da --- /dev/null +++ b/Open-ILS/web/conify/global/config/copy_status.js @@ -0,0 +1,106 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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. +# --------------------------------------------------------------------------- +*/ + +dojo.require('fieldmapper.dojoData'); +dojo.require('openils.I18N'); +dojo.require('dojo.parser'); +dojo.require('dojo.string'); +dojo.require('dojo.data.ItemFileWriteStore'); +dojo.require('dijit.form.TextBox'); +dojo.require('dijit.form.ValidationTextBox'); +dojo.require('dijit.form.Textarea'); +dojo.require('dijit.layout.ContentPane'); +dojo.require('dijit.layout.LayoutContainer'); +dojo.require('dijit.layout.BorderContainer'); +dojo.require('dojox.widget.Toaster'); +dojo.require('dojox.fx'); +dojo.require('dojox.grid.Grid'); +dojo.require('dojox.grid._data.model'); +dojo.require("dojox.grid.editors"); + +// some handy globals +var cgi = new CGI(); +var cookieManager = new HTTP.Cookies(); +var ses = cookieManager.read('ses') || cgi.param('ses'); +var pCRUD = new OpenSRF.ClientSession('open-ils.permacrud'); + +var current_status; +var virgin_out_id = -1; + +var highlighter = {}; + +function status_update (markup) { + if (parent !== window && parent.status_update) parent.status_update( markup ); +} + +function save_status () { + + var modified_ccs = new ccs().fromStoreItem( current_status ); + modified_ccs.ischanged( 1 ); + + pCRUD.request({ + method : 'open-ils.permacrud.update.ccs', + timeout : 10, + params : [ ses, modified_ccs ], + onerror : function (r) { + highlighter.red.play(); + status_update( 'Problem saving ' + status_store.getValue( current_status, 'name' ) ); + }, + oncomplete : function (r) { + var res = r.recv(); + if ( res && res.content() ) { + status_store.setValue( current_status, 'ischanged', 0 ); + highlighter.green.play(); + status_update( 'Saved changes to ' + status_store.getValue( current_status, 'name' ) ); + } else { + highlighter.red.play(); + status_update( 'Problem saving ' + status_store.getValue( current_status, 'name' ) ); + } + }, + }).send(); +} + +function save_them_all (event) { + + status_store.fetch({ + query : { ischanged : 1 }, + onItem : function (item, req) { try { if (this.isItem( item )) window.dirtyStore.push( item ); } catch (e) { /* meh */ } }, + scope : status_store + }); + + var confirmation = true; + + + if (event && dirtyStore.length > 0) { + confirmation = confirm( + 'There are unsaved modified Statuses! '+ + 'OK to save these changes, Cancel to abandon them.' + ); + } + + if (confirmation) { + for (var i in window.dirtyStore) { + window.current_status = window.dirtyStore[i]; + save_status(true); + } + + window.dirtyStore = []; + } +} + +dojo.addOnUnload( save_them_all ); + diff --git a/Open-ILS/web/conify/global/permission/grp_tree.html b/Open-ILS/web/conify/global/permission/grp_tree.html new file mode 100644 index 0000000000..31800c37bd --- /dev/null +++ b/Open-ILS/web/conify/global/permission/grp_tree.html @@ -0,0 +1,742 @@ + + + + Confiy :: Global :: Permission :: Group Tree + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + +
+
+ +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Group Name + + + + +
Description + + + + +
Permission Interval + + + +
Editing Permission +
+ +
+
Parent Group +
+ +
+
User Group + +
+ +
+ + + + + +
+ + + +
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ New Mapping +
+ + + + + + + + + + + + + +
Permission: +
+
Depth: +
+
Grantable: + +
+ + +
+
+ +
+ + + +
+
+
+
+
+
+ + diff --git a/Open-ILS/web/conify/global/permission/grp_tree.js b/Open-ILS/web/conify/global/permission/grp_tree.js new file mode 100644 index 0000000000..151a3431ff --- /dev/null +++ b/Open-ILS/web/conify/global/permission/grp_tree.js @@ -0,0 +1,146 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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. +# --------------------------------------------------------------------------- +*/ + +dojo.require('fieldmapper.dojoData'); +dojo.require('openils.I18N'); +dojo.require('dojo.parser'); +dojo.require('dojo.data.ItemFileWriteStore'); +dojo.require('dojo.date.stamp'); +dojo.require('dijit.form.NumberSpinner'); +dojo.require('dijit.form.TextBox'); +dojo.require('dijit.form.TimeTextBox'); +dojo.require('dijit.form.ValidationTextBox'); +dojo.require('dijit.form.CheckBox'); +dojo.require('dijit.form.FilteringSelect'); +dojo.require('dijit.form.Textarea'); +dojo.require('dijit.form.Button'); +dojo.require('dijit.Dialog'); +dojo.require('dijit.Tree'); +dojo.require('dijit.layout.ContentPane'); +dojo.require('dijit.layout.TabContainer'); +dojo.require('dijit.layout.LayoutContainer'); +dojo.require('dijit.layout.SplitContainer'); +dojo.require('dojox.widget.Toaster'); +dojo.require('dojox.fx'); +dojo.require('dojox.grid.Grid'); +dojo.require('dojox.grid._data.model'); +dojo.require("dojox.grid.editors"); + +// some handy globals +var cgi = new CGI(); +var cookieManager = new HTTP.Cookies(); +var ses = cookieManager.read('ses') || cgi.param('ses'); +var server = {}; +server.pCRUD = new OpenSRF.ClientSession('open-ils.permacrud'); +server.actor = new OpenSRF.ClientSession('open-ils.actor'); + +var current_group; +var virgin_out_id = -1; + +var highlighter = {}; + +function status_update (markup) { + if (parent !== window && parent.status_update) parent.status_update( markup ); +} + +function save_group () { + + var modified_pgt = new pgt().fromStoreItem( current_group ); + modified_pgt.ischanged( 1 ); + + new_kid_button.disabled = false; + save_out_button.disabled = false; + delete_out_button.disabled = false; + + server.pCRUD.request({ + method : 'open-ils.permacrud.update.pgt', + timeout : 10, + params : [ ses, modified_pgt ], + onerror : function (r) { + highlighter.editor_pane.red.play(); + status_update( 'Problem saving data for ' + group_store.getValue( current_group, 'name' ) ); + }, + oncomplete : function (r) { + var res = r.recv(); + if ( res && res.content() ) { + group_store.setValue( current_group, 'ischanged', 0 ); + highlighter.editor_pane.green.play(); + status_update( 'Saved changes to ' + group_store.getValue( current_group, 'name' ) ); + } else { + highlighter.editor_pane.red.play(); + status_update( 'Problem saving data for ' + group_store.getValue( current_group, 'name' ) ); + } + }, + }).send(); +} + +function save_perm_map (storeItem) { + + var modified_pgpm = new pgpm().fromStoreItem( storeItem ); + modified_pgpm.ischanged( 1 ); + + server.pCRUD.request({ + method : 'open-ils.permacrud.update.pgpm', + timeout : 10, + params : [ ses, modified_pgpm ], + onerror : function (r) { + highlighter.editor_pane.red.play(); + status_update( 'Problem saving permission data for ' + group_store.getValue( current_group, 'name' ) ); + }, + oncomplete : function (r) { + var res = r.recv(); + if ( res && res.content() ) { + perm_map_store.setValue( storeItem, 'ischanged', 0 ); + highlighter.editor_pane.green.play(); + status_update( 'Saved permission changes to ' + group_store.getValue( current_group, 'name' ) ); + } else { + highlighter.editor_pane.red.play(); + status_update( 'Problem saving permission data for ' + group_store.getValue( current_group, 'name' ) ); + } + }, + }).send(); +} + +function save_them_all (event) { + + var dirtyMaps = []; + + perm_map_store.fetch({ + query : { ischanged : 1 }, + onItem : function (item, req) { try { if (this.isItem( item )) dirtyMaps.push( item ); } catch (e) { /* meh */ } }, + scope : perm_map_store + }); + + var confirmation = true; + + + if (event && dirtyMaps.length > 0) { + confirmation = confirm( + 'There are unsaved modified Permission Maps! '+ + 'OK to save these changes, Cancel to abandon them.' + ); + } + + if (confirmation) { + for (var i in dirtyMaps) { + save_perm_map(dirtyMaps[i]); + } + } +} + +dojo.addOnUnload( save_them_all ); + diff --git a/Open-ILS/web/conify/global/permission/perm_list.html b/Open-ILS/web/conify/global/permission/perm_list.html new file mode 100644 index 0000000000..18aa9444eb --- /dev/null +++ b/Open-ILS/web/conify/global/permission/perm_list.html @@ -0,0 +1,249 @@ + + + + Confiy :: Global :: Permission :: Permission List + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ New Permission: +
+ +
+ +
+
+
+ + + --> +
+
+ +
+ + + + + +
+
+ + + diff --git a/Open-ILS/web/conify/global/permission/perm_list.js b/Open-ILS/web/conify/global/permission/perm_list.js new file mode 100644 index 0000000000..4dc76cffbb --- /dev/null +++ b/Open-ILS/web/conify/global/permission/perm_list.js @@ -0,0 +1,107 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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. +# --------------------------------------------------------------------------- +*/ + +dojo.require('fieldmapper.dojoData'); +dojo.require('dojo.parser'); +dojo.require('dojo.string'); +dojo.require('dojo.data.ItemFileWriteStore'); +dojo.require('dijit.form.TextBox'); +dojo.require('dijit.form.ValidationTextBox'); +dojo.require('dijit.form.Textarea'); +dojo.require('dijit.layout.ContentPane'); +dojo.require('dijit.layout.LayoutContainer'); +dojo.require('dijit.layout.BorderContainer'); +dojo.require('dojox.widget.Toaster'); +dojo.require('dojox.fx'); +dojo.require('dojox.grid.Grid'); +dojo.require('dojox.grid._data.model'); +dojo.require("dojox.grid.editors"); + +// some handy globals +var cgi = new CGI(); +var cookieManager = new HTTP.Cookies(); +var ses = cookieManager.read('ses') || cgi.param('ses'); +var pCRUD = new OpenSRF.ClientSession('open-ils.permacrud'); + +var current_perm; +var virgin_out_id = -1; + +var highlighter = {}; + +function status_update (markup) { + if (parent !== window && parent.status_update) parent.status_update( markup ); +} + +function save_perm () { + + var modified_ppl = new ppl().fromStoreItem( current_perm ); + modified_ppl.ischanged( 1 ); + modified_ppl.description( dojo.string.trim( modified_ppl.description() ) ); + modified_ppl.code( dojo.string.trim( modified_ppl.code() ) ); + + pCRUD.request({ + method : 'open-ils.permacrud.update.ppl', + timeout : 10, + params : [ ses, modified_ppl ], + onerror : function (r) { + highlighter.red.play(); + status_update( 'Problem saving data for ' + perm_store.getValue( current_perm, 'code' ) ); + }, + oncomplete : function (r) { + var res = r.recv(); + if ( res && res.content() ) { + perm_store.setValue( current_perm, 'ischanged', 0 ); + highlighter.green.play(); + status_update( 'Saved changes to ' + perm_store.getValue( current_perm, 'code' ) ); + } else { + highlighter.red.play(); + status_update( 'Problem saving data for ' + perm_store.getValue( current_perm, 'code' ) ); + } + }, + }).send(); +} + +function save_them_all (event) { + + perm_store.fetch({ + query : { ischanged : 1 }, + onItem : function (item, req) { try { if (this.isItem( item )) window.dirtyStore.push( item ); } catch (e) { /* meh */ } }, + scope : perm_store + }); + + var confirmation = true; + + + if (event && dirtyStore.length > 0) { + confirmation = confirm( + 'There are unsaved modified Permissions! '+ + 'OK to save these changes, Cancel to abandon them.' + ); + } + + if (confirmation) { + for (var i in window.dirtyStore) { + window.current_perm = window.dirtyStore[i]; + save_perm(true); + } + + window.dirtyStore = []; + } +} + +dojo.addOnUnload( save_them_all ); + diff --git a/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js b/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js new file mode 100644 index 0000000000..c6bc24ed34 --- /dev/null +++ b/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js @@ -0,0 +1,262 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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["fieldmapper.Fieldmapper"]){ + +/* generate fieldmapper javascript classes. This expects a global variable + called 'fmclasses' to be fleshed with the classes we need to build */ + + function FMEX(message) { this.message = message; } + FMEX.toString = function() { return "FieldmapperException: " + this.message + "\n"; } + + + dojo._hasResource["fieldmapper.Fieldmapper"] = true; + dojo.provide("fieldmapper.Fieldmapper"); + dojo.require("DojoSRF"); + dojo.require("fieldmapper.fmall", true); + + dojo.declare( "fieldmapper.Fieldmapper", null, { + + constructor : function (initArray) { + if (initArray) { + if (dojo.isArray(initArray)) { + this.a = initArray; + } else { + this.a = []; + } + } + }, + + _isfieldmapper : true, + fm_classes : fmclasses, + + clone : function() { + var obj = new this.constructor(); + + for( var i in this.a ) { + var thing = this.a[i]; + if(thing == null) continue; + + if( thing._isfieldmapper ) { + obj.a[i] = thing.clone(); + } else { + + if(instanceOf(thing, Array)) { + obj.a[i] = new Array(); + + for( var j in thing ) { + + if( thing[j]._isfieldmapper ) + obj.a[i][j] = thing[j].clone(); + else + obj.a[i][j] = thing[j]; + } + } else { + obj.a[i] = thing; + } + } + } + return obj; + }, + + 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._request = function ( meth, staff, params ) { + var ses = OpenSRF.CachedClientSession( meth[0] ); + if (!ses) return null; + + var result = null; + var args = {}; + + if (dojo.isArray(params)) { + args.params = params; + } else { + + if (dojo.isObject(params)) { + args = params; + } else { + args.params = arguments.splice(1, arguments.length - 1); + } + + } + + if (!args.async && !args.timeout) args.timeout = 10; + + if (!args.onerror) { + args.onerror = function (r) { + throw 'Error encountered! ' + r; + } + } + + if (!args.oncomplete) { + args.oncomplete = function (r) { + var x = r.recv(); + if (x) result = x.content(); + } + } + + args.method = meth[1]; + if (staff && meth[2]) args.method += '.staff'; + + ses.request(args).send(); + + return result; + }; + + fieldmapper.standardRequest = function (meth, params) { return fieldmapper._request(meth, false, params) }; + fieldmapper.Fieldmapper.prototype.standardRequest = fieldmapper.standardRequest; + + fieldmapper.staffRequest = function (meth, params) { return fieldmapper._request(meth, true, params) }; + fieldmapper.Fieldmapper.prototype.staffRequest = fieldmapper.staffRequest; + + 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.Identifier = 'id'; + this._fields = fmclasses[this.classname]; + for( var pos = 0; pos < this._fields.length; pos++ ) { + var p = parseInt(pos) + 3; + 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.ppl.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.chmt.Identifier = 'matchpoint'; + fieldmapper.ccmt.Identifier = 'matchpoint'; + fieldmapper.ccmrs.Identifier = 'matchpoint'; + + fieldmapper.OpenSRF = {}; + + /* Methods are defined as [ service, method, have_staff ] + An optional 3rd component is when a method is followed by true, such methods + have a staff counterpart and should have ".staff" appended to the method + before the method is called when in XUL mode */ + fieldmapper.OpenSRF.methods = { + SEARCH_MRS : ['open-ils.search','open-ils.search.metabib.multiclass',true], + SEARCH_RS : ['open-ils.search','open-ils.search.biblio.multiclass',true], + SEARCH_MRS_QUERY : ['open-ils.search','open-ils.search.metabib.multiclass.query',true], + SEARCH_RS_QUERY : ['open-ils.search','open-ils.search.biblio.multiclass.query',true], + FETCH_SEARCH_RIDS : ['open-ils.search','open-ils.search.biblio.record.class.search',true], + FETCH_MRMODS : ['open-ils.search','open-ils.search.biblio.metarecord.mods_slim.retrieve'], + FETCH_MODS_FROM_COPY : ['open-ils.search','open-ils.search.biblio.mods_from_copy'], + FETCH_MR_COPY_COUNTS : ['open-ils.search','open-ils.search.biblio.metarecord.copy_count',true], + FETCH_RIDS : ['open-ils.search','open-ils.search.biblio.metarecord_to_records',true], + FETCH_RMODS : ['open-ils.search','open-ils.search.biblio.record.mods_slim.retrieve'], + FETCH_R_COPY_COUNTS : ['open-ils.search','open-ils.search.biblio.record.copy_count',true], + FETCH_FLESHED_USER : ['open-ils.actor','open-ils.actor.user.fleshed.retrieve'], + FETCH_SESSION : ['open-ils.auth','open-ils.auth.session.retrieve'], + LOGIN_INIT : ['open-ils.auth','open-ils.auth.authenticate.init'], + LOGIN_COMPLETE : ['open-ils.auth','open-ils.auth.authenticate.complete'], + LOGIN_DELETE : ['open-ils.auth','open-ils.auth.session.delete'], + FETCH_USER_PREFS : ['open-ils.actor','open-ils.actor.patron.settings.retrieve'], + UPDATE_USER_PREFS : ['open-ils.actor','open-ils.actor.patron.settings.update'], + FETCH_COPY_STATUSES : ['open-ils.search','open-ils.search.config.copy_status.retrieve.all'], + FETCH_COPY_COUNTS_SUMMARY : ['open-ils.search','open-ils.search.biblio.copy_counts.summary.retrieve'], + FETCH_MARC_HTML : ['open-ils.search','open-ils.search.biblio.record.html'], + FETCH_CHECKED_OUT_SUM : ['open-ils.actor','open-ils.actor.user.checked_out'], + FETCH_HOLDS : ['open-ils.circ','open-ils.circ.holds.retrieve'], + FETCH_FINES_SUMMARY : ['open-ils.actor','open-ils.actor.user.fines.summary'], + FETCH_TRANSACTIONS : ['open-ils.actor','open-ils.actor.user.transactions.have_charge.fleshed'], + FETCH_MONEY_BILLING : ['open-ils.circ','open-ils.circ.money.billing.retrieve.all'], + FETCH_CROSSREF : ['open-ils.search','open-ils.search.authority.crossref'], + FETCH_CROSSREF_BATCH : ['open-ils.search','open-ils.search.authority.crossref.batch'], + CREATE_HOLD : ['open-ils.circ','open-ils.circ.holds.create'], + CREATE_HOLD_OVERRIDE : ['open-ils.circ','open-ils.circ.holds.create.override'], + CANCEL_HOLD : ['open-ils.circ','open-ils.circ.hold.cancel'], + UPDATE_USERNAME : ['open-ils.actor','open-ils.actor.user.username.update'], + UPDATE_PASSWORD : ['open-ils.actor','open-ils.actor.user.password.update'], + UPDATE_EMAIL : ['open-ils.actor','open-ils.actor.user.email.update'], + RENEW_CIRC : ['open-ils.circ','open-ils.circ.renew'], + CHECK_SPELL : ['open-ils.search','open-ils.search.spellcheck'], + FETCH_REVIEWS : ['open-ils.search','open-ils.search.added_content.review.retrieve.all'], + FETCH_TOC : ['open-ils.search','open-ils.search.added_content.toc.retrieve'], + FETCH_ACONT_SUMMARY : ['open-ils.search','open-ils.search.added_content.summary.retrieve'], + FETCH_USER_BYBARCODE : ['open-ils.actor','open-ils.actor.user.fleshed.retrieve_by_barcode'], + FETCH_ADV_MARC_MRIDS : ['open-ils.search','open-ils.search.biblio.marc',true], + FETCH_ADV_ISBN_RIDS : ['open-ils.search','open-ils.search.biblio.isbn'], + FETCH_ADV_ISSN_RIDS : ['open-ils.search','open-ils.search.biblio.issn'], + FETCH_ADV_TCN_RIDS : ['open-ils.search','open-ils.search.biblio.tcn'], + FETCH_CNBROWSE : ['open-ils.search','open-ils.search.callnumber.browse'], + FETCH_CONTAINERS : ['open-ils.actor','open-ils.actor.container.retrieve_by_class'], + FETCH_CONTAINERS : ['open-ils.actor','open-ils.actor.container.retrieve_by_class'], + CREATE_CONTAINER : ['open-ils.actor','open-ils.actor.container.create'], + DELETE_CONTAINER : ['open-ils.actor','open-ils.actor.container.full_delete'], + CREATE_CONTAINER_ITEM : ['open-ils.actor','open-ils.actor.container.item.create'], + DELETE_CONTAINER_ITEM : ['open-ils.actor','open-ils.actor.container.item.delete'], + FLESH_CONTAINER : ['open-ils.actor','open-ils.actor.container.flesh'], + FLESH_PUBLIC_CONTAINER : ['open-ils.actor','open-ils.actor.container.public.flesh'], + UPDATE_CONTAINER : ['open-ils.actor','open-ils.actor.container.update'], + FETCH_COPY : ['open-ils.search','open-ils.search.asset.copy.retrieve'], + FETCH_FLESHED_COPY : ['open-ils.search','open-ils.search.asset.copy.fleshed2.retrieve'], + CHECK_HOLD_POSSIBLE : ['open-ils.circ','open-ils.circ.title_hold.is_possible'], + UPDATE_HOLD : ['open-ils.circ','open-ils.circ.hold.update'], + FETCH_COPIES_FROM_VOLUME : ['open-ils.search','open-ils.search.asset.copy.retrieve_by_cn_label',true], + FETCH_VOLUME_BY_INFO : ['open-ils.search','open-ils.search.call_number.retrieve_by_info'], /* XXX staff method? */ + FETCH_VOLUME : ['open-ils.search','open-ils.search.asset.call_number.retrieve'], + FETCH_COPY_LOCATIONS : ['open-ils.circ','open-ils.circ.copy_location.retrieve.all'], + FETCH_COPY_NOTES : ['open-ils.circ','open-ils.circ.copy_note.retrieve.all'], + FETCH_COPY_STAT_CATS : ['open-ils.circ','open-ils.circ.asset.stat_cat_entries.fleshed.retrieve_by_copy'], + FETCH_LIT_FORMS : ['open-ils.search','open-ils.search.biblio.lit_form_map.retrieve.all'], + FETCH_ITEM_FORMS : ['open-ils.search','open-ils.search.biblio.item_form_map.retrieve.all'], + FETCH_ITEM_TYPES : ['open-ils.search','open-ils.search.biblio.item_type_map.retrieve.all'], + FETCH_AUDIENCES : ['open-ils.search','open-ils.search.biblio.audience_map.retrieve.all'], + FETCH_HOLD_STATUS : ['open-ils.circ','open-ils.circ.hold.status.retrieve'], + FETCH_NON_CAT_CIRCS : ['open-ils.circ','open-ils.circ.open_non_cataloged_circulation.user'], + FETCH_NON_CAT_CIRC : ['open-ils.circ','open-ils.circ.non_cataloged_circulation.retrieve'], + FETCH_NON_CAT_TYPES : ['open-ils.circ','open-ils.circ.non_cat_types.retrieve.all'], + FETCH_BRE : ['open-ils.search','open-ils.search.biblio.record_entry.slim.retrieve'], + CHECK_USERNAME : ['open-ils.actor','open-ils.actor.username.exists'], + FETCH_CIRC_BY_ID : ['open-ils.circ','open-ils.circ.retrieve'], + 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_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'] + }; + +} + + + diff --git a/Open-ILS/web/js/dojo/fieldmapper/OrgUtils.js b/Open-ILS/web/js/dojo/fieldmapper/OrgUtils.js new file mode 100644 index 0000000000..d29313bf50 --- /dev/null +++ b/Open-ILS/web/js/dojo/fieldmapper/OrgUtils.js @@ -0,0 +1,196 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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["fieldmapper.OrgUtils"]){ + + dojo._hasResource["fieldmapper.OrgUtils"] = true; + dojo.provide("fieldmapper.OrgUtils"); + dojo.require("fieldmapper.Fieldmapper"); + dojo.require("fieldmapper.OrgTree", true); + dojo.require("fieldmapper.OrgLasso", true); + + fieldmapper.aou.globalOrgTree = {}; + fieldmapper.aou.OrgCache = {}; + fieldmapper.aou.OrgCacheSN = {}; + fieldmapper.aout.OrgTypeCache = {}; + + fieldmapper.aout.LoadOrgTypes = function () { + for (var i in fieldmapper.aout.OrgTypeCache) { + return; + } + + var types = fieldmapper.standardRequest(['open-ils.actor','open-ils.actor.org_types.retrieve']); + + for (var i in types) { + fieldmapper.aout.OrgTypeCache[types[i].id()] = { + loaded : true, + type : types[i] + }; + } + } + + fieldmapper.aou.LoadOrg = function (id, slim_ok) { + var slim_o = fieldmapper.aou.OrgCache[id]; + + if (slim_o && (slim_ok || slim_o.loaded)) + return fieldmapper.aou.OrgCache[id].org; + + var o = fieldmapper.standardRequest(['open-ils.actor','open-ils.actor.org_unit.retrieve'],[null,id]); + fieldmapper.aou.OrgCache[o.id()] = { loaded : true, org : o }; + return o; + } + fieldmapper.aou.findOrgUnit = fieldmapper.aou.LoadOrg; + + if (window._l) { + for (var i in _l) { + fieldmapper.aou.OrgCache[_l[i][0]] = { + loaded: false, + org : new fieldmapper.aou().fromHash({ + id : _l[i][0], + ou_type : _l[i][1], + parent_ou : _l[i][2], + name : _l[i][3], + opac_visible : _l[i][4] + }) + }; + + } + + for (var i in fieldmapper.aou.OrgCache) { + var x = fieldmapper.aou.OrgCache[i].org; + if (x.parent_ou() == null || x.parent_ou() == '') { + fieldmapper.aou.globalOrgTree = x; + continue; + } + + var parent = fieldmapper.aou.findOrgUnit(x.parent_ou(),true); + if (!parent.children()) parent.children([]); + parent.children().push(x); + fieldmapper.aou.OrgCache[x.id()].treePtr = x; + } + + for (var i in globalOrgTypes) { + fieldmapper.aout.OrgTypeCache[globalOrgTypes[i].id()] = { + loaded : true, + type : globalOrgTypes[i] + }; + } + } + + + /* ---------------------------------------------------------------------- */ + + fieldmapper.aou.prototype.fetchOrgSettingDefault = function (name) { + return this.standardRequest( fieldmapper.OpenSRF.methods.FETCH_ORG_SETTING, name ); + } + + fieldmapper.aout.findOrgType = function (id) { + fieldmapper.aout.LoadOrgTypes(); + return fieldmapper.aout.OrgTypeCache[id].type; + } + + fieldmapper.aou.prototype.findOrgDepth = function (id) { + if (!id) id = this.id; + if (!id) return null; + + var org = fieldmapper.aou.findOrgUnit(id); + return fieldmapper.findOrgType( + fieldmapper.aou.findOrgUnit(id).ou_type() + ).depth; + } + fieldmapper.aou.findOrgDepth = fieldmapper.aou.prototype.findOrgDepth; + + fieldmapper.aout.findOrgTypeFromDepth = function (depth) { + if( depth == null ) return null; + fieldmapper.aout.LoadOrgTypes(); + for( var i in fieldmapper.aout.OrgTypeCache ) { + var t = fieldmapper.aout.OrgTypeCache[i].type; + if( t.depth() == depth ) return t; + } + return null; + } + + fieldmapper.aou.findOrgUnitSN = function (sn) { + var org = fieldmapper.aou.OrgCacheSN[sn]; + if (!org) { + for (var i in fieldmapper.aou.OrgCache) { + var o = fieldmapper.aou.OrgCache[i]; + if (o.loaded && o.org.shortname() == sn) { + fieldmapper.aou.OrgCacheSN[o.org.shortname()] = o; + return o.org; + } + } + + org = fieldmapper.standardRequest(fieldmapper.OpenSRF.methods.FETCH_ORG_BY_SHORTNAME, sn); + + fieldmapper.aou.OrgCache[org.id()] = { loaded : true, org : org }; + fieldmapper.aou.OrgCacheSN[org.shortname()] = { loaded : true, org : org }; + + } + + return org; + } + + fieldmapper.aou.prototype.orgNodeTrail = function (node) { + if (!node) node = this; + if (!node) return []; + + var na = []; + + while( node ) { + na.push(node); + node = fieldmapper.aou.findOrgUnit(node.parent_ou()); + } + + return na.reverse(); + } + fieldmapper.aou.orgNodeTrail = fieldmapper.aou.prototype.orgNodeTrail; + + fieldmapper.aou.prototype.orgIsMine = function (me, org) { + if (this._isfieldmapper) { + org = me; + me = this; + } + + if(!me || !org) return false; + + if(me.id() == org.id()) return true; + + for( var i in me.children() ) { + if(me.children()[i].orgIsMine(org)) return true; + } + return false; + } + + dojo.addOnUnload( function () { + for (var i in fieldmapper.aou.OrgCache) { + x=fieldmapper.aou.OrgCache[i].treePtr; + if (!x) continue; + + x.children(null); + x.parent_ou(null); + fieldmapper.aou.OrgCache[i]=null; + } + fieldmapper.aou.globalOrgTree = null; + fieldmapper.aou.OrgCache = null; + fieldmapper.aou.OrgCacheSN = null; + fieldmapper.aout.OrgTypeCache = null; + }); +} + + + diff --git a/Open-ILS/web/js/dojo/fieldmapper/dojoData.js b/Open-ILS/web/js/dojo/fieldmapper/dojoData.js new file mode 100644 index 0000000000..60d17e0c6b --- /dev/null +++ b/Open-ILS/web/js/dojo/fieldmapper/dojoData.js @@ -0,0 +1,119 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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['fieldmapper.dojoData']){ + + dojo._hasResource['fieldmapper.dojoData'] = true; + dojo.provide('fieldmapper.dojoData'); + dojo.require('fieldmapper.Fieldmapper'); + dojo.require('fieldmapper.hash'); + + + function _fromStoreItem (data) { + this.fromHash(data); + + for (var i in this._ignore_fields) + this[this._ignore_fields[i]](null); + + for ( var i=0; i < this._fields.length; i++) { + if (dojo.isArray( this[this._fields[i]]() )) + this[this._fields[i]]( this[this._fields[i]]()[0] ); + } + return this; + } + + function _toStoreData (list, label, params) { + + if (!params) params = {}; + if (!list) list = {}; + + // a sane default + if (!params.identifier) params.identifier = 'id'; + if (!label) label = params.label; + if (!label) label = params.identifier; + + var data = { label : label, identifier : params.identifier, items : [] }; + + for (var i in list) data.items.push( list[i].toHash() ); + + if (params.children && params.parent) { + var _hash_list = data.items; + + var _find_root = {}; + for (var i in _hash_list) { + _find_root[_hash_list[i][params.identifier]] = _hash_list[i]; + } + + var item_data = []; + for (var i in _hash_list) { + var obj = _hash_list[i] + obj[params.children] = []; + + for (var j in _hash_list) { + var kid = _hash_list[j]; + if (kid[params.parent] == obj[params.identifier]) { + obj[params.children].push( { _reference : kid[params.identifier] } ); + kid._iskid = true; + if (_find_root[kid[params.identifier]]) delete _find_root[kid[params.identifier]]; + } + } + + item_data.push( obj ); + } + + for (var j in _find_root) { + _find_root[j]['_top'] = 'true'; + if (!_find_root[j][params.parent]) + _find_root[j]['_trueRoot'] = 'true'; + } + + data.items = item_data; + } + + return data; + } + + for (var i in fmclasses) fieldmapper[i].prototype.fromStoreItem = _fromStoreItem; + for (var i in fmclasses) fieldmapper[i].toStoreData = _toStoreData; + + fieldmapper.aou.prototype._ignore_fields = ['children']; + fieldmapper.aout.prototype._ignore_fields = ['children']; + fieldmapper.pgt.prototype._ignore_fields = ['children']; + + fieldmapper.aou.toStoreData = function (list, label) { + if (!label) label = 'shortname'; + return _toStoreData(list, label, { 'parent' : 'parent_ou', 'children' : 'children' }); + } + + fieldmapper.aout.toStoreData = function (list, label) { + if (!label) label = 'name'; + return _toStoreData(list, label, { 'parent' : 'parent', 'children' : 'children' }); + } + + fieldmapper.pgt.toStoreData = function (list, label) { + if (!label) label = 'name'; + return _toStoreData(list, label, { 'parent' : 'parent', 'children' : 'children' }); + } + + /* + ppl.toStoreData = function (list, label) { + if (!label) label = 'code'; + return _toStoreData(list, label, {}); + } + */ + +} diff --git a/Open-ILS/web/js/dojo/fieldmapper/hash.js b/Open-ILS/web/js/dojo/fieldmapper/hash.js new file mode 100644 index 0000000000..c186dfac93 --- /dev/null +++ b/Open-ILS/web/js/dojo/fieldmapper/hash.js @@ -0,0 +1,46 @@ +/* +# --------------------------------------------------------------------------- +# Copyright (C) 2008 Georgia Public Library Service / Equinox Software, Inc +# Mike Rylander +# +# 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['fieldmapper.hash']){ + + dojo._hasResource['fieldmapper.hash'] = true; + dojo.provide('fieldmapper.hash'); + dojo.require('fieldmapper.Fieldmapper'); + + function _fromHash (_hash) { + for ( var i=0; i < this._fields.length; i++) { + if (_hash[this._fields[i]] != null) + this[this._fields[i]]( _hash[this._fields[i]] ); + } + return this; + } + + function _toHash () { + var _hash = {}; + for ( var i=0; i < this._fields.length; i++) { + if (this[this._fields[i]]() != null) + _hash[this._fields[i]] = '' + this[this._fields[i]](); + } + return _hash; + } + + for (var i in fmclasses) { + window[i].prototype.fromHash = _fromHash; + window[i].prototype.toHash = _toHash; + } + +} diff --git a/Open-ILS/web/js/dojo/openils/Event.js b/Open-ILS/web/js/dojo/openils/Event.js new file mode 100644 index 0000000000..bc82634055 --- /dev/null +++ b/Open-ILS/web/js/dojo/openils/Event.js @@ -0,0 +1,62 @@ +/* --------------------------------------------------------------------------- + * Copyright (C) 2008 Georgia Public Library Service + * Bill Erickson + * + * 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["openils.Event"]) { + + dojo._hasResource["openils.Event"] = true; + dojo.provide("openils.Event"); + dojo.declare('openils.Event', null, { + + constructor : function(kwargs) { + this.code = kwargs.ilsevent; + this.textcode = kwargs.textcode; + this.desc = kwargs.desc; + this.payload = kwargs.payload; + this.debug = kwargs.stacktrace; + this.servertime = kwargs.servertime; + this.ilsperm = kwargs.ilsperm; + this.ilspermloc = kwargs.ilspermloc; + }, + + toString : function() { + var s = 'Event: ' + this.code + ':' + this.textcode + ' -> ' + new String(this.desc); + if(this.ilsperm) + s += ' ' + this.ilsperm + '@' + this.ilspermloc; + return s; + } + }); + + /** + * Parses a proposed event object. If this object is an + * event, a new openils.Event is returned. Otherwise, + * null is returned + */ + openils.Event.parse = function(evt) { + if(evt && typeof evt == 'object' && 'ilsevent' in evt && 'textcode' in evt) + return new openils.Event(evt); + return null; + } + + /** + * If the provided object is a non-success event, the + * event is thrown as an exception. + */ + openils.Event.parse_and_raise = function(evt) { + var e = openils.Event.parse(evt); + if(e && e.ilsevent != 0) + throw e; + } +} diff --git a/Open-ILS/web/js/dojo/openils/I18N.js b/Open-ILS/web/js/dojo/openils/I18N.js new file mode 100644 index 0000000000..a99fa41692 --- /dev/null +++ b/Open-ILS/web/js/dojo/openils/I18N.js @@ -0,0 +1,260 @@ +/* --------------------------------------------------------------------------- + * Copyright (C) 2008 Georgia Public Library Service + * Copyright (C) 2008 Equinox Software, Inc + * Mike Rylander + * + * 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["openils.I18N"]) { + + dojo._hasResource["openils.I18N"] = true; + dojo.provide("openils.I18N"); + dojo.require("fieldmapper.dojoData"); + dojo.require("DojoSRF"); + dojo.require("dojo.data.ItemFileWriteStore"); + dojo.require("dijit._Widget"); + dojo.require("dijit._Templated"); + dojo.require("dijit.layout.ContentPane"); + dojo.require("dijit.Dialog"); + dojo.require("dijit.form.Button"); + dojo.require("dijit.form.TextBox"); + dojo.require("dijit.form.ComboBox"); + + + dojo.declare('openils.I18N', null, {}); + + openils.I18N.BaseLocales = { + "en" : "English", + "en_us" : "US English", + "en_ca" : "Canadian English", + "es" : "Spanish", + "es_us" : "US Spanish", + "fr" : "French", + "fr_ca" : "Canadian French" + }; + + openils.I18N.localeStore = new dojo.data.ItemFileWriteStore( { data : {identifier : 'locale', label : 'label', items : [] } } ); + + for (var i in openils.I18N.BaseLocales) { + openils.I18N.localeStore.newItem({ locale : i, label : openils.I18N.BaseLocales[i] }); + } + + openils.I18N.getTranslations = function ( obj /* Fieldmapper object */, field /* Field to translate */, locale /* optional locale */) { + var classname = obj.classname; + + // XXX need to derive identity field from IDL... + var ident_field = fieldmapper[classname].Identifier || 'id'; + var ident_value = obj[ident_field](); + + var fielder_args = { query : { fq_field : classname + '.' + field, identity_value : ident_value } }; + if (locale) fielder_args.translation = locale; + + var hash_list = fieldmapper.standardRequest( [ 'open-ils.fielder', 'open-ils.fielder.i18n.atomic'], [ fielder_args ] ); + var obj_list = dojo.map( hash_list, function (t) { return new fieldmapper.i18n().fromHash( t ) } ); + + if (locale) return obj_list[0]; + return obj_list; + } + +//---------------------------------------------------------------- + + dojo.declare( + 'openils.I18N.translationWidget', + [dijit._Widget, dijit._Templated], + { + + templateString : "
Translate
", + + widgetsInTemplate: true, + field : "", + targetObject : "", + unique : "" + } + ); + + openils.I18N.translationWidget.renderTranslationPopup = function (obj, field, num) { + var node = dojo.byId(field + '_translation_' + num); + + var trans_list = openils.I18N.getTranslations( obj, field ); + + var trans_template = dojo.query('.translation_tbody_template', node)[0]; + var trans_tbody = dojo.query('.translation_tbody', node)[0]; + + // Empty it + while (trans_tbody.lastChild) trans_tbody.removeChild( trans_tbody.lastChild ); + + for (var i in trans_list) { + if (!trans_list[i]) continue; + + var trans_obj = trans_list[i]; + var trans_id = trans_obj.id(); + + var trans_row = dojo.query('tr',trans_template)[0].cloneNode(true); + trans_row.id = 'translation_row_' + trans_id; + + var old_dijit = dijit.byId('locale_' + trans_id); + if (old_dijit) old_dijit.destroy(); + + old_dijit = dijit.byId('translation_' + trans_id); + if (old_dijit) old_dijit.destroy(); + + dojo.query('.locale_combobox',trans_row).instantiate( + dijit.form.ComboBox, + { store:openils.I18N.localeStore, + searchAttr:'locale', + lowercase:true, + required:true, + id:'locale_' + trans_id, + value: trans_obj.translation(), + invalidMessage:'Specify locale as {languageCode}_{countryCode}, like en_us', + regExp:'[a-z_]+' + } + ); + + dojo.query('.translation_textbox',trans_row).instantiate( + dijit.form.TextBox, + { required : true, + id:'translation_' + trans_id, + value: trans_obj.string() + } + ); + + dojo.query('.update_button',trans_row).style({ visibility : 'visible', display : 'inline'}).instantiate( + dijit.form.Button, + { onClick : + (function (trans_id, obj, field) { + return function () { openils.I18N.translationWidget.updateTranslation(trans_id, obj, field, num) } + })(trans_id, obj, field) + } + ); + + dojo.query('.delete_button',trans_row).style({ visibility : 'visible', display : 'inline'}).instantiate( + dijit.form.Button, + { onClick : + (function (trans_id, obj, field) { + return function () { openils.I18N.translationWidget.removeTranslation(trans_id, obj, field, num) } + })(trans_id, obj, field) + } + ); + + trans_tbody.appendChild( trans_row ); + } + + old_dijit = dijit.byId('i18n_new_locale_' + obj.classname + '.' + field + num); + if (old_dijit) old_dijit.destroy(); + + old_dijit = dijit.byId('i18n_new_translation_' + obj.classname + '.' + field + num); + if (old_dijit) old_dijit.destroy(); + + trans_row = dojo.query('tr',trans_template)[0].cloneNode(true); + + dojo.query('.locale_combobox',trans_row).instantiate( + dijit.form.ComboBox, + { store:openils.I18N.localeStore, + searchAttr:'locale', + id:'i18n_new_locale_' + obj.classname + '.' + field + num, + lowercase:true, + required:true, + invalidMessage:'Specify locale as {languageCode}_{countryCode}, like en_us', + regExp:'[a-z_]+' + } + ); + + dojo.query('.translation_textbox',trans_row).addClass('new_translation').instantiate( + dijit.form.TextBox, + { required : true, + id:'i18n_new_translation_' + obj.classname + '.' + field + num + } + ); + + dojo.query('.create_button',trans_row).style({ visibility : 'visible', display : 'inline'}).instantiate( + dijit.form.Button, + { onClick : function () { openils.I18N.translationWidget.createTranslation( obj, field, num) } } + ); + + trans_tbody.appendChild( trans_row ); + } + + openils.I18N.translationWidget.updateTranslation = function (trans_id, obj, field, num) { + return openils.I18N.translationWidget.changeTranslation('update', trans_id, obj, field, num); + } + + openils.I18N.translationWidget.removeTranslation = function (trans_id, obj, field, num) { + return openils.I18N.translationWidget.changeTranslation('delete', trans_id, obj, field, num); + } + + openils.I18N.translationWidget.changeTranslation = function (method, trans_id, obj, field, num) { + + var trans_obj = new i18n().fromHash({ + ischanged : method == 'update' ? 1 : 0, + isdeleted : method == 'delete' ? 1 : 0, + id : trans_id, + fq_field : obj.classname + '.' + field, + identity_value : obj.id(), + translation : dijit.byId('locale_' + trans_id).getValue(), + string : dijit.byId('translation_' + trans_id).getValue() + }); + + openils.I18N.translationWidget.writeTranslation(method, trans_obj, obj, field, num); + } + + openils.I18N.translationWidget.createTranslation = function (obj, field, num) { + var node = dojo.byId(field + '_translation_' + num); + + var trans_obj = new i18n().fromHash({ + isnew : 1, + fq_field : obj.classname + '.' + field, + identity_value : obj.id(), + translation : dijit.byId('i18n_new_locale_' + obj.classname + '.' + field + num).getValue(), + string : dijit.byId('i18n_new_translation_' + obj.classname + '.' + field + num).getValue() + }); + + openils.I18N.translationWidget.writeTranslation('create', trans_obj, obj, field, num); + } + + openils.I18N.translationWidget.writeTranslation = function (method, trans_obj, obj, field, num) { + + OpenSRF.CachedClientSession('open-ils.permacrud').request({ + method : 'open-ils.permacrud.' + method + '.i18n', + timeout: 10, + params : [ ses, trans_obj ], + onerror: function (r) { + //highlighter.editor_pane.red.play(); + if (status_update) status_update( 'Problem saving translation for ' + obj[field]() ); + }, + oncomplete : function (r) { + var res = r.recv(); + if ( res && res.content() ) { + //highlighter.editor_pane.green.play(); + if (status_update) status_update( 'Saved changes to translation for ' + obj[field]() ); + + if (method == 'delete') { + dojo.NodeList(dojo.byId('translation_row_' + trans_obj.id())).orphan(); + } else if (method == 'create') { + var node = dojo.byId(field + '_translation_' + num); + dijit.byId('i18n_new_locale_' + obj.classname + '.' + field + num).setValue(null); + dijit.byId('i18n_new_translation_' + obj.classname + '.' + field + num).setValue(null); + openils.I18N.translationWidget.renderTranslationPopup(obj, field, num); + } + + } else { + //highlighter.editor_pane.red.play(); + if (status_update) status_update( 'Problem saving translation for ' + obj[field]() ); + } + }, + }).send(); + } + +} + + diff --git a/Open-ILS/web/js/dojo/openils/User.js b/Open-ILS/web/js/dojo/openils/User.js new file mode 100644 index 0000000000..cbc2f195f3 --- /dev/null +++ b/Open-ILS/web/js/dojo/openils/User.js @@ -0,0 +1,114 @@ +/* --------------------------------------------------------------------------- + * Copyright (C) 2008 Georgia Public Library Service + * Bill Erickson + * + * 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["openils.User"]) { + + dojo._hasResource["openils.User"] = true; + dojo.provide("openils.User"); + dojo.require('openils.Event'); + dojo.require('DojoSRF'); + + dojo.declare('openils.User', null, {}); + + openils.User.user = null; + openils.User.authtoken = null; + openils.User.authtime = null; + + var ses = new OpenSRF.ClientSession('open-ils.auth'); + + openils.User.getBySession = function(onComplete) { + var req = ses.request('open-ils.auth.session.retrieve', openils.User.authtoken); + if(onComplete) { + req.oncomplete = function(r) { + var user = r.recv().content(); + openils.User.user = user; + if(onComplete) + onComplete(user); + } + req.send(); + } else { + req.timeout = 10; + req.send(); + return openils.User.user = req.recv().content(); + } + } + + openils.User.getById = function(id, onComplete) { + var ases = new OpenSRF.ClientSession('open-ils.actor'); + var req = ases.request('open-ils.actor.user.retrieve', openils.User.authtoken, id); + if(onComplete) { + req.oncomplete = function(r) { + var user = r.recv().content(); + onComplete(user); + } + req.send(); + } else { + req.timeout = 10; + req.send(); + return req.recv().content(); + } + } + + + /** + * Logs in, sets the authtoken/authtime vars, and fetches the logged in user + */ + openils.User.login = function(args, onComplete) { + var initReq = ses.request('open-ils.auth.authenticate.init', args.username); + + initReq.oncomplete = function(r) { + var seed = r.recv().content(); + alert(seed); + var loginInfo = { + password : hex_md5(seed + hex_md5(args.passwd)), + type : args.type || 'opac', + org : args.location, + }; + + var authReq = ses.request('open-ils.auth.authenticate.complete', loginInfo); + authReq.oncomplete = function(rr) { + var data = rr.recv().content(); + openils.User.authtoken = data.payload.authtoken; + openils.User.authtime = data.payload.authtime; + openils.User.getBySession(onComplete); + } + authReq.send(); + } + + initReq.send(); + } + + /** + * Returns a list of the "highest" org units where the user + * has the given permission. + */ + openils.User.getPermOrgList = function(perm, onload) { + + var ases = new OpenSRF.ClientSession('open-ils.actor'); + var req = ases.request( + 'open-ils.actor.user.work_perm.highest_org_set', + openils.User.authtoken, perm); + + req.oncomplete = function(r) { + org_list = r.recv().content(); + onload(org_list); + } + + req.send(); + } +} + + diff --git a/Open-ILS/web/opac/common/js/config.js b/Open-ILS/web/opac/common/js/config.js index 12499486e8..accdcd664b 100644 --- a/Open-ILS/web/opac/common/js/config.js +++ b/Open-ILS/web/opac/common/js/config.js @@ -9,6 +9,7 @@ var DO_AUTHORITY_LOOKUPS = true; var PARAM_TERM = "t"; /* search term */ var PARAM_STYPE = "tp"; /* search type */ var PARAM_LOCATION = "l"; /* current location */ +var PARAM_LASSO = "sg"; /* current location */ var PARAM_DEPTH = "d"; /* search depth */ var PARAM_FORM = "f"; /* search format */ var PARAM_OFFSET = "o"; /* search offset */ @@ -29,6 +30,7 @@ var PARAM_CN = "cn"; var PARAM_LITFORM = 'lf'; var PARAM_ITEMFORM = 'if'; var PARAM_ITEMTYPE = 'it'; +var PARAM_BIBLEVEL = 'bl'; var PARAM_AUDIENCE = 'a'; var PARAM_SEARCHES = 'ss'; var PARAM_LANGUAGE = 'la'; @@ -41,6 +43,7 @@ var PARAM_AVAIL = 'av'; /* limit search results to available items */ var TERM; var STYPE; var LOCATION; +var LASSO; var DEPTH; var FORM; var OFFSET; @@ -63,6 +66,7 @@ var CALLNUM; var LITFORM; var ITEMFORM; var ITEMTYPE; +var BIBLEVEL; var AUDIENCE; var SEARCHES; var LANGUAGE; @@ -338,6 +342,7 @@ var FETCH_COPY_STAT_CATS = 'open-ils.circ:open-ils.circ.asset.stat_cat_entries. var FETCH_LIT_FORMS = 'open-ils.search:open-ils.search.biblio.lit_form_map.retrieve.all'; var FETCH_ITEM_FORMS = 'open-ils.search:open-ils.search.biblio.item_form_map.retrieve.all'; var FETCH_ITEM_TYPES = 'open-ils.search:open-ils.search.biblio.item_type_map.retrieve.all'; +var FETCH_BIB_LEVELS = 'open-ils.search:open-ils.search.biblio.bib_level_map.retrieve.all'; var FETCH_AUDIENCES = 'open-ils.search:open-ils.search.biblio.audience_map.retrieve.all'; var FETCH_HOLD_STATUS = 'open-ils.circ:open-ils.circ.hold.status.retrieve'; var FETCH_NON_CAT_CIRCS = 'open-ils.circ:open-ils.circ.open_non_cataloged_circulation.user'; diff --git a/Open-ILS/web/opac/common/js/init.js b/Open-ILS/web/opac/common/js/init.js index 96b2e72755..9ad1ed8301 100644 --- a/Open-ILS/web/opac/common/js/init.js +++ b/Open-ILS/web/opac/common/js/init.js @@ -36,17 +36,22 @@ function init() { var org = G.user.prefs[PREF_DEF_LOCATION]; var depth = G.user.prefs[PREF_DEF_DEPTH]; - if(!org) org = G.user.ws_ou(); - if(!depth) depth = findOrgDepth(org); + if(org == null) org = G.user.ws_ou(); + if(depth == null) depth = findOrgDepth(org); LOCATION = org; - DEPTH = DEPTH; + DEPTH = depth; } } runEvt("common", "run"); //checkUserSkin(); - G.ui.common.now_searching.appendChild(text(findOrgUnit(getLocation()).name())); + + var loc = findOrgLasso(getLasso()); + if (!loc) loc = findOrgUnit(getLocation()); + + if (getLasso()) G.ui.common.now_searching.appendChild(text('Search group: ')); + G.ui.common.now_searching.appendChild(text(loc.name())); } function windowUnload() { runEvt("common", "unload"); } diff --git a/Open-ILS/web/opac/common/js/opac_utils.js b/Open-ILS/web/opac/common/js/opac_utils.js index fd50ebac9a..c730e50da0 100644 --- a/Open-ILS/web/opac/common/js/opac_utils.js +++ b/Open-ILS/web/opac/common/js/opac_utils.js @@ -109,11 +109,22 @@ function initParams() { /* handle the location var */ var org; var loc = cgi.param(PARAM_LOCATION); - if( loc ) { + var lasso = cgi.param(PARAM_LASSO); + + if ( lasso ) { + lasso = findOrgLasso( lasso ); + LASSO = lasso ? lasso.id() : null; + } + + if (loc) { org = findOrgUnit(loc); - if(!org) org = findOrgUnitSN(loc); - } - LOCATION = (org) ? org.id() : null; + LOCATION = org ? org.id() : null; + + if ( !LOCATION ){ + org = findOrgUnit(loc); + LOCATION = org ? org.id() : null; + } + } org = null; loc = cgi.param(PARAM_ORIGLOC); @@ -148,6 +159,7 @@ function initParams() { LITFORM = cgi.param(PARAM_LITFORM); ITEMFORM = cgi.param(PARAM_ITEMFORM); ITEMTYPE = cgi.param(PARAM_ITEMTYPE); + BIBLEVEL = cgi.param(PARAM_BIBLEVEL); AUDIENCE = cgi.param(PARAM_AUDIENCE); SEARCHES = cgi.param(PARAM_SEARCHES); LANGUAGE = cgi.param(PARAM_LANGUAGE); @@ -187,6 +199,7 @@ function clearSearchParams() { LITFORM = null; ITEMFORM = null; ITEMTYPE = null; + BIBLEVEL = null; AUDIENCE = null; SEARCHES = null; LANGUAGE = null; @@ -211,6 +224,7 @@ function initCookies() { function getTerm(){return TERM;} function getStype(){return STYPE;} function getLocation(){return LOCATION;} +function getLasso(){return LASSO;} function getDepth(){return DEPTH;} function getForm(){return FORM;} function getTform(){return TFORM;} @@ -234,6 +248,7 @@ function getCallnumber() { return CALLNUM; } function getLitForm() { return LITFORM; } function getItemForm() { return ITEMFORM; } function getItemType() { return ITEMTYPE; } +function getBibLevel() { return BIBLEVEL; } function getAudience() { return AUDIENCE; } function getSearches() { return SEARCHES; } function getLanguage() { return LANGUAGE; } @@ -343,6 +358,8 @@ function buildOPACLink(args, slim, ssl) { string += _appendParam(STYPE, PARAM_STYPE, args, getStype, string); if(getLocation() != 1) string += _appendParam(LOCATION, PARAM_LOCATION, args, getLocation, string); + if(getLasso() != null) + string += _appendParam(LASSO, PARAM_LASSO, args, getLasso, string); if(getDepth() != null) string += _appendParam(DEPTH, PARAM_DEPTH, args, getDepth, string); if(getForm() && (getForm() != 'all') ) @@ -371,6 +388,8 @@ function buildOPACLink(args, slim, ssl) { string += _appendParam(ITEMFORM, PARAM_ITEMFORM, args, getItemForm, string); if(getItemType()) string += _appendParam(ITEMTYPE, PARAM_ITEMTYPE, args, getItemType, string); + if(getBibLevel()) + string += _appendParam(BIBLEVEL, PARAM_BIBLEVEL, args, getBibLevel, string); if(getLitForm()) string += _appendParam(LITFORM, PARAM_LITFORM, args, getLitForm, string); if(getAudience()) @@ -695,7 +714,7 @@ function doLogin(suppressEvents) { return u; } -function doLogout(noredirect) { +function doLogout() { /* cancel everything else */ abortAllRequests(); @@ -771,8 +790,12 @@ function orgSelect(id) { showCanvas(); runEvt("common", "locationChanged", id, findOrgDepth(id) ); + + var loc = findOrgLasso(getLasso()); + if (!loc) loc = findOrgUnit(id); + removeChildren(G.ui.common.now_searching); - G.ui.common.now_searching.appendChild(text(findOrgUnit(id).name())); + G.ui.common.now_searching.appendChild(text(loc.name())); } function setFontSize(size) { diff --git a/Open-ILS/web/opac/common/js/org_utils.js b/Open-ILS/web/opac/common/js/org_utils.js index 4fcd742449..2acf826cb7 100644 --- a/Open-ILS/web/opac/common/js/org_utils.js +++ b/Open-ILS/web/opac/common/js/org_utils.js @@ -6,7 +6,7 @@ function fetchOrgSettingDefault(orgId, name) { var req = new Request(FETCH_ORG_SETTING, orgId, name); req.send(true); var res = req.result(); - return res.value; + return (res) ? res.value : null; } @@ -47,6 +47,14 @@ function findOrgUnit(org_id) { return (typeof org_id == 'object') ? org_id : orgArraySearcher[org_id]; } +function findOrgLasso(lasso_id) { + if (typeof lasso_id == 'object') return lasso_id; + for (var i in _lasso) { + if (_lasso[i].id() == lasso_id) return _lasso[i]; + } + return null; +} + var orgArraySearcherSN = {}; function findOrgUnitSN(shortname) { if (typeof shortname == 'object') return shortname; diff --git a/Open-ILS/web/opac/extras/slimpac/start.html b/Open-ILS/web/opac/extras/slimpac/start.html index 66cb824111..9cc06f500d 100644 --- a/Open-ILS/web/opac/extras/slimpac/start.html +++ b/Open-ILS/web/opac/extras/slimpac/start.html @@ -96,7 +96,7 @@
- &slimpac.search.nowSearching; + &slimpac.start.nowSearching; diff --git a/Open-ILS/web/opac/locale/en-CA/lang.dtd b/Open-ILS/web/opac/locale/en-CA/lang.dtd index 4f8d9cb166..ef0a5ed074 100644 --- a/Open-ILS/web/opac/locale/en-CA/lang.dtd +++ b/Open-ILS/web/opac/locale/en-CA/lang.dtd @@ -5,6 +5,7 @@ + @@ -39,6 +40,7 @@ + @@ -1130,6 +1132,7 @@ + @@ -1210,3 +1213,463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +YYYY-MM-DD. Times must have the form HH:MM"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd index 51a9a08526..ca15947bff 100644 --- a/Open-ILS/web/opac/locale/en-US/lang.dtd +++ b/Open-ILS/web/opac/locale/en-US/lang.dtd @@ -5,6 +5,7 @@ + @@ -39,6 +40,7 @@ + @@ -1130,6 +1132,7 @@ + @@ -1210,3 +1213,686 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +YYYY-MM-DD. Times must have the form HH:MM"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Open-ILS/web/opac/locale/en-US/opac.dtd b/Open-ILS/web/opac/locale/en-US/opac.dtd index 44f535b3df..3100a85d4b 100644 --- a/Open-ILS/web/opac/locale/en-US/opac.dtd +++ b/Open-ILS/web/opac/locale/en-US/opac.dtd @@ -42,7 +42,7 @@ - + @@ -69,15 +69,14 @@ +of the bookbag to be seen by others. Are you sure you wish to share this bookbag?"> @@ -174,7 +173,7 @@ avoid using bookbags all together. Thank you."> - + /jscalendar/calendar.js'> +
@@ -12,13 +13,10 @@ &opac.holds.xulRecipient;: - - + + - @@ -130,7 +128,7 @@ &opac.holds.freeze; - (&common.help;) + &common.help; + diff --git a/Open-ILS/web/opac/skin/default/xml/common/statusbar.xml b/Open-ILS/web/opac/skin/default/xml/common/statusbar.xml index a6462c0e03..237be6264b 100644 --- a/Open-ILS/web/opac/skin/default/xml/common/statusbar.xml +++ b/Open-ILS/web/opac/skin/default/xml/common/statusbar.xml @@ -13,7 +13,7 @@ - + diff --git a/Open-ILS/web/opac/skin/default/xml/myopac/myopac_holds.xml b/Open-ILS/web/opac/skin/default/xml/myopac/myopac_holds.xml index 7b81763b82..3d98e39d70 100644 --- a/Open-ILS/web/opac/skin/default/xml/myopac/myopac_holds.xml +++ b/Open-ILS/web/opac/skin/default/xml/myopac/myopac_holds.xml @@ -26,6 +26,18 @@ &myopac.holds.processing; +
+
&myopac.holds.freeze.select_thaw;
+

+ + + (&opac.holds.freeze.thaw_date.format;) +

+

+ +

+
+ @@ -78,8 +90,12 @@ diff --git a/Open-ILS/web/opac/skin/default/xml/result/filtersort.xml b/Open-ILS/web/opac/skin/default/xml/result/filtersort.xml index 6177b52be7..27eb382ee6 100644 --- a/Open-ILS/web/opac/skin/default/xml/result/filtersort.xml +++ b/Open-ILS/web/opac/skin/default/xml/result/filtersort.xml @@ -1,6 +1,6 @@ - &result.limit2avail; - + @@ -169,8 +175,11 @@ »» + diff --git a/Open-ILS/web/opac/theme/default/css/colors.css b/Open-ILS/web/opac/theme/default/css/colors.css index 9c62201ca6..9bfe478d33 100644 --- a/Open-ILS/web/opac/theme/default/css/colors.css +++ b/Open-ILS/web/opac/theme/default/css/colors.css @@ -93,3 +93,6 @@ a:focus { background: #E0F0E0; color: #000000;} .x_mark { color: red; } .check_mark { color: green; } +#myopac_holds_thaw_date_form { border: 1px solid #E0E0E0; } + +.invalid_field { border: 3px solid red; } diff --git a/Open-ILS/web/reports/oils_rpt_tforms.js b/Open-ILS/web/reports/oils_rpt_tforms.js index e890204945..38781f85d3 100644 --- a/Open-ILS/web/reports/oils_rpt_tforms.js +++ b/Open-ILS/web/reports/oils_rpt_tforms.js @@ -51,6 +51,16 @@ var OILS_RPT_TRANSFORMS = { label : 'Upper case' }, + first5 : { + datatype : [OILS_RPT_DTYPE_STRING, 'text'], + label : 'First 5 characters (for US ZIP code)' + }, + + first_word : { + datatype : [OILS_RPT_DTYPE_STRING, 'text'], + label : 'First contiguous non-space string' + }, + /* timestamp transforms ----------------------- */ dow : { datatype : OILS_RPT_DTYPE_TIMESTAMP, diff --git a/Open-ILS/web/reports/xul/transforms.js b/Open-ILS/web/reports/xul/transforms.js index c901f346ec..b81b684b40 100644 --- a/Open-ILS/web/reports/xul/transforms.js +++ b/Open-ILS/web/reports/xul/transforms.js @@ -88,6 +88,16 @@ var OILS_RPT_TRANSFORMS = { label : 'Upper case' }, + firt5 : { + datatype : [ OILS_RPT_DTYPE_STRING ], + label : 'First 5 characters (for US ZIP code)' + }, + + first_word : { + datatype : [OILS_RPT_DTYPE_STRING, 'text'], + label : 'First contiguous non-space string' + }, + /* timestamp transforms ----------------------- */ dow : { datatype : [ OILS_RPT_DTYPE_TIMESTAMP ], diff --git a/Open-ILS/xsl/locDoc2xml.xsl b/Open-ILS/xsl/locDoc2xml.xsl new file mode 100644 index 0000000000..596fef18ac --- /dev/null +++ b/Open-ILS/xsl/locDoc2xml.xsl @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + false + + + + + + + + + + + + + diff --git a/Open-ILS/xul/staff_client/Makefile b/Open-ILS/xul/staff_client/Makefile index 10428acbdc..05edd2fb56 100644 --- a/Open-ILS/xul/staff_client/Makefile +++ b/Open-ILS/xul/staff_client/Makefile @@ -9,19 +9,14 @@ else endif all: build - @echo - @echo build: build_dir generated open-ils custom stamp - @echo - @echo @echo To test the staff client: @echo " cd build/" @echo " xulrunner application.ini" build_dir: - @echo - @echo '********************************************************* Creating and populating build/ ' + @echo ' * Creating and populating build/ ' mkdir -p build/ cp -R chrome build/ cp -R server build/ @@ -34,13 +29,11 @@ build_dir: cp build/chrome/content/main/simple_auth.xul build/server/main/simple_auth.xul cp build/chrome/content/OpenILS/data.js build/server/OpenILS/data.js cp build/chrome/content/OpenILS/global_util.js build/server/OpenILS/global_util.js - @echo # Is the following portable? for i in `cd ../../../Evergreen/xul/staff_client/server/ && find -type f |grep -v \.svn|cut -f2- -d/`; do cp ../../../Evergreen/xul/staff_client/server/$$i build/server/$$i; done external/prune_dirs.sh build/ stamp: - @echo @/bin/date +"%Y%m%d.%H%M%S" > build/BUILD_ID @if [ -n "${STAFF_CLIENT_BUILD_ID}" ]; then ( echo "Stamping with Build ID: ${STAFF_CLIENT_BUILD_ID}" ; echo ${STAFF_CLIENT_BUILD_ID} > build/BUILD_ID ) ; fi @if [ -z "${STAFF_CLIENT_BUILD_ID}" ]; then ( echo "No Build ID for versioning" ; echo "none" > build/BUILD_ID ) ; fi @@ -53,28 +46,20 @@ stamp: @if [ -n "${STAFF_CLIENT_BUILD_ID}" ]; then find build/ -name '*.xml' -exec sed -i s/xul\\\/server/xul\\\/${STAFF_CLIENT_BUILD_ID}\\\/server/g {} \; ; fi generated: - @echo - @echo '********************************************************* Grabbing lang.dtd from the OPAC code ' + @echo ' * Grabbing lang.dtd from the OPAC code ' cp ../../../Open-ILS/web/opac/locale/en-US/lang.dtd build/chrome/locale/en-US/ - # Generate the lang.js file for the stamped build - external/dtd2js.pl build/chrome/locale/en-US/lang.dtd > build/chrome/content/main/lang.js - cp build/chrome/content/main/lang.js build/server/main/lang.js open-ils: - @echo - @echo '********************************************************* Grabbing more OPAC code and legacy code and custom code' + @echo ' * Grabbing more OPAC code and legacy code and custom code' #cp ../../../OpenSRF/src/javascript/*.js build/chrome/content/OpenSRF/ cp ../../../Open-ILS/web/opac/common/js/*.js build/chrome/content/OpenILS/util/ cp $(OPENSRF_JSLIBS)/*.js build/chrome/content/OpenILS/util/ external/prune_dirs.sh build/ custom: - @echo - @echo - @echo '********************************************************* Placeholder for debugging tweaks ' + @echo ' * Placeholder for debugging tweaks ' #(cd chrome/content/OpenILS/util; cp RemoteRequest.js~ RemoteRequest.js) clean: - @echo - @echo '********************************************************* Removing build/ ' + @echo ' * Removing build/ ' rm -rf build/ diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/data.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/data.js index c6e1159f23..4565aba5f6 100644 --- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/data.js +++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/data.js @@ -172,7 +172,7 @@ OpenILS.data.prototype = { if (obj.hash[key] && obj.hash[key][value]) return obj.hash[key][value]; switch(key) { case 'acpl': - found = obj.network.simple_request('FM_ACPL_RETRIEVE_VIA_ID',[ value ]); + found = obj.network.simple_request('FM_ACPL_RETRIEVE_VIA_ID.authoritative',[ value ]); break; default: return undefined; break; } @@ -704,6 +704,28 @@ OpenILS.data.prototype = { this.chain.push( function() { var f = gen_fm_retrieval_func( + 'my_cnct', + [ + api.FM_CNCT_RETRIEVE.app, + api.FM_CNCT_RETRIEVE.method, + [ obj.list.au[0].ws_ou() ], + false + ] + ); + try { + f(); + } catch(E) { + var error = 'Error: ' + js2JSON(E); + obj.error.sdump('D_ERROR',error); + throw(E); + } + } + ); + + + this.chain.push( + function() { + var f = gen_fm_retrieval_func( 'acpl', [ api.FM_ACPL_RETRIEVE.app, diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js index 987c2b75de..6302446a8f 100644 --- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js +++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js @@ -27,7 +27,8 @@ removeCSSClass(document.documentElement,'ALL_FONTS_XX_LARGE'); addCSSClass(document.documentElement,data.global_font_adjust); } catch(E) { - alert("Error with adjusting the font size: " + E); + var Strings = $('offlineStrings') || $('commonStrings'); + alert(Strings.getFormattedString('openils.global_util.font_size.error', [E])); } } @@ -42,16 +43,20 @@ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); if (frame && frame.contentWindow) { try { - if (typeof frame.contentWindow.wrappedJSObject != 'undefined') return frame.contentWindow.wrappedJSObject; + if (typeof frame.contentWindow.wrappedJSObject != 'undefined') { + return frame.contentWindow.wrappedJSObject; + } } catch(E) { - alert("Error with get_contentWindow("+frame+") and wrappedJSObject:" + E); + var Strings = $('offlineStrings') || $('commonStrings'); + alert(Strings.getFormattedString('openils.global_util.content_window_jsobject.error', [frame, E])); } return frame.contentWindow; } else { return null; } } catch(E) { - alert("Error with get_contentWindow("+frame+"): " + E); + var Strings = $('offlineStrings') || $('commonStrings'); + alert(Strings.getFormattedString('openils.global_util.content_window.error', [frame, E])); } } @@ -190,9 +195,11 @@ const gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"] .getService(Components.interfaces.nsIClipboardHelper); gClipboardHelper.copyString(text); - alert('Copied "'+text+'" to clipboard.'); + var Strings = $('offlineStrings') || $('commonStrings'); + alert(Strings.getFormattedString('openils.global_util.clipboard', [text])); } catch(E) { - alert('Clipboard action failed: ' + E); + var Strings = $('offlineStrings') || $('commonStrings'); + alert(Strings.getFormattedString('openils.global_util.clipboard.error', [E])); } } @@ -204,7 +211,8 @@ cacheService.evictEntries(Components.interfaces.nsICache.STORE_ON_DISK); cacheService.evictEntries(Components.interfaces.nsICache.STORE_IN_MEMORY); } catch(E) { - alert('Problem clearing the cache: ' + E); + var Strings = $('offlineStrings') || $('commonStrings'); + alert(Strings.getFormattedString('openils.global_util.clear_cache.error', [E])); } } @@ -213,4 +221,10 @@ window.open(uri, "_blank", winopts); } + function url_prefix(url) { + if (url.match(/^\//)) url = urls.remote + url; + if (! url.match(/^(http|chrome):\/\//) && ! url.match(/^data:/) ) url = 'http://' + url; + dump('url_prefix = ' + url + '\n'); + return url; + } diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/util/fmall.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/util/fmall.js index 88fe4dce07..2032b12336 100644 --- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/util/fmall.js +++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/util/fmall.js @@ -1,5 +1,7 @@ try { - if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); } + if (typeof JSAN == 'undefined') { + throw(document.getElementById('offlineStrings').getString('common.jsan.missing')); + } JSAN.errorLevel = "die"; // none, warn, or die JSAN.addRepository('..'); JSAN.use('OpenILS.data'); diff --git a/Open-ILS/xul/staff_client/chrome/content/admin/survey.js b/Open-ILS/xul/staff_client/chrome/content/admin/survey.js index 9dccae731c..24bdcbaabb 100644 --- a/Open-ILS/xul/staff_client/chrome/content/admin/survey.js +++ b/Open-ILS/xul/staff_client/chrome/content/admin/survey.js @@ -247,10 +247,10 @@ function add_question_row(my_asvq) { g_row_2.appendChild(g_tb); if (last_button) last_button.setAttribute('accesskey',''); var g_b = document.createElement('button'); - var strbundle = document.getElementById("adminStrings"); - g_b.setAttribute('label', strbundle.getString('staff.admin.survey.save_response.label')); - g_b.setAttribute('accesskey', strbundle.getString('staff.admin.survey.save_response.label')); - g_b.setAttribute('oncommand','add_answer(event,' + my_asvq.id() + ');'); + var strbundle = document.getElementById("offlineStrings"); + g_b.setAttribute('label', strbundle.getString('staff.admin.survey.save_response.label')); + g_b.setAttribute('accesskey', strbundle.getString('staff.admin.survey.save_response.label')); + g_b.setAttribute('oncommand','add_answer(event,' + my_asvq.id() + ');'); g_row_2.appendChild(g_b); var blank = document.createElement('row'); diff --git a/Open-ILS/xul/staff_client/chrome/content/admin/survey_wizard.xul b/Open-ILS/xul/staff_client/chrome/content/admin/survey_wizard.xul index 0061170ff2..a7ec139515 100644 --- a/Open-ILS/xul/staff_client/chrome/content/admin/survey_wizard.xul +++ b/Open-ILS/xul/staff_client/chrome/content/admin/survey_wizard.xul @@ -21,14 +21,13 @@ - - - - + diff --git a/Open-ILS/xul/staff_client/chrome/content/auth/controller.js b/Open-ILS/xul/staff_client/chrome/content/auth/controller.js index 482c98ec54..f49f3c1e53 100644 --- a/Open-ILS/xul/staff_client/chrome/content/auth/controller.js +++ b/Open-ILS/xul/staff_client/chrome/content/auth/controller.js @@ -1,4 +1,5 @@ dump('entering auth/controller.js\n'); +// vim:sw=4:ts=4:noet: if (typeof auth == 'undefined') auth = {}; auth.controller = function (params) { @@ -130,7 +131,7 @@ auth.controller.prototype = { } else { x.appendChild( document.createTextNode( - 'Not yet configured for the specified server.' + document.getElementById('authStrings').getString('staff.auth.controller.not_configured') ) ); } @@ -211,11 +212,11 @@ auth.controller.prototype = { obj.controller.view.submit_button.disabled = true; obj.controller.view.server_prompt.disabled = true; var s = document.getElementById('status'); - s.setAttribute('value','Testing hostname...'); + s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.testing_hostname')); s.setAttribute('style','color: orange;'); document.getElementById('version').value = ''; if (!url) { - s.setAttribute('value','Please enter a server hostname.'); + s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.prompt_hostname')); s.setAttribute('style','color: red;'); obj.controller.view.server_prompt.disabled = false; obj.controller.view.server_prompt.focus(); @@ -229,7 +230,7 @@ auth.controller.prototype = { x.onreadystatechange = function() { try { if (x.readyState != 4) return; - s.setAttribute('value',x.status + ' : ' + x.statusText); + s.setAttribute('value', document.getElementById('authStrings').getFormattedString('staff.auth.controller.status', [x.status, x.statusText])); if (x.status == 200) { s.setAttribute('style','color: green;'); } else { @@ -239,14 +240,14 @@ auth.controller.prototype = { } catch(E) { obj.controller.view.server_prompt.disabled = false; obj.controller.view.server_prompt.focus(); - s.setAttribute('value','There was an error testing this hostname.'); + s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.error_hostname')); s.setAttribute('style','color: red;'); obj.error.sdump('D_ERROR',E); } } x.send(null); } catch(E) { - s.setAttribute('value','There was an error testing this hostname.'); + s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.error_hostname')); s.setAttribute('style','color: brown;'); obj.error.sdump('D_ERROR',E); obj.controller.view.server_prompt.disabled = false; @@ -257,7 +258,7 @@ auth.controller.prototype = { 'test_version' : function(url) { var obj = this; var s = document.getElementById('version'); - s.setAttribute('value','Testing version...'); + s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.testing_version')); s.setAttribute('style','color: orange;'); try { var x = new XMLHttpRequest(); @@ -267,7 +268,7 @@ auth.controller.prototype = { x.onreadystatechange = function() { try { if (x.readyState != 4) return; - s.setAttribute('value',x.status + ' : ' + x.statusText); + s.setAttribute('value', document.getElementById('authStrings').getFormattedString('staff.auth.controller.status', [x.status, x.statusText])); if (x.status == 200) { s.setAttribute('style','color: green;'); obj.controller.view.submit_button.disabled = false; @@ -277,7 +278,7 @@ auth.controller.prototype = { } obj.controller.view.server_prompt.disabled = false; } catch(E) { - s.setAttribute('value','There was an error checking version support.'); + s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.error_version')); s.setAttribute('style','color: red;'); obj.error.sdump('D_ERROR',E); obj.controller.view.server_prompt.disabled = false; @@ -285,7 +286,7 @@ auth.controller.prototype = { } x.send(null); } catch(E) { - s.setAttribute('value','There was an error checking version support.'); + s.setAttribute('value', document.getElementById('authStrings').getString('staff.auth.controller.error_version')); s.setAttribute('style','color: brown;'); obj.error.sdump('D_ERROR',E); obj.controller.view.server_prompt.disabled = false; @@ -305,7 +306,7 @@ auth.controller.prototype = { if (x.status == 200) { window.open('data:text/html,'+window.escape(x.responseText),'upgrade','chrome,resizable,modal,centered'); } else { - alert('This server does not support your version of the staff client. Please check with your system administrator.'); + alert(document.getElementById('authStrings').getString('staff.auth.controller.version_mismatch')); } obj.controller.view.server_prompt.disabled = false; } catch(E) { @@ -324,10 +325,14 @@ auth.controller.prototype = { var obj = this; - this.error.sdump('D_AUTH','login with ' - + this.controller.view.name_prompt.value + ' and ' - + this.controller.view.password_prompt.value + ' at ' - + this.controller.view.server_prompt.value + '\n' + this.error.sdump('D_AUTH', + document.getElementById('authStrings').getFormattedString( + 'staff.auth.controller.error_login', [ + this.controller.view.name_prompt.value, + this.controller.view.password_prompt.value, + this.controller.view.server_prompt.value + ] + ) ); this.controller.view.server_prompt.disabled = true; this.controller.view.name_prompt.disabled = true; @@ -455,7 +460,7 @@ auth.controller.prototype = { this.error.sdump('D_AUTH','close' + this.w + '\n'); - if (window.confirm('Are you sure you would like to exit the program completely?')) { + if (window.confirm(document.getElementById('authStrings').getString('staff.auth.controller.confirm_close'))) { this.logoff(); this.w.close(); /* Probably won't go any further */ diff --git a/Open-ILS/xul/staff_client/chrome/content/auth/session.js b/Open-ILS/xul/staff_client/chrome/content/auth/session.js index 80baa7b13e..db1cff8883 100644 --- a/Open-ILS/xul/staff_client/chrome/content/auth/session.js +++ b/Open-ILS/xul/staff_client/chrome/content/auth/session.js @@ -1,4 +1,5 @@ dump('entering auth/session.js\n'); +// vim:sw=4:ts=4:noet: if (typeof auth == 'undefined') auth = {}; auth.session = function (view,login_type) { @@ -46,13 +47,13 @@ auth.session.prototype = { var robj = this.network.simple_request( 'AUTH_COMPLETE', [ params ]); - switch (robj.ilsevent) { + switch (Number(robj.ilsevent)) { case 0: this.key = robj.payload.authtoken; this.authtime = robj.payload.authtime; break; case 1520 /* WORKSTATION_NOT_FOUND */: - alert(params.workstation + ' is not registered with this server.'); + alert(document.getElementById('authStrings').getFormattedString('staff.auth.session.unregistered', [params.workstation])); delete(params.workstation); delete(data.ws_info[ this.view.server_prompt.value ]); data.stash('ws_info'); @@ -82,13 +83,13 @@ auth.session.prototype = { } else { - var error = 'open-ils.auth.authenticate.init returned false\n'; + var error = document.getElementById('authStrings').getString('staff.auth.session.init_false') + '\n'; this.error.sdump('D_ERROR',error); throw(error); } } catch(E) { - alert('Login failed. Please check your Server Hostname, Username, Password, and your CAPS LOCK key.'); + alert(document.getElementById('authStrings').getString('staff.auth.session.login_failed')); //obj.error.standard_unexpected_error_alert('Error on auth.session.init()',E); if (typeof this.on_init_error == 'function') { diff --git a/Open-ILS/xul/staff_client/chrome/content/cat/opac.js b/Open-ILS/xul/staff_client/chrome/content/cat/opac.js index 3675a68491..b11012d3aa 100644 --- a/Open-ILS/xul/staff_client/chrome/content/cat/opac.js +++ b/Open-ILS/xul/staff_client/chrome/content/cat/opac.js @@ -5,7 +5,7 @@ function $(id) { return document.getElementById(id); } function my_init() { try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - if (typeof JSAN == 'undefined') { throw(document.getElementById('commonStrings').getString('common.jsan.missing')); } + if (typeof JSAN == 'undefined') { throw(document.getElementById('offlineStrings').getString('common.jsan.missing')); } JSAN.errorLevel = "die"; // none, warn, or die JSAN.addRepository('..'); JSAN.use('util.error'); g.error = new util.error(); @@ -28,7 +28,7 @@ function my_init() { set_opac(); } catch(E) { - var err_msg = document.getElementById("commonStrings").getFormattedString("common.exception", ["cat/opac.xul", E]); + var err_msg = document.getElementById("offlineStrings").getFormattedString("common.exception", ["cat/opac.xul", E]); try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); } alert(err_msg); } @@ -43,7 +43,7 @@ function set_brief_view(reset) { { 'set_tab_name' : function(n) { if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') { - try { window.xulG.set_tab_name(document.getElementById('catStrings').getFormattedString("cat.bib_record", [n])); } catch(E) { alert(E); } + try { window.xulG.set_tab_name(document.getElementById('offlineStrings').getFormattedString("cat.bib_record", [n])); } catch(E) { alert(E); } } else { dump('no set_tab_name\n'); } @@ -62,24 +62,23 @@ function set_marc_view(reset) { } function set_marc_edit(reset) { - var strbundle = document.getElementById('catStrings'); g.view = 'marc_edit'; var a = xulG.url_prefix( urls.XUL_MARC_EDIT ); var b = {}; var c = { 'record' : { 'url' : '/opac/extras/supercat/retrieve/marcxml/record/' + docid }, 'save' : { - 'label' : strbundle.getString('cat.save_record'), + 'label' : document.getElementById('offlineStrings').getString('cat.save_record'), 'func' : function (new_marcxml) { try { var r = g.network.simple_request('MARC_XML_RECORD_UPDATE', [ ses(), docid, new_marcxml ]); if (typeof r.ilsevent != 'undefined') { throw(r); } else { - alert(strbundle.getString("cat.save.success")); + alert(document.getElementById('offlineStrings').getString("cat.save.success")); } } catch(E) { - g.error.standard_unexpected_error_alert(strbundle.getString("cat.save.failure"), E); + g.error.standard_unexpected_error_alert(document.getElementById('offlineStrings').getString("cat.save.failure"), E); } } } @@ -158,7 +157,7 @@ function set_opac(reset) { win.attachEvt("rdetail", "nextPrevDrawn", function(rIndex,rCount){ - $('record_pos').setAttribute('value', document.getElementById('catStrings').getFormattedString('cat.record.counter', [(1+rIndex), rCount])); + $('record_pos').setAttribute('value', document.getElementById('offlineStrings').getFormattedString('cat.record.counter', [(1+rIndex), rCount])); if (win.rdetailNext) { g.f_record_next = function() { g.view_override = g.view; @@ -232,12 +231,19 @@ function mark_for_overlay() { } function delete_record() { - if (g.error.yns_alert('Are you sure you want to delete title record #' + docid + ' from the catalog?','Delete Record','Delete','Cancel',null,'Check here to confirm this action.') == 0) { + if (g.error.yns_alert( + document.getElementById('offlineStrings').getFormattedString('cat.opac.delete_record.confirm', [docid]), + document.getElementById('offlineStrings').getString('cat.opac.delete_record'), + document.getElementById('offlineStrings').getString('cat.opac.delete'), + document.getElementById('offlineStrings').getString('cat.opac.cancel'), + null, + document.getElementById('offlineStrings').getString('cat.opac.record_deleted.confirm')) == 0) { var robj = g.network.simple_request('FM_BRE_DELETE',[ses(),docid]); if (typeof robj.ilsevent != 'undefined') { - alert('Error deleting Record #' + docid + ' : ' + robj.textcode + ' : ' + robj.desc + '\n'); + alert(document.getElementById('offlineStrings').getFormattedString('cat.opac.record_deleted.error', [docid, robj.textcode, robj.desc]) + '\n'); } else { - alert('Record deleted.'); refresh_display(docid,true); + alert(document.getElementById('offlineStrings').getString('cat.opac.record_deleted')); + refresh_display(docid,true); } } } @@ -280,7 +286,7 @@ function set_default() { [ ses(), g.data.list.au[0].id(), { 'staff_client.catalog.record_view.default' : g.view } ] ) if (typeof robj.ilsevent != 'undefined') { - if (robj.ilsevent != 0) g.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('cat.preference.error'), robj); + if (robj.ilsevent != 0) g.error.standard_unexpected_error_alert(document.getElementById('offlineStrings').getString('cat.preference.error'), robj); } } diff --git a/Open-ILS/xul/staff_client/chrome/content/cat/opac.xul b/Open-ILS/xul/staff_client/chrome/content/cat/opac.xul index a5a5e2bddc..8ecf5ddf3c 100644 --- a/Open-ILS/xul/staff_client/chrome/content/cat/opac.xul +++ b/Open-ILS/xul/staff_client/chrome/content/cat/opac.xul @@ -30,9 +30,7 @@ - - - - +
+ + &common.no; + &common.yes;
diff --git a/Open-ILS/xul/staff_client/chrome/content/circ/offline_checkin.js b/Open-ILS/xul/staff_client/chrome/content/circ/offline_checkin.js index 26fa0fe938..8c74f39caa 100644 --- a/Open-ILS/xul/staff_client/chrome/content/circ/offline_checkin.js +++ b/Open-ILS/xul/staff_client/chrome/content/circ/offline_checkin.js @@ -1,20 +1,18 @@ -var commonStrings; -var circStrings; +var offlineStrings; function my_init() { try { - commonStrings = $('commonStrings'); - circStrings = $('circStrings'); + offlineStrings = $('offlineStrings'); netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - if (typeof JSAN == 'undefined') { throw(commonStrings.getString('common.jsan.missing')); } + if (typeof JSAN == 'undefined') { throw(offlineStrings.getString('common.jsan.missing')); } JSAN.errorLevel = "die"; // none, warn, or die JSAN.addRepository('..'); JSAN.use('util.error'); g.error = new util.error(); g.error.sdump('D_TRACE','my_init() for offline_checkin.xul'); if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') { - try { window.xulG.set_tab_name(circStrings.getString('circ.standalone')); } catch(E) { alert(E); } + try { window.xulG.set_tab_name(offlineStrings.getString('circ.standalone')); } catch(E) { alert(E); } } JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'}); @@ -40,7 +38,7 @@ function my_init() { if (file._file.exists()) { g.delta = file.get_object()[0]; file.close(); } else { g.delta = 0; } } catch(E) { - var err_msg = commonStrings.getFormattedString('common.exception', ["circ/offline_checkin.xul", E]); + var err_msg = offlineStrings.getFormattedString('common.exception', ["circ/offline_checkin.xul", E]); try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); } alert(err_msg); } @@ -59,7 +57,7 @@ function handle_keypress(ev) { function handle_enter(ev) { JSAN.use('util.barcode'); if ( ($('strict_i_barcode').checked) && (! util.barcode.check($('i_barcode').value)) ) { - var r = g.error.yns_alert(circStrings.getString('circ.bad_checkdigit'),circStrings.getString('circ.barcode.warning'),commonStrings.getString('common.ok'),commonStrings.getString('common.clear'),null,commonStrings.getString('common.confirm')); + var r = g.error.yns_alert(offlineStrings.getString('circ.bad_checkdigit'),offlineStrings.getString('circ.barcode.warning'),offlineStrings.getString('common.ok'),offlineStrings.getString('common.clear'),null,offlineStrings.getString('common.confirm')); if (r == 1) { setTimeout( function() { diff --git a/Open-ILS/xul/staff_client/chrome/content/circ/offline_checkin.xul b/Open-ILS/xul/staff_client/chrome/content/circ/offline_checkin.xul index 8211c2f7c0..d19616d0b4 100644 --- a/Open-ILS/xul/staff_client/chrome/content/circ/offline_checkin.xul +++ b/Open-ILS/xul/staff_client/chrome/content/circ/offline_checkin.xul @@ -29,8 +29,7 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/Open-ILS/xul/staff_client/chrome/content/legacy/_marc.xul b/Open-ILS/xul/staff_client/chrome/content/legacy/_marc.xul deleted file mode 100644 index 8668a92cc2..0000000000 --- a/Open-ILS/xul/staff_client/chrome/content/legacy/_marc.xul +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Open-ILS/xul/staff_client/chrome/content/main/JSAN.js b/Open-ILS/xul/staff_client/chrome/content/main/JSAN.js index 9d778fcbcd..e75030b6c0 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/JSAN.js +++ b/Open-ILS/xul/staff_client/chrome/content/main/JSAN.js @@ -246,7 +246,7 @@ JSAN._createScript = function (js, pkg) { try { return JSAN._makeNamespace(js, pkg); } catch (e) { - JSAN._handleError("Could not create namespace[" + pkg + "]: " + e); + JSAN._handleError(document.getElementById('offlineStrings').getFormattedString('jsan.namespace.creation.error', [pkg, e])); } return null; } @@ -276,11 +276,11 @@ JSAN.Request.prototype = { if (this._req.status == 200 || this._req.status == 0) return this._req.responseText; } catch (e) { - JSAN._handleError("File not found: " + url); + JSAN._handleError(document.getElementById('offlineStrings').getFormattedString('jsan.file_not_found.error', [url])); return null; }; - JSAN._handleError("File not found: " + url); + JSAN._handleError(document.getElementById('offlineStrings').getFormattedString('jsan.file_not_found.error', [url])); return null; } }; diff --git a/Open-ILS/xul/staff_client/chrome/content/main/about.html b/Open-ILS/xul/staff_client/chrome/content/main/about.html index 41ec6c400f..dae16d5ca0 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/about.html +++ b/Open-ILS/xul/staff_client/chrome/content/main/about.html @@ -1,6 +1,7 @@

Evergreen

-

Build ID:

+

Target Server ID:

+

$HeadURL$

What is Evergreen?

diff --git a/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml b/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml index 641514d5b0..1bf2c10156 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml +++ b/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml @@ -17,23 +17,38 @@ @@ -41,18 +56,23 @@ @@ -61,81 +81,103 @@ = 0) in_comment = true; - - if (in_comment && line.indexOf('*/') > 0) { - var comment_start = line.indexOf('/*'); - var comment_end = line.indexOf('*/'); - line = line.substring(0, comment_start) + line.substring(0, comment_end + 2); - in_comment = false; - } else if (in_comment) continue; - - // get rid of entire-line comments - if (line.indexOf('#') == 0) { - line = ''; - continue; - } - - // handle end-of-line comments - var end_comment = line.indexOf('//'); - if (end_comment >= 0) line = line.substring(0, end_comment); + try { + var lines = str.split("\n"); + var props = {}; + var line = ''; + var in_comment = false; + + for (var l in lines) { + line += lines[l]; + + // handle multi-line comments + if (line.indexOf('/*') >= 0) in_comment = true; + + if (in_comment && line.indexOf('*/') > 0) { + var comment_start = line.indexOf('/*'); + var comment_end = line.indexOf('*/'); + line = line.substring(0, comment_start) + line.substring(0, comment_end + 2); + in_comment = false; + } else if (in_comment) continue; + + // get rid of entire-line comments + if (line.indexOf('#') == 0) { + line = ''; + continue; + } + + // handle end-of-line comments + var end_comment = line.indexOf('//'); + if (end_comment >= 0) line = line.substring(0, end_comment); + + // and line concatenation + if (line.charAt(line.length - 1) == '\\') { + line = line.substring(0,line.length - 1); + continue; + } + + var eq_pos = line.indexOf('='); + if (eq_pos < 0) continue; + + var k = line.substring(0,eq_pos); + k = k.replace(/\s+/g,""); + + var v = line.substring(eq_pos + 1); + + var current_m = 0; + var cont = false; + do { + if (v.indexOf( "{" + current_m + "}" ) >= 0 ) { + var mes_bund = new RegExp( "\\\{" + current_m + "\\\}", 'g' ); + var sprintf_format = "%" + (current_m + 1) + "$s"; + + v = v.replace( mes_bund, sprintf_format ); + + cont = true; + current_m++; + } else { + cont = false; + } + } while ( cont == true ); + + props[k] = v; + line = ''; + } + + return props; + } catch(E) { + alert('Error in props2object in messagecatalog in bindings.xml: ' + E); + throw(E); + } + ]]> + + - // and line concatenation - if (line.charAt(line.lenth - 1) == '\\') { - line = line.substring(0,line.lenth - 1); - continue; + + + + = 0 ) { - var mes_bund = new RegExp( "\\\{" + current_m + "\\\}", 'g' ); - var sprintf_format = "%" + (current_m + 1) + "$s"; - - v = v.replace( mes_bund, sprintf_format ); - - cont = true; - current_m++; - } else { - cont = false; - } - } while ( cont == true ); - - props[k] = v; - line = ''; - } - - return props; ]]> + @@ -148,7 +190,8 @@ 100) throw('Error purging transactions: Taking too long to find a unique filename for archival.'); + if (count++ > 100) { + throw(offlineStrings.getString('main.transaction_export.filename.error')); + } } file._file.moveTo(null,filename); } else { - alert('Please note that you now have two sets of identical transactions. Unless the set you just exported is soley for archival purposes, we run the risk of duplicate transactions being processed on the server.'); + alert(offlineStrings.getString('main.transaction_export.duplicate.warning')); } } else { - alert('No filename chosen. Or a bug where you tried to overwrite an existing file.'); + alert(offlineStrings.getString('main.transaction_export.no_filename.error')); } } else { - alert('There are no outstanding transactions to export.'); + alert(offlineStrings.getString('main.transaction_export.no_transactions.error')); } file.close(); } catch(E) { alert(E); } - } + }; G.auth.on_standalone_import = function() { try { JSAN.use('util.file'); var file = new util.file('pending_xacts'); if (file._file.exists()) { - alert('There are already outstanding transactions on this staff client. Upload these first.'); + alert(offlineStrings.getString('main.transaction_import.outstanding.error')); } else { var file2 = new util.file(''); - var f = file2.pick_file( { 'mode' : 'open', 'title' : 'Import Transaction File'} ); + var f = file2.pick_file( { 'mode' : 'open', 'title' : offlineStrings.getString('main.transaction_import.title')} ); if (f && f.exists()) { var i_file = new util.file(''); i_file._file = f; file.write_content( 'truncate', i_file.get_content() ); i_file.close(); var r = G.error.yns_alert( - 'Your transactions have been successfully migrated to this staff client.\n\nWe recommend that you delete the external copy. Would you like for us to delete ' + f.leafName + '?', - 'Transaction Import Successful', - 'Yes', - 'No', + offlineStrings.getFormattedString('main.transaction_import.delete.prompt', [f.leafName]), + offlineStrings.getString('main.transaction_import.success'), + offlineStrings.getString('common.yes'), + offlineStrings.getString('common.no'), null, - 'Check here to confirm this message' + offlineStrings.getString('common.confirm') ); if (r == 0) { f.remove(false); @@ -200,7 +206,7 @@ function main_init() { } catch(E) { alert(E); } - } + }; G.auth.on_debug = function(action) { switch(action) { @@ -209,13 +215,13 @@ function main_init() { break; case 'clear_cache' : clear_the_cache(); - alert('cache cleared'); + alert(offlineStrings.getString('main.on_debug.clear_cache')); break; default: - alert('debug the debug :D'); + alert(offlineStrings.getString('main.on_debug.debug')); break; } - } + }; G.auth.init(); // XML_HTTP_SERVER will get reset to G.auth.controller.view.server_prompt.value @@ -230,7 +236,7 @@ function main_init() { //var x = document.getElementById('version_label'); //x.setAttribute('value','Build ID: ' + version); var x = document.getElementById('about_btn'); - x.setAttribute('label','About this client...'); + x.setAttribute('label', offlineStrings.getString('main.about_btn.label')); x.addEventListener( 'command', function() { @@ -252,14 +258,13 @@ function main_init() { // }, // false //); - if (window.confirm('This version of the staff client stores local settings in a different location than your previous installation. Should we attempt to migrate these settings?')) { + if (window.confirm(offlineStrings.getString('main.settings.migrate'))) { setTimeout( function() { handle_migration(); }, 0 ); } } } catch(E) { - var error = "!! This software has encountered an error. Please tell your friendly " + - "system administrator or software developer the following:\n" + E + '\n'; + var error = offlineStrings.getFormattedString('common.exception', [E, '']); try { G.error.sdump('D_ERROR',error); } catch(E) { dump(error); } alert(error); } @@ -286,17 +291,14 @@ function found_ws_info_in_Uchrome() { function handle_migration() { if ( found_ws_info_in_Uchrome() ) { - alert('WARNING: Unable to migrate legacy settings. The settings and configuration files appear to exist in multiple locations.\n' - + 'To resolve manually, please consider:\n\t' + found_ws_info_in_Uchrome() + '\n' - + 'which is in the directory where we want to store settings for the current OS user, and:\n\t' - + found_ws_info_in_Achrome() + '\nwhich is where we used to store such information.\n' + alert(offlineStrings.getFormattedString('main.settings.migrate.failed', [found_ws_info_in_Uchrome(), found_ws_info_in_Achrome()]) ); } else { var dirService = Components.classes["@mozilla.org/file/directory_service;1"].getService( Components.interfaces.nsIProperties ); var f_new = dirService.get( "UChrm", Components.interfaces.nsIFile ); var f_old = dirService.get( "AChrom", Components.interfaces.nsIFile ); f_old.append(myPackageDir); f_old.append("content"); f_old.append("conf"); - if (window.confirm("Move the settings and configuration files from\n" + f_old.path + "\nto\n" + f_new.path + "?")) { + if (window.confirm(offlineStrings.getFormattedString("main.settings.migrate.confirm", [f_old.path, f_new.path]))) { var files = f_old.directoryEntries; while (files.hasMoreElements()) { var file = files.getNext(); @@ -304,10 +306,10 @@ function handle_migration() { try { file2.moveTo( f_new, '' ); } catch(E) { - alert('Error trying to move ' + file2.path + ' to directory ' + f_new.path + '\n'); + alert(offlineStrings.getFormattedString('main.settings.migrate.error', [file2.path, f_new.path]) + '\n'); } } - location.href = location.href; + location.href = location.href; // huh? } } } diff --git a/Open-ILS/xul/staff_client/chrome/content/main/main.xul b/Open-ILS/xul/staff_client/chrome/content/main/main.xul index e669399257..35b1c67115 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/main.xul +++ b/Open-ILS/xul/staff_client/chrome/content/main/main.xul @@ -49,13 +49,15 @@ - + + + diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu.js b/Open-ILS/xul/staff_client/chrome/content/main/menu.js index 4ac7492744..b5bf127edf 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/menu.js +++ b/Open-ILS/xul/staff_client/chrome/content/main/menu.js @@ -1,4 +1,8 @@ dump('entering main/menu.js\n'); +// vim:noet:sw=4:ts=4: + +var offlineStrings; +offlineStrings = document.getElementById('offlineStrings'); if (typeof main == 'undefined') main = {}; main.menu = function () { @@ -31,7 +35,7 @@ main.menu.prototype = { var cmd_map = { 'cmd_broken' : [ ['oncommand'], - function() { alert('Not Yet Implemented'); } + function() { alert(offlineStrings.getString('common.unimplemented')); } ], /* File Menu */ @@ -68,28 +72,28 @@ main.menu.prototype = { ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_COPY_BUCKETS),{'tab_name':'Copy Buckets'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_COPY_BUCKETS),{'tab_name':offlineStrings.getString('menu.cmd_edit_copy_buckets.tab')},{}); } ], 'cmd_edit_volume_buckets' : [ ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_VOLUME_BUCKETS),{'tab_name':'Volume Buckets'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_VOLUME_BUCKETS),{'tab_name':offlineStrings.getString('menu.cmd_edit_volume_buckets.tab')},{}); } ], 'cmd_edit_record_buckets' : [ ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_RECORD_BUCKETS),{'tab_name':'Record Buckets'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_RECORD_BUCKETS),{'tab_name':offlineStrings.getString('menu.cmd_edit_record_buckets.tab')},{}); } ], 'cmd_edit_user_buckets' : [ ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_USER_BUCKETS),{'tab_name':'User Buckets'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_USER_BUCKETS),{'tab_name':offlineStrings.getString('menu.cmd_edit_user_buckets.tab')},{}); } ], @@ -101,7 +105,7 @@ main.menu.prototype = { JSAN.use('util.network'); var network = new util.network(); - var old_bc = window.prompt('Enter original barcode for the item:','','Replace Barcode'); + var old_bc = window.prompt(offlineStrings.getString('menu.cmd_replace_barcode.prompt'),'',offlineStrings.getString('menu.cmd_replace_barcode.label')); if (!old_bc) return; var copy; @@ -110,7 +114,7 @@ main.menu.prototype = { if (typeof copy.ilsevent != 'undefined') throw(copy); if (!copy) throw(copy); } catch(E) { - alert('We were unable to retrieve an item with barcode "' + old_bc + '".\n'); + alert(offlineStrings.getFormattedString('menu.cmd_replace_barcode.retrieval.error', [old_bc]) + '\n'); return; } @@ -120,24 +124,24 @@ main.menu.prototype = { if (typeof copy.ilsevent != 'undefined') throw(copy); if (!copy) throw(copy); } catch(E) { - try { alert('We were unable to retrieve an item with barcode "' + old_bc + '".\n' + (typeof E.ilsevent == 'undefined' ? '' : E.textcode + ' : ' + E.desc)); } catch(F) { alert(E + '\n' + F); } + try { alert(offlineStrings.getFormattedString('menu.cmd_replace_barcode.retrieval.error', [old_bc]) + '\n' + (typeof E.ilsevent == 'undefined' ? '' : E.textcode + ' : ' + E.desc)); } catch(F) { alert(E + '\n' + F); } return; } - var new_bc = window.prompt('Enter the replacement barcode for the copy:','','Replace Barcode'); + var new_bc = window.prompt(offlineStrings.getString('menu.cmd_replace_barcode.replacement.prompt'),'',offlineStrings.getString('menu.cmd_replace_barcode.replacement.label')); new_bc = String( new_bc ).replace(/\s/g,''); if (!new_bc) { - alert('Rename aborted. Blank for barcode not allowed.'); + alert(offlineStrings.getString('menu.cmd_replace_barcode.blank.error')); return; } var test = network.simple_request('FM_ACP_RETRIEVE_VIA_BARCODE',[ new_bc ]); if (typeof test.ilsevent == 'undefined') { - alert('Rename aborted. Another copy has barcode "' + new_bc + '".'); + alert(offlineStrings.getFormattedString('menu.cmd_replace_barcode.duplicate.error', [new_bc])); return; } else { if (test.ilsevent != 1502 /* ASSET_COPY_NOT_FOUND */) { - obj.error.standard_unexpected_error_alert('Error testing replacement barcode "' + new_bc + '".',test); + obj.error.standard_unexpected_error_alert(offlineStrings.getFormattedString('menu.cmd_replace_barcode.testing.error', [new_bc]),test); return; } } @@ -147,14 +151,14 @@ main.menu.prototype = { if (typeof r.ilsevent != 'undefined') { if (r.ilsevent != 0) { if (r.ilsevent == 5000 /* PERM_FAILURE */) { - alert('Renamed aborted. Insufficient permission.'); + alert(offlineStrings.getString('menu.cmd_replace_barcode.permission.error')); } else { - obj.error.standard_unexpected_error_alert('Error renaming item.',r); + obj.error.standard_unexpected_error_alert(offlineStrings.getString('menu.cmd_replace_barcode.renaming.error'),r); } } } } catch(E) { - obj.error.standard_unexpected_error_alert('Rename did not likely occur.',copy); + obj.error.standard_unexpected_error_alert(offlineStrings.getString('menu.cmd_replace_barcode.renaming.failure'),copy); } } ], @@ -172,13 +176,13 @@ main.menu.prototype = { function() { obj.data.stash_retrieve(); var content_params = { 'session' : ses(), 'authtime' : ses('authtime') }; - obj.set_tab(obj.url_prefix(urls.XUL_OPAC_WRAPPER), {'tab_name':'Catalog'}, content_params); + obj.set_tab(obj.url_prefix(urls.XUL_OPAC_WRAPPER), {'tab_name':offlineStrings.getString('menu.cmd_search_opac.tab')}, content_params); } ], 'cmd_search_tcn' : [ ['oncommand'], function() { - var tcn = prompt('What is the TCN or accession ID for the record?','','TCN Lookup'); + var tcn = prompt(offlineStrings.getString('menu.cmd_search_tcn.tab'),'',offlineStrings.getString('menu.cmd_search_tcn.prompt')); function spawn_tcn(r) { for (var i = 0; i < r.count; i++) { @@ -214,9 +218,9 @@ main.menu.prototype = { if (robj.count == 0) { var robj2 = network.simple_request('FM_BRE_ID_SEARCH_VIA_TCN',[tcn,1]); if (robj2.count == 0) { - alert('"' + tcn + '" not found'); + alert(offlineStrings.getFormattedString('menu.cmd_search_tcn.not_found.error', [tcn])); } else { - if ( window.confirm('"' + tcn + '" is deleted. Show deleted record anyway?') ) { + if ( window.confirm(offlineStrings.getFormattedString('menu.cmd_search_tcn.deleted.error', [tcn])) ) { spawn_tcn(robj2); } } @@ -251,7 +255,7 @@ main.menu.prototype = { {}, { 'show_print_button' : true , - 'tab_name' : 'Editing Related Patron' , + 'tab_name' : offline.getString('menu.cmd_patron_register.related.tab'), 'passthru_content_params' : { 'spawn_search' : function(s) { obj.spawn_search(s); }, 'spawn_editor' : spawn_editor, @@ -268,7 +272,7 @@ main.menu.prototype = { {}, { 'show_print_button' : true , - 'tab_name' : 'Register Patron' , + 'tab_name' : offlineStrings.getString('menu.cmd_patron_register.tab'), 'passthru_content_params' : { 'spawn_search' : function(s) { obj.spawn_search(s); }, 'spawn_editor' : spawn_editor, @@ -302,14 +306,14 @@ main.menu.prototype = { ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_HOLDS_BROWSER),{ 'tab_name' : 'Hold Browser' },{}); + obj.set_tab(obj.url_prefix(urls.XUL_HOLDS_BROWSER),{ 'tab_name' : offlineStrings.getString('menu.cmd_browse_holds.tab') },{}); } ], 'cmd_browse_holds_shelf' : [ ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_HOLDS_BROWSER)+'?shelf=1',{ 'tab_name' : 'Holds Shelf' },{}); + obj.set_tab(obj.url_prefix(urls.XUL_HOLDS_BROWSER)+'?shelf=1',{ 'tab_name' : offlineStrings.getString('menu.cmd_browse_holds_shelf.tab') },{}); } ], 'cmd_circ_hold_pull_list' : [ @@ -319,7 +323,7 @@ main.menu.prototype = { var loc = urls.XUL_REMOTE_BROWSER + '?url=' + window.escape( obj.url_prefix(urls.XUL_HOLD_PULL_LIST) + '?ses='+window.escape(ses()) ); - obj.set_tab( loc, {'tab_name':'On Shelf Pull List'}, { 'show_print_button' : true, } ); + obj.set_tab( loc, {'tab_name' : offlineStrings.getString('menu.cmd_browse_hold_pull_list.tab')}, { 'show_print_button' : true, } ); } ], @@ -347,7 +351,7 @@ main.menu.prototype = { ); obj.set_tab( loc, - {'tab_name':'Local Administration', 'browser' : true }, + {'tab_name' : offlineStrings.getString('menu.cmd_local_admin.tab'), 'browser' : true }, { 'no_xulG' : false, 'show_nav_buttons' : true, 'show_print_button' : true } ); @@ -371,7 +375,7 @@ main.menu.prototype = { function() { obj.data.stash_retrieve(); if (!obj.data.last_patron) { - alert('No patron visited yet this session.'); + alert(offlineStrings.getString('menu.cmd_retrieve_last_patron.session.error')); return; } var url = obj.url_prefix( urls.XUL_PATRON_DISPLAY ); // + '?id=' + window.escape( obj.data.last_patron ) ); @@ -384,7 +388,7 @@ main.menu.prototype = { function() { obj.data.stash_retrieve(); if (!obj.data.last_record) { - alert('No record visited yet this session.'); + alert(offlineStrings.getString('menu.cmd_retrieve_last_record.session.error')); return; } var opac_url = obj.url_prefix( urls.opac_rdetail ) + '?r=' + obj.data.last_record; @@ -395,7 +399,7 @@ main.menu.prototype = { }; obj.set_tab( obj.url_prefix(urls.XUL_OPAC_WRAPPER), - {'tab_name':'Retrieving title...'}, + {'tab_name' : offlineStrings.getString('menu.cmd_retrieve_last_record.status')}, content_params ); } @@ -439,13 +443,13 @@ main.menu.prototype = { obj.data.stash('session'); removeCSSClass(document.getElementById('main_tabbox'),'operator_change'); } else { - if (network.get_new_session('Change Login',{'url_prefix':obj.url_prefix})) { + if (network.get_new_session(offlineStrings.getString('menu.cmd_chg_session.label'),{'url_prefix':obj.url_prefix})) { obj.data.stash_retrieve(); obj.data.list.au[1] = JSON2js( temp_au ); obj.data.stash('list'); obj.data.previous_session = JSON2js( temp_ses ); obj.data.stash('previous_session'); - x.setAttribute('label', 'Change Operator: ' + obj.data.list.au[1].usrname() ); + x.setAttribute('label', offlineStrings.getFormattedString('menu.cmd_chg_session.operator.label', [obj.data.list.au[1].usrname()]) ); addCSSClass(document.getElementById('main_tabbox'),'operator_change'); } } @@ -457,7 +461,7 @@ main.menu.prototype = { 'cmd_manage_offline_xacts' : [ ['oncommand'], function() { - obj.set_tab(obj.url_prefix(urls.XUL_OFFLINE_MANAGE_XACTS), {'tab_name':'Offline Transactions'}, {}); + obj.set_tab(obj.url_prefix(urls.XUL_OFFLINE_MANAGE_XACTS), {'tab_name' : offlineStrings.getString('menu.cmd_manage_offline_xacts.tab')}, {}); } ], 'cmd_download_patrons' : [ @@ -476,9 +480,9 @@ main.menu.prototype = { file = new util.file('offline_patron_list.date'); file.write_content('truncate',new Date()); file.close(); - alert('Download completed'); + alert(offlineStrings.getString('menu.cmd_download_patrons.complete.status')); } else { - alert('There was a problem with the download. The server returned a status ' + x.status + ' : ' + x.statusText); + alert(offlineStrings.getFormattedString('menu.cmd_download_patrons.error', [x.status, x.statusText])); } } catch(E) { obj.error.standard_unexpected_error_alert('cmd_download_patrons',E); @@ -489,7 +493,7 @@ main.menu.prototype = { ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_ADV_USER_BARCODE_ENTRY), {}, {}); + obj.set_tab(obj.url_prefix(urls.XUL_PATRON_BARCODE_ENTRY), {}, { 'perm_editor' : true }); } ], 'cmd_print_list_template_edit' : [ @@ -503,21 +507,21 @@ main.menu.prototype = { ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_STAT_CAT_EDIT) + '?ses='+window.escape(ses()),{'tab_name':'Stat Cat Editor'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_STAT_CAT_EDIT) + '?ses='+window.escape(ses()), {'tab_name' : offlineStrings.getString('menu.cmd_stat_cat_edit.tab')},{}); } ], 'cmd_non_cat_type_edit' : [ ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_NON_CAT_LABEL_EDIT) + '?ses='+window.escape(ses()),{'tab_name':'Non-Cataloged Type Editor'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_NON_CAT_LABEL_EDIT) + '?ses='+window.escape(ses()), {'tab_name' : offlineStrings.getString('menu.cmd_non_cat_type_edit.tab')},{}); } ], 'cmd_copy_location_edit' : [ ['oncommand'], function() { obj.data.stash_retrieve(); - obj.set_tab(obj.url_prefix(urls.XUL_COPY_LOCATION_EDIT) + '?ses='+window.escape(ses()),{'tab_name':'Copy Location Editor'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_COPY_LOCATION_EDIT) + '?ses='+window.escape(ses()),{'tab_name' : offlineStrings.getString('menu.cmd_copy_location_edit.tab')},{}); } ], 'cmd_test' : [ @@ -545,25 +549,25 @@ main.menu.prototype = { 'cmd_console' : [ ['oncommand'], function() { - obj.set_tab(obj.url_prefix(urls.XUL_DEBUG_CONSOLE),{'tab_name':'Console'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_DEBUG_CONSOLE),{'tab_name' : offlineStrings.getString('menu.cmd_console.tab')},{}); } ], 'cmd_shell' : [ ['oncommand'], function() { - obj.set_tab(obj.url_prefix(urls.XUL_DEBUG_SHELL),{'tab_name':'JS Shell'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_DEBUG_SHELL),{'tab_name' : offlineStrings.getString('menu.cmd_shell.tab')},{}); } ], 'cmd_xuleditor' : [ ['oncommand'], function() { - obj.set_tab(obj.url_prefix(urls.XUL_DEBUG_XULEDITOR),{'tab_name':'XUL Editor'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_DEBUG_XULEDITOR),{'tab_name' : offlineStrings.getString('menu.cmd_xuleditor.tab')},{}); } ], 'cmd_fieldmapper' : [ ['oncommand'], function() { - obj.set_tab(obj.url_prefix(urls.XUL_DEBUG_FIELDMAPPER),{'tab_name':'Fieldmapper'},{}); + obj.set_tab(obj.url_prefix(urls.XUL_DEBUG_FIELDMAPPER),{'tab_name' : offlineStrings.getString('menu.cmd_fieldmapper.tab')},{}); } ], 'cmd_survey_wizard' : [ @@ -581,7 +585,7 @@ main.menu.prototype = { ); obj.set_tab( loc, - {'tab_name':'OPAC', 'browser' : true}, + {'tab_name' : offlineStrings.getString('menu.cmd_public_opac.tab'), 'browser' : true}, { 'no_xulG' : true, 'show_nav_buttons' : true, 'show_print_button' : true } ); } @@ -611,25 +615,25 @@ main.menu.prototype = { 'cmd_extension_manager' : [ ['oncommand'], function() { - obj.set_tab('chrome://mozapps/content/extensions/extensions.xul?type=extensions',{'tab_name':'Extension Manager'},{}); + obj.set_tab('chrome://mozapps/content/extensions/extensions.xul?type=extensions',{'tab_name' : offlineStrings.getString('menu.cmd_extension_manager.tab')},{}); } ], 'cmd_theme_manager' : [ ['oncommand'], function() { - obj.set_tab('chrome://mozapps/content/extensions/extensions.xul?type=themes',{'tab_name':'Theme Manager'},{}); + obj.set_tab('chrome://mozapps/content/extensions/extensions.xul?type=themes',{'tab_name' : offlineStrings.getString('menu.cmd_theme_manager.tab')},{}); } ], 'cmd_about_config' : [ ['oncommand'], function() { - obj.set_tab('chrome://global/content/config.xul',{'tab_name':'about:config'},{}); + obj.set_tab('chrome://global/content/config.xul',{'tab_name' : 'about:config'},{}); } ], 'cmd_shutdown' : [ ['oncommand'], function() { - if (window.confirm('Exit Evergreen completely?')) { + if (window.confirm(offlineStrings.getString('menu.cmd_shutdown.prompt'))) { var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(); var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator); var enumerator = windowManagerInterface.getEnumerator(null); @@ -659,7 +663,7 @@ main.menu.prototype = { 'spawn_search' : function(s) { var obj = this; - obj.error.sdump('D_TRACE', 'Editor would like to search for: ' + js2JSON(s) ); + obj.error.sdump('D_TRACE', offlineStrings.getFormattedString('menu.spawn_search.msg', [js2JSON(s)]) ); obj.data.stash_retrieve(); var loc = obj.url_prefix(urls.XUL_PATRON_DISPLAY); loc += '?doit=1&query=' + window.escape(js2JSON(s)); @@ -704,7 +708,7 @@ main.menu.prototype = { for (var i = 0; i < count; i++) obj.close_tab(); setTimeout( function(){ obj.controller.view.tabs.firstChild.focus(); }, 0); } catch(E) { - obj.error.standard_unexpected_error_alert('Error closing all tabs',E); + obj.error.standard_unexpected_error_alert(offlineStrings.getString('menu.close_all_tabs.error'),E); } }, @@ -713,7 +717,6 @@ main.menu.prototype = { var tab = this.controller.view.tabs.childNodes[idx]; var panel = this.controller.view.panels.childNodes[ idx ]; while ( panel.lastChild ) panel.removeChild( panel.lastChild ); - tab.setAttribute('label','Tab ' + (idx+1)); if (idx == 0) { try { this.controller.view.tabs.advanceSelectedTab(+1); @@ -790,7 +793,8 @@ main.menu.prototype = { var tab = this.controller.view.tabs.childNodes[ tc ]; tab.hidden = false; if (!content_params) content_params = {}; - if (!params) params = { 'tab_name' : 'Tab ' + (tc+1) }; + if (!params) params = {}; + if (!params.tab_name) params.tab_name = offlineStrings.getString('menu.new_tab.tab'); if (!params.nofocus) params.focus = true; /* make focus the default */ try { if (params.focus) this.controller.view.tabs.selectedIndex = tc; @@ -863,7 +867,7 @@ main.menu.prototype = { } } catch(E) { this.error.sdump('D_ERROR', 'main.menu:2: ' + E); - alert('pause for error'); + alert(offlineStrings.getString('menu.set_tab.error')); } return frame; diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame.xul b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame.xul index 160c54ec0a..6d5ecece1a 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame.xul +++ b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame.xul @@ -1,6 +1,9 @@ + @@ -43,7 +46,7 @@ function my_init() { try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); } + if (typeof JSAN == 'undefined') { throw(document.getElementById('offlineStrings').getString('common.jsan.missing')); } JSAN.errorLevel = "die"; // none, warn, or die /* JSAN.addRepository('/xul/server/'); @@ -67,8 +70,7 @@ document.title = g.window.appshell_name_increment() + ': ' + g.data.list.au[0].usrname() + '@' + g.data.ws_name + '.' + g.data.server_unadorned; } catch(E) { - var err_msg = "!! This software has encountered an error. Please tell your friendly " + - "system administrator or software developer the following:\nmenu_frame.xul\n" + E + '\n'; + var err_msg = document.getElementById("offlineStrings").getFormattedString("common.exception", ["menu_frame.xul", E]); try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); } alert(err_msg); } @@ -77,6 +79,8 @@ + + diff --git a/Open-ILS/xul/staff_client/server/admin/cash_reports.xhtml b/Open-ILS/xul/staff_client/server/admin/cash_reports.xhtml index 8fbb556933..95345ba7bc 100644 --- a/Open-ILS/xul/staff_client/server/admin/cash_reports.xhtml +++ b/Open-ILS/xul/staff_client/server/admin/cash_reports.xhtml @@ -1,8 +1,15 @@ - + + + +]> + - Evergreen: Cash Reports + &staff.server.admin.cash.title; @@ -39,46 +46,46 @@

- Welcome + &staff.server.admin.cash.welcome;
- Start Date: + &staff.server.admin.cash.start_date; - End Date: + &staff.server.admin.cash.end_date; -
(YYYY-MM-DD)
+
&staff.server.admin.cash.date_format;
-
View reports for :
+
-

Desk Payments

+

&staff.server.admin.cash.desk;




-

User Payments

+

&staff.server.admin.cash.user;

diff --git a/Open-ILS/xul/staff_client/server/admin/closed_dates.js b/Open-ILS/xul/staff_client/server/admin/closed_dates.js index 73de8c78ef..d87bcb35ee 100644 --- a/Open-ILS/xul/staff_client/server/admin/closed_dates.js +++ b/Open-ILS/xul/staff_client/server/admin/closed_dates.js @@ -128,7 +128,7 @@ function cdInitCals() { } function cdDrawRange( start, end, alertSuccess ) { - start = (start) ? start : new Date().getYear() + 1900 + '-01-01'; + start = (start) ? start : new Date().getYear() + 1899 + '-01-01'; /* include last year's closed info for comparison */ end = (end) ? end : '3001-01-01'; if(alertSuccess) alertId('cd_update_success'); diff --git a/Open-ILS/xul/staff_client/server/admin/closed_dates.xhtml b/Open-ILS/xul/staff_client/server/admin/closed_dates.xhtml index ec96cc6f5c..4cbedebba9 100644 --- a/Open-ILS/xul/staff_client/server/admin/closed_dates.xhtml +++ b/Open-ILS/xul/staff_client/server/admin/closed_dates.xhtml @@ -1,8 +1,15 @@ - + + + +]> + - Evergreen: Libray Closed Dates Editor + &staff.server.admin.closed_dates.title; @@ -41,22 +48,22 @@
- Welcome + &staff.server.admin.closed_dates.welcome;
-
Closed Dates Editor
+
&staff.server.admin.closed_dates.editor.title;

- Edit Closed Dates for:

- - - + + + @@ -86,7 +93,7 @@ Every Day From through - + @@ -94,7 +101,7 @@
- Note: All dates must have the form YYYY-MM-DD. Times must have the form HH:MM + &staff.server.admin.closed_dates.editor.allmultiday.format;

@@ -103,11 +110,11 @@
Closed DurationReason for ClosingDelete&staff.server.admin.closed_dates.editor.duration;&staff.server.admin.closed_dates.editor.reason;&staff.server.admin.closed_dates.editor.delete;
+ onclick='cdShowEditRow("cd_edit_allday_row");'>&staff.server.admin.closed_dates.add.allday; + onclick='cdShowEditRow("cd_edit_allmultiday_row");'>&staff.server.admin.closed_dates.add.multiday; + onclick='cdShowEditRow("cd_edit_row");'>&staff.server.admin.closed_dates.add.detailed;
@@ -119,10 +126,10 @@ - - - - + + + + @@ -138,7 +145,7 @@
Start DateStart TimeEnd DateEnd Time&staff.server.admin.closed_dates.date.start;&staff.server.admin.closed_dates.time.start;&staff.server.admin.closed_dates.date.end;&staff.server.admin.closed_dates.time.end;
-
All Day
+
&staff.server.admin.closed_dates.allday.label;
-
All Day
+
&staff.server.admin.closed_dates.allday.label;
- All Day + &staff.server.admin.closed_dates.allday.label; @@ -197,19 +204,19 @@
-
Reason for closing:
+
&staff.server.admin.closed_dates.editor.reason.label;