Initial commit
This commit is contained in:
93
tools.py
Normal file
93
tools.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from datetime import datetime
|
||||
import geocoder
|
||||
import os
|
||||
import requests
|
||||
import subprocess
|
||||
|
||||
|
||||
def day_of_week() -> str:
|
||||
"""Returns the current day of the week.
|
||||
|
||||
Returns:
|
||||
The name of the current day, such as "Monday" or "Friday".
|
||||
"""
|
||||
return datetime.now().strftime("%A")
|
||||
|
||||
|
||||
def local_weather() -> str:
|
||||
"""Returns a brief description of today's weather at the user's location.
|
||||
|
||||
Uses the device's IP address to estimate location, then fetches the
|
||||
National Weather Service forecast for that location.
|
||||
|
||||
Returns:
|
||||
A short text description of the current weather conditions,
|
||||
or an error message if the weather cannot be fetched.
|
||||
"""
|
||||
location = geocoder.ip("me")
|
||||
if not location or not location.latlng:
|
||||
return "Unable to determine location for weather."
|
||||
lat, lng = location.latlng
|
||||
points_url = f"https://api.weather.gov/points/{lat},{lng}"
|
||||
points = requests.get(points_url)
|
||||
if not points.ok:
|
||||
return "Unable to fetch weather data."
|
||||
props = points.json()["properties"]
|
||||
office = props["gridId"]
|
||||
x = props["gridX"]
|
||||
y = props["gridY"]
|
||||
forecast_url = f"https://api.weather.gov/gridpoints/{office}/{x},{y}/forecast"
|
||||
forecast = requests.get(forecast_url)
|
||||
if not forecast.ok:
|
||||
return "No weather forecast available."
|
||||
periods = forecast.json()["properties"]["periods"]
|
||||
today = periods[0]
|
||||
return (
|
||||
f"{today['name']}: {today['shortForecast']}, "
|
||||
f"{today['temperature']}°{today['temperatureUnit']}, "
|
||||
f"wind {today['windSpeed']} {today['windDirection']}"
|
||||
)
|
||||
|
||||
|
||||
def read_file(path: str) -> tuple[bool, str]:
|
||||
"""Reads a file and returns its contents as plain text.
|
||||
|
||||
Supports many file formats including PDF, Word documents, HTML, and Markdown,
|
||||
using pdftotext (for PDFs) and pandoc (for everything else). If the required
|
||||
program is not installed or conversion fails, returns a description of the error.
|
||||
|
||||
Args:
|
||||
path: The path to the file to read.
|
||||
|
||||
Returns:
|
||||
A tuple of (success, text). When successful, success is True and text
|
||||
contains the plain-text contents of the file. When unsuccessful,
|
||||
success is False and text explains what went wrong.
|
||||
"""
|
||||
if not os.path.exists(path):
|
||||
return (False, f"File not found: {path}")
|
||||
|
||||
_, ext = os.path.splitext(path.lower())
|
||||
|
||||
if ext == ".pdf":
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["pdftotext", path, "-"],
|
||||
capture_output=True, text=True, check=True,
|
||||
)
|
||||
return (True, result.stdout)
|
||||
except FileNotFoundError:
|
||||
return (False, "pdftotext is not installed. Install poppler-utils to read PDF files.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
return (False, f"pdftotext failed: {e.stderr.strip()}")
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["pandoc", path, "--to", "plain"],
|
||||
capture_output=True, text=True, check=True,
|
||||
)
|
||||
return (True, result.stdout)
|
||||
except FileNotFoundError:
|
||||
return (False, "pandoc is not installed. Install pandoc to read this file format.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
return (False, f"pandoc failed: {e.stderr.strip()}")
|
||||
Reference in New Issue
Block a user