a
    ze?                  	   @   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yJ   dZY n0 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dZd&d'Z d[d(d)Z!erVd*d+ Z"G d,d- d-Z#erG d.d/ d/e#Z$e%d/ e&d0kr6d 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rLeZ.e$e-j/e.dJZ0e01 Z2dKe2v rte03  e04e-j4\Z5Z6Z7Z8Z9e:dLe9dMe6dNe7dOe8 dPdQ Z;e<e+e8e-j= dR Z7e0>e7e8\Z5Z?e?D ]Z\Z@ZAe	eAdS BdTdRd  ZCe	eAdU ZDe+eAd ZEe:dVFe@e;eCdWe;eDdXeE qe0G  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 n ty8   d| _Y n0 d S )Nr   zNo response given)	Exception__init__response
IndexError)selfargs r   /usr/lib/python3.9/nntplib.pyr   b   s
    zNNTPError.__init__N)__name__
__module____qualname__r   r   r   r   r   r   `   s   r   c                   @   s   e Zd ZdS )r   Nr   r   r   r   r   r   r   r   i   s   r   c                   @   s   e Zd ZdS )r   Nr   r   r   r   r   r   m   s   r   c                   @   s   e Zd ZdS )r   Nr   r   r   r   r   r   q   s   r   c                   @   s   e Zd ZdS )r	   Nr   r   r   r   r   r	   u   s   r	   c                   @   s   e Zd ZdS )r
   Nr   r   r   r   r   r
   y   s   r
   w   i3  >   Z224211Z220Z222Z225Z100Z231Z221215Z101Z230Z282)subjectfromdatez
message-idZ
references:bytes:linesr   r   )byteslines   
	GroupInfo)grouplastfirstflagArticleInfo)Znumber
message_idr    c                 C   sJ   g }t | D ]2\}}t|tr4|||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 ]`}|d dkr:|dd   d\}}}d| }n| d\}}}| }t||}|| qt}t|t|k rtd|d t| |krt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    
rA   c                 C   s   t t}g }| D ]}i }|d^}}t|}t|D ]\}	}
|	t |krLq6||	 }|d}|	|kr|s|d }|
r|
d t |  |krtd|
r|
t |d  nd }
|
|||	 < q6|||f q|S )N	r3   z: z?OVER/XOVER response doesn't include names of additional headers)	r:   r9   splitint	enumerate
startswithr6   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&    
rM   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 r|d7 }n|dk r|d	7 }t||||||S )
Ni      F   i  d   il  )rD   datetime)date_strtime_strZhoursZminutesZsecondsyearZmonthZdayr   r   r   _parse_datetime   s    
rX   c                 C   sP   t | tjsd}n
d| }| j}|r<|d }d|| }nd|| }||fS )NZ000000z({0.hour:02d}{0.minute:02d}{0.second:02d}rS   z{0:02d}{1.month:02d}{1.day:02d}z{0:04d}{1.month:02d}{1.day:02d})r,   rT   formatrW   )ZdtlegacyrV   yrU   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    ra   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dkd"d#Zdld$d%Zd&d' Zd(d) Zd*d+ Zdd,d-d.Zdd,d/d0Zdmdd,d1d2Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!dd,d;d<Z"d=d> Z#d?d@ Z$dndAdBZ%dCdD Z&dEdF Z'dodGdHZ(dpdd,dIdJZ)dqdd,dKdLZ*drd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 Z5dsdcddZ6dedf Z7e8rdtdgdhZ9dS )ur   zutf-8surrogateescapeNFc                 C   s~   || _ || _| || _d | _z2| jd| _| | |s@|rN| ||| W n(   | jrh| j  | j   Y n0 d S )Nrwb)	hostport_create_socketr^   filemakefile
_base_initloginclose)r   rd   re   userpassword
readermodeusenetrctimeoutr   r   r   r   8  s    


