想当年 jsdelivr 在国内还能用的时候, GitHub 就是免费小网盘。

现在虽然国内访问不那么流畅了,但是用来存一些小的琐碎的日志文件还是不错的。

为了实现自动化,使用 Python 参考 GitHub API 文档 封装了一些常用功能。

垃圾代码,还使用 PyGithub 吧

import requests
import base64

class githubAPI:
    def __init__(self, token=None, username=None):
        self._token = token
        self._username = username
        self._headers = {
            "Accept": "application/vnd.github+json",
            "Authorization": f"Bearer {self._token}",
            "X-GitHub-Api-Version": "2022-11-28"
        }
        
        if self._username is None:
            url = "https://api.github.com/user"
            response = requests.get(url, headers=self._headers)
            if response.status_code == 200:
                user_data = response.json()
                self._username = user_data["login"]
            else:
                raise Exception("Cannot obtain username")

    def get_public_repos_name(self):
        url = f"https://api.github.com/users/{self._username}/repos"
        response = requests.get(url, headers=self._headers)
        if response.status_code == 200:
            repos = response.json()
            repo_names = [repo["name"] for repo in repos]
            return repo_names
        else:
            print(f"Failed to fetch repositories. Status code: {response.status_code}")
            return None
        
    def get_private_repos_name(self):
        url = "https://api.github.com/user/repos"
        response = requests.get(url, headers=self._headers)
        
        if response.status_code == 200:
            repos = response.json()
            private_repo_names = [repo["name"] for repo in repos if repo["private"]]
            return private_repo_names
        else:
            print(f"Failed to fetch repositories. Status code: {response.status_code}")
            return None
    
    def get_all_repos_name(self):
        url = "https://api.github.com/user/repos"
        response = requests.get(url, headers=self._headers)
        
        if response.status_code == 200:
            repos = response.json()
            repo_names = [repo["name"] for repo in repos]
            return repo_names
        else:
            print(f"Failed to fetch repositories. Status code: {response.status_code}")
            return None
    
    def create_repo(self,
                    reponame,
                    description     = '',
                    homepage        = '',
                    is_private      = False,
                    has_issues      = True,
                    has_projects    = True,
                    has_wiki        = True,
                    has_discussions = True,
                    auto_init       = False,
                    has_downloads   = True,
                    is_template     = False):
        url = "https://api.github.com/user/repos"
        data = {
            "name": reponame,
            "private": is_private,
            "description": description,
            "homepage": homepage,
            "has_issues": has_issues,
            "has_projects": has_projects,
            "has_wiki": has_wiki,
            "has_discussions": has_discussions,
            "auto_init": auto_init,
            "has_downloads": has_downloads,
            "is_template": is_template
        }
        response = requests.post(url, headers=self._headers, json=data)
        if response.status_code == 201:
            return True
        else:
            print(f"Failed to create repository '{reponame}'. Status code: {response.status_code}")
        return False
    
    def delete_repo(self,
                    reponame):
        url = f"https://api.github.com/repos/{self._username}/{reponame}"
        response = requests.delete(url=url,headers=self._headers)
        if response.status_code == 204:
            return True
        elif response.status_code == 404:
            print(f"Repository '{reponame}' not found.")
        else:
            print(f"Failed to delete repository '{reponame}'. Status code: {response.status_code}")
        return False
    
    ## 这个函数还有 Bug
    def update_repo(self,
                    reponame,
                    description = '',
                    homepage    = '',
                    is_private  = False,
                    has_issues  = True,
                    has_projects= True,
                    has_wiki    = True,
                    is_template = False,
                    default_branch = 'master',
                    archived = False,
                    allow_forking = True):
        url = f"https://api.github.com/repos/{self._username}/{reponame}"
        data = {
            "description": description,
            "homepage": homepage,
            "private": is_private,
            "has_issues": has_issues,
            "has_projects": has_projects,
            "has_wiki": has_wiki,
            "is_template": is_template,
            "default_branch": default_branch,
            "archived": archived,
            "allow_forking": allow_forking
        }
        response = requests.patch(url=url,json=data,headers=self._headers)

        if response.status_code == 200:
            return True
        elif response.status_code == 307:
            print("Temporary Redirect")
        elif response.status_code == 403:
            print("Forbidden")
        elif response.status_code == 404:
            print("Resource not found")
        elif response.status_code == 422:
            print("Validation failed, or the endpoint has been spammed.")
        else:
            print(f"Unknow: {response.status_code} {response.text}")
        return False
    
    def get_repo_activity(self,
                          reponame):
        url = f"https://api.github.com/repos/{self._username}/{reponame}/activity"
        response = requests.get(url=url,headers=self._headers)
        if response.status_code == 200:
            activities = response.json()
            return activities
        else:
            print(f"Failed to fetch repository activities. Status code: {response.status_code}")
            return None
        
    def get_user_orgs(self):
        url = "https://api.github.com/user/orgs"
        response = requests.get(url, headers=self._headers)
        
        if response.status_code == 200:
            orgs_data = response.json()
            return orgs_data
        else:
            print(f"Failed to fetch user's organizations. Status code: {response.status_code}")
            return None
        
    def create_issue(self,
                     reponame,
                     title,
                     body = '',
                     labels = ['githubAPI']):
        url = f"https://api.github.com/repos/{self._username}/{reponame}/issues"
        data = {
            "title": title,
            "body": body,
            "labels": labels
        }

        response = requests.post(url=url, json=data, headers=self._headers)
        ret_data = response.json()
        if response.status_code == 201:
            return ret_data["number"]
        else:
            print(f"Create Issue Faild {response.status_code}")
            return None
    
    def upload_file(self,
                    reponame,
                    remote_file_path,
                    local_file_path = '',
                    file_content = ''):
        url = f"https://api.github.com/repos/{self._username}/{reponame}/contents/{remote_file_path}"
        if len(local_file_path) != 0:
            with open(local_file_path, 'rb') as file:
                file_content = file.read()
        
        data = {
            "message": "Upload file by githubAPI",
            "content": base64.b64encode(file_content).decode()
        }
        headers = self._headers
        headers["Content-Type"] = "application/json"
        response = requests.put(url=url, headers=headers, json=data)
        
        if response.status_code == 201:
            return True
        else:
            print(f"Failed to upload file. Status code: {response.status_code}")
            return False
    
    def delete_file(self, reponame, remote_file_path):
        url = f"https://api.github.com/repos/{self._username}/{reponame}/contents/{remote_file_path}"
        
        response = requests.get(url, headers=self._headers)
        if response.status_code == 200:
            file_data = response.json()
            file_sha = file_data["sha"]
        else:
            print(f"Failed to get file data. Status code: {response.status_code}")
            return False
        
        data = {
            "message": "Delete by githubAPI",
            "sha": file_sha
        }
        response = requests.delete(url=url, headers=self._headers, json=data)
        
        if response.status_code == 200:
            return True
        else:
            print(f"Failed to delete file. Status code: {response.status_code}")
            return False