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
        )