### Navigation

- index
- modules |
- Camelot documentation »
- Module code »

# Source code for camelot.view.utils

    #  ============================================================================
    #
    #  Copyright (C) 2007-2011 Conceptive Engineering bvba. All rights reserved.
    #  www.conceptive.be / project-camelot@conceptive.be
    #
    #  This file is part of the Camelot Library.
    #
    #  This file may be used under the terms of the GNU General Public
    #  License version 2.0 as published by the Free Software Foundation
    #  and appearing in the file license.txt included in the packaging of
    #  this file.  Please review this information to ensure GNU
    #  General Public Licensing requirements will be met.
    #
    #  If you are unsure which license is appropriate for your use, please
    #  visit www.python-camelot.com or contact project-camelot@conceptive.be
    #
    #  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    #  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    #
    #  For use of this library in commercial applications, please contact
    #  project-camelot@conceptive.be
    #
    #  ============================================================================
    """Helper functions for the view subpackage"""
    from HTMLParser import HTMLParser

    from PyQt4 import QtCore

    from datetime import datetime, time, date
    import re
    import logging
    import operator

    from camelot.core.sql import like_op
    from sqlalchemy.sql.operators import between_op
    from camelot.core.utils import ugettext
    from camelot.core.utils import ugettext_lazy as _

    logger = logging.getLogger('camelot.view.utils')

    #
    # Cached date and time formats, for internal use only
    #
    _local_date_format = None
    _local_datetime_format = None
    _local_time_format = None

    def local_date_format():
        """Get the local data format and cache it for reuse"""
        global _local_date_format
        if not _local_date_format:
            locale = QtCore.QLocale()
            format_sequence = re.split('y*', unicode(locale.dateFormat(locale.ShortFormat)))
            # make sure a year always has 4 numbers
            format_sequence.insert(-1, 'yyyy')
            _local_date_format = unicode(u''.join(format_sequence))
        return _local_date_format

    def local_datetime_format():
        """Get the local datatime format and cache it for reuse"""
        global _local_datetime_format
        if not _local_datetime_format:
            locale = QtCore.QLocale()
            format_sequence = re.split('y*', unicode(locale.dateTimeFormat(locale.ShortFormat)))
            # make sure a year always has 4 numbers
            format_sequence.insert(-1, 'yyyy')
            _local_datetime_format = unicode(u''.join(format_sequence))
        return _local_datetime_format

    def local_time_format():
        """Get the local time format and cache it for reuse"""
        global _local_time_format
        if not _local_time_format:
            locale = QtCore.QLocale()
            _local_time_format = unicode(locale.timeFormat(locale.ShortFormat) )
        return _local_time_format

    def default_language(*args):
        """takes arguments, to be able to use this function as a
        default field attribute"""
        locale = QtCore.QLocale()
        return unicode(locale.name())

    class ParsingError(Exception): pass

    def string_from_string(s):
        if not s:
            return None
        return unicode(s)

    def bool_from_string(s):
        if s is None: raise ParsingError()
        if s.lower() not in ['false', 'true']: raise ParsingError()
        return eval(s.lower().capitalize())

    def _insert_string(original, new, pos):
        '''Inserts new inside original at pos.'''
        return original[:pos] + new + original[pos:]

    def date_from_string(s):
        s = s.strip()
        if not s:
            return None
        from PyQt4.QtCore import QDate
        import string
        f = local_date_format()
        dt = QDate.fromString(s, f)
        if not dt.isValid():
            #
            # if there is a mismatch of 1 in length between format and
            # string, prepend a 0, to handle the case of 1/11/2011
            #
            if len(f) == len(s) + 1:
                s = '0' + s
                dt = QDate.fromString(s, f)
        if not dt.isValid():
            #
    	# try alternative separators
            #
            separators = u''.join([c for c in f if c not in string.ascii_letters])
            if separators:
                alternative_string = u''.join([(c if c in string.digits else separators[0]) for c in s])
                dt = QDate.fromString(alternative_string, f)
        if not dt.isValid():
            # try parsing without separators
            # attention : using non ascii letters will fail on windows
            # string.letters then contains non ascii letters of which we don't know the
            # encoding, so we cannot convert them to unicode to compare them
            only_letters_format = u''.join([c for c in f if c in string.ascii_letters])
            only_letters_string = u''.join([c for c in s if c in (string.ascii_letters+string.digits)])
            dt = QDate.fromString(only_letters_string, only_letters_format)
            if not dt.isValid():
                # try parsing without the year, and take the current year by default
                only_letters_format = u''.join([c for c in only_letters_format if c not in ['y']])
                dt = QDate.fromString(only_letters_string, only_letters_format)
                if not dt.isValid():
                    raise ParsingError()
    #                # try parsing without year and month, and take the current year and month by default
    #                only_letters_format = u''.join([c for c in only_letters_format if c not in ['M']])
    #                dt = QDate.fromString(only_letters_string, only_letters_format)
    #                if not dt.isValid():
    #                    raise ParsingError()
    #                else:
    #                    today = date.today()
    #                    return date(today.year, today.month, dt.day())
                else:
                    return date(date.today().year, dt.month(), dt.day())
        return date(dt.year(), dt.month(), dt.day())

    def time_from_string(s):
        s = s.strip()
        if not s:
            return None
        from PyQt4.QtCore import QTime
        f = local_time_format()
        tm = QTime.fromString(s, f)
        if not tm.isValid():
            raise ParsingError()
        return time( tm.hour(), tm.minute(), tm.second() )

    def datetime_from_string(s):
        s = s.strip()
        if not s:
            return None
        from PyQt4.QtCore import QDateTime
        f = local_datetime_format()
        dt = QDateTime.fromString(s, f)
        if not dt.isValid():
            raise ParsingError()
        return datetime(dt.date().year(), dt.date().month(), dt.date().day(),
                        dt.time().hour(), dt.time().minute(), dt.time().second())

    def code_from_string(s, separator):
        return s.split(separator)

    def int_from_string(s):
        if s is None: raise ParsingError()
        if s.isspace(): return int()

        s = s.strip()
        if len(s) == 0: return int()

        try:
            i = int(s)
        except ValueError:
            raise ParsingError()
        return i

    def float_from_string(s):
        if not s:
            return None
        locale = QtCore.QLocale()
        f, ok = locale.toFloat(s)
        if not ok:
            raise ParsingError()
        return f

    def pyvalue_from_string(pytype, s):
        if pytype is str:
            return str(s)
        elif pytype is unicode:
            return unicode(s)
        elif pytype is bool:
            return bool_from_string(s)
        elif pytype is date:
            return date_from_string(s)
        elif pytype is time:
            return date_from_string(s)
        elif pytype is datetime:
            return datetime_from_string(s)
        elif pytype is float:
            return float_from_string(s)
        elif pytype is int:
            return int_from_string(s)

    def enumeration_to_string(value):
        return ugettext(unicode(value or u'').replace('_', ' ').capitalize())

    operator_names = {
        operator.eq : _( u'=' ),
        operator.ne : _( u'!=' ),
        operator.lt : _( u'<' ),
        operator.le : _( u'<=' ),
        operator.gt : _( u'>' ),
        operator.ge : _( u'>=' ),
        like_op : _( u'like' ),
        between_op: _( u'between' ),
    }

    def text_from_richtext(unstripped_text):
        """funciton that returns a list of lines with escaped data, to be used in templates for example
        :arg unstripped_text: string
        :return: list of strings
        """
        strings = ['']
        if not unstripped_text:
    	    return strings

        class HtmlToTextParser(HTMLParser):
            def handle_endtag(self, tag):
                if tag == 'br':
                    strings.append('')

            def handle_data(self, data):
                from xml.sax.saxutils import escape
                data = data.strip()
                if data:
                    strings.append(escape(data))

        parser = HtmlToTextParser()
        parser.feed(unstripped_text.strip())

        return strings

### Navigation

- index
- modules |
- Camelot documentation »
- Module code »

Comments
blog comments powered by Disqus