source: server/lib/gutenbach/server/player.py @ bd5bffc

no-cups
Last change on this file since bd5bffc was bd5bffc, checked in by Jessica B. Hamrick <jhamrick@…>, 12 years ago

Fix logger issues in job and player

  • Property mode set to 100644
File size: 3.9 KB
Line 
1import logging
2import threading
3import subprocess
4import time
5from . import sync
6
7# initialize logger
8logger = logging.getLogger(__name__)
9
10class Player(threading.Thread):
11
12    def __init__(self, fh, *args, **kwargs):
13        self.lock = threading.RLock()
14
15        with self.lock:
16            super(Player, self).__init__(*args, **kwargs)
17            self.fh = fh
18            self.player = None
19            self._callback = None
20            self._paused = False
21            self._done = False
22            self._dryrun = False
23            self._dryrun_time = 0.5
24            self._lag = 0.01
25
26    @property
27    @sync
28    def is_playing(self):
29        if self._dryrun:
30            return self.ident is not None and \
31                   self.isAlive() and \
32                   not self.is_done
33        else:
34            return self.ident is not None and \
35                   self.isAlive() and \
36                   not self.is_done and \
37                   self.player is not None and \
38                   self.player.poll() is None
39       
40    @property
41    @sync
42    def is_paused(self):
43        return self.is_playing and self._paused
44
45    @property
46    def is_done(self):
47        return self._done
48
49    @property
50    def callback(self):
51        return self._callback
52    @callback.setter
53    @sync
54    def callback(self, val):
55        self._callback = val
56
57    def start(self):
58        super(Player, self).start()
59        time.sleep(self._lag)
60
61    def run(self):
62        if self.fh is None:
63            raise ValueError, "file handler is None"
64       
65        logger.info("playing file '%s'" % self.fh.name)
66
67        with self.lock:
68            self._paused = False
69            self._done = False
70
71        command = ["mplayer", "-really-quiet", "-slave", self.fh.name]
72        logger.info("running '%s'", " ".join(command))
73
74        if self._dryrun:
75            step = 0.01
76            while self._dryrun_time > 0:
77                time.sleep(step)
78                self._dryrun_time -= step
79                while self.is_paused:
80                    time.sleep(0.01)
81
82        else:
83            with self.lock:
84                self.player = subprocess.Popen(
85                    command,
86                    stdin=subprocess.PIPE,
87                    stderr=subprocess.PIPE,
88                    stdout=subprocess.PIPE)
89
90            # wait for mplayer to finish
91            while True:
92                with self.lock:
93                    playing = self.is_playing
94                if not playing:
95                    break
96                time.sleep(0.1)
97
98            logger.info("mplayer finished with code %d" % self.player.returncode)
99       
100            # get output from mplayer and log it
101            with self.lock:
102                stderr = self.player.stderr.read()
103                stdout = self.player.stdout.read()
104           
105            if stderr.strip() != "":
106                logger.error(stderr)
107            if stdout.strip() != "":
108                logger.debug(stdout)
109
110        with self.lock:
111            if self.callback:
112                self.callback()
113            self._done = True
114
115    def mplayer_pause(self):
116        # Note: Inner lock due to sleep.
117        with self.lock:
118            if self.is_playing:
119                if not self._dryrun:
120                    self.player.stdin.write("pause\n")
121                self._paused = not(self._paused)
122                logger.info("paused: %s", self.is_paused)
123            else:
124                logger.warning("trying to pause non-playing job")
125        time.sleep(self._lag)
126
127    def mplayer_stop(self):
128        # Note: Inner lock due to join.
129        with self.lock:
130            if self.is_playing:
131                if not self._dryrun:
132                    self.player.stdin.write("quit\n")
133                else:
134                    self._dryrun_time = 0.0
135                logger.info("stopped")
136            else:
137                logger.warning("trying to stop non-playing job")
138        self.join()
139
Note: See TracBrowser for help on using the repository browser.