zNNTP.__init__c                 C   s^   d| _ |  | _d | _|   d| _|rNd| jvrN|   | jsNd | _|   d| _d| _d S )Nr   FREADER)		debugging_getrespwelcome_capsgetcapabilitiesreadermode_afterauth_setreadermodetls_onauthenticated)r   rn   r   r   r   ri   [  s    
	zNNTP._base_initc                 C   s   | S Nr   r   r   r   r   	__enter__}  s    zNNTP.__enter__c              	      s^    fdd}| rZz6z    W n ttfy6   Y n0 W | rZ   n| rX   0 d S )Nc                      s
   t  dS )Nrg   )hasattrr   r|   r   r   <lambda>      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auditrd   re   socketcreate_connection)r   rp   r   r   r   rf     s    zNNTP._create_socketc                 C   s   | j rtdt| j | jS )Nz	*welcome*)rr   printreprrt   r|   r   r   r   
getwelcome  s    zNNTP.getwelcomec              	   C   s   | j d u r~d| _d | _z|  \}}W n ttfyB   i | _ Y n<0 || _ d|v rfttt|d | _d|v r~d	|d | _| j S )Nr4   VERSIONZIMPLEMENTATION )
ru   nntp_versionZnntp_implementationcapabilitiesr   r   maxmaprD   r/   )r   respcapsr   r   r   rv     s    
zNNTP.getcapabilitiesc                 C   s
   || _ d S r{   )rr   )r   levelr   r   r   set_debuglevel  s    zNNTP.set_debuglevelc                 C   sH   t d| | |t }| jdkr.tdt| | j| | j  d S )Nznntplib.putliner4   z*put*)	r   r   _CRLFrr   r   r   rg   writeflushr   r<   r   r   r   _putline  s
    zNNTP._putlinec                 C   s2   | j rtdt| || j| j}| | d S )Nz*cmd*)rr   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| |sDt|r|dd  t	krf|d d }n|dd  t	v r|d d }|S )Nr4   zline too longz*get*rQ   )
rg   readline_MAXLINEr:   r
   rr   r   r   r   r   )r   Z
strip_crlfr<   r   r   r   _getline  s    
zNNTP._getlinec                 C   sl   |   }| jrtdt| || j| j}|d d }|dkrHt||dkrXt||dvrht	||S )Nz*resp*r4   45Z123)
r   rr   r   r   r.   r   r   r   r   r	   )r   r   cr   r   r   rs     s    zNNTP._getrespc                 C   s   d }zt |ttfr"t|d }}|  }|d d tvrBt|g }|d urdt df}| d}||v rnq|	dr|dd  }|
| qZn8d}|  }||krq|	dr|dd  }|| qW |r|  n|r|  0 ||fS )Nwb      .s   .
Fs   ..r4   )r,   strr   openrs   	_LONGRESPr   r   r   rF   r   r-   rk   )r   rg   Z
openedFiler   r    Zterminatorsr<   
terminatorr   r   r   _getlongresp  s8    	




zNNTP._getlongrespc                 C   s   |  | |  S r{   )r   rs   r   r   r   r   	_shortcmd  s    
zNNTP._shortcmdc                 C   s   |  | | |S r{   r   r   )r   r<   rg   r   r   r   _longcmd  s    
zNNTP._longcmdc                    s.     |  |\}}| fdd|D fS )Nc                    s   g | ]}|  j jqS r   )r.   r   r   .0r<   r|   r   r   
<listcomp>+  s   z'NNTP._longcmdstring.<locals>.<listcomp>r   )r   r<   rg   r   listr   r|   r   _longcmdstring$  s
    
