snoopplugins.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. #! /usr/bin/env python3
  2. # Copyright (c) 2020 Snoop Project <snoopproject@protonmail.com>
  3. """Плагины Snoop Project/Черновик"""
  4. import ipaddress
  5. import json
  6. import locale
  7. import os
  8. import platform
  9. import re
  10. import random
  11. import requests
  12. import signal
  13. import socket
  14. import sys
  15. import threading
  16. import time
  17. import webbrowser
  18. from colorama import Fore, Style, init
  19. from rich.console import Console
  20. from rich.progress import TimeElapsedColumn, Progress
  21. from rich.table import Table
  22. from urllib.parse import urlparse
  23. import snoopbanner
  24. Android = True if hasattr(sys, 'getandroidapilevel') else False
  25. locale.setlocale(locale.LC_ALL, '')
  26. init(autoreset=True)
  27. console = Console()
  28. time_date = time.localtime()
  29. head0 = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' + \
  30. f'Chrome/{random.choice(range(97, 108, 1))}.0.{random.choice(range(2007, 3008, 23))}.100 Safari/537.36'}
  31. def ravno():
  32. console.rule(characters='=', style="cyan bold")
  33. def helpend():
  34. console.rule("[bold red]Конец справки")
  35. wZ1bad = [] #отфильтрованные ip (не ip) или отфильтрованные данные Yandex, отфильтрованные 'геокоординаты'
  36. azS = [] #список результатов future request
  37. coord = [] #координаты многоцелевой список
  38. my_session = requests.Session()
  39. da = requests.adapters.HTTPAdapter(max_retries=2)
  40. my_session.mount('https://', da)
  41. progressYa = Progress(TimeElapsedColumn(), "[progress.percentage]{task.percentage:>1.0f}%", auto_refresh=False)
  42. ## ERR.
  43. def Erf(hvostfile):
  44. print(f"\033[31;1mНе могу найти_прочитать файл: '{hvostfile}'.\033[0m \033[36m\n " + \
  45. f"\nПожалуйста, укажите текстовый файл в кодировке —\033[0m \033[36;1mutf-8.\033[0m\n" + \
  46. f"\033[36mПо умолчанию, например, блокнот в OS Windows сохраняет текст в кодировке — ANSI.\033[0m\n" + \
  47. f"\033[36mОткройте ваш файл '{hvostfile}' и измените кодировку [файл ---> сохранить как ---> utf-8].\n" + \
  48. f"\033[36mИли удалите из файла нечитаемые спецсимволы.")
  49. ravno()
  50. ## Карты, мета инфо.
  51. "Черновик."
  52. ## Модуль Yandex_parser.
  53. # api https://yandex.ru/dev/id/doc/dg/reference/response.html#response__norights_5
  54. def module3():
  55. while True:
  56. listlogin = []
  57. dicYa = {}
  58. # Парсинг.
  59. def parsingYa():
  60. for login in listlogin:
  61. urlYa = f'https://yandex.ru/collections/api/users/{login}/'
  62. #urlYa = f'https://yandex.ru/znatoki/api/user/public/{login}/'
  63. try:
  64. r = my_session.get(urlYa, headers=head0, timeout=3)
  65. azS.append(r)
  66. except Exception:
  67. print(f"\n{Fore.RED}Ошибка сети пропуск —> '{Style.RESET_ALL}{Style.BRIGHT}" + \
  68. f"{Fore.RED}{login}{Style.RESET_ALL}{Fore.RED}'{Style.RESET_ALL}")
  69. if Ya != '4':
  70. ravno()
  71. continue
  72. with progressYa:
  73. if Ya == '4':
  74. task = progressYa.add_task("", total=len(listlogin))
  75. for reqY, login in zip(azS, listlogin):
  76. if Ya == '4':
  77. progressYa.update(task, advance=1, refresh=True)
  78. rY = reqY.text
  79. #print(rY.text)
  80. try:
  81. rdict = json.loads(rY.text)
  82. if rdict.get('title') == "404 Not Found": #равно
  83. raise Exception("")
  84. except Exception:
  85. rdict = {}
  86. rdict.update(public_id="Увы", display_name="-No-")
  87. login_tab = login.split(sep='@', maxsplit=1)[0]
  88. pub = rdict.get("public_id")
  89. name = rdict.get("display_name")
  90. email = f"{login_tab}@yandex.ru"
  91. avatar = rdict.get("default_avatar_id")
  92. if rdict.get("display_name") == "-No-":
  93. if Ya != '4':
  94. print(Style.BRIGHT + Fore.RED + "\nНе сработало")
  95. console.rule(characters="=", style="cyan bold\n")
  96. else:
  97. continue
  98. continue
  99. else:
  100. table1 = Table(title=f"\n{Style.DIM}{Fore.CYAN}demo_func{Style.RESET_ALL}", style="green")
  101. table1.add_column("Имя", style="magenta", overflow="fold")
  102. table1.add_column("Логин", style="cyan", overflow="fold")
  103. table1.add_column("E-mail", style="cyan", overflow="fold")
  104. if Ya == '3':
  105. table1.add_row(name, "Пропуск", "Пропуск")
  106. else:
  107. table1.add_row(name, login_tab, email)
  108. console.print(table1)
  109. otzyv = f"https://reviews.yandex.ru/user/{pub}"
  110. market = f"https://market.yandex.ru/user/{pub}/reviews"
  111. if Ya == '3':
  112. music = f"\033[33;1mПропуск\033[0m"
  113. else:
  114. music = f"https://music.yandex.ru/users/{login}/tracks"
  115. dzen = f"https://zen.yandex.ru/user/{pub}"
  116. qu = f"https://yandex.ru/q/profile/{pub}/"
  117. avatar_html = f"https://avatars.mds.yandex.net/get-yapic/{avatar}/islands-retina-50"
  118. avatar_cli = f"https://avatars.mds.yandex.net/get-yapic/{avatar}/islands-300"
  119. print("\033[32;1mЯ.Отзывы:\033[0m", otzyv)
  120. print("\033[32;1mЯ.Маркет:\033[0m", market)
  121. print("\033[32;1mЯ.Музыка:\033[0m", music)
  122. print("\033[32;1mЯ.Дзен:\033[0m", dzen)
  123. print("\033[32;1mЯ.Кью:\033[0m", qu)
  124. print("\033[32;1mЯ.Avatar:\033[0m", avatar_cli)
  125. yalist = [avatar_html, otzyv, market, music, dzen, qu]
  126. for webopen in yalist:
  127. if webopen == music and Ya == '3':
  128. continue
  129. else:
  130. if "arm" in platform.platform(aliased=True, terse=0) or "aarch64" in platform.platform(aliased=True, terse=0):
  131. pass
  132. else:
  133. webbrowser.open(webopen)
  134. ravno()
  135. azS.clear()
  136. print("\n\033[36m[\033[0m\033[32;1m1\033[0m\033[36m] --> Указать логин пользователя\n" + \
  137. "[\033[0m\033[32;1m2\033[0m\033[36m] --> Указать публичную ссылку на Яндекс.Диск\n" + \
  138. "[\033[0m\033[32;1m3\033[0m\033[36m] --> Указать идентификатор пользователя\n" + \
  139. "[\033[0m\033[32;1m4\033[0m\033[36m] --> Указать файл с именами пользователей\n" + \
  140. "[\033[0m\033[32;1mhelp\033[0m\033[36m] --> Справка\n" + \
  141. "[\033[0m\033[31;1mq\033[0m\033[36m] --> Выход\n")
  142. Ya = console.input("[cyan]ввод ---> [/cyan]")
  143. # Выход.
  144. if Ya == "q":
  145. print(Style.BRIGHT + Fore.RED + "Выход")
  146. sys.exit()
  147. # Help.
  148. elif Ya == "help":
  149. snoopbanner.help_yandex_parser()
  150. helpend()
  151. # Указать login.
  152. elif Ya == '1':
  153. print("\033[36m└──Введите login/email разыскиваемого пользователя, например,\033[0m\033[32;1m bobbimonov\033[0m\n")
  154. login = console.input("[cyan]login/email ---> [/cyan]")
  155. login = login.split(sep='@', maxsplit=1)[0]
  156. listlogin.append(login)
  157. parsingYa()
  158. # Указать ссылку на Я.Диск.
  159. elif Ya == '2':
  160. print("\033[36m└──Введите публичную ссылку на Яндекс.Диск, например,\033[0m\033[32;1m https://yadi.sk/d/7C6Z9q_Ds1wXkw\033[0m\n")
  161. urlYD = console.input("[cyan]url ---> [/cyan]")
  162. try:
  163. r2 = my_session.get(urlYD, headers=head0, timeout=3)
  164. except Exception:
  165. print(Fore.RED + "\nОшибка" + Style.RESET_ALL)
  166. console.rule(characters='=', style="cyan bold\n")
  167. continue
  168. try:
  169. login = r2.text.split('displayName":"')[1].split('"')[0]
  170. except Exception:
  171. login = "NoneStop"
  172. print(Style.BRIGHT + Fore.RED + "\nНе сработало")
  173. if login != "NoneStop":
  174. listlogin.append(login)
  175. parsingYa()
  176. # Указать идентификатор Яндекс пользователя.
  177. elif Ya == '3':
  178. print("\033[36m└──Введите идентификатор пользователя Яндекс, например,\033[0m\033[32;1m tr6r2c8ea4tvdt3xmpy5atuwg0\033[0m\n")
  179. login = console.input("[cyan]hash ---> [/cyan]")
  180. listlogin.append(login)
  181. if len(login) != 26:
  182. print(Style.BRIGHT + Fore.RED + "└──Неверно указан идентификатор пользователя" + Style.RESET_ALL)
  183. ravno()
  184. else:
  185. parsingYa()
  186. # Указать файл с логинами.
  187. elif Ya == '4':
  188. print("\033[31;1m└──В demo version этот метод плагина недоступен\033[0m\n")
  189. snoopbanner.donate()
  190. else:
  191. print(Style.BRIGHT + Fore.RED + "└──Неверный выбор" + Style.RESET_ALL)
  192. ravno()
  193. ## Модуль Reverse Vgeocoder.
  194. def module2():
  195. if Android:
  196. print(Style.BRIGHT + Fore.RED + "└──Плагин Reverse Vgeocoder 'сложен' и не поддерживается (по умолчанию) " + \
  197. "в Snoop for Termux\n\nВыход\n" + Style.RESET_ALL)
  198. sys.exit()
  199. while True:
  200. print("""
  201. \033[36m[\033[0m\033[32;1m1\033[0m\033[36m] --> Выбрать файл\n\
  202. [\033[0m\033[32;1mhelp\033[0m\033[36m] --> Справка\n\
  203. [\033[0m\033[31;1mq\033[0m\033[36m] --> Выход\n""")
  204. Vgeo = console.input("[cyan]ввод ---> [/cyan]")
  205. # Выход.
  206. if Vgeo == "q":
  207. print(Style.BRIGHT + Fore.RED + "Выход")
  208. sys.exit()
  209. # Help.
  210. elif Vgeo == "help":
  211. snoopbanner.help_vgeocoder_vgeo()
  212. helpend()
  213. # выбрать файл с геокоординатами.
  214. elif Vgeo == '1':
  215. float_patern = '[-]? (?: (?: \d* \. \d+ ))'
  216. rx = re.compile(float_patern, re.VERBOSE)
  217. while True:
  218. print("\033[36m└──Введите \033[0m\033[32;1mабсолютный путь\033[0m \033[36mк файлу (кодировка файла -> utf-8) с данными: \n\
  219. [геокоординаты] или перетащите файл в окно терминала\033[0m\n")
  220. put = console.input("[cyan]File ---> [/cyan]")
  221. if sys.platform == 'win32':
  222. put = put.replace('"', '').strip()
  223. else:
  224. put = put.replace("'", "").strip()
  225. # Проверка пути файла с координатами.
  226. try:
  227. if os.path.exists(put) is False:
  228. raise Exception("")
  229. break
  230. except Exception:
  231. print("\033[31;1m└──Указан неверный путь. " + \
  232. "Укажите корректный абсолютный путь к объекту или перетащите файл в окно терминала\033[0m")
  233. hvostput = os.path.split(put)[1].replace('"', '')
  234. Erf(hvostput)
  235. while True:
  236. print("\n\033[36m╭Выберите режим геокодирования:\033[0m\n" + \
  237. "\033[36m├──\033[36m[\033[0m\033[32;1m1\033[0m\033[36m] --> Простой (full version)\033[0m\n" + \
  238. "\033[36m├──\033[36m[\033[0m\033[32;1m2\033[0m\033[36m] --> Подробный (full version)\033[0m\n" + \
  239. "\033[36m└──\033[36m[\033[0m\033[31;1mq\033[0m\033[36m] --> Выход\033[0m\n")
  240. rGeo = console.input("[cyan]ввод ---> [/cyan]")
  241. if rGeo == "q" or rGeo == '1' or rGeo == '2':
  242. break
  243. else:
  244. print(Style.BRIGHT + Fore.RED + "└──Неверный выбор" + Style.RESET_ALL)
  245. ravno()
  246. if rGeo == "q":
  247. print(Style.BRIGHT + Fore.RED + "Выход")
  248. break
  249. sys.exit()
  250. if rGeo == '1' or rGeo == '2':
  251. print("\033[31;1m└──В demo version этот метод плагина недоступен\033[0m\n")
  252. snoopbanner.donate()
  253. break
  254. sys.exit()
  255. else:
  256. print(Style.BRIGHT + Fore.RED + "└──Неверный выбор" + Style.RESET_ALL)
  257. ravno()
  258. ## Модуль GEO_IP/domain.
  259. def module1():
  260. t_socket = 4
  261. domain = None
  262. res4, res6 = None, None
  263. # Домен.
  264. def task_fbn(dip):
  265. nonlocal domain
  266. #time.sleep(11)
  267. domain = socket.getfqdn(dip)
  268. return domain
  269. # Домен > IPv4/v6.
  270. def res46(dipp):
  271. nonlocal res4, res6
  272. #time.sleep(11)
  273. try:
  274. res46 = socket.getaddrinfo(f"{dipp}", 443)
  275. try:
  276. res4 = res46[0][4][0] if ipaddress.IPv4Address(res46[0][4][0]) else ""
  277. except Exception:
  278. res4 = "-"
  279. try:
  280. res6 = res46[-1][4][0] if ipaddress.IPv6Address(res46[-1][4][0]) else ""
  281. except Exception:
  282. res6 = "-"
  283. except Exception:
  284. res4, res6 = "-", "-"
  285. return res4, res6
  286. # Потоки.
  287. def treads_dr(fun, args, dr):
  288. """Потоки необходимы для того, чтобы оборачивать встроенные socket-функции, не имеющие таймаута.
  289. В случае замедления (на Android ожидание может доходить до > 1 минуты, обычно возвращается пустой результат,
  290. когда ip/domain ложный) уничтожить потоки через заданное время 't_socket'.
  291. """
  292. d1 = threading.Thread(target=fun, args=(args,))
  293. d1.start()
  294. d1.join(t_socket)
  295. if domain is None or (dr=='res' and res4 is None and res6 is None):
  296. console.log("[bold red]--> таймаут | ресурс не существует.[/bold red]")
  297. os.kill(os.getpid(), signal.SIGBREAK) if sys.platform == 'win32' else os.kill(os.getpid(), signal.SIGKILL)
  298. # Запрос future request.
  299. def reqZ():
  300. try:
  301. r = req.result()
  302. return r.text
  303. except requests.exceptions.ConnectionError:
  304. print(Fore.RED + "\nОшибка соединения\n" + Style.RESET_ALL)
  305. except requests.exceptions.Timeout:
  306. print(Fore.RED + "\nОшибка таймаут\n" + Style.RESET_ALL)
  307. except requests.exceptions.RequestException:
  308. print(Fore.RED + "\nОшибка не идентифицирована\n" + Style.RESET_ALL)
  309. except requests.exceptions.HTTPError:
  310. print(Fore.RED + "\nОшибка HTTPS\n" + Style.RESET_ALL)
  311. return "Err"
  312. # Выбор поиска одиночный или '-f'.
  313. ravno()
  314. print("\n\033[36mВведите домен (пример:\033[0m \033[32;1mexample.com\033[0m\033[36m),\n" + \
  315. "или IPv4/IPv6 (пример:\033[0m" + \
  316. "\033[32;1m 8.8.8.8\033[0m\033[36m),\n" + \
  317. "или url (пример: \033[32;1mhttps://example.com/1/2/3/foo\033[0m\033[36m), \n" + \
  318. "или укажите файл с данными.\n" + \
  319. "[\033[0m\033[32;1mfile\033[0m\033[36m] --> обработка файла данных\n" + \
  320. "[\033[0m\033[32;1menter\033[0m\033[36m] --> информация о своем GEO_IP\n" + \
  321. "[\033[0m\033[31;1mq\033[0m\033[36m] --> Выход")
  322. dip = console.input("\n[cyan]ввод ---> [/cyan]")
  323. # выход.
  324. if dip == "q":
  325. print(Style.BRIGHT + Fore.RED + "Выход")
  326. sys.exit()
  327. # проверка данных.
  328. elif dip == 'file':
  329. while True:
  330. print("""\033[36m├──Выберите тип поиска
  331. [\033[0m\033[32;1m1\033[0m\033[36m] --> \033[30;1mOnline (медленно)\033[0m\033[36m
  332. [\033[0m\033[32;1m2\033[0m\033[36m] --> Offline (быстро)
  333. [\033[0m\033[32;1m3\033[0m\033[36m] --> Offline_тихий (очень быстро)
  334. [\033[0m\033[32;1mhelp\033[0m\033[36m] --> Справка\n\
  335. [\033[31;1mq\033[0m\033[36m] --> Выход\033[0m\n""")
  336. dipbaza = console.input("[cyan]ввод ---> [/cyan]")
  337. # Выход.
  338. if dipbaza == "q":
  339. print("\033[31;1mВыход\033[0m")
  340. sys.exit(0)
  341. # Справка.
  342. elif dipbaza == "help":
  343. snoopbanner.geo_ip_domain()
  344. helpend()
  345. # Оффлайн поиск.
  346. # Открываем GeoCity.
  347. elif dipbaza == "2" or dipbaza == "3":
  348. while True:
  349. print("\033[31;1m└──В demo version этот метод плагина недоступен\033[0m\n")
  350. snoopbanner.donate()
  351. break
  352. break
  353. # Онлайн поиск.
  354. elif dipbaza == "1":
  355. print("\033[31;1m└──В demo version этот метод плагина недоступен\033[0m\n")
  356. snoopbanner.donate()
  357. break
  358. # Неверный выбор ключа при оффлайн/онлайн поиске. Выход.
  359. else:
  360. print(Style.BRIGHT + Fore.RED + "└──Неверный выбор" + Style.RESET_ALL)
  361. ravno()
  362. # одиночный запрос.
  363. else:
  364. def ip_check(url_api, dip, res4, err):
  365. if dip == "": url_api = url_api
  366. elif res4 == "-": url_api = f"{url_api}{dip}"
  367. else: url_api = f"{url_api}{res4}"
  368. try:
  369. r = my_session.get(url=url_api, headers=head0, timeout=3)
  370. dip_dic = json.loads(r.text)
  371. T1 = dip_dic["country_code"] if err is False else dip_dic["country"]["isoCode"]
  372. T2 = dip_dic["region"] if err is False else dip_dic["city"]["name"]
  373. T3 = dip_dic["latitude"] if err is False else dip_dic["location"]["latitude"]
  374. T4 = dip_dic["longitude"] if err is False else dip_dic["location"]["longitude"]
  375. if err is True and res4 == '-':
  376. T5 = my_session.get(url=f"https://ipinfo.io/ip", timeout=3).text
  377. else:
  378. T5 = dip_dic.get("ip")
  379. except Exception:
  380. try:
  381. if err is True:
  382. if dip == '': p = ''
  383. elif res4 != '-': p = res4 + '/'
  384. else: dip + '/'
  385. console.log("[bold yellow]--> Внимание! Последний доступный url_ip[/bold yellow]")
  386. T1 = my_session.get(url=f"https://ipinfo.io/{p}country", timeout=3).text
  387. T2 = my_session.get(url=f"https://ipinfo.io/{p}region", timeout=3).text
  388. T5 = my_session.get(url=f"https://ipinfo.io/{p}ip", timeout=3).text
  389. T3 = "stop"
  390. T4 = "stop"
  391. return T1, T2, T3, T4, T5
  392. # raise Exception("")
  393. return ip_check('https://ipdb.ipcalc.co/ipdata/', dip, res4, err=True)
  394. except:
  395. T1 = "-"
  396. T2 = "-"
  397. T3 = "stop"
  398. T4 = "stop"
  399. T5 = "-"
  400. print("""\033[31;1m\n
  401. |\ | _ ._ _
  402. | \|(_)| |(/_\033[0m""")
  403. return T1, T2, T3, T4, T5
  404. table_name = "Мой ip" if dip == "" else dip
  405. if '.' not in dip and ':' not in dip and dip != "" or (dip != "" and len(dip) <= 4) or '..' in dip:
  406. print(Style.BRIGHT + Fore.RED + "└──Неверный ввод\n" + Style.RESET_ALL)
  407. return module1()
  408. else:
  409. u = urlparse(dip).hostname
  410. if bool(u) is False:
  411. dip = dip.split("/")[0].strip()
  412. else:
  413. dip = u.replace("www.", "").strip()
  414. with console.status("[cyan]работаю[/cyan]", spinner="earth"):
  415. treads_dr(task_fbn, dip, dr="dom")
  416. try:
  417. ipaddress.ip_address(dip)
  418. resD1 = domain
  419. except Exception:
  420. resD1 = dip
  421. treads_dr(res46, resD1, dr="res")
  422. T1, T2, T3, T4, T5 = ip_check('https://ipwho.is/', dip, res4, err=False)
  423. try:
  424. if ipaddress.IPv4Address(dip): res4 = dip
  425. except Exception: pass
  426. try:
  427. if ipaddress.IPv6Address(dip): res6 = dip
  428. except Exception: pass
  429. table = Table(title=table_name, title_style="italic bold red", style="green", header_style='green')
  430. table.add_column("Код", style="magenta")
  431. if dip == "":
  432. table.add_column("IP", style="cyan", overflow="fold")
  433. else:
  434. table.add_column("IPv4", style="cyan", overflow="fold")
  435. table.add_column("IPv6", style="cyan", overflow="fold")
  436. table.add_column("Домен", style="green", overflow="fold")
  437. table.add_column("Регион", style="green", overflow="fold")
  438. if dip == "":
  439. table.add_row(T1, T5, domain, T2)
  440. else:
  441. table.add_row(T1, res4, res6, domain, T2)
  442. console.print(table)
  443. if T3 == "stop" and T4 == "stop":
  444. print("\n")
  445. URL_GEO = ""
  446. else:
  447. URL_GEO = f"https://www.openstreetmap.org/#map=13/{T3}/{T4}"
  448. URL_GEO2 = f"https://www.google.com/maps/@{T3},{T4},12z"
  449. print(Style.BRIGHT + Fore.BLACK + f"{URL_GEO}" + Style.RESET_ALL)
  450. print(Style.BRIGHT + Fore.BLACK + f"{URL_GEO2}\n" + Style.RESET_ALL)
  451. return module1()
  452. if __name__ == "__main__":
  453. module1()