Update of /cvsroot/freevo/freevo/src/util
In directory sc8-pr-cvs1:/tmp/cvs-serv18569/util
Added Files:
fxdimdb.py
Log Message:
Moved fxdimdb.py to util; it doesn't use the OSD, and having in video
makes it import video/__init__...
There is a reason for this to follow shortly :)
--- NEW FILE: fxdimdb.py ---
#if 0 /*
# -----------------------------------------------------------------------
# helpers/fxdimdb.py - class and helpers for fxd/imdb generation
# -----------------------------------------------------------------------
# $Id: fxdimdb.py,v 1.1 2004/01/08 17:33:15 outlyer Exp $
#
# Notes: see http://pintje.servebeer.com/fxdimdb.html for documentatio,
# Todo:
# - add support making fxds without imdb (or documenting it)
# - webradio support?
#
# -----------------------------------------------------------------------
# $Log: fxdimdb.py,v $
# Revision 1.1 2004/01/08 17:33:15 outlyer
# Moved fxdimdb.py to util; it doesn't use the OSD, and having in video
# makes it import video/__init__...
#
# There is a reason for this to follow shortly :)
#
# Revision 1.23 2004/01/03 17:43:15 dischi
# OVERLAY_DIR is always used
#
# Revision 1.22 2003/11/24 19:24:59 dischi
# move the handler for fxd from xml_parser to fxdhandler
#
# Revision 1.21 2003/11/22 20:35:50 dischi
# use new vfs
#
# Revision 1.20 2003/11/09 12:51:21 dischi
# fix poster download
#
# Revision 1.19 2003/10/03 16:46:13 dischi
# moved the encoding type (latin-1) to the config file config.LOCALE
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2003 Krister Lagerstrom, et al.
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# This program 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 program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
# CHANTABILITY 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 program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif
# python has no data hiding, but this is the intended use...
# subroutines completly in lowercase are regarded as more "private" functions
# subRoutines are regarded as public
#some data
__author__ = "den_RDC ([EMAIL PROTECTED])"
__version__ = "Revision 0.1"
__copyright__ = "Copyright (C) 2003 den_RDC"
__license__ = "GPL"
#Module Imports
import re
import urllib, urllib2, urlparse
import sys
import codecs
import os
import config
import util
from mmpython.disc.discinfo import cdrom_disc_id
#Constants
freevo_version = '1.3.4'
imdb_title_list = '/tmp/imdb-movies.list'
imdb_title_list_url = 'ftp://ftp.funet.fi/pub/mirrors/ftp.imdb.com/pub/movies.list.gz'
imdb_titles = None
imdb_info_tags = ('year', 'genre', 'tagline', 'plot', 'rating', 'runtime');
# headers for urllib2
txdata = None
txheaders = {
'User-Agent': 'freevo %s (%s)' % (freevo_version, sys.platform),
'Accept-Language': 'en-us',
}
#Begin class
class FxdImdb:
"""Class for creating fxd files and fetching imdb information"""
def __init__(self):
"""Initialise class instance"""
# these are considered as private variables - don't mess with them unless
# no other choise is given
# fyi, the other choice always exists : add a subroutine or ask :)
self.imdb_id_list = []
self.imdb_id = None
self.isdiscset = False
self.title = ''
self.info = {}
self.image = None # full path image filename
self.image_urls = [] # possible image url list
self.image_url = None # final image url
self.fxdfile = None # filename, full path, WITHOUT extension
self.append = False
self.device = None
self.regexp = None
self.mpl_global_opt = None
self.media_id = None
self.file_opts = []
self.video = []
self.variant = []
self.parts = []
self.var_mplopt = []
self.var_names = []
#initialize self.info
for t in imdb_info_tags:
self.info[t] = ""
#image_url_handler stuff
self.image_url_handler = {}
self.image_url_handler['www.impawards.com'] = self.impawards
def searchImdb(self, name):
"""name (string), returns id list
Search for name and returns an id list with tuples:
(id , name, year, type)"""
url = 'http://us.imdb.com/Tsearch?title=%s&restrict=Movies+and+TV' % \
urllib.quote(name)
req = urllib2.Request(url, txdata, txheaders)
searchstring = name
try:
response = urllib2.urlopen(req)
except urllib2.HTTPError, error:
raise FxdImdb_Net_Error("IMDB unreachable : " + error)
return None
regexp_get_imdb_id = re.compile(r'''
http://.*imdb\.com/
(?:Title\?|title/tt) # ( old style | new style )
(?P<id>\d+) # imdb id
''', re.VERBOSE)
m = re.match(regexp_get_imdb_id, response.geturl())
if m:
data = self.parsedata(response)
#print 'data[0]: ' + data[0]
self.imdb_id_list = [ ( m.group('id'),
data[0],
data[1]['year'],
"Movie/TV-Movie") ]
return self.imdb_id_list
regexp_type = re.compile(r'''
<H2><A[ ]NAME=.*?>
(?P<type>.*?) # Most popular searches/Movies/TV-Movies/Video Games etc.
</A></H2>
''', re.VERBOSE)
regexp_imdb_list_entry = re.compile(r'''
<LI><A[ ]HREF="/(?:Title\?|title/tt) # match both old and new style
(?P<id> \d+)/"> # imdb id
(?P<title> .*?)\s* # imdb movie title
\(
(?P<year> \d{4}.*?) # year and possibly /I, /II etc.
\)</A>
''', re.VERBOSE)
type = ''
for line in response.read().split("\n"):
m = regexp_type.match(line)
if m:
type = m.group('type')
# delete plural s
if type in ('Movies', 'TV-Movies'):
type = type[:-1]
m = regexp_imdb_list_entry.search(line)
if m and not type == 'Video Games':
id = m.group('id')
name = m.group('title')
year = m.group('year')
# delete " before and after name
if name[0] == '"' and name [-1] == '"':
name=name[1:-1]
# only add entries that hasn't been added before
for i in self.imdb_id_list:
if i[0] == id:
break
else:
self.imdb_id_list += [ ( id, name, year, type ) ]
response.close()
if len(self.imdb_id_list) > 20:
# too much results, check if there are stupid results in the
# list
words = []
# make a list of all words (no numbers) in the search string
for p in re.split('[\._ -]', searchstring):
if p and not p[0] in '0123456789':
words.append(p)
# at least one word has to be in the result
new_list = []
for result in self.imdb_id_list:
appended = False
for search_word in words:
if appended == False and \
result[1].lower().find(search_word.lower()) != -1:
new_list.append(result)
appended = True
self.imdb_id_list = new_list
return self.imdb_id_list
def setImdbId(self, id):
"""id (number)
Set an imdb_id number for object, and fetch data"""
self.imdb_id = id
url = 'http://us.imdb.com/Title?%s' % id
req = urllib2.Request(url, txdata, txheaders)
try:
idpage = urllib2.urlopen(req)
except urllib2.HTTPError, error:
raise FxdImdb_Net_Error("IMDB unreachable" + error)
return None
self.parsedata(idpage, id)
idpage.close()
def setFxdFile(self, fxdfilename = None, overwrite = False):
"""
fxdfilename (string, full path)
Set fxd file to write to, may be omitted, may be an existing file
(data will be added) unless overwrite = True
"""
if fxdfilename:
if vfs.splitext(fxdfilename)[1] == '.fxd':
self.fxdfile = vfs.splitext(fxdfilename)[0]
else: self.fxdfile = fxdfilename
else:
if self.isdiscset == True:
self.fxdfile = vfs.join(config.OVERLAY_DIR, 'disc-set',
self.getmedia_id(self.device))
else:
self.fxdfile = vfs.splitext(file)[0]
if overwrite == False:
try:
vfs.open(self.fxdfile + '.fxd')
self.append = True
except:
pass
else: self.append = False
# XXX: add this back in without using parseMovieFile
# if self.append == True and \
# parseMovieFile(self.fxdfile + '.fxd', None, []) == []:
# raise FxdImdb_XML_Error("FXD file to be updated is invalid, please
correct it.")
if not vfs.isdir(vfs.dirname(self.fxdfile)):
if vfs.dirname(self.fxdfile):
os.makedirs(vfs.dirname(self.fxdfile))
def setVideo(self, *videos, **mplayer_opt):
"""
videos (tuple (type, id-ref, device, mplayer-opts, file/param) (multiple
allowed),
global_mplayer_opts
Set media file(s) for fxd
"""
if self.isdiscset == True:
raise FxdImdb_XML_Error("<disc-set> already used, can't use both "+
"<movie> and <disc-set>")
if videos:
for video in videos:
self.video += [ video ]
if mplayer_opt and 'mplayer_opt' in mpl_global_opt:
self.mpl_global_opt = mplayer_opt['mplayer_opt']
def setVariants(self, *parts, **mplayer_opt):
"""
variants/parts (tuple (name, ref, mpl_opts, sub, s_dev, audio, a_dev)),
var_mplayer_opts
Set Variants & parts
"""
if self.isdiscset == True:
raise FxdImdb_XML_Error("<disc-set> already used, can't use both "+
"<movie> and <disc-set>")
if mplayer_opt and 'mplayer_opt' in mpl_global_opt:
self.varmpl_opt = (mplayer_opt['mplayer_opt'])
for part in parts:
self.variant += [ part ]
def writeFxd(self):
"""Write fxd file"""
#if fxdfile is empty, set it yourself
if not self.fxdfile:
self.setFxdFile()
try:
#should we add to an existing file?
if self.append == True :
if self.isdiscset == True:
self.update_discset()
else: self.update_movie()
else:
#fetch images
self.fetch_image()
#should we write a disc-set ?
if self.isdiscset == True:
self.write_discset()
else:
self.write_movie()
#check fxd
# XXX: add this back in without using parseMovieFile
# if parseMovieFile(self.fxdfile + '.fxd', None, []) == []:
# raise FxdImdb_XML_Error("""FXD file generated is invalid, please "+
# "post bugreport, tracebacks and fxd file.""")
except (IOError, FxdImdb_IO_Error), error:
raise FxdImdb_IO_Error('error saving the file: %s' % str(error))
def setDiscset(self, device, regexp, *file_opts, **mpl_global_opt):
"""
device (string), regexp (string), file_opts (tuple (mplayer-opts,file)),
mpl_global_opt (string)
Set media is dvd/vcd,
"""
if len(self.video) != 0 or len(self.variant) != 0:
raise FxdImdb_XML_Error("<movie> already used, can't use both "+
"<movie> and <disc-set>")
self.isdiscset = True
if (not device and not regexp) or (device and regexp):
raise FxdImdb_XML_Error("Can't use both media-id and regexp")
self.device = device
self.regexp = regexp
for opts in file_opts:
self.file_opts += [ opts ]
if mpl_global_opt and 'mplayer_opt' in mpl_global_opt:
self.mpl_global_opt = (mpl_global_opt['mplayer_opt'])
def isDiscset(self):
"""Check if fxd file describes a disc-set, returns 1 for true, 0 for false
None for invalid file"""
try:
file = vfs.open(self.fxdfile + '.fxd')
except IOError:
return None
content = file.read()
file.close()
if content.find('</disc-set>') != -1: return 1
return 0
def guessImdb(self, filename, label=False):
"""Guess possible imdb movies from filename. Same return as searchImdb"""
name = filename
name = vfs.basename(vfs.splitext(name)[0])
name = re.sub('([a-z])([A-Z])', point_maker, name)
name = re.sub('([a-zA-Z])([0-9])', point_maker, name)
name = re.sub('([0-9])([a-zA-Z])', point_maker, name.lower())
name = re.sub(',', ' ', name)
if label == True:
for r in config.IMDB_REMOVE_FROM_LABEL:
name = re.sub(r, '', name)
parts = re.split('[\._ -]', name)
name = ''
for p in parts:
if not p.lower() in config.IMDB_REMOVE_FROM_SEARCHSTRING and \
not re.search('[^0-9A-Za-z]', p):
# originally: not re.search(p, '[A-Za-z]'):
# not sure what's meant with that
name += '%s ' % p
return self.searchImdb(name)
#------ private functions below .....
def write_discset(self):
"""Write a <disc-set> to a fresh file"""
try:
i = vfs.codecs_open( (self.fxdfile + '.fxd') , 'w', encoding='utf-8')
except IOError, error:
raise FxdImdb_IO_Error("Writing FXD file failed : " + str(error))
return
#header
i.write("<?xml version=\"1.0\" ?>\n<freevo>\n")
i.write(" <copyright>\n" +
" The information in this file are from the Internet " +
"Movie Database (IMDb).\n" +
" Please visit http://www.imdb.com for more informations.\n")
i.write(" <source url=\"http://www.imdb.com/Title?%s\"/>\n" % self.imdb_id
+
" </copyright>\n")
#disc-set
i.write(" <disc-set title=\"%s\">\n" % self.str2XML(self.title))
#disc
i.write(" <disc")
if self.device:
i.write(" media-id=\"%s\"" % self.str2XML(self.getmedia_id(self.device)))
elif self.regexp:
i.write(" label-regexp=\"%s\"" % self.str2XML(self.regexp))
if self.mpl_global_opt:
i.write(" mplayer-options=\"%s\">" % self.str2XML(self.mpl_global_opt))
else: i.write(">")
#file-opts
if self.file_opts:
i.write("\n")
for opts in self.file_opts:
mplopts, fname = opts
i.write(" <file-opt mplayer-options=\"%s\">" %
self.str2XML(mplopts))
i.write("%s</file-opt>\n" % self.str2XML(fname))
i.write(" </disc>\n")
else: i.write(" </disc>\n")
#image
if self.image:
i.write(" <cover-img source=\"%s\">" % self.str2XML(self.image_url))
i.write("%s</cover-img>\n" % self.str2XML(self.image))
#print info
i.write(self.print_info())
#close tags
i.write(" </disc-set>\n")
i.write("</freevo>\n")
util.touch('/tmp/freevo-rebuild-database')
def write_movie(self):
"""Write <movie> to fxd file"""
try:
i = vfs.codecs_open( (self.fxdfile + '.fxd') , 'w', encoding='utf-8')
except IOError, error:
raise FxdImdb_IO_Error("Writing FXD file failed : " + str(error))
return
#header
i.write("<?xml version=\"1.0\" ?>\n<freevo>\n")
i.write(" <copyright>\n" +
" The information in this file are from the Internet " +
"Movie Database (IMDb).\n" +
" Please visit http://www.imdb.com for more informations.\n")
i.write(" <source url=\"http://www.imdb.com/Title?%s\"/>\n" % self.imdb_id
+
" </copyright>\n")
# write movie
i.write(" <movie title=\"%s\">\n" % self.str2XML(self.title))
#image
if self.image:
i.write(" <cover-img source=\"%s\">" % self.str2XML(self.image_url))
i.write("%s</cover-img>\n" % self.str2XML(self.image))
#video
if self.mpl_global_opt:
i.write(" <video mplayer-options=\"%s\">\n" % \
self.str2XML(self.mpl_global_opt))
else: i.write(" <video>\n")
# videos
i.write(self.print_video())
i.write(' </video>\n')
#variants <varinats !!
if len(self.variant) != 0:
i.write(' <variants>\n')
i.write(self.print_variant())
i.write(' </variants>\n')
#info
i.write(self.print_info())
#close tags
i.write(' </movie>\n')
i.write('</freevo>\n')
util.touch('/tmp/freevo-rebuild-database')
def update_movie(self):
"""Updates an existing file, adds exftra dvd|vcd|file and variant tags"""
passedvid = False
#read existing file in memory
try:
file = vfs.open(self.fxdfile + '.fxd')
except IOError, error:
raise FxdImdb_IO_Error("Updating FXD file failed : " + str(error))
return
content = file.read()
file.close()
if content.find('</video>') == -1:
raise FxdImdb_XML_Error("FXD cannot be updated, doesn't contain <video>
tag")
regexp_variant_start = re.compile('.*<variants>.*', re.I)
regexp_variant_end = re.compile(' *</variants>', re.I)
regexp_video_end = re.compile(' *</video>', re.I)
file = vfs.open(self.fxdfile + '.fxd', 'w')
for line in content.split('\n'):
if passedvid == True and content.find('<variants>') == -1:
#there is no variants tag
if len(self.variant) != 0:
file.write(' <variants>\n')
file.write(self.print_variant())
file.write(' </variants>\n')
file.write(line + '\n')
passedvid = False
elif regexp_video_end.match(line):
if len(self.video) != 0:
file.write(self.print_video())
file.write(line + '\n')
passedvid = True
elif regexp_variant_end.match(line):
if len(self.variant) != 0:
file.write(self.print_variant())
file.write(line + '\n')
else: file.write(line + '\n')
file.close()
util.touch('/tmp/freevo-rebuild-database')
def update_discset(self):
"""Updates an existing file, adds extra disc in discset"""
#read existing file in memory
try:
file = vfs.open(self.fxdfile + '.fxd')
except IOError, error:
raise FxdImdb_IO_Error("Updating FXD file failed : " + str(error))
return
content = file.read()
file.close()
if content.find('</disc-set>') == -1:
raise FxdImdb_XML_Error("FXD file cannot be updated, doesn't contain
<disc-set>")
regexp_discset_end = re.compile(' *</disc-set>', re.I)
file = vfs.open(self.fxdfile + '.fxd', 'w')
for line in content.split('\n'):
if regexp_discset_end.match(line):
file.write(" <disc")
if self.device:
file.write(" media-id=\"%s\"" % \
self.str2XML(self.getmedia_id(self.device)))
elif self.regexp:
file.write(" label-regexp=\"%s\"" % self.str2XML(self.regexp))
if self.mpl_global_opt:
file.write(" mplayer-options=\"%s\">" %
self.str2XML(self.mpl_global_opt))
else: file.write(">")
#file-opts
if self.file_opts:
file.write("\n")
for opts in self.file_opts:
mplopts, fname = opts
file.write(" <file-opt mplayer-options=\"%s\">" % \
self.str2XML(mplopts))
file.write("%s</file-opt>\n" % self.str2XML(fname))
file.write(" </disc>\n")
else: file.write(" </disc>\n")
file.write(line + '\n')
else: file.write(line + '\n')
file.close()
util.touch('/tmp/freevo-rebuild-database')
def parsedata(self, results, id=0):
"""results (imdb html page), imdb_id
Returns tuple of (title, info(dict), image_urls)"""
dvd = 0
regexp_title = re.compile('.*STRONG CLASS="title">(.*?)<', re.I)
regexp_year = re.compile('.*<A HREF="/Sections/Years/.*?([0-9]*)<', re.I)
regexp_genre = re.compile('.*href="/Sections/Genres(.*)$', re.I)
regexp_tagline = re.compile('.*<B CLASS="ch">Tagline.*?</B>(.*?)<', re.I)
regexp_plot1 = re.compile('.*<B CLASS="ch">Plot Outline.*?</B>(.*?)<', re.I)
regexp_plot2 = re.compile('.*<B CLASS="ch">Plot Summary.*?</B>(.*?)<', re.I)
regexp_rating = re.compile('.*<B>([0-9\.]*)/10</B> (.[0-9,]* votes.?)', re.I)
regexp_image = re.compile('.*ALT="cover".*src="(http://.*?)"', re.I)
regexp_runtime = re.compile('.*<b class="ch">Runtime', re.I)
regexp_dvd = re.compile('.*<a href="/DVD\?', re.I)
regexp_dvd_image = re.compile('.*(http://images.amazon.com.*?ZZZZZ.*?)"')
regexp_url = re.compile('.*href="(http.*?)"', re.I)
next_line_is = None
for line in results.read().split("\n"):
if next_line_is == 'runtime':
next_line_is = None
self.info['runtime'] = self.str2XML(line)
if regexp_runtime.match(line):
next_line_is = 'runtime'
continue
m = regexp_title.match(line)
if m: self.title = self.str2XML(m.group(1))
m = regexp_year.match(line)
if m: self.info['year'] = m.group(1)
m = regexp_genre.match(line)
if m:
for g in re.compile(' *</A>.*?> *', re.I).split(' </a>'+line+' > '):
if self.info['genre'] == "": self.info['genre'] = g
elif g != "" and g != "(more)": self.info['genre'] += " / "+ g
m = regexp_tagline.match('%s<' % line)
if m:
self.info['tagline'] = self.str2XML(re.compile('[\t ]+').sub(" ", ' '
+ m.group(1))[1:])
m = regexp_plot1.match('%s<' % line)
if m: self.info['plot'] = self.str2XML(re.compile('[\t ]+').sub(" ", ' ' +
m.group(1))[1:])
m = regexp_plot2.match('%s<' % line)
if m: self.info['plot'] = self.str2XML(re.compile('[\t ]+').sub(" ", ' ' +
m.group(1))[1:])
m = regexp_rating.match(line)
if m: self.info['rating'] = m.group(1) + '/10 ' + m.group(2)
m = regexp_dvd.match(line)
if m: dvd = 1
m = regexp_image.match(line)
if m: self.image_urls += [ m.group(1) ]
if not id:
return (self.title, self.info, self.image_urls)
if dvd:
url = 'http://us.imdb.com/DVD?%s' % id
req = urllib2.Request(url, txdata, txheaders)
try:
r = urllib2.urlopen(req)
for line in r.read().split("\n"):
m = regexp_dvd_image.match(line)
if m: self.image_urls += [ m.group(1) ]
r.close()
except urllib2.HTTPError, error:
pass
#oldcode
#if not self.image_url_handler:
# return #(title, info, image_urls)
url = 'http://us.imdb.com/title/tt%s/posters' % id
req = urllib2.Request(url, txdata, txheaders)
try:
r = urllib2.urlopen(req)
except urllib2.HTTPError, error:
print error
return (self.title, self.info, self.image_urls)
data = r.read().replace('</a>', '\n').replace('</A>', '\n')
for line in data.split('\n'):
m = regexp_url.match(line)
if m:
url = urlparse.urlsplit(m.group(1))
if url[0] == 'http' and self.image_url_handler.has_key(url[1]):
self.image_urls += self.image_url_handler[url[1]](url[1], url[2])
r.close()
return (self.title, self.info, self.image_urls)
def impawards(self, host, path):
"""parser for posters from www.impawards.com. TODO: check for licences
of each poster and add all posters"""
path = '%s/posters/%s.jpg' % (path[:path.rfind('/')], \
path[path.rfind('/')+1:path.rfind('.')])
return [ 'http://%s%s' % (host, path) ]
def fetch_image(self):
"""Fetch the best image"""
image_len = 0
for image in self.image_urls:
try:
# get sizes of images
req = urllib2.Request(image, txdata, txheaders)
r = urllib2.urlopen(req)
length = int(r.info()['Content-Length'])
r.close()
if length > image_len:
image_len = length
self.image_url = image
except:
pass
if not self.image_url:
print "Image dowloading failed"
return
self.image = (self.fxdfile + '.jpg')
req = urllib2.Request(self.image_url, txdata, txheaders)
r = urllib2.urlopen(req)
i = vfs.open(self.image, 'w')
i.write(r.read())
i.close()
r.close()
# try to crop the image to avoid borders by imdb
try:
import Image
image = Image.open(filename)
width, height = image.size
image.crop((2,2,width-4, height-4)).save(filename)
except:
pass
self.image = vfs.basename(self.image)
print "Downloaded cover image from %s" % self.image_url
print "Freevo knows nothing about the copyright of this image, please"
print "go to %s to check for more informations about private." % self.image_url
print "use of this image"
def str2XML(self, line):
"""return a valid XML string"""
try:
s = unicode(line, config.LOCALE)
while s[-1] == ' ':
s = s[:-1]
if s[:4] == '"':
s = s[5:]
if s[-4:] == '#34;':
s = s[:-5]
# replace all & to & ...
s = s.replace("&", "&")
# ... but this may be wrong for &#
s = s.replace("&#", "&#")
return s
except:
return line
def getmedia_id(self, drive):
"""drive (device string)
return a unique identifier for the disc"""
if not vfs.exists(drive): return drive
return cdrom_disc_id(drive)[1]
def print_info(self):
"""return info part for FXD writing"""
ret = ''
if self.info:
ret = ' <info>\n'
for k in self.info.keys():
ret += ' <%s>%s</%s>\n' % (k, self.info[k], k)
ret += ' </info>\n'
return ret
def print_video(self):
"""return info part for FXD writing"""
ret = ''
for vid in self.video:
type, idref, device, mpl_opts, fname = vid
ret += ' <%s' % self.str2XML(type)
ret += ' id=\"%s\"' % self.str2XML(idref)
if device: ret += ' media-id=\"%s\"' %
self.str2XML(self.getmedia_id(device))
if mpl_opts: ret += ' mplayer-options=\"%s\">' % self.str2XML(mpl_opts)
else: ret += '>'
ret += '%s' % self.str2XML(fname)
ret += '</%s>\n' % self.str2XML(type)
return ret
def print_variant(self):
"""return info part for FXD writing"""
ret = ''
for x in range(len(self.variant)):
name, idref, mpl_opts, sub, s_dev, audio, a_dev = self.variant[x]
ret += ' <variant name=\"%s\"' % self.str2XML(name)
if self.varmpl_opt:
ret += ' mplayer-options=\"%s\">\n' % self.str2XML(self.varmpl_opt)
else: ret += '>\n'
ret += ' <part ref=\"%s\"' % self.str2XML(idref)
if mpl_opts: ret += ' mplayer-options=\"%s\">\n' % self.str2XML(mpl_opts)
else: ret += ">\n"
if sub:
ret += ' <subtitle'
if s_dev: ret += ' media-id=\"%s\">' %
self.str2XML(self.getmedia_id(s_dev))
else: ret += '>'
ret += '%s</subtitle>\n' % self.str2XML(sub)
if audio:
ret += ' <audio'
if a_dev: ret += ' media-id=\"%s\">' %
self.str2XML(self.getmedia_id(a_dev))
else: ret += '>'
ret += '%s</audio>\n' % self.str2XML(audio)
ret += ' </part>\n'
ret += ' </variant>\n'
return ret
#--------- Exception class
class Error(Exception):
"""Base class for exceptions in Imdb_Fxd"""
def __str__(self):
return self.message
def __init__(self, message):
self.message = message
class FxdImdb_Error(Error):
"""used to raise exceptions"""
pass
class FxdImdb_XML_Error(Error):
"""used to raise exceptions"""
pass
class FxdImdb_IO_Error(Error):
"""used to raise exceptions"""
pass
class FxdImdb_Net_Error(Error):
"""used to raise exceptions"""
pass
#------- Helper functions for creating tuples - these functions are classless
def makeVideo(type, id_ref, file, **values):
"""Create a video tuple"""
device = mplayer_opt = None
types = ['dvd', 'file', 'vcd']
if type == None or id_ref == None or file == None:
raise FxdImdb_XML_Error("Required values missing for tuple creation")
if type not in types:
raise FxdImdb_XML_Error("Invalid type passed to makeVideo")
if values:
#print values
if 'device' in values: device = values['device']
if 'mplayer_opt' in values: mplayer_opt = values['mplayer_opt']
file = relative_path(file)
t = type, id_ref, device, mplayer_opt, file
return t
def makePart(name, id_ref, **values):
"""Create a part tuple"""
mplayer_opt = sub = s_dev = audio = a_dev = None
if id_ref == None or name == None:
raise FxdImdb_XML_Error("Required values missing for tuple creation")
if values:
if 'mplayer_opt' in values: mplayer_opt = values['mplayer_opt']
if 'sub' in values: sub = values['sub']
if 's_dev' in values: s_dev = values['s_dev']
if 'audio' in values: audio = values['audio']
if 'a_dev' in values: a_dev = values['a_dev']
if a_dev: audio = relative_path(audio)
if s_dev: sub = relative_path(sub)
t = name, id_ref, mplayer_opt, sub, s_dev, audio, a_dev
return t
def makeFile_opt(mplayer_opt, file):
"""Create a file_opt tuple"""
if mplayer_opt == None or file == None:
raise FxdImdb_XML_Error("Required values missing for tuple creation")
file = relative_path(file)
t = mplayer_opt, file
return t
#--------- classless private functions
def relative_path(filename):
"""return the relative path to a mount point for a file on a removable disc"""
from os.path import isabs, ismount, split, join
if not isabs(filename) and not ismount(filename): return filename
drivepaths = []
for item in config.REMOVABLE_MEDIA:
drivepaths.append(item.mountdir)
for path in drivepaths:
if filename.find(path) != -1:
head = filename
tail = ''
while (head != path):
x = split(head)
head = x[0]
if x[0] == '/' and x[1] == '' : return filename
elif tail == '': tail = x[1]
else: tail = join(x[1], tail)
if head == path: return tail
return filename
def point_maker(matching):
return '%s.%s' % (matching.groups()[0], matching.groups()[1])
-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
Freevo-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog