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

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

Changes to make cleaner logging in discovery/browse ..

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