Last active
December 2, 2016 13:00
-
-
Save Tamriel/204ee6e3fe84e7450d2a71d6127f34eb to your computer and use it in GitHub Desktop.
Quod Libet Plugin to sync saved searches to a device
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import cPickle | |
from gi.repository import Gtk | |
from quodlibet import get_user_dir | |
from quodlibet import qltk | |
from quodlibet.plugins.events import EventPlugin | |
from quodlibet.qltk.ccb import ConfigCheckButton | |
from quodlibet.query import Query | |
from quodlibet.plugins import PluginConfigMixin | |
from quodlibet import config | |
from pydub import AudioSegment | |
class SyncToDevice(EventPlugin, PluginConfigMixin): | |
PLUGIN_ID = "sync_to_device" | |
PLUGIN_NAME = ("Sync to device") | |
PLUGIN_DESC = ( | |
'Converts all songs from the selected saved searches to 192 kbs and synchronizes them to the specified path ' | |
"(all songs at that path which are not in the saved searches will be deleted). " | |
"Needs the python package 'pydub'.") | |
c_path = __name__ + '_path' | |
@classmethod | |
def PluginPreferences(self, parent): | |
vbox = Gtk.VBox(spacing=6) | |
queries = {} | |
query_path = os.path.join(get_user_dir(), 'lists', 'queries.saved') | |
with open(query_path, 'rU') as query_file: | |
for query_string in query_file: | |
name = next(query_file).strip() | |
queries[name] = Query(query_string.strip()) | |
for query_name, query in queries.iteritems(): | |
check_button = ConfigCheckButton((query_name), "plugins", self._config_key(query_name)) | |
check_button.set_active(self.config_get_bool(query_name)) | |
vbox.pack_start(check_button, False, True, 0) | |
def start(button): | |
enabled_queries = [] | |
for query_name, query in queries.iteritems(): | |
if self.config_get_bool(query_name): | |
enabled_queries.append(query) | |
selected_songs = [] | |
songs_path = os.path.join(get_user_dir(), 'songs') | |
with open(songs_path, 'rb') as songs_file: | |
songs = cPickle.load(songs_file) | |
for song in songs: | |
if any(query.search(song) for query in enabled_queries): | |
selected_songs.append(song) | |
filename_list = [] | |
destination_path = config.get('plugins', self.c_path) | |
for song in selected_songs: | |
song_path = song['~filename'] | |
song_file_name = song("artist") + song("album") + song("title") | |
song_file_name = "".join(c for c in song_file_name if c.isalnum()) + ".mp3" # colons don't work on FAT | |
filename_list.append(song_file_name) | |
destination_file = destination_path + song_file_name | |
# skip existing files | |
if not os.path.exists(destination_file): | |
sound = AudioSegment.from_file(song_path) | |
sound.export(destination_file, format="mp3", bitrate="192k", tags=song) | |
# delete files which are not in the saved searches anymore | |
for existing_file_name in os.listdir(destination_path): | |
if existing_file_name not in filename_list: | |
os.remove(destination_path + existing_file_name) | |
message = qltk.Message(Gtk.MessageType.WARNING, None, "", "Synchronization finished.") | |
message.run() | |
def path_changed(entry): | |
self.path = entry.get_text() | |
config.set('plugins', self.c_path, self.path) | |
try: | |
self.pattern = config.get('plugins', self.c_path) | |
except: | |
self.pattern = '' | |
config.set('plugins', self.c_path, self.pattern) | |
destination_path_box = Gtk.HBox(spacing=3) | |
destination_path = Gtk.Entry() | |
destination_path.set_text(self.pattern) | |
destination_path.connect('changed', path_changed) | |
destination_path_box.pack_start(Gtk.Label(label="Destination path:"), True, True, 0) | |
destination_path_box.pack_start(destination_path, True, True, 0) | |
start_button = Gtk.Button(label=("Start synchronization")) | |
start_button.connect('clicked', start) | |
vbox.pack_start(destination_path_box, True, True, 0) | |
vbox.pack_start(start_button, True, True, 0) | |
label = Gtk.Label(label="Quod Libet will become unresponsive. You will get a message when finished.") | |
vbox.pack_start(label, True, True, 0) | |
return qltk.Frame(("Select the saved searches to copy:"), child=vbox) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment