import requests import logging from typing import Tuple, Optional from app.core.config import ( RUIJIE_BASE_URL, RUIJIE_APPID, RUIJIE_SECRET, RUIJIE_ACCESS_TOKEN, RUIJIE_GROUP_ID, ) logger = logging.getLogger(__name__) BASE_URL = RUIJIE_BASE_URL def get_access_token() -> str: url = f"{BASE_URL}/service/api/oauth20/client/access_token?token=d63dss0a81e4415a889ac5b78fsc904a" payload = {"appid": RUIJIE_APPID, "secret": RUIJIE_SECRET} resp = requests.post(url, json=payload, timeout=15) resp.raise_for_status() token = resp.json().get("data", {}).get("access_token") if not token: raise ValueError(f"Token não retornado: {resp.json()}") return token def refresh_token(access_token: str) -> str: url = f"{BASE_URL}/service/api/token/refresh?appid={RUIJIE_APPID}&secret={RUIJIE_SECRET}&access_token={access_token}" resp = requests.get(url, timeout=15) resp.raise_for_status() token = resp.json().get("accessToken") or resp.json().get("data", {}).get("access_token") if not token: raise ValueError(f"Refresh falhou: {resp.json()}") return token def get_active_users(access_token: str, page_index: int = 1, page_size: int = 100) -> list[dict]: url = f"{BASE_URL}/logbizagent/logbiz/api/sta/sta_users" payload = { "groupId": int(RUIJIE_GROUP_ID), "pageSize": page_size, "pageIndex": page_index, "staType": "onofflineUserHistory", } headers = {"Content-Type": "application/json"} params = {"access_token": access_token} resp = requests.post(url, json=payload, headers=headers, params=params, timeout=15) resp.raise_for_status() return resp.json().get("list", []) def extract_all_users( access_token: str, watermark_ms: Optional[int] = None, page_size: int = 100 ) -> Tuple[list[dict], int]: """ Extrai sessões Ruijie com suporte a watermark. Args: access_token: Token Ruijie watermark_ms: onlineTime (epoch ms) da última sessão processada. Se fornecido, ignora registros com onlineTime <= watermark. page_size: Tamanho da página Returns: (lista_de_registros, novo_watermark) - novo_watermark = maior onlineTime encontrado (ou watermark anterior se nada novo) """ all_records = [] page = 1 max_online_ms = watermark_ms or 0 stopped_early = False while True: records = get_active_users(access_token, page_index=page, page_size=page_size) if not records: break # Filtra por watermark (se fornecido) ou adiciona tudo if watermark_ms is not None: filtered = [r for r in records if r.get('onlineTime', 0) > watermark_ms] if len(filtered) < len(records): # Parou de voltar no tempo — já viu tudo até o watermark stopped_early = True all_records.extend(filtered) break all_records.extend(filtered) else: # Sem watermark: adiciona todos os registros da página all_records.extend(records) # Atualiza max_online_ms page_max = max((r.get('onlineTime', 0) for r in records), default=0) if page_max > max_online_ms: max_online_ms = page_max logger.info(f"Ruijie: página {page} → {len(records)} registros (watermark={watermark_ms})") if len(records) < page_size or stopped_early: break page += 1 new_watermark = max_online_ms if max_online_ms > (watermark_ms or 0) else watermark_ms logger.info(f"Ruijie: total extraído = {len(all_records)} registros (novo watermark={new_watermark})") return all_records, new_watermark