Compare commits

...

22 Commits

Author SHA1 Message Date
a874398629 core: update requirements 2023-05-31 16:02:39 +02:00
8ea0ce9d20 core: update requirements 2023-05-31 16:01:37 +02:00
2cd08d5fb0 core: use new param of menu to remove useless global variable 2023-05-31 15:58:59 +02:00
55e67a5708 fix: remove print 2023-05-31 15:32:35 +02:00
2e34ae394f fix: remove print and remove a useless style color 2023-05-31 15:30:31 +02:00
06869df157 Merge remote-tracking branch 'refs/remotes/origin/main' 2023-05-31 15:28:56 +02:00
80481868db add: file already view is now in light grey 2023-05-31 15:28:47 +02:00
266f56f8e6 Update 'README.md' 2023-05-30 10:15:52 +00:00
a8279c146c add: save last cursor pos 2023-05-29 19:23:39 +02:00
3dd457c9dd Merge remote-tracking branch 'refs/remotes/origin/main' 2023-05-29 19:02:48 +02:00
03df28754a core: update: terminal_menu lib 2023-05-29 19:01:23 +02:00
d383d416ce Update 'README.md' 2023-05-27 22:18:35 +00:00
24a6dd1124 add subgit 2023-05-28 00:16:46 +02:00
445387dd80 add: requirements.txt 2023-05-28 00:13:16 +02:00
00881516b7 fix: crash: variable name error 2023-05-20 19:22:21 +02:00
36533495e7 fix: remove useless import 2023-05-20 19:17:43 +02:00
619427b81a fix: put import in a try 2023-05-20 19:15:19 +02:00
7a92e2c65f add: windows support 2023-05-20 19:04:18 +02:00
e14bb51127 clean: remove useless dependency 2023-05-20 18:36:40 +02:00
ac198c9cb0 fix: function missing arg 2023-05-17 11:14:23 +02:00
61f535fce4 fix: and clean 2023-05-17 11:08:40 +02:00
d39e9cfb62 fix: and clean 2023-05-16 23:25:05 +02:00
10 changed files with 180 additions and 64 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "terminal_menu"]
path = terminal_menu
url = git@git.chauvet.pro:starnakin/terminal_menu.git

View File

@ -20,6 +20,7 @@ cd VLC_HTTP_LAUNCHER
3. Install the dependencies: 3. Install the dependencies:
```bash ```bash
pip install -r requirements.txt pip install -r requirements.txt
pip install -r terminal_menu/requirements.txt
``` ```
## Usage ## Usage
@ -34,9 +35,11 @@ python3 main.py
To parse the html To parse the html
### Requests ### Requests
To get html with http requests To get html with http requests
### [simple-term-menu](https://pypi.org/project/simple-term-menu/)
To create navigate CLI menu
### [TinyDB](https://pypi.org/project/tinydb/) ### [TinyDB](https://pypi.org/project/tinydb/)
To store credential data and url of the http server To store credential data and url of the http server
### SubProcess and Os ### SubProcess and Os
To launch VLC To launch VLC
### Sys
To exit when a http request failed
### [Colorama](https://github.com/tartley/colorama)
To color text in terminal

View File

@ -11,6 +11,12 @@ class Database():
def get_viewing_data(self, url:str ): def get_viewing_data(self, url:str ):
return (self.viewing_table.get(self.query.url == url)) return (self.viewing_table.get(self.query.url == url))
def set_viewing_data(self, url:str, viewing_data: dict):
self.viewing_table.update(set(url, value), self.query.url == url)
def add_viewing_data(self, viewing_data):
self.viewing_table.insert(viewing_data)
def get_sites(self): def get_sites(self):
return (self.sites_table.all()) return (self.sites_table.all())
@ -45,11 +51,19 @@ class Database():
last_path = cookies.get("last_path") last_path = cookies.get("last_path")
return (last_path) return (last_path)
def get_last_cursor_pos(self):
cookies = self.get_cookies()
last_path = cookies.get("last_cursor_pos")
return (last_path)
def set_last_site(self, value): def set_last_site(self, value):
self.cookies_table.update(set("last_site", value), self.query.id == "0") self.cookies_table.update(set("last_site", value), self.query.id == "0")
def set_last_path(self, value): def set_last_path(self, value):
self.cookies_table.update(set("last_path", value), self.query.id == "0") self.cookies_table.update(set("last_path", value), self.query.id == "0")
def set_last_cursor_pos(self, value):
self.cookies_table.update(set("last_cursor_pos", value), self.query.id == "0")
def add_site(self, site): def add_site(self, site):
self.sites_table.insert(site) self.sites_table.insert(site)

51
main.py
View File

@ -1,8 +1,9 @@
from urllib.parse import unquote, quote from urllib.parse import unquote, quote
from scrapper import get_uri, get_files from scrapper import get_uri, get_files
from urllib.parse import quote, unquote
import player import player
from database import Database from database import Database
from utils import get_url import utils
import menu import menu
def files_navigator(site: dict): def files_navigator(site: dict):
@ -10,20 +11,23 @@ def files_navigator(site: dict):
path = database.get_last_path() path = database.get_last_path()
else: else:
path = '/' path = '/'
database.set_last_site(site.get("id"))
while True: while True:
pos = database.get_last_cursor_pos()
path = get_uri(utils.get_base_url(site) + path)
database.set_last_path(path) database.set_last_path(path)
file = menu.files(get_url(site) + path) file = menu.files(site, path, database, pos)
if (file == None): if (file == None):
return return
elif (file == "../" and path == "/"): elif (file == "../" and path == "/"):
return return
if (not file.endswith("/")): if (not file.endswith("/")):
player.play(get_url(site) + path + file, database) player.play(utils.get_base_url(site) + quote(path + file), database)
else: else:
path = path + file path = path + file
def add_site(): def add_site(database: Database):
site = menu.add_site() site = menu.add_site(database)
database.add_site(site) database.add_site(site)
def config_preview(site_name:str): def config_preview(site_name:str):
@ -36,12 +40,11 @@ def config_preview(site_name:str):
""" """
return (str) return (str)
def sites_deleter(): def sites_deleter(database: Database):
lst = [] lst = []
for i in sites_table.all(): for i in database.get_sites():
lst.append(f"{str(i.get('id'))}: {i.get('name')}") lst.append(f"{str(i.get('id'))}: {i.get('name')}")
terminal_menu = TerminalMenu(lst, show_search_hint=True, preview_title="delete", preview_command=config_preview) choose = menu.site_deleter(lst, database)
choose = terminal_menu.show()
if (choose == None): if (choose == None):
return (1) return (1)
site_name = lst[choose] site_name = lst[choose]
@ -51,20 +54,18 @@ def sites_deleter():
database.set_last_path("") database.set_last_path("")
database.set_last_site("") database.set_last_site("")
def sites_editor(site_id: int): def sites_editor(database: Database):
lst = [] lst = []
for i in database.get_sites(): for i in database.get_sites():
lst.append(f"{str(i.get('id'))}: {i.get('name')}") lst.append(f"{str(i.get('id'))}: {i.get('name')}")
terminal_menu = TerminalMenu(lst, show_search_hint=True, preview_title="delete", preview_command=config_preview) choose = menu.site_editor(lst, database)
choose = terminal_menu.show()
if (choose == None): if (choose == None):
return (1) return (1)
site_name = lst[choose] site_name = lst[choose]
id = int(site_name.split(": ")[0]) id = int(site_name.split(": ")[0])
site = database.get_site_by_id(id) site = database.get_site_by_id(id)
lst = [f"name: {site.get('name')}", f"url: {site.get('url')}", f"user: {site.get('user')}", f"password: {site.get('password')}"] lst = [f"name: {site.get('name')}", f"url: {site.get('url')}", f"user: {site.get('user')}", f"password: {site.get('password')}"]
terminal_menu = TerminalMenu(lst) choose = menu.param_editor(lst)
choose = terminal_menu.show()
if (choose == None): if (choose == None):
return (1); return (1);
for i in lst: for i in lst:
@ -78,34 +79,32 @@ def sites_editor(site_id: int):
elif (choose == 3): elif (choose == 3):
sites_table.update(set("password", input("password: ")), query.id == id) sites_table.update(set("password", input("password: ")), query.id == id)
def sites_navigator(): def sites_navigator(database: Database):
nb_site = database.get_sites_table_len() nb_site = database.get_sites_table_len()
if (nb_site == 0): if (nb_site == 0):
add_site() add_site(database)
nb_site = 1 nb_site = 1
last_site = database.get_last_site() last_site = database.get_last_site()
if (last_site != None): if (last_site != None):
files_navigator(last_site) files_navigator(last_site)
while True: while True:
nb_site = database.get_sites_table_len() nb_site = database.get_sites_table_len()
terminal_menu = TerminalMenu(get(database.get_sites(), "name") + ["", "add", "edit", "delete"], skip_empty_entries=True, show_search_hint=True) choose = menu.sites(database.get_sites())
choose = terminal_menu.show()
if (choose == None): if (choose == None):
return (1) return (1)
if (choose == nb_site + 1): if (choose == nb_site + 1):
add_site(); add_site(database);
elif (choose == nb_site + 2): elif (choose == nb_site + 2):
sites_editor() sites_editor(database)
elif (choose == nb_site + 3): elif (choose == nb_site + 3):
sites_deleter() sites_deleter(database)
sites_navigator() sites_navigator(database)
return return
else: else:
set_url(database.get_sites()[choose]) files_navigator(database.get_sites()[choose])
files_navigator()
database = Database() database = Database()
if (database.get_cookies_table_len() == 0): if (database.get_cookies_table_len() == 0):
database.add_cookies({"last_path": "", "last_site": "", "id": "0"}) database.add_cookies({"last_path": "", "last_site": "", "last_cursor_pos": 0, "id": "0"})
sites_navigator(); sites_navigator(database);

111
menu.py
View File

@ -1,8 +1,26 @@
from simple_term_menu import TerminalMenu
from database import Database from database import Database
from scrapper import get_files, get_uri import scrapper
import utils
from utils import get
import platform
import urllib
import colorama
from terminal_menu.Menu import Menu
url = ""
uri = ""
preview_site = {}
preview_database = ""
def get_user_choice_by_menu(options: list, title = None, preview_command=None, preview_size: float = 0.3, show_search_hint: bool = False, skip_empty_entries = False, cursor_pos: int = 0, preview_args=None):
menu = Menu(options,
title,
preview_body_function=preview_command,
preview_ratio=preview_size,
skip_empty_option=skip_empty_entries,
cursor_pos=cursor_pos,
preview_args=preview_args)
return (menu.show());
def add_site(database: Database) -> dict: def add_site(database: Database) -> dict:
print("add a site:") print("add a site:")
@ -10,35 +28,64 @@ def add_site(database: Database) -> dict:
site.update({"url": input("url without protocol (ip:port):")}) site.update({"url": input("url without protocol (ip:port):")})
site.update({"user": input("user(leave blank):")}) site.update({"user": input("user(leave blank):")})
site.update({"password": input("password(leave blank):")}) site.update({"password": input("password(leave blank):")})
site.update({"id": str(database.get_sites_table_len())}) site.update({"id": database.get_sites_table_len()})
name = input(f"name[{str(len(sites_table.all()))}] :") name = input(f"name[{str(database.get_sites_table_len())}]")
if (name == ""): if (name == ""):
name = str(database.get_sites_table_len()) name = database.get_sites_table_len()
site.update({"name": name}) site.update({"name": name})
return (site) return (site)
def files_preview(filename: str) -> str: def files_preview(url: str) -> str:
if (not filename.endswith("/")): if (not url.endswith("/")):
return (None) return (None)
files = get_files(url + filename) files = scrapper.get_files_by_url(url);
return ("\n".join(files)) return ("\n".join(files))
def files(base_url:str): def get_files_formated_by_viewing_data(database: Database, files: list, site: dict, path: str):
global url out = []
current_url = utils.get_base_url(site) + urllib.parse.quote(path);
for file in files:
if file == "..":
out.append(file);
continue
url = current_url + urllib.parse.quote(file)
viewing_data = database.get_viewing_data(url);
if (viewing_data == None) or (viewing_data.get("finished") == False):
out.append(colorama.Style.BRIGHT + file)
else:
out.append(colorama.Fore.LIGHTBLACK_EX + file);
return (out);
url = base_url def get_files_path(current_url: str, files: list):
files = get_files(base_url) out = []
terminal_menu = TerminalMenu(files, for file in files:
out.append(current_url + file);
return (out);
def files(site:dict, path:str, database:Database, pos:int):
current_url = scrapper.get_url(site, path);
files = scrapper.get_files(site, path)
files_displayed = get_files_formated_by_viewing_data(database, files, site, path)
preview_args = get_files_path(current_url, files)
choose = get_user_choice_by_menu(files_displayed,
preview_command=files_preview, preview_command=files_preview,
preview_args=preview_args,
preview_size=0.3, preview_size=0.3,
show_search_hint=True, show_search_hint=True,
title=f"Index of {get_uri(url)}") title=f"Index of {path}",
choose = terminal_menu.show() cursor_pos = pos)
if (choose == None):
database.set_last_cursor_pos(0)
return (None)
database.set_last_cursor_pos(choose)
return (files[choose]) return (files[choose])
def config_preview(site_name:str): def config_preview(site_name:str):
id = int(site_name.split(": ")[0]) id = int(site_name.split(": ")[0])
site = database.get_site_by_id(id) site = preview_database.get_site_by_id(id)
if (site == None):
return
str = f""" str = f"""
url: {site.get('url')} url: {site.get('url')}
user: {site.get('user')} user: {site.get('user')}
@ -46,21 +93,35 @@ def config_preview(site_name:str):
""" """
return (str) return (str)
def site_deleter(sites: list): def site_deleter(sites, database: Database):
terminal_menu = TerminalMenu(sites, global preview_database
preview_database = database
choose = get_user_choice_by_menu(sites,
show_search_hint=True, show_search_hint=True,
preview_title="delete", preview_title="delete",
preview_command=config_preview) preview_command=config_preview)
choose = terminal_menu.show()
return (choose) return (choose)
def site_editor(lst: list): def param_editor(lst: list):
terminal_menu = TerminalMenu(lst + ["", "quit"], choose = get_user_choice_by_menu(lst)
return (choose)
def site_editor(lst: list, database: Database):
global preview_database
preview_database = database
choose = get_user_choice_by_menu(lst + ["", "quit"],
skip_empty_entries=True, skip_empty_entries=True,
show_search_hint=True, show_search_hint=True,
preview_title="Edit", title="Edit")
preview_command=config_preview)
choose = terminal_menu.show()
if (choose == len(lst) + 1): if (choose == len(lst) + 1):
return (None) return (None)
return (choose) return (choose)
def sites(sites: list):
nb_site = len(sites)
choose = get_user_choice_by_menu(get(sites, "name") + ["", "add", "edit", "delete"],
skip_empty_entries=True,
show_search_hint=True)
return (choose)

View File

@ -1,13 +1,14 @@
from simple_term_menu import TerminalMenu
import vlc
from database import Database from database import Database
import menu
import terminal_menu.Menu as terminal_menu
from time import sleep
import os, subprocess
def play(url: str, database: Database): def _play(url: str, database: Database):
start_pos = 0 start_pos = 0
viewing_data = database.get_viewing_data(url) viewing_data = database.get_viewing_data(url)
if (viewing_data != None): if (viewing_data != None):
menu = TerminalMenu([f"go back to {str(viewing_data.get('last_pos'))}", "restart from 0:00"]) response = menu.start_pos([f"go back to {str(viewing_data.get('last_pos'))}", "restart from 0:00"])
response = menu.show()
if (response == None): if (response == None):
return (1); return (1);
elif (response == 0): elif (response == 0):
@ -17,3 +18,19 @@ def play(url: str, database: Database):
media = vlc_instance.media_new(url) media = vlc_instance.media_new(url)
player.set_media(media) player.set_media(media)
player.play() player.play()
sleep(1)
player.video_set_mouse_input(True)
player.set_position(start_pos / player.get_length())
player.set_fullscreen(True)
while True:
print("duration:", player.get_time(),":",player.get_length())
def play(url: str, database: Database):
viewing_data = database.get_viewing_data(url);
if (viewing_data == None):
viewing_data = {"url": url, "finished": True}
database.add_viewing_data(viewing_data);
with open(os.devnull, 'wb') as devnull:
subprocess.check_call(['vlc', url], stdout=devnull, stderr=subprocess.STDOUT)

