import socket from thread import start_new_thread from traceback import print_exc import codecs import os from mutagen.easyid3 import EasyID3 from clSettings import Settings VERSION='0.1' MUSIC_DIRECTORY="music_directory" ENCODING="UTF-8" class server: ssocket=None _sockets=[] def __init__(self): self._jmpd=jmpd() self._sockets=[] def start(self, port, type=socket.SOCK_STREAM): try: self.ssocket=socket.socket(socket.AF_INET, type) self._start_server(port) except: print_exc() return def _start_server(self, port): self.ssocket.bind(('localhost', port)) self.ssocket.listen(5) self.ssocket.settimeout(None) print("Started jmpd v%s" % (VERSION)) while True: csock,caddr=self.ssocket.accept() self._sockets.append(csock) #start_new_thread(self.handle, (csock, caddr)) self.handle(csock, caddr) def _read(self, file): line="" while line=="": line=file.readline() return line.strip() def _write(self, file, line): file.write("%s\n" % (line)) def handle(self, csocket, caddr): print("Incoming connection from %s" % (str(caddr))) file=csocket.makefile('rw', 0) self._write(file, 'hello jmpd %s'%(VERSION)) try: while True: line=self._read(file) print line except: print_exc() def closeAll(self): for socket in self._sockets: socket.close() def _getName(line): return line[0:line.find(': ')] def _getValue(line): return line[line.find(': ')+2:] tags=['title', 'artist', 'album', 'tracknumber', 'genre'] class jmpd: _lib=None # library _settings=None def __init__(self): self._lib=[] self._settings=Settings("mpdconf") self.readLib() def writeLib(self): all_tags=tags encoding=ENCODING tags.append('filename') fout=codecs.open(self._settings.get("db_file"), mode='w', encoding=encoding) fout.write("# jmpd\n") fout.write("begin info\n") fout.write("encoding: %s\n" % (encoding)) fout.write("jmpd: %s\n" % (VERSION)) fout.write("end info\n") fout.write("\n") fout.write("begin library\n") cur_path="" for entry in self._lib: if entry['path']!=cur_path: fout.write("set path: %s\n" % entry['path']) cur_path=entry['path'] fout.write("begin file\n") for tag in all_tags: if tag in entry: fout.write("%s: %s\n" % (tag, entry[tag])) fout.write("end file\n") fout.write("end library\n") fout.close() def readLib(self): """Restore the library from file""" db_file=self._settings.get("db_file") encoding=ENCODING if os.path.exists(db_file)==False: self._lib=[] return # we first open the file in ASCII-mode, and read on till the real encoding # then we reopen it in that encoding fin=open(db_file, 'r') fin.close() fin=codecs.open(db_file, mode='r', encoding=encoding) self._readLine(fin) # begin info encoding=_getValue(self._readLine(fin)) version=_getValue(self._readLine(fin)) if version!=VERSION: raise Exception("Invalid database file") self._readNext(fin, 'end info') self._readNext(fin, 'begin library') cur_path="" while True: line=self._readLine(fin) if line=="end library": break if _getName(line)=="set path: ": cur_path=_getValue(line) elif line=="begin file": self._readFile(fin, cur_path, encoding) fin.close() def _readFile(self, fin, cur_path, encoding): """Read the data for a file""" entry={'filepath': cur_path} line="" while line!="end file": line=self._readLine(fin) if line.find(': ')>0: entry[_getName(line)]=_getValue(line) self._lib.append(entry) def _readEnd(self, fin, section): """Read the next line containing an end section""" line="" while line!="end %s"%(section): line=self._readLine(fin) return line def _readBegin(self, fin, section): """Read the next line containing a begin section""" line="" while line!="begin %s"%(section): line=self._readLine(fin) return line def _readNext(self, fin, find): line="" while line!=find: line=self._readLine(fin) return line def _readLine(self, fin): """Reads the next line having characters and not being a commented line""" ret="\n" try: while ret=="\n" or ret[0]=='#': ret=fin.readline() except: pass if len(ret)==0: raise Exception("EOF") return ret.strip() def update(self): """Look for songs in the music_directory""" self._lib=[] for dir in self._settings.get(MUSIC_DIRECTORY).split(":"): self._update_rec(dir) self.writeLib() def _update_rec(self, path): subdirs=[] for filename in os.listdir(path): filepath="%s/%s"%(path,filename) if os.path.isdir(filepath): subdirs.append(filepath) if filename[-4:]==".mp3": audio=EasyID3(filepath) entry = {'path': path.decode(ENCODING) , 'filename': filename.decode(ENCODING) } for tag in tags: try: value=str(audio[tag]) entry[tag]=value[3:-2] except: entry[tag]='' self._lib.append(entry) for subdir in subdirs: self._update_rec(subdir) from test import port s=server() s.start(port)