Procura músicas em diretório local

Publicado por Vanderson Lucio Rodrigues 20/10/2006

[ Hits: 6.395 ]

Homepage: http://www.vandersongold.com.br

Download musicfind.py




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

  



Esconder código-fonte

#!/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()

Scripts recomendados

Verificador de números primos

Script para screen shot

Previsão do tempo - Py3K

Conversor de Temperaturas Kelvin Celsius e Fahrenheit

Interface para qemu


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts