Procura músicas em diretório local
Publicado por Vanderson Lucio Rodrigues 20/10/2006
[ Hits: 6.715 ]
Homepage: http://www.vandersongold.com.br
Esse programa procura por dado nome de arquivo de áudio dentro de um diretório local. Ele usa coisas bem legais como: XML (configuração), logs, etc.
Bem útil pra quem tem muitos mp3 e quer encontrar uma específica rapidamente.
[]'s
#!/usr/bin/python """ Usage: musicfind <options> <keywords> .... Example: musicfind beatles let it be Searches all mp3 files with the _all_ specified keywords, generates a playlist and execute it. $Author: vanderson $ $Date: 2006/06/03 02:06:35 $ """ import sys import time import string from tempfile import mkstemp import os import libxml2 from UserDict import UserDict # ----------------------- def stripnulls(data): "strip whitespace and nulls" return data.replace("{FONTE}0", " ").strip() class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None): UserDict.__init__(self) self["name"] = filename class MP3FileInfo(FileInfo): "store ID3v1.0 MP3 tags" tagDataMap = {"title" : ( 3, 33, stripnulls), "artist" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "year" : ( 93, 97, stripnulls), "comment" : ( 97, 126, stripnulls), "genre" : (127, 128, ord)} def __parse(self, filename): "parse ID3v1.0 tags from MP3 file" self.clear() try: fsock = open(filename, "rb", 0) try: fsock.seek(-128, 2) tagdata = fsock.read(128) finally: fsock.close() if tagdata[:3] == 'TAG': for tag, (start, end, parseFunc) in self.tagDataMap.items(): self[tag] = parseFunc(tagdata[start:end]) except IOError: pass def __setitem__(self, key, item): if key == "name" and item: self.__parse(item) FileInfo.__setitem__(self, key, item) # -------------------------------------------------------- def log_message(msg): """ Prints message string and executing necessary treatment """ try: print msg except UnicodeEncodeError, e: print e class ConfigEnv: """ classe de testes """ root_folder = "" player = "" playlist_filename = "" bla = [] def __init__(self, directory=os.path.join(os.path.expanduser("~"), ".music"), \ confile ="config.xml"): ##FIXME it seems that the logic is 'wrong', but it's working. if not os.path.exists(directory): log_message("creating dir %s ..." % directory) os.mkdir(directory) filename = os.path.join(directory, confile) if not os.path.isfile(filename): log_message("creating a file %s ..." % filename) try: f = open(filename, 'a') try: f.write("<?xml version=\"1.0\"?>\n") f.write("<musicinfo>\n") f.write(" <commom>\n") f.write(" <rootfolder>/extra/mp3</rootfolder>\n") f.write(" <player>xmms</player>\n") f.write(" <playerlist>%s/playlist.m3u</playerlist>\n" % directory) f.write(" </commom>\n") f.write("</musicinfo>\n") finally: f.close except IOError, e: log_message(e) #FIXME the method loadXml is just working if open the file 'filename' before. f = open(filename, "r") f.close() (self.__class__.root_folder, self.__class__.player, self.__class__.playerlist) = self.loadXml(filename) def parseStory (self,cur): list_return = [] cur = cur.children while cur != None: if cur.name == "player": list_return.append(cur.getContent()) if cur.name == "playerlist": list_return.append(cur.getContent()) if cur.name == "rootfolder": list_return.append(cur.getContent()) cur = cur.next # root_folder, player, playerlist return list_return def loadXml(self, filename): list_return = [] doc = libxml2.parseFile(filename) if doc == None: log_message("Document not parsed successfully.") doc.freeDoc() sys.exit(1) cur = doc.getRootElement() if cur.name != "musicinfo": log_message("Document of the wrong type, root node != story") doc.freeDoc() sys.exit(1) cur = cur.children while cur != None: if cur.name == "commom": list_return = self.parseStory(cur) cur = cur.next return list_return def findFiles(directory, keylist): """ Gets a list of files in the directory (and subdirectories) with contains all the keywords in 'keylist' at the filename """ filenames = [] for (path, dname, fnames) in os.walk(directory): for filename in fnames: # for each filename, check if it contains all the keywords lowercase = string.lower(filename) if lowercase.endswith(".mp3"): for keyword in keylist: if not keyword in lowercase: break # all keywords were found: add to the result list filenames.append(os.path.join(path, filename)) return filenames def makePlaylist(fileList, playlist): """ Generates a playlist file for the filenames at fileList """ playlist = open(playlist, "w") #create the file playlist.write("#EXTM3U\n") #add the standard header for file in fileList: playlist.write(file + "\n") #add the items playlist.close() def playIt(opt, player, playlist): """ Execute the playlist. """ opt = " ".join(opt) command = " ".join([player, opt, playlist, "&"]) os.popen(command) def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]): "get file info class from filename extension" subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:] return hasattr(module, subclass) and getattr(module, subclass) or FileInfo def main(): """ Program main function. """ import getopt def usage(): print "Usage: \n" \ " %s [options] <keywords>\n" \ " Where option are: \n" \ " -v --verbose verbose mode. Messages are printed into stdout instead the log file.\n" \ " -h --help display this help.\n" \ " -e --enqueque don't clear the playlist" \ % os.path.basename(sys.argv[0]) conf = ConfigEnv() conf.__init__ print "-" * 70 print "Searches all mp3 files with the _all_ specified keywords, generates\n" \ "a playlist and execute." print "-" * 70 print try: options, args = getopt.getopt(sys.argv[1:], 'hve', ['help', 'verbose', 'enqueque']) except getopt.GetoptError, e: usage() sys.exit(2) verbose = False; opt = "" for opt, value in options: if opt == '-v' or opt == '--verbose': verbose = True; elif opt == '-e' or opt == '--enqueque': pass elif opt == '-h' or opt == '--help': usage() else: usage() logfile = None if not verbose: t = time.localtime() logfile = mkstemp(suffix='.log', prefix='musicfind.%d-%02d-%02d.' %(t[0],t[1],t[2]), dir='/tmp') os.dup2(logfile[0], 2) os.dup2(logfile[0], 1) log_message("Starting %s..." % os.path.basename(sys.argv[0])) # get the keywords to search for the mp3s # if we don't use string.lower the user will never find # anything if it puts a uppercase letter in any of the # keywords. keylist = [string.lower(x) for x in args if x not in opt] print "Looking for mp3 files with the keyword(s): %s ..." % keylist files = findFiles(conf.root_folder, keylist) #print "Founds files:\n%s" % "\n".join(([os.path.basename(x) for x in files])) #for file in files: # info["name"] = file #print "\n".join(["%s=%s" % (k, v) for k, v in info.items()]) for info in [getFileInfoClass(f)(f) for f in files]: log_message("\n".join(["%s=%s" % (k, v) for k, v in info.items()])) print if files: print "Finished! Found %d file(s). So, let's play!" % len(files) makePlaylist(files, conf.playerlist) playIt(opt, conf.player, conf.playerlist) else: log_message("Didn't find anything :-( Did you mispell it?") if __name__ == '__main__': main()
Mensagem Randômica ao Conectar via SSH
Validador de cartão de crédito
Plano de fundo rotatório no Gnome
Nenhum comentário foi encontrado.
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Flatpak: remover runtimes não usados e pacotes
Mudar o gerenciador de login (GDM para SDDM e vice-versa) - parte 2
Como atualizar o Debian 8 para o 10 (10)
Dica sobre iptables ACCEPT e DROP (6)
NGNIX - Aplicar SNAT para evitar roteamento assimetrico (29)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta