Example #1
0
class _E164_Polisher_ (MOM.Attr.Polisher._Polisher_) :

    buddies        = ("cc", "ndc", "sn")

    _cleanup_value = Multi_Re_Replacer \
        ( Re_Replacer (r"[ \t]+", " ") ### compress space, tab
        , Re_Replacer (r" +",     " ") ### compress no-break space to space
        , Re_Replacer (r" +",     "" ) ### remove narrow no-break space
        )

    def _attr_value (self, attr, name, value, value_dict, essence) :
        result = self.__super._attr_value \
            (attr, name, value, value_dict, essence)
        if result is None and name != attr.name :
            result = getattr (essence, name, None)
        if result :
            result = self._cleanup_value (result)
        return result
Example #2
0
class VAT_IDN(TFL.Meta.Object):
    """Value added tax identification number"""

    Countries = _Country_Rule_.Table
    _cleaned = Re_Replacer("[- .,]", "")
    _value = None

    def __init__(self, vin):
        value       = vin.value \
            if isinstance (vin, VAT_IDN) else self._cleaned (vin.upper ())
        self.cc = value[:2]
        self.idn = value[2:]
        self._value = value
        rule = self.rule
        if rule is not None and not rule(self.idn):
            raise ValueError(_T("Invalid VAT identification number %s" % vin))

    # end def __init__

    @TFL.Meta.Once_Property
    def rule(self):
        try:
            return self.Countries[self.cc]
        except KeyError:
            pass

    # end def rule

    @property
    def value(self):
        return self._value

    # end def value

    def __eq__(self, rhs):
        r = rhs.value if isinstance(rhs, VAT_IDN) else rhs
        return self.value == r

    # end def __eq__

    def __hash__(self):
        return hash(self.value)

    # end def __hash__

    def __repr__(self):
        return pyk.reprify(self.value)

    # end def __repr__

    def __str__(self):
        return "%s" % (self.value, )
Example #3
0
        class name(A_String):
            """Short name of the sailing club."""

            kind = Attr.Primary
            example = "RORC"
            ignore_case = True
            max_length = 8
            completer = Attr.Completer_Spec(1, Attr.Selector.primary)

            _clean = Re_Replacer(r"\W+", "", re.UNICODE)

            @TFL.Meta.Class_and_Instance_Method
            def cooked(soc, value):
                if value is not None:
                    return soc._clean(pyk.text_type(value))
                return value
Example #4
0
from   _GTW                   import GTW
from   _TFL                   import TFL

import _GTW._OMP.deploy

from   _TFL                   import sos
from   _TFL.Filename          import Filename
from   _TFL.import_module     import import_module
from   _TFL.predicate         import uniq
from   _TFL.pyk               import pyk
from   _TFL.Regexp            import Re_Replacer, re

import sys

strip_empty_lines = Re_Replacer ("^( *\n)( *\n)+", r"\1", re.MULTILINE)

class _GT2W_Sub_Command_ (GTW.OMP.deploy._Sub_Command_) :

    _rn_prefix = "_GT2W"

_Sub_Command_ = _GT2W_Sub_Command_ # end class

_Ancestor = GTW.OMP.deploy.Command

class GT2W_Command (_Ancestor) :
    """Manage deployment applications based on GTW.Werkzeug."""

    _rn_prefix                  = "GT2W"

    _defaults                   = dict \
Example #5
0
class Canvas(TFL.Meta.Object):
    """Canvas for ASCII renderer"""

    _strip_empty = Multi_Re_Replacer \
        ( Re_Replacer ("^( *\n)+", "")
        , Re_Replacer ("(\n *)+$", "")
        )

    def __init__(self, min_x, min_y, max_x, max_y):
        self._body = list([" "] * max_x for i in range(max_y))

    # end def __init__

    def line(self, line, chars={}):
        h, t = line
        d = t - h
        if d.x == 0:
            return self._line_v(line, chars.get("y"))
        elif d.y == 0:
            return self._line_h(line, chars.get("x"))
        else:
            print("Slanted line [%s -> %s] not implemented " % (h, t))

    # end def line

    def rectangle(self, rect):
        self._line_h(rect.top)
        self._line_h(rect.bottom)
        self._line_v(rect.left)
        self._line_v(rect.right)
        for p in rect.corners:
            self[p] = "+"

    # end def rectangle

    def rendered(self):
        result = "\n".join("".join(l).rstrip() for l in self._body)
        return self._strip_empty(result)

    # end def rendered

    def text(self, p, v):
        self[p] = v

    # end def text

    def _line_h(self, line, char=None):
        if char is None:
            char = "-"
        head, tail = line
        assert head.y == tail.y
        if head.x > tail.x:
            head, tail = tail, head
        l = int(tail.x - head.x)
        self[head] = char * l

    # end def _line_h

    def _line_v(self, line, char=None):
        if char is None:
            char = "|"
        head, tail = line
        assert head.x == tail.x
        if head.y > tail.y:
            head, tail = tail, head
        x, y = head
        while y <= tail.y:
            self[x, y] = char
            y += 1

    # end def _line_v

    def __setitem__(self, key, value):
        if value:
            x, y = tuple(int(k) for k in key)
            l = len(value)
            line = self._body[y]
            line[x:x + l] = list(value)
class NDC(TFL.Meta.Object):

    ### Want three integer columns, two string columns
    _converters = (_str_int, int, int, _decoded, _decoded)

    ### DRY info
    _info_cleaner = Re_Replacer("^Area code for ", "")
    _info_map     = \
        {  "650" : "Mobile (Telering)"
        ,  "660" : "Mobile (Hutchison 3G/3)"
        ,  "664" : "Mobile (A1)"
        ,  "676" : "Mobile (T-Mobile Austria)"
        ,  "677" : "Mobile (HoT)"
        ,  "680" : "Mobile (BoB)"
        ,  "681" : "Mobile (yesss!)"
        ,  "688" : "Mobile (Previously Tele2)"
        ,  "699" : "Mobile (Previously Orange, yesss!)"
        }

    ### rtr.at specifies 67, 68, 69 as NDCs but these are not complete — the
    ### actual NDCs look like 676, 688, or 699
    _ndc_add_digit = Regexp("^6[789]$")

    ### Shorten usage to one word
    _usage_map    = \
        { "local network code" : "geographic"
        , "mobile services"    : "mobile"
        , "service number"     : "service"
        , "routing number"     : "routing"
        }

    def __init__(self, ndc, max_len, min_len, usage, info):
        self.ndc = ndc
        self.max_len = max_len
        self.min_len = min_len
        self.usage = usage
        self.info = info

    # end def __init__

    @classmethod
    def from_xls_row(cls, row):
        try:
            ndc, max_len, min_len, usage, info = tuple \
                (c (x.value) for c, x in zip (cls._converters, row))
        except Exception:
            pass
        else:
            if cls._ndc_add_digit.match(ndc):
                for i in range(10):
                    ndc_x = ndc + str(i)
                    yield cls._from_row(ndc_x, max_len, min_len, usage, info)
            else:
                yield cls._from_row(ndc, max_len, min_len, usage, info)

    # end def from_xls_row

    @classmethod
    def _from_row(cls, ndc, max_len, min_len, usage, info):
        ndc_len = len(ndc)
        usage = cls._usage_map.get(usage, usage)
        info = cls._info_cleaner(cls._info_map.get(ndc, info))
        if not info:
            info = usage.capitalize()
        return cls(ndc, max_len - ndc_len, min_len - ndc_len, usage, info)

    # end def _from_row

    def __repr__(self):
        return "%s (%s, %s)" % (self, self.min_len, self.max_len)

    # end def __repr__

    def __str__(self):
        return "%s [%s]" % (self.ndc, self.info)
Example #7
0
class Scope(TFL.Meta.Object):

    active = None
    ilk = "S"
    playback_p = False
    Table = {}

    after_commit_callback = TFL.Ordered_Set()
    init_callback = TFL.Ordered_Set()
    kill_callback = TFL.Ordered_Set()

    _cleaned_url = Re_Replacer(r"(://\w+:)(\w+)@", r"\1<elided>@")
    _deprecated_type_names = {}
    _pkg_ns = None
    __id = 0

    root = None
    _roots = None

    changes = property(TFL.Getter.historian.total_changes)
    changes_to_save        = property \
        (lambda s : len (s.ems.uncommitted_changes))
    db_meta_data = property(TFL.Getter.ems.db_meta_data)
    etypes = property(TFL.Getter.app_type.etypes)
    Fatal_Exceptions = property(TFL.Getter.ems.pm.dbs.Fatal_Exceptions)
    max_cid = property(TFL.Getter.ems.max_cid)
    max_pid = property(TFL.Getter.ems.max_pid)
    max_surrs = property(TFL.Getter.ems.max_surrs)
    name = property(lambda s: s.qname)
    readonly = property(TFL.Getter.ems.db_meta_data.readonly)
    reserve_surrogates = True
    T_Extension = property(TFL.Getter.app_type._T_Extension)
    uncommitted_changes = property(TFL.Getter.ems.uncommitted_changes)

    PNS_Proxy = None

    @property
    def qname(self):
        return self.bname or self.app_type.name

    # end def qname

    @TFL.Meta.Once_Property
    def relevant_roots(self):
        """Return the relevant roots of the application."""
        Top = self.MOM.Id_Entity.E_Type
        return sorted \
            (pyk.itervalues (Top.relevant_roots), key = Top.m_sorted_by)

    # end def relevant_roots

    @property
    def root_pid(self):
        try:
            return self.db_meta_data.root_pid
        except AttributeError:
            pass

    # end def root_pid

    @root_pid.setter
    def root_pid(self, value):
        root_pid = self.root_pid
        if not (root_pid is None or root_pid == value):
            raise TypeError \
                ( "Root pid of scope %s was already set to %r; "
                  "cannot change to %r"
                % (self, root_pid, value)
                )
        try:
            dbmd = self.db_meta_data
        except AttributeError:
            self._root_pid = value
        else:
            dbmd.root_pid = value

    # end def root_pid

    @TFL.Meta.Once_Property
    def Root_Type(self):
        RTN = self.app_type.Root_Type_Name
        if RTN:
            return self.etypes[RTN]

    # end def Root_Type

    @TFL.Meta.Once_Property
    def _Example(self):
        return _Example_(self)

    # end def _Example

    class Pkg_NS:
        """Just a container for the scope-specific etype-proxies for the
           essential classes of a package-namespace (delegates everything
           else to the original package namespace).
        """
        def __init__(self, scope, pns, qn):
            self._scope = scope
            self._pns = pns
            self._qname = qn

        # end def __init__

        def __getattr__(self, name):
            if name.startswith("__") and name.endswith("__"):
                ### Placate inspect.unwrap of Python 3.5,
                ### which accesses `__wrapped__` and eventually throws
                ### `ValueError`
                return getattr(self.__super, name)
            scope = self._scope
            etypes = scope.etypes
            pkg_ns = scope._pkg_ns
            qname = ".".join((self._qname, name))
            result = None
            if qname in pkg_ns:
                result = pkg_ns[qname]
            elif qname in etypes:
                etype = etypes[qname]
                result = scope._etm[qname] = etype.Manager(etype, scope)
                setattr(self, name, result)
            else:
                result = getattr(self._pns, name)
            return result

        # end def __getattr__

    # end class Pkg_NS

    ### Scope creation methods

    @classmethod
    def load(cls, app_type, db_url, user=None):
        """Load a scope for `app_type` from `db_url`.

           Depending on `app_type.EMS`, `load` might load all instances from
           `db_url` into the application or it might just connect to the
           database and load instances on demand in answer to queries.
        """
        db_url = app_type.Url(db_url)
        with cls._init_context(app_type, db_url, user) as self:
            app_type = self.app_type
            self.ems = ems = app_type.EMS.connect(self, db_url)
            with self._init_root_context():
                self._register_root(ems.load_root())
        return self

    # end def load

    @classmethod
    def new(cls, app_type, db_url, user=None, root_spec=None):
        """Create a scope for `app_type` for a new database `db_url`.

           If `app_type` has a :attr:`~_MOM.App_Type.App_Type.Root_Type`,
           `new` requires a `root_spec` passed in.

           `root_spec` must be one of:

           * a proper epk-tuple for :attr:`~_MOM.App_Type.App_Type.Root_Type`

           * a callable that takes the scope as its single parameter and
             returns the root object.
        """
        db_url = app_type.Url(db_url)
        with cls._init_context(app_type, db_url, user, root_spec) as self:
            app_type = self.app_type
            self.guid = self._new_guid()
            self.ems = ems = app_type.EMS.new(self, db_url)
            with self._init_root_context(root_spec):
                self._setup_root(app_type, root_spec)
                ems.register_scope()
        return self

    # end def new

    @classmethod
    @TFL.Contextmanager
    def _init_context(cls, app_type, db_url, user, root_spec=None):
        self = cls.__new__(cls)
        self.app_type = app_type
        self.db_url = db_url
        self.user = user
        self.bname = ""
        self.id = self._new_id()
        self.root = None
        self.historian = MOM.SCM.Tracker(self)
        self.db_errors = []
        self._attr_errors = []
        self._etm = {}
        self._roots = {}
        self._setup_pkg_ns(app_type)
        ### copy `*_callback` from cls to self
        self.after_commit_callback = self.after_commit_callback.copy()
        self.init_callback = self.init_callback.copy()
        self.kill_callback = self.kill_callback.copy()
        old_active = Scope.active
        try:
            Scope.active = self
            yield self
            self._run_init_callbacks()
            self.start_change_recorder()
            Scope.Table[self.id] = self
        except:
            Scope.active = old_active
            raise

    # end def _init_context

    @TFL.Contextmanager
    def _init_root_context(self, root_spec=None):
        yield

    # end def _init_root_context

    def __init__(self):
        raise TypeError \
            ( "Use {name}.new or {name}.load to create new scopes".format
                (name = self.__class__.__name__)
            )

    # end def __init__

    ### Scope methods

    def add(self, entity, pid=None):
        """Adds `entity` to scope `self`."""
        if entity._home_scope is None:
            entity.home_scope = self
        with self.ems.save_point():
            self.ems.add(entity, pid=pid)
            if not entity.init_finished:
                entity._finish__init__()
            self.record_change(MOM.SCM.Change.Create, entity)

    # end def add

    def add_from_pickle_cargo(self, type_name, cargo, pid):
        """Add an entity defined by (`type_name`, `pid`, `cargo`)."""
        Type = self.entity_type(type_name)
        if Type:
            try:
                result = Type.from_attr_pickle_cargo(self, cargo)
            except Exception as exc:
                self.db_errors.append((type_name, pid, cargo))
                if __debug__:
                    traceback.print_exc()
                print(repr(exc), file=sys.stderr)
                print \
                    ( "   add_from_pickle_cargo: couldn't restore"
                      " %s %s %s (app-type %s)"
                    % (type_name, pid, cargo, self.app_type)
                    , file = sys.stderr
                    )
            else:
                self.ems.add(result, pid=pid)
                if pid == self.root_pid:
                    self._register_root(result)
                if not result.init_finished:
                    result._finish__init__()
                return result

    # end def add_from_pickle_cargo

    @TFL.Meta.Class_and_Instance_Method
    def add_after_commit_callback(soc, *callbacks):
        """Add all `callbacks` to `after_commit_callback`. These
           callbacks are executed after each `.commit` of a scope
           (the scope and the MOM.SCM.Summary instance of the just commited
           changes are passed as arguments to each callback).
        """
        soc.after_commit_callback.extend(callbacks)

    # end def add_after_commit_callback

    @TFL.Meta.Class_and_Instance_Method
    def add_init_callback(soc, *callbacks):
        """Add all `callbacks` to `init_callback`. These
           callbacks are executed whenever a scope is
           created (the new scope is passed as the single argument to each
           callback).
        """
        soc.init_callback.extend(callbacks)

    # end def add_init_callback

    @TFL.Meta.Class_and_Instance_Method
    def add_kill_callback(soc, *callbacks):
        """Add all `callbacks` to `kill_callback` of the scope class
           or instance. These callbacks` are executed whenever the
           scope is destroyed (the scope to be destroyed is passed as
           the single argument to each callback).
        """
        soc.kill_callback.extend(callbacks)

    # end def add_kill_callback

    @TFL.Contextmanager
    def as_active(self):
        """Provide context with `self` as active scope."""
        with Scope.LET(active=self):
            yield

    # end def as_active

    def canonical_type_name(self, type_name):
        return self._deprecated_type_names.get(type_name, type_name)

    # end def canonical_type_name

    def commit(self):
        """Commit all outstanding changes to the database."""
        ems = self.ems
        ucc = ems.uncommitted_changes
        with ems.commit_context():
            if ucc:
                errs = self.r_incorrect(eiter=ucc.entities_transitive(ems))
                if errs:
                    exc = MOM.Error.Invariants(errs.errors)
                    raise exc
            ems.commit()
            for cb in self.after_commit_callback:
                cb(self, ucc)

    # end def commit

    def copy(self, app_type, db_url):
        """Copy all entities and change-history  of `self` into a new
           scope for `app_type` and `db_url`.
        """
        assert self.app_type.parent is app_type.parent
        db_url = app_type.Url(db_url)
        assert (db_url is None or not db_url.path
                or self.db_url.path != db_url.path)
        with self.as_active():
            result = self.__class__.new(app_type, db_url, user=self.user)
            result.root_pid = self.root_pid
            for e in sorted(self, key=TFL.Getter.pid):
                result.add_from_pickle_cargo(*e.as_pickle_cargo())
            for c in self.query_changes().order_by(TFL.Sorted_By("cid")):
                result.ems.register_change(c)
            result.ems.compact()
        return result

    # end def copy

    def count_change(self):
        self.historian.count_change()

    # end def count_change

    def close_connections(self):
        self.ems.close_connections()

    # end def close_connections

    def destroy(self):
        """Close connection to database and destroy all cached instances."""
        self.ems.close()
        if self.id in Scope.Table:
            del Scope.Table[self.id]
        self.stop_change_recorder()
        self.app_type.run_kill_callbacks(self)
        for c in self.kill_callback:
            c(self)
        del self.kill_callback
        self.root = None
        for d in (self._roots, self._pkg_ns):
            d.clear()
        ### XXX break circular links (references to this scope from
        ###     importers... )
        if Scope.active == self:
            Scope.active = None
        self.__dict__.clear()

    # end def destroy

    @classmethod
    def destroy_all(cls):
        """Destroy all scopes."""
        for i, s in sorted(pyk.iteritems(Scope.Table), reverse=True):
            try:
                s.destroy()
            except Exception:
                pass

    # end def destroy_all

    def entity_iter(self):
        """Yields all objects and links alive in `self` in unspecified
           order.
        """
        return iter(self.ems)

    # end def entity_iter

    def entity_iter_gauge(self,
                          gauge=Gauge_Logger(),
                          sort_key=None,
                          label=None):
        """Yields all entities alive in `self` in the
           order specified by `sort_key`.
        """
        gauge.reset \
            ( g_delta = 100
            , g_range = self.ems.count (self.MOM.Id_Entity, strict = False)
            , label   = label
            )
        entities = iter(self.ems)
        if sort_key:
            entities = sorted(entities, key=sort_key)
        i = 1
        for e in entities:
            yield e
            if i == 100:
                gauge.inc(100)
                i = 0
            i += 1

    # end def entity_iter_gauge

    def entity_type(self, entity):
        """Return scope specific entity type for `entity` (-name)."""
        if isinstance(entity, pyk.string_types):
            name = entity
        else:
            name = entity.type_name
        return self.app_type.entity_type(self.canonical_type_name(name))

    # end def entity_type

    @TFL.Contextmanager
    def example_etm(self, etm):
        """Return a E_Type_Manager for the E_Type of `etm` in an example scope."""
        with self._Example.context(self) as x_scope:
            x_etm = x_scope[etm.type_name]
            yield x_etm

    # end def example_etm

    @TFL.Meta.Lazy_Method_RLV
    def g_incorrect(self, gauge=Gauge_Logger()):
        """Returns all objects which are globally incorrect (i.e., violating
           the object's `system` predicates).
        """
        with self.as_active():
            return self._check_inv(gauge, "system")

    # end def g_incorrect

    def has_changed(self):
        """Indicates whether something saveworthy has changed, i.e., there if
           there are outstanding changes to be commited.
        """
        return bool(self.ems.uncommitted_changes)

    # end def has_changed

    @TFL.Meta.Lazy_Method_RLV
    def i_incorrect(self, gauge=Gauge_Logger()):
        """Returns all objects which are object-wise incorrect (i.e., violating
           the object's `object` predicates).
        """
        with self.as_active():
            return self._check_inv(gauge, "object")

    # end def i_incorrect

    @TFL.Contextmanager
    def nested_change_recorder(self, Change, *args, **kw):
        """Return context with `Change (* args, ** kw)` acting as nested
           change recorder.
        """
        with self.historian.nested_recorder(Change, *args, **kw) as c:
            yield c
            if c:
                c.user = self.user
                self.ems.register_change(c)
                c.do_callbacks(self)

    # end def nested_change_recorder

    def pid_query(self, pid, allow_zombie=False):
        """Returns entity with permanent id `pid`, if any."""
        result = self.ems.pid_query(pid)
        if (not allow_zombie
                and isinstance(result, MOM._Id_Entity_Destroyed_Mixin_)):
            raise LookupError(pid)
        return result

    # end def pid_query

    def query_changes(self, *filter, **kw):
        """Return changes matching `filter` and `kw`"""
        return self.ems.changes(*filter, **kw)

    # end def query_changes

    @TFL.Meta.Lazy_Method_RLV
    def r_incorrect(self, gauge=Gauge_Logger(), eiter=None):
        """Returns all objects which are region-wise incorrect (i.e., violating
           the object's `region` predicates).
        """
        with self.as_active():
            return self._check_inv(gauge, "region", eiter)

    # end def i_incorrect

    def record_change(self, Change, *args, **kw):
        """Record the `Change` specified by `args` and `kw`"""
        with self.ems.save_point():
            result = self.historian.record(Change, *args, **kw)
            if result is not None:
                result.user = self.user
                self.ems.register_change(result)
                result.do_callbacks(self)
            return result

    # end def record_change

    def remove(self, entity):
        """Remove `entity` from scope `self`"""
        assert (entity != self.root)
        Change = MOM.SCM.Change.Destroy
        with self.nested_change_recorder(Change, entity):
            entity._destroy()
            self.ems.remove(entity)

    # end def remove

    def rename(self, entity, new_epk, renamer):
        self.ems.rename(entity, new_epk, renamer)

    # end def rename

    def rollback(self, keep_zombies=False):
        """Rollback and discard the outstanding changes."""
        self.ems.rollback(keep_zombies)
        self.count_change()

    # end def rollback

    def rollback_pending_change(self):
        """Rollback the last, not yet recorded, change but keep all earlier
           outstanding changes.
        """
        changes = tuple(self.uncommitted_changes.changes)
        self.rollback(keep_zombies=True)
        for c in changes:
            c.redo(self)

    # end def rollback_pending_change

    def start_change_recorder(self):
        if not self.historian._rec_stack:
            self.historian.push_recorder(MOM.SCM.Tracker.Preferred_Recorder)

    # end def start_change_recorder

    def stop_change_recorder(self):
        if self.historian._rec_stack:
            self.historian.pop_recorder()

    # end def stop_change_recorder

    @TFL.Contextmanager
    def temp_change_recorder(self, Recorder):
        with self.historian.temp_recorder(Recorder):
            yield

    # end def temp_change_recorder

    def user_diff(self, other, ignore=()):
        """Return differences of entities `self` and `other` concerning user attributes."""
        result = {}
        seen = set()

        def diff(lhs, rhs):
            for e in lhs:
                k = e.epk_raw
                t = e.type_name
                if k not in seen:
                    seen.add(k)
                    o = rhs[t].instance(*k, raw=True)
                    if o is None:
                        diff = "Present in %s, missing in %s" % (lhs, rhs)
                    else:
                        diff = e.user_diff(o, ignore)
                    if diff:
                        result[(t, k)] = diff

        diff(self, other)
        diff(other, self)
        return result

    # end def user_diff

    def user_equal(self, other):
        """Compare entities of `self` and `other` regarding user attributes."""
        s_count = self.ems.count(self.MOM.Id_Entity.E_Type, strict=False)
        o_count = other.ems.count(other.MOM.Id_Entity.E_Type, strict=False)
        if s_count == o_count:
            for e in self:
                o = other[e.type_name].instance(*e.epk_raw, raw=True)
                if not (o and e.user_equal(o)):
                    break
            else:
                return True
        return False

    # end def user_equal

    def _check_inv(self, gauge, kind, eiter=None):
        err_result = []
        wrn_result = []
        sk = self.MOM.Id_Entity.sort_key
        if eiter is None:
            eiter  = self.entity_iter_gauge \
                (gauge, label = "Checking %s invariants" % kind)
        for e in eiter:
            try:
                ews = e._pred_man.check_kind(kind, e)
                if ews.errors:
                    err_result.append(e)
                if ews.warnings:
                    wrn_result.append(e)
            except Exception:
                print \
                    ( "Error during evaluation of", kind, "invariant for ", e
                    , file = sys.stderr
                    )
                traceback.print_exc()
                err_result.append(e)
        return MOM.Pred.Err_and_Warn_List \
            (sorted (err_result, key = sk), sorted (wrn_result, key = sk))

    # end def _check_inv

    def _get_etm(self, name):
        try:
            result = self._etm[name]
        except KeyError:
            pn, _, rest = split_hst(name, ".")
            try:
                result = self._pkg_ns[pn]
            except KeyError:
                raise AttributeError(name)
            for k in rest.split("."):
                result = getattr(result, k)
            self._etm[name] = result
        return result

    # end def _get_etm

    def _new_guid(self):
        return str(uuid.uuid4())

    # end def _new_guid

    def _new_id(self):
        result = Scope.__id
        Scope.__id += 1
        return result

    # end def _new_id

    def _outer_pgk_ns(self, outer, pns, _pkg_ns):
        while True:
            outer, _, name = rsplit_hst(outer, ".")
            if (not outer) or outer in _pkg_ns:
                break
            pns = pns._Outer
            yield outer, pns

    # end def _outer_pgk_ns

    def _register_root(self, root):
        if root is not None:
            if self.root is None:
                self.root = self._roots[root.type_base_name] = root
                self.root_pid = root.pid
                self.bname = root.ui_display
            else:
                raise TypeError("Root was already set to %r" % (self.root, ))

    # end def _register_root

    def _run_init_callbacks(self):
        for c in self.init_callback:
            c(self)
        self.app_type.run_init_callbacks(self)

    # end def _run_init_callbacks

    def _setup_pkg_ns(self, app_type):
        _pkg_ns = self._pkg_ns = {}
        Pkg_NS = self.Pkg_NS
        for name, pns in sorted \
                (pyk.iteritems (app_type.PNS_Map), key = TFL.Getter [0]) :
            _pkg_ns[name] = Pkg_NS(self, pns, name)
            for outer, pns in self._outer_pgk_ns(name, pns, _pkg_ns):
                _pkg_ns[outer] = Pkg_NS(self, pns, outer)

    # end def _setup_pkg_ns

    def _setup_root(self, app_type, root_spec):
        RT = self.Root_Type
        if root_spec and RT:
            if callable(root_spec):
                result = root_spec(self)
                if not isinstance(result, RT.Essence):
                    raise TypeError \
                        ( "%s returned %s %r, expected %s"
                        % (root_spec, result.__class__, result, RT)
                        )
            else:
                result = RT(*root_spec)
            self._register_root(result)
            return result

    # end def _setup_root

    def __getattr__(self, name):
        if name.startswith("__") and name.endswith("__"):
            ### Placate inspect.unwrap of Python 3.5,
            ### which accesses `__wrapped__` and eventually throws `ValueError`
            return getattr(self.__super, name)
        if "." in name:
            if name in self._etm:
                return self._etm[name]
            else:
                return self._get_etm(name)
        else:
            for dict in self._roots, self._pkg_ns:
                try:
                    result = dict[name]
                except KeyError:
                    pass
                else:
                    setattr(self, name, result)
                    return result
            return getattr(self.app_type, name)

    # end def __getattr__

    def __getitem__(self, name):
        if not isinstance(name, pyk.string_types):
            name = name.type_name
        try:
            return self._get_etm(name)
        except AttributeError:
            raise KeyError(name)

    # end def __getitem__

    def __iter__(self):
        """Generate all essential instances stored in database"""
        return iter(self.ems)

    # end def __iter__

    def __str__(self):
        url = self._cleaned_url(str(self.db_url))
        return "%s %s<%s>" % (self.__class__.__name__, self.bname, url)
Example #8
0
date_time_localizer_pattern = Regexp \
    ( ( r"(?P<head> ^|[[(\s])"
        r"(?P<year>  \d{4,4})"
        r"([-/]?)"
        r"(?P<month> \d{2,2})"
        r"\3"
        r"(?P<day>   \d{2,2})"
        r"[T ]"
      )
    + CAL.Date_Time.time_pattern.pattern
    + r"(?P<tail> $|[])\s])"
    , flags = re.VERBOSE | re.IGNORECASE
    )
_cleaned = Multi_Re_Replacer \
    ( Re_Replacer (r"^[[(\s]", "")
    , Re_Replacer (r"[])\s]$", "")
    )

def date_time_localizer \
        (s, format = "%Y-%m-%d %H:%M", pattern = None, count = 0) :
    """Convert date-times in `s` into local time without tzoffset.

    >>> print (portable_repr (date_time_localizer ("09d82ac 2012-03-29 21:06:26 +0200 [email protected]")))
    '09d82ac 2012-03-29 21:06 [email protected]'
    >>> print (portable_repr (date_time_localizer ("f6baffa 2012-03-29 10:06:46 -0400 [email protected]")))
    'f6baffa 2012-03-29 16:06 [email protected]'
    >>> print (portable_repr (date_time_localizer ("f99a29d 2005-03-22 09:34:40 +0000 [email protected]")))
    'f99a29d 2005-03-22 10:34 [email protected]'

    """
