From abd21efda75d3cb82c1b22fe57ab978599374418 Mon Sep 17 00:00:00 2001 From: erickson Date: Fri, 5 Jan 2007 19:16:20 +0000 Subject: [PATCH] adding oils libs git-svn-id: svn://svn.open-ils.org/ILS/trunk@6725 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/python/oils/__init__.py | 0 Open-ILS/src/python/oils/const.py | 22 ++++ Open-ILS/src/python/oils/system.py | 26 +++++ Open-ILS/src/python/oils/utils/__init__.py | 0 Open-ILS/src/python/oils/utils/csedit.py | 175 +++++++++++++++++++++++++++++ Open-ILS/src/python/oils/utils/idl.py | 133 ++++++++++++++++++++++ Open-ILS/src/python/oils/utils/utils.py | 32 ++++++ 7 files changed, 388 insertions(+) create mode 100644 Open-ILS/src/python/oils/__init__.py create mode 100644 Open-ILS/src/python/oils/const.py create mode 100644 Open-ILS/src/python/oils/system.py create mode 100644 Open-ILS/src/python/oils/utils/__init__.py create mode 100644 Open-ILS/src/python/oils/utils/csedit.py create mode 100644 Open-ILS/src/python/oils/utils/idl.py create mode 100644 Open-ILS/src/python/oils/utils/utils.py diff --git a/Open-ILS/src/python/oils/__init__.py b/Open-ILS/src/python/oils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Open-ILS/src/python/oils/const.py b/Open-ILS/src/python/oils/const.py new file mode 100644 index 0000000000..52ee81f67f --- /dev/null +++ b/Open-ILS/src/python/oils/const.py @@ -0,0 +1,22 @@ +# ----------------------------------------------------------------------- +# Copyright (C) 2007 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. +# ----------------------------------------------------------------------- + + +OILS_NS_OBJ='http://open-ils.org/spec/opensrf/IDL/objects/v1' +OILS_NS_PERSIST='http://open-ils.org/spec/opensrf/IDL/persistance/v1' +OILS_NS_REPORTER='http://open-ils.org/spec/opensrf/IDL/reporter/v1' + +OILS_APP_CSTORE='open-ils.cstore' + diff --git a/Open-ILS/src/python/oils/system.py b/Open-ILS/src/python/oils/system.py new file mode 100644 index 0000000000..b010db2ecc --- /dev/null +++ b/Open-ILS/src/python/oils/system.py @@ -0,0 +1,26 @@ +# ----------------------------------------------------------------------- +# Copyright (C) 2007 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. +# ----------------------------------------------------------------------- + +from osrf.log import * +from osrf.system import osrfConnect +from oils.utils.idl import oilsParseIDL +from oils.utils.csedit import oilsLoadCSEditor + +def oilsConnect(config): + """Connects to the opensrf network, parses the IDL file, and loads the CSEditor""" + osrfLogInfo("oilsConnect(): connecting with config %s" % config) + osrfConnect(config) + oilsParseIDL() + oilsLoadCSEditor() diff --git a/Open-ILS/src/python/oils/utils/__init__.py b/Open-ILS/src/python/oils/utils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Open-ILS/src/python/oils/utils/csedit.py b/Open-ILS/src/python/oils/utils/csedit.py new file mode 100644 index 0000000000..8054196243 --- /dev/null +++ b/Open-ILS/src/python/oils/utils/csedit.py @@ -0,0 +1,175 @@ +# ----------------------------------------------------------------------- +# Copyright (C) 2007 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. +# ----------------------------------------------------------------------- + +from osrf.log import * +from osrf.json import * +from oils.utils.utils import replace +from oils.utils.idl import oilsGetIDLParser +from osrf.ses import osrfClientSession +from oils.const import * +import re + +ACTIONS = ['create', 'retrieve', 'update', 'delete', 'search'] + +class CSEditor(object): + def __init__(self, **args): + + self.app = args.get('app', OILS_APP_CSTORE) + self.authtoken = args.get('authtoken', args.get('auth')) + self.requestor = args.get('requestor') + self.connect = args.get('connect') + self.xact = args.get('xact') + self.__session = None + + def die_event(self): + pass + def checkauth(self): + pass + + + # ------------------------------------------------------------------------- + # Creates a session if one does not already exist. If necessary, connects + # to the remote service and starts a transaction + # ------------------------------------------------------------------------- + def session(self, ses=None): + if not self.__session: + self.__session = osrfClientSession(self.app) + + if self.connect or self.xact: + self.log(osrfLogDebug,'connecting to ' + self.app) + self.__session.connect() + + if self.xact: + self.log(osrfLogInfo, "starting new db transaction") + self.request(self.app + '.transaction.begin') + + return self.__session + + + # ------------------------------------------------------------------------- + # Logs string with some meta info + # ------------------------------------------------------------------------- + def log(self, func, string): + s = "editor["; + if self.xact: s += "1|" + else: s += "0|" + if self.requestor: s += str(self.requestor.id()) + else: s += "0" + s += "]" + func("%s %s" % (s, string)) + + + # ------------------------------------------------------------------------- + # Rolls back the existing db transaction + # ------------------------------------------------------------------------- + def rollback(self): + if self.__session and self.xact: + self.log(osrfLogInfo, "rolling back db transaction") + self.request(self.app + '.transaction.rollback') + self.disconnect() + + # ------------------------------------------------------------------------- + # Commits the existing db transaction + # ------------------------------------------------------------------------- + def commit(self): + if self.__session and self.xact: + self.log(osrfLogInfo, "comitting db transaction") + self.request(self.app + '.transaction.commit') + self.disconnect() + + + # ------------------------------------------------------------------------- + # Disconnects from the remote service + # ------------------------------------------------------------------------- + def disconnect(self): + if self.__session: + self.__session.disconnect() + self.__session = None + + + # ------------------------------------------------------------------------- + # Sends a request + # ------------------------------------------------------------------------- + def request(self, method, params=[]): + + # XXX improve param logging here + + self.log(osrfLogInfo, "request %s %s" % (method, str(params))) + + if self.xact and self.session().state != OSRF_APP_SESSION_CONNECTED: + self.log(osrfLogErr, "csedit lost it's connection!") + + val = None + + try: + req = self.session().request2(method, params) + resp = req.recv() + val = resp.content() + + except Exception, e: + self.log(osrfLogErr, "request error: %s" % str(e)) + raise e + + return val + + + # ------------------------------------------------------------------------- + # Returns true if our requestor is allowed to perform the request action + # 'org' defaults to the requestors ws_ou + # ------------------------------------------------------------------------- + def allowed(self, perm, org=None): + pass + + + def runMethod(self, action, type, arg, options={}): + + method = "%s.direct.%s.%s" % (self.app, type, action) + + if options.get('idlist'): + method = replace(method, 'search', 'id_list') + del options['idlist'] + + if action == 'search': + method = replace(method, '$', '.atomic') + + params = [arg]; + if len(options.keys()): + params.append(options) + + val = self.request( method, params ) + + return val + + + +# ------------------------------------------------------------------------- +# Creates a class method for each action on each type of fieldmapper object +# ------------------------------------------------------------------------- +def oilsLoadCSEditor(): + obj = oilsGetIDLParser().IDLObject + + for k, fm in obj.iteritems(): + for action in ACTIONS: + + fmname = replace(fm['fieldmapper'], '::', '_') + type = replace(fm['fieldmapper'], '::', '.') + name = "%s_%s" % (action, fmname) + + str = 'def %s(self, arg, **options):\n' % name + str += '\treturn self.runMethod("%s", "%s", arg, dict(options))\n' % (action, type) + str += 'setattr(CSEditor, "%s", %s)' % (name, name) + + exec(str) + diff --git a/Open-ILS/src/python/oils/utils/idl.py b/Open-ILS/src/python/oils/utils/idl.py new file mode 100644 index 0000000000..7a7fa1e614 --- /dev/null +++ b/Open-ILS/src/python/oils/utils/idl.py @@ -0,0 +1,133 @@ +# ----------------------------------------------------------------------- +# Copyright (C) 2007 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. +# ----------------------------------------------------------------------- + +from osrf.json import * +from osrf.log import * +from osrf.set import osrfSettingsValue + +import sys, libxml2, osrf.conf, string +from oils.const import OILS_NS_OBJ, OILS_NS_PERSIST, OILS_NS_REPORTER + +__global_parser = None + +def oilsParseIDL(): + global __global_parser + idlParser = oilsIDLParser(); + idlParser.setIDL(osrfSettingsValue('IDL')) + idlParser.parseIDL() + __global_parser = idlParser + +def oilsGetIDLParser(): + global __global_parser + return __global_parser + +class oilsIDLParser(object): + + def __init__(self): + self.IDLObject = {} + + def setIDL(self, file): + osrfLogInfo("setting IDL file to " + file) + self.idlFile = file + + def parseIDL(self): + """Parses the IDL file and builds class objects""" + + doc = libxml2.parseFile(self.idlFile) + root = doc.children + child = root.children + + while child: + + if child.type == 'element': + + # ----------------------------------------------------------------------- + # 'child' is the main class node for a fieldmapper class. + # It has 'fields' and 'links' nodes as children. + # ----------------------------------------------------------------------- + + id = child.prop('id') + self.IDLObject[id] = {} + obj = self.IDLObject[id] + obj['fields'] = [] + + obj['controller'] = child.prop('controller') + obj['fieldmapper'] = child.nsProp('fieldmapper', OILS_NS_OBJ) + obj['virtual'] = child.nsProp('virtual', OILS_NS_PERSIST) + obj['rpt_label'] = child.nsProp('label', OILS_NS_REPORTER) + + class_node = child.children + #osrfLogInternal("parseIDL(): parsing class %s" % id) + + keys = [] + while class_node: + if class_node.type == 'element': + if class_node.name == 'fields': + keys = self.parseFields(id, class_node) + class_node = class_node.next + + #obj['fields'] = keys + osrfNetworkRegisterHint(id, keys, 'array' ) + + child = child.next + + doc.freeDoc() + + + def parseFields(self, cls, fields): + """Takes the fields node and parses the included field elements""" + + field = fields.children + keys = [] + idlobj = self.IDLObject[cls] + + while field: + if field.type == 'element': + keys.append(None) + field = field.next + + field = fields.children + while field: + obj = {} + if field.type == 'element': + name = field.prop('name') + position = int(field.nsProp('array_position', OILS_NS_OBJ)) + obj['name'] = name + + try: + keys[position] = name + except Exception, e: + osrfLogErr("parseFields(): position out of range. pos=%d : key-size=%d" % (position, len(keys))) + raise e + + virtual = field.nsProp('virtual', OILS_NS_PERSIST) + obj['rpt_label'] = field.nsProp('label', OILS_NS_REPORTER) + obj['rpt_dtype'] = field.nsProp('datatype', OILS_NS_REPORTER) + obj['rpt_select'] = field.nsProp('selector', OILS_NS_REPORTER) + + if virtual == string.lower('true'): + obj['virtual'] = True + else: + obj['virtual'] = False + + idlobj['fields'].append(obj) + + field = field.next + + return keys + + + + diff --git a/Open-ILS/src/python/oils/utils/utils.py b/Open-ILS/src/python/oils/utils/utils.py new file mode 100644 index 0000000000..9e03cb91ba --- /dev/null +++ b/Open-ILS/src/python/oils/utils/utils.py @@ -0,0 +1,32 @@ +# ----------------------------------------------------------------------- +# Copyright (C) 2007 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. +# ----------------------------------------------------------------------- + +import re + +# ----------------------------------------------------------------------- +# Grab-bag of general utility functions +# ----------------------------------------------------------------------- + + +# ----------------------------------------------------------------------- +# more succinct search/replace call +# ----------------------------------------------------------------------- +def replace(str, pattern, replace): + return re.compile(pattern).sub(replace, str) + + + + + -- 2.11.0