Выкладываю свой Macros для трака. Это переписанный макрос, который отображал тикеты по выбранному проекту в виде календаря.

На данный момент этот макрос выводит в список все активные тикеты по всем проектам, зашедшего в систему человека, и сортирует их по важности. В этом макросе есть возможность отследить время закрытия/создание/изменение тикетов по дате и по определенному человеку.

Код макроса:

  1. # Author: Vladimir Boichentsov
  2.  
  3. import time
  4. import calendar
  5. import sys
  6. import string
  7. import Cookie
  8. import os
  9. import fileinput
  10. import sqlite3 as sqlite
  11. import operator
  12. from StringIO import StringIO
  13. from trac.wiki.api import WikiSystem
  14. from trac.util import *
  15.  
  16.  
  17.  
  18. def execute(hdf, txt, env):
  19.     # building the output
  20.     buff = StringIO()
  21.    
  22.    
  23.     # you type ticket
  24.     if(hdf.getValue('args.close', 'no') == "yes"):
  25.     plist = ['none']
  26.     else:
  27.     plist = ['blocker','critical','high','major','medium','minor','trivial','low']
  28.    
  29.    
  30.     tickets = []
  31.     # directory by trac projects
  32.     DIR = '/home/pub/trac'
  33.     o = j = c = 0
  34.    
  35.     users = ''
  36.     #passwords for users trac projects
  37.     for line in fileinput.input('/home/pub/svn/.htpasswd'):
  38.     temp = line.split(':')
  39.     if(temp[0] != 'admin'):
  40.         users += '<a href="?user=' + temp[0] + '">' + temp[0] + '</a> &nbsp;'
  41.         
  42.     user = hdf.getValue('args.user', '')
  43.  
  44.     if(len(user) < 1):
  45.         owner = hdf.getValue("trac.authname", "anonymous")
  46.     else:
  47.         owner = user
  48.  
  49.     buff.write('<a href="?user=' + owner + '&close=yes&time=yes">close(create time)</a> <a href="?user=' + owner + '&close=yes">close(time close)</a> | ' + users + "\n" )
  50.    
  51.     buff.write('<table class="listing tickets"><tbody>\n')
  52.     buff.write('<thead><tr> <td class="ticket"> Ticket </a></td><td class="summary">Summary</td> <td> Project</td>  <td class="owner">Owner</td> <td>Priority</td> <td>Type</td> <td class="date"> Create </td> <td class="date"> Changetime </td> </tr> </thead>\n')
  53.     for p in plist:
  54.     for project in os.listdir(DIR):
  55.             con = sqlite.connect(DIR + '/' + project +'/db/trac.db')
  56.             cur = con.cursor()
  57.        
  58.         if(p != 'none'):
  59.             t = "and t.priority='" + p + "'"
  60.         else:
  61.             t = ''
  62.        
  63.        
  64.        
  65.         cur.execute("SELECT t.changetime,t.id,t.summary,t.owner,t.status,t.description,t.time,t.priority,t.type FROM ticket t, ticket_custom tc where tc.ticket=t.id and t.owner='" + owner +"' " + t)
  66.        
  67.        
  68.         if(hdf.getValue('args.close', 'no') != "yes"):
  69.             while (1):
  70.                 row = cur.fetchone()
  71.                
  72.                 if row == None:
  73.                 break
  74.             else:
  75.             j = j + 1
  76.                 
  77.             if(row[4] != 'closed'):
  78.                 o = o + 1
  79.             else:
  80.                 c = c + 1
  81.                     
  82.             if(row[4] != 'closed'):
  83.                 buff.write(show_ticket(row,project,env))
  84.         else:
  85.             while(1):
  86.             row = cur.fetchone()
  87.             ticket = []
  88.            
  89.                 if row == None:
  90.                         break   
  91.                        
  92.             for t in row:
  93.                 ticket.append(t)
  94.            
  95.             ticket.append(project)
  96.             tickets.append(ticket)
  97.            
  98.     if(hdf.getValue('args.close', 'no') == "yes"):
  99.     if(hdf.getValue('args.time', 'no') == "yes"):
  100.         tickets.sort(reverse=True,key=operator.itemgetter(6))
  101.     else:
  102.         tickets.sort(reverse=True)
  103.  
  104.     for row in tickets:
  105.     buff.write(show_ticket(row,row[9],env))
  106.    
  107.     j = j + 1
  108.    
  109.     if(row[4] != 'closed'):
  110.         o = o + 1
  111.     else:
  112.         c = c + 1
  113.    
  114.            
  115.     buff.write('</tbody></table>\n')
  116.     buff.write('<br>Ticket all: %(j)i Ticket open: %(o)i  Closed ticket: %(c)i \n' % { 'j':j,
  117.         'o':o,
  118.         'c':c, })
  119.     table = buff.getvalue()
  120.     buff.close()
  121.     return table
  122.  
  123.  
  124. def ticket_priority(row):
  125.     priority = ''
  126.     if (row[7] == 'minor'):
  127.     priority = "background: #e7ffff; border-color: #cee; color: #099;"
  128.     if (row[7] == 'major' or row[7] == 'medium'):
  129.         priority = "background: #fbfbfb; border-color: #ddd; color: #444;"
  130.     if (row[7] == 'trivial' or row[7] == 'low'):
  131.         priority = "background: #e7eeff; border-color: #cde; color: #469;"
  132.     if (row[7] == 'critical' or row[7] == 'high'):
  133.         priority = "background: #ffb; border-color: #eea; color: #880;"
  134.     if (row[7] == 'blocker'):
  135.         priority = "background: #fdc; border-color: #e88; color: #a22;"
  136.        
  137.     if(row[4] == 'closed'):
  138.         priority = "color: #777; background: #ddd; border-color: #ccc;"
  139.    
  140.     return priority
  141.  
  142.    
  143. def show_ticket(row,project,env):
  144.     ticket = row[2]
  145.     line = '<tr style="%(priority)s"> <td class="ticket"> <a href="/trac/%(project)s/ticket/%(id)i"> #%(id)i </a></td><td class="summary"><a href="/trac/%(project)s/ticket/%(id)i" title="%(description)s"> %(ticket)s </a></td><td>%(project)s</td>  <td class="owner">%(owner)s</td> <td>%(prio)s</td> <td>%(type)s</td> <td class="date"> %(time)s </td> <td class="date"> %(changetime)s </td> </tr>\n' % {
  146.                    'id' : row[1],
  147.                         'url': env.href.ticket(row[1]),
  148.                         'project' : project,
  149.                         'priority' : ticket_priority(row),
  150.                         'prio' : row[7],
  151.                         'type' : row[8],
  152.                         'ticket': ticket[0:100],
  153.                         'owner': row[3],
  154.                         'time' : time.strftime('%d/%m/%y',time.localtime(row[6])),
  155.                         'changetime' :  time.strftime('%d/%m/%y',time.localtime(row[0])),
  156.                         'style': row[4] == 'closed' and 'font-size: 9px; color: #777777; text-decoration: line-through;' or 'font-size: 9px; color: #000000',
  157.                             'description': " ", #replace(description, "\'", "&#39;") == None and " " or replace(description, "\'", "&#39;"),
  158.                         }
  159.     return line