
    Ojw                        S SK r S SKrS SKJrJrJr  S SKJr  S SKJ	r	  S SK
r
S SKJr  S SKJr  S SKJr  S SKJr  \ R&                  " S	5      rS
rSrSrSr  S"S\S\S\S\\   S\\   4
S jjrS\S\S\4S jrS\S\\   4S jrS\
R>                  S\\   4S jr S\
R>                  S\\   4S jr!S\
R>                  S\\   4S jr"S\S\S\S\\\4   4S jr#S\
R>                  S \S\\   4S! jr$g)#    N)OptionalTupleList)urlsplit)settings)BeautifulSoup)ValidationError)URLValidator)OutgoingWebmentionStatusdjangoz&The target URL could not be retrieved.z+The target URL returned an HTTP error code.z3The target endpoint URL returned an HTTP error codez*The target server accepted the webmention.outgoing_statusmessagesuccesstarget_endpointresponse_codec                 p    Xl         X l        U(       a  X0l        U(       a  X@l        U R	                  5         g )N)status_message
successfultarget_webmention_endpointr   save)r   r   r   r   r   s        1/opt/fre/webmention/tasks/outgoing_webmentions.py_save_statusr      s.     &-"!(5D2(5%    
source_urltextreturnc           	      d   [         R                  S5        Sn[        U5      n[         R                  SU SU 35        U(       d/  [         R                  S5        [         R                  SU S35        gU GH;  n[        R
                  R                  U US9n[         R                  S	U 35         [        R                  " U5      n[         R                  U5        UR                  S:  aA  [         R                  SU SUR                   35        [        U[        SUR                  S9  M  [        U5      nU(       aZ  [         R                  SU 35        [!        XU5      u  pU	(       a  US-  n[        U["        UU	U
S9  GM  [        U[$        UU	U
S9  GM#  [         R                  SU 35        GM>     U(       a  [         R                  SU S35        U$ [         R                  S5        U$ ! [         a6  n[         R                  S
U SU 35        [        U[        SS9   SnAGM  SnAff = f)az  
Find links and send webmentions if remote server accepts them.

Returns True if submissions is successful, False if submission fails, or
None if no endpoints were found.


Spec:
https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint

For each link found in text:
    - Check that the link is alive
    - Search for webmention endpoint in:
        - HTTP response headers
        - HTML <head> element
        - HTML <body> element
    - If an endpoint is found, send a webmention notification

source_url should be the value returned by model.get_absolute_url() -
it will be appended to settings.DOMAIN_NAME
z)Checking for outgoing webmention links...r   zlinks_in_text z in z&No webmentionable links found in text.z!No webmentionable links in text [])r   
target_urlzChecking url=zUnable to fetch url=: F)r   N,  zLink "z" returned status=)r   r   zFound webmention endpoint:    )r   r   r   z%No webmention endpoint found for url zSuccessfully sent z webmentionszNo webmentions were successful!)loginfo_find_links_in_textdebugr   objectscreaterequestsget	Exceptionwarningr   !STATUS_MESSAGE_TARGET_UNREACHABLEstatus_code STATUS_MESSAGE_TARGET_ERROR_CODE$_get_absolute_endpoint_from_response_send_webmentionSTATUS_MESSAGE_OK$STATUS_MESSAGE_TARGET_ENDPOINT_ERROR)r   r   mentions_sentlinks_in_textlink_urlr   responseeendpointr   r.   s              r   process_outgoing_webmentionsr:   /   s   , HH8:M'-MHH~m_D789:		5dV1=>!2::AA! B 

 	=
+,	||H-HHHX 3&KK
"4X5I5I4JKM0&22	 7AHH28*=>#3J(#S G"#%$,#"- #8$,#"- HH<XJGHa "d %m_LAB  	24[  	KK.xj1#>?*KUZ[	s   1+G//
H/9*H**H/c                 j    [        U S5      nUR                  SSS9 Vs/ s H  o"S   PM	     sn$ s  snf )Nhtml.parseraT)hrefr>   )r   find_all)r   soupr=   s      r   r%   r%      s7    }-D#}}St}<=<!fI<===s   0r7   c                     [        U 5      =(       d    [        U 5      n[        X5      n[        R	                  SU SU 35        U$ )NzAbsolute url: z -> )_get_endpoint_in_http_headers_get_endpoint_in_html_relative_to_absolute_urlr#   r&   )r7   r9   abs_urls      r   r0   r0      sD    -h7 0%h/ ';GIIxjWI67Nr   c                 D    U R                   R                  S5      R                  S5      S   nSU;   a=  [        R	                  S5        [
        R                  " SU5      R                  S5      nU$ g	! [         a"  n[        R	                  SU 35         S	nAg	S	nAff = f)
z/Search for webmention endpoint in HTTP headers.Link,r   
webmentionz(webmention endpoint found in http headerz-<(?P<url>.*)>[; ]*.rel=[\'"]?webmention[\'"]?r"   zError reading http headers: N)	headersr*   splitr#   r&   rematchgroupr+   )r7   header_linkr9   r8   s       r   rB   rB      s    	6&&**6288=a@;&II@Axx@"U1X  O '  6		04556s   A/A3 3
B=BBc                 "   [        U R                  S5      n UR                  R                  SSSS9nU H-  nSUS   ;   d  M  US   n[        R                  SU 35        Us  $     UR                  R                  SSSS9nU H*  nSUS   ;   d  M  [        R                  S5        US   nUs  $    g
! [         a"  n[        R                  S	U 35         S
nANtS
nAff = f! [         a"  n[        R                  SU 35         S
nAg
S
nAff = f)z)Search for a webmention endpoint in HTML.r<   linkT)r>   relrI   rR   r>   z5webmention endpoint found in document head - address=z'Error reading <head> of external link: Nr=   z*webmention endpoint found in document bodyzError reading <body> of link: )r   r   headr?   r#   r&   r+   body)r7   a_souplinksrQ   r9   r8   s         r   rC   rC      s   8==-8F
A$$V$D$ADtE{*<		'j*+   8$$St$>DtE{*		FG<	   A		;A3?@@A  8		21#6778sG   'B3  B3 $B3 ''C" C" 0C" 3
C=CC"
D,D		Dr9   targetc                 
   UU  S.n[         R                  U SU 35        [        R                  " XS9nUR                  nUS:  a  [         R                  SU SU 35        SU4$ [         R                  SU SU 35        S	U4$ )
N)rW   sourcer    )datar!   zSending webmention to "z" FAILED with status_code=Fz" successful with status_code=T)r#   r$   r)   postr.   r,   )r   r9   rW   payloadr7   r.   s         r   r1   r1      s    LG HHzG9%&}}X4H&&Kc-hZ 8//:m= 	>k!!*8* 500;}> 	?[  r   urlc                     U(       d  g [        5       " U5        U$ ! [         aR    [        U R                  5      u  p#    nU(       a  U(       d   gU SU SUR	                  S5      (       d  UOUSS  3s $ f = f)zS
If given url is relative, try to construct an absolute url using response domain.
Nz:///r"   )r
   r	   r   r]   
startswith)r7   r]   schemedomain_s        r   rD   rD      s     =s
 ="*8<<"81aVVHA..--s3qr7;= 	=	=s    2A8%A87A8)NN)%loggingrL   typingr   r   r   urllib.parser   django.confr   r)   bs4r   django.core.exceptionsr	   django.core.validatorsr
   webmention.modelsr   	getLoggerr#   r-   r/   r3   r2   strboolintr   r:   r%   Responser0   rB   rC   r1   rD    r   r   <module>rr      sx    	 
 "     2 / 6! %M !#P  '\ $@  *.'+1  "#	
  }"WS W W Wt>c >d3i >
83D3D RU 6H,=,= 6(3- 68H$5$5 8(3- 8:! ! !S !U4QT9EU !$=(9(9 = =QT =r   