diff --git a/.env b/.env new file mode 100644 index 0000000000000000000000000000000000000000..7d626ea5ca27a10b2c5e01946351f99e08e520fe --- /dev/null +++ b/.env @@ -0,0 +1 @@ +GITLAB_API_TOKEN=your_gitlab_api_token_here diff --git a/script.py b/script.py new file mode 100644 index 0000000000000000000000000000000000000000..b93525f82cc6ef67170fe5ee2142009be69350d2 --- /dev/null +++ b/script.py @@ -0,0 +1,242 @@ +import datetime +import gitlab +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +import subprocess +import requests +from dotenv import load_dotenv + + +gitlab_url = 'https://gitlab.ard.de' + +confluence_url = 'YOUR_CONFLUENCE_URL' +api_token = 'YOUR_API_TOKEN' + +sender_email = 'your_email@example.com' +sender_password = 'your_email_password' +recipient_email = 'recipient@example.com' + +def check_binaries(): + required_binaries = ['df', 'gitlab-ctl'] + missing_binaries = [binary for binary in required_binaries if not shutil.which(binary)] + + if missing_binaries: + print(f"Error: The following binaries are missing: {', '.join(missing_binaries)}") + print("Please ensure they are installed and available in the system's PATH.") + exit(1) + +def load_api_token(): + load_dotenv() # Load environment variables from .env file + api_token = os.getenv('GITLAB_API_TOKEN') + + if not api_token: + print("Error: API token not found in .env file.") + exit(1) + + return api_token + +def get_disk_space(): + # Run the df command to get disk space information + result = subprocess.run(['df', '-h'], capture_output=True, text=True) + + # Extract the output and parse the relevant information + output_lines = result.stdout.strip().split('\n') + header_line, *data_lines = output_lines + + # Assuming the output format of 'df -h' is as follows: + # Filesystem Size Used Avail Use% Mounted on + # /dev/sda1 100G 50G 50G 50% / + # ... + # Extracting the available space (Avail) from the first line of data + disk_space_info = header_line.split() + free_space_on_disk = disk_space_info[3] + + return free_space_on_disk + +def get_total_commits_last_month(gl): + # Calculate the date range for the last month + current_date = datetime.datetime.now() + last_month_start = (current_date.replace(day=1) - datetime.timedelta(days=1)).replace(day=1) + last_month_end = current_date.replace(day=1) - datetime.timedelta(days=1) + + # Get the total commits last month + total_commits_last_month = 0 + projects = gl.projects.list(all=True) + for project in projects: + commits = project.commits.list(since=last_month_start, until=last_month_end) + total_commits_last_month += len(commits) + + return total_commits_last_month + +def get_projects_with_no_activity(gl): + # Get projects with no activity in the last month + current_date = datetime.datetime.now() + last_month_start = (current_date.replace(day=1) - datetime.timedelta(days=1)).replace(day=1) + projects_with_no_activity = [] + projects = gl.projects.list(all=True) + for project in projects: + commits = project.commits.list(since=last_month_start) + if len(commits) == 0: + projects_with_no_activity.append(project.name) + + return projects_with_no_activity + +def get_gitlab_version(): + # Run 'gitlab-ctl' command to get GitLab version + result = subprocess.run(['gitlab-ctl', 'version'], capture_output=True, text=True) + + # Extract GitLab version from the output + gitlab_version = result.stdout.strip() + + return gitlab_version + +def get_gitlab_info(): + # Replace 'YOUR_GITLAB_URL' and 'YOUR_PRIVATE_TOKEN' with your GitLab URL and private token + + gl = gitlab.Gitlab(gitlab_url, private_token) + gl.auth() + + # Get the number of projects + projects = gl.projects.list() + num_projects = len(projects) + + # Get the number of users + users = gl.users.list(all=True) + num_users = len(users) + + # Get a list of admin users + admin_users = [user for user in users if user.is_admin] + admin_users_list = [user.name for user in admin_users] + + # Get free space on disk + free_space_on_disk = get_disk_space() + + # Get the total commits last month + total_commits_last_month = get_total_commits_last_month(gl) + + # Get projects with no activity + projects_with_no_activity = get_projects_with_no_activity(gl) + + # Get GitLab version + gitlab_version = get_gitlab_version() + + return num_projects, num_users, admin_users_list, free_space_on_disk, total_commits_last_month, projects_with_no_activity, gitlab_version + +def send_email(sender_email, sender_password, recipient_email, subject, body): + # Create the email body in HTML format + msg = MIMEMultipart('alternative') + msg['From'] = sender_email + msg['To'] = recipient_email + msg['Subject'] = subject + + # Create a nice HTML table for the report + html_table = f''' + <html> + <head></head> + <body> + <h2>Monthly GitLab Report - {datetime.datetime.now().strftime('%B %Y')}</h2> + <table border="1" cellpadding="5" style="border-collapse: collapse; width: 50%;"> + <tr> + <th>Metrics</th> + <th>Values</th> + </tr> + <tr> + <td>Number of Projects</td> + <td>{body['num_projects']}</td> + </tr> + <tr> + <td>Number of Users</td> + <td>{body['num_users']}</td> + </tr> + <tr> + <td>List of Admin Users</td> + <td> + <ul> + {"".join(f"<li>{admin_user}</li>" for admin_user in body['admin_users_list'])} + </ul> + </td> + </tr> + <tr> + <td>Free Space on Disk</td> + <td>{body['free_space_on_disk']}</td> + </tr> + </table> + </body> + </html> + ''' + + # Attach the HTML content to the email + msg.attach(MIMEText(html_table, 'html')) + + # Send the email + server = smtplib.SMTP('smtp.gmail.com', 587) + server.starttls() + server.login(sender_email, sender_password) + server.sendmail(sender_email, recipient_email, msg.as_string()) + server.quit() + +def create_blog_post(confluence_url, api_token, blog_post_content): + headers = { + "Authorization": f"Bearer {api_token}", + "Content-Type": "application/json" + } + + blog_post_content = { + "type": "blogpost", + "title": "Monthly GitLab Report", + "space": { + "key": "SPACE_KEY" # Replace with the key of the space where you want to create the blog post + }, + "body": { + "storage": { + "value": "<h2>Monthly GitLab Report</h2><p>This is your blog post content in HTML format.</p>", + "representation": "storage" + } + } + } + + + # Make a POST request to create the blog post + response = requests.post( + f"{confluence_url}/rest/api/content", + headers=headers, + json=blog_post_content + ) + + if response.status_code == 200: + print("Blog post created successfully!") + return response.json().get("id") + else: + print("Failed to create the blog post.") + print(f"Status code: {response.status_code}") + print(f"Response: {response.text}") + return None + +# Check if required binaries are available +check_binaries() + +api_token = load_api_token() + + +subject = 'Monthly GitLab Report - {month} {year}'.format(month=datetime.datetime.now().strftime('%B'), year=datetime.datetime.now().strftime('%Y')) + +# Get GitLab information +num_projects, num_users, admin_users_list, free_space_on_disk = get_gitlab_info() + +# Compose the email body as a dictionary +email_body = { + 'num_projects': num_projects, + 'num_users': num_users, + 'admin_users_list': admin_users_list, + 'free_space_on_disk': free_space_on_disk, + 'total_commits_last_month': total_commits_last_month, + 'projects_with_no_activity': projects_with_no_activity, + 'gitlab_version': gitlab_version +} + +# Send the email +send_email(sender_email, sender_password, recipient_email, subject, email_body) + +# create blog post +blog_post_id = create_blog_post(confluence_url, api_token, email_body) \ No newline at end of file