class UI_Spec(object): """UI specification for E_Types defined by GTW.OMP.SWP.""" Clip_X = dict \ ( list_display = ( "ui_display", "short_title", "date", "created_by", "format" , "last_changed" ) , sort_key = TFL.Sorted_By ("-date.start", "-prio", "perma_name") ) Gallery = dict \ ( sort_key = TFL.Sorted_By ("-date.start", "perma_name") ) Page = dict \ ( list_display = ( "ui_display", "short_title", "date", "created_by", "format" , "last_changed" ) , sort_key = TFL.Sorted_By ("-date.start", "-prio", "perma_name") , MF3_Attr_Spec = dict ( { "events.recurrence" : dict ( include_rev_refs = ("rules", ) ) } , events = dict ( include_rev_refs = ("recurrence", ) ) ) , MF3_Form_Spec = dict ( include_rev_refs = ("events", "clips") ) ) Picture = dict \ ( sort_key = TFL.Sorted_By \ ("-left.date.start", "left.perma_name", "number") ) Referral = dict \ ( list_display = \ ("date", "parent_url", "perma_name", "short_title") , sort_key = TFL.Sorted_By \ ("-date.start", "parent_url", "perma_name") ) Video = dict \ ( sort_key = TFL.Sorted_By ("-date.start", "perma_name") )
def _gen_roles(cls): for a in sorted \ ( pyk.itervalues (cls._Attributes._names) , key = TFL.Sorted_By ("rank", "name") ) : if a is not None and issubclass(a, MOM.Attr.A_Link_Role): yield a
def create_interfaces(self): for iface in self.contents['ip']: if iface.node_id not in self.dev_by_id: print "WARN: Ignoring IP %s %s: no device (node) %s" \ % (iface.id, iface.ip, iface.node_id) continue dev = self.dev_by_id[iface.node_id] net = self.net_by_id[iface.net_id] ip = IP4_Address(iface.ip) if ip not in net.net_address: parent = self.ffm.IP4_Network.query \ ( Q.net_address.CONTAINS (ip) , ~ Q.electric , sort_key = TFL.Sorted_By ("-net_address.mask_len") ).first () print "WARN: IP %s %s not in net %s %s found %s" \ % ( iface.id , iface.ip , iface.net_id , net.net_address , parent.net_address ) net = parent nw = net.reserve(ip, owner=dev.node.owner) nif = self.ffm.Wired_Interface(left=dev, name=iface.name) nii = self.ffm.Net_Interface_in_IP4_Network \ (nif, nw, mask_len = 32, name = iface.name) self.nifin_by_id[iface.id] = nii if len(self.scope.uncommitted_changes) > 10: self.scope.commit()
def create_nettypes(self): """ Network ranges for reservation """ by_mask = {} # first group by netmask for nw in self.contents['nettype']: if not nw.comment: print 'WARN: Ignoring nettype %s "%s"' % (nw.id, nw.name) continue for net_ip in nw.comment.split(','): ip = IP4_Address(net_ip) if ip.mask not in by_mask: by_mask[ip.mask] = [] by_mask[ip.mask].append((ip, nw.name, nw.id)) typ = self.ffm.IP4_Network for mask in sorted(by_mask): for ip, name, id in by_mask[mask]: if id not in self.ntype_by_id: self.ntype_by_id[id] = [] r = typ.query \ ( Q.net_address.CONTAINS (ip) , ~ Q.electric , sort_key = TFL.Sorted_By ("-net_address.mask_len") ).first () reserver = r.reserve if r else typ network = reserver(ip, owner=self.graz_admin) self.ntype_by_id[id].append(network) if name: network.set_raw(desc=name)
class UI_Spec(object): """UI specification for E_Types defined by GTW.OMP.EVT.""" Calendar = dict \ ( ) Event = dict \ ( list_display = ("date", "time", "short_title", "left", "calendar") , sort_key = TFL.Sorted_By ("-date.start", "-time.start", "short_title", "left") , MF3_Attr_Spec = dict ( recurrence = dict ( include_rev_refs = ("rules", ) ) ) , MF3_Form_Spec = dict ( include_rev_refs = ("recurrence", ) ) ) Recurrence_Spec = dict \ ( MF3_Form_Spec = dict ( include_rev_refs = ("rules", ) ) )
def __iter__ (self) : sk = TFL.Sorted_By ("pid") return itertools.chain \ (* ( self._query_single_root (r).order_by (sk) for r in self.scope.relevant_roots ) )
class Gallery \ ( GTW.RST.TOP._Gallery_ , GTW.RST.TOP.MOM.Entity_Mixin_Base , GTW.RST.TOP.MOM.E_Type_Mixin , GTW.RST.TOP.Dir_V ) : """Page displaying a gallery of pictures.""" Entity = Picture sort_key = TFL.Sorted_By("number") def __init__(self, **kw): kw["ETM"] = "SWP.Picture" self.__super.__init__(**kw) # end def __init__ @Once_Property @getattr_safe def change_query_filters(self): pid = self.obj.pid rq = self.ETM.query(Q.left == pid).attr("pid") result = (Q.OR(Q.pid.IN(rq), Q.pid == pid), ) return result # end def change_query_filters @property @getattr_safe def query_filters_d(self): return self.__super.query_filters_d + (Q.left == self.obj.pid, ) # end def query_filters_d def href_display(self, obj): return pp_join(self.abs_href_dynamic, obj.name) # end def href_display def _get_child(self, child, *grandchildren): result = self.__super._get_child(child, *grandchildren) if result and result.name in self._entry_map and not grandchildren: ### make sure to use result from `_entry_map` ### that allows `1`, `01`, `001`, `0001`, ... result = self._entry_map[result.name] return result # end def _get_child def _get_child_query(self, child): try: number = int(child.split(".")[0]) except (TypeError, ValueError): result = None else: n, result = self.ETM.query_1(number=number, *self.query_filters) if result is None: result = self.__super._get_child_query(child) return result
def all_attribute_types(self): """List of all attribute types used by the etypes of the application.""" result = set() for T in self._T_Extension: if not T.is_partial: for ak in pyk.itervalues(T.attributes): result.add(ak.attr) return sorted(result, key=TFL.Sorted_By("typ", "name"))
def setup_links(self): if not self._setup_links_p: sort_key = TFL.Sorted_By("slack", "type_name") nodes = sorted(pyk.itervalues(self.node_map), key=sort_key) for n in nodes: n.setup_links() for n in nodes: n.set_guides() placers = sorted \ ( itertools.chain (* (n.placers for n in nodes)) , key = TFL.Sorted_By ("prio") ) for p in placers: p.place_connectors() for p in placers: p.improve_connectors() self._setup_links_p = True
def attrs(self): E_Type = self.E_Type a_type = self.a_type sk = TFL.Sorted_By("rank", "name") result = tuple \ ( a for a in sorted (pyk.itervalues (E_Type.attributes), key = sk) if isinstance (a.attr, a_type) ) return result
def render(self): canvas = self.canvas nodes = sorted(self.nodes, key=TFL.Getter.entity.type_name) for n in nodes: self.render_node(n, canvas) link_sort_key = TFL.Sorted_By("relation.rid") for n in nodes: for l in sorted(pyk.itervalues(n.link_map), key=link_sort_key): self.render_link(l, canvas)
def reserve_net(self, nets, typ): for net, comment in sorted(nets.iteritems(), key=ip_mask_key): if self.verbose: pyk.fprint(net, comment) r = typ.query \ ( Q.net_address.CONTAINS (net) , sort_key = TFL.Sorted_By ("-net_address.mask_len") ).first () reserver = r.reserve if r else typ network = reserver(net, owner=self.ff_subject) if isinstance(comment, type('')): network.set_raw(desc=comment[:80])
class S_Placer(Dir_Placer_Y): """Placer for relations in direction south.""" name = "S" neighbor_names = ("E", "W") opposite_name = "N" side = "top" sign = -1 sort_sign = -1 sort_key_p = TFL.Sorted_By("-delta.x") def predicate(self, r): return r.delta.y < 0
class W_Placer(Dir_Placer_X): """Placer for relations in direction west.""" name = "W" neighbor_names = ("N", "S") opposite_name = "E" side = "right" sign = +1 sort_sign = +1 sort_key_p = TFL.Sorted_By("delta.y") def predicate(self, r): return r.delta.y == 0 and r.delta.x < 0
def Dyn_Slice_ReST_Dir(parent, src_dir): def _gen(parent, src_dir): for f in sos.expanded_globs(pjoin(src_dir, "*.txt")): info = _page_info(f) if info: n = info.get("name", f) info["perma_name"] = base = Filename(n).base info["name"] = name = "%s.html" % (base, ) yield GTW.RST.TOP.Page_ReST \ (parent = parent, src_dir = src_dir, ** info) sort_key = TFL.Sorted_By("rank", "-date", "name") entries = sorted(_gen(parent, src_dir), key=sort_key) parent.add_entries(*entries)
def _setup_order_by (self, E_Type, request, data) : s = data.pop ("order_by", "").strip () if s : def _gen (ns) : for n in ns : try : r = self._setup_order_by_1 (E_Type, n) except AttributeError as exc : pass else : yield r order_by = tuple (_gen (s.split (","))) if order_by : self.order_by, criteria = zip (* order_by) self.order_by_q = TFL.Sorted_By (* ichain (* criteria))
def _e_type_doc (self, ET) : dle = self._dl_element ref = self._e_type_ref tnd = ET.type_name adp = ET.auto_derived_p if ET.is_partial : tnd += " [partial type]" result = [dle ("Type name", tnd)] if ET.relevant_root and (ET.is_partial or ET.relevant_root is not ET) : result.append (dle ("Relevant root", ref (ET.relevant_root))) if ET.parents : ps = tuple ("* "+ ref (p) for p in ET.parents) result.append (dle ("Parents", * ps)) children = tuple \ (c for tn, c in pyk.iteritems (ET.children) if not c.immaterial) if children : sk = TFL.Sorted_By () cs = tuple (("* " + ref (c)) for c in sorted (children, key = sk)) result.append (dle ("Children", * cs)) rs = tuple ("* " + r for r in self._e_type_cross_refs (ET)) if rs : result.append (dle ("Reverse references", * rs)) if not adp : result.extend (self._e_type_doc_x (ET, "__doc_attr_head__")) result.extend (self._e_type_attrs_edit (ET)) if not adp : result.extend (self._e_type_attrs_q_able (ET)) result.extend (self._e_type_doc_x (ET, "__doc_attr_tail__")) result.extend (self._e_type_doc_x (ET, "__doc_pred_head__")) o_preds = ET._Predicates._pred_kind ["object"] if adp : _own = ET._Predicates._own_names o_preds = tuple (p for p in o_preds if p.name in _own) if o_preds : result.extend \ ( self._e_type_preds ( ET, o_preds , heading = "Object predicates" , leader = ":class:`Object predicates<_MOM._Pred.Kind.Object>` " "must be satisfied at all times. " "They are checked whenever the value of one or " "more essential attributes is set or changed." ) ) if not adp : result.extend (self._e_type_doc_x (ET, "__doc_pred_tail__")) return result
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
def create_networks(self): for net in self.contents['net']: parents = self.ntype_by_id.get(net.nettype_id, []) node = self.ffm_node.get(net.location_id) ip = IP4_Address(net.netip, net.netmask) if node: owner = node.owner else: print "WARN: Network %s %s Location %s missing" \ % (net.id, net.netip, net.location_id) owner = self.graz_admin parent = None for p in parents: if ip in p.net_address: parent = p break else: parent = None for ps in self.ntype_by_id.itervalues(): for p in ps: if ip in p.net_address: parent = p print "Got parent in ntype_by_id: %s" % parent break else: parent = self.ffm.IP4_Network.query \ ( Q.net_address.CONTAINS (ip) , ~ Q.electric , sort_key = TFL.Sorted_By ("-net_address.mask_len") ).first () if parent: print "Got parent by network query: %s" % parent if parent: reserver = parent.reserve else: print "WARN: No parent: new network: %s" % ip reserver = self.ffm.IP4_Network network = reserver(ip, owner=owner) self.net_by_id[net.id] = network if node: pool = self.ffm.IP4_Pool(left=network, node=node) if net.comment: network.set_raw(desc=net.comment) if len(self.scope.uncommitted_changes) > 10: self.scope.commit()
def __init__(self, entity): self.entity = entity self.placers = placers = dict \ ( (p.name, p) for p in ( self.N_Placer (self) , self.E_Placer (self) , self.S_Placer (self) , self.W_Placer (self) ) ) sort_key = TFL.Sorted_By("slack", "max_rels", "name") by_slack = sorted(pyk.itervalues(placers), key=sort_key) for dp in by_slack: if dp.slack < 0: dp.slacker() by_slack = sorted((dp for dp in by_slack if dp), key=sort_key) for dp in by_slack: dp.setup_connectors()
class Year(_E_Type_): """Display instances of a specific year.""" sort_key = TFL.Sorted_By("-date.start", "perma_name") @Once_Property @getattr_safe def query_filters_s(self): return \ ( self.parent._year_filter (self.year) + self.__super.query_filters_s ) # end def query_filters_s def _default_title(self, E_Type, name, short_title): return "%s %s" % \ (self.__super._default_title (E_Type, name, short_title), name)
class TOP_MOM_E_Type(_E_Type_): """Directory displaying the instances of one E_Type.""" _real_name = "E_Type" admin_args = {} et_map_name = "manager" sort_key = TFL.Sorted_By("-date.start", "perma_name") _admin = None def __init__(self, **kw): self.__super.__init__(**kw) if self.admin_args: if "sort_key" in self.admin_args: self.sort_key = self.admin_args["sort_key"] self._admin = self._admin_page(self.admin_args) # end def __init__ def _admin_page(self, admin_args): m_kw = admin_args.copy() short_title = _T("Admin") title = m_kw.pop \ ( "title" , "%s: %s" % (self.title.rstrip ("."), _T ("Administration")) ) ETM = m_kw.pop("ETM", self.ETM) Type = m_kw.pop("Type", GTW.RST.TOP.MOM.Admin.E_Type) return Type \ ( name = "admin" , parent = self , short_title = short_title , title = title , ETM = ETM , ** m_kw )
def __lt__(self, rhs): sk = TFL.Sorted_By() return sk(self.name) < sk(getattr(rhs, "name", rhs))
def _get_events(self, date): evm = self.event_manager return sorted \ ( (_Event_Wrapper_ (self, ev) for ev in evm.query (date = date)) , key = TFL.Sorted_By ("time", "short_title") )
class _Gallery_(_Ancestor): dir_template_name = "gallery" nav_off_canvas = True page_template_name = "photo" sort_key = TFL.Sorted_By("number") static_page_suffix = "/index.html" _greet_entry = None @property @getattr_safe def entries_transitive(self): yield from self.entries # end def entries_transitive @Once_Property @getattr_safe def max_height_photo(self): if self.pictures: return max(p.photo.height for p in self.pictures) return 0 # end def max_height_photo @Once_Property @getattr_safe def max_height_thumb(self): if self.pictures: return max(p.thumb.height for p in self.pictures) return 0 # end def max_height_thumb @Once_Property @getattr_safe def max_width_photo(self): if self.pictures: return max(p.photo.width for p in self.pictures) return 0 # end def max_width_photo @Once_Property @getattr_safe def max_width_thumb(self): if self.pictures: return max(p.thumb.width for p in self.pictures) return 0 # end def max_width_thumb @property @getattr_safe def pictures(self): result = self.entries if result and not isinstance(result[-1], self.Entity): result = result[:-1] return result # end def pictures def is_current_dir(self, page): return False # end def is_current_dir def is_current_page(self, page): return \ ( not self.hidden and self.href_dynamic in (page.href_dynamic, page.parent.href_dynamic) )
def referral_query_unbound (self) : sk = TFL.Sorted_By ("perma_name") return self.scope.SWP.Referral.query \ (Q.parent_url == Q.BVAR.parent_url, sort_key = sk)
def _fixed_order_by_str_(x): return TFL.Sorted_By(x)
def _fixed_order_by_tuple(xs): if len(xs) == 1: return fixed_order_by(xs[0]) else: return TFL.Sorted_By(*tuple(fixed_order_by(x) for x in xs))
class _RST_MOM_Mixin_ (Base_Mixin) : """Mixin for MOM-specific RST classes dealing with entities living in a scope.""" _real_name = "Mixin" _exclude_robots = True _objects = [] _sort_key_cid_reverse = TFL.Sorted_By ("-cid") show_rels = None @Once_Property @getattr_safe def ETM (self) : result = self._ETM if isinstance (result, pyk.string_types) : result = self.top.scope [result] return result # end def ETM @property @getattr_safe def change_info (self) : result = self._change_info if result is None : result = self._change_info = self._get_change_info () return result # end def change_info @property @getattr_safe def objects (self) : return self._get_objects () # end def objects @property @getattr_safe def query_filters (self) : return self.query_filters_d + self.query_filters_s # end def query_filters @property @getattr_safe def query_filters_d (self) : """Dynamic query filters""" return tuple () # end def query_filters_d @Once_Property @getattr_safe def query_filters_s (self) : """Static query filters: evaluated only once and cached""" return tuple () # end def query_filters_s @property @getattr_safe def _change_info (self) : return self.top._change_infos.get (self._change_info_key) # end def _change_info @_change_info.setter def _change_info (self, value) : self.top._change_infos [self._change_info_key] = value # end def _change_info @property @getattr_safe def _change_info_key (self) : return self.href # end def _change_info_key @property @getattr_safe def _old_cid (self) : return self.top._old_cids.get (self._change_info_key, -1) # end def _old_cid @_old_cid.setter def _old_cid (self, value) : self.top._old_cids [self._change_info_key] = value # end def _old_cid def add_doc_link_header (self, response) : top = self.top etd = top.ET_Map.get (self.type_name) if etd : doc = getattr (etd, "doc", None) or getattr (etd, "rest_doc", None) if doc is not None : response.add_link ("doc", doc.abs_href) # end def add_doc_link_header def pid_query_request (self, pid, E_Type = None, raise_not_found = True) : if E_Type is None : E_Type = self.E_Type scope = self.top.scope Status = self.Status try : ipid = int (pid) except (ValueError, TypeError) : pass else : try : result = scope.pid_query (ipid) except LookupError as exc : self._check_pid_gone (ipid, E_Type, scope) else : if result is None : self._check_pid_gone (ipid, E_Type, scope) elif isinstance (result, E_Type) : return result elif raise_not_found : error = \ ( _T ("`%s` refers to %s, not %s") % (pid, _T (result.E_Type.ui_name), _T (E_Type.ui_name)) ) raise Status.Bad_Request (error) if raise_not_found : error = (_T ("%s `%s` doesn't exist!") % (_T (E_Type.ui_name), pid)) raise Status.Not_Found (error) # end def pid_query_request def query_changes (self) : scope = self.top.scope cqfs = self.change_query_filters if cqfs is not None : return scope.query_changes \ (* cqfs).order_by (self._sort_key_cid_reverse) # end def query_changes def _changed_cid (self) : change_info = self.change_info cid = change_info.cid if change_info else None if self._old_cid != cid : return cid # end def _changed_cid def _change_query_types (self, E_Type) : if E_Type.is_partial : result = set (E_Type.children_np) else : result = set (E_Type.children) result.add (E_Type.type_name) return result # end def _change_query_types def _check_pid_gone (self, pid, E_Type, scope) : lc = scope.query_changes \ (pid = pid).order_by (self._sort_key_cid_reverse).first () if lc is not None : user = _T ("anonymous") if lc.user : try : user = scope.pid_query (lc.user) except Exception : user = lc.user else : if user.person : user = user.person user = str (user.FO) error = \ ( _T ("%s `%s` doesn't exist anymore!") % (_T (E_Type.ui_name), pid) ) info = \ ( _T ("It was deleted by user `%s` on %s") % (user, lc.time.strftime ("%Y-%m-%d %H:%M")) ) raise self.Status.Gone (error, info = info) # end def _check_pid_gone def _get_change_info (self) : result = None qc = self.query_changes () if qc is not None : lc = qc.first () if lc is not None : lm = lc.time.replace (microsecond = 0) result = TFL.Record \ ( cid = lc.cid , etag = str (lc.cid) , last_modified = lm ) return result # end def _get_change_info def _get_objects (self) : cid = self._changed_cid () if cid is not None : self._objects = self.query ().all () self._old_cid = cid return self._objects # end def _get_objects @TFL.Contextmanager def _handle_method_context (self, method, request, response) : with self.__super._handle_method_context (method, request, response) : with self.LET (_change_info = self._get_change_info ()) : with request.LET (_rst_seen = set ()) : yield
def children(self): return sorted \ (self.history, key = TFL.Sorted_By ("type_name", "pid", "cid"))