# Copyright (C) 2022 The Qt Company Ltd. # Contact: https://www.qt.io/licensing/ # # You may use this file under the terms of the CC0 license. # See the file LICENSE.CC0 from this package for details. import io import os import zipfile import requests def partially_hide(x): words = [] x_split = x.split() len_split = len(x_split) for i, name in enumerate(x_split): # Replace with dots # filled = '.' * (len(name) - 1) # words.append(f'{name[0]}{filled}') # Use first letter # words.append(name[0]) # User F. Lastime if i != len_split - 1: words.append(f"{name[0]}.") else: words.append(name) return " ".join(words) def get_domain_chart_data(df): d = df.groupby("domain")["domain"].count() d = d.to_frame() d.rename(columns={"domain": "domain_count"}, inplace=True) d = d.sort_values(by="domain_count", ascending=False) TOP = 5 d3 = d[:TOP].copy() d3.loc["Other"] = d[TOP:]["domain_count"].sum() d3 = d3.iloc[::-1] total = d3["domain_count"].sum() p = (d3["domain_count"] / total) * 100 return { "data": [ { "x": d3["domain_count"], "y": [f"{i} " for i in d3.index], "text": p, "type": "bar", "orientation": "h", # "marker": {"color": "#f9e56d"}, "marker": {"color": "#41CD52"}, "texttemplate": "%{value} (%{text:.2f} %)", "textposition": "auto", }, ], "layout": { "title": "Commits per email domain", "height": "400", "padding": { "r": "150", }, }, } def get_ranking_chart_data(df, top=10, column="commit_count"): d4 = ( df.groupby("name") .agg({"name": "count", "files_changed": "sum", "insertions": "sum", "deletions": "sum"}) .rename(columns={"name": "commit_count"}) ) d4 = d4.sort_values(by=column, ascending=False)[:top] d4 = d4.reset_index() d4["name"] = d4["name"].apply(partially_hide) d4 = d4.iloc[::-1] titles = { "files_changed": "Files changed", "commit_count": "Commits", "insertions": "Insertions", "deletions": "Deletions", } colors = { "files_changed": "#53586b", "commit_count": "#222840", "insertions": "#41CD52", "deletions": "#fb6761", } return { "data": [ { "y": d4["name"], "x": d4[column], "type": "bar", "name": "Commits", "orientation": "h", "marker": {"color": colors[column]}, }, ], "layout": { "title": f"Contributors ({titles[column]})", "yaxis": {"dtick": "1"}, "bargap": "2", "margin": { "l": "100", }, }, } def get_commit_chart_data(df): d = df.groupby("date_week")["date_week"].count() d = d.to_frame() d.rename(columns={"date_week": "date_count"}, inplace=True) d = d.reset_index() # d["week"] = d["date_week"].copy().apply(lambda x : int(x.split("W")[-1])) # d["year"] = d["date_week"].copy().apply(lambda x : int(x.split("W")[0])) return { "data": [ { "x": d["date_week"], "y": d["date_count"], "line": {"color": "#222840"}, "type": "lines", "xaxis": "x1", }, ], "layout": { "title": "Number of commits", "height": "400", "xaxis": {"tickangle": "45"}, }, } def get_collab_chart_data(df): d = df.groupby("date_week")["email"].nunique() d = d.to_frame() d.rename(columns={"email": "collaborators_count"}, inplace=True) return { "data": [ { "x": d.index, "y": d["collaborators_count"], "line": {"color": "#41CD52"}, "type": "lines", }, ], "layout": { "title": "Number of contributors", "height": "400", "xaxis": {"tickangle": "45"}, }, } # Download the data from an external source which runs a cronjob # to keep an updated ZIP file with the processed data. # Heroku will restart every day, so the data will be updated on # a daily basis. def download_data(): print("Downloading data") r = requests.get("https://qtstats.info/data_csv.zip") if r.status_code == 404: print("Error: Problem downloading the Data") return False with zipfile.ZipFile(io.BytesIO(r.content)) as z: z.extractall(".") print("Downloading data: DONE") return True