277 lines
9.7 KiB
Python
277 lines
9.7 KiB
Python
from datetime import date, timedelta
|
|
import fedmsg.meta
|
|
import fedmsg
|
|
import stats
|
|
import pygal
|
|
import math
|
|
import json
|
|
import csv
|
|
import os
|
|
|
|
# Default global variables
|
|
subcategory_json = None
|
|
category_json = None
|
|
path = ''
|
|
filename = stats.values['user']
|
|
csv_init = text_init = False
|
|
mode = 'text'
|
|
cat = None
|
|
|
|
|
|
# Gets a drawable object argument and renders an SVG Image of it.
|
|
def draw_svg(graph_obj):
|
|
if cat is None:
|
|
fname = "%s%s/%s_main.svg" % (path, stats.values['user'], filename)
|
|
print("[*] Output saved to ", fname)
|
|
else:
|
|
fname = "%s%s/%s_%smain.svg" % (path, stats.values['user'],
|
|
filename, cat)
|
|
print("[*] Output saved to ", fname)
|
|
graph_obj.render_to_file(fname)
|
|
|
|
|
|
# Gets a drawable object argument and renders a PNG image of it.
|
|
def draw_png(graph_obj):
|
|
if cat is None:
|
|
fname = "%s%s/%s_main.png" % (path, stats.values['user'], filename)
|
|
else:
|
|
fname = "%s%s/%s_%smain.png" % (path, stats.values['user'],
|
|
filename, cat)
|
|
graph_obj.render_to_png(fname)
|
|
|
|
|
|
# Generates a drawable pie chart object from a dictionary passed.
|
|
def draw_pie(output_json, title):
|
|
pie_chart = pygal.Pie(inner_radius=0.4, width=500, height=500)
|
|
pie_chart.title = str(title)
|
|
for key in output_json:
|
|
percent = output_json[key] / float(sum(output_json.values())) * 100
|
|
pie_chart.add(str(key), round(percent, 2))
|
|
return pie_chart
|
|
|
|
|
|
# Generates a drawable pie chart object from a dictionary passed.
|
|
def draw_bar(output_json, title):
|
|
bar_chart = pygal.Bar(width=500, height=500)
|
|
bar_chart.title = str(title)
|
|
for key in output_json:
|
|
bar_chart.add(str(key), output_json[key])
|
|
return bar_chart
|
|
|
|
|
|
# Generates CSV report for the user from the dictionary passed
|
|
def save_csv(output_json):
|
|
global csv_init, cat
|
|
fname = "%s%s/%s_main.csv" % (path, stats.values['user'], filename)
|
|
fout = open(fname, 'a')
|
|
csvw = csv.writer(fout)
|
|
|
|
# Write the dates into CSV
|
|
if not text_init and stats.end and stats.start:
|
|
csvw.writerows(
|
|
[['Start Date : ', stats.start],
|
|
['End Date : ', stats.end],
|
|
['']])
|
|
csv_init = True
|
|
# Initial heading row
|
|
data = [['Username', 'Category', 'Activity Count', 'Percentage'], []]
|
|
for key in output_json:
|
|
percent = round(output_json[key] / float(sum(output_json.values())) *
|
|
100, 2)
|
|
if cat is not None and cat.capitalize() != key.capitalize():
|
|
data.append([stats.values['user'],
|
|
cat.capitalize() + "." + key.capitalize(),
|
|
output_json[key],
|
|
str(percent) + '%'])
|
|
else:
|
|
data.append([stats.values['user'], key.capitalize(),
|
|
output_json[key], str(percent) + '%'])
|
|
# Insert blank lines and total
|
|
data.append([''])
|
|
data.append(['', 'Total : ', sum(output_json.values())])
|
|
data.append([''])
|
|
csvw.writerows(data)
|
|
fout.close()
|
|
|
|
|
|
def show_gource(unicode_json):
|
|
|
|
# Thanks Ralph. Color codes taken from fedmsg2gource
|
|
procs = [proc.__name__.lower() for proc in fedmsg.meta.processors]
|
|
colors = ["FFFFFF", "008F37", "FF680A", "CC4E00",
|
|
"8F0058", "8F7E00", "37008F", "7E008F"]
|
|
n_wraps = int(math.ceil(len(procs) / float(len(colors))))
|
|
colors = colors * n_wraps
|
|
color_lookup = dict(zip(procs, colors))
|
|
|
|
fname = "%s%s/%s_main.gource" % (path, stats.values['user'], filename)
|
|
fout = open(fname, 'w')
|
|
for activity in unicode_json['raw_messages']:
|
|
try:
|
|
user = list(fedmsg.meta.msg2usernames(activity))[0]
|
|
except IndexError:
|
|
user = stats.values['user']
|
|
|
|
fout.write(u"%i|%s|A|%s|%s\n" % (
|
|
activity['timestamp'],
|
|
user,
|
|
activity['topic'].split('.')[4] + " - " + activity['topic'].split('.')[3],
|
|
color_lookup[activity['topic'].split('.')[3]],
|
|
))
|
|
fout.close()
|
|
os.system("cat " + fname + " |gource --log-format custom --highlight-user "
|
|
+ stats.values['user'] + " -c 0.5 -")
|
|
|
|
|
|
# Saves category-wise text report of a user.
|
|
def save_text_log(unicode_json):
|
|
fname = "%s%s/%s_main.txt" % (path, stats.values['user'], filename)
|
|
fout = open(fname, 'w')
|
|
# Category-wise Log
|
|
fout.write("\n\n*** Category-wise activities ***\n\n")
|
|
for category in stats.return_categories():
|
|
flag = True
|
|
actcount = 0
|
|
for activity in unicode_json['raw_messages']:
|
|
if category == activity['topic'].split('.')[3]:
|
|
actcount += 1
|
|
# Print the category once
|
|
if flag is True:
|
|
fout.write(
|
|
"\n\n** Category : " +
|
|
category.capitalize() +
|
|
" **\n")
|
|
flag = False
|
|
try:
|
|
fout.write("* " + fedmsg.meta.msg2subtitle(activity).encode(
|
|
'utf-8') + "\n")
|
|
except AttributeError:
|
|
pass
|
|
fout.write("\nTotal Entries in category : " + str(actcount) + "\n")
|
|
fout.write("\nPercentage participation in category : " +
|
|
str(round(100 * actcount /
|
|
float(unicode_json['total']), 2)) + "\n")
|
|
fout.close()
|
|
|
|
|
|
def save_text_metrics(output_json):
|
|
global text_init
|
|
fname = path + stats.values['user'] + '/' + filename + '_main.txt'
|
|
print(fname)
|
|
fout = open(fname, 'a')
|
|
# Write the dates into CSV
|
|
if not text_init and stats.end and stats.start:
|
|
fout.write( "Start Date : {}\n End Date : {}\n".format(stats.start,stats.end))
|
|
#fout.write(
|
|
# [['Start Date : ', stats.start],
|
|
# ['End Date : ', stats.end],
|
|
# ['']])
|
|
text_init = True
|
|
|
|
# Initial heading row
|
|
data = 'Username\t\tCategory\t\tCount\t\tPercentage\n'
|
|
for key in output_json:
|
|
percent = round(output_json[key] / float(sum(output_json.values())) *
|
|
100, 2)
|
|
if cat is not None and cat.capitalize() != key.capitalize():
|
|
data += '%s\t\t%s\t\t%d\t\t%s\n' % (
|
|
stats.values['user'],
|
|
cat.capitalize() + "." + key.capitalize(),
|
|
output_json[key],
|
|
str(percent) + '%')
|
|
else:
|
|
data += '%s\t\t%s\t\t%d\t\t%s\n' % (
|
|
stats.values['user'], key.capitalize(),
|
|
output_json[key], str(percent) + '%')
|
|
# Insert blank lines and total
|
|
data += '\n\n Total : %d \n' % (sum(output_json.values()))
|
|
fout.write(data)
|
|
fout.close()
|
|
|
|
|
|
# Saves the markdown version of the text log
|
|
def save_markdown(unicode_json):
|
|
fname = path + stats.values['user'] + '/' + filename + '_main.md'
|
|
fout = open(fname, 'w')
|
|
# Category-wise Log, markdown ready
|
|
fout.write("\n\n### Category-wise activities\n\n")
|
|
for category in stats.return_categories():
|
|
flag = True
|
|
actcount = 0
|
|
for activity in unicode_json['raw_messages']:
|
|
if category == activity['topic'].split('.')[3]:
|
|
actcount += 1
|
|
# Print the category once
|
|
if flag is True:
|
|
fout.write(
|
|
"\n\n#### Category : " +
|
|
category.capitalize() +
|
|
"\n")
|
|
flag = False
|
|
try:
|
|
fout.write("* " + fedmsg.meta.msg2subtitle(activity).encode(
|
|
'utf-8', errors='ignore') + "\n")
|
|
except AttributeError:
|
|
pass
|
|
fout.write("\n* **Total Entries in category :** " +
|
|
str(actcount) + "\n")
|
|
fout.write("\n* **Percentage participation in category :** " +
|
|
str(round(100 * actcount /
|
|
float(unicode_json['total']), 2)) + "\n")
|
|
fout.close()
|
|
|
|
|
|
# Saves the JSON as a file.
|
|
def save_json(unicode_json):
|
|
fname = path + stats.values['user'] + '/' + filename + '_main.json'
|
|
try:
|
|
with open(fname, 'w') as outfile:
|
|
json.dump(unicode_json, outfile)
|
|
except IOError:
|
|
print("[!] Could not write into directory. Check Permissions")
|
|
|
|
|
|
# Identifies categories & generates drawable objects for the above functions.
|
|
def generate_graph(output_json, title, category=None, gtype=None):
|
|
global path
|
|
if stats.group:
|
|
path = stats.group + '/'
|
|
if not os.path.exists(stats.group):
|
|
os.makedirs(stats.group)
|
|
if not os.path.exists(path + stats.values['user']):
|
|
os.makedirs(path + stats.values['user'])
|
|
else:
|
|
if not os.path.exists(stats.values['user']):
|
|
os.makedirs(stats.values['user'])
|
|
|
|
global cat
|
|
cat = category
|
|
graph_obj = None
|
|
print('[*] Readying Output..')
|
|
if mode.lower() == 'svg':
|
|
if gtype == 'pie':
|
|
graph_obj = draw_pie(output_json, title)
|
|
elif gtype == 'bar':
|
|
graph_obj = draw_bar(output_json, title)
|
|
draw_svg(graph_obj)
|
|
elif mode.lower() == 'png':
|
|
if gtype == 'pie':
|
|
graph_obj = draw_pie(output_json, title)
|
|
elif gtype == 'bar':
|
|
graph_obj = draw_bar(output_json, title)
|
|
draw_png(graph_obj)
|
|
elif mode.lower() == 'json':
|
|
save_json(output_json)
|
|
elif mode.lower() == 'text':
|
|
if stats.log:
|
|
save_text_log(output_json)
|
|
else:
|
|
save_text_metrics(output_json)
|
|
elif mode.lower() == 'csv':
|
|
save_csv(output_json)
|
|
elif mode.lower() == 'markdown':
|
|
save_markdown(output_json)
|
|
elif mode.lower() == 'gource':
|
|
show_gource(output_json)
|
|
else:
|
|
print("[!] That output mode is not supported! Check README for help.")
|