""" utils.py

Module for utility methods.
"""
__copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
__license__ = """GNU General Public License

This program is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA. """

import re, string, htmlentitydefs
from htmlentitydefs import codepoint2name
import urllib, urlparse, locale
import time, calendar
import os
import os.path
import subprocess
import sys
import error
import constants
import gtk

entity = re.compile(r'\&.\w*?\;')


def convert_entities(text):
    def conv(ents):
        entities = htmlentitydefs.entitydefs
        ents = ents.group(0)
        ent_code = entities.get(ents[1:-1], None)
        if ent_code is not None:
            try:
                ents = unicode(ent_code, get_locale_encoding())
            except UnicodeDecodeError:
                ents = unicode(ent_code, 'latin-1')
            except Exception, ex:
                error.log("error occurred while converting entity %s: %s" % (ents, ex))

            # check if it still needs conversion
            if entity.search(ents) is None:
                return ents

        if ents[1] == '#':
            code = ents[2:-1]
            base = 10
            if code[0] == 'x':
                code = code[1:]
                base = 16
            return unichr(int(code, base))
        else:
            return

    in_entity = entity.search(text)
    if in_entity is None:
        return text
    else:
        ctext = in_entity.re.sub(conv, text)
        return ctext

def complete_url(url, feed_location):
    url = urllib.quote(url, safe=string.punctuation)
    if urlparse.urlparse(url)[0] == '':
        return urlparse.urljoin(feed_location, url)
    else:
        return url

def get_url_location(url):
    url = urllib.quote(url, safe=string.punctuation)
    parsed_url = urlparse.urlsplit(url)
    return urlparse.urlunsplit((parsed_url[0], parsed_url[1], '','',''))

def get_locale_encoding():
    try:
        encoding = locale.getpreferredencoding()
    except locale.Error:
        encoding = sys.getdefaultencoding()
    return encoding

def format_date(date, format=None, encoding=None):
    if format is None:
        format = get_date_format()
    if encoding is None:
        encoding = get_locale_encoding()
    timestr = time.strftime(format, time.localtime(calendar.timegm(date)))
    return unicode(timestr, encoding)

def get_date_format():
    # this is here just to make xgettext happy: it should be defined in
    # only one place, and a good one would be MainWindow.py module level.
    # however, we can't access _ there.
    # The format: %A is the full weekday name
    #             %B is the full month name
    #             %e is the day of the month as a decimal number,
    #                without leading zero
    # This should be translated to be suitable for the locale in
    # question, feel free to alter the order and the parameters (they
    # are strftime(3) parameters, the whole string is passed to the
    # function, Straw does no additional interpretation) if you feel
    # it's necessary in the translation file.
    return _('%A %B %e %H:%M')

def find_data_dir():
    datad = ''
    if os.environ.has_key("STRAW_DATA"):
        datad = os.environ["STRAW_DATA"]
    else:
        datad = constants.datadir
        if not os.path.isdir(datad):
            raise "FileNotFoundError", "couldn't find Straw data directory"
    return datad

def find_locale_dir():
    localed = ''
    if os.environ.has_key("STRAW_LOCALE"):
        localed = os.environ["STRAW_LOCALE"]
    else:
        localed = constants.localedir
        if not os.path.isdir(localed):
            raise "FileNotFoundError", "couldn't find locale data directory"
    return localed

def find_glade_file(libdir=None):
    gladef = ''
    if os.environ.has_key("STRAW_GLADE"):
        gladef = os.environ["STRAW_GLADE"]
    else:
        gladef = os.path.normpath(os.path.join(constants.gladedir, "straw.glade"))
        if not os.path.isfile(gladef):
            raise "FileNotFoundError", "couldn't find straw.glade"
    return gladef

def find_image_dir():
    if not os.path.isdir(constants.imagedir):
        raise "FileNotFoundError", "could not find image (pixmaps) directory"
    return constants.imagedir

def listdiff(l1, l2, test=None):
    if test is not None:
        return _listdifftest(l1, l2, test)
    common = []
    inl1 = []
    inl2 = []
    for e in l1:
        if e in l2:
            common.append(e)
        else:
            inl1.append(e)
    for e in l2:
        if e in l1:
            if e not in common:
                common.append(e)
        else:
            inl2.append(e)
    return (common, inl1, inl2)

import string
import gnomevfs
import Config
import dialogs

def url_show(url):
    config = Config.get_instance()
    if config.browser_cmd:
        try:
            cmdbin, args = string.splitfields(str(config.browser_cmd), maxsplit=1)
            link = args % url
            pid = subprocess.Popen([cmdbin, link]).pid
            return pid
        except ValueError, ve:
            dialogs.report_error(_("An error occurred while trying to open link"),
                                 _("There was a problem opening '%s'\n\nError thrown is '%s'") % (url,str(ve)))
    else:
        return gnomevfs.url_show(url)


def set_clipboard_text(text):
    clipboard = gtk.clipboard_get(selection="CLIPBOARD")
    clipboard.set_text(text)

def html_replace(exc):
    """ Python Cookbook 2ed, Section 1.23
    """
    if isinstance(exc, (UnicodeDecodeError, UnicodeTranslateError)):
        s = [ u'&%s;' % codepoint2name[ord(c)] for c in exc.object[exc.start:exc.end]]
        return ''.join(s), exc.end
    else:
        raise TypeError("can't handle %s" % exc.__name__)

import codecs
codecs.register_error('html_replace', html_replace)


syntax highlighted by Code2HTML, v. 0.9.1