Changeset 1293:28eed5438061

Show
Ignore:
Timestamp:
01/14/08 01:29:05 (3 years ago)
Author:
Ben Bangert <ben@…>
Branch:
trunk
Message:

* Added mimetype function and MIMETypes class for registering mimetypes.

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    r1286 r1293  
    33 
    440.9.7 (**tip**) 
     5* Added mimetype function and MIMETypes class for registering mimetypes. 
    56* WARNING: Removed pylons.Response, so do not attempt to import it or use it 
    67  as it's no longer there. If you must return a new Response object, import 
  • pylons/configuration.py

    r1264 r1293  
    1616import pylons.legacy 
    1717import pylons.templating 
     18from pylons.controllers.util import MIMETypes 
    1819 
    1920 
     
    287288        conf = self.current_conf() 
    288289         
     290        # Load the MIMETypes with its default types 
     291        MIMETypes.load_defaults() 
     292         
    289293        # Ensure all the keys from defaults are present, load them if not 
    290294        for key, val in copy.deepcopy(PylonsConfig.defaults).iteritems(): 
  • pylons/controllers/util.py

    r1292 r1293  
    44""" 
    55import logging 
     6import mimetypes 
    67import warnings 
    78 
     
    1314 
    1415import pylons 
    15 import pylons.legacy 
    1616 
    1717__all__ = ['abort', 'etag_cache', 'redirect_to', 'Request', 'Response'] 
     
    6969        return self.status, self.headers, self.body 
    7070 
    71      
     71 
     72class MIMETypes(object): 
     73    """MIMETypes registration mapping 
     74     
     75    The MIMETypes object class provides a single point to hold onto all 
     76    the registered mimetypes, and their association extensions. It's 
     77    used by the mimetypes function to determine the appropriat content 
     78    type to return to a client. 
     79     
     80    """ 
     81    extension_mapping = {} 
     82    type_mapping = {} 
     83     
     84    def load_defaults(cls): 
     85        """Loads a default mapping of extensions and mimetypes 
     86         
     87        These are suitable for most web applications by default.  
     88        Additional types can be added with the MIMETypes.register  
     89        method. 
     90         
     91        """ 
     92        extension_mapping = {} 
     93        type_mapping = {} 
     94        mimetypes.init() 
     95        for ext, mimetype in mimetypes.types_map.iteritems(): 
     96            type_mapping[mimetype] = ext[1:] 
     97            extension_mapping[ext[1:]] = mimetype 
     98        cls.extension_mapping.update(extension_mapping) 
     99        cls.type_mapping.update(type_mapping) 
     100         
     101        # Add some common defaults and aliases 
     102        MIMETypes.register('*/*', 'all') 
     103        MIMETypes.register('text/plain', 'text', ext_aliases=('txt',)) 
     104        MIMETypes.register('text/html', 'html',  
     105                           type_aliases=('application/xhtml+xml',),  
     106                           ext_aliases=('xhtml',)) 
     107        MIMETypes.register('text/javascript', 'js', 
     108                           type_aliases=('application/javascript',  
     109                                         'application/x-javascript')) 
     110        MIMETypes.register('text/css', 'css') 
     111        MIMETypes.register('text/calendar', 'ics') 
     112        MIMETypes.register('text/csv', 'csv') 
     113        MIMETypes.register('application/xml', 'xml', 
     114                           type_aliases=('text/xml', 'application/x-xml')) 
     115        MIMETypes.register('application/rss+xml', 'rss') 
     116        MIMETypes.register('application/atom+xml', 'atom') 
     117        MIMETypes.register('application/x-yaml', 'yaml', 
     118                           type_aliases=('text/yaml',)) 
     119        MIMETypes.register('multipart/form-data', 'multipart_form') 
     120        MIMETypes.register('application/x-www-form-urlencoded', 'url_encoded_form') 
     121        MIMETypes.register('application/json', 'json',  
     122                           type_aliases=('text/x-json',)) 
     123    load_defaults = classmethod(load_defaults) 
     124     
     125    def register(cls, mimetype, extension, type_aliases=None, ext_aliases=None): 
     126        """Register additional MIMETypes 
     127         
     128        Additional mimetypes that a user wants to recognize and handle 
     129        should be registered using this method. Extension aliases that 
     130        should be treated as equivilant to the desired extension, along 
     131        with alias mimetypes can also be registered. 
     132         
     133        Example: 
     134            # Register text/plain as the text extension, or txt 
     135            MIMETypes.register('text/plain', 'text', ext_aliases=('txt',)) 
     136         
     137        """ 
     138        cls.type_mapping[mimetype] = extension 
     139        if type_aliases: 
     140            for alias in type_aliases: 
     141                cls.type_mapping[alias] = extension 
     142         
     143        cls.extension_mapping[extension] = mimetype 
     144        if ext_aliases: 
     145            for alias in ext_aliases: 
     146                cls.extension_mapping[alias] = mimetype 
     147    register = classmethod(register) 
     148 
     149 
     150def mimetype(extension): 
     151    """Check the Routes match and client HTTP Accept to attempt to use 
     152    the appropriate mime-type 
     153     
     154    This works best with Routes ``map.resource`` which sets up routes 
     155    that can accept matches with a specific extension. 
     156     
     157    Example: 
     158        def somaction(self): 
     159            # prepare a bunch of data 
     160            # ...... 
     161             
     162            if mimetype('html'): 
     163                return render('/some/template.html') 
     164            elif mimetype('atom'): 
     165                return render('/some/xml_template.xml') 
     166            elif mimetype('csv'): 
     167                # write the data to a csv file 
     168                return csvfile 
     169            else: 
     170                abort(404) 
     171     
     172    """ 
     173    request = pylons.request._current_obj() 
     174    # Pull out the possible return content-type 
     175    return_type = MIMETypes.extension_mapping.get(extension) 
     176    if not return_type: 
     177        raise Exception("Can't check for extensions that haven't been " 
     178                        "registered") 
     179     
     180    # Check for a format in Route args first 
     181    route_format = request.environ['pylons.routes_dict'].get('format') 
     182    if route_format: 
     183        mime_type = MIMETypes.extension_mapping[route_format] 
     184        resolved_extension = MIMETypes.type_mapping[mime_type] 
     185        if resolved_extension == extension: 
     186            pylons.response.headers['Content-Type'] = mime_type 
     187            return True 
     188     
     189    # Check to see if this matches in the Request accept 
     190    if return_type in request.accept_language: 
     191        pylons.response.headers['Content-Type'] = return_type 
     192        return True 
     193     
     194    # Didn't match the route format or the Request accept, don't match 
     195    return False 
     196 
     197 
    72198def etag_cache(key=None): 
    73199    """Use the HTTP Entity Tag cache for Browser side caching 


Powered by Pylons - Contact Administrators