This repository has no description
5.2 kB
149 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
77geoip = geoip2.database.Reader(os.environ['MAXMIND_GEOIP_DB'])
78seen = {}
79output = []
80if len(sys.argv) > 1:
81 ips = sys.argv[1:]
82else:
83 ips = list(fileinput.input())
84if len(ips) > 5:
85 output.append('weather report.')
86 for ip in fileinput.input():
87 if "80.147.140.51" in ip:
88 output.append(
89 'Weather report for c-base.'
90 'temperature of -270 degrees, '
91 )
92 else:
93 try:
94 location = geoip.city(ip.strip())
95 if location.city.geoname_id not in seen:
96 seen[location.city.geoname_id] = True
97 url = (
98 f'https://api.open-meteo.com/v1/forecast'
99 f'?latitude={location.location.latitude}'
100 f'&longitude={location.location.longitude}'
101 f'¤t=temperature_2m,weather_code'
102 )
103 resp = requests.get(url)
104 weather = json.loads(resp.text)
105 output.append(
106 f'{location.city.name}, {location.country.name}. '
107 f'{weather_code_representation(weather["current"]["weather_code"])}. '
108 f'{weather["current"]["temperature_2m"]} degrees.'
109 )
110 except: # noqa E722
111 pass
112
113else:
114 for ip in ips:
115 if "80.147.140.51" in ip:
116 output.append(
117 'Weather report for c-base, space. '
118 'It is empty space outside '
119 'with a temperature of -270 degrees, '
120 'a lightspeed of 299792 kilometers per second '
121 'and a humidity of Not a Number percent. '
122 f'The probability of reincarnation is {random.randrange(0, 100)} percent. '
123 )
124 else:
125 try:
126 location = geoip.city(ip.strip())
127 if location.city.geoname_id not in seen:
128 seen[location.city.geoname_id] = True
129 url = (
130 f'https://api.open-meteo.com/v1/forecast'
131 f'?latitude={location.location.latitude}'
132 f'&longitude={location.location.longitude}'
133 '¤t=temperature_2m,precipitation,weather_code,relative_humidity_2m,wind_speed_10m'
134 '&wind_speed_unit=ms'
135 )
136 resp = requests.get(url)
137 weather = json.loads(resp.text)
138 output.append(
139 f'Weather report for {location.city.name}, {location.country.name}. '
140 f'It is {weather_code_representation(weather["current"]["weather_code"])} outside'
141 f'{downfall_representation(weather["current"]["precipitation"])}, '
142 f'with a temperature of {weather["current"]["temperature_2m"]} degrees, '
143 f'a wind speed of {weather["current"]["wind_speed_10m"]} meters per second '
144 f'and a humidity of {weather["current"]["relative_humidity_2m"]} percent. '
145 )
146 except: # noqa E722
147 pass
148
149print('\n'.join(output))