From: erickson Date: Thu, 17 Jan 2008 19:57:48 +0000 (+0000) Subject: Starting with new picklist interfaces, using new middleware code X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=a1488d3943bdea064262d05902c8162b5ad3b572;p=Evergreen.git Starting with new picklist interfaces, using new middleware code Took this chance to create an acq namespace in the controllers directory, since there will be quite a few acq-related controllers in the long run Created a picklist management class for fetching picklists, entries, etc. Created picklist view interface git-svn-id: svn://svn.open-ils.org/ILS/branches/acq-experiment@8407 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/web/oilsweb/oilsweb/controllers/acq.py b/Open-ILS/web/oilsweb/oilsweb/controllers/acq.py deleted file mode 100644 index 84164ab54b..0000000000 --- a/Open-ILS/web/oilsweb/oilsweb/controllers/acq.py +++ /dev/null @@ -1,125 +0,0 @@ -from oilsweb.lib.base import * -from oilsweb.lib.request import RequestMgr - -import logging, pylons -import oilsweb.lib.context -import oilsweb.lib.util -import oilsweb.lib.acq.search -import oilsweb.lib.bib -import osrf.cache, osrf.json -from oilsweb.lib.context import Context, SubContext, ContextItem - -log = logging.getLogger(__name__) - -class AcqContext(SubContext): - ''' Define the CGI params for this application ''' - def __init__(self): - self.query = ContextItem(cgi_name='acq.q') - self.search_class = ContextItem(cgi_name='acq.sc', multi=True) - self.search_source = ContextItem(cgi_name='acq.ss', multi=True) - self.picked_records = ContextItem(cgi_name='acq.sr', multi=True) - self.search_cache_key = ContextItem(cgi_name='acq.sk') - self.record_id = ContextItem(cgi_name='acq.r') - self.record = ContextItem(cgi_name='acq.r') - self.picklist_item = ContextItem(cgi_name='acq.pi', multi=True) - self.extract_bib_field = ContextItem(default_value=oilsweb.lib.acq.search.extract_bib_field) - self.prefix = ContextItem() - self.z39_sources = ContextItem() - self.search_classes = ContextItem() - self.search_classes_sorted = ContextItem() - - def postinit(self): - self.prefix = "%s/acq" % Context.getContext().core.prefix - -Context.applySubContext('acq', AcqContext) - - -class AcqController(BaseController): - - def index(self): - return RequestMgr().render('acq/index.html') - - def search(self): - r = RequestMgr() - r.ctx.acq.z39_sources = oilsweb.lib.acq.search.fetch_z39_sources(r.ctx) - - sc = {} - for data in r.ctx.acq.z39_sources.values(): - for key, val in data['attrs'].iteritems(): - sc[key] = val.get('label') or key - r.ctx.acq.search_classes = sc - keys = sc.keys() - keys.sort() - r.ctx.acq.search_classes_sorted = keys - log.debug("keys = %s" % unicode(r.ctx.acq.z39_sources)) - - return r.render('acq/search.html') - - - def pl_builder(self): - r = RequestMgr() - # add logic to see where we are fetching bib data from - # XXX fix - if r.ctx.acq.search_source: - c.oils_acq_records, r.ctx.acq.search_cache_key = self._build_z39_search(r.ctx) - - return r.render('acq/pl_builder.html') - - - def _build_z39_search(self, ctx): - - search = { - 'service' : [], - 'username' : [], - 'password' : [], - 'search' : {} - } - - # collect the sources and credentials - for src in ctx.acq.search_source: - search['service'].append(src) - search['username'].append("") # XXX config values? in-db? - search['password'].append("") # XXX config values? in-db? - - # collect the search classes - for cls in ctx.acq.search_class: - if request.params[cls]: - search['search'][cls] = request.params[cls] - - return oilsweb.lib.acq.search.multi_search(ctx, search) - - def rdetails(self): - r = RequestMgr() - rec_id = r.ctx.acq.record_id - cache_key = r.ctx.acq.search_cache_key - - results = osrf.cache.CacheClient().get(cache_key) - rec = self._find_cached_record(results, rec_id) - if rec: - r.ctx.acq.record = rec - r.ctx.acq.record_html = oilsweb.lib.bib.marc_to_html(rec['marcxml']) - return r.render('acq/rdetails.html') - return 'exception -> no record' - - - def create_picklist(self): - r = RequestMgr() - if not isinstance(r.ctx.acq.picklist_item, list): - r.ctx.acq.picklist_item = [r.ctx.acq.picklist_item] - - results = osrf.cache.CacheClient().get(r.ctx.acq.search_cache_key) - - records = [] - for cache_id in r.ctx.acq.picklist_item: - rec = self._find_cached_record(results, cache_id) - records.append(rec) - - c.oils_acq_records = records # XXX - return r.render('acq/picklist.html') - - def _find_cached_record(self, results, cache_id): - for res in results: - for rec in res['records']: - if str(rec['cache_id']) == str(cache_id): - return rec - diff --git a/Open-ILS/web/oilsweb/oilsweb/controllers/acq/__init__.py b/Open-ILS/web/oilsweb/oilsweb/controllers/acq/__init__.py new file mode 100644 index 0000000000..090be084f1 --- /dev/null +++ b/Open-ILS/web/oilsweb/oilsweb/controllers/acq/__init__.py @@ -0,0 +1,34 @@ +from oilsweb.lib.context import Context, SubContext, ContextItem +import oilsweb.lib.acq.search +import oilsweb.lib.acq.picklist + +# ---------------------------------------------------------------- +# Define the CGI params for this application +# ---------------------------------------------------------------- + +class AcqContext(SubContext): + def __init__(self): + self.query = ContextItem(cgi_name='acq.q') + self.search_class = ContextItem(cgi_name='acq.sc', multi=True) + self.search_source = ContextItem(cgi_name='acq.ss', multi=True) + self.picked_records = ContextItem(cgi_name='acq.sr', multi=True) + self.search_cache_key = ContextItem(cgi_name='acq.sk') + self.record_id = ContextItem(cgi_name='acq.ri') + self.record = ContextItem(cgi_name='acq.r') + self.picklist_item = ContextItem(cgi_name='acq.pi', multi=True) + self.prefix = ContextItem() + self.z39_sources = ContextItem() + self.search_classes = ContextItem() + self.search_classes_sorted = ContextItem() + self.picklist_id = ContextItem(cgi_name='acq.pl') + self.picklist = ContextItem() + self.offset = ContextItem(cgi_name='acq.os') + self.limit = ContextItem(cgi_name='acq.li') + + self.extract_bib_field = ContextItem(default_value=oilsweb.lib.acq.search.extract_bib_field) + self.find_entry_attr = ContextItem(default_value=oilsweb.lib.acq.picklist.PicklistMgr.find_entry_attr) + + def postinit(self): + self.prefix = "%s/acq" % Context.getContext().core.prefix + +Context.applySubContext('acq', AcqContext) diff --git a/Open-ILS/web/oilsweb/oilsweb/controllers/acq/base.py b/Open-ILS/web/oilsweb/oilsweb/controllers/acq/base.py new file mode 100644 index 0000000000..1bdde68cb2 --- /dev/null +++ b/Open-ILS/web/oilsweb/oilsweb/controllers/acq/base.py @@ -0,0 +1,6 @@ +from oilsweb.lib.base import * +from oilsweb.lib.request import RequestMgr + +class BaseController(BaseController): + def index(self): + return RequestMgr().render('acq/index.html') diff --git a/Open-ILS/web/oilsweb/oilsweb/controllers/acq/picklist.py b/Open-ILS/web/oilsweb/oilsweb/controllers/acq/picklist.py new file mode 100644 index 0000000000..76c03a6947 --- /dev/null +++ b/Open-ILS/web/oilsweb/oilsweb/controllers/acq/picklist.py @@ -0,0 +1,110 @@ +from oilsweb.lib.base import * +from oilsweb.lib.request import RequestMgr +import logging, pylons +import oilsweb.lib.context, oilsweb.lib.util +import oilsweb.lib.bib, oilsweb.lib.acq.search, oilsweb.lib.acq.picklist +import osrf.cache, osrf.json, osrf.ses +import oils.const, oils.utils.utils, oils.event + + +class PicklistController(BaseController): + + def view(self, **kwargs): + r = RequestMgr() + pl_manager = oilsweb.lib.acq.picklist.PicklistMgr(r, picklist_id=kwargs['id']) + pl_manager.retrieve() + pl_manager.retrieve_entries() + r.ctx.acq.picklist = pl_manager.picklist + return r.render('acq/picklist/view.html') + + + ''' + def search(self): + r = RequestMgr() + r.ctx.acq.z39_sources = oilsweb.lib.acq.search.fetch_z39_sources(r.ctx) + + sc = {} + for data in r.ctx.acq.z39_sources.values(): + for key, val in data['attrs'].iteritems(): + sc[key] = val.get('label') or key + r.ctx.acq.search_classes = sc + keys = sc.keys() + keys.sort() + r.ctx.acq.search_classes_sorted = keys + log.debug("keys = %s" % unicode(r.ctx.acq.z39_sources)) + + return r.render('acq/picklist/search.html') + + def pl_builder(self): + r = RequestMgr() + # add logic to see where we are fetching bib data from + # XXX fix + if r.ctx.acq.search_source: + c.oils_acq_records, r.ctx.acq.search_cache_key = self._build_z39_search(r.ctx) + + return r.render('acq/picklist/pl_builder.html') + + + def _build_z39_search(self, ctx): + + search = { + 'service' : [], + 'username' : [], + 'password' : [], + 'search' : {} + } + + # collect the sources and credentials + for src in ctx.acq.search_source: + search['service'].append(src) + search['username'].append("") # XXX config values? in-db? + search['password'].append("") # XXX config values? in-db? + + # collect the search classes + for cls in ctx.acq.search_class: + if request.params[cls]: + search['search'][cls] = request.params[cls] + + return oilsweb.lib.acq.search.multi_search(ctx, search) + + def rdetails(self): + r = RequestMgr() + rec_id = r.ctx.acq.record_id + cache_key = r.ctx.acq.search_cache_key + + results = osrf.cache.CacheClient().get(cache_key) + rec = self._find_cached_record(results, rec_id) + if rec: + r.ctx.acq.record = rec + r.ctx.acq.record_html = oilsweb.lib.bib.marc_to_html(rec['marcxml']) + return r.render('acq/picklist/rdetails.html') + return 'exception -> no record' + + + def view_picklist(self): + r = RequestMgr() + ses = osrf.ses.ClientSession(oils.const.OILS_APP_ACQ) + picklist = osrf + + + def create_picklist(self): + r = RequestMgr() + if not isinstance(r.ctx.acq.picklist_item, list): + r.ctx.acq.picklist_item = [r.ctx.acq.picklist_item] + + results = osrf.cache.CacheClient().get(r.ctx.acq.search_cache_key) + + records = [] + for cache_id in r.ctx.acq.picklist_item: + rec = self._find_cached_record(results, cache_id) + records.append(rec) + + c.oils_acq_records = records # XXX + return r.render('acq/picklist/view.html') + + def _find_cached_record(self, results, cache_id): + for res in results: + for rec in res['records']: + if str(rec['cache_id']) == str(cache_id): + return rec +''' diff --git a/Open-ILS/web/oilsweb/oilsweb/lib/acq/picklist.py b/Open-ILS/web/oilsweb/oilsweb/lib/acq/picklist.py new file mode 100644 index 0000000000..c092f9c3e8 --- /dev/null +++ b/Open-ILS/web/oilsweb/oilsweb/lib/acq/picklist.py @@ -0,0 +1,50 @@ +import osrf.cache, osrf.json, osrf.ses +import oils.const, oils.utils.utils, oils.event + +class PicklistMgr(object): + def __init__(self, request_mgr, **kwargs): + self.request_mgr = request_mgr + self.id = kwargs.get('picklist_id') + self.picklist = kwargs.get('picklist') + self.ses = osrf.ses.ClientSession(oils.const.OILS_APP_ACQ) + + def retrieve(self): + + picklist = self.ses.request( + 'open-ils.acq.picklist.retrieve', + self.request_mgr.ctx.core.authtoken, self.id).recv().content() + + oils.event.Event.parse_and_raise(picklist) + self.picklist = picklist + + def retrieve_entries(self, **kwargs): + # grab the picklist entries + entries = self.ses.request( + 'open-ils.acq.picklist_entry.picklist.retrieve', + self.request_mgr.ctx.core.authtoken, + self.picklist.id(), + { + "offset" : kwargs.get('offset'), + "limit" : kwargs.get('limit'), + "flesh" : 1, + "clear_marc" : 1 + } + ).recv().content() + + self.picklist.entries(entries) + + def retrieve_entry(self, entry_id): + entry = self.ses.request( + 'open-ils.acq.picklist_entry.retrieve', + self.request_mgr.ctx.core.auththoken, entry_id).recv.content() + oils.event.Event.parse_and_raise(entry) + return entry + + @staticmethod + def find_entry_attr(entry, attr_name, attr_type='picklist_marc_attr_definition'): + for entry_attr in entry.attributes(): + if entry_attr.attr_type() == attr_type and entry_attr.attr_name() == attr_name: + return entry_attr.attr_value() + return '' + + diff --git a/Open-ILS/web/oilsweb/oilsweb/lib/bib.py b/Open-ILS/web/oilsweb/oilsweb/lib/bib.py index a9cc127546..5a00c8a8d3 100644 --- a/Open-ILS/web/oilsweb/oilsweb/lib/bib.py +++ b/Open-ILS/web/oilsweb/oilsweb/lib/bib.py @@ -12,7 +12,7 @@ def marc_to_html(marcxml): def scrub_isbn(isbn): ''' removes trailing data from an ISBN ''' - if not isbn: return isbn + if not isbn: return '' return re.sub('\s.*','', isbn) diff --git a/Open-ILS/web/oilsweb/oilsweb/public/oils/media/css/skin/default/acq.css b/Open-ILS/web/oilsweb/oilsweb/public/oils/media/css/skin/default/acq.css index bf58d66581..0ff783e4e2 100644 --- a/Open-ILS/web/oilsweb/oilsweb/public/oils/media/css/skin/default/acq.css +++ b/Open-ILS/web/oilsweb/oilsweb/public/oils/media/css/skin/default/acq.css @@ -25,12 +25,12 @@ /* bib search results / picklist builder interface */ #oils-acq-pl_builder-table { width: 100%; } -.oils-acq-record_list-records-jacket-td { width: 46px; } -.oils-acq-record_list-records-jacket { width: 42px; height: 54px; padding-left: 0px; } -.oils-acq-record_list-records-title-row {} -.oils-acq-record_list-records-author-row td { padding-left: 30px; } -.oils-acq-record_list-records-phys_desc-row td { padding-left: 30px; } -.oils-acq-record_list-records-phys_desc-row {} +.oils-acq-picklist-records-jacket-td { width: 46px; } +.oils-acq-picklist-records-jacket { width: 42px; height: 54px; padding-left: 0px; } +.oils-acq-picklist-records-title-row {} +.oils-acq-picklist-records-author-row td { padding-left: 30px; } +.oils-acq-picklist-records-phys_desc-row td { padding-left: 30px; } +.oils-acq-picklist-records-phys_desc-row {} #oils-acq-rdetail-marc-block { margin-top: 0px; padding: 6px; } #oils-acq-rdetail-summary-block { margin-top: 0px; padding: 6px; } diff --git a/Open-ILS/web/oilsweb/oilsweb/public/oils/media/css/theme/default/acq.css b/Open-ILS/web/oilsweb/oilsweb/public/oils/media/css/theme/default/acq.css index ffb25c1838..8c48e5195c 100644 --- a/Open-ILS/web/oilsweb/oilsweb/public/oils/media/css/theme/default/acq.css +++ b/Open-ILS/web/oilsweb/oilsweb/public/oils/media/css/theme/default/acq.css @@ -13,9 +13,9 @@ #oils-acq-pl_builder-table thead td { font-weight: bold; } /* #oils-acq-pl_builder-table tr { border-bottom: 1px solid #808080;} */ -.oils-acq-record_list-records-phys_desc-row { border-bottom: 1px solid #6BA160; } -.oils-acq-record_list-picklist-td { border-style: solid; border-color: #A1A1A1; border-width: 0px 1px 0px 1px; } -.oils-acq-record_list-records-service-td { font-size: 85%; } +.oils-acq-picklist-records-phys_desc-row { border-bottom: 1px solid #6BA160; } +.oils-acq-picklist-picklist-td { border-style: solid; border-color: #A1A1A1; border-width: 0px 1px 0px 1px; } +.oils-acq-picklist-records-service-td { font-size: 85%; } #oils-acq-pl_builder-picklist-submit { text-align: right; } diff --git a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist.html b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist.html deleted file mode 100644 index 99d2959007..0000000000 --- a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist.html +++ /dev/null @@ -1,30 +0,0 @@ -<%inherit file='base.html'/> -<%def name="page_title()">${_('Evergreen ACQ Picklist')} -<%def name="block_content()"> - - % for rec in c.oils_acq_records: - - - - - - - - - - - - - - % endfor -
- - - ${c.oils.acq.extract_bib_field(rec, 'title')} - --source info--
${c.oils.acq.extract_bib_field(rec, 'author')}
- ${c.oils.util.scrub_isbn(c.oils.acq.extract_bib_field(rec, 'isbns.isbn'))} | - ${c.oils.acq.extract_bib_field(rec, 'pubdate')} | - ${c.oils.acq.extract_bib_field(rec, 'physicalSize')} -
- diff --git a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist/search.html b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist/search.html new file mode 100644 index 0000000000..1a01a58653 --- /dev/null +++ b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist/search.html @@ -0,0 +1,50 @@ +<%inherit file='base.html'/> +<%def name="page_title()">${_('Evergreen Acquisitions Search')} + +<%def name="block_content()"> +
+
+
+
${_('Search Sources')}
+
    +
  • ${_('Evergreen Catalog')}
  • +
  • +
    ${_("Z39.50 Sources")}
    +
      + % for src,cfg in c.oils.acq.z39_sources.iteritems(): +
    • + + ${src} ${cfg["host"]}:${cfg["db"]} + % if cfg['auth'] == 't': + * + % endif + +
    • + % endfor +
    +
  • +
