Skip to content

Upgraded options with search and autofill city latitude and longitude with geoapi #823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 93 additions & 2 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import subprocess
import sys
import webbrowser
import requests
import babel

MIN_PYTHON = (3, 9)
if sys.version_info < MIN_PYTHON:
Expand Down Expand Up @@ -554,7 +556,7 @@ def __init__(self, main_window: TuringConfigWindow):
self.window = Toplevel()
self.window.withdraw()
self.window.title('Configure weather & ping')
self.window.geometry("750x400")
self.window.geometry("750x680")

self.main_window = main_window

Expand Down Expand Up @@ -614,11 +616,39 @@ def __init__(self, main_window: TuringConfigWindow):
self.lang_cb = ttk.Combobox(self.window, values=list(weather_lang_map.values()), state='readonly')
self.lang_cb.place(x=190, y=325, width=250)

self.citysearch1_label = ttk.Label(self.window, text='Location search', font='bold')
self.citysearch1_label.place(x=80, y=370)

self.citysearch2_label = ttk.Label(self.window, text="Enter location to automatically get coordinates (latitude/longitude).\n"
"For example \"Berlin\" \"London, GB\", \"London, Quebec\".\n"
"Remember to set valid API key and pick language first!")
self.citysearch2_label.place(x=10, y=396)

self.citysearch3_label = ttk.Label(self.window, text="Enter location")
self.citysearch3_label.place(x=10, y=474)
self.citysearch_entry = ttk.Entry(self.window)
self.citysearch_entry.place(x=140, y=470, width=300)
self.citysearch_btn = ttk.Button(self.window, text="Search", command=lambda: self.on_search_click())
self.citysearch_btn.place(x=450, y=468, height=40, width=130)

self.citysearch4_label = ttk.Label(self.window, text="Select location\n(use after Search)")
self.citysearch4_label.place(x=10, y=540)
self.citysearch_cb = ttk.Combobox(self.window, values=[], state='readonly')
self.citysearch_cb.place(x=140, y=544, width=360)
self.citysearch_btn2 = ttk.Button(self.window, text="Fill in lat/long", command=lambda: self.on_filllatlong_click())
self.citysearch_btn2.place(x=520, y=540, height=40, width=130)

self.citysearch_warn_label = ttk.Label(self.window, text="")
self.citysearch_warn_label.place(x=20, y=600)
self.citysearch_warn_label.config(foreground="#ff0000")

self.save_btn = ttk.Button(self.window, text="Save settings", command=lambda: self.on_save_click())
self.save_btn.place(x=590, y=340, height=50, width=130)
self.save_btn.place(x=590, y=620, height=50, width=130)

self.window.protocol("WM_DELETE_WINDOW", self.on_closing)

self._city_entries = []

def validateCoord(self, coord: str):
if not coord:
return True
Expand Down Expand Up @@ -666,6 +696,67 @@ def load_config_values(self, config):
self.lang_cb.set(weather_lang_map[self.config['config']['WEATHER_LANGUAGE']])
except:
self.lang_cb.set(weather_lang_map["en"])

def citysearch_show_warning(self, warning):
self.citysearch_warn_label.config(text=warning)

def on_search_click(self):
OPENWEATHER_GEOAPI_URL = "http://api.openweathermap.org/geo/1.0/direct"
api_key = self.api_entry.get()
lang = [k for k, v in weather_lang_map.items() if v == self.lang_cb.get()][0]
city = self.citysearch_entry.get()

if len(api_key) == 0 or len(city) == 0:
self.citysearch_show_warning("API key and city name cannot be empty.")
return

try:
request = requests.get(OPENWEATHER_GEOAPI_URL, timeout=5, params={"appid": api_key, "lang": lang,
"q": city, "limit": 10})
except:
self.citysearch_show_warning("Error fetching OpenWeatherMap Geo API")
return

if request.status_code == 401:
self.citysearch_show_warning("Invalid OpenWeatherMap API key.")
return
elif request.status_code != 200:
self.citysearch_show_warning(f"Error #{request.status_code} fetching OpenWeatherMap Geo API.")
return

self._city_entries = []
cb_entries = []
for entry in request.json():
name = entry['name']
state = entry.get('state', None)
lat = entry['lat']
long = entry['lon']
country_code = entry['country'].upper()
country = babel.Locale(lang).territories[country_code]
if state is not None:
full_name = f"{name}, {state}, {country}"
else:
full_name = f"{name}, {country}"
self._city_entries.append({"full_name": full_name, "lat": str(lat), "long": str(long)})
cb_entries.append(full_name)

self.citysearch_cb.config(values = cb_entries)
if len(cb_entries) == 0:
self.citysearch_show_warning("No given city found.")
else:
self.citysearch_cb.current(0)
self.citysearch_show_warning("Select your city now from list and apply \"Fill in lat/long\".")

def on_filllatlong_click(self):
if len(self._city_entries) == 0:
self.citysearch_show_warning("No city selected or no search results.")
return
city = [i for i in self._city_entries if i['full_name'] == self.citysearch_cb.get()][0]
self.lat_entry.delete(0, END)
self.lat_entry.insert(0, city['lat'])
self.long_entry.delete(0, END)
self.long_entry.insert(0, city['long'])
self.citysearch_show_warning(f"Lat/long values filled for {city['full_name']}")

def on_save_click(self):
self.save_config_values()
Expand Down
Loading