o
    ~hp<                     @   s  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 d dl	m
Z
 d dlmZ d dlmZ d dlmZmZmZmZmZ d dlmZ d dlmZmZmZmZmZ d d	lmZ d d
lm Z  d dl!m"Z" d dl#m$Z$ d dl%m&Z& deee'ef  deee'ef  fddZ(dPdee' dee' fddZ)de'de'de'fddZ*de+dee' de,de,dee+ dee'e'f fdd Z-d!e+d"e+ddfd#d$Z.dee' d%e'd&e+d'e+d"e+de+d(e+de+d)e+d*ee d+ee' de+fd,d-Z/dQd.d/Z0d0ee'eee'e'f  f ddfd1d2Z1de,fd3d4Z2d5edeee'f fd6d7Z3d8e'd9ee'ef ddfd:d;Z4d<e'de'fd=d>Z5d?e+de+fd@dAZ6dBee'ef dee'ee f fdCdDZ7		dPdEe'd'e8dFe9dGej:d+ee' d*ee dee'ef fdHdIZ;dJedKef ddfdLdMZ<dNdO Z=dS )R    N)Future)HTTPResponse)IOBase)
SSLContext)AnyDictOptionalSequenceUnionurljoin)OpenerDirectorProxyHandlerHTTPSHandlerRequesturlopen)version)SlackRequestError)
Attachment)Block)Metadataparamsreturnc                 C   s   | rdd |   D S dS )aJ  Converts all bool values in dict to "0" or "1".

    Slack APIs safely accept "0"/"1" as boolean values.
    Using True/False (bool in Python) doesn't work with aiohttp.
    This method converts only the bool values in top-level of a given dict.

    Args:
        params: params as a dict

    Returns:
        Modified dict
    c                 S   s   i | ]	\}}|t |qS  )_to_0_or_1_if_bool.0kvr   r   T/var/www/html/zoom/venv/lib/python3.10/site-packages/slack_sdk/web/internal_utils.py
<dictcomp>%   s    z*convert_bool_to_0_or_1.<locals>.<dictcomp>Nitems)r   r   r   r   convert_bool_to_0_or_1   s   r#   prefixsuffixc                 C   sp   d dtj}dj tjd}d t t }d|||g}| r'|  dnd} |r0d| nd}| | | S )zConstruct the user-agent header with the package info,
    Python version and OS version.

    Returns:
        The user agent string.
        e.g. 'Python/3.6.7 slackclient/2.0.0 Darwin/17.7.0'
    z{0}/{1}slackclientz$Python/{v.major}.{v.minor}.{v.micro}r     )	formatr   __version__sysversion_infoplatformsystemreleasejoin)r$   r%   clientpython_versionsystem_infouser_agent_stringr   r   r   get_user_agent)   s   	r6   base_url
api_methodc                 C   s
   t | |S )a*  Joins the base Slack URL and an API method to form an absolute URL.

    Args:
        base_url (str): The base URL
        api_method (str): The Slack Web API method. e.g. 'chat.postMessage'

    Returns:
        The absolute API URL.
            e.g. 'https://slack.com/api/chat.postMessage'
    r   )r7   r8   r   r   r   _get_url;   s   
r9   headerstokenhas_json	has_filesrequest_specific_headersc                 C   s   ddi}| du sd| vrt  |d< |r|dd|i | du r#i } ||  |r/|| |r8|ddi |r@|dd |S )a3  Constructs the headers need for a request.
    Args:
        has_json (bool): Whether or not the request has json.
        has_files (bool): Whether or not the request has files.
        request_specific_headers (dict): Additional headers specified by the user for a specific request.

    Returns:
        The headers dictionary.
            e.g. {
                'Content-Type': 'application/json;charset=utf-8',
                'Authorization': 'Bearer xoxb-1234-1243',
                'User-Agent': 'Python/3.6.8 slack/2.1.0 Darwin/17.7.0'
            }
    zContent-Typez!application/x-www-form-urlencodedNz
User-AgentAuthorizationz	Bearer {}zapplication/json;charset=utf-8)r6   updater*   pop)r:   r;   r<   r=   r>   final_headersr   r   r   _get_headersI   s    


rC   targetdefault_paramsc                 C   s&   |  D ]\}}|| vr|| |< qd S Nr!   )rD   rE   namevaluer   r   r   _set_default_params{   s
   rI   	http_verbfilesdatajsonauthsslproxyc              	   C   s$  |d u}|d u}|r|dkrd}t ||d ur+t|tr+dd | D }t|| |d ur=t|tr=dd | D }|d urTt|trTdd | D }t|| |d urbt|trbt|| | } |d urqd|v rq|d} |d ur~d|v r~|d} t|| |||d|||||	|
|d	}|S )
NPOSTz`Json data can only be submitted as POST requests. GET requests should use the 'params' argument.c                 S      i | ]\}}|d ur||qS rF   r   r   r   r   r   r           z#_build_req_args.<locals>.<dictcomp>c                 S   rR   rF   r   r   r   r   r   r       rS   c                 S   rR   rF   r   r   r   r   r   r       rS   r;   )r:   r;   r<   r=   r>   )r:   rL   rK   r   rM   rO   rP   rN   )r   
isinstancedictr"   rI   rA   rC   )r;   rJ   rK   rL   rE   r   rM   r:   rN   rO   rP   r<   r=   msgreq_argsr   r   r   _build_req_args   sH   




rX   c                    s   dt ttttf fdd dD ]&}| |d }|d ur5t|tr5t|ts5 fdd|D }| 	||i q| dd }|d urZt|trZt|tsZ fdd|D }| 	d|i | d	d }|d urtt|trv| 	d	 |i d S d S d S )
Nobjc                 S   s:   t | tr	|  S t | tr|  S t | tr|  S | S rF   )rT   r   to_dictr   r   )rY   r   r   r   rZ      s   


z)_parse_web_class_objects.<locals>.to_dict)blocksuser_auth_blocksc                       g | ]} |qS r   r   )r   brZ   r   r   
<listcomp>       z,_parse_web_class_objects.<locals>.<listcomp>attachmentsc                    r]   r   r   )r   ar_   r   r   r`      ra   metadata)
r
   r   r   r   r   getrT   r	   strr@   )kwargsblocks_namer[   dict_blocksrb   dict_attachmentsrd   r   r_   r   _parse_web_class_objects   s   	rk   usersc                 C   sR   |d u rd S t |tr| dt|i d S t |tr%| d|i d S td)Nrl   z4users must be either str or Sequence[Dict[str, str]])rT   listr@   rM   dumpsrf   r   )rg   rl   r   r   r   _update_call_participants   s   

ro   c                 C   sX   d| v r| d dur| d dkp)d| v o)d| d v o)| d d duo)| d d dk}|S )zDetermine if the response contains 'next_cursor'
    and 'next_cursor' is not empty.

    Returns:
        A boolean value.
    next_cursorNr)   response_metadatar   )rL   presentr   r   r   _next_cursor_is_present   s    
rs   r   c                 C   s   t | tr| r	dS dS | S )N10)rT   boolr'   r   r   r   r      s   
r   endpointrg   c                 C   s   | d}|rt| dkrd S tj d}|rd S d|  d}d|  d}| d}|d urNt|trNtd	d
 |D sLt	|t
 t	|t
 d S d S t	|t
 d S )Ntextr   SKIP_SLACK_SDK_WARNINGzFThe top-level `text` argument is missing in the request payload for a z call - It's a best practice to always provide a `text` argument when posting a message. The `text` argument is used in places where content cannot be rendered such as: system push notifications, assistive technology such as screen readers, etc.z_Additionally, the attachment-level `fallback` argument is missing in the request payload for a aF   call - To avoid this warning, it is recommended to always provide a top-level `text` argument when posting a message. Alternatively you can provide an attachment-level `fallback` argument, though this is now considered a legacy field (see https://api.slack.com/reference/messaging/attachments#legacy_fields for more details).rb   c                 S   s.   g | ]}t |tot|d d dkqS )fallbackr)   r   )rT   rU   lenre   strip)r   