+
+
+
${_('Search Fields')}
+ + % for cls in c.oils.acq.search_classes_sorted: + + + + + % endfor +
${c.oils.acq.search_classes[cls]} + + +
+
+ +
+
+
+
+ + diff --git a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist/view.html b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist/view.html new file mode 100644 index 0000000000..4e8a0502d7 --- /dev/null +++ b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/picklist/view.html @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +<%inherit file='../base.html'/> +<%def name="page_title()">${_('Evergreen ACQ Picklist')} +<%def name="block_content()"> + + % for entry in c.oils.acq.picklist.entries(): + + + + + + + + + + + + + % endfor +
+ + + ${c.oils.acq.find_entry_attr(entry, "title")} + ${entry.provider()}
${c.oils.acq.find_entry_attr(entry, "author")} +
+ ${c.oils.acq.find_entry_attr(entry, "isbn")} | + ${c.oils.acq.find_entry_attr(entry, "pubdate")} | + ${c.oils.acq.find_entry_attr(entry, "pagination")} +
+ diff --git a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/pl_builder.html b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/pl_builder.html deleted file mode 100644 index 1e8670db21..0000000000 --- a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/pl_builder.html +++ /dev/null @@ -1,46 +0,0 @@ -<%inherit file='base.html'/> -<%def name="page_title()">${_('Evergreen Acquisitions Results')} -<%def name="block_content()"> -
- - - - % for res in c.oils_acq_records: - % for rec in res['records']: - - - - - - - - - - - - - - % endfor - % endfor - - - - -
- - - ${c.oils.acq.extract_bib_field(rec, 'title')} - ${res['service']} - -
${c.oils.acq.extract_bib_field(rec, 'author')}
- ${c.oils.util.scrub_isbn(c.oils.acq.extract_bib_field(rec, 'isbns.isbn'))} | - ${c.oils.acq.extract_bib_field(rec, 'pubdate')} | - ${c.oils.acq.extract_bib_field(rec, 'physicalSize')} -
- -
-
- diff --git a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/rdetails.html b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/rdetails.html deleted file mode 100644 index 595905c764..0000000000 --- a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/rdetails.html +++ /dev/null @@ -1,22 +0,0 @@ -<%inherit file='base.html'/> -<%def name="page_title()">${_('Evergreen ACQ Details')} -<%def name="block_content()"> -
Summary
-
- - % for key,val in c.oils.acq.record['extracts'].iteritems(): - - - - - % endfor -
${key}${val}
-
-
MARC Record
-
-
- ${unicode(c.oils.acq.record_html, 'utf-8')} -
-
- - diff --git a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/record_list.html b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/record_list.html deleted file mode 100644 index 1b4cef522c..0000000000 --- a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/record_list.html +++ /dev/null @@ -1,31 +0,0 @@ -% for res in c.oils_acq_records: - % for rec in res['records']: - - - - - - ${c.oils.acq.extract_bib_field(rec, 'title')} - - ${res['service']} - - - - - - - ${c.oils.acq.extract_bib_field(rec, 'author')} - - - - ${c.oils.util.scrub_isbn(c.oils.acq.extract_bib_field(rec, 'isbns.isbn'))} | - ${c.oils.acq.extract_bib_field(rec, 'pubdate')} | - ${c.oils.acq.extract_bib_field(rec, 'physicalSize')} - - - % endfor -% endfor - diff --git a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/search.html b/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/search.html deleted file mode 100644 index 1a01a58653..0000000000 --- a/Open-ILS/web/oilsweb/oilsweb/templates/oils/default/acq/search.html +++ /dev/null @@ -1,50 +0,0 @@ -<%inherit file='base.html'/> -<%def name="page_title()">${_('Evergreen Acquisitions Search')} - -<%def name="block_content()"> -
-
-
-
${_('Search Sources')}
-
    -
  • ${_('Evergreen Catalog')}
  • -
  • -
    ${_("Z39.50 Sources")}
    -
      - % for src,cfg in c.oils.acq.z39_sources.iteritems(): -
    • - - ${src} ${cfg["host"]}:${cfg["db"]} - % if cfg['auth'] == 't': - * - % endif - -
    • - % endfor -
    -
  • -
-
-
-
${_('Search Fields')}
- - % for cls in c.oils.acq.search_classes_sorted: - - - - - % endfor -
${c.oils.acq.search_classes[cls]} - - -
-
- -
-
-
-
- -