Procura músicas em diretório local

Publicado por Vanderson Lucio Rodrigues 20/10/2006

[ Hits: 6.128 ]

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

Cálculo de um número binomial

Gerador de cartão de crédito com Tkinter

ISOsync_pt-BR.py - Um Baixador Automático de ISOs de Sabayon, escrito em Python

Script para Away com varias funções para xchat.

Conversor 2


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts