source: mauRepo/CedaManager/trunk/ceda_markup/opensearch/os_request.py @ 8369

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/CedaManager/trunk/ceda_markup/opensearch/os_request.py@8369
Revision 8369, 9.0 KB checked in by mnagni, 7 years ago (diff)

CedaManager? contains python class definition for many markup languages used in ceda projects

  • Property svn:mime-type set to text/plain
Line 
1'''
2BSD Licence
3Copyright (c) 2012, Science & Technology Facilities Council (STFC)
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification,
7are permitted provided that the following conditions are met:
8
9    * Redistributions of source code must retain the above copyright notice,
10        this list of conditions and the following disclaimer.
11    * Redistributions in binary form must reproduce the above copyright notice,
12        this list of conditions and the following disclaimer in the documentation
13        and/or other materials provided with the distribution.
14    * Neither the name of the Science & Technology Facilities Council (STFC)
15        nor the names of its contributors may be used to endorse or promote
16        products derived from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29Created on 5 May 2012
30
31@author: Maurizio Nagni
32'''
33from xml.etree.ElementTree import Element, SubElement, tostring
34from xml.dom import minidom
35from ceda_markup.opensearch.os_engine import get_mimetype
36from ceda_markup.opensearch.osquery import URL_REL_DEFAULT, URL_INDEX_OFFSET_DEFAULT,\
37    URL_PAGE_OFFSET_DEFAULT
38
39MAX_OS_SHORT_NAME_LEN = 16
40MAX_OS_LONG_NAME_LEN = 48
41MAX_OS_TAGS_LEN = 256
42MAX_OS_DESCRIPTION_LEN = 1024
43MAX_OS_DEVELOPER_LEN = 64
44MAX_OS_ATTRIBUTION_LEN = 256
45
46SYNDACATION_OPEN = 'open'
47SYNDACATION_LIMITED = 'limited'
48SYNDACATION_PRIVATE = 'private'
49SYNDACATION_CLOSED = 'closed'
50OS_SYNDACATION_RIGHT = [SYNDACATION_OPEN, SYNDACATION_LIMITED, SYNDACATION_PRIVATE, SYNDACATION_CLOSED]
51OS_SYNDACATION_RIGHT_DEFAULT = SYNDACATION_OPEN
52
53OS_ADULT_CONTENT_DEFAULT = False
54OS_INPUT_ENCODING_DEFAULT = 'UTF-8'
55OS_OUTPUT_ENCODING_DEFAULT = 'UTF-8'
56
57class OpenSearchRequest(object):
58    '''
59    classdocs
60    '''
61
62    NAMESPACE = 'http://a9.com/-/spec/opensearch/1.1/'
63    PREFIX = ''
64    ROOT_TAG = 'OpenSearchDescription'
65
66    def __init__(self, query, responses, os_short_name, os_description, \
67                 os_contact = None, os_tags = None, os_long_name = None, \
68                 os_image = [], os_developer = None, os_attribution = None, \
69                 os_syndacation_right = None, os_adult_content = None, \
70                 os_language = ['*'], os_input_encoding = [OS_INPUT_ENCODING_DEFAULT], \
71                 os_output_encoding = [OS_OUTPUT_ENCODING_DEFAULT]):
72        '''
73            @param query: an OSQuery implementation
74            @param responses: a list of OSResponse instances           
75            @param oshelper: a list of OSResponse implementations
76        '''
77        self.query = query
78        self.responses = responses
79
80        if os_description:
81            self.os_description = os_description[:MAX_OS_DESCRIPTION_LEN]
82       
83        if os_short_name:
84            self.os_short_name = os_short_name[:MAX_OS_SHORT_NAME_LEN]
85                   
86        #Should check that is an email format
87        if os_contact:       
88            self.os_contact = os_contact
89         
90        if os_tags:
91            self.os_tags = os_tags[:MAX_OS_TAGS_LEN]
92
93        if os_long_name:
94            self.os_long_name = os_long_name[:MAX_OS_LONG_NAME_LEN]
95
96        if os_developer:
97            self.os_developer = os_developer[:MAX_OS_DEVELOPER_LEN]
98
99        if os_attribution:
100            self.os_attribution = os_attribution[:MAX_OS_ATTRIBUTION_LEN]           
101           
102        if os_syndacation_right and os_syndacation_right in OS_SYNDACATION_RIGHT:
103            self.os_syndacation_right = os_syndacation_right           
104           
105        if os_adult_content and os_adult_content not in ['false', 'FALSE', '0', 'no', 'NO']:
106            self.os_adult_content = True                       
107           
108        self.os_image = os_image
109        self.os_language = os_language
110        self.os_input_encoding = os_input_encoding       
111        self.os_output_encoding = os_output_encoding         
112       
113    def getDescription(self, ospath):
114        top = Element(OpenSearchRequest.ROOT_TAG)
115        top.set("xmlns", OpenSearchRequest.NAMESPACE)
116       
117        shortName = SubElement(top, 'ShortName')
118        shortName.text = self.os_short_name
119       
120        description = SubElement(top, 'Description')
121        description.text = self.os_description
122       
123        if hasattr(self, 'os_tags'):
124            tags = SubElement(top, 'Tags')
125            tags.text = self.os_tags
126       
127        if hasattr(self, 'os_contact'):
128            contact = SubElement(top, 'Contact')
129            contact.text = self.os_contact
130           
131        if hasattr(self, 'os_long_name'):
132            long_name = SubElement(top, 'LongName')
133            long_name.text = self.os_long_name         
134           
135        if hasattr(self, 'os_developer'):
136            developer = SubElement(top, 'Developer')
137            developer.text = self.os_developer           
138           
139        if hasattr(self, 'os_attribution'):
140            attribution = SubElement(top, 'Attribution')
141            attribution.text = self.os_attribution           
142       
143        if hasattr(self, 'os_image') and isinstance(self.os_image, list):
144            for img in self.os_image:
145                top.append(img.buildElement())           
146       
147        if hasattr(self, 'os_syndacation_right') and self.os_syndacation_right != OS_SYNDACATION_RIGHT_DEFAULT:
148            syndacation_right = SubElement(top, 'SyndacationRight')
149            syndacation_right.text = self.syndacation_right       
150       
151        if hasattr(self, 'os_adult_content'):
152            adult_content = SubElement(top, 'AdultContent')
153            adult_content.text = self.adult_content               
154       
155        if self.os_language and isinstance(self.os_language, list):
156            for item in self.os_language:
157                language = SubElement(top, 'Language')
158                language.text = item       
159       
160        if self.os_input_encoding and isinstance(self.os_input_encoding, list):
161            for item in self.os_input_encoding:
162                ie = SubElement(top, 'InputEncoding')
163                ie.text = item     
164       
165        if self.os_output_encoding and isinstance(self.os_output_encoding, list):
166            for item in self.os_output_encoding:
167                ie = SubElement(top, 'OuputEncoding')
168                ie.text = item             
169       
170        for item in self.responses:           
171            url = self._buildTemplateURL(top, item.extension, self.query.rel, self.query.indexOffset, self.query.pageOffset, ospath)
172            #self.oshelper.assignNamespacePrefix(url)   
173           
174       
175        reparsed = minidom.parseString(tostring(top))
176        return reparsed.toprettyxml(indent="  ")
177
178    def _assignPrefix(self, root, param):
179        if param.namespace is None:
180            return param.term_name
181       
182        for k,v in root.items():
183            if v == param.namespace:
184                return ("%s:%s") % (k[6:], param.term_name)
185       
186        index = 0
187        while True:
188            if "xmlns:a%d" % (index) not in root.keys():               
189                break
190            index = index + 1
191           
192        root.set("xmlns:a%d" % (index), param.namespace)
193        return ("a%d:%s") % (index, param.term_name)
194
195    def _buildTemplateURL(self, root, response_type, rel, indexOffset, pageOffset, ospath):
196        url = Element("Url")
197        url.set("type", get_mimetype(response_type))
198       
199        template_query = ""
200        for param in self.query.params_model:
201            term = self._assignPrefix(root, param)
202           
203            urlParam = ""
204            if param.required:             
205                urlParam = ("%s={%s}") % (param.par_name, term)
206            else:
207                urlParam = ("%s={%s?}") % (param.par_name, term)
208               
209            template_query += ("%s&") % (urlParam)           
210        query_template = ("%s%s?%s") % (ospath, response_type, template_query[:-1])
211        url.set("template", query_template)
212       
213        if rel and rel != URL_REL_DEFAULT:
214            url.set("rel", rel)
215       
216        if indexOffset and indexOffset != URL_INDEX_OFFSET_DEFAULT:           
217            url.set("indexOffset", str(indexOffset))
218       
219        if pageOffset and pageOffset != URL_PAGE_OFFSET_DEFAULT:                   
220            url.set("pageOffset", str(pageOffset))       
221       
222        root.append(url)
Note: See TracBrowser for help on using the repository browser.