Auto-update: Fri Aug 2 00:14:02 PDT 2024
This commit is contained in:
parent
7e83879c96
commit
913d133120
6 changed files with 45 additions and 304 deletions
|
@ -81,6 +81,7 @@ async def transcribe_endpoint(
|
||||||
# If we've reached this point, the transcription has taken too long
|
# If we've reached this point, the transcription has taken too long
|
||||||
return JSONResponse(content={"status": "timeout", "message": "Transcription is taking longer than expected. Please check back later."}, status_code=202)
|
return JSONResponse(content={"status": "timeout", "message": "Transcription is taking longer than expected. Please check back later."}, status_code=202)
|
||||||
|
|
||||||
|
|
||||||
async def transcribe_audio(file_path, params: TranscribeParams):
|
async def transcribe_audio(file_path, params: TranscribeParams):
|
||||||
debug(f"Transcribing audio file from {file_path}...")
|
debug(f"Transcribing audio file from {file_path}...")
|
||||||
file_path = await convert_to_wav(file_path)
|
file_path = await convert_to_wav(file_path)
|
||||||
|
|
|
@ -6,29 +6,20 @@ DEPENDS ON:
|
||||||
*unimplemented.
|
*unimplemented.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from fastapi import APIRouter, Request, Response, Query
|
from fastapi import APIRouter, Request, Query
|
||||||
from starlette.datastructures import Address
|
|
||||||
from fastapi.responses import JSONResponse, RedirectResponse
|
from fastapi.responses import JSONResponse, RedirectResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from aiohttp import ClientSession
|
||||||
from aiohttp import ClientSession, ClientTimeout
|
|
||||||
import aiofiles
|
import aiofiles
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
import yaml
|
import yaml
|
||||||
import ipaddress
|
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import os, re, io
|
|
||||||
import random
|
import random
|
||||||
from io import BytesIO
|
import os
|
||||||
import base64
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import shutil
|
|
||||||
# from photoprism.Session import Session
|
|
||||||
# from photoprism.Photo import Photo
|
|
||||||
# from webdav3.client import Client
|
|
||||||
from sijapi.routers.llm import query_ollama
|
from sijapi.routers.llm import query_ollama
|
||||||
from sijapi import API, L, COMFYUI_URL, COMFYUI_OUTPUT_DIR, IMG_CONFIG_PATH, IMG_DIR, IMG_WORKFLOWS_DIR
|
from sijapi import API, L, COMFYUI_URL, COMFYUI_OUTPUT_DIR, IMG_CONFIG_PATH, IMG_DIR, IMG_WORKFLOWS_DIR
|
||||||
|
|
||||||
|
@ -245,6 +236,7 @@ def get_scene(scene):
|
||||||
return scene_data
|
return scene_data
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# This returns the scene with the most trigger words present in the provided prompt,
|
# This returns the scene with the most trigger words present in the provided prompt,
|
||||||
# or otherwise if none match it returns the first scene in the array -
|
# or otherwise if none match it returns the first scene in the array -
|
||||||
# meaning the first should be considered the default scene.
|
# meaning the first should be considered the default scene.
|
||||||
|
@ -269,11 +261,6 @@ def get_matching_scene(prompt):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import socket
|
|
||||||
import subprocess
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
async def ensure_comfy(retries: int = 4, timeout: float = 6.0):
|
async def ensure_comfy(retries: int = 4, timeout: float = 6.0):
|
||||||
"""
|
"""
|
||||||
Ensures that ComfyUI is running, starting it if necessary.
|
Ensures that ComfyUI is running, starting it if necessary.
|
||||||
|
@ -311,35 +298,6 @@ async def ensure_comfy(retries: int = 4, timeout: float = 6.0):
|
||||||
crit(f"Failed to ensure ComfyUI is running after {retries} attempts with {timeout} second intervals.")
|
crit(f"Failed to ensure ComfyUI is running after {retries} attempts with {timeout} second intervals.")
|
||||||
raise RuntimeError(f"Failed to ensure ComfyUI is running after {retries} attempts with {timeout} second intervals.")
|
raise RuntimeError(f"Failed to ensure ComfyUI is running after {retries} attempts with {timeout} second intervals.")
|
||||||
|
|
||||||
# async def upload_and_get_shareable_link(image_path):
|
|
||||||
# try:
|
|
||||||
# Set up the PhotoPrism session
|
|
||||||
# pp_session = Session(PHOTOPRISM_USER, PHOTOPRISM_PASS, PHOTOPRISM_URL, use_https=True)
|
|
||||||
# pp_session.create()
|
|
||||||
|
|
||||||
# Start import
|
|
||||||
# photo = Photo(pp_session)
|
|
||||||
# photo.start_import(path=os.path.dirname(image_path))
|
|
||||||
|
|
||||||
# Give PhotoPrism some time to process the upload
|
|
||||||
# await asyncio.sleep(5)
|
|
||||||
|
|
||||||
# Search for the uploaded photo
|
|
||||||
# photo_name = os.path.basename(image_path)
|
|
||||||
# search_results = photo.search(query=f"name:{photo_name}", count=1)
|
|
||||||
|
|
||||||
# if search_results['photos']:
|
|
||||||
# photo_uuid = search_results['photos'][0]['uuid']
|
|
||||||
# shareable_link = f"https://{PHOTOPRISM_URL}/p/{photo_uuid}"
|
|
||||||
# return shareable_link
|
|
||||||
# else:
|
|
||||||
# err("Could not find the uploaded photo details.")
|
|
||||||
# return None
|
|
||||||
# except Exception as e:
|
|
||||||
# err(f"Error in upload_and_get_shareable_link: {e}")
|
|
||||||
# return None
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@img.get("/image/{prompt_id}")
|
@img.get("/image/{prompt_id}")
|
||||||
async def get_image_status(prompt_id: str):
|
async def get_image_status(prompt_id: str):
|
||||||
|
@ -455,7 +413,6 @@ Even more important, it finds and returns the key to the filepath where the file
|
||||||
return found_key[0]
|
return found_key[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def queue_prompt(workflow_data):
|
async def queue_prompt(workflow_data):
|
||||||
await ensure_comfy()
|
await ensure_comfy()
|
||||||
async with ClientSession() as session:
|
async with ClientSession() as session:
|
||||||
|
@ -465,4 +422,4 @@ async def queue_prompt(workflow_data):
|
||||||
data = await response.json()
|
data = await response.json()
|
||||||
return data.get('prompt_id')
|
return data.get('prompt_id')
|
||||||
else:
|
else:
|
||||||
raise Exception(f"Failed to queue prompt. Status code: {response.status}")
|
raise Exception(f"Failed to queue prompt. Status code: {response.status}")
|
|
@ -23,7 +23,6 @@ from sijapi import L, News, OBSIDIAN_VAULT_DIR, OBSIDIAN_RESOURCES_DIR, DEFAULT_
|
||||||
from sijapi.utilities import sanitize_filename, assemble_journal_path, assemble_archive_path
|
from sijapi.utilities import sanitize_filename, assemble_journal_path, assemble_archive_path
|
||||||
from sijapi.routers import gis, llm, tts, note
|
from sijapi.routers import gis, llm, tts, note
|
||||||
|
|
||||||
|
|
||||||
news = APIRouter()
|
news = APIRouter()
|
||||||
logger = L.get_module_logger("news")
|
logger = L.get_module_logger("news")
|
||||||
def debug(text: str): logger.debug(text)
|
def debug(text: str): logger.debug(text)
|
||||||
|
@ -407,188 +406,3 @@ async def save_file(file: UploadFile, folder: Path) -> Path:
|
||||||
with open(file_path, 'wb') as f:
|
with open(file_path, 'wb') as f:
|
||||||
shutil.copyfileobj(file.file, f)
|
shutil.copyfileobj(file.file, f)
|
||||||
return file_path
|
return file_path
|
||||||
|
|
||||||
|
|
||||||
deprecated = '''
|
|
||||||
async def process_article2(
|
|
||||||
bg_tasks: BackgroundTasks,
|
|
||||||
parsed_content: Article,
|
|
||||||
tts_mode: str = "summary",
|
|
||||||
voice: str = DEFAULT_11L_VOICE
|
|
||||||
):
|
|
||||||
timestamp = dt_datetime.now().strftime('%b %d, %Y at %H:%M')
|
|
||||||
|
|
||||||
readable_title = sanitize_filename(parsed_content.title or timestamp)
|
|
||||||
markdown_filename, relative_path = assemble_journal_path(dt_datetime.now(), subdir="Articles", filename=readable_title, extension=".md")
|
|
||||||
|
|
||||||
try:
|
|
||||||
summary = await llm.summarize_text(parsed_content.clean_doc, "Summarize the provided text. Respond with the summary and nothing else. Do not otherwise acknowledge the request. Just provide the requested summary.")
|
|
||||||
summary = summary.replace('\n', ' ') # Remove line breaks
|
|
||||||
|
|
||||||
if tts_mode == "full" or tts_mode == "content":
|
|
||||||
tts_text = parsed_content.clean_doc
|
|
||||||
elif tts_mode == "summary" or tts_mode == "excerpt":
|
|
||||||
tts_text = summary
|
|
||||||
else:
|
|
||||||
tts_text = None
|
|
||||||
|
|
||||||
banner_markdown = ''
|
|
||||||
try:
|
|
||||||
banner_url = parsed_content.top_image
|
|
||||||
if banner_url != '':
|
|
||||||
banner_image = download_file(banner_url, Path(OBSIDIAN_VAULT_DIR / OBSIDIAN_RESOURCES_DIR))
|
|
||||||
if banner_image:
|
|
||||||
banner_markdown = f"![[{OBSIDIAN_RESOURCES_DIR}/{banner_image}]]"
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err(f"No image found in article")
|
|
||||||
|
|
||||||
authors = ', '.join('[[{}]]'.format(author) for author in parsed_content.authors)
|
|
||||||
published_date = parsed_content.publish_date
|
|
||||||
frontmatter = f"""---
|
|
||||||
title: {readable_title}
|
|
||||||
authors: {authors}
|
|
||||||
published: {published_date}
|
|
||||||
added: {timestamp}
|
|
||||||
banner: "{banner_markdown}"
|
|
||||||
tags:
|
|
||||||
|
|
||||||
"""
|
|
||||||
frontmatter += '\n'.join(f" - {tag}" for tag in parsed_content.tags)
|
|
||||||
frontmatter += '\n---\n'
|
|
||||||
|
|
||||||
body = f"# {readable_title}\n\n"
|
|
||||||
if tts_text:
|
|
||||||
audio_filename = f"{published_date} {readable_title}"
|
|
||||||
try:
|
|
||||||
audio_path = await tts.generate_speech(bg_tasks=bg_tasks, text=tts_text, voice=voice, model="eleven_turbo_v2", podcast=True, title=audio_filename,
|
|
||||||
output_dir=Path(OBSIDIAN_VAULT_DIR) / OBSIDIAN_RESOURCES_DIR)
|
|
||||||
audio_ext = Path(audio_path).suffix
|
|
||||||
obsidian_link = f"![[{OBSIDIAN_RESOURCES_DIR}/{audio_filename}{audio_ext}]]"
|
|
||||||
body += f"{obsidian_link}\n\n"
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Failed to generate TTS for np3k. {e}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
body += f"by {authors} in {parsed_content.canonical_link}" # update with method for getting the newspaper name
|
|
||||||
body += f"> [!summary]+\n"
|
|
||||||
body += f"> {summary}\n\n"
|
|
||||||
body += parsed_content["content"]
|
|
||||||
markdown_content = frontmatter + body
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Failed to combine elements of article markdown.")
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(markdown_filename, 'w') as md_file:
|
|
||||||
md_file.write(markdown_content)
|
|
||||||
|
|
||||||
info(f"Successfully saved to {markdown_filename}")
|
|
||||||
await note.add_to_daily_note(relative_path)
|
|
||||||
return markdown_filename
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Failed to write markdown file")
|
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Failed to clip: {str(e)}")
|
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
|
||||||
|
|
||||||
|
|
||||||
async def process_article(
|
|
||||||
bg_tasks: BackgroundTasks,
|
|
||||||
url: str,
|
|
||||||
title: Optional[str] = None,
|
|
||||||
encoding: str = 'utf-8',
|
|
||||||
source: Optional[str] = None,
|
|
||||||
tts_mode: str = "summary",
|
|
||||||
voice: str = DEFAULT_11L_VOICE
|
|
||||||
):
|
|
||||||
|
|
||||||
timestamp = dt_datetime.now().strftime('%b %d, %Y at %H:%M')
|
|
||||||
|
|
||||||
parsed_content = await parse_article(url, source)
|
|
||||||
if parsed_content is None:
|
|
||||||
return {"error": "Failed to retrieve content"}
|
|
||||||
|
|
||||||
readable_title = sanitize_filename(title or parsed_content.get("title") or timestamp)
|
|
||||||
markdown_filename, relative_path = assemble_journal_path(dt_datetime.now(), subdir="Articles", filename=readable_title, extension=".md")
|
|
||||||
|
|
||||||
try:
|
|
||||||
summary = await llm.summarize_text(parsed_content["content"], "Summarize the provided text. Respond with the summary and nothing else. Do not otherwise acknowledge the request. Just provide the requested summary.")
|
|
||||||
summary = summary.replace('\n', ' ') # Remove line breaks
|
|
||||||
|
|
||||||
if tts_mode == "full" or tts_mode == "content":
|
|
||||||
tts_text = parsed_content["content"]
|
|
||||||
elif tts_mode == "summary" or tts_mode == "excerpt":
|
|
||||||
tts_text = summary
|
|
||||||
else:
|
|
||||||
tts_text = None
|
|
||||||
|
|
||||||
banner_markdown = ''
|
|
||||||
try:
|
|
||||||
banner_url = parsed_content.get('image', '')
|
|
||||||
if banner_url != '':
|
|
||||||
banner_image = download_file(banner_url, Path(OBSIDIAN_VAULT_DIR / OBSIDIAN_RESOURCES_DIR))
|
|
||||||
if banner_image:
|
|
||||||
banner_markdown = f"![[{OBSIDIAN_RESOURCES_DIR}/{banner_image}]]"
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err(f"No image found in article")
|
|
||||||
|
|
||||||
authors = ', '.join('[[{}]]'.format(author) for author in parsed_content.get('authors', ['Unknown']))
|
|
||||||
|
|
||||||
frontmatter = f"""---
|
|
||||||
title: {readable_title}
|
|
||||||
authors: {', '.join('[[{}]]'.format(author) for author in parsed_content.get('authors', ['Unknown']))}
|
|
||||||
published: {parsed_content.get('date_published', 'Unknown')}
|
|
||||||
added: {timestamp}
|
|
||||||
excerpt: {parsed_content.get('excerpt', '')}
|
|
||||||
banner: "{banner_markdown}"
|
|
||||||
tags:
|
|
||||||
|
|
||||||
"""
|
|
||||||
frontmatter += '\n'.join(f" - {tag}" for tag in parsed_content.get('tags', []))
|
|
||||||
frontmatter += '\n---\n'
|
|
||||||
|
|
||||||
body = f"# {readable_title}\n\n"
|
|
||||||
|
|
||||||
if tts_text:
|
|
||||||
datetime_str = dt_datetime.now().strftime("%Y%m%d%H%M%S")
|
|
||||||
audio_filename = f"{datetime_str} {readable_title}"
|
|
||||||
try:
|
|
||||||
audio_path = await tts.generate_speech(bg_tasks=bg_tasks, text=tts_text, voice=voice, model="eleven_turbo_v2", podcast=True, title=audio_filename,
|
|
||||||
output_dir=Path(OBSIDIAN_VAULT_DIR) / OBSIDIAN_RESOURCES_DIR)
|
|
||||||
audio_ext = Path(audio_path).suffix
|
|
||||||
obsidian_link = f"![[{OBSIDIAN_RESOURCES_DIR}/{audio_filename}{audio_ext}]]"
|
|
||||||
body += f"{obsidian_link}\n\n"
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Failed to generate TTS for np3k. {e}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
body += f"by {authors} in [{parsed_content.get('domain', urlparse(url).netloc.replace('www.', ''))}]({url}).\n\n"
|
|
||||||
body += f"> [!summary]+\n"
|
|
||||||
body += f"> {summary}\n\n"
|
|
||||||
body += parsed_content["content"]
|
|
||||||
markdown_content = frontmatter + body
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Failed to combine elements of article markdown.")
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(markdown_filename, 'w', encoding=encoding) as md_file:
|
|
||||||
md_file.write(markdown_content)
|
|
||||||
|
|
||||||
info(f"Successfully saved to {markdown_filename}")
|
|
||||||
await note.add_to_daily_note(relative_path)
|
|
||||||
return markdown_filename
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Failed to write markdown file")
|
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Failed to clip {url}: {str(e)}")
|
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
|
||||||
'''
|
|
|
@ -383,7 +383,6 @@ created: "{dt_datetime.now().strftime("%Y-%m-%d %H:%M:%S")}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def build_daily_timeslips(date):
|
async def build_daily_timeslips(date):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -956,17 +955,6 @@ async def format_events_as_markdown(event_data: Dict[str, Union[str, List[Dict[s
|
||||||
|
|
||||||
if event['description']:
|
if event['description']:
|
||||||
description = event['description']
|
description = event['description']
|
||||||
# # This was intended to clean up the descriptions of Zoom and Teams events but is presently broken; should be an easy fix.
|
|
||||||
# if 'Zoom Meeting' in description:
|
|
||||||
# description_parts = description.split('---')
|
|
||||||
# if len(description_parts) > 2:
|
|
||||||
# description = description_parts[1].strip()
|
|
||||||
# if 'Microsoft Teams' in description:
|
|
||||||
# description_parts = description.split('---')
|
|
||||||
# if len(description_parts) > 2:
|
|
||||||
# event_data['description'] = description_parts[1].strip()
|
|
||||||
# description = remove_characters(description)
|
|
||||||
# description = remove_characters(description)
|
|
||||||
if len(description) > 150:
|
if len(description) > 150:
|
||||||
description = await llm.summarize_text(description, length_override=150)
|
description = await llm.summarize_text(description, length_override=150)
|
||||||
|
|
||||||
|
|
|
@ -167,8 +167,6 @@ async def generate_speech(
|
||||||
raise HTTPException(status_code=500, detail=f"Failed to generate speech: {str(e)}")
|
raise HTTPException(status_code=500, detail=f"Failed to generate speech: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_model(voice: str = None, voice_file: UploadFile = None):
|
async def get_model(voice: str = None, voice_file: UploadFile = None):
|
||||||
if voice_file or (voice and await select_voice(voice)):
|
if voice_file or (voice and await select_voice(voice)):
|
||||||
return "xtts"
|
return "xtts"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
Uses the VisualCrossing API and Postgres/PostGIS to source local weather forecasts and history.
|
Uses the VisualCrossing API and Postgres/PostGIS to source local weather forecasts and history.
|
||||||
'''
|
'''
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import traceback
|
||||||
from fastapi import APIRouter, HTTPException, Query
|
from fastapi import APIRouter, HTTPException, Query
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
|
@ -166,7 +167,7 @@ async def store_weather_to_db(date_time: dt_datetime, weather_data: dict):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
daily_weather_query = '''
|
daily_weather_query = '''
|
||||||
INSERT INTO DailyWeather (
|
INSERT INTO dailyweather (
|
||||||
sunrise, sunriseepoch, sunset, sunsetepoch, description,
|
sunrise, sunriseepoch, sunset, sunsetepoch, description,
|
||||||
tempmax, tempmin, uvindex, winddir, windspeed, icon, last_updated,
|
tempmax, tempmin, uvindex, winddir, windspeed, icon, last_updated,
|
||||||
datetime, datetimeepoch, temp, feelslikemax, feelslikemin, feelslike,
|
datetime, datetimeepoch, temp, feelslikemax, feelslikemin, feelslike,
|
||||||
|
@ -178,7 +179,7 @@ async def store_weather_to_db(date_time: dt_datetime, weather_data: dict):
|
||||||
RETURNING id
|
RETURNING id
|
||||||
'''
|
'''
|
||||||
|
|
||||||
daily_weather_id = await API.execute_write_query(daily_weather_query, *daily_weather_params, table_name="DailyWeather")
|
daily_weather_id = await API.execute_write_query(daily_weather_query, *daily_weather_params, table_name="dailyweather")
|
||||||
|
|
||||||
if 'hours' in day_data:
|
if 'hours' in day_data:
|
||||||
debug(f"Processing hours now...")
|
debug(f"Processing hours now...")
|
||||||
|
@ -219,13 +220,13 @@ async def store_weather_to_db(date_time: dt_datetime, weather_data: dict):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
hourly_weather_query = '''
|
hourly_weather_query = '''
|
||||||
INSERT INTO HourlyWeather (daily_weather_id, datetime, datetimeepoch, temp, feelslike, humidity, dew, precip, precipprob,
|
INSERT INTO hourlyweather (daily_weather_id, datetime, datetimeepoch, temp, feelslike, humidity, dew, precip, precipprob,
|
||||||
preciptype, snow, snowdepth, windgust, windspeed, winddir, pressure, cloudcover, visibility, solarradiation, solarenergy,
|
preciptype, snow, snowdepth, windgust, windspeed, winddir, pressure, cloudcover, visibility, solarradiation, solarenergy,
|
||||||
uvindex, severerisk, conditions, icon, stations, source)
|
uvindex, severerisk, conditions, icon, stations, source)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26)
|
||||||
RETURNING id
|
RETURNING id
|
||||||
'''
|
'''
|
||||||
hourly_weather_id = await API.execute_write_query(hourly_weather_query, *hourly_weather_params, table_name="HourlyWeather")
|
hourly_weather_id = await API.execute_write_query(hourly_weather_query, *hourly_weather_params, table_name="hourlyweather")
|
||||||
debug(f"Done processing hourly_weather_id {hourly_weather_id}")
|
debug(f"Done processing hourly_weather_id {hourly_weather_id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
err(f"EXCEPTION: {e}")
|
err(f"EXCEPTION: {e}")
|
||||||
|
@ -241,60 +242,42 @@ async def store_weather_to_db(date_time: dt_datetime, weather_data: dict):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_weather_from_db(date_time: dt_datetime, latitude: float, longitude: float):
|
async def get_weather_from_db(date_time: dt_datetime, latitude: float, longitude: float):
|
||||||
warn(f"Using {date_time.strftime('%Y-%m-%d %H:%M:%S')} as our datetime in get_weather_from_db.")
|
warn(f"Using {date_time.strftime('%Y-%m-%d %H:%M:%S')} as our datetime in get_weather_from_db.")
|
||||||
async with API.get_connection() as conn:
|
query_date = date_time.date()
|
||||||
query_date = date_time.date()
|
try:
|
||||||
try:
|
# Query to get daily weather data
|
||||||
# Query to get daily weather data
|
daily_query = '''
|
||||||
query = '''
|
SELECT DW.* FROM dailyweather DW
|
||||||
SELECT DW.* FROM DailyWeather DW
|
WHERE DW.datetime::date = $1
|
||||||
WHERE DW.datetime::date = $1
|
AND ST_DWithin(DW.location::geography, ST_MakePoint($2,$3)::geography, 8046.72)
|
||||||
AND ST_DWithin(DW.location::geography, ST_MakePoint($2,$3)::geography, 8046.72)
|
ORDER BY ST_Distance(DW.location, ST_MakePoint($4, $5)::geography) ASC
|
||||||
ORDER BY ST_Distance(DW.location, ST_MakePoint($4, $5)::geography) ASC
|
LIMIT 1
|
||||||
LIMIT 1
|
'''
|
||||||
'''
|
|
||||||
|
|
||||||
daily_weather_record = await conn.fetchrow(query, query_date, longitude, latitude, longitude, latitude)
|
daily_weather_records = await API.execute_read_query(daily_query, query_date, longitude, latitude, longitude, latitude, table_name='dailyweather')
|
||||||
|
|
||||||
if daily_weather_record is None:
|
|
||||||
debug(f"No daily weather data retrieved from database.")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Convert asyncpg.Record to a mutable dictionary
|
|
||||||
daily_weather_data = dict(daily_weather_record)
|
|
||||||
# debug(f"Daily weather data prior to tz corrections: {daily_weather_data}")
|
|
||||||
# Now we can modify the dictionary
|
|
||||||
# tz = await GEO.tz_at(latitude, longitude)
|
|
||||||
# daily_weather_data['datetime'] = await gis.dt(daily_weather_data.get('datetime'), tz)
|
|
||||||
# daily_weather_data['sunrise'] = await gis.dt(daily_weather_data.get('sunrise'), tz)
|
|
||||||
# daily_weather_data['sunset'] = await gis.dt(daily_weather_data.get('sunset'), tz)
|
|
||||||
|
|
||||||
# debug(f"Daily weather data after tz corrections: {daily_weather_data}")
|
|
||||||
|
|
||||||
# Query to get hourly weather data
|
|
||||||
query = '''
|
|
||||||
SELECT HW.* FROM HourlyWeather HW
|
|
||||||
WHERE HW.daily_weather_id = $1
|
|
||||||
'''
|
|
||||||
|
|
||||||
hourly_weather_records = await conn.fetch(query, daily_weather_data['id'])
|
|
||||||
|
|
||||||
hourly_weather_data = []
|
|
||||||
for record in hourly_weather_records:
|
|
||||||
hour_data = dict(record)
|
|
||||||
# hour_data['datetime'] = await gis.dt(hour_data.get('datetime'), tz)
|
|
||||||
hourly_weather_data.append(hour_data)
|
|
||||||
|
|
||||||
# debug(f"Hourly weather data after tz corrections: {hourly_weather_data}")
|
|
||||||
day = {
|
|
||||||
'DailyWeather': daily_weather_data,
|
|
||||||
'HourlyWeather': hourly_weather_data,
|
|
||||||
}
|
|
||||||
# debug(f"day: {day}")
|
|
||||||
return day
|
|
||||||
except Exception as e:
|
|
||||||
err(f"Unexpected error occurred: {e}")
|
|
||||||
|
|
||||||
|
if not daily_weather_records:
|
||||||
|
debug(f"No daily weather data retrieved from database.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
daily_weather_data = daily_weather_records[0] # Get the first (and only) record
|
||||||
|
|
||||||
|
# Query to get hourly weather data
|
||||||
|
hourly_query = '''
|
||||||
|
SELECT HW.* FROM hourlyweather HW
|
||||||
|
WHERE HW.daily_weather_id = $1
|
||||||
|
'''
|
||||||
|
|
||||||
|
hourly_weather_records = await API.execute_read_query(hourly_query, daily_weather_data['id'], table_name='hourlyweather')
|
||||||
|
|
||||||
|
day = {
|
||||||
|
'DailyWeather': daily_weather_data,
|
||||||
|
'HourlyWeather': hourly_weather_records,
|
||||||
|
}
|
||||||
|
|
||||||
|
return day
|
||||||
|
except Exception as e:
|
||||||
|
err(f"Unexpected error occurred in get_weather_from_db: {e}")
|
||||||
|
err(f"Traceback: {traceback.format_exc()}")
|
||||||
|
return None
|
||||||
|
|
Loading…
Add table
Reference in a new issue