You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@community.apache.org by se...@apache.org on 2015/07/07 00:11:26 UTC

svn commit: r1689512 [4/9] - in /comdev/reporter.apache.org/tags/test/site: ./ css/ img/ js/ js/foundation/ js/vendor/

Added: comdev/reporter.apache.org/tags/test/site/deathnote.py
URL: http://svn.apache.org/viewvc/comdev/reporter.apache.org/tags/test/site/deathnote.py?rev=1689512&view=auto
==============================================================================
--- comdev/reporter.apache.org/tags/test/site/deathnote.py (added)
+++ comdev/reporter.apache.org/tags/test/site/deathnote.py Mon Jul  6 22:11:25 2015
@@ -0,0 +1,239 @@
+#!/usr/bin/env python
+import os, sys, re, json, subprocess, urllib, time
+import base64, urllib2, cgi
+
+form = cgi.FieldStorage();
+oproject = form['only'].value if ('only' in form and len(form['only'].value) > 0) else None
+
+
+jmap = {
+    'trafficserver': ['TS'],
+    'cordova': ['CB'],
+    'corinthia': ['COR']
+}
+
+pmap = {
+    'community': 'comdev',
+    'ws': 'webservices'
+}
+
+ldapmap = {
+    'webservices': 'ws'
+}
+
+jirapass = ""
+with open("/var/www/reporter.apache.org/data/jirapass.txt", "r") as f:
+    jirapass = f.read().strip()
+    f.close()
+
+def isMember(uid):
+    members = []
+    ldapdata = subprocess.check_output(['ldapsearch', '-x', '-LLL', '-b', 'cn=member,ou=groups,dc=apache,dc=org'])
+    for match in re.finditer(r"memberUid: ([-a-z0-9_.]+)", ldapdata):
+        group = match.group(1)
+        members.append(group)
+    if uid in members:
+        return True
+    return False
+
+
+def getProjectData(project):
+    try:
+        y = []
+        with open("/var/www/projects.apache.org/site/json/projects/%s.json" % project, "r") as f:
+            x = json.loads(f.read())
+            f.close()
+            with open("/var/www/projects.apache.org/site/json/foundation/pmcs.json", "r") as f:
+                p = json.loads(f.read())
+                f.close()
+                for xproject in p:
+                    y.append(xproject)
+                    if xproject == project:
+                        x['name'] = p[project]['name']
+            with open("/var/www/projects.apache.org/site/json/foundation/chairs.json", "r") as f:
+                c = json.loads(f.read())
+                f.close()
+                for xproject in c:
+                    if xproject.lower() == x['name'].lower():
+                        x['chair'] = c[xproject]
+
+        return x, y;
+    except:
+        x = {}
+        y = []
+        with open("/var/www/projects.apache.org/site/json/foundation/pmcs.json", "r") as f:
+            p = json.loads(f.read())
+            f.close()
+            for xproject in p:
+                y.append(xproject)
+                if xproject == project:
+                    x['name'] = p[project]['name']
+
+        with open("/var/www/projects.apache.org/site/json/foundation/chairs.json", "r") as f:
+            c = json.loads(f.read())
+            f.close()
+            for xproject in c:
+                if 'name' in x and xproject == x['name']:
+                    x['chair'] = c[xproject]
+        return x,y
+
+def getReleaseData(project):
+    try:
+        with open("/var/www/reporter.apache.org/data/releases/%s.json" % project, "r") as f:
+            x = json.loads(f.read())
+            f.close()
+        return x;
+    except:
+        return {}
+
+
+
+pchanges = {}
+cchanges = {}
+
+with open("/var/www/reporter.apache.org/data/pmcs.json", "r") as f:
+    pchanges = json.loads(f.read())
+    f.close()
+
+with open("/var/www/reporter.apache.org/data/projects.json", "r") as f:
+    cchanges = json.loads(f.read())
+    f.close()
+
+
+user = os.environ['HTTP_X_AUTHENTICATED_USER'] if 'HTTP_X_AUTHENTICATED_USER' in os.environ else ""
+m = re.match(r"^([-a-zA-Z0-9_.]+)$", user)
+groups = []
+
+afterHalf = time.time() - (6*31*86400)
+afterFull = time.time() - (12*31*86400)
+cdata = {}
+if m:
+    uid = m.group(1)
+    if isMember(uid):
+        mlstats = {}
+        with open("/var/www/reporter.apache.org/data/mailinglists.json", "r") as f:
+            ml = json.loads(f.read())
+            f.close()
+            for entry in ml:
+                tlp = entry.split(".")[0]
+                if tlp in pmap:
+                    tlp = pmap[tlp]
+                if True:
+                    mlstats[tlp] = mlstats[tlp] if tlp in mlstats else {}
+                    mlstats[tlp][entry] = ml[entry]
+        emails = {}
+        with open("/var/www/reporter.apache.org/data/maildata_extended.json", "r") as f:
+            mld = json.loads(f.read())
+            f.close()
+            for entry in mld:
+                tlp = entry.split("-")[0]
+                if tlp in pmap:
+                    tlp = pmap[tlp]
+                if True:
+                    emails[tlp] = emails[tlp] if tlp in emails else {}
+                    emails[tlp][entry] = mld[entry]
+        jdata = {}
+        ddata = {}
+        rdata = {}
+        allpmcs = []
+        keys = {}
+        count = {}
+        foo, allpmcs = getProjectData('httpd')
+        npmcs = {}
+        ncoms = {}
+        for group in allpmcs:
+            jiras = []
+            count[group] = [0,0]
+            xgroup = group
+            if group in ldapmap:
+                xgroup = ldapmap[group]
+            if xgroup in pchanges:
+                count[group][0] = len(pchanges[xgroup])
+            if xgroup in cchanges:
+                count[group][1] = len(cchanges[xgroup])
+            ddata[group], bleh = getProjectData(group)
+            rdata[group] = getReleaseData(group)
+            cdata[group] = cdata[xgroup] if xgroup in cdata else {'pmc': {}, 'committer': {}}
+            
+            for pmc in pchanges:
+                if pmc == xgroup:
+                    for member in pchanges[pmc]:
+                        if pchanges[pmc][member][1] > 0:
+                            cdata[group]['pmc'][member] = pchanges[pmc][member]
+                            npmcs[group] = npmcs[group] if (group in npmcs and npmcs[group] > pchanges[pmc][member][1]) else pchanges[pmc][member][1]
+            for pmc in cchanges:
+                if pmc == xgroup:
+                    for member in cchanges[pmc]:
+                        if cchanges[pmc][member][1] > 0:
+                            cdata[group]['committer'][member] = cchanges[pmc][member]
+                            ncoms[group] = ncoms[group] if (group in ncoms and ncoms[group] > cchanges[pmc][member][1]) else cchanges[pmc][member][1]
+        
+        notes = []
+        for group in allpmcs:
+            x = 0
+            y = 0
+            score = 0
+            note = []
+            if group in emails:
+                for entry in emails[group]:
+                    x += emails[group][entry]['quarterly'][0]
+                    y += emails[group][entry]['quarterly'][1]
+            if x < 90:
+                score += 1
+                note.append("Less than one email per day to all MLs in the past quarter")
+            if y < 90 and x < 90:
+                score += 1
+                note.append("Less than one email per day to all MLs in the past six months")
+            if group in rdata:
+                tooold = True if len(rdata[group]) > 0 else False
+                for version in rdata[group]:
+                    if rdata[group][version] > afterFull:
+                        tooold = False
+                if tooold:
+                    score += 1
+                    note.append("No releases in the last year")
+                if len(rdata[group]) == 0:
+                    score += 0.5
+                    note.append("No release data available!")
+            if group in npmcs:
+                if npmcs[group] < afterFull:
+                    score += 1
+                    note.append("No new PMC members invited for more than a year")
+            elif group != "bookkeeper":
+                score += 2
+                note.append("No new PMC members invited for more than 2 years")
+                
+            if group in ncoms:
+                if ncoms[group] < afterFull:
+                    score += 1
+                    note.append("No new committers invited for more than a year")
+            elif group != "bookkeeper":
+                score += 2
+                note.append("No new committers invited for more than 2 years")
+                
+            notes.append ({
+                'pmc': group,
+                'score': score,
+                'notes': note
+            })
+        
+        print ("Content-Type: text/html\r\n\r\n<h2>Community health issues</h2>")
+        values = ["Healthy", "Mostly Okay", "Unhealthy", "Action required!"]
+        colors = ["#070", "#470", "#770", "#700"]
+        for entry in sorted(notes, key=lambda x: x['score'], reverse=True):
+            s = int(entry['score']/2)
+            if s > 3:
+                s = 3
+            print("<font color='%s'>" % colors[s])
+            print "<b>%s: %s</b><br/>\n" % (entry['pmc'], values[s] )
+            print "<blockquote><b>Health score:</b> %u<br>" % (-1 * entry['score'])
+            for l in entry['notes']:
+                print("<b>Problem: </b>%s<br/>" % l)
+            print("</blockquote></font><hr/>\n")
+            
+    else:
+        print ("Content-Type: text/html\r\n\r\n")
+        print("Unknown or invalid member id presented")
+else:
+    print ("Content-Type: text/html\r\n\r\n")
+    print("Unknown or invalid user id presented")

Propchange: comdev/reporter.apache.org/tags/test/site/deathnote.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: comdev/reporter.apache.org/tags/test/site/deathnote.py
------------------------------------------------------------------------------
    svn:executable = *

Added: comdev/reporter.apache.org/tags/test/site/getjson.py
URL: http://svn.apache.org/viewvc/comdev/reporter.apache.org/tags/test/site/getjson.py?rev=1689512&view=auto
==============================================================================
--- comdev/reporter.apache.org/tags/test/site/getjson.py (added)
+++ comdev/reporter.apache.org/tags/test/site/getjson.py Mon Jul  6 22:11:25 2015
@@ -0,0 +1,311 @@
+#!/usr/bin/env python
+import os, sys, re, json, subprocess, urllib, time
+import base64, urllib2, cgi
+
+form = cgi.FieldStorage();
+oproject = form['only'].value if ('only' in form and len(form['only'].value) > 0) else None
+
+
+jmap = {
+    'trafficserver': ['TS'],
+    'cordova': ['CB'],
+    'corinthia': ['COR']
+}
+
+pmap = {
+    'community': 'comdev',
+    'ws': 'webservices'
+}
+
+ldapmap = {
+    'webservices': 'ws'
+}
+
+jirapass = ""
+with open("/var/www/reporter.apache.org/data/jirapass.txt", "r") as f:
+    jirapass = f.read().strip()
+    f.close()
+
+def getPMCs(uid):
+    groups = []
+    ldapdata = subprocess.check_output(['ldapsearch', '-x', '-LLL', '(|(memberUid=%s)(member=uid=%s,ou=people,dc=apache,dc=org))' % (uid, uid), 'cn'])
+    picked = {}
+    for match in re.finditer(r"dn: cn=([a-zA-Z0-9]+),ou=pmc,ou=committees,ou=groups,dc=apache,dc=org", ldapdata):
+        group = match.group(1)
+        if group != "incubator":
+
+            groups.append(group)
+    return groups
+
+
+def isMember(uid):
+    members = []
+    ldapdata = subprocess.check_output(['ldapsearch', '-x', '-LLL', '-b', 'cn=member,ou=groups,dc=apache,dc=org'])
+    for match in re.finditer(r"memberUid: ([-a-z0-9_.]+)", ldapdata):
+        group = match.group(1)
+        members.append(group)
+    if uid in members:
+        return True
+    return False
+
+def getJIRAProjects(project):
+    project = project.replace("Apache ", "").strip().lower()
+    refresh = True
+    x = {}
+    jiras = []
+    try:
+        mtime = 0
+        try:
+            st=os.stat("/var/www/reporter.apache.org/data/JIRA/projects.json")
+            mtime=st.st_mtime
+        except:
+            pass
+        if mtime >= (time.time() - 86400):
+            refresh = False
+            with open("/var/www/reporter.apache.org/data/JIRA/projects.json", "r") as f:
+                x = json.loads(f.read())
+                f.close()
+        else:
+            base64string = base64.encodestring('%s:%s' % ('githubbot', jirapass))[:-1]
+    
+            try:
+                req = req = urllib2.Request("https://issues.apache.org/jira/rest/api/2/project.json")
+                req.add_header("Authorization", "Basic %s" % base64string)
+                x = json.loads(urllib2.urlopen(req).read())
+                with open("/var/www/reporter.apache.org/data/JIRA/projects.json", "w") as f:
+                    f.write(json.dumps(x))
+                    f.close()
+            except:
+                pass
+    except:
+        pass
+    
+    for entry in x:
+        if entry['name'].replace("Apache ", "").strip().lower() == project:
+            jiras.append(entry['key'])
+        elif 'projectCategory' in entry and entry['projectCategory']['name'].replace("Apache ", "").strip().lower() == project:
+            jiras.append(entry['key'])
+    return jiras
+
+def getJIRAS(project):
+    refresh = True
+    try:
+        st=os.stat("/var/www/reporter.apache.org/data/JIRA/%s.json" % project)
+        mtime=st.st_mtime
+        if mtime >= (time.time() - (2*86400)):
+            refresh = False
+            with open("/var/www/reporter.apache.org/data/JIRA/%s.json" % project, "r") as f:
+                x = json.loads(f.read())
+                f.close()
+                return x[0], x[1], x[2]
+    except:
+        pass
+
+    if refresh:
+        base64string = base64.encodestring('%s:%s' % ('githubbot', jirapass))[:-1]
+
+        try:
+            req = req = urllib2.Request("""https://issues.apache.org/jira/rest/api/2/search?jql=project%20=%20""" + project + """%20AND%20created%20%3E=%20-91d""")
+            req.add_header("Authorization", "Basic %s" % base64string)
+            cdata = json.loads(urllib2.urlopen(req).read())
+            req = req = urllib2.Request("""https://issues.apache.org/jira/rest/api/2/search?jql=project%20=%20""" + project + """%20AND%20resolved%20%3E=%20-91d""")
+            req.add_header("Authorization", "Basic %s" % base64string)
+            rdata = json.loads(urllib2.urlopen(req).read())
+            with open("/var/www/reporter.apache.org/data/JIRA/%s.json" % project, "w") as f:
+                f.write(json.dumps([cdata['total'], rdata['total'], project]))
+                f.close()
+            return cdata['total'], rdata['total'], project
+        except Exception as err:
+            with open("/var/www/reporter.apache.org/data/JIRA/%s.json" % project, "w") as f:
+                f.write(json.dumps([0,0,None]))
+                f.close()
+            return 0,0, None
+
+def getProjectData(project):
+    try:
+        y = []
+        with open("/var/www/projects.apache.org/site/json/projects/%s.json" % project, "r") as f:
+            x = json.loads(f.read())
+            f.close()
+            with open("/var/www/projects.apache.org/site/json/foundation/pmcs.json", "r") as f:
+                p = json.loads(f.read())
+                f.close()
+                for xproject in p:
+                    y.append(xproject)
+                    if xproject == project:
+                        x['name'] = p[project]['name']
+            with open("/var/www/projects.apache.org/site/json/foundation/chairs.json", "r") as f:
+                c = json.loads(f.read())
+                f.close()
+                for xproject in c:
+                    if xproject.lower() == x['name'].lower():
+                        x['chair'] = c[xproject]
+        z = {}
+        with open("/var/www/reporter.apache.org/data/health.json", "r") as f:
+            h = json.loads(f.read())
+            f.close()
+            z = {}
+            for entry in h:
+                if entry['group'] == project:
+                    z = entry
+                    
+        return x, y, z;
+    except:
+        x = {}
+        y = []
+        with open("/var/www/projects.apache.org/site/json/foundation/pmcs.json", "r") as f:
+            p = json.loads(f.read())
+            f.close()
+            for xproject in p:
+                y.append(xproject)
+                if xproject == project:
+                    x['name'] = p[project]['name']
+
+        with open("/var/www/projects.apache.org/site/json/foundation/chairs.json", "r") as f:
+            c = json.loads(f.read())
+            f.close()
+            for xproject in c:
+                if 'name' in x and xproject == x['name']:
+                    x['chair'] = c[xproject]
+        z = {}
+        with open("/var/www/reporter.apache.org/data/health.json", "r") as f:
+            h = json.loads(f.read())
+            f.close()
+            z = {}
+            for entry in h:
+                if entry['group'] == project:
+                    z = entry
+        return x,y,z
+
+def getReleaseData(project):
+    try:
+        with open("/var/www/reporter.apache.org/data/releases/%s.json" % project, "r") as f:
+            x = json.loads(f.read())
+            f.close()
+        return x;
+    except:
+        return {}
+
+
+
+pchanges = {}
+cchanges = {}
+
+with open("/var/www/reporter.apache.org/data/pmcs.json", "r") as f:
+    pchanges = json.loads(f.read())
+    f.close()
+
+with open("/var/www/reporter.apache.org/data/projects.json", "r") as f:
+    cchanges = json.loads(f.read())
+    f.close()
+
+
+user = os.environ['HTTP_X_AUTHENTICATED_USER'] if 'HTTP_X_AUTHENTICATED_USER' in os.environ else ""
+m = re.match(r"^([-a-zA-Z0-9_.]+)$", user)
+groups = []
+
+cdata = {}
+if m:
+    uid = m.group(1)
+    groups = getPMCs(uid)
+    include = os.environ['QUERY_STRING'] if 'QUERY_STRING' in os.environ else None
+    if include and isMember(uid) and not include in groups and len(include) > 1:
+        groups.append(include)
+    if oproject and len(oproject) > 0 and isMember(uid):
+        groups = [oproject]
+    mlstats = {}
+    with open("/var/www/reporter.apache.org/data/mailinglists.json", "r") as f:
+        ml = json.loads(f.read())
+        f.close()
+        for entry in ml:
+            tlp = entry.split(".")[0]
+            if tlp in pmap:
+                tlp = pmap[tlp]
+            if tlp in groups:
+                mlstats[tlp] = mlstats[tlp] if tlp in mlstats else {}
+                mlstats[tlp][entry] = ml[entry]
+    emails = {}
+    with open("/var/www/reporter.apache.org/data/maildata_extended.json", "r") as f:
+        mld = json.loads(f.read())
+        f.close()
+        for entry in mld:
+            tlp = entry.split("-")[0]
+            if tlp in pmap:
+                tlp = pmap[tlp]
+            if tlp in groups:
+                emails[tlp] = emails[tlp] if tlp in emails else {}
+                emails[tlp][entry] = mld[entry]
+    jdata = {}
+    ddata = {}
+    rdata = {}
+    allpmcs = []
+    keys = {}
+    count = {}
+    health = {}
+    for group in groups:
+        jiras = []
+        count[group] = [0,0]
+        xgroup = group
+        if group in ldapmap:
+            xgroup = ldapmap[group]
+        if xgroup in pchanges:
+            count[group][0] = len(pchanges[xgroup])
+        if xgroup in cchanges:
+            count[group][1] = len(cchanges[xgroup])
+        jdata[group] = [0,0, None]
+        ddata[group], allpmcs, phealth = getProjectData(group)
+        health[group] = phealth
+        rdata[group] = getReleaseData(group)
+        jiraname = group.upper()
+        if group in jmap:
+            for jiraname in jmap[group]:
+                x,y, p = getJIRAS(jiraname)
+                jdata[group][0] += x
+                jdata[group][1] += y
+                jdata[group][2] = p
+        elif group in ddata and 'name' in ddata[group]:
+            jiras = getJIRAProjects(ddata[group]['name'])
+            keys[group] = jiras
+            for jiraname in jiras:
+                x,y, p= getJIRAS(jiraname)
+                jdata[group][0] += x
+                jdata[group][1] += y
+                jdata[group][2] = p
+        elif jiraname:
+            x,y, p= getJIRAS(jiraname)
+            jdata[group][0] += x
+            jdata[group][1] += y
+            jdata[group][2] = p
+
+        cdata[group] = cdata[xgroup] if xgroup in cdata else {'pmc': {}, 'committer': {}}
+        for pmc in pchanges:
+            if pmc == xgroup:
+                for member in pchanges[pmc]:
+                    if pchanges[pmc][member][1] > 0:
+                        cdata[group]['pmc'][member] = pchanges[pmc][member]
+        for pmc in cchanges:
+            if pmc == xgroup:
+                for member in cchanges[pmc]:
+                    if cchanges[pmc][member][1] > 0:
+                        cdata[group]['committer'][member] = cchanges[pmc][member]
+    if not isMember(uid):
+        allpmcs = []
+    output = {
+        'count': count,
+        'pmcs': groups,
+        'all': allpmcs,
+        'mail': mlstats,
+        'delivery': emails,
+        'jira': jdata,
+        'changes': cdata,
+        'pdata': ddata,
+        'releases': rdata,
+        'keys': keys,
+        'health': health
+    }
+    dump = json.dumps(output)
+    print ("Content-Type: application/json\r\nContent-Length: %u\r\n\r\n" % (len(dump)+1))
+    print(dump)
+else:
+    print ("Content-Type: text/html\r\n\r\n")
+    print("Unknown or invalid user id presented")

