
    M8j                         d Z ddlZddlZddlZddlmZmZ ddlmZmZ ddl	m
Z
 ddlmZ  G d de      Zd	efd
Zd	ee   fdZdefdZdeded	efdZdeded	ee
   fdZ G d de      Zy)u  Proveedor de datos REAL vía Scweet (https://github.com/Altimis/Scweet).

Usa la GraphQL interna de X con la cookie `auth_token` de una cuenta SECUNDARIA
(nunca tu cuenta personal). Scweet gestiona internamente el token anti-bot
'x-client-transaction-id', por eso funciona donde twikit fallaba, y trae datos
FRESCOS de cualquier cuenta (resuelve el caché viejo de syndication).

La cookie se lee, por orden:
  1) variable de entorno SCWEET_AUTH_TOKEN
  2) archivo de secretos local (cfg['scweet_secrets_file'], por defecto secrets.local.json)
  3) cfg['scweet_auth_token']  (desaconsejado: no lo pongas en un config.yaml versionado)

Guía para obtener la cookie: ver SETUP_SCWEET.md.
    N)datetimetimezone)ListOptional)Tweet)TweetProviderc                       e Zd Zy)ScweetErrorN)__name__
__module____qualname__     "agent/providers/scweet_provider.pyr
   r
      s    r   r
   returnc                    | yt        | t        t        f      rt        |       S t        |       j	                         j                         j                  dd      }|syd}|j                  d      rd|dd }}n1|j                  d	      rd
|dd }}n|j                  d      rd|dd }}	 t        t        |      |z        S # t        $ r Y yw xY w)z/Convierte 1234, '1,234', '1.2K', '3.4M' -> int.Nr   ,    Ki  Mi@B Bi ʚ;)	
isinstanceintfloatstrstripupperreplaceendswith
ValueError)valuesmults      r   _to_intr&      s    }%#u&5zE
  "**33ADzz#3Ba	
CQsVa	
C3Ba58d?## s   ,C 	CCc                 ~   | y t        | t              r.| j                  r| S | j                  t        j
                        S t        | t        t        f      r:t        |       }|dkD  r|dz  }t        j                  |t        j
                        S t        |       j                         }	 t        j                  |j                  dd            S # t        $ r Y nw xY wdD ]Y  }	 t        j                  ||      }|j                  r|c S |j                  t        j
                        c S # t        $ r Y Ww xY w y )N)tzinfog   mBg     @@)tzZz+00:00)z%a %b %d %H:%M:%S %z %Yz%Y-%m-%d %H:%M:%Sz%Y-%m-%dT%H:%M:%S)r   r   r(   r    r   utcr   r   fromtimestampr   r   fromisoformatr"   strptime)r#   vr$   fmtdts        r   	_parse_tsr2   4   s   }%"uL%--x||-*LL%#u&%Lt8KA%%aHLL99E
A%%aiiX&>?? T	""1c*B2G

(,,
(GG 			 U s*   ,$C 	CC&#D.D..	D:9D:rowc                 ^    |D ](  }| j                  |      dvs| j                  |      c S  y )N)Nr   )get)r3   keysks      r   _firstr8   L   s/    771:Z'771:  r   fallbackc                     | j                  d      }t        |t              r(|j                  d      xs |j                  d      xs |S t        |t              r|r|j	                  d      S |S )Nuserscreen_namename@)r5   r   dictr   lstrip)r3   r9   us      r   
_author_ofrB   S   sY    A!Tuu]#@quuV}@@!Saxx}Or   handlec                 l   t        t        | ddd            }|yt        | |j                  d            }| j	                  d      xs i }t        t        | ddd	      xs |j	                  d	      xs d
      }t        | dd      xs |rd| d| nd
}t        ||t        | ddd      xs d
|t        t        | ddd            t        t        | dd            t        t        | ddd            t        |j	                  d            t        t        | dd      xs |j	                  d            |
      S )z^Mapea un dict de Scweet (TweetRecord) a nuestro modelo Tweet. Tolerante a variantes de claves.	timestampdate
created_atNr>   rawtweet_ididid_strr   	tweet_urlurlzhttps://x.com/z/status/textembedded_text	full_textlikesfavorite_count
like_countretweetsretweet_countcommentsreply_countrepliesquote_countviews
view_count)
rJ   authorrN   rG   rQ   rT   rX   quotesrZ   rM   )r2   r8   rB   r@   r5   r   r   r&   )r3   rC   createdr\   rH   tidrM   s          r   row_to_tweetr`   \   s(   sKFGGV]]3/0F
''%.
BC
fS*dH5P9JPb
QC
k5
)
dX[vhhse.TacCC+>D"fS'+;\JKZABsJyIJsww}-.fS'<8QCGGL<QR r   c            
       T    e Zd ZddefdZdefdZd ZddZdded	e	d
e
dee   fdZy)ScweetProviderNcfgc                 d   |xs i }|| _         t        |j                  dd            | _        |j                  dd      | _        |j                  dd      | _        t        |j                  dd            | _        t        |j                  d	d
            | _	        d | _
        d| _        i | _        y )Nscweet_limit2   scweet_db_pathzdata/scweet_state.dbscweet_secrets_filezsecrets.local.jsonscweet_manifest_scrape_on_initFscweet_delay_seconds   g        )rc   r   r5   limitdb_pathsecrets_fileboolmanifest_scraper   delay_client_last_request	last_meta)selfrc   s     r   __init__zScweetProvider.__init__t   s    iR45
ww/1GHGG$9;OP#CGG,Le$TU377#91=>
 r   r   c                    t         j                  j                  d      }|r|j                         S | j                  }t         j
                  j                  |      s2t         j
                  j                  t        j                         |      }t         j
                  j                  |      rZ	 t        |d      5 }t        j                  |      }d d d        j                  d      rt        |d         j                         S 	 | j                  j                  d      r&t        | j                  d         j                         S t!        d| j                   d      # 1 sw Y   xY w# t        $ r Y qw xY w)NSCWEET_AUTH_TOKENzutf-8)encodingscweet_auth_tokenz=Falta la cookie auth_token. Define SCWEET_AUTH_TOKEN o crea 'z8' con {"scweet_auth_token": "..."}. Ver SETUP_SCWEET.md.)osenvironr5   r   rn   pathisabsjoingetcwdexistsopenjsonloadr   	Exceptionrc   r
   )ru   tokr}   fdatas        r   _auth_tokenzScweetProvider._auth_token   s,   jjnn0199;  ww}}T"77<<		T2D77>>$$1Q99Q<D 288/0t$789??AA 1 88<<+,txx 345;;==!!""`b
 	
 21  s*   /E. <E"4E. "E+'E. .	E:9E:c                    | j                   	 ddlm} | j                         }| j                  }t        j                  j                  |      s2t        j                  j                  t        j                         |      }t        j                  t        j                  j                  |      xs dd        |||| j                        | _         | j                   S # t        $ r}t	        d|       d }~ww xY w)Nr   )ScweetzNo se pudo importar Scweet: .T)exist_ok)
auth_tokenrm   manifest_scrape_on_init)rr   Scweet.clientr   r   r
   r   rm   r{   r}   r~   r   r   makedirsdirnamerp   )ru   ScweetClientetokendbs        r   _get_clientzScweetProvider._get_client   s    <<F@ $$&EB77==$WW\\"))+r2KK+2sTB' (,(<(<DL
 ||  F!$@"DEEFs   C 	C;(C66C;c                     | j                   t        j                         | j                  z
  z
  }|dkD  rt        j                  |       t        j                         | _        y )Nr   )rq   time	monotonicrs   sleep)ru   waits     r   	_throttlezScweetProvider._throttle   sD    zzT^^-0B0BBC!8JJt!^^-r   rC   sincerl   c                 >   | j                         }| j                          	 |j                  j                  d      g|xs | j                        }fd|xs g D        D cg c]  }|s|	 }}t        d |D        d       }	|	dt        |      d	| j                  j                  d      <   |D cg c]  }|j                  |k\  s| }}|j                  d
 d       |d | S # t
        $ r  t        $ r}t        d d|       d }~ww xY wc c}w c c}w )Nr>   )rl   u   Scweet falló en @z: c              3   6   K   | ]  }t        |        y wN)r`   ).0rrC   s     r   	<genexpr>z3ScweetProvider.fetch_user_tweets.<locals>.<genexpr>   s     L
!l1f5
s   c              3   4   K   | ]  }|j                     y wr   rG   )r   ts     r   r   z3ScweetProvider.fetch_user_tweets.<locals>.<genexpr>   s     3FqallFs   )defaultF)neweststalen_rawc                     | j                   S r   r   )r   s    r   <lambda>z2ScweetProvider.fetch_user_tweets.<locals>.<lambda>   s    !,,r   T)keyreverse)r   r   get_profile_tweetsr@   rl   r
   r   maxlenrt   rG   sort)
ru   rC   r   rl   clientrowsr   r   tweetsr   s
    `        r   fetch_user_tweetsz ScweetProvider.fetch_user_tweets   s*   !!#	B,,fmmC.@-AI\RVR\R\,]D M

LRLPQ!LR3F3TB8>Y\]cYd-ev}}S)*#=Vq||u'<!V=.=fu~  	 	B 26("QC@AA	B S >s/   1C* %D-D6DD*D<DDr   )r   N)rf   )r   r   r   r?   rv   r   r   r   r   r   r   r   r   r   r   r   r   rb   rb   s   sL    
D 

S 
,$. H S RVW\R] r   rb   )__doc__r   r{   r   r   r   typingr   r   agent.modelsr   agent.providers.baser   r   r
   r   r&   r2   r?   r8   r   rB   r`   rb   r   r   r   <module>r      s     	  ' !  .	) 	c ,* 0 D C C d C HUO .K] Kr   