Procura músicas em diretório local
Publicado por Vanderson Lucio Rodrigues 20/10/2006
[ Hits: 7.143 ]
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()
Adição de chaves a repositórios
Gerador de números para Mega-Sena
Nenhum comentário foi encontrado.
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
[Resolvido] VirtualBox can't enable the AMD-V extension
Como verificar a saúde dos discos no Linux
Como instalar , particionar, formatar e montar um HD adicional no Linux?
Como automatizar sua instalação do Ubuntu para desenvolvimento de software.
Não consigo instalar distro antiga no virtualbox nem direto no hd (11)
Quais os códigos mais dificeis que vcs sabem fazer? (12)
systemd-resol... precisa ser reiniciado periodicamente [RESOLVIDO] (7)









