class DBShortMessage(item.Item): """ I represent a contact on the DB """ # (id integer, category integer, number text, date text, smstext text) typeName = 'DBShortMessage' schemaVersion = 1 date = attributes.timestamp(allowNone=False) number = attributes.text(allowNone=False) text = attributes.text(allowNone=False) where = attributes.integer(allowNone=False) def __repr__(self): args = (self.number, self.text, self.date) return '<DBShortMessage number="%s" text="%s" date="%s">' % args def __eq__(self, m): if isinstance(m, DBShortMessage): return (self.number == m.number and self.text == m.text and self.date == m.date) return False def __ne__(self, m): return not (self.number == m.number and self.text == m.text and self.date == m.date) def get_index(self): return self.storeID def get_number(self): return self.number def get_text(self): return self.text
class LoginMethod(Item): typeName = 'login_method' schemaVersion = 2 localpart = text(doc=""" A local-part of my user's identifier. """, indexed=True, allowNone=False) domain = text(doc=""" The domain part of my user's identifier. [XXX See TODO below] May be None (generally for "system" users). """, indexed=True) internal = boolean(doc=""" Flag indicating whether this is a method maintained by this server, or if it represents an external contact mechanism (such as a third-party email provider) """, allowNone=False) protocol = text(indexed=True, allowNone=False) account = reference(doc=""" A reference to the LoginAccount for which this is a login method. """, allowNone=False) verified = boolean(indexed=True, allowNone=False)
class DBShortMessage(item.Item): """ I represent a contact on the DB """ # (id integer, category integer, number text, date text, smstext text) typeName = 'DBShortMessage' schemaVersion = 1 date = attributes.timestamp(allowNone=False) number = attributes.text(allowNone=False) text = attributes.text(allowNone=False) where = attributes.integer(allowNone=False) def __repr__(self): args = (self.number, self.text, self.date) return '<DBShortMessage number="%s" text="%s" date="%s">' % args def __eq__(self, m): if isinstance(m, DBShortMessage): return (self.number == m.number and self.text == m.text and self.date == m.date) return False def __ne__(self, m): return not (self.number == m.number and self.text == m.text and self.date == m.date) def get_index(self): return self.storeID def get_number(self): return self.number def get_text(self): return self.text def to_csv(self): """Returns a list with the date, number and text formatted for csv""" tzinfo = osobj.get_tzinfo() date = '"' + time.strftime( "%c", self.date.asDatetime(tzinfo=tzinfo).timetuple()) + '"' number = '"' + self.number + '"' text = '"' + self.text + '"' return [date, number, text]
class DBContact(item.Item): """ I represent a contact on the DB """ implements(IContact) # (id integer, category integer, name text, number text) typeName = 'DBContact' schemaVersion = 1 name = attributes.text(allowNone=False) number = attributes.text(allowNone=False) writable = True def __repr__(self): return '<DBContact name="%s" number="%s">' % (self.name, self.number) def __eq__(self, c): return self.name == c.name and self.number == c.number def __ne__(self, c): return not (self.name == c.name and self.number == c.number) def get_index(self): return self.storeID def get_name(self): return self.name def get_number(self): return self.number def is_writable(self): return self.writable def external_editor(self): return None def image_16x16(self): return join(consts.IMAGES_DIR, 'computer.png') def to_csv(self): """Returns a list with the name and number formatted for csv""" name = '"' + self.name + '"' number = '"' + self.number + '"' return [name, number]
class _PowerupConnector(Item): """ I am a connector between the store and a powerup. """ typeName = 'axiom_powerup_connector' powerup = reference() item = reference() interface = text() priority = integer()
class DBContact(item.Item): """ I represent a contact on the DB """ implements(IContact) # (id integer, category integer, group text, name text, number text) typeName = 'DBContact' schemaVersion = 1 group = attributes.text(allowNone=False) name = attributes.text(allowNone=False) number = attributes.text(allowNone=False) def __repr__(self): return '<DBContact group="%s" name="%s" number="%s">' % ( self.group, self.name, self.number) def __eq__(self, c): return self.name == c.name and self.number == c.number def __ne__(self, c): return not self.__eq__(c) def get_index(self): return self.storeID def get_group(self): return self.group def get_name(self): return self.name def get_number(self): return self.number def to_csv(self): """Returns a list with the name and number formatted for csv""" group = '"' + self.group + '"' name = '"' + self.name + '"' number = '"' + self.number + '"' return [group, name, number]
class DBNetworkOperator(item.Item): netid = attributes.textlist(allowNone=False) country = attributes.text(allowNone=False) name = attributes.text(allowNone=False) smsc = attributes.text(allowNone=False) apn = attributes.text(allowNone=False) username = attributes.text(allowNone=False) password = attributes.text(allowNone=False) dns1 = attributes.text(allowNone=True) dns2 = attributes.text(allowNone=True) def __repr__(self): return '<%s netid=%s>' % (self.__class__.__name__, self.netid) def get_full_name(self): return self.name + ' ' + self.country
class _TagName(Item): """ Helper class to make Catalog.tagNames very fast. One of these is created for each distinct tag name that is created. _TagName Items are never deleted from the database. """ typeName = 'tagname' name = text(doc=""" The short string which uniquely represents this tag. """, indexed=True) catalog = reference(doc=""" The L{Catalog} item in which this tag exists. """)
class Tag(Item): typeName = 'tag' schemaVersion = 1 name = text(doc=""" The short string which is being applied as a tag to an Item. """) created = timestamp(doc=""" When this tag was applied to the Item to which it applies. """) object = reference(doc=""" The Item to which this tag applies. """) catalog = reference(doc=""" The L{Catalog} item in which this tag was created. """) tagger = reference(doc=""" An optional reference to the Item which is responsible for this tag's existence. """)
class LoginAccount(Item): """ I am an entry in a LoginBase. @ivar avatars: An Item which is adaptable to various cred client interfaces. Plural because it represents a collection of potentially disparate implementors, such as an IResource for web access and an IContact for SIP access. @ivar disabled: This account has been disabled. It is still database-resident but the user should not be allowed to log in. """ typeName = 'login' schemaVersion = 2 password = text() avatars = reference() # reference to a thing which can be adapted to # implementations for application-level # protocols. In general this is a reference to # a SubStore because this is optimized for # applications where per-user data is a # substantial portion of the cost. disabled = integer() def __conform__(self, interface): """ For convenience, forward adaptation to my 'avatars' attribute. """ ifa = interface(self.avatars, None) return ifa def migrateDown(self): """ Assuming that self.avatars is a SubStore which should contain *only* the LoginAccount for the user I represent, remove all LoginAccounts and LoginMethods from that store and copy all methods from the site store down into it. """ ss = self.avatars.open() def _(): oldAccounts = ss.query(LoginAccount) oldMethods = ss.query(LoginMethod) for x in list(oldAccounts) + list(oldMethods): x.deleteFromStore() self.cloneInto(ss, ss) sched = IScheduler(ss, None) if sched is not None: sched.migrateDown() ss.transact(_) def migrateUp(self): """ Copy this LoginAccount and all associated LoginMethods from my store (which is assumed to be a SubStore, most likely a user store) into the site store which contains it. """ siteStore = self.store.parent def _(): # No convenience method for the following because needing to do it is # *rare*. It *should* be ugly; 99% of the time if you need to do this # you're making a mistake. -glyph siteStoreSubRef = siteStore.getItemByID(self.store.idInParent) self.cloneInto(siteStore, siteStoreSubRef) sched = IScheduler(self.store, None) if sched is not None: sched.migrateUp() siteStore.transact(_) def cloneInto(self, newStore, avatars): """ Create a copy of this LoginAccount and all associated LoginMethods in a different Store. Return the copied LoginAccount. """ la = LoginAccount(store=newStore, password=self.password, avatars=avatars, disabled=self.disabled) for siteMethod in self.store.query(LoginMethod, LoginMethod.account == self): lm = LoginMethod(store=newStore, localpart=siteMethod.localpart, domain=siteMethod.domain, internal=siteMethod.internal, protocol=siteMethod.protocol, verified=siteMethod.verified, account=la) return la def deleteLoginMethods(self): self.store.query(LoginMethod, LoginMethod.account == self).deleteFromStore() def addLoginMethod(self, localpart, domain, protocol=ANY_PROTOCOL, verified=False, internal=False): """ Add a login method to this account, propogating up or down as necessary to site store or user store to maintain consistency. """ # Out takes you west or something if self.store.parent is None: # West takes you in otherStore = self.avatars.open() peer = otherStore.findUnique(LoginAccount) else: # In takes you east otherStore = self.store.parent subStoreItem = self.store.parent.getItemByID(self.store.idInParent) peer = otherStore.findUnique(LoginAccount, LoginAccount.avatars == subStoreItem) # Up and down take you home for store, account in [(otherStore, peer), (self.store, self)]: store.findOrCreate(LoginMethod, account=account, localpart=localpart, domain=domain, protocol=protocol, verified=verified, internal=internal)