Ë
    uºãj­-  ã                   ó¬  — d Z ddlZddlZddlZddlZddlZddlmZ ej                  j                  dd¬«        ee
«      j                  «       j                  j                  Zedz  Zedz  d	z  Zd
Z G d„ d«      Zdeddfd„Zdefd„Zdedefd„Zdefd„ZdZdZdedefd„Zd#defd„Zd„ Zd„ Zdededefd„Z dedefd „Z!d$d!„Z"e#d"k(  r e"«        yy)%a¸  Token de Pixiv (OAuth de `gppt`) -> `.env`, con reintentos y log.

Lo llama `pixiv_login.bat`; tambien funciona a mano:

    python Engine/pixiv_token.py --login     # login OAuth (navegador + codigo), con reintentos
    python Engine/pixiv_token.py             # guarda el token cacheado en .env
    python Engine/pixiv_token.py --check     # solo prueba el token que ya hay en .env
    python Engine/pixiv_token.py --browser   # plan B: navegador automatizado con tu clave
    python Engine/pixiv_token.py --profile otro --login

Diferencias con `python -m gppt login`:

- **No imprime el token** (gppt lo escribe en stdout; aqui nunca se ve).
- **Reintenta sin relanzar**: la URL y el `code_verifier` valen para toda la
  ejecucion, asi que si el codigo caduca puedes volver a logearte y pegar otro
  sin cerrar la ventana (el fallo tipico es que el codigo dura ~30 s).
- **Todo queda en `Logs/pixiv_login.log`**, incluido el error exacto de Pixiv.
é    N)ÚPathúutf-8Úbackslashreplace©ÚencodingÚerrorsz.envÚLogszpixiv_login.logÚPIXIV_REFRESH_TOKENc                   ó.   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zy)Ú_Teez8Escribe en la consola y, a la vez, en el fichero de log.c                 ó"   — ||c| _         | _        y ©N)ÚstreamÚfp)Úselfr   r   s      ú3C:\Users\Usuario\Downloads\SD\Engine/pixiv_token.pyÚ__init__z_Tee.__init__&   s   € Ø% rÐˆŒ�T•Wó    c                 ó¸  — t        j                  t        «      5  | j                  j	                  |«       | j                  j                  «        d d d «       t        j                  t        «      5  | j                  j	                  |«       | j                  j                  «        d d d «       t        |«      S # 1 sw Y   ŒkxY w# 1 sw Y   t        |«      S xY wr   )Ú
contextlibÚsuppressÚ	Exceptionr   ÚwriteÚflushr   Úlen)r   Útexts     r   r   z
_Tee.write)   s�   € Ü× Ñ ¤Õ+Ø�K‰K×Ñ˜dÔ#Ø�K‰K×ÑÔ÷ ,ô × Ñ ¤Õ+Ø�G‰G�M‰M˜$ÔØ�G‰G�M‰MŒO÷ ,ô �4‹yÐ÷ ,Ð+ú÷ ,ô �4‹yÐús   š6B:Á16CÂ:CÃCc                 óº   — | j                   | j                  fD ]4  }t        j                  t        «      5  |j                  «        d d d «       Œ6 y # 1 sw Y   ŒAxY wr   )r   r   r   r   r   r   )r   Útargets     r   r   z
_Tee.flush2   s?   € Ø—{‘{ D§G¡GÓ,ˆFÜ×$Ñ$¤YÕ/Ø—‘”÷ 0Ð/ñ -ß/Ð/ús   µAÁA	c                 óV   — 	 | j                   j                  «       S # t        $ r Y yw xY w)NF)r   Úisattyr   )r   s    r   r    z_Tee.isatty7   s,   € ð	Ø—;‘;×%Ñ%Ó'Ð'øÜò 	Ùð	ús   ‚ œ	(§(c                 ó.   — t        | j                  |«      S r   )Úgetattrr   )r   Únames     r   Ú__getattr__z_Tee.__getattr__=   s   € Ü�t—{‘{ DÓ)Ð)r   N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r    r$   © r   r   r   r   #   s   „ ÙBò*òòò
ó*r   r   ÚheaderÚreturnc                 ó2  — t         j                  j                  dd¬«       t         j                  ddd¬«      }|j	                  dd| › d�z   «       t        t        j                  |«      t        _        t        t        j                  |«      t        _        y )	NT)ÚparentsÚexist_okÚar   r   r   z?
==============================================================Ú
)	ÚLOGÚparentÚmkdirÚopenr   r   ÚsysÚstdoutÚstderr)r*   r   s     r   Ú
attach_logr8   A   sk   € Ü‡J�J×Ñ˜T¨DÐÔ1Ü	�‰�# Ð0BˆÓ	C€BØ‡H�Hˆ_  F 8¨2˜Ñ.Ô/Ü”c—j‘j "Ó%„C„JÜ”c—j‘j "Ó%„C…Jr   c                  ó  — t         j                  «       sg dfS t         j                  «       j                  dd¬«      } d| v rdnd}| j	                  dd«      j                  d«      D �cg c]  }|j                  d«      ‘Œ }}||fS c c}w )z.(lineas sin saltos, salto de linea dominante).z
r   Úreplace)r   r0   Ú)ÚENVÚexistsÚ
read_bytesÚdecoder:   ÚsplitÚrstrip)ÚrawÚeolÚlnÚliness       r   Úread_env_textrF   J   s‚   € ä�:‰:Œ<Ø�6ˆzÐÜ
�.‰.Ó
×
!Ñ
! '°)Ð
!Ó
<€CØ˜c‘M‰& t€CØ'*§{¡{°6¸4Ó'@×'FÑ'FÀtÔ'LÓMÑ'L ˆR�Y‰Y�t�_Ð'L€EÐMØ�#ˆ:Ðùò Ns   Á)BÚvaluec                 ó  — t        «       \  }}g d}}|D ]S  }|j                  «       j                  t        «      r|j	                  t        › d| › �«       d}ŒC|j	                  |«       ŒU |sL|r9|d   j                  «       s&|j                  «        |r|d   j                  «       sŒ&|ddt        › d| › �gz  }t        j                  |j                  |«      j                  «       |z   j                  d«      «       |rdS d	S )
zDEscribe/actualiza `PIXIV_REFRESH_TOKEN` sin tocar el resto del .env.FÚ=TéÿÿÿÿÚ zE# Token de Pixiv (gppt): lee obras y mide co-ocurrencia real de tags.r   ÚactualizadoÚanadido)rF   ÚstripÚ
startswithÚVARÚappendÚpopr<   Úwrite_bytesÚjoinrA   Úencode)rG   rE   rC   ÚoutÚdoneÚlines         r   Ú
update_envrY   T   sè   € ä“�J€Eˆ3Ø�Eˆ€CÛˆØ�:‰:‹<×"Ñ"¤3Ô'Ø�J‰Jœ#˜˜a ˜wÐ'Ô(Ø‰Dà�J‰J�tÕð ñ Ù˜#˜b™'Ÿ-™-œ/Ø�G‰GŒIñ ˜#˜b™'Ÿ-™-�/à�ØWÜ�%�q˜˜Ð ð"ñ 	"ˆô ‡O�O�S—X‘X˜c“]×)Ñ)Ó+¨cÑ1×9Ñ9¸'ÓBÔCÙ ˆ=Ð/ iÐ/r   c                  ó$  — dd l } | j                  j                  t        «      xs d}|sYt	        j
                  t        «      5  ddlm}  |t        «       | j                  j                  t        «      xs d}d d d «       |S |S # 1 sw Y   |S xY w)Nr   rK   )Úload_dotenv)
ÚosÚenvironÚgetrP   r   r   r   Údotenvr[   r<   )r\   rG   r[   s      r   Ú	env_tokenr`   h   sl   € ÛØ�J‰J�N‰Nœ3ÓÒ% 2€EÙÜ× Ñ ¤Õ+Ý*ÙœÔØ—J‘J—N‘N¤3Ó'Ò-¨2ˆE÷ ,ð €Lˆ5€L÷	 ,ð €Lús   Á6BÂBae  ------------------------------------------------------------
 1. En el navegador abre una pestana y pulsa F12
    (pestana Network -> marca "Preserve log").
 2. Vuelve aqui y pulsa Enter: se abrira esta URL:

    {url}

 3. Logeate en Pixiv.
 4. En el Network saldra "callback?state=...&code=..." o "pixiv://...".
 5. Copia SOLO el valor de code= y pegalo aqui abajo
    (tambien vale pegar la URL entera).

 El codigo caduca a los ~30 s: no te entretengas.
 Si falla, no cierres esto: la URL sigue valiendo, vuelve a logearte
 y pega un codigo nuevo.
------------------------------------------------------------
))zoauth processz=codigo caducado (30 s), ya usado, o de otra pestana/ejecucion)zinvalid requestzClo pegado no es un `code` valido: copia el valor de code=, no state)zinvalid grantzcodigo caducado o ya usado)Úratez0demasiados intentos seguidos: espera 1-2 minutos)Ú918z7peticion mal formada: el codigo no es el valor de code=Úmessagec                 óp   — | j                  «       j                  dd«      }t        D ]  \  }}||v sŒ|c S  y)NÚ_Ú rK   )Úlowerr:   ÚHINTS)rc   ÚlowÚneedleÚhints       r   Ú	explicaterl   �   s9   € Ø
�-‰-‹/×
!Ñ
! # sÓ
+€Cß‰ˆ�Ø�SŠ=ØŠKð ð r   Útriesc                 ó>  — ddl m}m}m}m} ddlm}m} t        j                  t        «      5  ddlm} |j                  j                  dd«       ddd«        |«       \  }}	 ||	«      }
t        t        j!                  |
¬«      «       	 t#        d«       t        j                  t        «      5  t+        j,                  |
«       ddd«       t        d
«       t/        d| dz   «      D ]W  }	 t#        d|› d| › d�«      }	  ||«      }t1        |«      dk  rt        dt1        |«      › d�«       ŒF	  | |||¬«      «      c S  t)        d«      ‚# 1 sw Y   ŒüxY w# t$        t&        f$ r t)        d	«      ‚w xY w# 1 sw Y   Œ²xY w# t$        t&        f$ r t)        d	«      ‚w xY w# t        $ r}t        d|› �«       Y d}~ŒÕd}~ww xY w# |$ rS}t        d«       t        d|› �«       t3        t5        |«      «      }|rt        d|› �«       t        d«       Y d}~�Œ0d}~ww xY w)z>Login OAuth con la MISMA url/verifier para todos los intentos.r   )ÚAuthorizationÚbuild_login_urlÚextract_codeÚgenerate_pkce)Ú
TokenErrorÚexchangeNzaccept-languageúen-us)Úurlz=>>> Enter cuando tengas F12 abierto y 'Preserve log' marcado z,[X] cancelado: no se ha escrito nada en .envz[..] abriendo el navegador...é   zcode (Ú/z): z[!] é   z"[!] eso no es un codigo de Pixiv (z% caracteres): copia el valor de code=)ÚcodeÚcode_verifierz[X] Pixiv rechazo el codigo.z    z    -> zJ    La URL de arriba sigue valiendo: vuelve a logearte y pega otro codigo.z8[X] agotados los intentos: no se ha escrito nada en .env)Ú
gppt.oauthro   rp   rq   rr   Ú
gppt.tokenrs   rt   r   r   r   ÚtokenÚ_HEADERSÚ
setdefaultÚprintÚINSTRUCCIONESÚformatÚinputÚEOFErrorÚKeyboardInterruptÚ
SystemExitÚ
webbrowserr4   Úranger   rl   Ústr)rm   ro   rp   rq   rr   rs   rt   Ú_gtÚverifierÚ	challengerv   ÚnrB   rz   Úerk   s                   r   Úlogin_oauthr�   ˜   s  € çVÓVß/ä	×	Ñ	œYÕ	'å Ø�‰×ÑÐ 1°7Ô;÷ 
(ñ
 (›/Ñ€HˆiÙ
˜)Ó
$€Cô 
Œ-×
Ñ
 3Ð
Ó
'Ô(ðIÜÐMÔNô 
×	Ñ	œYÕ	'Ü�‰˜Ô÷ 
(ä	Ð
)Ô*ä�1�e˜a‘iÖ ˆð	MÜ˜&   1 U G¨3Ð/Ó0ˆCð	Ù Ó$ˆDô ˆt‹9�rŠ>ÜÐ6´s¸4³y°kð B,ð -ô .àð	`Ù™M¨tÀ8ÔLÓMÒMð !ô. ÐOÓ
PÐP÷U 
(Ð	'ûô Ô'Ð(ò IÜÐGÓHÐHðIúç	'Ð	'ûô Ô+Ð,ò 	MÜÐKÓLÐLð	Mûô ò 	Ü�D˜˜�*ÔÜûð	ûð ò 	`ÜÐ0Ô1Ü�D˜˜�*ÔÜœS ›VÓ$ˆDÙÜ˜ ˜vÐ&Ô'ÜÐ^×_Ò_ûð	`ús`   ®#EÂE Â/E6Ã+FÃ>F Ä.GÅEÅE3Å6E?ÆFÆ 	GÆ)F<Æ<GÇHÇ	AHÈHc                  óv  — ddl } t        d«       t        d«       t        d«       t        d«      j                  «       }t	        j                  d«      j                  «       }|r|st        d«      ‚	 | j                  ||d	¬
«      S # t        $ r)}t        dt        |«      j                  › d|› �«      ‚d}~ww xY w)zEPlan B: navegador automatizado con tus credenciales (no guarda nada).r   Nz3[..] login con navegador automatizado (Playwright).z6     La primera vez descarga Chromium y tarda un poco.z.     No se guarda ninguna credencial en disco.zpixiv ID o email: zpassword (no se muestra): z[X] faltan credencialesF)Úheadlessz"[X] fallo el login con navegador: ú: )
Úgpptr�   r„   rN   Úgetpassr‡   Úloginr   Útyper%   )r”   ÚuserÚpwdr�   s       r   Úlogin_browserrš   Ê   s°   € ãÜ	Ð
?Ô@Ü	Ð
BÔCÜ	Ð
:Ô;ÜÐ%Ó&×,Ñ,Ó.€DÜ
�/‰/Ð6Ó
7×
=Ñ
=Ó
?€CÙ‘sÜÐ2Ó3Ð3ðWØ�z‰z˜$ ¨eˆzÓ4Ð4øÜò WÜÐ=¼dÀ1»g×>NÑ>NÐ=OÈrÐRSÐQTÐUÓVÐVûðWús   Á2B Â	B8Â$B3Â3B8c                  ó@   — 	 dd l } | S # t        $ r t        d«      ‚w xY w)Nr   z5[!] falta gppt:  python -m pip install --upgrade gppt)r”   ÚImportErrorr‡   )r”   s    r   Ú	load_gpptr�   Û   s1   € ðRÛð €Køô ò RÜÐPÓQÐQðRús   ‚ ˆÚprofileÚfreshÚbrowserc                 óR  — t        «       }|rt        «       }n-|rt        d«       t        «       }n	 |j	                  | dd¬«      S |j                  j                  | |«       t        d|j                  j                  | «      › �«       |S # t
        $ r}t        d|› �«      ‚d }~ww xY w)NzE[..] login manual de Pixiv (OAuth), sin escribir el token en pantallaÚoauthT)rž   ÚmethodÚsavez&[X] no hay token utilizable en cache: z[OK] token guardado en )r�   rš   r�   r�   Ú	get_tokenr   r‡   r~   r¤   ÚconfigÚ
token_path)rž   rŸ   r    r”   Útokr�   s         r   Úobtainr©   ã   s¡   € Ü‹;€DÙÜ‹o‰Ù	ÜÐUÔVÜ‹m‰ð	KØ—>‘>¨'¸'È�>ÓMÐMð 	‡J�J‡O�O�G˜SÔ!Ü	Ð# D§K¡K×$:Ñ$:¸7Ó$CÐ#DÐ
EÔFØ€Jøô	 ò 	KÜÐEÀaÀSÐIÓJÐJûð	Kús   ±B
 Â
	B&ÂB!Â!B&c                 ó$  — 	 ddl m} | st        d«       d| fS 	  |«       }|j	                  | ¬«       |j                  d«       |j                  dd	d
d¬«      }t        |t        «      r|j                  d«      nt        |dd«      xs g }t        dt        |«      › d�«       dt        |dd«      xs | fS # t        $ r t        d«       d| fcY S w xY w# t        $ r2}t        dt        |«      j                  › d|› �«       d| fcY d}~S d}~ww xY w)zA(sirve?, token_posiblemente_rotado) leyendo obras R-18 de verdad.r   )ÚAppPixivAPIz3[!] falta pixivpy3:  python -m pip install pixivpy3Fz[X] no hay token que probar)Úrefresh_tokenru   u   åŽŸç¥ž R-18Úpartial_match_for_tagsÚ	date_descÚfor_ios)ÚwordÚsearch_targetÚsortÚfilterz[X] el token no funciona: r“   NÚillustsz[OK] token valido: z obras R-18 leidas de verdadTr¬   rK   )Úpixivpy3r«   rœ   r�   ÚauthÚset_accept_languageÚsearch_illustr   r—   r%   Ú
isinstanceÚdictr^   r"   r   )rG   r«   ÚapiÚresr�   r´   s         r   Úcheckr½   ô   s*  € ðÝ(ñ ÜÐ+Ô,Ø�eˆ|Ðð	Ù‹mˆØ�‰˜uˆÔ%Ø×Ñ Ô(Ø×Ñ ]Ø.FØ%0¸ð  ó Dˆô &0°´TÔ%:ˆs�w‰w�yÔ!Ü˜C ¨DÓ1ò9Ø68ð ä	Ð¤ G£˜~Ð-IÐ
JÔKØ”˜˜o¨rÓ2Ò;°eÐ;Ð;øô' ò ÜÐCÔDØ�eˆ|Òðûô ò ÜÐ*¬4°«7×+;Ñ+;Ð*<¸B¸q¸cÐBÔCØ�eˆ|Õûðús.   ‚B6 š?C Â6CÃCÃ	DÃ'D
ÄDÄ
Dc            
      óÄ  — t        j                  d¬«      } | j                  ddd¬«       | j                  ddd	¬
«       | j                  ddd¬
«       | j                  ddd¬
«       | j                  «       }ddlm} t        d|j                  «       d›d|j                  rdn|j                  rdn|j                  rdnd› �«       |j                  ryt        «       }|st        dt        › d�«      ‚t        dt        |«      › d�«       t        |«      \  }}|r|r||k7  rt        dt        |«      › d�«       t        |rd«      ‚d«      ‚t!        |j"                  |j                  |j                  ¬«      }|j$                  xs d }t        d!|› d"|j&                  xs d › d#|j(                  xs d › d$�«       t        |j*                  «      }t        d%t        › d&|› d't        |j*                  «      › d�«       t        |j*                  «      \  }}|r)|r'||j*                  k7  rt        dt        |«      › d�«       t        d(t,        › �«       t        |rd«      ‚d«      ‚))NzToken de Pixiv -> .env)Údescriptionz	--profileÚdefaultzperfil de gppt (default))rÀ   Úhelpz--loginÚ
store_truez,login OAuth interactivo (navegador + codigo))ÚactionrÁ   z	--browserz3plan B: navegador automatizado con tus credencialesz--checkz+no toca .env: solo prueba el token guardador   )Údatetimezrun z%Y-%m-%d %H:%M:%Sz  modo=r½   r    r–   Úcachez[X] z esta vacio en .envz![..] probando el token guardado (z caracteres)z"[..] Pixiv roto el refresh_token: z en .envrw   )rŸ   r    Ú?z[OK] sesion de Pixiv: z (@z, id Ú)z[OK] rf   z
 en .env (z[..] log completo: )ÚargparseÚArgumentParserÚadd_argumentÚ
parse_argsrÄ   r8   Únowr½   r    r–   r`   r‡   rP   r�   r   rY   r©   rž   Ú	user_nameÚuser_accountÚuser_idr¬   r1   )	ÚpÚargsrÄ   rG   ÚokÚrotatedr¨   ÚwhoÚstates	            r   ÚmainrÖ     sK  € Ü×ÑÐ,DÔE€AØ‡N�N�;¨	Ð8R€NÔSØ‡N�N�9 \ØFð ô Hà‡N�N�; |ØMð ô Oà‡N�N�9 \ØEð ô Gà�<‰<‹>€Då!Ü��h—l‘l“nÐ%6Ð7ð 8Ø"&§*¢*‘w¸t¿|º|±)Ð\`×\fÒ\fÑQXÐlsÐtðvô wð ‡z‚zÜ“ˆÙÜ˜t¤C 5Ð(;Ð<Ó=Ð=ÜÐ1´#°e³*°¸\ÐJÔKÜ˜E“l‰ˆˆGÙ‘'˜g¨Ò.ÜÐ6´zÀ'Ó7JÐ6KÈ8ÐTÔUÜ™b˜Ó(Ð( aÓ(Ð(ä
�—‘ T§Z¡Z¸¿¹Ô
F€CØ
�-‰-Ò
˜3€CÜ	Ð" 3 % s¨3×+;Ñ+;Ò+B¸sÐ*Cð DØ—‘Ò"˜sÐ# 1ð&ô 'ä�s×(Ñ(Ó)€EÜ	ˆE”#��a˜�w˜j¬¨S×->Ñ->Ó)?Ð(@ÀÐ
MÔNÜ˜×)Ñ)Ó*�K€BˆÙ	‰g˜' S×%6Ñ%6Ò6ÜÐ2´:¸gÓ3FÐ2GÀxÐPÔQÜ	Ð¤˜uÐ
%Ô&Ü
™"�QÓ
$Ð$ !Ó
$Ð$r   Ú__main__)é   )r+   N)$r(   rÈ   r   r•   r5   rˆ   Úpathlibr   r6   ÚreconfigureÚ__file__Úresolver2   ÚBASE_DIRr<   r1   rP   r   rŠ   r8   ÚtuplerF   rY   r`   r‚   rh   rl   Úintr�   rš   r�   Úboolr©   r½   rÖ   r%   r)   r   r   Ú<module>rá      s=  ðñó$ Û Û Û 
Û Ý à ‡
�
× Ñ  Ð0BÐ Ô Cá�‹>×!Ñ!Ó#×*Ñ*×1Ñ1€Ø�Ñ€Ø�ÑÐ+Ñ+€Ø€÷*ñ *ð<&�sð &˜tó &ð�uó ð0�cð 0˜có 0ð(�3ó ð€ð&	€ð�sð ˜só ñ/Q�só /QòdWò"ð�Cð  ð ¨tó ð"<�ð <˜ó <ó6#%ðL ˆzÒÙ…Fð r   