Propchange: comdev/reporter.apache.org/tags/test/site/getjson.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: comdev/reporter.apache.org/tags/test/site/getjson.py
------------------------------------------------------------------------------
    svn:executable = *

Added: comdev/reporter.apache.org/tags/test/site/img/.gitkeep
URL: http://svn.apache.org/viewvc/comdev/reporter.apache.org/tags/test/site/img/.gitkeep?rev=1689512&view=auto
==============================================================================
--- comdev/reporter.apache.org/tags/test/site/img/.gitkeep (added)
+++ comdev/reporter.apache.org/tags/test/site/img/.gitkeep Mon Jul  6 22:11:25 2015
@@ -0,0 +1 @@
+

Added: comdev/reporter.apache.org/tags/test/site/img/chi.png
URL: http://svn.apache.org/viewvc/comdev/reporter.apache.org/tags/test/site/img/chi.png?rev=1689512&view=auto
==============================================================================
Binary file - no diff available.

Propchange: comdev/reporter.apache.org/tags/test/site/img/chi.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: comdev/reporter.apache.org/tags/test/site/img/equation.png
URL: http://svn.apache.org/viewvc/comdev/reporter.apache.org/tags/test/site/img/equation.png?rev=1689512&view=auto
==============================================================================
Binary file - no diff available.

Propchange: comdev/reporter.apache.org/tags/test/site/img/equation.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: comdev/reporter.apache.org/tags/test/site/index.html
URL: http://svn.apache.org/viewvc/comdev/reporter.apache.org/tags/test/site/index.html?rev=1689512&view=auto
==============================================================================
--- comdev/reporter.apache.org/tags/test/site/index.html (added)
+++ comdev/reporter.apache.org/tags/test/site/index.html Mon Jul  6 22:11:25 2015
@@ -0,0 +1,143 @@
+<!doctype html>
+<html class="no-js" lang="en">
+  <head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <link rel="stylesheet" href="css/foundation.css" />    
+    <script src="js/vendor/modernizr.js"></script>
+   <script src="https://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
+   <script src="https://code.jquery.com/ui/1.11.3/jquery-ui.js" type="text/javascript"></script>
+   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
+   <script type="text/javascript" src="https://www.google.com/jsapi"></script>
+   <script src="render.js"></script>
+   <style type="text/css">
+    html,body {
+      background: #AAA;
+      height:100%;
+      padding:0;
+      margin:0;
+  }
+    #tabs {
+      overflow: hidden;
+      width: 100%;
+      margin: 0;
+      padding: 0;
+      list-style: none;
+    }
+    
+    #tabs li {
+      float: left;
+      margin: 0 .5em 0 0;
+    }
+    
+    #tabs a {
+      position: relative;
+      background: #ddd;
+      background-image:  linear-gradient(to bottom, #fceabb 0%,#fccd4d 50%,#f8b500 51%,#fbdf93 100%);
+      padding: .7em 1.5em;
+      float: left;
+      text-decoration: none;
+      color: #444;
+      text-shadow: 0 1px 0 rgba(255,255,255,.8);
+      border-radius: 5px 0 0 0;
+      box-shadow: 0 2px 2px rgba(0,0,0,.4);
+    }
+    
+    #tabs a:hover,
+    #tabs a:hover::after,
+    #tabs a:focus,
+    #tabs a:focus::after {
+      background: linear-gradient(to bottom, #b7deed 0%,#71ceef 50%,#21b4e2 51%,#b7deed 100%);
+    }
+    
+    #tabs a:focus {
+      outline: 0;
+    }
+    
+    #tabs a::after {
+      content:'';
+      position:absolute;
+      z-index: 1;
+      top: 0;
+      right: -.5em;  
+      bottom: 0;
+      width: 1em;
+      background: #ddd;
+      background-image:  linear-gradient(to bottom, #fceabb 0%,#fccd4d 50%,#f8b500 51%,#fbdf93 100%);
+      box-shadow: 2px 2px 2px rgba(0,0,0,.4);
+      transform: skew(10deg);
+      border-radius: 0 5px 0 0;  
+    }
+    
+    #tabs #current a,
+    #tabs #current a::after, #tabs #current a::before {
+      background: linear-gradient(to bottom, #b7deed 0%,#71ceef 50%,#21b4e2 51%,#b7deed 100%);
+      z-index: 3;
+    }
+    #contents {
+      height: calc(100% - 200px)
+    }
+    
+   
+    #tabcontents {
+      background: #fff;
+      padding: 2em;
+      height: 220px;
+      position: relative;
+      z-index: 2; 
+      border-radius: 0 5px 5px 5px;
+      box-shadow: 0 -2px 3px -2px rgba(0, 0, 0, .5);
+    }
+    
+    #footer {
+      break-after: always;
+      break-before: always;
+      position:absolute;
+      bottom:20px;
+      text-align: center;
+      width: 100%;
+    }
+    
+    @media only screen and (max-height: 680px) {
+      #footer {
+        display: none;
+      }
+      
+      h2 {
+        font-size: 18px;
+        font-weight: bold;
+        margin: 5px;
+      }
+      #contents {
+        height: calc(100% - 120px);
+      }
+    }
+    
+   </style>
+   <title>Apache Project Report Helper</title>
+</head>
+<body>
+
+<div id="contents" class="row-12" style="text-align: left; margin: 0 auto; width: 1000px; ">
+   <p style="text-align: center;">
+      <div id="pct">Requesting project data, please wait...</div>
+      <div id="chart"></div>
+   </p>
+   <noscript>
+      This site relies heavily on JavaScript.
+      Please enable it or get a browser that supports it.
+   </noscript>
+</div>
+<div id="footer" class="footer">
+   Copyright&copy; 2015, the Apache Software Foundation. Licensed under the Apache License v/2.0<br/>
+   For inquiries, contact <a href="mailto:dev@community.apache.org">dev@community.apache.org</a>.
+</div>
+<script type="text/javascript">
+   google.load("visualization", "1", {packages:["corechart", "timeline"]});
+   google.setOnLoadCallback(function() {
+      var project = document.location.search.substr(1);
+      GetAsyncJSON("/getjson.py?" + project, project, renderFrontPage)
+   });
+</script>
+</body>
+<html>

Propchange: comdev/reporter.apache.org/tags/test/site/index.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: comdev/reporter.apache.org/tags/test/site/jiraversions.py
URL: http://svn.apache.org/viewvc/comdev/reporter.apache.org/tags/test/site/jiraversions.py?rev=1689512&view=auto
==============================================================================
--- comdev/reporter.apache.org/tags/test/site/jiraversions.py (added)
+++ comdev/reporter.apache.org/tags/test/site/jiraversions.py Mon Jul  6 22:11:25 2015
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+import os, sys, json, urllib2, re, time, base64, cgi, subprocess
+
+form = cgi.FieldStorage();
+user = os.environ['HTTP_X_AUTHENTICATED_USER'] if 'HTTP_X_AUTHENTICATED_USER' in os.environ else "nobody"
+project = form['project'].value if ('project' in form and len(form['project'].value) > 0) else None
+jiraname = form['jiraname'].value if ('jiraname' in form and len(form['jiraname'].value) > 0) else None
+prepend = form['prepend'].value if ('prepend' in form and len(form['prepend'].value) > 0) else None
+    
+def getPMCs(uid):
+    groups = []
+    ldapdata = subprocess.check_output(['ldapsearch', '-x', '-LLL', '(|(memberUid=%s)(member=uid=%s,ou=people,dc=apache,dc=org))' % (uid, uid), 'cn'])
+    picked = {}
+    for match in re.finditer(r"dn: cn=([a-zA-Z0-9]+),ou=pmc,ou=committees,ou=groups,dc=apache,dc=org", ldapdata):
+        group = match.group(1)
+        if group != "incubator":
+            
+            groups.append(group)
+    return groups
+
+
+def getReleaseData(project):
+    try:
+        with open("/var/www/reporter.apache.org/data/releases/%s.json" % project, "r") as f:
+            x = json.loads(f.read())
+            f.close()
+        return x;
+    except:
+        return {}
+
+
+def isMember(uid):
+    members = []
+    ldapdata = subprocess.check_output(['ldapsearch', '-x', '-LLL', '-b', 'cn=member,ou=groups,dc=apache,dc=org'])
+    for match in re.finditer(r"memberUid: ([-a-z0-9_.]+)", ldapdata):
+        group = match.group(1)
+        members.append(group)
+    if uid in members:
+        return True
+    return False
+
+
+jirapass = ""
+with open("/var/www/reporter.apache.org/data/jirapass.txt", "r") as f:
+    jirapass = f.read().strip()
+    f.close()
+
+groups = getPMCs(user)
+if (isMember(user) or project in groups)  and jiraname:
+       jiraname = jiraname.upper()
+       base64string = base64.encodestring('%s:%s' % ('githubbot', jirapass))[:-1]
+       rdata = getReleaseData(project)
+       try:
+           req = req = urllib2.Request("https://issues.apache.org/jira/rest/api/2/project/%s/versions" % jiraname)
+           req.add_header("Authorization", "Basic %s" % base64string)
+           cdata = json.loads(urllib2.urlopen(req).read())
+           for entry in cdata:
+              if ('name' in entry and 'releaseDate' in entry and 'released' in entry and entry['released']):
+                     date = time.mktime(time.strptime(entry['releaseDate'], "%Y-%m-%d"))
+                     if prepend:
+                        entry['name'] = "%s-%s" % (prepend, entry['name'])
+                     rdata[entry['name']] = date
+       except Exception as err:
+           pass
+       with open("/var/www/reporter.apache.org/data/releases/%s.json" % project, "w") as f:
+              f.write(json.dumps(rdata))
+              f.close()
+              
+       print("Content-Type: application/json\r\n\r\n")
+       print(json.dumps({'status': 'Fetched', 'versions': rdata}))
+    
+else:
+       print("Content-Type: application/json\r\n\r\n{\"status\": \"Data missing\"}\r\n")

Propchange: comdev/reporter.apache.org/tags/test/site/jiraversions.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: comdev/reporter.apache.org/tags/test/site/jiraversions.py
------------------------------------------------------------------------------
    svn:executable = *