source: mauRepo/CedaMarkup/tags/0.0.4/ceda_markup/opensearch/os_request.py @ 8448

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/CedaMarkup/tags/0.0.4/ceda_markup/opensearch/os_request.py@8448
Revision 8448, 9.3 KB checked in by mnagni, 7 years ago (diff)

Incomplete - # 22518: The description is broken
 http://team.ceda.ac.uk/trac/ceda/ticket/22518

The pythonlib is not able to correctly serialize boolean type as explained here  http://code.google.com/p/gdata-python-client/issues/detail?id=611 where a workaround is suggested and applied here

  • 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 os_engine import get_mimetype
36from 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        self.os_syndacation_right = None
80       
81        # should be set to True but because of
82        # http://code.google.com/p/gdata-python-client/issues/detail?id=611
83        # we cannot (for now)
84        self.os_adult_content = '1'
85
86        if os_description:
87            self.os_description = os_description[:MAX_OS_DESCRIPTION_LEN]
88       
89        if os_short_name:
90            self.os_short_name = os_short_name[:MAX_OS_SHORT_NAME_LEN]
91                   
92        #Should check that is an email format
93        if os_contact:       
94            self.os_contact = os_contact
95         
96        if os_tags:
97            self.os_tags = os_tags[:MAX_OS_TAGS_LEN]
98
99        if os_long_name:
100            self.os_long_name = os_long_name[:MAX_OS_LONG_NAME_LEN]
101
102        if os_developer:
103            self.os_developer = os_developer[:MAX_OS_DEVELOPER_LEN]
104
105        if os_attribution:
106            self.os_attribution = os_attribution[:MAX_OS_ATTRIBUTION_LEN]           
107           
108        if os_syndacation_right and os_syndacation_right in OS_SYNDACATION_RIGHT:
109            self.os_syndacation_right = os_syndacation_right           
110           
111        if os_adult_content and os_adult_content in ['false', 'FALSE', '0', 'no', 'NO']:
112            # should be set to False but because of
113            # http://code.google.com/p/gdata-python-client/issues/detail?id=611
114            # we cannot (for now)           
115            self.os_adult_content = '0'                       
116           
117        self.os_image = os_image
118        self.os_language = os_language
119        self.os_input_encoding = os_input_encoding       
120        self.os_output_encoding = os_output_encoding         
121       
122    def getDescription(self, ospath):
123        top = Element(OpenSearchRequest.ROOT_TAG)
124        top.set("xmlns", OpenSearchRequest.NAMESPACE)
125       
126        shortName = SubElement(top, 'ShortName')
127        shortName.text = self.os_short_name
128       
129        description = SubElement(top, 'Description')
130        description.text = self.os_description
131       
132        if hasattr(self, 'os_tags'):
133            tags = SubElement(top, 'Tags')
134            tags.text = self.os_tags
135       
136        if hasattr(self, 'os_contact'):
137            contact = SubElement(top, 'Contact')
138            contact.text = self.os_contact
139           
140        if hasattr(self, 'os_long_name'):
141            long_name = SubElement(top, 'LongName')
142            long_name.text = self.os_long_name         
143           
144        if hasattr(self, 'os_developer'):
145            developer = SubElement(top, 'Developer')
146            developer.text = self.os_developer           
147           
148        if hasattr(self, 'os_attribution'):
149            attribution = SubElement(top, 'Attribution')
150            attribution.text = self.os_attribution           
151       
152        if hasattr(self, 'os_image') and isinstance(self.os_image, list):
153            for img in self.os_image:
154                top.append(img.buildElement())           
155       
156        if hasattr(self, 'os_syndacation_right') and self.os_syndacation_right != OS_SYNDACATION_RIGHT_DEFAULT:
157            syndacation_right = SubElement(top, 'SyndacationRight')
158            syndacation_right.text = self.syndacation_right       
159       
160        if hasattr(self, 'os_adult_content'):
161            adult_content = SubElement(top, 'AdultContent')
162            adult_content.text = self.adult_content               
163       
164        if self.os_language and isinstance(self.os_language, list):
165            for item in self.os_language:
166                language = SubElement(top, 'Language')
167                language.text = item       
168       
169        if self.os_input_encoding and isinstance(self.os_input_encoding, list):
170            for item in self.os_input_encoding:
171                ie = SubElement(top, 'InputEncoding')
172                ie.text = item     
173       
174        if self.os_output_encoding and isinstance(self.os_output_encoding, list):
175            for item in self.os_output_encoding:
176                ie = SubElement(top, 'OuputEncoding')
177                ie.text = item             
178       
179        for item in self.responses:           
180            self._buildTemplateURL(top, item.extension, self.query.rel, self.query.indexOffset, self.query.pageOffset, ospath)
181       
182        reparsed = minidom.parseString(tostring(top))
183        return reparsed.toprettyxml(indent="  ")
184
185    def _assignPrefix(self, root, param):
186        if param.namespace is None:
187            return param.term_name
188       
189        for k,v in root.items():
190            if v == param.namespace:
191                return ("%s:%s") % (k[6:], param.term_name)
192       
193        index = 0
194        while True:
195            if "xmlns:a%d" % (index) not in root.keys():               
196                break
197            index = index + 1
198           
199        root.set("xmlns:a%d" % (index), param.namespace)
200        return ("a%d:%s") % (index, param.term_name)
201
202    def _buildTemplateURL(self, root, response_type, rel, indexOffset, pageOffset, ospath):
203        url = Element("Url")
204        url.set("type", get_mimetype(response_type))
205       
206        template_query = ""
207        for param in self.query.params_model:
208            term = self._assignPrefix(root, param)
209           
210            urlParam = ""
211            if param.required:             
212                urlParam = ("%s={%s}") % (param.par_name, term)
213            else:
214                urlParam = ("%s={%s?}") % (param.par_name, term)
215               
216            template_query += ("%s&") % (urlParam)           
217        query_template = ("%s%s?%s") % (ospath, response_type, template_query[:-1])
218        url.set("template", query_template)
219       
220        if rel and rel != URL_REL_DEFAULT:
221            url.set("rel", rel)
222       
223        if indexOffset and indexOffset != URL_INDEX_OFFSET_DEFAULT:           
224            url.set("indexOffset", str(indexOffset))
225       
226        if pageOffset and pageOffset != URL_PAGE_OFFSET_DEFAULT:                   
227            url.set("pageOffset", str(pageOffset))       
228       
229        root.append(url)
Note: See TracBrowser for help on using the repository browser.