Spaces:
Sleeping
Sleeping
File size: 6,053 Bytes
30944a6 c6e2f75 30944a6 1eba8dd 30944a6 |
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
from datetime import datetime, timezone
from typing import Tuple, List
import urllib
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
)
@staticmethod
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
@staticmethod
def get_wikipedia_page_historical_content(page_title: str, target_date_str: str) -> 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
)
|