~launchpad-pqm/launchpad/devel

11411.6.3 by Julian Edwards
move ArchiveJobType
1
# Copyright 2010 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
11017.5.16 by James Westby
Fix some lint.
3
4
__metaclass__ = object
5
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
6
from lazr.delegates import delegates
11017.5.1 by James Westby
Initial work on ArchiveJob.
7
import simplejson
8
from sqlobject import SQLObjectNotFound
9
from storm.expr import And
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
10
from storm.locals import (
11
    Int,
12
    Reference,
13
    Unicode,
14
    )
11017.5.1 by James Westby
Initial work on ArchiveJob.
15
from zope.component import getUtility
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
16
from zope.interface import (
17
    classProvides,
18
    implements,
19
    )
11017.5.1 by James Westby
Initial work on ArchiveJob.
20
21
from canonical.database.enumcol import EnumCol
22
from canonical.launchpad.webapp.interfaces import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
23
    DEFAULT_FLAVOR,
24
    IStoreSelector,
25
    MAIN_STORE,
26
    MASTER_FLAVOR,
27
    )
14550.1.1 by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad
28
from lp.services.database.stormbase import StormBase
11017.5.1 by James Westby
Initial work on ArchiveJob.
29
from lp.services.job.model.job import Job
30
from lp.services.job.runner import BaseRunnableJob
11411.6.3 by Julian Edwards
move ArchiveJobType
31
from lp.soyuz.enums import ArchiveJobType
11017.5.1 by James Westby
Initial work on ArchiveJob.
32
from lp.soyuz.interfaces.archivejob import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
33
    IArchiveJob,
34
    IArchiveJobSource,
35
    )
11017.5.1 by James Westby
Initial work on ArchiveJob.
36
from lp.soyuz.model.archive import Archive
37
38
12243.4.2 by j.c.sackett
Updated all uses of storm.base.Storm with lp.services.stormbase.StormBase
39
class ArchiveJob(StormBase):
11017.5.1 by James Westby
Initial work on ArchiveJob.
40
    """Base class for jobs related to Archives."""
41
42
    implements(IArchiveJob)
43
44
    __storm_table__ = 'archivejob'
45
46
    id = Int(primary=True)
47
48
    job_id = Int(name='job')
49
    job = Reference(job_id, Job.id)
50
51
    archive_id = Int(name='archive')
52
    archive = Reference(archive_id, Archive.id)
53
54
    job_type = EnumCol(enum=ArchiveJobType, notNull=True)
55
56
    _json_data = Unicode('json_data')
57
58
    @property
59
    def metadata(self):
60
        return simplejson.loads(self._json_data)
61
62
    def __init__(self, archive, job_type, metadata):
11017.5.23 by James Westby
Fixes from review. Thanks Edwin.
63
        """Create an ArchiveJob.
11017.5.1 by James Westby
Initial work on ArchiveJob.
64
65
        :param archive: the archive this job relates to.
66
        :param job_type: the bugjobtype of this job.
67
        :param metadata: the type-specific variables, as a json-compatible
68
            dict.
69
        """
70
        super(ArchiveJob, self).__init__()
71
        json_data = simplejson.dumps(metadata)
72
        self.job = Job()
73
        self.archive = archive
74
        self.job_type = job_type
75
        # XXX AaronBentley 2009-01-29 bug=322819: This should be a bytestring,
76
        # but the db representation is unicode.
77
        self._json_data = json_data.decode('utf-8')
78
79
    @classmethod
80
    def get(cls, key):
81
        """Return the instance of this class whose key is supplied."""
82
        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
83
        instance = store.get(cls, key)
84
        if instance is None:
85
            raise SQLObjectNotFound(
86
                'No occurence of %s has key %s' % (cls.__name__, key))
87
        return instance
88
89
90
class ArchiveJobDerived(BaseRunnableJob):
91
    """Intermediate class for deriving from ArchiveJob."""
92
    delegates(IArchiveJob)
93
    classProvides(IArchiveJobSource)
94
95
    def __init__(self, job):
96
        self.context = job
97
98
    @classmethod
11017.5.3 by James Westby
There can only be one CopyArchiveJob per target archive.
99
    def create(cls, archive, metadata=None):
11017.5.1 by James Westby
Initial work on ArchiveJob.
100
        """See `IArchiveJob`."""
11017.5.3 by James Westby
There can only be one CopyArchiveJob per target archive.
101
        if metadata is None:
102
            metadata = {}
103
        job = ArchiveJob(archive, cls.class_job_type, metadata)
11017.5.1 by James Westby
Initial work on ArchiveJob.
104
        return cls(job)
105
106
    @classmethod
107
    def get(cls, job_id):
108
        """Get a job by id.
109
110
        :return: the ArchiveJob with the specified id, as the current
111
                 BugJobDerived subclass.
112
        :raises: SQLObjectNotFound if there is no job with the specified id,
113
                 or its job_type does not match the desired subclass.
114
        """
115
        job = ArchiveJob.get(job_id)
116
        if job.job_type != cls.class_job_type:
117
            raise SQLObjectNotFound(
118
                'No object found with id %d and type %s' % (job_id,
119
                cls.class_job_type.title))
120
        return cls(job)
121
122
    @classmethod
123
    def iterReady(cls):
124
        """Iterate through all ready BugJobs."""
125
        store = getUtility(IStoreSelector).get(MAIN_STORE, MASTER_FLAVOR)
126
        jobs = store.find(
127
            ArchiveJob,
128
            And(ArchiveJob.job_type == cls.class_job_type,
129
                ArchiveJob.job == Job.id,
130
                Job.id.is_in(Job.ready_jobs),
131
                ArchiveJob.archive == Archive.id))
132
        return (cls(job) for job in jobs)
133
134
    def getOopsVars(self):
135
        """See `IRunnableJob`."""
12243.4.9 by j.c.sackett
Lint fixes.
136
        vars = BaseRunnableJob.getOopsVars(self)
11017.5.1 by James Westby
Initial work on ArchiveJob.
137
        vars.extend([
138
            ('archive_id', self.context.archive.id),
139
            ('archive_job_id', self.context.id),
140
            ('archive_job_type', self.context.job_type.title),
141
            ])
142
        return vars