audiogen_mostrecent.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import os
  2. import logging
  3. import shutil
  4. import time
  5. from tempfile import mkstemp
  6. import fnmatch
  7. from pytimeparse.timeparse import timeparse
  8. def scan_dir(dirname, extension=None):
  9. if extension is None:
  10. extension = '*'
  11. for root, dirnames, filenames in os.walk(dirname):
  12. for fname in fnmatch.filter(filenames, extension):
  13. yield os.path.join(root, fname)
  14. def get_mtime(fname):
  15. return int(os.path.getmtime(fname))
  16. def recent_choose(paths, howmany, minepoch):
  17. found_files = {}
  18. for path in paths:
  19. if not os.path.exists(path):
  20. logging.warn("Can't find requested path: %s" % path)
  21. continue
  22. if os.path.isfile(path):
  23. found_files[path] = get_mtime(path)
  24. elif os.path.isdir(path):
  25. found_files.update({fname: get_mtime(fname)
  26. for fname in scan_dir(path)})
  27. found_files = [(fname, mtime)
  28. for (fname, mtime) in found_files.items()
  29. if mtime >= minepoch]
  30. return [fname for fname, mtime in
  31. sorted(found_files, key=lambda x: x[1])[:howmany]]
  32. def generate(spec):
  33. '''
  34. resolves audiospec-randomdir
  35. Recognized arguments:
  36. - path [mandatory] source dir
  37. - maxage [default=ignored] max age of audio files to pick
  38. '''
  39. for attr in ('path', 'maxage'):
  40. if attr not in spec:
  41. raise ValueError("Malformed audiospec: missing '%s'" % attr)
  42. if spec['maxage'].strip():
  43. try:
  44. maxage = int(spec['maxage'])
  45. except ValueError:
  46. maxage = timeparse(spec['maxage'])
  47. if maxage is None:
  48. raise ValueError("Unknown format for maxage: '{}'"
  49. .format(spec['maxage']))
  50. assert type(maxage) is int
  51. else:
  52. maxage = None
  53. now = int(time.time())
  54. minepoch = 0 if maxage is None else now - maxage
  55. picked = recent_choose([spec['path']], 1, minepoch)
  56. for path in picked:
  57. tmp = mkstemp(suffix=os.path.splitext(path)[-1],
  58. prefix='audiogen-randomdir-')
  59. os.close(tmp[0])
  60. shutil.copy(path, tmp[1])
  61. yield 'file://{}'.format(tmp[1])
  62. generate.description = 'Select most recent file inside a directory'