Search and info
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# 🎠horsy [](https://horsy.ml/)
|
||||
# [🎠horsy](https://horsy.ml/) [](https://horsy.ml/)
|
||||
|
||||
## _The Best Open Source Package Manager_
|
||||
|
||||
horsy in Python-powered multi launcher and app installer
|
||||
@@ -7,5 +8,8 @@ horsy in Python-powered multi launcher and app installer
|
||||
- 🎛️CLI and custom very simple Text UI
|
||||
- 🖼️GUI (development)
|
||||
- ✨VirusTotal Magic
|
||||
|
||||
------
|
||||
|
||||
## Installation
|
||||
Project in development, you will see something interesting soon 🤖
|
||||
17
horsy.py
17
horsy.py
@@ -8,14 +8,15 @@ from modules.manager import install, uninstall
|
||||
from modules.virustotal import add_to_cfg
|
||||
from modules.uploader import upload
|
||||
from modules.source import get_source
|
||||
from modules.search import search, info
|
||||
import modules.vars as horsy_vars
|
||||
|
||||
# Getting the arguments
|
||||
parser = argparse.ArgumentParser(description='horsy - the best package manager')
|
||||
parser.add_argument('option', help='options for horsy (install/i | uninstall/un | source/s | update/u | list/l | '
|
||||
'upload)',
|
||||
'upload | search | info)',
|
||||
choices=['install', 'i', 'uninstall', 'un', 'source', 's', 'update', 'u', 'list', 'l', 'upload',
|
||||
'search'],
|
||||
'search', 'info'],
|
||||
nargs='?')
|
||||
parser.add_argument('app', help='app to install/uninstall/download source', nargs='?')
|
||||
parser.add_argument('--vt', help='your virustotal api key (account -> api key in VT)', dest='vt_key')
|
||||
@@ -58,13 +59,13 @@ if args.vt_key:
|
||||
|
||||
# Checking if arguments are empty to use in-app CLI
|
||||
if not args.option:
|
||||
option = ['install', 'uninstall', 'source', 'update', 'list', 'upload', 'search'][
|
||||
option = ['install', 'uninstall', 'source', 'update', 'list', 'upload', 'search', 'info'][
|
||||
tui.menu(['install app', 'uninstall app', 'get source', 'update app', 'list of installed apps',
|
||||
'upload your app', 'search for app'])]
|
||||
'upload your app', 'search for app', 'get information about app'])]
|
||||
isNoArgs = True
|
||||
|
||||
if not args.app:
|
||||
if option not in ['list', 'upload']:
|
||||
if option not in ['list', 'upload', 'update']:
|
||||
print('\n')
|
||||
app = tui.get(f'Select app to {option}')
|
||||
|
||||
@@ -80,5 +81,11 @@ if option in ['uninstall', 'un']:
|
||||
if option in ['source', 's']:
|
||||
get_source(app)
|
||||
|
||||
if option in ['search']:
|
||||
search(app)
|
||||
|
||||
if option in ['info']:
|
||||
info(app)
|
||||
|
||||
if isNoArgs:
|
||||
input('[EXIT] Press enter to exit horsy...')
|
||||
|
||||
@@ -11,15 +11,15 @@ from modules.virustotal import get_key, scan_file, get_report
|
||||
|
||||
def install(package, is_gui=False):
|
||||
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"] == "not found":
|
||||
print("[red]Package not found[/]")
|
||||
return
|
||||
if r["message"] == "Internal server error":
|
||||
print("[red]Internal server error[/]")
|
||||
return
|
||||
@@ -55,7 +55,8 @@ def install(package, is_gui=False):
|
||||
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))
|
||||
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")
|
||||
|
||||
@@ -78,8 +79,8 @@ def install(package, is_gui=False):
|
||||
|
||||
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:
|
||||
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:
|
||||
@@ -120,7 +121,7 @@ def install(package, is_gui=False):
|
||||
|
||||
except:
|
||||
print("[red]Unexpected error[/]")
|
||||
raise
|
||||
# raise
|
||||
return
|
||||
|
||||
|
||||
|
||||
49
modules/search.py
Normal file
49
modules/search.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import textwrap
|
||||
from algoliasearch.search_client import SearchClient
|
||||
import os
|
||||
import requests
|
||||
import modules.vars as horsy_vars
|
||||
import json
|
||||
from rich import print
|
||||
|
||||
|
||||
client = SearchClient.create('VBUJO9OW62', '759f6c7986842fd8218e79e3b9ddb964')
|
||||
index = client.init_index('packages')
|
||||
|
||||
|
||||
def search(query):
|
||||
res = index.search(query)['hits']
|
||||
for i in res:
|
||||
print(textwrap.shorten(f"{i['name']} by {i['authorName']} - {i['description']}",
|
||||
width=os.get_terminal_size().columns))
|
||||
|
||||
|
||||
def info(package):
|
||||
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
|
||||
|
||||
print(f"[bold]{r['name']}{'✅' if r['verified'] else ''} by {r['authorName']}[/]")
|
||||
print(f"{r['description']}")
|
||||
print(f"👍{r['likes']} | 👎{r['dislikes']}")
|
||||
if not r['verified']:
|
||||
print("This package is not verified by the horsy team. This means that it \n"
|
||||
"can be unstable or it can be malware. Most packages have unverified\n"
|
||||
"state, but use it at your own risk.")
|
||||
else:
|
||||
print("This package is [green]verified[/] by the horsy team! \n"
|
||||
"Keep in mind, developers can change the code after verification \n"
|
||||
"We [red]don't call you to trust this app[/], use it at your own risk \n"
|
||||
"but we recommend you more to install verified packages")
|
||||
@@ -2,4 +2,5 @@ rich
|
||||
requests
|
||||
Cryptography
|
||||
Pyinstaller
|
||||
tqdm
|
||||
tqdm
|
||||
algoliasearch
|
||||
Reference in New Issue
Block a user