View File

@ -2,11 +2,10 @@ beautifulsoup4==4.12.2
bs4==0.0.1 bs4==0.0.1
certifi==2023.5.7 certifi==2023.5.7
charset-normalizer==3.1.0 charset-normalizer==3.1.0
enzyme==0.4.1 colorama==0.4.6
getch==1.0
idna==3.4 idna==3.4
install==1.3.5
requests==2.30.0 requests==2.30.0
simple-term-menu==1.6.1
soupsieve==2.4.1 soupsieve==2.4.1
tinydb==4.7.1 tinydb==4.7.1
urllib3==2.0.2 urllib3==2.0.2

View File

@ -1,13 +1,25 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from urllib.parse import quote, unquote from urllib.parse import quote, unquote
import utils
import sys
import requests import requests
def get_files(url: str) -> []: def get_url(site: dict, path: str):
url = utils.get_base_url(site) + quote(path)
return (url)
def get_files(site:dict, path:str) -> []:
url = get_url(site, path)
files = get_files_by_url(url)
return (files)
def get_files_by_url(url: str):
if (url in ["/../", "../"]): if (url in ["/../", "../"]):
return ([]) return ([])
response = requests.get(url) response = requests.get(url)
if (response.status_code != 200): if (response.status_code != 200):
print("connection:", response.reason) print("connection:", response.reason)
print(url)
sys.exit(1) sys.exit(1)
soup = BeautifulSoup(response.text, 'html.parser') soup = BeautifulSoup(response.text, 'html.parser')
files = [] files = []
@ -15,6 +27,7 @@ def get_files(url: str) -> []:
files.append(unquote(element["href"])) files.append(unquote(element["href"]))
return (files) return (files)
def get_uri(url: str) -> []: def get_uri(url: str) -> []:
if (url in ["/../", "../"]): if (url in ["/../", "../"]):
return ([]) return ([])

1
terminal_menu Submodule

Submodule terminal_menu added at 5c07857c79

View File

@ -1,6 +1,12 @@
def get_url(site: dict): def get_base_url(site: dict):
if (site.get("user") == "" and site.get("password") == ""): if (site.get("user") == "" and site.get("password") == ""):
return (f"http://{site.get('url')}") return (f"http://{site.get('url')}")
else: else:
return (f"http://{site.get('user')}:{site.get('password')}@{site.get('url')}") return (f"http://{site.get('user')}:{site.get('password')}@{site.get('url')}")
def get(dictionnarys: list, key: str):
lst = []
for dictionnary in dictionnarys:
lst.append(dictionnary.get(key))
return (lst)