Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. from __future__ import absolute_import
  2. import os
  3. from os.path import join, exists
  4. import shutil
  5. import logging
  6. import textwrap
  7. import oscar
  8. def create_local_app_folder(local_app_path):
  9. if exists(local_app_path):
  10. raise ValueError(
  11. "There is already a '%s' folder! Aborting!" % local_app_path)
  12. for folder in subfolders(local_app_path):
  13. if not exists(folder):
  14. os.mkdir(folder)
  15. init_path = join(folder, '__init__.py')
  16. if not exists(init_path):
  17. create_file(init_path)
  18. def subfolders(path):
  19. """
  20. Decompose a path string into a list of subfolders
  21. Eg Convert 'apps/dashboard/ranges' into
  22. ['apps', 'apps/dashboard', 'apps/dashboard/ranges']
  23. """
  24. folders = []
  25. while path not in ('/', ''):
  26. folders.append(path)
  27. path = os.path.dirname(path)
  28. folders.reverse()
  29. return folders
  30. def inherit_app_config(local_app_path, app_package, app_label):
  31. if 'dashboard' in app_label:
  32. config_name = '%sDashboardConfig' % app_label.split('.').pop().title()
  33. else:
  34. config_name = app_label.title() + 'Config'
  35. create_file(
  36. join(local_app_path, '__init__.py'),
  37. "default_app_config = '{app_package}.config.{config_name}'\n".format(
  38. app_package=app_package, config_name=config_name))
  39. create_file(
  40. join(local_app_path, 'config.py'),
  41. "from oscar.apps.{app_label} import config\n\n\n"
  42. "class {config_name}(config.{config_name}):\n"
  43. " name = '{app_package}'\n".format(
  44. app_package=app_package,
  45. app_label=app_label,
  46. config_name=config_name))
  47. def fork_app(label, folder_path, logger=None):
  48. """
  49. Create a custom version of one of Oscar's apps
  50. The first argument isn't strictly an app label as we allow things like
  51. 'catalogue' or 'dashboard.ranges'.
  52. """
  53. if logger is None:
  54. logger = logging.getLogger(__name__)
  55. # Check label is valid
  56. valid_labels = [x.replace('oscar.apps.', '') for x in oscar.OSCAR_CORE_APPS
  57. if x.startswith('oscar')]
  58. if label not in valid_labels:
  59. raise ValueError("There is no Oscar app that matches '%s'" % label)
  60. # Create folder
  61. label_folder = label.replace('.', '/') # eg 'dashboard/ranges'
  62. local_app_path = join(folder_path, label_folder)
  63. logger.info("Creating package %s" % local_app_path)
  64. create_local_app_folder(local_app_path)
  65. # Create minimum app files
  66. app_package = local_app_path.replace('/', '.')
  67. oscar_app_path = join(oscar.__path__[0], 'apps', label_folder)
  68. if exists(os.path.join(oscar_app_path, 'admin.py')):
  69. logger.info("Creating admin.py")
  70. create_file(join(local_app_path, 'admin.py'),
  71. "from oscar.apps.%s.admin import * # noqa\n" % label)
  72. logger.info("Creating app config")
  73. inherit_app_config(local_app_path, app_package, label)
  74. # Only create models.py and migrations if it exists in the Oscar app
  75. oscar_models_path = join(oscar_app_path, 'models.py')
  76. if exists(oscar_models_path):
  77. logger.info("Creating models.py")
  78. create_file(
  79. join(local_app_path, 'models.py'),
  80. "from oscar.apps.%s.models import * # noqa\n" % label)
  81. for migrations_path in ['migrations', 'south_migrations']:
  82. source = join(oscar_app_path, migrations_path)
  83. if exists(source):
  84. logger.info("Creating %s folder", migrations_path)
  85. destination = join(local_app_path, migrations_path)
  86. shutil.copytree(source, destination)
  87. # Final step needs to be done by hand
  88. msg = (
  89. "The final step is to add '%s' to INSTALLED_APPS "
  90. "(replacing the equivalent Oscar app). This can be "
  91. "achieved using Oscar's get_core_apps function - e.g.:"
  92. ) % app_package
  93. snippet = (
  94. " # settings.py\n"
  95. " ...\n"
  96. " INSTALLED_APPS = [\n"
  97. " 'django.contrib.auth',\n"
  98. " ...\n"
  99. " ]\n"
  100. " from oscar import get_core_apps\n"
  101. " INSTALLED_APPS = INSTALLED_APPS + get_core_apps(\n"
  102. " ['%s'])"
  103. ) % app_package
  104. record = "\n%s\n\n%s" % (
  105. "\n".join(textwrap.wrap(msg)), snippet)
  106. logger.info(record)
  107. def create_file(filepath, content=''):
  108. with open(filepath, 'w') as f:
  109. f.write(content)