1+ import json
2+ import argparse
3+ import os
4+ import sys
5+ from init_paths import *
6+ from paths import *
7+ VALID_PROTOCOLS = ("vmess://" , "vless://" , "ss://" , "trojan://" )
8+
9+ def read_configs ():
10+ if not os .path .exists (EXTRA_CONFIG_PATH ):
11+ return []
12+ try :
13+ with open (EXTRA_CONFIG_PATH , 'r' ) as f :
14+ content = f .read ()
15+ if not content :
16+ return []
17+ return json .loads (content )
18+ except (json .JSONDecodeError , IOError ):
19+ return []
20+
21+ def write_configs (configs ):
22+ try :
23+ os .makedirs (os .path .dirname (EXTRA_CONFIG_PATH ), exist_ok = True )
24+ with open (EXTRA_CONFIG_PATH , 'w' ) as f :
25+ json .dump (configs , f , indent = 4 )
26+ except IOError as e :
27+ print (f"Error writing to { EXTRA_CONFIG_PATH } : { e } " , file = sys .stderr )
28+ sys .exit (1 )
29+
30+ def add_config (name , uri ):
31+ if not any (uri .startswith (protocol ) for protocol in VALID_PROTOCOLS ):
32+ print (f"Error: Invalid URI. Must start with one of { ', ' .join (VALID_PROTOCOLS )} " , file = sys .stderr )
33+ sys .exit (1 )
34+
35+ configs = read_configs ()
36+
37+ if any (c ['name' ] == name for c in configs ):
38+ print (f"Error: A configuration with the name '{ name } ' already exists." , file = sys .stderr )
39+ sys .exit (1 )
40+
41+ configs .append ({"name" : name , "uri" : uri })
42+ write_configs (configs )
43+ print (f"Successfully added configuration '{ name } '." )
44+
45+ def delete_config (name ):
46+ configs = read_configs ()
47+
48+ initial_length = len (configs )
49+ configs = [c for c in configs if c ['name' ] != name ]
50+
51+ if len (configs ) == initial_length :
52+ print (f"Error: No configuration found with the name '{ name } '." , file = sys .stderr )
53+ sys .exit (1 )
54+
55+ write_configs (configs )
56+ print (f"Successfully deleted configuration '{ name } '." )
57+
58+ def list_configs ():
59+ configs = read_configs ()
60+ print (json .dumps (configs , indent = 4 ))
61+
62+ def get_config (name ):
63+ configs = read_configs ()
64+ config = next ((c for c in configs if c ['name' ] == name ), None )
65+
66+ if config :
67+ print (json .dumps (config , indent = 4 ))
68+ else :
69+ print (f"Error: No configuration found with the name '{ name } '." , file = sys .stderr )
70+ sys .exit (1 )
71+
72+ def main ():
73+ parser = argparse .ArgumentParser (description = "Manage extra proxy configurations for subscription links." )
74+ subparsers = parser .add_subparsers (dest = "command" , required = True )
75+
76+ parser_add = subparsers .add_parser ("add" , help = "Add a new proxy configuration." )
77+ parser_add .add_argument ("--name" , type = str , required = True , help = "A unique name for the configuration." )
78+ parser_add .add_argument ("--uri" , type = str , required = True , help = "The proxy URI (vmess, vless, ss, trojan)." )
79+
80+ parser_delete = subparsers .add_parser ("delete" , help = "Delete a proxy configuration." )
81+ parser_delete .add_argument ("--name" , type = str , required = True , help = "The name of the configuration to delete." )
82+
83+ subparsers .add_parser ("list" , help = "List all extra proxy configurations." )
84+
85+ parser_get = subparsers .add_parser ("get" , help = "Get a specific proxy configuration by name." )
86+ parser_get .add_argument ("--name" , type = str , required = True , help = "The name of the configuration to retrieve." )
87+
88+ args = parser .parse_args ()
89+
90+ if os .geteuid () != 0 :
91+ print ("This script must be run as root." , file = sys .stderr )
92+ sys .exit (1 )
93+
94+ if args .command == "add" :
95+ add_config (args .name , args .uri )
96+ elif args .command == "delete" :
97+ delete_config (args .name )
98+ elif args .command == "list" :
99+ list_configs ()
100+ elif args .command == "get" :
101+ get_config (args .name )
102+
103+ if __name__ == "__main__" :
104+ main ()
0 commit comments