You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.py 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import os
  2. from subprocess import PIPE, Popen
  3. from django.apps import apps as installed_apps
  4. from django.utils.crypto import get_random_string
  5. from django.utils.encoding import DEFAULT_LOCALE_ENCODING
  6. from .base import CommandError, CommandParser
  7. def popen_wrapper(args, stdout_encoding='utf-8'):
  8. """
  9. Friendly wrapper around Popen.
  10. Return stdout output, stderr output, and OS status code.
  11. """
  12. try:
  13. p = Popen(args, shell=False, stdout=PIPE, stderr=PIPE, close_fds=os.name != 'nt')
  14. except OSError as err:
  15. raise CommandError('Error executing %s' % args[0]) from err
  16. output, errors = p.communicate()
  17. return (
  18. output.decode(stdout_encoding),
  19. errors.decode(DEFAULT_LOCALE_ENCODING, errors='replace'),
  20. p.returncode
  21. )
  22. def handle_extensions(extensions):
  23. """
  24. Organize multiple extensions that are separated with commas or passed by
  25. using --extension/-e multiple times.
  26. For example: running 'django-admin makemessages -e js,txt -e xhtml -a'
  27. would result in an extension list: ['.js', '.txt', '.xhtml']
  28. >>> handle_extensions(['.html', 'html,js,py,py,py,.py', 'py,.py'])
  29. {'.html', '.js', '.py'}
  30. >>> handle_extensions(['.html, txt,.tpl'])
  31. {'.html', '.tpl', '.txt'}
  32. """
  33. ext_list = []
  34. for ext in extensions:
  35. ext_list.extend(ext.replace(' ', '').split(','))
  36. for i, ext in enumerate(ext_list):
  37. if not ext.startswith('.'):
  38. ext_list[i] = '.%s' % ext_list[i]
  39. return set(ext_list)
  40. def find_command(cmd, path=None, pathext=None):
  41. if path is None:
  42. path = os.environ.get('PATH', '').split(os.pathsep)
  43. if isinstance(path, str):
  44. path = [path]
  45. # check if there are funny path extensions for executables, e.g. Windows
  46. if pathext is None:
  47. pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD').split(os.pathsep)
  48. # don't use extensions if the command ends with one of them
  49. for ext in pathext:
  50. if cmd.endswith(ext):
  51. pathext = ['']
  52. break
  53. # check if we find the command on PATH
  54. for p in path:
  55. f = os.path.join(p, cmd)
  56. if os.path.isfile(f):
  57. return f
  58. for ext in pathext:
  59. fext = f + ext
  60. if os.path.isfile(fext):
  61. return fext
  62. return None
  63. def get_random_secret_key():
  64. """
  65. Return a 50 character random string usable as a SECRET_KEY setting value.
  66. """
  67. chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
  68. return get_random_string(50, chars)
  69. def parse_apps_and_model_labels(labels):
  70. """
  71. Parse a list of "app_label.ModelName" or "app_label" strings into actual
  72. objects and return a two-element tuple:
  73. (set of model classes, set of app_configs).
  74. Raise a CommandError if some specified models or apps don't exist.
  75. """
  76. apps = set()
  77. models = set()
  78. for label in labels:
  79. if '.' in label:
  80. try:
  81. model = installed_apps.get_model(label)
  82. except LookupError:
  83. raise CommandError('Unknown model: %s' % label)
  84. models.add(model)
  85. else:
  86. try:
  87. app_config = installed_apps.get_app_config(label)
  88. except LookupError as e:
  89. raise CommandError(str(e))
  90. apps.add(app_config)
  91. return models, apps
  92. def get_command_line_option(argv, option):
  93. """
  94. Return the value of a command line option (which should include leading
  95. dashes, e.g. '--testrunnner') from an argument list. Return None if the
  96. option wasn't passed or if the argument list couldn't be parsed.
  97. """
  98. parser = CommandParser(add_help=False, allow_abbrev=False)
  99. parser.add_argument(option, dest='value')
  100. try:
  101. options, _ = parser.parse_known_args(argv[2:])
  102. except CommandError:
  103. return None
  104. else:
  105. return options.value