using wttr.in instead of bing

This commit is contained in:
Death916 2025-03-19 02:37:38 -07:00
parent 765a02e8d4
commit 9474b4b848
6 changed files with 62 additions and 35 deletions

View file

@ -19,14 +19,14 @@ def create_app():
html.H2("NBA Scores"), html.H2("NBA Scores"),
html.Div(id='nba-scores-display', className='score-container') html.Div(id='nba-scores-display', className='score-container')
]), ]),
html.Div(id='weather-display') html.Div(id='weather-display', style={"display": "flex", "justify-content": "center", "margin-bottom":"20px"})
], id='scores-weather-container'), ], id='scores-weather-container', style={"display": "flex", "gap": "20px"}),
]), ]),
html.Div(id='news-ticker'), html.Div(id='news-ticker'),
dcc.Interval(id='clock-interval', interval=60000, n_intervals=0), dcc.Interval(id='clock-interval', interval=60000, n_intervals=0),
dcc.Interval(id='weather-interval', interval=150000, n_intervals=0), dcc.Interval(id='weather-interval', interval=550000, n_intervals=0),
dcc.Interval(id='news-interval', interval=300000, n_intervals=0), dcc.Interval(id='news-interval', interval=300000, n_intervals=0),
dcc.Interval(id='nba-interval', interval=300000, n_intervals=0) dcc.Interval(id='nba-interval', interval=300000, n_intervals=0)
]) ])

View file

@ -1,30 +1,55 @@
from playwright.sync_api import sync_playwright
import os import os
import subprocess
import datetime
class Weather: class Weather:
def __init__(self): def __init__(self):
if not os.path.exists('assets'): # Get the directory where this script (weather.py) is located
os.makedirs('assets') self.script_dir = os.path.dirname(os.path.abspath(__file__))
# Construct the absolute path to the 'assets' directory in the same directory as the script
self.assets_dir = os.path.join(self.script_dir, 'assets')
# Ensure the assets directory exists
if not os.path.exists(self.assets_dir):
os.makedirs(self.assets_dir)
def delete_old_screenshots(self):
"""
Deletes all PNG files in the 'assets' directory that start with 'sacramento_weather_'.
"""
for filename in os.listdir(self.assets_dir):
if filename.startswith("sacramento_weather_"):
os.remove(os.path.join(self.assets_dir, filename))
def get_weather_screenshot(self): def get_weather_screenshot(self):
with sync_playwright() as p: """
browser = p.chromium.launch(headless=True) Fetches weather information for Sacramento from wttr.in using curl and saves it as a PNG.
context = browser.new_context() Returns the path to the saved image.
context.add_init_script(""" """
Object.defineProperty(navigator, 'webdriver', { try:
get: () => undefined, # Create a timestamp for the filename
}); timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
""") screenshot_filename = f"sacramento_weather_{timestamp}.png"
page = context.new_page() screenshot_path = os.path.join(self.assets_dir, screenshot_filename) # save to the proper location
# Navigate to Sacramento weather # Use curl to get the weather data from wttr.in and save it as a PNG.
page.goto("https://www.bing.com/search?q=sacramento+weather&qs=n&form=QBRE&sp=-1&ghc=1&lq=0&pq=sacramento+weathe&sc=12-17&sk=&cvid=9D84287D34AC483C85F6E3AA7F943C4F&ghsh=0&ghacc=0&ghpl=") # add the scale #2 to make the png larger
curl_command = [
"curl",
"-s", # Silent mode
"wttr.in/Sacramento.png?u",
"-o",
screenshot_path,
]
self.delete_old_screenshots()
subprocess.run(curl_command, check=True)
# Wait for and screenshot weather widget
page.wait_for_selector('#wtr_cardContainer > div.b_antiTopBleed.b_antiSideBleed.b_antiBottomBleed.b_weainner')
weather_element = page.locator('#wtr_cardContainer > div.b_antiTopBleed.b_antiSideBleed.b_antiBottomBleed.b_weainner')
screenshot_path = os.path.join('assets', 'sacramento_weather_map.png')
weather_element.screenshot(path=screenshot_path)
browser.close()
return screenshot_path return screenshot_path
except subprocess.CalledProcessError as e:
print(f"Error fetching weather data: {e}")
return None
except Exception as e:
print(f"An unexpected error occurred: {e}")
return None

View file

@ -10,8 +10,6 @@ class WeatherModule:
self.setup_callbacks() self.setup_callbacks()
def get_weather_object(self): def get_weather_object(self):
if not os.path.exists('assets'):
os.makedirs('assets')
return Weather() return Weather()
def setup_callbacks(self): def setup_callbacks(self):
@ -24,11 +22,15 @@ class WeatherModule:
print("UPDATING WEATHER...") print("UPDATING WEATHER...")
screenshot_path = self.weather_obj.get_weather_screenshot() screenshot_path = self.weather_obj.get_weather_screenshot()
image_name = os.path.basename(screenshot_path) image_name = os.path.basename(screenshot_path)
return html.Div([ return html.Div(
html.H2("Sacramento Weather"), [
html.Img(src=self.app.get_asset_url(image_name html.H2("Sacramento Weather"),
+ f"?v={datetime.datetime.now().timestamp()}"), html.Img(
style={'maxWidth': '500px'}) src=self.app.get_asset_url(image_name + f"?v={datetime.datetime.now().timestamp()}"),
]) style={"width": "100%", "display": "block", "image-rendering": "crisp-edges"}
),
],
style={"width": "600px", "margin": "0 auto", "border": "1px solid black"}
)
except Exception as e: except Exception as e:
return html.Div(f"Weather update error: {str(e)}") return html.Div(f"Weather update error: {str(e)}")