__init__.py 3.94 KB
import sys
import traceback
from datetime import (
    datetime,
    date,
    time,
    )
from ..waktu import (
    dmy,
    dmyhms,
    )
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO


def clean(s):
    r = ''
    for ch in s:
        ascii = ord(ch)
        if ascii > 126 or ascii < 32:
            ch = ' '
        r += ch
    return r


def to_str(v):
    if isinstance(v, date):
        if isinstance(v, datetime):
            return dmyhms(v)
        return dmy(v)
    if v == 0:
        return '0'
    if isinstance(v, bytes):
        return v.encode('utf-8')
    if sys.version_info.major == 2 and isinstance(v, unicode):
        v = str(v)
    if isinstance(v, str):
        return v.strip()
    elif isinstance(v, bool):
        return v and '1' or '0'
    return v and str(v) or ''


def dict_to_str(d):
    r = {}
    for key in d:
        val = d[key]
        r[key] = to_str(val)
    return r


def left(s, width):
    s = to_str(s)
    return s.ljust(width)[:width]


def right(s, width):
    s = to_str(s)
    return s.zfill(width)[:width]


class FixLength:
    def __init__(self, struct):
        self.set_struct(struct)

    def set_struct(self, struct):
        self.struct = []
        self.fields = {}
        for s in struct:
            name = s[0]
            size = s[1:] and s[1] or 1
            typ = s[2:] and s[2] or 'A'  # N: numeric, A: alphanumeric
            self.fields[name] = {'value': None, 'type': typ, 'size': size}
            self.struct.append((name, size, typ))

    def set(self, name, value):
        self.fields[name]['value'] = value

    def get(self, name):
        return self.fields[name]['value'] or ''

    def __setitem__(self, name, value):
        self.set(name, value)

    def __getitem__(self, name):
        return self.get(name)

    def get_raw(self):
        s = ''
        for name, size, typ in self.struct:
            v = self.fields[name]['value']
            pad_func = typ == 'N' and right or left
            if v and typ == 'N':
                i = int(v)
                if v == i:
                    v = i
            s += pad_func(v, size)
        return s

    def set_raw(self, raw):
        awal = 0
        for t in self.struct:
            name = t[0]
            size = t[1:] and t[1] or 1
            akhir = awal + size
            value = raw[awal:akhir]
            if not value:
                return
            self.set(name, value)
            awal += size
        return True

    def from_dict(self, d):
        for name in d:
            value = d[name]
            self.set(name, value)


class DateVar(FixLength):
    def __init__(self):
        FixLength.__init__(self, [
            ['month', 2, 'N'],
            ['day', 2, 'N'],
            ])

    def get_value(self, year=None):
        year = year or date.today().year
        return date(year, self.get('month'), self.get('day'))


class DateTimeVar(FixLength):
    def __init__(self):
        FixLength.__init__(self, [
            ['month', 2, 'N'],
            ['day', 2, 'N'],
            ['hour', 2, 'N'],
            ['minute', 2, 'N'],
            ['second', 2, 'N'],
            ])

    def get_value(self, year=None):
        year = year or date.today().year
        return datetime(year, self.get('month'), self.get('day'),
                        self.get('hour'), self.get('minute'),
                        self.get('second'))


class TimeVar(FixLength):
    def __init__(self):
        FixLength.__init__(self, [
            ['hour', 2, 'N'],
            ['minute', 2, 'N'],
            ['second', 2, 'N'],
            ])

    def get_value(self):
        return time(self.get('hour'), self.get('minute'), self.get('second'))


def exception_message():
    f = StringIO()
    traceback.print_exc(file=f)
    s = f.getvalue()
    f.close()
    return s