o
     JAf?                  	   @   s<  	 d dl Z d dlZd dlZd dlZd dlZzd dlZW n ey&   dZY nw dZd dlm	Z
 d dlmZ g dZdZG dd	 d	eZG d
d deZG dd deZG dd deZG dd deZG dd deZdZdZh dZg dZdddZdZedg dZedg dZd d! Z	d"d# ZdYd$d%ZdYd&d'Z dZd(d)Z!erd*d+ Z"G d,d- d-Z#erG d.d/ d/e#Z$e%d/ e&d0krd dl'Z'e'j(d1d2Z)e)j*d3d4d5d6d7 e)j*d8d9d:d;d7 e)j*d<d=d>e+d?eef d@ e)j*dAdBdCe+dDd@ e)j*dEdFdGddHdI e), Z-e-j.Z.e-jse.d>kreZ.e#e-j/e.dJZ0ne.d>kr%eZ.e$e-j/e.dJZ0e01 Z2dKe2v r9e03  e04e-j4\Z5Z6Z7Z8Z9e:dLe9dMe6dNe7dOe8 dPdQ Z;e<e+e8e-j= dR Z7e0>e7e8\Z5Z?e?D ]-\Z@ZAe	eAdS BdTdRd  ZCe	eAdU ZDe+eAd ZEe:dVFe@e;eCdWe;eDdXeE qhe0G  dS dS )[    NFT)decode_header)_GLOBAL_DEFAULT_TIMEOUT)NNTP	NNTPErrorNNTPReplyErrorNNTPTemporaryErrorNNTPPermanentErrorNNTPProtocolErrorNNTPDataErrorr   i   c                   @   s   e Zd Z	 dd ZdS )r   c                 G   s>   t j| g|R   z|d | _W d S  ty   d| _Y d S w )Nr   zNo response given)	Exception__init__response
IndexError)selfargs r   /usr/lib/python3.10/nntplib.pyr   b   s   zNNTPError.__init__N)__name__
__module____qualname__r   r   r   r   r   r   `   s    r   c                   @      e Zd Z	 dS )r   Nr   r   r   r   r   r   r   r   i       r   c                   @   r   )r   Nr   r   r   r   r   r   m   r   r   c                   @   r   )r   Nr   r   r   r   r   r   q   r   r   c                   @   r   )r	   Nr   r   r   r   r   r	   u   r   r	   c                   @   r   )r
   Nr   r   r   r   r   r
   y   r   r
   w   i3  >   Z100Z231215Z221Z224Z222Z230Z282Z225Z101Z220211)subjectfromdatez
message-idZ
references:bytes:linesr   r    )byteslines   
	GroupInfo)grouplastfirstflagArticleInfo)Znumber
message_idr"   c                 C   sL   	 g }t | D ]\}}t|tr|||pd q|| qd|S )Nascii )_email_decode_header
isinstancer!   appenddecodejoin)Z
header_strpartsvencr   r   r   r      s   

r   c                 C   s   	 g }| D ]0}|d dkr|dd   d\}}}d| }n| d\}}}| }t||}|| qt}t|t|k rDtd|d t| |krRtd|S )Nr   :   z$LIST OVERVIEW.FMT response too shortz*LIST OVERVIEW.FMT redefines default fields)	partitionlower_OVERVIEW_FMT_ALTERNATIVESgetr/   _DEFAULT_OVERVIEW_FMTlenr
   )r"   fmtlinename_suffixdefaultsr   r   r   _parse_overview_fmt   s    
rC   c                 C   s   	 t t}g }| D ]]}i }|d^}}t|}t|D ]B\}	}
|	t |kr'q||	 }|d}|	|krX|sX|d }|
rL|
d t |  |krLtd|
rV|
t |d  nd }
|
|||	 < q|||f q	|S )N	r5   z: z?OVER/XOVER response doesn't include names of additional headers)	r<   r;   splitint	enumerate
startswithr8   r
   r/   )r"   r=   Zdata_process_funcZ
n_defaultsZoverviewr>   fieldsZarticle_numbertokensitoken
field_nameZis_metadatahr   r   r   _parse_overview   s(   
rO   c                 C   s   	 |d u r| dd  }| d d } t |d d }t |dd }t |dd  }t | d d }t | dd }t | dd  }|dk rJ|d7 }n|dk rR|d	7 }t||||||S )
Ni      F   i  d   il  )rF   datetime)date_strtime_strZhoursZminutesZsecondsyearZmonthZdayr   r   r   _parse_datetime   s   
rZ   c                 C   sX   	 t | tjs
d}nd| }| j}|r"|d }d|| }||fS d|| }||fS )NZ000000z({0.hour:02d}{0.minute:02d}{0.second:02d}rU   z{0:02d}{1.month:02d}{1.day:02d}z{0:04d}{1.month:02d}{1.day:02d})r.   rV   formatrY   )ZdtlegacyrX   yrW   r   r   r   _unparse_datetime   s   
r^   c                 C   s    	 |d u r	t  }|j| |dS )N)Zserver_hostname)sslZ_create_stdlib_contextZwrap_socket)sockcontexthostnamer   r   r   _encrypt_on  s   rc   c                   @   s  e Zd ZdZdZeddddefddZdd Zd	d
 Z	dd Z
dd Zdd Zdd Zdd ZeZdd Zdd ZdiddZdd ZdjddZd d! Zdjd"d#Zdjd$d%Zd&d' Zd(d) Zd*d+ Zdd,d-d.Zdd,d/d0Zdjdd,d1d2Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!dd,d;d<Z"d=d> Z#d?d@ Z$djdAdBZ%dCdD Z&dEdF Z'djdGdHZ(djdd,dIdJZ)djdd,dKdLZ*djdd,dMdNZ+dOdP Z,dd,dQdRZ-dd,dSdTZ.dd,dUdVZ/dWdX Z0dYdZ Z1d[d\ Z2d]d^ Z3d_d` Z4dadb Z5dkdcddZ6dedf Z7e8rdjdgdhZ9dS dS )lr   zutf-8surrogateescapeNFc                 C   s~   	 || _ || _| || _d | _z| jd| _| | |s!|r+| ||| W d S W d S    | jr9| j  | j   )Nrwb)	hostport_create_socketr`   filemakefile
_base_initloginclose)r   rf   rg   userpassword
readermodeusenetrctimeoutr   r   r   r   8  s    


zNNTP.__init__c                 C   s`   	 d| _ |  | _d | _|   d| _|r(d| jvr(|   | js(d | _|   d| _d| _d S )Nr   FREADER)		debugging_getrespwelcome_capsgetcapabilitiesreadermode_afterauth_setreadermodetls_onauthenticated)r   rp   r   r   r   rk   [  s   
	
zNNTP._base_initc                 C   s   | S Nr   r   r   r   r   	__enter__}  s   zNNTP.__enter__c              	      sf    fdd}| r1zz    W n ttfy   Y nw W | r&   d S d S | r0   w w d S )Nc                      s
   t  dS )Nri   )hasattrr   r~   r   r   <lambda>  s   
 zNNTP.__exit__.<locals>.<lambda>)quitOSErrorEOFError_close)r   r   Zis_connectedr   r~   r   __exit__  s   

zNNTP.__exit__c                 C   s<   |d ur
|s
t dtd| | j| j t| j| jf|S )Nz0Non-blocking socket (timeout=0) is not supportedznntplib.connect)
ValueErrorsysauditrf   rg   socketcreate_connection)r   rr   r   r   r   rh     s   zNNTP._create_socketc                 C   s   	 | j rtdt| j | jS )Nz	*welcome*)rt   printreprrv   r~   r   r   r   
getwelcome  s   zNNTP.getwelcomec              	   C   s   	 | j d u rBd| _d | _z|  \}}W n ttfy$   i | _ Y | j S w || _ d|v r6ttt|d | _d|v rBd	|d | _| j S )Nr6   VERSIONZIMPLEMENTATION )
rw   nntp_versionZnntp_implementationcapabilitiesr   r   maxmaprF   r1   )r   respcapsr   r   r   rx     s    
	zNNTP.getcapabilitiesc                 C   s   	 || _ d S r}   )rt   )r   levelr   r   r   set_debuglevel  s   
zNNTP.set_debuglevelc                 C   sJ   	 t d| | |t }| jdkrtdt| | j| | j  d S )Nznntplib.putliner6   z*put*)	r   r   _CRLFrt   r   r   ri   writeflushr   r>   r   r   r   _putline  s   zNNTP._putlinec                 C   s4   	 | j rtdt| || j| j}| | d S )Nz*cmd*)rt   r   r   encodeencodingerrorsr   r   r   r   r   _putcmd  s   zNNTP._putcmdTc                 C   s   	 | j td }t|tkrtd| jdkrtdt| |s#t|rC|dd  t	kr5|d d }|S |dd  t	v rC|d d }|S )Nr6   zline too longz*get*rS   )
ri   readline_MAXLINEr<   r
   rt   r   r   r   r   )r   Z
strip_crlfr>   r   r   r   _getline  s   
zNNTP._getlinec                 C   sn   	 |   }| jrtdt| || j| j}|d d }|dkr%t||dkr-t||dvr5t	||S )Nz*resp*r6   45Z123)
r   rt   r   r   r0   r   r   r   r   r	   )r   r   cr   r   r   ru     s   zNNTP._getrespc                 C   s   	 d }zot |ttfrt|d }}|  }|d d tvr"t|g }|d urKdt df}	 | d}||v r9n|	drD|dd  }|
| q/nd}	 |  }||krWn|	drb|dd  }|| qNW |ro|  ||fS |rz|  w w )Nwb      .s   .
r6   Fs   ..)r.   strr!   openru   	_LONGRESPr   r   r   rH   r   r/   rm   )r   ri   Z
openedFiler   r"   Zterminatorsr>   
terminatorr   r   r   _getlongresp  sH   




	
zNNTP._getlongrespc                 C   s   	 |  | |  S r}   )r   ru   r   r   r   r   	_shortcmd  s   
zNNTP._shortcmdc                 C   s   	 |  | | |S r}   r   r   )r   r>   ri   r   r   r   _longcmd  s   

zNNTP._longcmdc                    s0   	   |  |\}}| fdd|D fS )Nc                    s   g | ]
}|  j jqS r   )r0   r   r   .0r>   r~   r   r   
<listcomp>+  s    z'NNTP._longcmdstring.<locals>.<listcomp>r   )r   r>   ri   r   listr   r~   r   _longcmdstring$  s   
zNNTP._longcmdstringc                 C   sb   	 z| j W S  ty   Y nw z	| d\}}W n ty'   td d  }Y nw t|}|| _ |S )NzLIST OVERVIEW.FMT)Z_cachedoverviewfmtAttributeErrorr   r   r;   rC   )r   r   r"   r=   r   r   r   _getoverviewfmt.  s   zNNTP._getoverviewfmtc                 C   s   dd |D S )Nc                 S   s   g | ]}t |  qS r   )r$   rE   r   r   r   r   r   A  s    z#NNTP._grouplist.<locals>.<listcomp>r   )r   r"   r   r   r   
_grouplist?  s   zNNTP._grouplistc                 C   s:   	 i }|  d\}}|D ]}| ^}}|||< q||fS )NZCAPABILITIES)r   rE   )r   r   r   r"   r>   r?   rJ   r   r   r   r   C  s   
zNNTP.capabilities)ri   c                C   sd   	 t |tjtjfstd|jjt|| jdk \}}d||}| 	||\}}|| 
|fS )NAthe date parameter must be a date or datetime object, not '{:40}'rP   zNEWGROUPS {0} {1})r.   rV   r   	TypeErrorr[   	__class__r   r^   r   r   r   )r   r   ri   rW   rX   cmdr   r"   r   r   r   	newgroupsQ  s   
zNNTP.newgroupsc                C   sT   	 t |tjtjfstd|jjt|| jdk \}}d|||}| 	||S )Nr   rP   zNEWNEWS {0} {1} {2})
r.   rV   r   r   r[   r   r   r^   r   r   )r   r%   r   ri   rW   rX   r   r   r   r   newnewsa  s   
zNNTP.newnewsc                C   s6   	 |d ur
d| }nd}|  ||\}}|| |fS )NzLIST ACTIVE LIST)r   r   )r   group_patternri   commandr   r"   r   r   r   r   q  s   
z	NNTP.listc                 C   s   t d}| d| \}}|ds| d| \}}i }|D ]}|| }|r=|dd\}	}
|s9|
  S |
||	< q |rD||fS dS )Nz^(?P<group>[^ 	]+)[ 	]+(.*)$zLIST NEWSGROUPS r   zXGTITLE r6   rP   r,   )recompiler   rH   searchstripr%   )r   r   Z
return_allZline_patr   r"   groupsZraw_linematchr?   Zdescr   r   r   _getdescriptions  s    

zNNTP._getdescriptionsc                 C      	 |  |dS )NFr   )r   r%   r   r   r   description  s   
zNNTP.descriptionc                 C   r   )NTr   )r   r   r   r   r   descriptions  s   zNNTP.descriptionsc                 C   s   	 |  d| }|dst|| }d } }}t|}|dkrA|d }|dkrA|d }|dkrA|d }|dkrA|d  }|t|t|t||fS )NzGROUP r   r   r6   rP   r   rQ   )r   rH   r   rE   r<   r8   rF   )r   r?   r   wordscountr'   r&   nr   r   r   r%     s    	
z
NNTP.groupc                C      	 |  d|S )NZHELP)r   )r   ri   r   r   r   help  s   z	NNTP.helpc                 C   s:   	 | ds
t|| }t|d }|d }|||fS )NZ22r6   rP   )rH   r   rE   rF   )r   r   r   art_numr*   r   r   r   
_statparse  s   

zNNTP._statparsec                 C   s   	 |  |}| |S r}   )r   r   )r   r>   r   r   r   r   _statcmd  s   

zNNTP._statcmdc                 C   s    	 |r|  d|S |  dS )NzSTAT {0}ZSTAT)r   r[   )r   message_specr   r   r   stat  s   
z	NNTP.statc                 C      	 |  dS )NZNEXTr   r~   r   r   r   next     
z	NNTP.nextc                 C   r   )NZLASTr   r~   r   r   r   r&     r   z	NNTP.lastc                 C   s2   	 |  ||\}}| |\}}}|t|||fS r}   )r   r   r)   )r   r>   ri   r   r"   r   r*   r   r   r   _artcmd  s   zNNTP._artcmdc                C   &   	 |d urd |}nd}| ||S )NzHEAD {0}ZHEADr[   r   r   r   ri   r   r   r   r   head  
   z	NNTP.headc                C   r   )NzBODY {0}ZBODYr   r   r   r   r   body  r   z	NNTP.bodyc                C   r   )NzARTICLE {0}ZARTICLEr   r   r   r   r   article  r   zNNTP.articlec                 C   r   )NZSLAVE)r   r~   r   r   r   slave!  s   
z
NNTP.slavec                   sF   	 t d | d|||\}} fdd|fdd|D fS )Nz^([0-9]+) ?(.*)
?zXHDR {0} {1}c                    s     | }|r|ddS | S )Nr6   rP   )r   r%   )r>   m)patr   r   remove_number2  s   
z NNTP.xhdr.<locals>.remove_numberc                    s   g | ]} |qS r   r   r   )r   r   r   r   5  s    zNNTP.xhdr.<locals>.<listcomp>)r   r   r   r[   )r   Zhdrr   ri   r   r"   r   )r   r   r   xhdr'  s
   
z	NNTP.xhdrc                C   s0   	 |  d|||\}}|  }|t||fS )NzXOVER {0}-{1})r   r[   r   rO   )r   startendri   r   r"   r=   r   r   r   xover7  s   z
NNTP.xoverc          	      C   sz   	 d| j v rdnd}t|ttfr |\}}|d||pd7 }n
|d ur*|d | }| ||\}}|  }|t||fS )NZOVERZXOVERz {0}-{1}r,   r   )rw   r.   tupler   r[   r   r   rO   )	r   r   ri   r   r   r   r   r"   r=   r   r   r   overE  s   z	NNTP.overc                 C   sd   	 |  d}|dst|| }t|dkrt||d }t|dkr+t||t|d fS )NZDATEZ111rP   r6      )r   rH   r   rE   r<   r
   rZ   )r   r   elemr   r   r   r   r   `  s   

z	NNTP.datec                 C   s   |  |}|dst|t|ttfr| }|D ]}|ts)|	dt }|dr2d| }| j
| q| j
d | j
  |  S )N3r#   r   s   .
)r   rH   r   r.   r!   	bytearray
splitlinesendswithr   rstripri   r   r   ru   )r   r   fr   r>   r   r   r   _postq  s   




z
NNTP._postc                 C   r   )NZPOST)r   )r   datar   r   r   post  s   z	NNTP.postc                 C   s   	 |  d||S )Nz	IHAVE {0})r   r[   )r   r*   r   r   r   r   ihave  s   z
NNTP.ihavec                 C   sB   z| j r| j   | ` W | j  d S W | j  d S | j  w r}   )ri   rm   r`   r~   r   r   r   r     s   
zNNTP._closec                 C   s&   	 z|  d}W |   |S |   w )NZQUIT)r   r   )r   r   r   r   r   r     s   
z	NNTP.quitc                 C   s   | j rtd|s|stdz|r,|s,dd l}| }|| j}|r,|d }|d }W n	 ty6   Y nw |s;d S | d| }|dr]|sMt|| d| }|ds]t	|d | _
|   | jryd	| j
vr{|   d | _
|   d S d S d S )
NzAlready logged in.z7At least one of `user` and `usenetrc` must be specifiedr   rP   zauthinfo user Z381zauthinfo pass Z281rs   )r|   r   netrcZauthenticatorsrf   r   r   rH   r   r   rw   rx   ry   rz   )r   rn   ro   rq   r   ZcredentialsZauthr   r   r   r   rl     sD   

z
NNTP.loginc              
   C   sb   z	|  d| _W d S  ty   Y d S  ty0 } z|jdr$d| _n W Y d }~d S d }~ww )Nzmode readerZ480T)r   rv   r   r   r   rH   ry   )r   er   r   r   rz     s   zNNTP._setreadermodec                 C   s|   	 | j rtd| jrtd| d}|dr:| j  t| j|| j	| _| j
d| _d| _ d | _|   d S td)NzTLS is already enabled.z+TLS cannot be started after authentication.STARTTLSZ382re   TzTLS failed to start.)r{   r   r|   r   rH   ri   rm   rc   r`   rf   rj   rw   rx   r   )r   ra   r   r   r   r   starttls  s   


zNNTP.starttls)Tr}   )NNT):r   r   r   r   r   	NNTP_PORTr   r   rk   r   r   rh   r   rx   r   debugr   r   r   ru   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r   r   r   r   r   r&   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rl   rz   	_have_sslr   r   r   r   r   r   (  st    
#"		

.






	
	)r   c                       s8   e Zd Zedddddef fdd	Z fddZ  ZS )NNTP_SSLNFc	           	   	      s$   	 || _ t ||||||| d S r}   )ssl_contextsuperr   )	r   rf   rg   rn   ro   r  rp   rq   rr   r   r   r   r     s
   zNNTP_SSL.__init__c                    s4   t  |}zt|| j| j}W |S    |   r}   )r  rh   rc   r  rf   rm   )r   rr   r`   r  r   r   rh     s   zNNTP_SSL._create_socket)r   r   r   NNTP_SSL_PORTr   r   rh   __classcell__r   r   r  r   r    s    r  __main__zJ        nntplib built-in demo - display the latest articles in a newsgroup)r   z-gz--groupzgmane.comp.python.generalz3group to fetch messages from (default: %(default)s))defaultr   z-sz--serverznews.gmane.ioz+NNTP server hostname (default: %(default)s)z-pz--portr   z#NNTP port number (default: %s / %s))r
  typer   z-nz--nb-articles
   z2number of articles to fetch (default: %(default)s)z-Sz--ssl
store_truezuse NNTP over SSL)actionr
  r   )rf   rg   r   ZGroupZhaszarticles, rangetoc                 C   s$   t | |kr| d |d  d } | S )NrQ   z...)r<   )sZlimr   r   r   cut3  s   r  r6   r   <r   z{:7} {:20} {:42} ({})   *   r}   )F)Hr   r   collectionsrV   r   r_   ImportErrorr  Zemail.headerr   r-   r   __all__r   r   r   r   r   r   r	   r
   r   r  r   r;   r9   r   
namedtupler$   r)   rC   rO   rZ   r^   rc   r   r  r/   r   argparseArgumentParserparseradd_argumentrF   
parse_argsr   rg   Zserverr  rx   r   r   r%   r   r   r'   r&   r?   r   r  r   Znb_articlesr   Z	overviewsZartnumr   rE   Zauthorr   r"   r[   r   r   r   r   r   <module>   s    A
	


     S








