File size: 8,024 Bytes
a73fa4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
242
243
244
245
246
247
"""
手紙管理マネージャー
Letter management manager
"""

import uuid
import asyncio
from typing import List, Optional, Dict, Any
from datetime import datetime
from letter_models import Letter, LetterRequest, LetterContent, LetterStatus, UserPreferences
from letter_storage import get_storage
from letter_logger import get_app_logger

logger = get_app_logger()

class LetterManager:
    """手紙の生成と管理を行うマネージャークラス"""
    
    def __init__(self):
        self.storage = get_storage()
        self.logger = logger
    
    async def create_letter_request(
        self, 
        user_id: str, 
        message: Optional[str] = None,
        preferences: Optional[Dict[str, Any]] = None
    ) -> str:
        """
        手紙生成リクエストを作成する
        
        Args:
            user_id: ユーザーID
            message: ユーザーからのメッセージ
            preferences: ユーザー設定
            
        Returns:
            作成された手紙のID
        """
        try:
            # 一意のIDを生成
            letter_id = str(uuid.uuid4())
            
            # リクエストオブジェクトを作成
            request = LetterRequest(
                user_id=user_id,
                message=message,
                preferences=preferences or {}
            )
            
            # 手紙オブジェクトを作成
            letter = Letter(
                id=letter_id,
                request=request,
                status=LetterStatus.PENDING
            )
            
            # ストレージに保存
            await self.storage.save_letter(letter.dict())
            
            self.logger.info(f"手紙リクエストを作成しました: {letter_id}")
            return letter_id
            
        except Exception as e:
            self.logger.error(f"手紙リクエストの作成中にエラーが発生しました: {e}")
            raise
    
    async def get_letter(self, letter_id: str) -> Optional[Letter]:
        """
        手紙データを取得する
        
        Args:
            letter_id: 手紙のID
            
        Returns:
            手紙データ(見つからない場合はNone)
        """
        try:
            letter_data = await self.storage.get_letter_by_id(letter_id)
            if letter_data:
                return Letter(**letter_data)
            return None
            
        except Exception as e:
            self.logger.error(f"手紙データの取得中にエラーが発生しました: {e}")
            return None
    
    async def get_user_letters(self, user_id: str) -> List[Letter]:
        """
        ユーザーの手紙一覧を取得する
        
        Args:
            user_id: ユーザーID
            
        Returns:
            ユーザーの手紙リスト
        """
        try:
            all_letters = await self.storage.load_letters()
            user_letters = []
            
            for letter_data in all_letters:
                letter = Letter(**letter_data)
                if letter.request.user_id == user_id:
                    user_letters.append(letter)
            
            # 作成日時でソート(新しい順)
            user_letters.sort(key=lambda x: x.created_at, reverse=True)
            
            return user_letters
            
        except Exception as e:
            self.logger.error(f"ユーザー手紙一覧の取得中にエラーが発生しました: {e}")
            return []
    
    async def update_letter_status(
        self, 
        letter_id: str, 
        status: LetterStatus,
        error_message: Optional[str] = None
    ) -> bool:
        """
        手紙のステータスを更新する
        
        Args:
            letter_id: 手紙のID
            status: 新しいステータス
            error_message: エラーメッセージ(エラー時)
            
        Returns:
            更新が成功したかどうか
        """
        try:
            letter = await self.get_letter(letter_id)
            if not letter:
                self.logger.warning(f"更新対象の手紙が見つかりませんでした: {letter_id}")
                return False
            
            letter.update_status(status, error_message)
            
            # ストレージを更新
            await self._update_letter_in_storage(letter)
            
            self.logger.info(f"手紙ステータスを更新しました: {letter_id} -> {status}")
            return True
            
        except Exception as e:
            self.logger.error(f"手紙ステータスの更新中にエラーが発生しました: {e}")
            return False
    
    async def set_letter_content(
        self, 
        letter_id: str, 
        content: LetterContent
    ) -> bool:
        """
        手紙の内容を設定する
        
        Args:
            letter_id: 手紙のID
            content: 手紙の内容
            
        Returns:
            設定が成功したかどうか
        """
        try:
            letter = await self.get_letter(letter_id)
            if not letter:
                self.logger.warning(f"対象の手紙が見つかりませんでした: {letter_id}")
                return False
            
            letter.set_content(content)
            
            # ストレージを更新
            await self._update_letter_in_storage(letter)
            
            self.logger.info(f"手紙の内容を設定しました: {letter_id}")
            return True
            
        except Exception as e:
            self.logger.error(f"手紙内容の設定中にエラーが発生しました: {e}")
            return False
    
    async def delete_letter(self, letter_id: str) -> bool:
        """
        手紙を削除する
        
        Args:
            letter_id: 削除する手紙のID
            
        Returns:
            削除が成功したかどうか
        """
        try:
            result = await self.storage.delete_letter(letter_id)
            if result:
                self.logger.info(f"手紙を削除しました: {letter_id}")
            return result
            
        except Exception as e:
            self.logger.error(f"手紙の削除中にエラーが発生しました: {e}")
            return False
    
    async def get_pending_letters(self) -> List[Letter]:
        """
        処理待ちの手紙一覧を取得する
        
        Returns:
            処理待ちの手紙リスト
        """
        try:
            all_letters = await self.storage.load_letters()
            pending_letters = []
            
            for letter_data in all_letters:
                letter = Letter(**letter_data)
                if letter.status == LetterStatus.PENDING:
                    pending_letters.append(letter)
            
            # 作成日時でソート(古い順)
            pending_letters.sort(key=lambda x: x.created_at)
            
            return pending_letters
            
        except Exception as e:
            self.logger.error(f"処理待ち手紙一覧の取得中にエラーが発生しました: {e}")
            return []
    
    async def _update_letter_in_storage(self, letter: Letter) -> None:
        """内部用:ストレージ内の手紙データを更新する"""
        # 既存データを削除
        await self.storage.delete_letter(letter.id)
        
        # 新しいデータを保存
        await self.storage.save_letter(letter.dict())

# グローバルマネージャーインスタンス
manager_instance = None

def get_letter_manager() -> LetterManager:
    """手紙マネージャーインスタンスを取得(シングルトン)"""
    global manager_instance
    
    if manager_instance is None:
        manager_instance = LetterManager()
    
    return manager_instance