A simple cli for n3ro
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

97 satır
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