def _wizcb_aent_init(wizard, model, req): def _wizcb_aent_submit(wiz, em, step, act, val, req): sess = DBSession() em = ExtModel(AccessEntity) obj = AccessEntity() # Work around field name clash if 'state' in val: del val['state'] em.set_values(obj, val, req, True) sess.add(obj) return { 'do' : 'close', 'reload' : True } wizard.steps.append(Step( ExternalWizardField('AccessEntity', 'password'), ExternalWizardField('AccessEntity', 'stash'), ExternalWizardField('AccessEntity', 'rate'), id='ent_accessentity1', title=_('Access entity properties'), on_prev='generic', on_submit=_wizcb_aent_submit ))
class Host(Base): """ Host object. """ __tablename__ = 'hosts_def' __table_args__ = (Comment('Hosts'), Index('hosts_def_u_hostname', 'domainid', 'name', unique=True), Index('hosts_def_i_hgid', 'hgid'), Index('hosts_def_i_entityid', 'entityid'), Index('hosts_def_i_aliasid', 'aliasid'), Index('hosts_def_i_cby', 'cby'), Index('hosts_def_i_mby', 'mby'), Trigger('before', 'insert', 't_hosts_def_bi'), Trigger('before', 'update', 't_hosts_def_bu'), Trigger('after', 'insert', 't_hosts_def_ai'), Trigger('after', 'update', 't_hosts_def_au'), Trigger('after', 'delete', 't_hosts_def_ad'), { 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8', 'info': { 'cap_menu': 'BASE_HOSTS', 'cap_read': 'HOSTS_LIST', 'cap_create': 'HOSTS_CREATE', 'cap_edit': 'HOSTS_EDIT', 'cap_delete': 'HOSTS_DELETE', 'menu_name': _('Hosts'), 'show_in_menu': 'modules', 'menu_main': True, 'default_sort': ({ 'property': 'name', 'direction': 'ASC' }, ), 'grid_view': ('hostid', MarkupColumn(name='name', header_string=_('Name'), template='{__str__}', column_flex=3, sortable=True), 'domain', 'group', 'entity'), 'grid_hidden': ('hostid', 'domain'), 'form_view': ('name', 'domain', 'group', 'entity', 'original', 'aliastype', 'descr', 'ctime', 'cby', 'mtime', 'mby'), 'easy_search': ('name', ), 'detail_pane': ('netprofile_core.views', 'dpane_simple'), 'create_wizard': Wizard(Step('name', 'domain', 'entity', title=_('New host data')), Step('group', 'original', 'aliastype', 'descr', title=_('New host details')), title=_('Add new host')) } }) id = Column('hostid', UInt32(), Sequence('hosts_def_hostid_seq'), Comment('Host ID'), primary_key=True, nullable=False, info={'header_string': _('ID')}) group_id = Column('hgid', UInt32(), ForeignKey('hosts_groups.hgid', name='hosts_def_fk_hgid', onupdate='CASCADE'), Comment('Host group ID'), nullable=False, info={ 'header_string': _('Group'), 'filter_type': 'nplist', 'column_flex': 1 }) entity_id = Column('entityid', UInt32(), ForeignKey('entities_def.entityid', name='hosts_def_fk_entityid', onupdate='CASCADE', ondelete='CASCADE'), Comment('Entity ID'), nullable=False, info={ 'header_string': _('Entity'), 'filter_type': 'none', 'column_flex': 1 }) domain_id = Column('domainid', UInt32(), ForeignKey('domains_def.domainid', name='hosts_def_fk_domainid', onupdate='CASCADE'), Comment('Domain ID'), nullable=False, info={ 'header_string': _('Domain'), 'filter_type': 'nplist', 'column_flex': 2 }) name = Column(Unicode(255), Comment('Host Name'), nullable=False, info={'header_string': _('Name')}) original_id = Column('aliasid', UInt32(), ForeignKey('hosts_def.hostid', name='hosts_def_fk_aliasid', ondelete='CASCADE', onupdate='CASCADE'), Comment('Aliased host ID'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string': _('Aliased'), 'filter_type': 'nplist' }) alias_type = Column('aliastype', HostAliasType.db_type(), Comment('Host alias type'), nullable=False, default=HostAliasType.symbolic, server_default=HostAliasType.symbolic, info={'header_string': _('Alias Type')}) creation_time = Column('ctime', TIMESTAMP(), Comment('Time of creation'), nullable=True, default=None, server_default=FetchedValue(), info={ 'header_string': _('Created'), 'read_only': True }) modification_time = Column('mtime', TIMESTAMP(), Comment('Time of last modification'), CurrentTimestampDefault(on_update=True), nullable=False, info={ 'header_string': _('Modified'), 'read_only': True }) created_by_id = Column('cby', UInt32(), ForeignKey('users.uid', name='hosts_def_fk_cby', ondelete='SET NULL', onupdate='CASCADE'), Comment('Created by'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string': _('Created'), 'read_only': True }) modified_by_id = Column('mby', UInt32(), ForeignKey('users.uid', name='hosts_def_fk_mby', ondelete='SET NULL', onupdate='CASCADE'), Comment('Last modified by'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string': _('Modified'), 'read_only': True }) description = Column('descr', UnicodeText(), Comment('Host description'), nullable=True, default=None, server_default=text('NULL'), info={'header_string': _('Description')}) group = relationship('HostGroup', innerjoin=True, backref='hosts') entity = relationship('Entity', innerjoin=True, backref=backref('hosts', cascade='all, delete-orphan', passive_deletes=True)) domain = relationship('Domain', innerjoin=True, backref='hosts') original = relationship('Host', backref=backref('aliases', cascade='all, delete-orphan', passive_deletes=True), remote_side=[id]) created_by = relationship('User', foreign_keys=created_by_id, backref=backref('created_hosts', passive_deletes=True)) modified_by = relationship('User', foreign_keys=modified_by_id, backref=backref('modified_hosts', passive_deletes=True)) services = relationship('Service', backref=backref('host', innerjoin=True), cascade='all, delete-orphan', passive_deletes=True) @property def real(self): if not self.original: return self h = self while h.original: h = h.original return h def __str__(self): if self.domain: return '%s.%s' % (str(self.name), str(self.domain)) return str(self.name) @classmethod def resolve(cls, name, domain_aliases=True): parts = name.strip('.').split('.') num_parts = len(parts) if num_parts == 1: # TODO: support specifying default domain raise ValueError('Hostname must be fully qualified') variants = list(('.'.join(parts[:i]), '.'.join(parts[i:])) for i in range(1, num_parts)) sess = DBSession() for host_part, domain_part in variants: domain = Domain.resolve(domain_part, domain_aliases=domain_aliases) if domain is None: continue try: return sess.query(Host).filter(Host.domain == domain, Host.name == host_part).one() except NoResultFound: pass
class PDNSTemplate(Base): """ PDNS Association table for both template and field types """ __tablename__ = 'pdns_templates' __table_args__ = ( Comment('PowerDNS Template-Field Association Table'), { 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8', 'info': { 'cap_menu': 'BASE_DOMAINS', # 'cap_read' : 'DOMAINS_LIST', # 'cap_create' : 'DOMAINS_CREATE', # 'cap_edit' : 'DOMAINS_EDIT', # 'cap_delete' : 'DOMAINS_DELETE', 'show_in_menu': 'admin', 'menu_name': _('PDNS Templates'), 'menu_order': 50, 'grid_view': ('template', 'field', 'defaultvalues'), 'form_view': ('template', 'field', 'defaultvalues'), 'easy_search': ('template', ), 'detail_pane': ('netprofile_core.views', 'dpane_simple'), 'create_wizard': Wizard(Step( 'template', 'field', id='generic', title=_('Add new template'), on_submit=_wizcb_pdnstemplate_submit('PDNSTemplate')), title=_('New domain template'), validator='CreateDomainTemplate') } }) id = Column('relationid', UInt32(), Sequence('pdns_templates_relationid_seq'), Comment('ID'), primary_key=True, nullable=False, info={'header_string': _('ID')}) templateid = Column('templ_id', UInt32(), ForeignKey('pdns_templatetypes.id'), info={'header_string': _('Template')}) fieldid = Column('field_id', UInt32(), ForeignKey('pdns_recordtypes.id'), info={ 'header_string': _('Record'), 'editor_xtype': 'gridfield' }) defaultvalues = Column('defvalues', Unicode(255), Comment('Default Values'), nullable=True, default=None, info={'header_string': _('Default Values')}) template = relationship("PDNSTemplateType", backref=backref('template_fields', cascade="all, delete-orphan")) field = relationship("PDNSFieldType") def __str__(self): return '%s %s Record' % (self.template.name, self.field.name)
def dyn_ticket_uwiz(params, request): tid = int(params['ticketid']) sess = DBSession() loc = request.localizer trans = [{ 'name': 'ttrid', 'boxLabel': '<div class="np-xradiolabel"><div class="title">%s</div>%s</div>' % (html_escape(loc.translate(_('No changes')), True), html_escape(loc.translate(_('Do not change ticket state.')), True)), 'inputValue': '', 'checked': True }] ticket = sess.query(Ticket).get(tid) if ticket is None: raise KeyError('Invalid ticket ID') model = ExtModel(Ticket) ch_model = ExtModel(TicketChange) fields = [] if request.has_permission('ENTITIES_LIST'): fields.append( ExternalWizardField( model, 'entity', value=ticket.entity, extra_config={ 'readOnly': not bool(request.has_permission('TICKETS_CHANGE_ENTITY')) })) if request.has_permission('TICKETS_CHANGE_STATE'): for tr in ticket.state.transitionmap_to: label = '<div class="np-xradiolabel"><div class="title">%s</div>%s</div>' % ( html_escape(tr.name, True), html_escape((tr.description if tr.description else ''), True)) trans.append({ 'name': 'ttrid', 'boxLabel': label, 'inputValue': tr.id }) fields.append( ExtJSWizardField({ 'xtype': 'radiogroup', 'fieldLabel': loc.translate(_('Transition')), 'vertical': True, 'columns': 1, 'items': trans })) if request.has_permission('TICKETS_CHANGE_FLAGS'): fields.append(ExternalWizardField(model, 'flags', value=ticket.flags)) if request.has_permission('USERS_LIST'): fields.append( ExternalWizardField( model, 'assigned_user', value=ticket.assigned_user, extra_config={ 'readOnly': not bool(request.has_permission('TICKETS_CHANGE_UID')) })) if request.has_permission('GROUPS_LIST'): fields.append( ExternalWizardField( model, 'assigned_group', value=ticket.assigned_group, extra_config={ 'readOnly': not bool(request.has_permission('TICKETS_CHANGE_GID')) })) fields.extend( (ExternalWizardField(model, 'ticketid', value=ticket.id), CompositeWizardField( ExternalWizardField( model, 'assigned_time', value=ticket.assigned_time, extra_config={ 'readOnly': not bool(request.has_permission('TICKETS_CHANGE_DATE')) }), ExtJSWizardField({ 'xtype': 'button', 'text': 'Schedule', 'iconCls': 'ico-schedule', 'margin': '0 0 0 2', 'itemId': 'btn_sched' })), ExternalWizardField( model, 'archived', value=ticket.archived, extra_config={ 'readOnly': not bool(request.has_permission('TICKETS_ARCHIVAL')) }), ExternalWizardField(ch_model, 'show_client', value=False))) if request.has_permission('TICKETS_COMMENT'): fields.append(ExternalWizardField(ch_model, 'comments')) wiz = Wizard(Step(*fields), title=_('Update ticket')) ret = { 'success': True, 'fields': wiz.get_cfg(model, request, use_defaults=True) } return ret
class StashIO(Base): """ Stash I/O operation object. """ __tablename__ = 'stashes_io_def' __table_args__ = ( Comment('Stashes input/output operations'), Index('stashes_io_def_i_siotypeid', 'siotypeid'), Index('stashes_io_def_i_stashid', 'stashid'), Index('stashes_io_def_i_currid', 'currid'), Index('stashes_io_def_i_uid', 'uid'), Index('stashes_io_def_i_entityid', 'entityid'), Index('stashes_io_def_i_ts', 'ts'), Trigger('before', 'insert', 't_stashes_io_def_bi'), Trigger('after', 'insert', 't_stashes_io_def_ai'), { 'mysql_engine' : 'InnoDB', 'mysql_charset' : 'utf8', 'info' : { 'cap_menu' : 'BASE_STASHES', 'cap_read' : 'STASHES_IO', 'cap_create' : 'STASHES_IO', 'cap_edit' : '__NOPRIV__', 'cap_delete' : '__NOPRIV__', 'menu_name' : _('Operations'), 'show_in_menu' : 'modules', 'default_sort' : ({ 'property': 'ts', 'direction': 'DESC' },), 'grid_view' : ('sioid', 'type', 'stash', 'entity', 'user', 'ts', 'currency', 'diff'), 'grid_hidden' : ('sioid', 'currency'), 'form_view' : ('type', 'stash', 'currency', 'entity', 'user', 'ts', 'diff', 'descr'), 'extra_data' : ('formatted_difference',), 'detail_pane' : ('netprofile_core.views', 'dpane_simple'), 'create_wizard' : Wizard( Step( 'stash', 'type', 'diff', 'descr', id='generic', on_submit=_wizcb_stashio_submit ), title=_('Add new operation') ) } } ) id = Column( 'sioid', UInt32(), Sequence('stashes_io_def_sioid_seq'), Comment('Stash I/O ID'), primary_key=True, nullable=False, info={ 'header_string' : _('ID') } ) type_id = Column( 'siotypeid', UInt32(), Comment('Stash I/O type ID'), ForeignKey('stashes_io_types.siotypeid', name='stashes_io_def_fk_siotypeid', ondelete='CASCADE', onupdate='CASCADE'), nullable=False, info={ 'header_string' : _('Type'), 'filter_type' : 'nplist', 'editor_xtype' : 'simplemodelselect', 'editor_config' : { 'extraParams' : { '__ffilter' : [{ 'property' : 'oper_visible', 'operator' : 'eq', 'value' : True }]} }, 'column_flex' : 2 } ) stash_id = Column( 'stashid', UInt32(), Comment('Stash ID'), ForeignKey('stashes_def.stashid', name='stashes_io_def_fk_stashid', ondelete='CASCADE', onupdate='CASCADE'), nullable=False, info={ 'header_string' : _('Stash'), 'filter_type' : 'none', 'column_flex' : 2 } ) currency_id = Column( 'currid', UInt32(), Comment('Currency ID'), ForeignKey('currencies_def.currid', name='stashes_io_def_fk_currid', onupdate='CASCADE'), # ondelete=RESTRICT nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Currency'), 'editor_xtype' : 'simplemodelselect', 'editor_config' : { 'extraParams' : { '__ffilter' : [{ 'property' : 'oper_visible', 'operator' : 'eq', 'value' : True }]} }, 'filter_type' : 'nplist' } ) user_id = Column( 'uid', UInt32(), Comment('User ID'), ForeignKey('users.uid', name='stashes_io_def_fk_uid', ondelete='SET NULL', onupdate='CASCADE'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Operator'), 'filter_type' : 'nplist' } ) entity_id = Column( 'entityid', UInt32(), Comment('Related entity ID'), ForeignKey('entities_def.entityid', name='stashes_io_def_fk_entityid', ondelete='SET NULL', onupdate='CASCADE'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Entity'), 'filter_type' : 'none', 'column_flex' : 1 } ) timestamp = Column( 'ts', TIMESTAMP(), Comment('Time stamp of operation'), CurrentTimestampDefault(), nullable=False, info={ 'header_string' : _('Date'), 'column_flex' : 1 } ) difference = Column( 'diff', Money(), Comment('Operation result'), nullable=False, info={ 'header_string' : _('Change'), 'column_xtype' : 'templatecolumn', 'template' : '{formatted_difference}' } ) description = Column( 'descr', UnicodeText(), Comment('Description'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Description') } ) type = relationship( 'StashIOType', innerjoin=True, lazy='joined', backref=backref( 'ios', cascade='all, delete-orphan', passive_deletes=True ) ) stash = relationship( 'Stash', innerjoin=True, backref=backref( 'ios', cascade='all, delete-orphan', passive_deletes=True ) ) currency = relationship( 'Currency', lazy='joined', backref=backref( 'ios', passive_deletes='all' ) ) user = relationship( 'User', backref=backref( 'stash_ios', passive_deletes=True ) ) entity = relationship( 'Entity', backref=backref( 'stash_ios', passive_deletes=True ) ) def __str__(self): return '%s: %s' % ( str(self.stash), str(self.type) ) def formatted_difference(self, req): return money_format(req, self.difference, currency=self.currency)
class FuturePayment(Base): """ Future payment object. """ __tablename__ = 'futures_def' __table_args__ = ( Comment('Future payments'), Index('futures_def_i_futures', 'state', 'ptime'), Index('futures_def_i_entityid', 'entityid'), Index('futures_def_i_stashid', 'stashid'), Index('futures_def_i_cby', 'cby'), Index('futures_def_i_mby', 'mby'), Index('futures_def_i_pby', 'pby'), Trigger('before', 'insert', 't_futures_def_bi'), Trigger('before', 'update', 't_futures_def_bu'), Trigger('after', 'insert', 't_futures_def_ai'), Trigger('after', 'update', 't_futures_def_au'), Trigger('after', 'delete', 't_futures_def_ad'), { 'mysql_engine' : 'InnoDB', 'mysql_charset' : 'utf8', 'info' : { 'cap_menu' : 'BASE_FUTURES', 'cap_read' : 'FUTURES_LIST', 'cap_create' : 'FUTURES_CREATE', 'cap_edit' : 'FUTURES_EDIT', 'cap_delete' : '__NOPRIV__', # TODO: APPROVE/CANCEL 'menu_name' : _('Promised Payments'), 'default_sort' : ({ 'property': 'ctime', 'direction': 'DESC' },), 'grid_view' : ('futureid', 'entity', 'stash', 'diff', 'state', 'ctime'), 'grid_hidden' : ('futureid',), 'form_view' : ( 'entity', 'stash', 'diff', 'state', 'origin', 'ctime', 'created_by', 'mtime', 'modified_by', 'ptime', 'paid_by' ), 'detail_pane' : ('netprofile_core.views', 'dpane_simple'), 'create_wizard' : Wizard( Step( 'entity', 'stash', 'diff', 'descr', id='generic', on_submit=_wizcb_future_submit ), title=_('Add new promised payment') ) } } ) id = Column( 'futureid', UInt32(), Sequence('futures_def_futureid_seq'), Comment('Future payment ID'), primary_key=True, nullable=False, info={ 'header_string': _('ID') } ) entity_id = Column( 'entityid', UInt32(), Comment('Entity ID'), ForeignKey('entities_def.entityid', name='futures_def_fk_entityid', onupdate='CASCADE', ondelete='SET NULL'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Entity'), 'filter_type' : 'none', 'column_flex' : 2 } ) stash_id = Column( 'stashid', UInt32(), Comment('Stash ID'), ForeignKey('stashes_def.stashid', name='futures_def_fk_stashid', ondelete='CASCADE', onupdate='CASCADE'), nullable=False, info={ 'header_string' : _('Stash'), 'filter_type' : 'none', 'column_flex' : 2 } ) difference = Column( 'diff', Money(), Comment('Payment result'), nullable=False, default=0.0, server_default=text('0.0'), info={ 'header_string' : _('Change') } ) state = Column( FuturePaymentState.db_type(), Comment('Active / Paid / Cancelled'), nullable=False, default=FuturePaymentState.active, server_default=FuturePaymentState.active, info={ 'header_string' : _('State') } ) origin = Column( FuturePaymentOrigin.db_type(), Comment('Origin of payment'), nullable=False, default=FuturePaymentOrigin.operator, server_default=FuturePaymentOrigin.operator, info={ 'header_string' : _('Origin') } ) creation_time = Column( 'ctime', TIMESTAMP(), Comment('Creation timestamp'), nullable=True, default=None, server_default=FetchedValue(), info={ 'header_string' : _('Created'), 'read_only' : True } ) modification_time = Column( 'mtime', TIMESTAMP(), Comment('Last modification timestamp'), CurrentTimestampDefault(on_update=True), nullable=False, info={ 'header_string' : _('Modified'), 'read_only' : True } ) payment_time = Column( 'ptime', TIMESTAMP(), Comment('Payment timestamp'), nullable=True, default=None, server_default=FetchedValue(), info={ 'header_string' : _('Confirmed'), 'read_only' : True } ) created_by_id = Column( 'cby', UInt32(), ForeignKey('users.uid', name='futures_def_fk_cby', ondelete='SET NULL', onupdate='CASCADE'), Comment('Created by'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Created'), 'read_only' : True } ) modified_by_id = Column( 'mby', UInt32(), ForeignKey('users.uid', name='futures_def_fk_mby', ondelete='SET NULL', onupdate='CASCADE'), Comment('Modified by'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Modified'), 'read_only' : True } ) paid_by_id = Column( 'pby', UInt32(), ForeignKey('users.uid', name='futures_def_fk_pby', ondelete='SET NULL', onupdate='CASCADE'), Comment('Payment confirmed by'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Confirmed'), 'read_only' : True } ) description = Column( 'descr', UnicodeText(), Comment('Description'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Description') } ) stash = relationship( 'Stash', innerjoin=True, backref=backref( 'futures', cascade='all, delete-orphan', passive_deletes=True ) ) entity = relationship( 'Entity', backref=backref( 'stash_futures', passive_deletes=True ) ) created_by = relationship( 'User', foreign_keys=created_by_id, backref=backref( 'created_futures', passive_deletes=True ) ) modified_by = relationship( 'User', foreign_keys=modified_by_id, backref=backref( 'modified_futures', passive_deletes=True ) ) paid_by = relationship( 'User', foreign_keys=paid_by_id, backref=backref( 'paid_futures', passive_deletes=True ) ) def __str__(self): return '%s: %s' % ( str(self.stash), str(self.difference) )
class House(Base): """ House object. Used for anything with an exact address. """ @classmethod def _filter_hgroup(cls, query, value): if not isinstance(value, list): value = [value] return query.filter(House.id.in_( DBSession().query(HouseGroupMapping.house_id)\ .filter(HouseGroupMapping.group_id.in_(value)) )) @classmethod def _filter_address(cls, query, value): if not isinstance(value, dict): return query if 'streetid' in value: val = int(value['streetid']) if val > 0: query = query.filter(House.street_id == val) elif 'districtid' in value: val = int(value['districtid']) if val > 0: query = query.join(House.street).filter(or_( Street.district_id == val, House.district_id == val )) elif 'cityid' in value: val = int(value['cityid']) if val > 0: query = query.join(House.street).filter(Street.city_id == val) return query __tablename__ = 'addr_houses' __table_args__ = ( Comment('Houses'), Index('addr_houses_u_house', 'streetid', 'number', 'num_slash', 'num_suffix', 'building', unique=True), Index('addr_houses_i_districtid', 'districtid'), { 'mysql_engine' : 'InnoDB', 'mysql_charset' : 'utf8', 'info' : { 'cap_menu' : 'BASE_GEO', 'cap_read' : 'GEO_LIST', 'cap_create' : 'GEO_CREATE', 'cap_edit' : 'GEO_EDIT', 'cap_delete' : 'GEO_DELETE', 'show_in_menu' : 'admin', 'menu_name' : _('Houses'), 'default_sort' : ( { 'property' : 'streetid', 'direction' : 'ASC' }, { 'property' : 'number', 'direction' : 'ASC' }, { 'property' : 'num_slash', 'direction' : 'ASC' }, { 'property' : 'num_suffix', 'direction' : 'ASC' }, { 'property' : 'building', 'direction' : 'ASC' } ), 'grid_view' : ( 'houseid', 'street', 'number', 'num_slash', 'num_suffix', 'building', 'entrnum', 'postindex' ), 'grid_hidden' : ('houseid',), 'form_view' : ( 'street', 'number', 'num_slash', 'num_suffix', 'building', 'district', 'house_groups', 'entrnum', 'postindex', 'descr' ), 'easy_search' : ('number',), 'detail_pane' : ('netprofile_core.views', 'dpane_simple'), 'extra_search' : ( CheckboxGroupFilter('hg', _filter_hgroup, title=_('House Group'), data='NetProfile.store.geo.HouseGroup', value_field='ahgid', display_field='name' ), AddressFilter('address', _filter_address, title=_('Address'), show_houses=False ) ), 'create_wizard' : Wizard( Step('street', 'number', 'num_slash', 'num_suffix', 'building', title=_('Basic house data')), Step('house_groups', 'entrnum', 'postindex', title=_('Additional house data')), title=_('Add new house') ) } } ) id = Column( 'houseid', UInt32(), Sequence('addr_houses_houseid_seq'), Comment('House ID'), primary_key=True, nullable=False, info={ 'header_string' : _('ID') } ) street_id = Column( 'streetid', UInt32(), ForeignKey('addr_streets.streetid', name='addr_houses_fk_streetid', ondelete='CASCADE', onupdate='CASCADE'), Comment('Street ID'), nullable=False, info={ 'header_string' : _('Street'), 'filter_type' : 'nplist', 'column_flex' : 1 } ) district_id = Column( 'districtid', UInt32(), ForeignKey('addr_districts.districtid', name='addr_houses_fk_districtid', ondelete='SET NULL', onupdate='CASCADE'), Comment('District ID'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('District'), 'filter_type' : 'nplist', 'column_flex' : 1 } ) number = Column( UInt16(), Comment('House number'), nullable=False, default=0, server_default=text('0'), info={ 'header_string' : _('Number') } ) building = Column( UInt16(), Comment('House building'), nullable=False, default=0, server_default=text('0'), info={ 'header_string' : _('Building') } ) second_number = Column( 'num_slash', UInt16(), Comment('Second house number'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Second Num.') } ) number_suffix = Column( 'num_suffix', Unicode(32), Comment('House number suffix'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Num. Suffix') } ) entrances = Column( 'entrnum', UInt8(), Comment('Number of entrances'), nullable=False, default=1, server_default=text('1'), info={ 'header_string' : _('Entr. #') } ) postal_code = Column( 'postindex', Unicode(8), Comment('Postal code'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Postal Code') } ) description = Column( 'descr', UnicodeText(), Comment('House description'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Description') } ) places = relationship( 'Place', backref=backref('house', innerjoin=True), cascade='all, delete-orphan', passive_deletes=True ) house_groupmap = relationship( 'HouseGroupMapping', backref=backref('house', innerjoin=True), cascade='all, delete-orphan', passive_deletes=True ) user_locations = relationship( 'UserLocation', backref='house', cascade='all, delete-orphan', passive_deletes=True ) house_groups = association_proxy( 'house_groupmap', 'group', creator=lambda v: HouseGroupMapping(group=v) ) @classmethod def __augment_query__(cls, sess, query, params, req): flist = [] if '__filter' in params: flist.extend(params['__filter']) if '__ffilter' in params: flist.extend(params['__ffilter']) for flt in flist: prop = flt.get('property', None) oper = flt.get('operator', None) value = flt.get('value', None) if prop == 'xdistrictid': if oper in ('eq', '=', '==', '==='): query = query.join(House.street).options(contains_eager(House.street)) query = query.filter(or_( House.district_id == int(value), Street.district_id == int(value) )) if prop == 'cityid': if oper in ('eq', '=', '==', '==='): query = query.join(House.street).options(contains_eager(House.street)) query = query.filter(Street.city_id == int(value)) return query @classmethod def __augment_result__(cls, sess, res, params, req): populate_related_list( res, 'id', 'house_groupmap', HouseGroupMapping, sess.query(HouseGroupMapping), None, 'house_id' ) return res def __str__(self): loc = str req = getattr(self, '__req__', None) if req: loc = req.localizer.translate l = [str(self.street), str(self.number)] if self.number_suffix: l.append(self.number_suffix) if self.second_number: l.append('/' + str(self.second_number)) if self.building: l.append(loc(_('bld.'))) l.append(str(self.building)) return ' '.join(l)
class Domain(Base): """ Domain object. """ __tablename__ = 'domains_def' __table_args__ = ( Comment('Domains'), Index('domains_def_u_domain', 'parentid', 'name', unique=True), Trigger('after', 'insert', 't_domains_def_ai'), Trigger('after', 'update', 't_domains_def_au'), Trigger('after', 'delete', 't_domains_def_ad'), { 'mysql_engine' : 'InnoDB', 'mysql_charset' : 'utf8', 'info' : { 'cap_menu' : 'BASE_DOMAINS', 'cap_read' : 'DOMAINS_LIST', 'cap_create' : 'DOMAINS_CREATE', 'cap_edit' : 'DOMAINS_EDIT', 'cap_delete' : 'DOMAINS_DELETE', 'show_in_menu' : 'modules', 'menu_name' : _('Domains'), 'menu_main' : True, 'default_sort' : ({ 'property': 'name' ,'direction': 'ASC' },), 'grid_view' : ( 'domainid', MarkupColumn( name='name', header_string=_('Name'), template='{__str__}', column_flex=1, sortable=True ), 'parent', MarkupColumn( name='state', header_string=_('State'), template=TemplateObject('netprofile_domains:templates/domain_icons.mak'), cell_class='np-nopad', column_width=60, column_resizable=False ) ), 'grid_hidden' : ('domainid',), 'form_view' : ( 'name', 'parent', 'enabled', 'public', 'signed', 'soa_refresh', 'soa_retry', 'soa_expire', 'soa_minimum', 'spf_gen', 'spf_rule', 'spf_errmsg', 'dkim_name', 'dkim_data', 'dkim_test', 'dkim_subdomains', 'dkim_strict', 'dmarc_trailer', 'descr' ), 'easy_search' : ('name', 'descr'), 'detail_pane' : ('netprofile_core.views', 'dpane_simple'), 'create_wizard' : Wizard( Step('name', 'parent', 'enabled', 'public', 'signed', 'descr', title=_('Domain info')), Step('soa_refresh', 'soa_retry', 'soa_expire', 'soa_minimum', 'dkim_name', 'dkim_data', title=_('DNS options')), title=_('Add new domain') ) } } ) id = Column( 'domainid', UInt32(), Sequence('domains_def_domainid_seq'), Comment('Domain ID'), primary_key=True, nullable=False, info={ 'header_string' : _('ID') } ) parent_id = Column( 'parentid', UInt32(), ForeignKey('domains_def.domainid', name='domains_def_fk_parentid', onupdate='CASCADE'), Comment('Parent domain ID'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Parent'), 'column_flex' : 1 } ) name = Column( Unicode(255), Comment('Domain name'), nullable=False, info={ 'header_string' : _('Name') } ) enabled = Column( NPBoolean(), Comment('Is domain enabled?'), nullable=False, default=True, server_default=npbool(True), info={ 'header_string' : _('Enabled') } ) public = Column( NPBoolean(), Comment('Is domain visible to outsiders?'), nullable=False, default=False, server_default=npbool(False), info={ 'header_string' : _('Public') } ) signed = Column( NPBoolean(), Comment('Needs DNSSEC signing?'), nullable=False, default=False, server_default=npbool(False), info={ 'header_string' : _('Signed') } ) soa_refresh = Column( UInt32(), Comment('SOA refresh field'), nullable=False, default=3600, info={ 'header_string' : _('SOA Refresh') } ) soa_retry = Column( UInt32(), Comment('SOA retry field'), nullable=False, default=300, info={ 'header_string' : _('SOA Retry') } ) soa_expire = Column( UInt32(), Comment('SOA expire field'), nullable=False, default=1814400, info={ 'header_string' : _('SOA Expire') } ) soa_minimum = Column( UInt32(), Comment('SOA minimum field'), nullable=False, default=3600, info={ 'header_string' : _('SOA Minimum') } ) serial_date = Column( Date(), Comment('Domain serial date'), nullable=False, info={ 'header_string' : _('Serial Date'), 'secret_value' : True } ) serial_revision = Column( 'serial_rev', UInt8(), Comment('Domain serial revision'), nullable=False, default=1, info={ 'header_string' : _('Serial Revision'), 'secret_value' : True } ) dkim_name = Column( ASCIIString(255), Comment('DKIM public key name'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('DKIM Name') } ) dkim_data = Column( ASCIIText(), Comment('DKIM public key body'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('DKIM Key') } ) dkim_test = Column( NPBoolean(), Comment('Use DKIM in test mode'), nullable=False, default=False, server_default=npbool(False), info={ 'header_string' : _('DKIM Test') } ) dkim_subdomains = Column( NPBoolean(), Comment('Propagate DKIM rules to subdomains'), nullable=False, default=False, server_default=npbool(False), info={ 'header_string' : _('DKIM in Subdomains') } ) dkim_strict = Column( NPBoolean(), Comment('Use DKIM strict check and discard'), nullable=False, default=False, server_default=npbool(False), info={ 'header_string' : _('DKIM Strict') } ) spf_generate = Column( 'spf_gen', NPBoolean(), Comment('Generate SPF record'), nullable=False, default=True, server_default=npbool(True), info={ 'header_string' : _('Use SPF') } ) spf_rule = Column( ASCIIText(), Comment('Custom SPF rule'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Custom SPF Rule') } ) spf_error_message = Column( 'spf_errmsg', UnicodeText(), Comment('Custom SPF error explanation string'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('SPF Error') } ) dmarc_trailer = Column( ASCIIString(255), Comment('DMARC record trailer'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('DMARC Trailer') } ) description = Column( 'descr', UnicodeText(), Comment('Domain description'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Description') } ) children = relationship( 'Domain', backref=backref('parent', remote_side=[id]) ) @property def serial(self): if not self.serial_date: return str(self.serial_revision % 100) return '%s%02d' % ( self.serial_date.strftime('%Y%m%d'), (self.serial_revision % 100) ) def __str__(self): if self.parent: return '%s.%s' % ( str(self.name), str(self.parent) ) return str(self.name) @classmethod def resolve(cls, name, domain_aliases=True): name = name.strip('.') sess = DBSession() candidates = [(None, domain_candidates(name), None)] while len(candidates) > 0: old_candidates = candidates candidates = [] domain_cond = [] da_cond = [] for domain, names, suffix in old_candidates: if domain is None or isinstance(domain, Domain): domain_cond.append(and_( Domain.parent_id == (domain.id if domain else None), Domain.name.in_(names) )) if not domain_aliases: continue if domain is None or isinstance(domain, DomainAlias): da_cond.append(and_( DomainAlias.parent_id == (domain.id if domain else None), DomainAlias.name.in_(names) )) if len(domain_cond) > 0: for domain in sess.query(Domain).filter(or_(*domain_cond)): if suffix is None: domain_name = str(domain) else: domain_name = '.'.join((domain.name, suffix)) if name == domain_name: return domain offset = name.find('.' + domain_name) if offset > 0: left_part = name[:offset] candidates.append((domain, domain_candidates(left_part), domain_name)) if domain_aliases and len(da_cond) > 0: for da in sess.query(DomainAlias).filter(or_(*da_cond)): if suffix is None: domain_name = str(da) else: domain_name = '.'.join((da.name, suffix)) if name == domain_name: return da.domain offset = name.find('.' + domain_name) if offset > 0: left_part = name[:offset] dc = domain_candidates(left_part) candidates.extend(( (da, dc, domain_name), (da.domain, dc, domain_name) ))
class AccessEntity(Entity): """ Access entity object. """ DN_ATTR = 'uid' __tablename__ = 'entities_access' __table_args__ = ( Comment('Access entities'), Index('entities_access_i_stashid', 'stashid'), Index('entities_access_i_rateid', 'rateid'), Index('entities_access_i_aliasid', 'aliasid'), Index('entities_access_i_ipaddrid', 'ipaddrid'), Index('entities_access_i_ip6addrid', 'ip6addrid'), Index('entities_access_i_nextrateid', 'nextrateid'), Trigger('before', 'insert', 't_entities_access_bi'), Trigger('before', 'update', 't_entities_access_bu'), Trigger('after', 'update', 't_entities_access_au'), Trigger('after', 'delete', 't_entities_access_ad'), { 'mysql_engine' : 'InnoDB', 'mysql_charset' : 'utf8', 'info' : { 'cap_menu' : 'BASE_ENTITIES', 'cap_read' : 'ENTITIES_LIST', 'cap_create' : 'ENTITIES_CREATE', 'cap_edit' : 'ENTITIES_EDIT', 'cap_delete' : 'ENTITIES_DELETE', 'show_in_menu' : 'modules', 'menu_name' : _('Access Entities'), 'menu_parent' : 'entities', 'default_sort' : ({ 'property': 'nick' ,'direction': 'ASC' },), 'grid_view' : ( MarkupColumn( name='icon', header_string=' ', help_text=_('Entity icon'), column_width=22, column_name=_('Icon'), column_resizable=False, cell_class='np-nopad', template='<img class="np-block-img" src="{grid_icon}" />' ), 'entityid', 'nick', 'stash', 'rate' ), 'grid_hidden' : ('entityid',), 'form_view' : ( 'nick', 'parent', 'state', 'flags', 'password', 'stash', 'rate', 'next_rate', #'alias_of', 'ipv4_address', 'ipv6_address', 'ut_ingress', 'ut_egress', 'u_sec', 'qpend', 'access_state', 'pol_ingress', 'pol_egress', 'bcheck', 'pcheck', 'descr' ), 'easy_search' : ('nick',), 'extra_data' : ('grid_icon',), 'detail_pane' : ('netprofile_core.views', 'dpane_simple'), 'create_wizard' : Wizard( Step( 'nick', 'parent', 'state', 'flags', 'descr', id='generic', title=_('Generic entity properties'), ), Step( 'password', 'stash', 'rate', id='ent_access1', title=_('Access entity properties'), ), title=_('Add new access entity'), validator='CreateAccessEntity' ) } } ) __mapper_args__ = { 'polymorphic_identity' : 5 } id = Column( 'entityid', UInt32(), ForeignKey('entities_def.entityid', name='entities_access_fk_entityid', ondelete='CASCADE', onupdate='CASCADE'), Comment('Entity ID'), primary_key=True, nullable=False, info={ 'header_string' : _('ID') } ) password = Column( Unicode(255), Comment('Cleartext password'), nullable=False, info={ 'header_string' : _('Password'), 'secret_value' : True, 'editor_xtype' : 'passwordfield' } ) stash_id = Column( 'stashid', UInt32(), ForeignKey('stashes_def.stashid', name='entities_access_fk_stashid', onupdate='CASCADE'), Comment('Used stash ID'), nullable=False, info={ 'header_string' : _('Stash'), 'column_flex' : 3 } ) rate_id = Column( 'rateid', UInt32(), ForeignKey('rates_def.rateid', name='entities_access_fk_rateid', onupdate='CASCADE'), Comment('Used rate ID'), nullable=False, info={ 'header_string' : _('Rate'), 'filter_type' : 'nplist', 'column_flex' : 2 } ) alias_of_id = Column( 'aliasid', UInt32(), ForeignKey('entities_access.entityid', name='entities_access_fk_aliasid', ondelete='CASCADE', onupdate='CASCADE'), Comment('Aliased access entity ID'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Alias Of'), 'filter_type' : 'none' } ) next_rate_id = Column( 'nextrateid', UInt32(), ForeignKey('rates_def.rateid', name='entities_access_fk_nextrateid', ondelete='SET NULL', onupdate='CASCADE'), Comment('Next rate ID'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Next Rate'), 'filter_type' : 'nplist' } ) ipv4_address_id = Column( 'ipaddrid', UInt32(), ForeignKey('ipaddr_def.ipaddrid', name='entities_access_fk_ipaddrid', ondelete='SET NULL', onupdate='CASCADE'), Comment('IPv4 address ID'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('IPv4 Address') } ) ipv6_address_id = Column( 'ip6addrid', UInt64(), ForeignKey('ip6addr_def.ip6addrid', name='entities_access_fk_ip6addrid', ondelete='SET NULL', onupdate='CASCADE'), Comment('IPv6 address ID'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('IPv6 Address') } ) used_traffic_ingress = Column( 'ut_ingress', Traffic(), Comment('Used ingress traffic'), nullable=False, default=0, server_default=text('0'), info={ 'header_string' : _('Used Ingress'), 'read_only' : True } ) used_traffic_egress = Column( 'ut_egress', Traffic(), Comment('Used egress traffic'), nullable=False, default=0, server_default=text('0'), info={ 'header_string' : _('Used Egress'), 'read_only' : True } ) used_seconds = Column( 'u_sec', UInt32(), Comment('Used seconds'), nullable=False, default=0, server_default=text('0'), info={ 'header_string' : _('Used Seconds'), 'read_only' : True } ) quota_period_end = Column( 'qpend', TIMESTAMP(), Comment('End of quota period'), nullable=True, default=None, server_default=FetchedValue(), info={ 'header_string' : _('Ends'), 'read_only' : True } ) access_state = Column( 'state', UInt8(), Comment('Access code'), nullable=False, default=0, server_default=text('0'), info={ 'header_string' : _('Access Code'), 'choices' : AccessState, 'write_cap' : 'ENTITIES_ACCOUNTSTATE_EDIT' } ) policy_ingress = Column( 'pol_ingress', ASCIIString(255), Comment('Ingress traffic policy'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Ingress Policy') } ) policy_egress = Column( 'pol_egress', ASCIIString(255), Comment('Egress traffic policy'), nullable=True, default=None, server_default=text('NULL'), info={ 'header_string' : _('Egress Policy') } ) check_block_state = Column( 'bcheck', NPBoolean(), Comment('Check block state'), nullable=False, default=False, server_default=npbool(False), info={ 'header_string' : _('Check Blocks') } ) check_paid_services = Column( 'pcheck', NPBoolean(), Comment('Check paid services'), nullable=False, default=False, server_default=npbool(False), info={ 'header_string' : _('Check Services') } ) stash = relationship( 'Stash', innerjoin=True, backref='access_entities' ) rate = relationship( 'Rate', innerjoin=True, foreign_keys=rate_id, backref='access_entities' ) next_rate = relationship( 'Rate', foreign_keys=next_rate_id, backref=backref( 'pending_access_entities', passive_deletes=True ) ) alias_of = relationship( 'AccessEntity', foreign_keys=alias_of_id, remote_side=[id], backref='aliases' ) ipv4_address = relationship( 'IPv4Address', backref=backref( 'access_entities', passive_deletes=True ) ) ipv6_address = relationship( 'IPv6Address', backref=backref( 'access_entities', passive_deletes=True ) ) blocks = relationship( 'AccessBlock', backref=backref('entity', innerjoin=True), cascade='all, delete-orphan', passive_deletes=True ) def data(self, req): ret = super(AccessEntity, self).data if self.rate: ret['rate'] = str(self.rate) if self.next_rate: ret['nextrate'] = str(self.next_rate) if self.quota_period_end: ret['qpend'] = format_datetime(self.quota_period_end, locale=req.current_locale) ret['accessstate'] = self.access_state_string(req) if self.access_state == AccessState.ok.value: ret['accessimg'] = 'ok' elif self.access_state == AccessState.block_auto.value: ret['accessimg'] = 'stop' elif self.access_state == AccessState.block_manual.value: ret['accessimg'] = 'manual' else: ret['accessimg'] = 'misc' return ret def access_state_string(self, req): if self.access_state is None: return None return req.localizer.translate(AccessState.from_string(self.access_state).description) def grid_icon(self, req): return req.static_url('netprofile_access:static/img/access.png')