Compare commits

..

18 Commits

Author SHA1 Message Date
Richard Mwewa
6d1e163d9a Update LICENSE 2022-04-11 13:03:07 +02:00
Richard Mwewa
a8730864e9 Update README.md 2022-04-11 13:01:03 +02:00
Richard Mwewa
315cb7ec6f Update colors.py 2022-04-11 12:59:10 +02:00
Richard Mwewa
2afac6c0d4 Update banner.py 2022-04-11 12:58:23 +02:00
Richard Mwewa
b226f1b53b Update main.py 2022-04-11 12:56:19 +02:00
Richard Mwewa
bb38d95e57 Update README.md 2022-04-09 21:18:56 +02:00
Richard Mwewa
eae41866ec Create config.yml 2022-04-09 20:57:07 +02:00
Richard Mwewa
1e71c2d3bd Create feature_request.md 2022-04-09 20:42:46 +02:00
Richard Mwewa
d91f88d31b Create bug_report.md 2022-04-09 20:40:44 +02:00
Richard Mwewa
d5119a87b0 Update banner.py 2022-04-01 02:26:53 +02:00
Richard Mwewa
c4bd431620 Update main.py 2022-04-01 02:26:06 +02:00
Richard Mwewa
fe16b23fc7 Update banner.py 2022-03-31 12:54:23 +02:00
Richard Mwewa
8156af38d5 Update main.py 2022-03-31 12:53:29 +02:00
Richard Mwewa
6fb6a0ec98 Update main.py 2022-03-28 13:33:54 +02:00
Richard Mwewa
dc2a22aae0 Update dependabot.yml 2022-03-28 13:22:03 +02:00
Richard Mwewa
a2aac88da3 Create dependabot.yml 2022-03-28 13:09:04 +02:00
Richard Mwewa
3dbfc0f18e Update README.md 2022-03-28 12:52:56 +02:00
Richard Mwewa
392b3022d7 Update main.py 2022-03-27 23:01:12 +02:00
9 changed files with 275 additions and 110 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Richard Mwewa (Telegram)
url: https://t.me/rly0nheart/
about: Please ask and answer questions here.
- name: Richard Mwewa (Twitter)
url: https://m.twitter.com/rly0nheart/
about: Please report security vulnerabilities or bugs here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

13
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
# Enable version updates for pip
- package-ecosystem: "pip"
directory: "/" # Location of package manifests
# Check the tqdm registry for updates every day (weekdays)
schedule:
interval: "daily"

View File

