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

Reply via email to