
    iC                     &   S r SSKJrJr  SSKJrJrJ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 " S S\	5      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.artstation.com/   )	ExtractorMessage   )textutil	exception    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S jrS rS rSrg)ArtstationExtractor   z$Base class for artstation extractors
artstationz/{category}_{id}_{asset[id]}_{title}.{extension})
{category}{userinfo[username]}z{asset[id]}firefoxFzhttps://www.artstation.comc                 \    [         R                  " X5        US   =(       d    US   U l        g )Nr   r   )r   __init__userselfmatchs     L/app/mltbenv/lib/python3.13/site-packages/gallery_dl/extractor/artstation.pyr   ArtstationExtractor.__init__   s$    4'!H(a	    c                    SU R                   R                  S'   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      U l        g )
Nz	max-age=0zCache-ControlmviewsTvideosexternalFpreviewsz	max-posts)sessionheadersconfigr   r   r   r   	max_postsr   s    r   _initArtstationExtractor._init   sn    0;_-kk(D1kk(D1J6J6[1r   c              #   B  #    U R                  5       nU R                  5       nU R                  (       a   [        R                  " X R                  5      nU GHC  n[        U R                  US   5      S5       GH  u  pEUR                  U5        US   nXES'   [        R                  SU4v   US   (       aU  U R                  U5      =n(       a*  [        R                  " Xu5        [        R                  Xu4v   U R                  (       d  M  US   (       d  M  US   n[        R                  " Xu5        U R                  U5      nS	U;   a6  UR!                  S
5      u  pn
U
(       a  U SU
 3nU R#                  X5      US'   [        R                  Xu4v   GM     GMF     g 7f)Nhash_idr   assetnum has_embedded_player	has_image	image_urlz/images/images//large/z/8k/	_fallback)metadataprojectsr"   	itertoolsislice	enumerateget_project_assetsupdater   	Directory_extract_embedr   nameext_from_urlUrlr   	_no_cache	partition_image_fallback)r   datar1   projectr)   r(   adicturllhs_rhss              r   itemsArtstationExtractor.items&   s_    }}==?>> ''..AHG'++GI,>?D
T"g"e''U22./"11%88s8--c9%kk355== %%,C))#5..-C(C/&)mmI&>%(EcU"3C151E1Ec1OE+.!++s113D  s   DFBFc                 `   US   nUS   n[         R                  " USS5      =(       d    [         R                  " USS5      nUR                  U R                  5      (       a  [         R                  " UR	                  SS5      S	S
5      nUS:X  aT  U R
                  (       d  g U R                  U5      R                   n[         R                  " USS5      R                  S5      $ U(       a[  U R                  (       d  g U R                  U5      R                   n[         R                  " USSUR                  S5      S-   5      S   $ U(       a  U R                  (       d  g SUS'   SU-   $ U R                  R                  U5        U R                  R                  SUR	                  S5      5        g )Nr(   player_embeddedzsrc=""zsrc=''r-   r*   z/assets//	marmosetszmarmoset.embed(z",z"' z src="z
id="video"r   r	   mp4	extensionzytdl:z*Failed to extract embedded player URL (%s)id)r   extr
startswithrootgetr   requeststripr   extractfindr   logdebugwarning)r   r(   r@   playerrA   typepages          r   r8   "ArtstationExtractor._extract_embedH   s^   g()yy#. /yy#. 	 >>$))$$99UYY{B7SID{"{{||C(--yy'8$?EEfMM{{||C(--||(C<)@)BDDEG G ==!&E+S= vE4	*r   c              #   T   #    U SU 3v   U SU 3v   U SU 3v   U SU 3v   g 7f)Nz/4k/r.   z/medium/z/small/ )r   rB   rD   s      r   r=   #ArtstationExtractor._image_fallbacki   sI     T#WSE""XcU##WSE""s   &(c                 <    SU R                  U R                  5      0$ )zReturn general metadatauserinfo)get_user_infor   r#   s    r   r0   ArtstationExtractor.metadatao   s    D..tyy9::r   c                     g)z6Return an iterable containing all relevant project IDsNr`   r#   s    r   r1   ArtstationExtractor.projectss   s    r   c              #   4  #    U R                    SU S3n U R                  U5      n[        R                  " US   5      US'   [        R                  " [        R                  " US   5      5      US'   U R                  US   5      US'   US   nUS	 [        U5      US	'   [        U5      S
:X  a  US   US'   Uv   gU H  nXcS'   UR                  5       v   M     g! [        R                   a%  nU R                  R                  U5         SnAgSnAff = f7f)z.Return all assets associated with 'project_id'z
/projects/.jsonNtitledescription
created_atdateassetscountr   r	   r(   )rR   request_jsonr   	HttpErrorrX   rZ   r   unescaperemove_htmlparse_datetime_isolencopy)r   
project_idrA   r>   excrn   r(   s          r   r5   &ArtstationExtractor.get_project_assetsv   s    :j\7	$$S)D
 d7m4W"mmD,<,<-! "]..tL/ABVhNFWv;!"1IDMJ %Wiik!  # "" 	HHS!	s.   DC B5DD0DDDDc                     U R                    SUR                  5        S3nU R                  USS9nUR                  5       $ )z#Return metadata for a specific user/users/z/quick.jsonr   )notfound)rR   lowerrT   json)r   usernamerA   responses       r   rd   !ArtstationExtractor.get_user_info   s>    78>>#3"4K@<<f<5}}r   Nc              #   ,  #    SU R                   S.nU(       a  UnU R                  5       US'   SXCS.nOU(       d  0 nX$S.nSnSUS	'    U R                  " U40 UD6nUS
    S h  vN   U[        US
   5      -  nXgS   :  a  g US	==   S-  ss'   MI   N-7f)Nz!application/json, text/plain, */*AcceptOriginzPUBLIC-CSRF-TOKENPOSTmethodr    r~   )paramsr    r	   r   r]   r>   total_count)rR   _init_csrf_tokenrp   ru   )r   rA   r   r~   r    kwargstotalr>   s           r   _paginationArtstationExtractor._pagination   s     :yy

 F+/+@+@+BG'( &7IF &;Fv$$S3F3DF|##Sf&&E]++6NaN #s   A"B$B%.Bc                 h    U R                   S-   nSU R                   S.nU R                  USU0 S9S   $ )Nz"/api/v2/csrf_protection/token.jsonz*/*r   r   r   public_csrf_token)rR   rp   )r   rA   r    s      r   r   $ArtstationExtractor._init_csrf_token   sO    ii>>yy
   b ! ::MO 	Or   c                 h    SU;   a  SOSn[         R                  " S5      nX-   USS -   S-   USS -   $ )a{  Cause a cache miss to prevent Cloudflare 'optimizations'

Cloudflare's 'Polish' optimization strips image metadata and may even
recompress an image as lossy JPEG. This can be prevented by causing
a cache miss when requesting an image by adding a random dummy query
parameter.

Ref:
https://github.com/r888888888/danbooru/issues/3528
https://danbooru.donmai.us/forum_topics/14952
?&   N   =)r   generate_token)r   rA   septokens       r   r;   ArtstationExtractor._no_cache   sD     CZcS##A&y5!9$s*U12Y66r   )r   r"   r   r   r   r   )NN)__name__
__module____qualname____firstlineno____doc__categoryfilename_fmtdirectory_fmtarchive_fmtbrowsertls12rR   r   r$   rE   r8   r=   r0   r1   r5   rd   r   r   r;   __static_attributes__r`   r   r   r   r      sh    .HDL:MKGE'D)2 2D*B#;E"6 8O7r   r   c                   *    \ rS rSrSrSrSrSrS rSr	g)	ArtstationUserExtractor   z0Extractor for all projects of an artstation userr   z(?:https?://)?(?:(?:www\.)?artstation\.com/(?!artwork|projects|search)([^/?#]+)(?:/albums/all)?|((?!www)[\w-]+)\.artstation\.com(?:/projects)?)/?$zhttps://www.artstation.com/USERc                 d    U R                    SU R                   S3nSS0nU R                  X5      $ )Nr{   /projects.jsonalbum_idallrR   r   r   r   rA   r   s      r   r1    ArtstationUserExtractor.projects   s7    7499+^<e$,,r   r`   N)
r   r   r   r   r   subcategorypatternexampler1   r   r`   r   r   r   r      s    :KFG 0G-r   r   c                   >    \ 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)ArtstationAlbumExtractor   z1Extractor for all projects in an artstation albumalbum)r   r   Albumsz{album[id]} - {album[title]}za_{album[id]}_{asset[id]}z~(?:https?://)?(?:(?:www\.)?artstation\.com/(?!artwork|projects|search)([^/?#]+)|((?!www)[\w-]+)\.artstation\.com)/albums/(\d+)z,https://www.artstation.com/USER/albums/12345c                 j    [         R                  X5        [        R                  " US   5      U l        g )N   )r   r   r   	parse_intr   r   s     r   r   !ArtstationAlbumExtractor.__init__   s$    $$T1uQx0r   c                     U R                  U R                  5      nS nUS    H  nUS   U R                  :X  d  M    O   [        R                  " S5      eUUS.$ )Nalbums_with_community_projectsrO   r   )rc   r   )rd   r   r   r   NotFoundError)r   rc   r   s      r   r0   !ArtstationAlbumExtractor.metadata   sd    %%dii0>?ET{dmm+ @ ))'22 !
 	
r   c                 x    U R                    SU R                   S3nSU R                  0nU R                  X5      $ )Nr{   r   r   )rR   r   r   r   r   s      r   r1   !ArtstationAlbumExtractor.projects   s;    7499+^<dmm,,,r   )r   Nr   r   r   r   r   r   r   r   r   r   r   r0   r1   r   r`   r   r   r   r      s4    ;K5M-KBG =G1
-r   r   c                   2    \ rS rSrSrSrSrSrSrSr	S r
S	rg
)ArtstationLikesExtractor   z2Extractor for liked projects of an artstation userlikes)r   r   Likeszf_{userinfo[id]}_{asset[id]}zR(?:https?://)?(?:www\.)?artstation\.com/(?!artwork|projects|search)([^/?#]+)/likesz%https://www.artstation.com/USER/likesc                 \    U R                    SU R                   S3nU R                  U5      $ )Nr{   z/likes.jsonr   r   rA   s     r   r1   !ArtstationLikesExtractor.projects  s-    7499+[9$$r   r`   N)r   r   r   r   r   r   r   r   r   r   r1   r   r`   r   r   r   r      s%    <KCM0K>G5G%r   r   c                   >    \ 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)ArtstationCollectionExtractori  z&Extractor for an artstation collection
collection)r   z{user}z#{collection[id]} {collection[name]}zc_{collection[id]}_{asset[id]}z^(?:https?://)?(?:www\.)?artstation\.com/(?!artwork|projects|search)([^/?#]+)/collections/(\d+)z1https://www.artstation.com/USER/collections/12345c                 B    [         R                  X5        US   U l        g )Nr   )r   r   collection_idr   s     r   r   &ArtstationCollectionExtractor.__init__  s    $$T1"1Xr   c                     U R                    SU R                   S3nSU R                  0nU R                  XSS9nX0R                  S.$ )N/collections/ri   r   Tr   r|   )r   r   )rR   r   r   rp   r   rA   r   r   s       r   r0   &ArtstationCollectionExtractor.metadata  sT    =););(<EBdii(&& ' /
())<<r   c                 x    U R                    SU R                   S3nSU R                  0nU R                  X5      $ )Nr   r   r   )rR   r   r   r   s      r   r1   &ArtstationCollectionExtractor.projects"  s@    =););(<NK!4#5#56,,r   )r   Nr   r`   r   r   r   r     s2    0K<M2KJGAG&=-r   r   c                   *    \ rS rSrSrSrSrSrS rSr	g)	ArtstationCollectionsExtractori(  z.Extractor for an artstation user's collectionscollectionsz[(?:https?://)?(?:www\.)?artstation\.com/(?!artwork|projects|search)([^/?#]+)/collections/?$z+https://www.artstation.com/USER/collectionsc              #      #    U R                   S-   nSU R                  0nU R                  XSS9 HA  nU R                    SU R                   SUS    3n[        US'   [        R
                  X4v   MC     g 7f)	Nz/collections.jsonr   Tr   rK   r   rO   
