Mercurial > bitten > bitten-test
annotate bitten/admin.py @ 431:11658e4af0cc
Require WebAdmin plugin to ensure the plugin is loaded before Bitten.
author | cmlenz |
---|---|
date | Tue, 14 Aug 2007 22:45:09 +0000 |
parents | d6e1a05f32f7 |
children | 74c51f648466 |
rev | line source |
---|---|
429 | 1 # -*- coding: utf-8 -*- |
2 # | |
3 # Copyright (C) 2007 Edgewall Software | |
4 # All rights reserved. | |
5 # | |
6 # This software is licensed as described in the file COPYING, which | |
7 # you should have received as part of this distribution. The terms | |
8 # are also available at http://bitten.edgewall.org/wiki/License. | |
9 | |
10 """Implementation of the web administration interface.""" | |
11 | |
431
11658e4af0cc
Require WebAdmin plugin to ensure the plugin is loaded before Bitten.
cmlenz
parents:
429
diff
changeset
|
12 from pkg_resources import require |
429 | 13 import re |
14 | |
15 from trac.core import * | |
431
11658e4af0cc
Require WebAdmin plugin to ensure the plugin is loaded before Bitten.
cmlenz
parents:
429
diff
changeset
|
16 try: |
11658e4af0cc
Require WebAdmin plugin to ensure the plugin is loaded before Bitten.
cmlenz
parents:
429
diff
changeset
|
17 require("TracWebAdmin") |
11658e4af0cc
Require WebAdmin plugin to ensure the plugin is loaded before Bitten.
cmlenz
parents:
429
diff
changeset
|
18 from webadmin.web_ui import IAdminPageProvider |
11658e4af0cc
Require WebAdmin plugin to ensure the plugin is loaded before Bitten.
cmlenz
parents:
429
diff
changeset
|
19 except ImportError: |
11658e4af0cc
Require WebAdmin plugin to ensure the plugin is loaded before Bitten.
cmlenz
parents:
429
diff
changeset
|
20 IAdminPageProvider = None |
429 | 21 |
22 from bitten.model import BuildConfig, TargetPlatform | |
23 from bitten.recipe import Recipe | |
24 from bitten.util import xmlio | |
25 | |
26 | |
27 class BuildMasterAdminPageProvider(Component): | |
28 """Web administration panel for configuring the build master.""" | |
29 | |
30 implements(IAdminPageProvider) | |
31 | |
32 # IAdminPageProvider methods | |
33 | |
34 def get_admin_pages(self, req): | |
35 if req.perm.has_permission('BUILD_ADMIN'): | |
36 yield ('bitten', 'Bitten', 'master', 'Build Master') | |
37 | |
38 def process_admin_request(self, req, cat, page, path_info): | |
39 from bitten.master import BuildMaster | |
40 master = BuildMaster(self.env) | |
41 | |
42 if req.method == 'POST': | |
43 changed = False | |
44 build_all = 'build_all' in req.args | |
45 if build_all != master.build_all: | |
46 self.config['bitten'].set('build_all', | |
47 build_all and 'yes' or 'no') | |
48 changed = True | |
49 adjust_timestamps = 'adjust_timestamps' in req.args | |
50 if adjust_timestamps != master.adjust_timestamps: | |
51 self.config['bitten'].set('adjust_timestamps', | |
52 adjust_timestamps and 'yes' or 'no') | |
53 changed = True | |
54 slave_timeout = int(req.args.get('slave_timeout', 0)) | |
55 if slave_timeout != master.slave_timeout: | |
56 self.config['bitten'].set('slave_timeout', str(slave_timeout)) | |
57 changed = True | |
58 if changed: | |
59 self.config.save() | |
60 | |
61 req.hdf['admin.master'] = { | |
62 'build_all': master.build_all, | |
63 'adjust_timestamps': master.adjust_timestamps, | |
64 'slave_timeout': master.slave_timeout, | |
65 } | |
66 return 'bitten_admin_master.cs', None | |
67 | |
68 | |
69 class BuildConfigurationsAdminPageProvider(Component): | |
70 """Web administration panel for configuring the build master.""" | |
71 | |
72 implements(IAdminPageProvider) | |
73 | |
74 # IAdminPageProvider methods | |
75 | |
76 def get_admin_pages(self, req): | |
77 if req.perm.has_permission('BUILD_MODIFY'): | |
78 yield ('bitten', 'Bitten', 'configs', 'Configurations') | |
79 | |
80 def process_admin_request(self, req, cat, page, config_name): | |
81 data = {} | |
82 | |
83 if config_name: | |
84 config = BuildConfig.fetch(self.env, config_name) | |
85 platforms = list(TargetPlatform.select(self.env, config=config.name)) | |
86 | |
87 if req.method == 'POST': | |
88 if 'save' in req.args: | |
89 name = req.args.get('name') | |
90 if not name: | |
91 raise TracError('Missing required field "name"', | |
92 'Missing field') | |
93 if not re.match(r'^[\w.-]+$', name): | |
94 raise TracError('The field "name" may only contain ' | |
95 'letters, digits, periods, or dashes.', | |
96 'Invalid field') | |
97 | |
98 path = req.args.get('path', '') | |
99 repos = self.env.get_repository(req.authname) | |
100 max_rev = req.args.get('max_rev') or None | |
101 try: | |
102 node = repos.get_node(path, max_rev) | |
103 assert node.isdir, '%s is not a directory' % node.path | |
104 except (AssertionError, TracError), e: | |
105 raise TracError(e, 'Invalid repository path') | |
106 if req.args.get('min_rev'): | |
107 try: | |
108 repos.get_node(path, req.args.get('min_rev')) | |
109 except TracError, e: | |
110 raise TracError(e, | |
111 'Invalid value for oldest revision') | |
112 | |
113 recipe_xml = req.args.get('recipe', '') | |
114 if recipe_xml: | |
115 try: | |
116 Recipe(xmlio.parse(recipe_xml)).validate() | |
117 except xmlio.ParseError, e: | |
118 raise TracError('Failure parsing recipe: %s' % e, | |
119 'Invalid recipe') | |
120 except InvalidRecipeError, e: | |
121 raise TracError(e, 'Invalid recipe') | |
122 | |
123 config.name = name | |
124 config.path = repos.normalize_path(path) | |
125 config.recipe = recipe_xml | |
126 config.min_rev = req.args.get('min_rev') | |
127 config.max_rev = req.args.get('max_rev') | |
128 config.label = req.args.get('label', '') | |
129 config.description = req.args.get('description', '') | |
130 config.update() | |
131 req.redirect(self.env.href.admin(cat, page)) | |
132 | |
133 elif 'cancel' in req.args: | |
134 req.redirect(self.env.href.admin(cat, page)) | |
135 | |
136 data['config'] = { | |
137 'name': config.name, 'label': config.label or config.name, | |
138 'active': config.active, 'path': config.path, | |
139 'min_rev': config.min_rev, 'max_rev': config.max_rev, | |
140 'description': config.description, | |
141 'recipe': config.recipe, | |
142 'platforms': [{ | |
143 'name': platform.name, | |
144 'id': platform.id, | |
145 'href': req.href.admin('bitten', 'configs', config.name, | |
146 platform.id) | |
147 } for platform in platforms] | |
148 } | |
149 | |
150 else: | |
151 if req.method == 'POST': | |
152 # Add configuration | |
153 if 'add' in req.args: | |
154 config = BuildConfig(self.env) | |
155 config.name = req.args.get('name') | |
156 config.label = req.args.get('label', config.name) | |
157 config.path = req.args.get('path') | |
158 config.insert() | |
159 req.redirect(self.env.href.admin(cat, page, config.name)) | |
160 | |
161 # Remove configurations | |
162 elif 'remove' in req.args: | |
163 sel = req.args.get('sel') | |
164 sel = isinstance(sel, list) and sel or [sel] | |
165 if not sel: | |
166 raise TracError('No configuration selected') | |
167 db = self.env.get_db_cnx() | |
168 for name in sel: | |
169 config = BuildConfig.fetch(self.env, name, db=db) | |
170 config.delete(db=db) | |
171 db.commit() | |
172 req.redirect(self.env.href.admin(cat, page)) | |
173 | |
174 # Set active state | |
175 elif 'apply' in req.args: | |
176 active = req.args.get('active') | |
177 active = isinstance(active, list) and active or [active] | |
178 db = self.env.get_db_cnx() | |
179 for config in BuildConfig.select(self.env, db=db, | |
180 include_inactive=True): | |
181 config.active = config.name in active | |
182 config.update(db=db) | |
183 db.commit() | |
184 req.redirect(self.env.href.admin(cat, page)) | |
185 | |
186 configs = [] | |
187 for config in BuildConfig.select(self.env, include_inactive=True): | |
188 configs.append({ | |
189 'name': config.name, 'label': config.label or config.name, | |
190 'active': config.active, 'path': config.path, | |
191 'min_rev': config.min_rev, 'max_rev': config.max_rev, | |
192 'href': req.href.admin('bitten', 'configs', config.name), | |
193 }) | |
194 data['configs'] = configs | |
195 | |
196 req.hdf['admin'] = data | |
197 return 'bitten_admin_configs.cs', None |