-
Notifications
You must be signed in to change notification settings - Fork 1
/
chitra.py
executable file
·226 lines (164 loc) · 7.28 KB
/
chitra.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#!/usr/bin/python2.7
from __future__ import division
from datetime import datetime, date , timedelta
import logging
import pprint
import psycopg2
import sys
import time;
import datetime
from redmine_stats import buildTopParentMap, groupByTopParentChitra;
import os
import time
#from subprocess import call
import subprocess
from config import username, password, chatroom, adminuser, ignoreUsers, xmppHandles, userConfig, conn_string, firstNames, docURL
from configChitra import settings, adminEmail
def debug(message):
print message
def first_day_of_month(d):
return date(d.year, d.month, 1)
def divide_safe(a, b):
if b == 0:
return a
else:
return a / b
# Send an email to $address with $content as attachment
# dateUntil is for inclusion in subject line and body message
def send_email(redmineLogin, content, dateUntil):
msg="Banque pour les makers " + dateUntil.strftime('%Y-%m-%d')
emailAddress = None
attachmentPathPart = None
if redmineLogin == ':admin':
emailAddress = adminEmail
attachmentPathPart = 'admin'
msg='Sommaire: ' + msg
else:
sql = "select address from users inner join email_addresses e on e.user_id = users.id where login = '%s'" % (redmineLogin)
sys.stderr.write(sql)
conn = psycopg2.connect(conn_string)
cursor = conn.cursor()
cursor.execute(sql)
emailAddress = cursor.fetchone()
emailAddress = emailAddress[0]
attachmentPathPart = emailAddress
#For using subprocess.calls, see
#https://stackoverflow.com/questions/89228/calling-an-external-command-in-python
#https://docs.python.org/3/library/subprocess.html#module-subprocess
#https://www.pythonforbeginners.com/os/subprocess-for-system-administrators
#echo $msg | mutt -a $output -s "$msg" -- "$address"
dataAttachmentContent = content
dataAttachmentPath = os.path.expanduser('~/banque-' + emailAddress + '.csv')
dataAttachmentFile = open(dataAttachmentPath, 'w+')
dataAttachmentFile.write(dataAttachmentContent)
dataAttachmentFile.close()
msg = "'" + msg + "'"
command = 'echo ' + msg + '| mutt -a ' + dataAttachmentPath + ' -s ' + msg + ' -- ' + emailAddress
#call([command])
print command
m1 = subprocess.Popen(command, shell=True)
m1.communicate()
def main():
email=True
if (sys.argv[2] != 'noemail'):
print "Will email\n"
else:
print "No email\n"
email=False
time.sleep(3)
# print the connection string we will use to connect
#debug("Connecting to database...")
# get a connection, if a connect cannot be made an exception will be raised here
conn = psycopg2.connect(conn_string)
# conn.cursor will return a cursor object, you can use this cursor to perform queries
cursor = conn.cursor()
#debug("Connected!\n")
dateUntil = first_day_of_month(datetime.datetime.now())
if sys.argv[1]:
dateUntil = datetime.datetime.strptime(sys.argv[1], '%Y-%m-%d')
dateUntil = dateUntil.date()
legend = ("Positive bank means maker ahead. Negative means maker owes hours.\n"
"All units in hours\n"
"The bank is calculated as bank = hoursSince - (hoursShouldHaveSince - bankAtStart)\n"
"Hours counted are until %s exclusively\n" % dateUntil.strftime('%Y-%m-%d')
)
bankTableForAdmin = ''
noticeTableForAdmin = ''
bankTableHeader = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % ("Client", "Maker", "Bank", "Since", "Work done since", "Work should have done since", "Bank at start", "Hours worked/week")
noticeTableHeader = 'Notice for projects ignored or not set'+"\n"
for user in settings:
bankTableForUser = ''
noticeTableForUser = ''
allClients = set()
checkedClients = set()
for client, config in settings[user].items():
dateSince = settings[user][client]["since"].strftime('%Y-%m-%d')
### We gather this inside the loop because dateSince varies on a per client basis
sql = """
select p.identifier, p.id, sum(te.hours) as s, min(spent_on)
from time_entries te, projects p, users u
where u.id = te.user_id
and te.project_id = p.id
and u.login = '%s'
and p.status != 5
and te.spent_on between '%s' and '%s'
group by u.login, p.identifier, p.id; """ % (user, dateSince, dateUntil.strftime('%Y-%m-%d'))
sys.stderr.write(sql)
cursor.execute(sql)
allTime = cursor.fetchall()
#### Group time stats by top parent project
allTime = groupByTopParentChitra(allTime, settings[user][client].get('ignore', ()))
bank = config["bank"]
since = config['since']
### This should represent the number of days since start, excluding today
daysSince = (dateUntil - since).days
weeksSince = daysSince / 7
hoursPerWeek = config['hoursPerWeek']
hoursShouldHaveSince = hoursPerWeek * weeksSince
hoursSince = 0
if client in allTime:
hoursSince = allTime[client]['hours']
checkedClients.add(client)
for key, row in allTime.items():
allClients.add(key)
# Generate string containing table data
print '-'
print hoursShouldHaveSince
print '-'
print bank
print '-'
bankTableRow = "%s\t%s\t% .2f\t%s\t%.2f\t%.2f\t%.2f\t%.1f\n" % (client, user, hoursSince - (hoursShouldHaveSince - bank), since, hoursSince, hoursShouldHaveSince, bank, divide_safe(hoursSince, weeksSince))
bankTableForUser = bankTableForUser + bankTableRow
bankTableForAdmin = bankTableForAdmin + bankTableRow
if settings[user][client].get('ignore'):
noticeTableRow = "%s\t%s\t%s\n" % (user, "Ignored", "\t".join(settings[user][client]['ignore']))
noticeTableForUser += noticeTableRow
noticeTableForAdmin += noticeTableRow
nonCheckedClients = list(allClients - checkedClients)
if nonCheckedClients:
noticeTableRow = "%s\t%s\t%s\n" % (user, "Not set", "\t".join(nonCheckedClients))
noticeTableForUser += noticeTableRow
noticeTableForAdmin += noticeTableRow
# Prepare email to user
emailContent = bankTableHeader
emailContent += "\n".join(sorted(bankTableForUser.split("\n"))) + "\n\n"
emailContent += noticeTableForUser
emailContent += ("\n" + legend)
print '=== Doing user ' + user + ' ' + ('=' * 72)
print emailContent
# At this point you should email someone
if email:
send_email(user, emailContent, dateUntil)
# At this point you should email admin
# Prepare email to user
emailContent = bankTableHeader
emailContent += "\n".join(sorted(bankTableForAdmin.split("\n"))) + "\n\n"
emailContent += noticeTableForAdmin
emailContent += ("\n" + legend)
print emailContent
# At this point you should email someone
if email:
send_email(':admin', emailContent, dateUntil)
return
if __name__ == "__main__":
main()