From 151f92a79e11b7c8e0bee4f8fd3852de99a105de Mon Sep 17 00:00:00 2001 From: Alexander Mayatsky Date: Sun, 17 Nov 2024 08:17:01 +0100 Subject: [PATCH] BREAKING CHANGE: Removed python 2 support --- README.md | 4 ++-- ss-genuri.py | 53 +++++++++++++++++++++++++++---------------- test_generates_uri.py | 13 +++++------ 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index c395f93..1427a63 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,11 @@ Input: ``` Output: ``` -ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpmYWtlX3B3ZEBnaXRodWIuY29tOjgzODg=#ShadowSocksServer +ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpmYWtlX3B3ZEBnaXRodWIuY29tOjgzODg=#ShadowSocks%20Server ``` ### Requirements -Python (compatible with both 2 and 3 interpeter versions). +Python 3.9+ ### Contribution Feel free to send your PRs and report any issues. diff --git a/ss-genuri.py b/ss-genuri.py index 9a0d047..29a5ed5 100755 --- a/ss-genuri.py +++ b/ss-genuri.py @@ -1,29 +1,44 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import argparse import json import base64 +from pathlib import Path +from urllib.parse import quote -parser = argparse.ArgumentParser(description='A script that parses Shadowsocks server configuration file and generates ' - 'a client configuration URI') -parser.add_argument('--config', '-c', type=str, help='A path to your Shadowsocks server config.json') +def parse_arguments(): + parser = argparse.ArgumentParser( + description='A script that parses Shadowsocks server configuration file and generates a client configuration URI' + ) + parser.add_argument( + '--config', '-c', + type=str, + help='A path to your Shadowsocks server config.json', + default='/etc/shadowsocks-libev/config.json' + ) + return parser.parse_args() -args = parser.parse_args() +def load_config(config_path: str) -> dict: + config_file = Path(config_path) + if not config_file.exists(): + raise FileNotFoundError(f"Configuration file not found: {config_path}") -if args.config is None: - args.config='/etc/shadowsocks-libev/config.json' - print('Using default config path: {}'.format(args.config)) + with open(config_file, 'r') as file: + return json.load(file) -config = json.load(open(args.config, 'r')) +def generate_ss_uri(config: dict) -> str: + uri = f"{config['method']}:{config['password']}@{config['server']}:{config['server_port']}" + encoded_uri = base64.b64encode(uri.encode('utf-8')).decode('utf-8') -uri = "%s:%s@%s:%d" % ( - config['method'], - config['password'], - config['server'], - config['server_port'], -) + remarks = config.get('remarks', 'Shadowsocks Server') + encoded_remarks = quote(remarks) -encoded_uri = base64.b64encode(uri.encode('utf-8')).decode('utf-8') + return f'ss://{encoded_uri}#{encoded_remarks}' -remarks = config.get('remarks', 'Shadowsocks Server') -remarks = "".join(remarks.split(' ')) -print('ss://%s#%s' % (encoded_uri, remarks)) +def main(): + args = parse_arguments() + config = load_config(args.config) + ss_uri = generate_ss_uri(config) + print(ss_uri) + +if __name__ == '__main__': + main() diff --git a/test_generates_uri.py b/test_generates_uri.py index 8602a2c..d6f88c2 100644 --- a/test_generates_uri.py +++ b/test_generates_uri.py @@ -7,11 +7,11 @@ class TestScript(unittest.TestCase): def setUp(self): self.config_path = 'test_config.json' sample_config = { - "server": "my-server.com", - "server_port": 8388, - "password": "mypassword", - "method": "aes-256-gcm", - "remarks": "Test Server" + "remarks": "ShadowSocks Server", + "server":"github.com", + "server_port":8388, + "password":"fake_pwd", + "method":"chacha20-ietf-poly1305" } with open(self.config_path, 'w') as f: json.dump(sample_config, f) @@ -26,8 +26,7 @@ def test_generate_uri(self): capture_output=True, text=True ) - self.assertEqual('ss://YWVzLTI1Ni1nY206bXlwYXNzd29yZEBteS1zZXJ2ZXIuY29tOjgzODg=#TestServer\n', result.stdout) + self.assertEqual('ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpmYWtlX3B3ZEBnaXRodWIuY29tOjgzODg=#ShadowSocks%20Server\n', result.stdout) if __name__ == '__main__': unittest.main() -