source: TI07-MOLES/trunk/PythonCode/browse/portal/cgi/browse/Utilities.py @ 1644

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI07-MOLES/trunk/PythonCode/browse/portal/cgi/browse/Utilities.py@1644
Revision 1644, 6.1 KB checked in by lawrence, 14 years ago (diff)

Modifications for wsgi (and hence fastcgi) compliance in new discovery

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
6import ConfigParser
7import os
8import re
9import urllib
10
11class myConfig:
12        ''' Handle missing sections and variables in a config file a bit gracefully '''
13        def __init__(self,configfile):
14                self.config=ConfigParser.ConfigParser()
15                if not os.path.exists(configfile):
16                        raise 'No config file: %s'%configfile
17                self.config.read(configfile)
18                logfile=self.get('logging','debugLog',None)
19                self.logfile=None
20                if logfile is not None:
21                        self.logfile=open(logfile,'a')
22
23        def get(self,section,key,default=None):
24                try:
25                        return self.config.get(section,key)
26                except:
27                        return default
28       
29        def log(self,string):
30            ''' Log some debug information '''
31            if self.logfile is None: return
32            if string is not None:
33                self.logfile.write('%s\n'%string)
34            else:
35                self.logfile.write('empty log entry\n')
36               
37class Request:
38    ''' Holds the request URL etc '''
39    def __init__(self,env,cgi,wsgi=0):
40        ''' Instantiates attributes:
41            env: the environment
42            URL: a url to recreate the request SANS any security info and selection arguments
43            variables: any arguments to the request ... '''
44        self.env=env
45        self.URL='http://%s:%s%s'%(env.get('SERVER_NAME'),env.get('SERVER_PORT'),
46                                   env.get('SCRIPT_NAME'))
47        self.baseURL=self.URL
48        try:   
49             if wsgi:
50                 # in this case we've got it externally
51                 self.variables=getURLdict(cgi)
52             else:
53                 self.variables=getURLdict(cgi.FieldStorage())
54        except Exception,e:
55            self.variables={'Error':'<p> Error in Request, parseing url [%s]</p>'%self.URL}
56            return
57        self.URL=self.__rebuildURL()
58
59    def __rebuildURL(self):
60        ''' builds  a url from the cgi variables that are loaded '''
61        url=self.baseURL
62        try: 
63            #reconstruct the url carefully, to avoid the selector and any
64            #ndg security info if present ...
65            tmp={}
66            reject=['select','NDG-ID1','NDG-ID2']
67            for i in self.variables:
68                if i not in reject: tmp[i]=self.variables[i]
69            if tmp!={}: url+='?%s'%urllib.urlencode(tmp)
70        except Exception,e:
71            #raise e
72            self.variables={'Error':'<p> Error rebuilding URL from [%s] </p>'%url}
73        return url
74           
75    def modify(self,variables):
76        ''' Used to take a GET request url, and modify some of the variables and provide
77        a new modified GET '''
78        for var in variables:
79            self.variables[var]=variables[var]
80        return self.__rebuildURL()
81class Response:
82        ''' Holds all the parts of the response to an HTML get or post '''
83        def __init__(self,content='text/html'):
84                self.headers=[]
85                self.cookie=None
86                self.contentType=content
87                self.content=''
88        def write(self,out):
89                for name,value in self.headers:
90                        out.write("%s: %s\n"( name,value))
91                if self.cookie:
92                        out.write("%s\n"%self.cookie)
93                out.write("Content-type: %s\n"%self.contentType)
94                out.write("\n")
95                self.content=self.content.encode('utf-8')
96                out.write(self.content)
97
98class RingBuffer(deque):
99    #deque is a python 2.4 class!
100    #credit http://www.onlamp.com/pub/a/python/excerpt/pythonckbk_chap1/index1.html
101    def __init__(self, size_max):
102        deque.__init__(self)
103        self.size_max = size_max
104    def append(self, datum):
105        deque.append(self, datum)
106        if len(self) > self.size_max:
107            self.popleft( )
108    def tolist(self):
109        return list(self)
110
111def wrapGetText(element,xpathExpression,multiple=0):
112        ''' Wraps a call to ET to get a text object in an error handler '''
113        def none2txt(i):
114            if i is None: return ''
115            return i
116        if element is None:
117            if multiple:
118                 return ['',]
119            else: return ''
120        if multiple:
121                r=element.findall(xpathExpression)
122        else:
123                r=[element.find(xpathExpression),]
124        try:
125                rr=[i.text for i in r]
126        except:
127                rr=['',]
128        rr=map(none2txt,rr) 
129        if multiple: 
130                return rr
131        else: return rr[0] 
132
133def getURLdict(cgiFieldStorage):
134    ''' takes a cgi field storage object and converts it to a dictionary '''
135    result={}
136    for item in cgiFieldStorage:
137            result[item]=cgiFieldStorage[item].value
138    return result
139##
140### convert the followign two methods into one class that can handle
141## xml directly too if necessary
142##
143def DIFid2NDGid(string):
144    ''' takes a dif thing parses it and produces an ET ndg element id ...
145    and use this in dif ... '''
146    s=string.split(':')
147    try:
148        r='''<DIFid><schemeIdentifier>%s</schemeIdentifier>
149         <repositoryIdentifier>%s</repositoryIdentifier>
150         <localIdentifier>%s</localIdentifier></DIFid>'''%(s[1],s[0],s[2])
151        return ET.fromstring(r)
152    except:
153        r='''<DIFid><schemeIdentifier>DIF</schemeIdentifier>
154        <repositoryIdentifier>Unknown</repositoryIdentifier>
155        <localIdentifier>%s</localIdentifier></DIFid>'''%string
156        return ET.fromstring(r)
157
158def EnumerateString(string):
159    ''' Takes a string, and if it's got a number on the end, increments it,
160    otherwise adds a number on the end, used to differentiate strings which
161    would otherwise be identical '''
162    def addNum(matchObj):
163        s=matchObj.group()
164        return str(int(s)+1)
165    r=re.sub('\d+$',addNum,string)
166    if r==string: r=r+'1'
167    return r
168
169def dateParse(string,instruction):
170    ''' Simple date manipulations on a string, if it is understood ...
171       if instruction = YYYY, return the year '''
172    s=string.split('-')
173    if instruction=='YYYY':
174        if len(s)==3: # expecting year,mon,day or day,mon,year ...
175            if int(s[0])>int(s[2]): 
176                return s[0]
177            else:
178                return s[2]
179        else:
180            return string # unknown format as yet ...
181    else:
182        return 'unknown instruction to dateParse %s'%instruction
183       
184if __name__=="__main__":
185    s,t='abc12','def'
186    print s,EnumerateString(s),t,EnumerateString(t)
187   
Note: See TracBrowser for help on using the repository browser.