A simple cli for n3ro
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

97 Zeilen
3.5KB

  1. import base64
  2. import csv
  3. import sys
  4. import os
  5. import urllib.request
  6. from urllib.parse import parse_qs
  7. class N3ROCLI:
  8. def __init__(self):
  9. self.config_path = os.path.expanduser('~/.config/n3ro-cli')
  10. self.ssr_command = f"python {self.config_path}/shadowsocksr/shadowsocks/local.py"
  11. self.url_path = os.path.join(self.config_path, 'url')
  12. self.cache_path = os.path.join(self.config_path, 'cache')
  13. self.subscribe_url = self.read_url()
  14. os.makedirs(self.config_path, exist_ok=True)
  15. def read_url(self):
  16. path_ok = os.path.exists(self.url_path)
  17. if path_ok:
  18. with open(self.url_path) as u:
  19. url = u.read()
  20. return url
  21. else:
  22. return None
  23. def decode_str(self, s, to_str=True):
  24. paddings = 4 - len(s) % 4
  25. padded_s = f"{s}{'='*paddings}"
  26. decoded = base64.urlsafe_b64decode(padded_s)
  27. if to_str:
  28. decoded = str(decoded, encoding='utf-8')
  29. return decoded
  30. def sync(self):
  31. if not self.subscribe_url:
  32. print("add a ssr subscribe url in ~/.config/n3ro-cli/url")
  33. else:
  34. with urllib.request.urlopen(self.subscribe_url) as resp:
  35. data = str(resp.read(), encoding='utf-8')
  36. ssr_urls = self.decode_str(data).strip().split('\n')
  37. ssr_paths = (self.decode_str(u[6:]) for u in ssr_urls)
  38. with open(self.cache_path, 'w') as c:
  39. fields = ['id', 'info', 'args']
  40. server_writer = csv.DictWriter(c, fieldnames=fields)
  41. server_writer.writeheader()
  42. for n, p in enumerate(ssr_paths):
  43. path, params = p.split('/?')
  44. d = self.decode_str
  45. host, port, proto, enc, obfs, passwd = path.split(':')
  46. raw_passwd = d(passwd)
  47. parsed_params = parse_qs(params)
  48. obfs_param = parsed_params.get('obfsparam', '')
  49. if obfs_param:
  50. obfs_param = d(obfs_param)
  51. proto_param = parsed_params.get('proto_param', '')
  52. if proto_param:
  53. proto_param = d(proto_param)
  54. name = d(parsed_params.get('remarks', ''),
  55. to_str=False).decode()
  56. group = d(parsed_params.get('group', ''),
  57. to_str=False).decode()
  58. args = f"-s {host} -p {port} -k {raw_passwd} -m {enc} -O {proto} -o {obfs} -b 127.0.0.1 -l 1080"
  59. if obfs_param:
  60. args = f"{args} -g {obfs_param}"
  61. if proto_param:
  62. args = f"{args} -G {proto_param}"
  63. server_writer.writerow({'id': n,
  64. 'args': args,
  65. 'info': f"{name} {group}"})
  66. def conn(self, node_id):
  67. with open(self.cache_path) as c:
  68. reader = csv.DictReader(c)
  69. ssr_args = None
  70. for row in reader:
  71. if row['id'] == str(node_id):
  72. ssr_args = row['args']
  73. os.system(f"{self.ssr_command} {ssr_args}")
  74. def ls(self):
  75. with open(self.cache_path) as c:
  76. reader = csv.DictReader(c)
  77. for row in reader:
  78. s = f"{row['id']}:{row['info']} "
  79. sys.stdout.write(s)
  80. cli = N3ROCLI()
  81. ls = cli.ls
  82. l = cli.ls
  83. conn = cli.conn
  84. c = cli.conn
  85. sync = cli.sync
  86. s = cli.sync