actual scripts
This commit is contained in:
143
backup_mpd_playlist.py
Executable file
143
backup_mpd_playlist.py
Executable file
@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python
|
||||
# Back up the state of MPD (current playlist and so on)
|
||||
|
||||
import ast
|
||||
import datetime
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import pprint
|
||||
import mpd
|
||||
from optparse import OptionParser
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option("-s", "--server", dest="host",
|
||||
help="set the MPD hostname (default: localhost)", metavar="HOST")
|
||||
parser.add_option("-p", "--port", dest="port",
|
||||
help="set the MPD port (default: 6600)", metavar="6600")
|
||||
parser.add_option("-d", dest="dest",
|
||||
help="save or load the backup to directory <DIR>", metavar="DIR")
|
||||
parser.add_option("-l", dest="load", action="store_true",
|
||||
help="load the last backup")
|
||||
parser.add_option("-f", "--file", dest="load_file",
|
||||
help="load the backup in file <FILE>", metavar="FILE")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
host = options.host or 'localhost'
|
||||
port = options.port or '6600'
|
||||
backup_dir = options.dest or '/var/lib/mpd/backups'
|
||||
now = datetime.datetime.now().strftime("%Y%m%d@%H:%M")
|
||||
|
||||
client = mpd.MPDClient()
|
||||
client.timeout = 10
|
||||
client.idletimeout = 10
|
||||
client.connect(host, port)
|
||||
|
||||
# Get the contents of the most recent backup
|
||||
all_backups = [os.path.join(backup_dir, f) for f in os.listdir(backup_dir) if f.startswith('mpd_state')]
|
||||
last_backup = max(all_backups, key=os.path.getctime) if all_backups else []
|
||||
backup_output = open(last_backup).read() if last_backup else ''
|
||||
|
||||
if options.load or options.load_file:
|
||||
# Override the last backup if the user desires
|
||||
if options.load_file:
|
||||
if not os.path.exists(options.load_file):
|
||||
sys.exit("No such file: " + options.load_file)
|
||||
backup_output = open(options.load_file).read()
|
||||
|
||||
# load file into backup_output
|
||||
backup = ast.literal_eval(backup_output)
|
||||
# Check server and port
|
||||
if backup['src'] != host+":"+port:
|
||||
if not sys.stdin.isatty():
|
||||
sys.exit("Error: Backup is from a different server or port.")
|
||||
c = raw_input("Error: Backup is from a different server or port. Continue? (y/N) ").rstrip('\n')
|
||||
if c != 'Y' and c != 'y':
|
||||
sys.exit("Exiting.")
|
||||
# Clear playlist
|
||||
client.clear()
|
||||
# Load songs
|
||||
for song in backup['playlist']:
|
||||
try:
|
||||
client.add(song)
|
||||
except mpd.CommandError as e:
|
||||
print("File not found: %s" % e)
|
||||
pass
|
||||
# Parse and communicate extra info
|
||||
if 'repeat' in backup:
|
||||
client.repeat(backup['repeat'])
|
||||
if 'random' in backup:
|
||||
client.random(backup['random'])
|
||||
if 'single' in backup:
|
||||
client.single(backup['single'])
|
||||
if 'consume' in backup:
|
||||
client.consume(backup['consume'])
|
||||
id = None
|
||||
if 'current' in backup:
|
||||
for song in client.playlistinfo():
|
||||
if song['file'] == backup['current']:
|
||||
id = song['id']
|
||||
print song['file']
|
||||
print id
|
||||
next
|
||||
if not id:
|
||||
print "Error: Can't find currently-playing song on playlist."
|
||||
if 'time' in backup and id:
|
||||
client.seekid(id, backup['time'])
|
||||
if 'state' in backup:
|
||||
if backup['state'] == 'play':
|
||||
client.play()
|
||||
elif backup['state'] == 'pause':
|
||||
client.pause(1)
|
||||
elif backup['state'] == 'stop':
|
||||
client.stop()
|
||||
# setvol returns an error, for some reason
|
||||
# mpd.CommandError: [52@0] {setvol} problems setting volume
|
||||
#if 'volume' in backup:
|
||||
# client.setvol(backup['volume'])
|
||||
|
||||
else:
|
||||
# Get current state
|
||||
get_status = client.status()
|
||||
get_playlist = client.playlistinfo()
|
||||
get_currentsong = client.currentsong()
|
||||
|
||||
state = {}
|
||||
playlist = []
|
||||
for song in get_playlist:
|
||||
playlist.append(song["file"])
|
||||
|
||||
state = dict(
|
||||
playlist = playlist,
|
||||
src = host+":"+port,
|
||||
consume = get_status['consume'],
|
||||
current = get_currentsong['file'] if get_currentsong['file'] else '',
|
||||
time = get_status['time'].split(":")[0] if get_status['time'] else '',
|
||||
random = get_status['random'],
|
||||
repeat = get_status['repeat'],
|
||||
single = get_status['single'],
|
||||
state = get_status['state'],
|
||||
volume = get_status['volume'],
|
||||
)
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
current_output = pp.pformat(state)
|
||||
|
||||
# We don't care if the volume or currently-playing song has changed, only
|
||||
# the playlist
|
||||
strip = re.compile(r'\s*?[\'\"](consume|current|random|repeat|single|state|time|volume)[\'\"]:\s*?[\'\"].*?[\'\"],?');
|
||||
curr = strip.sub('', current_output)
|
||||
prev = strip.sub('', backup_output)
|
||||
|
||||
# Only copy if the current playlist has changed
|
||||
if current_output != backup_output:
|
||||
new_backup_file = os.path.join(backup_dir, 'mpd_state' + "-" + now)
|
||||
# Write backup
|
||||
new_backup = open(new_backup_file, 'w')
|
||||
new_backup.write(current_output)
|
||||
new_backup.close()
|
||||
|
||||
client.close()
|
||||
client.disconnect()
|
||||
|
||||
# vim: set expandtab shiftwidth=4 softtabstop=4 textwidth=79:
|
Reference in New Issue
Block a user