Example #9
0
            from cssmin import cssmin as _cssmin
            cssmin = lambda style, keep_bang_comments: _cssmin(style)
        except ImportError:
            logging.warning("Couldn't import either rcssmin nor cssmin")
    if cssmin is not None:
        try:
            return cssmin(style, keep_bang_comments=keep_bang_comments)
        except Exception as exc:
            logging.error("Exception during minified_css\n    %s" % (exc, ))
    return style


# end def minified_css

_clean_minified_js = Multi_Re_Replacer \
    ( Re_Replacer (r";+\}",    "}")
    , Re_Replacer (r";+\(",    ";(")
    , Re_Replacer (r";?\s*\Z", "\n")
    , Re_Replacer (r"\A;\s*",  "")
    )


def minified_js(code):
    """Return minified javascript `code`.

       If neither `jsmin`_ nor `rjsmin`_ is installed, `code` is returned
       unchanged.

       .. _`jsmin`: https://bitbucket.org/dcs/jsmin/
       .. _`rjsmin`: http://opensource.perlig.de/rjsmin/
    """
Example #10
0
from   _TFL                   import sos

import _TFL.CAO
import _TFL.Command
import _TFL.Context
import _TFL.Environment
import _TFL.Filename
import _TFL.Secure_Hash
import _TFL.Undef
import _TFL._Meta.Once_Property

