Author: dmeyer
Date: Mon Feb 20 16:02:15 2006
New Revision: 1211
Added:
trunk/WIP/thumb2/src/thumbnail.py
Removed:
trunk/WIP/thumb2/src/interface.py
Modified:
trunk/WIP/thumb2/bin/kaa-thumb
trunk/WIP/thumb2/src/__init__.py
trunk/WIP/thumb2/src/server.py
trunk/WIP/thumb2/src/videothumb.py
Log:
Kaa.thumb2 has now all the features of kaa.thumb, even more like using
an external process, feed data to be stored as thumbnail and support
for reading metadata images like images in id3 tags. The only thing
missing (besides integration into Freevo) is a nice way to check if
a thumbnail needs an update or not.
Modified: trunk/WIP/thumb2/bin/kaa-thumb
==============================================================================
--- trunk/WIP/thumb2/bin/kaa-thumb (original)
+++ trunk/WIP/thumb2/bin/kaa-thumb Mon Feb 20 16:02:15 2006
@@ -1,12 +1,73 @@
#!/usr/bin/python
import sys
-import kaa.thumb
+import os
+import kaa
+import kaa.thumb2
+import kaa.metadata
-for file in sys.argv[1:]:
- type, thumbnail = kaa.thumb.check(file)
- if type != kaa.thumb.MISSING:
- print '%s: %s' % (file, thumbnail)
+counter = 0
+
+def finished(t, size):
+ global counter
+ counter -= 1
+ if t.get(size):
+ print t.name, '->', t.get(size)
else:
- print 'thumbnailing %s' % file
- kaa.thumb.create(file)
+ print t.name, '(failed)'
+ if not counter:
+ sys.exit(0)
+
+
+if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'):
+ print 'kaa-thumb [options] [ files ]'
+ print
+ print 'options:'
+ print ' -l create large thumbnails of the files'
+ print ' -c clean up .thumbnails dir'
+ print ' -h show this help'
+ print
+ sys.exit(0)
+
+
+size = kaa.thumb2.NORMAL
+if sys.argv[1] == '-l':
+ sys.argv = sys.argv[1:]
+ size = kaa.thumb2.LARGE
+
+
+if sys.argv[1] == '-c':
+ print 'clean thumbnails directory'
+ listing = []
+ for type in (kaa.thumb2.LARGE, kaa.thumb2.NORMAL):
+ d = os.path.join(os.environ['HOME'], '.thumbnails/%s' % type)
+ listing += [ '%s/%s' % (d,x) for x in os.listdir(d) ]
+
+ total = len(listing)
+ cur = 0
+ for f in listing:
+ cur += 1
+ n = int((cur / float(total)) * 50)
+
+ sys.stdout.write("|%51s| %d / %d\r" % (("="*n + ">").ljust(51), cur,
total))
+ sys.stdout.flush()
+
+ info =kaa.metadata.parse(f)
+ if not info or not info['Thumb::URI']:
+ os.unlink(f)
+ continue
+ if not info['Thumb::URI'].startswith('file:/'):
+ continue
+ if os.path.exists(info['Thumb::URI'][5:]):
+ continue
+ os.unlink(f)
+ print
+ sys.exit(0)
+
+
+for file in sys.argv[1:]:
+ t = kaa.thumb2.Thumbnail(file)
+ t.create(size).connect(finished, t, size)
+ counter += 1
+
+kaa.main()
Modified: trunk/WIP/thumb2/src/__init__.py
==============================================================================
--- trunk/WIP/thumb2/src/__init__.py (original)
+++ trunk/WIP/thumb2/src/__init__.py Mon Feb 20 16:02:15 2006
@@ -29,3 +29,4 @@
#
# -----------------------------------------------------------------------------
+from thumbnail import Thumbnail, NORMAL, LARGE
Modified: trunk/WIP/thumb2/src/server.py
==============================================================================
--- trunk/WIP/thumb2/src/server.py (original)
+++ trunk/WIP/thumb2/src/server.py Mon Feb 20 16:02:15 2006
@@ -32,6 +32,7 @@
# python imports
import os
import sys
+import logging
# insert kaa path information
__site__ = '../lib/python%s.%s/site-packages' % sys.version_info[:2]
@@ -95,7 +96,7 @@
def _create_failed_image(self, job):
- dirname = os.path.dirname(os.path.dirname(job.imagefile)) +
'/failed/kaa/'
+ dirname = os.path.dirname(os.path.dirname(job.imagefile)) +
'/fail/kaa/'
job.imagefile = dirname + os.path.basename(job.imagefile) + '.png'
if not os.path.isdir(dirname):
os.makedirs(dirname, 0700)
@@ -125,7 +126,8 @@
job.imagefile += '.png'
self._notify_client(job)
return True
- except (IOError, ValueError):
+ except (IOError, ValueError), e:
+ print e
pass
# maybe this is no image
@@ -160,13 +162,25 @@
return self.next_client_id
- def thumbnail(self, id, filename, imagefile, size, update=True):
+ def schedule(self, id, filename, imagefile, size, update=True):
self._jobs.append(Job(id, filename, imagefile, size, update))
if not self._timer.active():
self._timer.start(0.001)
+ def remove(self, id):
+ for job in self._jobs:
+ if id == (job.client, job.id):
+ print 'remove job'
+ self._jobs.remove(job)
+ return
+ for job in self.videothumb._jobs:
+ if id == (job.client, job.id):
+ print 'remove video job'
+ self.videothumb._jobs.remove(job)
+ return
+
def _client_closed(self, client):
for client_info in self.clients[:]:
id, c = client_info
@@ -196,13 +210,26 @@
sys.exit(0)
return True
-
+ try:
+ # detach for parent using a new sesion
+ os.setsid()
+ except OSError:
+ # looks like we are started from the shell
+ # TODO: start some extra debug here and disable autoshutdown
+ pass
+
# create tmp dir and change directory to it
tmpdir = os.path.join(kaa.TEMP, 'thumb')
if not os.path.isdir(tmpdir):
os.mkdir(tmpdir)
os.chdir(tmpdir)
+ # Setup logger. This module should produce no output at all, but a crash
+ # will result in a backtrace which is nice to have.
+ handler = logging.FileHandler('log')
+ handler.setFormatter(logging.Formatter('%(filename)s %(lineno)s:
%(message)s'))
+ logging.getLogger().addHandler(handler)
+
# create thumbnailer object
thumbnailer = Thumbnailer(tmpdir)
Added: trunk/WIP/thumb2/src/thumbnail.py
==============================================================================
--- (empty file)
+++ trunk/WIP/thumb2/src/thumbnail.py Mon Feb 20 16:02:15 2006
@@ -0,0 +1,153 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# thumbnail.py - Client part for thumbnailing files
+# -----------------------------------------------------------------------------
+# $Id$
+#
+# -----------------------------------------------------------------------------
+# kaa-thumb - Thumbnailing module
+# Copyright (C) 2005-2006 Dirk Meyer, et al.
+#
+# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
+# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+#
+# Please see the file AUTHORS 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__ = [ 'Thumbnail', 'NORMAL', 'LARGE' ]
+
+NORMAL = 'normal'
+LARGE = 'large'
+
+# python imports
+import os
+import md5
+import logging
+
+# kaa imports
+from kaa.base import ipc, weakref
+from kaa.notifier import Signal, step
+
+# kaa.thumb imports
+from thumbnailer import png
+
+# get logging object
+log = logging.getLogger('thumb')
+
+# default .thumbnail dir
+DOT_THUMBNAIL = os.path.join(os.environ['HOME'], '.thumbnails')
+
+# sizes for the thumbnails
+SIZE = { NORMAL: (128, 128), LARGE: (256, 256) }
+
+class Job(object):
+
+ all = []
+
+ def __init__(self, file, id):
+ self.file = weakref(file)
+ self.id = id
+ self.signal = Signal()
+ self.finished = False
+ Job.all.append(self)
+
+
+class Thumbnail(object):
+
+ next_id = 0
+
+ def __init__(self, name, destdir=DOT_THUMBNAIL, url=None):
+ self.name = os.path.realpath(name)
+ self.destdir = destdir
+
+ if not url:
+ # create url to be placed in the thumbnail
+ url = 'file://' + os.path.normpath(name)
+ self.url = url
+
+ # create digest for filename (with %s for the size)
+ self._thumbnail = destdir + '/%s/' + md5.md5(url).hexdigest()
+
+
+ def get(self, type=NORMAL):
+ if os.path.isfile(self._thumbnail % type + '.png'):
+ return self._thumbnail % type + '.png'
+ if os.path.isfile(self._thumbnail % type + '.jpg'):
+ return self._thumbnail % type + '.jpg'
+ return None
+
+
+ def set(self, image, type=NORMAL):
+ png(self.name, self._thumbnail % type + '.png', SIZE[type],
image._image)
+
+
+ def exists(self):
+ return self.get(NORMAL) or self.get(LARGE) or self.get('fail/kaa')
+
+
+ def is_failed(self):
+ return self._get_thumbnail('fail/kaa')
+
+
+ def create(self, type=NORMAL, wait=False, force=True):
+ Thumbnail.next_id += 1
+
+ dest = '%s/%s' % (self.destdir, type)
+ if not os.path.isdir(dest):
+ os.makedirs(dest, 0700)
+
+ # schedule thumbnail creation
+ _schedule((_client_id, Thumbnail.next_id), self.name,
+ self._thumbnail % type, SIZE[type], update=force,
+ __ipc_oneway=True, __ipc_noproxy_args=True)
+
+ job = Job(self, Thumbnail.next_id)
+
+ if not wait:
+ return job.signal
+
+ while not job.finished:
+ step()
+
+
+def _callback(id, *args):
+ if not id:
+ for i in args[0]:
+ log.error(i)
+ return
+
+ for job in Job.all[:]:
+ if job.id == id:
+ log.info('finished job %s->%s', args[0], args[1])
+ Job.all.remove(job)
+ job.finished = True
+ job.signal.emit()
+ elif not job.file:
+ Job.all.remove(job)
+ job.finished = True
+ log.info('remove job %s', job.id)
+ _remove((_client_id, job.id), __ipc_oneway=True,
__ipc_noproxy_args=True)
+
+
+# connect to ipc
+_server = os.path.join(os.path.dirname(__file__), 'server.py')
+_server = ipc.launch(_server, 2, ipc.IPCClient,
'thumb/socket').get_object('thumb')
+
+_client_id = _server.connect(_callback)
+_schedule = _server.schedule
+_remove = _server.remove
Modified: trunk/WIP/thumb2/src/videothumb.py
==============================================================================
--- trunk/WIP/thumb2/src/videothumb.py (original)
+++ trunk/WIP/thumb2/src/videothumb.py Mon Feb 20 16:02:15 2006
@@ -123,7 +123,7 @@
# scale thumbnail
width, height = job.size
- image = kaa.imlib2.open(captures[-1])
+ image = kaa.imlib2.open_without_cache(captures[-1])
if image.width > width or image.height > height:
image = image.scale_preserve_aspect((width,height))
if image.width * 3 > image.height * 4:
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog