
    tĀi9"              	           d 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	Z	ddl
mZ ddlmZmZ  ej                  e      Ze G d d	             Z G d
 d      Z	 	 ddedee   dedefdZy)zv
WordPress REST API integration for publishing articles.
Handles media upload, post creation, and Yoast SEO metadata.
    N)	dataclass)Path)Optional)get_settings)ArticleArticleRepositoryc                   h    e Zd ZU eed<   dZee   ed<   dZee   ed<   dZ	ee
   ed<   dZee
   ed<   y)PublishResultsuccessN
wp_post_idwp_media_idpost_urlerror)__name__
__module____qualname__bool__annotations__r   r   intr   r   strr        =/var/www/html/content-pipeline/modules/wordpress_publisher.pyr
   r
      s?    M $J$!%K#%"Hhsm"E8C=r   r
   c                      e Zd ZdZd Z	 	 ddededee   dee   dej                  f
d	Z
dee   fd
ZdefdZdedee   fdZddededee   fdZ	 	 ddedededededee   dee   dedefdZ	 	 ddedededefdZy) WordPressClientzWordPress REST API client.c                     t               }|j                  j                  d      | _        | j                   d| _        |j
                  | _        d | _        y )N/z/wp-json/wp/v2)r   wp_urlrstripbase_urlapi_urlwp_authauth_authors_cache)selfsettingss     r   __init__zWordPressClient.__init__    sF    > ..s3--7$$	"r   Nmethodendpointdatafilesreturnc           	          | j                    d| }t        j                  ||| j                  |dk7  s|s|nd|r|nd|d      }|S )z*Make authenticated request to WP REST API.r   POSTN<   )r#   jsonr*   r+   timeout)r!   requestsrequestr#   )r%   r(   r)   r*   r+   urlresponses          r   _requestzWordPressClient._request'   sW     az*##6)DD
 r   c                    | j                   | j                   S 	 | j                  dd      }|j                          |j                         | _         | j                   S # t        $ r$}t
        j                  d|        g cY d}~S d}~ww xY w)z"Get all users for author rotation.NGETzusers?per_page=100zFailed to fetch authors: )r$   r6   raise_for_statusr0   	Exceptionloggerr   )r%   r5   es      r   get_authorszWordPressClient.get_authors;   s    *&&&	}}U,@AH%%'"*--/D&&& 	LL4QC89I	s   AA 	B
&B?B
B
c                    | j                         }|st        j                  d       yt        j                         }|rL|j
                  r@|D cg c]  }|d   	 }}	 |j                  |j
                        }|dz   t        |      z  }nd}||   }t        j                  d|j                  d|d                 |d   S c c}w # t        $ r d}Y Gw xY w)z.Get next author ID using round-robin rotation.z(No authors found, using default author 1   idr   zSelected author: name)r=   r;   warningr   get_last_published	author_idindexlen
ValueErrorinfoget)r%   authorslast_articlea
author_idscurrent_idxnext_idxnext_authors           r   get_next_author_idz"WordPressClient.get_next_author_idI   s    ""$NNEF );;=L22+23a!D'3J3(..|/E/EF'!Os7|; Hh''D@Q(R'STU4   4  s   C,C CCcategory_slugc                     	 | j                  dd|       }|j                          |j                         }|r|d   d   S y# t        $ r"}t        j                  d|        Y d}~yd}~ww xY w)zGet category ID by slug.r8   zcategories?slug=r   r@   NzFailed to fetch category: )r6   r9   r0   r:   r;   r   )r%   rR   r5   
categoriesr<   s        r   get_category_idzWordPressClient.get_category_ida   sr    		}}U.>}o,NOH%%'!J!!}T** 	LL5aS9:	s   >A 	A-A((A-	file_pathtitlec                    t        |      }|j                         st        j                  d|        yt	        j
                  |      d   xs d}|j                  }	 t        |d      5 }t        j                  | j                   d| j                  d| d|d	|j                         d
      }ddd       j                          |j                         }|d   }	t        j                  d|	 d|        |r| j!                  dd|	 ||d       |	S # 1 sw Y   gxY w# t"        $ r"}
t        j                  d|
        Y d}
~
yd}
~
ww xY w)zq
        Upload image to WordPress Media Library.

        Returns media ID on success, None on failure.
        zFile not found: Nr   z
