From 1f8d857f1f0dd2e5fbb932fb132f9da339cfc25d Mon Sep 17 00:00:00 2001 From: back-to Date: Fri, 17 Jun 2022 13:10:22 +0200 Subject: [PATCH] added /cmd/ example, removed --file support --- CHANGELOG.md | 2 + MANIFEST.in | 2 - README.md | 79 +++++++------------------- liveproxy/__init__.py | 2 +- liveproxy/argparser.py | 123 ++++++++++++----------------------------- liveproxy/files.py | 64 --------------------- liveproxy/main.py | 82 +++++++++++++-------------- 7 files changed, 99 insertions(+), 255 deletions(-) delete mode 100644 liveproxy/files.py diff --git a/CHANGELOG.md b/CHANGELOG.md index bcb55b2..bb60e63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - YT-DLP can now also be used. +- new URL with `/cmd/commands without encoding` ### Changed @@ -15,6 +16,7 @@ - Python 3.6 support - URL with `/play/` `/streamlink/` `/301/` `/streamlink_301/` such as `http://127.0.0.1:53422/play/?url=https://foo.bar&q=worst` +- commands to create files for Base64, use direct URLs with /cmd/ instead ## 2.0.0 diff --git a/MANIFEST.in b/MANIFEST.in index 0258c60..5d62e09 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,5 @@ include CHANGELOG.md include README.md -recursive-include tests *py - prune */__pycache__ global-exclude *.pyc *~ *.bak *.swp *.pyo diff --git a/README.md b/README.md index 4171bd3..f023b68 100644 --- a/README.md +++ b/README.md @@ -27,14 +27,6 @@ sudo -H python3 -m pip install --upgrade liveproxy sudo -H python3 -m pip install --upgrade git+https://github.com/back-to/liveproxy.git ``` -## source - -```text -git clone https://github.com/back-to/liveproxy.git -cd liveproxy -python3 setup.py install -``` - # URL-GUIDE ## Tutorial @@ -59,92 +51,63 @@ Now that LiveProxy is running, you will have to create a valid URL. For the examples here, ``53422`` is used as **default port**. -## Base64 - -You will need to base64 encode your used commands. +## CMD -#### Streamlink +If needed, you can use `quote` for special characters +https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote ```text -http://127.0.0.1:53422/base64/STREAMLINK-COMMANDS/ +http://127.0.0.1:53422/cmd/COMMANDS/ ``` Example for `streamlink https://www.youtube.com/user/france24/live best` ```text -http://127.0.0.1:53422/base64/c3RyZWFtbGluayBodHRwczovL3d3dy55b3V0dWJlLmNvbS91c2VyL2ZyYW5jZTI0L2xpdmUgYmVzdA==/ +http://127.0.0.1:53422/cmd/streamlink https://www.youtube.com/user/france24/live best/ ``` -#### Youtube-DL +Example for `yt-dlp https://www.youtube.com/user/france24/live` ```text -http://127.0.0.1:53422/base64/YOUTUBE-DL-COMMANDS/ +http://127.0.0.1:53422/cmd/yt-dlp https://www.youtube.com/user/france24/live/ ``` -Example for `youtube-dl https://www.youtube.com/user/france24/live` +## Base64 -```text -http://127.0.0.1:53422/base64/eW91dHViZS1kbCBodHRwczovL3d3dy55b3V0dWJlLmNvbS91c2VyL2ZyYW5jZTI0L2xpdmU=/ -``` +You will need to base64 encode your used commands. -#### YT-DLP +#### Streamlink ```text -http://127.0.0.1:53422/base64/YT-DLP-COMMANDS/ +http://127.0.0.1:53422/base64/STREAMLINK-COMMANDS/ ``` -Example for `yt-dlp https://www.youtube.com/user/france24/live` +Example for `streamlink https://www.youtube.com/user/france24/live best` ```text -http://127.0.0.1:53422/base64/eXQtZGxwIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3VzZXIvZnJhbmNlMjQvbGl2ZQ==/ +http://127.0.0.1:53422/base64/c3RyZWFtbGluayBodHRwczovL3d3dy55b3V0dWJlLmNvbS91c2VyL2ZyYW5jZTI0L2xpdmUgYmVzdA==/ ``` -### LiveProxy-Command - -LiveProxy can create this URL automatically. - -Create a new file with your commands. +#### Youtube-DL ```text -#EXTM3U -#EXTINF:-1,Arte FR -streamlink https://www.arte.tv/fr/direct/ 720p,720p_alt,best -#EXTINF:-1,France24 -streamlink https://www.youtube.com/user/france24/live best -#EXTINF:-1 tvg-id="EuroNews" tvg-name="EuroNews",Euronews -streamlink https://www.euronews.com/live best -#EXTINF:-1,France24 YOUTUBE-DL -youtube-dl https://www.youtube.com/user/france24/live -#EXTINF:-1,France24 YT-DLP -yt-dlp https://www.youtube.com/user/france24/live +http://127.0.0.1:53422/base64/YOUTUBE-DL-COMMANDS/ ``` -For this example the filename is `example.m3u` +Example for `youtube-dl https://www.youtube.com/user/france24/live` ```text -liveproxy --file example.m3u +http://127.0.0.1:53422/base64/eW91dHViZS1kbCBodHRwczovL3d3dy55b3V0dWJlLmNvbS91c2VyL2ZyYW5jZTI0L2xpdmU=/ ``` -It will create a new file `example.m3u.new` with valid URLs, -only lines with `streamlink`, `youtube-dl`, `youtube_dl`, `yt-dlp` or `yt_dlp` at the start will be changed. +#### YT-DLP ```text -#EXTM3U -#EXTINF:-1,Arte FR -http://127.0.0.1:53422/base64/c3RyZWFtbGluayBodHRwczovL3d3dy5hcnRlLnR2L2ZyL2RpcmVjdC8gNzIwcCw3MjBwX2FsdCxiZXN0/ -#EXTINF:-1,France24 -http://127.0.0.1:53422/base64/c3RyZWFtbGluayBodHRwczovL3d3dy55b3V0dWJlLmNvbS91c2VyL2ZyYW5jZTI0L2xpdmUgYmVzdA==/ -#EXTINF:-1 tvg-id="EuroNews" tvg-name="EuroNews",Euronews -http://127.0.0.1:53422/base64/c3RyZWFtbGluayBodHRwczovL3d3dy5ldXJvbmV3cy5jb20vbGl2ZSBiZXN0/ -#EXTINF:-1,France24 YOUTUBE-DL -http://127.0.0.1:53422/base64/eW91dHViZS1kbCBodHRwczovL3d3dy55b3V0dWJlLmNvbS91c2VyL2ZyYW5jZTI0L2xpdmU=/ -#EXTINF:-1,France24 YT-DLP -http://127.0.0.1:53422/base64/eXQtZGxwIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3VzZXIvZnJhbmNlMjQvbGl2ZQ==/ +http://127.0.0.1:53422/base64/YT-DLP-COMMANDS/ ``` -You can also use ``--file-output`` for a specified new file, -but be careful don't overwrite any important files. +Example for `yt-dlp https://www.youtube.com/user/france24/live` ```text -liveproxy --file example.m3u --file-output my_file.m3u +http://127.0.0.1:53422/base64/eXQtZGxwIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3VzZXIvZnJhbmNlMjQvbGl2ZQ==/ ``` diff --git a/liveproxy/__init__.py b/liveproxy/__init__.py index 7f5003a..95f848e 100644 --- a/liveproxy/__init__.py +++ b/liveproxy/__init__.py @@ -1 +1 @@ -__version__ = '2.1.0.dev3' +__version__ = "2.1.0.dev4" diff --git a/liveproxy/argparser.py b/liveproxy/argparser.py index 0adade6..b99741d 100644 --- a/liveproxy/argparser.py +++ b/liveproxy/argparser.py @@ -3,28 +3,19 @@ from liveproxy import __version__ as liveproxy_version -FILE_OUTPUT_LIST = ['.m3u', '.m3u8', '.new', '.txt'] - - -def file_output_list(value): - if not value.endswith(tuple(FILE_OUTPUT_LIST)): - raise ValueError - - return value - def num(type, min=None, max=None): def func(value): value = type(value) if min is not None and not (value > min): raise argparse.ArgumentTypeError( - '{0} value must be more than {1} but is {2}'.format( + "{0} value must be more than {1} but is {2}".format( type.__name__, min, value ) ) if max is not None and not (value <= max): raise argparse.ArgumentTypeError( - '{0} value must be at most {1} but is {2}'.format( + "{0} value must be at most {1} but is {2}".format( type.__name__, max, value ) ) @@ -35,112 +26,70 @@ def func(value): parser = argparse.ArgumentParser( - fromfile_prefix_chars='@', + fromfile_prefix_chars="@", add_help=False, - usage='%(prog)s --host [HOST] --port [PORT]', - description=dedent(''' + usage="%(prog)s --host [HOST] --port [PORT]", + description=dedent(""" LiveProxy is a local URL Proxy for Streamlink - '''), - epilog=dedent(''' + """), + epilog=dedent(""" For more in-depth documentation see: - https://liveproxy.github.io/ - ''') + https://github.com/back-to/liveproxy/blob/master/README.md + """) ) -general = parser.add_argument_group('General options') +general = parser.add_argument_group("General options") general.add_argument( - '-h', '--help', - action='store_true', - help=''' + "-h", "--help", + action="store_true", + help=""" Show this help message and exit. - ''' + """ ) general.add_argument( - '-V', '--version', - action='version', - version='%(prog)s {0}'.format(liveproxy_version), - help=''' + "-V", "--version", + action="version", + version="%(prog)s {0}".format(liveproxy_version), + help=""" Show version number and exit. - ''' + """ ) general.add_argument( - '--loglevel', - metavar='LEVEL', - choices=('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'), - default='INFO', - help=''' + "--loglevel", + metavar="LEVEL", + choices=("CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "NOTSET"), + default="INFO", + help=""" Set the log message threshold. https://docs.python.org/3/library/logging.html#logging-levels Valid levels are: CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET - ''' + """ ) -server = parser.add_argument_group('Server options') +server = parser.add_argument_group("Server options") server.add_argument( - '--host', - metavar='HOST', + "--host", + metavar="HOST", type=str, - default='127.0.0.1', - help=''' + default="127.0.0.1", + help=""" A fixed IP to use as a HOST. - Can also be used for `--file` - Default is 127.0.0.1 - ''' + """ ) server.add_argument( - '--port', - metavar='PORT', + "--port", + metavar="PORT", type=num(int, min=0, max=65535), default=53422, - help=''' + help=""" A fixed PORT to use for the HOST. - Can also be used for `--file` - Default is 53422 - ''' -) - -url = parser.add_argument_group('URL options') -url.add_argument( - '--file', - metavar='FILE', - help=''' - Read the given file and create a new file with base64 - encoded URLs for LiveProxy. - - It will only encode lines that starts with `streamlink`, - other lines will be ignored. - - You can use `--file-output` to specify the new file. - ''' -) -url.add_argument( - '--file-output', - metavar='FILE', - type=file_output_list, - help=''' - Use a custom output file for `--file` instead of a '.new' file. - - Valid files are: {0} - '''.format(' '.join(FILE_OUTPUT_LIST)) -) -url.add_argument( - '--format', - default='m3u', - choices=['m3u', 'e2'], - help=''' - Some playlists need special settings: - - For E2 Linux Receivers with Userbouquets, - use `--format e2` - - Default is m3u - ''', + """ ) -__all__ = ['parser'] +__all__ = ["parser"] diff --git a/liveproxy/files.py b/liveproxy/files.py deleted file mode 100644 index 838b3bf..0000000 --- a/liveproxy/files.py +++ /dev/null @@ -1,64 +0,0 @@ -import base64 -import codecs -import logging -import os - -from liveproxy.argparser import FILE_OUTPUT_LIST - -log = logging.getLogger(__name__.replace('liveproxy.', '')) - - -def create_file(args): - HOST = str(args.host) - PORT = int(args.port) - - if not os.path.isfile(args.file): - log.error('File does not exist: {0}'.format(args.file)) - return - elif not os.access(args.file, os.F_OK): - log.error('Can\'t read file: {0}'.format(args.file)) - return - - if args.format == 'm3u': - URL_TEMPLATE = 'http://{host}:{port}/base64/{base64}/' - # %3a - elif args.format == 'e2': - URL_TEMPLATE = 'http%3a//{host}%3a{port}/base64/{base64}/' - else: - return - - new_lines = [] - log.info('open old file: {0}'.format(args.file)) - with codecs.open(args.file, 'r', 'utf-8') as temp: - text = temp.read() - for line in text.splitlines(): - if line.startswith(('streamlink', 'youtube-dl', 'youtube_dl', 'yt-dlp', 'yt_dlp')): - line = URL_TEMPLATE.format( - host=HOST, - port=PORT, - base64=base64.urlsafe_b64encode(line.encode('utf-8')).decode('utf-8'), - ) - new_lines.append(line) - - if args.file_output: - new_file = args.file_output - else: - new_file = args.file + '.new' - - if args.file == new_file: - log.warning('Don\'t use the same name for the old and the new file.') - return - - if not new_file.endswith(tuple(FILE_OUTPUT_LIST)): - log.error(f'Invalid file type: {new_file}') - return - - log.info('open new file: {0}'.format(new_file)) - with codecs.open(new_file, 'w', 'utf-8') as new_temp: - for line in new_lines: - new_temp.write(line + '\n') - - log.info('Done.') - - -__all__ = ('create_file') diff --git a/liveproxy/main.py b/liveproxy/main.py index 2262d51..8d7f564 100644 --- a/liveproxy/main.py +++ b/liveproxy/main.py @@ -7,10 +7,9 @@ from liveproxy import __version__ as liveproxy_version from liveproxy.argparser import parser -from liveproxy.files import create_file from liveproxy.server import HTTPRequest, ThreadedHTTPServer -log = logging.getLogger(__name__.replace('liveproxy.', '')) +log = logging.getLogger(__name__.replace("liveproxy.", "")) def main(): @@ -23,63 +22,60 @@ def main(): logging.basicConfig( stream=sys.stdout, level=args.loglevel, - format='[%(name)s][%(levelname)s] %(message)s', + format="[%(name)s][%(levelname)s] %(message)s", ) - if hasattr(os, 'getuid'): + if hasattr(os, "getuid"): if os.geteuid() == 0: - log.info('LiveProxy is running as root! Be careful!') + log.info("LiveProxy is running as root! Be careful!") # MAC OS X - if sys.platform == 'darwin': - os_version = f'macOS {platform.mac_ver()[0]}' + if sys.platform == "darwin": + os_version = f"macOS {platform.mac_ver()[0]}" # Windows - elif sys.platform.startswith('win'): - os_version = f'{platform.system()} {platform.release()}' + elif sys.platform.startswith("win"): + os_version = f"{platform.system()} {platform.release()}" # Linux / other else: os_version = platform.platform() - log.info('For LiveProxy support visit https://github.com/back-to/liveproxy') - log.debug(f'OS: {os_version}') - log.debug(f'Python: {platform.python_version()}') - log.debug(f'LiveProxy: {liveproxy_version}') + log.info("For LiveProxy support visit https://github.com/back-to/liveproxy") + log.debug(f"OS: {os_version}") + log.debug(f"Python: {platform.python_version()}") + log.debug(f"LiveProxy: {liveproxy_version}") HOST = str(args.host) PORT = int(args.port) - if args.file: - create_file(args) - else: - log.info(f'Starting server: {HOST} on port {PORT}') + log.info(f"Starting server: {HOST} on port {PORT}") - try: - httpd = ThreadedHTTPServer((HOST, PORT), HTTPRequest) - except OSError as err: - if err.errno == errno.EADDRINUSE: - log.error(f'Could not listen on port {PORT}! Exiting...') - sys.exit(errno.EADDRINUSE) - elif err.errno == errno.EADDRNOTAVAIL: - log.error(f'Cannot assign requested address {HOST}') - sys.exit(err.errno) - log.error(f'Error {err}! Exiting...') + try: + httpd = ThreadedHTTPServer((HOST, PORT), HTTPRequest) + except OSError as err: + if err.errno == errno.EADDRINUSE: + log.error(f"Could not listen on port {PORT}! Exiting...") + sys.exit(errno.EADDRINUSE) + elif err.errno == errno.EADDRNOTAVAIL: + log.error(f"Cannot assign requested address {HOST}") sys.exit(err.errno) - try: - httpd.serve_forever() - except KeyboardInterrupt: - # close server - if httpd: + log.error(f"Error {err}! Exiting...") + sys.exit(err.errno) + try: + httpd.serve_forever() + except KeyboardInterrupt: + # close server + if httpd: + httpd.shutdown() + httpd.server_close() + log.error("Interrupted! Exiting...") + error_code = 130 + finally: + if httpd: + try: + log.info(f"Closing server {HOST} on port {PORT} ...") httpd.shutdown() httpd.server_close() - log.error('Interrupted! Exiting...') - error_code = 130 - finally: - if httpd: - try: - log.info(f'Closing server {HOST} on port {PORT} ...') - httpd.shutdown() - httpd.server_close() - except KeyboardInterrupt: - error_code = 130 + except KeyboardInterrupt: + error_code = 130 - sys.exit(error_code) + sys.exit(error_code)