Initial commit

This commit is contained in:
noisymime 2007-08-15 01:10:53 +00:00
commit 1fbc9ea10e
98 changed files with 1656 additions and 0 deletions

255
Menu.py Normal file
View File

@ -0,0 +1,255 @@
import clutter
import pygtk
import gtk
import time
from ReflectionTexture import Texture_Reflection
class Menu:
item_gap = 10 #Distance between items
def __init__ (self, menuMgr):
self.menuMgr = menuMgr
self.stage = self.menuMgr.get_stage()
self.menuItems = []
self.selected = 0
self.displayPosition = (0, 0)
self.itemGroup = clutter.Group()
self.menuGroup = clutter.Group()
self.stage.add(self.itemGroup)
self.stage.add(self.menuGroup)
#self.hasTimeline = False
self.timeline = clutter.Timeline(15, 75) #This timeline is used on any movements that occur when changing items
self.timeline_completed=True
self.menuMgr.addMenu(self)
#self.itemGroup.hide_all()
def addItem(self, itemLabel, imagePath):
if len(self.menuItems) == 0:
label_height = 0
label_width = 0
else:
(label_width, label_height) = self.menuItems[0].get_size()
label_y = label_height * len(self.menuItems)+self.item_gap
newItem = ListItem(self, itemLabel, label_y, imagePath)
self.menuItems.append(newItem)
self.itemGroup.add(newItem)
group_x = self.itemGroup.get_x()
group_y = self.itemGroup.get_y() - (label_height)
self.itemGroup.set_position(group_x, group_y)
return newItem
def getItem(self, index):
return self.menuItems[index]
def getStage(self):
return self.stage
def getMenuMgr(self):
return self.menuMgr
def setMenuPositionByName(self, location):
if location == "center":
menu_y = (self.stage.get_height()-self.itemGroup.get_height())/2
menu_x = (self.stage.get_width()-self.itemGroup.get_width())/2
self.itemGroup.set_position(menu_x, menu_y)
self.displayPosition = (menu_x, menu_y)
print "Original Group size: " + str(self.itemGroup.get_width())
print "Starting at : " + str(menu_x) + ":" + str(menu_y)
#The display position is the x, y coords of where the menu is when it is active
def get_display_position(self):
return self.displayPosition
def setMenuPosition(self, x, y):
self.itemGroup.set_position(x,y)
def getItemGroup(self):
return self.itemGroup
def getMenuGroup(self):
return self.menuGroup
def setListFont(self, newFont):
currentY= 0 #self.itemGroup.get_y()
self.font = newFont
for li in self.menuItems:
x = li.get_x()
#y = li.getPositionY()
li.set_font_name(newFont)
li.set_position(x,currentY)
currentY = currentY + li.get_height()
#Returns the newly selected item
def selectNext(self):
#Initially check whether the last animation is still going
if self.timeline.is_playing():
self.timeline.set_speed(1000) # Nasty hack to make sure the timeline finishes
self.timeline = clutter.Timeline (15,85)
#Check if we're at the last item in the list
if (self.selected) != (len(self.menuItems)-1):
self.selected = self.selected+1
self.menuItems[self.selected].scaleLabel(0, self.timeline)
self.menuItems[self.selected-1].scaleLabel(1, self.timeline)
if (self.selected >= 2):
self.menuItems[self.selected-2].scaleLabel(2, self.timeline)
#Finally move the selection bar
self.menuMgr.get_selector_bar().selectItem(self.menuItems[self.selected], self.timeline)
if self.selected != (len(self.menuItems)-1):
self.menuItems[self.selected+1].scaleLabel(1, self.timeline)
self.timeline.start()
#Returns the newly selected item
def selectPrevious(self):
#Initially check whether the last animation is still going
if self.timeline.is_playing():
self.timeline.set_speed(1000) # Nasty hack to make sure the timeline finishes
self.timeline = clutter.Timeline (15,85)
self.timeline_completed=False
#Check if we're at the first item in the list
if (self.selected) != 0:
self.selected = self.selected-1
#Move the selection bar
self.menuMgr.get_selector_bar().selectItem(self.menuItems[self.selected], self.timeline)
self.menuItems[self.selected].scaleLabel(0, self.timeline)
self.menuItems[self.selected+1].scaleLabel(1, self.timeline)
if self.selected <= (len(self.menuItems)-3):
self.menuItems[self.selected+2].scaleLabel(2, self.timeline)
if self.selected != 0:
self.menuItems[self.selected-1].scaleLabel(1, self.timeline)
self.timeline.start()
def selectFirst(self, moveBar):
self.timeline = clutter.Timeline(15, 75)
self.selected = 0
for i in range(0,len(self.menuItems)):
if i == 0:
self.menuItems[i].scaleLabel(0, self.timeline)
elif i == 1:
self.menuItems[i].scaleLabel(1, self.timeline)
else:
self.menuItems[i].scaleLabel(2, self.timeline)
if moveBar:
self.menuMgr.get_selector_bar().selectItem(self.menuItems[self.selected], self.timeline)
self.timeline.start()
def get_item_gap(self):
return self.item_gap
def get_current_item(self):
return self.menuItems[self.selected]
class ListItem (clutter.Label):
zoomLevel = 0.5
opacityStep = 120
def __init__ (self, menu, itemLabel, y, imagePath):
clutter.Label.__init__ (self)
self.itemTexturesGroup = clutter.Group()
font = menu.getMenuMgr().get_skinMgr().get_menu_font()
self.set_font_name(font)
self.set_text(itemLabel)
self.color = clutter.Color(0xff, 0xff, 0xff, 0xdd)
self.set_color(self.color)
self.currentOpacity = 255
self.menu = menu
#Text is actually scaled down in 'regular' position so that it doesn't get jaggies when zoomed in
self.set_scale(self.zoomLevel, self.zoomLevel)
self.currentZoom = self.zoomLevel
#(label_width, label_height) = self.label.get_size()
label_x = 0 #x #self.stage.get_width() - label_width - 50
label_y = y #self.stage.get_height() - label_height
self.set_position(0, y)
self.addImage(imagePath, True)
#Add textures group and hide it
self.menu.getMenuGroup().add(self.itemTexturesGroup)
self.itemTexturesGroup.hide_all()
def scaleLabel(self, level, timeline):
self.timeline = timeline
self.timeline.set_loop(False)
#Determine the zooming level
zoomTo=0
opacityTo = 255
if level==0:
zoomTo = 1 #self.zoomLevel * 1.5
opacityTo = 255
self.itemTexturesGroup.show_all()
if level==1:
zoomTo = self.zoomLevel * 1.2
opacityTo = 255 - self.opacityStep
self.itemTexturesGroup.hide_all()
if level==2:
zoomTo = self.zoomLevel
opacityTo = 255 - 2*self.opacityStep
self.itemTexturesGroup.hide_all()
alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
self.behaviour1 = clutter.BehaviourScale(alpha, self.currentZoom, zoomTo, clutter.GRAVITY_WEST)
self.behaviour2 = clutter.BehaviourOpacity(alpha, self.currentOpacity, opacityTo)
self.behaviour1.apply(self)
self.behaviour2.apply(self)
self.currentZoom = zoomTo
self.currentOpacity = opacityTo
return self.timeline
def get_zoom_level(self):
return self.zoomLevel
def addImage(self, path, useReflection):
self.tempTexture = clutter.Texture()
pixbuf = gtk.gdk.pixbuf_new_from_file(path)
self.tempTexture.set_pixbuf(pixbuf)
(abs_x, abs_y) = self.get_abs_position()
print abs_x
x = abs_x# - self.tempTexture.get_width()
y = (self.menu.getStage().get_height()/2) - (self.tempTexture.get_height()/2)
self.tempTexture.set_position(x, y)
self.tempTexture.rotate_y(45,0,0)
self.itemTexturesGroup.add(self.tempTexture)
self.tempTexture.hide_all()
#Scale the image down by half
#self.tempTexture.set_width(self.tempTexture.get_width()/2)
#self.tempTexture.set_height(self.tempTexture.get_height()/2)
if useReflection:
self.reflectionTexture = Texture_Reflection(self.tempTexture)
#self.reflectionTexture.set_position(0, 0)#self.tempTexture.get_height())
self.itemTexturesGroup.add(self.reflectionTexture)
self.itemTexturesGroup.hide_all()
def setAction(self, newAction):
self.action = newAction
def getAction(self):
return self.action
def get_menu(self):
return self.menu

