source: TI07-MOLES/trunk/PythonCode/wsgi/Utilities.py @ 1958

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI07-MOLES/trunk/PythonCode/wsgi/Utilities.py@1958
Revision 1958, 5.7 KB checked in by lawrence, 13 years ago (diff)

Refactoring discovery wsgi for cleaner service binding. (Done, but
there will be implications for wsgi browse which may now be broken,
but I can't test it til the database is updated).

Line 
1from collections import deque # python 2.4
2try: #python 2.5
3    from xml.etree import ElementTree as ET
4except:
5    import ElementTree as ET
6from ETxmlView import *
7import ConfigParser
8import os
9import re
10import urllib
11import logging
12
13__NOCONFIG='Missing Config File'
14
15class myConfig:
16   
17   ''' Handle missing sections and variables in a config file a bit gracefully. Also
18   instantiates a logger if necessary '''
19   
20   def __init__(self,configfile,logName='NDGLOG'):
21       self.config=ConfigParser.ConfigParser()
22       if not os.path.exists(configfile): raise __NOCONFIG, configfile
23       self.config.read(configfile)
24       logfile=self.get('logging','debugLog',None)
25       self.logfile=None #deprecated
26       self.logger=None
27       if logfile is not None:
28           logger=logging.getLogger(logName)
29           handler=logging.FileHandler(logfile)
30           formatter=logging.Formatter('%(asctime)s %(levelname)s %(message)s')
31           handler.setFormatter(formatter)
32           logger.addHandler(handler)
33           logger.setLevel(logging.INFO)
34           self.logger=logger
35       
36   def get(self,section,key,default=None):
37       ''' Return a config file value for key frm section '''
38       try:
39           return self.config.get(section,key)
40       except:
41           return default
42       
43   def log(self,string):
44       ''' Log some debug information '''
45       if self.logger is None: return
46       if string is not None:
47          self.logger.info(string)
48       else:
49          self.logger.info('empty log entry')
50         
51   def getLog(self):
52       return self.logger
53
54class RingBuffer(deque):
55    #deque is a python 2.4 class!
56    #credit http://www.onlamp.com/pub/a/python/excerpt/pythonckbk_chap1/index1.html
57    def __init__(self, size_max):
58        deque.__init__(self)
59        self.size_max = size_max
60    def append(self, datum):
61        deque.append(self, datum)
62        if len(self) > self.size_max:
63            self.popleft( )
64    def tolist(self):
65        return list(self)
66
67def wrapGetText(element,xpathExpression,multiple=0):
68        ''' Wraps a call to ET to get a text object in an error handler '''
69        def none2txt(i):
70            if i is None: return ''
71            return i
72        if element is None:
73            if multiple:
74                 return ['',]
75            else: return ''
76        if multiple:
77                r=element.findall(xpathExpression)
78        else:
79                r=[element.find(xpathExpression),]
80        try:
81                rr=[i.text for i in r]
82        except:
83                rr=['',]
84        rr=map(none2txt,rr) 
85        if multiple: 
86                return rr
87        else: return rr[0] 
88
89def getURLdict(cgiFieldStorage):
90    ''' takes a cgi field storage object and converts it to a dictionary '''
91    result={}
92    for item in cgiFieldStorage:
93            result[item]=cgiFieldStorage[item].value
94    return result
95##
96### convert the followign two methods into one class that can handle
97## xml directly too if necessary
98##
99def DIFid2NDGid(string):
100    ''' takes a dif thing parses it and produces an ET ndg element id ...
101    and use this in dif ... '''
102    s=string.split(':')
103    try:
104        r='''<DIFid><schemeIdentifier>%s</schemeIdentifier>
105         <repositoryIdentifier>%s</repositoryIdentifier>
106         <localIdentifier>%s</localIdentifier></DIFid>'''%(s[1],s[0],s[2])
107        return ET.fromstring(r)
108    except:
109        r='''<DIFid><schemeIdentifier>DIF</schemeIdentifier>
110        <repositoryIdentifier>Unknown</repositoryIdentifier>
111        <localIdentifier>%s</localIdentifier></DIFid>'''%string
112        return ET.fromstring(r)
113
114def EnumerateString(string):
115    ''' Takes a string, and if it's got a number on the end, increments it,
116    otherwise adds a number on the end, used to differentiate strings which
117    would otherwise be identical '''
118    def addNum(matchObj):
119        s=matchObj.group()
120        return str(int(s)+1)
121    r=re.sub('\d+$',addNum,string)
122    if r==string: r=r+'1'
123    return r
124
125def dateParse(string,instruction):
126    ''' Simple date manipulations on a string, if it is understood ...
127       if instruction = YYYY, return the year '''
128    s=string.split('-')
129    if instruction=='YYYY':
130        if len(s)==3: # expecting year,mon,day or day,mon,year ...
131            if int(s[0])>int(s[2]): 
132                return s[0]
133            else:
134                return s[2]
135        else:
136            return string # unknown format as yet ...
137    else:
138        return 'unknown instruction to dateParse %s'%instruction
139
140def idget(xml,dataType='DIF'):
141    ''' Given an xml document (string), parse it using ElementTree and
142    find the identifier within it. Supports dataTypes of 'DIF' ...
143    (actually only DIF for now).
144    '''
145    et=loadET(xml)
146    helper=nsdumb(et)
147    if dataType=='DIF':
148        return helper.getText(et,'Entry_ID')
149    else:
150        raise TypeError,'idget does not support datatype [%s]'%dataType
151
152import unittest
153
154class TestCase(unittest.TestCase):
155    """ Tests as required """
156
157    configFile='examples/example.config'
158    difFile='examples/neodc.eg1.dif'
159   
160    def setUp(self):
161        # If pkg_resources is available assume the module is eggified and
162        # get a stream to the input data from the egg.
163        #try:
164        #    import pkg_resources
165        #    f = pkg_resources.resource_stream(__name__, self.configFile)
166        #except ImportError:
167            # Else take the input file from __file__
168            #import os
169        self.config=myConfig(self.configFile)
170        f=file(self.difFile,'r')
171        self.difxml=f.read()
172            #f=file(os.path.join(os.path.basepath(__file__), self.configFile))
173
174        #self.config=myConfig(f)
175
176    def testConfig(self):
177        print 'Discovery Icon [%s]'%self.config.get('DISCOVERY','icon')
178       
179    def testidget(self):
180        self.assertEqual(idget(self.difxml),'NOCSDAT192')
181   
182
183if __name__=="__main__":
184    unittest.main()
185
186
187
Note: See TracBrowser for help on using the repository browser.