@@ -1,3 +1,4 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
@@ -631,8 +632,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
octosuite Advanced Github OSINT Framework
Copyright (C) 2022 Richard Mwewa
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,18 +1,36 @@
![Screenshot_2022-03-17_10-12-53](https://user-images.githubusercontent.com/74001397/158868105-b5aba7e8-7342-4268-bd7a-6d6ae0bdae5a.png)
![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/rly0nheart/octosuite?style=for-the-badge&logo=github)
![OS](https://img.shields.io/badge/OS-GNU%2FLinux-red?style=for-the-badge&logo=Linux)
![OS](https://img.shields.io/badge/OS-Windows-blue?style=for-the-badge&logo=Windows)
![OS](https://img.shields.io/badge/OS-Mac-blue?style=for-the-badge&logo=apple)
![OS](https://img.shields.io/badge/OS-Mac-white?style=for-the-badge&logo=apple)
![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/rly0nheart/octosuite?style=for-the-badge&logo=github)
![GitHub commits since latest release (by date)](https://img.shields.io/github/commits-since/rly0nheart/octosuite/1.5.1-beta?style=for-the-badge&logo=github)
![GitHub last commit](https://img.shields.io/github/last-commit/rly0nheart/octosuite?style=for-the-badge&logo=github)
![GitHub](https://img.shields.io/github/license/rly0nheart/octosuite?style=for-the-badge&logo=github)
![GitHub repo size](https://img.shields.io/github/repo-size/rly0nheart/octosuite?style=for-the-badge&logo=github)
> *Simply gather OSINT on Github users and organizations like a god🔥*
> *Simply gather OSINT on Github users & organizations like a God🔥*
# FEATURES
- [x] Fetches organization info
- [x] Fetches user info
- [x] Fetches repository info
- [x] Returns contents of a path from a repository
- [x] Returns a list of repos owned by an organization
- [x] Returns a list of repos owned by a user
- [x] Returns a list of gists owned by a user
- [x] Returns a list of a user's followers
- [x] Checks whether user A follows user B
- [x] Searches users
- [x] Searches repositories
- [x] Searches topics
- [x] Searches issues
- [x] Searches commits
- [x] Easily updates with the 'update' command
- [x] Automatically logs network activity (.logs folder)
# INSTALLATION
**clone project**:
## Clone from Github
```
git clone https://github.com/rly0nheart/octosuite.git
@@ -26,8 +44,13 @@ cd octosuite
pip install -r requirements.txt
```
# USAGE
**Linux**:
## Install from PyPI
```
pip install octosuite
```
# GITHUB FORK USAGE
## Linux
```
sudo chmod +x octosuite
```
@@ -36,16 +59,32 @@ sudo chmod +x octosuite
sudo ./octosuite
```
**Windows**:
## Windows
```
python3 octosuite
```
**Mac**:
## Mac
```
python3 octosuite
```
# PYPI PACKAGE USAGE
## Linux
```
octosuite
```
## Windows
```
octosuite
```
## Mac
```
octosuite
```
# AVAILABLE COMMANDS
| Command | Usage|
| ------------- |:---------:|
@@ -63,7 +102,6 @@ python3 octosuite
| ``topicsearch`` | *search topics(s)* |
| ``issuesearch`` | *search issue(s)* |
| ``commitsearch`` | *search commit(s)* |
| ``usersearch`` | *search user(s)* |
| ``update`` | *update octosuite* |
| ``changelog`` | *show changelog* |
| ``author`` | *show author info* |
@@ -75,6 +113,9 @@ python3 octosuite
* *octosuite automatically logs network and minor user activity. The logs are saved by date and time in .logs folder*
* *Although octosuite was developed to work on **Mac**, **Windows**, or any **Linux** *Distribution*, it has only been tested on **Termux** *and* **Kali Linux***
# PYPI
[PyPI](https://pypi.org/project/octosuite)
# LICENSE
![license](https://user-images.githubusercontent.com/74001397/137917929-2f2cdb0c-4d1d-4e4b-9f0d-e01589e027b5.png)

View File

@@ -1,3 +1,4 @@
import os
from lib.colors import red,white,green,reset
banner = f'''{red}
▒█████ ▄████▄ ▄▄▄█████▓ ▒█████ ██████ █ ██ ██▓▄▄▄█████▓▓█████
@@ -7,11 +8,13 @@ banner = f'''{red}
░ ████▓▒░▒ ▓███▀ ░ ▒██▒ ░ ░ ████▓▒░▒██████▒▒▒█████▓ ░██░ ▒██▒ ░ ░▒████▒
░ ▒░▒░▒░ ░ ░▒ ▒ ░ ▒ ░░ ░ ▒░▒░▒░ ▒ ▒▓▒ ▒ ░░▒▓▒ ▒ ▒ ░▓ ▒ ░░ ░░ ▒░ ░
░ ▒ ▒░ ░ ▒ ░ ░ ▒ ▒░ ░ ░▒ ░ ░░░▒░ ░ ░ ▒ ░ ░ ░ ░ ░
░ ░ ░ ▒ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ░░░ ░ ░ ▒ v1.3.0
░ ░ ░ ▒ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ░░░ ░ ░ ▒ v1.5.1-beta
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
{white}— Advanced Github {red}OSINT{white} Framework{reset}
> {white}Welcome {os.getlogin()}{reset}
> {white}use '{green}help{white}' command for usage{reset}
> {white}commands are case sensitive
{'-'*30}

View File

@@ -3,7 +3,7 @@ import sys
# Colors will be unavailable on non-linux machines
colors = True
machine = sys.platform
if machine.lower().startswith(("os", "win", "darwin")):
if machine.lower().startswith(("os", "win", "darwin","ios")):
colors = False
if not colors:

View File

@@ -1,13 +1,28 @@
'''
octosuite Advanced Github OSINT Framework
Copyright (C) 2022 Richard Mwewa
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
'''
import os
import logging
import requests
import platform
import subprocess
import urllib.request
from tqdm import tqdm
from pprint import pprint
from lib import colors,banner
from lib.banner import banner
from datetime import datetime
from lib.colors import red, white, green, reset
class octosuite:
def __init__(self):
@@ -160,8 +175,8 @@ class octosuite:
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} ''')
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':
@@ -196,208 +211,210 @@ class octosuite:
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.')
exit(f'\n{colors.white}[{colors.red}-{colors.white}] Session terminated.{colors.reset}')
logging.info('Session terminated with \'exit\' command')
exit(f'\n{white}[{red}-{white}] Session terminated with \'exit\' command{reset}')
else:
print(f'\n{colors.white}[{colors.red}!{colors.white}] Unknown command: {command}{colors.reset}')
logging.warning(f'Unknown command: {command}')
print(f'\n{white}[{red}!{white}] Command not found: {command}{reset}')
logging.warning(f'command not found: {command}')
input(f'\n{colors.white}^ Press any key to continue{colors.reset} ')
input(f'\n{white}[{green}?{white}] Press any key to continue{reset} ')
def org_info(self):
organization = input(f'{colors.white}@{colors.green}Organization{colors.white} >> {colors.reset}')
organization = input(f'{white}@{green}Organization {white}>>{reset} ')
api = f'https://api.github.com/orgs/{organization}'
response = requests.get(api)
if response.status_code != 200:
print(f'\n{colors.white}[{colors.red}-{colors.white}] Organization @{organization} {colors.red}Not Found{colors.reset}')
print(f'\n{white}[{red}-{white}] Organization @{organization} {red}Not Found{reset}')
else:
response = response.json()
print(f"\n{colors.white}{response['name']}{colors.reset}")
print(f"\n{white}{response['name']}{reset}")
for attr in self.org_attrs:
print(f'{colors.white}├─ {self.org_attr_dict[attr]}: {colors.green}{response[attr]}{colors.reset}')
print(f'{white}├─ {self.org_attr_dict[attr]}: {green}{response[attr]}{reset}')
# Fetching user information
def user_profile(self):
username = input(f'{colors.white}@{colors.green}Username{colors.white} >> {colors.reset}')
username = input(f'{white}@{green}Username{white} >> {reset}')
api = f'https://api.github.com/users/{username}'
response = requests.get(api)
if response.status_code != 200:
print(f'\n{colors.white}[{colors.red}-{colors.white}] User @{username} {colors.red}Not Found{colors.reset}')
print(f'\n{white}[{red}-{white}] User @{username} {red}Not Found{reset}')
else:
response = response.json()
print(f"\n{colors.white}{response['name']}{colors.reset}")
print(f"\n{white}{response['name']}{reset}")
for attr in self.profile_attrs:
print(f'{colors.white}├─ {self.profile_attr_dict[attr]}: {colors.green}{response[attr]}{colors.reset}')
print(f'{white}├─ {self.profile_attr_dict[attr]}: {green}{response[attr]}{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}')
username = input(f'{white}@{green}Owner-username{white} >> {reset}')
repo_name = input(f'{white}%{green}reponame{white} >> {reset}')
api = f'https://api.github.com/repos/{username}/{repo_name}'
response = requests.get(api)
if response.status_code != 200:
print(f'\n{colors.white}[{colors.red}-{colors.white}] Repository %{repo_name} {colors.red}Not Found{colors.reset}')
print(f'\n{white}[{red}-{white}] Repository %{repo_name} {red}Not Found{reset}')
else:
response = response.json()
print(f"\n{colors.white}{response['full_name']}{colors.reset}")
print(f"\n{white}{response['full_name']}{reset}")
for attr in self.repo_attrs:
print(f"{colors.white}├─ {self.repo_attr_dict[attr]}: {colors.green}{response[attr]}{colors.reset}")
print(f"{white}├─ {self.repo_attr_dict[attr]}: {green}{response[attr]}{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} ')
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} ')
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{colors.white}[{colors.red}-{colors.white}] Information {colors.red}Not Found{colors.reset}')
print(f'\n{white}[{red}-{white}] Information {red}Not Found{reset}')
else:
response = response.json()
for item in response:
print(f"\n{colors.white}{item['name']}{colors.reset}")
print(f"\n{white}{item['name']}{reset}")
for attr in self.path_attrs:
print(f'{colors.white}├─ {self.path_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}')
print(f'{white}├─ {self.path_attr_dict[attr]}: {green}{item[attr]}{reset}')
# Fetching organozation repositories
def org_repos(self):
organization = input(f'{colors.white}@{colors.green}Organization{colors.white} >> {colors.reset}')
organization = input(f'{white}@{green}Organization{white} >> {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{colors.white}[{colors.red}-{colors.white}] Organization @{organization} {colors.red}Not Found{colors.reset}')
print(f'\n{white}[{red}-{white}] Organization @{organization} {red}Not Found{reset}')
else:
response = response.json()
for repo in response:
print(f"\n{colors.white}{repo['full_name']}{colors.reset}")
print(f"\n{white}{repo['full_name']}{reset}")
for attr in self.repo_attrs:
print(f"{colors.white}├─ {self.repo_attr_dict[attr]}: {colors.green}{repo[attr]}{colors.reset}")
print(f"{white}├─ {self.repo_attr_dict[attr]}: {green}{repo[attr]}{reset}")
print('\n')
# Fetching user repositories
def user_repos(self):
username = input(f'{colors.white}@{colors.green}Username{colors.white} >> {colors.reset}')
username = input(f'{white}@{green}Username{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{colors.white}[{colors.red}-{colors.white}] User @{username} {colors.red}Not Found{colors.reset}')
print(f'\n{white}[{red}-{white}] User @{username} {red}Not Found{reset}')
else:
response = response.json()
for repo in response:
print(f"\n{colors.white}{repo['full_name']}{colors.reset}")
print(f"\n{white}{repo['full_name']}{reset}")
for attr in self.repo_attrs:
print(f"{colors.white}├─ {self.repo_attr_dict[attr]}: {colors.green}{repo[attr]}{colors.reset}")
print(f"{white}├─ {self.repo_attr_dict[attr]}: {green}{repo[attr]}{reset}")
print('\n')
# Fetching user's gists
def user_gists(self):
username = input(f'{colors.white}@{colors.green}Username{colors.white} >> {colors.reset}')
username = input(f'{white}@{green}Username{white} >> {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}]User @{username} does not have any active gists.{colors.reset}')
print(f'{white}[{red}-{white}]User @{username} does not have any active gists.{reset}')
else:
for item in response:
print(f"\n{colors.white}{item['id']}{colors.reset}")
print(f"\n{white}{item['id']}{reset}")
for attr in self.gists_attrs:
print(f"{colors.white}├─ {self.gists_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}")
print(f"{white}├─ {self.gists_attr_dict[attr]}: {green}{item[attr]}{reset}")
print('\n')
# Fetching user's followera'
def followers(self):
username = input(f'{colors.white}@{colors.green}Username{colors.white} >> {colors.reset}')
username = input(f'{white}@{green}Username{white} >> {reset}')
api = f'https://api.github.com/users/{username}/followers?per_page=100'
response = requests.get(api).json()
if response == []:
print(f'\n{colors.white}[{colors.red}-{colors.white}]User @{username} does not have followers.{colors.reset}')
print(f'\n{white}[{red}-{white}]User @{username} does not have followers.{reset}')
else:
for item in response:
print(f"\n{colors.white}@{item['login']}{colors.reset}")
print(f"\n{white}@{item['login']}{reset}")
for attr in self.user_attrs:
print(f"{colors.white}├─ {self.user_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}")
print(f"{white}├─ {self.user_attr_dict[attr]}: {green}{item[attr]}{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}')
user_a = input(f'{white}@{green}User[A]{white} >> {reset}')
user_b = input(f'{white}@{green}User[B]{white} >> {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}')
print(f'{white}[{green}+{white}] @{user_a} follows @{user_b}.{reset}')
else:
print(f'{colors.white}[{colors.red}-{colors.white}] @{user_a} does not follow @{user_b}.{colors.reset}')
print(f'{white}[{red}-{white}] @{user_a} does not follow @{user_b}.{reset}')
# User search
def user_search(self):
query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}')
query = input(f'{white}#{green}Query{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']:
print(f"\n{colors.white}@{item['login']}{colors.reset}")
print(f"\n{white}@{item['login']}{reset}")
for attr in self.user_attrs:
print(f"{colors.white}├─ {self.user_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}")
print(f"{white}├─ {self.user_attr_dict[attr]}: {green}{item[attr]}{reset}")
print('\n')
# Repository search
def repo_search(self):
query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}')
query = input(f'{white}#{green}Query{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']:
print(f"\n{colors.white}{item['full_name']}{colors.reset}")
print(f"\n{white}{item['full_name']}{reset}")
for attr in self.repo_attrs:
print(f"{colors.white}├─ {self.repo_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}")
print(f"{white}├─ {self.repo_attr_dict[attr]}: {green}{item[attr]}{reset}")
print('\n')
# Topics search
def topic_search(self):
query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}')
query = input(f'{white}#{green}Query{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']:
print(f"\n{colors.white}{item['name']}{colors.reset}")
print(f"\n{white}{item['name']}{reset}")
for attr in self.topic_attrs:
print(f"{colors.white}├─ {self.topic_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}")
print(f"{white}├─ {self.topic_attr_dict[attr]}: {green}{item[attr]}{reset}")
print('\n')
# Issue search
def issue_search(self):
query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}')
query = input(f'{white}#{green}Query{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']:
print(f"\n{colors.white}{item['title']}{colors.reset}")
print(f"\n{white}{item['title']}{reset}")
for attr in self.issue_attrs:
print(f"{colors.white}├─ {self.issue_attr_dict[attr]}: {colors.green}{item[attr]}{colors.reset}")
print(f"{white}├─ {self.issue_attr_dict[attr]}: {green}{item[attr]}{reset}")
print('\n')
# Commits search
def commits_search(self):
query = input(f'{colors.white}#{colors.green}Query{colors.white} >> {colors.reset}')
query = input(f'{white}#{green}Query{white} >> {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}')
print(f'{white}{n}.{reset}')
pprint(item['commit'])
print('\n')
@@ -405,64 +422,88 @@ class octosuite:
# Update program
def update(self):
logging.info('Fetching updates...')
files_to_update = ['src/main.py','lib/banner.py','lib/colors.py','octosuite','LICENSE','README.md','requirements.txt']
for file in tqdm(files_to_update,desc=f'{colors.white}[{colors.green}*{colors.white}] Fetching updates...{colors.reset}'):
data = urllib.request.urlopen(f'https://raw.githubusercontent.com/rly0nheart/octosuite/master/{file}').read()
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}'):
data = requests.get(f'https://raw.githubusercontent.com/rly0nheart/octosuite/master/{file}')
with open(file, 'wb') as code:
code.write(data)
code.write(data.content)
code.close()
logging.info('Update complete.')
exit(f'\n{colors.white}[{colors.green}+{colors.white}] Update complete. Re-run octosuite.{colors.reset}')
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}')
# Show changelog
def changelog(self):
# lol yes the changelog is hard coded
changelog_text = '''
v1.3.0 Changelog:
v1.5.1-beta CHANGELOG:
Adjusted to work on Mac
Added changelog command
Added progress bar when fetching updates
Minor bug fixes
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
# Author info
def author(self):
print(f'\n{colors.white}Richard Mwewa (Ritchie){colors.reset}')
print(f'\n{white}Richard Mwewa (Ritchie){reset}')
for key,value in self.author_dict.items():
print(f'{colors.white}├─ {key}: {colors.green}{value}{colors.reset}')
print(f'{white}├─ {key}: {green}{value}{reset}')
def help(self):
help = '''
help = f'''
usage:
orginfo --> Get target organization info
userinfo --> Get target user profile info
repoinfo --> Get target repository info
pathcontents --> Get contents of a specified path from a target repository
orgrepos --> Get a list of repositories owned by a target organization
userrepos --> Get a list of repositories owned by a target user
usergists --> Get a list of gists owned by a target user
userfollowers --> Get a list of the target's 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 --> Update octosuite
changelog --> Show changelog
author --> Show author info
help --> Show usage/help
exit --> Exit session
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}
'''
return help
if os.path.exists('.logs'):
pass
else:
# Creating the .logs directory
if platform.system() == "Windows":
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',level=logging.DEBUG)
logging.basicConfig(filename=f'.logs/{datetime.now()}.log',format='%(asctime)s %(message)s',datefmt='%Y-%m-%d %H:%M:%S',level=logging.DEBUG)