获取用户到期时间(四)
执行脚本(根据仓库数量用户数量大概耗时5分钟./getGitlabExpireUserMsg.py 或python3 getGitlabExpireUserMsg.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() return response.json() 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]) for member in members: username member[username] if username not in user_projects: user_projects[username] [] user_projects[username].append({ project_name: project[name], project_url: project[web_url] }) return user_projects def main(): try: # 获取所有项目 all_projects fetch_all_projects() print(f发现 {len(all_projects)} 个项目) # 遍历处理每个项目 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, []) # 输出或保存用户所在的项目信息 with open(user_projects.txt, w) as f: for username, projects in user_projects.items(): f.write(f用户名: {username}\n) for project in projects: f.write(f - {project[project_name]}: {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()

相关新闻

MCP Client实战翻车记:两个Server同时跑,AI调错了Tool

MCP Client实战翻车记:两个Server同时跑,AI调错了Tool

前面写完 MCP Server 那篇文章之后,我又接了个需求:让一个 Agent 同时调两个 MCP Server。一个查 SQLite 数据库,一个查本地文件系统。Agent 跑了一轮,返回了一个答案。我看着答案觉得不太对,对了一下原始数据——AI 给…

2026/7/21 8:13:09阅读更多 →
AstrBot:一个以「IM 平台粘合剂」为核心竞争力的开源 AI Agent 框架

AstrBot:一个以「IM 平台粘合剂」为核心竞争力的开源 AI Agent 框架

信源已充分收集,现在输出完整笔记。 AstrBot:一个以「IM 平台粘合剂」为核心竞争力的开源 AI Agent 框架 项目地址:github.com/AstrBotDevs/AstrBot | Stars: ~28.4k | 许可证: AGPL-3.0 | 主语言: Python 3.12 核心观点 AstrBot 的本质不是…

2026/7/21 8:13:09阅读更多 →
Windows 11必备效率工具全解析

Windows 11必备效率工具全解析

1. Windows 11必备工具全景解析作为从Windows 95时代就开始折腾系统的老用户,我见证了操作系统从简陋到精致的演变过程。Windows 11无疑是微软近年来最具革新性的版本,但就像精装修的房子需要软装搭配一样,系统原生的功能总有些让人不顺手的地…

2026/7/21 8:11:09阅读更多 →
AI建站工具怎么选?一份真实用的对比指南与筛选标准

AI建站工具怎么选?一份真实用的对比指南与筛选标准

面对市面上琳琅满目的建站工具,很多人都会陷入选择困难。是选操作简单的,还是功能强大的?是相信“AI生成”,还是继续用传统模板?这篇指南的核心目的,不是直接告诉你“买哪个”,而是帮你建立一套…

2026/7/21 17:12:06阅读更多 →
delete-docker-registry-image:解决私有Docker仓库磁盘占用问题的终极工具

delete-docker-registry-image:解决私有Docker仓库磁盘占用问题的终极工具

delete-docker-registry-image:解决私有Docker仓库磁盘占用问题的终极工具 【免费下载链接】delete-docker-registry-image If you are running a private v2 docker registry, and you are storing your data on disk, running this script from the machine where…

2026/7/21 17:12:06阅读更多 →
Camellia核心组件解析:从架构到实现原理

Camellia核心组件解析:从架构到实现原理

Camellia核心组件解析:从架构到实现原理 【免费下载链接】camellia Camellia provide easy-to-use server toolkits, such as: redis proxy、delay queue、id gen、hot key and more 项目地址: https://gitcode.com/gh_mirrors/ca/camellia Camellia是网易云…

2026/7/21 17:12:06阅读更多 →
DeepONet处理分数阶微积分:1D Caputo导数案例详解

DeepONet处理分数阶微积分:1D Caputo导数案例详解

DeepONet处理分数阶微积分:1D Caputo导数案例详解 【免费下载链接】deeponet Learning nonlinear operators via DeepONet based on the universal approximation theorem of operators 项目地址: https://gitcode.com/gh_mirrors/de/deeponet 分数阶微积分作…

2026/7/21 17:12:06阅读更多 →
SRS WebRTC配置教程:3步实现低延迟实时音视频传输

SRS WebRTC配置教程:3步实现低延迟实时音视频传输

SRS WebRTC配置教程:3步实现低延迟实时音视频传输 【免费下载链接】srs Please use https://github.com/ossrs/srs because this is my personal experimental repository, so its not updated and not stable. 项目地址: https://gitcode.com/gh_mirrors/srs1/sr…

2026/7/21 17:12:06阅读更多 →
Unity Multiplayer:10个Netcode for GameObjects核心概念解析与实战技巧

Unity Multiplayer:10个Netcode for GameObjects核心概念解析与实战技巧

Unity Multiplayer:10个Netcode for GameObjects核心概念解析与实战技巧 【免费下载链接】com.unity.multiplayer.docs [ARCHIVED] Open Source documentation for Unity Multiplayer, which includes Netcode for GameObjects, the Unity Transport Package, Multi…

2026/7/21 17:10:04阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 0:51:49阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 0:51:49阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 0:51:49阅读更多 →
Windows+macOS 通用 OpenClaw 部署流程,内置依赖一键启动智能桌面助手

Windows+macOS 通用 OpenClaw 部署流程,内置依赖一键启动智能桌面助手

📌教程适配:OpenClaw v2.7.9 | 兼容 Windows10/11、macOS 双系统 📖前言 当下各类本地 AI 工具层出不穷,多数产品仅能完成文字问答交互,很难直接操控电脑执行实际操作。OpenClaw,业内常称小龙虾 AI&#…

2026/7/21 0:01:46阅读更多 →
Codex 接入后 Bug 反增?复盘从个人演示到团队协作的“流程陷阱”

Codex 接入后 Bug 反增?复盘从个人演示到团队协作的“流程陷阱”

聊《一次Codex项目复盘,问题最后出在流程而不是模型》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要先把这篇文章的目标说清楚:看完之后,你应该能判断这件事值不值得做&…

2026/7/21 0:01:46阅读更多 →
手把手搓一个五子棋游戏,零代码也能当“游戏开发者”

手把手搓一个五子棋游戏,零代码也能当“游戏开发者”

大家好,还是我。前几期带大家做了心情日记本和可视化大屏,后台有朋友留言:“能不能教点好玩的?我想做游戏,但一行代码都不会。”行,这期就安排。今天的目标:从零做一个五子棋游戏。 带AI对战、三…

2026/7/21 0:03:46阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/20 22:51:39阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/20 18:51:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/20 18:51:18阅读更多 →