class UserAccount(SQLObject): """A store of user information. A user account is created when a user is registered. """ username = StringCol(length=20, notNone=True, unique=True, alternateID=True) password = StringCol(length=40, notNone=True) # Store SHA-1 hex hashes. allowLogin = BoolCol(default=True) # If False, account login is disabled. email = StringCol(default=None, length=320) # See RFC 2821 section 4.5.3.1. # Don't split name field - see http://people.w3.org/rishida/blog/?p=100 realname = UnicodeCol(default=None, length=40) profile = UnicodeCol(default=None) #country = StringCol(length=2, default=None) # ISO 3166 country code. created = DateTimeCol(default=datetime.now) lastLogin = DateTimeCol(default=None) # friends = MultipleJoin('UserFriend', joinColumn='from_user') def _set_username(self, value): if not isinstance(value, str) or not(1 <= len(value) <= 20): raise ValueError("Invalid specification of username") if re.search("[^A-z0-9_]", value): raise ValueError("Username may only be alphanumeric characters") self._SO_set_username(value) def _set_password(self, value): if not isinstance(value, str) or not(1 <= len(value) <= 40): raise ValueError("Invalid specification of password") self._SO_set_password(value) def _set_email(self, value): # This regexp matches virtually all well-formatted email addresses. if value and not email_re.search(value): raise ValueError("Invalid or ill-formatted email address") self._SO_set_email(value)
class AbstractCard(InheritableSQLObject): tableversion = 7 sqlmeta.lazyUpdate = True canonicalName = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) name = UnicodeCol() text = UnicodeCol() # Most of these names are singular when they should be plural # since they refer to lists. We've decided to live with the # inconsistency for old columns but do the right thing for new # ones. rarity = CachedRelatedJoin('RarityPair', intermediateTable='abs_rarity_pair_map', joinColumn="abstract_card_id", createRelatedTable=False) cardtype = CachedRelatedJoin('CardType', intermediateTable='abs_type_map', joinColumn="abstract_card_id", createRelatedTable=False) rulings = CachedRelatedJoin('Ruling', intermediateTable='abs_ruling_map', joinColumn="abstract_card_id", createRelatedTable=False) artists = CachedRelatedJoin('Artist', intermediateTable='abs_artist_map', joinColumn="abstract_card_id", createRelatedTable=False) keywords = CachedRelatedJoin('Keyword', intermediateTable='abs_keyword_map', joinColumn="abstract_card_id", createRelatedTable=False) physicalCards = MultipleJoin('PhysicalCard')
class TG_Group(InheritableSQLObject): """An ultra-simple group definition.""" class sqlmeta: table = "tg_group" group_name = UnicodeCol(length=16, alternateID=True, alternateMethodName="by_group_name") display_name = UnicodeCol(length=255) created = DateTimeCol(default=datetime.now) # Old names groupId = DeprecatedAttr("groupId", "group_name") displayName = DeprecatedAttr("displayName", "display_name") # collection of all users belonging to this group users = RelatedJoin("TG_User", intermediateTable="tg_user_group", joinColumn="group_id", otherColumn="user_id") # collection of all permissions for this group permissions = RelatedJoin("TG_Permission", joinColumn="group_id", intermediateTable="tg_group_permission", otherColumn="permission_id")
class PrintingProperty(SQLObject): tableversion = 1 canonicalValue = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) value = UnicodeCol(length=MAX_ID_LENGTH) printings = RelatedJoin('Printing', intermediateTable='printing_data_map', createRelatedTable=False)
class Artist(SQLObject): tableversion = 1 canonicalName = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) name = UnicodeCol() cards = RelatedJoin('AbstractCard', intermediateTable='abs_artist_map', createRelatedTable=False)
class Expansion(SQLObject): tableversion = 5 name = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) shortname = UnicodeCol(default=None) pairs = MultipleJoin('RarityPair') printings = MultipleJoin('Printing')
class Group(SQLObject): """ An ultra-simple group definition. """ # names like "Group", "Order" and "User" are reserved words in SQL # so we set the name to something safe for SQL class sqlmeta: table = 'tg_group' group_name = UnicodeCol(length=16, alternateID=True, alternateMethodName='by_group_name') display_name = UnicodeCol(length=255) created = DateTimeCol(default=datetime.now) # collection of all users belonging to this group users = RelatedJoin('User', intermediateTable='user_group', joinColumn='group_id', otherColumn='user_id') # collection of all permissions for this group permissions = RelatedJoin('Permission', joinColumn='group_id', intermediateTable='group_permission', otherColumn='permission_id')
class Metadata_v1(SQLObject): """Table used to upgrade from Metasa v1""" class sqlmeta: """meta class used to set the correct table""" table = Metadata.sqlmeta.table key = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) value = UnicodeCol()
class Ruling(SQLObject): tableversion = 2 text = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) code = UnicodeCol() url = UnicodeCol(default=None) cards = RelatedJoin('AbstractCard', intermediateTable='abs_ruling_map', createRelatedTable=False)
class Task(SQLObject): title = UnicodeCol() creationDate = DateTimeCol(notNone=True) dueDate = DateTimeCol(default=None) doneDate = DateTimeCol(default=None) description = UnicodeCol(default="", notNone=True) urgency = IntCol(default=0, notNone=True) status = EnumCol(enumValues=['new', 'started', 'done']) project = ForeignKey("Project") keywords = RelatedJoin("Keyword", createRelatedTable=False, intermediateTable="task_keyword", joinColumn="task_id", otherColumn="keyword_id") recurrence = ForeignKey("Recurrence", default=None) def setKeywordDict(self, dct): """ Defines keywords of a task. Dict is of the form: keywordName => value """ for taskKeyword in TaskKeyword.selectBy(task=self): taskKeyword.destroySelf() for name, value in dct.items(): keyword = Keyword.selectBy(name=name)[0] TaskKeyword(task=self, keyword=keyword, value=value) def getKeywordDict(self): """ Returns all keywords of a task as a dict of the form: keywordName => value """ dct = {} for keyword in TaskKeyword.selectBy(task=self): dct[keyword.keyword.name] = keyword.value return dct def getKeywordsAsString(self): """ Returns all keywords as a string like "key1=value1, key2=value2..." """ return ", ".join( list(("%s=%s" % k for k in self.getKeywordDict().items()))) def getUserKeywordsNameAsString(self): """ Returns all keywords keys as a string like "key1, key2, key3...". Internal keywords (starting with _) are ignored. """ keywords = [ k for k in self.getKeywordDict().keys() if not k.startswith("_") ] keywords.sort() if keywords: return ", ".join(keywords) else: return ""
class AbstractCard_v6(SQLObject): """Table used to upgrade AbstractCard from v6""" class sqlmeta: """meta class used to set the correct table""" table = AbstractCard.sqlmeta.table cacheValues = False canonicalName = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) name = UnicodeCol() text = UnicodeCol() search_text = UnicodeCol(default="") group = IntCol(default=None, dbName='grp') capacity = IntCol(default=None) cost = IntCol(default=None) life = IntCol(default=None) costtype = EnumCol(enumValues=['pool', 'blood', 'conviction', None], default=None) level = EnumCol(enumValues=['advanced', None], default=None) # Most of these names are singular when they should be plural # since they refer to lists. We've decided to live with the # inconsistency for old columns but do the right thing for new # ones. discipline = RelatedJoin('DisciplinePair', intermediateTable='abs_discipline_pair_map', createRelatedTable=False) rarity = RelatedJoin('RarityPair', intermediateTable='abs_rarity_pair_map', createRelatedTable=False) clan = RelatedJoin('Clan', intermediateTable='abs_clan_map', createRelatedTable=False) cardtype = RelatedJoin('CardType', intermediateTable='abs_type_map', createRelatedTable=False) sect = RelatedJoin('Sect', intermediateTable='abs_sect_map', createRelatedTable=False) title = RelatedJoin('Title', intermediateTable='abs_title_map', createRelatedTable=False) creed = RelatedJoin('Creed', intermediateTable='abs_creed_map', createRelatedTable=False) virtue = RelatedJoin('Virtue', intermediateTable='abs_virtue_map', createRelatedTable=False) rulings = RelatedJoin('Ruling', intermediateTable='abs_ruling_map', createRelatedTable=False) artists = RelatedJoin('Artist', intermediateTable='abs_artist_map', createRelatedTable=False) keywords = RelatedJoin('Keyword', intermediateTable='abs_keyword_map', createRelatedTable=False) physicalCards = MultipleJoin('PhysicalCard')
class Config(SQLObject): """yokadi config""" class sqlmeta: defaultOrder = "name" name = UnicodeCol(alternateID=True, notNone=True) value = UnicodeCol(default="", notNone=True) system = BoolCol(default=False, notNone=True) desc = UnicodeCol(default="", notNone=True)
class Virtue(SQLObject): tableversion = 2 name = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) fullname = UnicodeCol(default=None) cards = RelatedJoin('SutekhAbstractCard', intermediateTable='abs_virtue_map', otherColumn="abstract_card_id", createRelatedTable=False)
class Site(SQLObject): name = UnicodeCol() desc = UnicodeCol() key = UnicodeCol() dump_date = UnicodeCol() import_date = DateTimeCol() base_url = UnicodeCol() siteKey_index = DatabaseIndex(key, unique=True)
class Genre(SQLObject): name = UnicodeCol(notNull=True, unique=True) title = UnicodeCol(notNull=True) count = IntCol(notNull=True) books = RelatedJoin('Book', otherColumn='book_id', intermediateTable='book_genre', createRelatedTable=False) title_idx = DatabaseIndex(title) count_idx = DatabaseIndex(count)
class Competition(SQLObject): name = UnicodeCol() place = UnicodeCol() plannedStartTime = DateTimeCol(default=None) startTime = DateTimeCol(default=None) finishTime = DateTimeCol(default=None) notes = UnicodeCol(default=None) active = BoolCol(default=None) competitors = MultipleJoin('Competitor') splits = MultipleJoin('Split')
class Expansion_v3(SQLObject): """Table used to update Expansion from v3""" class sqlmeta: """meta class used to set the correct table""" table = Expansion.sqlmeta.table cacheValues = False name = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) shortname = UnicodeCol(default=None) pairs = MultipleJoin('RarityPair_Ev3')
class PhysicalCardSet(SQLObject): tableversion = 7 name = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) author = UnicodeCol(default='') comment = UnicodeCol(default='') annotations = UnicodeCol(default='') inuse = BoolCol(default=False) parent = ForeignKey('PhysicalCardSet', default=None) cards = RelatedJoin('PhysicalCard', intermediateTable='physical_map', createRelatedTable=False) parentIndex = DatabaseIndex(parent)
class Competitor(SQLObject): name = UnicodeCol(default=None) contact = UnicodeCol(default=None) team = UnicodeCol(default=None) number = IntCol(default=None) starting = BoolCol(default=False) category = ForeignKey('Category') competition = ForeignKey('Competition') splits = MultipleJoin('Split')
class LookupHints(SQLObject): # This is a collection of lookup hints for use in various # places. # The domain field is used to indicate which domain the lookup # will be used for, while the (lookup, value) are the lookup # pairs tableversion = 1 domain = UnicodeCol(length=MAX_ID_LENGTH) lookup = UnicodeCol() value = UnicodeCol()
class Permission(SQLObject): """ A relationship that determines what each Group can do """ permission_name = UnicodeCol(length=16, alternateID=True, alternateMethodName='by_permission_name') description = UnicodeCol(length=255) groups = RelatedJoin('Group', intermediateTable='group_permission', joinColumn='permission_id', otherColumn='group_id')
class TG_User(InheritableSQLObject): """Reasonably basic User definition.""" class sqlmeta: table = "tg_user" user_name = UnicodeCol(length=16, alternateID=True, alternateMethodName="by_user_name") email_address = UnicodeCol(length=255, alternateID=True, alternateMethodName="by_email_address") display_name = UnicodeCol(length=255) password = UnicodeCol(length=40) created = DateTimeCol(default=datetime.now) # Old attribute names userId = DeprecatedAttr("userId", "user_name") emailAddress = DeprecatedAttr("emailAddress", "email_address") displayName = DeprecatedAttr("displayName", "display_name") # groups this user belongs to groups = RelatedJoin("TG_Group", intermediateTable="tg_user_group", joinColumn="user_id", otherColumn="group_id") def _get_permissions(self): perms = set() for g in self.groups: perms = perms | set(g.permissions) return perms def _set_password(self, cleartext_password): """Run cleartext_password through the hash algorithm before saving.""" try: hash = identity.current_provider.encrypt_password( cleartext_password) except identity.exceptions.IdentityManagementNotEnabledException: # Creating identity provider just to encrypt password # (so we don't reimplement the encryption step). ip = SqlObjectCsrfIdentityProvider() hash = ip.encrypt_password(cleartext_password) if hash == cleartext_password: log.info("Identity provider not enabled," " and no encryption algorithm specified in config." " Setting password as plaintext.") self._SO_set_password(hash) def set_password_raw(self, password): """Save the password as-is to the database.""" self._SO_set_password(password)
class TG_Permission(InheritableSQLObject): """Permissions for a given group.""" class sqlmeta: table = "tg_permission" permission_name = UnicodeCol(length=16, alternateID=True, alternateMethodName="by_permission_name") description = UnicodeCol(length=255) groups = RelatedJoin("TG_Group", intermediateTable="tg_group_permission", joinColumn="permission_id", otherColumn="group_id")
class Metadata(SQLObject): # This is a simple key-value table, used to store any # arbitary additional information that should be tied to the # database but is hard to fit into other tables, such as # "update date" for the cardlist and so on. # Since this is a common requirement across different tools, this lives in # base, even though the use cases are implementation specific. tableversion = 2 # The first version used 'key' here, but that breaks on mysql dataKey = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) value = UnicodeCol()
class PhysicalCardSet_PCv3(SQLObject): """Physical Card Set to update from Physical Card v2""" class sqlmeta: """meta class used to set the correct table""" table = PhysicalCardSet.sqlmeta.table cacheValues = False name = UnicodeCol(alternateID=True, length=MAX_ID_LENGTH) author = UnicodeCol(default='') comment = UnicodeCol(default='') annotations = UnicodeCol(default='') inuse = BoolCol(default=False) parent = ForeignKey('PhysicalCardSet_PCv3', default=None) cards = RelatedJoin('PhysicalCard_v2', intermediateTable='physical_map', createRelatedTable=False)
class CA(SQLObject): name = UnicodeCol(unique=True) key = ForeignKey("Key") serial = IntCol(default=0) hostca = BoolCol(default=False) signed = MultipleJoin("Key", joinColumn="ca_id") krl = BLOBCol()
class Author(SQLObject): surname = UnicodeCol(notNull=True) name = UnicodeCol(notNull=True) misc_name = UnicodeCol(notNull=True) count = IntCol(notNull=True) books = RelatedJoin('Book', otherColumn='book_id', intermediateTable='author_book', createRelatedTable=False) @property def fullname(self): fullnames = filter(None, (self.surname, self.name, self.misc_name)) return ' '.join(fullnames) full_name_idx = DatabaseIndex(surname, name, misc_name, unique=True) count_idx = DatabaseIndex(count)
class User(SQLObject): sourceId = IntCol() site = ForeignKey('Site', cascade=True) reputation = IntCol() creationDate = DateTimeCol(datetimeFormat=ISO_DATE_FORMAT) displayName = UnicodeCol() emailHash = UnicodeCol() lastAccessDate = DateTimeCol(datetimeFormat=ISO_DATE_FORMAT) websiteUrl = UnicodeCol() location = UnicodeCol() age = IntCol() aboutMe = UnicodeCol() views = IntCol() upVotes = IntCol() downVotes = IntCol() siteId_sourceId_index = DatabaseIndex(site, sourceId, unique=True)
class PodEntry(SQLObject): '''A lookup table of all your podcast subscriptions''' pod_title = StringCol() hashed = UnicodeCol() pub_date = DateTimeCol() cover = StringCol() description = StringCol() category = StringCol() active = BoolCol()
class Message(SQLObject): class sqlmeta: table = 'messages' message_id = StringCol() account_id = UnicodeCol(length=128) remote_uri = UnicodeCol(length=128) display_name = UnicodeCol(length=128) uri = UnicodeCol(length=128, default='') timestamp = DateTimeCol() direction = StringCol() content = UnicodeCol(sqlType='LONGTEXT') content_type = StringCol(default='text') state = StringCol(default='pending') encryption_type = StringCol(default='') disposition = StringCol(default='') remote_idx = DatabaseIndex('remote_uri') id_idx = DatabaseIndex('message_id') unq_idx = DatabaseIndex(message_id, account_id, remote_uri, unique=True)