Skip to content

Commit e11e23d

Browse files
authored
Update configure.py to add autofill lat/long with geo api
Updated configure.py to add search option for a given city/location and autofill lat/long boxes from one of selected search results.
1 parent 4088cc9 commit e11e23d

File tree

1 file changed

+95
-3
lines changed

1 file changed

+95
-3
lines changed

configure.py

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import subprocess
2626
import sys
2727
import webbrowser
28+
import requests
29+
import babel
2830

2931
MIN_PYTHON = (3, 9)
3032
if sys.version_info < MIN_PYTHON:
@@ -475,7 +477,11 @@ def on_save_click(self):
475477

476478
def on_saverun_click(self):
477479
self.save_config_values()
478-
subprocess.Popen(f'"{MAIN_DIRECTORY}{glob.glob("main.*", root_dir=MAIN_DIRECTORY)[0]}"', shell=True)
480+
kwargs = {}
481+
if hasattr(subprocess, "DETACHED_PROCESS"):
482+
kwargs["creationflags"] = subprocess.DETACHED_PROCESS
483+
subprocess.Popen([sys.executable, os.path.join(os.getcwd(), "main.py")], **kwargs)
484+
# subprocess.Popen(f'"{MAIN_DIRECTORY}{glob.glob("main.*", root_dir=MAIN_DIRECTORY)[0]}"', shell=True)
479485
self.window.destroy()
480486

481487
def on_brightness_change(self, e=None):
@@ -554,7 +560,7 @@ def __init__(self, main_window: TuringConfigWindow):
554560
self.window = Toplevel()
555561
self.window.withdraw()
556562
self.window.title('Configure weather & ping')
557-
self.window.geometry("750x400")
563+
self.window.geometry("750x680")
558564

559565
self.main_window = main_window
560566

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

623+
self.citysearch1_label = ttk.Label(self.window, text='Location search', font='bold')
624+
self.citysearch1_label.place(x=80, y=370)
625+
626+
self.citysearch2_label = ttk.Label(self.window, text="Enter location to automatically get coordinates (latitude/longitude).\n"
627+
"For example \"Berlin\" \"London, GB\", \"London, Quebec\".\n"
628+
"Remember to set valid API key and pick language first!")
629+
self.citysearch2_label.place(x=10, y=396)
630+
631+
self.citysearch3_label = ttk.Label(self.window, text="Enter location")
632+
self.citysearch3_label.place(x=10, y=474)
633+
self.citysearch_entry = ttk.Entry(self.window)
634+
self.citysearch_entry.place(x=140, y=470, width=300)
635+
self.citysearch_btn = ttk.Button(self.window, text="Search", command=lambda: self.on_search_click())
636+
self.citysearch_btn.place(x=450, y=468, height=40, width=130)
637+
638+
self.citysearch4_label = ttk.Label(self.window, text="Select location\n(use after Search)")
639+
self.citysearch4_label.place(x=10, y=540)
640+
self.citysearch_cb = ttk.Combobox(self.window, values=[], state='readonly')
641+
self.citysearch_cb.place(x=140, y=544, width=360)
642+
self.citysearch_btn2 = ttk.Button(self.window, text="Fill in lat/long", command=lambda: self.on_filllatlong_click())
643+
self.citysearch_btn2.place(x=520, y=540, height=40, width=130)
644+
645+
self.citysearch_warn_label = ttk.Label(self.window, text="")
646+
self.citysearch_warn_label.place(x=20, y=600)
647+
self.citysearch_warn_label.config(foreground="#ff0000")
648+
617649
self.save_btn = ttk.Button(self.window, text="Save settings", command=lambda: self.on_save_click())
618-
self.save_btn.place(x=590, y=340, height=50, width=130)
650+
self.save_btn.place(x=590, y=620, height=50, width=130)
619651

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

654+
self._city_entries = []
655+
622656
def validateCoord(self, coord: str):
623657
if not coord:
624658
return True
@@ -666,6 +700,64 @@ def load_config_values(self, config):
666700
self.lang_cb.set(weather_lang_map[self.config['config']['WEATHER_LANGUAGE']])
667701
except:
668702
self.lang_cb.set(weather_lang_map["en"])
703+
704+
def citysearch_show_warning(self, warning):
705+
self.citysearch_warn_label.config(text=warning)
706+
707+
def on_search_click(self):
708+
OPENWEATHER_GEOAPI_URL = "http://api.openweathermap.org/geo/1.0/direct"
709+
api_key = self.api_entry.get()
710+
lang = [k for k, v in weather_lang_map.items() if v == self.lang_cb.get()][0]
711+
city = self.citysearch_entry.get()
712+
713+
if len(api_key) == 0 or len(city) == 0:
714+
self.citysearch_show_warning("API key and city name cannot be empty.")
715+
return
716+
717+
try:
718+
request = requests.get(OPENWEATHER_GEOAPI_URL, timeout=5, params={"appid": api_key, "lang": lang,
719+
"q": city, "limit": 10})
720+
except:
721+
self.citysearch_show_warning("Error fetching OpenWeatherMap Geo API")
722+
return
723+
724+
if request.status_code == 401:
725+
self.citysearch_show_warning("Invalid OpenWeatherMap API key.")
726+
return
727+
elif request.status_code != 200:
728+
self.citysearch_show_warning(f"Error #{request.status_code} fetching OpenWeatherMap Geo API.")
729+
return
730+
731+
self._city_entries = []
732+
cb_entries = []
733+
for entry in request.json():
734+
name = entry['name']
735+
state = entry['state']
736+
lat = entry['lat']
737+
long = entry['lon']
738+
country_code = entry['country'].upper()
739+
country = babel.Locale(lang).territories[country_code]
740+
full_name = f"{name}, {state}, {country}"
741+
self._city_entries.append({"full_name": full_name, "lat": str(lat), "long": str(long)})
742+
cb_entries.append(full_name)
743+
744+
self.citysearch_cb.config(values = cb_entries)
745+
if len(cb_entries) == 0:
746+
self.citysearch_show_warning("No given city found.")
747+
else:
748+
self.citysearch_cb.current(0)
749+
self.citysearch_show_warning("Select your city now from list and apply \"Fill in lat/long\".")
750+
751+
def on_filllatlong_click(self):
752+
if len(self._city_entries) == 0:
753+
self.citysearch_show_warning("No city selected or no search results.")
754+
return
755+
city = [i for i in self._city_entries if i['full_name'] == self.citysearch_cb.get()][0]
756+
self.lat_entry.delete(0, END)
757+
self.lat_entry.insert(0, city['lat'])
758+
self.long_entry.delete(0, END)
759+
self.long_entry.insert(0, city['long'])
760+
self.citysearch_show_warning(f"Lat/long values filled for {city['full_name']}")
669761

670762
def on_save_click(self):
671763
self.save_config_values()

0 commit comments

Comments
 (0)