231 lines
7.4 KiB
Python
231 lines
7.4 KiB
Python
import time
|
|
from importlib import invalidate_caches
|
|
|
|
from sqlalchemy import select
|
|
|
|
from cache.cache import invalidate_shout_related_cache, invalidate_shouts_cache
|
|
from orm.author import Author
|
|
from orm.draft import Draft
|
|
from orm.shout import Shout
|
|
from services.auth import login_required
|
|
from services.db import local_session
|
|
from services.schema import mutation, query
|
|
from utils.logger import root_logger as logger
|
|
|
|
|
|
@query.field("load_drafts")
|
|
@login_required
|
|
async def load_drafts(_, info):
|
|
user_id = info.context.get("user_id")
|
|
author_dict = info.context.get("author", {})
|
|
author_id = author_dict.get("id")
|
|
|
|
if not user_id or not author_id:
|
|
return {"error": "User ID and author ID are required"}
|
|
|
|
with local_session() as session:
|
|
drafts = session.query(Draft).filter(Draft.authors.any(Author.id == author_id)).all()
|
|
return {"drafts": drafts}
|
|
|
|
|
|
@mutation.field("create_draft")
|
|
@login_required
|
|
async def create_draft(_, info, shout_id: int = 0):
|
|
user_id = info.context.get("user_id")
|
|
author_dict = info.context.get("author", {})
|
|
author_id = author_dict.get("id")
|
|
|
|
if not user_id or not author_id:
|
|
return {"error": "User ID and author ID are required"}
|
|
|
|
with local_session() as session:
|
|
draft = Draft(created_by=author_id)
|
|
if shout_id:
|
|
draft.shout = shout_id
|
|
session.add(draft)
|
|
session.commit()
|
|
return {"draft": draft}
|
|
|
|
|
|
@mutation.field("update_draft")
|
|
@login_required
|
|
async def update_draft(_, info, draft_input):
|
|
user_id = info.context.get("user_id")
|
|
author_dict = info.context.get("author", {})
|
|
author_id = author_dict.get("id")
|
|
draft_id = draft_input.get("id")
|
|
if not user_id or not author_id:
|
|
return {"error": "User ID and author ID are required"}
|
|
|
|
with local_session() as session:
|
|
draft = session.query(Draft).filter(Draft.id == draft_id).first()
|
|
Draft.update(draft, {**draft_input})
|
|
if not draft:
|
|
return {"error": "Draft not found"}
|
|
|
|
draft.updated_at = int(time.time())
|
|
session.commit()
|
|
return {"draft": draft}
|
|
|
|
|
|
@mutation.field("delete_draft")
|
|
@login_required
|
|
async def delete_draft(_, info, draft_id: int):
|
|
user_id = info.context.get("user_id")
|
|
author_dict = info.context.get("author", {})
|
|
author_id = author_dict.get("id")
|
|
|
|
with local_session() as session:
|
|
draft = session.query(Draft).filter(Draft.id == draft_id).first()
|
|
if not draft:
|
|
return {"error": "Draft not found"}
|
|
session.delete(draft)
|
|
session.commit()
|
|
return {"draft": draft}
|
|
|
|
|
|
@mutation.field("publish_draft")
|
|
@login_required
|
|
async def publish_draft(_, info, draft_id: int):
|
|
user_id = info.context.get("user_id")
|
|
author_dict = info.context.get("author", {})
|
|
author_id = author_dict.get("id")
|
|
if not user_id or not author_id:
|
|
return {"error": "User ID and author ID are required"}
|
|
|
|
with local_session() as session:
|
|
draft = session.query(Draft).filter(Draft.id == draft_id).first()
|
|
if not draft:
|
|
return {"error": "Draft not found"}
|
|
return publish_shout(None, None, draft.shout, draft)
|
|
|
|
|
|
@mutation.field("unpublish_draft")
|
|
@login_required
|
|
async def unpublish_draft(_, info, draft_id: int):
|
|
user_id = info.context.get("user_id")
|
|
author_dict = info.context.get("author", {})
|
|
author_id = author_dict.get("id")
|
|
if not user_id or not author_id:
|
|
return {"error": "User ID and author ID are required"}
|
|
|
|
with local_session() as session:
|
|
draft = session.query(Draft).filter(Draft.id == draft_id).first()
|
|
shout_id = draft.shout
|
|
unpublish_shout(None, None, shout_id)
|
|
|
|
|
|
@mutation.field("publish_shout")
|
|
@login_required
|
|
async def publish_shout(_, info, shout_id: int, draft=None):
|
|
"""Publish draft as a shout or update existing shout.
|
|
|
|
Args:
|
|
session: SQLAlchemy session to use for database operations
|
|
"""
|
|
user_id = info.context.get("user_id")
|
|
author_dict = info.context.get("author", {})
|
|
author_id = author_dict.get("id")
|
|
if not user_id or not author_id:
|
|
return {"error": "User ID and author ID are required"}
|
|
|
|
try:
|
|
# Use proper SQLAlchemy query
|
|
with local_session() as session:
|
|
if not draft:
|
|
find_draft_stmt = select(Draft).where(Draft.shout == shout_id)
|
|
draft = session.execute(find_draft_stmt).scalar_one_or_none()
|
|
|
|
now = int(time.time())
|
|
|
|
if not shout:
|
|
# Create new shout from draft
|
|
shout = Shout(
|
|
body=draft.body,
|
|
slug=draft.slug,
|
|
cover=draft.cover,
|
|
cover_caption=draft.cover_caption,
|
|
lead=draft.lead,
|
|
description=draft.description,
|
|
title=draft.title,
|
|
subtitle=draft.subtitle,
|
|
layout=draft.layout,
|
|
media=draft.media,
|
|
lang=draft.lang,
|
|
seo=draft.seo,
|
|
created_by=author_id,
|
|
community=draft.community,
|
|
authors=draft.authors.copy(), # Create copies of relationships
|
|
topics=draft.topics.copy(),
|
|
draft=draft.id,
|
|
deleted_at=None,
|
|
)
|
|
else:
|
|
# Update existing shout
|
|
shout.authors = draft.authors.copy()
|
|
shout.topics = draft.topics.copy()
|
|
shout.draft = draft.id
|
|
shout.created_by = author_id
|
|
shout.title = draft.title
|
|
shout.subtitle = draft.subtitle
|
|
shout.body = draft.body
|
|
shout.cover = draft.cover
|
|
shout.cover_caption = draft.cover_caption
|
|
shout.lead = draft.lead
|
|
shout.description = draft.description
|
|
shout.layout = draft.layout
|
|
shout.media = draft.media
|
|
shout.lang = draft.lang
|
|
shout.seo = draft.seo
|
|
|
|
shout.updated_at = now
|
|
shout.published_at = now
|
|
draft.updated_at = now
|
|
draft.published_at = now
|
|
session.add(shout)
|
|
session.add(draft)
|
|
session.commit()
|
|
|
|
invalidate_shout_related_cache(shout)
|
|
invalidate_shouts_cache()
|
|
return {"shout": shout}
|
|
except Exception as e:
|
|
import traceback
|
|
|
|
logger.error(f"Failed to publish shout: {e}")
|
|
logger.error(traceback.format_exc())
|
|
session.rollback()
|
|
return {"error": "Failed to publish shout"}
|
|
|
|
|
|
@mutation.field("unpublish_shout")
|
|
@login_required
|
|
async def unpublish_shout(_, info, shout_id: int):
|
|
"""Unpublish a shout.
|
|
|
|
Args:
|
|
shout_id: The ID of the shout to unpublish
|
|
|
|
Returns:
|
|
dict: The unpublished shout or an error message
|
|
"""
|
|
author_dict = info.context.get("author", {})
|
|
author_id = author_dict.get("id")
|
|
if not author_id:
|
|
return {"error": "Author ID is required"}
|
|
|
|
shout = None
|
|
with local_session() as session:
|
|
try:
|
|
shout = session.query(Shout).filter(Shout.id == shout_id).first()
|
|
shout.published_at = None
|
|
session.commit()
|
|
invalidate_shout_related_cache(shout)
|
|
invalidate_shouts_cache()
|
|
|
|
except Exception:
|
|
session.rollback()
|
|
return {"error": "Failed to unpublish shout"}
|
|
|
|
return {"shout": shout}
|