# Author: Pranav Sastry [Copyright (c) 2021] # Created: 8th Feb 2021 # Disclaimer: File contents shouldn't be copied into another repository without prior permission by emailing to pranava.sri@gmail.com, # however to fork the repository, you needn't take any class GitIt: ''' Methods: __init__ - Constructor for GitIt class search_file - Search for a file recursively in GitHub Repository based on the content in the base_url create_repo - Create a new Repository with minimal readme and mit license_template delete_repo - Delete a Repository delete_file - Delete a file search_dir - Search for a directory recursively in GitHub Repository based on the content in the base_url delete_dir - Delete a directory and its contents recursively update_file - Upload a local file on your computer to GitHub update_dir - Update a local directory on your computer to GitHub ''' # Imports TODO: Modify the path in sys.path.append based on your system's python package location import sys sys.path.append("/opt/anaconda3/lib/python3.7/site-packages/") import base64 as b64 import os import requests import json def __init__(self): ''' TODO: Set environment variables on your system that contains your GitHub Username and GitHub Token Parameters: None Returns: None ''' self.owner = GitIt.os.getenv('GITHUB_USERNAME') self.token = GitIt.os.getenv('GITHUB_TOKEN') self.headers = {"Authorization": "token {}".format(self.token),"Accept":"application/vnd.github.v3+json"} def search_file(self,base_url,fname): ''' Parameters: base_url (string): GitHub API URL in which to search for a file fname (string): Name of the file to be searched Returns: flag (boolean): True if file is found, else False path (string): path of file if found, else None sha (string): sha of file if found, else None ''' repo_contents = GitIt.requests.get(base_url,headers=self.headers).json() flag = False path = None sha = None for content in repo_contents: try: if(content["type"]=="file"): if(content["name"]==fname): flag = True path = content["path"] sha = content["sha"] break else: url = base_url+"/{}".format(content["name"]) flag,path,sha = self.search_file(url,fname) if(flag): break except: pass return flag,path,sha def create_repo(self,name,license="mit",is_private=None): ''' Parameters: name (string): Name of the new repo license (string): License Template of the new repo. Default - mit is_private (string): false if the new repo is Public, else the new repo is Private Default - None Returns: None ''' print("Creating Repo...") url = "https://api.github.com/user/repos" if(is_private=="false"): params = {"name":name,"auto_init":True,"license_template":license,"private":False} else: params = {"name":name,"auto_init":True,"license_template":license,"private":True} r = GitIt.requests.post(url,headers=self.headers,data=GitIt.json.dumps(params)) print(r.text) def delete_repo(self,repo): ''' Parameters: repo (string): Name of the repo to be deleted Returns: None ''' print("Deleting Repo...") url = "https://api.github.com/repos/{}/{}".format(self.owner,repo) r = GitIt.requests.delete(url,headers=self.headers) print(r.text) def delete_file(self,repo,fname,filepath_gh=None): ''' Parameters: repo (string): Name of the Repository fname (string): Name of the file to be deleted filepath_gh (string): Path of the file on GitHub. Default - None Returns: None ''' print("Deleting file...") if(filepath_gh is None): _,path,sha = self.search_file("https://api.github.com/repos/{}/{}/contents".format(self.owner,repo),fname=fname) url = "https://api.github.com/repos/{}/{}/contents/{}".format(self.owner,repo,path) else: url = "https://api.github.com/repos/{}/{}/contents/{}".format(self.owner,repo,filepath_gh) file_contents = GitIt.requests.get(url,headers=self.headers).json() sha = file_contents["sha"] params = {"message":"Deleted {}".format(fname),"sha":sha} r = GitIt.requests.delete(url,headers=self.headers,data=GitIt.json.dumps(params)) print(r.text) def search_dir(self,base_url,dir_name): ''' Parameters: base_url (string): GitHub API URL in which to search for a directory dir_name (string): Name of the Directory to be searched for Returns: flag (boolean): True if directory is found, else False path (string): Path of the directory if found, else None ''' flag = False path = None repo_contents = GitIt.requests.get(base_url,headers=self.headers).json() for content in repo_contents: try: if(content["type"]=="dir"): if(content["name"]==dir_name): flag = True path = content["path"] break else: url = base_url+"/{}".format(content["name"]) flag,path = self.search_dir(url,dir_name) if(flag): break except: pass return flag,path def delete_dir(self,repo,dir_name,dir_path=None): ''' Parameters: repo (string): Name of the Repository dir_name (string): Name of the directory to be deleted dir_path (string): Path of the directory to be deleted. Default - None Returns: None ''' try: print("Deleting directory...") if(dir_path is None): _,path = self.search_dir(base_url="https://api.github.com/repos/{}/{}/contents".format(self.owner,repo),dir_name=dir_name) url = "https://api.github.com/repos/{}/{}/contents/{}".format(self.owner,repo,path) else: url = "https://api.github.com/repos/{}/{}/contents/{}".format(self.owner,repo,dir_path) repo_contents = GitIt.requests.get(url,headers=self.headers).json() for content in repo_contents: if(content["type"]=="file"): self.delete_file(repo,fname=content["name"],filepath_gh=content["path"]) else: self.delete_dir(repo,content["name"],dir_path=content["path"]) except: print("Directory unavailable!") def update_file(self,repo,filepath_local,message="",filepath_gh=None): ''' Parameters: repo (string): Name of the Repository filepath_local (string): Path of the file on your local computer message (string): Commit message. Default - "", if Default, then when file is created, "Added filename.py" will be default and if updated "Updated filename.py" will be the default commit messages filepath_gh (string): Path of the file on GitHub, default - None Returns: None ''' file_b64 = GitIt.b64.b64encode(open(filepath_local,"rb").read()).decode("ascii") fname = filepath_local.split("/")[-1] if(filepath_gh is not None): url = "https://api.github.com/repos/{}/{}/contents/{}".format(self.owner,repo,filepath_gh) sha = None url_contents = GitIt.requests.get(url,headers=self.headers).json() try: sha = url_contents["sha"] path = url_contents["path"] except: pass if(sha is None): print("File not present! Creating file...") if(message==""): message = "Added {}".format(fname) params = {"message":message,"content":file_b64,"path":filepath_gh} else: print("File already present! Updating file...") if(message==""): message = "Updated {}".format(fname) params = {"message":message,"content":file_b64,"path":path,"sha":sha} else: _,path,sha = self.search_file("https://api.github.com/repos/{}/{}/contents".format(self.owner,repo),fname=fname) if(sha is None): url = "https://api.github.com/repos/{}/{}/contents/{}".format(self.owner,repo,fname) print("File not present! Creating file...") if(message==""): message = "Added {}".format(fname) params = {"message":message,"content":file_b64,"path":fname} else: url = "https://api.github.com/repos/{}/{}/contents/{}".format(self.owner,repo,path) print("File already present! Updating file...") if(message==""): message = "Updated {}".format(fname) params = {"message":message,"content":file_b64,"path":path,"sha":sha} r = GitIt.requests.put(url,headers=self.headers,data=GitIt.json.dumps(params)) print(r.text) def update_dir(self,repo,base_path,dirpath_local,dirpath_gh=None): ''' Parameters: repo (string): Name of the Repository base_path (string): Path of the directory on your computer dirpath_local (string): Path of the directory on your computer dirpath_gh (string): Path of the direcory on GitHub to be updated Returns: None ''' print("Updating directory...") print(dirpath_local) dir_contents = GitIt.os.listdir(dirpath_local) dir_name = dirpath_local.split("/")[-1] for content in dir_contents: temp_path = "{}/{}".format(dirpath_local,content) dir_tree = temp_path.replace("{}/".format(base_path),"") if(dirpath_gh is not None): dir_tree = "{}/".format(dirpath_gh) + dir_tree # print(dir_tree) if(GitIt.os.path.isdir(temp_path)): self.update_dir(repo,base_path,temp_path,dirpath_gh) else: self.update_file(repo,temp_path,"",dir_tree) # Example code # gitit = GitIt() # flag,path,sha = gitit.search_file(base_url="https://api.github.com/repos/pranavsastry/neowise/contents",fname="profiles_settings.xml") # gitit.update_file("stargar","Hello World! This is test!","/Users/pranavsastry/Documents/CP/DivideIt.java","test/DivideIt.java") # gitit.delete_file("stargar","test") # gitit.create_repo("hello") # gitit.delete_repo("hello") # flag,path = gitit.search_dir(base_url="https://api.github.com/repos/pranavsastry/neowise/contents",dir_name="Visuals") # print(flag) # print(path) # gitit.update_file("stargar","Yahoo! New Commit","/Users/pranavsastry/Documents/CP/KDivisibleSum.java","test/hello/hello_again/KDivisibleSum.java") # gitit.delete_dir("stargar","test") # gitit.update_dir("testing","/Users/pranavsastry/Documents/javaFiles","/Users/pranavsastry/Documents/javaFiles")