Example #1
0
	def settag(self):
#        if len(self.tagger.tags):
#           loggy.log( str(self.tagger.tags))
		loggy.log(str(len(self.totag))+' of '+str(self.totaltotag)+' remaining')
		mime = mimetypes.guess_type(self.tagger.filename)[0] # take mime out into function?
		if not mime:
			loggy.warn('Mime type error in settag - no mime info')
		elif mime.startswith("audio"):
			type = 'audio'
		elif mime.startswith("video"):
			type = 'video'
		else:
			loggy.warn('Mime type error in settag - mime info incorrect')
		self.tagger.tags['uri'] = self.tagger.filename
		if len(type)>0:
			#try:
				row = []
				for key in self.keys:
					if key in self.tagger.tags:
						row.append(self.tagger.tags[key])
					else:
						row.append('')
				row.append(type)
				#(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(self.tagger.filename)
				row = row + [1,2,3,4,5]
				print row
				self.insert_row('media', row)
				#self.insert_row(type, [self.tagger.filename, self.tagger.tags['artist'], self.tagger.tags['title']])
			#except:
				#loggy.log('OOOOOOOOOOOOOOOOOOOOOOOOOOOO')#TODO: - deal with errors properly
		self.gettag()
Example #2
0
 def settag(self):
     loggy.log(str(len(self.totag)) + " of " + str(self.totaltotag) + " remaining")
     mime = mimetypes.guess_type(self.tagger.uri)[0]  # take mime out into function?
     if not mime:
         loggy.warn("Mime type error in settag - no mime info")
     elif mime.startswith("audio"):
         type = "audio"
     elif mime.startswith("video"):
         type = "video"
     else:
         loggy.warn("Mime type error in settag - mime info incorrect")
     self.tagger.tags["uri"] = self.tagger.uri
     self.tagger.tags["mime"] = type
     # print self.tagger.uri[7:]
     # (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(self.tagger.uri[7:])
     # filetemp = Gio.file_new_for_uri(self.tagger.uri) #file_new_for_uri
     # temp.query_info('*',flags=gio.FILE_QUERY_INFO_NONE, cancellable=None)
     # info = filetemp.query_info('standard::mtime')
     self.tagger.tags["mtime"] = int(os.path.getmtime(self.tagger.uri[7:]))
     if len(type) > 0:
         # try:
         row = []
         for key in self.keys:
             if key in self.tagger.tags:
                 row.append(self.tagger.tags[key])
             else:
                 row.append(None)
         print(str(row))
         self.insert_media(row)
     self.gettag()
Example #3
0
	def load_id(self, songid):
		#self.sb.player.load_uri(self.sb.sbdb.get_id_db_info(id)['uri'])
		try:
			self.sb.player.load_uri(self.sb.sbdb.get_id_db_info(songid)['uri'])
		except TypeError:
			loggy.warn('could not get next playlist item, skipping')
			self.get_next()
Example #4
0
 def load_uri(self, uri, callback):
     self.__init__()#TODO work out how to load file without recreating pipeline
     self.tags = {}
     self.uri = uri
     self.error = None
     self.callback = callback
     loggy.warn( "Tagger loading " + uri)
     self.playbin.set_property("uri", uri)
     self.player.set_state(Gst.State.PLAYING)
Example #5
0
	def on_play_state_change(self, player):
		#TODO: - make player only emit one signal for each event
		#state = self.sb.player.getstate()
		loggy.debug('gui.on_play_state_change ' + self.sb.player.state)
		if (self.sb.player.state == 'play'):
			for playbutton in self.widgets['play_buttons']:
				playbutton.set_label(Gtk.STOCK_MEDIA_PAUSE)
		elif (self.sb.player.state == 'pause' or self.sb.player.state == 'stop'):
			for playbutton in self.widgets['play_buttons']:
				playbutton.set_label(Gtk.STOCK_MEDIA_PLAY)
		else:
			loggy.warn('gui.on_play_state_change got unknown state: ' + self.sb.player.state)
Example #6
0
	def on_message(self, bus, message):
		if message.type == gst.MESSAGE_EOS: #TODO: reorder for speed , or take signals out individually...
			self.get_next()
		elif message.type == gst.MESSAGE_ERROR:
			self.reset()
			err, debug = message.parse_error()
			loggy.log( "Player GST_MESSAGE_ERROR: " + str(err) + str(debug))
			self.get_next()
		elif message.type == gst.MESSAGE_STATE_CHANGED:
			self.update_play_state()
		elif message.type == gst.MESSAGE_STREAM_STATUS:
			self.update_position()
		elif message.type == gst.MESSAGE_NEW_CLOCK:
			None
		elif message.type == gst.MESSAGE_ASYNC_DONE:
			self.emit('async-done')
			for comm in self.on_update_tags:
				comm()
			loggy.log('Player Async Done')
		elif message.type == gst.MESSAGE_TAG: # thanks to http://www.jezra.net/blog/use_python_and_gstreamer_to_get_the_tags_of_an_audio_file
			taglist = message.parse_tag()
			for key in taglist.keys():
				self.tags[key] = taglist[key]
#                if key == 'image':
#                    img = open('temp', 'w')
#                    img.write(taglist[key])
#                    img.close()
#                else:
#                    True
					#loggy.log('Player GST tag:' + key + ' : ' + str(taglist[key]) )
			#gst_tag_list_free()?
		elif message.type == gst.MESSAGE_DURATION:
			format = gst.Format(gst.FORMAT_TIME)
			self.dur = self.player.query_duration(format)[0]
			self.dursec = int(self.dur / gst.SECOND)
		elif message.type == gst.MESSAGE_ELEMENT:
			if message.structure is None:
				return
			message_name = message.structure.get_name()
			if message_name == "prepare-xwindow-id":
				imagesink = message.src
				loggy.warn('Player prepare-xwindow-id got')
				imagesink.set_property("force-aspect-ratio", True)
				#gtk.gdk.threads_enter()
				if self.vidout.has_key('xid'): imagesink.set_xwindow_id(self.vidout['xid'])
				#imagesink.set_xwindow_id(self.VID.window.xid)
				#gtk.gdk.threads_leave()
			elif message_name == "have-xwindow-id":
				None
			else:
				loggy.log( "Player GST message unhandled:" + str(message.type))
		else:
			loggy.warn('Player - unknown messge' + str(message.type))
Example #7
0
	def startserver(self, host, port):
		self.host = host
		self.port = port
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		try:
			self.sock.bind((self.host, self.port)) #TODO: check port empty first
		except:
			loggy.warn('mpdserver failed to start on host %s port %s' % (self.host, self.port))
			return False
		self.sock.listen(1)
		loggy.log('mpdserver Interface Running on ' + host + ':' + str(port) )
		GObject.io_add_watch(self.sock, GObject.IO_IN, self.listener)
Example #8
0
	def add_uri(self, uri, pos=None):
		loggy.debug('playlist.add_uri '+str(uri)+str(pos))
		songid = self.sb.sbdb.get_uri_db_info(uri)
		if songid:
			songid = songid['songid']
			if pos is not None:
				self.add_songid(songid, pos)
			else:
				self.add_songid(songid)
			return songid
		else:
			loggy.warn('could not add uri {0} to playlist - not in db')
			return False				
Example #9
0
	def read_playlist_from_giofile(self, giofile):
		name = giofile.get_path()
		(success, contents, tag) =  giofile.load_contents()
		contents = contents.decode().splitlines()
		#print(contents)
		if contents.pop(0).startswith('#EXTM3U'):
			#playlist found, wipe/create playlist with that name
			self.playlists[name] = []
			for line in contents:
				if line.startswith('/'):
					self.playlists[name].append('file://'+line)
				elif (line.startswith('#')): None
				else:
					loggy.warn('Could not analyse line in playlist '+name+' :'+line)
			loggy.log('Found '+str(len(self.playlists[name]))+' items in m3u playlist '+name)
			self.playlist=self.playlists[name]
			self.sb.player.emit('new-playlist',name)
Example #10
0
	def read_playlist_dir(self):
		self.plfolder = Gio.File.new_for_path(path=self.sb.config.config['playlistfolder'])
		query = self.plfolder.query_file_type(Gio.FileQueryInfoFlags.NONE, None)
		if (query != Gio.FileType.DIRECTORY):
			loggy.warn('Playlist folder is not a directory:' + self.sb.config.config['playlistfolder'])
			return
		childrenenumerator = self.plfolder.enumerate_children('standard::display-name,time::modified', Gio.FileQueryInfoFlags.NONE, None)#fills childrenenumerator with fileinfos of child files of directory with information on display name and modified (only). Follows symlinks. See https://developer.gnome.org/pygobject/2.18/gio-constants.html#gio-file-attribute-constants. Content type does not seem to be particularly useful in this context
		while True:
			fl = childrenenumerator.next_file()
			if fl:
				if fl.get_display_name().lower().endswith('.m3u'):
					#loggy.log('found playlist'+ fl.get_display_name())
					self.read_playlist_from_giofile(self.plfolder.get_child_for_display_name(fl.get_display_name()), )
			else:
				loggy.log('Done reading playlist folder')
				break
		self.plmonitor = self.plfolder.monitor_directory(Gio.FileMonitorFlags.NONE, None)
		if self.plmonitor == None: loggy.warn('unable to monitor playlist directory')
		self.plmonitor.connect('changed', self.playlist_monitor_changed)
Example #11
0
	def __init__(self, soundblizzard):
		#load defaults first then config file then command line args
		self.config = { 'configfile' : os.path.expanduser('~/.config/soundblizzard/soundblizzard.conf'),
									'libraryfolders' : [os.path.expanduser('~/Music')], #TODO: support multiple folders
									'playlistfolder' : '~/.config/playlists',
									'databasefile' : os.path.expanduser('~/.config/soundblizzard/soundblizzard.db'),
									'mpdhost' : 'localhost',
									'mpdport' : 6600,
									'dbupdatetime' : loggy.currenttime()
								}
			
		if (not(os.path.isdir(os.path.dirname(self.config['configfile'])))):
			os.makedirs(os.path.dirname(self.config['configfile'])) or loggy.warn ('could not create config dir')
