Skip to content

Instantly share code, notes, and snippets.

@agateau
Created March 27, 2012 14:33
Show Gist options
  • Save agateau/2216442 to your computer and use it in GitHub Desktop.
Save agateau/2216442 to your computer and use it in GitHub Desktop.
Copy album covers downloaded by Clementine in the matching album dir
#!/usr/bin/env python
# encoding: utf-8
# Author: Aurélien Gâteau <agateau@kde.org>
# License: GPLv3+
import filecmp
import os
import shutil
import sqlite3
import sys
import urllib
from optparse import OptionParser
DEFAULT_DB_PATH = os.path.expanduser("~/.config/Clementine/clementine.db")
USAGE=("""%%prog [options] [<clementine_db>]
Copy album covers downloaded by Clementine in the matching album dir.
Cover images are saved under the name "folder.jpg" in the album dir.
<clementine_db> defaults to "%s".
""" % DEFAULT_DB_PATH).strip()
def list_covers(conn, dir_filter_expr=""):
def dir_for_url(url):
d = urllib.url2pathname(str(url))
# Remove file://
d = d[7:]
assert d[0] == "/"
return unicode(os.path.dirname(d), "utf-8")
curs = conn.cursor()
if dir_filter_expr == "":
curs.execute("select distinct art_manual, filename from songs group by art_manual")
else:
args = ("%" + dir_filter_expr + "%",)
curs.execute("select distinct art_manual, filename from songs where filename like ? group by art_manual", args)
return [(x, dir_for_url(y)) for x, y in curs if x]
def u8(txt):
return txt.encode("utf-8")
def main():
parser = OptionParser(usage=USAGE)
parser.add_option("-f", "--filter", dest="filter", default="",
metavar="FILTER",
help="Only apply to songs whose path contains FILTER")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=False,
help="Be more verbose")
parser.add_option("--dry-run",
action="store_true", dest="dry_run", default=False,
help="Simulate")
(options, args) = parser.parse_args()
if len(args) > 1:
parser.error("Wrong number of arguments")
if len(args) == 1:
db_path = args[0]
else:
db_path = DEFAULT_DB_PATH
print "Using '%s' as db path" % db_path
assert os.path.isfile(db_path)
conn = sqlite3.connect(db_path)
lst = list_covers(conn, options.filter)
for cover, dir in lst:
dst_name = os.path.join(dir, "folder.jpg")
if os.path.exists(dst_name) and filecmp.cmp(cover, dst_name):
if options.verbose:
print "Skipping %s" % dst_name
else:
if options.dry_run:
print "Would copy '%s' to '%s'" % (u8(cover), u8(dst_name))
else:
print "Copying '%s' to '%s'" % (u8(cover), u8(dst_name))
shutil.copy2(cover, dst_name)
return 0
if __name__ == "__main__":
sys.exit(main())
# vi: ts=4 sw=4 et
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment