Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jinja2 #34

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ dist
*.pyc
*.swp
*.egg-info
*.mo
tags
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
package_data={
'tracsubtickets': [
'htdocs/css/*.css',
'htdocs/js/*.js',
'locale/*/LC_MESSAGES/*.mo',
],
},
Expand Down
2 changes: 1 addition & 1 deletion tracsubtickets/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
NotificationSystem = TicketChangeEvent = None
from trac.ticket.notification import TicketNotifyEmail

import db_default
from . import db_default


NUMBERS_RE = re.compile(r'\d+', re.U)
Expand Down
8 changes: 4 additions & 4 deletions tracsubtickets/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

from trac.env import open_environment

from api import NUMBERS_RE
from .api import NUMBERS_RE


def check_subtickets(db):
Expand Down Expand Up @@ -68,9 +68,9 @@ def check_subtickets(db):
result = True

if not result:
print "Mismatch in ticket #%i" % id
print " custom field :", cfield.get(id, '--')
print " subtickets :", subtickets.get(id, '--')
print("Mismatch in ticket #%i" % id)
print(" custom field :", cfield.get(id, '--'))
print(" subtickets :", subtickets.get(id, '--'))


def main(args=sys.argv[1:]):
Expand Down
60 changes: 60 additions & 0 deletions tracsubtickets/htdocs/js/appendsubticketsdata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
(function() {
var $, args;

$ = jQuery;

// subtickets_script_args must have been defined via add_script_data()
args = $.parseJSON(subtickets_script_args);

createButton = function() {
var form = $(`<form method="get" action="${args.href_req_newticket}"></form>`);
var div = $(`<div class="inlinebuttons"></div>`);
var submitButton = $(`<input type="submit" value="${args.localized_button_label}" title="${args.localized_button_title}"></input>`);
var parentsArg = $(`<input type="hidden" name="parents" value="${args.parent_id}"></input>`);

div.append(submitButton);
div.append(parentsArg);
$.each($.parseJSON(args.inherited_args), function(key, value) {
var inheritedArg = $(`<input type="hidden" name="${key}" value="${value}"></input>`);
div.append(inheritedArg);
});

form.append(div);

return form;
}

createLink = function() {
return $(`<span class="addsubticket">(<a href="${args.href_req_newticket_with_parent}">${args.localized_link_label}</a>)</span>`);
}

$(document).ready(function() {
var div = $('<div class="description"></div>');
var table = $('<table class="subtickets"></table>');

$.each($.parseJSON(args.subtickets_table), function(key, value) {
var row = $('<tr></tr>');
row.append(value.summary);
row.append(value.status);
row.append(value.owner);
table.append(row);
});

if (args.add_style == 'link') {
var link = createLink();
var separator = $(`<h3>${args.localized_separator_label}</h3>`);
separator.append(link);
div.append(separator);
}
else {
var button = createButton();
var separator = $(`<h3>${args.localized_separator_label}</h3>`);
div.append(button);
div.append(separator);
}
div.append(table);

$('div#ticket').append(div);
});

}).call(this);
108 changes: 47 additions & 61 deletions tracsubtickets/web_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,24 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import json
from trac.config import Option, IntOption, ChoiceOption, ListOption
from trac.core import Component, implements
from trac.web.api import IRequestFilter, ITemplateStreamFilter
from trac.web.api import IRequestFilter
from trac.web.chrome import ITemplateProvider, add_stylesheet
from trac.util.html import html as tag
from trac.web.chrome import add_script, add_script_data
from trac.util.html import html as tag, escape
from trac.ticket.api import ITicketManipulator
from trac.ticket.model import Ticket
from trac.ticket.model import Type as TicketType
from trac.resource import ResourceNotFound
from genshi.filters import Transformer

from api import NUMBERS_RE, _
from .api import NUMBERS_RE, _


class SubTicketsModule(Component):

implements(IRequestFilter, ITicketManipulator, ITemplateProvider,
ITemplateStreamFilter)
implements(IRequestFilter, ITicketManipulator, ITemplateProvider)

# Simple Options

Expand Down Expand Up @@ -110,7 +110,7 @@ def __init__(self):

def get_htdocs_dirs(self):
from pkg_resources import resource_filename
return [('subtickets', resource_filename(__name__, 'htdocs'))]
yield 'subtickets', resource_filename(__name__, 'htdocs')

def get_templates_dirs(self):
return []
Expand Down Expand Up @@ -143,6 +143,9 @@ def post_process_request(self, req, template, data, content_type):
and data['add'] == 'Add':
self._add_per_ticket_type_option(data['name'])

# append subtickets data (happended in filter_stream() before)
self._append_subtickets_data(req, data)

return template, data, content_type

def _append_parent_links(self, req, data, ids):
Expand Down Expand Up @@ -206,9 +209,7 @@ def validate_ticket(self, req, ticket):
"is closed", id=id)
yield None, msg

# ITemplateStreamFilter method

def _create_subtickets_table(self, req, children, tbody, depth=0):
def _create_subtickets_table(self, req, children, tdict, depth=0):
"""Recursively create list table of subtickets
"""
if not children:
Expand All @@ -217,15 +218,15 @@ def _create_subtickets_table(self, req, children, tbody, depth=0):
ticket = Ticket(self.env, id)

# the row
r = []
rdict = dict()
# Always show ID and summary
attrs = {'href': req.href.ticket(id)}
if ticket['status'] == 'closed':
attrs['class_'] = 'closed'
link = tag.a('#%s' % id, **attrs)
summary = tag.td(link, ': %s' % ticket['summary'],
style='padding-left: %dpx;' % (depth * 15))
r.append(summary)
rdict['summary'] = str(summary)

# Add other columns as configured.
for column in \
Expand All @@ -246,69 +247,54 @@ def _create_subtickets_table(self, req, children, tbody, depth=0):
href=href))
else:
e = tag.td(ticket[column])
r.append(e)
tbody.append(tag.tr(*r))
rdict[column] = str(e)
tdict[id] = rdict

self._create_subtickets_table(req, children[id], tbody, depth + 1)
self._create_subtickets_table(req, children[id], tdict, depth + 1)

def filter_stream(self, req, method, filename, stream, data):
def _append_subtickets_data(self, req, data):
if not req.path_info.startswith('/ticket/'):
return stream
return

div = None
link = None
button = None
# arguments we need in javascript
script_args = dict()
# common arguments
script_args['localized_separator_label'] = _('Subtickets ')
script_args['add_style'] = self.opt_add_style

if 'ticket' in data:
# get parents data
ticket = data['ticket']
# title
div = tag.div(class_='description')

if 'TICKET_CREATE' in req.perm(ticket.resource) \
and ticket['status'] != 'closed':
opt_inherit = self.env.config.getlist(
'subtickets', 'type.%(type)s.child_inherits' % ticket)
inh = {f: ticket[f] for f in opt_inherit}

if self.opt_add_style == 'link':
inh = {f: ticket[f] for f in opt_inherit}
link = tag.a(_('add'),
href=req.href.newticket(parents=ticket.id,
**inh))
link = tag.span('(', link, ')', class_='addsubticket')
# link-specific arguments
script_args['href_req_newticket_with_parent'] \
= req.href.newticket(parents=ticket.id, **inh)
script_args['localized_link_label'] = _('add')
else:
inh = [tag.input(type='hidden',
name=f,
value=ticket[f]) for f in opt_inherit]

button = tag.form(
tag.div(
tag.input(type="submit",
value=_("Create"),
title=_("Create a child ticket")),
inh,
tag.input(type="hidden",
name="parents",
value=str(ticket.id)),
class_="inlinebuttons"),
method="get", action=req.href.newticket())
div.append(button)
div.append(tag.h3(_('Subtickets '), link))

if 'subtickets' in data:
# button-specific arguments
script_args['localized_button_label'] = _("Create")
script_args['localized_button_title'] = \
_("Create new child ticket")
script_args['href_req_newticket'] = req.href.newticket()
script_args['parent_id'] = str(ticket.id)
script_args['inherited_args'] = json.dumps(inh)

# table
tbody = tag.tbody()
div.append(tag.table(tbody, class_='subtickets'))
# tickets
self._create_subtickets_table(req, data['subtickets'], tbody)
tdict = dict()
if 'subtickets' in data:
# tickets
self._create_subtickets_table(req, data['subtickets'], tdict)

# subtickets table argument: can be empty but must be set!
script_args['subtickets_table']=json.dumps(tdict)

if div:
add_stylesheet(req, 'subtickets/css/subtickets.css')
'''
If rendered in preview mode, DIV we're interested in isn't a child
but the root and transformation won't succeed.
According to HTML specification, id's must be unique within a
document, so it's safe to omit the leading '.' in XPath expression
to select all matching regardless of hierarchy their in.
'''
stream |= Transformer('//div[@id="ticket"]').append(div)

return stream
add_script(req, 'subtickets/js/appendsubticketsdata.js')
add_script_data(req, subtickets_script_args=json.dumps(script_args))