Procura músicas em diretório local
Publicado por Vanderson Lucio Rodrigues 20/10/2006
[ Hits: 7.020 ]
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()
Validador de cartão de crédito
Sugestão aleatória de filmes e séries para assistir por streaming
Nenhum comentário foi encontrado.
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Atualizando o Fedora 42 para 43
Como saber se o seu e-mail já teve a senha vazada?
Como descobrir se a sua senha já foi vazada na internet?
Mint Xfce não mantém a conexão no wi-fi (2)
Problemas com Driver NVIDIA (5)
Warcraft II Remastered no Linux? (8)









