Commit 357ba8ad authored by Frank Scholz's avatar Frank Scholz
Browse files

* some more work on the button handling code

 * mark images as junk to hide them from the slideshow
 * if there is a local MediaServer (currently hardcoded to ''Coherence Test Content''), enable the image copy from the Flickr Images MediaServer to the local one
parent 813ba87c
...@@ -21,6 +21,7 @@ from pygame.locals import * ...@@ -21,6 +21,7 @@ from pygame.locals import *
# Coherence # Coherence
from coherence.base import Coherence from coherence.base import Coherence
from coherence.upnp.core import DIDLLite
import louie import louie
SCREENRECT = Rect(0, 0, 800, 480) SCREENRECT = Rect(0, 0, 800, 480)
...@@ -57,9 +58,9 @@ class MainBackground(object): ...@@ -57,9 +58,9 @@ class MainBackground(object):
def clear_part(self, rect): def clear_part(self, rect):
#print "background clear part", rect #print "background clear part", rect
self.screen.blit(self.background, rect, rect) self.screen.blit(self.background, rect, rect)
class Menu(object): class Menu(object):
def __init__(self, location, buttons, screen, background): def __init__(self, location, buttons, screen, background):
self.image = pygame.image.load(os.path.join('data','menu-frame-%s.png' % location)).convert() self.image = pygame.image.load(os.path.join('data','menu-frame-%s.png' % location)).convert()
self.image.set_colorkey((0,0,0), pygame.RLEACCEL) self.image.set_colorkey((0,0,0), pygame.RLEACCEL)
...@@ -68,20 +69,20 @@ class Menu(object): ...@@ -68,20 +69,20 @@ class Menu(object):
if location == 'right': if location == 'right':
self.offset = 705 self.offset = 705
self.rect[0] = self.offset self.rect[0] = self.offset
self.select_frame = pygame.image.load(os.path.join('data','button-selected.png')).convert() self.select_frame = pygame.image.load(os.path.join('data','button-selected.png')).convert()
self.select_frame.set_colorkey((255,255,255), pygame.RLEACCEL) self.select_frame.set_colorkey((255,255,255), pygame.RLEACCEL)
self.unselect_frame = pygame.image.load(os.path.join('data','button-unselected.png')).convert() self.unselect_frame = pygame.image.load(os.path.join('data','button-unselected.png')).convert()
self.unselect_frame.set_colorkey((255,255,255), pygame.RLEACCEL) self.unselect_frame.set_colorkey((255,255,255), pygame.RLEACCEL)
self.pressed_frame = pygame.image.load(os.path.join('data','button-pressed.png')).convert() self.pressed_frame = pygame.image.load(os.path.join('data','button-pressed.png')).convert()
self.pressed_frame.set_colorkey((255,255,255), pygame.RLEACCEL) self.pressed_frame.set_colorkey((255,255,255), pygame.RLEACCEL)
self.screen = screen self.screen = screen
self.background = background self.background = background
self.visible = False self.visible = False
self.buttons = [] self.buttons = []
for args in buttons: for args in buttons:
button = Button(self,*args) button = Button(self,*args)
...@@ -123,7 +124,7 @@ class Menu(object): ...@@ -123,7 +124,7 @@ class Menu(object):
self.screen.blit(self.unselect_frame,(selected.rect[0]+self.offset-3,selected.rect[1]-3,54,54)) self.screen.blit(self.unselect_frame,(selected.rect[0]+self.offset-3,selected.rect[1]-3,54,54))
pygame.display.update((selected.rect[0]+self.offset-3,selected.rect[1]-3,54,54)) pygame.display.update((selected.rect[0]+self.offset-3,selected.rect[1]-3,54,54))
selected.selected = False selected.selected = False
def hide(self): def hide(self):
if self.visible == True: if self.visible == True:
self.visible = False self.visible = False
...@@ -133,17 +134,17 @@ class Menu(object): ...@@ -133,17 +134,17 @@ class Menu(object):
if b.selected == True: if b.selected == True:
self.image.blit(self.unselect_frame,(b.rect[0]-3,b.rect[1]-3,54,54)) self.image.blit(self.unselect_frame,(b.rect[0]-3,b.rect[1]-3,54,54))
def check(self, button, pos): def check(self, button, pos):
if self.visible == False: if self.visible == False:
return None return None
def clear_pressed(pressed): def clear_pressed(pressed):
if pressed.selected == True: if pressed.selected == True:
self.image.blit(self.select_frame,(pressed.rect[0]-3,pressed.rect[1]-3,54,54)) self.image.blit(self.select_frame,(pressed.rect[0]-3,pressed.rect[1]-3,54,54))
self.screen.blit(self.select_frame,(pressed.rect[0]+self.offset-3,pressed.rect[1]-3,54,54)) self.screen.blit(self.select_frame,(pressed.rect[0]+self.offset-3,pressed.rect[1]-3,54,54))
pygame.display.update((pressed.rect[0]+self.offset-3,pressed.rect[1]-3,54,54)) pygame.display.update((pressed.rect[0]+self.offset-3,pressed.rect[1]-3,54,54))
for b in self.buttons: for b in self.buttons:
if( b.rect.collidepoint(pos[0]-self.rect[0],pos[1]) and if( b.rect.collidepoint(pos[0]-self.rect[0],pos[1]) and
b.action is not None): b.action is not None):
...@@ -152,31 +153,37 @@ class Menu(object): ...@@ -152,31 +153,37 @@ class Menu(object):
pygame.display.update((b.rect[0]+self.offset-3,b.rect[1]-3,54,54)) pygame.display.update((b.rect[0]+self.offset-3,b.rect[1]-3,54,54))
reactor.callLater(2,clear_pressed, b) reactor.callLater(2,clear_pressed, b)
b.call() b.call()
def toggle(self, image, rect): def toggle(self, image, rect):
self.background.clear_part((rect[0]+self.offset,rect[1],rect[2],rect[3])) self.background.clear_part((rect[0]+self.offset,rect[1],rect[2],rect[3]))
self.image.blit(self.background.background,rect,(rect[0]+self.offset,rect[1],rect[2],rect[3])) self.image.blit(self.background.background,rect,(rect[0]+self.offset,rect[1],rect[2],rect[3]))
self.image.blit(image,rect) self.image.blit(image,rect)
self.screen.blit(self.image,(rect[0]+self.offset,rect[1],rect[2],rect[3]), rect) self.screen.blit(self.image,(rect[0]+self.offset,rect[1],rect[2],rect[3]), rect)
pygame.display.update((rect[0]+self.offset,rect[1],rect[2],rect[3])) pygame.display.update((rect[0]+self.offset,rect[1],rect[2],rect[3]))
def set_button_action(self, name, action):
for b in self.buttons:
if b.name == name:
b.action = action
class Button(object): class Button(object):
def __init__(self, menu, imagefile, position, action,alt_imagefile): def __init__(self, menu, name, position, action,alt_imagefile):
self.menu = menu self.menu = menu
self.image = pygame.image.load(os.path.join('data',imagefile)).convert() self.name = name
self.image = pygame.image.load(os.path.join('data','%s.png' % name)).convert()
self.image.set_colorkey((0,0,0), pygame.RLEACCEL) self.image.set_colorkey((0,0,0), pygame.RLEACCEL)
self.rect = self.image.get_rect() self.rect = self.image.get_rect()
self.rect[0] = position[0] self.rect[0] = position[0]
self.rect[1] = position[1] self.rect[1] = position[1]
self.action = action self.action = action
self.selected = False self.selected = False
if alt_imagefile is not None: if alt_imagefile is not None:
self.alt_image = pygame.image.load(os.path.join('data',alt_imagefile)).convert() self.alt_image = pygame.image.load(os.path.join('data',alt_imagefile)).convert()
self.alt_image.set_colorkey((0,0,0), pygame.RLEACCEL) self.alt_image.set_colorkey((0,0,0), pygame.RLEACCEL)
self.toggle=self.alt_image self.toggle=self.alt_image
def call(self): def call(self):
if self.action is not None: if self.action is not None:
self.action() self.action()
...@@ -204,17 +211,17 @@ class MediaRenderer(object): ...@@ -204,17 +211,17 @@ class MediaRenderer(object):
self.mainbg = MainBackground(self.screen, SCREENRECT) self.mainbg = MainBackground(self.screen, SCREENRECT)
self.mainbg.clear_screen() self.mainbg.clear_screen()
buttons = (('return.png',(4,50),None,None), buttons = (('return',(4,50),None,None),
('server-scan.png',(22,216),None,None), ('server-scan',(22,216),None,None),
('exit.png',(4,380),self.quit,None)) ('exit',(4,380),self.quit,None))
self.left_menu = Menu('left', buttons, self.left_menu = Menu('left', buttons,
self.screen, self.mainbg) self.screen, self.mainbg)
buttons = (('save.png',(44,50),None,None), buttons = (('save',(44,50),None,None),
('backward.png',(31,140),self.proceed_to_previous_image,None), ('backward',(31,140),self.proceed_to_previous_image,None),
('pause.png',(31,216),self.pause,'play.png'), ('pause',(31,216),self.pause,'play.png'),
('forward.png',(31,300),self.proceed_to_next_image,None), ('forward',(31,300),self.proceed_to_next_image,None),
('mark-junk.png',(44,380),None,None)) ('mark-junk',(44,380),self.mark_junk,None))
self.right_menu = Menu('right', buttons, self.screen, self.mainbg) self.right_menu = Menu('right', buttons, self.screen, self.mainbg)
config = {} config = {}
...@@ -236,16 +243,58 @@ class MediaRenderer(object): ...@@ -236,16 +243,58 @@ class MediaRenderer(object):
self.displaying = None self.displaying = None
self.current_image = None self.current_image = None
self.client = {} self.client = {}
self.local_store = None
def quit(self): def quit(self):
reactor.stop() reactor.stop()
def loop_start(self, x):
if len(self.images) and not self.display_loop.running:
self.display_loop.start(20, now=False)
def loop_stop(self):
if self.display_loop.running:
self.display_loop.stop()
def pause(self): def pause(self):
if self.display_loop.running: if self.display_loop.running:
self.display_loop.stop() self.display_loop.stop()
elif len(self.images): elif len(self.images) and not self.display_loop.running:
self.display_loop.start(20, now=True) self.display_loop.start(20, now=True)
def store_locally(self):
print "store current image", self.image_index, self.images[self.image_index].get('url')
if(isinstance(self.local_store, tuple) is True and
len(self.local_store) == 2):
print "at", self.local_store[0].device.get_friendly_name(), "in container id", self.local_store[1]
d = self.local_store[0].content_directory.create_object(self.local_store[1],
{'title':self.images[self.image_index].get('title'),
'upnp_class':'object.item.imageItem.photo',
'parentID':self.local_store[1]})
def got_import_result(r,s,d):
print "import from", s, "to", d, "was successful"
def got_result(r, source_uri):
print "store_locally got_result", r
elt = DIDLLite.DIDLElement.fromString(r.get('Result',''))
for item in elt:
for res in item.findall('res'):
destination_uri = res.get('importUri', None)
if destination_uri is not None:
d = self.local_store[0].content_directory.import_resource(source_uri, destination_uri)
d.addCallback(got_import_result, self.images[self.image_index].get('url'), destination_uri)
d.addErrback(got_error)
def got_error(failure):
print "store_locally got_error", failure
d.addCallback(got_result, self.images[self.image_index].get('url'))
d.addErrback(got_error)
def mark_junk(self):
print "mark junk image", self.image_index, self.images[self.image_index].get('url')
self.images[self.image_index]['junk'] = True
self.proceed_to_next_image()
def toggle_fullscreen(self): def toggle_fullscreen(self):
if self.fullscreen == 1: if self.fullscreen == 1:
self.fullscreen = FULLSCREEN self.fullscreen = FULLSCREEN
...@@ -257,30 +306,48 @@ class MediaRenderer(object): ...@@ -257,30 +306,48 @@ class MediaRenderer(object):
self.displaying = self.current_image.get_rect(center=((self.screen.get_width()/2)-1,(self.screen.get_height()/2)-1)) self.displaying = self.current_image.get_rect(center=((self.screen.get_width()/2)-1,(self.screen.get_height()/2)-1))
self.screen.blit(self.current_image,self.displaying) self.screen.blit(self.current_image,self.displaying)
pygame.display.update(self.displaying) pygame.display.update(self.displaying)
def proceed_to_next_image(self): def proceed_to_next_image(self):
if len(self.images)>0: if len(self.images)>0:
try: self.loop_stop()
self.image_index += 1 while True:
image_url, image_title = self.images[self.image_index] try:
except IndexError: self.image_index += 1
self.image_index = 0 image = self.images[self.image_index]
image_url, image_title = self.images[self.image_index] except IndexError:
d = client.getPage(image_url) self.image_index = 0
d.addCallback(self.got_image, image_title) image = self.images[self.image_index]
d.addErrback(self.got_error, image_url) print image
if image.has_key('junk'):
continue
image_url = image.get('url')
image_title = image.get('title')
d = client.getPage(image_url)
d.addCallback(self.got_image, image_title)
d.addCallback(self.loop_start)
d.addErrback(self.got_error, image_url)
break
def proceed_to_previous_image(self): def proceed_to_previous_image(self):
if len(self.images)>0: if len(self.images)>0:
try: self.loop_stop()
self.image_index -= 1 while True:
image_url, image_title = self.images[self.image_index] try:
except IndexError: self.image_index -= 1
self.image_index = len(self.images)-1 image = self.images[self.image_index]
image_url, image_title = self.images[self.image_index] except IndexError:
d = client.getPage(image_url) self.image_index = len(self.images)-1
d.addCallback(self.got_image, image_title) image = self.images[self.image_index]
d.addErrback(self.got_error, image_url) print image
if image.has_key('junk'):
continue
image_url = image.get('url')
image_title = image.get('title')
d = client.getPage(image_url)
d.addCallback(self.got_image, image_title)
d.addCallback(self.loop_start)
d.addErrback(self.got_error, image_url)
break
def got_image(self, result, title = ''): def got_image(self, result, title = ''):
try: try:
...@@ -345,12 +412,29 @@ class MediaRenderer(object): ...@@ -345,12 +412,29 @@ class MediaRenderer(object):
self.container_watch.append(values['parent_id']) self.container_watch.append(values['parent_id'])
if len(values['resources']): if len(values['resources']):
title = values.get('title', 'untitled').encode('ascii', 'ignore') title = values.get('title', 'untitled').encode('ascii', 'ignore')
self.images.append((values['resources'].keys()[0], title)) self.images.append({'url': values['resources'].keys()[0], 'title': title})
random.shuffle(self.images) random.shuffle(self.images)
if len(self.images): if len(self.images):
if not self.display_loop.running: if not self.display_loop.running:
self.display_loop.start(20, now=True) self.display_loop.start(20, now=True)
def process_local_media_server_browse( self, results, usn):
for k,v in results.iteritems():
#print k, v
if k == 'items':
for id, values in v.iteritems():
#print values
if(values['upnp_class'].startswith('object.container') and
values['title'] == 'content'):
d = self.client[usn].content_directory.browse(id, browse_flag='BrowseDirectChildren',
backward_compatibility=False)
d.addCallback( self.process_local_media_server_browse, usn)
if(values['upnp_class'].startswith('object.container') and
values['title'] == 'images'):
print "found object id", values['id'], "as storage point"
self.right_menu.set_button_action('save',self.store_locally)
self.local_store = (self.local_store,values['id'])
def media_server_found(self, client, usn): def media_server_found(self, client, usn):
print "media_server_found", client.device.get_friendly_name() print "media_server_found", client.device.get_friendly_name()
if 'Flickr Images' == client.device.get_friendly_name(): if 'Flickr Images' == client.device.get_friendly_name():
...@@ -362,9 +446,21 @@ class MediaRenderer(object): ...@@ -362,9 +446,21 @@ class MediaRenderer(object):
client.content_directory.subscribe_for_variable('ContainerUpdateIDs', self.state_variable_change) client.content_directory.subscribe_for_variable('ContainerUpdateIDs', self.state_variable_change)
client.content_directory.subscribe_for_variable('SystemUpdateID', self.state_variable_change) client.content_directory.subscribe_for_variable('SystemUpdateID', self.state_variable_change)
if 'Coherence Test Content' == client.device.get_friendly_name():
print "found a local MediaServer for storage"
self.local_store = self.client[usn] = client
d = self.client[usn].content_directory.browse(0, browse_flag='BrowseDirectChildren',
backward_compatibility=False)
d.addCallback( self.process_local_media_server_browse, usn)
def media_server_removed(self, usn): def media_server_removed(self, usn):
print "media_server_removed", usn print "media_server_removed", usn
if self.client.has_key(usn) == True: if self.client.has_key(usn) == True:
if self.client[usn] == self.local_store:
self.local_store = None
self.right_menu.set_button_action('save',None)
del self.client[usn]
return
if self.display_loop.running: if self.display_loop.running:
self.display_loop.stop() self.display_loop.stop()
del self.client[usn] del self.client[usn]
...@@ -413,7 +509,7 @@ class MediaRenderer(object): ...@@ -413,7 +509,7 @@ class MediaRenderer(object):
else: else:
self.right_menu.hide() self.right_menu.hide()
self.left_menu.hide() self.left_menu.hide()
if event.type == MOUSEBUTTONUP: if event.type == MOUSEBUTTONUP:
self.left_menu.check(event.button, event.pos) self.left_menu.check(event.button, event.pos)
self.right_menu.check(event.button, event.pos) self.right_menu.check(event.button, event.pos)
......
from setuptools import setup, find_packages from setuptools import setup, find_packages
__version__ = '0.0.2' __version__ = '0.0.3'
setup( setup(
name="MediaRenderer", name="MediaRenderer",
......
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