
    iaH                         S r SSKJrJr  SSKJrJrJrJr  SSK	J
r
  SSKrSSKr " S S	\5      r " S
 S\5      r " S S\5      r " S S\5      r " S S\5      rg)z'Extractors for https://www.patreon.com/   )	ExtractorMessage   )textutildt	exception)memcache    Nc                       \ 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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\" SS9S 5       rS r S  r!S! r"S" r#S# r$S$ r%S% r&S&r'g')(PatreonExtractor   z!Base class for patreon extractorspatreonzhttps://www.patreon.comz.patreon.com)
{category}{creator[full_name]}z"{id}_{title}_{num:>02}.{extension}z
{id}_{num}z4Patreon/126.9.0.15 (Android; Android 14; Scale/2.10)Tc                 &   U R                  SSS9(       a  SU l        O>SU l        U R                  (       a&  S[        l        U R                  R                  S5        U R                  S5      =n(       a  Xl        U R                  U l	        S U l
        g )N)
session_idT)
subdomainsFzno 'session_id' cookie setzformat-images)cookies_check
_logged_in_warningr   logwarningconfig_images_fmt_images_url_fmt_images_url_cursor)selfformat_imagess     I/app/mltbenv/lib/python3.13/site-packages/gallery_dl/extractor/patreon.py_initPatreonExtractor._init   su    o$?"DO#DO}},1 )  !=> KK88=8,#33D    c              #   T  ^	#    U R                  U R                  S5      5      nU R                  5        GHn  m	[        R                  ST	4v   T	R                  SS5      (       d!  U R                  R                  ST	S   5        MQ  ST	S'   [        5       n[        R                  R                  U	4S	 jU 5       5       H  u  p4pVU R                  U5      nXr;  d  U(       d  UR                  U5        UT	S
'   UT	S'   UT	S'   T	S==   S-  ss'   [        R                  " UT	5        [        R                   " U5      S:X  a,  SU-   nSU R"                  S-   0nST	S'   UT	S'   SU0T	S'   ST	S'   [        R$                  UT	4v   M  U R                  R'                  SXWU5        M     GMq     g 7f)Nfiles current_user_can_viewTzNot allowed to view post %sidr   numc              3   2   >#    U  H  o" T5      v   M     g 7fN ).0gposts     r!   	<genexpr>)PatreonExtractor.items.<locals>.<genexpr>8   s      G1%/AdGGZs   hashtypefiler   m3u8zytdl:referer/hls_ytdl_manifest_ytdl_manifest_headershttp_headers_ytdl_extramp4	extensionzskipping %s (%s %s))_build_file_generatorsr   postsr   	Directorygetr   r   set	itertoolschainfrom_iterable	_filehashaddr   nameext_from_urlext_from_urlrootUrldebug)
r   
generatorshasheskindr5   urlnamefhashheadersr0   s
            @r!   itemsPatreonExtractor.items,   s    00W1EF
JJLD##R--883T::  !>T
KDKUF)2)F)F G1%/G1 *1%Cs+&eJJu%#(DL#'DL#'DLK1$K))$5((-7%m#,dii#o">16-.9@56/=w.G]+,1[)!++sD00HHNN#8#dK'*1 !s   F%F(c                 t    U R                   (       a'  U R                  R                  SU R                   5        g g )NzDUse '-o cursor=%s' to continue downloading from the current position)r   r   infor   s    r!   finalizePatreonExtractor.finalizeM   s+    <<HHMM 67;||E r$   c                     UR                  S5      =n(       aV  US   nUR                  S5      =n(       d3  UR                  S5      (       a  UnOU R                  U5      =(       d    UnSX#U44$ g)N	post_filerR   rS   zhttps://stream.mux.com/postfiler-   )rC   
startswith	_filename)r   r0   r_   rR   rS   s        r!   	_postfilePatreonExtractor._postfileR   sn    xx,,8,5/C$LL00D0>>";<<D>>#.5#D577r$   c              #      #    UR                  S5      =n(       a]  U HV  nU R                  U5      =n(       d  M  UR                  S5      =(       d    U R                  U5      =(       d    UnSX4U4v   MX     g g 7f)Nimages	file_nameimage)rC   r   ra   )r   r0   re   rg   rR   rS   s         r!   _imagesPatreonExtractor._images]   sl     XXh''6'**51131 99[1OT^^C5HOCD!5t33   (s
   4A9?A9c                 $    UR                  S5      $ )Ndownload_urlrC   r   rg   s     r!   r   PatreonExtractor._images_urld   s    yy((r$   c                 j     US   U R                      $ ! [         a    UR                  S5      s $ f = f)N
image_urlsrk   )r   	ExceptionrC   rm   s     r!   r    PatreonExtractor._images_url_fmtg   s;    	-&t'7'788 	-99^,,	-s    22c                     UR                  S5      =n(       aP  UR                  S5      =n(       a8  UR                  S5      =(       d    U R                  U5      =(       d    UnSX#U44$ g)Nrg   	large_urlrf   image_larger-   )rC   ra   )r   r0   rg   rR   rS   s        r!   _image_largePatreonExtractor._image_largem   s^    HHW%%5%ii,,s,yy-K1DK&D9;;r$   c              #   $  #    UR                  S5      =(       d    S H)  nU R                  US   SS9=n(       d  M  SX#US   4v   M+     UR                  S5      =(       d    S H'  nUR                  S	5      =n(       d  M  SX#US
   4v   M)     g 7f)Nattachmentsr-   rR   Ffatal
attachmentrS   attachments_mediark   rf   )rC   request_location)r   r0   r|   rR   s       r!   _attachmentsPatreonExtractor._attachmentst   s     ((=17R7J++Ju,=U+KKsK"JZ5GGG 8 ((#67=2=J nn^44s4"JZ5LLL >s   6BABBc              #      #    UR                  S5      =n(       a`  [        R                  " USS5       HC  n[        R                  " USS5      =n(       d  M$  SS X@R	                  U5      =(       d    U4v   ME     g g 7f)Ncontentz<img data-media-id=">zsrc="")rC   r   extract_iterextrra   )r   r0   r   imgrR   s        r!   _contentPatreonExtractor._content}   sn     hhy))7)((3S:))C#6636#T3s0C0JsJJ: *s   AA<%A<c                     g)z Return all relevant post objectsNr-   rZ   s    r!   rA   PatreonExtractor.posts   s    r$   c              #   j  #    SS0nU(       a  U R                  U5        [        R                  " U5      nU R                  XS9nSU;   a3  U R	                  US   5      nUS    H  nU R                  XT5      v   M     SU;  a  OUS   R                  S5      nU(       a  M  U R                  S5        g 7f)	NzContent-Typezapplication/vnd.api+json)rU   includeddatalinksnextr'   )_update_cursorr   ensure_http_schemerequest_json
_transform_processrC   )r   rR   rU   rA   r   r0   s         r!   _paginationPatreonExtractor._pagination   s     6
 $))#.C%%c%;EU"??5+<=!&MD--77 * e#.$$V,C c 	Bs   BB3!B3c                 r    U R                  SS5      =n(       a	  USL a  S$ U$ [        R                  U l        g)NcursorTr'   )r   r   identityr   )r   r   s     r!   _init_cursorPatreonExtractor._init_cursor   s8    [[40060423V3"mmr$   c                     [         R                  " UR                  S5      S   5      nUR                  S5      =U l        nU(       a  U R
                  R                  SU5        U$ )N?r   zpage[cursor]z
Cursor: %s)r   parse_query	partitionrC   r   r   rN   )r   rR   paramsr   s       r!   r   PatreonExtractor._update_cursor   sO    !!#--"4Q"78 &

> ::vHHNN<0r$   c                 f   US   n[         R                  " US   5      US'   US   nU R                  XS5      US'   U R                  XS5      US'   U R                  XS5      US'   U R                  US   5      US'    US	   US	   S
   S      US	'   UR                  S5      nU(       a4  US
    Vs/ s H#  nUS   S:X  d  M  US   R                  SS5      PM%     snO/ US'   US   nU R                  US   S   5      =(       d    US   US
   S      US'   U$ ! [         a    SUS	'    Nf = fs  snf )z"Process and extend a 'post' object
attributesr)   relationshipsre   ry   r}   published_atdatecampaignr   Nuser_defined_tagsr4   post_tagzuser_defined;r'   tagsuserr   relatedcreator)r   	parse_int_filesparse_datetime_isorq   rC   replace_user)r   r0   r   attrr   r   tagr   s           r!   r   PatreonExtractor._process   s   L!^^DJ/T
_-H&X"kkM+]$(KK/%1 !..tN/CDV	$ ( 4 -j 9& A$ G!ID
   !45
  F|
#6{j( 3CIor2#
 	 	V V$JJtG}Y/0 1VT&\$/0 	Y   	$#D	$
s   >D 1D.D.D+*D+c                 l    [         R                  " [        5      nU H  nUS   X#S      US   '   M     U$ )z4Transform 'included' into an easier to handle formatr   r4   r)   )collectionsdefaultdictdict)r   r   resultincs       r!   r   PatreonExtractor._transform   s;    ((.C-0->Fv;D	* r$   c                     US   R                  U5      nU(       a7  UR                  S5      (       a!  US    Vs/ s H  nX%S      US      PM     sn$ / $ s  snf )zBuild a list of filesr   r   r4   r)   rl   )r   r0   r   keyr&   r5   s         r!   r   PatreonExtractor._files   sj    _%))#.UYYv&& "&M)D f&tDz2)  		s   Ar   )keyargc                     U R                  USS9nUR                  S:  a  gUR                  5       S   nUS   nUS   US'   U R                  US   5      US	'   U$ )
zFetch user informationFrz   i  Nr   r   r)   createdr   )requeststatus_codejsonr   )r   rR   responser   r   s        r!   r   PatreonExtractor._user   sk     <<5<13&}}v&L!$ZT
..tI?Vr$   c                     U R                    SU 3nU R                  U5      nUS   nUS   nUS   US'   U R                  US   5      US'   U$ )Nz/api/collection/r   r   r)   
created_atr   )rL   r   r   )r   collection_idrR   r   collr   s         r!   _collectionPatreonExtractor._collection   se    +M?;  %F|L!$ZT
..tL/ABVr$   c                     U R                  USSS9nUR                  R                  S5      n[        R                  " USS5      $ )z7Fetch filename from an URL's Content-Disposition headerHEADF)methodr{   zContent-Dispositionz
filename="r   )r   rU   rC   r   r   )r   rR   r   cds       r!   ra   PatreonExtractor._filename   s@    <<F%<@!!"78yy\3//r$   c                     UR                  S5      S   R                  S5      nUR                  5         U H  n[        U5      S:X  d  M  Us  $    g)z$Extract MD5 hash from a download URLr   r   r8       r'   )r   splitreverselen)r   rR   partsparts       r!   rH   PatreonExtractor._filehash   sH    c"1%++C0D4yB  r$   c                 V    SU SU R                  5        U U R                  U5       S3$ )Nzhttps://www.patreon.com/api/a  ?include=campaign,access_rules,attachments,attachments_media,audio,images,media,native_video_insights,poll.choices,poll.current_user_responses.user,poll.current_user_responses.choice,poll.current_user_responses.poll,user,user_defined_tags,ti_checks&fields[campaign]=currency,show_audio_post_download_links,avatar_photo_url,avatar_photo_image_urls,earnings_visibility,is_nsfw,is_monthly,name,url&fields[post]=change_visibility_at,comment_count,commenter_count,content,current_user_can_comment,current_user_can_delete,current_user_can_view,current_user_has_liked,embed,image,insights_last_updated_at,is_paid,like_count,meta_image_url,min_cents_pledged_to_view,post_file,post_metadata,published_at,patreon_url,post_type,pledge_url,preview_asset_type,thumbnail,thumbnail_url,teaser_text,title,upgrade_url,url,was_posted_by_campaign_owner,has_ti_violation,moderation_status,post_level_suspension_removal_date,pls_one_liners_by_category,video_preview,view_count&fields[post_tag]=tag_type,value&fields[user]=image_url,full_name,url&fields[access_rule]=access_rule_type,amount_cents&fields[media]=id,image_urls,download_url,metadata,file_name&fields[native_video_insights]=average_view_duration,average_view_pct,has_preview,id,last_updated_at,num_views,preview_views,video_duration&page[cursor]=z&json-api-version=1.0)r   _order)r   endpointsortquerys       r!   
_build_urlPatreonExtractor._build_url  s@    *8*< "..01gdkk$'(#G#$%	
r$   c                     U R                  S5      =n(       a  US;   a  SnSU-   $ US;   a  SnSU-   $ U(       a  SU-   $ S$ )Norder-posts>   ddesc-published_at>   arascr   r   &sort=r'   r   r   r   orders      r!   r   PatreonExtractor._order)  s\    KK..5.%' e## 66&e##"&x$.B.r$   c                 n   Uc9  U R                   U R                  U R                  U R                  U R                  4$ U R                   U R                  U R                  U R                  U R                  S.n[        U[        5      (       a  UR                  S5      nU Vs/ s H  o2U   PM	     sn$ s  snf )N)re   ru   ry   r_   r   ,)rh   rv   r   rb   r   
isinstancestrr   )r   	filetypesgenmapfts       r!   r@   'PatreonExtractor._build_file_generators2  s    LL$"3"3%%t~~t}}F F  <<,,,,>>==
 i%%!,I%./Yrr
Y///s   !B2c                     U R                  U5      nUS   S   S   nUR                  S5      =(       d    US   $ ! [         a;  nU R                  R	                  SUR
                  R                  U5         S nAOS nAff = f[        R                  " USS5      nU(       a  [        R                  " US	-   5      $ [        R                  " US
S5      nU(       a  [        R                  " US	-   5      $ [        R                  " USS5      =n(       a  [        R                  " US	-   5      $ [        R                  " USS5      =n(       a.   [        R                  " SU S	35      S   $ ! [         a     Of = f[        R                  " S5      e)Nprops	pagePropsbootstrapEnvelopepageBootstrap	bootstrapz%s: %szwindow.patreon = {"bootstrap":z},"apiServer"}z*window.patreon = wrapInProxy({"bootstrap":zwindow.patreon.bootstrap,z});zwindow.patreon = {z};
{z Unable to extract bootstrap data)_extract_nextdatarC   rq   r   rN   	__class____name__r   r   r   
json_loadsr	   AbortExtraction)r   pager   envexcr   s         r!   _extract_bootstrap#PatreonExtractor._extract_bootstrapA  sb   	B))$/Dw-,-@AC77?+?s;/?? 	BHHNN8S]]%;%;SAA	B II2OE	??9s?33II8	 ??9s?33		$(CUKK9K??9s?3399T#7@@4@D6}5kBB  ''(JKKs'   8; 
B 1A;;B E( (
E54E5)r   r   r   r   r   N)(r  
__module____qualname____firstlineno____doc__categoryrL   cookies_domaindirectory_fmtfilename_fmtarchive_fmt	useragentr   r"   rV   r[   rb   rh   r   r   rv   r   r   rA   r   r   r   r   r   r   r
   r   r   ra   rH   r   r   r@   r  __static_attributes__r-   r$   r!   r   r      s    +H$D#N:M7LKFIHLBE
	4)-MK/ * D Q	 	0&
P/0Lr$   r   c                   4    \ rS rSrSrSrSrSrSrS r	S r
S	rg
)PatreonCollectionExtractoria  z"Extractor for a patreon collection
collection)r   r   Collectionsz&{collection[title]} ({collection[id]})z5(?:https?://)?(?:www\.)?patreon\.com/collection/(\d+)z(https://www.patreon.com/collection/12345c           	          U R                   S   nU R                  U5      =U R                  S'   n[        R                  " US   S   SS5      nU R                  SSS	U S
U S35      nU R                  U5      $ )Nr   r  	thumbnailrR   z
/campaign/r8   rA   collection_order&filter[campaign_id]=zT&filter[contains_exclusive_posts]=true&filter[is_draft]=false&filter[collection_id]=z&filter[include_drops]=true)groupsr   kwdictr   r   r   r   )r   r   r  campaign_idrR   s        r!   rA    PatreonCollectionExtractor.postsi  s    A]+	,L!Jii{#E*L#? oog'9#K=&&3_)	* $$r$   c                     U R                  S5      =n(       a  US;   a  SnSU-   $ US;   a  SnSU-   $ U(       a  SU-   $ S$ )Nr   >   r   r   r  >   r   r   r   r   r   r   r'   r   r   s      r!   r   !PatreonCollectionExtractor._orderz  s\    KK..5.$* e## 77'e##"&x$.B.r$   r-   N)r  r
  r  r  r  subcategoryr  patternexamplerA   r   r  r-   r$   r!   r  r  a  s&    ,KNMFG8G%"/r$   r  c                   6    \ rS rSrSrSrSrSrS rS r	S r
S	rg
)PatreonCreatorExtractori  zExtractor for a creator's worksr   z(?:https?://)?(?:www\.)?patreon\.com/(?!(?:home|create|login|signup|search|posts|messages)(?:$|[/?#]))(?:profile/creators|(?:cw?/)?([^/?#]+)(?:/posts)?)/?(?:\?([^#]+))?zhttps://www.patreon.com/c/USERc           
      6   U R                   u  p[        R                  " U5      nU R                  X5      nU R                  R                  SU5        U R                  SUR                  SS5      SU SU R                  U5       35      nU R                  U5      $ )Nzcampaign_id: %srA   r   r   r  z=&filter[contains_exclusive_posts]=true&filter[is_draft]=false)
r  r   r   _get_campaign_idr   rN   r   rC   _get_filtersr   )r   r   r   r   r  rR   s         r!   rA   PatreonCreatorExtractor.posts  s    !!%(++G<(+6oogvzz&/'J#K=&  ()+ $$r$   c                    U(       a  UR                  S5      (       a  USS  $ UR                  S5      =(       d    UR                  S5      =n(       a  U$ UR                  S5      =n(       a  U R                   SU 3nOU R                   SU 3nU R                  USS	9R                  n S nU R                  U5      nUS
   S   S   $ ! [        R                   a     Od[         aX  nW(       a  U R                  R                  U5        [        R                  " SUR                  R                   SU S35      eS nAff = f[        R                  " USS5      =n	(       a  U	$ [        R                  " S5      e)Nzid:   cr  uz/user?u=r8   T)notfoundr   r   r)   zUnable to extract campaign ID (z: )z-{\"value\":{\"campaign\":{\"data\":{\"id\":\"z\"zFailed to extract campaign ID)r`   rC   rL   r   r   r  r	   ControlExceptionrq   r   rN   r  r  r  r   )
r   r   r   r  user_idrR   r  r   r  cids
             r!   r)  (PatreonCreatorExtractor._get_campaign_id  so   w))%0012; **S/FVZZ-FF;Fjjo%7%YYKxy1CYYKq	*C||C$|/44	6D**40D
#F+D11)) 	 	6t$++MM**+2cU!56 6	6 ))FO O3 OJ''(GHHs   +C	 	E 	E (AD;;E c                 N    SR                  S UR                  5        5       5      $ )Nr'   c              3      #    U  H>  u  pUR                  S 5      (       d  M  SUSS  S[        R                  " U5       3v   M@     g7f)zfilters[z&filter[   N=)r`   r   escape)r.   r   values      r!   r1   7PatreonCreatorExtractor._get_filters.<locals>.<genexpr>  sD      
,
~~j) 6hs12wiqU!3 45,s
   A&A)joinrV   )r   r   s     r!   r*  $PatreonCreatorExtractor._get_filters  s&    ww 
$lln
 
 	
r$   r-   N)r  r
  r  r  r  r#  r$  r%  rA   r)  r*  r  r-   r$   r!   r'  r'    s)    )K#G
 /G%IB
r$   r'  c                   *    \ rS rSrSrSrSrSrS rSr	g)	PatreonUserExtractori  z2Extractor for media from creators supported by your   z*(?:https?://)?(?:www\.)?patreon\.com/home$zhttps://www.patreon.com/homec                    ^ U R                  S S 5      S   =n(       a6  [        R                  " U5      R                  5       =U l        mU4S jU l        U R                  SS S5      nU R                  U5      $ )Nr   c                     > T $ r,   r-   )r   s   r!   <lambda>,PatreonUserExtractor.posts.<locals>.<lambda>  s    r$   streamz>&filter[is_following]=true&json-api-use-default-includes=false)_get_date_min_maxr   from_ts	isoformatr   r   r   r   )r   date_maxrR   r   s      @r!   rA   PatreonUserExtractor.posts  sp    --dD9!<<8<$&JJx$8$B$B$DDDL6 .Dooh3 $$r$   )r   r   N
r  r
  r  r  r  r#  r$  r%  rA   r  r-   r$   r!   r@  r@    s    <K;G,G	%r$   r@  c                   *    \ rS rSrSrSrSrSrS rSr	g)	PatreonPostExtractori  z&Extractor for media from a single postr0   z4(?:https?://)?(?:www\.)?patreon\.com/posts/([^/?#]+)z)https://www.patreon.com/posts/TITLE-12345c                 &   U R                   (       d+  U R                  R                  S   U R                  L a  SS0nOS nU R                   SU R
                  S    3nU R                  X!SS9R                  nU R                  U5      n US   nU R                  US   5      nU R                  US   U5      4$ ! [         aN    U R                  R                  U5        UR                  S5      S	:X  a  U R                  R                  S
5         gf = f)Nz
User-Agentz0Patreon/14.2.1 (Android; Android 11; Scale/2.10)z/posts/r   T)rU   r0  r0   campaignDisciplinaryStatus	suspendedzAccount suspendedr-   r   r   )r   sessionrU   r  rL   r  r   r   r  KeyErrorr   rN   rC   r   r   r   )r   rU   rR   r  r   r0   r   s          r!   rA   PatreonPostExtractor.posts  s   $$\2dnnD#IKG G74;;q>"23||C4|@EE++D1		V$D ??4
#34d6lH577  	HHNN9%}}9:kI  !45		s   	B8 8ADDr-   NrK  r-   r$   r!   rM  rM    s    0KEG9G8r$   rM  )r  commonr   r   r'   r   r   r   r	   cacher
   r   rE   r   r  r'  r@  rM  r-   r$   r!   <module>rV     sc    . & ( (   LLy LL^
!/!1 !/H?
. ?
D%+ %$8+ 8r$   