# HG changeset patch # User cmlenz # Date 1120561937 0 # Node ID 1d4fa4c32afac8c65e93cd8b64162e383b76dc6a # Parent 6d7753ea179811aad43229fd40a616b45438e858 Add template and static resources, hooked up using the new {{{ITemplateProvider}}} extension point in Trac. diff --git a/bitten/model.py b/bitten/model.py --- a/bitten/model.py +++ b/bitten/model.py @@ -158,6 +158,19 @@ exists = property(fget=lambda self: self.id is not None) + def delete(self, db=None): + if not db: + db = self.env.get_db_cnx() + handle_ta = True + else: + handle_ta = False + + cursor = db.cursor() + cursor.execute("DELETE FROM bitten_rule WHERE id=%s", (self.id,)) + cursor.execute("DELETE FROM bitten_platform WHERE id=%s", (self.id,)) + if handle_ta: + db.commit() + def insert(self, db=None): if not db: db = self.env.get_db_cnx() diff --git a/bitten/trac_ext/tests/web_ui.py b/bitten/trac_ext/tests/web_ui.py --- a/bitten/trac_ext/tests/web_ui.py +++ b/bitten/trac_ext/tests/web_ui.py @@ -33,6 +33,7 @@ PermissionSystem(self.env).grant_permission('joe', 'BUILD_VIEW') req = Mock(Request, path_info='/build', args={}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -45,6 +46,7 @@ PermissionSystem(self.env).grant_permission('joe', 'BUILD_ADMIN') req = Mock(Request, path_info='/build', args={}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -60,6 +62,7 @@ PermissionSystem(self.env).grant_permission('joe', 'BUILD_VIEW') req = Mock(Request, path_info='/build/test', args={}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -76,6 +79,7 @@ PermissionSystem(self.env).grant_permission('joe', 'BUILD_ADMIN') req = Mock(Request, path_info='/build/test', args={}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -87,6 +91,7 @@ PermissionSystem(self.env).grant_permission('joe', 'BUILD_ADMIN') req = Mock(Request, path_info='/build', args={'action': 'new'}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -106,6 +111,7 @@ args={'action': 'new', 'name': 'test', 'active': 'on', 'label': 'Test', 'path': 'test/trunk', 'description': 'Bla bla'}) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -129,6 +135,7 @@ redirect=redirect, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe'), args={'action': 'new', 'cancel': '1', 'name': 'test'}) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -145,6 +152,7 @@ PermissionSystem(self.env).grant_permission('joe', 'BUILD_ADMIN') req = Mock(Request, path_info='/build/test', args={'action': 'edit'}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -168,6 +176,7 @@ args={'action': 'edit', 'name': 'foo', 'active': 'on', 'label': 'Test', 'path': 'test/trunk', 'description': 'Bla bla'}) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -197,6 +206,7 @@ redirect=redirect, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe'), args={'action': 'edit', 'cancel': '1'}) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -209,8 +219,10 @@ config.insert() PermissionSystem(self.env).grant_permission('joe', 'BUILD_ADMIN') - req = Mock(Request, path_info='/build/test', args={'action': 'new'}, + req = Mock(Request, path_info='/build/test', + args={'action': 'edit', 'new': '1'}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -231,6 +243,7 @@ req = Mock(Request, method='POST', path_info='/build/test', redirect=redirect, args={'action': 'new', 'name': 'Test'}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -250,6 +263,7 @@ req = Mock(Request, method='POST', path_info='/build/test', redirect=redirect, args={'action': 'new', 'cancel': '1'}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -270,6 +284,7 @@ req = Mock(Request, path_info='/build/test', args={'action': 'edit', 'platform': platform.id}, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -297,6 +312,7 @@ 'name': 'Test'}, redirect=redirect, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) @@ -323,6 +339,7 @@ 'cancel': '1'}, redirect=redirect, hdf=HDFWrapper(), perm=PermissionCache(self.env, 'joe')) + req.hdf['htdocs_location'] = '/htdocs' module = BuildModule(self.env) assert module.match_request(req) diff --git a/bitten/trac_ext/web_ui.py b/bitten/trac_ext/web_ui.py --- a/bitten/trac_ext/web_ui.py +++ b/bitten/trac_ext/web_ui.py @@ -24,7 +24,8 @@ from trac.core import * from trac.Timeline import ITimelineEventProvider from trac.util import escape, pretty_timedelta -from trac.web.chrome import INavigationContributor, add_link +from trac.web.chrome import INavigationContributor, ITemplateProvider, \ + add_link, add_stylesheet from trac.web.main import IRequestHandler from trac.wiki import wiki_to_html from bitten.model import Build, BuildConfig, TargetPlatform @@ -32,144 +33,8 @@ class BuildModule(Component): - implements(INavigationContributor, IRequestHandler, ITimelineEventProvider) - - build_cs = """ - - -
-

-

-
- - -
-
- - - - - - - - -
- -

- -
-
- - - -
-
-

Target Platforms

-
-
- - -
-
-
-
- - -
-
-
-

Rules

- - - - - - - -
Property nameMatch pattern
-
-
-
- - - - -
-
- -

Triggered by: Changeset [] of

-

Built by: ( on )

-

Completed: ( ago)
Took:

- - - -""" + implements(INavigationContributor, IRequestHandler, ITimelineEventProvider, + ITemplateProvider) _status_label = {Build.IN_PROGRESS: 'in progress', Build.SUCCESS: 'completed', @@ -210,10 +75,18 @@ if action == 'new': self._do_create_platform(req, config) else: + self.log.debug('Request args: %s', req.args.keys()) platform_id = req.args.get('platform') if platform_id: if action == 'edit': self._do_save_platform(req, config, platform_id) + elif 'delete' in req.args.keys(): + self._do_delete_platforms(req) + self._render_config_form(req, config) + elif 'new' in req.args.keys(): + platform = TargetPlatform(self.env) + platform.config = config + self._render_platform_form(req, platform) else: self._do_save_config(req, config) else: @@ -228,12 +101,11 @@ if platform_id: platform = TargetPlatform(self.env, int(platform_id)) self._render_platform_form(req, platform) + elif 'new' in req.args.keys(): + platform = TargetPlatform(self.env) + self._render_platform_form(req, platform) else: self._render_config_form(req, config) - elif action == 'new': - platform = TargetPlatform(self.env) - platform.config = config - self._render_platform_form(req, platform) else: self._render_config(req, config) else: @@ -242,7 +114,16 @@ else: self._render_overview(req) - return req.hdf.parse(self.build_cs), None + add_stylesheet(req, 'build.css') + return 'build.cs', None + + # ITemplatesProvider methods + + def get_htdocs_dir(self): + return self.config.get('bitten', 'htdocs_dir') + + def get_templates_dir(self): + return self.config.get('bitten', 'templates_dir') # ITimelineEventProvider methods @@ -252,6 +133,7 @@ def get_timeline_events(self, req, start, stop, filters): if 'build' in filters: + add_stylesheet(req, 'build.css') db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT id,config,label,rev,slave,stopped,status " @@ -343,6 +225,19 @@ req.redirect(self.env.href.build(config_name, action='edit')) + def _do_delete_platforms(self, req): + """Delete selected target platforms.""" + req.perm.assert_permission('BUILD_MODIFY') + self.log.debug('_do_delete_platforms') + + db = self.env.get_db_cnx() + for platform_id in [int(id) for id in req.args.get('delete_platform')]: + platform = TargetPlatform(self.env, platform_id, db=db) + self.log.info('Deleting target platform %s of configuration %s', + platform.name, platform.config) + platform.delete(db=db) + db.commit() + def _do_save_platform(self, req, config_name, platform_id): """Save changes to a target platform.""" req.perm.assert_permission('BUILD_MODIFY') @@ -411,6 +306,9 @@ } req.hdf['build.mode'] = 'view_config' + platforms = TargetPlatform.select(self.env, config=config_name) + req.hdf['build.platforms'] = [platform.name for platform in platforms] + repos = self.env.get_repository(req.authname) root = repos.get_node(config.path) num = 0 @@ -431,11 +329,6 @@ 'exists': config.exists } - if 'new' in req.args.keys() or 'platform' in req.args.keys(): - self._render_platform_form(req, config_name, - req.args.get('platform')) - return - req.hdf['title'] = 'Edit Build Configuration "%s"' \ % escape(config.label or config.name) for idx, platform in enumerate(TargetPlatform.select(self.env, @@ -452,12 +345,15 @@ def _render_platform_form(self, req, platform): req.perm.assert_permission('BUILD_MODIFY') - req.hdf['title'] = 'Edit Target Platform "%s"' \ - % escape(platform.name) + if platform.exists: + req.hdf['title'] = 'Edit Target Platform "%s"' \ + % escape(platform.name) + else: + req.hdf['title'] = 'Add Target Platform' req.hdf['build.platform'] = { 'name': platform.name, 'id': platform.id, 'exists': platform.exists, 'rules': [{'property': propname, 'pattern': pattern} - for propname, pattern in platform.rules] + for propname, pattern in platform.rules] + [('', '')] } req.hdf['build.mode'] = 'edit_platform' diff --git a/htdocs/build.css b/htdocs/build.css new file mode 100644 --- /dev/null +++ b/htdocs/build.css @@ -0,0 +1,10 @@ +/* Timeline styles */ +#content.timeline dt.successbuild, #content.timeline dt.successbuild a, +#content.timeline dt.failedbuild, #content.timeline dt.failedbuild a { + background-image: url(build.png) !important +} + +#content.build form.config td.active { vertical-align: bottom; } +#content.build form.platforms ul { list-style: none; padding-left: 1em; } + +#content.build #builds { margin-top: 2em; } diff --git a/htdocs/build.png b/htdocs/build.png new file mode 100755 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1e2f5669121b121d8119ca1ca05ff66663a41075 GIT binary patch literal 300 zc%17D@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&%*9TgAsieWw;%dH0CH6Vd_r9R z|NsB&*|Vd^PoG~B(Kl^QOH0e_8mF|hwBjhusHi9_D=SMa-YEH<-$7=T1o;Is{6_%J zBLQkaan1sd$YKTtZXpn6ymYtj4^U9C#5JNMI6tkVJh3R1!8b9vC_gtfB{NaMEwd=K zJijQrSiwZk;FX$sDNwN(NU?KKYGO%dex5=|W^O8jfw{hcp}v8s@ER``pb8657srr_ zImrnLAwek&Oo7(}7}?m4P0(;<6-c-A$O#MC$vB}aC1N7aBcp=tk_|6qZ|sy!=t^W} ZIP#C{{ok5>vOqH!JYD@<);T3K0RZWzW`O_z diff --git a/templates/build.cs b/templates/build.cs new file mode 100644 --- /dev/null +++ b/templates/build.cs @@ -0,0 +1,143 @@ + + +
+

+

+
+ + +
+
+ + + + + + + + +
+ +

+ +
+
+ + + +
+
+
+

Target Platforms

+
+ + +
+
+
+
+ + +
+
Build +
+
+
+

Rules

+ + + + + + + +
Property nameMatch pattern
+
+
+
+ + + + +
+
+ +

Triggered by: Changeset [] of

+

Built by: ( on )

+

Completed: ( ago)
Took:

+ + +