Many changes. Reworked most of ocarina-core. I have also began a new

xml system for creating the gui.
This commit is contained in:
bjschuma 2010-05-16 23:21:20 -04:00
parent b200fbd696
commit 9efb3255bc
55 changed files with 1127 additions and 798 deletions

View File

@ -16,10 +16,10 @@ from ct.path import *
from ct.call import * from ct.call import *
# Helpful variables used by the application # Helpful variables used by the application
# vars["$user"] is the users home directory # vars.USER is the users home directory
# vars["$ocarina"] is the directory ocarina uses to store all its files # vars.OCARINA is the directory ocarina uses to store all its files
# vars["$lockfile"] is the lockfile used by the application # vars.LOCKFILE is the lockfile used by the application
# vars["$writeenable"] controls enables printing from ct.call.write() # vars.WRITEENABLE controls enables printing from ct.call.write()
################################################################################ ################################################################################
################################################################################ ################################################################################
@ -35,29 +35,35 @@ from ct.call import *
# Set this variable to force verbosity to always be at the same value. # Set this variable to force verbosity to always be at the same value.
# Calling ocarina with the -v option will have no effect. A higher value will # Calling ocarina with the -v option will have no effect. A higher value will
# print more output # print more output
#vars["$verbose"] = 0 #vars.VERBOSE = 0
# Setting this variable to change the prompt that is presented to the user # Setting this variable to change the prompt that is presented to the user
# by the built in command line. This variable is only used in ocarina-core # by the built in command line. This variable is only used in ocarina-core
#vars["$prompt"] = ">>>" #vars.PROMPT = ">>>"
# This variable controls if ocarina begins playback as soon as a song is loaded # This variable controls if ocarina begins playback as soon as a song is loaded
# The default value is True # The default value is True
vars["$playonload"] = False vars.PLAYONLOAD = False
# This variable controls the gstreamer volume at startup. Values must be # This variable controls the gstreamer volume at startup. Values must be
# between 0.0 and 1.0, values less than 0.0 will be changed to 0.0 and values # between 0.0 and 1.0, values less than 0.0 will be changed to 0.0 and values
# greater than 1.0 will be changed to 1.0 # greater than 1.0 will be changed to 1.0
#vars["$volume"] = 1.0 #vars.VOLUME = 1.0
# This variable controls how much the volume changes when calling # This variable controls how much the volume changes when calling
# volup() or voldown() # volup() or voldown()
#vars["$volumeincr"] = 0.05 #vars.VOLUMEINCR = 0.05
# This variable controls the port that ocarina listens on for requests. Other # This variable controls the port that ocarina listens on for requests. Other
# ocarina instances will connect to this port to forward a song to load. # ocarina instances will connect to this port to forward a song to load.
# Setting this variable to 0 will cause ocarina to use a random port. # Setting this variable to 0 will cause ocarina to use a random port.
#vars["$port"] = 12345 #vars.PORT = 12345
# These next variables are the initial text shown in the artist, album, title
# labels. They will be overwritten when a song is loaded.
#vars.ARTIST = ""
#vars.ALBUM = ""
#vars.TITLE = ""
@ -80,7 +86,7 @@ readline.parse_and_bind("tab:complete")
# Configure readline history. # Configure readline history.
# This file is written after every command entered, but you can comment out # This file is written after every command entered, but you can comment out
# these lines to ignore the file # these lines to ignore the file
history = join(ocarina.vars["$ocarina"],"history") history = join(vars.OCARINA,"history")
if exists( history ): if exists( history ):
readline.read_history_file(history) readline.read_history_file(history)
@ -104,14 +110,10 @@ readline.set_history_length(50)
# Ocarina uses an xml-based system to build up the GUI. This allows you to # Ocarina uses an xml-based system to build up the GUI. This allows you to
# create your own custom gui. # create your own custom gui.
#vars["$theme"] = "themes/simple.xml" #vars.THEME = "themes/simple.xml"
vars["$theme"] = "themes/classic.xml" #vars.THEME = "themes/classic.xml"
#vars.THEME = "themes/ocarina3.xml"
# These next variables are the initial text shown in the artist, album, title vars.THEME = "themes/simple2.xml"
# labels. They will be overwritten when a song begins playback.
#vars["$artist"] = ""
#vars["$album"] = ""
#vars["$title"] = ""
# Initial text for library / playlist / queue filtering # Initial text for library / playlist / queue filtering
#vars["$filterText"] = "" #vars.FILTERTEXT = ""

View File

@ -1,38 +0,0 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$Mar 13, 2010 9:08:56 PM$"
import ocarina
from ct.path import *
from ct.call import *
import readline
global history
history = join(ocarina.vars["$ocarina"],"history")
def loop():
while True:
try:
state = ocarina.vars["$writeenable"]
ocarina.vars["$writeenable"] = True
exec raw_input(ocarina.vars["$prompt"] + " ")
ocarina.vars["$writeenable"] = state
global history
readline.write_history_file(history)
# Catch this so that we can use ctrl-d to exit
except EOFError:
print ""
exit()
except Exception,e:
print e
#ocarina.events.invite("ocarina-start",loop)

View File

@ -1,38 +0,0 @@
#! /usr/bin/python
__author__="bjschuma"
__date__ ="$Mar 15, 2010 9:53:46 PM$"
import ocarina
import os
from ct import path
from ct import opts
from ocarina import vars
# Set the default values of ocarina variables
vars["$user"] = path.expand("~")
vars["$ocarina"] = path.join(vars["$user"],".ocarina3")
vars["$lockfile"] = path.join(vars["$ocarina"],"lock")
vars["$writeenable"] = True
vars["$verbose"] = 0
vars["$prompt"] = ">>>"
vars["$playonload"] = True
vars["$playing"] = False
vars["$volume"] = 1.0
vars["$volumeincr"] = 0.05
vars["$port"] = 0
opts.parse()
path.mkdir(vars["$ocarina"])
# Set verbose value
if opts.opts.has("v") == True:
vars["$verbose"] += opts.opts["v"]
if opts.opts.has("verbose") == True:
vars["$verbose"] += opts.opts["verbose"]
#import gstreamer

View File

@ -2,4 +2,4 @@ __author__="bjschuma"
__date__ ="$Mar 13, 2010 4:20:16 PM$" __date__ ="$Mar 13, 2010 4:20:16 PM$"
__all__ = ["call", "dict", "opts", "path", "plugin", "slist", "tcp", "times"] __all__ = ["call", "opts", "path", "tags", "tcp", "times"]

View File

@ -7,27 +7,28 @@ __author__="bjschuma"
__date__ ="$Mar 30, 2010 11:24:43 PM$" __date__ ="$Mar 30, 2010 11:24:43 PM$"
import ocarina from ocarina import events
import sys from ocarina import vars
from ct import times from ct import times
from ct import path from ct import path
def exit(): def exit():
'''Safely exit ocarina''' '''Safely exit ocarina'''
path.rm(ocarina.vars["$lockfile"]) path.rm(vars.LOCKFILE)
import gstreamer import gstreamer
ocarina.events.start("ocarina-close") import sys
events.start(events.OCARINA_QUIT)
sys.exit(0) sys.exit(0)
def about(): def about():
print "Ocarina Version 3.0" write("Ocarina Version 3.0")
print "Written by Bryan Schumaker (bjschuma@umich.edu)" write("Written by Bryan Schumaker (bjschuma@umich.edu)")
def write(s,verbose): def write(s,verbose=0):
if (ocarina.vars["$writeenable"]==True) and (ocarina.vars["$verbose"]>=verbose): if vars.VERBOSE >= verbose:
print str(s) print str(s)
@ -35,22 +36,24 @@ def load(path):
'''Load the song located at path''' '''Load the song located at path'''
import gstreamer import gstreamer
gstreamer.load(path) gstreamer.load(path)
from ct import tags
tags.get(path)
def seek(prcnt): def seek(prcnt):
''' Seek to prcnt% of the song. If 0 < prcnt < 1, then we will seek to ''' Seek to prcnt% of the song. If 0 < prcnt < 1, then we will seek to
(prcnt * 100)% of song's duration. If prcnt < 100, then we will seek (prcnt * 100)% of song's duration. If prcnt < 100, then we will seek
to prcnt% of the song's duration.''' to prcnt% of the song's duration.'''
import gstreamer from gstreamer import position
good = gstreamer.seek(prcnt) good = position.seek(prcnt)
if good == -1: if good == -1:
write("There was an error seeking to: "+str(prcnt)) write("There was an error seeking to: "+str(prcnt))
def progress(): def progress():
'''Return the fraction of the song that we have already played''' '''Return the fraction of the song that we have already played'''
import gstreamer from gstreamer import position
progress = gstreamer.getProgress() progress = position.getProgress()
write(progress) write(progress)
return progress return progress
@ -59,8 +62,8 @@ def duration():
'''Return the total duration of the song. If message printing is enabled, '''Return the total duration of the song. If message printing is enabled,
then we will also print out string representing the duration in then we will also print out string representing the duration in
hh:mm:ss form''' hh:mm:ss form'''
import gstreamer from gstreamer import position
duration = gstreamer.duration() duration = position.duration()
write(times.ms2str(duration)) write(times.ms2str(duration))
return duration return duration
@ -69,28 +72,50 @@ def time():
'''Returns how far into the song gstreamer currently is. If message printing '''Returns how far into the song gstreamer currently is. If message printing
is enabled, then we will also print out a string representing the duration in is enabled, then we will also print out a string representing the duration in
hh:mm:ss form''' hh:mm:ss form'''
import gstreamer from gstreamer import position
time = gstreamer.currentpos() time = position.currentpos()
message.write(times.ms2str(time)) write(times.ms2str(time))
return time return time
def gsstate(): def gsstate():
'''Returns the current gstreamer state''' '''Returns the current gstreamer state'''
import gstreamer from gstreamer import playback
state = gstreamer.getstate() state = playback.getstate()
message.write(state) write(state)
return state return state
def playing(disp=True):
'''Returns true if ocarina is currently playing'''
from gstreamer import playback
import gst
state = playback.getstate() == gst.STATE_PLAYING
if disp==True:
if state == True:
write("Ocarina is playing")
else:
write("Ocarina is not playing")
return state
def tags(disp=True):
'''Returns (title, artist, album) for the current track'''
if disp == True:
print vars.TITLE
print "by",vars.ARTIST
print "from",vars.ALBUM
return (vars.TITLE, vars.ARTIST, vars.ALBUM)
def play(): def play():
'''Begin playback of the loaded song''' '''Begin playback of the loaded song'''
ocarina.events.start("ocarina-play") events.start(events.OCARINA_PLAY)
def pause(): def pause():
'''Pause playback of the current song''' '''Pause playback of the current song'''
ocarina.events.start("ocarina-pause") events.start(events.OCARINA_PAUSE)
def stop(): def stop():
@ -101,14 +126,14 @@ def stop():
def volup(): def volup():
'''Increase the volume''' '''Increase the volume'''
import gstreamer from gstreamer import volume
gstreamer.volup() volume.volup()
def voldown(): def voldown():
'''Decrease the volume''' '''Decrease the volume'''
import gstreamer from gstreamer import volume
gstreamer.voldown() volume.voldown()
def pyfile(file): def pyfile(file):

View File

@ -1,17 +0,0 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$Feb 24, 2010 8:59:47 PM$"
class Dict(dict):
def __init__(self):
dict.__init__(self)
def has(self,key):
return (key in self.keys())

View File

@ -1,49 +0,0 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$Mar 14, 2010 2:58:02 PM$"
import inspect
import os
from ct.message import write
class Plugin:
def __init__(self):
self.enabled = True
self.help = dict()
self.usage = dict()
self.minarg = 0
def open(self):
pass
def close(self):
pass
def run(self,args):
return None
def start(self,args=None):
if len(args) < self.minarg:
return
try:
return self.run(args)
# Find out information about the error
except Exception,e:
trace = inspect.trace()
frame = trace[len(trace)-1]
filename = frame[1]
lineno = str(frame[2])
filename = filename.rsplit(os.sep,1)[1]
write(filename+" ("+lineno+"): "+str(e))

View File

@ -1,22 +0,0 @@
__author__="bjschuma"
__date__ ="$Feb 22, 2010 10:52:13 PM$"
# This is a sorted list (as long as items are inserted with add() )
class Slist(list):
def __init__(self):
list.__init__(self)
def add(self, item, priority):
self += [(priority,item)]
self.sort()
def remove(self, item):
for tuple in self:
if tuple[1] == item:
list.remove(self,tuple)
break

19
src/core/ct/tags.py Normal file
View File

@ -0,0 +1,19 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 12, 2010 10:34:18 AM$"
import tagpy
from ocarina import vars
def get(path):
file = tagpy.FileRef(path)
tags = file.tag()
vars.ARTIST = tags.artist
vars.ALBUM = tags.album
vars.TITLE = tags.title

View File

@ -39,3 +39,40 @@ def ms2str(ms):
# Convert ms to s # Convert ms to s
time = int(ms) / 1000000000 time = int(ms) / 1000000000
return ftime(time) return ftime(time)
def hms2sec(hms):
if hms == None:
return 0
split = hms.split(":")[::-1]
sec = int( split[0] )
if len(split) >= 2:
sec += int( split[1] ) * 60
if len(split) == 3:
sec += int( split[2] ) * 60 * 60
return sec
def sec2text(s):
def fmt(time, field):
if time <= 0:
return ""
if time > 1:
field += "s"
return str(time) + " " + field + " "
sec = s
day = sec / 86500
sec -= day*86500
hour = sec / 3600
sec -= hour*3600
min = sec / 60
sec -= min*60
st = fmt(day,"day") + fmt(hour,"hour") + fmt(min,"minute") + fmt(sec,"second")
return st

View File

@ -7,39 +7,43 @@ __author__="bjschuma"
__date__ ="$Feb 24, 2010 9:13:41 PM$" __date__ ="$Feb 24, 2010 9:13:41 PM$"
from ct.dict import Dict
from ct.slist import Slist
from ct.call import *
# Maintain the list of guests # Maintain the list of guests
class GuestList(Slist): class GuestList(list):
def __init__(self,name): def __init__(self):
Slist.__init__(self) list.__init__(self)
self.name = name
self.active = False self.active = False
def add(self, item, priority):
self += [(priority, item)]
self.sort()
class Event(Dict): class Event(dict):
def __init__(self): def __init__(self):
Dict.__init__(self) dict.__init__(self)
self.nextEvent = 0
self.create("OCARINA_START")
self.create("OCARINA_QUIT")
self.create("OCARINA_PLAY")
self.create("OCARINA_PAUSE")
def type(self,guest): def create(self,name):
return type(guest).__name__ var = "self." + name.upper()
exec var + " = " + str(self.nextEvent)
self.nextEvent += 1
exec "self["+var+"] = GuestList()"
def has(self,key):
return (key in self.keys())
# Add a "guest" (function or script) to this event # Add a "guest" (function or script) to this event
def invite(self, name, guest, priority=None): def invite(self, name, guest, priority=None):
type = self.type(guest)
if priority==None: if priority==None:
if type=='str' or type=='unicode':
priority = 200
else:
priority = 100 priority = 100
if self.has(name) == False:
self[name] = GuestList(name)
self[name].add(guest, priority) self[name].add(guest, priority)
@ -60,17 +64,13 @@ class Event(Dict):
self[name].active = True self[name].active = True
for priority,guest in self[name]: for priority,guest in self[name]:
if self[name].active == True: if self[name].active == False:
if self.type(guest)=='unicode' or self.type(guest)=='str': break
pyfile(guest) elif self[name].active == True:
elif args==None: if args==None:
guest() guest()
else: else:
guest(args) guest(args)
self.stop(name) self.stop(name)

View File

@ -1,267 +0,0 @@
#! /usr/bin/python
__author__ = "bjschuma"
__date__ = "$Feb 5, 2010 7:53:19 PM$"
from ct import path
from ct.call import write
from ct.opts import args
import gst
import ocarina
global player
global time
player = gst.element_factory_make("playbin2", "player")
time = gst.Format(gst.FORMAT_TIME)
bus = player.get_bus()
def getstate():
global player
state = player.get_state()[1]
write("Gstreamer state: "+str(state), 3)
return player.get_state()[1]
def play():
global player
player.set_state(gst.STATE_PLAYING)
if getstate() != gst.STATE_PLAYING:
ocarina.events.stop("ocarina-play")
else:
ocarina.vars["$playing"] = True
def pause():
global player
player.set_state(gst.STATE_PAUSED)
if getstate() != gst.STATE_PAUSED:
ocarina.events.stop("ocarina-pause")
else:
ocarina.vars["$playing"] = False
def load(song):
song = path.expand(song)
if path.exists(song) == False:
write("Path does not exist: " + song)
return
curstate = getstate()
pause()
write("Loading file: " + song, 1)
global player
player.set_state(gst.STATE_NULL)
player.set_property("uri", "file://" + song)
if ocarina.vars["$playonload"]==True or curstate==gst.STATE_PLAYING:
play()
else:
pause()
#player.set_state(gst.STATE_PAUSED)
def uninit():
global player
player.set_state(gst.STATE_NULL)
def onMessage(bus, message):
#print message.type
if message.type == gst.MESSAGE_TAG:
taglist = message.parse_tag()
for tag in taglist.keys():
write("Found tag: ("+tag+", "+str(taglist[tag])+")",1)
if tag == "title":
ocarina.vars["$title"] = taglist[tag]
elif tag == "artist":
ocarina.vars["$artist"]= taglist[tag]
elif tag == "album":
ocarina.vars["$album"] = taglist[tag]
ocarina.events.start("tags-changed")
def duration():
global player
global time
state = getstate()
if (state!=gst.STATE_PLAYING) and (state!=gst.STATE_PAUSED):
return 0
total = player.query_duration(time)[0]
return total
def currentpos():
global player
global time
state = getstate()
if (state!=gst.STATE_PLAYING) and (state!=gst.STATE_PAUSED):
return 0
position = player.query_position(time)[0]
return position
def getProgress():
global player
global time
state = getstate()
if (state!=gst.STATE_PLAYING) and (state!=gst.STATE_PAUSED):
return 0
total = duration()
current = currentpos()
fraction = float(current) / float(total)
if fraction < 0.0:
return 0.0
elif fraction > 1.0:
return 1.0
return fraction
# Seek to the desired percent of the song.
# Fraction is True if prcnt is already a fraction
def seek(prcnt):
global player
global time
if prcnt < 0:
prcnt = 0
elif prcnt > 100:
prcnt = 1
elif prcnt > 1:
prcnt = float(prcnt) / 100.0
newTime = duration() * prcnt
player.seek_simple(time,gst.SEEK_FLAG_FLUSH,newTime)
return 0
def setvol(volume):
global player
if volume > 1.0:
volume = 1.0
elif volume < 0.0:
volume = 0.0
player.set_property("volume",volume)
ocarina.vars["$volume"] = volume
def volup():
volume = ocarina.vars["$volume"]
volume += ocarina.vars["$volumeincr"]
setvol(volume)
def voldown():
volume = ocarina.vars["$volume"]
volume -= ocarina.vars["$volumeincr"]
setvol(volume)
bus.add_signal_watch()
bus.connect("message", onMessage)
ocarina.events.invite("ocarina-close", uninit)
ocarina.events.invite("ocarina-play", play,50)
ocarina.events.invite("ocarina-pause", pause,50)
setvol(ocarina.vars["$volume"])
#
#def setvol(value):
# global pipeline
# curvol = float( settings.get("volume") )
#
# vol = pipeline.get_by_name("vol")
# if value == "up":
# value = curvol + 0.05
# elif value == "down":
# value = curvol - 0.05
# else:
# # Prevent converting strings
# try:
# value = float(value)
# except:
# return
#
# if value > 1.0:
# value = 1.0
# if value < 0.0:
# value = 0.0
# settings.set("volume",value)
# vol.set_property("volume",value )
#
#
#def getProgress(tuple=False):
# global pipeline
# global time
#
# # Don't bother to go on if the pipeline isn't playing
# if not pipeline.get_state()[1] == gst.STATE_PLAYING:
# return -1
#
# position = pipeline.query_position(time)[0]
# total = pipeline.query_duration(time)[0]
# if tuple==False:
# return float(position) / float(total)
# else:
# return (position,total)
#
#
## Draw the progress bar on the command line
#def drawProgress():
# p = getProgress()
# if p == -1:
# return
# win = settings.get("maxyx")
# max = int(win[1] * p)
# if max > win[1]:
# max = win[1]
# if max == 0:
# cline.message.disp(" "*(win[1]-1) ,win[0]-1)
# else:
# cline.message.disp("="*max, win[0]-1)
#
#
## A callback when there are messages on the bus
#def onMessage(bus,message):
# if message.type == gst.MESSAGE_EOS:
# manager.run("next")
#
#
## Manually check the bus for messages
#def checkBus():
# global bus
# if bus.peek() == None:
# return
# onMessage(bus,bus.pop())
#
#
#
#def init():
# # Register signals
# signal.register("play",play)
# signal.register("pause",pause)
# signal.register("cliloop",drawProgress)
# signal.register("cliloop",checkBus,90)
#
# # Check for settings values
# if settings.has("args") == True:
# input = settings.get("args")
# if not input == []:
# join = ' '
# path = join.join(input)
# load(path)
# else:
# if settings.has("curtrk")==True:
# track = settings.get("curtrk")
# if track > 0:
# manager.run("next",[track,False])
# if settings.has("volume") == False:
# settings.set("volume",1.0)
# setvol(settings.get("volume"))
#
#
#def close():
# global pipeline
# global bin
# pause()
# pipeline.set_state(gst.STATE_NULL)
# bin.set_state(gst.STATE_NULL)

View File

@ -0,0 +1,50 @@
__author__="bjschuma"
__date__ ="$May 11, 2010 10:31:27 PM$"
__all__ = ["playback", "position", "volume"]
import gst
from ocarina import vars
from ocarina import events
from ct import path
from ct import call
global player
global time
player = gst.element_factory_make("playbin2", "player")
time = gst.Format(gst.FORMAT_TIME)
def load(song):
song = path.expand(song)
if path.exists(song) == False:
call.write("Path does not exist: " + song)
return
playing = call.playing(False)
if playing == True:
call.pause()
call.write("Loading file: " + song, 1)
global player
player.set_state(gst.STATE_NULL)
player.set_property("uri", "file://" + song)
if (vars.PLAYONLOAD == True) or (playing==True):
call.play()
def init():
from gstreamer import playback
from gstreamer import volume
from gstreamer import position
init()

View File

@ -0,0 +1,34 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 11, 2010 10:55:54 PM$"
import gst
from ocarina import events
from gstreamer import player
from ct import call
def getstate():
state = player.get_state()[1]
call.write("Gstreamer state: "+str(state), 3)
return player.get_state()[1]
def play():
player.set_state(gst.STATE_PLAYING)
if getstate() != gst.STATE_PLAYING:
events.stop(events.OCARINA_PLAY)
def pause():
player.set_state(gst.STATE_PAUSED)
if getstate() != gst.STATE_PAUSED:
events.stop(events.OCARINA_PAUSE)
events.invite(events.OCARINA_PLAY, play, 50)
events.invite(events.OCARINA_PAUSE, pause, 50)

View File

@ -0,0 +1,57 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 11, 2010 11:50:23 PM$"
import gst
from gstreamer import player
from gstreamer import time
from gstreamer.playback import getstate
def duration():
state = getstate()
if (state!=gst.STATE_PLAYING) and (state!=gst.STATE_PAUSED):
return 0
total = player.query_duration(time)[0]
return total
def currentpos():
state = getstate()
if (state!=gst.STATE_PLAYING) and (state!=gst.STATE_PAUSED):
return 0
position = player.query_position(time)[0]
return position
def getProgress():
state = getstate()
if (state!=gst.STATE_PLAYING) and (state!=gst.STATE_PAUSED):
return 0
total = duration()
current = currentpos()
fraction = float(current) / float(total)
if fraction < 0.0:
return 0.0
elif fraction > 1.0:
return 1.0
return fraction
# Seek to the desired percent of the song.
# Fraction is True if prcnt is already a fraction
def seek(prcnt):
if prcnt < 0:
prcnt = 0
elif prcnt > 100:
prcnt = 1
elif prcnt > 1:
prcnt = float(prcnt) / 100.0
newTime = duration() * prcnt
player.seek_simple(time,gst.SEEK_FLAG_FLUSH,newTime)
return 0

View File

@ -0,0 +1,35 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 11, 2010 10:32:12 PM$"
from gstreamer import player
from ocarina import vars
def setvol(volume):
if volume > 1.0:
volume = 1.0
elif volume < 0.0:
volume = 0.0
player.set_property("volume",volume)
vars.VOLUME = volume
def volup():
volume = vars.VOLUME
volume += vars.VOLUMEINCR
setvol(volume)
def voldown():
volume = vars.VOLUME
volume -= vars.VOLUMEINCR
setvol(volume)
setvol(vars.VOLUME)

View File

@ -3,23 +3,31 @@
__author__="bjschuma" __author__="bjschuma"
__date__ ="$Mar 13, 2010 4:19:31 PM$" __date__ ="$Mar 13, 2010 4:19:31 PM$"
import ocarina import ocarina
import coredefaults
import cli print "Welcome to Ocarina 3.0 (core)"
ocarina.config()
ocarina.events.start(ocarina.events.OCARINA_START)
from ct.call import * from ct.call import *
from ct import tcp from ct.path import *
import readline
# ocarina-core main loop
while True:
try:
exec raw_input(ocarina.vars.PROMPT + " ")
readline.write_history_file(ocarina.vars.HISTORYFILE)
def main(): # Catch this so that we can use ctrl-d to exit
# Potentially the first thing printed except EOFError:
write("Welcome to Ocarina (core)", 1) print ""
exit()
ocarina.events.start("ocarina-start") except Exception,e:
code = ocarina.config() print 1,e
if code == 0:
cli.loop()
if __name__ == "__main__":main()

View File

@ -3,36 +3,45 @@
__author__="bjschuma" __author__="bjschuma"
__date__ ="$Mar 13, 2010 4:19:39 PM$" __date__ ="$Mar 13, 2010 4:19:39 PM$"
import variables
from ct.dict import Dict
from ct import path
import event import event
global vars global vars
global events global events
vars = variables.Vars()
vars = Dict()
events = event.Event() events = event.Event()
from ct import path
from ct import opts
path.mkdir(vars.OCARINA)
opts.parse()
# Set verbose value
if opts.opts.has("v") == True:
vars.VERBOSE += opts.opts["v"]
if opts.opts.has("verbose") == True:
vars.VERBOSE += opts.opts["verbose"]
import gstreamer
def postConfig(): def postConfig():
from ct import tcp from ct import tcp
global vars global vars
lock = vars["$lockfile"] lock = vars.LOCKFILE
from ct.opts import args from ct.opts import args
# Load a song if we were passed one on load # Load a song if we were passed one on load
space = ' ' space = ' '
song = space.join(args) song = space.join(args)
#if exists( song ):
# load(song)
# Check if another instance already has the lock # Check if another instance already has the lock
if path.exists(lock) == True: if path.exists(lock) == True:
# Print a warning message, and tell where the lock file is so the user # Print a warning message, and tell where the lock file is so the user
# can remove it if this message is in error # can remove it if this message is in error
print "Warning: an instance of Ocarina may already be running!" print "Warning: an instance of Ocarina may already be running!"
print "If this is not the case, remove the lock file located at:" print "If this is not the case, remove the lock file located at:"
print lock print lock
# Find the port of the other application # Find the port of the other application
fin = open(lock) fin = open(lock)
@ -43,7 +52,7 @@ def postConfig():
tcp.send(port,song) tcp.send(port,song)
return -1 return -1
except: except:
print "Alert: I could not connect to port",port print "Warning: I could not connect to port",port
print "We will continue as if this is the only Ocarina" print "We will continue as if this is the only Ocarina"
# Become a tcp server # Become a tcp server
@ -67,7 +76,10 @@ def config():
global vars global vars
from ct.call import pyfile from ct.call import pyfile
config = "config.py" config = "config.py"
pyfile(path.join(vars["$ocarina"],config)) pyfile(path.join(vars.OCARINA,config))
pyfile(config) pyfile(config)
return postConfig() if postConfig() != 0:
import sys
sys.exit()

29
src/core/variables.py Normal file
View File

@ -0,0 +1,29 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 10, 2010 5:57:02 PM$"
from ct import path
class Vars:
def __init__(self):
self.USER = path.expand("~")
self.OCARINA = path.join(self.USER, ".ocarina3")
self.LOCKFILE = path.join(self.OCARINA, "lock")
self.HISTORYFILE = path.join(self.OCARINA, "history")
self.PLAYONLOAD = True
self.PORT = 0
self.PROMPT = ">>>"
self.VERBOSE = 0
self.VOLUME = 1.0
self.VOLUMEINCR = 0.05
self.ARTIST = ""
self.ALBUM = ""
self.TITLE = ""

View File

@ -162,7 +162,7 @@ def gettrack(trid):
select = "track.id,track.name,track.length,artist.name,album.name,track.count" select = "track.id,track.name,track.length,artist.name,album.name,track.count"
where = "track.artist=artist.id AND track.album=album.id AND track.id="+str(trid) where = "track.artist=artist.id AND track.album=album.id AND track.id="+str(trid)
sel = sql.Select(select,"track,artist,album",where) sel = sql.Select(select,"track,artist,album",where)
return sel.execute().fetchone() return list( sel.execute().fetchone() )
init() init()

View File

@ -14,7 +14,7 @@ import ocarina
def getdb(): def getdb():
return join(ocarina.vars["$ocarina"],"ocarina.db") return join(ocarina.vars.OCARINA,"ocarina.db")
def dbexists(): def dbexists():

View File

@ -1,21 +0,0 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$Mar 15, 2010 9:56:53 PM$"
from ocarina import vars
import coredefaults
vars["$theme"] = "themes/simple.xml"
#vars["$theme"] = "themes/classic.xml"
vars["$artist"] = ""
vars["$album"] = ""
vars["$title"] = ""
vars["$filterText"] = ""
import guibuilder
from oGtk import *

View File

@ -0,0 +1,5 @@
__author__="bjschuma"
__date__ ="$May 16, 2010 7:21:27 PM$"
__all__ = ["dialog"]

View File

@ -0,0 +1,34 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 16, 2010 7:21:50 PM$"
import gtk
class FileChooser(gtk.FileChooserDialog):
def __init__(self,title,file=None,seldir=False):
buttons = (gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)
action=gtk.FILE_CHOOSER_ACTION_OPEN
gtk.FileChooserDialog.__init__(self,title,None,action=action,buttons=buttons)
if file != None:
self.select_filename(file)
if seldir == True:
self.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
def choose(self):
response = self.run()
self.hide()
file = ""
#print response
if response == gtk.RESPONSE_OK:
file = self.get_filename()
if response != gtk.RESPONSE_OK:
return None
return file

View File

@ -0,0 +1,46 @@
__author__="bjschuma"
__date__ ="$May 13, 2010 10:37:20 AM$"
__all__ = ["box", "importnode", "menu", "node", "window"]
from ct.call import write
global parts
parts = dict()
def make(child):
global parts
name = str(child.nodeName).lower()
if (name in parts.keys()) == False:
return None
node = parts[name](child)
if name == "import":
return node.part
return node
from gtknodes.box import *
parts["vbox"] = VBox
parts["hbox"] = HBox
from gtknodes.importnode import *
parts["import"] = Import
from gtknodes.menu import *
parts["menubar"] = bar.MenuBar
parts["menuitem"] = item.MenuItem
parts["menuchangetheme"] = theme.MenuChangeTheme
parts["menureloadtheme"] = theme.MenuReloadTheme
parts["menuselectsong"] = playback.MenuSelectSong
from gtknodes.window import *
parts["window"] = Window
parts["scrollwindow"] = ScrolledWindow

53
src/extra/gtknodes/box.py Normal file
View File

@ -0,0 +1,53 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 13, 2010 11:46:36 AM$"
from gtknodes.node import Node
import gtk
class BoxNode(Node):
def __init__(self, elm, box):
Node.__init__(self, elm)
self["pack"] = "start"
self["expand"] = "false"
self["fill"] = "false"
self["pad"] = 0
self.part = box()
self.setattrs()
self.pack()
def packval(self,key,node):
if ( key in node.keys() ) == True:
return node[key]
return self[key]
def pack(self):
for child in self.children:
pack = self.packval("pack", child)
expand = self.packval("expand", child) == "true"
fill = self.packval("fill", child) == "true"
pad = int( self.packval("pad", child) )
if pack == "start":
self.part.pack_start(child.part, expand, fill, pad)
else:
self.part.pack_end(child.part, expand, fill, pad)
class HBox(BoxNode):
def __init__(self,elm):
BoxNode.__init__(self, elm, gtk.HBox)
class VBox(BoxNode):
def __init__(self,elm):
BoxNode.__init__(self, elm, gtk.VBox)

View File

@ -0,0 +1,19 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 16, 2010 10:24:55 PM$"
from gtknodes.node import Node
class Import(Node):
def __init__(self,elm):
Node.__init__(self,elm)
self["show"] = False
self.setattrs()
from gui import buildfile
self.part = buildfile(self["src"])

View File

@ -0,0 +1,20 @@
__author__="bjschuma"
__date__ ="$May 16, 2010 7:23:22 PM$"
__all__ = ["bar", "item", "playback", "theme"]
import gtk
from gtknodes import Node
class MenuNode(Node):
def __init__(self, elm, title):
Node.__init__(self,elm)
self.part = gtk.MenuItem(title)
self.setattrs()
self.part.connect("activate", self.onclick)
def onclick(self, menu):
pass

Binary file not shown.

View File

@ -0,0 +1,23 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 16, 2010 7:25:18 PM$"
from gtknodes import Node
import gtk
class MenuBar(Node):
def __init__(self,elm):
Node.__init__(self,elm)
self.part = gtk.MenuBar()
self.setattrs()
self.makemenu()
def makemenu(self):
for child in self.children:
self.part.append(child.part)

Binary file not shown.

View File

@ -0,0 +1,27 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 16, 2010 7:26:59 PM$"
from gtknodes import Node
import gtk
class MenuItem(Node):
def __init__(self,elm):
Node.__init__(self,elm)
self["name"] = "menu"
self.part = gtk.MenuItem()
self.menu = gtk.Menu()
self.part.set_submenu(self.menu)
self.setattrs()
self.part.set_label(self["name"].title())
self.makemenu()
def makemenu(self):
for child in self.children:
self.menu.append(child.part)

Binary file not shown.

View File

@ -0,0 +1,25 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 16, 2010 10:08:35 PM$"
from gtknodes.menu import MenuNode
class MenuSelectSong(MenuNode):
def __init__(self,elm):
MenuNode.__init__(self, elm, "Select a song")
self.file = None
def onclick(self, menu):
from gtkextras import dialog
song = dialog.FileChooser("Select a song", self.file).choose()
if song != None:
from ct import call
self.file = song
call.load(song)

Binary file not shown.

View File

@ -0,0 +1,32 @@
#! /usr/bin/python
__author__="bjschuma"
__date__ ="$May 16, 2010 7:24:02 PM$"
import gui
from ocarina import vars
from gtknodes.menu import MenuNode
class MenuReloadTheme(MenuNode):
def __init__(self,elm):
MenuNode.__init__(self, elm, "Reload Theme")
def onclick(self,menu):
gui.build()
class MenuChangeTheme(MenuNode):
def __init__(self,elm):
MenuNode.__init__(self, elm, "Change Theme")
def onclick(self,menu):
from gtkextras import dialog
file = dialog.FileChooser("Select a theme file",vars.THEME).choose()
if file != None:
vars.THEME = file
gui.build()

Binary file not shown.

View File

@ -0,0 +1,70 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 16, 2010 10:27:25 PM$"
from ct.call import write
from gtknodes import make
class Node:
def __init__(self,elm):
write("Creating node: "+elm.nodeName, 2)
self.elm = elm
self.part = None
self.init2()
def __del__(self):
write("Deleting node: "+self.elm.nodeName, 2)
def init2(self):
self.name = self.elm.nodeName.lower()
self.attrs = dict()
self.children = self.getchildren()
def __setitem__(self,key,value):
self.attrs[str(key).lower()] = str(value).lower()
def __getitem__(self,key):
return self.attrs[str(key).lower()]
def keys(self):
return self.attrs.keys()
def show(self):
self.part.show()
def hide(self):
self.part.hide()
def setattrs(self):
if ("show" in self.keys()) == False:
self["show"] = "true"
self["viewport"] = "false"
if self.elm.hasAttributes() == True:
for i in range( self.elm.attributes.length ):
item = self.elm.attributes.item(i)
self[item.name.lower()] = item.nodeValue.lower()
if self["show"] == "true":
self.part.show()
def getchildren(self):
if self.elm.hasChildNodes() == False:
return []
children = []
for node in self.elm.childNodes:
if not node.nodeName[0] == "#":
child = self.make(node)
if child != None:
children += [child]
return children
def make(self,child):
return make(child)

View File

@ -0,0 +1,96 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 13, 2010 10:37:48 AM$"
from gtknodes import Node
from ct import call
import gtk
class Window(Node):
def __init__(self,elm):
Node.__init__(self,elm)
self.part = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.part.connect("delete_event", self.onquit)
self.wininit()
def wininit(self):
self["title"] = "Ocarina 3.0"
self["width"] = "400"
self["height"] = "150"
#self["show"] = "false"
self.setattrs()
self.part.set_title(self["title"].title())
self.part.resize(int(self["width"]), int(self["height"]))
self.add()
def newContent(self,elm):
call.write("Window redrawing content!", 2)
self.elm = elm
self.init2()
self.wininit()
def onquit(self,a,b):
call.exit()
def add(self):
if len(self.children) == 0:
return
# Add the first child to the window
self.part.add(self.children[0].part)
def clear(self):
self.part.remove(self.children[0].part)
class ScrolledWindow(Node):
def __init__(self,elm):
Node.__init__(self,elm)
self["hscroll"] = "auto"
self["vscroll"] = "auto"
self.part = gtk.ScrolledWindow()
self.setattrs()
hscroll = gtk.POLICY_AUTOMATIC
if self["hscroll"] == "none":
hscroll = gtk.POLICY_NONE
elif self["hscroll"] == "always":
hscroll = gtk.POLICY_ALWAYS
vscroll = gtk.POLICY_AUTOMATIC
if self["vscroll"] == "none":
vscroll = gtk.POLICY_NONE
elif self["vscroll"] == "always":
vscroll = gtk.POLICY_ALWAYS
self.part.set_policy(hscroll, vscroll)
self.add()
def add(self):
if len(self.children) == 0:
return
# Add the child to the scrolled window
child = self.children[0]
if child["viewport"] == "false":
self.part.add(child.part)
else:
self.part.add_with_viewport(child.part)

43
src/extra/gui.py Normal file
View File

@ -0,0 +1,43 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$May 13, 2010 10:28:46 AM$"
global window
window = None
from ocarina import vars
import gtknodes
import xml
import xml.dom.minidom as xml
def load(path):
fin = open(path)
if fin == None:
return None
return xml.parse(fin)
def build():
global window
doc = load(vars.THEME)
if doc == None:
return
if window != None:
window.clear()
window.newContent(doc.firstChild)
else:
window = gtknodes.make(doc.firstChild)
def buildfile(file):
doc = load(file)
if doc == None:
return
return gtknodes.make(doc.firstChild)

View File

@ -1,154 +0,0 @@
#! /usr/bin/python
# To change this template, choose Tools | Templates
# and open the template in the editor.
__author__="bjschuma"
__date__ ="$Mar 14, 2010 9:52:10 PM$"
import ocarina
from et import xm
from ct.call import write
#from oGtk import *
import gtk
global parts
parts = dict()
global buildFunc
buildFunc = None
global window
window = None
def setPacking(old,newVals):
for field in newVals:
if (field=="expand") or (field=="fill"):
if newVals[field]=="True":
old[field] = True
else:
old[field] = False
elif field=="padding":
old[field] = int(newVals[field])
return old
def buildTabs(node,tabs):
global buildFunc
for child in xm.children(node):
if child.nodeName=="tab":
label = None
content = None
for gchild in xm.children(child):
if gchild.nodeName == "tablabel":
for ggchild in xm.children(gchild):
item = buildFunc(ggchild)
if item != None:
label = item
elif gchild.nodeName == "tabcontent":
for ggchild in xm.children(gchild):
item = buildFunc(ggchild)
if item != None:
content = item
if content != None:
tabs.append_page(content,label)
attrs = setPacking({"expand":False,"fill":False}, xm.attributes(child) )
tabs.set_tab_label_packing(content,attrs["expand"],attrs["fill"],gtk.PACK_START)
def buildMenu(node,menu):
global buildFunc
for child in xm.children(node):
item = buildFunc(child)
if item!=None:
if node.nodeName == "menu-bar":
menu.append(item)
elif node.nodeName == "menuitem":
menu.addSubMenu(item)
def setPacking(old,newVals):
for field in newVals:
if (field=="expand") or (field=="fill"):
if newVals[field]=="True":
old[field] = True
else:
old[field] = False
elif field=="padding":
old[field] = int(newVals[field])
return old
def fill(node,container):
global buildFunc
pack = True
packing = {"expand":False,"fill":False,"padding":0}
for child in xm.children(node):
viewport = False
if child.nodeName == "add" or child.nodeName == "add-viewport":
if child.nodeName == "add-viewport":
write("We are adding to "+node.nodeName+" with a viewport",2)
viewport = True
else:
write("We are adding to "+node.nodeName,2)
pack = False
for grandchild in xm.children(child):
item = buildFunc(grandchild)
if item != None:
if viewport == False:
container.add(item)
else:
container.add_with_viewport(item)
elif child.nodeName == "pack":
packing = setPacking( packing,xm.attributes(child) )
write("Now using packing: "+str(packing), 2)
else:
item = buildFunc(child)
if item != None:
if pack == False:
container.add(item)
else:
container.pack_start(item,packing["expand"],packing["fill"],packing["padding"])
def build(node):
global parts
tag = node.nodeName
if (tag in parts.keys()) == True:
write("Creating part from tag: "+tag,2)
part = parts[tag](xm.attributes(node))
if (tag=="hbox") or (tag=="vbox") or (tag=="window") or (tag=="scrolled-window"):
fill(node,part)
elif (tag=="menu-bar") or (tag=="menuitem"):
buildMenu(node,part)
elif (tag=="tabs"):
buildTabs(node,part)
return part
def init():
global window
if window != None:
window.hide()
write("Building gui from file: "+ocarina.vars["$theme"],1)
doc = xm.load(ocarina.vars["$theme"])
window = build( xm.child(doc) )
ocarina.events.start("ocarina-gui-done")
window.show()
buildFunc = build
ocarina.events.invite("ocarina-start",init,50)
ocarina.events.invite("ocarina-stop",gtk.main_quit)

View File

@ -23,13 +23,13 @@ alpha = dict()
global filePath global filePath
filePath = path.join( ocarina.vars["$ocarina"], "index.pickle" ) filePath = path.join( ocarina.vars.OCARINA, "index.pickle" )
#if path.exists(filePath) == True: if path.exists(filePath) == True:
file = open( filePath ) file = open( filePath )
p = pickle.Unpickler( file ) p = pickle.Unpickler( file )
(index,alpha) = p.load() (index,alpha) = p.load()
file.close() file.close()
#filePath = "/home/bjschuma/.ocarina3/index.pickle" #filePath = "/home/bjschuma/.ocarina3/index.pickle"

View File

@ -2,5 +2,5 @@ __author__="bjschuma"
__date__ ="$Mar 14, 2010 10:21:40 PM$" __date__ ="$Mar 14, 2010 10:21:40 PM$"
__all__ = ["box", "button", "dialog","entry", "label", "label", "list", "menu", __all__ = ["align", "box", "button", "dialog","entry", "label", "label", "list",
"progbar", "tabs", "window", "volume"] "menu", "progbar", "tabs", "window", "volume"]

View File

@ -94,17 +94,17 @@ class ButtonImage(gtk.Button):
def make_button(attrs):return Button(attrs) def make_button(attrs):return Button(attrs)
def make_buttonplay(attrs): def make_buttonplay(attrs):
attrs["show"] = "ocarina-pause" attrs["show"] = ocarina.events.OCARINA_PAUSE
attrs["hide"] = "ocarina-play" attrs["hide"] = ocarina.events.OCARINA_PLAY
attrs["func"] = call.play attrs["func"] = call.play
attrs["shownow"] = str( not ocarina.vars["$playing"] ).lower() attrs["shownow"] = str( call.playing() ).lower()
return ButtonImage(attrs,gtk.STOCK_MEDIA_PLAY) return ButtonImage(attrs,gtk.STOCK_MEDIA_PLAY)
def make_buttonpause(attrs): def make_buttonpause(attrs):
attrs["show"] = "ocarina-play" attrs["show"] = ocarina.events.OCARINA_PLAY
attrs["hide"] = "ocarina-pause" attrs["hide"] = ocarina.events.OCARINA_PAUSE
attrs["func"] = call.pause attrs["func"] = call.pause
attrs["shownow"] = str( ocarina.vars["$playing"] ).lower() attrs["shownow"] = str( call.playing() ).lower()
return ButtonImage(attrs,gtk.STOCK_MEDIA_PAUSE) return ButtonImage(attrs,gtk.STOCK_MEDIA_PAUSE)
def make_buttonstop(attrs): def make_buttonstop(attrs):

View File

@ -12,6 +12,9 @@ import guibuilder
import ocarina import ocarina
import db import db
from ct import times
class Label(gtk.Label): class Label(gtk.Label):
def __init__(self,attrs): def __init__(self,attrs):
gtk.Label.__init__(self) gtk.Label.__init__(self)
@ -21,11 +24,28 @@ class Label(gtk.Label):
self.show() self.show()
class TimeLabel(gtk.Label):
def __init__(self,variable):
gtk.Label.__init__(self)
self.variable = variable
ocarina.events.invite(ocarina.events.FILTER_START,self.settime,10000)
ocarina.events.invite(ocarina.events.GUI_DONE,self.settime,10000)
self.show()
def settime(self):
self.set_text( times.sec2text(self.variable) )
class LabelLibTime(TimeLabel):
def __init__(self):
TimeLabel.__init__(self,ocarina.vars.LIBRARYLENGTH)
class LabelLibCount(gtk.Label): class LabelLibCount(gtk.Label):
def __init__(self): def __init__(self):
gtk.Label.__init__(self) gtk.Label.__init__(self)
ocarina.events.invite("ocarina-filter-start",self.setcount,10000) ocarina.events.invite(ocarina.events.FILTER_START,self.setcount,10000)
#ocarina.events.invite("ocarina-gui-done",self.setcount,10000) #ocarina.events.invite("ocarina-gui-done",self.setcount,10000)
def setcount(self): def setcount(self):
@ -68,31 +88,31 @@ class Label2(gtk.Alignment):
class SongTitleLabel(Label2): class SongTitleLabel(Label2):
def __init__(self): def __init__(self):
Label2.__init__(self,13000, 700) Label2.__init__(self,13000, 700)
ocarina.events.invite("tags-changed", self.setTitle) ocarina.events.invite(ocarina.events.TAGS_CHANGED, self.setTitle)
self.setTitle() self.setTitle()
def setTitle(self): def setTitle(self):
self.set_text(ocarina.vars["$title"]) self.set_text(ocarina.vars.TITLE)
class SongAlbumLabel(Label2): class SongAlbumLabel(Label2):
def __init__(self): def __init__(self):
Label2.__init__(self,10000, 400) Label2.__init__(self,10000, 400)
ocarina.events.invite("tags-changed", self.setAlbum) ocarina.events.invite(ocarina.events.TAGS_CHANGED, self.setAlbum)
self.setAlbum() self.setAlbum()
def setAlbum(self): def setAlbum(self):
self.set_text("from " + ocarina.vars["$album"]) self.set_text("from " + ocarina.vars.ALBUM)
class SongArtistLabel(Label2): class SongArtistLabel(Label2):
def __init__(self): def __init__(self):
Label2.__init__(self,10000, 400) Label2.__init__(self,10000, 400)
ocarina.events.invite("tags-changed", self.setArtist) ocarina.events.invite(ocarina.events.TAGS_CHANGED, self.setArtist)
self.setArtist() self.setArtist()
def setArtist(self): def setArtist(self):
self.set_text("by " + ocarina.vars["$artist"]) self.set_text("by " + ocarina.vars.ARTIST)
@ -101,8 +121,10 @@ def make_libcountlabel(attrs):return LabelLibCount()
def make_titlelabel(attrs):return SongTitleLabel() def make_titlelabel(attrs):return SongTitleLabel()
def make_albumlabel(attrs):return SongAlbumLabel() def make_albumlabel(attrs):return SongAlbumLabel()
def make_artistlabel(attrs):return SongArtistLabel() def make_artistlabel(attrs):return SongArtistLabel()
def make_libtimelabel(attrs):return LabelLibTime()
guibuilder.parts["label"] = make_label guibuilder.parts["label"] = make_label
guibuilder.parts["libcountlabel"] = make_libcountlabel guibuilder.parts["libcountlabel"] = make_libcountlabel
guibuilder.parts["libtimelabel"] = make_libtimelabel
guibuilder.parts["titlelabel"] = make_titlelabel guibuilder.parts["titlelabel"] = make_titlelabel
guibuilder.parts["albumlabel"] = make_albumlabel guibuilder.parts["albumlabel"] = make_albumlabel
guibuilder.parts["artistlabel"] = make_artistlabel guibuilder.parts["artistlabel"] = make_artistlabel

View File

@ -21,7 +21,8 @@ class SongList(gtk.TreeView):
def __init__(self): def __init__(self):
gtk.TreeView.__init__(self) gtk.TreeView.__init__(self)
self.countvar = None self.countvar = None
ocarina.events.invite("ocarina-filter-start",self.filter) self.timevar = None
ocarina.events.invite(ocarina.events.FILTER_START,self.filter)
self.list = gtk.ListStore(int,str,str,str,str,int) self.list = gtk.ListStore(int,str,str,str,str,int)
self.set_reorderable(True) self.set_reorderable(True)
@ -35,7 +36,7 @@ class SongList(gtk.TreeView):
col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
col.set_min_width(2) col.set_min_width(2)
col.set_max_width(700) col.set_max_width(700)
col.set_fixed_width(150) col.set_fixed_width(200)
col.set_sort_indicator(True) col.set_sort_indicator(True)
if cols[i] != "Id": if cols[i] != "Id":
self.append_column(col) self.append_column(col)
@ -52,13 +53,18 @@ class SongList(gtk.TreeView):
#self.add(self.tree) #self.add(self.tree)
self.filterModel = self.list.filter_new() self.filterModel = self.list.filter_new()
self.filterModel.set_visible_func(self.setvisible) self.filterModel.set_visible_func(self.setvisible)
#self.show_all() self.sort = gtk.TreeModelSort(self.filterModel)
self.set_model(self.sort)
#self.set_model(self.list)
#self.show()
self.show_all()
# Add a row to the list # Add a row to the list
def insert(self,trackid): def insert(self,trackid):
file = list(db.gettrack(trackid)) file = list(db.gettrack(trackid))
ocarina.vars[self.timevar] += file[2]
file[2] = times.ftime(file[2]) file[2] = times.ftime(file[2])
self.list.append(file) self.list.append(file)
if self.countvar != None: if self.countvar != None:
@ -67,16 +73,19 @@ class SongList(gtk.TreeView):
def filter(self): def filter(self):
text = ocarina.vars["$filterText"] text = ocarina.vars["$filterText"]
ocarina.vars[self.timevar] = 0
self.results = index.search(ocarina.vars["$filterText"]) self.results = index.search(ocarina.vars["$filterText"])
if self.countvar != None: if self.countvar != None:
ocarina.vars[self.countvar] = len(self.results) ocarina.vars[self.countvar] = len(self.results)
self.filterModel.refilter() self.filterModel.refilter()
for row in self.sort:
ocarina.vars[self.timevar] += times.hms2sec(row[2])
def setvisible(self,list,iter): def setvisible(self,songlist,iter):
if ocarina.vars["$filterText"] == "": if ocarina.vars["$filterText"] == "":
return True return True
if (list[iter][0] in self.results) == True: if (songlist[iter][0] in self.results) == True:
return True return True
return False return False
@ -86,9 +95,6 @@ class SongList(gtk.TreeView):
path = db.getpath(trid) path = db.getpath(trid)
load(path) load(path)
play() play()
#cmd.run("load "+path)
#cmd.run("play")
#print self.sort[index][1],self.sort[index][0]
@ -96,11 +102,14 @@ class LibraryList(SongList):
def __init__(self): def __init__(self):
SongList.__init__(self) SongList.__init__(self)
self.countvar = "$libcount" self.countvar = "$libcount"
ocarina.vars["$libcount"] = 0 self.timevar = "$LibraryLength"
ocarina.events.invite("ocarina-gui-done",self.populate) ocarina.vars.LIBCOUNT = 0
ocarina.vars.LIBRARYLENGTH = 0
ocarina.events.invite(ocarina.events.GUI_DONE,self.populate)
def populate(self): def populate(self):
ocarina.events.start("ocarina-filter-start")
thread = needle.Needle(self.insertLibrary) thread = needle.Needle(self.insertLibrary)
thread.start() thread.start()
#self.insertLibrary() #self.insertLibrary()
@ -109,20 +118,20 @@ class LibraryList(SongList):
def insertLibrary(self): def insertLibrary(self):
# Freeze the model before inserting a lot of rows # Freeze the model before inserting a lot of rows
# this speeds up performance # this speeds up performance
self.hide()
self.freeze_child_notify() self.freeze_child_notify()
self.set_model(None) self.set_model(None)
try: try:
libid = db.libid("Music") libid = db.libid("Music")
ocarina.events.start("ocarina-filter-start")
for track in db.getsongs(libid): for track in db.getsongs(libid):
self.insert(track[1]) self.insert(track[1])
except Exception,e: except Exception,e:
print e print e
self.sort = gtk.TreeModelSort(self.filterModel) ocarina.events.start("ocarina-filter-start")
self.set_model(self.sort) self.set_model(self.sort)
# Unfreeze the model # Unfreeze the model
self.thaw_child_notify() self.thaw_child_notify()
self.show_all() self.show()

View File

@ -59,8 +59,8 @@ class MenuItem(gtk.MenuItem):
class MenuPlay(gtk.ImageMenuItem): class MenuPlay(gtk.ImageMenuItem):
def __init__(self): def __init__(self):
gtk.ImageMenuItem.__init__(self,gtk.STOCK_MEDIA_PLAY) gtk.ImageMenuItem.__init__(self,gtk.STOCK_MEDIA_PLAY)
ocarina.events.invite("ocarina-play",self.hide) ocarina.events.invite(ocarina.events.OCARINA_PLAY,self.hide)
ocarina.events.invite("ocarina-pause",self.show) ocarina.events.invite(ocarina.events.OCARINA_PAUSE,self.show)
self.connect("activate",self.clicked) self.connect("activate",self.clicked)
self.show() self.show()
@ -73,8 +73,8 @@ class MenuPlay(gtk.ImageMenuItem):
class MenuPause(gtk.ImageMenuItem): class MenuPause(gtk.ImageMenuItem):
def __init__(self): def __init__(self):
gtk.ImageMenuItem.__init__(self,gtk.STOCK_MEDIA_PAUSE) gtk.ImageMenuItem.__init__(self,gtk.STOCK_MEDIA_PAUSE)
ocarina.events.invite("ocarina-pause",self.hide) ocarina.events.invite(ocarina.events.OCARINA_PAUSE,self.hide)
ocarina.events.invite("ocarina-play",self.show) ocarina.events.invite(ocarina.events.OCARINA_PLAY,self.show)
self.connect("activate",self.clicked) self.connect("activate",self.clicked)
def clicked(self,item): def clicked(self,item):
@ -85,8 +85,8 @@ class MenuPause(gtk.ImageMenuItem):
class MenuStop(gtk.ImageMenuItem): class MenuStop(gtk.ImageMenuItem):
def __init__(self): def __init__(self):
gtk.ImageMenuItem.__init__(self,gtk.STOCK_MEDIA_STOP) gtk.ImageMenuItem.__init__(self,gtk.STOCK_MEDIA_STOP)
ocarina.events.invite("ocarina-pause",self.hide) ocarina.events.invite(ocarina.events.OCARINA_PAUSE,self.hide)
ocarina.events.invite("ocarina-play",self.show) ocarina.events.invite(ocarina.events.OCARINA_PLAY,self.show)
self.connect("activate",self.clicked) self.connect("activate",self.clicked)
def clicked(self,item): def clicked(self,item):
@ -123,35 +123,35 @@ class MenuLibNew(gtk.MenuItem):
class MenuTheme(gtk.MenuItem): #class MenuTheme(gtk.MenuItem):
def __init__(self): # def __init__(self):
gtk.MenuItem.__init__(self,"Change Theme") # gtk.MenuItem.__init__(self,"Change Theme")
self.connect("activate", self.onclick) # self.connect("activate", self.onclick)
self.show() # self.show()
#
def onclick(self,menu): # def onclick(self,menu):
file = dialog.FileChooser("Select a theme file").choose() # file = dialog.FileChooser("Select a theme file").choose()
if file!=None: # if file!=None:
#print file # #print file
ocarina.vars["$theme"] = str(file) # ocarina.vars["$theme"] = str(file)
guibuilder.init() # guibuilder.init()
def make_menubar(attrs=None):return MenuBar() #def make_menubar(attrs=None):return MenuBar()
def make_menuitem(attrs=None):return MenuItem(attrs) #def make_menuitem(attrs=None):return MenuItem(attrs)
def make_menuplay(attrs=None):return MenuPlay() #def make_menuplay(attrs=None):return MenuPlay()
def make_menupause(attrs=None):return MenuPause() #def make_menupause(attrs=None):return MenuPause()
def make_menustop(attrs=None):return MenuStop() #def make_menustop(attrs=None):return MenuStop()
def make_menusongsel(attrs=None):return MenuSongSelect() #def make_menusongsel(attrs=None):return MenuSongSelect()
def make_menulibnew(attrs=None):return MenuLibNew() #def make_menulibnew(attrs=None):return MenuLibNew()
def make_menutheme(attrs=None):return MenuTheme() #def make_menutheme(attrs=None):return MenuTheme()
guibuilder.parts["menu-bar"] = make_menubar #guibuilder.parts["menu-bar"] = make_menubar
guibuilder.parts["menuitem"] = make_menuitem #guibuilder.parts["menuitem"] = make_menuitem
guibuilder.parts["menuplay"] = make_menuplay #guibuilder.parts["menuplay"] = make_menuplay
guibuilder.parts["menupause"] = make_menupause #guibuilder.parts["menupause"] = make_menupause
guibuilder.parts["menustop"] = make_menustop #guibuilder.parts["menustop"] = make_menustop
guibuilder.parts["menusongsel"] = make_menusongsel #guibuilder.parts["menusongsel"] = make_menusongsel
guibuilder.parts["menulibnew"] = make_menulibnew #guibuilder.parts["menulibnew"] = make_menulibnew
guibuilder.parts["menutheme"] = make_menutheme #guibuilder.parts["menutheme"] = make_menutheme

View File

@ -58,8 +58,8 @@ class LibScanBar(gtk.ProgressBar):
def __init__(self): def __init__(self):
gtk.ProgressBar.__init__(self) gtk.ProgressBar.__init__(self)
gobject.timeout_add(500,self.updatebar) gobject.timeout_add(500,self.updatebar)
ocarina.events.invite("ocarina-scanlib-start",self.show) ocarina.events.invite(ocarina.events.SCANLIB_START,self.show)
ocarina.events.invite("ocarina-scanlib-stop",self.hide) ocarina.events.invite(ocarina.events.SCANLIB_STOP,self.hide)
def updatebar(self): def updatebar(self):

View File

@ -11,11 +11,40 @@ import gtk
import guibuilder import guibuilder
class Tabs(gtk.Notebook): class Tabs(gtk.Notebook):
def __init__(self): def __init__(self,attrs):
gtk.Notebook.__init__(self) gtk.Notebook.__init__(self)
self.set_show_border(True) self.tabPos = gtk.POS_TOP
self.border = True
for a in attrs:
if a == "tabpos":
if attrs[a] == "left":
self.tabPos = gtk.POS_LEFT
elif attrs[a] == "right":
self.tabPos = gtk.POS_RIGHT
elif attrs[a] == "bottom":
self.tabPos = gtk.POS_BOTTOM
else:
self.tabPos = gtk.POS_TOP
elif a == "border":
if attrs[a] == "False":
self.border = False
self.set_show_border(False)
self.set_tab_pos(self.tabPos)
self.show() self.show()
def make_tabs(attrs=None):return Tabs() def addpage(self,page,label):
# Only rotate labels
if( isinstance(label, gtk.Label) ):
if self.tabPos == gtk.POS_LEFT:
label.set_angle(90)
elif self.tabPos == gtk.POS_RIGHT:
label.set_angle(-90)
self.append_page(page, label)
def make_tabs(attrs=None):return Tabs(attrs)
guibuilder.parts["tabs"] = make_tabs guibuilder.parts["tabs"] = make_tabs

View File

@ -24,14 +24,14 @@ class VolumeControl(gtk.VolumeButton):
self.set_relief(relief) self.set_relief(relief)
adj = self.get_adjustment() adj = self.get_adjustment()
adj.set_page_increment(ocarina.vars["$volumeincr"]) adj.set_page_increment(ocarina.vars.VOLUMEINCR)
self.setValue() self.setValue()
self.connect("value-changed",self.valueChanged) self.connect("value-changed",self.valueChanged)
self.show() self.show()
def setValue(self): def setValue(self):
self.set_value(ocarina.vars["$volume"]) self.set_value(ocarina.vars.VOLUME)
def valueChanged(self, widget, value): def valueChanged(self, widget, value):
gstreamer.setvol(value) gstreamer.setvol(value)

View File

@ -6,28 +6,37 @@ __date__ ="$Mar 14, 2010 9:50:09 PM$"
import sys import sys
sys.path.append("core") sys.path.append("core")
import ocarina import ocarina
import extradefaults from ct import path
from ocarina import vars
from ocarina import events
# Configure additional variables needed for ocarina-extra
vars.THEME = "themes/classic.xml"
vars.FILTERTEXT = ""
# Make new events
events.create("TAGS_CHANGED")
events.create("FILTER_START")
events.create("GUI_DONE")
events.create("SCANLIB_START")
events.create("SCANLIB_STOP")
ocarina.config()
from ct.call import write from ct.call import write
write("Welcome to Ocarina 3.0 (extra)", 1)
#import guibuilder
#from oGtk import *
import gtk import gtk
import gobject import gobject
gobject.threads_init() gobject.threads_init()
import gui
gui.build()
#gui.window.part.show()
def main(): #ocarina.events.start(ocarina.events.OCARINA_START)
# Potentially the first thing printed
write("Welcome to Ocarina (extra)", 1)
code = ocarina.config() gtk.main()
ocarina.events.start("ocarina-start")
if code == 0:
gtk.main()
if __name__ == "__main__":main()

View File

@ -50,6 +50,10 @@
</tabs> </tabs>
<pack expand="False"/> <pack expand="False"/>
<hbox> <hbox>
<vbox>
<pack expand="True" fill="False"/>
<scanlibbar/>
</vbox>
<pack expand="True" fill="True"/> <pack expand="True" fill="True"/>
<vbox> <vbox>
<pack expand="True" fill="False"/> <pack expand="True" fill="False"/>
@ -61,7 +65,12 @@
<button-stop relief="none"/> <button-stop relief="none"/>
<volume relief="none" /> <volume relief="none" />
</hbox> </hbox>
<scanlibbar/> <pack expand="False" fill="False" pack="End"/>
<align xalign="1">
<add>
<libtimelabel/>
</add>
</align>
</vbox> </vbox>
</add> </add>
</window> </window>

15
src/themes/menu.xml Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<MenuBar>
<MenuItem name="Playback">
<!--<menuplay/>
<menupause/>
<menustop/>-->
<MenuSelectSong/>
</MenuItem>
<MenuItem name="Theme">
<MenuChangeTheme/>
<MenuReloadTheme/>
</MenuItem>
</MenuBar>

21
src/themes/simple2.xml Normal file
View File

@ -0,0 +1,21 @@
<?xml version="1.0" ?>
<window width="400" height="150" title="Ocarina 3.0">
<vbox>
<import src="themes/menu.xml" />
<scrollwindow hscroll="always">
<vbox viewport="true">
<!--<titlelabel/>
<albumlabel/>
<artistlabel/>-->
</vbox>
</scrollwindow>
<hbox>
<!--<button-play size="large"/>
<button-pause size="large"/>
<button-stop size="large"/>
<volume/>-->
</hbox>
<!--<progbar/>-->
</vbox>
</window>

20
src/themes/simple3.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" ?>
<window width="400" height="150" title="Ocarina 3.0">
<vbox>
<scrollwindow hscroll="always">
<vbox viewport="true">
<!--<titlelabel/>
<albumlabel/>
<artistlabel/>-->
</vbox>
</scrollwindow>
<hbox>
<!--<button-play size="large"/>
<button-pause size="large"/>
<button-stop size="large"/>
<volume/>-->
</hbox>
<!--<progbar/>-->
<import src="themes/menu.xml" />
</vbox>
</window>