Update main.py

This commit is contained in:
Richard Mwewa
2022-04-14 11:09:43 +02:00
committed by GitHub
parent 82a95d84b0
commit b4f009c7d4

View File

@@ -22,10 +22,32 @@ from tqdm import tqdm
from pprint import pprint
from lib.banner import banner
from datetime import datetime
from lib.colors import red, white, green, reset
from lib.colors import red, white, green, green_bg, white_bg, red_bg, reset
class octosuite:
def __init__(self):
# A list of tuples, mapping commands to their respective functionalities
self.commands_base = [('info:org', self.org_info),
('info:user', self.user_profile),
('info:repo', self.repo_info),
('path:contents', self.path_contents),
('repos:org', self.org_repos),
('repos:user', self.user_repos),
('user:gists', self.user_gists),
('user:followers', self.followers),
('user:following', self.following),
('search:users', self.user_search),
('search:repos', self.repo_search),
('search:topics', self.topic_search),
('search:issues', self.issue_search),
('search:commits', self.commits_search),
('update', self.update),
('changelog', self.changelog),
('info:dev', self.author),
('help', self.help),
('exit', self.exit_session)]
# Path attribute
self.path_attrs =['size','type','path','sha','html_url']
# Path attribute dictionary
@@ -35,6 +57,7 @@ class octosuite:
'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
@@ -57,6 +80,8 @@ class octosuite:
'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
@@ -88,6 +113,7 @@ class octosuite:
'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
@@ -109,6 +135,7 @@ class octosuite:
'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
@@ -119,6 +146,7 @@ class octosuite:
'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']
@@ -130,6 +158,7 @@ class octosuite:
'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']
@@ -143,6 +172,7 @@ class octosuite:
'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
@@ -162,75 +192,44 @@ class octosuite:
'created_at': 'Created at',
'body': 'Body'}
# Author dictionary
self.author_dict = {'Alias': 'rly0nheart',
'Country': 'Zambia, Africa',
'About.me': 'https://about.me/rly0nheart'}
def on_start(self):
# Start new session
logging.info(f'Started new session on {platform.node()}:{os.getlogin()}')
# Use 'cls' to clear screen on Windows based machines
# Otherwise, use 'clear'
while True:
if platform.system() == 'Windows':
subprocess.run(['cls'])
if platform.system().lower().startswith(('win','darwin')):
subprocess.run(['cls'])
else:
subprocess.run(['clear'],shell=False)
print(banner)
command = input(f'''{white}┌─({red}{os.getlogin()}{white}@{red}octosuite{white})-[{green}{os.getcwd()}{white}]\n└─╼[{green}:~{white}]{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 == 'changelog':
print(self.changelog())
elif command == 'author':
self.author()
elif command == 'ilinso':
self.easter_egg()
elif command == 'help':
print(self.help())
elif command == 'exit':
logging.info('Session terminated with \'exit\' command')
exit(f'\n{white}[{red}-{white}] Session terminated with \'exit\' command{reset}')
else:
print(f'\n{white}[{red}!{white}] Command not found: {command}{reset}')
logging.warning(f'command not found: {command}')
input(f'\n{white}[{green}?{white}] Press any key to continue{reset} ')
command_input = input(f'''{white}┌───({red}{os.getlogin()}{white}@{red}octosuite{white})-[{green}{os.getcwd()}{white}]\n└─╼[{green}:~{white}]{reset} ''')
# Looping through the commands base to check if the user input command matches any command in the commands base, and return its functionality
# If no match is found, we ignore it
for command, functionality in self.commands_base:
if command == command_input:
functionality()
else:
pass
input(f'\n{white}[{green} ? {white}] Press {white_bg}any key{reset}{white} to continue{reset} ')
def org_info(self):
organization = input(f'{white}@{green}Organization {white}>>{reset} ')
organization = input(f'\n{white}[{white_bg}@Organization{reset}{white}] (username){reset} ')
api = f'https://api.github.com/orgs/{organization}'
response = requests.get(api)
if response.status_code != 200:
print(f'\n{white}[{red}-{white}] Organization @{organization} {red}Not Found{reset}')
print(f'\n{white}[{red}-{white}] Organization @{organization} {red_bg}Not Found{reset}')
else:
response = response.json()
print(f"\n{white}{response['name']}{reset}")
@@ -240,11 +239,11 @@ class octosuite:
# Fetching user information
def user_profile(self):
username = input(f'{white}@{green}Username{white} >> {reset}')
username = input(f'\n{white}[{white_bg}@Username{reset}{white}]{reset} ')
api = f'https://api.github.com/users/{username}'
response = requests.get(api)
if response.status_code != 200:
print(f'\n{white}[{red}-{white}] User @{username} {red}Not Found{reset}')
print(f'\n{white}[{red} - {white}] User @{username} {red_bg}Not Found{reset}')
else:
response = response.json()
print(f"\n{white}{response['name']}{reset}")
@@ -254,12 +253,12 @@ class octosuite:
# Fetching repository information
def repo_info(self):
username = input(f'{white}@{green}Owner-username{white} >> {reset}')
repo_name = input(f'{white}%{green}reponame{white} >> {reset}')
repo_name = input(f'\n{white}[{white_bg}%reponame{reset}{white}]{reset} ')
username = input(f'{white}[{white_bg}@Owner{reset}{white}] (username){reset} ')
api = f'https://api.github.com/repos/{username}/{repo_name}'
response = requests.get(api)
if response.status_code != 200:
print(f'\n{white}[{red}-{white}] Repository %{repo_name} {red}Not Found{reset}')
print(f'\n{white}[{red} - {white}] Repository %{repo_name} or user @{username} {red_bg}Not Found{reset}')
else:
response = response.json()
print(f"\n{white}{response['full_name']}{reset}")
@@ -269,13 +268,13 @@ class octosuite:
# Get path contents
def path_contents(self):
username = input(f'{white}@{green}Owner-username{white} >> {reset}')
repo_name = input(f'{white}%{green}reponame{white} >> {reset}')
path_name = input(f'{white}/path/name >>{reset} ')
username = input(f'\n{white}[{white_bg}@Owner{reset}{white}] (username){reset} ')
repo_name = input(f'{white}[{white_bg}%reponame{reset}{white}]{reset} ')
path_name = input(f'{white}[{white_bg}/path/name{reset}{white}]{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'\n{white}[{red}-{white}] Information {red}Not Found{reset}')
print(f'\n{white}[{red} - {white}] Information {red_bg}Not Found{reset}')
else:
response = response.json()
for item in response:
@@ -286,11 +285,11 @@ class octosuite:
# Fetching organozation repositories
def org_repos(self):
organization = input(f'{white}@{green}Organization{white} >> {reset}')
organization = input(f'\n{white}[{white_bg}@Organization{reset}{white}] (username){reset} ')
api = f'https://api.github.com/orgs/{organization}/repos?per_page=100'
response = requests.get(api)
if response.status_code != 200:
print(f'\n{white}[{red}-{white}] Organization @{organization} {red}Not Found{reset}')
print(f'\n{white}[{red} - {white}] Organization @{organization} {red_bg}Not Found{reset}')
else:
response = response.json()
for repo in response:
@@ -302,11 +301,11 @@ class octosuite:
# Fetching user repositories
def user_repos(self):
username = input(f'{white}@{green}Username{white} >> {reset}')
username = input(f'\n{white}[{white_bg}@Username{reset}{white}]{reset} ')
api = f'https://api.github.com/users/{username}/repos?per_page=100'
response = requests.get(api)
if response.status_code != 200:
print(f'\n{white}[{red}-{white}] User @{username} {red}Not Found{reset}')
print(f'\n{white}[{red} - {white}] User @{username} {red_bg}Not Found{reset}')
else:
response = response.json()
for repo in response:
@@ -318,11 +317,13 @@ class octosuite:
# Fetching user's gists
def user_gists(self):
username = input(f'{white}@{green}Username{white} >> {reset}')
username = input(f'\n{white}[{white_bg}@Username{reset}{white}]{reset} ')
api = f'https://api.github.com/users/{username}/gists'
response = requests.get(api).json()
if response == []:
print(f'{white}[{red}-{white}]User @{username} does not have any active gists.{reset}')
print(f'\n{white}[{red} - {white}] User @{username} {red_bg}does not{reset}{white} have any active gists.{reset}')
elif "Not Found" in response['message']:
print(f'\n{white}[{red} - {white}] User @{username} {red_bg}Not Found{reset}')
else:
for item in response:
print(f"\n{white}{item['id']}{reset}")
@@ -333,11 +334,13 @@ class octosuite:
# Fetching user's followera'
def followers(self):
username = input(f'{white}@{green}Username{white} >> {reset}')
username = input(f'\n{white}[{white_bg}@Username{reset}{white}]{reset} ')
api = f'https://api.github.com/users/{username}/followers?per_page=100'
response = requests.get(api).json()
if response == []:
print(f'\n{white}[{red}-{white}]User @{username} does not have followers.{reset}')
print(f'\n{white}[{red} - {white}]User @{username} {red_bg}does not{reset}{white} have followers.{reset}')
elif "Not Found" in response['message']:
print(f'\n{white}[{red} - {white}] User @{username} {red_bg}Not Found{reset}')
else:
for item in response:
print(f"\n{white}@{item['login']}{reset}")
@@ -348,19 +351,19 @@ class octosuite:
# Checking whether or not user[A] follows user[B]
def following(self):
user_a = input(f'{white}@{green}User[A]{white} >> {reset}')
user_b = input(f'{white}@{green}User[B]{white} >> {reset}')
user_a = input(f'\n{white}[{white_bg}@User A{reset}{white}] (username){reset} ')
user_b = input(f'{white}[{white_bg}@User B{reset}{white}] (username){reset} ')
api = f'https://api.github.com/users/{user_a}/following/{user_b}'
response = requests.get(api)
if response.status_code == 204:
print(f'{white}[{green}+{white}] @{user_a} follows @{user_b}.{reset}')
print(f'\n{white}[{green} + {white}] @{user_a} {green_bg}follows{reset}{white} @{user_b}.{reset}')
else:
print(f'{white}[{red}-{white}] @{user_a} does not follow @{user_b}.{reset}')
print(f'\n{white}[{red} - {white}] @{user_a} {red_bg}does not{reset}{white} follow @{user_b}.{reset}')
# User search
def user_search(self):
query = input(f'{white}#{green}Query{white} >> {reset}')
query = input(f'\n{white}[{white_bg}#@Query{reset}{white}]{reset} ')
api = f'https://api.github.com/search/users?q={query}&per_page=100'
response = requests.get(api).json()
for item in response['items']:
@@ -372,7 +375,7 @@ class octosuite:
# Repository search
def repo_search(self):
query = input(f'{white}#{green}Query{white} >> {reset}')
query = input(f'\n{white}[{white_bg}#%Query{reset}{white}]{reset} ')
api = f'https://api.github.com/search/repositories?q={query}&per_page=100'
response = requests.get(api).json()
for item in response['items']:
@@ -384,7 +387,7 @@ class octosuite:
# Topics search
def topic_search(self):
query = input(f'{white}#{green}Query{white} >> {reset}')
query = input(f'\n{white}[{white_bg}##Query{reset}{white}]{reset} ')
api = f'https://api.github.com/search/topics?q={query}&per_page=100'
response = requests.get(api).json()
for item in response['items']:
@@ -396,7 +399,7 @@ class octosuite:
# Issue search
def issue_search(self):
query = input(f'{white}#{green}Query{white} >> {reset}')
query = input(f'\n{white}[{white_bg}#!Query{reset}{white}]{reset} ')
api = f'https://api.github.com/search/issues?q={query}&per_page=100'
response = requests.get(api).json()
for item in response['items']:
@@ -408,53 +411,45 @@ class octosuite:
# Commits search
def commits_search(self):
query = input(f'{white}#{green}Query{white} >> {reset}')
query = input(f'\n{white}[{white_bg}#:Query{reset}{white}]{reset} ')
api = f'https://api.github.com/search/commits?q={query}&per_page=100'
response = requests.get(api).json()
n=0
number=0
for item in response['items']:
n+=1
print(f'{white}{n}.{reset}')
number+=1
print(f'{white}{number}.{reset}')
pprint(item['commit'])
print('\n')
# Update program
def update(self):
logging.info('Fetching updates...')
files_to_update = ['src/main.py','lib/banner.py','lib/colors.py','octosuite','.github/dependabot.yml','LICENSE','README.md','requirements.txt']
for file in tqdm(files_to_update,desc=f'{white}[{green}*{white}] Updating{reset}'):
logging.info('Updating...')
files_to_update = ['src/main.py','lib/banner.py','lib/colors.py','octosuite','.github/dependabot.yml','.github/ISSUE_TEMPLATE/bug_report.md','.github/ISSUE_TEMPLATE/feature_request.md','.github/ISSUE_TEMPLATE/config.yml','LICENSE','README.md','requirements.txt']
for file in tqdm(files_to_update,desc=f'{white}[{green} * {white}] Updating{reset}'):
data = requests.get(f'https://raw.githubusercontent.com/rly0nheart/octosuite/master/{file}')
with open(file, 'wb') as code:
code.write(data.content)
code.close()
logging.info('Update complete.')
exit(f'{white}[{green}+{white}] Updated successfully. Re-run octosuite.{reset}')
def easter_egg(self):
print(f'\n{white}[{green}*{white}] Downloading. Please wait...{reset}')
file = requests.get('https://drive.google.com/uc?export=download&id=1IRu4kWSuNpYWH8hZkqQ8mLnv4sSDu-GN')
with open('EasterEgg.zip','wb') as f:
f.write(file.content)
exit(f'{white}[{green}+{white}] Downloaded (EasterEgg.zip).\n{white}[{green}!{white}] The password is: {green}horus{white}\n[{green}!{white}] Happy hunting! :).{reset}')
exit(f'{white}[{green} + {white}] {green_bg}Updated{reset}{white} successfully. Re-run octosuite.{reset}')
# Show changelog
def changelog(self):
# lol yes the changelog is hard coded
changelog_text = '''
v1.5.1-beta CHANGELOG:
• First pypi package release
• Termux users will now have to manually create the .logs folder
• Changed logs date/time format
• Removed 1 internal dependency
• There's an easter egg somewhere in here ;) (use the command 'ilinso')
'''
return changelog_text
changelog_text = f'''
{red_bg}v1.5.2-alpha [CHANGELOG]{reset}
• Users will now get to choose whether to enable colors or not
• Cleaned code
• Improved perfomance
• Will be ignoring unknown commands instead of printing the error
• Major bug fixes
{red_bg} {reset}
'''
print(changelog_text)
# Author info
@@ -464,46 +459,51 @@ class octosuite:
print(f'{white}├─ {key}: {green}{value}{reset}')
def exit_session(self):
logging.info('Session closed with \'exit\' command.')
exit(f'\n{white}[{green} ! {white}] Session closed with {white_bg}exit{reset}{white} command.{reset}')
def help(self):
help = f'''
help:
{white}Command Descritption
------------ ---------------------------------------------------------
{green}orginfo{white} --> Get target organization info{reset}
{green}userinfo{white} --> Get target user profile info{reset}
{green}repoinfo{white} --> Get target repository info{reset}
{green}pathcontents{white} --> Get contents of a specified path from a target repository{reset}
{green}orgrepos{white} --> Get a list of repositories owned by a target organization{reset}
{green}userrepos{white} --> Get a list of repositories owned by a target user{reset}
{green}usergists{white} --> Get a list of gists owned by a target user{reset}
{green}userfollowers{white} --> Get a list of the target's followers{reset}
{green}userfollowing{white} --> Check whether or not User[A] follows User[B]{reset}
{green}usersearch{white} --> Search user(s){reset}
{green}reposearch{white} --> Search repositor[y][ies]{reset}
{green}topicsearch{white} --> Search topic(s){reset}
{green}issuesearch{white} --> Search issue(s){reset}
{green}commitsearch{white} --> Search commit(s){reset}
{green}update{white} --> Update octosuite{reset}
{green}changelog{white} --> Show changelog{reset}
{green}author{white} --> Show author info{reset}
{green}help{white} --> Show usage/help{reset}
{green}exit{white} --> Exit session{reset}
{white}------------ ---------------------------------------------------------{reset}
{red_bg}[COMMAND] [DESCRIPTION] {reset}
info:org Get target organization info
info:user Get target user profile info
info:repo Get target repository info
info:dev Show developer's info
path:contents Get contents of a specified path from a target repository
repos:org Get a list of repositories owned by a target organization
repos:user Get a list of repositories owned by a target user
user:gists Get a list of gists owned by a target user
user:followers Get a list of the target's followers
user:following Check whether or not User[A] follows User[B]
search:users Search user(s)
search:repos Search repositor[y][ies]
search:topics Search topic(s)
search:issues Search issue(s)
search:commits Search commit(s)
update Update octosuite
changelog Show changelog
help Show usage/help
exit Exit session
{red_bg} {reset}
'''
return help
print(help)
# If .logs folder exists, pass
if os.path.exists('.logs'):
pass
else:
# Creating the .logs directory
if platform.system() == "Windows":
# If the current system is Windows based, we run mkdir command without sudo
# Else we run the mkdir command with sudo
if platform.system().lower().startswith(('win','darwin')):
subprocess.run(['mkdir','.logs'])
else:
subprocess.run(['sudo','mkdir','.logs'],shell=False)
# Set to automatically monitor and log network and user activity into the .logs folder
logging.basicConfig(filename=f'.logs/{datetime.now()}.log',format='%(asctime)s %(message)s',datefmt='%Y-%m-%d %H:%M:%S',level=logging.DEBUG)
logging.basicConfig(filename=f'.logs/{datetime.now()}.log',format='[%(asctime)s] [%(levelname)s] %(message)s',datefmt='%Y-%m-%d %H:%M:%S%p',level=logging.DEBUG)