This repository has no description
5.2 kB
150 lines
1import geoip2.database
2import fileinput
3import json
4import requests
5import os
6import random
7import sys
8
9
10# https://open-meteo.com/en/docs
11def weather_code_representation(code: int) -> str:
12 if code == 0:
13 return 'clear sky'
14 if code == 1:
15 return 'mainly clear'
16 if code == 2:
17 return 'partly cloudy'
18 if code == 3:
19 return 'overcast'
20 if code == 45:
21 return 'fog'
22 if code == 48:
23 return 'depositing rime fog'
24 if code == 51:
25 return 'light drizzle'
26 if code == 53:
27 return 'moderate drizzle'
28 if code == 55:
29 return 'heavy drizzle'
30 if code == 56:
31 return 'light freezing drizzle'
32 if code == 57:
33 return 'heavy freezing drizzle'
34 if code == 61:
35 return 'light rain'
36 if code == 63:
37 return 'moderate rain'
38 if code == 65:
39 return 'heavy rain'
40 if code == 66:
41 return 'light freezing rain'
42 if code == 67:
43 return 'heavy freezing rain'
44 if code == 71:
45 return 'light snow'
46 if code == 73:
47 return 'moderate snow'
48 if code == 75:
49 return 'heavy snow'
50 if code == 77:
51 return 'light snow grains'
52 if code == 80:
53 return 'light rain showers'
54 if code == 81:
55 return 'moderate rain showers'
56 if code == 82:
57 return 'heavy rain showers'
58 if code == 85:
59 return 'light snow showers'
60 if code == 86:
61 return 'heavy snow showers'
62 if code == 95:
63 return 'thunderstorm'
64 if code == 96:
65 return 'thunderstorm with light hail'
66 if code == 99:
67 return 'thunderstorm with heavy hail'
68 return f'unknown weather code {code}'
69
70
71def downfall_representation(precipitation: float) -> str:
72 if precipitation > 0:
73 return f' the precipitation is {precipitation} millimeter'
74 else:
75 return ''
76
77
78geoip = geoip2.database.Reader(os.environ['MAXMIND_GEOIP_DB'])
79seen = {}
80output = []
81if len(sys.argv) > 1:
82 ips = sys.argv[1:]
83else:
84 ips = list(fileinput.input())
85if len(ips) > 5:
86 output.append('weather report.')
87 for ip in fileinput.input():
88 if "80.147.140.51" in ip:
89 output.append(
90 'Weather report for c-base.'
91 'temperature of -270 degrees, '
92 )
93 else:
94 try:
95 location = geoip.city(ip.strip())
96 if location.city.geoname_id not in seen:
97 seen[location.city.geoname_id] = True
98 url = (
99 f'https://api.open-meteo.com/v1/forecast'
100 f'?latitude={location.location.latitude}'
101 f'&longitude={location.location.longitude}'
102 f'¤t=temperature_2m,weather_code'
103 )
104 resp = requests.get(url)
105 weather = json.loads(resp.text)
106 output.append(
107 f'{location.city.name}, {location.country.name}. '
108 f'{weather_code_representation(weather["current"]["weather_code"])}. '
109 f'{weather["current"]["temperature_2m"]} degrees.'
110 )
111 except: # noqa E722
112 pass
113
114else:
115 for ip in ips:
116 if "80.147.140.51" in ip:
117 output.append(
118 'Weather report for c-base, space. '
119 'It is empty space outside '
120 'with a temperature of -270 degrees, '
121 'a lightspeed of 299792 kilometers per second '
122 'and a humidity of Not a Number percent. '
123 f'The probability of reincarnation is {random.randrange(0, 100)} percent. '
124 )
125 else:
126 try:
127 location = geoip.city(ip.strip())
128 if location.city.geoname_id not in seen:
129 seen[location.city.geoname_id] = True
130 url = (
131 f'https://api.open-meteo.com/v1/forecast'
132 f'?latitude={location.location.latitude}'
133 f'&longitude={location.location.longitude}'
134 '¤t=temperature_2m,precipitation,weather_code,relative_humidity_2m,wind_speed_10m'
135 '&wind_speed_unit=ms'
136 )
137 resp = requests.get(url)
138 weather = json.loads(resp.text)
139 output.append(
140 f'Weather report for {location.city.name}, {location.country.name}. '
141 f'It is {weather_code_representation(weather["current"]["weather_code"])} outside'
142 f'{downfall_representation(weather["current"]["precipitation"])}, '
143 f'with a temperature of {weather["current"]["temperature_2m"]} degrees, '
144 f'a wind speed of {weather["current"]["wind_speed_10m"]} meters per second '
145 f'and a humidity of {weather["current"]["relative_humidity_2m"]} percent. '
146 )
147 except: # noqa E722
148 pass
149
150print('\n'.join(output))