Update of /cvsroot/freevo/freevo/src/mediadb
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1831/mediadb
Added Files:
.cvsignore __init__.py db.py debug.py item.py listing.py
Log Message:
New mediadb as replacement for util.mediainfo and other parts of freevo
getting informations about media items. It is not integrated yet! The
goal is to create one module dealing with all parts of informations in
freevo and to make creating menu listings much faster.
--- NEW FILE: debug.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# mediainfo.py -
# -----------------------------------------------------------------------------
# $Id: debug.py,v 1.1 2005/03/13 10:13:35 dischi Exp $
#
# -----------------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
#
# 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
#
# -----------------------------------------------------------------------------
import time
import sys
import os
import stat
import mmpython
import pickle
import cPickle
import re
import logging
import copy
from mmpython.disc.discinfo import cdrom_disc_id
import sysconfig
import config
import util.fxdparser
import util.vfs as vfs
import util.cache as cache
from util.callback import *
log = logging.getLogger('mediainfo')
def print_data(data, space=' '):
for key, info in data.items():
if isinstance(info, (list, tuple)):
print '%s%s: [' % (space, key)
for i in info:
if isinstance(i, dict):
print_data(i, space + ' ')
print
else:
print '%s %s' % (space, i)
print '%s ]' % (space)
elif not key in ( 'mminfo', 'fxd' ):
print '%s%s: %s' % (space, key, info)
if not data.has_key('mminfo'):
return
mminfo = cPickle.loads(data['mminfo'])
print_data(mminfo, ' ')
print
# XXX MEDIAINFO UPDATE XXX
t1 = time.time()
l = Listing(sys.argv[1])
t2 = time.time()
l.update()
t3 = time.time()
print 'time: %s %s' % (t2 - t1, t3 - t1)
print
print
print 'Listing for %s' % l.cache.dirname
for key in l.cache.data:
if not key in ('overlay', 'items'):
print ' %s: %s' % (key, l.cache.data[key])
print
for file, info in l.cache.items.items():
print ' %s' % file
print_data(info)
print
for file, info in l.cache.overlay.items():
print ' %s' % file
print_data(info)
print
--- NEW FILE: .cvsignore ---
*.pyc *.pyo
--- NEW FILE: item.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# item.py -
# -----------------------------------------------------------------------------
# $Id: item.py,v 1.1 2005/03/13 10:13:35 dischi Exp $
#
# -----------------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
#
# 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
#
# -----------------------------------------------------------------------------
__all__ = [ 'ItemInfo' ]
# python imports
import pickle
import cPickle
import logging
# freevo imports
from util.callback import *
# get logging object
log = logging.getLogger('mediainfo')
class ItemInfo:
def __init__(self, basename, dirname, attr, cache=None):
if not attr:
attr = {}
self.attr = attr
self.basename = basename
self.tmp = {}
self.mminfo = None
self.hidden_variables = {}
self.dirname = dirname
self.filename = self.dirname + '/' + self.basename
self.cache = cache
def __str__(self):
return self.basename
def __getitem__(self, key):
if key in ('cover', 'audiocover'):
if self.attr.has_key(key):
return self.attr[key]
elif self.cache:
return self.cache.data[key]
return ''
if self.tmp.has_key(key):
return self.tmp[key]
if self.attr.has_key(key):
return self.attr[key]
if self.hidden_variables.has_key(key):
return self.hidden_variables[key]
if not self.attr.has_key('mminfo'):
return None
if self.mminfo == None:
log.debug('unpickle %s' % self.basename)
self.mminfo = cPickle.loads(self.attr['mminfo'])
log.debug('mmget %s (%s)' % (self.basename, key))
if self.mminfo.has_key(key):
return self.mminfo[key]
return None
def __setitem__(self, key, value):
if self.attr.has_key(key):
self.attr[key] = value
if self.cache:
self.cache.changed = True
call_later(self.cache.save)
else:
self.tmp[key] = value
def has_key(self, key):
if key in ('cover', 'audiocover'):
return True
if self.tmp.has_key(key):
return True
if self.attr.has_key(key):
return True
if self.hidden_variables.has_key(key):
return True
if not self.attr.has_key('mminfo'):
return False
if self.mminfo == None:
log.debug('unpickle %s' % self.basename)
self.mminfo = cPickle.loads(self.attr['mminfo'])
log.debug('mmget %s (%s)' % (self.basename, key))
if self.mminfo.has_key(key):
return True
return False
def keys(self):
ret = [ 'cover', 'audiocover' ]
if self.mminfo == None:
if self.attr.has_key('mminfo'):
log.debug('unpickle %s' % self.basename)
self.mminfo = cPickle.loads(self.attr['mminfo'])
else:
self.mminfo = {}
for vardict in self.tmp, self.attr, self.hidden_variables, self.mminfo:
for key in vardict:
if not key in ret:
ret.append(key)
return ret
def store(self, key, value):
self.attr[key] = value
if self.cache:
self.cache.changed = True
call_later(self.cache.save)
return True
def store_with_mtime(self, key, value):
self.attr[key] = value
if self.cache:
self.cache.changed = True
call_later(self.cache.save)
if not key in self.attr['mtime_dep']:
self.attr['mtime_dep'].append(key)
return True
def get_variables(self):
return self.tmp
def set_variables(self, list):
self.tmp = list
def set_permanent_variables(self, variables):
self.hidden_variables = variables
def delete(self, key):
pass
--- NEW FILE: db.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# db.py -
# -----------------------------------------------------------------------------
# $Id: db.py,v 1.1 2005/03/13 10:13:35 dischi Exp $
#
# -----------------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
#
# 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
#
# -----------------------------------------------------------------------------
__all__ = [ 'Cache', 'FileCache', 'save', 'get' ]
# python imports
import time
import os
import stat
import mmpython
import pickle
import cPickle
import re
import logging
# freevo imports
import config
import util.fxdparser
import util.vfs as vfs
import util.cache as cache
from util.callback import *
# get logging object
log = logging.getLogger('mediadb')
VERSION = 1.6
def _simplify(object):
"""
mmpython has huge objects to cache, we don't need them.
This function simplifies them to be only string, integer, dict or
list of one of those above. This makes the caching much faster
"""
ret = {}
for k in object.keys:
if not k in [ 'thumbnail', 'url' ] and getattr(object,k) != None:
value = getattr(object,k)
if isstring(value):
value = Unicode(value.replace('\0', '').lstrip().rstrip())
if value:
ret[k] = value
for k in ( 'video', 'audio'):
# if it's an AVCORE object, also simplify video and audio
# lists to string and it
if hasattr(object, k) and getattr(object, k):
ret[k] = []
for o in getattr(object, k):
ret[k].append(_simplify(o))
if hasattr(object, 'tracks') and object.tracks:
# read track informations for dvd
ret['tracks'] = []
for o in object.tracks:
track = _simplify(o)
if not track.has_key('audio'):
track['audio'] = []
if not track.has_key('subtitles'):
track['subtitles'] = []
ret['tracks'].append(track)
for k in ('subtitles', 'chapters', 'mime', 'id' ):
if hasattr(object, k) and getattr(object, k):
ret[k] = getattr(object, k)
return ret
def _parse_fxd_node(node):
children = []
for c in node.children:
children.append(_parse_fxd_node(c))
return (node.name, node.attrs, children, node.textof(), node.first_cdata,
node.following_cdata)
def _parse_fxd(filename):
data = util.fxdparser.FXDtree(filename, False)
if data.tree.name != 'freevo':
return {}
is_skin_fxd = False
for node in data.tree.children:
if node.name == 'skin':
is_skin_fxd = True
break
tree = []
for node in data.tree.children:
tree.append(_parse_fxd_node(node))
return is_skin_fxd, tree
def _cover_filter(x):
"""
filter function to get valid cover names
"""
return re.search(config.AUDIO_COVER_REGEXP, x, re.IGNORECASE)
def _add_info(filename, object):
mminfo = None
if not object['ext'] in [ 'xml', 'fxd' ]:
mminfo = mmpython.parse(filename)
title = _getname(filename)
object['title:filename'] = title
if mminfo:
# store mmpython data as pickle for faster loading
object['mminfo'] = cPickle.dumps(_simplify(mminfo),
pickle.HIGHEST_PROTOCOL)
if mminfo.title:
object['title'] = mminfo.title
else:
object['title'] = title
elif object.has_key('mminfo'):
del object['mminfo']
object['title'] = title
else:
object['title'] = title
if filename.endswith('.fxd'):
# store fxd tree as pickle for faster loading
object['fxd'] = cPickle.dumps(_parse_fxd(filename),
pickle.HIGHEST_PROTOCOL)
if os.path.isdir(filename):
object['isdir'] = True
listing = vfs.listdir(filename, include_overlay=True)
# get directory cover
for l in listing:
if l.endswith('/cover.png') or l.endswith('/cover.jpg') or \
l.endswith('/cover.gif'):
object['cover'] = l
break
else:
if object.has_key('cover'):
del object['cover']
if object.has_key('audiocover'):
del object['audiocover']
files = util.find_matches(listing, ('jpg', 'gif', 'png' ))
if len(files) == 1:
object['audiocover'] = files[0]
elif len(files) > 1 and len(files) < 10:
files = filter(_cover_filter, files)
if files:
object['audiocover'] = files[0]
# save directory overlay mtime
overlay = vfs.getoverlay(filename)
if os.path.isdir(overlay):
mtime = os.stat(overlay)[stat.ST_MTIME]
object['overlay_mtime'] = mtime
else:
object['overlay_mtime'] = 0
else:
if object.has_key('isdir'):
del object['isdir']
_FILENAME_REGEXP = re.compile("^(.*?)_(.)(.*)$")
def _getname(file):
"""
make a nicer display name from file
"""
if len(file) < 2:
return Unicode(file)
# basename without ext
if file.rfind('/') < file.rfind('.'):
name = file[file.rfind('/')+1:file.rfind('.')]
else:
name = file[file.rfind('/')+1:]
if not name:
# Strange, it is a dot file, return the complete
# filename, I don't know what to do here. This should
# never happen
return Unicode(file)
name = name[0].upper() + name[1:]
while file.find('_') > 0 and _FILENAME_REGEXP.match(name):
m = _FILENAME_REGEXP.match(name)
if m:
name = m.group(1) + ' ' + m.group(2).upper() + m.group(3)
if name.endswith('_'):
name = name[:-1]
return Unicode(name)
class CacheList:
def __init__(self):
self.caches = {}
def get(self, dirname):
if dirname in self.caches:
cache = self.caches[dirname]
mtime = os.stat(cache.file)[stat.ST_MTIME]
if mtime == cache.mtime:
return cache
c = Cache(dirname)
self.caches[dirname] = c
return c
def save(self):
for cache in self.caches.values():
cache.save()
# global object
_cache_list = CacheList()
class Cache:
"""
A cache object for the mediainfo holding one directory.
"""
def __init__(self, dirname):
self.dirname = dirname
self.overlay_file = vfs.getoverlay(dirname)
self.file = self.overlay_file + '/freevo.db'
self.data = None
self.changed = False
self.check_time = 0
if os.path.isfile(self.file):
# load cache file
self.data = cache.load(self.file, VERSION)
self.mtime = os.stat(self.file)[stat.ST_MTIME]
elif not os.path.isdir(os.path.dirname(self.overlay_file)):
# create vfs overlay dir; we will need it anyway for
# storing the db file
os.makedirs(os.path.dirname(self.overlay_file))
if not self.data:
# create a new cache data dict
self.data = {'items_mtime': 0,
'items': {},
'overlay_mtime': {},
'overlay': {},
'cover': '',
'audiocover': '',
}
# save file to make sure the file itself exist in the future
# process and to avoid directory changes just because the cache
# is saved to a new file.
self.changed = True
self.save()
# 'normal' files
self.items = self.data['items']
# file sin the overlay dir
self.overlay = self.data['overlay']
# internal stuff about changes
self.__added = []
self.__changed = []
self.__check_global = False
# a hidden list of files only to check when checking the cache
self.reduce_files = []
def reduce(self, files):
"""
Reduce the files to be checked to the given list of basenames.
"""
self.reduce_files = files
def check(self, overlay = False):
"""
Check the directory for changes.
"""
if overlay:
# handling the overlay dir
dirname = self.overlay_file
listing = self.overlay
mtime = 'overlay_mtime'
else:
# handling the 'normal' dir
dirname = self.dirname
listing = self.items
mtime = 'items_mtime'
deleted = []
# get mtime (may be 0 for devices)
data_mtime = os.stat(dirname)[stat.ST_MTIME]
if data_mtime != self.data[mtime] or not data_mtime:
log.debug('check %s' % dirname)
# mtime differs, check directory for added and deleted files
if not self.reduce_files:
# store new mtime
self.data[mtime] = data_mtime
# get a current filelisting
files = os.listdir(dirname)
for file, info in listing.items():
if file in files:
# in cache already
files.remove(file)
else:
# deleted
deleted.append(file)
for d in deleted:
log.debug('deleted: %s' % d)
# FIXME: if this file is an image, search every item in
# the list if it uses this file as cover image.
del listing[d]
for f in files:
# check all files f not in the cache
if self.reduce_files and not f in self.reduce_files:
# ignore the file for now
continue
if f in ('CVS', 'lost+found') or f.startswith('.'):
# ignore such files
continue
if overlay and (f == 'freevo.db' or f.find('.thumb.') > 0 or \
f.endswith('.raw') or f.endswith('.cache')):
# ignore such files in overlay
continue
fullname = dirname + '/' + f
if overlay and os.path.isdir(fullname):
# ignore directories in overlay
continue
# add as added
self.__added.append((f, fullname))
for basename, info in listing.items():
# check all files for changes (compare mtime)
if self.reduce_files and not basename in self.reduce_files:
continue
filename = dirname + '/' + basename
mtime = os.stat(filename)[stat.ST_MTIME]
if mtime != info['mtime']:
# changed
info['mtime'] = mtime
self.__changed.append((basename, filename, info))
elif info.has_key('isdir'):
# For directories also check the overlay directory. A change
# in the overlay will change the directory, too
overlay = vfs.getoverlay(filename)
if os.path.isdir(overlay):
mtime = os.stat(overlay)[stat.ST_MTIME]
if mtime != info['overlay_mtime']:
info['overlay_mtime'] = mtime
self.__changed.append((basename, filename, info))
if deleted and len(self.__added):
self.__check_global = True
self.changed = True
if overlay:
self.check_time = time.time()
if self.changed:
call_later(self.save)
return
self.check(True)
def save(self):
"""
Save the cache.
"""
if not self.changed:
return
log.info('save %s' % self.file)
cache.save(self.file, self.data, VERSION)
self.mtime = os.stat(self.file)[stat.ST_MTIME]
self.changed = False
def parse(self, callback):
"""
Parse added and changed files. If callback is not None, the callback
will be called after each file.
"""
if not self.__added and not self.__changed and \
not self.__check_global:
return
self.changed = True
for basename, filename in self.__added:
# check new files
log.debug('new: %s' % basename)
ext = basename[basename.rfind('.')+1:].lower()
if ext == basename:
ext = ''
info = { 'ext' : ext,
'mtime' : os.stat(filename)[stat.ST_MTIME],
'mtime_dep': []
}
_add_info(filename, info)
prefix = basename[:-len(ext)]
if ext in ('png', 'jpg', 'gif'):
# the new item is an image, search all items for a similar
# name to add the file as cover
for i_basename, i_info in self.items.items():
if i_basename[:-len(i_info['ext'])] == prefix:
i_info['cover'] = filename
else:
# search the items in the list for covers matching the
# basename of the new item
for ext in ('png', 'jpg', 'gif'):
if prefix + ext in self.items:
info['cover'] = self.dirname + '/' + prefix + ext
if prefix + ext in self.overlay:
info['cover'] = self.overlay_file + '/' + prefix + ext
if vfs.isoverlay(filename):
self.overlay[basename] = info
else:
self.items[basename] = info
if callback:
callback()
for basename, filename, info in self.__changed:
# check changed files
log.debug('changed: %s' % filename)
_add_info(filename, info)
log.debug(info['mtime_dep'])
for key in info['mtime_dep']:
del info[key]
if callback:
callback()
if self.__check_global:
# check global data when files are added or deleted
for cover in ('cover.png', 'cover.jpg', 'cover.gif'):
if self.items.has_key(cover):
# directory cover image
self.data['cover'] = self.dirname + '/' + cover
self.data['audiocover'] = self.data['cover']
break
if self.overlay.has_key(cover):
# cover in overlay
self.data['cover'] = self.overlay_file + '/' + cover
self.data['audiocover'] = self.data['cover']
break
else:
# no cover, try to find at least some image that can be used
# as cover for audio items
self.data['cover'] = ''
self.data['audiocover'] = ''
cover = []
for f, i in self.items.items():
if i['ext'] in ('png', 'jpg', 'gif'):
cover.append(f)
if len(cover) > 10:
cover = []
break
if len(cover) == 1:
self.data['audiocover'] = cover[0]
else:
cover = filter(_cover_filter, cover)
if cover:
self.data['audiocover'] = cover[0]
if callback:
callback()
self.save()
self.__added = []
self.__changed = []
self.__check_global = False
self.reduce_files = []
def list(self):
"""
Return all items.
"""
return self.items.items() + self.overlay.items()
def num_changes(self):
"""
Return the number of changes in the directory. If the number is
greater than zero, parse _must_ be called.
"""
if self.check_time + 2 < time.time():
self.check()
changes = len(self.__added) + len(self.__changed)
if self.__check_global:
return changes + 1
if not changes:
self.reduce_files = []
return changes
class FileCache:
"""
Cache for one file
"""
def __init__(self, filename, db):
self.file = db
self.data = None
if os.path.isfile(self.file):
# load cache file
self.data = cache.load(self.file, VERSION)
self.mtime = os.stat(self.file)[stat.ST_MTIME]
if not self.data:
# create a new cache data dict
self.data = { 'ext': '',
'cover': '',
'audiocover': '',
'mtime' : os.stat(filename)[stat.ST_MTIME],
'mtime_dep': []
}
# save file to make sure the file itself exist in the future
# process and to avoid directory changes just because the cache
# is saved to a new file.
self.changed = True
_add_info(filename, self.data)
self.save()
def save(self):
"""
Save the cache.
"""
if not self.changed:
return
log.info('save %s' % self.file)
cache.save(self.file, self.data, VERSION)
self.mtime = os.stat(self.file)[stat.ST_MTIME]
self.changed = False
def save():
_cache_list.save()
def get(dirname):
return _cache_list.get(dirname)
--- NEW FILE: listing.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# mediainfo.py -
# -----------------------------------------------------------------------------
# $Id: listing.py,v 1.1 2005/03/13 10:13:35 dischi Exp $
#
# -----------------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
#
# 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
#
# -----------------------------------------------------------------------------
__all__ = [ 'Listing', 'FileListing' ]
# python imports
import logging
# mediadb imports
import db
from db import Cache, FileCache
from item import ItemInfo
log = logging.getLogger('mediadb')
class Listing:
def __init__(self, dirname):
try:
self.cache = db.get(dirname)
except:
log.exception('Listing error for %s' % dirname)
self.data = []
self.visible = []
self.num_changes = 0
return
self.num_changes = self.cache.num_changes()
self.dirname = dirname
self.data = []
if self.num_changes > 0:
self.visible = []
return
for basename, item in self.cache.list():
self.data.append(ItemInfo(basename, dirname, item, self.cache))
self.visible = self.data
def update(self, callback=None):
if self.num_changes == 0:
return
self.cache.parse(callback)
dirname = self.dirname
cache = self.cache
for basename, item in self.cache.list():
self.data.append(ItemInfo(basename, dirname, item, cache))
self.num_changes = 0
self.visible = self.data
def get_dir(self):
ret = filter(lambda x: x.attr.has_key('isdir'), self.visible)
self.visible = filter(lambda x: not x.attr.has_key('isdir'),
self.visible)
return ret
def remove(self, item_or_name):
if isinstance(item_or_name, ItemInfo):
self.visible.remove(item_or_name)
return
for item in self.visible:
if item.filename == item_or_name or \
item.basename == item_or_name:
self.visible.remove(item)
return
def get_by_name(self, name):
for item in self.visible:
if item.basename == name:
return item
return None
def match_suffix(self, suffix_list):
visible = self.visible
self.visible = []
ret = []
for v in visible:
if v.attr['ext'] in suffix_list: ret.append(v)
else: self.visible.append(v)
return ret
class FileListing(Listing):
def __init__(self, files):
self.caches = {}
for f in files:
if f == '/':
# root directory in the list, ignore it for now
log.error('unable to parse root directory')
continue
if f.endswith('/'):
dirname = f[:f[:-1].rfind('/')]
basename = f[f[:-1].rfind('/')+1:-1]
else:
dirname = f[:f.rfind('/')]
basename = f[f[:-1].rfind('/')+1:]
try:
if not dirname in self.caches:
cache = db.get(dirname)
self.caches[dirname] = ( cache, [ basename ] )
else:
self.caches[dirname][1].append(basename)
except:
log.exception('Listing error for %s' % dirname)
self.num_changes = 0
for cache, files in self.caches.values():
cache.reduce(files)
self.num_changes += cache.num_changes()
self.data = []
if self.num_changes > 0:
self.visible = []
return
for dirname, ( cache, all_files ) in self.caches.items():
for basename, item in cache.list():
if basename in all_files:
self.data.append(ItemInfo(basename, dirname, item, cache))
self.visible = self.data
def update(self, callback=None):
for dirname, ( cache, all_files ) in self.caches.items():
cache.parse(callback)
for basename, item in cache.list():
if basename in all_files:
self.data.append(ItemInfo(basename, dirname, item, cache))
self.num_changes = 0
self.visible = self.data
--- NEW FILE: __init__.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# mediadb
# -----------------------------------------------------------------------------
# $Id: __init__.py,v 1.1 2005/03/13 10:13:35 dischi Exp $
#
# TODO: o remove old functions (see below)
# o include extendedmeta
# o add SQLListing
# o maybe preload whole cache? Expire cache?
# o add InfoItem for / and network url
# o add InfoItem for subditems
#
# -----------------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
#
# 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
#
# -----------------------------------------------------------------------------
# python imports
import os
import logging
# mmpython
from mmpython.disc.discinfo import cdrom_disc_id
# freevo imports
import sysconfig
# mediadb imports
from db import Cache, FileCache, save
from item import ItemInfo
from listing import Listing, FileListing
# get logging object
log = logging.getLogger('mediadb')
def disc_info(media, force=False):
"""
Return information for the media
"""
type, id = cdrom_disc_id(media.devicename)
if not id:
# bad disc, e.g. blank disc
return ItemInfo(None, None, None)
cachefile = os.path.join(sysconfig.VFS_DIR, 'disc/metadata/%s.db' % id)
if force and os.path.isfile(cachefile):
os.unlink(cachefile)
cache = FileCache(media.devicename, cachefile)
info = ItemInfo('', '', cache.data, cache)
info.filename = info['mime'][6:] + '://'
return info
#
# FIXME: the following functions will be removed in the future
# also missing the attribute mmdata used by videoitem.py
#
def get(filename):
# used by directory.py, item.py, videoitem.py and extendedmeta.py
log.warning('get simple info %s', filename)
listing = FileListing( [ filename ] )
if listing.num_changes:
listing.update()
return listing.get_by_name(os.path.basename(filename))
def del_cache():
# used by cache.py
log.error('del_cache not defined anymore')
def set(filename, key, value):
# used by extendedmeta.py
log.error('set not defined anymore')
def cache_recursive(dirlist, verbose=False):
# used by cache.py
log.error('cache_recursive not defined anymore')
def cache_dir(dirname, callback=None):
# used by cache.py, extendedmeta.py
log.error('cache_dir not defined anymore')
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog