Exemple #1
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))		
	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