Example #1
0
class Race(Storm):
    __storm_table__ = 'race'

    id = Int(primary=True, default=AutoReload)
    name = Unicode()
    start_time = DateTime()
    end_time = DateTime()

    def start(self):
        now = datetime.datetime.now().replace(microsecond=0)
        self.start_time = now

    def get_categories(self):
        return Store.of(self).find(Category, race=self)

    @cached_property
    def start_hour(self):
        return self.start_time.time()

    @property
    def time_elapsed(self):
        if not self.start_time:
            return None
        delta = datetime.datetime.now() - self.start_time
        return datetime.timedelta(seconds=delta.seconds)
Example #2
0
class User(BaseModel):

    __storm_table__ = "sfec_user"

    name = Unicode()

    # Basic login data
    email = Unicode()
    password = Unicode()

    birth_date = DateTime()
    register_date = DateTime()

    def __init__(self):
        self.register_date = datetime.now()

    #
    # Properties
    #

    @property
    def is_admin(self):
        store = get_default_store()
        return store.find(Admin, id=self.id).one() is not None

    #
    # Static API
    #

    @staticmethod
    def hash(password):
        """The hash function to be used by the table"""
        return unicode(sha512(password).hexdigest())

    @classmethod
    def authenticate(cls, store, email, password):
        """Returns the user that matches the email password combination"""
        pw_hash = cls.hash(password)
        queries = [cls.email == email, cls.password == pw_hash]

        user = store.find(cls, And(*queries)).one()
        if user:
            user.last_login = datetime.now()
            user.last_ip = unicode(request.remote_addr)
            store.commit()
            return user

        return False

    #
    # Public API
    #

    def dict(self):
        super_dict = super(User, self).dict()
        super_dict['is_admin'] = self.is_admin
        return super_dict

    def set_password(self, password):
        self.password = self.hash(password)
Example #3
0
class BugSubscriptionFilterMute(StormBase):
    """Bug subscription filters a person has decided to block emails from."""

    implements(IBugSubscriptionFilterMute)

    __storm_table__ = "BugSubscriptionFilterMute"

    def __init__(self, person=None, filter=None):
        if person is not None:
            self.person = person
        if filter is not None:
            self.filter = filter.id

    person_id = Int("person", allow_none=False, validator=validate_person)
    person = Reference(person_id, "Person.id")

    filter_id = Int("filter", allow_none=False)
    filter = Reference(filter_id, "BugSubscriptionFilter.id")

    __storm_primary__ = 'person_id', 'filter_id'

    date_created = DateTime("date_created",
                            allow_none=False,
                            default=UTC_NOW,
                            tzinfo=pytz.UTC)
Example #4
0
class PhotoImage(BaseModel):
    '''Image file references and metadata'''

    __storm_table__ = 'photoimage'
    id = Int(primary=True)
    filename = Unicode()
    thumbnail = Unicode()
    title = Unicode()
    description = Unicode()
    creation_date = DateTime()
    album_id = Int()
    album = Reference(album_id, 'PhotoAlbum.id')

    def to_dict(self, recurse=True):
        '''See BaseModel.to_dict'''
        ret = {
            'id': self.id,
            'filename': self.filename,
            'thumbnail': self.thumbnail,
            'title': self.title,
            'description': self.description,
            'creation_date': self.creation_date,
        }
        if recurse:
            ret['album_id'] = self.album_id
            ret['album'] = self.album.to_dict(recurse=False)
        return ret
