gitlab api 获取有效用户的名称,仓库,有效期(一)
1代码文件getGitlabExpireActiveUserMsg.pyrootrke2-10-30:~/gitlabUserExpire# more getGitlabExpireActiveUserMsg.py #!/usr/bin/python3 import requests import json from datetime import datetime, timedelta # GitLab API URL 和访问令牌 GITLAB_URL https://gitlab.umi.com/api/v4 PRIVATE_TOKEN X HEADERS {PRIVATE-TOKEN: PRIVATE_TOKEN} def fetch_all_projects(): 获取所有项目列表自动处理分页 page 1 projects [] while True: params { per_page: 100, page: page } response requests.get(f{GITLAB_URL}/projects, headersHEADERS, paramsparams) response.raise_for_status() current_page_projects response.json() if not current_page_projects: break projects.extend(current_page_projects) # 检查是否最后一页 if len(current_page_projects) 100: break page 1 return projects def fetch_project_members(project_id): 获取项目成员并过滤非活跃用户 members_url f{GITLAB_URL}/projects/{project_id}/members/all response requests.get(members_url, headersHEADERS) if response.status_code 403: print(f项目 {project_id} 权限不足跳过) return [] response.raise_for_status() # 调试日志打印原始成员数 all_members response.json() print(f项目 {project_id} 原始成员数: {len(all_members)}) # 调整过滤条件 active_members [ member for member in all_members if member[state] active and not member.get(blocked, False) # 暂时注释严格过滤条件 # and member.get(last_activity_at) is not None ] print(f项目 {project_id} 有效成员数: {len(active_members)}) return active_members def parse_date(date_str): 解析日期字符串 if date_str is None or date_str 永久有效: return None if T in date_str: # ISO 8601 格式 return datetime.strptime(date_str, %Y-%m-%dT%H:%M:%S.%fZ) else: # 简单日期格式 return datetime.strptime(date_str, %Y-%m-%d) def format_output(project, members): 格式化输出结果 output [] output.append(f项目名称: {project[name]}) output.append(f项目地址: {project[web_url]}) output.append(f最后活跃: {project[last_activity_at]}) output.append(\n成员列表:) output.append(f{用户名:15}{姓名:10}{权限等级:10}{到期时间:20}) output.append(- * 55) for member in members: expires_at member[expires_at] or 永久有效 access_level { 10: Guest, 20: Reporter, 30: Developer, 40: Maintainer, 50: Owner }.get(member[access_level], 未知) output.append( f{member[username]:15} f{member[name]:10} f{access_level:10} f{expires_at:20} ) return \n.join(output) def save_to_special_record(project, member): 保存到期时间在今天起30天内的用户信息和仓库到单独记录 expires_at parse_date(member[expires_at]) if expires_at is not None: today datetime.now() expires_in_one_month today timedelta(days30) if today expires_at expires_in_one_month: with open(soon_to_expire.txt, a) as f: f.write(f项目名称: {project[name]}\n) f.write(f项目地址: {project[web_url]}\n) f.write(f用户名: {member[username]}\n) f.write(f姓名: {member[name]}\n) f.write(f到期时间: {member[expires_at]}\n\n) def get_user_projects(all_projects, all_members): 根据用户名获取其所在的所有项目过滤非活跃用户 user_projects {} for project in all_projects: members fetch_project_members(project[id]) print(f处理项目 {project[name]}成员数: {len(members)}) for member in members: username member[username] # 新增权限到期时间提取 expires_at member.get(expires_at, None) or 永久有效 # 处理空值 access_level { 10: Guest, 20: Reporter, 30: Developer, 40: Maintainer, 50: Owner }.get(member[access_level], 未知) if username not in user_projects: user_projects[username] { name: member[name], projects: [] } user_projects[username][projects].append({ project_name: project[name], project_url: project[web_url], access_level: access_level, expires_at: expires_at # 新增到期时间字段 }) return user_projects def main(): try: # 获取所有项目 all_projects fetch_all_projects() print(f发现 {len(all_projects)} 个项目) # 清空旧文件避免残留数据 open(gitlab_permission_report.txt, w).close() open(user_projects.txt, w).close() open(soon_to_expire.txt, w).close() # 遍历处理每个项目 for project in all_projects: members fetch_project_members(project[id]) report format_output(project, members) # 输出到控制台并保存文件 print(\n *60) print(report) with open(gitlab_permission_report.txt, a) as f: f.write(report \n\n) # 保存到期时间在今天起30天内的用户信息 for member in members: save_to_special_record(project, member) # 获取用户所在的所有项目 user_projects get_user_projects(all_projects, []) print(f汇总用户项目数据共 {len(user_projects)} 个用户) # 调试日志 # 输出或保存用户所在的项目信息 with open(user_projects.txt, w) as f: for username, data in user_projects.items(): f.write(f用户名: {username} ({data[name]})\n) for project in data[projects]: # 新增到期时间显示 expires_display project[expires_at] if project[expires_at] else 永久有效 f.write(f - {project[project_name]} ({project[access_level]}, 到期时间: {expires_display})) f.write(f: {project[project_url]}\n) f.write(\n) except requests.exceptions.HTTPError as e: print(fAPI 请求失败: {e.response.status_code} {e.response.text}) except Exception as e: print(f程序异常: {str(e)}) if __name__ __main__: main()