Changeset 8463


Ignore:
Timestamp:
12/07/12 15:59:54 (8 years ago)
Author:
mnagni
Message:

Major changes

  • Improved Opensearch engine
  • Refactored other markups to the "createMarkup" style
  • Included an opensoftware library for managing Date
Location:
mauRepo/CedaMarkup/trunk/ceda_markup
Files:
13 added
5 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • mauRepo/CedaMarkup/trunk/ceda_markup/__init__.py

    r8454 r8463  
    3434__version__ = '0.0.6' 
    3535 
     36import mimetypes 
     37if not mimetypes.inited: 
     38    mimetypes.init() 
     39    if not getattr(mimetypes, 'types_map').has_key('.atom'): 
     40        mimetypes.add_type('application/atom+xml', '.atom') 
     41    if not getattr(mimetypes, 'types_map').has_key('.opensearchdescription'):         
     42        mimetypes.add_type('application/opensearchdescription+xml', '.opensearchdescription') 
     43 
     44 
    3645def extendElement(element, collectionToAppend): 
    3746    ''' 
     
    4756 
    4857    for item in collectionToAppend: 
    49         getattr(element, 'append')(item) 
     58        getattr(element, 'append')(item)        
     59 
     60def get_mimetype(extension): 
     61    """ 
     62        Returns the mimetypes for a given file extension.  
     63        For example 'xml' should return 'text/xml' 
     64        @param extension: the file extension  
     65        @return: the associated mimetype 
     66    """ 
     67    return getattr(mimetypes, 'types_map')[('.%s') % (extension)] 
  • mauRepo/CedaMarkup/trunk/ceda_markup/atom/atom.py

    r8452 r8463  
    3131@author: Maurizio Nagni 
    3232''' 
    33 from xml.etree.ElementTree import SubElement 
    34 from ceda_markup.markup import createMarkup 
     33from ceda_markup.markup import createMarkup, createSimpleMarkup 
     34from ceda_markup import extendElement 
    3535 
    3636ATOM_NAMESPACE = 'http://www.w3.org/2005/Atom' 
     
    3838ATOM_ROOT_TAG = 'feed' 
    3939 
    40 def createDocument(iid, title, updated, subtitle = None, rights = None): 
    41     top = createAtom()         
     40def createAtomDocument(iid, title, updated, subtitle = None, rights = None): 
     41    ''' 
     42        Returns an ElementTree.Element representing an Atom document     
     43        @param iid: a string 
     44        @param title: a string 
     45        @param updated: a string 
     46        @param subtitle: a string         
     47        @param rights: a string                 
     48        @return: a new ElementTree.Element instance         
     49    ''' 
     50    atom = createAtom()         
    4251    
    43     ititle = SubElement(top, 'title') 
    44     ititle.text = title 
    45      
    46     iupdated = SubElement(top, 'updated') 
    47     iupdated.text = updated               
    48      
    49     doc_id = SubElement(top, 'id') 
    50     doc_id.text = iid 
     52    _id = createID(iid, atom) 
     53    atom.append(_id) 
     54     
     55    _title = createTitle(title, atom) 
     56    atom.append(_title) 
     57     
     58    _updated = createUpdated(updated, atom) 
     59    atom.append(_updated) 
    5160     
    5261    if subtitle is not None: 
    53         subtitle = SubElement(top, 'subtitle') 
    54         subtitle.text = subtitle 
     62        _subtitle = createSubTitle(subtitle, atom) 
     63        atom.append(_subtitle) 
    5564         
    5665    if rights is not None: 
    57         rights = SubElement(top, 'rights') 
    58         rights.text = rights             
    59  
    60      
    61     return top 
     66        _rights = createRigths(rights, atom) 
     67        atom.append(_rights)         
     68     
     69    return atom 
     70 
     71def createEntry(iid, title, updated, \ 
     72                 author = None, content = None, link = None, \ 
     73                 published = None, root = None,  
     74                 ns = ATOM_NAMESPACE):       
     75        ''' 
     76            Constructor 
     77            @param iid: an atom.ID instance 
     78            @param title: an atom.Title instance  
     79            @param updated: an atom.Update instance 
     80            @param author: one or more atom.Author instances 
     81            @param content: an atom.Content instance              
     82            @param link: one or more atom.Link instances                                      
     83            @param published: an atom.Published instance                           
     84            @param root: the document root element where attach the prefix:namespace for this element                         
     85        ''' 
     86        markup = createMarkup('entry', ATOM_PREFIX, ns, root)         
     87        markup.append(iid)                 
     88        markup.append(title)         
     89        markup.append(updated) 
     90         
     91        if author is not None: 
     92            if isinstance(author, list): 
     93                extendElement(markup, author) 
     94            else: 
     95                markup.append(author)                
     96                 
     97        if content is not None: 
     98            markup.append(content) 
     99             
     100        if link is not None: 
     101            markup.append(link) 
     102                                             
     103        if published is not None: 
     104            markup.append(published)                
     105               
     106        return markup 
    62107 
    63108def createAtom(root = None, tagName = ATOM_ROOT_TAG, ns = ATOM_NAMESPACE):       
    64109    ''' 
     110        Returns an ElementTree.Element representing an Atom tag 
    65111        @param root: the root tag of the document containing this element 
    66112        @param tagName: the tagName  
    67         @param ns: the tag namespace        
     113        @param ns: the tag namespace 
     114        @return: a new ElementTree.Element instance      
    68115    ''' 
    69116    return createMarkup(tagName, ATOM_PREFIX, ns, root) 
     
    71118def createID(iid, root = None, ns = ATOM_NAMESPACE):       
    72119    ''' 
     120        Returns an Atom.id instance as ElementTree 
    73121        @param iid: a unique identifier, eventually an URI     
    74122        @param root: the root tag of the document containing this element  
    75123        @param ns: the tag namespace        
    76     ''' 
    77     markup = createMarkup('id', ATOM_PREFIX, ns, root)         
    78     markup.text = str(iid)     
    79     return markup 
     124        @return: a new ElementTree.Element instance         
     125    ''' 
     126    return createSimpleMarkup(str(iid), root, 'id', ns, ATOM_PREFIX)     
     127 
     128def createTitle(title, root = None, ns = ATOM_NAMESPACE):       
     129    ''' 
     130        Returns an Atom.title instance as ElementTree 
     131        @param title: the title's text     
     132        @param root: the root tag of the document containing this element  
     133        @param ns: the tag namespace        
     134        @return: a new ElementTree.Element instance         
     135    ''' 
     136    return createSimpleMarkup(title, root, 'title', ns, ATOM_PREFIX)     
     137 
     138def createSubTitle(subtitle, root = None, ns = ATOM_NAMESPACE):       
     139    ''' 
     140        Returns an Atom.subtitle instance as ElementTree 
     141        @param title: the title's text     
     142        @param root: the root tag of the document containing this element  
     143        @param ns: the tag namespace        
     144        @return: a new ElementTree.Element instance         
     145    ''' 
     146    return createSimpleMarkup(str(subtitle), root, 'subtitle', ns, ATOM_PREFIX) 
     147 
     148def createRigths(rigths, root = None, ns = ATOM_NAMESPACE):       
     149    ''' 
     150        Returns an Atom.title instance as ElementTree 
     151        @param rigths: the rigths's text     
     152        @param root: the root tag of the document containing this element  
     153        @param ns: the tag namespace        
     154        @return: a new ElementTree.Element instance         
     155    ''' 
     156    return createSimpleMarkup(str(rigths), root, 'rigths', ns, ATOM_PREFIX) 
     157 
    80158 
    81159def createUpdated(updated, root = None, ns = ATOM_NAMESPACE):       
    82160    ''' 
     161        Returns an Atom.updated instance as ElementTree 
    83162        @param updated: is a Date construct indicating the most 
    84163   recent instant in time when an entry or feed was modified in a way 
    85164   the publisher considers significant. 
    86165        @param root: the root tag of the document containing this element  
    87         @param ns: the tag namespace        
    88     ''' 
    89     markup = createMarkup('updated', ATOM_PREFIX, ns, root)         
    90     markup.text = str(updated)     
    91     return markup 
     166        @param ns: the tag namespace    
     167        @return: a new ElementTree.Element instance             
     168    ''' 
     169    return createSimpleMarkup(str(updated), root, 'updated', ns, ATOM_PREFIX)     
     170 
    92171 
    93172def createPublished(published, root = None, ns = ATOM_NAMESPACE):       
     
    97176   the entry     
    98177        @param root: the root tag of the document containing this element  
    99         @param ns: the tag namespace        
    100     ''' 
    101     markup = createMarkup('published', ATOM_PREFIX, ns, root)         
    102     markup.text = str(published)     
    103     return markup 
     178        @param ns: the tag namespace  
     179        @return: a new ElementTree.Element instance               
     180    ''' 
     181    return createSimpleMarkup(str(published), root, 'published', ns, ATOM_PREFIX)     
    104182 
    105183ATOM_LINK_REL_SELF = 'self' 
     
    114192        @param itype: an advisory media type as 'application/atom+xml'        
    115193        @param root: the root tag of the document containing this element  
    116         @param ns: the tag namespace        
     194        @param ns: the tag namespace    
     195        @return: a new ElementTree.Element instance             
    117196    ''' 
    118197    markup = createMarkup('link', ATOM_PREFIX, ns, root) 
  • mauRepo/CedaMarkup/trunk/ceda_markup/atom/info.py

    r8418 r8463  
    5858 
    5959def createTitle(root = None, ns = ATOM_NAMESPACE, body = None, itype = TEXT_TYPE): 
     60    """ 
     61        Creates an Atom.title element. 
     62        The 'body' parameter is assigned to the tag according to the 'itype' parameter; 
     63        itype == XHTML_TYPE ---> body must be an ElementTree.Element instance 
     64        itype == HTML_TYPE or TEXT_TYPE ---> body should be a text string 
     65        @param root: the document owning this tag 
     66        @param ns: the namespace associated with this tag 
     67        @param body: the tag content 
     68        @param itype: the tag content type. It accepts TEXT_TYPE, HTML_TYPE, XHTML_TYPE values 
     69        @return: an ElementTree.Element instance           
     70    """ 
    6071    markup = createMarkup('title', ATOM_PREFIX, ns, root = root) 
    6172    return _assignTypeAtribute(itype, markup, body) 
  • mauRepo/CedaMarkup/trunk/ceda_markup/atom/link.py

    r8452 r8463  
    3131@author: Maurizio Nagni 
    3232''' 
    33 from ceda_markup.atom.atom import ATOM_ROOT_TAG, ATOM_NAMESPACE, ATOM_PREFIX 
     33from ceda_markup.atom.atom import ATOM_NAMESPACE, ATOM_PREFIX 
    3434from ceda_markup.markup import createMarkup 
    3535 
  • mauRepo/CedaMarkup/trunk/ceda_markup/markup.py

    r8418 r8463  
    3434def createMarkup(tagName, tagPrefix, tagNamespace, root = None): 
    3535        ''' 
    36             Constructor 
     36            Returns an ElementTree.Element instance 
    3737            @param tagName: the tag name     
    3838            @param tagPrefix: the prefix to use for this tag 
    3939            @param tagNamespace: the tag's namespace 
    40             @param root: the root Element of the document containing this element                         
     40            @param root: the root Element of the document containing this element 
     41            @return: a new instance                        
    4142        ''' 
    4243        #attach gml namespace to the document root element 
     
    5657            markup.set("xmlns", tagNamespace) 
    5758        return markup 
     59     
     60def createSimpleMarkup(text, root, tagName, ns, prefix): 
     61    """ 
     62        Returns a new markup filling only its 'text' attribute 
     63    """ 
     64    markup = createMarkup(tagName, prefix, ns, root) 
     65    markup.text = text 
     66    return markup 
  • mauRepo/CedaMarkup/trunk/ceda_markup/opensearch/__init__.py

    r8369 r8463  
     1import math 
     2from ceda_markup.atom.link import REL_SEARCH, REL_SELF, REL_ALTERNATE 
     3from ceda_markup import get_mimetype 
     4from ceda_markup.atom.atom import ATOM_LINK_REL_SEARCH, createLink 
     5 
     6def assignPrefix(root, param): 
     7    if param.namespace is None: 
     8        return param.term_name 
     9     
     10    for k,v in root.items(): 
     11        if v == param.namespace: 
     12            return ("%s:%s") % (k[6:], param.term_name) 
     13     
     14    index = 0 
     15    while True: 
     16        if "xmlns:a%d" % (index) not in root.keys():                 
     17            break  
     18        index = index + 1 
     19         
     20    root.set("xmlns:a%d" % (index), param.namespace) 
     21    return ("a%d:%s") % (index, param.term_name) 
     22 
     23def createTemplateQuery(root, query): 
     24    ''' 
     25        Creates a string to be used as parameters template list in the "description". 
     26        As this description is used in a OpenSearch URL tag, the root parameter is required  
     27        in order to update the tag with the necessary namespaces 
     28        @param root: the OpenSearchRequest.ROOT_TAG tag. 
     29        @param query: an OSQuery instance.         
     30        @return: a string describing the parameters query 
     31    ''' 
     32    template_query = "" 
     33    for param in query.params_model: 
     34        term = assignPrefix(root, param) 
     35         
     36        urlParam = "" 
     37        if param.required:              
     38            urlParam = ("%s={%s}") % (param.par_name, term) 
     39        else: 
     40            urlParam = ("%s={%s?}") % (param.par_name, term) 
     41            
     42        template_query += ("%s&") % (urlParam) 
     43    return template_query 
     44 
     45COUNT_DEFAULT = 10 
     46START_INDEX_DEFAULT = 1 
     47START_PAGE_DEFAULT = 1 
     48 
     49def filterResults(results, count = COUNT_DEFAULT, startIndex = START_INDEX_DEFAULT, startPage = START_PAGE_DEFAULT): 
     50    """ 
     51        Returns the opensearch results list according to the  
     52        'count', 'startIndex', 'startPage' parameters 
     53        @param results: an instance or a list of instances to be displayed in the opensearch response 
     54        @param count: the number of search results per page desired by the search client 
     55        @param startIndex: the index of the first search result desired by the search client 
     56        @param startPage: the page number of the set of search results desired by the search client 
     57        @return: the selected results or None if the results is None or is not a list or is an empty list 
     58    """ 
     59    if results is None: 
     60        return None 
     61    elif isinstance(results, list) and len(results) == 0: 
     62        return None 
     63    elif not isinstance(results, list): 
     64        _results = [results] 
     65    else: 
     66        _results = results 
     67         
     68    tot_res = len(_results) 
     69         
     70    if count is not None and count > 0: 
     71        int_count = count 
     72    else: 
     73        int_count = COUNT_DEFAULT 
     74 
     75    if startIndex is not None and startIndex > 1 and startIndex <= tot_res: 
     76        int_startIndex = startIndex 
     77    else: 
     78        int_startIndex = START_INDEX_DEFAULT     
     79     
     80    if startPage is not None and math.ceil((tot_res - int_startIndex + 1)/float(int_count)) >= startPage: 
     81        int_startPage = startPage 
     82    else: 
     83        int_startPage = START_PAGE_DEFAULT 
     84             
     85    firstResult = int_startIndex - 1 
     86    lastResult = firstResult + int_count 
     87     
     88    if int_startPage > 1 and firstResult + (int_startPage - 1)*int_count <= tot_res: 
     89        firstResult = firstResult + (int_startPage - 1)*int_count 
     90         
     91    if firstResult + int_count <= tot_res:             
     92        lastResult = firstResult + int_count 
     93    else: 
     94        lastResult = tot_res 
     95 
     96    return _results[firstResult:lastResult] 
     97 
     98def generateAutodiscoveryPath(path, linkid, extension, startIndex = None, rel = REL_SELF): 
     99    """ 
     100        Assemble a path pointing to an opensearch engine  
     101        @param path: the host URL 
     102        @param linkid: the search id 
     103        @param extension: the extension 
     104        @param startIndex: the starting index 
     105        @param rel: a Link type identificator. If None returns a generic ID    
     106    """ 
     107    if rel == None: 
     108        if linkid: 
     109            return "%s/search/%s/" % (path, linkid) 
     110        else: 
     111            return "%s/search/" % (path) 
     112 
     113    if rel == REL_SEARCH: 
     114        if linkid: 
     115            return "%s%s/description" % (path, linkid)     
     116        else: 
     117            return "%sdescription" % (path) 
     118     
     119    if rel == REL_ALTERNATE: 
     120        if linkid: 
     121            return "%s%s/%s" % (path, linkid, extension) 
     122        else: 
     123            return "%s%s" % (path, extension) 
     124 
     125    if linkid: 
     126        return "%s%s/%s/?startIndex=%d" % (path, linkid, extension, startIndex) 
     127    else: 
     128        return "%s%s/?startIndex=%d" % (path, extension, startIndex) 
     129 
     130 
     131def createAutodiscoveryLink(root, path, extension = None, linkid = None, startIndex = 0, rel = REL_SELF): 
     132    """ 
     133        Appends an autodiscovery link to the given 'root' document  
     134        @param path: the host URL 
     135        @param extension: the extension 
     136        @param linkid: the search id         
     137        @param startIndex: the starting index 
     138        @param rel: a Link type identificator. If None returns a generic ID   
     139    """ 
     140    href = generateAutodiscoveryPath(path, linkid, extension, startIndex, rel)     
     141    itype = get_mimetype(extension) 
     142    if rel == ATOM_LINK_REL_SEARCH: 
     143        itype = get_mimetype('opensearchdescription')       
     144    return createLink(href, rel, itype, root)                     
  • mauRepo/CedaMarkup/trunk/ceda_markup/opensearch/os_engine.py

    r8452 r8463  
    3232''' 
    3333 
    34 import mimetypes 
    35 from query import QueryTag 
     34 
    3635from os_engine_helper import OSEngineHelper 
     36from ceda_markup.opensearch.query import createQuery 
     37from ceda_markup.opensearch.os_request import createOSDescription 
     38from xml.etree.ElementTree import tostring 
     39from xml.dom import minidom 
    3740 
    38 if not mimetypes.inited: 
    39     mimetypes.init() 
    40     if not mimetypes.types_map.has_key('.atom'): 
    41         mimetypes.add_type('application/atom+xml', '.atom') 
    42     if not mimetypes.types_map.has_key('.opensearchdescription'):         
    43         mimetypes.add_type('application/opensearchdescription+xml', '.opensearchdescription') 
    44  
    45 def get_mimetype(extension): 
    46     return mimetypes.types_map[('.%s') % (extension)]   
     41   
    4742 
    4843class OSEngine(object): 
     
    5146    ''' 
    5247 
    53     def __init__(self, osRequest, osEngineHelper = OSEngineHelper()): 
     48    def __init__(self, query, osEnResponses, osDescription, osEngineHelper = OSEngineHelper()): 
    5449        ''' 
    5550        Constructor 
    56             @param osRequest: an OSREquest instance  
     51            @param osQuery: an OSQuery instance  
     52            @param osResponses: a list of OSEngineResponse instances 
     53            @param osDescription: an OpenSearchDescription instance                         
    5754            @param ospath: the URL where the OpenSearch service is hosted 
    5855            @param osEngineHelper:  
    5956        ''' 
    60         self.osRequest = osRequest 
     57        self.osQuery = query 
     58        self.osEnResponses = osEnResponses 
     59        self.osDescription = osDescription         
    6160        self.osEngineHelper = osEngineHelper 
    6261        self.osHostURL = 'http://localhost'              
    6362         
    64     def doSearch(self, hostURL, mimetype, params_values, **kwargs): 
     63    def doSearch(self, hostURL, mimetype, context): 
     64        """ 
     65            Executes the Opensearch call. 
     66            @param hostURL: the opensearch engine URL 
     67            @param mimetype: the desired mimetype output 
     68            @param context: a dictionary containing all the necessary information to exploit the request 
     69            @return: a response in the required mimetype or None if the mimetype is not supported    
     70        """ 
    6571        self.osHostURL = hostURL 
    6672        response = None 
    67         for item in self.osRequest.responses: 
     73        for item in self.osEnResponses: 
    6874            if item.extension == mimetype: 
    6975                response = item 
    7076        if response is not None: 
    71             kwargs['params_values'] = params_values 
    72             queries = QueryTag.queryWithRoleRequest(mimetype, self.osRequest.query.params_model, params_values) 
    73             results = self.osRequest.query.doSearch(**kwargs) 
    74             return response.generateResponse(results, [queries], self.osHostURL, **kwargs) 
    75         return None                 
     77            queries = createQuery(mimetype, self.osQuery.params_model, context) 
     78            result = self.osQuery.doSearch(context) 
     79            packagedResults = response.digestSearchResults(result, context) 
     80            return response.generateResponse(packagedResults, [queries], self.osHostURL, context) 
     81        return None               
    7682     
    7783    def getDescription(self, ospath): 
    78         reqDoc = self.osRequest.getDescription(ospath) 
     84        reqDoc = createOSDescription(self.osEnResponses, self.osDescription, self.osQuery, ospath) 
    7985        self.osEngineHelper.additionalDescription(reqDoc) 
    80         return reqDoc 
     86        reparsed = minidom.parseString(tostring(reqDoc)) 
     87        return reparsed.toprettyxml(indent="  ") 
     88 
     89    def createQueryDictionary(self): 
     90        ''' 
     91            Returns a dictionary having as keys the query parameters. This method is  
     92            supposed to be used as utility to migrate the request parameters from the  
     93            http request to an internal neutral (not any django QueryDict) dictionary. 
     94            @return: a dictionary 
     95        '''         
     96        ret = {} 
     97        for param in self.osQuery.params_model: 
     98            ret[param.par_name] = None 
     99        return ret  
  • mauRepo/CedaMarkup/trunk/ceda_markup/opensearch/os_request.py

    r8452 r8463  
    3131@author: Maurizio Nagni 
    3232''' 
    33 from xml.etree.ElementTree import Element, SubElement, tostring 
    34 from xml.dom import minidom 
    35 from os_engine import get_mimetype 
    3633from osquery import URL_REL_DEFAULT, URL_INDEX_OFFSET_DEFAULT,\ 
    3734    URL_PAGE_OFFSET_DEFAULT 
     35from ceda_markup.markup import createMarkup, createSimpleMarkup 
     36from ceda_markup.opensearch import createTemplateQuery 
     37from ceda_markup import get_mimetype 
    3838 
    3939MAX_OS_SHORT_NAME_LEN = 16 
     
    5555OS_OUTPUT_ENCODING_DEFAULT = 'UTF-8'  
    5656 
    57 class OpenSearchRequest(object): 
     57OS_NAMESPACE = 'http://a9.com/-/spec/opensearch/1.1/' 
     58OS_PREFIX = 'os' 
     59OS_ROOT_TAG = 'OpenSearchDescription' 
     60 
     61def createURL(query, response_type, ospath, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     62    markup = createMarkup('Url', OS_PREFIX, ns, root)     
     63    markup.set("type", get_mimetype(response_type)) 
     64     
     65    template_query = createTemplateQuery(root, query) 
     66        
     67    query_template = ("%s%s?%s") % (ospath, response_type, template_query[:-1]) 
     68    markup.set("template", query_template) 
     69     
     70    if query.rel is not None and query.rel != URL_REL_DEFAULT: 
     71        markup.set("rel", query.rel) 
     72     
     73    if query.indexOffset  is not None and query.indexOffset != URL_INDEX_OFFSET_DEFAULT:             
     74        markup.set("indexOffset", str(query.indexOffset)) 
     75     
     76    if query.pageOffset  is not None and query.pageOffset != URL_PAGE_OFFSET_DEFAULT:                     
     77        markup.set("pageOffset", str(query.pageOffset))         
     78    return markup 
     79 
     80def createShortName(shortName, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     81    return createSimpleMarkup(shortName, root, 'ShortName', ns, OS_PREFIX) 
     82 
     83def createDescription(description, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     84    return createSimpleMarkup(description, root, 'Description', ns, OS_PREFIX) 
     85 
     86def createTags(tags, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     87    return createSimpleMarkup(tags, root, 'Tags', ns, OS_PREFIX)     
     88 
     89def createContact(contact, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     90    return createSimpleMarkup(contact, root, 'Contact', ns, OS_PREFIX) 
     91 
     92def createLongName(longName, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     93    return createSimpleMarkup(longName, root, 'LongName', ns, OS_PREFIX)     
     94 
     95def createDeveloper(developer, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     96    return createSimpleMarkup(developer, root, 'Developer', ns, OS_PREFIX) 
     97 
     98def createAttribution(attribution, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     99    return createSimpleMarkup(attribution, root, 'Attribution', ns, OS_PREFIX)     
     100 
     101def createSyndacationRight(syndacation_right, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     102    return createSimpleMarkup(syndacation_right, root, 'SyndacationRight', ns, OS_PREFIX) 
     103 
     104def createAdultContent(adult_content, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     105    return createSimpleMarkup(adult_content, root, 'AdultContent', ns, OS_PREFIX) 
     106 
     107def createLanguage(language, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     108    return createSimpleMarkup(language, root, 'Language', ns, OS_PREFIX)     
     109 
     110def createInputEncoding(inputEncoding, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     111    return createSimpleMarkup(inputEncoding, root, 'InputEncoding', ns, OS_PREFIX) 
     112 
     113def createOutputEncoding(outputEncoding, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     114    return createSimpleMarkup(outputEncoding, root, 'OutputEncoding', ns, OS_PREFIX) 
     115 
     116def createImage(url, height = None, width = None, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     117    markup = createSimpleMarkup(url, root, 'Image', ns, OS_PREFIX) 
     118    if height  is not None and isinstance(height, (int, long)): 
     119        markup.set("height", height)             
     120 
     121    if width  is not None and isinstance(width, (int, long)): 
     122        markup.set("width", width)  
     123    return markup 
     124     
     125 
     126def createOSDescription(osResponses, os_description, query, ospath, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
     127    """ 
     128        @param osResponses: a list of OSResponse instances 
     129        @param os_description: an OpenSearchDescription instance 
     130        @param query: an OSQuery instance         
     131    """ 
     132    markup = createMarkup(OS_ROOT_TAG, OS_PREFIX, ns, root) 
     133    markup.append(createShortName(os_description.os_short_name, root = markup)) 
     134    markup.append(createDescription(os_description.os_description, root = markup))     
     135 
     136    if hasattr(os_description, 'os_tags'): 
     137        markup.append(createTags(os_description.os_tags, root = markup))         
     138 
     139    if hasattr(os_description, 'os_contact'): 
     140        markup.append(createContact(os_description.os_contact, root = markup)) 
     141     
     142    if hasattr(os_description, 'os_long_name'): 
     143        markup.append(createLongName(os_description.os_long_name, root = markup))     
     144 
     145    if hasattr(os_description, 'os_developer'): 
     146        markup.append(createDeveloper(os_description.os_developer, root = markup))         
     147          
     148    if hasattr(os_description, 'os_attribution'): 
     149        markup.append(createAttribution(os_description.os_attribution, root = markup))          
     150     
     151    if hasattr(os_description, 'os_image') and isinstance(os_description.os_image, list): 
     152        for img in os_description.os_image: 
     153            markup.append(createImage(img.url, img.height, img.width, root = markup))            
     154     
     155    if hasattr(os_description, 'os_syndacation_right') and os_description.os_syndacation_right != OS_SYNDACATION_RIGHT_DEFAULT: 
     156        markup.append(createSyndacationRight(os_description.os_syndacation_right, root = markup))         
     157     
     158    if hasattr(os_description, 'os_adult_content'): 
     159        markup.append(createAdultContent(os_description.os_adult_content, root = markup))                
     160     
     161    if os_description.os_language and isinstance(os_description.os_language, list):         
     162        for item in os_description.os_language: 
     163            markup.append(createLanguage(item, root = markup)) 
     164 
     165     
     166    if os_description.os_input_encoding and isinstance(os_description.os_input_encoding, list): 
     167        for item in os_description.os_input_encoding: 
     168            markup.append(createInputEncoding(item, root = markup))      
     169     
     170    if os_description.os_output_encoding and isinstance(os_description.os_output_encoding, list): 
     171        for item in os_description.os_output_encoding: 
     172            markup.append(createOutputEncoding(item, root = markup)) 
     173     
     174    for item in osResponses:                     
     175        url = createURL(query, item.extension, ospath, root = markup) 
     176        markup.append(url) 
     177 
     178    return markup 
     179 
     180class OpenSearchDescription(object): 
    58181    ''' 
    59182    classdocs 
    60183    ''' 
    61184 
    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, \ 
     185    def __init__(self, os_short_name, os_description, \ 
    67186                 os_contact = None, os_tags = None, os_long_name = None, \ 
    68187                 os_image = [], os_developer = None, os_attribution = None, \ 
     
    70189                 os_language = ['*'], os_input_encoding = [OS_INPUT_ENCODING_DEFAULT], \ 
    71190                 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 
     191         
     192        """ 
     193         
     194            @param os_image: a list of osImage instances 
     195        """ 
     196         
     197         
    79198        self.os_syndacation_right = None 
    80199         
     
    118237        self.os_language = os_language 
    119238        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 = self.query.createTemplateQuery(root) 
    207             
    208         query_template = ("%s%s?%s") % (ospath, response_type, template_query[:-1]) 
    209         url.set("template", query_template) 
    210          
    211         if rel  is not None and rel != URL_REL_DEFAULT: 
    212             url.set("rel", rel) 
    213          
    214         if indexOffset  is not None and indexOffset != URL_INDEX_OFFSET_DEFAULT:             
    215             url.set("indexOffset", str(indexOffset)) 
    216          
    217         if pageOffset  is not None and pageOffset != URL_PAGE_OFFSET_DEFAULT:                     
    218             url.set("pageOffset", str(pageOffset))         
    219          
    220         root.append(url)  
     239        self.os_output_encoding = os_output_encoding           
  • mauRepo/CedaMarkup/trunk/ceda_markup/opensearch/os_response.py

    r8452 r8463  
    3131@author: Maurizio Nagni 
    3232''' 
    33 from xml.etree.ElementTree import SubElement, Element 
     33from ceda_markup.opensearch.os_request import OS_ROOT_TAG, OS_NAMESPACE,\ 
     34    OS_PREFIX 
     35from ceda_markup.markup import createSimpleMarkup 
    3436 
    3537MAX_OS_SHORT_NAME_LEN = 16 
     
    5153OS_OUTPUT_ENCODING_DEFAULT = 'UTF-8' 
    5254 
    53 class OpenSearchResponse(object): 
    54     ''' 
    55     classdocs 
    56     ''' 
     55def createTotalResults(totalResults, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE):     
     56    tr = totalResults 
     57    if isinstance(totalResults, int): 
     58        tr = str(totalResults) 
     59    return createSimpleMarkup(tr, root, 'totalResults', ns, OS_PREFIX) 
    5760 
    58     NAMESPACE = 'http://a9.com/-/spec/opensearch/1.1/' 
    59     PREFIX = 'os' 
    60     ROOT_TAG = 'OpenSearchDescription' 
     61def createStartIndex(startIndex, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE):     
     62    tr = startIndex 
     63    if isinstance(startIndex, int): 
     64        tr = str(startIndex) 
     65    return createSimpleMarkup(tr, root, 'startIndex', ns, OS_PREFIX) 
    6166 
    62     def __init__(self, root = None):                
    63         ''' 
    64             Constructor 
    65         ''' 
    66         self._hasns = False 
    67         self._root = root 
    68         if self._root is not None: 
    69             self._root.set("xmlns:%s" % (OpenSearchResponse.PREFIX), OpenSearchResponse.NAMESPACE) 
    70             self._hasns = True 
    71         else: 
    72             self._root = Element(OpenSearchResponse.ROOT_TAG) 
    73             self._root.set("xmlns", OpenSearchResponse.NAMESPACE)         
     67def createItemsPerPage(itemsPerPage, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE):     
     68    tr = itemsPerPage 
     69    if isinstance(itemsPerPage, int): 
     70        tr = str(itemsPerPage) 
     71    return createSimpleMarkup(tr, root, 'indexPerPage', ns, OS_PREFIX) 
    7472 
    75     @classmethod 
    76     def assignPrefix(self, tag, is_response = True): 
    77         if is_response: 
    78             return "%s:%s" % (OpenSearchResponse.PREFIX, tag) 
    79         else: 
    80             return tag 
    81          
    82     def createDocument(self, totalResults = None, startIndex = None, itemsPerPage = None, query = None):         
    83         if totalResults is not None: 
    84             os_totalResults =  SubElement(self._root, OpenSearchResponse.assignPrefix('totalResults')) 
    85             os_totalResults.text = totalResults 
    86          
    87         if startIndex is not None: 
    88             os_startIndex =  SubElement(self._root, OpenSearchResponse.assignPrefix('startIndex')) 
    89             os_startIndex.text = startIndex 
     73def createOpenSearchRespose(root, totalResults = None, startIndex = None, itemsPerPage = None, queries = None):                 
     74    if totalResults is not None: 
     75        markup = createTotalResults(totalResults, root) 
     76        root.append(markup)             
     77     
     78    if startIndex is not None: 
     79        markup = createStartIndex(startIndex, root) 
     80        root.append(markup)             
     81                     
     82    if itemsPerPage is not None: 
     83        markup = createItemsPerPage(itemsPerPage, root) 
     84        root.append(markup) 
    9085 
    91         if itemsPerPage is not None: 
    92             os_itemsPerPage =  SubElement(self._root, OpenSearchResponse.assignPrefix('itemsPerPage')) 
    93             os_itemsPerPage.text = itemsPerPage                
    94         ''' 
    95         Constructor 
    96         '''             
     86    for query in queries:                        
     87        root.append(query) 
  • mauRepo/CedaMarkup/trunk/ceda_markup/opensearch/osimage.py

    r8452 r8463  
    3131@author: Maurizio Nagni 
    3232''' 
    33 from xml.etree.ElementTree import Element 
    34  
    3533class OSImage(object): 
    3634    ''' 
     
    4846        self.width = width 
    4947        self.type = itype 
    50          
    51     def buildElement(self): 
    52         url = Element("Image") 
    53         if self.height  is not None and isinstance(self.height, (int, long)): 
    54             url.set("height", self.height)             
    55          
    56         if self.width  is not None and isinstance(self.width, (int, long)): 
    57             url.set("width", self.width)  
    58              
    59         url.text = self.url 
    60         return url 
  • mauRepo/CedaMarkup/trunk/ceda_markup/opensearch/osquery.py

    r8452 r8463  
    7272             
    7373    @abstractmethod 
    74     def doSearch(self, **kwargs): 
    75         pass 
    76         
    77     def createTemplateQuery(self, root): 
    78         ''' 
    79             Creates a string to be used as parameters template list in the "description". 
    80             As this description is used in a OpenSearch URL tag, the root parameter is required  
    81             in order to update the tag with the necessary namespaces 
    82             @param root: the OpenSearchRequest.ROOT_TAG tag. 
    83             @return: a string describing the parameters query 
    84         ''' 
    85         template_query = "" 
    86         for param in self.query.params_model: 
    87             term = self._assignPrefix(root, param) 
    88              
    89             urlParam = "" 
    90             if param.required:              
    91                 urlParam = ("%s={%s}") % (param.par_name, term) 
    92             else: 
    93                 urlParam = ("%s={%s?}") % (param.par_name, term) 
    94                 
    95             template_query += ("%s&") % (urlParam) 
    96         return template_query  
     74    def doSearch(self, context): 
     75        """ 
     76            Implements the search call. 
     77            @param context: a dictionary populated by the client containing all the necessary informations 
     78            @return: a list of results items  
     79        """ 
     80        pass  
  • mauRepo/CedaMarkup/trunk/ceda_markup/opensearch/query.py

    r8452 r8463  
    3131@author: Maurizio Nagni 
    3232''' 
    33 from xml.etree.ElementTree import Element 
    34 from ceda_markup.opensearch.os_response import OpenSearchResponse 
     33from ceda_markup.opensearch.os_request import OS_PREFIX, OS_ROOT_TAG,\ 
     34    OS_NAMESPACE 
     35from ceda_markup.markup import createMarkup 
    3536 
    36 class QueryTag(object): 
     37def createQuery(mimetype, params_model, params_values, is_response = True, root = None, tagName = OS_ROOT_TAG, ns = OS_NAMESPACE): 
    3738    ''' 
    38     classdocs 
     39        Returns an ElementTree.Element representing an OpenSearch.Query tag 
     40        @param mimetype: 
     41        @param params_model: a list of OSParam instances 
     42        @param params_values: a dictionary containing one value or None to pair with the params_model  
     43        @param root: the root tag of the document containing this element 
     44        @param tagName: the tagName  
     45        @param ns: the tag namespace 
     46        @return: a new ElementTree.Element instance      
    3947    ''' 
    40  
    41  
    42     def __init__(self): 
    43         ''' 
    44         Constructor 
    45         '''        
    46  
    47     @classmethod         
    48     def queryWithRoleRequest(self, mimetype, params_model, params_values, is_response = True): 
    49         os_query =  Element(OpenSearchResponse.assignPrefix('Query', is_response)) 
    50         os_query.set("role", "request")  
    51         for param in params_model: 
    52             if param.par_name in params_values and params_values[param.par_name] is not None: 
    53                 if param.term_name == 'searchTerms': 
    54                     os_query.set(param.term_name, ' '.join(str(x) for x in params_values[param.par_name])) 
    55                 else: 
    56                     os_query.set(param.par_name, params_values[param.par_name]) 
    57         return os_query         
     48    markup = createMarkup('Query', OS_PREFIX, ns, root) 
     49    markup.set("role", "request") 
     50    for param in params_model: 
     51        if param.par_name in params_values and params_values[param.par_name] is not None: 
     52            if param.term_name == 'searchTerms': 
     53                markup.set(param.term_name, ' '.join(str(x) for x in params_values[param.par_name])) 
     54            else: 
     55                markup.set(param.par_name, params_values[param.par_name]) 
     56    return markup        
  • mauRepo/CedaMarkup/trunk/ceda_markup/tests/atom.py

    r8418 r8463  
    3232''' 
    3333import unittest 
    34 from ceda_markup.atom.atom import createAtom, createID, createUpdated 
     34from ceda_markup.atom.atom import createAtom, createID, createUpdated,\ 
     35    createEntry, createAtomDocument 
    3536from xml.etree.ElementTree import tostring, Element 
    36 from ceda_markup.atom.entry import createEntry 
    3737from ceda_markup.atom.info import createTitle 
    3838 
     
    6767        update = createUpdated('2012-0619T21:02:00.626Z', root = atom) 
    6868        entry = createEntry(iid, title, update, root = atom) 
    69         atom.append(entry)  
    70         print tostring(atom)                
     69        atom.append(entry)                 
    7170        self.assertEqual(tostring(atom), '<feed xmlns="http://www.w3.org/2005/Atom">\ 
    7271<entry><id>1</id><title>testEntry</title><updated>2012-0619T21:02:00.626Z</updated></entry></feed>') 
     
    8281</atom:entry></myCustomTag>')         
    8382         
     83        root = createAtomDocument(1, 'atomTitle', '2012-0619T21:02:00.626Z') 
     84        iid = createID(2, root = root) 
     85        title = createTitle(root = root, body = 'testEntry') 
     86        update = createUpdated('2012-0619T21:02:00.626Z', root = root) 
     87        entry = createEntry(iid, title, update, root = root) 
     88        root.append(entry) 
     89        self.assertEqual(tostring(root), '<feed xmlns="http://www.w3.org/2005/Atom"><id>1</id>\ 
     90<title>atomTitle</title><updated>2012-0619T21:02:00.626Z</updated><entry><id>2</id>\ 
     91<title>testEntry</title><updated>2012-0619T21:02:00.626Z</updated></entry></feed>', 'Error') 
Note: See TracChangeset for help on using the changeset viewer.