pendora-box/pendora-box.py

176 lines
4.9 KiB
Python

import json
import pathlib
import hashlib
import requests
import base64
import sys
from os import geteuid
import subprocess
def compute_file_hash(filepath):
with open(filepath, 'rb') as file_for_hash:
data = file_for_hash.read()
filesize = len(data)
# Github sha value is computed as such:
return hashlib.sha1(b"blob " + bytes(str(filesize), 'utf-8') + b"\0" + data).hexdigest()
def get_info(repo, filepath):
url = f"https://api.github.com/repos/{repo}/contents/{filepath}"
r = requests.get(url)
sha = r.json()['sha']
content = r.json()['content']
return sha, content
def update():
with open("config.json", "r") as jsonfile:
config = json.load(jsonfile)
print("Updating...")
for repo in config['githubfilesync']:
for reponame, value in repo.items():
for filepath in value:
localfile = pathlib.Path('files').joinpath(pathlib.Path(filepath).name)
print(f" * {localfile} ", end='')
lastsha, content = get_info(reponame, filepath)
if not localfile.exists():
content = base64.b64decode(content)
with open(localfile, 'wb') as f:
f.write(content)
print('-> Installed! ;)')
else:
sha = compute_file_hash(localfile)
if sha == lastsha:
print('-> Up-to-date.')
else:
content = base64.b64decode(content)
with open(localfile, 'wb') as f:
f.write(content)
print('-> Updated!')
def print_menu(menu_options):
for key in menu_options.keys():
print(key, '->', menu_options[key])
def is_sudo():
return True if geteuid() == 0 else False
def ask_port(default_port):
while True:
try:
choice = input(f'What port would you like to listen on ? [{default_port}]: ')
if choice == '':
port = default_port
else:
port = int(choice)
break
except ValueError:
print('Wrong input. Please enter a number ...')
return port
def listen_http(files_dir):
port = ask_port(80)
ips = get_ips()
print('The HTTP server is about to start.\nAvailable endpoints:')
for iname in ips:
if port == 80:
print(f' -> {iname}: http://{ips[iname]}/')
else:
print(f' -> {iname}: http://{ips[iname]}:{port}/')
if port < 1024 and not is_sudo():
print('Listening on any port under 1024 requires root permissions.')
cmd = ['sudo', 'python', '-m', 'http.server', '-d', files_dir, str(port)]
else:
cmd = ['python', '-m', 'http.server', '-d', files_dir, str(port)]
subprocess.call(cmd)
def listen_smb(files_dir):
port = ask_port(445)
ips = get_ips()
print('The HTTP server is about to start.\nAvailable endpoints:')
for iname in ips:
if port == 445:
print(f' -> {iname}: \\\\{ips[iname]}\\share\\')
else:
print(f' -> {iname}: \\\\{ips[iname]}:{port}\\share\\ # This syntax (:port) is not supported on Windows ?')
if port < 1024 and not is_sudo():
print('Listening on any port under 1024 requires root permissions.')
cmd = ['sudo', 'smbserver.py', '-port', str(port), 'share', files_dir]
else:
cmd = ['smbserver.py', '-port', str(port), 'share', files_dir]
subprocess.call(cmd)
def get_public_ip():
return requests.get('https://api.ipify.org').text
def get_ips():
ips = dict()
try:
ips['public'] = get_public_ip()
except requests.exceptions.ConnectionError:
pass
cmd = ['ip', 'a']
out = subprocess.run(cmd, capture_output=True).stdout.decode('utf-8')
lines = out.split('\n')
while("" in lines):
lines.remove("")
for line in lines:
if line[0].isdigit():
iname = line.split(' ')[1].split(':')[0]
if 'inet ' in line:
ip = line.split(' ')[5].split('/')[0]
if ip != '127.0.0.1':
ips[iname] = ip
return ips
def menu_choice(menu_options):
while(True):
print_menu(menu_options)
option = ''
try:
option = int(input('Enter your choice: '))
except ValueError:
print('Wrong input. Please enter a number ...')
files_dir = pathlib.Path.cwd().joinpath('files')
if option == 1:
listen_http(files_dir)
elif option == 2:
listen_smb(files_dir)
elif option == 0:
sys.exit('Quitting')
else:
print('Invalid option. Please enter a valid number.')
if __name__ == '__main__':
menu_options = {
1: 'HTTP',
2: 'SMB',
0: 'Exit',
}
update()
menu_choice(menu_options)