########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Server/Common/Util.py,v 1.17 2005/03/28 10:59:01 mbrown Exp $
"""
Common (client and server) utilities for repo code

Copyright 2004 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""

from Ft.Lib.Uri import PercentEncode
from Ft.Server import FTSS_URI_SCHEME, RESERVED_NAMESPACE

try:
    import os
    if os.name == 'posix':
        imt_file_paths = ['/etc/mime.types',
                          '/usr/local/etc/mime.types',
                          '/usr/local/apache/conf/mime.types',
                          '/etc/httpd/conf/mime.types',
                         ]
    elif os.name == 'nt':
        #FIXME: use registry, pending outcome of
        # http://sourceforge.net/tracker/index.php?func=detail&aid=977553&group_id=5470&atid=305470
        ds = os.environ.get('SystemDrive', 'C:')
        imt_file_paths = [r'%s\Program Files\Apache Group\Apache2\conf\mime.types' % ds,
                          r'%s\Program Files\Apache Group\Apache\conf\mime.types' % ds,
                         ]
        del ds
    else:
        imt_file_paths = []
    found_imts = 0
    for imt_file_path in imt_file_paths:
        if os.access(imt_file_path, os.R_OK):
            found_imts = 1
            break
    if not found_imts:
        raise
    IMT_MAP = {}
    imt_file = open(imt_file_path, 'r')
    #print "IMTs read from %s" % imt_file_path
    for line in imt_file.readlines():
        if line[0] == '#':
            continue
        splitl = line.split()
        if len(splitl) < 2:
            continue
        imt = splitl[0]
        for ext in splitl[1:]:
            IMT_MAP[ext] = imt
    del found_imts, os, imt_file_paths
    del imt_file_path, imt_file, line, splitl, imt, ext
except:
    IMT_MAP = {
        '.xml' : 'text/xml',
        '.xsl' : 'text/xml',
        '.xslt': 'text/xml',
        '.rdf' : 'text/xml',

        '.htm' : 'text/html',
        '.html': 'text/html',
        '.xhtml': 'text/html',

        '.gif' : 'image/gif',
        '.png' : 'image/png',
        '.jpg' : 'image/jpeg',
        '.jpeg': 'image/jpeg',
        '.svg' : 'image/svg',
#        '': '',
        }

#Get user's namespace mappings
from Ft.Xml import Domlette
from Ft.Xml import XPath

DASHBOARD_NS = "http://chimezie.ogbuji.net/4ss/tools/dashboard/schema#"

NSM_NSM = {'fres': RESERVED_NAMESPACE}

PREFIXES = XPath.Compile("/fres:NsMappings/fres:NsMapping/Prefix/text()")
URIS = XPath.Compile("/fres:NsMappings/fres:NsMapping/Uri/text()")

def GetUserNsMappings(repo, baseMappings=None):
    ns_map = baseMappings and baseMappings.copy() or {}
    model = repo.getModel()
    username = repo.getCurrentUser()
    if not username: return {}
    user = username.getAbsolutePathAsUri()
    stmts = model.complete(user, DASHBOARD_NS+"ns-mappings", None)
    if stmts:
        nsm_res = repo.fetchResource(stmts[0].object)
        content = nsm_res.getContent()
        nsm_doc = Domlette.NonvalidatingReader.parseString(
            content, stmts[0].object
            )
        con = XPath.Context.Context(nsm_doc, processorNss=NSM_NSM)
        prefixes = PREFIXES.evaluate(con)
        uris = URIS.evaluate(con)
        #FIXME: Dangerous under arcane conditions where processor
        #Divides elements into multiple text children
        #FIXME: Also relies on ordering of node sets
        for i in xrange(len(prefixes)):
            ns_map[prefixes[i].data] = uris[i].data
    return ns_map


def RepoPathToUri(path):
    """
    Converts an absolute repo path, given as a string or instance of
    Ft.Server.Server.Drivers.PathImp.Path, to a URI of the %s
    scheme. If the path is not a Unicode string, it is assumed to be
    UTF-8 encoded.
    """ % FTSS_URI_SCHEME
    if isinstance(path, str):
        path = unicode(path, 'utf-8')
    elif not isinstance(path, unicode):
        try:
            from Ft.Server.Server.Drivers import PathImp
            if isinstance(path, PathImp.Path):
                path = path.absolutePath
                if isinstance(path, str):
                    path = unicode(path, 'utf-8')
        except ImportError:
            #FIXME: Should be an error
            import sys; print >> sys.stderr, "Unable to import PathImp from Ft.Server.Server.Drivers"
            pass
    if not path or not path.startswith('/'):
        from Ft.Server.Server import FtServerServerException, Error
        raise FtServerServerException(
            Error.RELATIVE_PATH_FOR_FTSS_URI,
            path=path, ftssScheme=FTSS_URI_SCHEME)

    # when repo path strings use ';foo' parameters, we have to avoid
    # percent-encoding the ';' characters.
    path = '/'.join(map(lambda s: PercentEncode(s, encodeReserved=False, reservedChars=";="), path.split('/')))
    return '%s://%s' % (FTSS_URI_SCHEME, path)


def RepoUriToPath(uri):
    """
    Converts a URI of the %s scheme to an absolute repo path string.
    This function is less flexible than RepoPathToUri.  Suggested use
    if you have a path or URI you're unsure of is to first convert it
    to a sure repo URI using RepoPathToUri and then, if need be, get
    the equivalent path using this function.  e.g.:

    uri = RepoPathToUri(unknown)
    path = RepoUriToPath(uri)

    At which point you're sure uri is a repo URI and that path is
    a repo path
    """ % FTSS_URI_SCHEME
    if not uri.startswith(FTSS_URI_SCHEME + '//'):
        raise TypeError("Invalid argument for RepoUriToPath: %s"(str(uri)))
    return uri[len(FTSS_URI_SCHEME)+2:]

