-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.py
executable file
·148 lines (131 loc) · 5.61 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env python
import arrow
import os
import shutil
import glob
import tqdm
import base64
import shodan
import shodan.helpers as helpers
import time
import utils
import telegram
# Settings
############################################################
SHODAN_API_KEY = ''
BOT_TOKEN = ''
ROOM_ID = ''
SNAPS_MIN = 7 # The minimum number of snapshots to create a time-lapse
SHOW_IP = False # Set "True" to show the IP in the post
############################################################
bot = telegram.Bot(token=BOT_TOKEN)
while True:
ip = ''
country = ''
city = ''
res_count = 0
print('Looking for a random city...')
while res_count == 0:
city = utils.randomizer()
res_count = utils.downloader(city)
if res_count > 0:
print(f'{city} selected.')
print(f'{res_count} results retrieved from JSON')
# GIFs are stored in the local "snapshots" directory
try:
os.makedirs('snapshots/tmp')
except OSError:
pass
# Setup the Shodan API object
api = shodan.Shodan(SHODAN_API_KEY)
# Show a progress indicator
BAR_FORMAT = '{desc}{percentage:3.0f}%[{bar}] {n_fmt}/{total_fmt} '
'[{elapsed}<{remaining}, {rate_fmt}{postfix}]'
pbar = tqdm.tqdm(total=res_count, ascii=True, bar_format=BAR_FORMAT)
pbar.set_description(desc='Сollecting snapshots from the JSON')
# Loop over all of the Shodan data files the user provided
for banner in helpers.iterate_files(f'{city.lower()}-data.json.gz'):
# See whether the current banner has a screenshot,
# if it does then lets lookup more information about this IP
has_screenshot = helpers.get_screenshot(banner)
if has_screenshot:
try:
ip = helpers.get_ip(banner)
pbar.write(f'Looking up {ip}')
host = api.host(ip, history=True)
country = host['country_name']
city = host['city']
# Store all the historical screenshots for this IP
screenshots = []
for tmp_banner in host['data']:
# Try to extract the image from the banner data
screenshot = helpers.get_screenshot(tmp_banner)
if screenshot:
# Sort the images by the time they were
# collected so the GIF will loop based on
# the local time regardless of which day the
# banner was taken.
timestamp = arrow.get(banner['timestamp']).time()
sort_key = timestamp.hour
# Add the screenshot to the list of screenshots
# which we'll use to create the timelapse
screenshots.append((
sort_key,
str.encode(screenshot['data'])
))
# Extract the screenshots and turn them into a GIF if
# we've got more than a few images
if len(screenshots) >= SNAPS_MIN:
# screenshots is a list where each item is a tuple of:
# (sort key, screenshot in base64 encoding)
#
# Lets sort that list based on the sort key and
# then use Python's enumerate
# to generate sequential numbers for
# the temporary image filenames
for (i, screenshot) in enumerate(sorted(screenshots,
key=lambda x: x[0],
reverse=True)):
# Create a temporary image file
open(f'snapshots/tmp/gif-image-{i}.jpg', 'wb').write(
base64.decodebytes(screenshot[1]))
# Create the actual GIF using the
# ImageMagick "convert" command
# The resulting GIFs are stored in the local
# "snapshots" directory
os.system(f'convert -layers OptimizePlus -delay 5x10 '
f'snapshots/tmp/gif-image-*.jpg '
f'-loop 0 +dither -colors 256 -depth 8 '
f'snapshots/{ip}.gif')
# Clean up the temporary files
files = glob.glob('snapshots/tmp/gif-image-*.jpg')
for f in files:
os.remove(f)
pbar.update(1)
pbar.write(f'GIF created for {ip}')
else:
open(f'snapshots/{ip}.jpg', 'wb').write(
base64.decodebytes(screenshots[0][1]))
pbar.update(1)
pbar.write(f'JPG created for {ip}')
time.sleep(4)
except Exception as e:
pbar.update(1)
pbar.write(repr(e))
pbar.close()
dir = 'snapshots'
fcount = 0
for path in os.listdir(dir):
if os.path.isfile(os.path.join(dir, path)):
fcount += 1
pbar = tqdm.tqdm(total=fcount, ascii=True, bar_format=BAR_FORMAT)
pbar.set_description(desc='Sending snapnshots to the telegram channel')
for file in os.listdir(dir):
if file.endswith('.jpg'):
utils.jpg_poster(pbar, file, bot, ROOM_ID, country, city, SHOW_IP)
elif file.endswith('.gif'):
utils.gif_poster(pbar, file, bot, ROOM_ID, country, city, SHOW_IP)
else:
continue
pbar.close()
shutil.rmtree('snapshots')