SF.net SVN: gar:[23437] csw/mgar/gar/v2/lib/python
wahwah at users.sourceforge.net
wahwah at users.sourceforge.net
Sun Apr 20 16:32:29 CEST 2014
Revision: 23437
http://sourceforge.net/p/gar/code/23437
Author: wahwah
Date: 2014-04-20 14:32:28 +0000 (Sun, 20 Apr 2014)
Log Message:
-----------
Maintainer activity: incorporate mantis info
Mantis is the canonical source of maintainer status. This patch makes
the script download the mantis information and incorporate it in the
report.
Existing limitations:
- The script doesn't know who's old and who's new, it only looks whether
there are any packages built by certain maintainer.
- The script doesn't look at the mailing lists, so some active people
are marked as "to retire".
Modified Paths:
--------------
csw/mgar/gar/v2/lib/python/activity.py
csw/mgar/gar/v2/lib/python/maintainer_activity_report.py
Modified: csw/mgar/gar/v2/lib/python/activity.py
===================================================================
--- csw/mgar/gar/v2/lib/python/activity.py 2014-04-20 11:55:53 UTC (rev 23436)
+++ csw/mgar/gar/v2/lib/python/activity.py 2014-04-20 14:32:28 UTC (rev 23437)
@@ -10,7 +10,8 @@
from lib.python import opencsw
Maintainer = namedtuple('Maintainer',
- ['username', 'pkgs', 'last_activity', 'last_activity_pkg', 'active'])
+ ['username', 'pkgs', 'last_activity', 'last_activity_pkg',
+ 'active', 'mantis_status', 'fullname'])
INACTIVE_MAINTAINER_CUTOFF = 2
STALE_PACKAGE_CUTOFF = 4
@@ -98,7 +99,9 @@
Maintainer(username=entry['maintainer'], pkgs={},
last_activity=datetime.datetime(1970, 1, 1, 0, 0),
last_activity_pkg=None,
- active=True))
+ active=True,
+ mantis_status=None,
+ fullname=None))
if entry['catalogname'] not in maintainer.pkgs:
maintainer.pkgs[entry['catalogname']] = entry
if maintainer.last_activity < date:
Modified: csw/mgar/gar/v2/lib/python/maintainer_activity_report.py
===================================================================
--- csw/mgar/gar/v2/lib/python/maintainer_activity_report.py 2014-04-20 11:55:53 UTC (rev 23436)
+++ csw/mgar/gar/v2/lib/python/maintainer_activity_report.py 2014-04-20 14:32:28 UTC (rev 23437)
@@ -44,26 +44,51 @@
color: red;
font-weight: bold;
}
- .can-be-retired-True {
- background-color: #FED;
+ .retired-True {
+ background-color: #DDD;
+ color: #AAA;
}
+ .action-needed-True {
+ background-color: #FA8;
+ }
</style>
</head>
<body>
- <h1>Maintainer activity report</h1>
+ <h1>OpenCSW Maintainer activity report</h1>
+ <h2>Maintainers to retire</h2>
+
+ <p>Limitations: This report doesn't know which maintainers are new and which ones are old.
+ New maintainers are reported as "to retire" until they release their first
+ package. The script only detects activity in the package catalogs. There are
+ people who are active in the project, even though they don't release
+ packages. They might be wrongly listed here as "to retire". Incorporating the
+ mailing list activity should help, but is not implemented right now.</p>
+
+ <p>The following list contains maintainers with no detected activity within
+ the last 2 years.</p>
+
<p>
+ {% for username in analysis_by_username|sort %}
+ {% if analysis_by_username[username].to_retire %}
+ <a id="{{ username }}" class="maintainer"
+ href="http://www.opencsw.org/maintainers/{{ username }}/"
+ title="{{ maintainers[username].fullname }}">{{ username }}</a>
+ {% endif %}
+ {% endfor %}
</p>
+ <h2>Activity</h2>
<table>
<tr>
<th>username</th>
<th>last activity</th>
<th>years</th>
<th>active?</th>
+ <th>mantis</th>
<th>last pkg</th>
<th># pkgs</th>
</tr>
{% for username in maintainers|sort %}
- <tr class="active-{{ maintainers[username].active }} can-be-retired-{{ analysis_by_username[username].can_be_retired }}">
+ <tr class="active-{{ maintainers[username].active }} retired-{{ maintainers[username].mantis_status != 'Active' }} action-needed-{{ analysis_by_username[username].to_retire }}">
<td>
<a id="{{ username }}" class="maintainer"
href="http://www.opencsw.org/maintainers/{{ username }}/">{{ username }}</a>
@@ -82,6 +107,9 @@
{% endif %}
</td>
<td>
+ {{ maintainers[username].mantis_status }}
+ </td>
+ <td>
<a href="http://buildfarm.opencsw.org/pkgdb/srv4/{{ maintainers[username].last_activity_pkg.md5_sum }}/">
{{ maintainers[username].last_activity_pkg.catalogname }}</a>
</td>
@@ -105,14 +133,20 @@
return requests.get(url).json()
results_by_catrel = {}
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
- future_to_catrel = dict((executor.submit(Fetch, catrel), catrel)
- for catrel in catrels)
- for future in concurrent.futures.as_completed(future_to_catrel):
- catrel = future_to_catrel[future]
+ key_by_future = dict((executor.submit(Fetch, catrel), catrel)
+ for catrel in catrels)
+
+ # Additional query: maintainers from Mantis
+ mantis_url = 'http://www.opencsw.org/buglist/maintainers'
+ mantis_future = executor.submit(lambda: requests.get(mantis_url).json())
+ key_by_future[mantis_future] = 'mantis'
+
+ for future in concurrent.futures.as_completed(key_by_future):
+ key = key_by_future[future]
if future.exception() is not None:
logging.warning('Fetching %r failed', url)
else:
- results_by_catrel[catrel] = future.result()
+ results_by_catrel[key] = future.result()
return results_by_catrel
@@ -136,16 +170,51 @@
with open(args.save_as, 'w') as fd:
cPickle.dump(results_by_catrel, fd)
+ # We need to remove the mantis part.
+ mantis_maintainers = results_by_catrel['mantis']
+ del results_by_catrel['mantis']
+
+ # Flatten packages from all catalogs into a single list. For activity
+ # detection, we don't care which catalog a maintainer submitted a package to.
pkgs = [item for sublist in results_by_catrel.values() for item in sublist]
+
+ # Shared code for activity detection. We're processing the unstable catalog
+ # separately, so we can detect whether each maintainer has any packages in
+ # the unstable catalog.
maintainers, bad_dates = activity.Maintainers(pkgs)
maintainers_in_unstable, _ = activity.Maintainers(results_by_catrel['unstable'])
+ for d in mantis_maintainers:
+ # maintainer, fullname, status
+ username = d['maintainer']
+ status = d['status']
+ if username in maintainers:
+ maintainers[username] = (
+ maintainers[username]._replace(mantis_status=status))
+ else:
+ maintainers[username] = (
+ activity.Maintainer(
+ username=username,
+ pkgs={},
+ last_activity=datetime.datetime(1970, 1, 1, 0, 0),
+ last_activity_pkg=None,
+ active=False,
+ mantis_status=status,
+ fullname=d['fullname']))
+
+ mantis_m_by_username = dict((m['maintainer'], m) for m in mantis_maintainers)
analysis_by_username = {}
for username, maintainer in maintainers.iteritems():
- d = {'can_be_retired': False}
+ d = {'can_be_retired': False,
+ 'to_retire': False,
+ 'bogus': False}
+ if username not in mantis_m_by_username:
+ d['bogus'] = True
if not maintainer.active:
if username not in maintainers_in_unstable:
d['can_be_retired'] = True
+ if maintainer.mantis_status != 'Retired' and not d['bogus']:
+ d['to_retire'] = True
analysis_by_username[username] = d
with open(args.output, 'w') as outfd:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the devel
mailing list