root/timingandestimationplugin/branches/trac0.11/scripts/trac_billing.py

Revision 1283, 5.4 kB (checked in by bobbysmith007, 2 years ago)

TimingAndEstimationPlugin:

Moved everything into the trunk folder

Line 
1 from datetime import datetime as dt
2 import time
3 from utils import mail
4 import adw_tracdb as db
5
6 #defaultUrl= "https://sekhemt.acceleration.net/ADW/"
7 _defaultUrl= "https://10.10.10.219/projects"
8 _htmlLocation = '/var/BigVisibleCharts/Billing'
9
10 def cond ( boolExpr, trueResult, falseResult ):
11     """ This is the classic ?: operator from languages like C expressed in python (from dive into python)
12     """
13     return (boolExpr and [trueResult] or [falseResult])[0]
14
15
16
17 def accumulator():
18     var = [0]
19     def fn(*params):
20         for param in params:
21             var[0] = var[0] + param
22         return var[0]
23     return fn
24
25 def progn(*params):
26     return params[-1]
27
28 def prinTrue(s):
29     print s
30     return True
31
32
33 def wn (name, attribs, *children):
34     return "<%s %s>\n%s\n</%s>\n" % \
35            (name, \
36             ' '.join(['%s="%s"' % (key, val) for (key, val) in attribs.items()]), \
37             '\n'.join([str(c) for c in children]), \
38             name)
39
40 def ticket_link (number, projUrl):
41     return wn('a' , {'href':'/'.join([projUrl,'ticket' ,str(number)])}, "#"+str(number))
42
43 def milestone_link (name, projUrl):
44     name = str(name)
45     return wn('a' , {'href':'/'.join([projUrl,'milestone' ,name])}, name)
46
47 def make_project_output(project, rs, totalAcc):
48     projAcc = accumulator()
49     projLink = '/'.join([_defaultUrl, project ])
50    
51     def make_cell(idx, val):
52         if(idx == rs.columnMap['ticket']):
53             val = ticket_link(val, projLink)
54         elif idx == rs.columnMap['milestone'] and val != '&nbsp;':
55             val = milestone_link(val, projLink)
56         elif idx == rs.columnMap['hours']:
57             projAcc(float(val))
58             totalAcc(float(val))
59         return wn('td', {}, val)
60    
61     return progn(wn('div', {},
62                     wn('h2', {},
63                        wn('a',{'href':projLink},project)),
64                     wn('table', {"cellspacing":"0", "border":"1", "cellpadding":"3"},
65                        wn('tr', {},
66                           *[wn('th',{}, name) for name in rs.columnNames]),
67                        *[wn('tr', {},
68                             *[make_cell(idx, val)
69                               for idx in range(0, len(row))
70                               for val in [row[idx]]])
71                          for row in rs.rows]),
72                     wn('span',{}, "Total: "+str(projAcc()))))
73
74 def make_all_projects_output():
75     totalAcc = accumulator()
76     sql = """
77 SELECT
78  CASE WHEN t.milestone IS NOT NULL and t.milestone <> '' THEN t.milestone
79  ELSE '&nbsp;'
80  END as milestone,
81  t.id as ticket,
82  SUM(newvalue) as hours,
83  t.summary as summary,
84  strftime('%m/%d/%Y %H:%M:%S', MAX(ticket_change.time), 'unixepoch', 'localtime') as [most-recent-update] ,
85  (SELECT CASE WHEN MAX(time) IS NOT NULL THEN strftime('%m/%d/%Y %H:%M:%S', MAX(time), 'unixepoch', 'localtime')
86        ELSE 'No previous bill date'
87        END as time FROM bill_date ) as [previous-bill-date]
88 FROM ticket as t
89 LEFT JOIN ticket_custom as billable on billable.ticket = t.id
90   AND billable.name = 'billable'
91 JOIN ticket_change on t.id = ticket_change.ticket
92   AND (
93      ticket_change.time >
94      (SELECT CASE WHEN MAX(time) IS NOT NULL THEN MAX(time)
95        ELSE 0
96        END as time FROM bill_date )
97 )
98 WHERE ticket_change.field = 'hours'
99     AND billable.value=1
100 GROUP BY t.milestone, t.id
101 """
102
103     billingInfo = db.collectResultsFromAllTracs(sql);
104     projects_output = '\n'.join([make_project_output(project, rs, totalAcc)
105                                  for (project, rs) in billingInfo
106                                  if rs.rows ])
107     return wn('html', {},
108               wn('head', {}),
109               wn('body', {},
110                  projects_output,
111                  wn('span',{},"Total hours billed: "+str(totalAcc()))))
112
113
114 def save_output_to_file(output, when=0):
115     if not when:
116         when = dt.now()
117     fname = '_'.join(["billing", str(when.year),
118                       str(when.month), str(when.day),
119                       str(when.hour), str(when.minute), ".html"])
120     p = "/".join([_htmlLocation, fname])
121     print "----"
122     print "Writing out billing information to '%s'" % p
123     print "----"
124     f = open(p, "w")
125     f.write(output)
126     f.close();
127
128
129
130 def run_billing(emails="ryan@acceleration.net", when=0):   
131     if not when:
132         when = dt.now()
133     date = '/'.join([str(when.month), str(when.day), str(when.year)])
134    
135     print "Collecting output..."
136     output = make_all_projects_output()
137     save_output_to_file(output, when)
138     print "Emailing results to %s" % emails
139     if emails:
140         mail.mail(emails, 'Trac Billing - %s ' % date, output, html=True, fromEmail='trac-tickets@acceleration.net')
141     return output
142    
143    
144
145 def add_bill_date(project, username="Timing and Estimation Plugin",  when=0):
146     now = time.time()
147     if not when:
148         when = now
149     when = int(when)
150     now = int(now)
151     sql = """
152     INSERT INTO bill_date (time, set_when, str_value)
153     VALUES (?, ?, strftime('%m/%d/%Y %H:%M:%S',?, 'unixepoch', 'localtime'))
154     """
155     db.executeNonQuery(project, sql, when, now, when)
156
157 def mark_billing_date_in_all_projects(when=0 ):
158     print "Marking the bill date on all projects."
159     if not when:
160         when = time.time()
161     for project in db.projects:
162         try:
163             add_bill_date(project,  "Timing and Estimation Plugin",  when);
164             print "%s Succeeded." % project
165         except Exception, e:
166             print "* %s failed: %s" % (project , e.args)
167     print "Done marking bill dates"
168    
169
170
171              
172              
173        
Note: See TracBrowser for help on using the browser.