remove tmp files when they leave playlist

however, this doesn't work consistently across larigira restarts: you should expect that restarting larigira
will cause leftover files to remain.
refs #12
This commit is contained in:
boyska 2016-09-14 13:56:14 +02:00
parent 5c6f9b746f
commit e35834a21d
2 changed files with 52 additions and 0 deletions

View file

@ -9,6 +9,7 @@ from mpd import MPDClient, ConnectionError, CommandError
from .event import Monitor from .event import Monitor
from .eventutils import ParentedLet, Timer from .eventutils import ParentedLet, Timer
from .audiogen import audiogenerate from .audiogen import audiogenerate
from .unused import UnusedCleaner
def get_mpd_client(conf): def get_mpd_client(conf):
@ -99,6 +100,7 @@ class Controller(gevent.Greenlet):
self.conf = conf self.conf = conf
self.q = Queue() self.q = Queue()
self.player = Player(self.conf) self.player = Player(self.conf)
self.tmpcleaner = UnusedCleaner(conf)
if 'DB_URI' in self.conf: if 'DB_URI' in self.conf:
self.monitor = Monitor(self.q, self.conf) self.monitor = Monitor(self.q, self.conf)
self.monitor.parent_greenlet = self self.monitor.parent_greenlet = self
@ -125,6 +127,7 @@ class Controller(gevent.Greenlet):
if kind == 'timer' or (kind == 'mpc' and if kind == 'timer' or (kind == 'mpc' and
args[0] in ('player', 'playlist')): args[0] in ('player', 'playlist')):
gevent.Greenlet.spawn(self.player.check_playlist) gevent.Greenlet.spawn(self.player.check_playlist)
self.tmpcleaner.check_playlist()
elif kind == 'mpc': elif kind == 'mpc':
pass pass
elif kind == 'uris_enqueue': elif kind == 'uris_enqueue':
@ -135,6 +138,9 @@ class Controller(gevent.Greenlet):
except Exception: except Exception:
self.log.exception("Error while adding to queue; " self.log.exception("Error while adding to queue; "
"bad audiogen output?") "bad audiogen output?")
else:
for fname in args[0]['uris']:
self.tmpcleaner.watch(fname)
elif (kind == 'signal' and args[0] == signal.SIGALRM) or \ elif (kind == 'signal' and args[0] == signal.SIGALRM) or \
kind == 'refresh': kind == 'refresh':
# it's a tick! # it's a tick!

46
larigira/unused.py Normal file
View file

@ -0,0 +1,46 @@
'''
This component will look for files to be removed. There are some assumptions:
* Only files in $TMPDIR are removed. Please remember that larigira has its
own specific TMPDIR
* MPD URIs are parsed, and only file:/// is supported
'''
import os
import logging
import mpd
class UnusedCleaner:
def __init__(self, conf):
self.conf = conf
self.waiting_removal_files = set()
self.log = logging.getLogger(self.__class__.__name__)
def _get_mpd(self):
mpd_client = mpd.MPDClient(use_unicode=True)
mpd_client.connect(self.conf['MPD_HOST'], self.conf['MPD_PORT'])
return mpd_client
def watch(self, uri):
'''
adds fpath to the list of "watched" file
as soon as it leaves the mpc playlist, it is removed
'''
if not uri.startswith('file:///'):
raise ValueError('not a file URI')
fpath = uri[len('file://'):]
if not os.path.exists(fpath):
self.log.warning('a path that does not exist is being monitored')
self.waiting_removal_files.add(fpath)
def check_playlist(self):
'''check playlist + internal watchlist to see what can be removed'''
mpd = self._get_mpd()
files_in_playlist = {song['file'] for song in mpd.playlistid()
if song['file'].startswith('/')}
for fpath in self.waiting_removal_files - files_in_playlist:
# we can remove it!
self.log.debug('removing unused: {}'.format(fpath))
self.waiting_removal_files.remove(fpath)
if os.path.exists(fpath):
os.unlink(fpath)