~ubuntu-branches/ubuntu/karmic/calibre/karmic

« back to all changes in this revision

Viewing changes to src/calibre/utils/ipc/job.py

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-30 12:49:41 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730124941-qjdsmri25zt8zocn
Tags: 0.6.3+dfsg-0ubuntu1
* New upstream release. Please see http://calibre.kovidgoyal.net/new_in_6/
  for the list of new features and changes.
* remove_postinstall.patch: Update for new version.
* build_debug.patch: Does not apply any more, disable for now. Might not be
  necessary any more.
* debian/copyright: Fix reference to versionless GPL.
* debian/rules: Drop obsolete dh_desktop call.
* debian/rules: Add workaround for weird Python 2.6 setuptools behaviour of
  putting compiled .so files into src/calibre/plugins/calibre/plugins
  instead of src/calibre/plugins.
* debian/rules: Drop hal fdi moving, new upstream version does not use hal
  any more. Drop hal dependency, too.
* debian/rules: Install udev rules into /lib/udev/rules.d.
* Add debian/calibre.preinst: Remove unmodified
  /etc/udev/rules.d/95-calibre.rules on upgrade.
* debian/control: Bump Python dependencies to 2.6, since upstream needs
  it now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
 
3
from __future__ import with_statement
 
4
 
 
5
__license__   = 'GPL v3'
 
6
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
 
7
__docformat__ = 'restructuredtext en'
 
8
 
 
9
_count = 0
 
10
 
 
11
import time, cStringIO
 
12
from Queue import Queue, Empty
 
13
 
 
14
class BaseJob(object):
 
15
 
 
16
    WAITING  = 0
 
17
    RUNNING  = 1
 
18
    FINISHED = 2
 
19
 
 
20
    def __init__(self, description, done=lambda x: x):
 
21
        global _count
 
22
        _count += 1
 
23
 
 
24
        self.id            = _count
 
25
        self.description   = description
 
26
        self.done          = done
 
27
        self.done2         = None
 
28
        self.killed        = False
 
29
        self.failed        = False
 
30
        self.start_time    = None
 
31
        self.result        = None
 
32
        self.duration      = None
 
33
        self.log_path      = None
 
34
        self.notifications = Queue()
 
35
 
 
36
        self._run_state    = self.WAITING
 
37
        self.percent       = 0
 
38
        self._message      = None
 
39
        self._status_text  = _('Waiting...')
 
40
        self._done_called  = False
 
41
 
 
42
    def update(self, consume_notifications=True):
 
43
        if self.duration is not None:
 
44
            self._run_state   = self.FINISHED
 
45
            self.percent = 100
 
46
            if self.killed:
 
47
                self._status_text = _('Stopped')
 
48
            else:
 
49
                self._status_text = _('Error') if self.failed else _('Finished')
 
50
            if not self._done_called:
 
51
                self._done_called = True
 
52
                try:
 
53
                    self.done(self)
 
54
                except:
 
55
                    pass
 
56
                try:
 
57
                    if callable(self.done2):
 
58
                        self.done2(self)
 
59
                except:
 
60
                    pass
 
61
        elif self.start_time is not None:
 
62
            self._run_state = self.RUNNING
 
63
            self._status_text = _('Working...')
 
64
 
 
65
        while consume_notifications:
 
66
            try:
 
67
                self.percent, self._message = self.notifications.get_nowait()
 
68
                self.percent *= 100.
 
69
            except Empty:
 
70
                break
 
71
 
 
72
    @property
 
73
    def status_text(self):
 
74
        if self._run_state == self.FINISHED or not self._message:
 
75
            return self._status_text
 
76
        return self._message
 
77
 
 
78
    @property
 
79
    def run_state(self):
 
80
        return self._run_state
 
81
 
 
82
    @property
 
83
    def running_time(self):
 
84
        if self.duration is not None:
 
85
            return self.duration
 
86
        if self.start_time is not None:
 
87
            return time.time() - self.start_time
 
88
        return None
 
89
 
 
90
    @property
 
91
    def is_finished(self):
 
92
        return self._run_state == self.FINISHED
 
93
 
 
94
    @property
 
95
    def is_started(self):
 
96
        return self._run_state != self.WAITING
 
97
 
 
98
    @property
 
99
    def is_running(self):
 
100
        return self.is_started and not self.is_finished
 
101
 
 
102
    def __cmp__(self, other):
 
103
        if self.is_finished == other.is_finished:
 
104
            if self.start_time is None:
 
105
                if other.start_time is None: # Both waiting
 
106
                    return cmp(other.id, self.id)
 
107
                else:
 
108
                    return 1
 
109
            else:
 
110
                if other.start_time is None:
 
111
                    return -1
 
112
                else: # Both running
 
113
                    return cmp(other.start_time, self.start_time)
 
114
 
 
115
        else:
 
116
            return 1 if self.is_finished else -1
 
117
        return 0
 
118
 
 
119
    @property
 
120
    def log_file(self):
 
121
        if self.log_path:
 
122
            return open(self.log_path, 'rb')
 
123
        return cStringIO.StringIO(_('No details available.'))
 
124
 
 
125
    @property
 
126
    def details(self):
 
127
        return self.log_file.read().decode('utf-8')
 
128
 
 
129
 
 
130
class ParallelJob(BaseJob):
 
131
 
 
132
    def __init__(self, name, description, done, args=[], kwargs={}):
 
133
        self.name, self.args, self.kwargs = name, args, kwargs
 
134
        BaseJob.__init__(self, description, done)
 
135
 
 
136
 
 
137