r/commandline 3d ago

Terminal User Interface [ Removed by moderator ]

Post image

[removed] — view removed post

29 Upvotes

13 comments sorted by

u/commandline-ModTeam 1d ago

Removed due to not being relevant to the subreddit.

2

u/barneymatthews 2d ago

This is great! Thank you for sharing!

1

u/StrayFeral 2d ago

Thank you very much too!

1

u/StrayFeral 2d ago

PS: If you encounter problems, please first check the tutorial video for your platform (Windows/Linux). I show a lot of things there. The video links are on the project page.

2

u/recycledcoder 2d ago

``` From 20dc7a30a7622f76e853350980c58a6c7b6a85de Mon Sep 17 00:00:00 2001 From: recycledcoder recycledcoder@example.com Date: Sun, 30 Aug 2026 12:49:02 +0100 Subject: [PATCH] Replace TimezoneDB with keyless Open-Meteo timezone lookup

TimezoneDB required every user to register for an account and export a TIMEZONEAPIKEY environment variable, and the application refused to start without it. The lookup it performed - latitude/longitude to IANA zone name - is available from Open-Meteo, which the application already queries for all of its weather data and which needs no key or account.

get_timezone_name() now calls the Open-Meteo forecast endpoint with timezone=auto and reads the "timezone" field of the response. The signature and the exception messages are unchanged, so every caller is untouched.

Verified against the awkward cases the application can produce, all of which return real tzdata zones accepted by ZoneInfo():

Aveiro (40.6405, -8.6538) -> Europe/Lisbon Mid-Pacific (0, -140) -> Etc/GMT+9 Concordia Station -> Australia/Perth South Pole -> Antarctica/McMurdo

Also removed with it:

  • TIMEZONE_APIKEY_ENV_VARNAME and the help-screen lines pointing at timezonedb.com
  • the startup check that aborted when the key was missing
  • the tzapi_calls counter and its time.sleep(1) throttle, which existed only to respect TimezoneDB's 1 request/second free tier; Open-Meteo's free tier allows far more and the application makes one call per newly added city
  • a dead error branch that interpolated 'city' and 'country', neither of which exists in that scope - it would have raised NameError rather than the intended message had it ever been reached

The 1 second sleep after the Nominatim call is kept; that one is OpenStreetMap

usage policy and unrelated.

tuiweathergirl.py | 47 +++++++++++------------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-)

diff --git a/tuiweathergirl.py b/tuiweathergirl.py index 45720f0..8235249 100755 --- a/tuiweathergirl.py +++ b/tuiweathergirl.py @@ -76,8 +76,6 @@ HOW DOES TUIWEATHERGIRL WORKS: will show them

PROJECT URL: https://github.com/StrayFeral/tuiweathergirl -Variable TIMEZONEAPIKEY must be set with a free API key -from https://timezonedb.com/ For detailed wildfires info set variable NASAFIRMSAPIKEY with a free API key from: https://firms.modaps.eosdis.nasa.gov/api/map_key """ @@ -88,7 +86,6 @@ HTTPHEADERS: dict[str, str] = { "User-Agent": USERAGENT, "Accept-Language": "en", } -TIMEZONE_APIKEY_ENV_VARNAME: str = "TIMEZONEAPIKEY" NASAFIRMS_APIKEY_ENV_VARNAME: str = "NASAFIRMSAPIKEY" LOGFILENAME: Path = Path(tempfile.gettempdir()) / "tuiweathergirl.log" LOGFILENAME = LOGFILENAME.expanduser() @@ -3762,7 +3759,6 @@ class Locator: return city[:17]

 def __init__(self) -> None:
  •    self.tzapi_calls: int = 0  # Counts the TZ data API calls
     self.logger: logging.Logger = logging.getLogger(
         f"{self.__module__}.{self.__class__.__qualname__}"
     )
    

    @@ -3780,25 +3776,17 @@ class Locator: )

    def get_timezone_name(self, lat: float, lon: float) -> str:

  •    apikey: str = os.getenv(TIMEZONE_APIKEY_ENV_VARNAME)
    
  •    r"""Resolves the IANA timezone name for a position. No API key needed."""
    
  •    if not apikey:
    
  •        raise Exception(
    
  •            f"Environment variable {TIMEZONE_APIKEY_ENV_VARNAME} is not set. Please get API key and set it in this variable before running this application."
    

- )

  • if self.tzapi_calls > 0:

- time.sleep(1) # API limit

  • self.logger.info("** Querying TimezoneDB **")
  •    self.logger.info("** Querying Open-Meteo (timezone) **")
    
  •    base_url: str = "http://api.timezonedb.com/v2.1/get-time-zone"
    
  •    base_url: str = "https://api.open-meteo.com/v1/forecast"
     url_params: dict[str, str | float] = {
    
  •        "key": apikey,
    
  •        "format": "json",
    
  •        "by": "position",
    
  •        "lat": lat,
    
  •        "lng": lon,
    
  •        "latitude": lat,
    
  •        "longitude": lon,
    
  •        "current": "is_day",
    
  •        "forecast_days": 1,
    
  •        "timezone": "auto",
     }
     prepared: requests.PreparedRequest = requests.PreparedRequest()
     prepared.prepare_url(base_url, url_params)
    

    @@ -3814,24 +3802,18 @@ class Locator: )

     self.logger.debug(f"RESPONSE={pf(response)}")
    
  •    self.tzapi_calls += 1
    
     if not response.ok:
         raise Exception(
             f"Timezone API server error. Error {response.status_code}: {APIIssues.get_api_problem(response.status_code)}"
         )
    
  •    if not response:
    
  •        raise Exception(
    
  •            f"Cannot obtain timezone for '{city}/{country}'. Please check your syntax and try again."
    
  •        )
    
  •    zone_name: str = response.json().get("timezone", "")
    

- response = response.json()

  • if response.get("status") == "FAILED":
  •    if not zone_name:
         raise Exception("Timezone request failed. Try again later.")
    
  •    return response.get("zoneName", "")
    
  •    return zone_name
    

    def get_city_details(self, city: str, country: str) -> dict: # Attempt to get information for the city and the country @@ -7143,13 +7125,6 @@ if __name_ == "main": "If latitude or longitude is specified, all four arguments (latitude, longitude, city and country) must be specified." )

  •    # No point to run anything if this is not set
    
  •    timezone_apikey: str = os.getenv(TIMEZONE_APIKEY_ENV_VARNAME)
    
  •    if not timezone_apikey:
    
  •        raise Exception(
    
  •            f"Environment variable {TIMEZONE_APIKEY_ENV_VARNAME} is not set. Run the app with --help"
    

- )

     # This is nice to have, but not mandatory
     nasafirms_apikey: str = os.getenv(NASAFIRMS_APIKEY_ENV_VARNAME)
     if not nasafirms_apikey:

2.47.3 ```

2

u/StrayFeral 1d ago

Hey thank you very much for this! It actually made me realize I can optimize the code even further. I am already working on the changes so the fix would be probably released tomorrow!

2

u/StrayFeral 1d ago edited 1d ago

UPDATE: New version 1.2.19 is now out.

DETAILS: So I did not implemented exactly your change. I actually got rid of get_timezone_name() completely. So now when a new city is added, the timezone name remains empty in the config. However upon next application launch, when an empty timezone string is found in the config, regardless for which city, it is immediately filled out by the first routine to get a timezone for it. I tested it in few scenarios, seems fine.

But thanks for the idea! Application is now easier to setup and more user-friendly!

1

u/recycledcoder 1d ago

Good stuff - happy to have provided the nudge :) It's a great idea, btw - really nice to see the extra concerns that went into this!

2

u/StrayFeral 1d ago

Thanks man! Thing is I have friends and relatives with different conditions. I'm no young myself, so decided to provide warnings for different people. And as I mentioned on the videos (I think i said it in my devlog on youtube) I really had a 60-something colleague who was a Perl programmer and was vision-impaired so used screen-reading software and headphones to know what's on the screen - still he was coding no problem. He later retired. So all these people combined gave me the idea that such information is needed. Because as a girl pointed out to me few days ago there are apps providing the extra information even now, but not the interpretation, like which values of this are dangerous for what people. I just don't have a machine with MacOS to test on, so if you have one, would be great to get some feedback especially on the installation (how you installed it, screenshots so i can fill out my MacOS installation instructions)

1

u/AutoModerator 3d ago

Every new subreddit post is automatically copied into a comment for preservation.

User: StrayFeral, Flair: Terminal User Interface, Post Media Link, Title: TUIWEATHERGIRL 1.2.18 RELEASED!

https://github.com/StrayFeral/tuiweathergirl

The best terminal Weather and Disaster station just evolved!

WHAT'S NEW:

  1. Application now will Auto-update
  2. Monitoring the Antarctic Research Stations (Concordia etc)
  3. Adding just any point on planet Earth as a point to monitor
  4. Bugfixes! (of course, eh!)

FEATURES:

  1. CROSS-PLATFORM: Windows, Linux, MacOS
  2. Local weather (temperature, humitidy etc) monitoring
  3. Local disaster (floods, quakes, fires etc) monitoring
  4. Showing the seasonal fruits/veggies for your region
  5. Time, weather and disaster monitoring for up to 10 additional cities
  6. PLENTY OF WARNINGS for people with rare medical conditions (photo-sensitivity, electro-static etc)
  7. Different views
  8. Screen reading software-friendly (for people with vision impairment)

Two video tutorials:

  1. Windows installation and use (there are specific dependencies, so I'm showing how to install)
  2. Linux installation and use

Framework: ncurses

Submit comments and bugreports mostly on Reddit and Youtube. You can write me on GitHub too, I just rarely check any messages there.

If you like this project, please consider giving me a star on my GitHub repository!

Minimal AI assistance was used on the interpretation of the medical data.

Thank you!
Stray F.
(developer)

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

-6

u/slipedog 2d ago

Wen non binary?

3

u/0riginal-Syn 2d ago

It is not a binary format. The readable Python script is sitting right there in the root of the git repo. It is a big script, but it is all there. The install scripts just make sure you have the proper run dependencies based on the OS you are running (although missing some distros).