#		if (not (os.path.isfile('~/.config/soundblizzard/soundblizzard.conf')))
		fd = None
		try:
			fd = open(self.config['configfile'], 'r')#tries to open config file
		except:
			loggy.warn('Could not open config file '+ self.config['configfile'])
		try:
			self.config.update(json.load(fd)) #adds config file to dictionary and overrides with config file
		except:
			loggy.warn('Could not read config file '+ self.config['configfile'])
		
		#Handle command line arguments	
		#Splits command line args into dict, if key starts with -- then takes this as an argument and prints these
		# if key is help prints defaults
		#TODO: improve command line argument recognition
		a = sys.argv[1:]
		if len(a) % 2:
			a.append('')
		b = {a[i]: a[i+1] for i in range(0, len(a), 2)}
		c ={}
		for key in b:
			if key.startswith('--help'):
				loggy.warn ('Soundblizzard media player\nTo amend config settings please use --key \'value\' on the command line. \n Current values:')
				print json.dumps(self.config, sort_keys=True, indent=2)
				loggy.die('help delivered')
			elif key.startswith('--'):
				c[key[2:]] = b[key]

		self.config.update(c)
		loggy.log('Configuration:' +str(self.config))		
Example #12
0
	def on_message(self, bus, message):
		if message.type == gst.MESSAGE_EOS: #TODO: reorder for speed , or take signals out individually...
			self.emit('eos')#called when end of stream reached
		elif message.type == gst.MESSAGE_ERROR:
			self.reset()
			err, debug = message.parse_error()
			loggy.warn( "Player GST_MESSAGE_ERROR: " + str(err) + str(debug))
			self.emit('eos')
		elif message.type == gst.MESSAGE_STATE_CHANGED:
			if message.src == self.player:
				self.updatestate()
		elif message.type == gst.MESSAGE_STREAM_STATUS:
			#loggy.log('ss') appears to be related to buffering status
			#self.update_position()
			None
		elif message.type == gst.MESSAGE_NEW_CLOCK:
			None
		elif message.type == gst.MESSAGE_ASYNC_DONE:
			self.emit('async-done')
			loggy.log('Player Async Done')
		elif message.type == gst.MESSAGE_TAG: # thanks to http://www.jezra.net/blog/use_python_and_gstreamer_to_get_the_tags_of_an_audio_file
			taglist = message.parse_tag()
			for key in taglist.keys():
				self.tags[key] = taglist[key]
			#gst_tag_list_free()?
		elif message.type == gst.MESSAGE_DURATION:
			self.updatedur()
		elif message.type == gst.MESSAGE_QOS:
			loggy.log('QOS')
		elif message.type == gst.MESSAGE_ELEMENT:
			if message.structure is None:
				return
			message_name = message.structure.get_name()
			if message_name == "prepare-xwindow-id":
				imagesink = message.src
				loggy.warn('Player prepare-xwindow-id got')
				imagesink.set_property("force-aspect-ratio", True)
				#gtk.gdk.threads_enter()
				if self.vidout.has_key('xid'): imagesink.set_xwindow_id(self.vidout['xid'])
				#imagesink.set_xwindow_id(self.VID.window.xid)
				#gtk.gdk.threads_leave()
			elif message_name == "have-xwindow-id":
				loggy.log('have xwindow id')
			else:
				loggy.log( "Player GST message unhandled:" + str(message.type))
		else:
			loggy.warn('Player - unknown messge' + str(message.type))
Example #13
0
 def on_message(self, bus, message):
     if message.type == Gst.MessageType.EOS: #TODO: reorder for speed , or take signals out individually... see http://bazaar.launchpad.net/~jderose/+junk/gst-examples/view/head:/video-player-1.0
         self.emit('eos')#called when end of stream reached
     elif message.type == Gst.MessageType.ERROR:
         self.reset()
         err, debug = message.parse_error()
         loggy.warn( "Player GST_MESSAGE_ERROR: " + str(err) + str(debug))
         self.emit('eos')
     elif message.type == Gst.MessageType.STATE_CHANGED:
         if message.src == self.player:
             self.updatestate()
     elif message.type == Gst.MessageType.STREAM_STATUS:
         #loggy.log('ss') appears to be related to buffering status
         #self.update_position()
         None
     elif message.type == Gst.MessageType.NEW_CLOCK:
         None
     elif message.type == Gst.MessageType.ASYNC_DONE:
         self.emit('async-done')
         loggy.log('Player Async Done')
     elif message.type == Gst.MessageType.TAG: # thanks to http://www.jezra.net/blog/use_python_and_gstreamer_to_get_the_tags_of_an_audio_file
         taglist = message.parse_tag()
         #gst_tag_list_free()?
         for key in dbtags.keys():
             self.tags[key] = taglist.get_value_index(key, 0)
     elif message.type == Gst.MessageType.DURATION_CHANGED:
         self.updatedur()#could query message?
     elif message.type == Gst.MessageType.QOS:
         loggy.log('QOS')
     elif message.type == Gst.MessageType.ELEMENT:
         if message.structure is None:
             return
         message_name = message.get_structure().get_name()
         if message_name == "prepare-window-handle":
             loggy.warn('Player prepare-window-handle got')
             message.src.set_property("force-aspect-ratio", True)
             #gtk.gdk.threads_enter()
             if self.vidout.has_key('xid'): message.src.set_window_handle(self.vidout['xid'])
             #imagesink.set_xwindow_id(self.VID.window.xid)
             #gtk.gdk.threads_leave()
         elif message_name == "have-xwindow-id":
             loggy.log('have xwindow id')
         else:
             loggy.log( "Player GST message unhandled:" + str(message.type))
     elif (message.type == Gst.MessageType.STREAM_START or message.type == Gst.MessageType.RESET_TIME): None
     else:
         loggy.warn('Player - unknown message' + str(message.type))
Example #14
0
 def on_message(self, bus, message):
     #Gst.MESSAGE_TAG:thanks to http://www.jezra.net/blog/use_python_and_gstreamer_to_get_the_tags_of_an_audio_file
     #msgtype = (Gst.message_type_get_name(message.type))
     #print('message') 'TODO implement as dict rather than if elif for speed
     if ((message.type == Gst.MessageType.STREAM_STATUS) or (message.type == Gst.MessageType.STATE_CHANGED) or (message.type == Gst.MessageType.STREAM_START)):
         True
     elif (message.type == Gst.MessageType.TAG):
         print('tag MESSAGE')
         print (self.player.query_duration(Gst.Format.TIME))
         taglist = message.parse_tag()
         #other ways of accessing list are taglist.to_string() or taglist.foreach() or taglist.get_string('artist')
         for key in dbtags.keys():
             self.tags[key] = taglist.get_value_index(key, 0)
     elif (message.type == Gst.MessageType.ASYNC_DONE):   #Gst.MESSAGE_ASYNC_DONE:
         query = Gst.Query.new_duration(Gst.Format.TIME)
         print(self.playbin.query(query))
         print (self.player.query_duration(Gst.Format.TIME))
         #print (self.player.get_state(1))
         self.tags['duration'] = int ((self.playbin.query_duration(Gst.Format.TIME)[1]) / Gst.SECOND)
         #print str(self.player.query_duration(Gst.Format.TIME))
         self.tags['uri'] = self.uri
         #self.tags['date'] = self.tags['date'].year
         loggy.log('Tagger got ' + str(self.tags))
         #self.player.set_state(Gst.State.NULL)
         #TODO: replace mime types with Gstreamer alternative from Gst.extend
         self.callback()
     elif (message.type == Gst.MessageType.DURATION_CHANGED):   #Gst.MESSAGE_DURATION: ?does this ever happen
         
         self.tags['duration'] = int ((int(self.playbin.query_duration(Gst.Format.TIME)[1]) / Gst.SECOND))
         loggy.warn('got duration huzzah!') #TODO not working at present
     elif (message.type == Gst.MessageType.ERROR):   #Gst.MESSAGE_ERROR:
         err, debug = message.parse_error()
         loggy.warn( "Player GST_MESSAGE_ERROR: " + str(err) + str(debug)) #TODO: sort out unicode
         self.error = str(debug)
         if self.error:
             self.player.set_state(Gst.State.NULL)
             self.__init__()
             self.callback()
     else:
         loggy.warn( "Player GST message unhandled:" + str(message.type))
Example #15
0
try:
	import pygst, gobject, loggy, config
	pygst.require("0.10")
	import gst
except:
	loggy.warn('player - Could not find required libraries: pygst, gst, gobject, loggy, config')

class player(gobject.GObject):
	'''
	Player - gst player
	'''
	__gproperties__ = {
						'vol' : (gobject.TYPE_INT, 'volume',
						'Current volume of gstreamer pipeline',
						0, 100, 50, gobject.PARAM_READWRITE)
					   }
	__gsignals__ = {
					'async-done' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
										()),
					'hemisecond' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
										())
					}
#    def do_get_property(self, property):
#        if property.name == 'vol':
#            return self.vol
#        else:
#            raise AttributeError, 'unknown property %s' % property.name
	def do_set_property(self, property, value):
		loggy.log('player.do_set_property')
		if property.name == 'vol':
			self.vol = value
Example #16
0
try:
	import ConfigParser, os, loggy
except:
	loggy.warn('config - Could not find required libraries: ConfigParser')

class config( ConfigParser.SafeConfigParser ): #TODO: use linux format, not ini (could not find suitable python module
	def load(self):
		self.file = os.path.expanduser('~') + "/.spambox/spambox.ini"
		self.read(self.file)
	def defaults(self):
		try:
			self.add_section('Main')
		except:
			None
		self.set('Main', 'dbfile', os.path.expanduser('~') + "/.spambox/spambox.sqlite")
		self.set('Main', 'imagefile', os.path.expanduser('~') + "/.spambox/image")
		self.set('Main', 'playlistsfolder', os.path.expanduser('~') + "/Music/Playlists")
		self.set('Main', 'libraryfolders', os.path.expanduser('~') + "/Music " + os.path.expanduser('~') + "/Videos ")
		self.set('Main', 'mediatags', ' '.join(['uri', 'artist', 'title', 'album', 'date', 'genre', 'duration', 'rating']))
	def __del__(self):
		with open(self.file, 'wb') as configfile:
			self.write(configfile)

if __name__ == "__main__":
	conf = config()
	conf.load()
	conf.defaults()
Example #17
0
	def save_config(self):
		#import json
		configfd = open(self.config['configfile'], 'w') or loggy.warn('Could not open config file for writing')
		json.dump(self.config, configfd, sort_keys=True, indent=2) #or loggy.warn ('Could not write config file')
		configfd.close()
Example #18
0
	def handler(self, conn, *args):
		'''Asynchronous connection handler. Processes each line from the socket.'''
		buff = conn.recv(65536) #TODO: handle if more on conn to recieve than 4096
		if not len(buff):
			loggy.log( "mpdserver Connection closed - no input." )
			return False
		elif len(buff)>60000:
			loggy.warn('mpdserver Connection buff full, data may be lost' . buff)
		#loggy.log('MPD Server got:' +buff)
		while '\n' in buff:
			(line, buff) = buff.split("\n", 1)
			output = ''
			if not len(line):
				loggy.log( "mpdserver Connection closed - no input." )
				return False
			else:
				arg = line.strip().split(' ', 1) #strips whitespace from right and left, then splits first word off as command
				command = arg[0].lower() # prevents case sensitivity
				#TODO: reimplement using a dict?
				if (len(arg)>1): # if there are arguments to the command
					args = arg[1].strip()
				else:
					args = ''
				#Tries to recognise command
				#Playback control
				func = None
				loggy.debug('mpdserver got {0} {1}'.format(command, args))
				# Makes sure command is not internal function
				if command in self.list_of_commands:
					#loggy.warn('mpdserver attempt to access internals {0}'.format(command))
				#Searches for command in current class
					try:
						func = getattr(self, command)
					except Exception as detail:
						output = 'ACK 50@1 {{{0}}} Command not recognised\n'.format (command)
						loggy.warn('mpdserver: {0}'.format(output))
						self.queueing = False
						self.ok_queueing = False
					else:
						#Executes command
						try:
							output = func(args)
						except Exception as detail:
							output = 'ACK 50@1 {{{0}}} {1} {2} {3}\n'.format(command, detail, str(type(detail)), traceback.format_exc().replace('\n', '|')) 
							loggy.warn('mpdserver: {0}'.format(output))
							self.queueing = False
							self.ok_queueing = False
				else: # not in list_of_commands
					output = 'ACK 50@1 {{{0}}} Command not in command list\n'.format (command)
					loggy.debug('mpdserver {0} not in command list'.format(command))
				#Handles output - with respect to list queueing
				if not output:
					output = 'ACK 1@1 {{{0}}} Command returned no output - not implemented yet\n'.format(command)
					loggy.warn('mpdserver: {0}'.format(output))
				elif output.startswith('ACK'):
					self.queueing = False
					self.ok_queueing = False
					output = self.queue + output
					self.queue = ''
				if self.ok_queueing:
					#if output[-3:-1] == 'OK':
						#output = output[:-3] + 'list_OK\n'
					output = output.replace("OK", "list_OK")
					self.queue += output
					output = ''
				elif self.queueing:
					self.queue += output
					output = ''
				#send output
				if (output != None):
					loggy.debug( 'MPD Server sending: {0}'.format( output) )
					conn.send(output)
		return True
Example #19
0
try:
	import loggy, os, sqlite3, mimetypes, tagger,
except:
	loggy.warn('sbdb - Could not find required libraries: loggy, os, sqlite3, mimetypes, tagger, gobject, config')

class sbdb(object):
	keys = ('uri', 'artist', 'title', 'album', 'date', 'genre', 'duration', 'rating') # + mimetype , atime, mtime, ctime, dtime
	def __init__(self, soundblizzard):
		self.config = soundblizzard.config
		self.config.load()
		self.dbpath = self.config.get('Main', 'dbfile')
		loggy.log("Database: Loading database from " + self.dbpath)
		self.conn = sqlite3.connect(self.dbpath)
		self.curs = self.conn.cursor()
		self.conn.row_factory = sqlite3.Row
		self.keys = ('uri', 'artist', 'title', 'album', 'date', 'genre', 'duration', 'rating') # + mimetype , atime, mtime, ctime, dtime
		self.addkeys = ('mimetype', 'atime', 'mtime', 'ctime', 'dtime', 'size')
		self.totkeys = self.keys + self.addkeys
		self.conn.commit()
		#self.conn.close()
	def sqlexec(self, string):
		loggy.log('Database sqlexec:' + string)
		self.curs.execute(string) # vulnerable to sql injection attacks - should assemble strings within execute
		#self.conn.commit()
	def create_table(self, name, fields):
		self.sqlexec('create table if not exists "%s" ( "%s" )' % (name, '" , "'.join(fields)))
	def recreate_table(self, name, fields):
		self.sqlexec('drop table if exists "%s" ' % name)
		self.sqlexec('create table "%s" ("%s")' % (name, '" , "'.join(fields)))
	def insert_row(self, table, data):
		data = [str(item) for item in data]
Example #20
0
	def handler(self, conn, *args):
		'''Asynchronous connection handler. Processes each line from the socket.'''
		buffer = conn.recv(4096) #TODO: handle if more on conn to recieve than 4096
		if not len(buffer):
			loggy.log( "MPD Connection closed - no input." )
			return False
		elif len(buffer)>4000:
			loggy.warn('MPD Connection buffer full, data may be lost' . buffer)
		loggy.log('MPD Server got:' +buffer)
		while '\n' in buffer:
			(line, buffer) = buffer.split("\n", 1)
			output = ''
			if not len(line):
				loggy.log( "MPD Connection closed - no input." )
				return False
			else:
				arg = line.rstrip().lstrip().split(' ', 1) #strips whitespace from right and left, then splits first word off as command
				command = arg[0].lower() # prevents case sensitivity
				#TODO: reimplement using a dict?
				if (len(arg)>1): # if there are arguments to the command
					args = arg[1].lower().lstrip()
				else:
					args = False
				#Tries to recognise command
				#Playback control
				if command == 'play':
					self.player.play()
					output = 'OK\n'
				elif command == 'next':
					output = 'OK\n' #TODO:
				elif command == 'pause':
					self.player.pause()
					output = 'OK\n'
				elif command == 'playid':
					output = 'OK\n' #TODO:
				elif command == 'previous':
					output = 'OK\n'#TODO:
				elif command == 'seek':
					#TODO: handle songpos
					if args.isdigit() and self.player.setpos(int(args)) :
						output = 'OK\n'
					else:
						loggy.log('mpdserver - could not understand seek to ' + args)
						output = 'ACK could not understand arguments\n'
				elif command == 'seekid': #TODO:
					output = 'OK\n'
				elif command == 'stop':
					self.player.stop()
					output = 'OK\n'
				#Status
				elif command == 'clearerror':#TODO: implement
					print 'Recognised command clearerror'
					output = 'OK'
				elif command == 'currentsong':
					output += 'file: %s\n' % (self.player.filename)
					output += 'Time: %i\n' % (self.player.dursec)
					output += 'Artist: %s\n' % (self.player.tags['artist'])
					output += 'AlbumArtist: %s\n' % (self.player.tags['album-artist'])
					output += 'Title: %s\n' % (self.player.tags['title'])
					output += 'Album: %s\n' % (self.player.tags['artist'])
					output += 'Track: %s\n' % ((str(self.player.tags['track-number'])+'/'+str(self.player.tags['track-count'])))
					output += 'Date: %s\n' % (str(self.player.tags['date'].year))
					output += 'Genre: %s\n' % (self.player.tags['genre'])
					output += 'Pos: %i\n' % (1)
					output += 'Id: %i\n' % (1)
					output += 'OK\n'
				elif command == 'idle':
					output = 'changed: database update stored_playlist playlist player mixer output options sticker subscription message\nOK\n'#TODO: handle properly
				elif command == 'status':
					output += 'volume: %i\n' % (self.player.getvol())
					output += 'repeat: %i\n' % (0)
					output += 'random: %i\n' % (0)
					output += 'single: %i\n' % (0)
					output += 'consume: %i\n' % (0)
					output += 'playlist: %i\n' % (1)
					output += 'playlistlength: %i\n' % (1)
					output += 'xfade: %i\n' % (0)
					output += 'state: %s\n' % (self.player.getstate())
					output += 'song: %i\n' % (1)
					output += 'songid: %i\n' % (1)
					output += 'Time: %s\n' % (self.player.getpos())
					output += 'bitrate: %i\n' % (1)
					output += 'audio: %s\n' % ('x')
					output += 'nextsong: %i\n' % (1)
					output += 'nextsongid: %i\n' % (1)
					output += 'OK\n'
				elif command == 'stats':
					print 'Recognised status command'
					output = 'artists: %i\nalbums: %i\nsongs: %i\nuptime: %i\nplaytime: %i\ndb_playtime: %i\ndb_update: %i\nOK\n' % (1,1,1,1,1,1,1)
				#Playback Options
				elif command == 'consume':
					print 'Recognised consume command'
					if args == '0':
						output = 'OK\n'
						print 'set consume 0'
					elif args == '1':
						output = 'OK\n'
						print 'set consume 1'
					else:
						output = 'ACK [2@0] {consume} usage consume 0 or consume 1\n'
				elif command == 'crossfade':
					output = 'OK\n'
				elif command == 'mixrampdb':
					output = 'OK\n'
				elif command == 'mixrampdelay':
					output = 'OK\n'
				elif command == 'random':
					output = 'OK\n'
				elif command == 'repeat':
					output = 'OK\n'
				elif command == 'setvol':
					vol = args.strip('"')
					if vol.isdigit() and int(vol) <=100 and int(vol) >=0 and self.player.setvol(vol):
						output = 'OK\n'
					else:
						loggy.log('mpdserver - could not understand setvol to ' + args)
						output = 'ACK could not understand arguments\n'

				elif command == 'single':
					output = 'OK\n'
				elif command == 'replay_gain_mode':
					output = 'OK\n'
				elif command == 'replay_gain_status':
					output = 'OK\n'
				#Current Playlist
				elif command == 'add':
					output = 'OK\n'
				elif command == 'addid':
					output = 'OK\n'
				elif command == 'clear':
					output = 'OK\n'
				elif command == 'delete':
					output = 'OK\n'
				elif command == 'deleteid':
					output = 'OK\n'
				elif command == 'move':
					output = 'OK\n'
				elif command == 'moveid':
					output = 'OK\n'
				elif command == 'playlist':
					output = 'OK\n'
				elif command == 'playlistfind':
					output = 'OK\n'
				elif command == 'playlistid':
					output = 'OK\n'
				elif command == 'playlistinfo':
					output = 'OK\n'
				elif command == 'playlistsearch':
					output = 'OK\n'
				elif command == 'plchanges':
					self.trackdetails('file:///home/sam/Music/09 - Girl Talk - Make Me Wanna.mp3')
					output = 'OK\n'
				elif command == 'plchangesposid':
					output = 'OK\n'
				elif command == 'shuffle':
					output = 'OK\n'
				elif command == 'swap':
					output = 'OK\n'
				elif command == 'swapid':
					output = 'OK\n'
				#Stored playlists
				elif command == 'listplaylist':
					output = 'OK\n'
				elif command == 'listplaylistinfo':
					output = 'OK\n'
				elif command == 'listplaylists':
					output = 'OK\n'
				elif command == 'load':
					output = 'OK\n'
				elif command == 'playlistadd':
					output = 'OK\n'
				elif command == 'playlistclear':
					output = 'OK\n'
				elif command == 'playlistdelete':
					output = 'OK\n'
				elif command == 'playlistmove':
					output = 'OK\n'
				elif command == 'rename':
					output = 'OK\n'
				elif command == 'rm':
					output = 'OK\n'
				elif command == 'save':
					output = 'OK\n'
				#Music db
				elif command == 'count':
					output = 'OK\n'
				elif command == 'find':
					output = 'OK\n'
				elif command == 'findadd':
					output = 'OK\n'
				elif command == 'list':
					output = 'OK\n'
				elif command == 'listall':
					output = 'OK\n'
				elif command == 'listallinfo':
					output = 'OK\n'
				elif command == 'lsinfo':
					output = 'OK\n'
				elif command == 'search':
					output = 'OK\n'
				elif command == 'update':
					output = 'OK\n'
				elif command == 'rescan':
					output = 'OK\n'
				elif command == '':
					output = 'OK\n'
				#Command queueing
				elif command == 'command_list_begin':
					print 'starting queueing commands'
					loggy.warn('command_list_begin used on mpd client')
					self.queueing = True
				elif command == 'command_list_end':
					print 'ended queueing commands'
					self.queueing = False
					self.ok_queueing = False
					output = self.queue + 'OK\n'
					self.queue = ''
				elif command == 'command_list_ok_begin':
					print 'starting queueing commands'
					self.ok_queueing = True
					loggy.warn('command_list_ok_begin used on mpd client')
				#Connection
				elif command == 'close':
					conn.send('OK\n')
					conn.close()
					loggy.log('MPD Connection closed by client')
					return False
				elif command == 'ping':
					output = 'OK\n'
				elif command == 'kill':
					conn.send('OK\n')
					conn.close()
					loggy.die('MPD Client Killed spambox, weep!')
				#Output
				elif command == 'disableoutput':
					output = 'OK\n'
				elif command == 'enableoutput':
					output = 'OK\n'
				elif command == 'outputs':
					output = 'OK\n'
				#Error handler
				else:
					loggy.log(''.join(['MPD Interface - Unrecognised Command (Perhaps a newer client version?) :', command,':']))
					output += 'ACK Unrecognised Command\n'
					self.queueing = False
					self.ok_queueing = False
				#TODO: reflection, stickers, client to client
				#Respond to client
				if self.ok_queueing:
					#if output[-3:-1] == 'OK':
						#output = output[:-3] + 'list_OK\n'
					output.replace("OK", "list_OK")
					self.queue += output
					output = ''
				elif self.queueing:
					self.queue += output
					output = ''
				loggy.log( 'MPD Server sending:' + output )
				conn.send(output)
				#TODO: if error
		return True
Example #21
0
'''
Created on 20 Mar 2011

@author: sam
'''
try:
	import socket, gobject, loggy, player
except:
	loggy.warn('Could not find required libraries: socket gobject loggy player')

class mpdserver(object):
	'''
	MPD Server Class - creates MPD Server connection
	Settings - self.port = tcp_port
	self.host = tcp_host
	'''
	def __init__(self, gst_obj):
		'''
		'''
		self.queue = ''
		self.queueing = False
		self.ok_queueing = False
		self.player = gst_obj
	def startserver(self, host, port):
		self.host = host
		self.port = port
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		self.sock.bind((self.host, self.port)) #TODO: check port empty first
		self.sock.listen(1)
		loggy.log('MPD Server Interface Running on ' + host + ':' + str(port) )
Example #22
0
try:
    import loggy, player, gobject
except:
    loggy.warn("Could not find required libraries: loggy, player, gobject")


class playlist(object):
    def __init__(self, player):
        self.player = player
        self.playlist = []
        self.random = False
        self.repeat = True
        self.player.bus.connect("message::eos", self.get_next)
        self.load_playlist("ben")
        self.get_next()

    def load_playlist(self, filename):
        self.playlist = [
            "file:///data/Music/Alien Ant Farm/ANThology/01 Courage.mp3",
            "file:///data/Music/Armand Van Helden/NYC Beat/02 - NYC Beat (Original).mp3",
            "file:///data/Music/Various Artists/Reloaded 4/13. Flavor Of The Weak.mp3",
        ]
        self.position = -1
        self.get_next()

    def get_next(self):
        if self.random:
            True
        else:
            self.position += 1
            if self.position >= (len(self.playlist)):
Example #23
0
try:
	import pygst
	pygst.require("0.10")
	import gst
	import gobject
	import loggy
	import datetime
except:
	loggy.warn('Could not find required libraries: pygst, gst, gobject, datetime')

class gstr(object):
	'''
	Player - gst player
	'''
	def __init__(self):
		self.player = gst.element_factory_make("playbin", "player")
		#self.vis = gst.element_factory_make("goom", "vis")
		self.bus = self.player.get_bus()
		self.bus.add_signal_watch()
		self.bus.enable_sync_message_emission()
		self.bus.connect("message", self.on_message)
		self.bus.connect("sync-message::element", self.on_sync_message)
		self.reset
	def load_file(self, filename):
		self.reset()
		loggy.log( "Player loading " + filename )
		self.player.set_property("uri", "file://" + filename)
		#self.player.set_state(gst.STATE_PLAYING)
		self.player.set_state(gst.STATE_PAUSED)
		#self.player.set_property("vis-plugin", self.vis)
	def reset(self):
Example #24
0
    def __init__(self, sb):
        GObject.GObject.__init__(self)
        self.sb = soundblizzard.soundblizzard  # fakes for tab completion
        self.sb = sb

        # self.config = soundblizzard.config.config #provides direct access to config dictionary
        if not (os.path.isdir(os.path.dirname(self.sb.config.config["databasefile"]))):
            loggy.warn("Creating directories for requested database file")
            os.makedirs(os.path.dirname(self.sb.config.config["databasefile"])) or loggy.warn(
                "...could not create config dir"
            )
        self.dbpath = self.sb.config.config["databasefile"]
        loggy.log("Database: Loading database from " + self.dbpath)
        if loggy.debug:
            sqlite3.enable_callback_tracebacks(True)
        self.conn = sqlite3.connect(self.dbpath) or loggy.warn("Could not connect to database")
        self.conn.row_factory = sqlite3.Row
        self.curs = self.conn.cursor()
        self.curs.row_factory = sqlite3.Row
        self.keys = (
            "artist",
            "title",
            "album",
            "date",
            "genre",
            "duration",
            "rating",
            "album-artist",
            "track-count",
            "track-number",
            "mimetype",
            #'atime',
            "mtime",
            #'ctime',
            #'dtime',
            #'size',
            "uri",
            "songid",
        )  # songid must be last as it's the primary key
        self.blanktags = {
            "artist": "",
            "title": "",
            "album": "",
            "date": 0,
            "genre": "",
            "duration": 0,
            "rating": 0,
            "album-artist": "",
            "track-count": 1,
            "track-number": 1,
            "mimetype": "",
            #'atime':0,
            "mtime": 0,
            #'ctime':0,
            #'dtime':0,
            #'size':0,
            "uri": "",
            "songid": None,
        }

        # self.keys = self.blanktags.keys()[0:10]#('uri', 'artist', 'title', 'album', 'date', 'genre', 'duration', 'rating','album-artist', 'track-count', 'track-number') # + mimetype , atime, mtime, ctime, dtime #TODO:autogenerate from blank dict
        # self.addkeys = self.blanktags.keys()[10:] #('mimetype', 'atime', 'mtime', 'ctime', 'dtime', 'size')
        # self.totkeys = self.keys + self.addkeys +('songid',)
        # 		self.blanktags = {} # creates blank key set so no type errors when key looked up does not exist
        # 		for key in self.totkeys:
        # 			self.blanktags[key] = None # TODO: move gubbins to config
        # 		self.conn.commit()
        # TODO: check database is okay, contains tables and necessary fields etc.
        try:
            self.curs.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='media'")
            self.curs.execute("SELECT * from 'media'")
        except sqlite3.OperationalError:
            loggy.log("Database: no media table, recreating")
            self.recreate_media_table()
Example #25
0
	def on_sync_message(self):
		loggy.warn('Player got sync message, unhandled')
Example #26
0
#!/usr/bin/env python
#try:
try:
	import gi, loggy, player
	gi.require_version('Gst', '1.0')
	from gi.repository import GObject, Gst, Gtk, GdkPixbuf, GdkX11, GstVideo
except:
	loggy.warn('Gui could not import required libraries')
# import soundblizzard
# import player, loggy, gst, cairo, aspectimage
# from gi.repository import Gtk
# from gi.repository import GdkPixbuf
# from gi.repository import GdkX11
# from gi.repository import GObject
#TODO: look at kiwi for pygtk lists etc.
#pyGtk.require("2.0")
#except:
#	print "gui - Required libraries not found - pyGtk, Gtk, player, loggy, gst, sbdb! Please install\n"
#TODO: while gtk.gtk_events_pending(): gtk.gtk_main_iteration() - does this work?
class GTKGui(object):
	def __init__(self, sb):
		loggy.log('Gui loading...')
		#self.play_buttons = []
		#self.progress_bars    = []
		#self.position_labels    = []
		self.volume_scales =[]
		#self.info_labels = []
		self.album_arts = []
		self.main_trees = []
		self.slave_windows = []
		self.main_tree_modes = {}
Example #27
0
#!/usr/bin/python

try:
    import gi, loggy
    #gi.require_version('Gst', '1.0')
    from gi.repository import GObject, Gst
except:
    loggy.warn('Tagger 3 could not import required libraries')

GObject.threads_init()
Gst.init(None)

dbtags = {'artist':'',
        'title':'',
        'album':'',
        'date':0, 
        'genre':'', 
        'duration':0, 
        'rating':0,
        'album-artist':'', 
        'track-count':1, 
        'track-number':1,
        #'mimetype':'', 
        #'atime':0, 
        #'mtime':0, 
        #'ctime':0, 
        #'dtime':0, 
        #'size':0,
        #'uri':'',
        #'songid':None
        }