Author: dammina
Date: Thu Jun 19 06:05:23 2014
New Revision: 1603720

URL: http://svn.apache.org/r1603720
Log:
removed the changes in the existing templates. Implement the 
ITemplateStreamFilter methods instead.

Removed:
    
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_empty_table.html
Modified:
    
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/theme.js
    
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_query.html
    
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_wiki_view.html
    
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py
    bloodhound/branches/bep_0011_batch_create_tickets/trac/trac/ticket/model.py

Modified: 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/theme.js
URL: 
http://svn.apache.org/viewvc/bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/theme.js?rev=1603720&r1=1603719&r2=1603720&view=diff
==============================================================================
--- 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/theme.js
 (original)
+++ 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/theme.js
 Thu Jun 19 06:05:23 2014
@@ -126,8 +126,27 @@ $(function() {
     }
   }
 
+  // Update QCT select fields on product change.
   $('#field-product').change(function(e) {
     set_qct_more_enabled($(this).val());
+    $qct_form = $('#qct-form');
+    var product = $qct_form.find('#field-product').val()
+    if(product) {
+      var form_token = $qct_form.find('input[name="__FORM_TOKEN"]').val();
+      var fields_to_update = ['version', 'type'];
+      $.post('update-menus', { product: product, __FORM_TOKEN: form_token,
+          fields_to_update: fields_to_update }).done(function(data) {
+        $.each(data, function(i, v) {
+          $field = $('#field-' + i);
+          $field.empty();
+          $field.append('<option value="">Choose...</option>');
+          $.each(v, function(i, v) {
+            $field.append('<option value="' + v + '">' + v + '</option>');
+          });
+
+        });
+      });
+    }
   });
 
   set_qct_more_enabled($('#field-product').val());

Modified: 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_query.html
URL: 
http://svn.apache.org/viewvc/bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_query.html?rev=1603720&r1=1603719&r2=1603720&view=diff
==============================================================================
--- 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_query.html
 (original)
+++ 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_query.html
 Thu Jun 19 06:05:23 2014
@@ -256,7 +256,7 @@
         <hr />
       </form>
 
-         <div class="span12">
+      <div class="span12">
         <xi:include href="widget_query_results.html" />
       </div>
       <div py:if="tickets and batch_modify" class="span12">
@@ -264,9 +264,6 @@
           <xi:include href="bh_batch_modify.html" />
         </div>
       </div>
-         <div class="span12">
-        <xi:include href="bh_empty_table.html" />
-      </div>
 
       <div class="buttons span12"
            py:with="edit = report_resource and 'REPORT_MODIFY' in 
perm(report_resource);

Modified: 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_wiki_view.html
URL: 
http://svn.apache.org/viewvc/bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_wiki_view.html?rev=1603720&r1=1603719&r2=1603720&view=diff
==============================================================================
--- 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_wiki_view.html
 (original)
+++ 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/templates/bh_wiki_view.html
 Thu Jun 19 06:05:23 2014
@@ -143,12 +143,6 @@
                 <button class="btn" type="submit" 
name="rename_page_button">${_('Rename page')}</button>
               </div>
             </form>
-                       <form method="get" style="display:inline" 
action="${href.query()}" id="batchcreate">
-              <input type="hidden" name="actionticketbatchcreate" 
value="rename" />
-              <div class="btn-group">
-                <button class="btn" type="submit" 
name="batchcreate">${_('Batch Create')}</button>
-              </div>
-            </form>
             <form method="get" style="display:inline" 
action="${href.wiki(page.name)}" py:if="page.exists and delete_perm">
               <input type="hidden" name="action" value="delete" />
               <input type="hidden" name="version" value="$page.version" />

Modified: 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py
URL: 
http://svn.apache.org/viewvc/bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py?rev=1603720&r1=1603719&r2=1603720&view=diff
==============================================================================
--- 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py
 (original)
+++ 
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py
 Thu Jun 19 06:05:23 2014
@@ -25,6 +25,8 @@ from genshi.builder import tag
 from genshi.core import TEXT
 from genshi.filters.transform import Transformer
 from genshi.output import DocType
+from genshi.core import Markup
+from genshi import HTML
 
 from trac.config import ListOption, Option
 from trac.core import Component, TracError, implements
@@ -619,19 +621,11 @@ class QuickCreateTicketDialog(Component)
         try:
             tm = self._get_ticket_module()
             req.perm.require('TICKET_CREATE')
-            if 'field_summary' in req.args:
-                summary = req.args.pop('field_summary', '')
-                desc = ""
-                attrs = dict([k[6:], v] for k, v in req.args.iteritems()
+            summary = req.args.pop('field_summary', '')
+            desc = ""
+            attrs = dict([k[6:], v] for k, v in req.args.iteritems()
                          if k.startswith('field_'))
-
-                product, tid = self.create(req, summary, desc, attrs, True)
-            elif 'field_summary' not in req.args:
-                attrs = dict([k[6:], v] for k, v in req.args.iteritems()
-                         if k.startswith('field_'))
-                #new_tkts variable will contain the tickets that have been 
created as a batch
-                #that information will be used to load the resultant query 
table
-                product, tid, new_tkts = self.batch_create(req, attrs, True)
+            product, tid = self.create(req, summary, desc, attrs, True)
         except Exception, exc:
             self.log.exception("BH: Quick create ticket failed %s" % (exc,))
             req.send(str(exc), 'plain/text', 500)
@@ -684,10 +678,282 @@ class QuickCreateTicketDialog(Component)
                 self.log.exception("Failure sending notification on creation "
                                    "of ticket #%s: %s" % (t.id, e))
         return t['product'], t.id
+
+from pkg_resources import get_distribution
+application_version = get_distribution('BloodhoundTheme').version
+
+################################################################################################################
+
+class BatchCreateTicketDialog(Component):
+    implements(IRequestFilter, IRequestHandler, ITemplateStreamFilter)
+    bct_fields = ListOption('ticket', 'batch_create_fields',
+                            'product, version, type',
+        doc="""Multiple selection fields displayed in create ticket menu""",
+                            doc_domain='bhtheme')
+
+    def __init__(self, *args, **kwargs):
+        import pkg_resources
+        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
+        add_domain(self.env.path, locale_dir)
+        super(BatchCreateTicketDialog, self).__init__(*args, **kwargs)
+
+    # IRequestFilter(Interface):
+
+    def pre_process_request(self, req, handler):
+        """Nothing to do.
+        """
+        return handler
+
+    def post_process_request(self, req, template, data, content_type):
+        """Append necessary ticket data
+        """
+        try:
+            tm = self._get_ticket_module()
+        except TracError:
+            # no ticket module so no create ticket button
+            return template, data, content_type
+
+        if (template, data, content_type) != (None,) * 3:  # TODO: Check !
+            if data is None:
+                data = {}
+            dum_req = dummy_request(self.env)
+            dum_req.perm = req.perm
+            ticket = Ticket(self.env)
+            tm._populate(dum_req, ticket, False)
+            all_fields = dict([f['name'], f]
+                              for f in tm._prepare_fields(dum_req, ticket)
+                              if f['type'] == 'select')
+
+            product_field = all_fields.get('product')
+            if product_field:
+                # When at product scope, set the default selection to the
+                # product at current scope. When at global scope the default
+                # selection is determined by [ticket] default_product
+                if self.env.product and \
+                        self.env.product.prefix in product_field['options']:
+                    product_field['value'] = self.env.product.prefix
+                # Transform the options field to dictionary of product
+                # attributes and filter out products for which user doesn't
+                #  have TICKET_CREATE permission
+                product_field['options'] = [
+                    dict(value=p,
+                         new_ticket_url=dum_req.href.products(p, 'newticket'),
+                         description=ProductEnvironment.lookup_env(self.env, p)
+                                                       .product.name
+                    )
+                for p in product_field['options']
+                    if req.perm.has_permission('TICKET_CREATE',
+                                               Neighborhood('product', p)
+                                               .child(None, None))]
+            else:
+                msg = _("Missing ticket field '%(field)s'.", field='product')
+                if ProductTicketModule is not None and \
+                        self.env[ProductTicketModule] is not None:
+                    # Display warning alert to users
+                    add_warning(req, msg)
+                else:
+                    # Include message in logs since this might be a failure
+                    self.log.warning(msg)
+            data['bct'] = {
+                'fields': [all_fields[k] for k in self.bct_fields
+                           if k in all_fields],
+                'hidden_fields': [all_fields[k] for k in all_fields.keys()
+                                  if k not in self.bct_fields] }
+        return template, data, content_type
+
+    # IRequestHandler methods
+
+    def match_request(self, req):
+        """Handle requests sent to /bct
+        """
+        m = PRODUCT_RE.match(req.path_info)
+        return req.path_info == '/bct' or \
+            (m and m.group('pathinfo').strip('/') == 'bct')
+
+    def process_request(self, req):
+
+        self.log.debug("BatchCreateTicketsModule: process_request entered")
+        """Forward new ticket request to `trac.ticket.web_ui.TicketModule`
+        but return plain text suitable for AJAX requests.
+        """
+        try:
+            tm = self._get_ticket_module()
+            req.perm.require('TICKET_CREATE')
+
+            attrs = dict([k[6:], v] for k, v in req.args.iteritems()
+                         if k.startswith('field_'))
+            #new_tkts variable will contain the tickets that have been created 
as a batch
+            #that information will be used to load the resultant query table
+            product, tid, new_tkts = self.batch_create(req, attrs, True)
+        except Exception, exc:
+            self.log.exception("BH: Batch create tickets failed %s" % (exc,))
+            req.send(str(exc), 'plain/text', 500)
+        else:
+            tres = Neighborhood('product', product)('ticket', tid)
+            href = req.href
+            req.send(to_json({'product': product, 'id': tid,
+                              'url': get_resource_url(self.env, tres, href)}),
+                     'application/json')
+
+    def _get_ticket_module(self):
+        ptm = None
+        if ProductTicketModule is not None:
+            ptm = self.env[ProductTicketModule]
+        tm = self.env[TicketModule]
+        if not (tm is None) ^ (ptm is None):
+            raise TracError('Unable to load TicketModule (disabled)?')
+        if tm is None:
+            tm = ptm
+        return tm
+
+    #Template Stream Filter methods
+    def filter_stream(self, req, method, filename, stream, data):
+        #headers = 
{'summary':'Summary','description':'Description','product':'Product','status':'Status','priority':'Priority','type':'Type','owner':'Owner','cc':'Cc','keywords':'Keywords','milestone':'Milestone'}
+        headers = 
{'summary':'Summary','description':'Description','product':'Product','status':'Status'}
+        xpath = '//div[@id="content"]'
+        div = tag.div(class_="span12", id="batch_create_empty_table")
+        text = tag.text("Batch Create Tickets")
+        h1 = tag.h1(text)
+        div.append(h1)
+        form = tag.form(id="qct-form", name="bct", method="post", 
action=req.href()+"/bct")
+        table = tag.table(class_="listing tickets table table-bordered 
table-condensed query", style="border-radius: 0px 0px 4px 4px")
+        tr = tag.tr(class_="trac-columns")
+        for header in sorted(headers):
+            font = tag.font(color="#1975D1")
+            text = tag.text(headers[header])
+            font.append(text)
+            th = tag.th(font)
+            tr.append(th)
+        table.append(tr)
+        tbody = tag.tbody()
+        for num in range(0,5):
+            tr_rows = tag.tr()
+            for header in sorted(headers):
+                if header == "summary":
+                    td_row = tag.td()
+                    input_summary = tag.input(type="text", id = 
"field-summary"+str(num), class_="input-block-level", 
name="field_summary"+str(num))
+                    td_row.append(input_summary)
+                    tr_rows.append(td_row)
+                elif header == "description":
+                    td_row = tag.td()
+                    input_description = tag.textarea(id = 
"field-description"+str(num), name="field_description"+str(num), 
class_="input-block-level", rows="1", cols="28")
+                    td_row.append(input_description)
+                    tr_rows.append(td_row)
+                elif header == "status":
+                    td_row = tag.td()
+                    input_status = tag.select(id = "field-status"+str(num), 
name="field_status"+str(num))
+                    option = tag.option(value="accepted")
+                    text = tag.text("accepted")
+                    option.append(text)
+                    input_status.append(option)
+                    option = tag.option(value="assigned")
+                    text = tag.text("assigned")
+                    option.append(text)
+                    input_status.append(option)
+                    option = tag.option(value="closed")
+                    text = tag.text("closed")
+                    option.append(text)
+                    input_status.append(option)
+                    option = tag.option(value="new", selected="selected")
+                    text = tag.text("new")
+                    option.append(text)
+                    input_status.append(option)
+                    option = tag.option(value="reopened")
+                    text = tag.text("reopened")
+                    option.append(text)
+                    input_status.append(option)
+                    td_row.append(input_status)
+                    tr_rows.append(td_row)
+                elif header == "priority":
+                    td_row = tag.td()
+                    input_priority = tag.select(id = 
"field-priority"+str(num), name="field_priority"+str(num))
+                    option = tag.option(value="blocker")
+                    text = tag.text("blocker")
+                    option.append(text)
+                    input_priority.append(option)
+                    option = tag.option(value="critical")
+                    text = tag.text("critical")
+                    option.append(text)
+                    input_priority.append(option)
+                    option = tag.option(value="major")
+                    text = tag.text("major")
+                    option.append(text)
+                    input_priority.append(option)
+                    option = tag.option(value="minor", selected="selected")
+                    text = tag.text("minor")
+                    option.append(text)
+                    input_priority.append(option)
+                    option = tag.option(value="trivial")
+                    text = tag.text("trivial")
+                    option.append(text)
+                    input_priority.append(option)
+                    td_row.append(input_priority)
+                    tr_rows.append(td_row)
+                elif header=="type":
+                    td_row = tag.td()
+                    input_type = tag.select(id = "field-type"+str(num), 
name="field_type"+str(num))
+                    option = tag.option(value="defect")
+                    text = tag.text("defect")
+                    option.append(text)
+                    input_type.append(option)
+                    option = tag.option(value="enhancement")
+                    text = tag.text("enhancement")
+                    option.append(text)
+                    input_type.append(option)
+                    option = tag.option(value="task", selected="selected")
+                    text = tag.text("task")
+                    option.append(text)
+                    input_type.append(option)
+                    td_row.append(input_type)
+                    tr_rows.append(td_row)
+                elif header == "product":
+                    td_row = tag.td()
+                    input_product = tag.select(id = "field-product"+str(num), 
name="field_product"+str(num))
+                    option = tag.option(value="")
+                    text = tag.text("Choose...")
+                    option.append(text)
+                    input_product.append(option)
+                    option = tag.option(value="@")
+                    text = tag.text("Default")
+                    option.append(text)
+                    input_product.append(option)
+                    td_row.append(input_product)
+                    tr_rows.append(td_row)
+                elif header == "owner":
+                    td_row = tag.td()
+                    input_owner = tag.input(type="text", id = 
"field-owner"+str(num), class_="input-block-level", name="field_owner"+str(num))
+                    td_row.append(input_owner)
+                    tr_rows.append(td_row)
+                elif header == "cc":
+                    td_row = tag.td()
+                    input_cc = tag.input(type="text", id = 
"field-cc"+str(num), class_="input-block-level", name="field_cc"+str(num))
+                    td_row.append(input_cc)
+                    tr_rows.append(td_row)
+                elif header == "milestone":
+                    td_row = tag.td()
+                    input_cc = tag.input(type="text", id = 
"field-milestone"+str(num), class_="input-block-level", 
name="field_milestone"+str(num))
+                    td_row.append(input_cc)
+                    tr_rows.append(td_row)
+                elif header == "keywords":
+                    td_row = tag.td()
+                    input_cc = tag.input(type="text", id = 
"field-keywords"+str(num), class_="input-block-level", 
name="field_keywords"+str(num))
+                    td_row.append(input_cc)
+                    tr_rows.append(td_row)
+            tbody.append(tr_rows)
+        table.append(tbody)
+        form.append(table)
+        div_button = tag.div(class_="btn-group pull-right")
+        input_button = tag.input(type="submit", class_="btn pull-right", 
name="save", value="save")
+        div_button.append(input_button)
+        form.append(div_button)
+        div.append(form)
+        div.append("\n")
+        stream |= Transformer(xpath).append(div)
+        return stream
+
     # Public API
     def batch_create(self, req, attributes={}, notify=False):
         """ Create batch of tickets, returning created tickets.
-
         """
         num_of_tkts = attributes.__len__()/4
         for i in range(0,num_of_tkts):
@@ -722,6 +988,3 @@ class QuickCreateTicketDialog(Component)
         created_tickets = t._get_tickets_by_id(prev_max+1)
         return t['product'], t.id, created_tickets
 
-
-from pkg_resources import get_distribution
-application_version = get_distribution('BloodhoundTheme').version

Modified: 
bloodhound/branches/bep_0011_batch_create_tickets/trac/trac/ticket/model.py
URL: 
http://svn.apache.org/viewvc/bloodhound/branches/bep_0011_batch_create_tickets/trac/trac/ticket/model.py?rev=1603720&r1=1603719&r2=1603720&view=diff
==============================================================================
--- bloodhound/branches/bep_0011_batch_create_tickets/trac/trac/ticket/model.py 
(original)
+++ bloodhound/branches/bep_0011_batch_create_tickets/trac/trac/ticket/model.py 
Thu Jun 19 06:05:23 2014
@@ -109,6 +109,20 @@ class Ticket(object):
             if default:
                 self.values.setdefault(field['name'], default)
 
+    def _get_max_ticket_id(self):
+        return self.env.db_query("SELECT MAX(id) FROM ticket")
+
+    def _get_tickets_by_id(self, tkt_id):
+        #this method returns standard ticket fields of all the tickets which 
have a ticket id over the parameter id value
+        row = None
+        if self.id>=tkt_id:
+            # Fetch the standard ticket fields
+            return self.env.db_query("SELECT %s FROM ticket WHERE id>=%%s" %
+                                        ','.join(self.std_fields), (tkt_id,))
+        else:
+            raise ResourceNotFound(_("Ticket %(id)s does not exist.",
+                                    id=self.id), _("Invalid ticket number"))
+
     def _fetch_ticket(self, tkt_id):
         row = None
         if self.id_is_valid(tkt_id):


Reply via email to