BIN
Menu.pyc Normal file

Binary file not shown.

203
MenuMgr.py Normal file
View File

@ -0,0 +1,203 @@
import clutter
from SkinMgr import SkinMgr
from Spinner import Spinner
import pygtk
import gtk
class MenuMgr():
def __init__ (self, stage):
self.stage = stage
self.menus = []
self.currentMenu = None
self.skinMgr = SkinMgr(self.stage)
background = self.skinMgr.get_Background()
self.stage.add(background)
self.selector_bar = MenuSelector(self)
self.stage.add(self.selector_bar)
self.selector_bar.show_all()
self.currentPlugin = None
def addMenu(self, newMenu):
self.menus.append(newMenu)
#If this is the first menu, make it the active one
if self.currentMenu == None:
self.currentMenu = newMenu
self.currentMenu.getItemGroup().show_all()
self.currentMenu.getMenuGroup().show_all()
self.selector_bar.set_menu(self.currentMenu)
def get_selector_bar(self):
return self.selector_bar
def get_stage(self):
return self.stage
def get_skinMgr(self):
return self.skinMgr
def transition_fade_zoom(self, fromMenu, toMenu):
oldGroup = fromMenu.getItemGroup()
oldMenuGroup = fromMenu.getMenuGroup()
newGroup = toMenu.getItemGroup()
newMenuGroup = toMenu.getMenuGroup()
oldGroup.set_opacity(255)
self.timeline = clutter.Timeline(25, 50)
self.alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
#self.exit_behaviour_scale = clutter.BehaviourScale(self.alpha, 1, 0.5, clutter.GRAVITY_CENTER)
self.exit_behaviour_opacity = clutter.BehaviourOpacity(self.alpha, 150, 0)
#Setup some knots
knots_exiting = (\
(oldGroup.get_x(), oldGroup.get_y()),\
#(-oldGroup.get_x(), int(fromMenu.getStage().get_height()/2))
(-oldGroup.get_x(), oldGroup.get_y())\
)
self.exit_behaviour_path = clutter.BehaviourPath(self.alpha, knots_exiting)
#self.exit_behaviour_scale.apply(oldGroup)
self.exit_behaviour_opacity.apply(oldGroup)
self.exit_behaviour_opacity.apply(oldMenuGroup)
self.exit_behaviour_path.apply(oldGroup)
##################################################################
#Start incoming menu
#self.exit_behaviour_scale = clutter.BehaviourScale(self.alpha, 1, 0.5, clutter.GRAVITY_CENTER)
self.entrance_behaviour_opacity = clutter.BehaviourOpacity(self.alpha, 0, 255)
#Setup some knots
start_y = int(self.stage.get_height()/2 - newGroup.get_height()/2)
start_x = int(self.stage.get_width())
newGroup.set_position(start_x, start_y)
#end_x = int(self.stage.get_width() - newGroup.get_width())/2
(end_x, end_y) = toMenu.get_display_position()
end_x = oldGroup.get_x() #int(end_x)
end_y = oldGroup.get_y() #int(end_y)
knots_entering = (\
(newGroup.get_x(), newGroup.get_y()),\
#(-oldGroup.get_x(), int(fromMenu.getStage().get_height()/2))
(end_x, end_y) \
#toMenu.get_display_position()
)
self.entrance_behaviour_path = clutter.BehaviourPath(self.alpha, knots_entering)
self.entrance_behaviour_opacity.apply(newGroup)
self.entrance_behaviour_opacity.apply(newMenuGroup)
self.entrance_behaviour_path.apply(newGroup)
newGroup.show_all()
newMenuGroup.show_all()
#Finally, move the selector bar
self.selector_bar.selectItem(fromMenu.getItem(0), self.timeline)
#(to_x, to_y) = toMenu.get_display_position() #fromMenu.getItem(0).get_abs_position()
#self.selector_bar.move_to(int(to_x), int(to_y), self.timeline)
toMenu.selectFirst(False)
#self.timeline.connect('completed', self.on_transition_complete)
self.timeline.start()
self.currentMenu = toMenu
def on_key_press_event (self, stage, event):
#Firstly checking whether we are in the process of running a plugin (And that the key isn't escape)
if (not self.currentPlugin == None) and (not event.keyval == clutter.keysyms.Escape):
#If it is, simply pass the event details along to the plugin
self.currentPlugin.on_key_press_event(stage, event)
return None
#print event.hardware_keycode
if event.keyval == clutter.keysyms.Up: #Up button pressed
self.currentMenu.selectPrevious()
if event.keyval == clutter.keysyms.Down: #Down button pressed
self.currentMenu.selectNext()
if event.keyval == clutter.keysyms.q:
clutter.main_quit()
if event.hardware_keycode == 36: #return button pressed
#self.aList.set_processing(True)
action = self.currentMenu.get_current_item().getAction()
if action.__class__.__name__ == "Menu": # Check whether we're a pointing to a menu object
self.transition_fade_zoom(self.currentMenu, action)
else:
#We have a plugin and need to start it
self.currentPlugin = action
action.begin(self)
if event.keyval == clutter.keysyms.p:
self.mySlideshow.startShow(self.stage)
if event.keyval == clutter.keysyms.Escape:
if not self.currentPlugin == None:
self.currentPlugin.stop()
self.currentPlugin = None
#print event.hardware_keycode
def get_current_menu(self):
return self.currentMenu
class MenuSelector(clutter.Texture):
x_offset = -50
def __init__ (self, menuMgr):
clutter.Texture.__init__ (self)
self.menuMgr = menuMgr
pixbuf = gtk.gdk.pixbuf_new_from_file("ui/active_bar.png")
self.set_pixbuf(pixbuf)
self.set_width(400)
pixbuf = gtk.gdk.pixbuf_new_from_file("ui/spinner1.gif")
self.spinner = clutter.Texture()
self.spinner.set_pixbuf(pixbuf)
self.spinner.hide()
def selectItem(self, selectee, timeline):
(x, y) = selectee.get_abs_position()
group_x = selectee.get_menu().getItemGroup().get_x()
group_y = selectee.get_menu().getItemGroup().get_y()
x = x + self.x_offset
self.timeline = timeline
#Check if we're going up or down
if y > self.get_y():
#Going down
y = int(y - selectee.get_menu().get_item_gap()/2)
else:
#Going up
y = int(y - selectee.get_menu().get_item_gap()/2)
self.move_to(x, y, self.timeline)
def move_to(self, x, y, timeline):
self.timeline = timeline
knots = (\
(self.get_x(), self.get_y()),\
(x, y)\
)
self.alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
self.behaviour = clutter.BehaviourPath(self.alpha, knots)
self.behaviour.apply(self)
def set_menu(self, menu):
self.menu = menu
def set_spinner(self, state):
if state:
self.spinner = Spinner()
self.spinner.show()
self.menuMgr.get_stage().add(self.spinner)
else:
self.menuMgr.get_stage().remove(self.spinner)
self.spinner = None
def get_x_offset(self):
return self.x_offset

