Commit 09eb00c7 authored by Frank Scholz's avatar Frank Scholz
Browse files

* making use of a config file

* create a list of images pointed to in the config, optionally shuffle and autoplay them (needs some more work)
parent 59e9d8b3
import platform
__version_info__ = (0,0,4)
__version_info__ = (0,0,5)
__version__ = '%d.%d.%d' % (__version_info__[0],__version_info__[1],__version_info__[2],)
......@@ -3,53 +3,215 @@
# Copyright 2009 Frank Scholz <coherence@beebits.net>
import os,random
try:
_ = set()
except:
from sets import Set as set
import traceback
import mimetypes
mimetypes.init()
# Twisted
from twisted.internet import reactor
from twisted.python.filepath import FilePath
# Coherence
from coherence.base import Coherence
from coherence.upnp.devices.media_renderer import MediaRenderer
from coherence.upnp.core import DIDLLite
import coherence.extern.louie as louie
from coherence import log
from coherence.upnp.core.utils import means_true
from cadre.scribbling import Canvas
from cadre.renderer import PictureRenderer
from cadre.renderer import CadreRenderer
def xmeans_true(value):
if isinstance(value,basestring):
value = value.lower()
return value in [True,1,'1','true','yes','ok']
class Cadre(log.Loggable):
logCategory = 'renderer'
def __init__(self, fullscreen=1):
def __init__(self,config):
self.config = config
fullscreen = 0
try:
if means_true(self.config['fullscreen']):
fullscreen = 1
except:
pass
self.canvas = Canvas(fullscreen)
config = {}
config['logmode'] = 'warning'
config['controlpoint'] = 'yes'
try:
overlays = self.config['overlay']
if not isinstance(overlays,list):
overlays = [overlays]
except:
overlays = []
map(self.canvas.add_overlay,overlays)
coherence_config = {}
#coherence_config['version'] = '1'
coherence_config['logmode'] = 'warning'
#coherence_config['controlpoint'] = 'yes'
louie.connect(self.media_server_found, 'Coherence.UPnP.ControlPoint.MediaServer.detected', louie.Any)
louie.connect(self.media_server_removed, 'Coherence.UPnP.ControlPoint.MediaServer.removed', louie.Any)
self.coherence = Coherence(config)
self.coherence = Coherence(coherence_config)
name = self.config.get('name','Cadre - Coherence Picture-Frame')
kwargs = {'version':1,
'no_thread_needed':True}
name = 'Cadre - Coherence Picture-Frame'
if name:
kwargs['name'] = name
'no_thread_needed':True,
'name':name}
self.canvas.set_title(name)
kwargs['controller'] = self
uuid = self.config.get('uuid')
if uuid:
kwargs['uuid'] = uuid
print kwargs
self.renderer = MediaRenderer(self.coherence,CadreRenderer,**kwargs)
if 'uuid' not in self.config:
self.config['uuid'] = str(self.renderer.uuid)[5:]
try:
self.config.save()
except AttributeError:
pass
reactor.callLater(0.5,self.start,name)
def init_logging(self):
logmode = self.config.get('logging').get('level','warning')
_debug = []
try:
subsystems = self.config.get('logging')['subsystem']
except KeyError:
subsystems = []
if isinstance(subsystems,dict):
subsystems = [subsystems]
for subsystem in subsystems:
try:
if subsystem['active'] == 'no':
continue
except (KeyError,TypeError):
pass
self.info( "setting log-level for subsystem %s to %s" % (subsystem['name'],subsystem['level']))
_debug.append('%s:%d' % (subsystem['name'].lower(), log.human2level(subsystem['level'])))
if len(_debug) > 0:
_debug = ','.join(_debug)
else:
_debug = '*:%d' % log.human2level(logmode)
logfile = self.config.get('logging').get('logfile',None)
if logfile != None:
logfile = unicode(logfile)
log.init(logfile, _debug)
def start(self,name):
self.canvas.set_title(name)
self.renderer = MediaRenderer(self.coherence,PictureRenderer,**kwargs)
try:
self.content = self.config['content']
except:
self.content = []
if not isinstance( self.content, list):
self.content = [self.content]
self.content = set(map(os.path.abspath,self.content))
self.files = []
self.playlist = []
self.warning("checking for files...")
for path in self.content:
self.walk(path)
self.warning("done")
self.renderer.av_transport_server.get_variable('AVTransportURI').subscribe(self.state_variable_change)
self.renderer.av_transport_server.get_variable('NextAVTransportURI').subscribe(self.state_variable_change)
#self.renderer.av_transport_server.get_variable('TransportState').subscribe(self.state_variable_change)
#self.renderer.av_transport_server.get_variable('AVTransportURI').subscribe(self.state_variable_change)
#self.renderer.av_transport_server.get_variable('LastChange').subscribe(self.state_variable_change)
try:
if means_true(self.config['autostart']):
self.playlist = self.files[:]
if means_true(self.config['shuffle']):
random.shuffle(self.playlist)
file = self.playlist.pop()
try:
uri = "file://" + file.path
except:
uri = file
self.renderer.backend.stop()
self.renderer.backend.load(uri,'')
self.renderer.backend.play()
file = self.playlist.pop()
try:
uri = "file://" + file.path
except:
uri = file
self.renderer.backend.upnp_SetNextAVTransportURI(InstanceID='0',NextURI=uri,NextURIMetaData='')
except KeyError:
pass
except:
traceback.print_exc()
def quit(self):
reactor.stop()
def walk(self, path):
containers = []
filepath = FilePath(path)
if filepath.isdir():
containers.append(filepath)
elif filepath.isfile():
self.files.append(FilePath(path))
while len(containers)>0:
container = containers.pop()
try:
for child in container.children():
if child.isdir():
containers.append(child)
elif child.isfile() or child.islink():
mimetype,_ = mimetypes.guess_type(child.path, strict=False)
if mimetype and mimetype.startswith("image/"):
self.files.append(child)
except UnicodeDecodeError:
self.warning("UnicodeDecodeError - there is something wrong with a file located in %r", container.get_path())
def media_server_found(self, client,udn):
print "media_server_found", client.device.get_friendly_name()
def media_server_removed(self, udn):
print "media_server_removed", udn
\ No newline at end of file
print "media_server_removed", udn
def state_variable_change(self,variable):
print "state_variable %r changed from %r -> %r" % (variable.name,variable.old_value,variable.value)
if variable.name == 'NextAVTransportURI':
if variable.value == '' and self.renderer.av_transport_server.get_variable('TransportState').value == 'TRANSITIONING':
try:
file = self.playlist.pop()
except IndexError:
self.playlist = self.files[:]
if means_true(self.config['shuffle']):
random.shuffle(self.playlist)
file = self.playlist.pop()
try:
uri = "file://" + file.path
except:
uri = file
self.renderer.backend.upnp_SetNextAVTransportURI(InstanceID='0',NextURI=uri,NextURIMetaData='')
......@@ -26,7 +26,7 @@ import coherence.extern.louie as louie
from coherence import log
class PictureRenderer(log.Loggable):
class CadreRenderer(log.Loggable):
logCategory = 'renderer'
......@@ -81,7 +81,6 @@ class PictureRenderer(log.Loggable):
connection_id = self.server.connection_manager_server.lookup_avt_id(self.current_connection_id)
if self.playcontainer == None:
self.server.av_transport_server.set_variable(connection_id, 'AVTransportURI',uri)
self.server.av_transport_server.set_variable(connection_id, 'AVTransportURIMetaData',metadata)
......@@ -133,11 +132,15 @@ class PictureRenderer(log.Loggable):
item = elt.getItems()[0]
image_title = item.title
self.stop_auto_next_image()
d = client.getPage(image_url, timeout=111)
d.addCallback(self.got_image, image_title)
d.addCallback(lambda x: self.start_auto_next_image())
d.addErrback(got_error, image_url)
d.addErrback(got_error, image_url)
if image_url.startswith("file://"):
self.got_image(image_url)
self.start_auto_next_image()
else:
d = client.getPage(image_url, timeout=111)
d.addCallback(self.got_image, image_title)
d.addCallback(lambda x: self.start_auto_next_image())
d.addErrback(got_error, image_url)
d.addErrback(got_error, image_url)
self.server.av_transport_server.set_variable(connection_id,'TransportState','PLAYING')
......@@ -396,13 +399,13 @@ class PictureRenderer(log.Loggable):
if NewDisplayTransition in supported_transition_modes:
self.display_transition = NewDisplayTransition
if self.server:
self.server.av_transport_server.set_variable(InstanceID, 'X_COHESonntagRENCE_DisplayTransition', self.display_transition)
self.server.av_transport_server.set_variable(InstanceID, 'X_COHERENCE_DisplayTransition', self.display_transition)
return {}
return failure.Failure(errorCode(600))
def upnp_init(self):
self.current_connection_id = None
self.display_time = 120
self.display_time = 20
self.display_transition = 'NONE'
self.server.connection_manager_server.set_variable(0, 'SinkProtocolInfo',
['http-get:*:image/jpeg:*',
......
......@@ -10,6 +10,8 @@ from twisted.internet import reactor
from coherence import log
import pango
# Clutter
import clutter
from clutter import cogl
......@@ -95,7 +97,6 @@ class Canvas(log.Loggable):
def __init__(self, fullscreen=1):
self.fullscreen = fullscreen
self.stage = clutter.Stage()
if self.fullscreen == 1:
self.stage.set_fullscreen(True)
......@@ -135,16 +136,58 @@ class Canvas(log.Loggable):
def set_title(self,title):
self.stage.set_title(title)
def add_overlay(self,overlay):
screen_width,screen_height = self.stage.get_size()
texture = clutter.Texture()
texture.set_keep_aspect_ratio(True)
texture.set_size(int(overlay['width']),int(overlay['height']))
print overlay['url']
texture.set_from_file(filename=overlay['url'])
def get_position(item_position,item_width):
p = float(str(item_position))
try:
orientation = item_position['orientation']
except:
orientation = 'left'
try:
unit = item_position['unit']
except:
unit = 'px'
if unit in ['%']:
p = screen_width * (p/100.0)
else:
position = int(p)
if orientation == 'right':
p -= int(item_width)
return p
position_x = get_position(overlay['position_x'],overlay['width'])
position_y = get_position(overlay['position_y'],overlay['width'])
print position_x, position_y
texture.set_position(position_x, position_y)
self.stage.add(texture)
def show_image(self,image,title=''):
#FIXME - we have the image as data already, there has to be
# a better way to get it into the texture
self.warning("show image %r" % title)
from tempfile import mkstemp
fp,filename = mkstemp()
os.write(fp,image)
os.close(fp)
if image.startswith("file://"):
filename = image[7:]
else:
from tempfile import mkstemp
fp,filename = mkstemp()
os.write(fp,image)
os.close(fp)
remove_file_after_loading = True
#self.texture.set_load_async(True)
self.warning("loading image from file %r" % filename)
self.texture.set_from_file(filename=filename)
self.set_title(title)
os.unlink(filename)
\ No newline at end of file
try:
if remove_file_after_loading:
os.unlink(filename)
except:
pass
\ No newline at end of file
<config>
<logging level="warning" />
<name>Cadre - Coherence Picture-Frame</name>
<content>/path/to/images/here</content>
<autostart>yes</autostart>
<shuffle>yes</shuffle>
<fullscreen>no</fullscreen>
<repeat>yes</repeat>
</config>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment