Mercurial > piecrust2
annotate piecrust/commands/builtin/themes.py @ 363:dd25bd3ce1f9
serve: Refactoring and fixes to be able to serve taxonomy pages.
* Page sources' `findPagePath` is renamed to `findPageFactory`, so that it
also returns source metadata.
* Page refs now store possible hits more properly, and use the previous point
to also store metadata. As a result, they can also return a proper factory.
* Implement `findPageFactory` correctly in all built-in sources.
* When the Chef server matches a taxonomy page, get the source metadata from
the page ref in order to make a more proper page.
* Make the `getRoute(s)` functions explicitely say if they want taxonomy routes
or not.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 26 Apr 2015 15:07:40 -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 |