source: TI03-DataExtractor/trunk/pydxc/common.py @ 1715

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/trunk/pydxc/common.py@1715
Revision 1715, 7.2 KB checked in by astephen, 13 years ago (diff)

Merged with titania version.

Line 
1#   Copyright (C) 2004 CCLRC & NERC( Natural Environment Research Council ).
2#   This software may be distributed under the terms of the
3#   Q Public License, version 1.0 or later. http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
4
5"""
6common.py
7=========
8
9Holds common functions and classes used in the Data Extractor software.
10
11"""
12
13# Import python modules
14import os, re
15
16# Import package modules
17from clientConfig import *
18
19# Set up commmon variables. These are CAPITALISED to
20# improve visibility in other modules.
21HTTP_HEADER="Content-Type: text/html\n\n"
22
23STAGES=["DatasetGroupPage", "DatasetPage", "VariablesPage", "DomainPage", "ResultsPage"]
24
25TIME_KEYS=["Year", "Month", "Day", "Hour", "Minute", "Second"]
26
27HORIZ_KEYS=["northernExtent", "easternExtent", "southernExtent", "westernExtent"]
28
29dateTimePattern=re.compile(r"^(\d{4}).(\d{1,2}).(\d{1,2})(\s+|T)(\d+):(\d+):(\d+\.?.*)$")
30
31# Set up common functions
32
33def getDateTimeComponents(dateTimeString):
34    """
35    Takes in a time string in standard DateTime format and returns the items in it.
36    """
37    match=dateTimePattern.match(dateTimeString)
38    if not match:
39        raise "Cannot match date time string: %s" % dateTimeString
40
41    items=match.groups()
42    (year, month, day, hour, minute)=[int(i) for i in items[:3]+items[4:6]]
43    second=float(items[6])
44    return (year, month, day, hour, minute, second)
45
46 
47def createSummaryDict(summaryString):
48    """
49    Takes in a summary string containing details of a user request and
50    returns a more user-friendly dictionary version held as:
51   
52    dict["datasetGroups"], dict["datasets"] etc
53   
54    with all global selections as dict[selectionName] etc
55    """
56    d={"globals":{}, "axes":{}}
57    for i in "datasetGroup dataset variable datasetURI outputFormat".split():
58        d[i+"s"]={}
59       
60    s=summaryString
61   
62    items=s.split("\n")
63
64    matcher=re.compile(r"^(datasetGroup|dataset|variable|datasetURI|axis|outputFormat)_(\d+.*)$")
65   
66    for item in items:
67        if item.find(":")<0: continue
68        colon=item.find(":")
69       
70        (name, value)=(item[:colon], item[colon+1:])
71        (name, value)=(name.strip(), value.strip())
72        # deCamelCase later...???
73        match=matcher.match(name)
74       
75        if match:
76            (stringMatched, index)=match.groups()
77            if stringMatched=="axis":
78                d["axes"][index]=value
79            else:
80                d[stringMatched+"s"][index]=value
81        else:
82            d["globals"][name]=value
83           
84    return d   
85   
86   
87def getDictSubsetMatching(dct, pattern, mode="string match"):
88    """
89    Returns a dictionary of all items in input dictionary 'dct'
90    where keys match 'pattern'.
91    """
92    rtdict={}
93    for key in dct.keys():
94        if mode=="string match":
95            if key.find(pattern)>-1:
96                rtdict[key]=dct[key]
97        elif mode=="regex":
98            match=re.search(pattern, key)
99            if match:
100                rtdict[key]=dct[key]       
101    return rtdict
102   
103   
104def deleteDictSubsetMatching(dct, pattern, mode="string match"):
105    """
106    Deletes any items in the dictionary subset matched when calling
107    getDictSubsetMatching above. Returns the number of items deleted.
108    """
109    subdict=getDictSubsetMatching(dct, pattern, mode)
110    counter=0;
111    for key in subdict.keys():
112        del dct[key]
113        counter=counter+1
114    return counter
115   
116
117def translateURI(uri):
118    """
119    Takes a URL and returns the location of the file on the local network
120    or takes a local path and returns the URL of the file/directory.
121    """
122    if uri.find("http")>-1:
123        newpath=uri.replace(OUTPUT_DIR_URL_PATH, OUTPUT_DIR_LOCAL_PATH)
124    else:
125        newpath=uri.replace(OUTPUT_DIR_LOCAL_PATH, OUTPUT_DIR_URL_PATH)
126    return newpath
127
128
129def getIdenticalDomains(varLists):
130    """
131    Returns a list of var IDs that are the on the same domain.
132    """
133    sameDomains=[]
134    (categories, details)=varLists[0:2]
135    foundDict={}
136   
137    for c in range(len(categories)):
138        category=categories[c]
139        detail=details[c]
140        found=None
141        for (cat, det) in foundDict.items():
142            if detail==det[0]:
143                foundDict[cat].append(category)
144                found=1 
145        if found==None:
146            foundDict[category]=[detail]
147
148    codePattn=re.compile(r"axis_(\d+\.\d+\.\d+)\.\d+")
149    for (cat, content) in foundDict.items():
150        if len(content)>1:
151            axes=[cat]+content[1:]
152            # Now we test for differences in the axes
153            codelist=[codePattn.match(ax).groups()[0] for ax in axes]
154
155            found=[]
156            for code in codelist:
157                if code not in found: found.append(code)
158               
159            if len(found)>1:
160                stuffToAdd=[("variable_%s" % f) for f in found]
161                if stuffToAdd not in sameDomains:
162                    sameDomains.append(stuffToAdd)
163   
164    return sameDomains
165
166
167def deUnicodeObject(obj):
168    """
169    Returns the object identical except unicode strings are all
170    converted to normal strings.
171    """
172    tupleFound=None
173    if type(obj)==type((1,2)):
174        tupleFound=1
175        obj=list(obj)
176
177    if type(obj)==type([]):
178        rtobj=[]
179        for i in obj:
180            if type(i) in (type([]), type((1,2))):
181                rtobj.append(deUnicodeObject(i))
182            elif type(i)==type(u""):
183                rtobj.append(str(i))
184            else:
185                rtobj.append(i)
186        if tupleFound==1: rtobj=tuple(rtobj)
187
188    elif type(obj)==type(u""):
189        rtobj=str(obj)
190    else:
191        rtobj=obj
192    return rtobj
193
194
195# Set up common classes
196class RedirectStdout:
197    """
198    RedirectStdout class - used to direct standard output away from
199    the screen in CGI scripts.
200    """
201
202    def write(self, item):
203        """
204        write method - allows dummy standard out to work.
205        """
206        pass
207
208    def flush(self):
209        """
210        Method to do nothing, again!
211        """
212        pass
213
214
215if __name__=="__main__":
216    print createSummaryDict("""status: constructing
217    username: None
218    accessTime: 1146079648.25
219    variable_3.1.1: var3
220    proceed: Proceed
221    dataset_2.1: Test Dataset 2
222    userRoles: []
223    dataset_3.1: Test Dataset 3
224    datasetGroup_2: Test Data Group 2
225    datasetGroup_3: Test Data Group 3
226    sessionID: session_20060426190723114
227    datasetGroup_1: Test Data Group 1
228    variable_1.1.1: pqn
229    dataset_1.1: Test Dataset 1
230    variable_2.1.1: var2 """)
231   
232    print getDateTimeComponents("2004-1-1T12:0:0.0")
233    print getDateTimeComponents("2004-07-04T12:45:33.489")
234   
235    print getIdenticalDomains([["axis_1.3.1.1", "axis_1.1.1.2", "axis_1.1.1.3"], [["lat", None, 32], ["lon", "ough", 45], ["lat", None, 32]]])
236   
237    print getIdenticalDomains([['axis_1.1.1.1', 'axis_1.1.1.2', 'axis_1.1.1.3',
238        'axis_1.1.2.1', 'axis_1.1.2.2', 'axis_1.1.2.3'], [['time', 'time', 'Time', 'hour', 'start end interval', '', '1999-1-1T0:0:0.0', '1999-1-1T6:0:0.0', 6.0],  ['latitude', 'latitude', 'Latitude', 'degrees_north', 'start end', '', 90.0, -90.0], ['longitude', 'longitude', 'Longitude', 'degrees_east', 'start end', '', 0, 355], ['time', 'time', 'Time', 'hour', 'start end interval', '', '1999-1-1T0:0:0.0', '1999-1-1T6:0:0.0', 6.0], ['latitude', 'latitude', 'Latitude', 'degrees_north', 'start end', '', 90.0, -90.0], ['longitude', 'longitude', 'Longitude', 'degrees_east', 'start end', '', 0, 355]]])
Note: See TracBrowser for help on using the repository browser.