+
     h4  c                   s    ^ RI t ^ RIt^ RIt^ RIt^ RIt^RIHtHt ^RIH	t	H
t
HtHt ^RIHtHtHtHtHtHtHtHt ^RIHt ] ! R R]4      4       t] ! R R	]4      4       t] ! R
 R]4      4       tR# )i    N)Mirror	Thumbnail)AddonCategoryFileCategoryMediaCategoryThumbnailType)BASE_URLconcat_docsget_dateget_page	get_viewsjoinprepare_requestraise_for_status)BaseMetaClassc                   s\   a a ] tR t^t oRtV3R lV 3R lltR tRR/R ltR tR	t	Vt
V ;t# )
Fileaj	  An oject representing a file on ModDB, a file is something posted by the page owner which is directly linked
to the page. It is endorsed by the page owner and they should do everythign they can to make sure that it is safe.
As compared to an addon that may be added by fans to the page and that are files meant to work with the page but
that are not directly related to the page. E.x the file of a mod page would be the mod files used to install the
mod whereas an addon could be something like a fan-made texture pack for the mod or a map.

Parameters
-----------
html : bs4.BeautifulSoup
    The html to parse. Allows for finer control.

Filtering
----------
category  : :class:`.FileCategory`
    The type of file (audio, video, demo, full version....)
categoryaddon : :class:`.AddonCategory`
    The type of addon (map, textures, ect...)
game : Union[:class:`.Game`, :class:`.Object`]
    An game object or an object with an id attribute which represents the
    game the file belongs to.
timeframe : :class:`.TimeFrame`
    The time period this was released in (last 24hr, last week, last month)

Sorting
--------
    * **released** - when the object was released, asc is oldest, desc is most recent
    * **id** - when it was added to moddb, asc is oldest, desc is most recent
    * **ranktoday** - order by daily ranking, asc is highest ranked, desc is lowest rank
    * **visitstotal** - order by most views, asc is highest views, desc is lowest views
    * **rating** - order by rating, asc is highest rating, desc is lowest rating
    * **name** - order alphabetically, asc is a-z, desc is z-a
    * **date** - order by upload date, asc is most recent first, desc is oldest first

Attributes
-----------
filename : str
    The name of the file
hash : str
    The MD5 hash of the file
name : str
    The name of the page
size : int
    the file size in bytes
today : int
    The number of downloads today
downloads : int
    The total number of times this file has been downloaded
category : FileCategory
    The category of the file
author : Thumbnail
    A member type thumbnail of the member who uploaded the file
date : datetime.datetime
    The date the file was uploaded
button : str
    html code for the embed button
widget : str
    html code for the embed widget
description : str
    Description of the file, as written by the author
preview : str
    URL of the preview image for the file
c                4   < V ^8  d   QhRS[ P                  /# i   htmlbs4ZBeautifulSoupZformat__classdict__   "5/usr/lib/python3.14/site-packages/moddb/pages/file.py__annotate__ZFile.__annotate__X   s     *@ *@S.. *@    c           
     sT  < VP                  R RRR7      '       d   \        R4      hVP                  RRR7      pVP                  RR(R	7       Uu/ uFJ  pVP                  P	                  4       VP
                  P                  P                  P                  4       bKL  	  ppVP                  R
RR7      P
                  P
                  P                  R RR7      P                  V n        VR,          V n	        \        SV `-  V4       VR,          V n        \        \        P                  ! RRVR,          P!                  R4      ^,          4      4      V n        VP                  RRR	7      P
                  P$                  P                  p\        \        P                  ! RRVP!                  R4      ^,          4      4      V n        \        VP!                  R4      ^ ,          P)                  RR4      4      V n         \-        \        VP                  RRR	7      P
                  P$                  R,          P!                  R4      R),          4      4      V n        VP                  RRR	7      P
                  P$                  p\3        VR,          VP                  \4        P6                  R7      V n        \;        VP                  RRR	7      P
                  P                  P<                  R,          4      V n        VP                  RRR	7      P
                  P                  P@                  R,          V n!        VP                  RRR	7      P
                  P                  P@                  R,          V n"        VP                  R R!R"7      P                  V n#        VP                  R#R$R%7      ^ ,          R&,          V n$        R'# u upi   \         d`    \1        \        TP                  RRR	7      P
                  P$                  R,          P!                  R4      R),          4      4      T n         ELi ; i)*spanzFile DeletedZheading)stringclass_zThis file has been removeddivztable tablemenur   h5r   aZReport)titlefilenamezmd5 hashz
[(),bytes] sizeZ Z	Downloadsz
[(),today],ZCategoryhrefZ=ZUploaderurlnametypeZAddeddatetimezEmbed ButtonZvaluezEmbed WidgetpZdownloadsummaryidimgT)srcr2   N)FilenameSizezMD5 Hash)%findZ
ValueErrorfind_allr   lowerparentr   stripr+   r$   super__init__hashintreZsubsplitr&   r"   todayreplace	downloadsr   categoryr   r   r   memberauthorr   timedateZinputbuttonwidgetdescriptionpreview)selfr   ZinfoxZfilerC   Zuploader	__class__s   &&     r   r<   ZFile.__init__X   s5   99VN99EE9::yy'8y9 ]]40P]Q
Q HHNNahhmm2288::Q 	 

 IIcI*1188==fY=W^^ 		 Z($	}b$v,2D2DS2I!2LMN	IId;I7>>@@GG	r9??33G3JKL
Y__S1!4<<S"EF	(DIId:I6==??GMMcRSUVWDM 99T*95<<>> x]=Q=Q
 TYYtGY<CCHHMMjYZ	ii^i<CCHHNNwWii^i<CCHHNNwW99S->9?FF}}U}5a8?K
*  	)DIId:I6==??GMMcRSUVWDM	s   AN8:AN= =A&P'&P'c                s~    R V P                   P                   RV P                   RV P                  P                   R2# )Z<z name= type=>)rO   __name__r+   rD   rM      &r   __repr__ZFile.__repr__   s8    4>>**+6$))F4==CUCUBVVWXXr   mirrorNc               s"   VfG   \        \         RV P                   24      pVP                  RRV P                   2R7      R,          pMVP
                  p\        P                  R,          P                  p\        \        P                  ! R\        V4      4      V4      pVP                  VR	R
7      ;_uu_ 4       p\        V4       VP                  RR7       F  pVP!                  V4       K  	  RRR4       R#   + '       g   i     R# ; i)av  Save the file to an object. This functions makes
two requests. If you pass a valid mirror it will
make only one request.

Parameters
-----------
file_obj : typing.BinaryIO
    The file obj to save the file to. The binary data
    will be streamed to that object.
mirror : Optional[Mirror]
    An optional mirror object to download the
    file from a specific moddb mirror

Nz/downloads/start/r"   z	download r!   r(   moddbGETTZstream    Z
chunk_size)r	   r   r0   r6   r$   Z_urlsysmodulesSESSIONr   requestsRequestr   sendr   iter_contentwrite)	rM   file_objrV   Zdownloadr*   r^   preppedrchunks	   &&$      r   saveZ	File.save   s     >8*,=dggY GHH--i,G-HPC++C++g&..!("2"25$s)"DgN\\'$\//1Q48u% 9 0///s   =6C==D	c                s.   \        RV P                   R24      pVP                  RRR7      P                  RRR7      p. pV EFN  p\        P
                  ! RVP                  P                  P                  R,          P                  4       4      p\        P
                  ! R	VP                  P                  P                  4      pVP                  \        VP                  ^4      \        VP                  ^4      4      VP                  ^4      VP                  ^4      \        VP                  ^4      P!                  R
R4      4      \#        VP                  ^4      4      VP                  P                  P$                  R,          R7      4       EKQ  	  V# )zGet all the mirrors from which a file can be downloaded. This
can then be passed to File.save to download from a specific mirror.


Returns
--------
List[Mirror]
    A list of Mirror objectsz&https://www.moddb.com/downloads/start/z/allr   mirrorsr   F)Z	recursivez(.*) #([0-9]*) \((\w+), (\w+)\)z0([0-9,]*) downloads? served, ([0-9.]*)% capacityr'   r%   r(   )r+   indexZcityZcountryZservedZcapacityr*   r5   )r	   r0   r6   r7   r?   Zmatchr   r.   Zcontentsr:   r   r   Zappendr    Zgroupr>   rB   Zfloatr"   )rM   r   Zmirrors_divri   rV   Zmirror_matchZstats_matchs   &      r   get_mirrorsZFile.get_mirrors   sB    @	NOiiii8AA%SXAY!F882FJJLL4I4I"4M4S4S4UL ((C

&&K
 NN%++A.l0034%++A.(..q1{003;;CDE";#4#4Q#78

v.
 "* r   )rF   rI   rD   rH   rK   rC   r$   r=   r+   rL   r&   rA   rJ   )rR   
__module____qualname____firstlineno____doc__r<   rU   rh   rk   __static_attributes____classdictcell____classcell__rO   r      @@r   r   r      s4     =~*@ *@XY&t &8" "r   r   c                   s    ] tR t^tRtRtR# )Addonac  Object representing an addon. Seemingly the only difference between an addon and a file is in
the semantics. A file often represents something official released by the page, e.g. the mod installation
or an official guide where as addons are often fan made and might not be directly endorsed by the page owners
even if it is allowed. They literally add on to the page's content without becoming part of it. There is a slight
difference in their profiles but nothing beyond that.

Parameters
-----------
html : bs4.BeautifulSoup
    The html to parse. Allows for finer control.

Filtering
----------
categoryaddon : :class:`.AddonCategory`
    The type of addon (map, textures, ect...)
licence : :class:`.Licence`
    The licence of the addon
game : Union[:class:`.Game`, :class:`.Object`]
    An game object or an object with an id attribute which represents the
    game the addon belongs to.
timeframe : :class:`.TimeFrame`
    The time period this was released in (last 24hr, last week, last month)

Sorting
--------
    * **released** - when the object was released, asc is oldest, desc is most recent
    * **id** - when it was added to moddb, asc is oldest, desc is most recent
    * **ranktoday** - order by daily ranking, asc is highest ranked, desc is lowest rank
    * **visitstotal** - order by most views, asc is highest views, desc is lowest views
    * **rating** - order by rating, asc is highest rating, desc is lowest rating
    * **name** - order alphabetically, asc is a-z, desc is z-a
    * **licence** - order based on licence
    * **date** - order by upload date, asc is most recent first, desc is oldest first


 N)rR   rl   rm   rn   ro   rp   rv   r   r   ru   ru      s    #J 	r   ru   c                   sN   a a ] tR t^t oRtV3R lV 3R lltR tR tRtVt	V ;t
# )Mediaa  Represents an image, audio file or video file on

Parameters
-----------
html : bs4.BeautifulSoup
    The html to parse. Allows for finer control.

Filtering
-----------
sitearea : :class:`.Category`
    The type of model the media belongs to. Category.downloads is not valid for this.

Sorting
--------
    * **ranktoday** - order by daily ranking, asc is highest ranked, desc is lowest rank
    * **visitstotal** - order by most views, asc is highest views, desc is lowest views
    * **name** - order alphabetically, asc is a-z, desc is z-a
    * **id** - order by upload date, asc is most recent first, desc is oldest first

    Exclusive to videos and audios
    * **duration** - order by duration, asc is shortest to longest, desc is longest first

Attributes
-----------
date : datetime.datetime
    The date the media was uploaded
name : str
    The name of the media
author : Thumbnail
    Member type thumbnail of the media uploader
duration : datetime.timedelta
    Duration of the media in seconds, 0 if it's an image
size : int
    Size of the files in bytes
views : int
    Total amount of views
today : int
    Amount of views today
filename : str
    The name of the file for the media
fileurl : str
    The url of the file for the media
category : MediaCategory
    Whether the media is an image, a video or an audio
description : str
    The description of the file as given by the file uploader.
c                r   r   r   r   r   r   r   ZMedia.__annotate__$  s     0Q 0QS.. 0Qr   c                s@  <  VP                  R RR7      R,          V n        \        S
V `  V4       VP                  RRR	7      pV Uu/ uF'  q3P                  P                  4       VP                  bK)  	  pp\        VR
,          P                  P                  R,          4      V n        VR,          P                  P                  p\        VR,          VP                  P                  4       \         P"                  R7      V n        RV9   d   VR,          P                  P                  P                  P                  4       P'                  R4      pVP)                  4        . R Op\*        P,                  ! R!/ V Uu/ uF$  qVP/                  V4      ,          \1        V4      bK&  	  upB V n        M^ V n        RV9   dI   \5        VR,          P                  P                  P                  4       P'                  R4      4      V n        \9        VR,          P                  P                  4      w  V n        V n        VP                  RRR7      p	V	'       g6   \>        P@                  V n!        VP                  R RR7      R,          V n"        M[V	PF                  R,          V n"        RV	PF                  R,          9   d   \>        PH                  V n!        M\>        PJ                  V n!        RV9   d2   VR,          P                  P                  P                  4       V n&        M'V PD                  P'                  R4      R",          V n&        VP                  R RR/4      R,          V n'        R#   \         d$    TP                  RRR7      R,          T n         ELpi ; iu upi u upi )#Zmetar+   )ZitempropZcontentr1   Z
mediaimager/   r#   r    r!   rH   r-   Zbyr(   r)   durationZ:r&   t   ×viewsvideoZmediaplayerzog:image)Zpropertyr2   audior,   r$   Z/rK   N)ZDateZByZDurationr4   ZViewsr3   )ZsecondsZminutesZhoursrv   r5   )(r6   r+   Z	TypeErrorr;   r<   r7   r   r8   r9   r   r   rG   rH   r"   r   r:   r   rE   rF   r@   Zreverser-   Z	timedeltarj   r>   rx   Ztupler&   r
   ry   rA   r   ZimagerD   fileurlZsourcer{   rz   r$   rK   )rM   r   ZmediasZmediaZ	raw_mediarF   rx   ZtimesrN   Zmedia_playerrO   s   &&        r   r<   ZMedia.__init__$  s   	C		&6	:9EDI 	t,cdEKLVE\\'')5<<7V	LYv.3388DE	4%%''vV]]%8%8%:AUAU
 " ,1166==CCEKKCPH3E$.. =EFX*+SV3XFDM DMYi/44;;AACII$OPDI!*9W+=+?+?+F+F!G
DJyy]y;)//DM99Vj9A)LDL'..u5DL,--f55 - 3 3 - 3 3"%j166==CCEDM LL..s3B7DM99Vfm-DEiP[  	C		%L	9'BDI	C
 M Gs   M% -N;*N%*NNc                sP    R V P                    RV P                  P                    R2# )z<Media name=rP   rQ   )r+   rD   rS   rT   r   rU   ZMedia.__repr__V  s&    dii[t}}/A/A.B!DDr   c                sx   \         P                  R,          P                  p\        \        P
                  ! RV P                  4      V4      pVP                  VRR7      ;_uu_ 4       p\        V4       VP                  RR7       F  pVP                  V4       K  	  RRR4       R#   + '       g   i     R# ; i)zSave the media to an object.

Parameters
-----------
file_obj : typing.BinaryIO
    The file obj to save the file to. The binary data
    will be streamed to that object.

rW   rX   TrY   rZ   r[   N)r\   r]   r^   r   r_   r`   r|   ra   r   rb   rc   )rM   rd   r^   re   rf   rg   s   &&    r   rh   Z
Media.saveY  s     ++g&..!("2"25$,,"GQ\\'$\//1Q48u% 9 0///s   (6B((B9	)rF   rD   rH   rK   rx   r$   r|   r+   r&   rA   ry   )rR   rl   rm   rn   ro   r<   rU   rh   rp   rq   rr   rs   rt   r   rw   rw      s(     .`0Q 0QdE& &r   rw   )r-   r?   r\   r   r_   Zboxesr    r   Zenumsr   r   r   r   Zutilsr   r   r   r	   r
   r   r   r   Zbaser   r   ru   rw   rv   r   r   <module>r}      s     	 
 
  % M M	 	 	   m= m m` &	D &	 &	R v&M v& v&r   