utils.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. from __future__ import unicode_literals
  2. import os
  3. from subprocess import PIPE, Popen
  4. import sys
  5. from django.utils.encoding import force_text, DEFAULT_LOCALE_ENCODING
  6. from django.utils import six
  7. from .base import CommandError
  8. def popen_wrapper(args, os_err_exc_type=CommandError):
  9. """
  10. Friendly wrapper around Popen.
  11. Returns stdout output, stderr output and OS status code.
  12. """
  13. try:
  14. p = Popen(args, shell=False, stdout=PIPE, stderr=PIPE,
  15. close_fds=os.name != 'nt', universal_newlines=True)
  16. except OSError as e:
  17. six.reraise(os_err_exc_type, os_err_exc_type('Error executing %s: %s' %
  18. (args[0], e.strerror)), sys.exc_info()[2])
  19. output, errors = p.communicate()
  20. return (
  21. output,
  22. force_text(errors, DEFAULT_LOCALE_ENCODING, strings_only=True),
  23. p.returncode
  24. )
  25. def handle_extensions(extensions=('html',), ignored=('py',)):
  26. """
  27. Organizes multiple extensions that are separated with commas or passed by
  28. using --extension/-e multiple times. Note that the .py extension is ignored
  29. here because of the way non-*.py files are handled in make_messages() (they
  30. are copied to file.ext.py files to trick xgettext to parse them as Python
  31. files).
  32. For example: running 'django-admin makemessages -e js,txt -e xhtml -a'
  33. would result in an extension list: ['.js', '.txt', '.xhtml']
  34. >>> handle_extensions(['.html', 'html,js,py,py,py,.py', 'py,.py'])
  35. set(['.html', '.js'])
  36. >>> handle_extensions(['.html, txt,.tpl'])
  37. set(['.html', '.tpl', '.txt'])
  38. """
  39. ext_list = []
  40. for ext in extensions:
  41. ext_list.extend(ext.replace(' ', '').split(','))
  42. for i, ext in enumerate(ext_list):
  43. if not ext.startswith('.'):
  44. ext_list[i] = '.%s' % ext_list[i]
  45. return set(x for x in ext_list if x.strip('.') not in ignored)
  46. def find_command(cmd, path=None, pathext=None):
  47. if path is None:
  48. path = os.environ.get('PATH', '').split(os.pathsep)
  49. if isinstance(path, six.string_types):
  50. path = [path]
  51. # check if there are funny path extensions for executables, e.g. Windows
  52. if pathext is None:
  53. pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD').split(os.pathsep)
  54. # don't use extensions if the command ends with one of them
  55. for ext in pathext:
  56. if cmd.endswith(ext):
  57. pathext = ['']
  58. break
  59. # check if we find the command on PATH
  60. for p in path:
  61. f = os.path.join(p, cmd)
  62. if os.path.isfile(f):
  63. return f
  64. for ext in pathext:
  65. fext = f + ext
  66. if os.path.isfile(fext):
  67. return fext
  68. return None