plain 0.48.0__tar.gz → 0.50.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plain-0.48.0 → plain-0.50.0}/.gitignore +0 -3
- {plain-0.48.0 → plain-0.50.0}/PKG-INFO +1 -1
- plain-0.50.0/plain/CHANGELOG.md +33 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/README.md +7 -1
- {plain-0.48.0 → plain-0.50.0}/plain/cli/core.py +2 -0
- plain-0.50.0/plain/cli/help.py +27 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/preflight.py +4 -5
- {plain-0.48.0 → plain-0.50.0}/plain/cli/urls.py +8 -2
- {plain-0.48.0 → plain-0.50.0}/plain/preflight/registry.py +2 -2
- {plain-0.48.0 → plain-0.50.0}/plain/runtime/README.md +13 -20
- {plain-0.48.0 → plain-0.50.0}/plain/test/client.py +7 -44
- {plain-0.48.0 → plain-0.50.0}/pyproject.toml +1 -1
- {plain-0.48.0 → plain-0.50.0}/tests/test_cli.py +8 -0
- {plain-0.48.0 → plain-0.50.0}/LICENSE +0 -0
- {plain-0.48.0 → plain-0.50.0}/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/__main__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/assets/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/assets/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/assets/compile.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/assets/finders.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/assets/fingerprints.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/assets/urls.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/assets/views.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/chores/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/chores/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/chores/registry.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/build.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/chores.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/docs.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/formatting.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/print.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/registry.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/scaffold.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/settings.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/shell.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/startup.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/cli/utils.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/csrf/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/csrf/middleware.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/csrf/views.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/debug.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/exceptions.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/forms/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/forms/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/forms/boundfield.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/forms/exceptions.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/forms/fields.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/forms/forms.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/http/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/http/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/http/cookie.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/http/multipartparser.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/http/request.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/http/response.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/files/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/files/base.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/files/locks.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/files/move.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/files/temp.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/files/uploadedfile.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/files/uploadhandler.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/files/utils.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/handlers/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/handlers/base.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/handlers/exception.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/handlers/wsgi.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/middleware/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/middleware/headers.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/middleware/https.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/internal/middleware/slash.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/json.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/logs/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/logs/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/logs/configure.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/logs/loggers.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/logs/utils.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/packages/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/packages/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/packages/config.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/packages/registry.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/paginator.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/preflight/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/preflight/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/preflight/files.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/preflight/messages.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/preflight/security.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/preflight/urls.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/runtime/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/runtime/global_settings.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/runtime/user_settings.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/signals/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/signals/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/signals/dispatch/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/signals/dispatch/dispatcher.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/signals/dispatch/license.txt +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/signing.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/templates/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/templates/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/templates/core.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/templates/jinja/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/templates/jinja/environments.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/templates/jinja/extensions.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/templates/jinja/filters.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/templates/jinja/globals.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/test/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/test/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/test/encoding.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/test/exceptions.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/urls/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/urls/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/urls/converters.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/urls/exceptions.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/urls/patterns.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/urls/resolvers.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/urls/routers.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/urls/utils.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/cache.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/crypto.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/datastructures.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/dateparse.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/deconstruct.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/decorators.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/duration.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/encoding.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/functional.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/hashable.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/html.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/http.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/inspect.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/ipv6.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/itercompat.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/module_loading.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/regex_helper.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/safestring.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/text.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/timesince.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/timezone.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/utils/tree.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/validators.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/README.md +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/base.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/csrf.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/errors.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/exceptions.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/forms.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/objects.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/redirect.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/views/templates.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/plain/wsgi.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/.gitignore +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/app/.gitignore +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/app/settings.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/app/test/__init__.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/app/test/default_settings.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/app/urls.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/conftest.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/test_runtime.py +0 -0
- {plain-0.48.0 → plain-0.50.0}/tests/test_wsgi.py +0 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# plain changelog
|
2
|
+
|
3
|
+
## [0.50.0](https://github.com/dropseed/plain/releases/plain@0.50.0) (2025-06-23)
|
4
|
+
|
5
|
+
### What's changed
|
6
|
+
|
7
|
+
- The URL inspection command has moved; run `plain urls list` instead of the old `plain urls` command ([6146fcb](https://github.com/dropseed/plain/commit/6146fcba536c551277d625bd750c385431ea18eb))
|
8
|
+
- `plain preflight` gains a simpler `--database` flag that enables database checks for your default database. The previous behaviour that accepted one or more database aliases has been removed ([d346d81](https://github.com/dropseed/plain/commit/d346d81567d2cc45bbed93caba18a195de10c572))
|
9
|
+
- Settings overhaul: use a single `DATABASE` setting instead of `DATABASES`/`DATABASE_ROUTERS` ([d346d81](https://github.com/dropseed/plain/commit/d346d81567d2cc45bbed93caba18a195de10c572))
|
10
|
+
|
11
|
+
### Upgrade instructions
|
12
|
+
|
13
|
+
- Update any scripts or documentation that call `plain urls …`:
|
14
|
+
- Replace `plain urls --flat` with `plain urls list --flat`
|
15
|
+
- If you invoke preflight checks in CI or locally:
|
16
|
+
- Replace `plain preflight --database <alias>` (or multiple aliases) with the new boolean flag: `plain preflight --database`
|
17
|
+
- In `settings.py` migrate to the new database configuration:
|
18
|
+
```python
|
19
|
+
# Before
|
20
|
+
DATABASES = {
|
21
|
+
"default": {
|
22
|
+
"ENGINE": "plain.backends.sqlite3",
|
23
|
+
"NAME": BASE_DIR / "db.sqlite3",
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
# After
|
28
|
+
DATABASE = {
|
29
|
+
"ENGINE": "plain.backends.sqlite3",
|
30
|
+
"NAME": BASE_DIR / "db.sqlite3",
|
31
|
+
}
|
32
|
+
```
|
33
|
+
Remove any `DATABASES` and `DATABASE_ROUTERS` settings – they are no longer read.
|
@@ -30,6 +30,12 @@ Run a Python script in the context of your app.
|
|
30
30
|
|
31
31
|
View the runtime value of a named setting.
|
32
32
|
|
33
|
+
### `plain help`
|
34
|
+
|
35
|
+
Print help for all available commands and subcommands.
|
36
|
+
Each command's help output is prefixed with the full command name for
|
37
|
+
readability.
|
38
|
+
|
33
39
|
### `plain shell`
|
34
40
|
|
35
41
|
Open a Python shell with the Plain loaded.
|
@@ -46,7 +52,7 @@ __all__ = [
|
|
46
52
|
]
|
47
53
|
```
|
48
54
|
|
49
|
-
### `plain urls`
|
55
|
+
### `plain urls list`
|
50
56
|
|
51
57
|
List all the URL patterns in your app.
|
52
58
|
|
@@ -10,6 +10,7 @@ from .build import build
|
|
10
10
|
from .chores import chores
|
11
11
|
from .docs import docs
|
12
12
|
from .formatting import PlainContext
|
13
|
+
from .help import help_cmd
|
13
14
|
from .preflight import preflight_checks
|
14
15
|
from .registry import cli_registry
|
15
16
|
from .scaffold import create
|
@@ -34,6 +35,7 @@ plain_cli.add_command(urls)
|
|
34
35
|
plain_cli.add_command(setting)
|
35
36
|
plain_cli.add_command(shell)
|
36
37
|
plain_cli.add_command(run)
|
38
|
+
plain_cli.add_command(help_cmd)
|
37
39
|
|
38
40
|
|
39
41
|
class CLIRegistryGroup(click.Group):
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import click
|
2
|
+
from click.core import MultiCommand
|
3
|
+
|
4
|
+
|
5
|
+
@click.command("help")
|
6
|
+
@click.pass_context
|
7
|
+
def help_cmd(ctx):
|
8
|
+
"""Show help for all commands and subcommands."""
|
9
|
+
|
10
|
+
root = ctx.parent.command
|
11
|
+
info_name = ctx.parent.info_name or "plain"
|
12
|
+
|
13
|
+
def print_help(cmd, prog, parent=None):
|
14
|
+
sub_ctx = click.Context(cmd, info_name=prog, parent=parent)
|
15
|
+
|
16
|
+
title = sub_ctx.command_path
|
17
|
+
click.secho(title, fg="green", bold=True)
|
18
|
+
click.secho("-" * len(title), fg="green")
|
19
|
+
click.echo(sub_ctx.get_help())
|
20
|
+
|
21
|
+
if isinstance(cmd, MultiCommand):
|
22
|
+
for name in cmd.list_commands(sub_ctx):
|
23
|
+
click.echo()
|
24
|
+
sub_cmd = cmd.get_command(sub_ctx, name)
|
25
|
+
print_help(sub_cmd, name, sub_ctx)
|
26
|
+
|
27
|
+
print_help(root, info_name)
|
@@ -19,11 +19,10 @@ from plain.packages import packages_registry
|
|
19
19
|
)
|
20
20
|
@click.option(
|
21
21
|
"--database",
|
22
|
-
|
23
|
-
|
24
|
-
help="Run database related checks against these aliases.",
|
22
|
+
is_flag=True,
|
23
|
+
help="Run database related checks as part of preflight.",
|
25
24
|
)
|
26
|
-
def preflight_checks(package_label, deploy, fail_level,
|
25
|
+
def preflight_checks(package_label, deploy, fail_level, database):
|
27
26
|
"""
|
28
27
|
Use the system check framework to validate entire Plain project.
|
29
28
|
Raise CommandError for any serious message (error or critical errors).
|
@@ -42,7 +41,7 @@ def preflight_checks(package_label, deploy, fail_level, databases):
|
|
42
41
|
all_issues = preflight.run_checks(
|
43
42
|
package_configs=package_configs,
|
44
43
|
include_deployment_checks=include_deployment_checks,
|
45
|
-
|
44
|
+
database=database,
|
46
45
|
)
|
47
46
|
|
48
47
|
header, body, footer = "", "", ""
|
@@ -3,9 +3,15 @@ import sys
|
|
3
3
|
import click
|
4
4
|
|
5
5
|
|
6
|
-
@click.
|
6
|
+
@click.group()
|
7
|
+
def urls():
|
8
|
+
"""URL related commands"""
|
9
|
+
pass
|
10
|
+
|
11
|
+
|
12
|
+
@urls.command("list")
|
7
13
|
@click.option("--flat", is_flag=True, help="List all URLs in a flat list")
|
8
|
-
def
|
14
|
+
def list_urls(flat):
|
9
15
|
"""Print all URL patterns under settings.URLS_ROUTER"""
|
10
16
|
from plain.runtime import settings
|
11
17
|
from plain.urls import URLResolver, get_resolver
|
@@ -42,7 +42,7 @@ class CheckRegistry:
|
|
42
42
|
self,
|
43
43
|
package_configs=None,
|
44
44
|
include_deployment_checks=False,
|
45
|
-
|
45
|
+
database=False,
|
46
46
|
):
|
47
47
|
"""
|
48
48
|
Run all registered checks and return list of Errors and Warnings.
|
@@ -51,7 +51,7 @@ class CheckRegistry:
|
|
51
51
|
checks = self.get_checks(include_deployment_checks)
|
52
52
|
|
53
53
|
for check in checks:
|
54
|
-
new_errors = check(package_configs=package_configs,
|
54
|
+
new_errors = check(package_configs=package_configs, database=database)
|
55
55
|
if not is_iterable(new_errors):
|
56
56
|
raise TypeError(
|
57
57
|
f"The function {check!r} did not return a list. All functions "
|
@@ -79,28 +79,21 @@ from os import environ
|
|
79
79
|
|
80
80
|
from . import database_url
|
81
81
|
|
82
|
-
# Make
|
83
|
-
|
82
|
+
# Make DATABASE a required setting
|
83
|
+
DATABASE: dict
|
84
84
|
|
85
|
-
# Automatically configure
|
85
|
+
# Automatically configure DATABASE if a DATABASE_URL was given in the environment
|
86
86
|
if "DATABASE_URL" in environ:
|
87
|
-
|
88
|
-
"
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
"1",
|
98
|
-
],
|
99
|
-
)
|
100
|
-
}
|
101
|
-
|
102
|
-
# Classes used to implement DB routing behavior.
|
103
|
-
DATABASE_ROUTERS = []
|
87
|
+
DATABASE = database_url.parse_database_url(
|
88
|
+
environ["DATABASE_URL"],
|
89
|
+
# Enable persistent connections by default
|
90
|
+
conn_max_age=int(environ.get("DATABASE_CONN_MAX_AGE", 600)),
|
91
|
+
conn_health_checks=environ.get("DATABASE_CONN_HEALTH_CHECKS", "true").lower()
|
92
|
+
in [
|
93
|
+
"true",
|
94
|
+
"1",
|
95
|
+
],
|
96
|
+
)
|
104
97
|
```
|
105
98
|
|
106
99
|
### .env files
|
@@ -6,7 +6,7 @@ from http.cookies import SimpleCookie
|
|
6
6
|
from io import BytesIO, IOBase
|
7
7
|
from urllib.parse import unquote_to_bytes, urljoin, urlparse, urlsplit
|
8
8
|
|
9
|
-
from plain.http import HttpHeaders,
|
9
|
+
from plain.http import HttpHeaders, QueryDict
|
10
10
|
from plain.internal import internalcode
|
11
11
|
from plain.internal.handlers.base import BaseHandler
|
12
12
|
from plain.internal.handlers.wsgi import WSGIRequest
|
@@ -775,57 +775,20 @@ class Client(RequestFactory):
|
|
775
775
|
@property
|
776
776
|
def session(self):
|
777
777
|
"""Return the current session variables."""
|
778
|
-
from plain.sessions import
|
778
|
+
from plain.sessions.test import get_client_session
|
779
779
|
|
780
|
-
|
781
|
-
if cookie:
|
782
|
-
return SessionStore(cookie.value)
|
783
|
-
session = SessionStore()
|
784
|
-
session.save()
|
785
|
-
self.cookies[settings.SESSION_COOKIE_NAME] = session.session_key
|
786
|
-
return session
|
780
|
+
return get_client_session(self)
|
787
781
|
|
788
782
|
def force_login(self, user):
|
789
|
-
|
783
|
+
from plain.auth.test import login_client
|
790
784
|
|
791
|
-
|
792
|
-
from plain.auth import login
|
793
|
-
from plain.sessions import SessionStore
|
794
|
-
|
795
|
-
# Create a fake request to store login details.
|
796
|
-
request = HttpRequest()
|
797
|
-
if self.session:
|
798
|
-
request.session = self.session
|
799
|
-
else:
|
800
|
-
request.session = SessionStore()
|
801
|
-
login(request, user)
|
802
|
-
# Save the session values.
|
803
|
-
request.session.save()
|
804
|
-
# Set the cookie to represent the session.
|
805
|
-
session_cookie = settings.SESSION_COOKIE_NAME
|
806
|
-
self.cookies[session_cookie] = request.session.session_key
|
807
|
-
cookie_data = {
|
808
|
-
"max-age": None,
|
809
|
-
"path": "/",
|
810
|
-
"domain": settings.SESSION_COOKIE_DOMAIN,
|
811
|
-
"secure": settings.SESSION_COOKIE_SECURE or None,
|
812
|
-
"expires": None,
|
813
|
-
}
|
814
|
-
self.cookies[session_cookie].update(cookie_data)
|
785
|
+
login_client(self, user)
|
815
786
|
|
816
787
|
def logout(self):
|
817
788
|
"""Log out the user by removing the cookies and session object."""
|
818
|
-
from plain.auth import
|
819
|
-
from plain.sessions import SessionStore
|
789
|
+
from plain.auth.test import logout_client
|
820
790
|
|
821
|
-
|
822
|
-
if self.session:
|
823
|
-
request.session = self.session
|
824
|
-
request.user = get_user(request)
|
825
|
-
else:
|
826
|
-
request.session = SessionStore()
|
827
|
-
logout(request)
|
828
|
-
self.cookies = SimpleCookie()
|
791
|
+
logout_client(self)
|
829
792
|
|
830
793
|
def _parse_json(self, response, **extra):
|
831
794
|
if not hasattr(response, "_json"):
|
@@ -15,3 +15,11 @@ def test_plain_cli_build():
|
|
15
15
|
result = runner.invoke(cli, ["build"], prog_name="plain")
|
16
16
|
assert result.exit_code == 0
|
17
17
|
assert "Compiled 0 assets into 0 files" in result.output
|
18
|
+
|
19
|
+
|
20
|
+
def test_plain_help_command():
|
21
|
+
runner = CliRunner()
|
22
|
+
result = runner.invoke(cli, ["help"], prog_name="plain")
|
23
|
+
assert result.exit_code == 0
|
24
|
+
assert "Usage: plain build" in result.output
|
25
|
+
assert "Usage: plain shell" in result.output
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|