Example #5
0
class XRef(StormBase):
    """Cross-reference between two objects.

    For references to local objects (there is currently no other kind),
    another reference in the opposite direction exists.

    The to_id_int and from_id_int columns exist for efficient SQL joins.
    They are set automatically when the ID looks like an integer.

    NOTE: This should rarely be used directly. Prefer IXRefSet unless
    porting an old query.
    """

    __storm_table__ = 'XRef'
    __storm_primary__ = "from_type", "from_id", "to_type", "to_id"

    to_type = Unicode(allow_none=False)
    to_id = Unicode(allow_none=False)
    to_id_int = Int()  # For efficient joins.
    from_type = Unicode(allow_none=False)
    from_id = Unicode(allow_none=False)
    from_id_int = Int()  # For efficient joins.
    creator_id = Int(name="creator")
    creator = Reference(creator_id, "Person.id")
    date_created = DateTime(name='date_created', tzinfo=pytz.UTC)
    metadata = JSON()
class AccessArtifactGrant(StormBase):
    implements(IAccessArtifactGrant)

    __storm_table__ = 'AccessArtifactGrant'
    __storm_primary__ = 'abstract_artifact_id', 'grantee_id'

    abstract_artifact_id = Int(name='artifact')
    abstract_artifact = Reference(abstract_artifact_id, 'AccessArtifact.id')
    grantee_id = Int(name='grantee')
    grantee = Reference(grantee_id, 'Person.id')
    grantor_id = Int(name='grantor')
    grantor = Reference(grantor_id, 'Person.id')
    date_created = DateTime(tzinfo=pytz.UTC)

    @property
    def concrete_artifact(self):
        if self.abstract_artifact is not None:
            return self.abstract_artifact.concrete_artifact

    @classmethod
    def grant(cls, grants):
        """See `IAccessArtifactGrantSource`."""
        return create((cls.abstract_artifact, cls.grantee, cls.grantor),
                      grants,
                      get_objects=True)

    @classmethod
    def find(cls, grants):
        """See `IAccessArtifactGrantSource`."""
        return IStore(cls).find(
            cls,
            Or(*(And(cls.abstract_artifact == artifact, cls.grantee == grantee)
                 for (artifact, grantee) in grants)))

    @classmethod
    def findByArtifact(cls, artifacts, grantees=None):
        """See `IAccessArtifactGrantSource`."""
        artifact_ids = [artifact.id for artifact in artifacts]
        constraints = [cls.abstract_artifact_id.is_in(artifact_ids)]
        if grantees:
            grantee_ids = [grantee.id for grantee in grantees]
            constraints.append(cls.grantee_id.is_in(grantee_ids))
        return IStore(cls).find(cls, *constraints)

    @classmethod
    def revokeByArtifact(cls, artifacts, grantees=None):
        """See `IAccessArtifactGrantSource`."""
        cls.findByArtifact(artifacts, grantees).remove()
Example #7
0
class RacerLap(Storm):
    __storm_table__ = 'racer_lap'

    id = Int(primary=True, default=AutoReload)
    event_time = DateTime()
    race_id = Int()
    race = Reference(race_id, 'Race.id')
    racer_id = Int()
    racer = Reference(racer_id, 'Racer.id')

    @property
    def previous_lap(self):
        laps = self.racer.get_laps(before=self.event_time)
        return laps.last()

    @cached_property
    def number(self):
        return self.racer.number

    @cached_property
    def name(self):
        return self.racer.name

    @cached_property
    def category(self):
        return self.racer.category.short_name

    @cached_property
    def remaining_laps(self):
        return self.racer.category.total_laps - self.lap_number

    @cached_property
    def lap_time(self):
        previous = self.previous_lap
        if previous:
            delta = self.event_time - previous.event_time
        else:
            # This is the first lap. Calculate it using the race start.
            delta = self.event_time - self.race.start_time

        # Create a new timedelta without the microseconds
        return datetime.timedelta(seconds=delta.seconds)

    @cached_property
    def lap_number(self):
        laps = self.racer.get_laps(before=self.event_time)
        return laps.count() + 1
