"""
$RCSfile: ProductProperties.py,v $

This module includes all of those properties that really belong to the
ExternalFile Product as a whole, rather than to any particular
_instance_ of ExternalFile.

These properties are loaded in from ASCII configuration files at
Zope startup time.  See the comments in the top of 'mime.types'
and 'display.types' for more information.

Author: <a href="mailto:cstrong@arielpartners.com">Craeg Strong</a>
Release: 1.2

"""

__cvstag__  = '$Name:  $'[6:-2]
__date__    = '$Date: 2003/04/21 00:56:27 $'[6:-2]
__version__ = '$Revision: 1.3 $'[10:-2]

# Python builtins
import mimetypes, os.path, sys

display_type_map = {}

def initMimeTypeList(filepath):
    """

    Initialize the mimetype list with addl mimetypes
    from the file 'mime.types'

    """
    # print "Loading custom mimetypes from:", os.path.abspath(filepath)
    
    typemap = mimetypes.read_mime_types(filepath)
    if not typemap:
        print "Empty or non-existent mime.types file"
    if typemap:
        mimetypes.types_map.update(typemap)

def initDisplayTypeList(filepath):
    """

    Initialize the custom DisplayType list from the file
    'display.types' Using an algorithm adapted from Python builtin
    mimetypes.py

    """
    # print "Loading displaytypes from:", os.path.abspath(filepath)

    try:
        f = open(filepath)
    except IOError:
        print "Error reading display.types file"
        return
    map = {}
    while 1:
        line = f.readline()
        if not line: break
        words = line.split()
        for i in range(len(words)):
            if words[i][0] == '#':
                del words[i:]
                break
        if not words: continue
        if len(words) > 2:
            print "Extra characters in display.types ignored",words[2:]
        mimetype, displaytype = words[0], words[1]
        display_type_map[mimetype] = displaytype
    f.close()

def getDefaultMimeType():
    """
    The mimetype to assign by default if we can't figure it
    out by looking at the suffix (or if there is no suffix)
    """
    return 'application/octet-stream'

def getMimeTypeList():
    "Return list of available mime types."
    
    typelist = mimetypes.types_map.values()

    # return sorted, unique-ified list.
    # Code stolen from python FAQ answer 4.64
    typelist.sort()
    last = typelist[-1]
    for i in range(len(typelist)-2, -1, -1):
        if last==typelist[i]: del typelist[i]
        else: last=typelist[i]
    return typelist

def getMimeTypeFromFile(filepath):
    """

    Given a file, return the appropriate mime type.  If the mime type
    cannot be guessed from the suffix (or there is no suffix), return
    the default mimetype.  If the file is None, automatically return
    the default mimetype.

    """
    (mimetype, encoding) = ('','')
    if filepath:
        mimetype, encoding = mimetypes.guess_type(filepath)
    if not mimetype:
        mimetype = getDefaultMimeType()
    return mimetype

def getDisplayTypeFromMimeType(mimetype):
    """

    Derive the DisplayType of file from its mimetype.  DisplayType is
    an invented concept that is used _solely_ to decide how to edit
    and view ExternalFiles in the ZMI.  There are three types:

    'ascii'  Editable TTW, viewed in a readonly textarea
    'image'  Not editable TTW, viewed via image tag eg <img src="foo.jpg"/>
    'binary' Not editable TTW, viewed via hyperlink eg <a href="foo.doc"/>

    Generally, the DisplayType is derived by parsing the type from the
    mimetype.  That is,

    'image/jpeg'     -> 'image'
    'text/plain'     -> 'ascii'
    'application/zip -> 'binary'

    In certain circumstances, this is not appropriate.  For example,
    'application/xml' should be 'ascii' rather than 'binary.'
    
    """

    displaytype = display_type_map.get(mimetype, None)
    if not displaytype:
        type, subtype  = mimetype.split('/', 2)
        if type == 'image':
            displaytype = 'image'
        elif type == 'text':
            displaytype = 'ascii'
        else:
            displaytype = 'binary'
    return displaytype

# EOF ProductProperties.py