zNNTP._longcmdstringc                 C   s`   z| j W S  ty   Y n0 z| d\}}W n tyL   td d  }Y n
0 t|}|| _ |S )NzLIST OVERVIEW.FMT)Z_cachedoverviewfmtAttributeErrorr   r   r9   rA   )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"   rC   r   r   r   r   r   A  r   z#NNTP._grouplist.<locals>.<listcomp>r   )r   r    r   r   r   
_grouplist?  s    zNNTP._grouplistc                 C   s8   i }|  d\}}|D ]}| ^}}|||< q||fS )NZCAPABILITIES)r   rC   )r   r   r   r    r<   r=   rH   r   r   r   r   C  s    
zNNTP.capabilities)rg   c                C   sb   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}'rN   zNEWGROUPS {0} {1})r,   rT   r   	TypeErrorrY   	__class__r   r\   r   r   r   )r   r   rg   rU   rV   cmdr   r    r   r   r   	newgroupsQ  s    zNNTP.newgroupsc                C   sR   t |tjtjfs$td|jjt|| jdk \}}d|||}| 	||S )Nr   rN   zNEWNEWS {0} {1} {2})
r,   rT   r   r   rY   r   r   r\   r   r   )r   r#   r   rg   rU   rV   r   r   r   r   newnewsa  s    zNNTP.newnewsc                C   s4   |d urd| }nd}|  ||\}}|| |fS )NzLIST ACTIVE LIST)r   r   )r   group_patternrg   commandr   r    r   r   r   r   q  s
    
z	NNTP.listc                 C   s   t d}| d| \}}|ds8| d| \}}i }|D ]:}|| }|r@|dd\}	}
|sr|
  S |
||	< q@|r||fS dS d S )Nz^(?P<group>[^ 	]+)[ 	]+(.*)$zLIST NEWSGROUPS r   zXGTITLE r4   rN   r*   )recompiler   rF   searchstripr#   )r   r   Z
return_allZline_patr   r    groupsZraw_linematchr=   Zdescr   r   r   _getdescriptions  s    


zNNTP._getdescriptionsc                 C   s   |  |dS )NFr   )r   r#   r   r   r   description  s    zNNTP.descriptionc                 C   s   |  |dS )NTr   )r   r   r   r   r   descriptions  s    zNNTP.descriptionsc                 C   s   |  d| }|ds t|| }d } }}t|}|dkr|d }|dkr|d }|dkr|d }|dkr|d  }|t|t|t||fS )NzGROUP r   r   r4   rN   r   rO   )r   rF   r   rC   r:   r6   rD   )r   r=   r   wordscountr%   r$   nr   r   r   r#     s    

z
NNTP.groupc                C   s   |  d|S )NZHELP)r   )r   rg   r   r   r   help  s    z	NNTP.helpc                 C   s8   | dst|| }t|d }|d }|||fS )NZ22r4   rN   )rF   r   rC   rD   )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 d S )NzSTAT {0}ZSTAT)r   rY   )r   message_specr   r   r   stat  s    	z	NNTP.statc                 C   s
   |  dS )NZNEXTr   r|   r   r   r   next  s    z	NNTP.nextc                 C   s
   |  dS )NZLASTr   r|   r   r   r   r$     s    z	NNTP.lastc                 C   s0   |  ||\}}| |\}}}|t|||fS r{   )r   r   r'   )r   r<   rg   r   r    r   r(   r   r   r   _artcmd  s    zNNTP._artcmdc                C   s$   |d urd |}nd}| ||S )NzHEAD {0}ZHEADrY   r   r   r   rg   r   r   r   r   head  s    z	NNTP.headc                C   s$   |d urd |}nd}| ||S )NzBODY {0}ZBODYr   r   r   r   r   body  s    z	NNTP.bodyc                C   s$   |d urd |}nd}| ||S )NzARTICLE {0}ZARTICLEr   r   r   r   r   article  s    zNNTP.articlec                 C   s
   |  dS )NZSLAVE)r   r|   r   r   r   slave!  s    z
NNTP.slavec                   sD   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 )Nr4   rN   )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  r   zNNTP.xhdr.<locals>.<listcomp>)r   r   r   rY   )r   Zhdrr   rg   r   r    r   )r   r   r   xhdr'  s    	
z	NNTP.xhdrc                C   s.   |  d|||\}}|  }|t||fS )NzXOVER {0}-{1})r   rY   r   rM   )r   startendrg   r   r    r;   r   r   r   xover7  s
    	z
NNTP.xoverc          	      C   sx   d| j v rdnd}t|ttfr>|\}}|d||p6d7 }n|d urR|d | }| ||\}}|  }|t||fS )NZOVERZXOVERz {0}-{1}r*   r   )ru   r,   tupler   rY   r   r   rM   )	r   r   rg   r   r   r   r   r    r;   r   r   r   overE  s    z	NNTP.overc                 C   sb   |  d}|dst|| }t|dkr8t||d }t|dkrTt||t|d fS )NZDATEZ111rN   r4      )r   rF   r   rC   r:   r
   rX   )r   r   elemr   r   r   r   r   `  s    

