import os import logging import platform import subprocess import urllib.request from pprint import pprint from lib import colors,banner from datetime import datetime try: import requests except ImportError: print(f'{colors.white}[{colors.green}*{colors.white}] Installing requirement(s). Please wait...{colors.reset}') subprocess.run(['pip', 'install', 'requests'],shell=False) class octosuite: def __init__(self): # Path attribute self.path_attrs =['size','type','path','sha','html_url'] # Path attribute dictionary self.path_attr_dict = {'size': 'Size (bytes)', 'type': 'Type', 'path': 'Path', 'sha': 'SHA', 'html_url': 'URL'} # Organization attributes self.org_attrs = ['avatar_url','login','id','node_id','email','description','blog','location','followers','following','twitter_username','public_gists','public_repos','type','is_verified','has_organization_projects','has_repository_projects','created_at','updated_at'] # Organization attribute dictionary self.org_attr_dict = {'avatar_url': 'Profile Photo', 'login': 'Username', 'id': 'ID#', 'node_id': 'Node ID', 'email': 'Email', 'description': 'About', 'location': 'Location', 'blog': 'Blog', 'followers': 'Followers', 'following': 'Following', 'twitter_username': 'Twitter Handle', 'public_gists': 'Gists (public)', 'public_repos': 'Repositories (public)', 'type': 'Account type', 'is_verified': 'Is verified?', 'has_organization_projects': 'Has organization projects?', 'has_repository_projects': 'Has repository projects?', 'created_at': 'Created at', 'updated_at': 'Updated at'} # Repository attributes self.repo_attrs = ['id','description','forks','allow_forking','fork','stargazers_count','watchers','license','default_branch','visibility','language','open_issues','topics','homepage','clone_url','ssh_url','private','archived','has_downloads','has_issues','has_pages','has_projects','has_wiki','pushed_at','created_at','updated_at'] # Repository attribute dictionary self.repo_attr_dict = {'id': 'ID#', 'description': 'About', 'forks': 'Forks', 'allow_forking': 'Is forkable?', 'fork': 'Is fork?', 'stargazers_count': 'Stars', 'watchers': 'Watchers', 'license': 'License', 'default_branch': 'Branch', 'visibility': 'Visibility', 'language': 'Language(s)', 'open_issues': 'Open issues', 'topics': 'Topics', 'homepage': 'Homepage', 'clone_url': 'Clone URL', 'ssh_url': 'SSH URL', 'private': 'Is private?', 'archived': 'Is archived?', 'is_template': 'Is template?', 'has_wiki': 'Has wiki?', 'has_pages': 'Has pages?', 'has_projects': 'Has projects?', 'has_issues': 'Has issues?', 'has_downloads': 'Has downloads?', 'pushed_at': 'Pushed at', 'created_at': 'Created at', 'updated_at': 'Updated at'} # Profile attributes self.profile_attrs = ['avatar_url','login','id','node_id','bio','blog','location','followers','following','twitter_username','public_gists','public_repos','company','hireable','site_admin','created_at','updated_at'] # Profile attribute dictionary self.profile_attr_dict = {'avatar_url': 'Profile Photo', 'login': 'Username', 'id': 'ID#', 'node_id': 'Node ID', 'bio': 'Bio', 'blog': 'Blog', 'location': 'Location', 'followers': 'Followers', 'following': 'Following', 'twitter_username': 'Twitter Handle', 'public_gists': 'Gists (public)', 'public_repos': 'Repositories (public)', 'company': 'Organization', 'hireable': 'Is hireable?', 'site_admin': 'Is site admin?', 'created_at': 'Joined at', 'updated_at': 'Updated at'} # User attributes self.user_attrs = ['avatar_url','id','node_id','gravatar_id','site_admin','type','html_url'] # User attribute dictionary self.user_attr_dict = {'avatar_url': 'Profile Photo', 'id': 'ID#', 'node_id': 'Node ID', 'gravatar_id': 'Gravatar ID', 'site_admin': 'Is site admin?', 'type': 'Account type', 'html_url': 'URL'} # Topic atrributes self.topic_attrs = ['score','curated','featured','display_name','created_by','created_at','updated_at'] # Topic attribute dictionary self.topic_attr_dict = {'score': 'Score', 'curated': 'Curated', 'featured': 'Featured', 'display_name': 'Display Name', 'created_by': 'Created by', 'created_at': 'Created at', 'updated_at': 'Updated at'} # Gists attributes self.gists_attrs = ['node_id','description','comments','files','git_push_url','public','truncated','updated_at'] # Gists attribute dictionary self.gists_attr_dict = {'node_id': 'Node ID', 'description': 'About', 'comments': 'Comments', 'files': 'Files', 'git_push_url': 'Git Push URL', 'public': 'Is public?', 'truncated': 'Is truncated?', 'updated_at': 'Updated at'} # Issue attributes self.issue_attrs = ['id','node_id','score','state','number','comments','milestone','assignee','assignees','labels','locked','draft','closed_at','body'] # Issue attribute dict self.issue_attr_dict = {'id': 'ID#', 'node_id': 'Node ID', 'score': 'Score', 'state': 'State', 'closed_at': 'Closed at', 'number': 'Number', 'comments': 'Comments', 'milestone': 'Milestone', 'assignee': 'Assignee', 'assignees': 'Assignees', 'labels': 'Labels', 'draft': 'Is draft?', 'locked': 'Is locked?', 'created_at': 'Created at', 'body': 'Body'} # Author dictionary self.author_dict = {'Alias': 'rly0nheart', 'Country': 'Zambia, Africa', 'Github': 'https://github.com/rly0nheart', 'Twitter': 'https://twitter.com/rly0nheart', 'Facebook': 'https://fb.me/rly0nheart', 'About.me': 'https://about.me/rly0nheart'} def on_start(self): logging.info(f'Started new session on {platform.node()}') while True: if platform.system() == 'Windows': subprocess.run(['cls']) else: subprocess.run(['clear'],shell=False) print(banner.banner) command = input(f'''{colors.white}┌─({colors.red}{platform.node()}{colors.white}@{colors.red}octosuite{colors.white})-[{colors.green}{os.getcwd()}{colors.white}]\n└─╼[{colors.green}:~{colors.white}]{colors.reset} ''') if command == 'orginfo': self.org_info() elif command == 'userinfo': self.user_profile() elif command == 'repoinfo': self.repo_info() elif command == 'pathcontents': self.path_contents() elif command == 'orgrepos': self.org_repos() elif command == 'userrepos': self.user_repos() elif command == 'usergists': self.user_gists() elif command == 'userfollowers': self.followers() elif command == 'userfollowing': self.following() elif command == 'usersearch': self.user_search() elif command == 'reposearch': self.repo_search() elif command == 'topicsearch': self.topic_search() elif command == 'issuesearch': self.issue_search() elif command == 'commitsearch': self.commits_search() elif command == 'update': self.update() elif command == 'author': self.author() elif command == 'help': print(self.help()) elif command == 'exit': logging.info('Session terminated.') exit(f'\n{colors.white}[{colors.red}-{colors.white}] Session terminated.{colors.reset}') else: print(f'\n{colors.white}[{colors.red}!{colors.white}] Unknown command: ‘{command}’{colors.reset}') logging.warning(f'Unknown command: ‘{command}’') input(f'\n{colors.white}^ Press any key to continue{colors.reset} ') def org_info(self): organization = input(f'{colors.white}@{colors.green}Organization{colors.white} >> {colors.reset}') api = f'https://api.github.com/orgs/{organization}' response = requests.get(api).json() print(f"\n{colors.white}{response['name']}{colors.reset}") for attr in self.org_attrs: print(f'{colors.white}├─ {self.org_attr_dict[attr]}: {colors.green}{response[attr]}{colors.reset}') # Fetching user information def user_profile(self): username = input(f'{colors.white}@{colors.green}Username{colors.white} >> {colors.reset}') api = f'https://api.github.com/users/{username}' response = requests.get(api) if response.status_code != 200: print(f'{colors.white}[{colors.red}-{colors.white}] @{username} {colors.red}Not found{colors.reset}') response = response.json() print(f"\n{colors.white}{response['name']}{colors.reset}") for attr in self.profile_attrs: print(f'{colors.white}├─ {self.profile_attr_dict[attr]}: {colors.green}{response[attr]}{colors.reset}') # Fetching repository information def repo_info(self): username = input(f'{colors.white}@{colors.green}Owner-username{colors.white} >> {colors.reset}') repo_name = input(f'{colors.white}%{colors.green}reponame{colors.white} >> {colors.reset}') api = f'https://api.github.com/repos/{username}/{repo_name}' response = requests.get(api).json() print(f"\n{colors.white}{response['full_name']}{colors.reset}") for attr in self.repo_attrs: print(f"{colors.white}├─ {self.repo_attr_dict[attr]}: {colors.green}{response[attr]}{colors.reset}") # Get path contents def path_contents(self): username = input(f'{colors.white}@{colors.green}Owner-username{colors.white} >> {colors.reset}') repo_name = input(f'{colors.white}%{colors.green}reponame{colors.white} >> {colors.reset}') path_name = input(f'{colors.white}/path/name >>{colors.reset} ') api = f'https://api.github.com/repos/{username}/{repo_name}/contents/{path_name}' response = requests.get(api) if response.status_code != 200: print(f'{colors.white}[{colors.red}-{colors.white}] [Repo/User] not found.{colors.reset}') response = response.json() for item in response: print(f"\n{colors.white}{item['name']}{colors.reset}") for attr in self.path_attrs: print(f'{colors.white}├─ {self.path_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}') # Fetching organozation repositories def org_repos(self): organization = input(f'{colors.white}@{colors.green}Organization{colors.white} >> {colors.reset}') api = f'https://api.github.com/orgs/{organization}/repos?per_page=100' response = requests.get(api).json() for repo in response: print(f"\n{colors.white}{repo['full_name']}{colors.reset}") for attr in self.repo_attrs: print(f"{colors.white}├─ {self.repo_attr_dict[attr]}: {colors.green}{repo[attr]}{colors.reset}") print('\n') # Fetching user repositories def user_repos(self): username = input(f'{colors.white}@{colors.green}Username{colors.white} >> {colors.reset}') api = f'https://api.github.com/users/{username}/repos?per_page=100' response = requests.get(api).json() for repo in response: print(f"\n{colors.white}{repo['full_name']}{colors.reset}") for attr in self.repo_attrs: print(f"{colors.white}├─ {self.repo_attr_dict[attr]}: {colors.green}{repo[attr]}{colors.reset}") print('\n') # Fetching user's gists def user_gists(self): username = input(f'{colors.white}@{colors.green}Username{colors.white} >> {colors.reset}') api = f'https://api.github.com/users/{username}/gists' response = requests.get(api).json() if response == []: print(f'{colors.white}[{colors.red}-{colors.white}] @{username} does not have any active gists.{colors.reset}') for item in response: print(f"\n{colors.white}{item['id']}{colors.reset}") for attr in self.gists_attrs: print(f"{colors.white}├─ {self.gists_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}") print('\n') # Fetching user's followera' def followers(self): username = input(f'{colors.white}@{colors.green}Username{colors.white} >> {colors.reset}') api = f'https://api.github.com/users/{username}/followers?per_page=100' response = requests.get(api).json() for item in response: print(f"\n{colors.white}@{item['login']}{colors.reset}") for attr in self.user_attrs: print(f"{colors.white}├─ {self.user_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}") print('\n') # Checking whether or not user[A] follows user[B] def following(self): user_a = input(f'{colors.white}@{colors.green}User[A]{colors.white} >> {colors.reset}') user_b = input(f'{colors.white}@{colors.green}User[B]{colors.white} >> {colors.reset}') api = f'https://api.github.com/users/{user_a}/following/{user_b}' response = requests.get(api) if response.status_code == 204: print(f'{colors.white}[{colors.green}+{colors.white}] @{user_a} follows @{user_b}.{colors.reset}') else: print(f'{colors.white}[{colors.red}-{colors.white}] @{user_a} does not follow @{user_b}.{colors.reset}') # User search def user_search(self): query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}') api = f'https://api.github.com/search/users?q={query}&per_page=100' response = requests.get(api).json() for item in response['items']: print(f"\n{colors.white}@{item['login']}{colors.reset}") for attr in self.user_attrs: print(f"{colors.white}├─ {self.user_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}") print('\n') # Repository search def repo_search(self): query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}') api = f'https://api.github.com/search/repositories?q={query}&per_page=100' response = requests.get(api).json() for item in response['items']: print(f"\n{colors.white}{item['full_name']}{colors.reset}") for attr in self.repo_attrs: print(f"{colors.white}├─ {self.repo_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}") print('\n') # Topics search def topic_search(self): query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}') api = f'https://api.github.com/search/topics?q={query}&per_page=100' response = requests.get(api).json() for item in response['items']: print(f"\n{colors.white}{item['name']}{colors.reset}") for attr in self.topic_attrs: print(f"{colors.white}├─ {self.topic_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}") print('\n') # Issue search def issue_search(self): query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}') api = f'https://api.github.com/search/issues?q={query}&per_page=100' response = requests.get(api).json() for item in response['items']: print(f"\n{colors.white}{item['title']}{colors.reset}") for attr in self.issue_attrs: print(f"{colors.white}├─ {self.issue_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}") print('\n') # Commits search def commits_search(self): query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}') api = f'https://api.github.com/search/commits?q={query}&per_page=100' response = requests.get(api).json() n=0 for item in response['items']: n+=1 print(f'{colors.white}{n}.{colors.reset}') pprint(item['commit']) print('\n') # Update program def update(self): logging.info('Checking for update(s)...') files_to_update = ['src/main.py','lib/banner.py','lib/colors.py','octosuite'] print(f'\n{colors.white}[{colors.green}*{colors.white}] Fetching update(s). Please wait...{colors.reset}') for file in files_to_update: data = urllib.request.urlopen(f'https://raw.githubusercontent.com/rly0nheart/octosuite/master/{file}').read() with open(file, 'wb') as code: code.write(data) code.close() logging.info('Update complete.') exit(f'{color.white}[{colors.green}+{colors.white}] Update complete. Re-run octosuite.{colors.reset}') # Author info def author(self): print(f'\n{colors.white}Richard Mwewa (Ritchie){colors.reset}') for key,value in self.author_dict.items(): print(f'{colors.white}├─ {key}: {colors.green}{value}{colors.reset}') def help(self): help = ''' usage: orginfo --> Get organization info userinfo --> Get user profile info repoinfo --> Get user repository info pathcontents --> Get contents of a specified path from a repository orgrepos --> Get organization repositories userrepos --> Get user repositories usergists --> Get user gists userfollowers --> Get user followers userfollowing --> Check whether or not User[A] follows User[B] usersearch --> Search user(s) reposearch --> Search repositor[y][ies] topicsearch --> Search topic(s) issuesearch --> Search issue(s) commitsearch --> Search commit(s) update --> Check for/download update(s) author --> Show author information help --> Show usage/help exit --> Exit session ''' return help file_exists = os.path.exists('.logs') if file_exists: pass else: os.mkdir('.logs') # Set to automatically monitor and log network and user activity to .log folder logging.basicConfig(filename=f'.logs/{datetime.now()}.log',format='[%(asctime)s] %(message)s',level=logging.DEBUG)