|
- #!/usr/bin/env python
-
- import errno
- import os
- import sets
- import stat
- from DIDLLite import StorageFolder, Item, VideoItem, AudioItem, TextItem, ImageItem, Resource
- from twisted.web import static
- from twisted.python import log
-
- mimedict = static.loadMimeTypes()
-
- def statcmp(a, b, cmpattrs = [ 'st_ino', 'st_dev', 'st_size', 'st_mtime', ]):
- if a is None or b is None:
- return False
-
- for i in cmpattrs:
- if getattr(a, i) != getattr(b, i):
- return False
- return True
-
- class FSObject(object):
- def __init__(self, path):
- self.FSpath = path
- self.pstat = None
-
- def checkUpdate(self):
- # need to handle no such file or directory
- # push it up? but still need to handle disappearing
- try:
- nstat = os.stat(self.FSpath)
- if statcmp(self.pstat, nstat):
- return self
-
- self.pstat = nstat
- self.doUpdate()
- except OSError, x:
- log.msg('os.stat, OSError: %s' % x)
- if x.errno in (errno.ENOENT, errno.ENOTDIR, errno.EPERM, ):
- # We can't access it anymore, delete it
- self.cd.delItem(self.id)
- else:
- raise x
-
- return self
-
- def doUpdate(self):
- raise NotImplementedError
-
- class FSItem(FSObject, Item):
- def __init__(self, *args, **kwargs):
- FSObject.__init__(self, kwargs['path'])
- del kwargs['path']
- urlbase = kwargs['urlbase']
- del kwargs['urlbase']
- mimetype = kwargs['mimetype']
- del kwargs['mimetype']
- Item.__init__(self, *args, **kwargs)
- self.url = '%s%s' % (urlbase, self.FSpath)
- self.mimetype = mimetype
-
- def doUpdate(self):
- self.res = Resource(self.url, 'http-get:*:%s:*' % self.mimetype)
- self.res.size = os.path.getsize(self.FSpath)
- Item.doUpdate(self)
-
- class FSVideoItem(FSItem, VideoItem):
- pass
-
- class FSAudioItem(FSItem, AudioItem):
- pass
-
- class FSTextItem(FSItem, TextItem):
- pass
-
- class FSImageItem(FSItem, ImageItem):
- pass
-
- mimetoklass = {
- 'application/ogg': FSAudioItem,
- 'video': FSVideoItem,
- 'audio': FSAudioItem,
- 'text': FSTextItem,
- 'image': FSImageItem,
- }
-
- def dofileadd(cd, parent, urlbase, path, name):
- fn, ext = os.path.splitext(name)
- ext = ext.lower()
- try:
- mt = mimedict[ext]
- except KeyError:
- log.msg('no mime-type for: %s' % name)
- return
-
- ty = mt.split('/')[0]
- if mimetoklass.has_key(mt):
- klass = mimetoklass[mt]
- elif mimetoklass.has_key(ty):
- klass = mimetoklass[ty]
- else:
- log.msg('no item for mt: %s' % mt)
- return
-
- return cd.addItem(parent, klass, name, urlbase = urlbase,
- path = os.path.join(path, name), mimetype = mt)
-
- class FSDirectory(FSObject, StorageFolder):
- def __init__(self, *args, **kwargs):
- path = kwargs['path']
- del kwargs['path']
- urlbase = kwargs['urlbase']
- del kwargs['urlbase']
- StorageFolder.__init__(self, *args, **kwargs)
- FSObject.__init__(self, path)
-
- # mapping from path to objectID
- self.pathObjmap = {}
- self.urlbase = urlbase
-
- def doUpdate(self):
- # We need to rescan this dir, and see if our children has
- # changed any.
- children = sets.Set(os.listdir(self.FSpath))
- for i in self.pathObjmap.keys():
- if i not in children:
- # delete
- self.cd.delItem(self.pathObjmap[i])
- del self.pathObjmap[i]
-
- for i in children:
- fname = os.path.join(self.FSpath, i)
- if i in self.pathObjmap:
- continue
-
- # new object
- if os.path.isdir(fname):
- # new dir
- nf = self.cd.addContainer(self.id, i, klass = FSDirectory, path = fname, urlbase = self.urlbase)
- elif os.path.isfile(fname):
- # new file
- nf = dofileadd(self.cd, self.id, self.urlbase, self.FSpath, i)
- else:
- nf = None
- log.msg('skipping: %s' % fname)
-
- if nf is not None:
- self.pathObjmap[i] = nf
-
- # sort our children
- self.sort(lambda x, y: cmp(x.title, y.title))
-
- # Pass up to handle UpdateID
- StorageFolder.doUpdate(self)
|