attachmentr   r   r   r`     s   . zC_warn_if_text_or_attachment_fallback_is_missing.<locals>.<listcomp>)re   r{   r|   osenvironrT   rm   allwarningswarnUserWarning)rw   rg   rx   skip_deprecationmissing_text_messagemissing_fallback_messagerb   r   r   r   /_warn_if_text_or_attachment_fallback_is_missing   s&   




r   bodyc                 C   sL   d dd | dddD }t|dkr|d d d }d| }|S )	Nr)   c                 S   s   g | ]}|  qS r   )r|   )r   liner   r   r   r`   '  ra   z8_build_unexpected_body_error_message.<locals>.<listcomp>
d   z...z*Received a response in a non-JSON format: )r1   replacesplitr{   )r   body_for_loggingmessager   r   r   $_build_unexpected_body_error_message&  s
   "
r   dc                 C   s   dd |   D S )Nc                 S   rR   rF   r   r   r   r   r   r    6  rS   z'_remove_none_values.<locals>.<dictcomp>r!   )r   r   r   r   _remove_none_values.  s   r   upload_filec                 C   sd  |  d}|  d}d }|d urRt|tr3t|ddd}| }W d    n1 s-w   Y  n:t|tr;|}n2t|trN| }t|trM| }ntd|d urmt|tra|d}nt|tri|}ntd|  d}|d u rt|tr|	t
jjd	 }nd
}|  dd
}|d u rtd| d| |d u r|}||t|||  d|  ddS )Nfilecontentutf-8ignorerbz<file parameter must be any of filepath, bytes, and io.IOBasezKcontent for file upload must be 'str' (UTF-8 encoded) or 'bytes' (for data)filenamezUploaded filetitlez%File content not found for filename: z	, title: alt_txtsnippet_type)r   rL   lengthr   r   r   )re   rT   rf   openencodereadbytesr   r   r   r~   pathsepr{   )r   r   r   rL   readabler   r   r   r   r   _to_v2_file_upload_item9  sP   










r   urltimeoutloggerc                 C   s   d }|d ur#t |trtjt||dt|d}ntd| d|jt	j
kr1|d|   d }td| |i d}|rE|j||d}nt|||d	}|j pRd
}	| |	}
|jt	j
krtd|j dt|j d|
 }|| |j|j|
dS )N)httphttps)contextzInvalid proxy detected: z must be a str valuezSending a request: POST rQ   )methodr   rL   r:   )r   )r   r   r   z*Received the following response - status: z, headers: z, body: )statusr:   r   )rT   rf   urllibrequestbuild_openerr   r   r   levelloggingDEBUGdebugr   r   r   r:   get_content_charsetr   decoder   rU   )r   rL   r   r   rP   rO   openerrespreqcharsetr   r   r   r   r   _upload_file_via_v2_urlj  s8   

r   responseSlackResponsec                 C   s   t | trd}t|d S )NzSorry! This SDK does not support run_async=True option for this API calls. Please migrate to AsyncWebClient, which is a new and stable way to go.)rT   r   r   )r   r   r   r   r   _validate_for_legacy_client  s
   
r   c                  C   s   d} t |  d S )Nzclient.files_upload() may cause some issues like timeouts for relatively large files. Our latest recommendation is to use client.files_upload_v2(), which is mostly compatible and much stabler, instead.)r   r   )r   r   r   r   !_print_files_upload_v2_suggestion  s   r   )NN)r   N)>rM   r   r~   r.   r,   r   r   asyncior   http.clientr   ior   rO   r   typingr   r   r   r	   r
   urllib.parser   urllib.requestr   r   r   r   r   	slack_sdkr   slack_sdk.errorsr   slack_sdk.models.attachmentsr   slack_sdk.models.blocksr   slack_sdk.models.metadatar   rf   r#   r6   r9   rU   rv   rC   rI   rX   rk   ro   rs   r   r   r   r   r   r   intLoggerr   r   r   r   r   r   r   <module>   s    *

2	


:&.&6

*

