Mercurial > piecrust2
annotate piecrust/commands/builtin/themes.py @ 411:e7b865f8f335
bake: Enable multiprocess baking.
Baking is now done by running a worker per CPU, and sending jobs to them.
This changes several things across the codebase:
* Ability to not cache things related to pages other than the 'main' page
(i.e. the page at the bottom of the execution stack).
* Decouple the baking process from the bake records, so only the main process
keeps track (and modifies) the bake record.
* Remove the need for 'batch page getters' and loading a page directly from
the page factories.
There are various smaller changes too included here, including support for
scope performance timers that are saved with the bake record and can be
printed out to the console. Yes I got carried away.
For testing, the in-memory 'mock' file-system doesn't work anymore, since
we're spawning processes, so this is replaced by a 'tmpfs' file-system which
is saved in temporary files on disk and deleted after tests have run.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 12 Jun 2015 17:09:19 -0700 |
parents | d70a4adb61dd |
children | c5df200354e8 |
rev | line source |
---|---|
273
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
1 import os |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
2 import os.path |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
3 import shutil |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
4 import logging |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
5 import yaml |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
6 from piecrust import ( |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
7 RESOURCES_DIR, THEME_DIR, THEME_CONFIG_PATH, THEME_INFO_PATH) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
8 from piecrust.commands.base import ChefCommand |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
9 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
10 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
11 logger = logging.getLogger(__name__) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
12 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
13 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
14 class ThemesCommand(ChefCommand): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
15 def __init__(self): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
16 super(ThemesCommand, self).__init__() |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
17 self.name = 'themes' |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
18 self.description = "Manage the themes for the current website." |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
19 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
20 def setupParser(self, parser, app): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
21 if app.root_dir is None: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
22 return |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
23 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
24 subparsers = parser.add_subparsers() |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
25 p = subparsers.add_parser( |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
26 'create', |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
27 help="Create a new theme for the current website.") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
28 p.add_argument( |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
29 '--from-default', |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
30 action='store_true', |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
31 help=("Create a new theme by copying the default PieCrust " |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
32 "theme into the theme directory")) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
33 p.add_argument( |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
34 'theme_name', |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
35 help=("The name of the theme")) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
36 p.set_defaults(sub_func=self._createTheme) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
37 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
38 p = subparsers.add_parser( |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
39 'override', |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
40 help="Copies a theme to the website for customization.") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
41 p.set_defaults(sub_func=self._overrideTheme) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
42 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
43 def checkedRun(self, ctx): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
44 ctx.args.sub_func(ctx) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
45 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
46 def _createTheme(self, ctx): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
47 theme_dir = os.path.join(ctx.app.root_dir, THEME_DIR) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
48 if os.path.exists(theme_dir): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
49 logger.warning("A theme already exists, and will be overwritten. " |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
50 "Are you sure? [Y/n]") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
51 ans = input() |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
52 if len(ans) > 0 and ans.lower() not in ['y', 'yes']: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
53 return 1 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
54 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
55 shutil.rmtree(theme_dir) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
56 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
57 try: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
58 if ctx.args.from_default: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
59 def reporting_copy2(src, dst): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
60 rel_dst = os.path.relpath(dst, ctx.app.root_dir) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
61 logger.info(rel_dst) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
62 shutil.copy2(src, dst) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
63 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
64 default_theme_dir = os.path.join(RESOURCES_DIR, 'theme') |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
65 shutil.copytree(default_theme_dir, theme_dir, |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
66 copy_function=reporting_copy2) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
67 return 0 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
68 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
69 logger.info("Creating theme directory.") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
70 os.makedirs(theme_dir) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
71 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
72 logger.info("Creating theme_config.yml") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
73 config_path = os.path.join(theme_dir, THEME_CONFIG_PATH) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
74 with open(config_path, 'w', encoding='utf8') as fp: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
75 fp.write('') |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
76 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
77 logger.info("Creating theme_info.yml") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
78 info_path = os.path.join(theme_dir, THEME_INFO_PATH) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
79 with open(info_path, 'w', encoding='utf8') as fp: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
80 yaml.dump( |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
81 { |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
82 'name': ctx.args.theme_name or 'My New Theme', |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
83 'description': "A new PieCrust theme.", |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
84 'authors': ['Your Name Here <email or twitter>'], |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
85 'url': 'http://www.example.org'}, |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
86 fp, |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
87 default_flow_style=False) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
88 return 0 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
89 except: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
90 logger.error("Error occured, deleting theme directory.") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
91 shutil.rmtree(theme_dir) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
92 raise |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
93 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
94 def _overrideTheme(self, ctx): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
95 app_dir = ctx.app.root_dir |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
96 theme_dir = ctx.app.theme_dir |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
97 if not theme_dir: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
98 logger.error("There is not theme currently applied to override.") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
99 return 1 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
100 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
101 copies = [] |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
102 for dirpath, dirnames, filenames in os.walk(theme_dir): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
103 rel_dirpath = os.path.relpath(dirpath, theme_dir) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
104 for name in filenames: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
105 if (dirpath == theme_dir and |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
106 name in [THEME_CONFIG_PATH, THEME_INFO_PATH]): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
107 continue |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
108 src_path = os.path.join(dirpath, name) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
109 dst_path = os.path.join(app_dir, rel_dirpath, name) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
110 copies.append((src_path, dst_path)) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
111 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
112 conflicts = [] |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
113 for c in copies: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
114 if os.path.exists(c[1]): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
115 conflicts.append(c[1]) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
116 if conflicts: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
117 logger.warning("Some website files will be overwritten:") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
118 for c in conflicts: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
119 logger.warning(os.path.relpath(c, app_dir)) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
120 logger.warning("Are you sure? [Y/n]") |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
121 ans = input() |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
122 if len(ans) > 0 and ans.lower() not in ['y', 'yes']: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
123 return 1 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
124 |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
125 for c in copies: |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
126 logger.info(os.path.relpath(c[1], app_dir)) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
127 if not os.path.exists(os.path.dirname(c[1])): |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
128 os.makedirs(os.path.dirname(c[1])) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
129 shutil.copy2(c[0], c[1]) |
d70a4adb61dd
themes: Add the `chef themes` command
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
130 |