image/webprbz/mediazattachment; filename="")zContent-DispositionzContent-Typex   )r#   headersr*   r1   r@   zUploaded media: ID=z, file=r.   zmedia/)alt_textrW   r*   zMedia upload failed: )r   existsr;   r   	mimetypes
guess_typerA   openr2   postr!   r#   readr9   r0   rH   r6   r:   )r%   rV   rW   path	mime_typefilenamefr5   mediamedia_idr<   s              r   upload_mediazWordPressClient.upload_median   sR    I{{}LL+I;78((3A6F,	99	i& 
!#==||nF+1GzQR/S(1 	
 %%'MMOET{HKK-hZwxjIJ XJ'&+e<   O3
 
6  	LL045	s2   D# *AD1A%D# D D# #	E,E		Econtent_htmlslugmeta_descriptionrD   category_idsfeatured_media_idstatusc	           	         ||||||ddd}	|r||	d<   |dd dd|	d<   	 | j                  d	d
|	      }
|
j                          |
j                         }|d   }|j                  dd      }t        j                  d| d|        t        d|||      S # t        j                  j                  $ r}t        |      }	 |j                  j                         }|j                  dt        |            }n# t        $ r Y nw xY wt        j                  d|        t        d|      cY d}~S d}~wt        $ r8}t        j                  d|        t        dt        |            cY d}~S d}~ww xY w)zF
        Create a new WordPress post with Yoast SEO metadata.
        rb   )rW   contentrm   rq   authorrT   comment_statusping_statusfeatured_mediaN    _yoast_wpseo_metadesc_yoast_wpseo_focuskwmetar.   postsr^   r@   linkzCreated post: ID=z, URL=T)r   r   r   r   messagezPost creation failed: F)r   r   )r6   r9   r0   rI   r;   rH   r
   r2   
exceptions	HTTPErrorr   r5   r:   r   )r%   rW   rl   rm   rn   rD   ro   rp   rq   	post_datar5   rc   post_idr   r<   	error_msg
error_datas                    r   create_postzWordPressClient.create_post   s|    #&$!	
	 *;I&' &6ds%;$&
	&
	>}}VW9}EH%%'==?D4jGxx+HKK+G9F8*EF "-!	  "",, 	AAIZZ__.
&NN9c!f=	 LL1)=> i@@ 	>LL1!56 c!f==	>sT   A4B E01D,=5C32D,3	C?<D,>C??'D,&E0,E08-E+%E0+E0r   focus_keywordc                     	 | j                  dd| d|dd |di      }|j                          y# t        $ r"}t        j	                  d	|        Y d}~y
d}~ww xY w)z,Update Yoast SEO metadata for existing post.r.   zposts/r}   Nrx   rz   r^   TzYoast meta update failed: F)r6   r9   r:   r;   r   )r%   r   r   rn   r5   r<   s         r   update_yoast_metaz!WordPressClient.update_yoast_meta   sy    	}}	"1A$31G0= % 	H %%' 	LL5aS9:	s   /2 	AAA)NN)ry   )Npublish)ry   ry   )r   r   r   __doc__r'   r   r   dictr2   Responser6   listr=   r   rQ   rU   rk   r
   r   r   r   r   r   r   r   r      sH   $#  $ $  tn	
 ~ 
		(T$Z !C !0S Xc] ,c ,# ,x} ,l ,0?>?> ?> 	?>
 ?> ?> 3i?> $C=?> ?> 
?>H   "	  	
 
r   r   articlethumbnail_pathrR   r,   c           	      *   t               }|j                         }|j                  |      }|r|gng }d}|r|j                  || j                        }|j                  | j                  | j                  | j                  | j                  |||      }|S )z
    Publish article to WordPress.

    Args:
        article: Article model with content
        thumbnail_path: Path to thumbnail image
        category_slug: WordPress category slug

    Returns:
        PublishResult with post details
    N)rW   rl   rm   rn   rD   ro   rp   )	r   rQ   rU   rk   rW   r   rl   rm   rn   )	r   r   rR   clientrD   category_idro   rj   results	            r   publish_articler      s      F ))+I ((7K$/K=RL H&&~w}}E mm))\\ 11!"   F Mr   )Nblog)r   loggingr`   dataclassesr   pathlibr   typingr   r2   config.settingsr   database.modelsr   r   	getLoggerr   r;   r
   r   r   r   r   r   r   <module>r      s   
   !    ( 6			8	$      V Vv %)))SM) ) 	)r   