z	NNTP.datec                 C   s   |  |}|dst|t|ttfr2| }|D ]:}|tsR|	dt }|drdd| }| j
| q6| j
d | j
  |  S )N3r!   r   s   .
)r   rF   r   r,   r   	bytearray
splitlinesendswithr   rstriprg   r   r   rs   )r   r   fr   r<   r   r   r   _postq  s    




z
NNTP._postc                 C   s   |  d|S )NZPOST)r   )r   datar   r   r   post  s    z	NNTP.postc                 C   s   |  d||S )Nz	IHAVE {0})r   rY   )r   r(   r   r   r   r   ihave  s    z
NNTP.ihavec                 C   s4   z"| j r| j   | ` W | j  n| j  0 d S r{   )rg   rk   r^   r|   r   r   r   r     s
    
zNNTP._closec                 C   s&   z|  d}W |   n
|   0 |S )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<|rX|sXdd l}| }|| j}|rX|d }|d }W n tyl   Y n0 |svd S | d| }|dr|st|n | d| }|dst	|d | _
|   | jrd	| j
vr|   d | _
|   d S )
NzAlready logged in.z7At least one of `user` and `usenetrc` must be specifiedr   rN   zauthinfo user Z381zauthinfo pass Z281rq   )rz   r   netrcZauthenticatorsrd   r   r   rF   r   r   ru   rv   rw   rx   )r   rl   rm   ro   r   ZcredentialsZauthr   r   r   r   rj     s>    


z
NNTP.loginc              
   C   s`   z|  d| _W nJ ty"   Y n: tyZ } z"|jdrDd| _n W Y d }~n
d }~0 0 d S )Nzmode readerZ480T)r   rt   r   r   r   rF   rw   )r   er   r   r   rx     s    zNNTP._setreadermodec                 C   s|   | j rtd| jrtd| d}|drp| j  t| j|| j	| _| j
d| _d| _ d | _|   ntdd S )NzTLS is already enabled.z+TLS cannot be started after authentication.STARTTLSZ382rc   TzTLS failed to start.)ry   r   rz   r   rF   rg   rk   ra   r^   rd   rh   ru   rv   r   )r   r_   r   r   r   r   starttls  s    



zNNTP.starttls)T)N)N)N)N)N)N)N)N)N)NNT)N):r   r   r   r   r   	NNTP_PORTr   r   ri   r}   r   rf   r   rv   r   debugr   r   r   rs   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   rj   rx   	_have_sslr   r   r   r   r   r   (  sp   
#"		

.






		
)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   rd   re   rl   rm   r   rn   ro   rp   r   r   r   r     s    zNNTP_SSL.__init__c                    s@   t  |}zt|| j| j}W n   |   Y n0 |S d S r{   )r   rf   ra   r   rd   rk   )r   rp   r^   r   r   r   rf     s    zNNTP_SSL._create_socket)r   r   r   NNTP_SSL_PORTr   r   rf   __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   )rd   re   r   ZGroupZhaszarticles, rangetoc                 C   s$   t | |kr | d |d  d } | S )NrO   z...)r:   )sZlimr   r   r   cut3  s    r
  r4   r   <r   z{:7} {:20} {:42} ({})   *   )N)N)F)Hr   r   collectionsrT   r   r]   ImportErrorr   Zemail.headerr   r+   r   __all__r   r   r   r   r   r   r	   r
   r   r   r   r9   r7   r   
namedtupler"   r'   rA   rM   rX   r\   ra   r   r   r-   r   argparseArgumentParserparseradd_argumentrD   
parse_argsr   re   Zserverr	  rv   r   r   r#   r   r   r%   r$   r=   r   r
  r   Znb_articlesr   Z	overviewsZartnumr   rC   Zauthorr   r    rY   r   r   r   r   r   <module>B   s   

	


     S








