Created
July 12, 2019 11:40
-
-
Save moetayuko/53fb977e3e49696a5b179bf5e5fb15bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import base64 | |
| import json | |
| import sys | |
| def to_bytes(s): | |
| if bytes != str: | |
| if type(s) == str: | |
| return s.encode('utf-8') | |
| return s | |
| def to_str(s): | |
| if bytes != str: | |
| if type(s) == bytes: | |
| return s.decode('utf-8') | |
| return s | |
| def b64decode(data): | |
| if b':' in data: | |
| return data | |
| if len(data) % 4 == 2: | |
| data += b'==' | |
| elif len(data) % 4 == 3: | |
| data += b'=' | |
| return base64.urlsafe_b64decode(data) | |
| def decode_ssr_subscription(ssr_subscription): | |
| ssr_subscription = to_bytes(ssr_subscription) | |
| ssr_profiles = to_str(b64decode(ssr_subscription)) | |
| return ssr_profiles.split() | |
| def decode_ssr_profile(ssr_profile): | |
| if ssr_profile[:6] != 'ssr://': | |
| raise ValueError('Invalid SSR profile URI!') | |
| ssr_profile = to_bytes(ssr_profile[6:]) | |
| ssr_profile = to_str(b64decode(ssr_profile)) | |
| ssr_profile_params = {} | |
| if '/' in ssr_profile: | |
| ssr_profile, extra_params = ssr_profile.split('/', 1) | |
| delimiter_pos = extra_params.find('?') | |
| if delimiter_pos >= 0: | |
| extra_params = extra_params[delimiter_pos + 1:] | |
| extra_params = extra_params.split('&') | |
| for param in extra_params: | |
| k, v = param.split('=', 1) | |
| if k in ['obfsparam', 'protoparam', 'group', 'remarks']: | |
| v = to_str(b64decode(to_bytes(v))) | |
| key_mapping = {'obfsparam': 'obfs_param', | |
| 'protoparam': 'protocol_param'} | |
| k = key_mapping.get(k, k) | |
| ssr_profile_params[k] = v | |
| ssr_profile = ssr_profile.split(':') | |
| if len(ssr_profile) != 6: | |
| raise ValueError('Invalid SSR profile configuration!') | |
| ssr_profile_params.update({ | |
| 'server': ssr_profile[0], | |
| 'server_port': int(ssr_profile[1]), | |
| 'protocol': ssr_profile[2], | |
| 'method': ssr_profile[3], | |
| 'obfs': ssr_profile[4], | |
| 'password': to_str(b64decode(to_bytes(ssr_profile[5]))), | |
| 'local_address': '127.0.0.1', | |
| 'local_port': 1080 | |
| }) | |
| return ssr_profile_params | |
| def to_ss_qt5(ssr_profile_params): | |
| if ssr_profile_params['protocol'] != 'origin': | |
| return None | |
| ss_conf_key = ['method', 'password', 'remarks', 'server', 'server_port'] | |
| return dict((k, ssr_profile_params[k]) for k in ss_conf_key if k in ssr_profile_params) | |
| def main(): | |
| ssr_subscription_file = sys.argv[1] | |
| with open(ssr_subscription_file) as f: | |
| ssr_subscription = f.read() | |
| ssr_profiles = decode_ssr_subscription(ssr_subscription) | |
| ss_qt5_params = { | |
| 'configs': [], | |
| 'localPort': 1080, | |
| 'shareOverLan': False | |
| } | |
| for ssr_profile in ssr_profiles: | |
| ssr_profile_params = decode_ssr_profile(ssr_profile) | |
| ss_profile_params = to_ss_qt5(ssr_profile_params) | |
| if ss_profile_params is not None: | |
| ss_qt5_params['configs'].append(ss_profile_params) | |
| with open('gui-config.json', 'w') as f: | |
| json.dump(ss_qt5_params, f, indent=4, | |
| sort_keys=True, ensure_ascii=False) | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment