plain 0.34.1__py3-none-any.whl → 0.36.0__py3-none-any.whl

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/assets/views.py CHANGED
@@ -254,7 +254,7 @@ class AssetView(View):
254
254
 
255
255
  if not range_header.startswith("bytes="):
256
256
  return Response(
257
- status=416, headers=[("Content-Range", f"bytes */{file_size}")]
257
+ status_code=416, headers=[("Content-Range", f"bytes */{file_size}")]
258
258
  )
259
259
 
260
260
  range_values = range_header.split("=")[1].split("-")
@@ -263,7 +263,7 @@ class AssetView(View):
263
263
 
264
264
  if start >= file_size:
265
265
  return Response(
266
- status=416, headers=[("Content-Range", f"bytes */{file_size}")]
266
+ status_code=416, headers=[("Content-Range", f"bytes */{file_size}")]
267
267
  )
268
268
 
269
269
  end = min(end, file_size - 1)
@@ -272,7 +272,7 @@ class AssetView(View):
272
272
  f.seek(start)
273
273
  content = f.read(end - start + 1)
274
274
 
275
- response = StreamingResponse(BytesIO(content), status=206)
275
+ response = StreamingResponse(BytesIO(content), status_code=206)
276
276
  response.headers = self.update_headers(response.headers, path)
277
277
  response.headers["Content-Range"] = f"bytes {start}-{end}/{file_size}"
278
278
  response.headers["Content-Length"] = str(end - start + 1)
plain/cli/build.py ADDED
@@ -0,0 +1,107 @@
1
+ import shutil
2
+ import subprocess
3
+ import sys
4
+ import tomllib
5
+ from importlib.metadata import entry_points
6
+ from pathlib import Path
7
+
8
+ import click
9
+
10
+ import plain.runtime
11
+ from plain.assets.compile import compile_assets, get_compiled_path
12
+
13
+
14
+ @click.command()
15
+ @click.option(
16
+ "--keep-original/--no-keep-original",
17
+ "keep_original",
18
+ is_flag=True,
19
+ default=False,
20
+ help="Keep the original assets",
21
+ )
22
+ @click.option(
23
+ "--fingerprint/--no-fingerprint",
24
+ "fingerprint",
25
+ is_flag=True,
26
+ default=True,
27
+ help="Fingerprint the assets",
28
+ )
29
+ @click.option(
30
+ "--compress/--no-compress",
31
+ "compress",
32
+ is_flag=True,
33
+ default=True,
34
+ help="Compress the assets",
35
+ )
36
+ def build(keep_original, fingerprint, compress):
37
+ """Pre-deployment build step (compile assets, css, js, etc.)"""
38
+
39
+ if not keep_original and not fingerprint:
40
+ click.secho(
41
+ "You must either keep the original assets or fingerprint them.",
42
+ fg="red",
43
+ err=True,
44
+ )
45
+ sys.exit(1)
46
+
47
+ # Run user-defined build commands first
48
+ pyproject_path = plain.runtime.APP_PATH.parent / "pyproject.toml"
49
+ if pyproject_path.exists():
50
+ with pyproject_path.open("rb") as f:
51
+ pyproject = tomllib.load(f)
52
+
53
+ for name, data in (
54
+ pyproject.get("tool", {})
55
+ .get("plain", {})
56
+ .get("build", {})
57
+ .get("run", {})
58
+ .items()
59
+ ):
60
+ click.secho(f"Running {name} from pyproject.toml", bold=True)
61
+ result = subprocess.run(data["cmd"], shell=True)
62
+ print()
63
+ if result.returncode:
64
+ click.secho(f"Error in {name} (exit {result.returncode})", fg="red")
65
+ sys.exit(result.returncode)
66
+
67
+ # Then run installed package build steps (like tailwind, typically should run last...)
68
+ for entry_point in entry_points(group="plain.build"):
69
+ click.secho(f"Running {entry_point.name}", bold=True)
70
+ result = entry_point.load()()
71
+ print()
72
+
73
+ # Compile our assets
74
+ target_dir = get_compiled_path()
75
+ click.secho(f"Compiling assets to {target_dir}", bold=True)
76
+ if target_dir.exists():
77
+ click.secho("(clearing previously compiled assets)")
78
+ shutil.rmtree(target_dir)
79
+ target_dir.mkdir(parents=True, exist_ok=True)
80
+
81
+ total_files = 0
82
+ total_compiled = 0
83
+
84
+ for url_path, resolved_url_path, compiled_paths in compile_assets(
85
+ target_dir=target_dir,
86
+ keep_original=keep_original,
87
+ fingerprint=fingerprint,
88
+ compress=compress,
89
+ ):
90
+ if url_path == resolved_url_path:
91
+ click.secho(url_path, bold=True)
92
+ else:
93
+ click.secho(url_path, bold=True, nl=False)
94
+ click.secho(" → ", fg="yellow", nl=False)
95
+ click.echo(resolved_url_path)
96
+
97
+ print("\n".join(f" {Path(p).relative_to(Path.cwd())}" for p in compiled_paths))
98
+
99
+ total_files += 1
100
+ total_compiled += len(compiled_paths)
101
+
102
+ click.secho(
103
+ f"\nCompiled {total_files} assets into {total_compiled} files", fg="green"
104
+ )
105
+
106
+ # TODO could do a jinja pre-compile here too?
107
+ # environment.compile_templates() but it needs a target, ignore_errors=False