/examples/shell/remix.py

http://echo-nest-remix.googlecode.com/ · Python · 154 lines · 120 code · 20 blank · 14 comment · 25 complexity · 4b5eb69f682219327102b39398653837 MD5 · raw file

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. """
  4. shell.py
  5. Created by Adam on 2009-11-22.
  6. Copyright (c) 2009 . All rights reserved.
  7. """
  8. import sys
  9. import cmd
  10. import os.path
  11. import subprocess
  12. import tempfile
  13. import glob
  14. import types
  15. from optparse import OptionParser
  16. from echonest.audio import *
  17. from echonest.audio import AudioQuantumList as aql
  18. from echonest.audio import AudioQuantum as aq
  19. from echonest.selection import *
  20. from echonest.sorting import *
  21. USAGE = '''
  22. %prog [options] [filename]
  23. Optional filename pre-loads the file.
  24. '''
  25. def main(argv=None):
  26. if argv is None:
  27. argv = sys.argv
  28. parser = OptionParser(usage=USAGE)
  29. parser.add_option("-q", "--quiet",
  30. action="store_false", dest="verbose", default=True,
  31. help="try to suppress messages")
  32. parser.add_option("-v", "--verbose", action="store_true", dest="verbose")
  33. (options, args) = parser.parse_args()
  34. r = Remix()
  35. r.options = options
  36. r.args = args
  37. r.cmdloop()
  38. class Remix(cmd.Cmd):
  39. """Loop while keeping track of the last thing."""
  40. prompt = "(no file) > "
  41. currfile = None
  42. currfilename = ""
  43. cwd = ""
  44. env = dict()
  45. renderable = None
  46. renderablename = ""
  47. options = dict()
  48. args = list()
  49. def do_EOF(self, line):
  50. return True
  51. def preloop(self):
  52. if self.args:
  53. self.do_load(self.args[0])
  54. self.cwd = os.getcwd()
  55. def postloop(self):
  56. print
  57. def default(self, line):
  58. """execute a command"""
  59. self.execute(line)
  60. def do_play(self, line):
  61. """plays the current buffer or a given filename"""
  62. if not line:
  63. if self.renderable and not self.renderablename:
  64. foo, line = tempfile.mkstemp(".wav")
  65. self.renderablename = line
  66. self.renderable.encode(self.renderablename)
  67. elif self.renderablename:
  68. line = self.renderablename
  69. if not line:
  70. print "nothing to play"
  71. return
  72. CMD = ["qlmanage", '-p', line]
  73. pid=subprocess.Popen(CMD, stderr=subprocess.PIPE).pid
  74. def do_load(self, path):
  75. """loads the requested file (or directory)"""
  76. if os.path.isdir(path):
  77. self.cwd = os.path.abspath(path)
  78. os.chdir(self.cwd)
  79. else:
  80. try:
  81. self.currfile = LocalAudioFile(path, verbose=self.options.verbose)
  82. except:
  83. print "unable to load %s" % path
  84. return
  85. self.currfilename = os.path.abspath(path)
  86. self.prompt = "%s > " % os.path.basename(self.currfilename)
  87. self.renderable = self.currfile
  88. self.renderablename = self.currfilename
  89. self.env['segments'] = self.currfile.analysis.segments
  90. self.env['sections'] = self.currfile.analysis.sections
  91. self.env['beats'] = self.currfile.analysis.beats
  92. self.env['bars'] = self.currfile.analysis.bars
  93. self.env['tatums'] = self.currfile.analysis.tatums
  94. self.env['analysis'] = self.currfile.analysis
  95. self.env['_'] = None
  96. def complete_load(self, text, line, begidx, endidx):
  97. l = line.split(None, 1)[1]
  98. wav = [os.path.basename(f) for f in glob.glob("%s*.wav" % l)]
  99. mp3 = [os.path.basename(f) for f in glob.glob("%s*.mp3" % l)]
  100. dirs = [os.path.basename(d) + '/' for d in glob.glob("%s*" % l) if os.path.isdir(d)]
  101. return mp3 + wav + dirs
  102. def do_save(self, line):
  103. """saves to the designated filename in the current directory"""
  104. if not line:
  105. print "missing filename"
  106. return
  107. if not self.renderable:
  108. print "nothing to save"
  109. self.renderable.encode(line)
  110. print "saved as " + os.path.abspath(os.path.join(os.getcwd(), line))
  111. def execute(self, rawcmd):
  112. try:
  113. result = eval(rawcmd, globals(), self.env)
  114. except:
  115. print "syntax error"
  116. return
  117. if isinstance(result, tuple) or isinstance(result, dict) or isinstance(result, types.StringTypes):
  118. print result
  119. return
  120. try:
  121. if not isinstance(result, AudioRenderable):
  122. self.renderable = AudioQuantumList(result, source=self.currfile)
  123. self.renderable.attach(None)
  124. else:
  125. self.renderable = result
  126. self.renderablename = ""
  127. self.env['_'] = self.renderable
  128. except TypeError:
  129. print result
  130. if __name__ == "__main__":
  131. sys.exit(main())
  132. # Remix().cmdloop()