blackhole.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-"
  3. """
  4. This file is part of the UFONet project, https://ufonet.03c8.net
  5. Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
  6. You should have received a copy of the GNU General Public License along
  7. with UFONet; if not, write to the Free Software Foundation, Inc., 51
  8. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  9. """
  10. import socket, re, time, string, sys, os, traceback, gzip, shutil
  11. from threading import *
  12. class AI(Thread):
  13. def __init__(self, parent):
  14. Thread.__init__(self)
  15. self.power_on = False
  16. self.parent = parent
  17. self.tmp_dir = parent.tmp_dir
  18. self.target_dir = parent.target_dir
  19. def find_meat(self):
  20. self.meats = []
  21. try:
  22. for f in os.listdir(self.tmp_dir + "blackhole"):
  23. if f[-3:] == '.gz':
  24. print("[Info] [AI] Found meat in "+str(f))
  25. self.meats.append(f)
  26. except:
  27. print("[info] [AI] No meat in the fridge "+self.tmp_dir + "blackhole")
  28. traceback.print_exc()
  29. return self.meats != []
  30. def process( self ):
  31. zombies_incoming=[]
  32. aliens_incoming=[]
  33. droids_incoming=[]
  34. ucavs_incoming=[]
  35. rpcs_incoming=[]
  36. ntps_incoming=[]
  37. dnss_incoming=[]
  38. for meat in self.meats:
  39. f_in = gzip.open(self.tmp_dir+"blackhole/"+meat)
  40. if 'community_zombies.txt.gz' in f_in: # zombies found
  41. f_out = open(self.tmp_dir+'meat.txt', 'wb')
  42. for line in f_in.readlines():
  43. zombies_incoming.append(line)
  44. f_out.write(line.strip()+os.linesep)
  45. f_out.close()
  46. elif 'community_aliens.txt.gz' in f_in: # aliens found
  47. f_out = open(self.tmp_dir+'larva.txt', 'wb')
  48. for line in f_in.readlines():
  49. aliens_incoming.append(line)
  50. f_out.write(line.strip()+os.linesep)
  51. f_out.close()
  52. elif 'community_droids.txt.gz' in f_in: # droids found
  53. f_out = open(self.tmp_dir+'chip.txt', 'wb')
  54. for line in f_in.readlines():
  55. droids_incoming.append(line)
  56. f_out.write(line.strip()+os.linesep)
  57. f_out.close()
  58. elif 'community_ucavs.txt.gz' in f_in: # ucavs found
  59. f_out = open(self.tmp_dir+'arduino.txt', 'wb')
  60. for line in f_in.readlines():
  61. ucavs_incoming.append(line)
  62. f_out.write(line.strip()+os.linesep)
  63. f_out.close()
  64. elif 'community_rpcs.txt.gz' in f_in: # rpcs found
  65. f_out = open(self.tmp_dir+'mirror.txt', 'wb')
  66. for line in f_in.readlines():
  67. rpcs_incoming.append(line)
  68. f_out.write(line.strip()+os.linesep)
  69. f_out.close()
  70. elif 'community_ntps.txt.gz' in f_in: # ntps found
  71. f_out = open(self.tmp_dir+'clock.txt', 'wb')
  72. for line in f_in.readlines():
  73. ntps_incoming.append(line)
  74. f_out.write(line.strip()+os.linesep)
  75. f_out.close()
  76. elif 'community_dnss.txt.gz' in f_in: # dnss found
  77. f_out = open(self.tmp_dir+'label.txt', 'wb')
  78. for line in f_in.readlines():
  79. dnss_incoming.append(line)
  80. f_out.write(line.strip()+os.linesep)
  81. f_out.close()
  82. f_in.close()
  83. os.remove(self.tmp_dir+"blackhole/"+meat)
  84. import subprocess
  85. f_tmp = open(self.tmp_dir + 'meat.tmp','wb')
  86. try:
  87. subprocess.call('../../ufonet --force-yes -t "'+self.tmp_dir+'meat.txt"', shell=True, stdout=f_tmp) # testing zombies (GET) (path: core/tools/blackhole.py)
  88. except:
  89. pass
  90. f_tmp.close()
  91. f_tmp = open(self.tmp_dir + 'meat.tmp')
  92. testoutput=f_tmp.read()
  93. f_tmp.close()
  94. if "Not any zombie active" in testoutput:
  95. if not aliens_incoming and not droids_incoming and not ucavs_incoming: # not any valid zombie (GET or POST)
  96. print("[Info] [AI] no valid zombies !")
  97. return
  98. else:
  99. f_tested = open(self.tmp_dir+'meat.txt')
  100. zombies_community = f_tested.readlines()
  101. f_tested.close()
  102. o_in = gzip.open(self.target_dir+'abductions.txt.gz', 'rb')
  103. zombies_army = o_in.readlines()
  104. initial = len(zombies_army)
  105. o_in.close()
  106. for zombie in zombies_community:
  107. if zombie.strip() not in zombies_army:
  108. zombies_army.append(zombie)
  109. else:
  110. pass
  111. fc = gzip.open(self.tmp_dir+'newzombies.txt.gz', 'wb')
  112. for zombie in zombies_army:
  113. fc.write(zombie.strip()+os.linesep)
  114. fc.close()
  115. shutil.move(self.tmp_dir+'newzombies.txt.gz', self.target_dir+'abductions.txt.gz')
  116. print("[info] [AI] Zombies tested : " +str(len(zombies_community)) + " / initial : " +str(initial) + " / final : " + str(len(zombies_army)))
  117. f_tested = open(self.tmp_dir+'larva.txt')
  118. aliens_community = f_tested.readlines()
  119. f_tested.close()
  120. o_in = gzip.open(self.target_dir+'troops.txt.gz', 'rb')
  121. aliens_army = o_in.readlines()
  122. initial = len(aliens_army)
  123. o_in.close()
  124. for alien in aliens_community:
  125. if alien.strip() not in aliens_army:
  126. aliens_army.append(alien)
  127. else:
  128. pass
  129. fc = gzip.open(self.tmp_dir+'newaliens.txt.gz', 'wb')
  130. for alien in aliens_army:
  131. fc.write(alien.strip()+os.linesep)
  132. fc.close()
  133. shutil.move(self.tmp_dir+'newaliens.txt.gz', self.target_dir+'troops.txt.gz')
  134. print("[Info] [AI] Aliens tested : " +str(len(aliens_community)) + " / initial : " +str(initial) + " / final : " + str(len(aliens_army)))
  135. f_tested = open(self.tmp_dir+'chip.txt')
  136. droids_community = f_tested.readlines()
  137. f_tested.close()
  138. o_in = gzip.open(self.target_dir+'robots.txt.gz', 'rb')
  139. droids_army = o_in.readlines()
  140. initial = len(droids_army)
  141. o_in.close()
  142. for droid in droids_community:
  143. if droid.strip() not in droids_army:
  144. droids_army.append(droid)
  145. else:
  146. pass
  147. fc = gzip.open(self.tmp_dir+'newdroids.txt.gz', 'wb')
  148. for droid in droids_army:
  149. fc.write(droid.strip()+os.linesep)
  150. fc.close()
  151. shutil.move(self.tmp_dir+'newdroids.txt.gz', self.target_dir+'robots.txt.gz')
  152. print("[Info] [AI] Droids tested : " +str(len(droids_community)) + " / initial : " +str(initial) + " / final : " + str(len(droids_army)))
  153. f_tested = open(self.tmp_dir+'arduino.txt')
  154. ucavs_community = f_tested.readlines()
  155. f_tested.close()
  156. o_in = gzip.open(self.target_dir+'drones.txt.gz', 'rb')
  157. ucavs_army = o_in.readlines()
  158. initial = len(ucavs_army)
  159. o_in.close()
  160. for ucav in ucavs_community:
  161. if ucav.strip() not in ucavs_army:
  162. ucavs_army.append(ucav)
  163. else:
  164. pass
  165. fc = gzip.open(self.tmp_dir+'newucavs.txt.gz', 'wb')
  166. for ucav in ucavs_army:
  167. fc.write(ucav.strip()+os.linesep)
  168. fc.close()
  169. shutil.move(self.tmp_dir+'newucavs.txt.gz', self.target_dir+'drones.txt.gz')
  170. print("[Info] [AI] UCAVs tested : " +str(len(ucavs_community)) + " / initial : " +str(initial) + " / final : " + str(len(ucavs_army)))
  171. f_tested = open(self.tmp_dir+'mirror.txt')
  172. rpcs_community = f_tested.readlines()
  173. f_tested.close()
  174. o_in = gzip.open(self.target_dir+'reflectors.txt.gz', 'rb')
  175. rpcs_army = o_in.readlines()
  176. initial = len(rpcs_army)
  177. o_in.close()
  178. for rpc in rpcs_community:
  179. if rpc.strip() not in rpcs_army:
  180. rpcs_army.append(rpc)
  181. else:
  182. pass
  183. fc = gzip.open(self.tmp_dir+'newrpcs.txt.gz', 'wb')
  184. for rpc in rpcs_army:
  185. fc.write(rpc.strip()+os.linesep)
  186. fc.close()
  187. shutil.move(self.tmp_dir+'newrpcs.txt.gz', self.target_dir+'reflectors.txt.gz')
  188. print("[Info] [AI] X-RPCs tested : " +str(len(rpcs_community)) + " / initial : " +str(initial) + " / final : " + str(len(rpcs_army)))
  189. f_tested = open(self.tmp_dir+'clock.txt')
  190. ntps_community = f_tested.readlines()
  191. f_tested.close()
  192. o_in = gzip.open(self.target_dir+'crystals.txt.gz', 'rb')
  193. ntps_army = o_in.readlines()
  194. initial = len(ntps_army)
  195. o_in.close()
  196. for ntp in ntps_community:
  197. if ntp.strip() not in ntps_army:
  198. ntps_army.append(ntp)
  199. else:
  200. pass
  201. fc = gzip.open(self.tmp_dir+'newntps.txt.gz', 'wb')
  202. for ntp in ntps_army:
  203. fc.write(ntp.strip()+os.linesep)
  204. fc.close()
  205. shutil.move(self.tmp_dir+'newntps.txt.gz', self.target_dir+'crystals.txt.gz')
  206. print("[Info] [AI] NTPs tested : " +str(len(ntps_community)) + " / initial : " +str(initial) + " / final : " + str(len(ntps_army)))
  207. f_tested = open(self.tmp_dir+'label.txt')
  208. dnss_community = f_tested.readlines()
  209. f_tested.close()
  210. o_in = gzip.open(self.target_dir+'warps.txt.gz', 'rb')
  211. dnss_army = o_in.readlines()
  212. initial = len(dnss_army)
  213. o_in.close()
  214. for dns in dnss_community:
  215. if dns.strip() not in dnss_army:
  216. dnss_army.append(dns)
  217. else:
  218. pass
  219. fc = gzip.open(self.tmp_dir+'newdnss.txt.gz', 'wb')
  220. for dns in dnss_army:
  221. fc.write(dns.strip()+os.linesep)
  222. fc.close()
  223. shutil.move(self.tmp_dir+'newdnss.txt.gz', self.target_dir+'warps.txt.gz')
  224. print("[Info] [AI] DNSs tested : " +str(len(dnss_community)) + " / initial : " +str(initial) + " / final : " + str(len(dnss_army)))
  225. def run(self):
  226. self.power_on = True
  227. print("[Info] [AI] Power On")
  228. while self.power_on :
  229. # load list of files to process
  230. if self.find_meat():
  231. # if data -> process
  232. self.process()
  233. time.sleep(5)
  234. print("[Info] [AI] Power Off")
  235. class BlackRay(Thread):
  236. def __init__(self, parent):
  237. Thread.__init__(self)
  238. self.parent = parent
  239. self.active = False
  240. self.sock = None
  241. self.shining = False
  242. def run( self ):
  243. conn = None
  244. addr = None
  245. self.sock = self.parent.try_bind(9991)
  246. if self.sock is not None:
  247. self.sock.listen(1)
  248. print('[Info] [AI] [BlackRay] Emitting on port 9991')
  249. self.shining = True
  250. else:
  251. print('[Error] [AI] [BlackRay] Failed to emit on port 9991')
  252. while self.shining:
  253. try:
  254. conn,addr = self.sock.accept()
  255. print('[Info] [AI] [BlackRay] Got connection from', addr)
  256. except socket.timeout:
  257. pass
  258. except socket.error as e:
  259. if self.shining == False:
  260. print("[Error] [AI] [BlackRay] Socket Error /return : "+str(e))
  261. return
  262. else:
  263. print("[Error] [AI] [BlackRay] Socket Error /break : "+str(e))
  264. break
  265. else:
  266. data = conn.recv(1024)
  267. if data :
  268. if data[0:4] == "SEND" :
  269. print("[Info] [AI] [BlackRay] Meat ready : "+data[5:])
  270. conn.close()
  271. print('[Info] [AI] [BlackRay] End of emission')
  272. self.sock.close()
  273. class Eater(Thread):
  274. def __init__(self, client, parent):
  275. Thread.__init__(self)
  276. self.client = client
  277. self.parent = parent
  278. def run(self):
  279. print('[Info] [AI] Yum... got meat')
  280. zombie_meat = "community_zombies.txt.gz"
  281. alien_meat = "community_aliens.txt.gz"
  282. droid_meat = "community_droids.txt.gz"
  283. ucav_meat = "community_ucavs.txt.gz"
  284. rpc_meat = "community_rpcs.txt.gz"
  285. ntp_meat = "community_ntps.txt.gz"
  286. dns_meat = "community_dnss.txt.gz"
  287. while 1:
  288. data = self.client.recv(1024)
  289. if not data:
  290. break
  291. if zombie_meat in data: # get zombies
  292. r = re.compile(".*("+zombie_meat+").*") # regex magics
  293. meat_type = r.search(data)
  294. m = meat_type.group(1)
  295. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  296. f.write(data)
  297. print('\n[Info] [AI] Got "%s Closing media transfer"' % f.name)
  298. f.close()
  299. elif alien_meat in data: # get aliens
  300. r = re.compile(".*("+alien_meat+").*") # regex magics
  301. meat_type = r.search(data)
  302. m = meat_type.group(1)
  303. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  304. f.write(data)
  305. print('\n[Info] [AI] Got "%s Closing media transfer"' % f.name)
  306. f.close()
  307. elif droid_meat in data: # get zombies
  308. r = re.compile(".*("+droid_meat+").*") # regex magics
  309. meat_type = r.search(data)
  310. m = meat_type.group(1)
  311. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  312. f.write(data)
  313. print('\n[Info] [AI] Got "%s Closing media transfer"' % f.name)
  314. f.close()
  315. elif ucav_meat in data: # get ucavs
  316. r = re.compile(".*("+ucav_meat+").*") # regex magics
  317. meat_type = r.search(data)
  318. m = meat_type.group(1)
  319. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  320. f.write(data)
  321. print('\n[Info] [AI] Got "%s Closing media transfer"' % f.name)
  322. f.close()
  323. elif rpc_meat in data: # get ucavs
  324. r = re.compile(".*("+rpc_meat+").*") # regex magics
  325. meat_type = r.search(data)
  326. m = meat_type.group(1)
  327. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  328. f.write(data)
  329. print('\n[Info] [AI] Got "%s Closing media transfer"' % f.name)
  330. f.close()
  331. elif ntp_meat in data: # get ntps
  332. r = re.compile(".*("+ntp_meat+").*") # regex magics
  333. meat_type = r.search(data)
  334. m = meat_type.group(1)
  335. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  336. f.write(data)
  337. print('\n[Info] [AI] Got "%s Closing media transfer"' % f.name)
  338. f.close()
  339. elif dns_meat in data: # get dnss
  340. r = re.compile(".*("+dns_meat+").*") # regex magics
  341. meat_type = r.search(data)
  342. m = meat_type.group(1)
  343. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  344. f.write(data)
  345. print('\n[Info] [AI] Got "%s Closing media transfer"' % f.name)
  346. f.close()
  347. self.client.close()
  348. self.parent.eater_full(self)
  349. class Absorber(Thread):
  350. def __init__(self, parent):
  351. Thread.__init__(self)
  352. self.parent = parent
  353. self.overflow = True
  354. self._eaters = []
  355. self.tmp_dir = parent.tmp_dir
  356. self.sock = False
  357. def run( self ):
  358. self.sock = self.parent.try_bind(9990)
  359. if self.sock is not None:
  360. self.sock.listen(1)
  361. print('[Info] [AI] Ready to feed on port 9990')
  362. self.overflow = False
  363. else:
  364. print('[Error] [AI] Failed to listen on port 9990')
  365. while not self.overflow:
  366. try:
  367. conn,addr = self.sock.accept()
  368. print('[Info] [AI] Got connection from', addr)
  369. except socket.timeout:
  370. pass
  371. except socket.error as e:
  372. if self.hungry == False:
  373. print("[Error] [AI] Socket Error /return : "+str(e))
  374. return
  375. else:
  376. print("[Error] [AI] Socket Error /break : "+str(e))
  377. break
  378. else:
  379. t = Eater(conn, self)
  380. t.start()
  381. self._eaters.append(t)
  382. self.sock.close()
  383. print('[Info] [AI] Dinner time is over')
  384. def eater_full(self, _thread):
  385. self._eaters.remove(_thread)
  386. class BlackHole ( Thread ):
  387. def __init__(self):
  388. Thread.__init__( self )
  389. self.daemon = True
  390. self.awake = True
  391. self.tmp_dir = "/tmp/"
  392. self.target_dir = '/var/www/ufonet/'
  393. self.blackray = None
  394. self.absorber = None
  395. self.computer = None
  396. def dream(self):
  397. if not os.path.exists(self.target_dir+"abductions.txt.gz"):
  398. abductions_fail = 0
  399. try:
  400. fc = gzip.open(self.target_dir+'abductions.txt.gz', 'wb')
  401. fc.close()
  402. except:
  403. print("[Error] [AI] Not 'abductions.txt.gz' file in "+self.target_dir)
  404. abductions_fail = abductions_fail + 1
  405. else:
  406. abductions_fail = 0
  407. if not os.path.exists(self.target_dir+"troops.txt.gz"):
  408. troops_fail = 0
  409. try:
  410. fc = gzip.open(self.target_dir+'troops.txt.gz', 'wb')
  411. fc.close()
  412. except:
  413. print("[Error] [AI] Not 'troops.txt.gz' file in "+self.target_dir)
  414. troops_fail = troops_fail + 1
  415. else:
  416. troops_fail = 0
  417. if not os.path.exists(self.target_dir+"robots.txt.gz"):
  418. robots_fail = 0
  419. try:
  420. fc = gzip.open(self.target_dir+'robots.txt.gz', 'wb')
  421. fc.close()
  422. except:
  423. print("[Error] [AI] Not 'robots.txt.gz' file in "+self.target_dir)
  424. robots_fail = robots_fail + 1
  425. else:
  426. robots_fail = 0
  427. if not os.path.exists(self.target_dir+"drones.txt.gz"):
  428. drones_fail = 0
  429. try:
  430. fc = gzip.open(self.target_dir+'drones.txt.gz', 'wb')
  431. fc.close()
  432. except:
  433. print("[Error] [AI] Not 'drones.txt.gz' file in "+self.target_dir)
  434. drones_fail = drones_fail + 1
  435. else:
  436. drones_fail = 0
  437. if not os.path.exists(self.target_dir+"reflectors.txt.gz"):
  438. reflectors_fail = 0
  439. try:
  440. fc = gzip.open(self.target_dir+'reflectors.txt.gz', 'wb')
  441. fc.close()
  442. except:
  443. print("[Error] [AI] Not 'reflectors.txt.gz' file in "+self.target_dir)
  444. reflectors_fail = reflectors_fail + 1
  445. else:
  446. reflectors_fail = 0
  447. if not os.path.exists(self.target_dir+"crystals.txt.gz"):
  448. ntps_fail = 0
  449. try:
  450. fc = gzip.open(self.target_dir+'crystals.txt.gz', 'wb')
  451. fc.close()
  452. except:
  453. print("[Error] [AI] Not 'crystals.txt.gz' file in "+self.target_dir)
  454. ntps_fail = ntps_fail + 1
  455. else:
  456. ntps_fail = 0
  457. if not os.path.exists(self.target_dir+"warps.txt.gz"):
  458. dnss_fail = 0
  459. try:
  460. fc = gzip.open(self.target_dir+'warps.txt.gz', 'wb')
  461. fc.close()
  462. except:
  463. print("[Error] [AI] Not 'warps.txt.gz' file in "+self.target_dir)
  464. dnss_fail = dnss_fail + 1
  465. else:
  466. dnss_fail = 0
  467. if not os.access(self.target_dir+"abductions.txt.gz",os.W_OK):
  468. print("[Error] [AI] Write access denied for 'abductions' file in "+self.target_dir)
  469. abductions_fail = abductions_fail + 1
  470. if not os.access(self.target_dir+"troops.txt.gz",os.W_OK):
  471. print("[Error] [AI] Write access denied for 'troops' file in "+self.target_dir)
  472. troops_fail = troops_fail + 1
  473. if not os.access(self.target_dir+"robots.txt.gz",os.W_OK):
  474. print("[Error] [AI] Write access denied for 'robots' file in "+self.target_dir)
  475. robots_fail = robots_fail + 1
  476. if not os.access(self.target_dir+"drones.txt.gz",os.W_OK):
  477. print("[Error] [AI] Write access denied for 'drones' file in "+self.target_dir)
  478. drones_fail = drones_fail + 1
  479. if not os.access(self.target_dir+"reflectors.txt.gz",os.W_OK):
  480. print("[Error] [AI] Write access denied for 'reflectors' file in "+self.target_dir)
  481. reflectors_fail = reflectors_fail + 1
  482. if not os.access(self.target_dir+"crystals.txt.gz",os.W_OK):
  483. print("[Error] [AI] Write access denied for 'crystals' file in "+self.target_dir)
  484. ntps_fail = ntps_fail + 1
  485. if not os.access(self.target_dir+"warps.txt.gz",os.W_OK):
  486. print("[Error] [AI] Write access denied for 'warps' file in "+self.target_dir)
  487. dnss_fail = dnss_fail + 1
  488. if abductions_fail > 0 and troops_fail > 0 and robots_fail > 0 and drones_fail > 0 and reflectors_fail > 0 and ntps_fail > 0 and dnss_fail > 0:
  489. print("\n[Error] [AI] Cannot found any container... -> [Aborting!]")
  490. print("\n[Info] [AI] Suspend [Blackhole] with: Ctrl+z")
  491. sys.exit(2)
  492. if self.consume():
  493. os.mkdir(self.tmp_dir + "blackhole")
  494. else:
  495. print("[Error] [AI] [Blackhol] Unable to consume in "+self.tmp_dir+"blackhole...")
  496. sys.exit(2)
  497. if not os.path.isdir(self.tmp_dir + "blackhole"):
  498. print("[Error] [AI] [Blackhole] Unable to create "+self.tmp_dir+"blackhole...")
  499. sys.exit(2)
  500. self.blackray = BlackRay(self)
  501. self.absorber = Absorber(self)
  502. self.computer = AI(self)
  503. self.awake = False
  504. print("[Info] [AI] [Blackhole] Having sweet dreams...")
  505. def consume(self):
  506. if os.path.isdir(self.tmp_dir + "blackhole"):
  507. try:
  508. shutil.rmtree(self.tmp_dir + "blackhole")
  509. except OSError as e:
  510. print("[Error] [AI] [Blackhole] Unable to consume : " + str(e))
  511. return False
  512. return True
  513. def try_bind(self, port):
  514. s=None
  515. try:
  516. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  517. s.settimeout(10)
  518. s.bind(('', port))
  519. except socket.error as e:
  520. if e.errno == 98: # if is in use wait a bit and retry
  521. time.sleep(3)
  522. return self.try_bind(port)
  523. print(("[Error] [AI] [Blackhole] Socket busy, connection failed on port " + str(port)))
  524. return s
  525. def run(self):
  526. self.dream()
  527. try:
  528. self.blackray.start()
  529. self.absorber.start()
  530. self.computer.start()
  531. if not self.blackray.shining or self.absorber.overflow or not self.computer.power_on:
  532. print("[Info] [AI] Advancing time in another space (waiting for server)"+os.linesep)
  533. time.sleep(1)
  534. while not self.blackray.shining or self.absorber.overflow or not self.computer.power_on:
  535. time.sleep(1)
  536. print("\n[Info] [AI] [BlackHole] All up and running...")
  537. while self.blackray.shining and not self.absorber.overflow and self.computer.power_on:
  538. time.sleep(1)
  539. except:
  540. traceback.print_exc()
  541. self.awaken()
  542. print("[Info] [AI] [Blackhole] Lifespan is up...")
  543. def collapse(self):
  544. self.blackray.shining = False
  545. self.absorber.overflow = True
  546. self.computer.power_on = False
  547. self.computer.join()
  548. self.blackray.join()
  549. self.absorber.join()
  550. def awaken(self):
  551. self.consume()
  552. self.collapse()
  553. self.awake = True
  554. if __name__ == "__main__":
  555. try:
  556. print("\n[Info] [AI] Initiating void generation sequence...\n")
  557. print('='*22 + '\n')
  558. app = BlackHole()
  559. app.start()
  560. while True: time.sleep(1)
  561. except KeyboardInterrupt:
  562. print("\n[Info] [AI] Terminating void generation sequence...\n")
  563. app.collapse()
  564. except Exception as e:
  565. traceback.print_exc()
  566. print ("\n[Error] [AI] Something wrong creating [Blackhole] -> [Passing!]\n")