File size: 8,657 Bytes
2c72e40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
import logging
import os
import json
import requests
from typing import Dict, Any, Optional
from datetime import datetime

from models import ConsolidatedHoroscope

logger = logging.getLogger(__name__)

class WordPressService:
    """Service for interacting with WordPress REST API"""
    
    def __init__(self):
        """Initialize WordPress service"""
        # WordPress API settings
        self.api_url = os.environ.get("WORDPRESS_API_URL", "")
        self.username = os.environ.get("WORDPRESS_USERNAME", "")
        self.password = os.environ.get("WORDPRESS_PASSWORD", "")
        
        self.auth = None
        if self.username and self.password:
            self.auth = (self.username, self.password)
        
        # Check if WordPress integration is properly configured
        self.is_configured = bool(self.api_url and self.auth)
        if not self.is_configured:
            logger.warning("WordPress service not properly configured. Missing API URL, username, or password.")
    
    def test_connection(self) -> Dict[str, Any]:
        """Test the WordPress API connection"""
        if not self.is_configured:
            return {"success": False, "error": "WordPress API not configured"}
        
        try:
            response = requests.get(f"{self.api_url}/wp/v2", auth=self.auth)
            if response.status_code == 200:
                return {"success": True, "message": "WordPress connection successful"}
            else:
                return {
                    "success": False,
                    "error": f"WordPress connection failed: {response.status_code}",
                    "details": response.text
                }
        except Exception as e:
            logger.error(f"Error testing WordPress connection: {str(e)}")
            return {"success": False, "error": str(e)}
    
    def publish_horoscope(self, horoscope: ConsolidatedHoroscope) -> Dict[str, Any]:
        """
        Publish a consolidated horoscope to WordPress
        
        Args:
            horoscope: ConsolidatedHoroscope object to publish
            
        Returns:
            Dictionary with status and post details
        """
        if not self.is_configured:
            return {"success": False, "error": "WordPress API not configured"}
        
        try:
            # Format the horoscope for WordPress
            post_data = self._format_horoscope_for_wordpress(horoscope)
            
            # Create the post via WordPress API
            response = requests.post(
                f"{self.api_url}/wp/v2/posts",
                auth=self.auth,
                json=post_data
            )
            
            if response.status_code in (200, 201):
                post_data = response.json()
                return {
                    "success": True,
                    "post_id": post_data.get("id"),
                    "url": post_data.get("link"),
                    "status": post_data.get("status")
                }
            else:
                logger.error(f"WordPress API error: {response.status_code}, {response.text}")
                return {
                    "success": False,
                    "error": f"WordPress API error: {response.status_code}",
                    "details": response.text
                }
        except Exception as e:
            logger.error(f"Error publishing horoscope to WordPress: {str(e)}")
            return {"success": False, "error": str(e)}
    
    def _format_horoscope_for_wordpress(self, horoscope: ConsolidatedHoroscope) -> Dict[str, Any]:
        """Format horoscope data for WordPress post"""
        # Capitalize sign
        sign = horoscope.sign.capitalize()
        
        # Format date
        formatted_date = horoscope.date.strftime("%B %d, %Y")
        
        # Construct title
        title = f"{sign} Horoscope for {formatted_date}"
        
        # Construct content
        content = f"""
        <p><strong>{sign} Daily Horoscope - {formatted_date}</strong></p>
        
        <div class="horoscope-content">
            {horoscope.consolidated_prediction}
        </div>
        
        <p class="horoscope-footer">This horoscope is consolidated from multiple trusted astrological sources.</p>
        """
        
        # Extract sources
        try:
            sources = json.loads(horoscope.sources)
            if sources:
                sources_text = "\n<p class=\"horoscope-sources\">Sources: " + ", ".join(sources) + "</p>"
                content += sources_text
        except Exception:
            pass
        
        # Construct post data
        post_data = {
            "title": title,
            "content": content,
            "status": "publish",  # Could be: publish, draft, pending, future
            "excerpt": horoscope.consolidated_prediction[:150] + "...",
            "categories": [self._get_horoscope_category_id()],
            "tags": [self._get_tag_id(sign.lower())]
        }
        
        # Schedule post if needed
        # if schedule_time:
        #     post_data["status"] = "future"
        #     post_data["date"] = schedule_time.isoformat()
        
        return post_data
    
    def _get_horoscope_category_id(self) -> int:
        """
        Get or create the horoscope category ID
        
        Returns:
            Category ID
        """
        # Default to a common category ID if we can't find/create the specific one
        default_category_id = 1  # Usually "Uncategorized"
        
        if not self.is_configured:
            return default_category_id
        
        try:
            # Check if Horoscopes category exists
            response = requests.get(
                f"{self.api_url}/wp/v2/categories",
                auth=self.auth,
                params={"search": "Horoscopes"}
            )
            
            if response.status_code == 200:
                categories = response.json()
                if categories:
                    # Return the first matching category
                    return categories[0].get("id", default_category_id)
                
                # Create the category if it doesn't exist
                create_response = requests.post(
                    f"{self.api_url}/wp/v2/categories",
                    auth=self.auth,
                    json={
                        "name": "Horoscopes",
                        "slug": "horoscopes",
                        "description": "Daily horoscopes for all zodiac signs"
                    }
                )
                
                if create_response.status_code in (200, 201):
                    category_data = create_response.json()
                    return category_data.get("id", default_category_id)
            
            return default_category_id
            
        except Exception as e:
            logger.error(f"Error getting horoscope category ID: {str(e)}")
            return default_category_id
    
    def _get_tag_id(self, tag_name: str) -> int:
        """
        Get or create a tag ID
        
        Args:
            tag_name: Name of the tag
            
        Returns:
            Tag ID
        """
        # Default to 0 which will be ignored by WordPress
        default_tag_id = 0
        
        if not self.is_configured:
            return default_tag_id
        
        try:
            # Check if tag exists
            response = requests.get(
                f"{self.api_url}/wp/v2/tags",
                auth=self.auth,
                params={"search": tag_name}
            )
            
            if response.status_code == 200:
                tags = response.json()
                if tags:
                    # Return the first matching tag
                    return tags[0].get("id", default_tag_id)
                
                # Create the tag if it doesn't exist
                create_response = requests.post(
                    f"{self.api_url}/wp/v2/tags",
                    auth=self.auth,
                    json={
                        "name": tag_name,
                        "slug": tag_name.lower().replace(" ", "-")
                    }
                )
                
                if create_response.status_code in (200, 201):
                    tag_data = create_response.json()
                    return tag_data.get("id", default_tag_id)
            
            return default_tag_id
            
        except Exception as e:
            logger.error(f"Error getting tag ID: {str(e)}")
            return default_tag_id


# Create a singleton instance
wordpress_service = WordPressService()