
    bfx                        d dl Z d dlmZ d dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlZd dlZddlmZmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZm Z  ddl!m"Z"m#Z#m$Z$m%Z% ddl&m'Z'm(Z(  G d d	          Z)dS )
    N)closing   )AttribAccessDictAttribAccessListparse_version_string)MastodonNetworkErrorMastodonIllegalArgumentErrorMastodonRatelimitErrorMastodonNotFoundErrorMastodonUnauthorizedErrorMastodonInternalServerErrorMastodonBadGatewayErrorMastodonServiceUnavailableErrorMastodonGatewayTimeoutErrorMastodonServerErrorMastodonAPIErrorMastodonMalformedEventError)urlparsemagicPurePathPath)_DEFAULT_STREAM_TIMEOUT"_DEFAULT_STREAM_RECONNECT_WAIT_SECc                   D   e Zd Zd Zd Zed             Zed             Zed             Zed             Z	ed             Z
ed             Zi i i d	d	d
dd
ddd	fdZd Zi dedefdZg fdZddZd Zd Zd Zd Zd Zd ZddZed             Zed             Zd Zd	S )Mastodonc                     |j         %|                    t          j        j                  }|                                S )z
        Converts a python datetime to unix epoch, accounting for
        time zones and such.

        Assumes UTC if timezone is not given.
        N)tzinfo)r   replacedatetimetimezoneutc	timestamp)self	date_times     `/home/feoh/.local/pipx/venvs/mastodon-archive/lib/python3.11/site-packages/mastodon/internals.py__datetime_to_epochzMastodon.__datetime_to_epoch   s;     #!))1B1F)GGI""$$$    c                 Z    | j         |                                 j        | _         | j         S )z^
        Fetch the logged in user's ID, with caching. ID is reset on calls to log_in.
        )_Mastodon__logged_in_idaccount_verify_credentialsidr#   s    r%   __get_logged_in_idzMastodon.__get_logged_in_id)   s-     &"&"A"A"C"C"FD""r'   c                 N    t          | t                    rt          |           S | S )z
        Makes it possible to use attribute notation to access a dicts
        elements, while still allowing the dict to act as a dict.
        )
isinstancedictr   json_objects    r%   __json_allow_dict_attrsz Mastodon.__json_allow_dict_attrs1   s*     k4(( 	1#K000r'   c                 r   g d}g }|                                  D ]\  }}||v r|	 t          |t                    r3t          j                            |t          j        j                  | |<   n"t          j        	                    |          | |<   w#  |
                    |           Y xY w|D ]}| |= | S )zH
        Parse dates in certain known json fields, if possible.
        )
created_atweekday
expires_atscheduled_at
updated_atlast_status_at	starts_atends_atpublished_at	edited_atdateperiod)itemsr/   intr   fromtimestampr    r!   dateutilparserparseappend)r2   known_date_fieldsmark_deletekvs        r%   __json_date_parsezMastodon.__json_date_parse;   s    
G G G%%'' 
	. 
	.DAq%%%=.%a-- F-5->-L-LQPXPaPe-f-fKNN-5_-B-B1-E-EKN.#**1----- 	 	AAs   A*BB+c                     dD ]l}|| v rft          | |         t          j                  rF| |                                         dk    rd| |<   | |                                         dk    rd| |<   m| S )zH
        Parse 'True' / 'False' strings in certain known fields
        )
follow	favouritereblogmention	confirmed	suspendedsilenceddisabledapprovedall_daytrueTfalseF)r/   six	text_typelowerr2   keys     r%   __json_truefalse_parsezMastodon.__json_truefalse_parseS   s    
 I 	- 	-C{""z+c2BCM'R'R"s#))++v55'+K$s#))++w66',K$r'   c                     dD ]P}|| v rJt          | |         t          j                  r*	 t          | |                   | |<   @# t          $ r Y Lw xY wQ| S )zI
        Converts json string numerals to native python bignums.
        )r+   r6   in_reply_to_idin_reply_to_account_idloginsregistrationsstatusesr7   last_read_idvalue	frequencyrateinvited_by_account_idcount)r/   r[   r\   rC   
ValueErrorr^   s     r%   __json_strnum_to_bignumz Mastodon.__json_strnum_to_bignum`   s}    
k 	 	C{""z+c2BCM'R'R"'*;s+;'<'<K$$!   D s   A
AAc                     t                               |           } t                               |           } t                               |           } t                               |           } | S )z>
        All the json hooks. Used in request parsing.
        )r    _Mastodon__json_strnum_to_bignum_Mastodon__json_date_parse_Mastodon__json_truefalse_parse _Mastodon__json_allow_dict_attrsr1   s    r%   __json_hookszMastodon.__json_hookso   sV    
 66{CC00==55kBB66{CCr'   c                     |                      t          j        j                                      d          }|d         dk    r|dd         dz   |dd         z   }|S )z
        Function that does what isoformat does but it actually does the same
        every time instead of randomly doing different things on some systems
        and also it represents that time as the equivalent UTC time.
        z%Y-%m-%dT%H:%M:%S%z:N)
astimezoner   r    r!   strftime)datetime_valisotimes     r%   __consistent_isoformat_utcz#Mastodon.__consistent_isoformat_utcz   s_     ))(*;*?@@IIJ_``2;#crclS(7233<7Gr'   NTFc                    d}d}| j         }||}|||d<   |r| j        dk    r| j        dk    rF| j        t	          j                    z
  }|dk    r$t          |d          }t	          j        |           n]t	          j                    | j        z
  }t          | j        t	          j                    z
            t          | j                  z  }||z
  }|dk    r.|| j	        z  }t          |d          }t	          j        |           t          j        |          }| j        d| j        z   |d<   |d|z   |d<   | j        r
| j        |d<   | j        }||}| j        rNt!          d	| | d
| d           t!          d|            t!          d|            t!          d|            d}|s4d}d}	 t#          ||| j                  }|	r||d<   n|dk    r||d<   n||d<    | j        j        |||z   fi |}n$# t*          $ r}t-          d|           d}~ww xY w|t/          d          d|j        v r|rt3          |j        d                   | _        t3          |j        d                   | _        	 t7          t3          |j        d                             }n	#  d}Y nxY w	 |1||j        d         k    r t3          |j        d                   | _        nDt8          j                            |j        d                   }|                     |          | _        d|j        v r}t8          j                            |j        d                   }|                     |          }t	          j                    |z
  }| xj        |z  c_        t	          j                    | _        n$# t*          $ r}tA          d|           d}~ww xY w| j        rFt!          d|j!         d           t!          d|j                    t!          d |j"                    |j#        s	 |$                    | j%        !          }tM          |t"                    rd"|v r	|d"         }ntM          |t6                    r|}nd}n# tN          $ r d}Y nw xY w|j!        d#k    rn| j        d$k    s|stA          d%          | j        d&v rI| j        t	          j                    z
  }|dk    r(t          |d          }t	          j        |           d}^|s|j!        d'k    rtP          }|sd(}n|j!        d)k    rtR          }nq|j!        d*k    rtT          }n^|j!        d+k    rtV          }nK|j!        d,k    rtX          }n8|j!        d-k    rtZ          }n%|j!        d*k    r|j!        d.k    rt\          }nt^          } |d/|j!        |j0        |          |r|S |
rB	 |$                    | j%        !          }n,#  t_          d0|j!         d1|j1        d          xY w|j1        }tM          |td                    rd2|j        v r|j        d2         d3k    rtg          |          }th          j5        6                    |j        d2         7                    d4          8                    d5d6                    } | D ]<}!d7|!vr|!d7         d8k    r|!d9         }"ts          j:        d:|"          }#|#rt          j        |          }$||$d;<   ||$d<<   |#;                    d=          }%|%<                                rt3          |%          |$d><   n|%|$d><   d?|$v r|$d?= d@|$v r|$d@= |$|_=        tM          |dA         t|                    r|$|dA         _=        |!d7         dBk    r`|!d9         }&ts          j:        dC|&          }#|#rt          j        |          }'||'d;<   ||'d<<   |#;                    d=          }(|(<                                rt3          |(          |'d?<   n|(|'d?<   d>|'v r|'d>= |'|_?        tM          |d         t|                    r|'|d         _?        ts          j:        dD|&          }#|#rt          j        |          }'||'d;<   ||'d<<   |#;                    d=          })|)<                                rt3          |)          |'d@<   n|)|'d@<   d>|'v r|'d>= |'|_?        tM          |d         t|                    r|'|d         _?        >|4|S )Ez.
        Internal API request helper.
        Nr   langpacei,  Bearer Authorization
User-AgentzMastodon: Request to endpoint "z" using method "z".zParameters: z	Headers: zFiles: FT)headersfilestimeoutjsonGETparamsdatazCould not complete request: zIllegal request.zX-RateLimit-RemainingzX-RateLimit-LimitzX-RateLimit-ResetDatez%Rate limit time calculations failed: z&Mastodon: Response received with code .zresponse headers: zResponse text content: )object_hookerrori  throwzHit rate limit.)waitr   i  zEndpoint not found.i  i  i  i  i  i  zMastodon API returned errorz4Could not parse response as JSON, response code was z, bad json content was Link >z>,<z,<relnexturlz[?&]max_id=([^&]+)_pagination_method_pagination_endpointr   max_idsince_idmin_idprevz[?&]since_id=([^&]+)z[?&]min_id=([^&]+))@r~   ratelimit_methodratelimit_remainingratelimit_resettimeminsleepratelimit_lastcallfloatratelimit_pacefactorcopydeepcopyaccess_token
user_agentapi_base_urldebug_requestsprintr0   request_timeoutsessionrequest	Exceptionr   r	   r   rC   ratelimit_limitstrrE   rF   rG   _Mastodon__datetime_to_epochr
   status_codetextokr   _Mastodon__json_hooksr/   rm   r   r   r   r   r   r   r   r   reasoncontentlistr   requestsutilsparse_header_linksrstripr   researchgroupisdigit_pagination_nextr   _pagination_prev)*r#   methodendpointr   r   r   access_token_overridebase_url_overridedo_ratelimitinguse_jsonrG   return_response_objectskip_error_checklang_overrideresponseremaining_waitr~   to_nexttime_waited	time_waitbase_urlrequest_completeresponse_objectkwargseratelimit_intrepratelimit_reset_datetimeserver_time_datetimeserver_timeserver_time_diff	error_msgex_typetmp_urlsr   next_urlmatchgroupsnext_paramsr   prev_urlprev_paramsr   r   s*                                             r%   __api_requestzMastodon.__api_request   s
   
  y$ D!F6N  	$t4>>'1,,.<Q;;!'622GJw'''"ikkD,CC!$"6"DEEdNfHgHgg	!*[!8!!(4+DDgv..
7### -((('043D'DGO$ ,'03H'HGO$ ? 	4$(OGL! $((H 	%bHbhbbX^bbbccc)))***'g''(((#E##$$$ !" I	K#"OOgUDDXYYY ,%+F6NNu__'-F8$$%+F6N"6$,"6vx(?R"]"]V\"]"] O O O*+M!+M+MNNNO &23EFFF '/*AAAoA+.#+,CD,F ,F('*#+,?@(B (B$,'*3/FGZ/[+\+\']']$$,'+$$$^'38HOLcdwLx8x8x/2+34GH0J 0J,, 4<?3H3HI`atIu3v3v0/3/G/GH`/a/a, !888/7/D/D_E\]cEd/e/e,&*&>&>?S&T&T+/9;;+D(,,0@@,,26)++/  ^ ^ ^01\YZ1\1\]]]^ " H]?Z]]]^^^D?+BDDEEEF0DFFGGG"% 0A	%.33@Q3RRH!(D11 )g6I6I$,W$5		#Hc22 )$,		$(	! % % % $III% #.#55,77745FGGG.2BBB"&"6"D"Q;;&)'6&:&:G Jw////4,$' A&2c99"7( >(=I )4;;";(4;;"=(4;;"9(4;;"A(4;;"=(4;;@[_b@b@b"5"2!'"?A\^m^tv  A  A  A% '&& 	3.33@Q3RRHH*MOj M M0?0GM M M  
 +2 (D)) OKo555#+F3r99+H55#><<#+F3::3??GGtTTV V# IK IKCC'' 5zV++#&u:&(i0Ex&P&P& L*.-*?*?K@FK(<=BJK(>?%0%6%6q%9%9F%~~// ?8;FH 5 58>H 5)[88$/
$;';66$/$98CH5  *(2,8HII L@K =5zV++#&u: ')i3X'? '?& K*.-*?*?K@FK(<=BJK(>?'2'8'8';';H'//11 C:=h--J 7 7:BJ 7';66$/$98CH5  *(1+7GHH K?J < ')i18'= '=& K*.-*?*?K@FK(<=BJK(>?%0%6%6q%9%9F%~~// ?8;FH 5 58>H 5';66$/$98CH5  *(1+7GHH K?J <S # I	KV s]   3AG; ;
HHH<'J$ $J*.C=N, ,
O6OO&AQ> >RRW! !"Xc                 J   |                                  }d|d         v r}|d         d         | j        k    rft          |d         d                   }|j        dk    rd|j        z   }n<|j        dk    rd|j        z   }n&t          d|d         d          d          | j        }|S )	zh
        Internal streaming API helper.

        Returns the correct URL for the streaming API.
        streaming_apiurlswsshttps://wshttp://z=Could not parse streaming api location returned from server: r   )instancer   r   schemenetlocr   )r#   r   rG   r   s       r%   __get_streaming_basezMastodon.__get_streaming_base  s     ==??hv...8F3CO3TX\Xi3i3i Xf-o>??E|u$$ 5</%%%,.&xT\]cTdetTuxxx   #C
r'   c                                                       d         dk    r
dd          fd}d}	 G fdd          }
|rF |
|	|||          }t          j        d|j                  }d	|_        |                                 |S  |            }	t          |	          5 }                    |           ddd           dS # 1 swxY w Y   dS )
z
        Internal streaming API helper.

        Returns a handle to the open connection that the user can close if they
        wish to terminate it.
        r   /Nc                      j         rddj         z   ini } j        r
j        | d<   j                            z   | dj        f          }|j        dk    rt          d|j                   |S )Nr   r   r   T)r   r   streamr      z'Could not connect to streaming server: )r   r   r   getr   r   r   r   )r   
connectionr   r   r#   r   r   s     r%   connect_funcz'Mastodon.__stream.<locals>.connect_func  s    JNJ[c	D4E(EFFacG 8(,%))#.'PV_c595I74S * U UJ %,,*+hU_Uf+h+hiiir'   c                   8    e Zd Zd Zd Zd Zd Zd Z fdZdS )*Mastodon.__stream.<locals>.__stream_handlec                 h    d| _         d| _        || _        || _        || _        || _        d| _        d S NFT)closedrunningr   r   reconnect_asyncreconnect_async_wait_secreconnecting)r#   r   r   r   r   s        r%   __init__z3Mastodon.__stream.<locals>.__stream_handle.__init__  s=    ##",$0!'6$0H-$)!!!r'   c                 X    d| _         | j        | j                                         d S d S )NT)r   r   closer,   s    r%   r  z0Mastodon.__stream.<locals>.__stream_handle.close  s3    "?.O))+++++ /.r'   c                 4    | j                                         S )N)_threadis_aliver,   s    r%   r  z3Mastodon.__stream.<locals>.__stream_handle.is_alive  s    |,,...r'   c                 \    | j         s"| j        r| j        s|                                 sdS dS r   )r   r   r  r  r,   s    r%   is_receivingz7Mastodon.__stream.<locals>.__stream_handle.is_receiving  s8    ;  dl  d6G  t}}   54r'   c                     | j         t          j                    k    rt          d          | j        }|dk    r/| j        s,t          j        d           |dz  }|dk    r| j        &d S d S d S d S )Nz2Illegal call from outside the stream_handle threadr   g      ?)r  	threadingcurrent_threadRuntimeErrorr   r   r   r   )r#   time_remainings     r%   _sleep_attentivez;Mastodon.__stream.<locals>.__stream_handle._sleep_attentive  s    <9#;#=#===&LN N N!%!>$q(((JsOOO"c)N %q(((((((((((r'   c                 6   t          j                    | _        | j        rw| j        t          | j                  5 }	                     |           nB# t          t          t          f$ r(}| j
        s	| j        s|| j
        rd| _        Y d }~nd }~ww xY wd d d            n# 1 swxY w Y   | j        r| j
        r| j        d| _        d}|s| j
        rd| _        n	 |                                 }|j        dk    r@t          d|j                   }                    |           |                                  | j
        r|                                 n	|| _        d}n#  |                                  d}Y nxY w|d| _        nd| _        | j        wdS )NFTr   z*Could not connect to server. HTTP status: r   )r  r  r  r   r   r   handle_streamAttributeErrorr   r   r   r   r  r   r   on_abortr  r  )r#   rr   connect_successthe_connection	exceptionlisteners         r%   _threadprocz6Mastodon.__stream.<locals>.__stream_handle._threadproc  s=   (799 l (-2$T_55 == ( 6 6q 9 9 9 9$24OQe#f = = =(, !=t7K !=*+G'+{ %=7<== = = = = = = = = = = = = = = , -T[ -T_E\,0)*/"1 8#{ &/4 %8151B1B1D1D#1#=#D#D0D FuXfXrFu Fu 1v 1vI$,$5$5i$@$@$@$($9$9$;$;$;#'; !; %3$8$8$:$:$:$:6DDO6:O8 $ 5 5 7 7 727+ #2 8, -2))',Q l (-R qsG   B#AB#B,B
B#BB##B'*B'BE# #E=N)	__name__
__module____qualname__r  r  r  r	  r  r  )r  s   r%   __stream_handler     sy        * * *, , ,
/ / /     * * *- - - - - - -r'   r   )argstargetT)_Mastodon__get_streaming_baser  Threadr  daemonstartr   r  )r#   r   r  r   	run_asyncr   r   r   r   r   _Mastodon__stream_handlehandletr  r   s   ```` `        @r%   __streamzMastodon.__stream  s    '')) r7c>>crc(C		 		 		 		 		 		 		 		 		 
N	 N	 N	 N	 N	 N	 N	 N	 N	 N	`  	*$_L/;SU UF b1CDDDAAHGGIIIM &J$$ *&&q)))* * * * * * * * * * * * * * * * * *s   ,CCCc                    t          j        |          }d|v r|d= t          |                                          }|D ],}t	          ||         t
                    r||         rdnd||<   -|D ]}||         ||v r||= t          |                                          }|D ].}t	          ||         t                    r||         ||dz   <   ||= /|S )a,  
        Internal named-parameters-to-dict helper.

        Note for developers: If called with locals() as params,
        as is the usual practice in this code, the __generate_params call
        (or at least the locals() call) should generally be the first thing
        in your function.
        r#   10Nz[])collectionsOrderedDictr   keysr/   bool)r#   r   exclude
param_keysr_   s        r%   __generate_paramszMastodon.__generate_params  s     (00Vv&++--((
 	: 	:C&+t,, :%+C[9cccs 	  	 Cc{"cWnn3K&++--((
 	  	 C&+t,,  %+C[sTz"3Kr'   c                     t          |t                    rd|v r|d         }|rAt          |t          j                  r't          |                                          dz  dz  }|S )z
        Internal object-to-id converter

        Checks if id is a dict that contains id and
        returns the id inside, otherwise just returns
        the id straight.

        Also unpacks datetimes to snowflake IDs if requested.
        r+      i  )r/   r0   r   rC   r"   )r#   r+   dateconvs      r%   __unpack_idzMastodon.__unpack_id=  sg     b$ 	DBJJDB 	4
2x'899 	4bllnn%%+t3B	r'   c                 p    t          |          dz  }|dk    r|dd|z
  z  z  }t          j        |          S )z5
        Re-pads and decodes urlsafe base64.
           r   =)lenbase64urlsafe_b64decode)r#   r   missing_paddings      r%   __decode_webpush_b64zMastodon.__decode_webpush_b64M  sC     d))a-aC1.//D'---r'   c                 P    | j         t          j                                        k     S Internal helper for oauth code)_token_expiredr   nowr,   s    r%   __get_token_expiredzMastodon.__get_token_expiredV  s    "X%6%:%:%<%<<<r'   c                 x    t           j                                         t          j        |          z   | _        dS )rB  )secondsN)r   rD  	timedeltarC  r#   rh   s     r%   __set_token_expiredzMastodon.__set_token_expiredZ  s2    &/33558JSX8Y8Y8YYr'   c                     | j         S rA  _refresh_tokenr,   s    r%   __get_refresh_tokenzMastodon.__get_refresh_token_  s    ""r'   c                     || _         dS )rB  NrL  rI  s     r%   __set_refresh_tokenzMastodon.__set_refresh_tokenc  s    #r'   c                     d}	 t          j        |d          }n*# t          $ r t          j        |          d         }Y nw xY w|S )z(Internal helper to guess media file typeNT)mimer   )r   	from_filer  	mimetypes
guess_type)r#   
media_file	mime_types      r%   __guess_typezMastodon.__guess_typeh  s\    		<
>>>II 	< 	< 	<!,Z88;III	<s    $AAc                 N   t          |t                    rt          |          }t          |t                    r7	 t          t          |                                                    }n#  Y nxY wt          |t                    rDt
          j                            |          r%|                     |          }t          |d          }|t          d          |Et          j                    j        }dt          j                     d| t          j        |           }|||fS )NrbzHCould not determine mime type or data passed directly without mime type.mastodonpyupload__)r/   r   r   r   resolveospathisfile_Mastodon__guess_typeopenr	   uuiduuid4hexr   rT  guess_extension)r#   rV  rW  	file_namerandom_suffixs        r%   __load_media_filezMastodon.__load_media_fileq  s   j(++ 	)ZJj#&& 	 j!1!1!9!9!;!;<<

j#&& 	027>>*+E+E 	0))*55Ij$//J./yzzz JLL,MoDIKKoo-oIbclImImooI:y11s   .A* *A.c                     |                      d          s|                      d          sd| z   } |                     d          } | S )z#Internal add-protocol-to-url helperr   r   r   )
startswithr   r   s    r%   __protocolizezMastodon.__protocolize  sQ     ""9-- 	-h6I6I*6U6U 	-!H,H ??3''r'   c                     |                      d          r| dd         } n4|                      d          s|                      d          r
| dd         } | S )z2Internal helper to strip http and https from a URLr      Nr   zonion://   )rk  rl  s    r%   __deprotocolizezMastodon.__deprotocolize  sf     y)) 	$|HH  ,, 	$0C0CJ0O0O 	$|Hr'   c                    |                     d          d         }	 t          |                     d          d                    |                     d          d         S #  |                     d          d         cY S xY w)N r   +r   )splitr   )r#   version_strings     r%   __normalize_version_stringz#Mastodon.__normalize_version_string  s    '--c2215	0 !5!5c!:!:1!=>>>!'',,Q//	0!'',,Q////s   AA   A?)F)NN)r  r  r  r   _Mastodon__get_logged_in_idstaticmethodrs   rq   rr   rp   r   #_Mastodon__consistent_isoformat_utc_Mastodon__api_requestr!  r   r   _Mastodon__stream_Mastodon__generate_params_Mastodon__unpack_id_Mastodon__decode_webpush_b64_Mastodon__get_token_expired_Mastodon__set_token_expired_Mastodon__get_refresh_token_Mastodon__set_refresh_tokenra  _Mastodon__load_media_file_Mastodon__protocolize_Mastodon__deprotocolize#_Mastodon__normalize_version_stringr  r'   r%   r   r      s0       	% 	% 	%# # #   \   \. 
 
 \
   \   \ 	 	 \	 68r2ei  ~B(,uDafy~  OSE E E EN  . 35Ofx}  Y{ x* x* x* x*t 13    >    . . .= = =  
# # #  
  2 2 2 2$   \   \	0 	0 	0 	0 	0r'   r   )*r   
contextlibr   rT  r  r[   rc  dateutil.parserrE   r   r   r   r   r-  r<  r^  utilityr   r   r   errorsr   r	   r
   r   r   r   r   r   r   r   r   r   compatr   r   r   r   defaultsr   r   r   r  r'   r%   <module>r     s                  



         				      				 M M M M M M M M M Mt t t t t t t t t t t t t t t t t t t t t t t t t t t t 4 3 3 3 3 3 3 3 3 3 3 3 Q Q Q Q Q Q Q QB
0 B
0 B
0 B
0 B
0 B
0 B
0 B
0 B
0 B
0r'   