Spaces:
Sleeping
Sleeping
from datetime import datetime, timezone | |
from typing import Tuple | |
import urllib | |
from gradio import List | |
from pydantic import BaseModel | |
import requests | |
import wikipediaapi | |
class Wikipedia_Historical_Page(BaseModel): | |
title: str | |
url: str | |
revision_id: str | |
timestamp: str | |
class Wikipedia_Util: | |
WIKI_LANG = 'en' # Linguagem da Wikipedia (atualizado para inglês) | |
MEDIAWIKI_API_URL = f"https://{WIKI_LANG}.wikipedia.org/w/api.php" | |
HEADERS = { | |
'User-Agent': 'MyCoolSearchBot/1.0 ([email protected])' | |
} | |
wiki_executor = wikipediaapi.Wikipedia( | |
language=WIKI_LANG, | |
extract_format=wikipediaapi.ExtractFormat.HTML, # Usado apenas para page.exists() | |
user_agent='MyCoolSearchBot/1.0 ([email protected])' # Definir um User-Agent é boa prática | |
) | |
def get_wikipedia_revision_info(page_title: str, target_date_str: str) -> Tuple[str,str]: | |
""" | |
Busca o ID e timestamp da revisão mais próxima (<=) da data fornecida via API MediaWiki. | |
Args: | |
page_title: wikipedia encontra páginas históricas pelo titulo | |
target_date_str: data no formato "YYYY-MM-DD" | |
Returns: | |
Uma tupla contendo o ID da revisão e o timestamp da revisão. | |
""" | |
try: | |
# Converte a data string para um objeto datetime e formata para ISO 8601 com Z (UTC) | |
target_dt = datetime.strptime(target_date_str, '%Y-%m-%d') | |
# Precisamos do final do dia para garantir que incluímos todas as revisões daquele dia | |
target_dt_end_of_day = target_dt.replace(hour=23, minute=59, second=59, tzinfo=timezone.utc) | |
target_timestamp_iso = target_dt_end_of_day.strftime('%Y-%m-%dT%H:%M:%SZ') | |
except ValueError: | |
print("Formato de data inválido. Use AAAA-MM-DD.") | |
return None, None | |
params = { | |
"action": "query", | |
"prop": "revisions", | |
"titles": page_title, | |
"rvlimit": 1, | |
"rvdir": "older", # Busca a revisão imediatamente anterior ou igual ao timestamp | |
"rvprop": "ids|timestamp", # Queremos o ID da revisão e o timestamp | |
"rvstart": target_timestamp_iso, # Começa a busca a partir desta data/hora | |
"format": "json", | |
"formatversion": 2 # Formato JSON mais moderno e fácil de parsear | |
} | |
try: | |
print(f"Consultando API MediaWiki para revisão de '{page_title}' em {target_date_str}...") | |
response = requests.get(Wikipedia_Util.MEDIAWIKI_API_URL, params=params, headers=Wikipedia_Util.HEADERS, timeout=15) | |
response.raise_for_status() | |
data = response.json() | |
# Verifica se a página foi encontrada | |
page_data = data.get("query", {}).get("pages", []) | |
if not page_data or page_data[0].get("missing", False): | |
print(f"Página '{page_title}' não encontrada na API MediaWiki.") | |
# Tenta verificar com a biblioteca wikipediaapi como fallback (pode pegar redirecionamentos) | |
page = Wikipedia_Util.wiki_executor.page(page_title) | |
if page.exists(): | |
print(f"Página '{page_title}' existe (possivelmente redirecionada para '{page.title}'). Tentando novamente com o título canônico...") | |
return Wikipedia_Util.get_wikipedia_revision_info(page.title, target_date_str) # Chama recursivamente com o título correto | |
else: | |
print(f"Página '{page_title}' realmente não encontrada.") | |
return None, None | |
# Extrai as revisões | |
revisions = page_data[0].get("revisions", []) | |
if not revisions: | |
print(f"Nenhuma revisão encontrada para '{page_title}' antes ou em {target_date_str}.") | |
# Pode acontecer se a página foi criada depois da data alvo | |
return None, None | |
revision = revisions[0] | |
revid = revision.get("revid") | |
timestamp = revision.get("timestamp") | |
print(f"Encontrada revisão: ID={revid}, Timestamp={timestamp}") | |
return revid, timestamp | |
except requests.exceptions.RequestException as e: | |
print(f"Erro ao chamar a API MediaWiki: {e}") | |
return None, None | |
except Exception as e: | |
print(f"Erro ao processar resposta da API MediaWiki: {e}") | |
return None, None | |
def get_wikipedia_page_historical_content(page_title: str, target_date_str: str) -> List[Wikipedia_Historical_Page]: | |
"""Obtém o conteúdo Markdown de uma revisão histórica específica da Wikipedia.""" | |
# Busca o ID da revisão correta usando a API MediaWiki | |
revid, timestamp = Wikipedia_Util.get_wikipedia_revision_info(page_title, target_date_str) | |
if not revid: | |
print(f"Não foi possível encontrar uma revisão adequada para '{page_title}' em {target_date_str}.") | |
return None | |
# Constrói a URL para a revisão específica | |
# Nota: Codifica o título da página para a URL | |
# Precisamos garantir que estamos usando o título correto (pode ter sido redirecionado) | |
page_check = Wikipedia_Util.wiki_executor.page(page_title) # Verifica novamente para obter o título canônico se houve redirecionamento | |
if not page_check.exists(): | |
print(f"Erro inesperado: Página '{page_title}' não encontrada após busca de revisão.") | |
return None | |
canonical_title = page_check.title | |
encoded_title = urllib.parse.quote(canonical_title.replace(' ', '_')) | |
revision_url = f"https://{Wikipedia_Util.WIKI_LANG}.wikipedia.org/w/index.php?title={encoded_title}&oldid={revid}" | |
return Wikipedia_Historical_Page( | |
title=canonical_title, | |
url=revision_url, | |
revision_id=str(revid), #parametro obrigatoriamente string | |
timestamp=timestamp | |
) | |