class AccessPolicyGrant(StormBase):
    implements(IAccessPolicyGrant)

    __storm_table__ = 'AccessPolicyGrant'
    __storm_primary__ = 'policy_id', 'grantee_id'

    policy_id = Int(name='policy')
    policy = Reference(policy_id, 'AccessPolicy.id')
    grantee_id = Int(name='grantee')
    grantee = Reference(grantee_id, 'Person.id')
    grantor_id = Int(name='grantor')
    grantor = Reference(grantor_id, 'Person.id')
    date_created = DateTime(tzinfo=pytz.UTC)

    @classmethod
    def grant(cls, grants):
        """See `IAccessPolicyGrantSource`."""
        return create((cls.policy, cls.grantee, cls.grantor),
                      grants,
                      get_objects=True)

    @classmethod
    def find(cls, grants):
        """See `IAccessPolicyGrantSource`."""
        return IStore(cls).find(
            cls,
            Or(*(And(cls.policy == policy, cls.grantee == grantee)
                 for (policy, grantee) in grants)))

    @classmethod
    def findByPolicy(cls, policies):
        """See `IAccessPolicyGrantSource`."""
        ids = [policy.id for policy in policies]
        return IStore(cls).find(cls, cls.policy_id.is_in(ids))

    @classmethod
    def revoke(cls, grants):
        """See `IAccessPolicyGrantSource`."""
        cls.find(grants).remove()

    @classmethod
    def revokeByPolicy(cls, policies):
        """See `IAccessPolicyGrantSource`."""
        cls.findByPolicy(policies).remove()
Example #9
0
class MilestoneTag(object):
    """A tag belonging to a milestone."""

    __storm_table__ = 'milestonetag'

    id = Int(primary=True)
    milestone_id = Int(name='milestone', allow_none=False)
    milestone = Reference(milestone_id, 'milestone.id')
    tag = Unicode(allow_none=False)
    created_by_id = Int(name='created_by', allow_none=False)
    created_by = Reference(created_by_id, 'person.id')
    date_created = DateTime(allow_none=False)

    def __init__(self, milestone, tag, created_by, date_created=None):
        self.milestone_id = milestone.id
        self.tag = tag
        self.created_by_id = created_by.id
        if date_created is not None:
            self.date_created = date_created
Example #10
0
class LatestPersonSourcePackageReleaseCache(Storm):
    """See `LatestPersonSourcePackageReleaseCache`."""

    __storm_table__ = 'LatestPersonSourcePackageReleaseCache'

    cache_id = Int(name='id', primary=True)
    publication_id = Int(name='publication')
    publication = Reference(publication_id,
                            'SourcePackagePublishingHistory.id')
    dateuploaded = DateTime(name='date_uploaded')
    creator_id = Int(name='creator')
    maintainer_id = Int(name='maintainer')
    upload_archive_id = Int(name='upload_archive')
    upload_archive = Reference(upload_archive_id, 'Archive.id')
    archive_purpose = EnumCol(schema=ArchivePurpose)
    upload_distroseries_id = Int(name='upload_distroseries')
    upload_distroseries = Reference(upload_distroseries_id, 'DistroSeries.id')
    sourcepackagename_id = Int(name='sourcepackagename')
    sourcepackagename = Reference(sourcepackagename_id, 'SourcePackageName.id')
    sourcepackagerelease_id = Int(name='sourcepackagerelease')
    sourcepackagerelease = Reference(sourcepackagerelease_id,
                                     'SourcePackageRelease.id')
Example #11
0
class PhotoAlbum(BaseModel):
    '''A photo group'''

    __storm_table__ = 'photoalbum'
    id = Int(primary=True)
    title = Unicode()
    description = Unicode()
    creation_date = DateTime()
    images = ReferenceSet('PhotoAlbum.id', 'PhotoImage.album_id')

    def to_dict(self, recurse=True):
        '''See BaseModel.to_dict.'''
        ret = {
            'id': self.id,
            'title': self.title,
            'description': self.description,
            'creation_date': self.creation_date,
        }
        if recurse:
            ret['images'] = [
                image.to_dict(recurse=False) for image in self.images
            ]
        return ret
