Initial commit
This commit is contained in:
457
env/lib/python3.10/site-packages/wagtail/bin/wagtail.py
vendored
Normal file
457
env/lib/python3.10/site-packages/wagtail/bin/wagtail.py
vendored
Normal file
@@ -0,0 +1,457 @@
|
||||
#!/usr/bin/env python
|
||||
import fileinput
|
||||
import fnmatch
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from argparse import ArgumentParser
|
||||
from difflib import unified_diff
|
||||
|
||||
from django.core.management import ManagementUtility
|
||||
|
||||
CURRENT_PYTHON = sys.version_info[:2]
|
||||
REQUIRED_PYTHON = (3, 7)
|
||||
|
||||
if CURRENT_PYTHON < REQUIRED_PYTHON:
|
||||
sys.stderr.write(
|
||||
"This version of Wagtail requires Python {}.{} or above - you are running {}.{}\n".format(
|
||||
*(REQUIRED_PYTHON + CURRENT_PYTHON)
|
||||
)
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def pluralize(value, arg="s"):
|
||||
return "" if value == 1 else arg
|
||||
|
||||
|
||||
class Command:
|
||||
description = None
|
||||
|
||||
def create_parser(self, command_name=None):
|
||||
if command_name is None:
|
||||
prog = None
|
||||
else:
|
||||
# hack the prog name as reported to ArgumentParser to include the command
|
||||
prog = f"{prog_name()} {command_name}"
|
||||
|
||||
parser = ArgumentParser(
|
||||
description=getattr(self, "description", None), add_help=False, prog=prog
|
||||
)
|
||||
self.add_arguments(parser)
|
||||
return parser
|
||||
|
||||
def add_arguments(self, parser):
|
||||
pass
|
||||
|
||||
def print_help(self, command_name):
|
||||
parser = self.create_parser(command_name=command_name)
|
||||
parser.print_help()
|
||||
|
||||
def execute(self, argv):
|
||||
parser = self.create_parser()
|
||||
options = parser.parse_args(sys.argv[2:])
|
||||
options_dict = vars(options)
|
||||
self.run(**options_dict)
|
||||
|
||||
|
||||
class CreateProject(Command):
|
||||
description = "Creates the directory structure for a new Wagtail project."
|
||||
|
||||
def __init__(self):
|
||||
self.default_template_path = self.get_default_template_path()
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("project_name", help="Name for your Wagtail project")
|
||||
parser.add_argument(
|
||||
"dest_dir",
|
||||
nargs="?",
|
||||
help="Destination directory inside which to create the project",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--template",
|
||||
help="The path or URL to load the template from.",
|
||||
default=self.default_template_path,
|
||||
)
|
||||
|
||||
def get_default_template_path(self):
|
||||
import wagtail
|
||||
|
||||
wagtail_path = os.path.dirname(wagtail.__file__)
|
||||
default_template_path = os.path.join(wagtail_path, "project_template")
|
||||
return default_template_path
|
||||
|
||||
def run(self, project_name=None, dest_dir=None, **options):
|
||||
# Make sure given name is not already in use by another python package/module.
|
||||
try:
|
||||
__import__(project_name)
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
sys.exit(
|
||||
"'%s' conflicts with the name of an existing "
|
||||
"Python module and cannot be used as a project "
|
||||
"name. Please try another name." % project_name
|
||||
)
|
||||
|
||||
template_name = options["template"]
|
||||
if template_name == self.default_template_path:
|
||||
template_name = "the default Wagtail template"
|
||||
|
||||
print( # noqa: T201
|
||||
"Creating a Wagtail project called %(project_name)s using %(template_name)s"
|
||||
% {"project_name": project_name, "template_name": template_name}
|
||||
)
|
||||
|
||||
# Call django-admin startproject
|
||||
utility_args = [
|
||||
"django-admin",
|
||||
"startproject",
|
||||
"--template=" + options["template"],
|
||||
"--ext=html,rst",
|
||||
"--name=Dockerfile",
|
||||
project_name,
|
||||
]
|
||||
|
||||
if dest_dir:
|
||||
utility_args.append(dest_dir)
|
||||
|
||||
utility = ManagementUtility(utility_args)
|
||||
utility.execute()
|
||||
|
||||
print( # noqa: T201
|
||||
"Success! %(project_name)s has been created"
|
||||
% {"project_name": project_name}
|
||||
)
|
||||
|
||||
|
||||
class UpdateModulePaths(Command):
|
||||
description = "Update a Wagtail project tree to use Wagtail 2.x module paths"
|
||||
|
||||
REPLACEMENTS = [
|
||||
# Added in Wagtail 2.0
|
||||
(re.compile(r"\bwagtail\.wagtailcore\b"), "wagtail"),
|
||||
(re.compile(r"\bwagtail\.wagtailadmin\b"), "wagtail.admin"),
|
||||
(re.compile(r"\bwagtail\.wagtaildocs\b"), "wagtail.documents"),
|
||||
(re.compile(r"\bwagtail\.wagtailembeds\b"), "wagtail.embeds"),
|
||||
(re.compile(r"\bwagtail\.wagtailimages\b"), "wagtail.images"),
|
||||
(re.compile(r"\bwagtail\.wagtailsearch\b"), "wagtail.search"),
|
||||
(re.compile(r"\bwagtail\.wagtailsites\b"), "wagtail.sites"),
|
||||
(re.compile(r"\bwagtail\.wagtailsnippets\b"), "wagtail.snippets"),
|
||||
(re.compile(r"\bwagtail\.wagtailusers\b"), "wagtail.users"),
|
||||
(re.compile(r"\bwagtail\.wagtailforms\b"), "wagtail.contrib.forms"),
|
||||
(re.compile(r"\bwagtail\.wagtailredirects\b"), "wagtail.contrib.redirects"),
|
||||
(
|
||||
re.compile(r"\bwagtail\.contrib\.wagtailfrontendcache\b"),
|
||||
"wagtail.contrib.frontend_cache",
|
||||
),
|
||||
(
|
||||
re.compile(r"\bwagtail\.contrib\.wagtailroutablepage\b"),
|
||||
"wagtail.contrib.routable_page",
|
||||
),
|
||||
(
|
||||
re.compile(r"\bwagtail\.contrib\.wagtailsearchpromotions\b"),
|
||||
"wagtail.contrib.search_promotions",
|
||||
),
|
||||
(
|
||||
re.compile(r"\bwagtail\.contrib\.wagtailsitemaps\b"),
|
||||
"wagtail.contrib.sitemaps",
|
||||
),
|
||||
(
|
||||
re.compile(r"\bwagtail\.contrib\.wagtailstyleguide\b"),
|
||||
"wagtail.contrib.styleguide",
|
||||
),
|
||||
# Added in Wagtail 3.0
|
||||
(re.compile(r"\bwagtail\.tests\b"), "wagtail.test"),
|
||||
(re.compile(r"\bwagtail\.core\.utils\b"), "wagtail.coreutils"),
|
||||
(re.compile(r"\bwagtail\.core\b"), "wagtail"),
|
||||
(re.compile(r"\bwagtail\.admin\.edit_handlers\b"), "wagtail.admin.panels"),
|
||||
(
|
||||
re.compile(r"\bwagtail\.contrib\.forms\.edit_handlers\b"),
|
||||
"wagtail.contrib.forms.panels",
|
||||
),
|
||||
]
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("root_path", nargs="?", help="Path to your project's root")
|
||||
parser.add_argument(
|
||||
"--list",
|
||||
action="store_true",
|
||||
dest="list_files",
|
||||
help="Show the list of files to change, without modifying them",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--diff",
|
||||
action="store_true",
|
||||
help="Show the changes that would be made, without modifying the files",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ignore-dir",
|
||||
action="append",
|
||||
dest="ignored_dirs",
|
||||
metavar="NAME",
|
||||
help="Ignore files in this directory",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ignore-file",
|
||||
action="append",
|
||||
dest="ignored_patterns",
|
||||
metavar="NAME",
|
||||
help="Ignore files with this name (supports wildcards)",
|
||||
)
|
||||
|
||||
def run(
|
||||
self,
|
||||
root_path=None,
|
||||
list_files=False,
|
||||
diff=False,
|
||||
ignored_dirs=None,
|
||||
ignored_patterns=None,
|
||||
):
|
||||
if root_path is None:
|
||||
root_path = os.getcwd()
|
||||
|
||||
absolute_ignored_dirs = [
|
||||
os.path.abspath(dir_path) + os.sep for dir_path in (ignored_dirs or [])
|
||||
]
|
||||
|
||||
if ignored_patterns is None:
|
||||
ignored_patterns = []
|
||||
|
||||
checked_file_count = 0
|
||||
changed_file_count = 0
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(root_path):
|
||||
dirpath_with_slash = os.path.abspath(dirpath) + os.sep
|
||||
if any(
|
||||
dirpath_with_slash.startswith(ignored_dir)
|
||||
for ignored_dir in absolute_ignored_dirs
|
||||
):
|
||||
continue
|
||||
|
||||
for filename in filenames:
|
||||
if not filename.lower().endswith(".py"):
|
||||
continue
|
||||
|
||||
if any(
|
||||
fnmatch.fnmatch(filename, pattern) for pattern in ignored_patterns
|
||||
):
|
||||
continue
|
||||
|
||||
path = os.path.join(dirpath, filename)
|
||||
relative_path = os.path.relpath(path, start=root_path)
|
||||
checked_file_count += 1
|
||||
|
||||
if diff:
|
||||
change_count = self._show_diff(path, relative_path=relative_path)
|
||||
else:
|
||||
if list_files:
|
||||
change_count = self._count_changes(path)
|
||||
else: # actually update
|
||||
change_count = self._rewrite_file(path)
|
||||
if change_count:
|
||||
print( # noqa: T201
|
||||
"%s - %d change%s"
|
||||
% (relative_path, change_count, pluralize(change_count))
|
||||
)
|
||||
|
||||
if change_count:
|
||||
changed_file_count += 1
|
||||
|
||||
if diff or list_files:
|
||||
print( # noqa: T201
|
||||
"\nChecked %d .py file%s, %d file%s to update."
|
||||
% (
|
||||
checked_file_count,
|
||||
pluralize(checked_file_count),
|
||||
changed_file_count,
|
||||
pluralize(changed_file_count),
|
||||
)
|
||||
)
|
||||
else:
|
||||
print( # noqa: T201
|
||||
"\nChecked %d .py file%s, %d file%s updated."
|
||||
% (
|
||||
checked_file_count,
|
||||
pluralize(checked_file_count),
|
||||
changed_file_count,
|
||||
pluralize(changed_file_count),
|
||||
)
|
||||
)
|
||||
|
||||
def _rewrite_line(self, line):
|
||||
for pattern, repl in self.REPLACEMENTS:
|
||||
line = re.sub(pattern, repl, line)
|
||||
return line
|
||||
|
||||
def _show_diff(self, filename, relative_path=None):
|
||||
change_count = 0
|
||||
found_unicode_error = False
|
||||
original = []
|
||||
updated = []
|
||||
|
||||
with open(filename, mode="rb") as f:
|
||||
for raw_original_line in f:
|
||||
try:
|
||||
original_line = raw_original_line.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
found_unicode_error = True
|
||||
# retry decoding as utf-8, mangling invalid bytes so that we have a usable string to use the diff
|
||||
line = original_line = raw_original_line.decode(
|
||||
"utf-8", errors="replace"
|
||||
)
|
||||
else:
|
||||
line = self._rewrite_line(original_line)
|
||||
|
||||
original.append(original_line)
|
||||
updated.append(line)
|
||||
if line != original_line:
|
||||
change_count += 1
|
||||
|
||||
if found_unicode_error:
|
||||
sys.stderr.write(
|
||||
"Warning - %s is not a valid UTF-8 file. Lines with decode errors have been ignored\n"
|
||||
% filename
|
||||
)
|
||||
|
||||
if change_count:
|
||||
relative_path = relative_path or filename
|
||||
|
||||
sys.stdout.writelines(
|
||||
unified_diff(
|
||||
original,
|
||||
updated,
|
||||
fromfile="%s:before" % relative_path,
|
||||
tofile="%s:after" % relative_path,
|
||||
)
|
||||
)
|
||||
|
||||
return change_count
|
||||
|
||||
def _count_changes(self, filename):
|
||||
change_count = 0
|
||||
found_unicode_error = False
|
||||
|
||||
with open(filename, mode="rb") as f:
|
||||
for raw_original_line in f:
|
||||
try:
|
||||
original_line = raw_original_line.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
found_unicode_error = True
|
||||
else:
|
||||
line = self._rewrite_line(original_line)
|
||||
if line != original_line:
|
||||
change_count += 1
|
||||
|
||||
if found_unicode_error:
|
||||
sys.stderr.write(
|
||||
"Warning - %s is not a valid UTF-8 file. Lines with decode errors have been ignored\n"
|
||||
% filename
|
||||
)
|
||||
|
||||
return change_count
|
||||
|
||||
def _rewrite_file(self, filename):
|
||||
change_count = 0
|
||||
found_unicode_error = False
|
||||
|
||||
with fileinput.FileInput(filename, inplace=True, mode="rb") as f:
|
||||
for raw_original_line in f:
|
||||
try:
|
||||
original_line = raw_original_line.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
sys.stdout.write(raw_original_line)
|
||||
found_unicode_error = True
|
||||
else:
|
||||
line = self._rewrite_line(original_line)
|
||||
if CURRENT_PYTHON >= (3, 8):
|
||||
sys.stdout.write(line.encode("utf-8"))
|
||||
else:
|
||||
# Python 3.7 opens the output stream in text mode, so write the line back as
|
||||
# text rather than bytes:
|
||||
# https://github.com/python/cpython/commit/be6dbfb43b89989ccc83fbc4c5234f50f44c47ad
|
||||
sys.stdout.write(line)
|
||||
|
||||
if line != original_line:
|
||||
change_count += 1
|
||||
|
||||
if found_unicode_error:
|
||||
sys.stderr.write(
|
||||
"Warning - %s is not a valid UTF-8 file. Lines with decode errors have been ignored\n"
|
||||
% filename
|
||||
)
|
||||
|
||||
return change_count
|
||||
|
||||
|
||||
class Version(Command):
|
||||
description = "List which version of Wagtail you are using"
|
||||
|
||||
def run(self):
|
||||
import wagtail
|
||||
|
||||
version = wagtail.get_version(wagtail.VERSION)
|
||||
|
||||
print(f"You are using Wagtail {version}") # noqa: T201
|
||||
|
||||
|
||||
COMMANDS = {
|
||||
"start": CreateProject(),
|
||||
"updatemodulepaths": UpdateModulePaths(),
|
||||
"--version": Version(),
|
||||
}
|
||||
|
||||
|
||||
def prog_name():
|
||||
return os.path.basename(sys.argv[0])
|
||||
|
||||
|
||||
def help_index():
|
||||
print( # noqa: T201
|
||||
"Type '%s help <subcommand>' for help on a specific subcommand.\n" % prog_name()
|
||||
)
|
||||
print("Available subcommands:\n") # NOQA: T201
|
||||
for name, cmd in sorted(COMMANDS.items()):
|
||||
print(f" {name.ljust(20)}{cmd.description}") # NOQA: T201
|
||||
|
||||
|
||||
def unknown_command(command):
|
||||
print("Unknown command: '%s'" % command) # NOQA: T201
|
||||
print("Type '%s help' for usage." % prog_name()) # NOQA: T201
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
command_name = sys.argv[1]
|
||||
except IndexError:
|
||||
help_index()
|
||||
return
|
||||
|
||||
if command_name == "help":
|
||||
try:
|
||||
help_command_name = sys.argv[2]
|
||||
except IndexError:
|
||||
help_index()
|
||||
return
|
||||
|
||||
try:
|
||||
command = COMMANDS[help_command_name]
|
||||
except KeyError:
|
||||
unknown_command(help_command_name)
|
||||
return
|
||||
|
||||
command.print_help(help_command_name)
|
||||
return
|
||||
|
||||
try:
|
||||
command = COMMANDS[command_name]
|
||||
except KeyError:
|
||||
unknown_command(command_name)
|
||||
return
|
||||
|
||||
command.execute(sys.argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user