@@ -146,60 +146,52 @@ def clean_input(data: str) -> str:
146146
147147def resolve_location (
148148 redis_client : redis .client ,
149+ geolocator : Nominatim ,
149150 data = "Oslo/Norway" ,
150151) -> Tuple [Optional [float ], Optional [float ], str , bool ]:
151- """Get coordinates from location name. Return lat, long, name."""
152- cache = None
153-
152+ """Get coordinates from location name. Return lat, long, name, cached."""
154153 # Check if coordinates
155154 if "," in data :
156- lat , lon = data .split ("," )
157155 try :
158- lat = float (lat )
159- lon = float (lon )
156+ lat_str , lon_str = data .split ("," , 1 )
157+ lat = float (lat_str )
158+ lon = float (lon_str )
160159 return lat , lon , f"coordinates { lat } , { lon } " , False
161- except ValueError :
160+ except ( ValueError , IndexError ) :
162161 pass
163162
164- lat = None
165- lon = None
166- address = None
167-
168163 # Check if in redis cache
169- if redis_client is not None :
170- cache = redis_client .get (data )
164+ cache = redis_client .get (data ) if redis_client is not None else None
171165 if cache :
172- lat , lon , address = cache .decode ("utf-8" ).split ("|" )
173- lat = float (lat )
174- lon = float (lon )
166+ lat_str , lon_str , address = cache .decode ("utf-8" ).split ("|" , 2 )
167+ return float (lat_str ), float (lon_str ), address , True
175168
176- else :
177- coordinate = None
178- try :
179- coordinate = geolocator .geocode (data , language = "en" )
180- except socket .timeout as err :
181- # nominatim.openstreetmap.org down
182- print (f"nominatim.openstreetmap.org down. { err } " )
183- return None , None , "No service" , False
184- if coordinate :
185- lat = coordinate .latitude
186- lon = coordinate .longitude
187- try :
188- address = coordinate .address .decode ("utf-8" )
189- except AttributeError :
190- address = coordinate .address
169+ # Geocode the location
170+ try :
171+ coordinate = geolocator .geocode (data , language = "en" )
172+ except socket .timeout as err :
173+ logger .warning ("Geocoding service timeout: %s" , err )
174+ return None , None , "No service" , False
191175
192- if lat :
193- # Store to redis cache as <search>: "lat,lon,address"
194- if not cache :
176+ if not coordinate :
177+ return None , None , "No location found" , False
178+
179+ lat = coordinate .latitude
180+ lon = coordinate .longitude
181+ address = coordinate .address if isinstance (coordinate .address , str ) else str (coordinate .address )
182+
183+ # Store to redis cache as <search>: "lat|lon|address"
184+ if redis_client is not None :
185+ try :
195186 redis_client .setex (
196187 data ,
197188 datetime .timedelta (days = 7 ),
198- "|" .join ([str (lat ), str (lon ), str ( address ) ]),
189+ "|" .join ([str (lat ), str (lon ), address ]),
199190 )
200- return lat , lon , address , cache
191+ except redis .exceptions .RedisError as err :
192+ logger .warning ("Redis cache write failed: %s" , err )
201193
202- return None , None , "No location found" , False
194+ return lat , lon , address , False
203195
204196
205197def fetch_weather (lat : float , lon : float , address : str = "" ):
@@ -504,6 +496,8 @@ def format_oneliner(forecast, timezone, imperial=False, beaufort=False, offset=0
504496
505497async def handle_request (reader , writer ):
506498 """Receives connections and responds."""
499+ global r , geolocator
500+
507501 data = await reader .read (input_limit )
508502 response = ""
509503 updated = None
@@ -544,16 +538,20 @@ async def handle_request(reader, writer):
544538 user_input = user_input [1 :]
545539 wind_chill = True
546540
541+ # Parse screen width
547542 if "~" in user_input :
548- screenwidth = int (user_input .split ("~" )[1 ])
549- user_input = user_input .split ("~" )[0 ]
543+ try :
544+ user_input , width_str = user_input .split ("~" , 1 )
545+ screenwidth = max (80 , min (int (width_str ), 200 ))
546+ except ValueError :
547+ pass
550548
551549 if user_input == "help" or len (user_input ) == 0 :
552550 logger .info ("%s help" , addr [0 ])
553551 response = service_usage ()
554552
555553 else :
556- lat , lon , address , cached_location = resolve_location (r , user_input )
554+ lat , lon , address , cached_location = resolve_location (r , geolocator , user_input )
557555 if not lat :
558556 if address == "No service" :
559557 response += "Error: address service down. You can still use coordinates."
@@ -605,9 +603,11 @@ async def handle_request(reader, writer):
605603 writer .close ()
606604
607605 if last_reply_file :
608- with open (last_reply_file , mode = "w" , encoding = "utf-8" ) as f :
609- f .write (addr [0 ] + " " + user_input + "\n \n " )
610- f .write (response )
606+ try :
607+ with open (last_reply_file , mode = "w" , encoding = "utf-8" ) as f :
608+ f .write (f"{ addr [0 ]} { user_input } \n \n { response } " )
609+ except OSError as err :
610+ logger .warning ("Failed to write last reply file: %s" , err )
611611
612612
613613async def main (args ):
0 commit comments