Example #12
0
class UserData(object):
    """
        User database table abstraction.
        """

    __storm_table__ = 'goliat_user'
    id = Int(primary=True)
    username = Unicode(allow_none=False)
    password = Unicode(allow_none=False)
    groups = Unicode()
    created_on = DateTime()
    last_login = DateTime()
    is_active = Bool(value_factory=True)
    superuser = Bool(value_factory=False)

    def __init__(self, username='', password=''):
        """
            Initialized the object.
            """
        super(UserData, self).__init__()
        self.username = unicode(username)
        self.password = unicode(password)

    def set_username(self, username):
        """
            Set the username.
            """
        self.username = unicode(username)

    def set_password(self, password):
        """
            Set the password.
            """
        self.password = unicode(password)

    def set_groups(self, groups=[]):
        """
            Set the groups
            """
        self.groups = unicode(','.join(groups))

    def set_creation_date(self):
        """
            Set the creation datetime.
            """
        self.created_on = datetime.datetime.now()

    def set_last_login(self):
        """
            Set the last login datetime.
            """
        self.last_login = datetime.datetime.now()

    def activate(self):
        """
            Activate the user.
            """
        self.is_active = True

    def deactivate(self):
        """
            Deactivate the user.
            """
        self.is_active = False

    def set_superuser(self, value):
        """
            Set the superuser flag.
            """
        self.superuser = value
Example #13
0
class BuildQueue(SQLBase):
    _table = "BuildQueue"
    _defaultOrder = "id"

    def __init__(self,
                 build_farm_job,
                 estimated_duration=DEFAULT,
                 virtualized=DEFAULT,
                 processor=DEFAULT,
                 lastscore=None):
        super(BuildQueue, self).__init__(_build_farm_job=build_farm_job,
                                         virtualized=virtualized,
                                         processor=processor,
                                         estimated_duration=estimated_duration,
                                         lastscore=lastscore)
        if lastscore is None and self.specific_build is not None:
            self.score()

    _build_farm_job_id = Int(name='build_farm_job')
    _build_farm_job = Reference(_build_farm_job_id, 'BuildFarmJob.id')
    status = EnumCol(enum=BuildQueueStatus, default=BuildQueueStatus.WAITING)
    date_started = DateTime(tzinfo=pytz.UTC)

    builder = ForeignKey(dbName='builder', foreignKey='Builder', default=None)
    logtail = StringCol(dbName='logtail', default=None)
    lastscore = IntCol(dbName='lastscore', default=0)
    manual = BoolCol(dbName='manual', default=False)
    estimated_duration = IntervalCol()
    processor = ForeignKey(dbName='processor', foreignKey='Processor')
    virtualized = BoolCol(dbName='virtualized')

    @cachedproperty
    def specific_build(self):
        """See `IBuildQueue`."""
        bfj = self._build_farm_job
        specific_source = specific_build_farm_job_sources()[bfj.job_type]
        return specific_source.getByBuildFarmJob(bfj)

    @property
    def build_cookie(self):
        """See `IBuildQueue`."""
        return self.specific_build.build_cookie

    def _clear_specific_build_cache(self):
        del get_property_cache(self).specific_build

    @staticmethod
    def preloadSpecificBuild(queues):
        from lp.buildmaster.model.buildfarmjob import BuildFarmJob
        queues = [removeSecurityProxy(bq) for bq in queues]
        load_related(BuildFarmJob, queues, ['_build_farm_job_id'])
        bfj_to_bq = dict((bq._build_farm_job, bq) for bq in queues)
        key = attrgetter('_build_farm_job.job_type')
        for job_type, group in groupby(sorted(queues, key=key), key=key):
            source = getUtility(ISpecificBuildFarmJobSource, job_type.name)
            builds = source.getByBuildFarmJobs(
                [bq._build_farm_job for bq in group])
            for build in builds:
                bq = bfj_to_bq[removeSecurityProxy(build).build_farm_job]
                get_property_cache(bq).specific_build = build

    @property
    def current_build_duration(self):
        """See `IBuildQueue`."""
        date_started = self.date_started
        if date_started is None:
            return None
        else:
            return self._now() - date_started

    def destroySelf(self):
        """Remove this record."""
        builder = self.builder
        specific_build = self.specific_build
        Store.of(self).remove(self)
        Store.of(self).flush()
        if builder is not None:
            del get_property_cache(builder).currentjob
        del get_property_cache(specific_build).buildqueue_record
        self._clear_specific_build_cache()

    def manualScore(self, value):
        """See `IBuildQueue`."""
        self.lastscore = value
        self.manual = True

    def score(self):
        """See `IBuildQueue`."""
        if self.manual:
            return
        # Allow the `IBuildFarmJob` instance with the data/logic specific to
        # the job at hand to calculate the score as appropriate.
        self.lastscore = self.specific_build.calculateScore()

    def markAsBuilding(self, builder):
        """See `IBuildQueue`."""
        self.builder = builder
        self.status = BuildQueueStatus.RUNNING
        self.date_started = UTC_NOW
        self.specific_build.updateStatus(BuildStatus.BUILDING)
        if builder is not None:
            del get_property_cache(builder).currentjob

    def collectStatus(self, slave_status):
        """See `IBuildQueue`."""
        builder_status = slave_status["builder_status"]
        if builder_status == "BuilderStatus.ABORTING":
            self.logtail = "Waiting for slave process to be terminated"
        elif slave_status.get("logtail") is not None:
            # slave_status["logtail"] is normally an xmlrpclib.Binary
            # instance, and the contents might include invalid UTF-8 due to
            # being a fixed number of bytes from the tail of the log.  Turn
            # it into Unicode as best we can.
            self.logtail = str(slave_status.get("logtail")).decode(
                "UTF-8", errors="replace")

    def suspend(self):
        """See `IBuildQueue`."""
        if self.status != BuildQueueStatus.WAITING:
            raise AssertionError("Only waiting jobs can be suspended.")
        self.status = BuildQueueStatus.SUSPENDED

    def resume(self):
        """See `IBuildQueue`."""
        if self.status != BuildQueueStatus.SUSPENDED:
            raise AssertionError("Only suspended jobs can be resumed.")
        self.status = BuildQueueStatus.WAITING

    def reset(self):
        """See `IBuildQueue`."""
        builder = self.builder
        self.builder = None
        self.status = BuildQueueStatus.WAITING
        self.date_started = None
        self.logtail = None
        self.specific_build.updateStatus(BuildStatus.NEEDSBUILD)
        if builder is not None:
            del get_property_cache(builder).currentjob

    def cancel(self):
        """See `IBuildQueue`."""
        if self.status == BuildQueueStatus.WAITING:
            # If the job's not yet on a slave then we can just
            # short-circuit to completed cancellation.
            self.markAsCancelled()
        elif self.status == BuildQueueStatus.RUNNING:
            # Otherwise set the statuses to CANCELLING so buildd-manager
            # can kill the slave, grab the log, and call
            # markAsCancelled() when it's done.
            self.status = BuildQueueStatus.CANCELLING
            self.specific_build.updateStatus(BuildStatus.CANCELLING)
        else:
            raise AssertionError("Tried to cancel %r from %s" %
                                 (self, self.status.name))

    def markAsCancelled(self):
        """See `IBuildQueue`."""
        self.specific_build.updateStatus(BuildStatus.CANCELLED)
        self.destroySelf()

    def getEstimatedJobStartTime(self, now=None):
        """See `IBuildQueue`."""
        from lp.buildmaster.queuedepth import estimate_job_start_time
        return estimate_job_start_time(self, now or self._now())

    @staticmethod
    def _now():
        """Return current time (UTC).  Overridable for test purposes."""
        return datetime.now(pytz.utc)