esc-reporting/esc-analyze.py | 118 ++++++++- esc-reporting/esc-collect.py | 352 +++++++++++++++++++++++++++ esc-reporting/esc-report.py | 557 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 926 insertions(+), 101 deletions(-)
New commits: commit 72959ef97eee9ad305726b422e7a97dd780fc51e Author: jan Iversen <j...@libreoffice.org> Date: Tue Apr 25 11:31:08 2017 +0200 update to esc-report as pr contract. Added flatODF and ESC minutes. Solved problem with report_qa, that caused "done by" not to be correct diff --git a/esc-reporting/esc-analyze.py b/esc-reporting/esc-analyze.py index 7957a9d..23d9d1a 100755 --- a/esc-reporting/esc-analyze.py +++ b/esc-reporting/esc-analyze.py @@ -216,9 +216,11 @@ def util_create_statList(): 'qa': {'unconfirmed': {'count': 0, 'documentation': 0, 'enhancement': 0, 'needsUXEval': 0, 'haveBacktrace': 0, 'needsDevAdvice': 0}}, 'easyhacks' : {'needsDevEval': 0, 'needsUXEval': 0, 'cleanup_comments': 0, - 'total': 0, 'assigned': 0, 'open': 0}}, + 'total': 0, 'assigned': 0, 'open': 0}, + 'esc': {}}, 'stat': {'openhub_last_analyse': "2001-01-01"}, - 'people': {}} + 'people': {}, + 'escList': {}} @@ -462,6 +464,87 @@ def analyze_qa(): if entry['added'] == 'FIXED' and row['resolution'] == 'FIXED': util_build_period_stat(xDate, email, 'qa', 'fixed') + + +def analyze_esc(): + global cfg, statList, bugzillaData, bugzillaESCData, weekList + + print("esc: analyze bugzilla", flush=True) + + statList['data']['esc']['QAstat'] = {'opened': bugzillaESCData['ESC_QA_STATS_UPDATE']['opened'], + 'closed': bugzillaESCData['ESC_QA_STATS_UPDATE']['closed']} + statList['data']['esc']['MAB'] = {} + statList['escList']['QAstat'] = {'top15_squashers' : {}, + 'top15_reporters' : {}, + 'top15_fixers' : []} + for line in bugzillaESCData['ESC_QA_STATS_UPDATE']['top15_closers']: + statList['escList']['QAstat']['top15_squashers'][line['who']] = line['closed'] + for line in bugzillaESCData['ESC_QA_STATS_UPDATE']['top15_reporters']: + statList['escList']['QAstat']['top15_reporters'][line['who']] = line['reported'] + + bug_fixers = {} + for id, bug in bugzillaData['bugs'].items(): + if not bug['status'] == 'RESOLVED': + continue + if 'FIXED' != bug['resolution'] != 'VERIFIED': + continue + if datetime.datetime.strptime(bug['last_change_time'], "%Y-%m-%dT%H:%M:%SZ") < cfg['1weekDate']: + continue + + who = None + for i in range(len(bug['history'])-1,-1,-1): + fixed = False + changes = bug['history'][i]['changes'] + for j in range(0,len(changes)): + if changes[j]['added'] == 'FIXED': + fixed = True + break + if fixed: + who = bug['history'][i]['who'].lower() + break + if not who: + continue + if who == 'libreoffice-comm...@lists.freedesktop.org': + continue + if who in statList['aliases']: + who = statList['aliases'][who] + if who in statList['people']: + who = statList['people'][who]['name'] + if not who in bug_fixers: + bug_fixers[who] = 0 + bug_fixers[who] += 1 + statList['escList']['QAstat']['top15_fixers'] = bug_fixers + + for id, row in bugzillaESCData['ESC_MAB_UPDATE'].items(): + statList['data']['esc']['MAB'][id] = row + statList['data']['esc']['MAB'][id]['%'] = int((row['open'] / row['total'])*100) + + statList['escList']['bisect'] = weekList['escList']['bisect'] + statList['escList']['bisect'].insert(0, [bugzillaESCData['ESC_BISECTED_UPDATE']['open'], + bugzillaESCData['ESC_BISECTED_UPDATE']['total']]) + del statList['escList']['bisect'][-1] + statList['escList']['bibisect'] = weekList['escList']['bibisect'] + statList['escList']['bibisect'].insert(0, [bugzillaESCData['ESC_BIBISECTED_UPDATE']['open'], + bugzillaESCData['ESC_BIBISECTED_UPDATE']['total']]) + del statList['escList']['bibisect'][-1] + + statList['data']['esc']['regression'] = {} + statList['data']['esc']['regression']['high'] = bugzillaESCData['ESC_REGRESSION_UPDATE']['high'] + statList['data']['esc']['regression']['open'] = bugzillaESCData['ESC_REGRESSION_UPDATE']['open'] + statList['data']['esc']['regression']['total'] = bugzillaESCData['ESC_REGRESSION_UPDATE']['total'] + + statList['data']['esc']['component'] = {} + statList['data']['esc']['component']['high'] = {} + for id, row in bugzillaESCData['ESC_COMPONENT_UPDATE']['high'].items(): + statList['data']['esc']['component']['high'][id] = row['count'] + statList['data']['esc']['component']['all'] = {} + for id, row in bugzillaESCData['ESC_COMPONENT_UPDATE']['all'].items(): + statList['data']['esc']['component']['all'][id] = row['count'] + statList['data']['esc']['component']['os'] = {} + for id, row in bugzillaESCData['ESC_COMPONENT_UPDATE']['os'].items(): + statList['data']['esc']['component']['os'][id] = row['count'] + + def analyze_myfunc(): global cfg, statList, openhubData, bugzillaData, gerritData, gitData, licenceCompanyData, licencePersonalData @@ -496,8 +579,8 @@ def analyze_trend(): -def analyze_final(weekList = None): - global cfg, statList, openhubData, bugzillaData, gerritData, gitData +def analyze_final(): + global cfg, statList, openhubData, bugzillaData, gerritData, gitData, weekList print("Analyze final") statList['addDate'] = datetime.date.today().strftime('%Y-%m-%d') @@ -507,22 +590,21 @@ def analyze_final(weekList = None): person['newestCommit'] = person['newestCommit'].strftime("%Y-%m-%d") person['prevCommit'] = person['prevCommit'].strftime("%Y-%m-%d") - analyze_trend() +# analyze_trend() myDay = cfg['nowDate'] - x = (myDay - datetime.timedelta(days=7)).strftime('%Y-%m-%d') - if weekList is None: - weekList = util_load_file(cfg['homedir'] + 'archive/stats_' + x + '.json') - if weekList is None: - weekList = {'data': {}} statList['diff'] = util_build_diff(statList['data'], weekList['data']) sFile = cfg['homedir'] + 'stats.json' util_dump_file(sFile, statList) x = myDay.strftime('%Y-%m-%d') os.system('cp '+ sFile + ' ' + cfg['homedir'] + 'archive/stats_' + x + '.json') if myDay.strftime('%w') == '4': + if 'people' in statList: del statList['people'] + if 'aliases' in statList: del statList['aliases'] - util_dump_file(cfg['homedir'] + 'weeks/week_' + myDay.strftime('%Y_%W') + '.json', statList) + if 'escList' in statList: + del statList['escList'] + util_dump_file(cfg['homedir'] + 'weeks/week_' + myDay.strftime('%Y_%W') + '.json', statList) @@ -565,6 +647,7 @@ def loadCfg(platform): homeDir = os.environ['esc_homedir'] else: homeDir = '/home/esc-mentoring/esc' + cfg = util_load_data_file(homeDir + '/config.json') cfg['homedir'] = homeDir + '/' cfg['platform'] = platform @@ -579,10 +662,14 @@ def loadCfg(platform): def runAnalyze(): - global cfg, statList, openhubData, bugzillaData, gerritData, gitData + global cfg, statList, openhubData, bugzillaData, bugzillaESCData, gerritData, gitData, weekList + + x = (cfg['nowDate'] - datetime.timedelta(days=7)).strftime('%Y-%m-%d') + weekList = util_load_file(cfg['homedir'] + 'archive/stats_' + x + '.json') openhubData = util_load_data_file(cfg['homedir'] + 'dump/openhub_dump.json') bugzillaData = util_load_data_file(cfg['homedir'] + 'dump/bugzilla_dump.json') + bugzillaESCData = util_load_data_file(cfg['homedir'] + 'dump/bugzilla_esc_dump.json') gerritData = util_load_data_file(cfg['homedir'] + 'dump/gerrit_dump.json') gitData = util_load_data_file(cfg['homedir'] + 'dump/git_dump.json') statList = util_create_statList() @@ -591,16 +678,18 @@ def runAnalyze(): analyze_mentoring() analyze_ui() analyze_qa() + analyze_esc() analyze_myfunc() analyze_final() def runUpgrade(args): - global cfg, statList, openhubData, bugzillaData, gerritData, gitData + global cfg, statList, openhubData, bugzillaData, bugzillaESCData, gerritData, gitData, weekList args = args[1:] openhubData = util_load_data_file(cfg['homedir'] + 'dump/openhub_dump.json') bugzillaData = util_load_data_file(cfg['homedir'] + 'dump/bugzilla_dump.json') + bugzillaESCData = util_load_data_file(cfg['homedir'] + 'dump/bugzilla_esc_dump.json') gerritData = util_load_data_file(cfg['homedir'] + 'dump/gerrit_dump.json') gitData = util_load_data_file(cfg['homedir'] + 'dump/git_dump.json') statList = util_create_statList() @@ -625,9 +714,10 @@ def runUpgrade(args): analyze_mentoring() analyze_ui() analyze_qa() + analyze_esc() analyze_myfunc() - analyze_final(weekList=weekList) + analyze_final() weekList = statList diff --git a/esc-reporting/esc-collect.py b/esc-reporting/esc-collect.py index e75201e..347242a 100755 --- a/esc-reporting/esc-collect.py +++ b/esc-reporting/esc-collect.py @@ -171,6 +171,356 @@ def get_bugzilla(cfg): +def do_ESC_QA_STATS_UPDATE(): + tmp= util_load_url('https://bugs.documentfoundation.org/page.cgi?id=weekly-bug-summary.html', useRaw=True) + + rawList = {} + + startIndex = tmp.find('Total Reports: ') + 15 + stopIndex = tmp.find(' ', startIndex) + rawList['total'] = int(tmp[startIndex:stopIndex]) + startIndex = tmp.find('>', stopIndex) +1 + stopIndex = tmp.find('<', startIndex) + rawList['opened'] = int(tmp[startIndex:stopIndex]) + startIndex = tmp.find('>', stopIndex + 5) +1 + stopIndex = tmp.find('<', startIndex) + rawList['closed'] = int(tmp[startIndex:stopIndex]) + + # outer loop, collect 3 Top 15 tables + topNames = ['top15_modules', 'top15_closers', 'top15_reporters'] + curTopIndex = -1 + while True: + startIndex = tmp.find('Top 15', startIndex+1) + if startIndex == -1: + break + startIndex = tmp.find('</tr>', startIndex+1) + 5 + stopIndex = tmp.find('</table', startIndex+1) + curTopIndex += 1 + rawList[topNames[curTopIndex]] = [] + + # second loop, collect all lines <tr>..</tr> + curLineIndex = -1 + while True: + startIndex = tmp.find('<tr', startIndex) + if startIndex == -1 or startIndex >= stopIndex: + startIndex = stopIndex + break + stopLineIndex = tmp.find('</tr>', startIndex) + curLineIndex += 1 + + # third loop, collect single element + curItemIndex = -1 + tmpList = [] + while True: + startIndex = tmp.find('<td', startIndex) + if startIndex == -1 or startIndex >= stopLineIndex: + startIndex = stopLineIndex + break + while tmp[startIndex] == '<': + tmpIndex = tmp.find('>', startIndex) + 1 + if tmp[startIndex+1] == 'a': + i = tmp.find('bug_id=', startIndex) +7 + if -1 < i < tmpIndex: + x = tmp[i:tmpIndex-2] + tmpList.append(x) + startIndex = tmpIndex + stopCellIndex = tmp.find('<', startIndex) + x = tmp[startIndex:stopCellIndex].replace('\n', '') + if '0' <= x[0] <= '9' or x[0] == '+' or x[0] == '-': + x = int(x) + tmpList.append(x) + if len(tmpList): + if curTopIndex == 0: + x = {'product': tmpList[0], + 'open': tmpList[1], + 'opened7DList': tmpList[2].split(','), + 'opened7D': tmpList[3], + 'closed7DList': tmpList[4].split(','), + 'closed7D': tmpList[5], + 'change': tmpList[6]} + elif curTopIndex == 1: + x = {'position': tmpList[0], + 'who': tmpList[1], + 'closedList' : tmpList[2].split(','), + 'closed': tmpList[3]} + else: + x = {'position': tmpList[0], + 'who': tmpList[1], + 'reportedList' : tmpList[2].split(','), + 'reported': tmpList[3]} + rawList[topNames[curTopIndex]].append(x) + return rawList + + + +def do_ESC_MAB_UPDATE(bz): + # load report from Bugzilla + url = bz + '&f1=version&o1=regexp&priority=highest&v1=^' + rawList = {} + + series = {'5.3' : '5.3', + '5.2' : '5.2', + '5.1' : '5.1', + '5.0' : '5.0', + '4.5' : '5.0', # urgh + '4.4' : '4.4', + '4.3' : '4.3', + '4.2' : '4.2', + '4.1' : '4.1', + '4.0' : '4.0', + '3.6' : 'old', + '3.5' : 'old', + '3.4' : 'old', + '3.3' : 'old', + 'Inherited from OOo' : 'old', + 'PreBibisect' : 'old', + 'unspecified' : 'old' + } + + for key, id in series.items(): + if id not in rawList: + rawList[id] = {'open': 0, 'total': 0} + + urlCall = url + key + '.*' + tmpTotal = util_load_url(urlCall, useRaw=True) + rawList[id]['total'] += len(tmpTotal.split('\n')) -1 + tmpOpen = util_load_url(urlCall + "&resolution=---", useRaw=True) + rawList[id]['open'] += len(tmpOpen.split('\n')) - 1 + + return rawList + + + +def do_ESC_counting(bz, urlAdd): + rawList = [] + tmp = util_load_url(bz + urlAdd, useRaw=True).split('\n')[1:] + cnt = len(tmp) + for line in tmp: + rawList.append(line.split(',')[0]) + return cnt, rawList + + + +def get_esc_bugzilla(cfg): + fileName = cfg['homedir'] + 'dump/bugzilla_esc_dump.json' + + print("Updating ESC bugzilla dump") + + rawList = {'ESC_QA_STATS_UPDATE': {}, + 'ESC_MAB_UPDATE': {}, + 'ESC_BISECTED_UPDATE': {}, + 'ESC_BIBISECTED_UPDATE': {}, + 'ESC_COMPONENT_UPDATE': {'all': {}, 'high': {}, 'os': {}}, + 'ESC_REGRESSION_UPDATE': {}} + + bz = 'https://bugs.documentfoundation.org/buglist.cgi?' \ + 'product=LibreOffice' \ + '&keywords_type=allwords' \ + '&query_format=advanced' \ + '&limit=0' \ + '&ctype=csv' \ + '&human=1' + + rawList['ESC_QA_STATS_UPDATE'] = do_ESC_QA_STATS_UPDATE() + rawList['ESC_MAB_UPDATE'] = do_ESC_MAB_UPDATE(bz) + + urlBi = '&keywords=bisected%2C' + url = '&order=tag DESC%2Cchangeddate DESC%2Cversion DESC%2Cpriority%2Cbug_severity' + rawList['ESC_BISECTED_UPDATE']['total'], \ + rawList['ESC_BISECTED_UPDATE']['total_list'] = do_ESC_counting(bz, urlBi+url) + url = '&bug_status=UNCONFIRMED' \ + '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&resolution=---' + rawList['ESC_BISECTED_UPDATE']['open'], \ + rawList['ESC_BISECTED_UPDATE']['open_list'] = do_ESC_counting(bz, urlBi + url) + + url = '&f2=status_whiteboard' \ + '&f3=OP' \ + '&f4=keywords' \ + '&f5=status_whiteboard' \ + '&j3=OR' \ + '&known_name=BibisectedAll' \ + '&n2=1' \ + '&o1=substring' \ + '&o2=substring' \ + '&o4=substring' \ + '&o5=substring' \ + '&order=changeddate DESC%2Cop_sys%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id' \ + '&resolution=---' \ + '&resolution=FIXED' \ + '&resolution=INVALID' \ + '&resolution=WONTFIX' \ + '&resolution=DUPLICATE' \ + '&resolution=WORKSFORME' \ + '&resolution=MOVED' \ + '&resolution=NOTABUG' \ + '&resolution=NOTOURBUG' \ + '&v1=bibisected' \ + '&v2=bibisected35older' \ + '&v4=bibisected' \ + '&v5=bibisected' + rawList['ESC_BIBISECTED_UPDATE']['total'], \ + rawList['ESC_BIBISECTED_UPDATE']['total_list'] = do_ESC_counting(bz, url) + url = '&f2=status_whiteboard' \ + '&f3=OP' \ + '&f4=keywords' \ + '&f5=status_whiteboard' \ + '&j3=OR' \ + '&known_name=Bibisected' \ + '&n2=1' \ + '&o1=substring' \ + '&o2=substring' \ + '&o4=substring' \ + '&o5=substring' \ + '&query_based_on=Bibisected' \ + '&resolution=---' \ + '&v1=bibisected' \ + '&v2=bibisected35older' \ + '&v4=bibisected' \ + '&v5=bibisected' + rawList['ESC_BIBISECTED_UPDATE']['open'], \ + rawList['ESC_BIBISECTED_UPDATE']['open_list'] = do_ESC_counting(bz, url) + + url = 'columnlist=bug_severity%2Cpriority%2Ccomponent%2Cop_sys%2Cassigned_to%2Cbug_status%2Cresolution%2Cshort_desc' \ + '&keywords=regression%2C%20' \ + '&order=bug_id' + rawList['ESC_REGRESSION_UPDATE']['total'], \ + rawList['ESC_REGRESSION_UPDATE']['total_list'] = do_ESC_counting(bz, url) + url = '&keywords=regression%2C%20' \ + '&columnlist=bug_severity%2Cpriority%2Ccomponent%2Cop_sys%2Cassigned_to%2Cbug_status%2Cresolution%2Cshort_desc' \ + '&resolution=---' \ + '&query_based_on=Regressions' \ + '&known_name=Regressions' + rawList['ESC_REGRESSION_UPDATE']['open'], \ + rawList['ESC_REGRESSION_UPDATE']['open_list'] = do_ESC_counting(bz, url) + url = url + '&bug_severity=blocker' \ + '&bug_severity=critical' \ + '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' + rawList['ESC_REGRESSION_UPDATE']['high'], \ + rawList['ESC_REGRESSION_UPDATE']['high_list'] = do_ESC_counting(bz, url) + + rawList['ESC_COMPONENT_UPDATE']['all']['Crashes'] = {} + url = '&keywords=regression' \ + '&short_desc=crash' \ + '&query_based_on=CrashRegressions' \ + '&bug_status=UNCONFIRMED' \ + '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=NEEDINFO' \ + '&short_desc_type=allwordssubstr' \ + '&known_name=CrashRegressions' + rawList['ESC_COMPONENT_UPDATE']['all']['Crashes']['count'], \ + rawList['ESC_COMPONENT_UPDATE']['all']['Crashes']['list'] = do_ESC_counting(bz, url) + rawList['ESC_COMPONENT_UPDATE']['all']['Borders'] = {} + url = '&keywords=regression' \ + '&short_desc=border' \ + '&query_based_on=BorderRegressions' \ + '&bug_status=UNCONFIRMED' \ + '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=NEEDINFO' \ + '&short_desc_type=allwordssubstr' \ + '&known_name=BorderRegressions' + rawList['ESC_COMPONENT_UPDATE']['all']['Borders']['count'], \ + rawList['ESC_COMPONENT_UPDATE']['all']['Borders']['list'] = do_ESC_counting(bz, url) + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: docx filter'] = {} + url = '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=PLEASETEST' \ + '&component=Writer' \ + '&keywords=regression%2C filter%3Adocx%2C ' + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: docx filter']['count'], \ + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: docx filter']['list'] = do_ESC_counting(bz, url) + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: doc filter'] = {} + url = '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=PLEASETEST' \ + '&component=Writer' \ + '&keywords=regression%2C filter%3Adoc%2C ' + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: doc filter']['count'], \ + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: doc filter']['list'] = do_ESC_counting(bz, url) + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: other filter'] = {} + url = '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=PLEASETEST' \ + '&component=Writer' \ + '&f1=keywords' \ + '&f2=keywords' \ + '&keywords=regression%2C' \ + '&o1=nowords' \ + '&o2=substring' \ + '&v1=filter%3Adocx%2C filter%3Adoc' \ + '&v2=filter%3A' + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: other filter']['count'], \ + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: other filter']['list'] = do_ESC_counting(bz, url) + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: perf'] = {} + url = '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=PLEASETEST' \ + '&component=Writer' \ + '&keywords=regression%2C perf%2C ' + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: perf']['count'], \ + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: perf']['list'] = do_ESC_counting(bz, url) + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: other'] = {} + url = '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=PLEASETEST' \ + '&component=Writer' \ + '&f1=keywords' \ + '&keywords=regression%2C' \ + '&o1=nowordssubstr' \ + '&v1=filter%3A%2C perf' + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: other']['count'], \ + rawList['ESC_COMPONENT_UPDATE']['all']['Writer: other']['list'] = do_ESC_counting(bz, url) + + for comp in ['Calc', 'Impress', 'Base', 'Draw', 'LibreOffice', 'Writer', 'BASIC', 'Chart', 'Extensions', + 'Formula Editor', 'Impress Remote', 'Installation', 'Linguistic', 'Printing and PDF export', + 'UI', 'filters and storage', 'framework', 'graphics stack', 'sdk']: + compUrl = comp + url = '&keywords=regression' \ + '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=PLEASETEST' \ + '&component=' + compUrl + rawList['ESC_COMPONENT_UPDATE']['all'][comp] = {} + rawList['ESC_COMPONENT_UPDATE']['all'][comp]['count'], \ + rawList['ESC_COMPONENT_UPDATE']['all'][comp]['list'] = do_ESC_counting(bz, url) + url = url + '&bug_severity=blocker' \ + '&bug_severity=critical' + rawList['ESC_COMPONENT_UPDATE']['high'][comp] = {} + rawList['ESC_COMPONENT_UPDATE']['high'][comp]['count'], \ + rawList['ESC_COMPONENT_UPDATE']['high'][comp]['list'] = do_ESC_counting(bz, url) + + for os in ['Linux (All)', 'Windows (All)', 'Mac OS X (All)', 'All']: + url = '&keywords=regression' \ + '&bug_status=NEW' \ + '&bug_status=ASSIGNED' \ + '&bug_status=REOPENED' \ + '&bug_status=PLEASETEST' \ + '&bug_severity=blocker' \ + '&bug_severity=critical' \ + '&op_sys=' + os + rawList['ESC_COMPONENT_UPDATE']['os'][os] = {} + rawList['ESC_COMPONENT_UPDATE']['os'][os]['count'], \ + rawList['ESC_COMPONENT_UPDATE']['os'][os]['list'] = do_ESC_counting(bz, url) + + util_dump_file(fileName, rawList) + return rawList + + + def get_gerrit(cfg): fileName = cfg['homedir'] + 'dump/gerrit_dump.json' searchDate, rawList = util_load_data_file(cfg, fileName, 'gerrit', {'patch': {}, 'committers' : []}) @@ -284,6 +634,7 @@ def runCfg(platform): homeDir = os.environ['esc_homedir'] else: homeDir = '/home/esc-mentoring/esc' + cfg = util_load_file(homeDir + '/config.json') if cfg == None: exit(-1) @@ -302,6 +653,7 @@ def runCfg(platform): def runBuild(cfg): openhubData = get_openhub(cfg) bugzillaData = get_bugzilla(cfg) + ESCData = get_esc_bugzilla(cfg) gerritData = get_gerrit(cfg) gitData = get_git(cfg) diff --git a/esc-reporting/esc-report.py b/esc-reporting/esc-report.py index 0e3c8d9..c3436b8 100755 --- a/esc-reporting/esc-report.py +++ b/esc-reporting/esc-report.py @@ -128,7 +128,7 @@ def util_build_matrix(title, lineDesc, index): -def report_mentoring(): +def report_day_mentoring(): global statList, openhubData, gerritData, gitData, bugzillaData, cfg myStatList = {'needsDevEval': [], 'needsUXEval': [], @@ -146,8 +146,6 @@ def report_mentoring(): 'missing_license': [], 'to_abandon' : [], 'to_review': [], - 'top10commit': [], - 'top10review': [], 'remove_cc': [] } mailedDate = datetime.datetime.strptime(cfg['git']['last-mail-run'], '%Y-%m-%d') - datetime.timedelta(days=90) @@ -243,32 +241,72 @@ def report_mentoring(): cDate = datetime.datetime.strptime(row['creation_time'], "%Y-%m-%dT%H:%M:%SZ") if cDate >= cfg['1weekDate'] or 'easyhack' in row['history'][-1]['changes'][0]['added']: myStatList['easyhacks_new'].append(key) - tmpClist = sorted(statList['people'], key=lambda k: (statList['people'][k]['commits']['1month']['owner']),reverse=True) - for i in tmpClist: - if not statList['people'][i]['isCommitter']: - x = {'mail': i, 'name': statList['people'][i]['name'], - 'month': statList['people'][i]['commits']['1month']['owner'], - 'year': statList['people'][i]['commits']['1year']['owner']} - myStatList['top10commit'].append(x) - if len(myStatList['top10commit']) >= 10: - break - tmpRlist = sorted(statList['people'], key=lambda k: (statList['people'][k]['gerrit']['1month']['reviewer']),reverse=True) - for i in tmpRlist: - if i != 'c...@libreoffice.org': - x = {'mail': i, 'name': statList['people'][i]['name'], - 'month': statList['people'][i]['gerrit']['1month']['reviewer'], - 'year': statList['people'][i]['gerrit']['1year']['reviewer']} - myStatList['top10review'].append(x) - if len(myStatList['top10review']) >= 10: - break - - fp = open('/tmp/esc_mentoring_report.txt', 'w', encoding='utf-8') - print('ESC mentoring report, generated {} based on stats.json from {}'.format( - datetime.datetime.now().strftime("%Y-%m-%d"), statList['addDate']), file=fp) - - print("copy/paste to esc pad:\n" - "* mentoring/easyhack update (janI)\n" - " + openhub statistics ({}), {} people did {} commits in 12 month in {} lines of code\n" + + fp = open('/tmp/esc_day_mentoring_report.txt', 'w', encoding='utf-8') + print('Day mentoring report, generated {} based on stats.json from {}'.format( + datetime.datetime.now().strftime("%Y-%m-%d"), statList['addDate']), file=fp) + + print(">> mail award pdf, and update award.json", file=fp) + for row in myStatList['award_1st_email'] : + print(' {} {} {}'.format(row['name'],row['email'],row['license']), file=fp) + + util_print_line(fp, myStatList['missing_license'], 'missing license statement' ) + util_print_line(fp, myStatList['to_abandon'], 'gerrit to abandon', doGerrit=True) + util_print_line(fp, myStatList['to_review'], 'gerrit to review', doGerrit=True) + util_print_line(fp, myStatList['to_unassign'], 'easyhacks to unassign', doBugzilla=True) + util_print_line(fp, myStatList['needinfo'], 'easyhacks with NEEDINFO', doBugzilla=True) + util_print_line(fp, myStatList['easyhacks_new'], 'easyhacks new', doBugzilla=True) + util_print_line(fp, myStatList['missing_cc'], 'easyhacks missing cc', doBugzilla=True) + util_print_line(fp, myStatList['remove_cc'], 'easyhacks remove cc', doBugzilla=True) + util_print_line(fp, myStatList['missing_ui_cc'], 'easyhacks missing ui cc', doBugzilla=True) + util_print_line(fp, myStatList['assign_problem'], 'easyhacks assign problem', doBugzilla=True) + util_print_line(fp, myStatList['to_be_closed'], 'easyhacks to be closed', doBugzilla=True) + util_print_line(fp, myStatList['needsDevEval'], 'easyhacks needsDevEval', doBugzilla=True) + util_print_line(fp, myStatList['needsUXEval'], 'easyhacks needsUXEval', doBugzilla=True) + util_print_line(fp, myStatList['we_miss_you_email'], 'we miss you email' ) + util_print_line(fp, myStatList['too_many_comments'], 'easyhacks reduce comments', doBugzilla=True) + util_print_line(fp, myStatList['pending_license'], 'pending license statement' ) + fp.close() + return {'title': 'esc_mentoring, Daily work', 'mail': 'mentor...@documentfoundation.org', 'file': '/tmp/esc_day_mentoring_report.txt'} + + + +def report_mentoring(): + global statList, openhubData, gerritData, gitData, bugzillaData, cfg + myStatList = {'award_1st_email': [], + 'top10commit': [], + 'top10review': [], + } + mailedDate = datetime.datetime.strptime(cfg['git']['last-mail-run'], '%Y-%m-%d') - datetime.timedelta(days=90) + zeroDate = datetime.datetime(year=2001, month=1, day=1) + for id, row in statList['people'].items(): + entry = {'name': row['name'], 'email': id, 'license': row['licenseText']} + newestCommitDate = datetime.datetime.strptime(row['newestCommit'], '%Y-%m-%d') + x = row['commits']['1month']['owner'] + if x != 0 and row['commits']['total'] == x and not id in cfg['award-mailed']: + myStatList['award_1st_email'].append(entry) + + tmpClist = sorted(statList['people'], key=lambda k: (statList['people'][k]['commits']['1month']['owner']),reverse=True) + for i in tmpClist: + if not statList['people'][i]['isCommitter']: + x = {'mail': i, 'name': statList['people'][i]['name'], + 'month': statList['people'][i]['commits']['1month']['owner'], + 'year': statList['people'][i]['commits']['1year']['owner']} + myStatList['top10commit'].append(x) + if len(myStatList['top10commit']) >= 10: + break + tmpRlist = sorted(statList['people'], key=lambda k: (statList['people'][k]['gerrit']['1month']['reviewer']),reverse=True) + for i in tmpRlist: + if i != 'c...@libreoffice.org': + x = {'mail': i, 'name': statList['people'][i]['name'], + 'month': statList['people'][i]['gerrit']['1month']['reviewer'], + 'year': statList['people'][i]['gerrit']['1year']['reviewer']} + myStatList['top10review'].append(x) + if len(myStatList['top10review']) >= 10: + break + + fp = open('/tmp/esc_mentoring_report.txt', 'w', encoding='utf-8') + print(" + openhub statistics ({}), {} people did {} commits in 12 month in {} lines of code\n" " + gerrit/git statistics:".format( statList['stat']['openhub_last_analyse'], util_build_escNumber('openhub', 'year_contributors'), @@ -287,8 +325,7 @@ def report_mentoring(): print(i1 + ' ' + util_build_escNumber('easyhacks', i1) + ' ', end="", file=fp) if i1 == 'cleanup_comments': print('\n ', end='', file=fp) - print("\n + received patches from " + str(len(myStatList['missing_license'])) + " emails the last month without licesense statement", file=fp) - print(" + top 5 contributors:", file=fp) + print("\n + top 5 contributors:", file=fp) for i in range(0, 5): print(' {} made {} patches in 1 month, and {} patches in 1 year'.format( myStatList['top10commit'][i]['name'], @@ -304,29 +341,362 @@ def report_mentoring(): print(" + big CONGRATULATIONS to contributors who have at least 1 merged patch, since last report:", file=fp) for row in myStatList['award_1st_email']: print(' {} {} {}'.format(row['name'],row['email'],row['license']), file=fp) - print("\n\n\n\n\n\n\n\n\n\n", file=fp) - print('Day mentoring report, generated {} based on stats.json from {}'.format( - datetime.datetime.now().strftime("%Y-%m-%d"), statList['addDate']), file=fp) + fp.close() + return - util_print_line(fp, myStatList['missing_license'], 'missing license statement' ) - util_print_line(fp, myStatList['to_abandon'], 'gerrit to abandon', doGerrit=True) - util_print_line(fp, myStatList['to_review'], 'gerrit to review', doGerrit=True) - util_print_line(fp, myStatList['to_unassign'], 'easyhacks to unassign', doBugzilla=True) - util_print_line(fp, myStatList['needinfo'], 'easyhacks with NEEDINFO', doBugzilla=True) - util_print_line(fp, myStatList['easyhacks_new'], 'easyhacks new', doBugzilla=True) - util_print_line(fp, myStatList['missing_cc'], 'easyhacks missing cc', doBugzilla=True) - util_print_line(fp, myStatList['remove_cc'], 'easyhacks remove cc', doBugzilla=True) - util_print_line(fp, myStatList['missing_ui_cc'], 'easyhacks missing ui cc', doBugzilla=True) - util_print_line(fp, myStatList['assign_problem'], 'easyhacks assign problem', doBugzilla=True) - util_print_line(fp, myStatList['to_be_closed'], 'easyhacks to be closed', doBugzilla=True) - util_print_line(fp, myStatList['needsDevEval'], 'easyhacks needsDevEval', doBugzilla=True) - util_print_line(fp, myStatList['needsUXEval'], 'easyhacks needsUXEval', doBugzilla=True) - util_print_line(fp, myStatList['we_miss_you_email'], 'we miss you email' ) - util_print_line(fp, myStatList['too_many_comments'], 'easyhacks reduce comments', doBugzilla=True) - util_print_line(fp, myStatList['pending_license'], 'pending license statement' ) + + +def report_esc_prototype(): + global statList, cfg + global text_bisected, text_bibisected, text_regression + + fp = open(cfg['homedir'] + '/esc-prototype.txt', encoding='utf-8') + escPrototype = fp.read() fp.close() - return {'title': 'esc_mentoring, MENTORING', 'mail': 'mentor...@documentfoundation.org', 'file': '/tmp/esc_mentoring_report.txt'} + fp = open('/tmp/esc_ui_report.txt', encoding='utf-8') + data = fp.read() + fp.close() + escPrototype = escPrototype.replace('$<ESC_UX_UPDATE>', data) + + fp = open('/tmp/esc_mentoring_report.txt', encoding='utf-8') + data = fp.read() + fp.close() + escPrototype = escPrototype.replace('$<ESC_MENTORING_UPDATE>', data) + + fp = open('/tmp/esc_qa_report.txt', encoding='utf-8') + data = fp.read() + fp.close() + escPrototype = escPrototype.replace('$<ESC_QA_UPDATE>', data) + + x1 = statList['data']['esc']['QAstat']['opened'] + x2 = statList['diff']['esc']['QAstat']['opened'] + x3 = statList['data']['esc']['QAstat']['closed'] + x4 = statList['diff']['esc']['QAstat']['closed'] + txt = ' {:+d}({:+d}) {:+d}({:+d}) ({:+d}({:+d}) overall)\n many thanks to the top bug squashers:\n'.format( + x1, -x2, -x3, x4, x1 - x3, x2 - x4) + x = statList['escList']['QAstat']['top15_squashers'] + for name, count in [(k, x[k]) for k in sorted(x, key=x.get, reverse=True)]: + txt += ' {:<23} {}\n'.format(name, count) + txt += '\n + top 10 bugs reporters:\n' + x = statList['escList']['QAstat']['top15_reporters'] + for name, count in [(k, x[k]) for k in sorted(x, key=x.get, reverse=True)]: + txt += ' {:<23} {}\n'.format(name, count) + txt += '\n + top 10 bugs fixers:\n' + x = statList['escList']['QAstat']['top15_reporters'] + for name, count in [(k, x[k]) for k in sorted(x, key=x.get, reverse=True)]: + txt += ' {:<23} {}\n'.format(name, count) + escPrototype = escPrototype.replace('$<ESC_QA_STATS_UPDATE>', txt) + + txt = '' + oldRow = statList['data']['esc']['MAB']['old'] + del statList['data']['esc']['MAB']['old'] + keyList = sorted(statList['data']['esc']['MAB'], reverse=True) + keyList.append('old') + statList['data']['esc']['MAB']['old'] = oldRow + for id in keyList: + row = statList['data']['esc']['MAB'][id] + diff = statList['diff']['esc']['MAB'][id] + txt += ' {} : {}/{} - {} % ({:+d})\n'.format(id, + row['open'], row['total'], row['%'], diff['open']) + escPrototype = escPrototype.replace('$<ESC_MAB_UPDATE>', txt) + + txt = ' +' + for row in statList['escList']['bisect']: + txt += str(row[0]) + '/' + str(row[1]) + ' ' + txt += '\n\n done by:\n' + text_bisected + escPrototype = escPrototype.replace('$<ESC_BISECTED_UPDATE>', txt) + + txt = ' +' + for row in statList['escList']['bibisect']: + txt += str(row[0]) + '/' + str(row[1]) + ' ' + txt += '\n\n done by:\n' + text_bibisected + escPrototype = escPrototype.replace('$<ESC_BIBISECTED_UPDATE>', txt) + + txt = ' + {}({:+d}) bugs open of {}({:+d}) total {}({:+d}) high prio.\n'.format( + statList['data']['esc']['regression']['open'], statList['diff']['esc']['regression']['open'], + statList['data']['esc']['regression']['total'], statList['diff']['esc']['regression']['total'], + statList['data']['esc']['regression']['high'], statList['diff']['esc']['regression']['high']) + txt += '\n done by:\n' + text_regression + escPrototype = escPrototype.replace('$<ESC_REGRESSION_UPDATE>', txt) + + txt = '' + for i in ['LibreOffice', 'Impress', 'Base', 'Calc', 'Extensions', 'Writer']: + txt += ' {:<13} - {}({:+d})\n'.format( + i, + statList['data']['esc']['component']['high'][i], + statList['diff']['esc']['component']['high'][i]) + txt += '\n by OS:\n' + for id,row in statList['data']['esc']['component']['os'].items(): + idx = id.replace(' (All)', '') + txt += ' {:<13} - {}({:+d})\n'.format(idx, row, statList['diff']['esc']['component']['os'][id]) + escPrototype = escPrototype.replace('$<ESC_COMPONENT_REGRESSION_HIGH_UPDATE>', txt) + + txt = '' + x = statList['data']['esc']['component']['all'] + for id, row in [(k, x[k]) for k in sorted(x, key=x.get, reverse=True)]: + xDiff = statList['diff']['esc']['component']['all'][id] + if row != 0 or xDiff != 0: + txt += ' {:<24} - {}({:+d})\n'.format(id, row, xDiff) + escPrototype = escPrototype.replace('$<ESC_COMPONENT_REGRESSION_ALL_UPDATE>', txt) + + fp = open('/tmp/esc_prototype_report.txt', 'w', encoding='utf-8') + print('ESC prototype report, generated {} based on stats.json from {}\n\n\n'.format( + datetime.datetime.now().strftime("%Y-%m-%d"), statList['addDate']), file=fp) + print(escPrototype, file=fp) + fp.close() + + data = 'ESC prototype, based on stats.json from '+statList['addDate'] + return {'title': data, 'mail': 'mentor...@documentfoundation.org', 'file': '/tmp/esc_prototype_report.txt'} + + + +def report_flatODF(): + global statList, cfg + + fp = open('/tmp/esc_flatODF.fods', 'w', encoding='utf-8') + print('<?xml version="1.0" encoding="UTF-8"?>' + + '<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" ' + + 'xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" ' + + 'xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" ' + + 'xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" ' + + 'xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" ' + + 'xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" ' + + 'xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" ' + + 'xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" ' + + 'xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" ' + + 'xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" ' + + 'xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" ' + + 'xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" ' + + 'xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" ' + + 'xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" ' + + 'xmlns:math="http://www.w3.org/1998/Math/MathML" ' + + 'xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" ' + + 'xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" ' + + 'xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" ' + + 'xmlns:ooo="http://openoffice.org/2004/office" ' + + 'xmlns:ooow="http://openoffice.org/2004/writer" ' + + 'xmlns:oooc="http://openoffice.org/2004/calc" ' + + 'xmlns:dom="http://www.w3.org/2001/xml-events" ' + + 'xmlns:xforms="http://www.w3.org/2002/xforms" ' + + 'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' + + 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' + + 'xmlns:rpt="http://openoffice.org/2005/report" ' + + 'xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" ' + + 'xmlns:xhtml="http://www.w3.org/1999/xhtml" ' + + 'xmlns:grddl="http://www.w3.org/2003/g/data-view#" ' + + 'xmlns:tableooo="http://openoffice.org/2009/table" ' + + 'xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" ' + + 'xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" ' + + 'xmlns:css3t="http://www.w3.org/TR/css3-text/" ' + + 'office:version="1.2" ' + + 'grddl:transformation="http://docs.oasis-open.org/office/1.2/xslt/odf2rdf.xsl" ' + + 'office:mimetype="application/vnd.oasis.opendocument.spreadsheet">' + + '\n', file=fp) + + print('<office:styles>' + + '<style:style style:name="boldheader" style:family="table-cell" style:parent-style-name="Default">' + + '<style:text-properties fo:font-style="italic" fo:font-weight="bold"/>' + + '</style:style>' + + '<number:date-style style:name="isodatenum">' + + '<number:year number:style="long"/>' + + '<number:text>-</number:text>' + + '<number:month number:style="long"/>' + + '<number:text>-</number:text>' + + '<number:day number:style="long"/>' + + '</number:date-style>' + + '<style:style style:name="isodate" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="isodatenum">' + + '<style:text-properties style:text-position=""/>' + + '</style:style>' + + '</office:styles>' + + '\n', file=fp) + + print('<office:body>' + + '<office:spreadsheet>' + + '<table:table table:name="Data">' + + '<table:table-row table:style-name="ro2">' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Date</text:p></table:table-cell>' + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open Old</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed Old</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open 4.0</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed 4.0</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open 4.1</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed 4.1</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open 4.2</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed 4.2</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open 4.3</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed 4.3</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open 4.4</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed 4.4</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open 5.0</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed 5.0</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open 5.1</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed 5.1</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Open 5.2</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed 5.2</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total Old</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total 4.0</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total 4.1</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total 4.2</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total 4.3</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total 4.4</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total 5.0</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total 5.1</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total 5.2</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total Open</text:p></table:table-cell>' + + '<table:table-cell office:value-type="string" calcext:value-type="string">' + + '<text:p>Total Closed</text:p></table:table-cell>' + + '<table:table-cell table:number-columns-repeated="11"/></table:table-row>' + + '\n', file=fp) + + print('<table:table-row table:style-name="ro1">' + + '<table:table-cell table:style-name="isodate" office:value-type="date" office:date-value="' + + statList['addDate'] + '" calcext:value-type="date"><text:p>' + + statList['addDate'] + '</text:p></table:table-cell>' + + '\n', file=fp) + + print('<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['old']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.T2]-[.B2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.0']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.U2]-[.D2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.1']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.V2]-[.F2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.2']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.W2]-[.H2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.3']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.X2]-[.J2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.4']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.Y2]-[.L2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['5.0']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.Z2]-[.N2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['5.1']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.AA2]-[.P2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['5.2']['open']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.AB2]-[.R2]" office:value-type="float" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['old']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.0']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.1']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.2']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.3']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['4.4']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['5.0']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['5.1']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['MAB']['5.2']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:style-name="ce3" table:formula="of:=[.B2]+[.D2]+[.F2]+[.H2]+[.J2]+[.L2]+[.N2]+[.P2]+[.R2]" office:value-type="float"/>' + + '<table:table-cell table:style-name="ce3" table:formula="of:=SUM([.T2:.Z2])-[.AC2]" office:value-type="float"/>' + + '</table:table-row>' + + '\n', file=fp) + + print('<table:table-row/>' + + '<table:table-row>' + + '<table:table-cell table:style-name="boldheader" office:value-type="string" calcext:value-type="string">' + + '<text:p>Date</text:p>' + + '</table:table-cell>' + + '<table:table-cell table:style-name="boldheader" office:value-type="string" calcext:value-type="string">' + + '<text:p>Open</text:p>' + + '</table:table-cell>' + + '<table:table-cell table:style-name="boldheader" office:value-type="string" calcext:value-type="string">' + + '<text:p>Closed</text:p>' + + '</table:table-cell>' + + '<table:table-cell table:style-name="boldheader" office:value-type="string" calcext:value-type="string">' + + '<text:p>Total</text:p>' + + '</table:table-cell>' + + '<table:table-cell table:style-name="boldheader" office:value-type="string" calcext:value-type="string">' + + '<text:p>Date</text:p>' + + '</table:table-cell>' + + '\n', file=fp) + + + myOrder = ['Calc', 'Impress', 'Base', 'Draw', 'LibreOffice', 'Borders', 'Crashes', 'BASIC', 'Writer/RTF', 'Writer', + 'Migration', 'Chart', 'Extensions', 'Formula Editor', 'Impress Remote', 'Installation', 'Linguistic', + 'Printing and PDF export', 'UI', 'filters and storage', 'framework', 'graphics stack', 'sdk'] + for i in myOrder: + print('<table:table-cell table:style-name="boldheader" office:value-type="string" calcext:value-type="string"><text:p>' + + i + '</text:p></table:table-cell>' + + '\n', file=fp) + print('</table:table-row>' + + '<table:table-row>' + + '<table:table-cell table:style-name="isodate" office:value-type="date" office:date-value="' + + statList['addDate'] + + '" calcext:value-type="date"><text:p>' + + statList['addDate'] + + '</text:p>' + + '</table:table-cell>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['regression']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:formula="of:=[.D5]-[.B5]" office:value-type="float"/>' + + '<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['regression']['total']) + '" calcext:value-type="float"/>' + + '<table:table-cell table:style-name="isodate" table:formula="of:=[.A5]" office:value-type="date" />' + + '\n', file=fp) + for i in myOrder: + if i in statList['data']['esc']['component']['all']: + print('<table:table-cell office:value-type="float" office:value="' + + str(statList['data']['esc']['component']['all'][i]) + '" calcext:value-type="float"/>' + + '\n', file = fp) + else: + print('<table:table-cell/>', + '\n', file = fp) + print('</table:table-row>' + + '</table:table>' + + '</office:spreadsheet>' + + '</office:body>' + + '</office:document>' + + '\n', file=fp) + fp.close() + fp = open('/tmp/esc_flatODF_body', 'w', encoding='utf-8') + print('File to add to series', file=fp) + fp.close + + data = 'ESC flatODF, based on stats.json from '+statList['addDate'] + return {'title': data, 'mail': 'mentor...@documentfoundation.org', 'attach': '/tmp/esc_flatODF.fods', 'file' : '/tmp/esc_flatODF_body'} def report_ui(): @@ -345,12 +715,7 @@ def report_ui(): break fp = open('/tmp/esc_ui_report.txt', 'w', encoding='utf-8') - print('ESC UI report, generated {} based on stats.json from {}'.format( - datetime.datetime.now().strftime("%Y-%m-%d"), statList['addDate']), file=fp) - - print("copy/paste to esc pad:\n" - "* UX update (heiko)\n" - " + Bugzilla (topicUI) statistics\n" + print(" + Bugzilla (topicUI) statistics\n" " {} (topicUI) bugs open, {} (needsUXEval) needs to be evaluated by the UXteam\n" " + Updates:".format( util_build_escNumber('ui', 'topicUI'), @@ -366,33 +731,33 @@ def report_ui(): print(' {} made {} changes in 1 month, and {} changes in 1 year'.format( top10list[i]['name'], top10list[i]['month'], top10list[i]['year']), file=fp) fp.close() - return {'title': 'esc_mentoring, UI', 'mail': 'mentor...@documentfoundation.org', - 'file': '/tmp/esc_ui_report.txt'} + return {'title': 'ESC UI report', 'mail': 'tietze.he...@gmail.com', 'file': '/tmp/esc_prototype_report.txt'} def report_qa(): global statList, openhubData, gerritData, gitData, bugzillaData, cfg + global text_bisected, text_bibisected, text_regression fp = open('/tmp/esc_qa_report.txt', 'w', encoding='utf-8') - print('ESC QA report, generated {} based on stats.json from {}'.format( - datetime.datetime.now().strftime("%Y-%m-%d"), statList['addDate']), file=fp) - - print("copy/paste to esc pad:\n" - "* qa update (xisco)\n", file=fp) - - print(" + UNCONFIRMED: {} ( )\n" - " + enhancements: {} ( )\n" - " + needsUXEval: {} ( )\n" - " + haveBackTrace: {} ( )\n" - " + needsDevAdvice: {} ( )\n" - " + documentation: {} ( )\n".format( + print(" + UNCONFIRMED: {} ({})\n" + " + enhancements: {} ({})\n" + " + needsUXEval: {} ({})\n" + " + haveBackTrace: {} ({})\n" + " + needsDevAdvice: {} ({})\n" + " + documentation: {} ({})\n".format( statList['data']['qa']['unconfirmed']['count'], + statList['diff']['qa']['unconfirmed']['count'], statList['data']['qa']['unconfirmed']['enhancement'], + statList['diff']['qa']['unconfirmed']['enhancement'], statList['data']['qa']['unconfirmed']['needsUXEval'], + statList['diff']['qa']['unconfirmed']['needsUXEval'], statList['data']['qa']['unconfirmed']['haveBacktrace'], + statList['diff']['qa']['unconfirmed']['haveBacktrace'], statList['data']['qa']['unconfirmed']['needsDevAdvice'], - statList['data']['qa']['unconfirmed']['documentation'],), file=fp) + statList['diff']['qa']['unconfirmed']['needsDevAdvice'], + statList['data']['qa']['unconfirmed']['documentation'], + statList['diff']['qa']['unconfirmed']['documentation'],), file=fp) reporters = sorted(statList['people'], key=lambda k: (statList['people'][k]['qa']['1week']['owner']), reverse=True) @@ -441,58 +806,62 @@ def report_qa(): max_width = 20 for i in top10bisected: if statList['people'][i]['qa']['1week']['bisected'] == 0: - break + continue max_width = max(max_width, len(statList['people'][i]['name'])) + text_bisected = '' for item in top10bisected: if statList['people'][item]['qa']['1week']['bisected'] == 0: - break + continue if not statList['people'][item]['name'] or statList['people'][item]['name'] == '*UNKNOWN*': statList['people'][item]['name'] = statList['people'][item]['email'].split('@')[0] - print(' {0:{2}s} {1:3d}'.format( + text_bisected += ' {0:{2}s} {1:3d}\n'.format( statList['people'][item]['name'], statList['people'][item]['qa']['1week']['bisected'], - max_width), file=fp) - + max_width) + print(text_bisected, file=fp) bibisected = sorted(statList['people'], key=lambda k: (statList['people'][k]['qa']['1week']['bibisected']), reverse=True) print("\nBibisected", file=fp) print("\n + Done by:", file=fp) top10bibisected = bibisected[0:10] + text_bibisected = '' max_width = 20 for i in top10bibisected: if statList['people'][i]['qa']['1week']['bibisected'] == 0: - break + continue max_width = max(max_width, len(statList['people'][i]['name'])) for item in top10bibisected: if statList['people'][item]['qa']['1week']['bibisected'] == 0: - break + continue if not statList['people'][item]['name'] or statList['people'][item]['name'] == '*UNKNOWN*': statList['people'][item]['name'] = statList['people'][item]['email'].split('@')[0] - print(' {0:{2}s} {1:3d}'.format( + text_bibisected = ' {0:{2}s} {1:3d}\n'.format( statList['people'][item]['name'], statList['people'][item]['qa']['1week']['bibisected'], - max_width), file=fp) + max_width) + print(text_bibisected, file=fp) regression = sorted(statList['people'], key=lambda k: (statList['people'][k]['qa']['1week']['regression']), reverse=True) print("\nRegressions", file=fp) print("\n + Done by:", file=fp) + text_regression = '' top10regression = regression[0:10] max_width = 20 for i in top10regression: if statList['people'][i]['qa']['1week']['regression'] == 0: - break + continue max_width = max(max_width, len(statList['people'][i]['name'])) for item in top10regression: if statList['people'][item]['qa']['1week']['regression'] == 0: - break + continue if not statList['people'][item]['name'] or statList['people'][item]['name'] == '*UNKNOWN*': statList['people'][item]['name'] = statList['people'][item]['email'].split('@')[0] - print(' {0:{2}s} {1:3d}'.format( + text_regression = ' {0:{2}s} {1:3d}\n'.format( statList['people'][item]['name'], statList['people'][item]['qa']['1week']['regression'], - max_width), file=fp) - + max_width) + print(text_regression, file=fp) backtrace = sorted(statList['people'], key=lambda k: (statList['people'][k]['qa']['1week']['backtrace']), reverse=True) @@ -567,6 +936,7 @@ def runCfg(platform): homeDir = os.environ['esc_homedir'] else: homeDir = '/home/esc-mentoring/esc' + cfg = util_load_data_file(homeDir + '/config.json') cfg['homedir'] = homeDir + '/' cfg['platform'] = platform @@ -593,6 +963,9 @@ def runReport(): gitData = util_load_data_file(cfg['homedir'] + 'dump/git_dump.json') xMail = [] + x = report_day_mentoring() + if not x is None: + xMail.append(x) x = report_mentoring() if not x is None: xMail.append(x) @@ -605,12 +978,22 @@ def runReport(): x = report_myfunc() if not x is None: xMail.append(x) + x = report_esc_prototype() + if not x is None: + xMail.append(x) + x = report_flatODF() + if not x is None: + xMail.append(x) fp = open('/tmp/runMail', 'w', encoding='utf-8') print("#!/bin/bash", file=fp) print("") for i in xMail: - print("mail -s '" + i['title'] + "' " + i['mail'] + " < " + i['file'], file=fp) + if 'attach' in i: + attach = '-a ' + i['attach'] + ' ' + else: + attach = '' + print("mail -s '" + i['title'] + "' " + attach + i['mail'] + " < " + i['file'], file=fp) fp.close() _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits