uc-recognition/tools/get_active_wg_members.py
Tom Fifield 721af3e73a Update meeting data config
Scientific WG's logs were missing from the meeting data downloader.
This patch adds them, so the group's members will be added to the
automated AUC machinery.

It also updates and adds for the new telco/nfv meeting space, the
ops meetups team, massively distributed clouds and the wos_mentoring
group.

Change-Id: I87eac8ced8df459b48a5c5e5478ee0dc67c92d90
2017-03-16 10:48:16 +01:00

177 lines
6.8 KiB
Python

#!/usr/bin/env python
#
# Copyright (c) 2016 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import datetime
from datetime import timedelta
import operator
import optparse
import os
meeting_mappings = {
'uc': 'user_committee',
'product_team': 'product_working_group',
'large_deployments_team_monthly_meeting': 'large_deployment_team',
'ops_meetup_team': 'ops_meetups_team',
'operators_telco_nfv': 'telcowg',
}
def get_recent_meets(log_dir, last_active_days=180):
"""
takes a directory heirachy that only contains meetbot
txt summary files, determines the users active within
the threshold. Returns a dictionary that has
one entry per meeting category, containing information about
who attended which meetings and how much they said.
"""
meetings = {}
now = datetime.now()
active_threshold = now - timedelta(days=last_active_days)
# get our list of meetings and timestamps
for root, dirs, files in os.walk(log_dir):
if len(files) > 0:
for txt_summary in files:
(meet_name, meet_date) = txt_summary.split('.', 1)
meet_date = meet_date[0:-4] # drop the .txt at the end
if meet_name in meeting_mappings.keys():
meet_name = meeting_mappings[meet_name]
meet_timestamp = datetime.strptime(meet_date, "%Y-%m-%d-%H.%M")
if meet_timestamp > active_threshold:
if meet_name not in meetings.keys():
meetings[meet_name] = []
meet_file = root + "/" + txt_summary
meetings[meet_name].append(get_people_in_meeting(meet_file))
return meetings
def get_people_in_meeting(meeting_txt):
"""
takes a meetbot summary file that has a section with the following format
and returns a dict with username<->lines said mapping
People present (lines said)
---------------------------
* username (117)
* username2 (50)
"""
meeting_people = []
in_people = False
txt_file = open(meeting_txt)
for line in txt_file:
if line == "People present (lines said)\n":
in_people = True
elif not in_people:
next
elif in_people and '*' not in line:
next
elif in_people and 'openstack' not in line:
ircnic, linessaid = line[2:-2].split('(')
ircnic = ircnic.strip(" _").lower()
meeting_people.append((ircnic, linessaid))
txt_file.close()
return meeting_people
def get_meeting_aggregates(meeting_data):
"""
Aggregates the attendance counts and lines said for users across
a meeting category
"""
meeting_aggregate = {}
for meeting_name in meeting_data.keys():
meeting_users = {}
for meeting in meeting_data[meeting_name]:
for user_tuple in meeting:
if user_tuple[0] not in meeting_users.keys():
meeting_users[user_tuple[0]] = {'attendance_count': 1,
'lines_said': int(user_tuple[1])}
else:
meeting_users[user_tuple[0]]["attendance_count"] += 1
meeting_users[user_tuple[0]]["lines_said"] += int(user_tuple[1])
meeting_aggregate[meeting_name] = meeting_users
return meeting_aggregate
def print_meet_stats(meeting_data):
for meeting_name in meeting_data.keys():
print "\n" + meeting_name + "\n=====================================\n"
sorted_users = sorted(meeting_data[meeting_name].items(), reverse=True,
key=operator.itemgetter(1))
for user in sorted_users:
print "{: <20} {: <20} {: <20}".format(user[0],
user[1]["attendance_count"],
user[1]["lines_said"])
def print_eligible_usernames(meeting_data, num_meetings=1, lines_said=1, human=False):
user_aggregate = {}
for meeting_name in meeting_data.keys():
for user_tuple in meeting_data[meeting_name].items():
if user_tuple[0] not in user_aggregate.keys():
user_aggregate[user_tuple[0]] = user_tuple[1]
else:
user_aggregate[user_tuple[0]]["lines_said"] += user_tuple[1]["lines_said"]
user_aggregate[user_tuple[0]]["attendance_count"] += user_tuple[1]["attendance_count"]
if human:
print "\n OVERALL STATS \n=====================================\n"
sorted_users = sorted(user_aggregate.items(), reverse=True,
key=operator.itemgetter(1))
for user in sorted_users:
if user[1]["attendance_count"] >= num_meetings or user[1]["lines_said"] >= lines_said:
if human:
print "{: <20} {: <20} {: <20}".format(user[0],
user[1]["attendance_count"],
user[1]["lines_said"])
else:
print "{},{},{}".format(user[0],
user[1]["attendance_count"],
user[1]["lines_said"])
def main():
optparser = optparse.OptionParser()
optparser.add_option(
'--human', help='If set, output results in human-readable format',
default=False, action="store_true")
optparser.add_option(
'-d', '--datadir', help='Where meeting data lives',
default='./eavesdrop.openstack.org/meetings')
optparser.add_option(
'-t', '--days', help='Validity of attendance in days',
type="int", default=183)
optparser.add_option(
'-n', '--nummeetings', help='Required number of meetings',
type="int", default=2)
optparser.add_option(
'-l', '--linessaid', help='Required number of line said',
type="int", default=10)
options, args = optparser.parse_args()
meeting_data = get_recent_meets(options.datadir, options.days)
meeting_aggregate = get_meeting_aggregates(meeting_data)
if options.human:
print_meet_stats(meeting_aggregate)
print_eligible_usernames(meeting_aggregate, options.nummeetings,
options.linessaid, options.human)
if __name__ == "__main__":
main()