You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by as...@apache.org on 2013/07/09 11:24:58 UTC
svn commit: r1501157 - in /bloodhound/trunk:
bloodhound_dashboard/bhdashboard/widgets/templates/
bloodhound_relations/bhrelations/ bloodhound_relations/bhrelations/templates/
bloodhound_relations/bhrelations/widgets/
Author: astaric
Date: Tue Jul 9 09:24:58 2013
New Revision: 1501157
URL: http://svn.apache.org/r1501157
Log:
EOL normalization.
Converted CRLF to LF to match the rest of the files.
Modified:
bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html
bloodhound/trunk/bloodhound_relations/bhrelations/templates/manage.html
bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py
bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py
Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html?rev=1501157&r1=1501156&r2=1501157&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html Tue Jul 9 09:24:58 2013
@@ -1,64 +1,64 @@
-<!--!
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-<div
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:py="http://genshi.edgewall.org/"
- xmlns:xi="http://www.w3.org/2001/XInclude">
-
- <py:choose test="">
- <py:when test="relations">
- <table class="table table-condensed table-bordered">
- <thead>
- <tr>
- <th>Type</th><th>Product</th><th>Ticket</th><th>Comment</th><th>Author</th><th class="hidden-phone">Changed</th>
- </tr>
- </thead>
-
- <tbody py:for="relgroup,items in relations.iteritems()">
- <tr py:for="item in items" class="relation">
- <td>${relgroup if items.index(item) == 0 else None}</td>
- <td>
- <a href="${href.products(item['destticket'].env.product.prefix)}">
- <span class="hidden-phone">${item['destticket'].env.product.name} (${item['destticket'].env.product.prefix})</span>
- <span class="visible-phone">${item['destticket'].env.product.prefix}</span>
- </a>
- </td>
- <td><a href="${item['desthref']}">#${item['destticket'].id}</a> - ${item['destticket'].summary}</td>
- <td>$item.comment</td>
- <td>$item.author</td>
- <td class="hidden-phone">${pretty_dateinfo(item.when)}</td>
- </tr>
- </tbody>
- </table>
- </py:when>
- <py:otherwise>
- <div class="alert alert-info">
- No defined relations for this ticket.
- </div>
- </py:otherwise>
- </py:choose>
-
- <div class="btn-group">
- <form method="get" action="${href.ticket(ticket.id, 'relations')}">
- <button type="submit" class="btn" id="manage-relations"><i class="icon-retweet"></i> Manage relations</button>
- </form>
- </div>
-</div>
-
+<!--!
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<div
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:py="http://genshi.edgewall.org/"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <py:choose test="">
+ <py:when test="relations">
+ <table class="table table-condensed table-bordered">
+ <thead>
+ <tr>
+ <th>Type</th><th>Product</th><th>Ticket</th><th>Comment</th><th>Author</th><th class="hidden-phone">Changed</th>
+ </tr>
+ </thead>
+
+ <tbody py:for="relgroup,items in relations.iteritems()">
+ <tr py:for="item in items" class="relation">
+ <td>${relgroup if items.index(item) == 0 else None}</td>
+ <td>
+ <a href="${href.products(item['destticket'].env.product.prefix)}">
+ <span class="hidden-phone">${item['destticket'].env.product.name} (${item['destticket'].env.product.prefix})</span>
+ <span class="visible-phone">${item['destticket'].env.product.prefix}</span>
+ </a>
+ </td>
+ <td><a href="${item['desthref']}">#${item['destticket'].id}</a> - ${item['destticket'].summary}</td>
+ <td>$item.comment</td>
+ <td>$item.author</td>
+ <td class="hidden-phone">${pretty_dateinfo(item.when)}</td>
+ </tr>
+ </tbody>
+ </table>
+ </py:when>
+ <py:otherwise>
+ <div class="alert alert-info">
+ No defined relations for this ticket.
+ </div>
+ </py:otherwise>
+ </py:choose>
+
+ <div class="btn-group">
+ <form method="get" action="${href.ticket(ticket.id, 'relations')}">
+ <button type="submit" class="btn" id="manage-relations"><i class="icon-retweet"></i> Manage relations</button>
+ </form>
+ </div>
+</div>
+
Modified: bloodhound/trunk/bloodhound_relations/bhrelations/templates/manage.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/bhrelations/templates/manage.html?rev=1501157&r1=1501156&r2=1501157&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/bhrelations/templates/manage.html (original)
+++ bloodhound/trunk/bloodhound_relations/bhrelations/templates/manage.html Tue Jul 9 09:24:58 2013
@@ -1,127 +1,127 @@
-<!--!
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- xmlns:py="http://genshi.edgewall.org/"
- xmlns:i18n="http://genshi.edgewall.org/i18n"
- xmlns:bh="http://issues.apache.org/bloodhound/wiki/Ui/Dashboard">
- <xi:include href="layout.html" />
- <xi:include href="widget_macros.html" />
-
- <head>
- <title py:choose="">Ticket relations for #${ticket.id}</title>
- </head>
-
- <body>
- <h1>Manage relations for ticket <a href="${href.ticket(ticket.id)}">#$ticket.id</a></h1>
-
- <div class="row">
- <div class="span8">
- <py:if test='error'>
- <div class="alert alert-error">
- <span class="label label-important">Oops !</span>
- Could not create relation.
- $error
- </div>
- </py:if>
-
- <form id="addrelation" class="well form-horizontal" method="post" action="">
- <fieldset>
- <legend>Add relation:</legend>
- </fieldset>
-
- <div class="control-group">
- <label class="control-label" for="dest_tid">Related ticket:</label>
- <div class="controls">
- <input type="text" id="dest_tid" class="span4" name="dest_tid" value="$relation.destination" />
- </div>
- </div>
-
- <div class="control-group">
- <label class="control-label" for="reltype">Relation type:</label>
- <div class="controls">
- <select class="span4" id="reltype" name="reltype">
- <option py:for="reltype,label in reltypes.iteritems()" value="$reltype" selected="${True if reltype == relation.type else None}">$label</option>
- </select>
- </div>
- </div>
-
- <div class="control-group">
- <label class="control-label" for="comment">Comment:</label>
- <div class="controls">
- <textarea name="comment" rows="3" class="span4">${relation.comment}</textarea>
- </div>
- </div>
-
- <div class="control-group">
- <div class="controls">
- <input type="submit" class="btn" name="add" value="${_('Add')}" />
- </div>
- </div>
- </form>
- </div>
- </div>
-
- <div class="row">
- <div class="span8">
- <py:choose>
- <form py:when="relations" id="rmrelations" class="form-horizontal" method="post" action="">
- <table class="table table-condensed table-bordered">
- <thead>
- <tr>
- <th class="sel"><i class="icon-check"></i></th>
- <th>Type</th><th>Product</th><th>Ticket</th><th>Comment</th><th>Author</th><th class="hidden-phone">Changed</th>
- </tr>
- </thead>
- <tbody py:for="relgroup,items in relations.iteritems()">
- <tr py:for="item in items">
- <td class="sel"><input type="checkbox" name="sel" value="${item.relation_id}" /></td>
- <td>${relgroup if items.index(item) == 0 else None}</td>
- <td>
- <a href="${href.products(item['destticket'].env.product.prefix)}">
- <span class="hidden-phone">${item['destticket'].env.product.name} (${item['destticket'].env.product.prefix})</span>
- <span class="visible-phone">${item['destticket'].env.product.prefix}</span>
- </a>
- </td>
- <td><a href="${item['desthref']}">#${item['destticket'].id}</a> - ${item['destticket'].summary}</td>
- <td>$item.comment</td>
- <td>$item.author</td>
- <td class="hidden-phone">${pretty_dateinfo(item.when)}</td>
- </tr>
- </tbody>
- </table>
-
- <div class="control-group">
- <input type="submit" class="btn" name="remove" value="${_('Remove selected relations')}" />
- </div>
- </form>
-
- <div py:otherwise="" class="alert alert-info">
- No defined relations for this ticket.
- </div>
- </py:choose>
- </div>
- </div>
- </body>
-</html>
-
+<!--!
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xmlns:py="http://genshi.edgewall.org/"
+ xmlns:i18n="http://genshi.edgewall.org/i18n"
+ xmlns:bh="http://issues.apache.org/bloodhound/wiki/Ui/Dashboard">
+ <xi:include href="layout.html" />
+ <xi:include href="widget_macros.html" />
+
+ <head>
+ <title py:choose="">Ticket relations for #${ticket.id}</title>
+ </head>
+
+ <body>
+ <h1>Manage relations for ticket <a href="${href.ticket(ticket.id)}">#$ticket.id</a></h1>
+
+ <div class="row">
+ <div class="span8">
+ <py:if test='error'>
+ <div class="alert alert-error">
+ <span class="label label-important">Oops !</span>
+ Could not create relation.
+ $error
+ </div>
+ </py:if>
+
+ <form id="addrelation" class="well form-horizontal" method="post" action="">
+ <fieldset>
+ <legend>Add relation:</legend>
+ </fieldset>
+
+ <div class="control-group">
+ <label class="control-label" for="dest_tid">Related ticket:</label>
+ <div class="controls">
+ <input type="text" id="dest_tid" class="span4" name="dest_tid" value="$relation.destination" />
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for="reltype">Relation type:</label>
+ <div class="controls">
+ <select class="span4" id="reltype" name="reltype">
+ <option py:for="reltype,label in reltypes.iteritems()" value="$reltype" selected="${True if reltype == relation.type else None}">$label</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for="comment">Comment:</label>
+ <div class="controls">
+ <textarea name="comment" rows="3" class="span4">${relation.comment}</textarea>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <div class="controls">
+ <input type="submit" class="btn" name="add" value="${_('Add')}" />
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="span8">
+ <py:choose>
+ <form py:when="relations" id="rmrelations" class="form-horizontal" method="post" action="">
+ <table class="table table-condensed table-bordered">
+ <thead>
+ <tr>
+ <th class="sel"><i class="icon-check"></i></th>
+ <th>Type</th><th>Product</th><th>Ticket</th><th>Comment</th><th>Author</th><th class="hidden-phone">Changed</th>
+ </tr>
+ </thead>
+ <tbody py:for="relgroup,items in relations.iteritems()">
+ <tr py:for="item in items">
+ <td class="sel"><input type="checkbox" name="sel" value="${item.relation_id}" /></td>
+ <td>${relgroup if items.index(item) == 0 else None}</td>
+ <td>
+ <a href="${href.products(item['destticket'].env.product.prefix)}">
+ <span class="hidden-phone">${item['destticket'].env.product.name} (${item['destticket'].env.product.prefix})</span>
+ <span class="visible-phone">${item['destticket'].env.product.prefix}</span>
+ </a>
+ </td>
+ <td><a href="${item['desthref']}">#${item['destticket'].id}</a> - ${item['destticket'].summary}</td>
+ <td>$item.comment</td>
+ <td>$item.author</td>
+ <td class="hidden-phone">${pretty_dateinfo(item.when)}</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <div class="control-group">
+ <input type="submit" class="btn" name="remove" value="${_('Remove selected relations')}" />
+ </div>
+ </form>
+
+ <div py:otherwise="" class="alert alert-info">
+ No defined relations for this ticket.
+ </div>
+ </py:choose>
+ </div>
+ </div>
+ </body>
+</html>
+
Modified: bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py?rev=1501157&r1=1501156&r2=1501157&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py (original)
+++ bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py Tue Jul 9 09:24:58 2013
@@ -1,171 +1,171 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-r"""Ticket relations for Apache(TM) Bloodhound
-
-Ticket relations user interface.
-"""
-
-import re
-import pkg_resources
-
-from trac.core import Component, implements, TracError
-from trac.resource import get_resource_url, Resource
-from trac.ticket.model import Ticket
-from trac.util.translation import _
-from trac.web import IRequestHandler, IRequestFilter
-from trac.web.chrome import ITemplateProvider, add_warning
-
-from bhrelations.api import RelationsSystem, ResourceIdSerializer, \
- TicketRelationsSpecifics, UnknownRelationType, NoSuchTicketError
-from bhrelations.model import Relation
-from bhrelations.validation import ValidationError
-
-
-class RelationManagementModule(Component):
- implements(IRequestFilter, IRequestHandler, ITemplateProvider)
-
- # IRequestHandler methods
- def match_request(self, req):
- match = re.match(r'/ticket/([0-9]+)/relations/*$', req.path_info)
- if not match:
- return False
-
- req.args['id'] = match.group(1)
- return True
-
- def process_request(self, req):
- tid = req.args.get('id')
- if not tid:
- raise TracError(_('No ticket id provided.'))
-
- try:
- ticket = Ticket(self.env, tid)
- except ValueError:
- raise TracError(_('Invalid ticket id.'))
-
- req.perm.require('TICKET_VIEW')
- relsys = RelationsSystem(self.env)
-
- data = {
- 'relation': {},
- }
- if req.method == 'POST':
- # for modifying the relations TICKET_MODIFY is required for
- # both the source and the destination tickets
- req.perm.require('TICKET_MODIFY')
-
- if 'remove' in req.args:
- rellist = req.args.get('sel')
- if rellist:
- if isinstance(rellist, basestring):
- rellist = [rellist, ]
- self.remove_relations(req, rellist)
- elif 'add' in req.args:
- relation = dict(
- destination=req.args.get('dest_tid', ''),
- type=req.args.get('reltype', ''),
- comment=req.args.get('comment', ''),
- )
- try:
- trs = TicketRelationsSpecifics(self.env)
- dest_ticket = trs.find_ticket(relation['destination'])
- except NoSuchTicketError:
- data['error'] = _('Invalid ticket ID.')
- else:
- req.perm.require('TICKET_MODIFY', Resource(dest_ticket.id))
-
- try:
- relsys.add(ticket, dest_ticket,
- relation['type'],
- relation['comment'],
- req.authname)
- except NoSuchTicketError:
- data['error'] = _('Invalid ticket ID.')
- except UnknownRelationType:
- data['error'] = _('Unknown relation type.')
- except ValidationError as ex:
- data['error'] = ex.message
-
- if 'error' in data:
- data['relation'] = relation
- else:
- raise TracError(_('Invalid operation.'))
-
- data.update({
- 'ticket': ticket,
- 'reltypes': relsys.get_relation_types(),
- 'relations': self.get_ticket_relations(ticket),
- })
- return 'manage.html', data, None
-
- # ITemplateProvider methods
- def get_htdocs_dirs(self):
- resource_filename = pkg_resources.resource_filename
- return [('relations', resource_filename('bhrelations', 'htdocs')), ]
-
- def get_templates_dirs(self):
- resource_filename = pkg_resources.resource_filename
- return [resource_filename('bhrelations', 'templates'), ]
-
- # IRequestFilter methods
- def pre_process_request(self, req, handler):
- return handler
-
- def post_process_request(self, req, template, data, content_type):
- if 'ticket' in data:
- ticket = data['ticket']
- rls = RelationsSystem(self.env)
- resid = ResourceIdSerializer.get_resource_id_from_instance(
- self.env, ticket)
-
- if rls.duplicate_relation_type:
- duplicate_relations = \
- rls._select_relations(resid, rls.duplicate_relation_type)
- if duplicate_relations:
- data['ticket_duplicate_of'] = \
- duplicate_relations[0].destination
- return template, data, content_type
-
- # utility functions
- def get_ticket_relations(self, ticket):
- grouped_relations = {}
- relsys = RelationsSystem(self.env)
- reltypes = relsys.get_relation_types()
- trs = TicketRelationsSpecifics(self.env)
- for r in relsys.get_relations(ticket):
- r['desthref'] = get_resource_url(self.env, r['destination'],
- self.env.href)
- r['destticket'] = trs._create_ticket_by_full_id(r['destination'])
- grouped_relations.setdefault(reltypes[r['type']], []).append(r)
- return grouped_relations
-
- def remove_relations(self, req, rellist):
- relsys = RelationsSystem(self.env)
- for relid in rellist:
- relation = Relation.load_by_relation_id(self.env, relid)
- resource = ResourceIdSerializer.get_resource_by_id(
- relation.destination)
- if 'TICKET_MODIFY' in req.perm(resource):
- relsys.delete(relid)
- else:
- add_warning(req,
- _('Not enough permissions to remove relation "%s"' % relid))
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+r"""Ticket relations for Apache(TM) Bloodhound
+
+Ticket relations user interface.
+"""
+
+import re
+import pkg_resources
+
+from trac.core import Component, implements, TracError
+from trac.resource import get_resource_url, Resource
+from trac.ticket.model import Ticket
+from trac.util.translation import _
+from trac.web import IRequestHandler, IRequestFilter
+from trac.web.chrome import ITemplateProvider, add_warning
+
+from bhrelations.api import RelationsSystem, ResourceIdSerializer, \
+ TicketRelationsSpecifics, UnknownRelationType, NoSuchTicketError
+from bhrelations.model import Relation
+from bhrelations.validation import ValidationError
+
+
+class RelationManagementModule(Component):
+ implements(IRequestFilter, IRequestHandler, ITemplateProvider)
+
+ # IRequestHandler methods
+ def match_request(self, req):
+ match = re.match(r'/ticket/([0-9]+)/relations/*$', req.path_info)
+ if not match:
+ return False
+
+ req.args['id'] = match.group(1)
+ return True
+
+ def process_request(self, req):
+ tid = req.args.get('id')
+ if not tid:
+ raise TracError(_('No ticket id provided.'))
+
+ try:
+ ticket = Ticket(self.env, tid)
+ except ValueError:
+ raise TracError(_('Invalid ticket id.'))
+
+ req.perm.require('TICKET_VIEW')
+ relsys = RelationsSystem(self.env)
+
+ data = {
+ 'relation': {},
+ }
+ if req.method == 'POST':
+ # for modifying the relations TICKET_MODIFY is required for
+ # both the source and the destination tickets
+ req.perm.require('TICKET_MODIFY')
+
+ if 'remove' in req.args:
+ rellist = req.args.get('sel')
+ if rellist:
+ if isinstance(rellist, basestring):
+ rellist = [rellist, ]
+ self.remove_relations(req, rellist)
+ elif 'add' in req.args:
+ relation = dict(
+ destination=req.args.get('dest_tid', ''),
+ type=req.args.get('reltype', ''),
+ comment=req.args.get('comment', ''),
+ )
+ try:
+ trs = TicketRelationsSpecifics(self.env)
+ dest_ticket = trs.find_ticket(relation['destination'])
+ except NoSuchTicketError:
+ data['error'] = _('Invalid ticket ID.')
+ else:
+ req.perm.require('TICKET_MODIFY', Resource(dest_ticket.id))
+
+ try:
+ relsys.add(ticket, dest_ticket,
+ relation['type'],
+ relation['comment'],
+ req.authname)
+ except NoSuchTicketError:
+ data['error'] = _('Invalid ticket ID.')
+ except UnknownRelationType:
+ data['error'] = _('Unknown relation type.')
+ except ValidationError as ex:
+ data['error'] = ex.message
+
+ if 'error' in data:
+ data['relation'] = relation
+ else:
+ raise TracError(_('Invalid operation.'))
+
+ data.update({
+ 'ticket': ticket,
+ 'reltypes': relsys.get_relation_types(),
+ 'relations': self.get_ticket_relations(ticket),
+ })
+ return 'manage.html', data, None
+
+ # ITemplateProvider methods
+ def get_htdocs_dirs(self):
+ resource_filename = pkg_resources.resource_filename
+ return [('relations', resource_filename('bhrelations', 'htdocs')), ]
+
+ def get_templates_dirs(self):
+ resource_filename = pkg_resources.resource_filename
+ return [resource_filename('bhrelations', 'templates'), ]
+
+ # IRequestFilter methods
+ def pre_process_request(self, req, handler):
+ return handler
+
+ def post_process_request(self, req, template, data, content_type):
+ if 'ticket' in data:
+ ticket = data['ticket']
+ rls = RelationsSystem(self.env)
+ resid = ResourceIdSerializer.get_resource_id_from_instance(
+ self.env, ticket)
+
+ if rls.duplicate_relation_type:
+ duplicate_relations = \
+ rls._select_relations(resid, rls.duplicate_relation_type)
+ if duplicate_relations:
+ data['ticket_duplicate_of'] = \
+ duplicate_relations[0].destination
+ return template, data, content_type
+
+ # utility functions
+ def get_ticket_relations(self, ticket):
+ grouped_relations = {}
+ relsys = RelationsSystem(self.env)
+ reltypes = relsys.get_relation_types()
+ trs = TicketRelationsSpecifics(self.env)
+ for r in relsys.get_relations(ticket):
+ r['desthref'] = get_resource_url(self.env, r['destination'],
+ self.env.href)
+ r['destticket'] = trs._create_ticket_by_full_id(r['destination'])
+ grouped_relations.setdefault(reltypes[r['type']], []).append(r)
+ return grouped_relations
+
+ def remove_relations(self, req, rellist):
+ relsys = RelationsSystem(self.env)
+ for relid in rellist:
+ relation = Relation.load_by_relation_id(self.env, relid)
+ resource = ResourceIdSerializer.get_resource_by_id(
+ relation.destination)
+ if 'TICKET_MODIFY' in req.perm(resource):
+ relsys.delete(relid)
+ else:
+ add_warning(req,
+ _('Not enough permissions to remove relation "%s"' % relid))
Modified: bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py?rev=1501157&r1=1501156&r2=1501157&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py (original)
+++ bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py Tue Jul 9 09:24:58 2013
@@ -1,75 +1,75 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-r"""Project dashboard for Apache(TM) Bloodhound
-
-Widgets displaying ticket relations.
-"""
-
-from trac.util.translation import _
-from trac.ticket.model import Ticket
-
-from bhdashboard.util import WidgetBase, check_widget_name, pretty_wrapper
-from bhrelations.web_ui import RelationManagementModule
-
-__metaclass__ = type
-
-
-class TicketRelationsWidget(WidgetBase):
- """Display ticket relations.
- """
- def get_widget_params(self, name):
- """Return a dictionary containing arguments specification for
- the widget with specified name.
- """
- return {
- 'tid' : {
- 'desc' : """Source ticket id""",
- 'type' : int
- },
-
- 'max' : {
- 'desc' : """Limit the number of relations displayed""",
- 'type' : int
- },
- }
-
- get_widget_params = pretty_wrapper(get_widget_params, check_widget_name)
-
- def render_widget(self, name, context, options):
- """Gather list of relations and render data in compact view
- """
- req = context.req
- title = _('Related tickets')
- params = ('tid', 'max')
- tid, max_ = self.bind_params(name, options, *params)
-
- ticket = Ticket(self.env, tid)
- data = {
- 'ticket': ticket,
- 'relations': \
- RelationManagementModule(self.env).get_ticket_relations(ticket),
- }
- return 'widget_relations.html', \
- {'title': title, 'data': data, }, context
-
- render_widget = pretty_wrapper(render_widget, check_widget_name)
-
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+r"""Project dashboard for Apache(TM) Bloodhound
+
+Widgets displaying ticket relations.
+"""
+
+from trac.util.translation import _
+from trac.ticket.model import Ticket
+
+from bhdashboard.util import WidgetBase, check_widget_name, pretty_wrapper
+from bhrelations.web_ui import RelationManagementModule
+
+__metaclass__ = type
+
+
+class TicketRelationsWidget(WidgetBase):
+ """Display ticket relations.
+ """
+ def get_widget_params(self, name):
+ """Return a dictionary containing arguments specification for
+ the widget with specified name.
+ """
+ return {
+ 'tid' : {
+ 'desc' : """Source ticket id""",
+ 'type' : int
+ },
+
+ 'max' : {
+ 'desc' : """Limit the number of relations displayed""",
+ 'type' : int
+ },
+ }
+
+ get_widget_params = pretty_wrapper(get_widget_params, check_widget_name)
+
+ def render_widget(self, name, context, options):
+ """Gather list of relations and render data in compact view
+ """
+ req = context.req
+ title = _('Related tickets')
+ params = ('tid', 'max')
+ tid, max_ = self.bind_params(name, options, *params)
+
+ ticket = Ticket(self.env, tid)
+ data = {
+ 'ticket': ticket,
+ 'relations': \
+ RelationManagementModule(self.env).get_ticket_relations(ticket),
+ }
+ return 'widget_relations.html', \
+ {'title': title, 'data': data, }, context
+
+ render_widget = pretty_wrapper(render_widget, check_widget_name)
+