From 4b18c0307e92c04cddaa8b031ce13aaaf5681b51 Mon Sep 17 00:00:00 2001 From: Richard Mwewa <74001397+rly0nheart@users.noreply.github.com> Date: Sat, 2 Jul 2022 21:42:24 +0200 Subject: [PATCH] Update main.py --- octosuite/main.py | 718 +++++++++++++++++++++++----------------------- 1 file changed, 362 insertions(+), 356 deletions(-) diff --git a/octosuite/main.py b/octosuite/main.py index a690d39..1a55fdc 100644 --- a/octosuite/main.py +++ b/octosuite/main.py @@ -9,14 +9,15 @@ import getpass import requests import platform import subprocess -from pprint import pprint +from rich.table import Table from datetime import datetime +from rich import print as xprint from octosuite.helper import Help -from octosuite.colors import Color -from octosuite.banner import Banner from octosuite.sign_vars import SignVar from octosuite.log_roller import logRoller from octosuite.csv_loggers import csvLogger +from octosuite.banner import name_logo, version_tag +from octosuite.colors import red, white, green, red_bold, white_bold, green_bold, header_title, reset global endpoint @@ -237,9 +238,9 @@ user_orgs_attr_dict = {'avatar_url': 'Profile Photo', # Author dictionary author_dict = {'Alias': 'rly0nheart', - 'Country': 'Zambia, Africa', + 'Country': ':zambia: Zambia, Africa', 'About.me': 'https://about.me/rly0nheart', - 'BuyMeACoffee': 'https://buymeacoffee.com/189381184'} + 'Buy Me A Coffee': 'https://buymeacoffee.com/189381184'} ''' @@ -250,52 +251,19 @@ and logging the start of a session. ''' def pathFinder(): ''' - Windows based machines - Here we check the existence of 3 directories - If the directories exist, we ignore them. - If not, we create them. + Here we create/check 3 directories (.logs, output, downloads) on startup + If they exists, we ignore, otherwise, we create them ''' - if sys.platform.lower().startswith(('win', 'darwin')): - if os.path.exists('.logs'): - pass - else: - subprocess.run(['mkdir','.logs']) - - if os.path.exists('output'): - pass - else: - subprocess.run(['mkdir','output']) - - if os.path.exists('downloads'): - pass - else: - subprocess.run(['mkdir','.downloads']) - else: - ''' - Here we do the same as above, - except we are not creating on windows based machines - ''' - if os.path.exists('.logs'): - pass - else: - subprocess.run(['sudo','mkdir','.logs'], shell=False) - - if os.path.exists('output'): - pass - else: - subprocess.run(['sudo','mkdir','output'], shell=False) - - if os.path.exists('downloads'): - pass - else: - subprocess.run(['sudo', 'mkdir', 'downloads'], shell=False) + directory_list = ['.logs', 'output', 'downloads'] + for directory in directory_list: + os.makedirs(directory, exist_ok=True) ''' Configure logging to log activities to a file, which will be named by the date and time a session was opened. ''' now = datetime.now() - now_formatted = now.strftime('%Y-%m-%d %H:%M:%S%p') - logging.basicConfig(filename=f'.logs/{now_formatted}.log', format='[%(asctime)s] [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S%p', level=logging.DEBUG) + now_formatted = now.strftime("%Y-%m-%d %H:%M:%S%p") + logging.basicConfig(filename=f".logs/{now_formatted}.log", format="[%(asctime)s] [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S%p", level=logging.DEBUG) # Log the start of a session logging.info(logRoller.sessionOpened.format(platform.node(), getpass.getuser())) @@ -307,68 +275,73 @@ This is the main function, responsible for mapping commands, calling other funct def onStart(): pathFinder() # A list of tuples mapping commands to their functions - command_map = [('org', Help.Org), - ('org:events', orgEvents), - ('org:profile', orgProfile), - ('org:repos', orgRepos), - ('org:member', orgMember), - ('repo', Help.Repo), - ('repo:pathcontents', pathContents), - ('repo:profile', repoProfile), - ('repo:contributors', repoContributors), - ('repo:stargazers', repoStargazers), - ('repo:forks', repoForks), - ('repo:issues', repoIssues), - ('repo:releases', repoReleases), - ('user', Help.User), - ('user:repos', userRepos), - ('user:gists', userGists), - ('user:orgs', userOrgs), - ('user:profile', userProfile), - ('user:events', userEvents), - ('user:followers', userFollowers), - ('user:follows', userFollows), - ('user:following', userFollowing), - ('user:subscriptions', userSubscriptions), - ('search', Help.Search), - ('search:users', userSearch), - ('search:repos', repoSearch), - ('search:topics', topicSearch), - ('search:issues', issueSearch), - ('search:commits', commitsSearch), - ('source', Help.Source), - ('source:tarball', downloadTarball), - ('source:zipball', downloadZipball), - ('logs', Help.Logs), - ('logs:view',viewLogs), - ('logs:read',readLog), - ('logs:delete',deleteLog), - ('help', Help.helpCommand), - ('help:version', Help.versionCommand), - ('help:source', Help.sourceCommand), - ('help:search', Help.searchCommand), - ('help:user', Help.userCommand), - ('help:repo', Help.repoCommand), - ('help:logs', Help.logsCommand), - ('help:org', Help.orgCommand), - ('author', author), - ('about', about), - ('clear',clearScreen), - ('version', Help.Version), - ('version:info', versionInfo), - ('version:check', versionCheck), - ('exit', exitSession)] + command_map = [("exit", exitSession), + ("clear",clearScreen), + ("about", about), + ("author", author), + ("help", Help.helpCommand), + ("help:version", Help.versionCommand), + ("help:source", Help.sourceCommand), + ("help:search", Help.searchCommand), + ("help:user", Help.userCommand), + ("help:repo", Help.repoCommand), + ("help:logs", Help.logsCommand), + ("help:csv", Help.csvCommand), + ("help:org", Help.orgCommand), + ("version", Help.Version), + ("version:info", versionInfo), + ("version:check", versionCheck), + ("source", Help.Source), + ("source:tarball", downloadTarball), + ("source:zipball", downloadZipball), + ("org", Help.Org), + ("org:events", orgEvents), + ("org:profile", orgProfile), + ("org:repos", orgRepos), + ("org:member", orgMember), + ("repo", Help.Repo), + ("repo:path_contents", pathContents), + ("repo:profile", repoProfile), + ("repo:contributors", repoContributors), + ("repo:stargazers", repoStargazers), + ("repo:forks", repoForks), + ("repo:issues", repoIssues), + ("repo:releases", repoReleases), + ("user", Help.User), + ("user:repos", userRepos), + ("user:gists", userGists), + ("user:orgs", userOrgs), + ("user:profile", userProfile), + ("user:events", userEvents), + ("user:followers", userFollowers), + ("user:follows", userFollows), + ("user:following", userFollowing), + ("user:subscriptions", userSubscriptions), + ("search", Help.Search), + ("search:users", userSearch), + ("search:repos", repoSearch), + ("search:topics", topicSearch), + ("search:issues", issueSearch), + ("search:commits", commitsSearch), + ("logs", Help.Logs), + ("logs:view",viewLogs), + ("logs:read",readLog), + ("logs:delete",deleteLog), + ("csv", Help.Csv), + ("csv:view", viewCsv), + ("csv:read", readCsv), + ("csv:delete", deleteCsv)] - print(Banner.nameLogo) + xprint(name_logo) ''' Main loop keeps octosuite running, this will break if Octosuite detects a KeyboardInterrupt (Ctrl+C) or if the 'exit' command is entered. ''' while True: try: - command_input = input(f'''{Color.white}┌──({Color.red}{getpass.getuser()}{Color.white}@{Color.red}octosuite{Color.white})\n├──[{Color.green}~{os.getcwd()}{Color.white}]\n└╼{Color.reset} ''').lower() - print('\n') + xprint(f"{white}┌──({red}{getpass.getuser()}{white}@{red}octosuite{white})\n├──[~{green}{os.getcwd()}{white}]\n└╼ {reset}", end="");command_input = input().lower() + print("\n") ''' Iterating over the command_map and check if the user input matches any command in it [command_map], if there's a match, we return its function. If no match is found, we ignore it. @@ -376,540 +349,574 @@ def onStart(): for command, function in command_map: if command_input == command: function() - print('\n') + print("\n") else: pass # This catches the KeyboardInterrupt exception (Ctrl+C) except KeyboardInterrupt: - logging.warning(logRoller.Ctrl.format('Ctrl+C')) - sys.stdout.write(f"{SignVar.warning} {logRoller.Ctrl}".format(f"{Color.red}Ctrl{Color.reset}+{Color.red}C{Color.reset}")+'\n');break + logging.warning(logRoller.Ctrl.format("Ctrl+C")) + xprint(f"{SignVar.warning} {logRoller.Ctrl.format('Ctrl+C')}") + break # This initially catches all exceptions (except the KeyboardInterrupt) except Exception as e: logging.error(logRoller.Error.format(e)) - sys.stderr.write(f"{SignVar.error} {logRoller.Error}".format(f'{Color.red}{e}{Color.reset}')+'\n') + xprint(f"{SignVar.error} {logRoller.Error.format(e)}") # Fetching organization info def orgProfile(): - organization = input(f'{Color.white}--> @{Color.green}Organization{Color.white} (username){Color.reset} ') - response = requests.get(f'{endpoint}/orgs/{organization}') + xprint(f"{white}>> @{green}Organization {white}(username){reset} ", end="");organization = input() + response = requests.get(f"{endpoint}/orgs/{organization}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.orgNotFound.format(organization)}\n") + xprint(f"{SignVar.negative} {logRoller.orgNotFound.format(organization)}") elif response.status_code == 200: - print(f"\n{Color.white}{response.json()['name']}{Color.reset}") + xprint(f"\n{white}{response.json()['name']}{reset}") for attr in org_attrs: - print(f'{Color.white}├─ {org_attr_dict[attr]}: {Color.green}{response.json()[attr]}{Color.reset}') + xprint(f"{white}├─ {org_attr_dict[attr]}:{reset} {response.json()[attr]}") csvLogger.logOrgProfile(response) else: - pprint(response.json()) + xprint(response.json()) # Fetching user information def userProfile(): - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - response = requests.get(f'{endpoint}/users/{username}') + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input() + response = requests.get(f"{endpoint}/users/{username}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.userNotFound.format(username)}\n") + xprint(f"{SignVar.negative} {logRoller.userNotFound.format(username)}") elif response.status_code == 200: - print(f"\n{Color.white}{response.json()['name']}{Color.reset}") + xprint(f"\n{white}{response.json()['name']}{reset}") for attr in profile_attrs: - print(f'{Color.white}├─ {profile_attr_dict[attr]}: {Color.green}{response.json()[attr]}{Color.reset}') + xprint(f"{white}├─ {profile_attr_dict[attr]}:{reset} {response.json()[attr]}") csvLogger.logUserProfile(response) else: - pprint(response.json()) + xprint(response.json()) # Fetching repository information def repoProfile(): - repo_name = input(f'{Color.white}--> %{Color.green}Repository{Color.reset} ') - username = input(f'{Color.white}--> @{Color.green}Owner{Color.white} (username){Color.reset} ') - response = requests.get(f'{endpoint}/repos/{username}/{repo_name}') + xprint(f"{white}>> %{green}Repository{reset} ", end="");repo_name = input() + xprint(f"{white}>> @{green}Owner{white} (username) ", end="");username = input() + response = requests.get(f"{endpoint}/repos/{username}/{repo_name}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}\n") + xprint(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}") elif response.status_code == 200: - print(f"\n{Color.white}{response.json()['full_name']}{Color.reset}") + xprint(f"\n{white}{response.json()['full_name']}{reset}") for attr in repo_attrs: - print(f"{Color.white}├─ {repo_attr_dict[attr]}: {Color.green}{response.json()[attr]}{Color.reset}") + xprint(f"{white}├─ {repo_attr_dict[attr]}:{reset} {response.json()[attr]}") csvLogger.logRepoProfile(response) else: - pprint(response.json()) + xprint(response.json()) # Get path contents def pathContents(): - repo_name = input(f'{Color.white}--> %{Color.green}Repository{Color.reset} ') - username = input(f'{Color.white}--> @{Color.green}Owner{Color.white} (username){Color.reset} ') - path_name = input(f'{Color.white}--> ~{Color.green}/path/name{Color.reset} ') - response = requests.get(f'{endpoint}/repos/{username}/{repo_name}/contents/{path_name}') + xprint(f"{white}>> %{green}Repository{reset} ", end="");repo_name = input() + xprint(f"{white}>> @{green}Owner{white} (username) ", end="");username = input() + xprint(f"{white}>> ~{green}/path/name{reset} ", end="");path_name = input() + response = requests.get(f"{endpoint}/repos/{username}/{repo_name}/contents/{path_name}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.infoNotFound.format(repo_name, username, path_name)}\n") + xprint(f"{SignVar.negative} {logRoller.infoNotFound.format(repo_name, username, path_name)}") elif response.status_code == 200: + content_count = 0 for content in response.json(): - print(f"\n{Color.white}{content['name']}{Color.reset}") + content_count += 1 + xprint(f"\n{white}{content['name']}{reset}") for attr in path_attrs: - print(f'{Color.white}├─ {path_attr_dict[attr]}: {Color.green}{content[attr]}{Color.reset}') + xprint(f"{white}├─ {path_attr_dict[attr]}:{reset} {content[attr]}") csvLogger.logRepoPathContents(content, repo_name) + xprint(SignVar.info, f"Found {content_count} file(s) in {repo_name}/{path_name}.") else: - pprint(response.json()) + xprint(response.json()) # repo contributors def repoContributors(): - repo_name = input(f'{Color.white}--> %{Color.green}Repository{Color.reset} ') - username = input(f'{Color.white}--> @{Color.green}Owner{Color.white} (username){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('contributors')) - response = requests.get(f'{endpoint}/repos/{username}/{repo_name}/contributors?per_page={limit}') + xprint(f"{white}>> %{green}Repository{reset} ", end="");repo_name = input() + xprint(f"{white}>> @{green}Owner{white} (username) ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format("contributors"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/repos/{username}/{repo_name}/contributors?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}\n") + xprint(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}") elif response.status_code == 200: for contributor in response.json(): - print(f"\n{Color.white}{contributor['login']}{Color.reset}") + xprint(f"\n{white}{contributor['login']}{reset}") for attr in user_attrs: - print(f'{Color.white}├─ {user_attr_dict[attr]}: {Color.green}{contributor[attr]}{Color.reset}') + xprint(f"{white}├─ {user_attr_dict[attr]}:{reset} {contributor[attr]}") csvLogger.logRepoContributors(contributor, repo_name) else: - pprint(response.json()) + xprint(response.json()) # repo stargazers def repoStargazers(): - repo_name = input(f'{Color.white}--> %{Color.green}Repository{Color.reset} ') - username = input(f'{Color.white}--> @{Color.green}Owner{Color.white} (username){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('repository stargazers')) - response = requests.get(f'{endpoint}/repos/{username}/{repo_name}/stargazers?per_page={limit}') + xprint(f"{white}>> %{green}Repository{reset} ");repo_name = input() + xprint(f"{white}>> @{green}Owner{white} (username){reset} ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format("repository stargazers"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/repos/{username}/{repo_name}/stargazers?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}\n") + xprint(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}") elif response.json() == {}: - sys.stdout.write(f'{SignVar.negative} Repository ({repo_name}) does not have any stargazers.{Color.reset}\n') + xprint(f"{SignVar.negative} Repository does not have any stargazers -> ({repo_name})") elif response.status_code == 200: for stargazer in response.json(): - print(f"\n{Color.white}{stargazer['login']}{Color.reset}") + xprint(f"\n{white}{stargazer['login']}{reset}") for attr in user_attrs: - print(f'{Color.white}├─ {user_attr_dict[attr]}: {Color.green}{stargazer[attr]}{Color.reset}') + xprint(f"{white}├─ {user_attr_dict[attr]}:{reset} {stargazer[attr]}") csvLogger.logRepoStargazers(stargazer, repo_name) else: - pprint(response.json()) + xprint(response.json()) # repo forks def repoForks(): - repo_name = input(f'{Color.white}--> %{Color.green}Repository{Color.reset} ') - username = input(f'{Color.white}--> @{Color.green}Owner{Color.white} (username){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('repository forks')) - response = requests.get(f'{endpoint}/repos/{username}/{repo_name}/forks?per_page={limit}') + xprint(f"{white}>> %{green}Repository{reset} ", end="");repo_name = input() + xprint(f"{white}>> @{green}Owner{white} (username){reset} ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format("repository forks"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/repos/{username}/{repo_name}/forks?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}\n") + xprint(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}") elif response.json() == {}: - sys.stdout.write(f'{SignVar.negative} Repository ({repo_name}) does not have forks.{Color.reset}\n') + xprint(f"{SignVar.negative} Repository does not have forks -> ({repo_name})") elif response.status_code == 200: count = 0 for fork in response.json(): count += 1 - print(f"\n{Color.white}{fork['full_name']}{Color.reset}") + xprint(f"\n{white}{fork['full_name']}{reset}") for attr in repo_attrs: - print(f'{Color.white}├─ {repo_attr_dict[attr]}: {Color.green}{fork[attr]}{Color.reset}') + xprint(f"{white}├─ {repo_attr_dict[attr]}:{reset} {fork[attr]}") csvLogger.logRepoForks(fork, count) else: - pprint(response.json()) + xprint(response.json()) # Repo issues def repoIssues(): - repo_name = input(f'{Color.white}--> %{Color.green}Repository{Color.reset} ') - username = input(f'{Color.white}--> @{Color.green}Owner{Color.white} (username){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('repository issues')) - response = requests.get(f'{endpoint}/repos/{username}/{repo_name}/issues?per_page={limit}') + xprint(f"{white}>> %{green}Repository{reset} ", end="");repo_name = input() + xprint(f"{white}>> @{green}Owner{white} (username){reset} ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format("repository issues"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/repos/{username}/{repo_name}/issues?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}\n") + xprint(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}") elif response.json() == []: - sys.stdout.write(f'{SignVar.negative} Repository ({repo_name}) does not have open issues.{Color.reset}\n') + xprint(f"{SignVar.negative} Repository does not have open issues -> ({repo_name})") elif response.status_code == 200: for issue in response.json(): - print(f"\n{Color.white}{issue['title']}{Color.reset}") + xprint(f"\n{white}{issue['title']}{reset}") for attr in repo_issues_attrs: - print(f'{Color.white}├─ {repo_issues_attr_dict[attr]}: {Color.green}{issue[attr]}{Color.reset}') - print(issue['body']) + xprint(f"{white}├─ {repo_issues_attr_dict[attr]}:{reset} {issue[attr]}") + xprint(issue['body']) csvLogger.logRepoIssues(issue, repo_name) else: - pprint(response.json()) + xprint(response.json()) # Repo releases def repoReleases(): - repo_name = input(f'{Color.white}--> %{Color.green}Repository{Color.reset} ') - username = input(f'{Color.white}--> @{Color.green}Owner{Color.white} (username){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('repository releases')) - response = requests.get(f'{endpoint}/repos/{username}/{repo_name}/releases?per_page={limit}') + xprint(f"{white}>> %{green}Repository{reset} ", end="");repo_name = input() + xprint(f"{white}>> @{green}Owner{white} (username){reset} ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format("repository releases"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/repos/{username}/{repo_name}/releases?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}\n") + xprint(f"{SignVar.negative} {logRoller.repoOrUserNotFound.format(repo_name, username)}") elif response.json() == []: - sys.stdout.write(f"{SignVar.negative} Repository ({repo_name}) does not have releases.{Color.reset}\n") + xprint(f"{SignVar.negative} Repository does not have releases -> ({repo_name})") elif response.status_code == 200: for release in response.json(): - print(f"\n{Color.white}{release['name']}{Color.reset}") + xprint(f"\n{white}{release['name']}{reset}") for attr in repo_releases_attrs: - print(f'{Color.white}├─ {repo_releases_attr_dict[attr]}: {Color.green}{release[attr]}{Color.reset}') - print(release['body']) + xprint(f"{white}├─ {repo_releases_attr_dict[attr]}:{reset} {release[attr]}") + xprint(release['body']) csvLogger.logRepoReleases(release, repo_name) else: - pprint(response.json()) + xprint(response.json()) # Fetching organization repositories def orgRepos(): - organization = input(f'{Color.white}--> @{Color.green}Organization{Color.white} (username){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('organization repositories')) - response = requests.get(f'{endpoint}/orgs/{organization}/repos?per_page={limit}') + xprint(f"{white}>> @{green}Organization{white} (username){reset} ", end="");organization = input() + xprint(SignVar.prompt, logRoller.limitInput.format("organization repositories"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/orgs/{organization}/repos?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.orgNotFound.format(organization)}\n") + xprint(f"{SignVar.negative} {logRoller.orgNotFound.format(organization)}") elif response.status_code == 200: for repository in response.json(): - print(f"\n{Color.white}{repository['full_name']}{Color.reset}") + xprint(f"\n{white}{repository['full_name']}{reset}") for attr in repo_attrs: - print(f"{Color.white}├─ {repo_attr_dict[attr]}: {Color.green}{repository[attr]}{Color.reset}") + xprint(f"{white}├─ {repo_attr_dict[attr]}:{reset} {repository[attr]}") csvLogger.logOrgRepos(repository, organization) else: - pprint(response.json()) + xprint(response.json()) # organization events def orgEvents(): - organization = input(f"{Color.white}--> @{Color.green}Organization{Color.white} (username){Color.reset} ") - limit = input(SignVar.prompt+logRoller.limitInput.format('organization events')) - response = requests.get(f'{endpoint}/orgs/{organization}/events?per_page={limit}') + xprint(f"{white}>> @{green}Organization{white} (username){reset} ", end="");organization = input() + xprint(SignVar.prompt, logRoller.limitInput.format("organization repositories"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/orgs/{organization}/events?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.orgNotFound.format(organization)}\n") + xprint(f"{SignVar.negative} {logRoller.orgNotFound.format(organization)}") elif response.status_code == 200: for event in response.json(): - print(f"\n{Color.white}{event['id']}{Color.reset}") - print(f"{Color.white}├─ Type: {Color.green}{event['type']}{Color.reset}\n{Color.white}├─ Created at: {Color.green}{event['created_at']}{Color.reset}") - pprint(event['payload']) + xprint(f"\n{white}{event['id']}{reset}") + xprint(f"{white}├─ Type:{reset} {event['type']}\n{white}├─ Created at:{reset} {event['created_at']}") + xprint(event['payload']) csvLogger.logOrgEvents(event, organization) else: - pprint(response.json()) + xprint(response.json()) # organization member def orgMember(): - organization = input(f"{Color.white}--> @{Color.green}Organization{Color.white} (username){Color.reset} ") - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - response = requests.get(f'{endpoint}/orgs/{organization}/public_members/{username}') + xprint(f"{white}>> @{green}Organization{white} (username){reset} ", end="");organization = input() + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input() + response = requests.get(f"{endpoint}/orgs/{organization}/public_members/{username}") if response.status_code == 204: - sys.stdout.write(f"{SignVar.positive} User ({username}) is a public member of the organization ({organization}){Color.reset}\n") + xprint(f"{SignVar.positive} User ({username}) is a public member of the organization -> ({organization})") else: - sys.stdout.write(f"{SignVar.negative} {response.json()['message']}{Color.reset}\n") + xprint(f"{SignVar.negative} {response.json()['message']}") # Fetching user repositories def userRepos(): - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('repositories')) - response = requests.get(f'{endpoint}/users/{username}/repos?per_page={limit}') + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format("repositories"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/users/{username}/repos?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.userNotFound.format(username)}\n") + xprint(f"{SignVar.negative} {logRoller.userNotFound.format(username)}") elif response.status_code == 200: for repository in response.json(): - print(f"\n{Color.white}{repository['full_name']}{Color.reset}") + xprint(f"\n{white}{repository['full_name']}{reset}") for attr in repo_attrs: - print(f"{Color.white}├─ {repo_attr_dict[attr]}: {Color.green}{repository[attr]}{Color.reset}") + xprint(f"{white}├─ {repo_attr_dict[attr]}:{reset} {repository[attr]}") csvLogger.logUserRepos(repository, username) else: - pprint(response.json()) + xprint(response.json()) # Fetching user's gists def userGists(): - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - limit = input(f'{SignVar.prompt+logRoller.limitInput.format("gists")}') - response = requests.get(f'{endpoint}/users/{username}/gists?per_page={limit}') - #pprint(response.json()) + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format('gists'), end="");limit = int(input()) + response = requests.get(f"{endpoint}/users/{username}/gists?per_page={limit}") + #xprint(response.json()) if response.json() == []: - sys.stdout.write(f'{SignVar.negative} User does not have gists.{Color.reset}\n') + xprint(f"{SignVar.negative} User does not have gists.") elif response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.userNotFound.format(username)}\n") + xprint(f"{SignVar.negative} {logRoller.userNotFound.format(username)}") elif response.status_code == 200: for gist in response.json(): - print(f"\n{Color.white}{gist['id']}{Color.reset}") + xprint(f"\n{white}{gist['id']}{reset}") for attr in gists_attrs: - print(f"{Color.white}├─ {gists_attr_dict[attr]}: {Color.green}{gist[attr]}{Color.reset}") + xprint(f"{white}├─ {gists_attr_dict[attr]}:{reset} {gist[attr]}") csvLogger.logUserGists(gist) else: - pprint(response.json()) + xprint(response.json()) - + # Fetching a list of organizations that a user owns or belongs to def userOrgs(): - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('user organizations')) - response = requests.get(f'{endpoint}/users/{username}/orgs?per_page={limit}') + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format("user organizations"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/users/{username}/orgs?per_page={limit}") if response.json() == []: - sys.stdout.write(f'{SignVar.negative} User ({username}) does not (belong to/own) any organizations.{Color.reset}\n') + xprint(f"{SignVar.negative} User ({username}) does not (belong to/own) any organizations.") elif response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.userNotFound.format(username)}\n") + xprint(f"{SignVar.negative} {logRoller.userNotFound.format(username)}") elif response.status_code == 200: for organization in response.json(): - print(f'\n{Color.white}{organization["login"]}{Color.reset}') + print(f"\n{white}{organization['login']}{reset}") for attr in user_orgs_attrs: - print(f'{Color.white}├─ {user_orgs_attr_dict[attr]}: {Color.green}{organization[attr]}{Color.reset}') + xprint(f"{white}├─ {user_orgs_attr_dict[attr]}:{reset} {organization[attr]}") csvLogger.logUserOrgs(organization, username) else: - pprint(response.json()) + xprint(response.json()) # Fetching a users events def userEvents(): - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('events')) - response = requests.get(f'{endpoint}/users/{username}/events/public?per_page={limit}') + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input() + xprint(SignVar.prompt, logRoller.limitInput.format("events"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/users/{username}/events/public?per_page={limit}") if response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.userNotFound.format(username)}\n") + xprint(f"{SignVar.negative} {logRoller.userNotFound.format(username)}") elif response.status_code == 200: for event in response.json(): - print(f"\n{Color.white}{event['id']}{Color.reset}") - print(f"{Color.white}├─ Actor: {Color.green}{event['actor']['login']}{Color.reset}") - print(f"{Color.white}├─ Type: {Color.green}{event['type']}{Color.green}") - print(f"{Color.white}├─ Repository: {Color.green}{event['repo']['name']}{Color.reset}") - print(f"{Color.white}├─ Created at: {Color.green}{event['created_at']}{Color.reset}") - pprint(event['payload']) + xprint(f"\n{white}{event['id']}{reset}") + xprint(f"{white}├─ Actor:{reset} {event['actor']['login']}") + xprint(f"{white}├─ Type:{reset} {event['type']}") + xprint(f"{white}├─ Repository:{reset} {event['repo']['name']}") + xprint(f"{white}├─ Created at:{reset} {event['created_at']}") + xprint(event['payload']) csvLogger.logUserEvents(event) else: - pprint(response.json()) + xprint(response.json()) # Fetching a target user's subscriptions def userSubscriptions(): - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('user subscriptions')) - response = requests.get(f'{endpoint}/users/{username}/subscriptions?per_page={limit}') + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input().lower() + xprint(SignVar.prompt, logRoller.limitInput.format("user subscriptions"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/users/{username}/subscriptions?per_page={limit}") if response.json() == []: - print(f"{SignVar.negative} User does not have any subscriptions.{Color.reset}\n") + xprint(f"{SignVar.negative} User does not have any subscriptions.") elif response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.userNotFound.format(username)}\n") + xprint(f"{SignVar.negative} {logRoller.userNotFound.format(username)}") elif response.status_code == 200: for repository in response.json(): - print(f"\n{Color.white}{repository['full_name']}{Color.reset}") + xprint(f"\n{white}{repository['full_name']}{reset}") for attr in repo_attrs: - print(f"{Color.white}├─ {repo_attr_dict[attr]}: {Color.green}{repository[attr]}{Color.reset}") + xprint(f"{white}├─ {repo_attr_dict[attr]}:{reset} {repository[attr]}") csvLogger.logUserSubscriptions(repository, username) else: - pprint(response.json()) + xprint(response.json()) # Fetching a list of users the target follows def userFollowing(): - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('user\' following')) - response = requests.get(f'{endpoint}/users/{username}/following?per_page={limit}') + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input().lower() + xprint(SignVar.prompt, logRoller.limitInput.format("user' following"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/users/{username}/following?per_page={limit}") if response.json() == []: - sys.stdout.write(f'{SignVar.negative} User ({username})does not follow anyone.{Color.reset}') + xprint(f"{SignVar.negative} User ({username})does not follow anyone.") elif response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.userNotFound.format(username)}\n") + xprint(f"{SignVar.negative} {logRoller.userNotFound.format(username)}") elif response.status_code == 200: for user in response.json(): - print(f"\n{Color.white}@{user['login']}{Color.reset}") + xprint(f"\n{white}@{user['login']}{reset}") for attr in user_attrs: - print(f"{Color.white}├─ {user_attr_dict[attr]}: {Color.green}{user[attr]}{Color.reset}") + xprint(f"{white}├─ {user_attr_dict[attr]}:{reset} {user[attr]}") csvLogger.logUserFollowing(user, username) else: - pprint(response.json()) + xprint(response.json()) # Fetching user's followera' def userFollowers(): - username = input(f'{Color.white}--> @{Color.green}Username{Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('user followers')) - response = requests.get(f'{endpoint}/users/{username}/followers?per_page={limit}') + xprint(f"{white}>> @{green}Username{reset} ", end="");username = input().lower() + xprint(SignVar.prompt, logRoller.limitInput.format("user followers"),end="");limit = int(input()) + response = requests.get(f"{endpoint}/users/{username}/followers?per_page={limit}") if response.json() == []: - sys.stdout.write(f'{SignVar.negative} User ({username})does not have followers.{Color.reset}') + xprint(f"{SignVar.negative} User ({username})does not have followers.") elif response.status_code == 404: - sys.stdout.write(f"{SignVar.negative} {logRoller.userNotFound.format(username)}\n") + xprint(f"{SignVar.negative} {logRoller.userNotFound.format(username)}") elif response.status_code == 200: for follower in response.json(): - print(f"\n{Color.white}@{follower['login']}{Color.reset}") + xprint(f"\n{white}@{follower['login']}{reset}") for attr in user_attrs: - print(f"{Color.white}├─ {user_attr_dict[attr]}: {Color.green}{follower[attr]}{Color.reset}") + xprint(f"{white}├─ {user_attr_dict[attr]}:{reset} {follower[attr]}") csvLogger.logUserFollowers(follower, username) else: - pprint(response.json()) + xprint(response.json()) # Checking whether or not user[A] follows user[B] def userFollows(): - user_a = input(f'{Color.white}--> @{Color.green}user{Color.white}(A) (username){Color.reset} ') - user_b = input(f'{Color.white}--> @{Color.green}user{Color.white}(B) (username){Color.reset} ') - response = requests.get(f'{endpoint}/users/{user_a}/following/{user_b}') + xprint(f"{white}>> @{green}user{white}(A) (username){reset} ", end="");user_a = input() + xprint(f"{white}>> @{green}user{white}(B) (username){reset} ", end="");user_b = input() + response = requests.get(f"{endpoint}/users/{user_a}/following/{user_b}") if response.status_code == 204: - sys.stdout.write(f'{SignVar.positive} @{user_a} FOLLOWS @{user_b}{Color.reset}\n') + xprint(f"{SignVar.positive} @{user_a} FOLLOWS @{user_b}") else: - sys.stdout.write(f'{SignVar.negative} @{user_a} DOES NOT FOLLOW @{user_b}{Color.reset}\n') + xprint(f"{SignVar.negative} @{user_a} DOES NOT FOLLOW @{user_b}") # User search def userSearch(): - query = input(f'{Color.white}--> @{Color.green}Query{Color.white} (eg. john){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('user search')) - response = requests.get(f'{endpoint}/search/users?q={query}&per_page={limit}').json() + xprint(f"{white}>> @{green}Query{white} (eg. john){reset} ", end="");query = input() + xprint(SignVar.prompt, logRoller.limitInput.format("user search"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/search/users?q={query}&per_page={limit}").json() for user in response['items']: - print(f"\n{Color.white}@{user['login']}{Color.reset}") + xprint(f"\n{white}@{user['login']}{reset}") for attr in user_attrs: - print(f"{Color.white}├─ {user_attr_dict[attr]}: {Color.green}{user[attr]}{Color.reset}") + xprint(f"{white}├─ {user_attr_dict[attr]}:{reset} {user[attr]}") csvLogger.logUserSearch(user, query) # Repository search def repoSearch(): - query = input(f'{Color.white}--> %{Color.green}Query{Color.white} (eg. git){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('repositor[y][ies] search')) - response = requests.get(f'{endpoint}/search/repositories?q={query}&per_page={limit}').json() + xprint(f"{white}>> %{green}Query{white} (eg. git){reset} ", end="");query = input() + xprint(SignVar.prompt, logRoller.limitInput.format("repositor[y][ies] search"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/search/repositories?q={query}&per_page={limit}").json() for repository in response['items']: - print(f"\n{Color.white}{repository['full_name']}{Color.reset}") + xprint(f"\n{white}{repository['full_name']}{reset}") for attr in repo_attrs: - print(f"{Color.white}├─ {repo_attr_dict[attr]}: {Color.green}{repository[attr]}{Color.reset}") + xprint(f"{white}├─ {repo_attr_dict[attr]}:{reset} {repository[attr]}") csvLogger.logRepoSearch(repository, query) # Topics search def topicSearch(): - query = input(f'{Color.white}--> #{Color.green}Query{Color.white} (eg. osint){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('topic(s) search')) - response = requests.get(f'{endpoint}/search/topics?q={query}&per_page={limit}').json() + xprint(f"{white}>> #{green}Query{white} (eg. osint){reset} ", end="");query = input() + xprint(SignVar.prompt, logRoller.limitInput.format("topic(s) search"),end="");limit = int(input()) + response = requests.get(f"{endpoint}/search/topics?q={query}&per_page={limit}").json() for topic in response['items']: - print(f"\n{Color.white}{topic['name']}{Color.reset}") + xprint(f"\n{white}{topic['name']}{reset}") for attr in topic_attrs: - print(f"{Color.white}├─ {topic_attr_dict[attr]}: {Color.green}{topic[attr]}{Color.reset}") + xprint(f"{white}├─ {topic_attr_dict[attr]}:{reset} {topic[attr]}") csvLogger.logTopicSearch(topic, query) # Issue search def issueSearch(): - query = input(f'{Color.white}--> !{Color.green}Query{Color.white} (eg. error){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('issue(s) search')) - response = requests.get(f'{endpoint}/search/issues?q={query}&per_page={limit}').json() + xprint(f"{white}>> !{green}Query{white} (eg. error){reset} ", end="");query = input() + xprint(SignVar.prompt, logRoller.limitInput.format("issue(s) search"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/search/issues?q={query}&per_page={limit}").json() for issue in response['items']: - print(f"\n\n{Color.white}{issue['title']}{Color.reset}") + xprint(f"\n\n{white}{issue['title']}{reset}") for attr in repo_issues_attrs: - print(f"{Color.white}├─ {repo_issues_attr_dict[attr]}: {Color.green}{issue[attr]}{Color.reset}") - print(issue['body']) + xprint(f"{white}├─ {repo_issues_attr_dict[attr]}:{reset} {issue[attr]}") + xprint(issue['body']) csvLogger.logIssueSearch(issue, query) # Commits search def commitsSearch(): - query = input(f'{Color.white}--> :{Color.green}Query{Color.white} (eg. filename:index.php){Color.reset} ') - limit = input(SignVar.prompt+logRoller.limitInput.format('commit(s) search')) - response = requests.get(f'{endpoint}/search/commits?q={query}&per_page={limit}').json() + xprint(f"{white}>> :{green}Query{white} (eg. filename:index.php){reset} ", end="");query = input() + xprint(SignVar.prompt, logRoller.limitInput.format("commit(s) search"), end="");limit = int(input()) + response = requests.get(f"{endpoint}/search/commits?q={query}&per_page={limit}").json() for commit in response['items']: - print(f"\n{Color.white}{commit['commit']['tree']['sha']}{Color.reset}") - print(f"{Color.white}├─ Author: {commit['commit']['author']['name']}{Color.reset}") - print(f"{Color.white}├─ Username: {Color.green}{commit['author']['login']}{Color.reset}") - print(f"{Color.white}├─ Email: {Color.green}{commit['commit']['author']['email']}{Color.reset}") - print(f"{Color.white}├─ Commiter: {Color.green}{commit['commit']['committer']['name']}{Color.reset}") - print(f"{Color.white}├─ Repository: {Color.green}{commit['repository']['full_name']}{Color.reset}") - print(f"{Color.white}├─ URL: {Color.green}{commit['html_url']}{Color.reset}") - pprint(commit['commit']['message']) + xprint(f"\n{white}{commit['commit']['tree']['sha']}{reset}") + xprint(f"{white}├─ Author:{reset} {commit['commit']['author']['name']}") + xprint(f"{white}├─ Username:{reset} {commit['author']['login']}") + xprint(f"{white}├─ Email:{reset} {commit['commit']['author']['email']}") + xprint(f"{white}├─ Commiter:{reset} {commit['commit']['committer']['name']}") + xprint(f"{white}├─ Repository:{reset} {commit['repository']['full_name']}") + xprint(f"{white}├─ URL:{reset} {commit['html_url']}") + xprint(commit['commit']['message']) csvLogger.logCommitsSearch(commit, query) - + +# View csv files +def viewCsv(): + logging.info(logRoller.viewingCsv) + csv_files = os.listdir("output") + csv_table =Table(show_header=True, header_style=header_title) + csv_table.add_column("CSV", style="dim", width=12) + csv_table.add_column("Size (bytes)") + for csv_file in csv_files: + csv_table.add_row(str(csv_file), str(os.path.getsize("output/"+csv_file))) + xprint(csv_table) + + +# Read a specified csv file +def readCsv(): + xprint(f"{white}>> {green}.csv {reset}(filename) ", end="");csv_file = input() + with open(f"output/{csv_file}.csv", "r") as file: + logging.info(logRoller.readingCsv.format(csv_file)) + xprint("\n"+file.read()) + + +# Delete a specified csv file +def deleteCsv(): + xprint(f"{white}>> {green}.csv {reset}filename{reset} ", end="");csv_file = input() + if sys.platform.lower().startswith(("win", "darwin")): + subprocess.run(['del',f'.output\{csv_file}.csv']) + else: + subprocess.run(['sudo','rm',f'output/{csv_file}.csv'],shell=False) + + logging.info(logRoller.deletedCsv.format(csv_file)) + xprint(f"{SignVar.positive} {logRoller.deletedCsv.format(csv_file)}") + + # View octosuite log files def viewLogs(): logging.info(logRoller.viewingLogs) - logs = os.listdir('.logs') - print(f'''{Color.white} -Log Size{Color.reset} ---- ---------''') + logs = os.listdir(".logs") + logs_table =Table(show_header=True, header_style=header_title) + logs_table.add_column("Log", style="dim", width=12) + logs_table.add_column("Size (bytes)") for log in logs: - print(f"{log}\t ",os.path.getsize(".logs/"+log),"bytes") - + logs_table.add_row(str(log), str(os.path.getsize(".logs/"+log))) + xprint(logs_table) + # Read a specified log file def readLog(): - log_file = input(f"{Color.white}--> .log date (eg. 2022-04-27 10:09:36AM){Color.reset} ") - with open(f'.logs/{log_file}.log', 'r') as log: + xprint(f"{white}>> {green}.log date{reset} (eg. 2022-04-27 10:09:36AM) ", end="");log_file = input() + with open(f".logs/{log_file}.log", "r") as log: logging.info(logRoller.readingLog.format(log_file)) - print("\n"+log.read()) - + xprint("\n"+log.read()) + # Delete a specified log file def deleteLog(): - log_file = input(f"{Color.white}--> .log date (eg. 2022-04-27 10:09:36AM){Color.reset} ") - if sys.platform.lower().startswith(('win','darwin')): + xprint(f"{white}>> {green}.log date{reset} (eg. 2022-04-27 10:09:36AM) ", end="");log_file = input() + if sys.platform.lower().startswith(("win", "darwin")): subprocess.run(['del',f'.logs\{log_file}.log']) else: subprocess.run(['sudo','rm',f'.logs/{log_file}.log'],shell=False) logging.info(logRoller.deletedLog.format(log_file)) - sys.stdout.write(f"{SignVar.positive} {logRoller.deletedLog.format(log_file)}\n") - + xprint(f"{SignVar.positive} {logRoller.deletedLog.format(log_file)}") + # Downloading release tarball def downloadTarball(): - logging.info(logRoller.fileDownloading.format(f'octosuite.v{Banner.versionTag}.tar')) - sys.stdout.write(SignVar.info+' '+logRoller.fileDownloading.format(f'octosuite.v{Banner.versionTag}.tar')+'...\n') - data = requests.get(f'{endpoint}/repos/rly0nheart/octosuite/tarball/{Banner.versionTag}') - if data.status_code == 404: - logging.info(logRoller.tagNotFound.format(Banner.versionTag)) - sys.stdout.write(f'{SignVar.negative} {logRoller.tagNotFound.format(Banner.versionTag)}\n') - else: - with open(f'downloads/octosuite.v{Banner.versionTag}.tar', 'wb') as file: - file.write(data.content) - file.close() + logging.info(logRoller.fileDownloading.format(f"octosuite.v{version_tag}.tar")) + xprint(SignVar.info, logRoller.fileDownloading.format(f"octosuite.v{version_tag}.tar")) + data = requests.get(f"{endpoint}/repos/rly0nheart/octosuite/tarballball/{version_tag}") + with open(f"downloads/octosuite.v{version_tag}.tar", "wb") as file: + file.write(data.content) + file.close() - logging.info(logRoller.fileDownloaded.format(f'octosuite.v{Banner.versionTag}.tar')) - sys.stdout.write(SignVar.positive+' '+logRoller.fileDownloaded.format(f'octosuite.v{Banner.versionTag}.tar')) + logging.info(logRoller.fileDownloaded.format(f"octosuite.v{version_tag}.tar")) + xprint(SignVar.positive, logRoller.fileDownloaded.format(f"octosuite.v{version_tag}.tar")) # Downloading release zipball def downloadZipball(): - logging.info(logRoller.fileDownloading.format(f'octosuite.v{Banner.versionTag}.zip')) - sys.stdout.write(SignVar.info+' '+logRoller.fileDownloading.format(f'octosuite.v{Banner.versionTag}.zip')+'...\n') - data = requests.get(f'{endpoint}/repos/rly0nheart/octosuite/zipball/{Banner.versionTag}') - if data.status_code == 404: - logging.info(logRoller.tagNotFound.format(Banner.versionTag)) - sys.sdtout.write(f'{SignVar.negative} {logRoller.tagNotFound.format(Banner.versionTag)}\n') - else: - with open(f'downloads/octosuite.v{Banner.versionTag}.zip', 'wb') as file: - file.write(data.content) - file.close() + logging.info(logRoller.fileDownloading.format(f"octosuite.v{version_tag}.zip")) + xprint(SignVar.info, logRoller.fileDownloading.format(f"octosuite.v{version_tag}.zip")) + data = requests.get(f"{endpoint}/repos/rly0nheart/octosuite/zipball/{version_tag}") + with open(f"downloads/octosuite.v{version_tag}.zip", "wb") as file: + file.write(data.content) + file.close() - logging.info(logRoller.fileDownloaded.format(f'octosuite.v{Banner.versionTag}.zip')) - sys.stdout.write(SignVar.positive+' '+logRoller.fileDownloaded.format(f'octosuite.v{Banner.versionTag}.zip')) + logging.info(logRoller.fileDownloaded.format(f"octosuite.v{version_tag}.zip")) + xprint(SignVar.positive, logRoller.fileDownloaded.format(f"octosuite.v{version_tag}.zip")) def versionCheck(): response = requests.get(f"{endpoint}/repos/rly0nheart/octosuite/releases/latest") - if response.json()['tag_name'] == Banner.versionTag: - sys.stdout.write(f"{SignVar.positive} Octosuite is up to date. Check again soon :)\n") + if response.json()['tag_name'] == version_tag: + xprint(f"{SignVar.positive} Octosuite is up to date. Check again soon! :)") else: - sys.stdout.write(f"{SignVar.info} A new release is available (octosuite.v{response.json()['tag_name']}). Exit Octosuite and run '{Color.green}pip install --upgrade octosuite{Color.white}' to download and install the update.{Color.reset}\n") + xprint(f"{SignVar.info} A new release is available (octosuite.v{response.json()['tag_name']}). Exit Octosuite and run '{green_bold}pip install --upgrade octosuite{white}' to download and install the update.") # Author info def author(): - print(f'{Color.white}Richard Mwewa (Ritchie){Color.reset}') + xprint(f"{white}Richard Mwewa (Ritchie){reset}") for key,value in author_dict.items(): - print(f'{Color.white}├─ {key}: {Color.green}{value}{Color.reset}') + xprint(f"{white}├─ {key}:{reset} {value}") +# About program def about(): - sys.stdout.write(''' - OCTOSUITE © 2022 Richard Mwewa + xprint(f""" + {white_bold}OCTOSUITE © 2022 Richard Mwewa{reset} An advanced and lightning fast framework for gathering open-source intelligence on GitHub users and organizations. +With over 20+ features, Octosuite only runs on 2 external dependencies, and returns the gathered intelligence in a highly readable format. -Read the wiki: https://github.com/rly0nheart/octosuite/wiki -GitHub REST API documentation: https://docs.github.com/rest -''') +'_This is how you gather GitHub OSINT like a god:fire:_' + +{white_bold}Read the wiki:{reset} https://github.com/rly0nheart/octosuite/wiki +{white_bold}GitHub REST API documentation:{reset} https://docs.github.com/rest +""") # Close session def exitSession(): - prompt = input(f'{SignVar.prompt} This will close the current session, continue? (Y/n) ').lower() + xprint(f"{SignVar.prompt} This will close the current session, continue? (Y/n) ", end="");prompt = input().lower() if prompt == 'y': - logging.info(logRoller.sessionClosed.format('exit')) - sys.stdout.write(f"{SignVar.info} {logRoller.sessionClosed.format(datetime.now())}\n");exit() + logging.info(logRoller.sessionClosed.format(datetime.now())) + xprint(f"{SignVar.info} {logRoller.sessionClosed.format(datetime.now())}") + exit() else: pass @@ -920,22 +927,21 @@ def clearScreen(): We use 'cls' on Windows machines to clear the screen, otherwise, we use 'clear' ''' - if sys.platform.lower().startswith(('win','darwin')): + if sys.platform.lower().startswith(("win", "darwin")): subprocess.run(['cls']) else: - subprocess.run(['clear'],shell=False) + subprocess.run(['clear'], shell=False) # Show version information def versionInfo(): ''' - Yes... the changelog is hard coded - It's actually frustrating having to change this everytime I publish a new release lol + Yes... the changelog is hard coded lol ''' - sys.stdout.write(f''' -OCTOSUITE.v{Banner.versionTag} - -What's changed? -{'='*15} -[fix] error in source commands (source:tarball, source:zipball) -''') + xprint(f""" +{white_bold}Whats new in v{version_tag}?{reset} +[ {green}improved{reset} ] added 'csv' command with 3 subcommands (view, read, delete) +[ {green}improved{reset} ] using the rich library for coloring and tables +[ {green}improved{reset} ] logs and commands will be displayed in a table +[ {green}fixed{reset} ] minor bug fixes +""")