Print MythArchive Native DVD Labels

From MythTV Official Wiki
Jump to: navigation, search

This script is from a posting on trac ticket #2968 by schachte@csse.unimelb.edu.au.

This script will generate attractive music instructional dvd box labels listing the content of MythArchive? native format archive discs.

PythonIcon.png mytharchive_label_print.py


#!/usr/bin/env python
#
#  Copyright 2007 by Peter Schachte
#
# This script is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.


################################################################
# Generate nice printed labels for standard DVD boxes holding up to 4
# mytharchive native archive format DVDs.  This relies on cdlabelgen
# (http://www.aczoom.com/tools/cdinsert/) to do the actual postscript
# formatting.  It examines the DVD(s), reading the relevant information
# from the xml file stored on the disc itself to construct a suitable
# label listing the videos included on each disc in the box.
# 
# Currently, this script supports only native format archives, and only
# mythvideo files.  I'd like to support DVD format archives as well,
# but they do not contain the necessary information.  This script
# should be able to support recordings, but I have not implemented this
# yet.
#
# This code supports naming all discs with a common prefix (by
# default "MythArchive Disc ").  As each disc is inserted, you will
# be prompted for its number; the full name of the disc is the prefix
# followed by the entered text.  The prefix can be set to anything on
# the command line, including the empty string, and any text can be
# entered for the disc "number."
################################################################


import sys, os, glob
from optparse import OptionParser
from elementtree.ElementTree import ElementTree

################################################################
# Command line parsing and help text

def parse_command_line():
    """Handle parsing of command line."""
    parser = OptionParser(version="0.1")
    parser.add_option("-o", "--outfile", metavar="FILE", default="-",
                      help="write postscript output to FILE [default: stdout]")
    parser.add_option("-q", "--quiet", action="store_false",
                      dest="verbose", default=True,
                      help="don't print status messages to stderr")
    parser.add_option("-m", "--mountpoint", metavar="DIR",
                      help="mount DVD on DIR [default /media/cdrom]",
                      default="/media/cdrom")
    parser.add_option("-p", "--prefix", metavar="TEXT",
                      help="common prefix for discs " +
                           "[default 'MythArchive Disc ']",
                      default="MythArchive Disc ")
    (options,args) = parser.parse_args()
    return options


################################################################
# Main code

def main():
    options = parse_command_line()
    discs = []
    while True:
        added = get_titles(options)
        if added is None: break
        discs.append(added)

    if discs: 
        generate_cover(discs, options)
    else:
        print >> sys.stderr, "No titles found; no label generated."
        sys.exit(1)


################################################################
# Read one DVD to see what's on it

def get_titles(options):
    """Ask user to insert one DVD, and return list of items it contains."""
    while True:
        print "Insert DVD to include in DVD label now, " + \
                         "then enter the MythArchive"
        print "disc number, or just hit enter if there are " + \
                         "no more DVDs to include"
        discnum = raw_input("Disc number, or enter to quit:  ")
        if discnum == "": return None
        if 0 != os.system("mount -r " + options.mountpoint):
            print >> stderr, "Error:  couldn't mount DVD on " + \
                             options.mountpoint
            continue
        items = []
        for dirname in os.listdir(options.mountpoint):
            if options.verbose:
                print >> sys.stderr, "    " + dirname
            for filename in glob.glob(options.mountpoint + "/" +
                                      dirname + "/*.xml"):
                # there should only be one xml file in each directory
                items.append(ElementTree(file=filename).getroot())
                
        os.system("eject " + options.mountpoint)
        return (discnum, items)

################################################################
# Finally generate the cover Postscript file

def generate_cover(discs, options):
    """Generate the DVD cover postscript output for the specified titles."""
    lines = []
    if len(discs) > 1:
        names = [name for (name,content) in discs]
        title = options.prefix + ", ".join(names[:-1]) + " and " + names[-1]
        for (name,content) in discs:
            lines.append("")
            lines.append("{#BI}     ----- " +
                           options.prefix + name + " -----")
            lines.append("")
            lines += text_for_one_disc(content, options)
            lines.append("")
    else:
        title = options.prefix + discs[0][0]
        lines += text_for_one_disc(discs[0][1], options)

    
    if options.verbose:
        print >> sys.stderr, \
            ("cdlabelgen --create-dvd-outside -c '%s' " +
             "-w -o '%s' -v 40 -i '%s'") % \
            (quote(title), quote(options.outfile), quote("%".join(lines)))
    sys.exit(os.system(
        "cdlabelgen --create-dvd-outside -c '%s' -w -o '%s' -v 40 -i '%s'" % \
        (quote(title), quote(options.outfile), quote("%".join(lines)))))


################################################################
# Generate the output for one disc

def text_for_one_disc(content, options):        
    lines = []
    for item in content:
        meta = item.find("videometadata")
        if item.get("type") == "video" and meta:
            title = meta.findtext("title")
            if title:
                text = "{#B}" + title
                year     = meta.findtext("year")
                if year: text += " (" + year + ")"
                lines.append(text)
                
                line = []
                gens     = item.find("genres")
                if gens:
                    line.append(", ".join([g.get("genre") for g in gens]))
                length   = meta.findtext("length")
                if length and length != "0":
                    line.append("Running time: %s minutes" % length)
                if line: lines.append("; ".join(line))

                line = []
                rating   = meta.findtext("rating")
                if rating: line.append(rating)
                tmdb     = meta.findtext("userrating")
                if tmdb: line.append("Internet rating: %s / 10" % tmdb)
                if line: lines.append("; ".join(line))
                lines.append("")
    return lines

################################################################
# Protect single quote characters from the shell

def quote(str):
    """Return the input string with single quotes escaped."""
    return str.replace("'", "'\"'\"'")

################################################################

if __name__ == "__main__":
    main()