Commit 78b154b8 authored by Hans-Christoph Steiner's avatar Hans-Christoph Steiner
Browse files

Merge branch 'mia' into 'master'

Add MIA script

See merge request !1
parents eac742d0 13392a56
#!/usr/bin/env python3
#
# mia.py - part of the FDroid admin tools
# Copyright (C) 2021 Jochen Sprickerhof <fdroid@jochen.sprickerhof.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from enum import Enum
from os import getenv
from sys import exit
from typing import Any
from gitlab import Gitlab
# https://github.com/python-gitlab/python-gitlab/pull/1688
class AccessLevel(Enum):
NO_ACCESS: int = 0
MINIMAL_ACCESS: int = 5
GUEST_ACCESS: int = 10
REPORTER_ACCESS: int = 20
DEVELOPER_ACCESS: int = 30
MAINTAINER_ACCESS: int = 40
OWNER_ACCESS: int = 50
def fdroid(private_token: str) -> dict[str, dict[str, Any]]:
gl = Gitlab("https://gitlab.com", private_token=private_token)
group = gl.groups.get("fdroid", lazy=True)
users = {
member.username: member.attributes
for member in group.members_all.list(all=True)
}
for project in group.projects.list(all=True):
if project.path == "wiki" or not project.path_with_namespace.startswith(
"fdroid"
):
continue # everyone gets access to the wiki
path = project.path
project = gl.projects.get(project.get_id(), lazy=True)
for member in project.members.list(all=True):
if member.username not in users:
users[member.username] = dict(member.attributes)
del users[member.username]["access_level"]
if "projects" not in users[member.username]:
users[member.username]["projects"] = {}
users[member.username]["projects"][path] = member.attributes.get(
"access_level", ""
)
# process events once we found all users as they could be active in different projects
for project in group.projects.list(all=True):
project = gl.projects.get(project.get_id(), lazy=True)
for event in project.events.list(all=True):
if event.author_username in users:
if event.created_at > users[event.author_username].get(
"last_active", ""
):
users[event.author_username]["last_active"] = event.created_at
return users
def markdown(props: dict[str, Any]) -> list[str]:
md = []
md.append(f'### {props["name"]}')
md.append(f'- URL: {props["web_url"]}')
if "last_active" in props:
md.append(f'- last active: {props["last_active"]}')
md.append(f'- created: {props["created_at"]}')
if "access_level" in props:
md.append(f'- access level global: {AccessLevel(props["access_level"]).name}')
for project, access_level in props.get("projects", {}).items():
md.append(f"- access level {project}: {AccessLevel(access_level).name}")
return md
def main() -> None:
private_token = getenv("PERSONAL_ACCESS_TOKEN")
if not private_token:
print("ERROR: GitLab Token not found in PERSONAL_ACCESS_TOKEN")
exit(1)
users = fdroid(private_token)
now = datetime.now()
for props in users.values():
mia = True
if "last_active" in props:
last_active = datetime.strptime(
props["last_active"], "%Y-%m-%dT%H:%M:%S.%fZ"
)
if (now - last_active).days < 6 * 30: # approx 6 month
mia = False
if mia:
print("\n".join(markdown(props)))
print()
if __name__ == "__main__":
main()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment