class HWSubmission(SQLBase): """See `IHWSubmission`.""" _table = 'HWSubmission' date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW) date_submitted = UtcDateTimeCol(notNull=True, default=UTC_NOW) format = EnumCol(enum=HWSubmissionFormat, notNull=True) status = EnumCol(enum=HWSubmissionProcessingStatus, notNull=True) private = BoolCol(notNull=True) contactable = BoolCol(notNull=True) submission_key = StringCol(notNull=True) owner = ForeignKey(dbName='owner', foreignKey='Person', storm_validator=validate_public_person) distroarchseries = ForeignKey(dbName='distroarchseries', foreignKey='DistroArchSeries') raw_submission = ForeignKey(dbName='raw_submission', foreignKey='LibraryFileAlias', notNull=False, default=DEFAULT) system_fingerprint = ForeignKey(dbName='system_fingerprint', foreignKey='HWSystemFingerprint', notNull=True) raw_emailaddress = StringCol() @property def devices(self): return HWSubmissionDeviceSet().getDevices(submission=self)
class CommercialSubscription(SQLBase): product = ForeignKey(dbName='product', foreignKey='Product', notNull=True) date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW) date_last_modified = UtcDateTimeCol(notNull=True, default=UTC_NOW) date_starts = UtcDateTimeCol(notNull=True, default=UTC_NOW) date_expires = UtcDateTimeCol(notNull=True, default=UTC_NOW) registrant = ForeignKey(dbName='registrant', foreignKey='Person', default=None, storm_validator=validate_public_person) purchaser = ForeignKey(dbName='purchaser', foreignKey='Person', default=None, storm_validator=validate_public_person) sales_system_id = StringCol(notNull=True) whiteboard = StringCol(default=None) @property def is_active(self): """See `ICommercialSubscription`""" now = datetime.datetime.now(pytz.timezone('UTC')) return self.date_starts < now < self.date_expires def delete(self): """See `ICommercialSubscription`""" if self.is_active: raise CannotDeleteCommercialSubscription( "This CommercialSubscription is still active.") self.destroySelf()
class CodeImportResult(SQLBase): """See `ICodeImportResult`.""" implements(ICodeImportResult) date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW) code_import = ForeignKey( dbName='code_import', foreignKey='CodeImport', notNull=True) machine = ForeignKey( dbName='machine', foreignKey='CodeImportMachine', notNull=True) requesting_user = ForeignKey( dbName='requesting_user', foreignKey='Person', storm_validator=validate_public_person, default=None) log_excerpt = StringCol(default=None) log_file = ForeignKey( dbName='log_file', foreignKey='LibraryFileAlias', default=None) status = EnumCol( enum=CodeImportResultStatus, notNull=True) date_job_started = UtcDateTimeCol(notNull=True) @property def date_job_finished(self): """See `ICodeImportResult`.""" return self.date_created @property def job_duration(self): return self.date_job_finished - self.date_job_started
class SessionData(Storm): """A user's Session.""" __storm_table__ = 'SessionData' client_id = Unicode(primary=True) created = UtcDateTimeCol() last_accessed = UtcDateTimeCol()
class Account(SQLBase): """An Account.""" implements(IAccount) date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW) displayname = StringCol(dbName='displayname', notNull=True) creation_rationale = EnumCol(dbName='creation_rationale', schema=AccountCreationRationale, notNull=True) status = AccountStatusEnumCol(enum=AccountStatus, default=AccountStatus.NOACCOUNT, notNull=True) date_status_set = UtcDateTimeCol(notNull=True, default=UTC_NOW) status_comment = StringCol(dbName='status_comment', default=None) openid_identifiers = ReferenceSet("Account.id", OpenIdIdentifier.account_id) def __repr__(self): displayname = self.displayname.encode('ASCII', 'backslashreplace') return "<%s '%s' (%s)>" % (self.__class__.__name__, displayname, self.status) def reactivate(self, comment): """See `IAccountSpecialRestricted`.""" self.status = AccountStatus.ACTIVE self.status_comment = comment
class ScriptActivity(SQLBase): implements(IScriptActivity) name = StringCol(notNull=True) hostname = StringCol(notNull=True) date_started = UtcDateTimeCol(notNull=True) date_completed = UtcDateTimeCol(notNull=True)
class SessionData(Storm): """A user's Session.""" classProvides(IUseSessionStore) implements(IUseSessionStore) __storm_table__ = 'SessionData' client_id = Unicode(primary=True) created = UtcDateTimeCol() last_accessed = UtcDateTimeCol()
class Cve(SQLBase, BugLinkTargetMixin): """A CVE database record.""" implements(ICve, IBugLinkTarget) _table = 'Cve' sequence = StringCol(notNull=True, alternateID=True) status = EnumCol(dbName='status', schema=CveStatus, notNull=True) description = StringCol(notNull=True) datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW) datemodified = UtcDateTimeCol(notNull=True, default=UTC_NOW) # joins bugs = SQLRelatedJoin('Bug', intermediateTable='BugCve', joinColumn='cve', otherColumn='bug', orderBy='id') bug_links = SQLMultipleJoin('BugCve', joinColumn='cve', orderBy='id') references = SQLMultipleJoin( 'CveReference', joinColumn='cve', orderBy='id') @property def url(self): """See ICve.""" return ('http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=%s' % self.sequence) @property def displayname(self): return 'CVE-%s' % self.sequence @property def title(self): return 'CVE-%s (%s)' % (self.sequence, self.status.title) # CveReference's def createReference(self, source, content, url=None): """See ICveReference.""" return CveReference(cve=self, source=source, content=content, url=url) def removeReference(self, ref): assert ref.cve == self CveReference.delete(ref.id) # Template methods for BugLinkTargetMixin buglinkClass = BugCve def createBugLink(self, bug): """See BugLinkTargetMixin.""" return BugCve(cve=self, bug=bug)
class CodeImportJob(SQLBase): """See `ICodeImportJob`.""" implements(ICodeImportJob) date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW) code_import = ForeignKey( dbName='code_import', foreignKey='CodeImport', notNull=True) machine = ForeignKey( dbName='machine', foreignKey='CodeImportMachine', notNull=False, default=None) date_due = UtcDateTimeCol(notNull=True) state = EnumCol( enum=CodeImportJobState, notNull=True, default=CodeImportJobState.PENDING) requesting_user = ForeignKey( dbName='requesting_user', foreignKey='Person', storm_validator=validate_public_person, notNull=False, default=None) ordering = IntCol(notNull=False, default=None) heartbeat = UtcDateTimeCol(notNull=False, default=None) logtail = StringCol(notNull=False, default=None) date_started = UtcDateTimeCol(notNull=False, default=None) def isOverdue(self): """See `ICodeImportJob`.""" # SQLObject offers no easy way to compare a timestamp to UTC_NOW, so # we must use trickery here. # First we flush any pending update to self to ensure that the # following database query will give the correct result even if # date_due was modified in this transaction. self.syncUpdate() # Then, we try to find a CodeImportJob object with the id of self, and # a date_due of now or past. If we find one, this means self is # overdue. import_job = CodeImportJob.selectOne( "id = %s AND date_due <= %s" % sqlvalues(self.id, UTC_NOW)) return import_job is not None
class RevisionCache(Storm): """A cached version of a recent revision.""" __storm_table__ = 'RevisionCache' id = Int(primary=True) revision_id = Int(name='revision', allow_none=False) revision = Reference(revision_id, 'Revision.id') revision_author_id = Int(name='revision_author', allow_none=False) revision_author = Reference(revision_author_id, 'RevisionAuthor.id') revision_date = UtcDateTimeCol(notNull=True) product_id = Int(name='product', allow_none=True) product = Reference(product_id, 'Product.id') distroseries_id = Int(name='distroseries', allow_none=True) distroseries = Reference(distroseries_id, 'DistroSeries.id') sourcepackagename_id = Int(name='sourcepackagename', allow_none=True) sourcepackagename = Reference(sourcepackagename_id, 'SourcePackageName.id') private = Bool(allow_none=False, default=False) def __init__(self, revision): # Make the revision_author assignment first as traversing to the # revision_author of the revision does a query which causes a store # flush. If an assignment has been done already, the RevisionCache # object would have been implicitly added to the store, and failes # with an integrity check. self.revision_author = revision.revision_author self.revision = revision self.revision_date = revision.revision_date
class CodeImportEvent(SQLBase): """See `ICodeImportEvent`.""" implements(ICodeImportEvent) _table = 'CodeImportEvent' date_created = UtcDateTimeCol(notNull=True, default=DEFAULT) event_type = EnumCol(dbName='entry_type', enum=CodeImportEventType, notNull=True) code_import = ForeignKey(dbName='code_import', foreignKey='CodeImport', default=None) person = ForeignKey(dbName='person', foreignKey='Person', storm_validator=validate_public_person, default=None) machine = ForeignKey(dbName='machine', foreignKey='CodeImportMachine', default=None) def items(self): """See `ICodeImportEvent`.""" return [(data.data_type, data.data_value) for data in _CodeImportEventData.selectBy(event=self)]
class BugBranch(SQLBase): """See `IBugBranch`.""" implements(IBugBranch, IHasBranchTarget) datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW) bug = ForeignKey(dbName="bug", foreignKey="Bug", notNull=True) branch_id = IntCol(dbName="branch", notNull=True) branch = ForeignKey(dbName="branch", foreignKey="Branch", notNull=True) revision_hint = StringCol(default=None) registrant = ForeignKey(dbName='registrant', foreignKey='Person', storm_validator=validate_public_person, notNull=True) @property def target(self): """See `IHasBranchTarget`.""" return self.branch.target @property def bug_task(self): """See `IBugBranch`.""" task = self.bug.getBugTask(self.branch.product) if task is None: # Just choose the first task for the bug. task = self.bug.bugtasks[0] return task
class BugNotification(SQLBase): """A textual representation about a bug change.""" implements(IBugNotification) message = ForeignKey(dbName='message', notNull=True, foreignKey='Message') activity = ForeignKey(dbName='activity', notNull=False, foreignKey='BugActivity') bug = ForeignKey(dbName='bug', notNull=True, foreignKey='Bug') is_comment = BoolCol(notNull=True) date_emailed = UtcDateTimeCol(notNull=False) status = EnumCol(dbName='status', schema=BugNotificationStatus, default=BugNotificationStatus.PENDING, notNull=True) @property def recipients(self): """See `IBugNotification`.""" return BugNotificationRecipient.selectBy(bug_notification=self, orderBy='id') @property def bug_filters(self): """See `IStructuralSubscription`.""" return IStore(BugSubscriptionFilter).find( BugSubscriptionFilter, (BugSubscriptionFilter.id == BugNotificationFilter.bug_subscription_filter_id), BugNotificationFilter.bug_notification == self)
class MailingListSubscription(SQLBase): """A mailing list subscription.""" person = ForeignKey(dbName='person', foreignKey='Person', storm_validator=validate_public_person, notNull=True) mailing_list = ForeignKey(dbName='mailing_list', foreignKey='MailingList', notNull=True) date_joined = UtcDateTimeCol(notNull=True, default=UTC_NOW) email_address = ForeignKey(dbName='email_address', foreignKey='EmailAddress') @property def subscribed_address(self): """See `IMailingListSubscription`.""" if self.email_address is None: # Use the person's preferred email address. return self.person.preferredemail else: # Use the subscribed email address. return self.email_address
class ProductReleaseFile(SQLBase): """A file of a product release.""" _table = 'ProductReleaseFile' productrelease = ForeignKey(dbName='productrelease', foreignKey='ProductRelease', notNull=True) libraryfile = ForeignKey(dbName='libraryfile', foreignKey='LibraryFileAlias', notNull=True) signature = ForeignKey(dbName='signature', foreignKey='LibraryFileAlias') filetype = EnumCol(dbName='filetype', enum=UpstreamFileType, notNull=True, default=UpstreamFileType.CODETARBALL) description = StringCol(notNull=False, default=None) uploader = ForeignKey(dbName="uploader", foreignKey='Person', storm_validator=validate_public_person, notNull=True) date_uploaded = UtcDateTimeCol(notNull=True, default=UTC_NOW)
class OpenIdIdentifier(Storm): """An OpenId Identifier that can be used to log into an Account""" __storm_table__ = "openididentifier" identifier = Unicode(primary=True) account_id = Int("account") account = Reference(account_id, "Account.id") date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)
class PersonLocation(SQLBase): """A person's location.""" _defaultOrder = ['id'] date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW) person = ForeignKey( dbName='person', foreignKey='Person', storm_validator=validate_public_person, notNull=True, unique=True) latitude = FloatCol(notNull=False) longitude = FloatCol(notNull=False) time_zone = StringCol(notNull=True) last_modified_by = ForeignKey( dbName='last_modified_by', foreignKey='Person', storm_validator=validate_public_person, notNull=True) date_last_modified = UtcDateTimeCol(notNull=True, default=UTC_NOW) visible = BoolCol(notNull=True, default=True)
class SprintSpecification(SQLBase): """A link between a sprint and a specification.""" _table = 'SprintSpecification' sprint = ForeignKey(dbName='sprint', foreignKey='Sprint', notNull=True) specification = ForeignKey(dbName='specification', foreignKey='Specification', notNull=True) status = EnumCol(schema=SprintSpecificationStatus, notNull=True, default=SprintSpecificationStatus.PROPOSED) whiteboard = StringCol(notNull=False, default=None) registrant = ForeignKey(dbName='registrant', foreignKey='Person', storm_validator=validate_public_person, notNull=True) date_created = UtcDateTimeCol(notNull=True, default=DEFAULT) decider = ForeignKey(dbName='decider', foreignKey='Person', storm_validator=validate_public_person, notNull=False, default=None) date_decided = UtcDateTimeCol(notNull=False, default=None) @property def is_confirmed(self): """See ISprintSpecification.""" return self.status == SprintSpecificationStatus.ACCEPTED @property def is_decided(self): """See ISprintSpecification.""" return self.status != SprintSpecificationStatus.PROPOSED def acceptBy(self, decider): """See ISprintSpecification.""" self.status = SprintSpecificationStatus.ACCEPTED self.decider = decider self.date_decided = UTC_NOW def declineBy(self, decider): """See ISprintSpecification.""" self.status = SprintSpecificationStatus.DECLINED self.decider = decider self.date_decided = UTC_NOW
class SignedCodeOfConduct(SQLBase): """Code of Conduct.""" _table = 'SignedCodeOfConduct' owner = ForeignKey(foreignKey="Person", dbName="owner", notNull=True) signedcode = StringCol(dbName='signedcode', notNull=False, default=None) signing_key_fingerprint = Unicode() datecreated = UtcDateTimeCol(dbName='datecreated', notNull=True, default=UTC_NOW) recipient = ForeignKey(foreignKey="Person", dbName="recipient", notNull=False, default=None) admincomment = StringCol(dbName='admincomment', notNull=False, default=None) active = BoolCol(dbName='active', notNull=True, default=False) @cachedproperty def signingkey(self): if self.signing_key_fingerprint is not None: return getUtility(IGPGKeySet).getByFingerprint( self.signing_key_fingerprint) @property def displayname(self): """Build a Fancy Title for CoC.""" displayname = self.datecreated.strftime('%Y-%m-%d') if self.signingkey: displayname += ( ': digitally signed by %s (%s)' % (self.owner.displayname, self.signingkey.displayname)) else: displayname += (': paper submission accepted by %s' % self.recipient.displayname) return displayname def sendAdvertisementEmail(self, subject, content): """See ISignedCodeOfConduct.""" assert self.owner.preferredemail template = get_email_template('signedcoc-acknowledge.txt', app='registry') fromaddress = format_address("Launchpad Code Of Conduct System", config.canonical.noreply_from_address) replacements = {'user': self.owner.displayname, 'content': content} message = template % replacements simple_sendmail(fromaddress, str(self.owner.preferredemail.email), subject, message)
class Account(SQLBase): """An Account.""" date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW) displayname = StringCol(dbName='displayname', notNull=True) creation_rationale = EnumCol(dbName='creation_rationale', schema=AccountCreationRationale, notNull=True) status = AccountStatusEnumCol(enum=AccountStatus, default=AccountStatus.NOACCOUNT, notNull=True) date_status_set = UtcDateTimeCol(notNull=True, default=UTC_NOW) status_history = StringCol(dbName='status_comment', default=None) openid_identifiers = ReferenceSet("Account.id", OpenIdIdentifier.account_id) def __repr__(self): displayname = self.displayname.encode('ASCII', 'backslashreplace') return "<%s '%s' (%s)>" % (self.__class__.__name__, displayname, self.status) def addStatusComment(self, user, comment): """See `IAccountModerateRestricted`.""" prefix = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') if user is not None: prefix += ' %s' % user.name old_lines = (self.status_history.splitlines() if self.status_history else []) self.status_history = '\n'.join(old_lines + ['%s: %s' % (prefix, comment), '']) def setStatus(self, status, user, comment): """See `IAccountModerateRestricted`.""" comment = comment or '' self.addStatusComment( user, '%s -> %s: %s' % (self.status.title, status.title, comment)) # date_status_set is maintained by a DB trigger. self.status = status def reactivate(self, comment): """See `IAccountSpecialRestricted`.""" self.setStatus(AccountStatus.ACTIVE, None, comment)
class BugTrackerPerson(SQLBase): """See `IBugTrackerPerson`.""" bugtracker = ForeignKey(dbName='bugtracker', foreignKey='BugTracker', notNull=True) person = ForeignKey(dbName='person', foreignKey='Person', notNull=True) name = StringCol(notNull=True) date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)
class BranchMergeQueue(Storm): """See `IBranchMergeQueue`.""" __storm_table__ = 'BranchMergeQueue' implements(IBranchMergeQueue) classProvides(IBranchMergeQueueSource) id = Int(primary=True) registrant_id = Int(name='registrant', allow_none=True) registrant = Reference(registrant_id, 'Person.id') owner_id = Int(name='owner', allow_none=True) owner = Reference(owner_id, 'Person.id') name = Unicode(allow_none=False) description = Unicode(allow_none=False) configuration = Unicode(allow_none=False) date_created = UtcDateTimeCol(notNull=True) @property def branches(self): """See `IBranchMergeQueue`.""" return Store.of(self).find( Branch, Branch.merge_queue_id == self.id) def setMergeQueueConfig(self, config): """See `IBranchMergeQueue`.""" try: simplejson.loads(config) self.configuration = config except ValueError: # The config string is not valid JSON raise InvalidMergeQueueConfig @classmethod def new(cls, name, owner, registrant, description=None, configuration=None, branches=None): """See `IBranchMergeQueueSource`.""" store = IMasterStore(BranchMergeQueue) if configuration is None: configuration = unicode(simplejson.dumps({})) queue = cls() queue.name = name queue.owner = owner queue.registrant = registrant queue.description = description queue.configuration = configuration if branches is not None: for branch in branches: branch.addToQueue(queue) store.add(queue) return queue
class Packaging(SQLBase): """A Packaging relating a SourcePackageName in DistroSeries and a Product. """ implements(IPackaging) _table = 'Packaging' productseries = ForeignKey(foreignKey="ProductSeries", dbName="productseries", notNull=True) sourcepackagename = ForeignKey(foreignKey="SourcePackageName", dbName="sourcepackagename", notNull=True) distroseries = ForeignKey(foreignKey='DistroSeries', dbName='distroseries', notNull=True) packaging = EnumCol(dbName='packaging', notNull=True, enum=PackagingType) datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW) owner = ForeignKey( dbName='owner', foreignKey='Person', storm_validator=validate_public_person, notNull=False, default=DEFAULT) @property def sourcepackage(self): from lp.registry.model.sourcepackage import SourcePackage return SourcePackage(distroseries=self.distroseries, sourcepackagename=self.sourcepackagename) def __init__(self, **kwargs): super(Packaging, self).__init__(**kwargs) notify(ObjectCreatedEvent(self)) def userCanDelete(self): """See `IPackaging`.""" user = getUtility(ILaunchBag).user if user is None: return False admin = getUtility(ILaunchpadCelebrities).admin registry_experts = (getUtility(ILaunchpadCelebrities).registry_experts) if (not user.is_probationary or user.inTeam(self.productseries.product.owner) or user.canAccess(self.sourcepackage, 'setBranch') or user.inTeam(registry_experts) or user.inTeam(admin)): return True return False def destroySelf(self): if not self.userCanDelete(): raise Unauthorized( 'Only the person who created the packaging and package ' 'maintainers can delete it.') notify(ObjectDeletedEvent(self)) super(Packaging, self).destroySelf()
class LaunchpadStatistic(SQLBase): """A table of Launchpad Statistics.""" _table = 'LaunchpadStatistic' _defaultOrder = 'name' # db field names name = StringCol(notNull=True, alternateID=True, unique=True) value = IntCol(notNull=True) dateupdated = UtcDateTimeCol(notNull=True, default=UTC_NOW)
class POFileTranslator(SQLBase): """See `IPOFileTranslator`.""" pofile = ForeignKey(foreignKey='POFile', dbName='pofile', notNull=True) person = ForeignKey(dbName='person', foreignKey='Person', storm_validator=validate_public_person, notNull=True) date_last_touched = UtcDateTimeCol(dbName='date_last_touched', notNull=False, default=None)
class LibraryFileContent(SQLBase): """A pointer to file content in the librarian.""" _table = 'LibraryFileContent' datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW) filesize = IntCol(notNull=True) sha256 = StringCol() sha1 = StringCol(notNull=True) md5 = StringCol(notNull=True)
class QuestionReopening(SQLBase): """A table recording each time a question is re-opened.""" _table = 'QuestionReopening' question = ForeignKey(dbName='question', foreignKey='Question', notNull=True) datecreated = UtcDateTimeCol(notNull=True, default=DEFAULT) reopener = ForeignKey(dbName='reopener', foreignKey='Person', storm_validator=validate_public_person, notNull=True) answerer = ForeignKey(dbName='answerer', foreignKey='Person', storm_validator=validate_public_person, notNull=False, default=None) date_solved = UtcDateTimeCol(notNull=False, default=None) priorstate = EnumCol(schema=QuestionStatus, notNull=True)
class BugBranch(SQLBase): """See `IBugBranch`.""" datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW) bug = ForeignKey(dbName="bug", foreignKey="Bug", notNull=True) branch_id = IntCol(dbName="branch", notNull=True) branch = ForeignKey(dbName="branch", foreignKey="Branch", notNull=True) registrant = ForeignKey(dbName='registrant', foreignKey='Person', storm_validator=validate_public_person, notNull=True)
class MirrorProbeRecord(SQLBase): """See IMirrorProbeRecord""" _table = 'MirrorProbeRecord' _defaultOrder = 'id' distribution_mirror = ForeignKey(dbName='distribution_mirror', foreignKey='DistributionMirror', notNull=True) log_file = ForeignKey(dbName='log_file', foreignKey='LibraryFileAlias', notNull=True) date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)
class BugWatchActivity(StormBase): """See `IBugWatchActivity`.""" __storm_table__ = 'BugWatchActivity' id = Int(primary=True) bug_watch_id = Int(name='bug_watch') bug_watch = Reference(bug_watch_id, BugWatch.id) activity_date = UtcDateTimeCol(notNull=True) result = EnumCol(enum=BugWatchActivityStatus, notNull=False) message = Unicode() oops_id = Unicode()