169 lines
4.6 KiB
Python
169 lines
4.6 KiB
Python
"""Feedback storage service"""
|
|||
|
|
import os
|
||
|
|
import shutil
|
||
|
|
from flask import current_app
|
||
|
|
from app.models.feedback import Feedback
|
||
|
|
from app.utils.file_validator import get_safe_filename
|
||
|
|
|
||
|
|
|
||
|
|
class FeedbackStorageService:
|
||
|
|
"""Service for storing feedback to filesystem"""
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def create_feedback(product_id, content_text=None, files=None):
|
||
|
|
"""Create new feedback entry
|
||
|
|
|
||
|
|
Args:
|
||
|
|
product_id: Product ID
|
||
|
|
content_text: Feedback text content (optional)
|
||
|
|
files: List of uploaded files (optional)
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Feedback: Created feedback instance
|
||
|
|
"""
|
||
|
|
# Generate unique feedback ID
|
||
|
|
feedback_id = Feedback.generate_id()
|
||
|
|
|
||
|
|
# Create content preview (first 200 chars)
|
||
|
|
content_preview = ''
|
||
|
|
if content_text:
|
||
|
|
content_preview = content_text[:200]
|
||
|
|
|
||
|
|
# Check attachments
|
||
|
|
has_attachments = bool(files and len(files) > 0)
|
||
|
|
attachment_count = len(files) if files else 0
|
||
|
|
|
||
|
|
# Create feedback instance
|
||
|
|
feedback = Feedback(
|
||
|
|
feedback_id=feedback_id,
|
||
|
|
product_id=product_id,
|
||
|
|
status='new',
|
||
|
|
content_preview=content_preview,
|
||
|
|
has_attachments=has_attachments,
|
||
|
|
attachment_count=attachment_count
|
||
|
|
)
|
||
|
|
|
||
|
|
# Create directory structure
|
||
|
|
feedback_dir = Feedback._get_feedback_dir(product_id, feedback_id)
|
||
|
|
os.makedirs(feedback_dir, exist_ok=True)
|
||
|
|
|
||
|
|
return feedback
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def save_metadata(feedback):
|
||
|
|
"""Save feedback metadata to YAML file
|
||
|
|
|
||
|
|
Args:
|
||
|
|
feedback: Feedback instance to save
|
||
|
|
"""
|
||
|
|
feedback.save_metadata()
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def save_content(feedback, content_text):
|
||
|
|
"""Save feedback content to text file
|
||
|
|
|
||
|
|
Args:
|
||
|
|
feedback: Feedback instance
|
||
|
|
content_text: Feedback text content
|
||
|
|
"""
|
||
|
|
if not content_text:
|
||
|
|
return
|
||
|
|
|
||
|
|
content_file = Feedback._get_content_file(feedback.product_id, feedback.feedback_id)
|
||
|
|
|
||
|
|
with open(content_file, 'w', encoding='utf-8') as f:
|
||
|
|
f.write(content_text)
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def save_attachments(feedback, files):
|
||
|
|
"""Save attachment files
|
||
|
|
|
||
|
|
Args:
|
||
|
|
feedback: Feedback instance
|
||
|
|
files: List of Werkzeug FileStorage objects
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
list: List of saved filenames
|
||
|
|
"""
|
||
|
|
if not files:
|
||
|
|
return []
|
||
|
|
|
||
|
|
attachments_dir = Feedback._get_attachments_dir(feedback.product_id, feedback.feedback_id)
|
||
|
|
os.makedirs(attachments_dir, exist_ok=True)
|
||
|
|
|
||
|
|
saved_files = []
|
||
|
|
|
||
|
|
for file in files:
|
||
|
|
if not file or file.filename == '':
|
||
|
|
continue
|
||
|
|
|
||
|
|
# Sanitize filename
|
||
|
|
safe_filename = get_safe_filename(file.filename)
|
||
|
|
|
||
|
|
# Save file
|
||
|
|
file_path = os.path.join(attachments_dir, safe_filename)
|
||
|
|
file.save(file_path)
|
||
|
|
|
||
|
|
saved_files.append(safe_filename)
|
||
|
|
|
||
|
|
return saved_files
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def save_complete_feedback(product_id, content_text=None, files=None):
|
||
|
|
"""Create and save complete feedback submission
|
||
|
|
|
||
|
|
Args:
|
||
|
|
product_id: Product ID
|
||
|
|
content_text: Feedback text content (optional)
|
||
|
|
files: List of uploaded files (optional)
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Feedback: Created and saved feedback instance
|
||
|
|
"""
|
||
|
|
# Create feedback
|
||
|
|
feedback = FeedbackStorageService.create_feedback(product_id, content_text, files)
|
||
|
|
|
||
|
|
# Save content
|
||
|
|
if content_text:
|
||
|
|
FeedbackStorageService.save_content(feedback, content_text)
|
||
|
|
|
||
|
|
# Save attachments
|
||
|
|
if files:
|
||
|
|
FeedbackStorageService.save_attachments(feedback, files)
|
||
|
|
|
||
|
|
# Save metadata
|
||
|
|
FeedbackStorageService.save_metadata(feedback)
|
||
|
|
|
||
|
|
return feedback
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def update_feedback_status(feedback, new_status):
|
||
|
|
"""Update feedback status
|
||
|
|
|
||
|
|
Args:
|
||
|
|
feedback: Feedback instance
|
||
|
|
new_status: New status value
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
bool: True if updated successfully, False otherwise
|
||
|
|
"""
|
||
|
|
if new_status not in Feedback.VALID_STATUSES:
|
||
|
|
return False
|
||
|
|
|
||
|
|
feedback.status = new_status
|
||
|
|
feedback.save_metadata()
|
||
|
|
|
||
|
|
return True
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def delete_feedback(feedback):
|
||
|
|
"""Delete feedback and all associated files
|
||
|
|
|
||
|
|
Args:
|
||
|
|
feedback: Feedback instance to delete
|
||
|
|
"""
|
||
|
|
feedback_dir = Feedback._get_feedback_dir(feedback.product_id, feedback.feedback_id)
|
||
|
|
|
||
|
|
if os.path.exists(feedback_dir):
|
||
|
|
shutil.rmtree(feedback_dir)
|