
    i                        S r SSKJrJrJr  SSKJrJrJrJ	r	  SSK
r
SSKrSSKrSSKrSSKrSSKrSr\S-   r " S	 S
\5      r " S S\5      r " S S\5      r " S S\\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S 5      r " S! S"\5      r " S# S$\5      r " S% S&\5      r  " S' S(\5      r! " S) S*\5      r" " S+ S,\5      r# " S- S.\5      r$ " S/ S05      r% " S1 S2\%5      r& " S3 S4\&5      r' " S5 S6\&5      r( " S7 S8\&5      r) " S9 S:\&5      r* " S; S<\&5      r+ " S= S>\&5      r, " S? S@\&5      r- " SA SB\%5      r.g)Cz&Extractors for https://www.tiktok.com/   )	ExtractorMessageDispatch   )textutilytdl	exception    Nz%(?:https?://)?(?:www\.)?tiktokv?\.comz/@([\w_.-]+)c                       \ rS rSrSrSrSrSrSrSr	Sr
0 r0 rS	 rS
 rS r/ 4/ S.S jjrSS jrS rS rS rS rS rS rS rS rS rS rS rS rSrg)TiktokExtractor   z Base class for TikTok extractorstiktok)z
{category}z{user}z<{id}{num:?_//>02} {title[b:150]}{file_id:? [/]/}.{extension}z{id}_{num}_{file_id}zhttps://www.tiktok.comz.tiktok.comc                 
   U R                  SS5      U l        U R                  SS5      U l        U R                  SS5      U l        U R                  SS5      U l        U R                  SS5      U l        U R                  S5      =(       d    S	U l        [        R                  " U R                  5      U l	        S U l
        S U l        U R
                  (       a  U R
                  S
:w  a  U R
                  SL d  [        U R
                  [        5      (       d  SU l        1 Skn[        U R
                  R                  S5      5      nUR!                  U5      =(       d    S U l
        UR#                  U5      =(       d    S U l        g g g )NphotosTaudiovideoscoversF	subtitlesztiktok-range allASR>   LCMTr   ,)configphotor   videocoverr   ranger   predicate_range_parserange_predicatesubtitle_sourcessubtitle_langs
isinstancestrsetsplitintersection
difference)selfknown_sourcesfilterss      H/app/mltbenv/lib/python3.13/site-packages/gallery_dl/extractor/tiktok.py_initTiktokExtractor._init"   s$   [[40
[[$/
[[40
[[51
[%8[[06B
#99$**E !%">>dnn5~~%Z-L-L!&/M$....s34G$1$>$>w$G$O4D!")"4"4]"C"KtD 6>    c              #   D  #    U R                  5        GH  n U R                  U5      nU R                  U5      nSU;  a(  U R                  US   S   5      nU R                  U5      nUS   nU R                  X1S5      (       d  Ms  US   S   nUR	                  S5      =n=(       a    US   =(       d    S	US
'   U R                  US   5      US'   SU;   a  SOSUS'   US   =pg[        R                  S	U4v   SnSU;   a  U R                  (       a  U(       d  SUS    3nUS   S   n	[        U	S5       Hn  u  pUS   S   S   n[        R                  " X5        UR                  SUUU
US   R                  S5      S   US   US   S.5        [        R                  X4v   Mp     U R                  (       aF  SU;   a@  U R                  S :X  a  S!nGOU R!                  U5      =n(       a  [        R                  X4v   GO_SU;   Ga<  U R"                  S :X  a  SnO@U R"                  (       a/  U R%                  U5      =n(       a  [        R                  X4v   US"	 U R&                  (       a?  U R)                  US5       H)  n[        R                  X4v   U R&                  S#:w  d  M)    O   U R*                  (       a  U R-                  US5       H  n[        R                  X4v   M     UR/                  S$S 5        UR/                  S%S 5        UR/                  S&S 5        UR/                  S'S 5        UR/                  S(S 5        OU R0                  R3                  S)U5        U(       aP  U(       d  S*U S+US    3nUR                  US S	US!:X  a  S,OS-USS	SSS..	5        [        R                  S/U-   U4v   GM  GM     g ! [4         aX  nU R0                  R7                  U5        U R0                  R9                  S0XR:                  R<                  U5         S nAGM  S nAff = f7f)1Nzwebapp.video-detailz
seo.abtest	canonicalpostitemInfo
itemStructauthoruniqueIdr   user
createTimedate	imagePostimager   	post_typedescFzTikTok photo #idimagesr   imageURLurlListr   filename~
imageWidthimageHeight)typer=   titlenumfile_idwidthheightmusicr	   r   	_fallbackr   subtitle_lang_idsubtitle_lang_codenamesubtitle_formatsubtitle_versionsubtitle_sourcez%s: Skipping postTikTok z #mp3mp4)	rH   r=   rD   	extensionrI   rJ   rK   rL   rM   zytdl:z#%s: Failed to extract post (%s: %s))posts_sanitize_url_extract_rehydration_data_check_status_codegetparse_timestampr   	Directoryr   	enumerater   nameext_from_urlupdate	partitionUrlr   _extract_audior   _extract_videor   _extract_coversr   _extract_subtitlespoploginfo	Exception	tracebackerror	__class____name__)r+   
tiktok_urldatavideo_detailr4   aoriginal_titlerI   
ytdl_mediaimg_listiimgurlexcs                 r.   itemsTiktokExtractor.items:   s    **,J_H!//
;
55jA(4 "&!3!3\*;7"9J99*ED#$9:..$&: :#J/= ((8,,Q?!J-E2 V#33D4FGV/:d/BG[!)-f5''T11"
$&zz-&4T$ZL$AE#'#4X#>&/!&<FA"%j/)"<Q"?C 11#< KK+2+.+0+,+/
+;+E+Ec+J1+M+.|+<+.}+=)  #*++s"88 '= zzgo::/)0J$($7$7$==S=")++s"88_zzV+%,
0C0CD0I)I)I%kk344 -zz#'#7#7g#FC")++s"88#zzU2 % $G
 ~~#'#:#:4#IC")++s"88 $J !3T:!94@!2D9!3T:!2D9HHMM"5zB)")*RT
| DKK&0&*&(!+w!6E&+&'&(&'&'!  "++w';TAA [ 'z  H""3'D)==+A+A3H HHsD   P A,N;P HN;%DN;2	P ;
PAPP PP c                 P    [         R                  " UR                  SSS5      5      $ )Nz/photo//video/r   )r   ensure_http_schemereplace)r+   rz   s     r.   rZ   TiktokExtractor._sanitize_url   s     &&s{{9i'KLLr1   has_keysc                   SnS nSn  U R                  U5      nUR                  (       aF  SUR                  ;   a6  [        R                  " SUR                  R                  S5      S    S35      eUR                  n[        R                  " USS	5      n[        R                  " U5      S
   nU H  n	X   nM	     U H  n
X;  d  M
  [        U
5      e   U$ ! [        [        4 Ga    U(       d  SnU R                  R                  S5         U R                  U5        S n GM  ! [         aS  nU R                  R!                  U5        U R                  R#                  SUR%                  S5      S   5         S nAOS nAff = fU R                  R#                  SUR%                  S5      S   US-   U R&                  5        X@R&                  :  a  e US-  nU R)                  U R*                  S5        SnS n Of = fGM  )Nr   FTz/loginzHTTP redirect to login page ('?z')zH<script id="__UNIVERSAL_DATA_FOR_REHYDRATION__" type="application/json">z	</script>__DEFAULT_SCOPE__zSolving JavaScript challengez%s: Failed to solve JavaScript challenge. If you keep encountering this issue, please try again with the --write-pages option and include the resulting page in your bug report/r   z/%s: Failed to retrieve rehydration data (%s/%s)r   retry)requesthistoryrz   r
   AuthorizationErrorrc   r   extrr   
json_loadsKeyError
ValueErrorrj   rk   _solve_challengerl   rm   warning
rpartition_retriessleep_timeout)r+   rz   additional_keysr   trieshtmlchallenge_attemptresponserr   key
assert_keyr{   s               r.   r[   )TiktokExtractor._extract_rehydration_data   s   !0<<,##HLL(@#66%\\33C8;<B@A A  }}yy /0;= t,-@A*C9D +"*J!-&z22 #+ )  )(,%HHMM"@A4--d3# $ 4**3/((@  NN3/24 44    "+,/NN3,?,BEAI!%0 MM)


4=='2$)!?% s>   B:C C 5G8D##
F -A	E;6G8;F  A5G87G8c                    XR                   ;   a  U R                   U   nO3U R                  USS/S9nUS   U R                   U'   US   U l        US   nU R                  X1S5      (       d  [        R
                  " U S35      e U H  nX4   nM	     U$ ! [         aG  nU R                  R                  U5        [        R
                  " SUSR                  U5      5      eS nAff = f)Nzwebapp.user-detailwebapp.app-contextr   profilez$: could not extract rehydration dataz+%s: could not extract rehydration data (%s), )
rehydration_data_cacher[   "rehydration_data_app_context_cacher\   r
   ExtractionErrorr   rj   rm   join)r+   profile_urlr   rr   r   r{   s         r.   _extract_rehydration_data_user.TiktokExtractor._extract_rehydration_data_user   s   555..{;D11.0DE 2 D
 )* ''4 )* 3,-D&&t)DD++-CDF F	9&y '   	9HHs#++=TYY79 9	9s   B 
C$ACC$c                 X    U R                   (       d  U R                  SS/5      U l         g g )Nzhttps://www.tiktok.com/r   )r   r[   r+   s    r.   7_ensure_rehydration_data_app_context_cache_is_populatedGTiktokExtractor._ensure_rehydration_data_app_context_cache_is_populated   s0    66..-0D/EG 3 7r1   c                 P   [         R                  " [         R                  " USS5      SS5      n[        R                  " [        R
                  " US-   5      R                  5       5      n[        R
                  " US   S   S-   5      n[        R                  " [        R
                  " US   S   S-   5      5      n[        S	5       HQ  nUR                  5       nUR                  [        U5      R                  5       5        UR                  5       U:X  d  MQ    O   [        R                   " S
5      e[         R                  " [         R                  " USS5      SS5      n[         R                  " [         R                  " USS5      SS5      n	[         R                  " [         R                  " USS5      SS5      n
U R"                  n[%        [&        R&                  " 5       5      S-   n[        R(                  " [        U5      R                  5       SS9R                  5       US'   [        R(                  " [        R*                  " U5      R                  5       SS9nU R,                  R/                  XR                  5       XS9  U
(       a  U R,                  R/                  XXS9  g g )Nzid="cs">zclass=""z==vcrt   i@B zfailed to find matching digestzid="wci"zid="rci"zid="rs"   F)newlined)domainexpires)r   r   r   r   binascii
a2b_base64decodehashlibsha256r    copyrb   r&   encodedigestr
   r   cookies_domaininttime
b2a_base64
json_dumpscookiesr'   )r+   r   csr   expectedbaseidxtestwcircirsr   r   r   s                 r.   r    TiktokExtractor._solve_challenge   s   YYtyyy#6	3GOOH//T	:AACD &&qvc{T'9:~~h11!C&+2DEF#C99;DKKC)*{{}(	 $ ++,LMM ii		$
C8)SIii		$
C8)SIYYtyyy#6	3G $$diik"Q&$$SX__%6FMMO# 2 9 9 ;UKhhjILLSVE r1   c                 d    U R                  XSS5      nUc  [        R                  " U S35      eU$ )NzMS4wLjABAAAA[\w-]{32,64}secUidz%: unable to extract secondary user ID_extract_idr
   AbortExtraction)r+   r   	user_namesec_uids       r.   _extract_sec_uid TiktokExtractor._extract_sec_uid  sE    ""$?K?+++BCE Er1   c                 d    U R                  XSS5      nUc  [        R                  " U S35      eU$ )Nz[0-9]+r@   z: unable to extract user IDr   )r+   r   r   	author_ids       r.   _extract_author_id"TiktokExtractor._extract_author_id  sC    $$It5	+++89; ;r1   c                     [         R                  " U5      R                  nU" U5      b  U$ U R                  USSU45      nU" U5      c  S $ U$ )NuserInfor9   )r   re	fullmatchr   )r+   r   r   regexid_keymatchr@   s          r.   r   TiktokExtractor._extract_id%  sX    ((' 00*ff57Ry(t0b0r1   c                    US   nU R                  U5      nU(       d  [        R                  " US    S35      eUS   n[        R                  " XA5        UR                  USS  SS US   =(       d    SUS    3UR                  S5      SS	UR                  S
5      UR                  S5      S.	5        US   (       d  UR                  SS5      US'   U$ )Nr   r@   zA: Failed to extract video URLs. You may need cookies to continue.r   r   r?   zTikTok video #durationr   rL   rM   )	rO   rH   r=   rI   r   rJ   rK   rL   rM   rX   formatrW   )_extract_video_urlsr
   r   r   ra   rb   r]   )r+   r4   r   urlsrz   s        r.   rf   TiktokExtractor._extract_video1  s    W''.++:, 4 56 6 1gc(ab fF>$t*)F:.7+8,

 
	 K  %		(E :D
r1   c                 F   SU;   a  US   n[        U[        5      (       d  U/n0 nU H  nUS   n[        R                  " UR	                  S5      5      n[        R                  " UR	                  S5      5      nXg-  nX;   a  X8==   UR	                  S5      -  ss'   Mx  UR	                  S5      R                  5       X8'   M     [        U5      n	U	R                  SS9  U	 VV
s/ s H  oU     H  oPM     M     nnn
O/ nSU;   a  UR                  US   5        U$ s  sn
nf )	NbitrateInfoPlayAddrWidthHeightUrlListTreverseplayAddr)r%   listr   	parse_intr]   r   sortappend)r+   r   bitrate_infobitrate_urls
video_info	play_addrrL   rM   sizesizesrz   r   s               r.   r   #TiktokExtractor._extract_video_urlsJ  s    E! /LlD11 ,~L*
&z2	y}}W'=>	h(?@~' &)--	*BB&)2y)A)F)F)HL& + &EJJtJ$$)HED$5GcC5GCEDHDD KKj)* Is   $Dc                     US   nUS   n[         R                  " X15        UR                  SS US   =(       d    SUS    3UR                  S5      SUR                  S5      SSS	.5        US
   (       d  SUS
'   U$ )NrN   playUrlr   r?   zTikTok audio #r@   r   r   )rH   r=   rI   r   rJ   rK   rL   rM   rX   rV   )r   ra   rb   r]   )r+   r4   r   rz   s       r.   re   TiktokExtractor._extract_audioi  s    WIc( fF>$t*)F:.4	
 		 K  %D
r1   c              #     #    X   nS Hv  nUR                  U5      =n(       d  M  [        R                  " XQ5        UR                  SSUUS   =(       d    SU SUS    3UR                  S5      S	US	S	S
.	5        Uv   Mx     g 7f)N)	thumbnailr   originCoverdynamicCoverr   jpgr?   rU   z cover #r@   r   r   )	rH   rX   r=   rI   r   rJ   rK   rL   rM   )r]   r   ra   rb   )r+   r4   rH   mediacover_idrz   s         r.   rg   TiktokExtractor._extract_covers{  s     
MHii))s)%%c0!(!&!$!%f "F#*4&d!E!&:!6!"!)!"!"  	 Ns    BABc              #   h  #    X   nU R                   S LnU R                  S LnUR                  SS5       GHw  nUR                  S5      nUR                  S5      nUR                  S5      n	UR                  S5      n
UR                  S5      nU=(       a    XR                   ;   nU=(       a    XR                  ;   nU(       d  U(       d  U(       d  U(       a  M  UR                  S5      =n(       d  M  [        R                  " X5        US	   (       dC  US
    SU SU
 SU 3US	'   U	R                  5       US'   US   S:X  a  SUS'   OUS   S:X  a  SUS'   UR                  SS US   =(       d    SU SUS
    3UR                  S5      SU SU SU SU
 SU	 3	UUU	U
USSS.5        Uv   GMz     g 7f)NsubtitleInfos 
LanguageIDLanguageCodeNameFormatVersionSourcerd   rD   r@   _rX   webvttvttcreator_captionjsonsubtitler?   rU   z subtitle #r   r   )rH   r=   rI   r   rJ   rK   rP   rQ   rR   rS   rT   rL   rM   )r#   r$   r]   r   ra   lowerrb   )r+   r4   rH   r  sources_filteredlangs_filteredr  sub_lang_idsub_lang_codename
sub_formatsub_version
sub_sourcesources_matchlangs_matchrz   s                  r.   rh   "TiktokExtractor._extract_subtitles  s    
00<,,D8		/26H",,|4K (-? @!h/J",,y1K!h/J - 4333 ( 9!%8%88  !%ll5))s)%%c0 J'+/:,a8I7J!+6-q)FD$(2(8(8(:D% K(H4,1[)k*.??,2[).8.2V @!${4:,?.3ii
.C./&-q):(;1ZL&-q6.9.?.8.9.8././# & 	k 7s   C.F24B>F2c                 .   UR                  S5      nU(       d  gUS:X  aX  U R                  U5      nUc  U R                  R                  SUU5        gUS:  a  gU R                  R                  SUU5         gUS:X  a  U R                  R                  SU5        gUS	:X  a  U R                  R                  S
X#5        gUS:X  a  U R                  R                  SU5        gU R                  R                  SX$UR                  S5      =(       d    S5        g)N
statusCodeTi'  z$%s: Login required to access this %sr   zJ%s: Login required to access this %s, or this profile has no videos postedi'  z#%s: User account could not be foundi'  z%s: Requested %s not availablei'  z?%s: Region locked - Try downloading with a VPN/proxy connectionz)%s: Received unknown error code %s ('%s')	statusMsgr   F)r]   %_extract_video_count_from_user_detailrj   rn   )r+   detailrz   type_of_urlstatusvideo_counts         r.   r\   "TiktokExtractor._check_status_code  s   L)U? DDVLK"Es*,& # q  >?B*,  u_HHNN@#F  u_HHNN;SN  u_HHNN 2368  HHNN;VZZ4:< r1   c                     UR                  S5      nU(       d  g UR                  S5      =(       d    UR                  S5      n [        US   5      $ ! [        [        4 a     g f = f)Nr   statsstatsV2
videoCount)r]   r   r   r   )r+   r&  	user_infor,  s       r.   r%  5TiktokExtractor._extract_video_count_from_user_detail  s`    JJz*	g&B)--	*B	 u\*++*% 		s   A A%$A%)
r   r   r   r    r"   r   r$   r#   r   r   N)r  )rp   
__module____qualname____firstlineno____doc__categorydirectory_fmtfilename_fmtarchive_fmtrootr   r   r   r/   r|   rZ   r[   r   r   r   r   r   r   rf   r   re   rg   rh   r\   r%  __static_attributes__r  r1   r.   r   r      s    *H,MF (K#D"N)+&L0aHFM >@ 6+-6p4GF:
12>$(:x#J
r1   r   c                   0    \ rS rSrSrSr\S-   rSrS r	Sr
g)	TiktokPostExtractori  z+Extract a single video or photo TikTok linkr4   z+/(?:@([\w_.-]*)|share)/(?:phot|vide)o/(\d+)z-https://www.tiktok.com/@USER/photo/1234567890c                 `    U R                   u  pU R                   SU=(       d    S SU 3nUS 0$ )N/@r   r   )groupsr9  )r+   r9   post_idrz   s       r.   rY   TiktokPostExtractor.posts  s5    2djb\	:T{r1   r  N)rp   r1  r2  r3  r4  subcategoryBASE_PATTERNpatternexamplerY   r:  r  r1   r.   r<  r<    s    5KKKG=Gr1   r<  c                   *    \ rS rSrSrSrSrSrS rSr	g)	TiktokVmpostExtractori	  z.Extract a single video or photo TikTok VM linkvmpostzP(?:https?://)?(?:(?:v[mt]\.)?tiktok\.com|(?:www\.)?tiktok\.com/t)/(?!@)([^/?#]+)zhttps://vm.tiktok.com/1a2B3c4E5c              #   *  #    [         R                  " U R                  5      nSS0nU R                  XSS9nU(       a  [	        U5      S::  a  [
        R                  " S5      eS[        0n[        R                  UR                  S5      S   U4v   g 7f)	Nz
User-Agentzfacebookexternalhit/1.1r4   )headersnotfound   
_extractorr   r   )r   r   rz   request_locationlenr
   NotFoundErrorr<  r   Queuerc   )r+   rz   rJ  rr   s       r.   r|   TiktokVmpostExtractor.items  s     %%dhh/!:;##C6#Jc#h"n))&1112mmS]]3/2D88s   BBr  N)
rp   r1  r2  r3  r4  rB  rD  rE  r|   r:  r  r1   r.   rG  rG  	  s    8K#G 0G
9r1   rG  c                   ,    \ rS rSrSr\S-   rSrS rSr	g)TiktokUserExtractori  z#Extractor for a TikTok user profilez/?(?:$|\?|#)zhttps://www.tiktok.com/@USERc           
          U R                    SU R                  S    S3nU R                  [        US-   4[        US-   4[
        US-   4[        US-   4[        US-   4[        US	-   44S
5      $ )Nr>  r   r   avatarrY   repostsstorieslikessaved)rV  rY   )	r9  r?  _dispatch_extractorsTiktokAvatarExtractorTiktokPostsExtractorTiktokRepostsExtractorTiktokStoriesExtractorTiktokLikesExtractorTiktokSavedExtractor)r+   r   s     r.   r|   TiktokUserExtractor.items#  s    ))Bt{{1~.a0(("TH_5!TG^4#TI%56#TI%56!TG^4!TG^4*
   	 r1   r  N)
rp   r1  r2  r3  r4  USER_PATTERNrD  rE  r|   r:  r  r1   r.   rT  rT    s    -_,G,G	 r1   rT  c                   ,    \ rS rSrSr\S-   rSrS rSr	g)r\  i/  rV  z/avatarz#https://www.tiktok.com/@USER/avatarc              #     #    U R                   S   nU R                   SU 3nU R                  US5      nUR                  SU5      US'   UR                  S5      =(       d    UR                  S5      =(       d    US   n[        R
                  " XCR                  5       5      nUR                  S	S
US   -   US   US   R                  S5      S   SS.5        [        R                  SU4v   [        R                  XE4v   g 7f)Nr   r>  )r   r9   r8   r9   avatarLargeravatarMediumavatarThumbrV  @r@   rD   rE   )rH   rI   r@   rK   rJ   r   )r?  r9  r   r]   r   ra   r   rb   rc   r   r_   rd   )r+   r   r   rr   
avatar_urlrV  s         r.   r|   TiktokAvatarExtractor.items4  s     KKN	2i[122-/xx
I6VXXn- #.1I #M" 	&&z99;?T&\)Dzj)33C8;
 	 V++kk:--s   D Dr  N)
rp   r1  r2  r3  rB  rc  rD  rE  r|   r:  r  r1   r.   r\  r\  /  s    KZ'G3G.r1   r\  c                   D    \ rS rSrSr\S-   rSrS rS r	S r
S rS	 rS
rg)r]  iJ  rY   z/postsz"https://www.tiktok.com/@USER/postsc                    U R                   S   nU R                   SU 3n[        U R                  5      U l        U R                  SS5      (       a<  U R                  U5      =n(       a  U$ SnU R                  R                  SU S35        OSnU R                  X!5      =n(       a  U$ SU 3nU(       d  US	-  nU R                  R                  U5        g
)Nr   r>  r	   FTzCould not extract TikTok user z= via yt-dlp or youtube-dl, attempting the extraction directlyz-Could not extract any posts from TikTok user zM, try extracting post information using yt-dlp with the -o ytdl=true argumentr  )
r?  r9  boolr   user_provided_cookiesr   _extract_posts_ytdlrj   r   _extract_posts_api)r+   r   r   rY   r	   messages         r.   rY   TiktokPostsExtractor.postsO  s    KKN	2i[1%)$,,%7" ;;vu%%00==u=DHH= ){ +BB C D++KCC5CLAK! ? ?G!r1   c           	          [         R                  " U R                  S5      5      nSSS.nU R                  U R                  U R                  (       + [        U R                  5      S.nU R                  (       a  U R                  R                  S5      US	'   [         R                   " X XT5      nU R"                  (       a1  UR$                  R&                  nU R"                   H  nU" U5        M     U n	U	R)                  XR+                  S
5      S0 S5      n
U
S    Vs/ s H  nUS   R-                  S5      S   PM     snsS S S 5        $ ! [        [        4 aN  nU R
                  R                  S[        USS5      5        U R
                  R                  U5        / s S nA$ S nAff = fs  snf ! , (       d  f       g = f)NmodulezCannot import module '%s'namer   T)extract_flatignore_no_formats_error)retriessocket_timeoutnocheckcertificateplaylist_itemshttpproxy
TikTokUserFentriesrz   r   r   )r	   import_moduler   ImportErrorSyntaxErrorrj   rn   getattrrm   r   r   _verifyr&   r    _proxiesr]   construct_YoutubeDLr   	cookiejar
set_cookie_YoutubeDL__extract_infoget_info_extractorrc   )r+   r   ru  r{   	extr_opts	user_optsytdl_instancer  cookieydl	info_dictr   s               r.   rp  (TiktokPostsExtractor._extract_posts_ytdlk  s   	''H(=>F (,'+
	
 (,}}'+}}+/<<'7'*4::	
	 ==!%!2!26!:Ig00)0 <<&00;;J,,6" ' c4433LAr4!I "+9!57!5 %L**3/2!57 ]9 [) 	HHNN6"335HHs#I		D7 ]s<   %E 3+F1!F,?F1F)AF$F)$F),F11
F?c                    U R                  S5      =(       d    SU l        U R                  S;  a  SU l        U R                  X5      nU R                  S:X  a  U R                  XU R                  5      $ U R
                  (       d8  U R                  R                  SU5        U R                  XU R                  5      $  U R                  XU R                  5      nU(       a  U$  U R                  R                  SU5        U R                  XU R                  5      $ ! [         a%  nU R                  R                  U5         S nANbS nAff = f)Nzorder-postsr?   )r?   ascr   popularz%s: no cookies have been provided so the order-posts option will not take effect. You must provide cookies in order to extract a profile's posts in non-descending orderz%s: failed to extract user posts using post/item_list (make sure you provide valid cookies). Attempting with legacy creator/item_list endpoint that does not support post ordering)r   
post_orderr   _extract_posts_api_legacyr"   ro  rj   r   _extract_posts_api_orderrl   rm   rn   )r+   r   r   r   r   r{   s         r.   rq  'TiktokPostsExtractor._extract_posts_api  s?   ++m4>??"GG$DO''? ??f$11d&:&:< < ))HH  11d&:&:< <	$00d&:&:<D 
 	M 		
 --$"6"68 	8  	$HHs##	$s   >$D 
E&EEc                    SnU R                   S;   a  SnOU R                   S;   a  SnUUSSS.n[        U5      nUR                  XU5      (       d  / $ UR                  XR                  U R
                  U R                  5      $ )	N0)r  r   2)r  115false)r   post_item_list_request_typecountneedPinnedItemIds)r  TiktokPostItemListRequestexecutegenerate_urlsr   r   r   )r+   r   r   r"   r  query_parametersr   s          r.   r  -TiktokPostsExtractor._extract_posts_api_order  s    &)#??00*-'__+*-'+F!(	
 ,O<t2BCCI$$[**djj%)ZZ1 	1r1   c                     USSS.n[        U5      nUR                  XU5        UR                  XR                  U R                  U R
                  5      $ )Nr  r  )r   rH   r  )TiktokCreatorItemListRequestr  r  r   r   r   )r+   r   r   r"   r  r   s         r.   r  .TiktokPostsExtractor._extract_posts_api_legacy  sT    

 /?+;<$$[**djj%)ZZ1 	1r1   )r  ro  N)rp   r1  r2  r3  rB  rc  rD  rE  rY   rp  rq  r  r  r:  r  r1   r.   r]  r]  J  s1    KY&G2G8&7P&8P1$	1r1   r]  c                   ,    \ rS rSrSr\S-   rSrS rSr	g)r^  i  rW  z/repostsz$https://www.tiktok.com/@USER/repostsc                    U R                   S   nU R                   SU 3nU R                  X!5      SSSS.n[        U R                  5      nUR                  XU5        UR                  X R                  U R                  U R                  5      $ Nr   r>  r  r  r  )r   r  r  r  )
r?  r9  r   TiktokRepostItemListRequestr"   r  r  r   r   r   r+   r   r   r  r   s        r.   rY   TiktokRepostsExtractor.posts  s    KKN	2i[1 ++KC+.!(	
 .d.B.BC+;<$$[**djj%)ZZ1 	1r1   r  N
rp   r1  r2  r3  rB  rc  rD  rE  rY   r:  r  r1   r.   r^  r^    s    K[(G4G1r1   r^  c                   ,    \ rS rSrSr\S-   rSrS rSr	g)r_  i  rX  z/storiesz$https://www.tiktok.com/@USER/storiesc                    U R                   S   nU R                   SU 3nU R                  X!5      SSS.n[        5       nUR	                  XU5        UR                  X R                  U R                  U R                  5      $ )Nr   r>  r  5)authorIdloadBackwardr  )	r?  r9  r   TiktokStoryItemListRequestr  r  r   r   r   r  s        r.   rY   TiktokStoriesExtractor.posts  s    KKN	2i[1 //G#

 -.+;<$$[**djj%)ZZ1 	1r1   r  Nr  r  r1   r.   r_  r_    s    K[(G4G1r1   r_  c                   ,    \ rS rSrSr\S-   rSrS rSr	g)r`  i  rY  z	/like[sd]z"https://www.tiktok.com/@USER/likedc                    U R                   S   nU R                   SU 3nU R                  X!5      SSSS.n[        U R                  5      nUR                  XU5        UR                  X R                  U R                  U R                  5      $ r  )
r?  r9  r   TiktokFavoriteItemListRequestr"   r  r  r   r   r   r  s        r.   rY   TiktokLikesExtractor.posts  s    KKN	2i[1 ++KC+.!(	
 00D0DE+;<$$[**djj%)ZZ1 	1r1   r  Nr  r  r1   r.   r`  r`    s    K\)G2G1r1   r`  c                   ,    \ rS rSrSr\S-   rSrS rSr	g)ra  i  rZ  z/savedz"https://www.tiktok.com/@USER/savedc                    U R                   S   nU R                   SU 3nU R                  X!5      SSSS.n[        U R                  5      nUR                  XU5        UR                  X R                  U R                  U R                  5      $ r  )
r?  r9  r   TiktokSavedPostItemListRequestr"   r  r  r   r   r   r  s        r.   rY   TiktokSavedExtractor.posts  s    KKN	2i[1 ++KC+.!(	
 11E1EF+;<$$[**djj%)ZZ1 	1r1   r  Nr  r  r1   r.   ra  ra    s    KY&G2G1r1   ra  c                   6    \ rS rSrSrSr\ S3rSrS r	S r
Srg	)
TiktokFollowingExtractori,  z9Extract all of the stories of all of the users you follow	followingz
/followingz https://www.tiktok.com/followingc                 2   SSS.n[        5       nUR                  X R                  U5      (       d&  U R                  R	                  SU R                  5        UR                  5       n[        U5      S:X  a&  U R                  R                  SU R                  5        0 n[        [        U5      S-
  S-  S-   5       GHK  nUS-   nX5S-  US-   n[        U5      S:X  a  U R                  US   S   5      (       a  M@  U R                  R                  S	US
R                  U VV	s/ s H  u  pU R                  U5      (       a  M  U	PM!     sn	n5      5        U VV	s/ s H.  u  pU R                  U5      (       a  M  U R                  X5      PM0     n
nn	SR                  U
5      SS.n[        5       nUR                  U SU 3U5        UR                  UR                  SU R                  U R                   U R"                  5      5        GMN     U$ s  sn	nf s  sn	nf )zMAttempt to extract all of the stories of all of the accounts
the user follows3r  )storyFeedScener  zN%s: could not extract follower list, make sure you are using logged-in cookiesr   z0%s: No followers with stories could be extractedr   
   z!TikTok user stories, batch %d: %sr   r   r  )	authorIdsstoryCallScenezBatch zhttps://www.tiktok.com/@_)TiktokStoryUserListRequestr  rz   rj   rn   r  rO  r   r    _is_current_userrk   r   r   TiktokStoryBatchItemListRequestrb   r   r   r   )r+   r  r   usersr  bbatch_number
user_batchuser_idr   
author_idss              r.   rY   TiktokFollowingExtractor.posts2  s   
 "
 -.tXX/?@@HHNN =>BhhH%%'u:?HH )*.((4 
 E
Q2-12Aq5LtLO4J :!#((Aq)9::HHMM=|))%/%3%/ 6JW7;7L7L)082 &1%/%3 45 7AA6@2g!%!6!6w!? H$11+G6@  A !XXj1"%  67GOODF<."9;KL NN7001L15TZZ15= >A 3H /%3As   "HHH9Hc                     U R                  5         SU R                  ;  a  gSU R                  S   ;  a  gU R                  S   S   U:H  $ )Nr9   Fuid)r   r   )r+   r  s     r.   r  )TiktokFollowingExtractor._is_current_usern  sU    DDF@@@??GG66v>uE 	r1   r  N)rp   r1  r2  r3  r4  rB  rC  rD  rE  rY   r  r:  r  r1   r.   r  r  ,  s&    CKz*G0G:xr1   r  c                        \ rS rSrS rS rSrg)TiktokPaginationCursorix  c                     g)ztMust return the page the cursor is currently pointing to.

Returns
-------
int
    The current value of the cursor.
r   r  r   s    r.   current_page#TiktokPaginationCursor.current_pagey  s     r1   c                     g)a?  Must progress the cursor to the next page.

Parameters
----------
data : dict
    The response of the most recent request.
query_parameters : dict
    All of the query parameters used for the most recent
    request.

Returns
-------
bool
    True if the cursor detects that we've reached the end, False
    otherwise.
Tr  r+   rr   r  s      r.   	next_page TiktokPaginationCursor.next_page  s    $ r1   r  N)rp   r1  r2  r3  r  r  r:  r  r1   r.   r  r  x  s    	r1   r  c                   F   ^  \ rS rSrSSSS.U 4S jjrS rS rS	 rS
rU =r	$ )TiktokTimeCursori  ThasMorecursorr   has_more_attributecursor_attributec                T   > [         TU ]  5         SU l        Xl        X l        X0l        g Nr   )super__init__r  r   has_more_key
cursor_key)r+   r   r  r  ro   s       r.   r  TiktokTimeCursor.__init__  s'     .*r1   c                     U R                   $ Nr  r   s    r.   r  TiktokTimeCursor.current_page      {{r1   c                    U R                   S:H  n[        UR                  U R                  S5      5      nU(       + nU(       dr  U R                  (       a(  X@R                   :  d  U(       a  U R                  U5      nOVU R                  (       d'  X@R                   :  d  U(       a  U R                  U5      nOU(       a  [        R                  " S5      eX@l         UR                  U R                  S5      (       + $ )Nr   zCould not extract next cursorF)	r  r   r]   r  r   fallback_cursorr
   r   r  )r+   rr   r  skip_fallback_logic
new_cursor	no_cursors         r.   r  TiktokTimeCursor.next_page  s    "kkQ.$//156
"N	" ||kk!9Y!11$7
\\zKK'?9!11$7
++,KLL 88D--u555r1   c                      [        US   S   S   5      S-  $ ! [         a    SU R                  (       a  SOS-  s $ f = f)NitemListr:      $r   )r   rl   r   r+   rr   s     r.   r   TiktokTimeCursor.fallback_cursor  sK    	@tJ'+L9:TAA 	@!4<<RQ??	@s    ">>)r  r  r  r   )
rp   r1  r2  r3  r  r  r  r  r:  __classcell__ro   s   @r.   r  r    s+    "&9"*+ +6 @ @r1   r  c                   (   ^  \ rS rSrU 4S jrSrU =r$ )TiktokForwardTimeCursori  c                     > [         TU ]  SS9  g )NFr   r  r  r+   ro   s    r.   r   TiktokForwardTimeCursor.__init__  s    'r1   r  rp   r1  r2  r3  r  r:  r   r  s   @r.   r  r    s    ( (r1   r  c                   (   ^  \ rS rSrU 4S jrSrU =r$ )TiktokBackwardTimeCursori  c                     > [         TU ]  SS9  g NTr   r  r  s    r.   r  !TiktokBackwardTimeCursor.__init__      &r1   r  r  r  s   @r.   r
  r
    s    ' 'r1   r
  c                   .   ^  \ rS rSrU 4S jrS rSrU =r$ )TiktokPopularTimeCursori  c                     > [         TU ]  SS9  g r  r  r  s    r.   r   TiktokPopularTimeCursor.__init__  r  r1   c                     g)Ni<r  r  s     r.   r  'TiktokPopularTimeCursor.fallback_cursor  s     r1   r  )rp   r1  r2  r3  r  r  r:  r   r  s   @r.   r  r    s    ' r1   r  c                   (   ^  \ rS rSrU 4S jrSrU =r$ )TiktokStoryTimeCursori  c                 $   > [         TU ]  SSSS9  g )NFHasMoreAfter	MaxCursorr  r  r  s    r.   r  TiktokStoryTimeCursor.__init__  s    >*5 	 	7r1   r  r  r  s   @r.   r  r    s    7 7r1   r  c                   4   ^  \ rS rSrU 4S jrS rS rSrU =r$ )TiktokLegacyTimeCursori  c                 n   > [         TU ]  5         [        [        R                  " 5       5      S-  U l        g )Nr  )r  r  r   r   r  r  s    r.   r  TiktokLegacyTimeCursor.__init__  s%    $))+&-r1   c                     U R                   $ r  r  r   s    r.   r  #TiktokLegacyTimeCursor.current_page  r  r1   c                 2   U R                   n [        US   S   S   5      S-  U l         U R                   (       a  X0R                   :X  a
  US-
  U l         UR                  S5      nU R                   S:  =(       d    U(       + $ ! [         a
    SU l          Nkf = f)	Nr  r  r:   r  r   r  hasMorePreviousl   4<H[)r  r   rl   r]   )r+   rr   r  
old_cursorhas_more_previouss        r.   r   TiktokLegacyTimeCursor.next_page  s    [[
	d:.r2<@ADHDK {{jKK7 %~5DK !HH%67{{]*C2C.CC  	DK	s   B BBr  )	rp   r1  r2  r3  r  r  r  r:  r   r  s   @r.   r  r    s    .D Dr1   r  c                   @   ^  \ rS rSrSS\4U 4S jjjrS rS rSrU =r	$ )TiktokItemCursori  list_keyc                 <   > [         TU ]  5         SU l        Xl        g r  )r  r  r  r(  )r+   r(  ro   s     r.   r  TiktokItemCursor.__init__  s     r1   c                     U R                   $ r  r  r   s    r.   r  TiktokItemCursor.current_page  r  r1   c                     U =R                   [        UR                  U R                  S5      5      -  sl         SU;   a
  US   (       + $ UR                  SS5      (       + $ )Nr  r  r  F)r  rO  r]   r(  r  s      r.   r  TiktokItemCursor.next_page  sO    
 	s488DMM2677I&&88NE222r1   )r  r(  )r  )
rp   r1  r2  r3  r&   r  r  r  r:  r   r  s   @r.   r'  r'    s#    ! ! !
3 3r1   r'  c                   V    \ rS rSrS rS rS rS rS rS r	S r
S	 rS
 rS rS rSrg)TiktokPaginationRequesti  c                 >    Xl         U R                  5         0 U l        g r  )endpoint_regenerate_device_idr|   )r+   r2  s     r.   r   TiktokPaginationRequest.__init__  s     ""$
r1   c           
      F   U R                  U5        0 U l        U R                  U5      nU(       a  U" 5       OSn[        R                  " SS9 GH  n[        U R                  5      nUR                  R                  SUU R                  XgUS:X  a  SOS5        Sn  U R                  UUU5      u  pU R                  U	5      nU R                  X[        U R                  R                  5       5      [        UR                  5       5      5        U R                  R                  U5        U(       a6  UR                  U	U
5      nU R!                  X5      nU(       d  U(       a    gGM    g   g! ["         a  nXR$                  :  aH  UR                  R'                  S	X R                  U5        UR                  R)                  U5         SnA  g
US-  nUR                  R+                  S	X R                  U5        UR-                  UR.                  S5         SnAOSnAff = fGM  )a  Performs requests until all pages have been retrieved.

The items retrieved from this request are stored in self.items.
Each call to execute() will clear the previous value of
self.items.

Usually extractors want a simple list of URLs. For this, each
request subtype is to implement generate_urls().

Parameters
----------
extractor : TiktokExtractor
    The TikTok extractor performing the request.
url : str
    The URL associated with this request for logging purposes.
query_parameters : dict[str, str]
    The query parameters to apply to this request.

Returns
-------
bool
    True if the request was performed successfully and all items
    were retrieved, False if no items or only some items could
    be retrieved.
Nr   )startz%%s: retrieving %s page %d (%d item%s)r   sr   Tz!%s: failed to retrieve %s page %dFr   )validate_query_parametersr|   cursor_type	itertoolsr  rO  rj   rk   r2  _request_dataextract_items_detect_duplicate_pagesr'   keysrb   r  
exit_earlyrl   r   rn   rm   r   r   r   )r+   	extractorrz   r  r9  r  page
item_countr   rr   final_parametersincoming_itemsfinal_page_reachedr?  r{   s                  r.   r  TiktokPaginationRequest.execute  s   6 	&&'78
&&'78"-4OO!,DTZZJMMF#}}d%/1_r#? EA-1-?-?!(.*D
 &*%7%7%=N0014TZZ__5F1G14^5H5H5J1KM JJ%%n5-3-=-=d>N.P*%)__Y%D
%);#'  $9 -: ! 	A 2 22!++ -125}}dL!//4$QJEMM))*M*-}}dDOOI$6$6@@	A/ s!   CE**
H4AHAHHc                     SU;   d   e[        US   5      [        L d   eUS   R                  5       (       d   eUS   S:w  d   eg)a  Used to validate the given parameters for this type of
pagination request.

For developer purposes only. You should call
super().validate_query_parameters() for most requests as they
will usually have a count parameter.

Parameters
----------
query_parameters : dict[str, str]
    The query parameters to validate.

Raises
-------
AssertionError
    If mandatory query parameters are not given, or they are
    given in the wrong format.
r  r  N)rH   r&   isdigitr+   r  s     r.   r8  1TiktokPaginationRequest.validate_query_parametersR  sY    ( ****$W-.#555(002222(C///r1   c                     g)a  Used to determine which type of cursor to use for this
request, if any.

Parameters
----------
query_parameters : dict[str, str]
    The query parameters given to the execute() call.

Returns
-------
Type[TiktokPaginationCursor] | None
    The type of cursor to use, if any.
Nr  rI  s     r.   r9  #TiktokPaginationRequest.cursor_typek  s     r1   c                     0 $ )a  Used to extract data from the response of a request.

Parameters
----------
data : dict
    The data given by TikTok.

Returns
-------
dict
    Each item from the response data, keyed on a unique ID.

Raises
------
Exception
    If items could not be extracted.
r  r  s     r.   r<  %TiktokPaginationRequest.extract_items|  s	    & 	r1   c                     g)ar  Used to determine if we should exit early from the request.

You have access to the items extracted so far (self.items).

Parameters
----------
extractor : TiktokExtractor
    The extractor making the requests.
url : str
    The URL associated with the executing request for logging
    purposes.

Returns
-------
bool
    True if we should exit early, False otherwise.
Fr  r+   r@  rz   s      r.   r?  "TiktokPaginationRequest.exit_early  s    & r1   c                     / $ )a  Used to convert the items retrieved from the request into a
list of URLs.

Returns
-------
dict
    Ideally one URL for each item, that points to a video detail
    object, although subclasses are permitted to return a list
    or dict of any format they wish.
r  r   s    r.   r  %TiktokPaginationRequest.generate_urls  s	     	r1   c                 N    [        [        R                  " SS5      5      U l        g )Nl     *{Y2$ l   B2n?- )r&   randomrandint	device_idr   s    r.   r3  -TiktokPaginationRequest._regenerate_device_id  s!    V^^%'@B Cr1   c                 
   Sn  U R                  UU5      u  pVUR                  U5      n[        R                  " UR                  5      U4$ ! [
         a*    US:X  a  e UR                  R                  S5        US-  n Of = fM  )Nr   r   z5Could not decode response for this page, trying again)_build_api_request_urlr   r   r   r   r   rj   r   )r+   r@  r  r  ry  rz   rC  r   s           r.   r;  %TiktokPaginationRequest._request_data  s     (,(C(C$)% %,,S168HII a<%%K 1 s   AA 1B ?B c                    0 SS_SS_SS_SS_S	S
_SS_SS_SS_SS_SS_SU R                   _SS_SS_SS_SS_SS_SS_SSSSS S!S"S#S$SR                  [        R                  " S%S&S'95      -   SS(.
EnU(       a%  [	        [        UR                  5       5      5      US)'   UR                  5        H
  u  pEU X4'   M     [        R                  " U5      nS*U R                   S+U 3U4$ ),Naid1988app_languageenapp_name
tiktok_webbrowser_languagezen-USbrowser_nameMozillabrowser_onlinetruebrowser_platformWin32browser_versionz5.0 (Windows)channelcookie_enabledrW  device_platformweb_pcfocus_state	from_pager9   history_lenr  is_fullscreenr  is_page_visiblewindowsr   US10801920UTCverify_0123456789abcdef   )k)
languageospriority_regionrefererregionscreen_heightscreen_widthtz_nameverifyFpwebcast_languager  zhttps://www.tiktok.com/api/z/?)rW  r   rU  choicesr&   r   r  r|   r   build_queryr2  )r+   r  extra_parametersr  r   value	query_strs          r.   rZ  .TiktokPaginationRequest._build_api_request_url  s   
6
D
 
 	

 I
 f
 
 
 |
 f
 
 x
 6
 
 3
  W!
" v#
$ !#"!BGGFNN"a-) %* * $9
< ),S1D1D1F-G)HX&*002JC',g! 3$$%56	-dmm_BykJ " 	"r1   c                     U(       aH  XC:X  aB  U R                  5         UR                  R                  SU5        [        R                  " S5      eg g )NzU%s: TikTok API keeps sending the same page. Taking measures to avoid an infinite loopz&TikTok API keeps sending the same page)r3  rj   r   r
   r   )r+   r@  rz   seen_idsincoming_idss        r.   r=  /TiktokPaginationRequest._detect_duplicate_pages  sQ    L4 &&(MM!! #)*-/ ++8: : 5<r1   )rW  r2  r|   N)rp   r1  r2  r3  r  r  r8  r9  r<  r?  r  r3  r;  rZ  r=  r:  r  r1   r.   r0  r0    s>    
EAN02"**C(&"P	:r1   r0  c                   @   ^  \ rS rSrU 4S jrS rS rS rS rSr	U =r
$ )TiktokItemListRequesti   c                 J   > [         TU ]  U5        X l        X0l        SU l        g )NF)r  r  type_of_itemsr"   exit_early_due_to_no_items)r+   r2  r  r"   ro   s       r.   r  TiktokItemListRequest.__init__  s$    "*.*/'r1   c                     SU;  a0  UR                  SUR                  SS5      5      (       d  SU l        0 $ US    Vs0 s H  o"S   U_M
     sn$ s  snf )Nr  r"  r  FTr@   )r]   r  r+   rr   items      r.   r<  #TiktokItemListRequest.extract_items  sZ    T!88-txx	5/IJJ26/I-1*-=>-=TT
D -=>>>s   Ac                     U R                   (       a'  UR                  R                  SX R                  5        gU R                  (       d  g[        U R                  5      [        S U R                   5       5      S-
  :  $ )Nz*%s: could not extract any %s for this userTFc              3   8   #    U  H  oR                   v   M     g 7fr  )stop).0rs     r.   	<genexpr>3TiktokItemListRequest.exit_early.<locals>.<genexpr>  s     $J5IVV5Is   r   )r  rj   r   r  r"   rO  r|   maxrP  s      r.   r?   TiktokItemListRequest.exit_early  sc    **MM!!"N"%'9'9;## 4::$JT5I5I$J!JQ!NNNr1   c                 p   0 n[        U R                  R                  5       5       Hu  u  pgU R                  U R                  R	                  U5      US-   UX45      (       d  M<   SU R                  U   S   S    SU 3nU R                  R	                  U5      XX'   Mw     U$ ! [
         a
    U SU 3n N6f = f)Nr   https://www.tiktok.com/@r7   r8   r   )r`   r|   r>  _matches_filtersr]   r   )	r+   r   r   r   r   r   indexr@   rz   s	            r.   r  #TiktokItemListRequest.generate_urls  s    "4::??#45IE(();UQY).7 720B1*=>gbTK
 

r*DI 6 	  2$WRD12s   #B!!B54B5c                     U R                   (       a&  SnU R                    H  nX';   d  M
  Sn  O   U(       d  gU(       d  gSU;   nU(       d  U(       d  U(       a  gU(       d  U(       d  gg)NFTr<   )r"   )	r+   r  r  r   r   r   range_matchr    is_image_posts	            r.   r  &TiktokItemListRequest._matches_filters,  s^     K-->"&K .  #t+U}]r1   )r  r"   r  )rp   r1  r2  r3  r  r<  r?  r  r  r:  r   r  s   @r.   r  r     s"    0?
O$ r1   r  c                   >   ^  \ rS rSrSrU 4S jrU 4S jrS rSrU =r	$ )r  iC  zhA less flaky version of the post/item_list endpoint that doesn't
support latest/popular/oldest ordering.c                 (   > [         TU ]  SSU5        g )Nzcreator/item_listrY   r  r+   r"   ro   s     r.   r  %TiktokCreatorItemListRequest.__init__G  s    ,gGr1   c                 n   > [         TU ]  U5        SU;   d   eSU;   d   eUS   S:X  d  US   S:X  d   eg g )Nr   rH   r  r  r  r8  r+   r  ro   s     r.   r8  6TiktokCreatorItemListRequest.validate_query_parametersJ  s]    )*:;++++))))
  '3.V$+	, ,+ /r1   c                     [         $ r  )r  rI  s     r.   r9  (TiktokCreatorItemListRequest.cursor_typeU  s    %%r1   r  
rp   r1  r2  r3  r4  r  r8  r9  r:  r   r  s   @r.   r  r  C  s    /H	,& &r1   r  c                   >   ^  \ rS rSrSrU 4S jrU 4S jrS rSrU =r	$ )r  iY  a\  Retrieves posts in latest/popular/oldest ordering.

Very often, this request will just return an empty response, making
it quite flaky, but the next attempt to make the request usually
does return a response. For this reason creator/item_list was kept
as a backup, though it doesn't seem to support ordering.

It also doesn't work without cookies.
c                 (   > [         TU ]  SSU5        g )Nzpost/item_listrY   r  r  s     r.   r  "TiktokPostItemListRequest.__init__d  s    )7ODr1   c                    > [         TU ]  U5        SU;   d   eSU;   d   eUS   S;   d   eSU;   d   eUS   S;   d   eg )Nr   r  )r  r  r  r  r  r  r  s     r.   r8  3TiktokPostItemListRequest.validate_query_parametersg  sq    )*:;++++,0@@@@
   => 	 "&6666   34	AAAr1   c                 H    US   nUS:X  a  [         $ US:X  a  [        $ [        $ )Nr  r  r  )r  r  r
  )r+   r  request_types      r.   r9  %TiktokPostItemListRequest.cursor_typey  s/    '(EF3**S **++r1   r  r  r  s   @r.   r  r  Y  s    EB$, ,r1   r  c                   >   ^  \ rS rSrSrU 4S jrU 4S jrS rSrU =r	$ )r  i  zlRetrieves a user's liked posts.

Appears to only support descending order, but it can work without
cookies.
c                 (   > [         TU ]  SSU5        g )Nzfavorite/item_listzliked postsr  r  s     r.   r  &TiktokFavoriteItemListRequest.__init__  s    -}oNr1   c                    > [         TU ]  U5        SU;   d   eSU;   d   eUS   S:X  d   eSU;   d   eUS   S;   d   eg Nr   r  r  r  r  r  r  s     r.   r8  7TiktokFavoriteItemListRequest.validate_query_parameters  f    )*:;++++,0@@@@ =>#EEE"&6666 34	AAAr1   c                     [         $ r  r  rI  s     r.   r9  )TiktokFavoriteItemListRequest.cursor_type      &&r1   r  r  r  s   @r.   r  r    s    OB' 'r1   r  c                   >   ^  \ rS rSrSrU 4S jrU 4S jrS rSrU =r	$ )r  i  zhRetrieves a user's reposts.

Appears to only support descending order, but it can work without
cookies.
c                 (   > [         TU ]  SSU5        g )Nzrepost/item_listrW  r  r  s     r.   r  $TiktokRepostItemListRequest.__init__  s    +YHr1   c                    > [         TU ]  U5        SU;   d   eSU;   d   eUS   S:X  d   eSU;   d   eUS   S;   d   eg r  r  r  s     r.   r8  5TiktokRepostItemListRequest.validate_query_parameters  r  r1   c                     [         $ r  )r'  rI  s     r.   r9  'TiktokRepostItemListRequest.cursor_type  s    r1   r  r  r  s   @r.   r  r    s    IB   r1   r  c                   >   ^  \ rS rSrSrU 4S jrU 4S jrS rSrU =r	$ )r  i  zlRetrieves a user's saved posts.

Appears to only support descending order, but it can work without
cookies.
c                 (   > [         TU ]  SSU5        g )Nzuser/collect/item_listzsaved postsr  r  s     r.   r  'TiktokSavedPostItemListRequest.__init__  s    1=(	*r1   c                    > [         TU ]  U5        SU;   d   eSU;   d   eUS   S:X  d   eSU;   d   eUS   S;   d   eg r  r  r  s     r.   r8  8TiktokSavedPostItemListRequest.validate_query_parameters  r  r1   c                     [         $ r  r  rI  s     r.   r9  *TiktokSavedPostItemListRequest.cursor_type  r  r1   r  r  r  s   @r.   r  r    s    *B' 'r1   r  c                   :   ^  \ rS rSrU 4S jrU 4S jrS rSrU =r$ )r  i  c                 (   > [         TU ]  SSS 5        g )Nzstory/item_listrX  r  r  s    r.   r  #TiktokStoryItemListRequest.__init__  s    *It<r1   c                 Z   > [         TU ]  U5        SU;   d   eSU;   d   eUS   S;   d   eg )Nr  r  )rg  r  r  r  s     r.   r8  4TiktokStoryItemListRequest.validate_query_parameters  sC    )*:;----!1111/3DDDDr1   c                     [         $ r  )r  rI  s     r.   r9  &TiktokStoryItemListRequest.cursor_type  s    $$r1   r  )	rp   r1  r2  r3  r  r8  r9  r:  r   r  s   @r.   r  r    s    =E% %r1   r  c                   :   ^  \ rS rSrU 4S jrS rU 4S jrSrU =r$ )r  i  c                 (   > [         TU ]  SSS 5        g )Nzstory/batch/item_listrX  r  r  s    r.   r  (TiktokStoryBatchItemListRequest.__init__  s    0)TBr1   c                     SU;   d   eUS   R                  S5      S-   nUS:  a  US::  d   eSU;   d   eUS   S:X  d   eg )Nr  r   r   r  r  r  )r  )r+   r  author_counts      r.   r8  9TiktokStoryBatchItemListRequest.validate_query_parameters  sg     .... (4::3?!Cq \R%777#3333 01S888r1   c                    > 0 n[        UR                  S5      5      [        La	  SU l        U$ US    H!  nUR	                  [
        TU ]  U5      5        M#     U$ )NbatchStoryItemListsT)rH   r]   r   r  rb   r  r<  )r+   rr   r|   userStoriesro   s       r.   r<  -TiktokStoryBatchItemListRequest.extract_items  sY     ./0<.2D+L 56KLL.{;< 7r1   )r  )	rp   r1  r2  r3  r  r8  r<  r:  r   r  s   @r.   r  r    s    C
9 r1   r  c                   L   ^  \ rS rSrU 4S jrU 4S jrS rS rS rS r	Sr
U =r$ )	r  i  c                 2   > [         TU ]  S5        SU l        g )Nzstory/user_listF)r  r  exit_early_due_to_no_cookiesr  s    r.   r  #TiktokStoryUserListRequest.__init__  s    *+,1)r1   c                 J   > [         TU ]  U5        SU;   d   eUS   S:X  d   eg )Nr  r  r  r  s     r.   r8  4TiktokStoryUserListRequest.validate_query_parameters  s4    )*:;#3333 01S888r1   c                 8    [         R                  " [        S5      $ )N
storyUsers)	functoolspartialr'  rI  s     r.   r9  &TiktokStoryUserListRequest.cursor_type  s      !1<@@r1   c                 p    SU;  a	  SU l         0 $ US    Vs0 s H  nUS   S   US   S   _M     sn$ s  snf )Nr  Tr9   r@   r8   r  r  s      r.   r<  (TiktokStoryUserListRequest.extract_items  sX    t#04D-I .0.D VT"DL$<<.0 	0 0s   3c                 r    U R                   (       a  UR                  R                  S5        U R                   $ )NzFYou must provide cookies to extract the stories of your following list)r  rj   rn   rP  s      r.   r?  %TiktokStoryUserListRequest.exit_early  s0    ,,MM !A B000r1   c                 v    U R                   R                  5        VVs/ s H  u  pUSU 34PM     snn$ s  snnf )Nr  )r|   )r+   r@   rv  s      r.   r  (TiktokStoryUserListRequest.generate_urls  sC     $

 0 0 24 2HB /v67 24 	4 4s   5r  )rp   r1  r2  r3  r  r8  r9  r<  r?  r  r:  r   r  s   @r.   r  r    s'    29A014 4r1   r  )/r4  commonr   r   r   r   r   r   r	   r
   r  r:  r   r   rU  r   rC  rc  r   r<  rG  rT  r\  r]  r^  r_  r`  ra  r  r  r  r  r
  r  r  r  r'  r0  r  r  r  r  r  r  r  r  r  r  r1   r.   <module>r     s   - 0 0 * *      7o-di dN	/ 	9O 9* (O  ".O .6L1? L1^1_ 1*1_ 1(1? 1*1? 1*I IX B"@- "@J(. (
'/ '
. 7, 7D3 D03- 3(x: x:v@3 @F&#8 &,', 5 ',T'$9 ', "7  ,'%: '.%!6 %&; >4!8 4r1   