import contextlib
import logging
import stat

_cleaned_url = Re_Replacer (r"(://\w+:)(\w+)@", r"\1<elided>@")

class SA_WE_Opt (TFL.CAO.Bool) :
    """Turn SA warnings into errors"""

    def __init__ (self, ** kw) :
        assert "name" not in kw
        kw ["name"] = self.__class__.__name__
        if "description" not in kw :
            kw ["description"] = self.__class__.__doc__
        self.__super.__init__ (** kw)
    # end def __init__

    def cook (self, value, cao = None) :
        result = self.__super.cook (value, cao)
        if result :
Example #11
0
from   _TFL.Regexp                import Multi_Re_Replacer, Re_Replacer, re

from   posixpath import join as pp_join

import multiprocessing
import requests
import subprocess
import sys
import time

skip_headers = set (["connection", "set-cookie", "x-frame-options"])

date_cleaner = Multi_Re_Replacer \
    ( Re_Replacer
        ( r"'date' : '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'"
        , r"'date' : <datetime>"
        )
    , Re_Replacer
        ( r"'(default_value|date)' : '\d{4}-\d{2}-\d{2}'"
        , r"'date' : <date instance>"
        )
    )

p_type_cleaner = Re_Replacer \
    ( r"'p_type' : 'unicode'"
    , r"'p_type' : 'str'"
    )

json_cleaner = Multi_Re_Replacer (date_cleaner, p_type_cleaner)

def req_json (r) :
Example #12
0
class Country(TFL.Meta.BaM(TFL.Meta.Object, metaclass=M_Country)):
    """Provide phone number mapping for a specific country."""

    Table = {}

    ###  3-Aug-2015 16:48
    ### https://en.wikipedia.org/wiki/Local_conventions_for_writing_telephone_numbers#Denmark
    ### A : ndc digit
    ### B : sn  digit

    format_map = \
        {  "31" : ["AA-BBBBBBB"]                                     # Netherlands
        ,  "32" : ["A BBB BB BB", "AA BB BB BB", "AAA BB BB BB"]     # Belgium
        ,  "33" : ["A BB BB BB BB"]                                  # France
        ,  "34" : ["AAA BBB BBB", "AA B BBB BBB", "A BB BBB BBB"]    # Spain
        , "351" : ["AA BB BB BBB", "AAA BBB BBB"]                    # Portugal
        , "353" : ["AA BBB BBBB"]                                    # Ireland
        , "358" : ["AA BBB BB BB", "A BBB BBB"]                      # Finland
        ,  "36" : ["A BBB BBB", "A BBB BBBB"]                        # Hungary
        ,  "39" : ["AAA BBBBBBB"]                                    # Italy
        ,  "41" : ["AA BBB BB BB"]                                   # Switzerland
        , "420" : ["A BB BBB BBB", "AA B BBB BBB", "AAA BBB BBB"]    # Czech Republic
        ,  "44" : ["AA BBBB BBBB", "AAAA BBB BBBB", "AAAAA BBBBBB"]  # UK
        ,  "45" : ["BB BB BB BB"]                                    # Denmark
        ,  "47" : ["A B BB BB BB", "AA BB BB BB", "AAA BB BBB"]      # Norway
        ,  "48" : ["AA BBB BB BB", "AAA BBB BBB"]                    # Poland
        ,  "49" : ["AAAA BBBBBB"]                                    # Germany
        }
    formatted_sn       = Multi_Re_Replacer \
        ( Re_Replacer (r"^(\d{2,3})(\d{2,3})(\d{2,4})$", r"\1 \2 \3")
        , Re_Replacer (r"^(\d{2})(\d{2,3})$",            r"\1 \2")
        , Re_Replacer (r"^(\d{4})(\d{3,5})(\d{4})$",     r"\1 \2 \3")
        )
    formatted_sn_4x2   = Re_Replacer \
        ( r"^(\d{2})(\d{2})(\d{2})(\d{2})$", r"\1 \2 \3 \4")

    ndc_info_map = None  ### Only available for `Country_M`
    ndc_max_length = 4
    ndc_min_length = 1

    ndc_prefix = "0"

    _number_cleaner = Re_Replacer(r"[^0-9]", "")

    def __init__(self, name, code):
        self.name = name
        self.code = code

    # end def __init__

    @Once_Property
    def ndc_sn_max_length(self):
        code = self.code
        default = 15 - len(code)
        return self.__class__.ndc_data.ndc_sn_max_length.get(code, default)

    # end def ndc_sn_max_length

    @Once_Property
    def ndc_sn_min_length(self):
        code = self.code
        return self.__class__.ndc_data.ndc_sn_min_length.get(code, 5)

    # end def ndc_sn_min_length

    def cleaned_ndc(self, ndc):
        if ndc:
            return self._number_cleaner(ndc)

    # end def cleaned_ndc

    def cleaned_sn(self, ndc, sn):
        if sn:
            result = self._number_cleaner(sn)
            l_sn = len(result)
            max_sn = self.sn_max_length(ndc)
            min_sn = self.sn_min_length(ndc)
            if min_sn > l_sn:
                raise E164.SN_Too_Short \
                    (self, "-".join ((ndc, sn)), l_sn, min_sn)
            elif l_sn > max_sn:
                raise E164.SN_Too_Long \
                    (self, "-".join ((ndc, sn)), l_sn, max_sn)
            else:
                return result

    # end def cleaned_sn

    def ndc_info(self, ndc):
        pass

    # end def ndc_info

    def sn_max_length(self, ndc):
        return self.ndc_sn_max_length - len(ndc)

    # end def sn_max_length

    def sn_min_length(self, ndc):
        return self.ndc_sn_min_length - len(ndc)

    # end def sn_min_length

    def split(self, ndc_sn):
        regexp = self.regexp
        match = regexp.match(ndc_sn)
        if match:
            try:
                r_ndc = regexp.ndc
            except AttributeError:
                ndc = ""
            else:
                ndc = self.cleaned_ndc(r_ndc)
            sn = self.cleaned_sn(ndc, regexp.sn)
            return ndc, sn
        raise E164.ValueError(self, ndc_sn, self._split_error_tail(""))

    # end def split

    def _split_error_tail(self, tail):
        return tail

    # end def _split_error_tail

    def __bool__(self):
        return True

    # end def __bool__

    def __repr__(self):
        return "%s (%s)" % (_T("Country"), self.code)

    # end def __repr__

    def __str__(self):
        return "%r [%s]" % (self, self.name)