BIN
MenuMgr.pyc Normal file

Binary file not shown.

85
MusicPlayer.py Normal file
View File

@ -0,0 +1,85 @@
import pygtk
import gtk
import clutter
import eyeD3
class MusicPlayer():
def __init__(self, stage):
self.stage = stage
self.cover_viewer = coverViewer(self.stage)
self.is_playing = False
def on_key_press_event (self, stage, event):
if event.keyval == clutter.keysyms.p:
if self.paused:
self.unpause()
else:
self.pause()
if event.keyval == clutter.keysyms.q:
clutter.main_quit()
def begin(self, MenuMgr):
#Create a backdrop for the player. In this case we just use the same background as the menus
self.backdrop = clutter.CloneTexture(MenuMgr.get_skinMgr().get_Background())
self.backdrop.set_size(self.stage.get_width(), self.stage.get_height())
self.backdrop.set_opacity(0)
self.backdrop.show()
self.stage.add(self.backdrop)
#Fade the backdrop in
timeline_backdrop = clutter.Timeline(10,40)
alpha = clutter.Alpha(timeline_backdrop, clutter.ramp_inc_func)
backdrop_behaviour = clutter.BehaviourOpacity(alpha, 0, 255)
backdrop_behaviour.apply(self.backdrop)
timeline_backdrop.start()
def stop(self):
pass
def pause(self):
pass
def unpause(self):
pass
class coverViewer(clutter.Group):
def __init__(self, stage):
clutter.Group.__init__(self)
self.stage = stage
self.covers = []
self.num_covers = 0
self.cover_size = 50 #A cover will be cover_size * cover_size (X * Y)
self.cover_gap = 10
self.num_rows = 2
self.num_columns = int(self.stage.get_width() / self.cover_size)
def add_image(self, imagePath):
tempTexture = clutter.Texture()
pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath)
tempTexture.set_pixbuf(pixbuf)
xy_ratio = tempTexture.get_width() / tempTexture.get_height()
height = int(self.cover_size * xy_ratio)
tempTexture.set_width(self.cover_size)
tempTexture.set_height(height)
self.add(tempTexture)
self.num_covers = self.num_covers +1
#Redo positioning on all textures to add new one :(
"""for i = 0 to self.num_covers:
tempTexture = self.get_nth_child(i)
x = (self.cover_gap + self.cover_size) * i
y = (i % self.num_rows) * self.cover_size
tempTexture.set_position(x, y)"""

BIN
MusicPlayer.pyc Normal file

Binary file not shown.

10
Page.py Normal file
View File

@ -0,0 +1,10 @@
import clutter
"""
A Page is like a menu, but without the menu and 'things' placed everywhere
instead of menu items
"""
class Page():
def __init__():
pass

0
Plugin.py Normal file
View File

29
ReflectionTexture.py Normal file
View File

@ -0,0 +1,29 @@
import clutter
class Texture_Reflection (clutter.Texture):
def __init__(self, origTexture):
clutter.Texture.__init__(self)
self.set_pixbuf(origTexture.get_pixbuf())
self.set_width(origTexture.get_width())
self.set_height(origTexture.get_height())
#Rotate the reflection based on any rotations to the master
ang_y = origTexture.get_ryang()
self.rotate_y(ang_y,0,0)
ang_x = origTexture.get_rxang()
self.rotate_x(ang_x,0,0)
ang_z = origTexture.get_rzang()
self.rotate_z(ang_z,0,0)
#Get the location for it
(x, y) = origTexture.get_abs_position()
#self.set_clip(0,self.get_height()/2,self.get_width(), (self.get_height()/2))
#Flip it upside down
self.rotate_x(180,origTexture.get_height(),0)
self.set_opacity(50)
self.set_position(x, y)

BIN
ReflectionTexture.pyc Normal file

Binary file not shown.

19
SkinMgr.py Normal file
View File

@ -0,0 +1,19 @@
import clutter
import pygtk
import gtk
class SkinMgr:
def __init__ (self, mainStage):
self.stage = mainStage
def get_Background(self):
pixbuf = gtk.gdk.pixbuf_new_from_file("ui/background.png")
self.background = clutter.Texture()
self.background.set_pixbuf(pixbuf)
self.background.set_size(self.stage.get_width(), self.stage.get_height())
self.background.show()
return self.background
def get_menu_font(self):
return 'Tahoma 40'

BIN
SkinMgr.pyc Normal file

Binary file not shown.

330
Slideshow.py Normal file
View File

@ -0,0 +1,330 @@
import clutter
from clutter import cluttergst
from Menu import Menu
import time
import os.path
import pygtk
import gtk
import random
import thread
class Slideshow:
image_file_types = ["jpg", "gif", "jpeg", "png", "bmp"]
sound_file_types = ["mp3", "wav", "ogg"] #possibly more supported by default?
imageDuration = 5 # In seconds
effect_FPS = 50
def __init__(self, MenuMgr, basedir):
self.image_texture_group = clutter.Group()
self.baseDir = basedir
self.MenuMgr = MenuMgr
self.currentTexture = clutter.Texture()
self.currentSong = None
self.paused = False
self.textures = []
self.music = []
self.overlay = clutter.Rectangle()
self.backdrop = None
def on_key_press_event (self, stage, event):
#print event.hardware_keycode
if event.keyval == clutter.keysyms.p:
if self.paused:
self.unpause()
else:
self.pause()
if event.keyval == clutter.keysyms.q:
clutter.main_quit()
def loadDir(self, dirPath, recurse):
if not os.path.isdir(dirPath):
print "ERROR: Invalid path"
return None
new_file_list = os.listdir(dirPath)
#If recursive sub-dirs is on, loop through any directories
if recurse:
for fs_object in new_file_list:
path = dirPath + "/" + fs_object
if os.path.isdir(path):
self.loadDir(path, True)
new_image_list = filter(self.filterImageFile, new_file_list)
new_sound_list = filter(self.filterSoundFile, new_file_list)
#Load pictures into textures array
i = len(self.textures)
for pic in new_image_list:
self.textures.append(clutter.Texture())
imgName = dirPath + "/" + pic
#print imgName
pixbuf = gtk.gdk.pixbuf_new_from_file(imgName)
self.textures[i].set_pixbuf(pixbuf)
self.textures[i].set_position(0,0)
self.image_texture_group.add(self.textures[i])
i = i+1
#Load sound into music array
i = len(self.music)
for sound in new_sound_list:
self.music.append(cluttergst.Audio())
sndName = dirPath + "/" + sound
self.music[i].set_filename(sndName)
i = i+1
#This makes sure we only take in image files
def filterImageFile(self, fileName):
extension = fileName[-3:] #Get 3 letter extension
if extension in self.image_file_types:
return True
else:
return False
#This makes sure we only take in sound files
def filterSoundFile(self, fileName):
extension = fileName[-3:] #Get 3 letter extension
if extension in self.sound_file_types:
return True
else:
return False
def begin(self, MenuMgr):
self.stage = self.MenuMgr.get_stage()
self.MenuMgr.get_selector_bar().set_spinner(True)
self.stage.queue_redraw()
slideName = self.baseDir + "/" + self.MenuMgr.get_current_menu().get_current_item().get_text()
self.loadDir(slideName, True)
self.MenuMgr.get_selector_bar().set_spinner(False)
if self.backdrop == None:
#Create a rectangle that serves as the backdrop for the slideshow
self.backdrop = clutter.Rectangle()
self.backdrop.set_color(clutter.color_parse('Black'))
self.backdrop.set_width(self.stage.get_width())
self.backdrop.set_height(self.stage.get_height())
self.stage.add(self.backdrop)
#Fade the backdrop in
self.image_texture_group.set_opacity(255)
self.backdrop.set_opacity(0)
self.backdrop.show()
timeline_backdrop = clutter.Timeline(10,30)
alpha = clutter.Alpha(timeline_backdrop, clutter.ramp_inc_func)
backdrop_behaviour = clutter.BehaviourOpacity(alpha, 0, 255)
backdrop_behaviour.apply(self.backdrop)
timeline_backdrop.start()
self.stage.add(self.image_texture_group)
#print "No of children: " + str(self.image_texture_group.get_n_children())
#Get a random texture
self.rand1 = random.randint(0, self.image_texture_group.get_n_children()-1)
self.currentTexture = self.textures[self.rand1]
#Make sure its visible
self.currentTexture.set_opacity(255)
#Get a random song (if there's songs available)
if not len(self.music) == 0:
self.rand1 = random.randint(0, len(self.music)-1)
self.currentSong = self.music[self.rand1]
self.playNextSong(None)
#Housekeeping
self.image_texture_group.hide_all()
self.nextTexture = None
self.nextSong = None
#Begin the show
self.currentTexture.show()
self.image_texture_group.show()
self.nextImage(self.currentTexture)
def end(self):
pass
def nextImage(self, currentTexture):
#Setup stuff for KEN BURNS EFFECT!!
self.timeline_main = clutter.Timeline((self.effect_FPS * self.imageDuration), self.effect_FPS)
self.timeline_main.connect('completed', self.image_timeline_end_event)
self.alpha = clutter.Alpha(self.timeline_main, clutter.ramp_inc_func)
#Decide on the next texture to use
self.nextTexture = None
while (self.nextTexture == None):
self.rand1 = random.randint(0, len(self.textures)-1 )
self.nextTexture = self.image_texture_group.get_nth_child(self.rand1)
#Make sure we don't show the same photo twice
if (self.nextTexture == self.currentTexture) and (len(self.textures) > 1):
self.nextTexture = None
#Make sure its not visible initially (Prevents a nasty flicker the first time a photo is shown)
self.nextTexture.set_opacity(0)
#Zooming stuff
rand_zoom = random.uniform(1,1.3) # Zoom somewhere between 1 and 1.3 times
self.behaviour1 = clutter.BehaviourScale(self.alpha, 1, rand_zoom, clutter.GRAVITY_CENTER)
#panning stuff
x_pos = self.currentTexture.get_x() + random.randint(-100, 100)
y_pos = self.currentTexture.get_y() + random.randint(-100, 100)
self.alpha = clutter.Alpha(self.timeline_main, clutter.ramp_inc_func)
knots = (\
(self.currentTexture.get_x(), self.currentTexture.get_y()),\
(x_pos, y_pos)\
)
self.behaviour2 = clutter.BehaviourPath(self.alpha, knots)
#Start and run the Ken Burns effect
self.behaviour1.apply(self.currentTexture)
self.behaviour2.apply(self.currentTexture)
self.timeline_main.start()
def image_timeline_end_event(self, data):
#Add the timeline for the dissolve at the end
self.timeline_dissolve = clutter.Timeline(30,30)
self.alpha_dissolve = clutter.Alpha(self.timeline_dissolve, clutter.ramp_inc_func)
#Setup the dissolve to the next image
self.behaviour3 = clutter.BehaviourOpacity(self.alpha_dissolve, 255, 0)
self.behaviour4 = clutter.BehaviourOpacity(self.alpha_dissolve, 0, 255)
self.behaviour3.apply(self.currentTexture)
self.behaviour4.apply(self.nextTexture)
#Pick a random spot for the next image
x_pos = random.randint(0, abs(self.stage.get_width() - self.nextTexture.get_width()) ) #Somewhere between 0 and (stage_width-image_width)
y_pos = random.randint(0, abs(self.stage.get_height() - self.nextTexture.get_height()) )
self.nextTexture.set_position(x_pos, y_pos)
self.currentTexture = self.nextTexture
self.nextTexture.show()
self.timeline_dissolve.start()
self.nextImage(self.currentTexture)
#Begins playing a new song
def playNextSong(self, data):
self.nextSong = None
#Check first that there actually is music
if len(self.music) == 0:
return None
#Decide on the next song to play
while self.nextSong == None:
self.rand1 = random.randint(0, len(self.music)-1)
self.nextSong = self.music[self.rand1]
#Make sure we don't play the same song twice
if (self.nextSong == self.currentSong) and (len(self.music) > 1):
self.nextSong = None
self.currentSong = self.nextSong
self.currentSong.set_playing(True)
self.currentSong.connect('eos', self.playNextSong)
def pause(self):
self.paused = True
#Use the overlay to go over show
self.overlay.set_color(clutter.color_parse('Black'))
self.overlay.set_width(self.stage.get_width())
self.overlay.set_height(self.stage.get_height())
self.overlay.set_opacity(0)
self.overlay.show()
#self.overlay.raise_top()
#self.image_texture_group.lower(self.overlay)
self.stage.add(self.overlay)
#Fade the backdrop in
timeline_overlay = clutter.Timeline(10,30)
alpha = clutter.Alpha(timeline_overlay, clutter.ramp_inc_func)
overlay_behaviour = clutter.BehaviourOpacity(alpha, 0, 100)
overlay_behaviour2 = clutter.BehaviourOpacity(alpha, 255, 100) #Used on the backdrop
overlay_behaviour3 = clutter.BehaviourOpacity(alpha, 255, 0) #Used on the current texture
overlay_behaviour.apply(self.overlay)
overlay_behaviour2.apply(self.backdrop)
overlay_behaviour3.apply(self.currentTexture)
timeline_overlay.start()
#Pause the main slideshow
self.timeline_main.pause()
#Pause any music
if not self.currentSong == None:
if self.currentSong.get_playing():
self.currentSong.set_playing(False)
def unpause(self):
self.paused = False
#Fade the backdrop in
timeline_overlay = clutter.Timeline(10,30)
alpha = clutter.Alpha(timeline_overlay, clutter.ramp_inc_func)
overlay_behaviour = clutter.BehaviourOpacity(alpha, 100, 0)
overlay_behaviour2 = clutter.BehaviourOpacity(alpha, 100, 255) #Used on the backdrop
overlay_behaviour3 = clutter.BehaviourOpacity(alpha, 0, 255) #Used on the current texture
overlay_behaviour.apply(self.overlay)
overlay_behaviour2.apply(self.backdrop)
overlay_behaviour3.apply(self.currentTexture)
timeline_overlay.start()
#Resume the main slideshow
self.timeline_main.start()
#Resume any music
if not self.currentSong == None:
self.currentSong.set_playing(True)
def stop(self):
#Stop any running timelines
self.timeline_main.stop()
#Fade everything out
timeline_stop = clutter.Timeline(10,30)
alpha = clutter.Alpha(timeline_stop, clutter.ramp_inc_func)
stop_behaviour = clutter.BehaviourOpacity(alpha, 255, 0)
stop_behaviour.apply(self.image_texture_group)
stop_behaviour.apply(self.backdrop)
stop_behaviour.apply(self.overlay)
timeline_stop.connect('completed', self.destroySlideshow)
timeline_stop.start()
#Stop any music
if not self.currentSong == None:
if self.currentSong.get_playing():
self.currentSong.set_playing(False)
self.currentSong.set_position(0)
def destroySlideshow(self, data):
self.stage.remove(self.image_texture_group)
self.backdrop.hide()
#self.stage.remove(self.overlay)
self.currentTexture = None
self.nextTexture = None
self.currentSong = None
self.nexttSong = None
#The following generates a menu with an option for each of the slideshows in the base menu
def generateMenu(self):
tempMenu = Menu(self.MenuMgr)
print self.baseDir
file_list = os.listdir(self.baseDir)
for directoryEntry in file_list:
subdir = self.baseDir + "/" + directoryEntry
if os.path.isdir(subdir):
imgPath = subdir + "/" + os.listdir(subdir)[0]
print imgPath
tempItem = tempMenu.addItem(directoryEntry, "/home/josh/.mythtv/MythVideo/0088763.jpg")
tempItem.setAction(self)
return tempMenu

BIN
Slideshow.pyc Normal file

Binary file not shown.

20
Spinner.py Normal file
View File

@ -0,0 +1,20 @@
import clutter
import gtk
class Spinner (clutter.Texture):
def __init__(self):
clutter.Texture.__init__ (self)
#self.texture = clutter.Texture()
pixbuf = gtk.gdk.pixbuf_new_from_file("ui/spinner.svg")
self.set_pixbuf(pixbuf)
timeline = clutter.Timeline(40,20)
timeline.set_loop(True)
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
spin_behaviour = clutter.BehaviourRotate(alpha, clutter.Z_AXIS, clutter.ROTATE_CW, 0, 359)
spin_behaviour.set_center(self.get_width()/2,self.get_height()/2, 0)
spin_behaviour.apply(self)
timeline.start()

BIN
Spinner.pyc Normal file

Binary file not shown.

46
TVPlayer.py Normal file
View File

@ -0,0 +1,46 @@
from clutter import cluttergst
from myth.MythMySQL import mythVideoDB
from myth.MythBackendConn import MythBackendConnection
class TVPlayer:
def __init__(self, stage):
self.video = cluttergst.VideoTexture()
self.stage = stage
#audio.set_filename('cast1.avi')
#audio.show()
#test = cluttercairo.Cairo()
#audio = cluttergst.Audio()
#audio.set_filename('test.mp3')
#stage.add(audio)
#audio.set_playing(True)
#self.db_conn = mythVideoDB()
def begin(self, menuMgr):
self.myConn = MythBackendConnection(self)
self.myConn.start()
#self.begin_playback()
def begin_playback(self, fd):
#self.video.set_filename("test.mpg")
print "File Descriptor: " + str(fd)
self.video.set_uri("fd://"+str(fd))
self.video.show()
self.stage.add(self.video)
self.video.set_playing(True)
def on_key_press_event (self, stage, event):
#print event.hardware_keycode
pass
"""if event.keyval == clutter.keysyms.p:
if self.paused:
self.unpause()
else:
self.pause()
if event.keyval == clutter.keysyms.q:
clutter.main_quit()"""

BIN
TVPlayer.pyc Normal file

Binary file not shown.

139
VideoPlayer.py Normal file
View File

@ -0,0 +1,139 @@
import pygtk
import gtk
import clutter
from myth.MythMySQL import mythVideoDB
class VideoPlayer():
def __init__(self, stage):
self.stage = stage
self.cover_viewer = coverViewer(self.stage)
self.videoLibrary = []
self.is_playing = False
#This block can be moved to begin() but causes a performance hit when loading the module *shrug*
dbMgr = mythVideoDB()
results = dbMgr.get_videos()
for record in results:
tempVideo = videoItem()
tempVideo.importFromMythObject(record)
self.videoLibrary.append(tempVideo)
self.cover_viewer.add_image(tempVideo.getCoverfile())
################################################################################
def on_key_press_event (self, stage, event):
if event.keyval == clutter.keysyms.p:
if self.paused:
self.unpause()
else:
self.pause()
if event.keyval == clutter.keysyms.q:
clutter.main_quit()
def begin(self, MenuMgr):
#Create a backdrop for the player. In this case we just use the same background as the menus
self.backdrop = clutter.CloneTexture(MenuMgr.get_skinMgr().get_Background())
self.backdrop.set_size(self.stage.get_width(), self.stage.get_height())
self.backdrop.set_opacity(0)
self.backdrop.show()
self.stage.add(self.backdrop)
#Fade the backdrop in
timeline_begin = clutter.Timeline(10,40)
alpha = clutter.Alpha(timeline_begin, clutter.ramp_inc_func)
begin_behaviour = clutter.BehaviourOpacity(alpha, 0, 255)
begin_behaviour.apply(self.backdrop)
self.cover_viewer.set_opacity(0)
self.cover_viewer.show_all()
self.cover_viewer.show()
self.stage.add(self.cover_viewer)
begin_behaviour.apply(self.cover_viewer)
timeline_begin.start()
def stop(self):
pass
def pause(self):
pass
def unpause(self):
pass
class videoItem():
def __init(self):
self.mythID = None
def importFromMythObject(self, mythObject):
self.mythID = mythObject[0]
self.title = mythObject[1]
self.director = mythObject[2]
self.plot = mythObject[3]
self.rating = mythObject[4]
self.inetRef = mythObject[5]
self.year = mythObject[6]
self.userRating = mythObject[7]
self.length = mythObject[8]
self.showLevel = mythObject[9]
self.filename = mythObject[10]
self.coverfile = mythObject[11]
self.childID = mythObject[12]
self.browse = mythObject[13]
self.playCommand = mythObject[14]
self.category = mythObject[15]
def getTitle(self):
return self.title
def getCoverfile(self):
return self.coverfile
class coverViewer(clutter.Group):
def __init__(self, stage):
clutter.Group.__init__(self)
self.stage = stage
self.covers = []
self.num_covers = 0
self.cover_size = 200 #A cover will be cover_size * cover_size (X * Y)
self.cover_gap = 10
self.num_rows = 2
self.num_columns = int(self.stage.get_width() / self.cover_size)
def add_image(self, imagePath):
tempTexture = clutter.Texture()
pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath)
tempTexture.set_pixbuf(pixbuf)
xy_ratio = float(tempTexture.get_width()) / tempTexture.get_height()
width = int(self.cover_size * xy_ratio)
tempTexture.set_width(width)
tempTexture.set_height(self.cover_size)
tempTexture.set_position( (self.num_covers * self.cover_size), 0)
x = (self.cover_gap + self.cover_size) * (self.num_covers/self.num_rows)
y = (self.num_covers % self.num_rows) * self.cover_size + ( (self.num_covers % self.num_rows) * self.cover_gap)
tempTexture.set_position(x, y)
self.add(tempTexture)
self.num_covers = self.num_covers +1
#Redo positioning on all textures to add new one :(
"""for i in range(self.num_covers):
tempTexture = self.get_nth_child(i)
x = (self.cover_gap + self.cover_size) * i
y = (i % self.num_rows) * self.cover_size
tempTexture.set_position(x, y)"""

BIN
VideoPlayer.pyc Normal file

Binary file not shown.

0
__init__.py Normal file
View File

BIN
cast1.avi Normal file

Binary file not shown.

97
gloss.py Normal file
View File

@ -0,0 +1,97 @@
import sys
import clutter
#import gobject
import pygtk
import gtk
from Menu import Menu
from MenuMgr import MenuMgr
from Slideshow import Slideshow
from VideoPlayer import VideoPlayer
from MusicPlayer import MusicPlayer
from TVPlayer import TVPlayer
class MainApp:
def __init__ (self):
gtk.gdk.threads_init()
self.stage = clutter.stage_get_default()
self.stage.set_color(clutter.color_parse('Black'))
#self.stage.set_size(800, 600)
self.stage.set_property("fullscreen", True)
self.stage.connect('button-press-event', self.on_button_press_event)
self.stage.show_all()
#color = clutter.Color(0xff, 0xcc, 0xcc, 0xdd)
color = clutter.Color(0, 0, 0, 0)
self.menuMgr = MenuMgr(self.stage)
self.stage.connect('key-press-event', self.menuMgr.on_key_press_event)
menu1 = Menu(self.menuMgr)
menu1.addItem("TV", "ui/dvd.png")
menu1.addItem("Slideshow", "ui/gallery.png")
menu1.addItem("Videos", "ui/videos.png")
menu1.addItem("Link", "ui/link.png")
menu1.addItem("nothing", "ui/music.png")
menu1.addItem("nothing", "ui/dvd.png")
menu1.addItem("nothing", "ui/dvd.png")
menu1.addItem("nothing", "ui/dvd.png")
#menu1.setListFont('Tahoma 42')
menu1.setMenuPositionByName("center")
self.menu1 = menu1
self.menu1.selectFirst(True)
self.menu1.getItemGroup().show_all()
self.menu2 = Menu(self.menuMgr)
self.menu2.addItem("Nothing", "ui/dvd.png")
self.menu2.addItem("Link", "ui/gallery.png")
self.menu2.addItem("blah3", "ui/game.png")
self.menu2.addItem("blah4", "ui/music.png")
self.menu2.addItem("blah", "ui/dvd.png")
self.menu2.addItem("blah2", "ui/dvd.png")
self.menu2.addItem("blah3", "ui/dvd.png")
self.menu2.addItem("blah4", "ui/dvd.png")
#self.menu2.setListFont('Tahoma 42')
self.menu2.setMenuPositionByName("center")
self.mySlideshow = Slideshow(self.menuMgr, "/mythdata/pics")
#self.mySlideshow.loadDir("images/", True)
self.vidPlayer = VideoPlayer(self.stage)
self.tvPlayer = TVPlayer(self.stage)
self.musicPlayer = MusicPlayer(self.stage)
menu1.getItem(0).setAction(self.tvPlayer)
#menu1.getItem(1).setAction(self.mySlideshow)
menu1.getItem(1).setAction(self.mySlideshow.generateMenu())
menu1.getItem(2).setAction(self.vidPlayer)
menu1.getItem(3).setAction(self.menu2)
self.menu2.getItem(1).setAction(self.menu1)
def on_button_press_event (self, stage, event):
print "mouse button %d pressed at (%d, %d)" % \
(event.button, event.x, event.y)
if event.button == 1:
pass
def run (self):
self.stage.show()
#self.timeline.start()
clutter.main()
def main (args):
app = MainApp()
app.run()
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

BIN
images/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
images/tmp/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

BIN
images/tmp/Thumbs.db Normal file

Binary file not shown.

BIN
media_pics/0088763.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
media_pics/0096874.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
media_pics/0099088.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
media_pics/0102926.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
media_pics/0120601.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
media_pics/0120663.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
media_pics/0120889.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
media_pics/0124819.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
media_pics/0133093.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
media_pics/0147800.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
media_pics/0151804.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
media_pics/0167260.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
media_pics/0175880.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
media_pics/0221073.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
media_pics/0234215.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
media_pics/0242653.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
media_pics/0295297.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
media_pics/0304415.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
media_pics/0305999.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
media_pics/0310793.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
media_pics/0317198.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
media_pics/0330373.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
media_pics/0332280.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
media_pics/0343737.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
media_pics/0356150.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
media_pics/0361596.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
media_pics/0365748.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
media_pics/0366548.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
media_pics/0366551.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
media_pics/0367959.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
media_pics/0376541.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
media_pics/0381061.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
media_pics/0383574.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
media_pics/0388795.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
media_pics/0397535.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
media_pics/0401747.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
media_pics/0405296.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

BIN
media_pics/0410297.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
media_pics/0412080.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
media_pics/0413573.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
media_pics/0416449.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
media_pics/0424345.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
media_pics/0434409.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
media_pics/0436697.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
media_pics/0443453.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
media_pics/0449059.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
media_pics/0453467.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
media_pics/0457939.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
media_pics/0462538.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
media_pics/0483726.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
media_pics/0758766.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

24
myPyToy.pida Normal file
View File

@ -0,0 +1,24 @@
#python
[execution]
# project_file_to_execute
# The python file to run for this project
# default value =
project_file_to_execute = myPyToy.py
# use_python_to_execute
# None
# default value = True
use_python_to_execute = True
[general]
# python_binary_location
# The location of the python binary
# default value = /usr/bin/python
python_binary_location = /usr/bin/python
# source_directory
# The directory containing source code.
# default value = /home/josh
source_directory = /home/josh/clutter/toys/myPyToy

192
myth/MythBackendConn.py Normal file
View File

@ -0,0 +1,192 @@
import socket
import time
import threading
class MythBackendConnection(threading.Thread):
def __init__(self, videoPlayer):
self.protocolVersion = 31
self.localhost_name = "myhost" # Change this later
self.server = "192.168.0.8"
self.server_port = 6543
self.videoPlayer = videoPlayer
#2 Sockets, 1 for cmds, 1 for data
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.data_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#self.sock.connect( ("192.168.0.8", 6543) )
self.connected = False
self.recorder = None # Mythtv recorder
self.connect(self.server, self.server_port)
threading.Thread.__init__(self)
#def start(self):
# threading.Thread.start(self)
def run(self):
print "Starting thread"
self.setup_recorder()
self.spawn_live()
#self.disconnect()
def receive_reply(self, sock):
ret = ""
tmp = sock.recv(8)
count = int(tmp)
#debug("REPLY LEN: %d" % count)
ret = sock.recv(count)
#print "read<--" + ret
return ret
def send_cmd(self, sock, base_cmd):
cmd = str(len(base_cmd)).ljust(8) + base_cmd
sock.send(cmd)
#print "write-->" + cmd
def connect(self, host, port):
self.sock.connect((host, port))
#Do the protocol version check
protString = "MYTH_PROTO_VERSION "+ str(self.protocolVersion)
self.send_cmd(self.sock, protString)
protRecvString = "ACCEPT[]:[]" + str(self.protocolVersion)
result = self.receive_reply(self.sock)
print result
if not result == protRecvString:
#Protocol Version check failed
raise RuntimeError, "Myth Protocol version failure. Aborting."
#Perform the mandatory ANN
ANNstring = "ANN Playback " + self.localhost_name + " 0"
self.send_cmd(self.sock, ANNstring)
ANN_recv_string = "OK" #What a successful return should be
result = self.receive_reply(self.sock)
if not result == ANN_recv_string:
raise RuntimeError, "Myth: ANN connection failed"
#All looks good
self.connected = True
def disconnect(self):
self.sock.close()
def setup_recorder(self):
if not self.connected:
print "Cannot get recorder, no server connection exists"
return None
recorder_request_string = "GET_NEXT_FREE_RECORDER[]:[]-1"
self.send_cmd(self.sock, recorder_request_string)
result = self.receive_reply(self.sock)
result_list = result.rsplit("[]:[]")
if not result_list[0] == -1:
#Then everything worked fine
self.recorder = result_list[0]
else:
print "Myth: No recorders available"
def spawn_live(self):
if self.recorder == None:
print "Myth: Cannot spawn live tv, no recorder available"
chainID = "live-" + self.localhost_name + "-2007-08-03T21:54:21"#+str(time.clock())
spawn_string = "QUERY_RECORDER "+str(self.recorder)+"[]:[]SPAWN_LIVETV[]:[]"+chainID +"[]:[]0"
self.send_cmd(self.sock, spawn_string)
spawn_receive_string = "ok"
result = self.receive_reply(self.sock)
if not result == spawn_receive_string:
print "Myth: failed to spawn live tv. Result: "+str(result)
#Check the recording
check_string = "QUERY_RECORDER "+str(self.recorder)+"[]:[]IS_RECORDING"
self.send_cmd(self.sock, check_string)
is_recording = self.receive_reply(self.sock)
if not is_recording == str(1):
#Just send the check again
self.send_cmd(self.sock, check_string)
#Create a new data socket
self.data_sock.connect( (self.server, self.server_port) )
protString = "MYTH_PROTO_VERSION "+ str(self.protocolVersion)
self.send_cmd(self.data_sock, protString)
protRecvString = "ACCEPT[]:[]" + str(self.protocolVersion)
result = self.receive_reply(self.data_sock)
#This is just a hack to make sure the channel has locked, I'll fix it later
time.sleep(5)
#Get the recording filename
filename_string = "QUERY_RECORDER "+str(self.recorder)+"[]:[]GET_CURRENT_RECORDING"
self.send_cmd(self.sock, filename_string)
filedetails = self.receive_reply(self.sock)
detail_list = filedetails.rsplit("[]:[]")
filename_list = detail_list[8].rsplit("/")
filename_list.reverse()
filename = "/" + filename_list[0]
print filename
#Announce our intent to read a file
announce_cmd = "ANN FileTransfer " + self.localhost_name + "[]:[]" + filename
self.send_cmd(self.data_sock, announce_cmd)
result = self.receive_reply(self.data_sock)
result_list = result.rsplit("[]:[]")
data_socket_id = result_list[1]
print "Socket ID: " + str(data_socket_id)
#Do some housekeeping
frontend_ready_cmd = "QUERY_RECORDER "+str(self.recorder) +"[]:[]FRONTEND_READY"
self.send_cmd(self.sock, frontend_ready_cmd)
result = self.receive_reply(self.sock)
input_cmd = "QUERY_RECORDER "+ str(self.recorder) +"[]:[]GET_INPUT"
self.send_cmd(self.sock, input_cmd)
result = self.receive_reply(self.sock)
rec_list_cmd = "MESSAGE[]:[]RECORDING_LIST_CHANGE"
self.send_cmd(self.sock, rec_list_cmd)
result = self.receive_reply(self.sock)
#Start a recording thread
self.buffer_live(self.sock, self.data_sock, data_socket_id)
def buffer_live(self, cmd_sock, data_sock, socket_id):
#Create a buffer file
self.buffer_file = open("test.mpg","w")
print "grunt0"
#read some data
x=0
request_size = 32768
#Need to create a bit of a buffer so playback will begin
while x<80:
transfer_cmd = "QUERY_FILETRANSFER "+ str(socket_id) + "[]:[]REQUEST_BLOCK[]:[]"+str(request_size)
self.send_cmd(cmd_sock, transfer_cmd)
num_bytes = int(self.receive_reply(cmd_sock))
data = data_sock.recv(num_bytes)
self.buffer_file.write(data)
self.buffer_file.flush()
x=x+1
#data_sock.flush()
tempfile = data_sock.makefile("r", request_size)
tempfile.flush()
self.videoPlayer.begin_playback(tempfile.fileno())
print "BEGINNING PLAYBACK!"
while x<1000:
transfer_cmd = "QUERY_FILETRANSFER "+ str(socket_id) + "[]:[]REQUEST_BLOCK[]:[]"+str(request_size)
self.send_cmd(cmd_sock, transfer_cmd)
num_bytes = int(self.receive_reply(cmd_sock))
data_sock.recv(num_bytes)
#self.buffer_file.write(data)
#self.buffer_file.flush()
x=x+1
print "Ending playback"
self.buffer_file.close()
def end_stream(self):
self.stream = False

BIN
myth/MythBackendConn.pyc Normal file

Binary file not shown.

28
myth/MythMySQL.py Normal file
View File

@ -0,0 +1,28 @@
import MySQLdb
class mythVideoDB():
def __init__(self):
self.server = "127.0.0.1" #"192.168.0.1"
self.db = "mythconverg"
self.uid = "root"
self.passwd = ""
db = MySQLdb.connect(self.server, self.uid, self.passwd,self.db)
self.cursor = db.cursor()
#cursor.execute("SELECT * FROM videometadatagenre")
# get the resultset as a tuple
#result = cursor.fetchall()
# iterate through resultset
#for record in result:
#print record[0] , "-->", record[1]
def get_videos(self):
sql = "SELECT * FROM videometadata WHERE coverfile <> 'No Cover'"
self.cursor.execute(sql)
# get the resultset as a tuple
result = self.cursor.fetchall()
return result

BIN
myth/MythMySQL.pyc Normal file

Binary file not shown.

0
myth/__init__.py Normal file
View File

BIN
myth/__init__.pyc Normal file

Binary file not shown.

BIN
ui/active_bar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
ui/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
ui/dvd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

BIN
ui/gallery.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

BIN
ui/game.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
ui/link.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
ui/music.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

179
ui/spinner.svg Normal file
View File

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
id="svg2263"
sodipodi:version="0.32"
inkscape:version="0.45"
version="1.0"
sodipodi:docbase="/home/njp/o-hand/svn/clutter/trunk/toys/fluttr/data"
sodipodi:docname="spinner.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true">
<defs
id="defs2265">
<linearGradient
id="linearGradient3302">
<stop
style="stop-color:#dadada;stop-opacity:1;"
offset="0"
id="stop3304" />
<stop
id="stop3327"
offset="0.73949581"
style="stop-color:#d2d2d2;stop-opacity:1;" />
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0.86974788"
id="stop3333" />
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="1"
id="stop3306" />
</linearGradient>
<linearGradient
id="linearGradient3289">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3291" />
<stop
style="stop-color:#474747;stop-opacity:1;"
offset="1"
id="stop3293" />
</linearGradient>
<linearGradient
id="linearGradient3275">
<stop
id="stop3277"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop3279"
offset="1"
style="stop-color:#cfcfcf;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3133">
<stop
style="stop-color:#1f2221;stop-opacity:1;"
offset="0"
id="stop3135" />
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="1"
id="stop3137" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3133"
id="linearGradient3139"
x1="462.85715"
y1="0"
x2="462.85715"
y2="600.20575"
gradientUnits="userSpaceOnUse"
gradientTransform="scale(1,0.7333333)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3275"
id="linearGradient3273"
x1="478.57144"
y1="91.428574"
x2="478.57144"
y2="345.06439"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3133"
id="linearGradient3283"
gradientUnits="userSpaceOnUse"
x1="478.57144"
y1="91.428574"
x2="478.57144"
y2="345.06439"
gradientTransform="matrix(0.9328572,0,0,0.8971429,26.857143,22.628568)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3289"
id="linearGradient3287"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9328572,0,0,0.3085715,26.857139,78.54285)"
x1="478.57144"
y1="91.428574"
x2="478.57144"
y2="345.06439" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3302"
id="radialGradient3316"
cx="200"
cy="125"
fx="200"
fy="125"
r="50"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,-1,0,250)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3302"
id="radialGradient3331"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.662898,0.7231039,-0.7293767,0.6686485,194.30678,-79.630422)"
cx="200"
cy="125"
fx="200"
fy="125"
r="50" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#363636"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.75686275"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="152.97332"
inkscape:cy="93.594381"
inkscape:document-units="px"
inkscape:current-layer="layer4"
width="800px"
height="440px"
inkscape:window-width="910"
inkscape:window-height="624"
inkscape:window-x="4"
inkscape:window-y="47" />
<metadata
id="metadata2268">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer4"
transform="translate(-150,-75)">
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:6;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 200,77.857143 C 173.88286,77.857143 152.85714,98.882857 152.85714,125 C 152.85714,151.11714 173.88286,172.14286 200,172.14286 C 226.11714,172.14286 247.14286,151.11714 247.14286,125 C 247.14286,98.882857 226.11714,77.857143 200,77.857143 z M 192.60446,93.532143 L 192.60446,114.275 L 207.39554,114.275 L 207.39554,93.532143 C 221.71682,96.858206 232.32232,109.63693 232.32232,125 C 232.32232,142.9089 217.9089,157.32232 200,157.32232 C 182.0911,157.32233 167.67768,142.9089 167.67768,125 C 167.67768,109.63693 178.28317,96.858206 192.60446,93.532143 z "
id="rect3295" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
ui/spinner1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

BIN
ui/videos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB