android_mt6572_jiabo/lineage/slackbot/plugins/gerrit.py
2025-09-05 16:56:03 +08:00

106 lines
5.1 KiB
Python

from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
import re
from pygerrit2.rest import GerritRestAPI
import datetime
from rtmbot.core import Plugin
class GerritChangeFetcher(Plugin):
gerrit_url = "https://review.lineageos.org/" # Needs a trailing slash
rest = GerritRestAPI(url=gerrit_url)
def PostChangesInfo(self, channel, changenum):
# Use DETAILED_ACCOUNTS so we don't have to make a second API call for owner email and name
change = self.rest.get("/changes/{}?o=DETAILED_ACCOUNTS".format(changenum))
self.slack_client.api_call('chat.postMessage', channel=channel, as_user=True, attachments=[
{
"fallback": "{}#/c/{}: {}".format(self.gerrit_url,change['_number'],change['subject']),
"color": "good",
"title": "{}: {} ({})".format(change['_number'], change['subject'], 'Open' if change['status'] == 'NEW' else change['status'].capitalize()),
"title_link": "{}#/c/{}".format(self.gerrit_url,change['_number']),
"mrkdwn_in": ["text"],
'text': ("*Project*: <{base}#/q/project:{project}|{project}> ({branch})\n"
"*Topic*: {topic}\n"
"*Owner*: <{base}#/q/owner:{username}|{name} ({email})>")
.format(
project = change['project'],
branch = change['branch'],
topic = '<{}#/q/{topic}|{topic}>'.format(self.gerrit_url, topic = change['topic']) if 'topic' in change else 'None',
username = change['owner']['username'],
name = change['owner']['name'],
email = change['owner']['email'],
base = self.gerrit_url,
)
}
])
def PostTopicInfo(self, channel, topic_name):
topic = self.rest.get("/changes/?q=topic:{}".format(topic_name))
t_changes = ocn = mcn = acn = omcn = 0
# Initialise these separately (unlike before), so we don't end up with
# projects == branches
projects,branches = [],[]
for change in topic:
if change['project'] not in projects:
projects.append(change['project'])
if change['branch'] not in branches:
branches.append(change['branch'])
if change['status'] == 'NEW':
ocn = ocn + 1
if change['mergeable']:
omcn = omcn + 1
if change['status'] == 'MERGED':
mcn = mcn + 1
if change['status'] == 'ABANDONED':
acn = acn + 1
t_changes = t_changes + 1
self.slack_client.api_call('chat.postMessage', channel=channel, as_user=True, attachments=[
{
"fallback": "Topic: {}".format(topic_name),
"color": "good",
"title": "Topic: {}".format(topic_name),
"title_link": "{}#/q/topic:{}".format(self.gerrit_url,topic_name),
"mrkdwn_in": ["text"],
"text": ("{total} commits across {projects} projects on {branches} branch(es)\n"
"*Open*: <{base}#/q/status:open%20AND%20topic:{name}|{ocn}>, "
"of which <{base}#/q/status:open%20AND%20is:mergeable%20AND%20topic:{name}|{omcn}> are mergeable\n"
"*Merged*: <{base}#/q/status:merged%20AND%20topic:{name}|{mcn}>\n"
"*Abandoned*: <{base}#/q/status:abandoned%20AND%20topic:{name}|{acn}>")
.format(
projects = len(projects),
branches = len(branches),
total = t_changes,
base = self.gerrit_url,
name = topic_name,
ocn = ocn,
omcn = omcn,
mcn = mcn,
acn = acn,
)
}
])
def process_message(self, data):
text = data['text']
channel = data['channel']
changes = topics = []
number_detections = 0
if re.search(r'\bignore\b', text):
return False
for word in text.split():
if self.gerrit_url in word:
if number_detections >= 4:
break # only print first 4 changes. any more is excessive
number_detections += 1
topic = re.search(r'(?:topic:)(.+?(?:(?=[%\s+]|$|>)))',word)
# explicitly check for url as prefix to avoid detecting numbers in project name queries
change = re.search(r'(?:' + self.gerrit_url.replace('.', r'\.') + ')(?:(?:#\/c\/)|)([0-9]{4,7})',word)
if change is not None:
GerritChangeFetcher.PostChangesInfo(self, channel, change.group(1))
elif topic is not None:
GerritChangeFetcher.PostTopicInfo(self, channel, topic.group(1))
else:
return False