/usr/share/pyshared/quodlibet/qltk/tracker.py is in exfalso 3.0.2-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | # -*- coding: utf-8 -*-
# Copyright 2004-2005 Joe Wreschnig, Michael Urman, IƱigo Serna
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation
import time
from gi.repository import Gdk, GObject, GLib
import quodlibet
from quodlibet import const
from quodlibet import config
from quodlibet import util
from quodlibet.qltk.msg import ErrorMessage
MAX_ERRORS = 10
class TimeTracker(GObject.GObject):
"""Emits tick every second (with up to one second jitter) as long
as the player is activly playing.
Uses timeout_add_seconds, so multiple instances of this should
sync and not produce more wakeups.
"""
__gsignals__ = {
'tick': (GObject.SignalFlags.RUN_LAST, None, ()),
}
def __init__(self, player):
super(TimeTracker, self).__init__()
self.__player = player
self.__id = None
self.__sigs = [
player.connect("paused", self.__paused),
player.connect("unpaused", self.__unpaused),
]
def destroy(self):
map(self.__player.disconnect, self.__sigs)
self.__source_remove()
def __source_remove(self):
if self.__id is not None:
GLib.source_remove(self.__id)
self.__id = None
def __update(self):
if self.__stop:
self.__source_remove()
return False
self.emit("tick")
return True
def __paused(self, *args):
# By removing the timeout only in the callback we are safe from
# huge deviation caused by lots of pause/unpause actions.
self.__stop = True
def __unpaused(self, *args):
self.__stop = False
if self.__id is None:
self.__id = GLib.timeout_add_seconds(1, self.__update)
class SongTracker(object):
def __init__(self, librarian, player, pl):
player.connect_object('song-ended', self.__end, librarian, pl)
player.connect_object('song-started', self.__start, librarian)
player.connect('error', self.__error, librarian)
timer = TimeTracker(player)
timer.connect("tick", self.__timer)
self.__errors_in_a_row = 0
self.elapsed = 0
quodlibet.quit_add(1, self.__quit, librarian, player)
def __error(self, player, song, error, librarian):
newstr = u"%s: %s\n\n" % (
util.decode(time.asctime(), const.ENCODING), error)
self.__errors_in_a_row += 1
if self.__errors_in_a_row > MAX_ERRORS:
self.__errors_in_a_row = 0
ErrorMessage(None, _("Too Many Errors"),
_("Stopping playback because there were %d errors "
"in a row.") % MAX_ERRORS).run()
player.go_to(None)
player.paused = True
song["~errors"] = newstr + song.get("~errors", "")
def __start(self, librarian, song):
self.elapsed = 0
if song is not None:
if song.multisong:
song["~#lastplayed"] = int(time.time())
song["~#playcount"] = song.get("~#playcount", 0) + 1
else:
config.set("memory", "song", song["~filename"])
song["~#laststarted"] = int(time.time())
librarian.changed([song])
else:
config.set("memory", "song", "")
def __end(self, librarian, song, ended, pl):
if song is None or song.multisong:
return
elif self.elapsed > 0.5 * song.get("~#length", 1):
song["~#lastplayed"] = int(time.time())
song["~#playcount"] = song.get("~#playcount", 0) + 1
librarian.changed([song])
elif pl.current is not song:
if "~errors" not in song:
song["~#skipcount"] = song.get("~#skipcount", 0) + 1
librarian.changed([song])
if not ended and song and "~errors" in song:
del(song["~errors"])
self.__errors_in_a_row = 0
def __quit(self, librarian, player):
config.set("memory", "seek", player.get_position())
player.emit('song-ended', player.song, True)
return 0
def __timer(self, timer):
self.elapsed += 1
|