Example #13
0
date_time_localizer_pattern = Regexp \
    ( ( r"(?P<head> ^|[\[(\s])"
        r"(?P<year>  \d{4,4})"
        r"([-/]?)"
        r"(?P<month> \d{2,2})"
        r"\3"
        r"(?P<day>   \d{2,2})"
        r"[T ]"
      )
    + CAL.Date_Time.time_pattern.pattern
    + r"(?P<tail> $|[\])\s])"
    , flags = re.VERBOSE | re.IGNORECASE
    )
_cleaned = Multi_Re_Replacer \
    ( Re_Replacer (r"^[\[(\s]", "")
    , Re_Replacer (r"[\])\s]$", "")
    )

def date_time_localizer \
        (s, format = "%Y-%m-%d %H:%M", pattern = None, count = 0) :
    """Convert date-times in `s` into local time without tzoffset.

    >>> print_prepr (date_time_localizer ("09d82ac 2012-03-29 21:06:26 +0200 [email protected]"))
    '09d82ac 2012-03-29 21:06 [email protected]'
    >>> print_prepr (date_time_localizer ("f6baffa [2012-03-29 10:06:46 -0400] [email protected]"))
    'f6baffa [2012-03-29 16:06] [email protected]'
    >>> print_prepr (date_time_localizer ("f99a29d (2005-03-22 09:34:40 +0000) [email protected]"))
    'f99a29d (2005-03-22 10:34) [email protected]'

    """