GUI development
This commit is contained in:
@@ -74,13 +74,13 @@ def search_gui():
|
|||||||
ui.search_table.setItem(i // 4, i % 4, QtWidgets.QTableWidgetItem(str(found[i])))
|
ui.search_table.setItem(i // 4, i % 4, QtWidgets.QTableWidgetItem(str(found[i])))
|
||||||
|
|
||||||
def install_app():
|
def install_app():
|
||||||
from modules.manager import install
|
from modules.gui_manager import install
|
||||||
try:
|
try:
|
||||||
app_name = ui.search_table.currentItem().text()
|
app_name = ui.search_table.currentItem().text()
|
||||||
if app_name == "":
|
if app_name == "":
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
install(app_name, True)
|
install(app_name, UiDownloadWindow, download_ui)
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -91,7 +91,9 @@ def get_source_gui():
|
|||||||
if app_name == "":
|
if app_name == "":
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
get_source(app_name)
|
source = get_source(app_name)
|
||||||
|
if source is not None:
|
||||||
|
gui.popup("Error", source)
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -829,6 +829,9 @@ class Ui_DownloadWindow(object):
|
|||||||
self.logs_box.setPlaceholderText(_translate("MainWindow", "Logs"))
|
self.logs_box.setPlaceholderText(_translate("MainWindow", "Logs"))
|
||||||
|
|
||||||
|
|
||||||
|
def popup(title, text):
|
||||||
|
QtWidgets.QMessageBox.information(QtWidgets.QMainWindow(), title, text)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|||||||
136
modules/gui_manager.py
Normal file
136
modules/gui_manager.py
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
import json
|
||||||
|
import threading
|
||||||
|
import requests
|
||||||
|
import modules.vars as horsy_vars
|
||||||
|
import os
|
||||||
|
import zipfile
|
||||||
|
from modules.virustotal import get_key, scan_file, get_report
|
||||||
|
|
||||||
|
|
||||||
|
def install(package, UiDownloadWindow=None, ui_download=None):
|
||||||
|
r = requests.get(f"{horsy_vars.protocol}{horsy_vars.server_url}/packages/json/{package}").text
|
||||||
|
if r == "":
|
||||||
|
print(f"[red]Package {package} not found[/]")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
r = json.loads(r)
|
||||||
|
except:
|
||||||
|
print("[red]Error with unsupported message[/]")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
if r["message"] == "Internal server error":
|
||||||
|
print("[red]Internal server error[/]")
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f"[green]App {r['name']} found, information loaded[/]")
|
||||||
|
|
||||||
|
if not os.path.exists('{1}apps/{0}'.format(r['name'], horsy_vars.horsypath)):
|
||||||
|
os.makedirs('{1}apps/{0}'.format(r['name'], horsy_vars.horsypath))
|
||||||
|
|
||||||
|
# if not is_gui:
|
||||||
|
print(f"Downloading {r['url'].split('/')[-1]}")
|
||||||
|
|
||||||
|
chunk_size = 1024
|
||||||
|
file_r = requests.get(r['url'], stream=True)
|
||||||
|
with open('{2}apps/{0}/{1}'.format(r['name'], r['url'].split('/')[-1], horsy_vars.horsypath), "wb") as f:
|
||||||
|
pbar = tqdm(unit="B", unit_scale=True, total=int(file_r.headers['Content-Length']))
|
||||||
|
for chunk in file_r.iter_content(chunk_size=chunk_size):
|
||||||
|
if chunk:
|
||||||
|
pbar.update(len(chunk))
|
||||||
|
f.write(chunk)
|
||||||
|
pbar.close()
|
||||||
|
|
||||||
|
print(f"Starting virustotal scan")
|
||||||
|
if not get_key():
|
||||||
|
print(f"[red]Virustotal api key not found[/]")
|
||||||
|
print(f"You can add it by entering [bold]horsy --vt \[your key][/] in terminal")
|
||||||
|
else:
|
||||||
|
print(f"[green]Virustotal api key found[/]")
|
||||||
|
print(f"[italic white]If you want to disable scan, type [/][bold]horsy --vt disable[/]"
|
||||||
|
f"[italic white] in terminal[/]")
|
||||||
|
scan_file('{2}apps/{0}/{1}'.format(r['name'], r['url'].split('/')[-1], horsy_vars.horsypath))
|
||||||
|
print(f"[green]Virustotal scan finished[/]")
|
||||||
|
analysis = get_report('{2}apps/{0}/{1}'.format(r['name'], r['url'].split('/')[-1],
|
||||||
|
horsy_vars.horsypath))
|
||||||
|
print(f"[green]You can see report by opening: [white]{analysis['link']}[/]")
|
||||||
|
print(f"{analysis['detect']['malicious']} antivirus flagged this file as malicious")
|
||||||
|
|
||||||
|
print(f"[green][OK] Done[/]")
|
||||||
|
|
||||||
|
def unzip(file, where):
|
||||||
|
with zipfile.ZipFile(file, 'r') as zip_ref:
|
||||||
|
zip_ref.extractall(where)
|
||||||
|
print(f"[green]Extracted[/]")
|
||||||
|
|
||||||
|
if r['url'].split('.')[-1] == 'zip':
|
||||||
|
print(f"Extracting {r['url'].split('/')[-1]}")
|
||||||
|
unzip('{2}apps/{0}/{1}'.format(r['name'], r['url'].split('/')[-1], horsy_vars.horsypath),
|
||||||
|
'{1}apps/{0}'.format(r['name'], horsy_vars.horsypath))
|
||||||
|
|
||||||
|
if r['download']:
|
||||||
|
print(f"Found dependency")
|
||||||
|
# if not is_gui:
|
||||||
|
print(f"Downloading {r['download'].split('/')[-1]}")
|
||||||
|
|
||||||
|
chunk_size = 1024
|
||||||
|
file_r = requests.get(r['download'], stream=True)
|
||||||
|
with open('{2}apps/{0}/{1}'.format(r['name'], r['download'].split('/')[-1], horsy_vars.horsypath),
|
||||||
|
"wb") as f:
|
||||||
|
pbar = tqdm(unit="B", unit_scale=True, total=int(file_r.headers['Content-Length']))
|
||||||
|
for chunk in file_r.iter_content(chunk_size=chunk_size):
|
||||||
|
if chunk:
|
||||||
|
pbar.update(len(chunk))
|
||||||
|
f.write(chunk)
|
||||||
|
pbar.close()
|
||||||
|
|
||||||
|
print(f"Starting virustotal scan")
|
||||||
|
if not get_key():
|
||||||
|
print(f"[red]Virustotal api key not found[/]")
|
||||||
|
print(f"You can add it by entering [italic white]horsy --vt \[your key][/] in terminal")
|
||||||
|
else:
|
||||||
|
print(f"[green]Virustotal api key found[/]")
|
||||||
|
scan_file('{2}apps/{0}/{1}'.format(r['name'], r['download'].split('/')[-1], horsy_vars.horsypath))
|
||||||
|
print(f"[green]Virustotal scan finished[/]")
|
||||||
|
analysis = get_report('{2}apps/{0}/{1}'.format(r['name'], r['download'].split('/')[-1],
|
||||||
|
horsy_vars.horsypath))
|
||||||
|
print(f"[green]You can see report by opening: [white]{analysis['link']}[/]")
|
||||||
|
print(f"{analysis['detect']['malicious']} antivirus flagged this file as malicious")
|
||||||
|
if analysis['detect']['malicious'] > 0:
|
||||||
|
print(f"[red]Dependency can be malicious. It may run now, if this added to installation "
|
||||||
|
f"config[/]")
|
||||||
|
input("Press enter if you want continue, or ctrl+c to exit")
|
||||||
|
|
||||||
|
if r['install']:
|
||||||
|
print(f"Found install option")
|
||||||
|
threading.Thread(target=os.system, args=('{2}apps/{0}/{1}'.format(r['name'], r['install'],
|
||||||
|
horsy_vars.horsypath),)).start()
|
||||||
|
|
||||||
|
print(f"Generating launch script")
|
||||||
|
|
||||||
|
with open('{1}apps/{0}.bat'.format(r['name'], horsy_vars.horsypath), 'w') as f:
|
||||||
|
f.write(f"@ECHO off\n")
|
||||||
|
f.write(f"{horsy_vars.horsypath}apps/{r['name']}/{r['run']} %*\n")
|
||||||
|
|
||||||
|
print(f"[green][OK] All done![/]")
|
||||||
|
print(f"[green]You can run your app by entering [italic white]{r['name']}[/] in terminal[/]")
|
||||||
|
|
||||||
|
except:
|
||||||
|
print("[red]Unexpected error[/]")
|
||||||
|
# raise
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def uninstall(package, is_gui=False):
|
||||||
|
if os.path.exists('{1}apps/{0}'.format(package, horsy_vars.horsypath)):
|
||||||
|
os.system('rmdir /s /q "{1}apps/{0}"'.format(package, horsy_vars.horsypath))
|
||||||
|
print(f"[green][OK] Files deleted[/]")
|
||||||
|
else:
|
||||||
|
print(f"[red]App {package} is not installed or doesn't have files[/]")
|
||||||
|
if os.path.isfile('{1}apps/{0}.bat'.format(package, horsy_vars.horsypath)):
|
||||||
|
os.remove("{1}apps/{0}.bat".format(package, horsy_vars.horsypath))
|
||||||
|
print(f"[green][OK] Launch script deleted[/]")
|
||||||
|
else:
|
||||||
|
print(f"[red]App {package} is not installed or doesn't have launch script[/]")
|
||||||
@@ -9,7 +9,7 @@ import zipfile
|
|||||||
from modules.virustotal import get_key, scan_file, get_report
|
from modules.virustotal import get_key, scan_file, get_report
|
||||||
|
|
||||||
|
|
||||||
def install(package, is_gui=False):
|
def install(package, is_gui=False, UiDownloadWindow=None, ui_download=None):
|
||||||
r = requests.get(f"{horsy_vars.protocol}{horsy_vars.server_url}/packages/json/{package}").text
|
r = requests.get(f"{horsy_vars.protocol}{horsy_vars.server_url}/packages/json/{package}").text
|
||||||
if r == "":
|
if r == "":
|
||||||
print(f"[red]Package {package} not found[/]")
|
print(f"[red]Package {package} not found[/]")
|
||||||
|
|||||||
@@ -11,18 +11,20 @@ def get_source(package):
|
|||||||
r = json.loads(r)
|
r = json.loads(r)
|
||||||
except:
|
except:
|
||||||
print("[red]Error with unsupported message[/]")
|
print("[red]Error with unsupported message[/]")
|
||||||
return
|
return "Error with unsupported message"
|
||||||
try:
|
try:
|
||||||
if r["message"] == "not found":
|
if r["message"] == "not found":
|
||||||
print("[red]Package not found[/]")
|
print("[red]Package not found[/]")
|
||||||
return
|
return "Package not found"
|
||||||
if r["message"] == "Internal server error":
|
if r["message"] == "Internal server error":
|
||||||
print("[red]Internal server error[/]")
|
print("[red]Internal server error[/]")
|
||||||
return
|
return "Internal server error"
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
webbrowser.open(r["sourceUrl"])
|
webbrowser.open(r["sourceUrl"])
|
||||||
|
return None
|
||||||
except:
|
except:
|
||||||
print("[red]No source code available for this app[/]")
|
print("[red]No source code available for this app[/]")
|
||||||
|
return "No source code available for this app"
|
||||||
|
|||||||
@@ -97,18 +97,15 @@ def upload(is_gui=False, ui=None, login_ui=None, Ui_LoginWindow=None):
|
|||||||
|
|
||||||
project_name = ui.packagename_box.text()
|
project_name = ui.packagename_box.text()
|
||||||
if not matches(project_name) or len(project_name) > 64 or len(project_name) < 3:
|
if not matches(project_name) or len(project_name) > 64 or len(project_name) < 3:
|
||||||
print('[red]Invalid project name[/red]')
|
return 'Invalid project name'
|
||||||
return
|
|
||||||
|
|
||||||
description = ui.package_desc_box.toPlainText()
|
description = ui.package_desc_box.toPlainText()
|
||||||
if len(description) > 256:
|
if len(description) > 256:
|
||||||
print('[red]Description is too long[/red]')
|
return 'Description is too long'
|
||||||
return
|
|
||||||
|
|
||||||
url = ui.url_of_exe_box.text()
|
url = ui.url_of_exe_box.text()
|
||||||
if not urlmatch(url):
|
if not urlmatch(url):
|
||||||
print('[red]Invalid file url, also it should end on .exe or .zip[/red]')
|
return 'Invalid file url, also it should end on .exe or .zip'
|
||||||
return
|
|
||||||
|
|
||||||
source_url = ui.source_url_box.text()
|
source_url = ui.source_url_box.text()
|
||||||
source_url = None if source_url == '' else source_url
|
source_url = None if source_url == '' else source_url
|
||||||
@@ -117,16 +114,14 @@ def upload(is_gui=False, ui=None, login_ui=None, Ui_LoginWindow=None):
|
|||||||
if download == '':
|
if download == '':
|
||||||
download = None
|
download = None
|
||||||
elif not urlmatch(download):
|
elif not urlmatch(download):
|
||||||
print('[red]Invalid download url[/red]')
|
return 'Invalid download url'
|
||||||
return
|
|
||||||
|
|
||||||
install = ui.dependency_run_box.text()
|
install = ui.dependency_run_box.text()
|
||||||
install = None if install == '' else install
|
install = None if install == '' else install
|
||||||
|
|
||||||
run = ui.main_exe_box.text()
|
run = ui.main_exe_box.text()
|
||||||
if run == '':
|
if run == '':
|
||||||
print('[red]Please, specify runtime[/red]')
|
return 'Please, specify runtime'
|
||||||
return
|
|
||||||
|
|
||||||
request = {
|
request = {
|
||||||
'auth': auth,
|
'auth': auth,
|
||||||
@@ -154,22 +149,24 @@ def upload(is_gui=False, ui=None, login_ui=None, Ui_LoginWindow=None):
|
|||||||
r = None
|
r = None
|
||||||
|
|
||||||
elif r['message'] == 'Internal server error':
|
elif r['message'] == 'Internal server error':
|
||||||
print('[red]Internal server error, request is broken[/red]')
|
print('[red]Internal server error[/red]')
|
||||||
break
|
return 'Internal server error'
|
||||||
|
|
||||||
elif r['message'] == 'Success':
|
elif r['message'] == 'Success':
|
||||||
print('[green]Success, your project is created. You can install it by running[/] '
|
print('[green]Success, your project is created. You can install it by running[/] '
|
||||||
'[i]horsy install {0}[/]'.format(request['name']))
|
'[i]horsy install {0}[/]'.format(request['name']))
|
||||||
break
|
return 'Success, your project is created. You can install it by running horsy install {0}'.format(
|
||||||
|
request['name'])
|
||||||
|
|
||||||
elif 'already exists' in r['message']:
|
elif 'already exists' in r['message']:
|
||||||
print(f"[red]{r['message']}[/red]")
|
print(r['message'])
|
||||||
|
return {r['message']}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print('[red]Unknown error, please try again[/red]')
|
print('[red]Unknown error, please try again[/red]')
|
||||||
print('Server response:')
|
print('Server response:')
|
||||||
print(r)
|
print(r)
|
||||||
break
|
return 'Unknown error, please try again, \n Server response: \n' + str(r)
|
||||||
except:
|
except:
|
||||||
with open(f'error_{time.time()}.txt', 'w') as f:
|
with open(f'error_{time.time()}.txt', 'w') as f:
|
||||||
f.write(str(r))
|
f.write(str(r))
|
||||||
|
|||||||
Reference in New Issue
Block a user