_extractor)rR   r   rp   r   r   Queuer   s       r   rE   $ArtstationCollectionsExtractor.items/  s~     ii--dii(++T , 3JYYKq=D9I8JKC'DJ|$--00	3s   A4A6r`   N
r   r   r   r   r   r   r   r   rE   r   r`   r   r   r   r   (  s    8KGG;G1r   r   c                   B    \ 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)ArtstationChallengeExtractori:  z2Extractor for submissions of artstation challenges	challengez1{submission_id}_{asset_id}_{filename}.{extension})r   
Challengesz${challenge[id]} - {challenge[title]}zc_{challenge[id]}_{asset_id}z|(?:https?://)?(?:www\.)?artstation\.com/c(?:hallenges|ontests)/[^/?#]+/c(?:ategori|halleng)es/(\d+)/?(?:\?sorting=([a-z]+))?z;https://www.artstation.com/challenges/NAME/categories/12345c                 h    [         R                  X5        US   U l        US   =(       d    SU l        g )Nr   r   popular)r   r   challenge_idsortingr   s     r   r   %ArtstationChallengeExtractor.__init__F  s,    $$T1!!HQx,9r   c           	   #   j  #    U R                   S-   nU SU R                   S3nUS-   nU R                  U5      n[        R                  SSU04v   SSU R                  U R
                  S	.nU R                  X55       H  nU S
US    S3nSSS.nU R                  XuS9 H  nXHS'   [        R                  " [        R                  " US   SS5      5       HQ  n	U R                  U	5      US'   [        R                  " X5        [        R                  U R                  U	5      U4v   MS     M     M     g 7f)Nz/api/v2/competition/zchallenges/ri   zsubmissions.jsonr*   r   r   2   )r]   per_pager   sort_byzsubmissions/rO   z/submission_updates.json)r]   r   )r   bodyz href="rI   asset_id)rR   r   rp   r   r7   r   r   r   unique_sequencer   extract_iter_id_from_urlr9   r:   r;   )
r   basechallenge_urlsubmission_urlr   r   
submission
update_urlr6   rA   s
             r   rE   "ArtstationChallengeExtractor.itemsK  sG    yy11&D,=,=+>eD 22%%m4	k9%===  -- LL	
 **>BJ!F,z$/?.@46JR0F**:*E&/{#//0A0Av	318 9C)-):):3)?F:&))#6!++t~~c':FBB	9 F	 Cs   D1D3c                 t    UR                  S5      n[        R                  " SR                  USS 5      5      $ )z)Get an image's submission ID from its URLrK   r*      
   )splitr   r   join)r   rA   partss      r   r   )ArtstationChallengeExtractor._id_from_urlf  s-    		#~~bggeAbk233r   )r   r   N)r   r   r   r   r   r   r   r   r   r   r   r   rE   r   r   r`   r   r   r   r   :  s:    <KFL=M0K,G LG-
C64r   r   c                   >    \ 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)ArtstationSearchExtractoril  z'Extractor for artstation search resultssearch)r   Searchesz{search[query]}zs_{search[query]}_{asset[id]}z9(?:https?://)?(?:\w+\.)?artstation\.com/search/?\?([^#]+)z-https://www.artstation.com/search?query=QUERYc                    [         R                  X5        [        R                  " US   5      =U l        n[        R
                  " UR                  S5      =(       d    UR                  SS5      5      U l        UR                  SS5      R                  5       U l	        UR                  SS5      R                  S5      U l        g )	Nr   queryqr*   r   	relevancetags,)r   r   r   parse_queryr   unquoterS   r  r}   r   r   r
  )r   r   r  s      r   r   "ArtstationSearchExtractor.__init__u  s    $$T1"..uQx88e\\%))G"4"J		#r8JK
yyK8>>@IIfb)//4	r   c                 N    SU R                   U R                  U R                  S.0$ )Nr  r  r   r
  r  r#   s    r   r0   "ArtstationSearchExtractor.metadata|  s)    zz||yy
  	r   c                 z   / nU R                   R                  5        HG  u  p#UR                  S5      (       d  US:X  d  M#  UR                  USUR	                  S5      S.5        MI     U R
                  S-   nU R                  S SU R                  U R                  SS	5      (       a  S
OSUSS.nU R                  XES9$ )N_idsr
  includer  )fieldr   valuez/api/v2/search/projects.jsonr   z	pro-firstT10r`   )r  r]   r   r   	pro_firstfiltersadditional_fields)r~   )
r   rE   endswithappendr   rR   r  r   r!   r   )r   r  keyr  rA   r>   s         r   r1   "ArtstationSearchExtractor.projects  s    ++++-JC||F##sf}!'#kk#.   . ii88!%!%!#!%)-[$)G)G#"%!(!#	
 //r   )r   r  r   r
  Nr   r`   r   r   r  r  l  s/    1KAM1K%G=G50r   r  c                   >    \ 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)ArtstationArtworkExtractori  z3Extractor for projects on artstation's artwork pageartwork)r   Artworksz{artwork[sorting]!c}zA_{asset[id]}z:(?:https?://)?(?:\w+\.)?artstation\.com/artwork/?\?([^#]+)z/https://www.artstation.com/artwork?sorting=SORTc                 j    [         R                  X5        [        R                  " US   5      U l        g Nr   )r   r   r   r  r  r   s     r   r   #ArtstationArtworkExtractor.__init__  s&    $$T1%%eAh/
r   c                     SU R                   0$ )Nr"  r  r#   s    r   r0   #ArtstationArtworkExtractor.metadata  s    4::&&r   c                 r    U R                   S-   nU R                  XR                  R                  5       5      $ )Nr   )rR   r   r  rv   r   s     r   r1   #ArtstationArtworkExtractor.projects  s-    ii**ZZ__%677r   r(  Nr   r`   r   r   r!  r!    s/    =KFM!K&G?G0'8r   r!  c                   <    \ rS rSrSrSrSrSrS rS r	S r
S	 rS
rg)ArtstationImageExtractori  z5Extractor for images from a single artstation projectimagez](?:https?://)?(?:(?:[\w-]+\.)?artstation\.com/(?:artwork|projects|search)|artstn\.co/p)/(\w+)z(https://www.artstation.com/artwork/abcdec                 P    [         R                  X5        US   U l        S U l        g r%  )r   r   rw   rn   r   s     r   r   !ArtstationImageExtractor.__init__  s"    $$T1(r   c                     [        [        R                  X R                  5      5      U l         U R                  S   S   S   U l        [        R                  U 5      $ ! [         a
    SU l         N(f = f)Nr	   r   r   r*   )listr   r5   rw   rn   r   
IndexErrorr0   r#   s    r   r0   !ArtstationImageExtractor.metadata  sl    .AA//# $	Av.z:DI #++D11  	DI	s   A A21A2c                      SU R                   04$ )Nr'   )rw   r#   s    r   r1   !ArtstationImageExtractor.projects  s    DOO,..r   c                     U R                   $ )N)rn   )r   rw   s     r   r5   +ArtstationImageExtractor.get_project_assets  s    {{r   )rn   rw   r   N)r   r   r   r   r   r   r   r   r   r0   r1   r5   r   r`   r   r   r-  r-    s,    ?K'G 9G
2/r   r-  c                   *    \ rS rSrSrSrSrSrS rSr	g)	ArtstationFollowingExtractori  z%Extractor for a user's followed users	followingzV(?:https?://)?(?:www\.)?artstation\.com/(?!artwork|projects|search)([^/?#]+)/followingz)https://www.artstation.com/USER/followingc              #      #    U R                    SU R                   S3nU R                  U5       H4  nU R                    SUS    3n[        US'   [        R
                  X4v   M6     g 7f)Nr{   z/following.jsonrK   r   r   )rR   r   r   r   r   r   )r   rA   r   s      r   rE   "ArtstationFollowingExtractor.items  sg     7499+_=$$S)DYYKqj!1 23C!8D--** *s   A'A)r`   Nr   r`   r   r   r:  r:    s    /KBG9G+r   r:  )r   commonr   r   r*   r   r   r   r2   r   r   r   r   r   r   r   r  r!  r-  r:  r`   r   r   <module>r?     s    1 & $ $ z7) z7z-1 -!-2 !-H%2 %-$7 -61%8 1$/4#6 /4d,0 3 ,0^8!4 8*2 :+#6 +r   