From 536c094e72a8a869819992dca532de5d7b3805e5 Mon Sep 17 00:00:00 2001 From: Untone Date: Wed, 16 Apr 2025 11:45:38 +0300 Subject: [PATCH 1/4] draft-create-fix --- resolvers/draft.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resolvers/draft.py b/resolvers/draft.py index 2f47e01a..345318ed 100644 --- a/resolvers/draft.py +++ b/resolvers/draft.py @@ -116,7 +116,7 @@ async def create_draft(_, info, draft_input): if "id" in draft_input: del draft_input["id"] - if "seo" not in draft_input and not draft_input["seo"]: + if "seo" not in draft_input and not draft_input.get("seo"): body_teaser = draft_input.get("body", "")[:300].split("\n")[:-1].join("\n") draft_input["seo"] = draft_input.get("lead", body_teaser) From 243f836f0ab70de68f47c19de36d199173853dc1 Mon Sep 17 00:00:00 2001 From: Untone Date: Wed, 16 Apr 2025 11:48:47 +0300 Subject: [PATCH 2/4] draft-create-fix2 --- resolvers/draft.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/resolvers/draft.py b/resolvers/draft.py index 345318ed..d2c8d430 100644 --- a/resolvers/draft.py +++ b/resolvers/draft.py @@ -115,11 +115,7 @@ async def create_draft(_, info, draft_input): # Remove id from input if present since it's auto-generated if "id" in draft_input: del draft_input["id"] - - if "seo" not in draft_input and not draft_input.get("seo"): - body_teaser = draft_input.get("body", "")[:300].split("\n")[:-1].join("\n") - draft_input["seo"] = draft_input.get("lead", body_teaser) - + # Добавляем текущее время создания draft_input["created_at"] = int(time.time()) From d6ada44c7fa5fdd1a75076e76399c79bed015088 Mon Sep 17 00:00:00 2001 From: Untone Date: Wed, 16 Apr 2025 11:51:19 +0300 Subject: [PATCH 3/4] draft-create-fix3 --- resolvers/draft.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resolvers/draft.py b/resolvers/draft.py index d2c8d430..b3f68ba4 100644 --- a/resolvers/draft.py +++ b/resolvers/draft.py @@ -166,7 +166,7 @@ async def update_draft(_, info, draft_id: int, draft_input): body_text = trafilatura.extract(body_src) lead_src = draft_input["lead"] if "lead" in draft_input else draft.lead lead_text = trafilatura.extract(lead_src) - body_teaser = body_text[:300].split(". ")[:-1].join(".\n") + body_teaser = ". ".join(body_text[:300].split(". ")[:-1]) draft_input["seo"] = lead_text or body_teaser Draft.update(draft, draft_input) From aaa6022a53c2e70cf034514eeeb21ac249b5cb3f Mon Sep 17 00:00:00 2001 From: Untone Date: Wed, 16 Apr 2025 14:17:59 +0300 Subject: [PATCH 4/4] draft-create-fix4 --- app/resolvers/draft.py | 1 + resolvers/draft.py | 51 +++++++++++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 app/resolvers/draft.py diff --git a/app/resolvers/draft.py b/app/resolvers/draft.py new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/app/resolvers/draft.py @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resolvers/draft.py b/resolvers/draft.py index b3f68ba4..4c721c52 100644 --- a/resolvers/draft.py +++ b/resolvers/draft.py @@ -127,6 +127,11 @@ async def create_draft(_, info, draft_input): logger.error(f"Failed to create draft: {e}", exc_info=True) return {"error": f"Failed to create draft: {str(e)}"} +def generate_teaser(body, limit=300): + body_text = trafilatura.extract(body, include_comments=False, include_tables=False) + body_teaser = ". ".join(body_text[:limit].split(". ")[:-1]) + return body_teaser + @mutation.field("update_draft") @login_required @@ -161,21 +166,51 @@ async def update_draft(_, info, draft_id: int, draft_input): if not draft: return {"error": "Draft not found"} + # Generate SEO description if not provided and not already set if "seo" not in draft_input and not draft.seo: - body_src = draft_input["body"] if "body" in draft_input else draft.body - body_text = trafilatura.extract(body_src) - lead_src = draft_input["lead"] if "lead" in draft_input else draft.lead - lead_text = trafilatura.extract(lead_src) - body_teaser = ". ".join(body_text[:300].split(". ")[:-1]) - draft_input["seo"] = lead_text or body_teaser + body_src = draft_input.get("body") if "body" in draft_input else draft.body + lead_src = draft_input.get("lead") if "lead" in draft_input else draft.lead + body_text = None + if body_src: + try: + # Extract text, excluding comments and tables + body_text = trafilatura.extract(body_src, include_comments=False, include_tables=False) + except Exception as e: + logger.warning(f"Trafilatura failed to extract body text for draft {draft_id}: {e}") + + lead_text = None + if lead_src: + try: + # Extract text from lead + lead_text = trafilatura.extract(lead_src, include_comments=False, include_tables=False) + except Exception as e: + logger.warning(f"Trafilatura failed to extract lead text for draft {draft_id}: {e}") + + # Generate body teaser only if body_text was successfully extracted + body_teaser = generate_teaser(body_text, 300) if body_text else "" + + # Prioritize lead_text for SEO, fallback to body_teaser. Ensure it's a string. + generated_seo = lead_text if lead_text else body_teaser + draft_input["seo"] = generated_seo if generated_seo else "" + + # Update the draft object with new data from draft_input + # Assuming Draft.update is a helper that iterates keys or similar. + # A more standard SQLAlchemy approach would be: + # for key, value in draft_input.items(): + # if hasattr(draft, key): + # setattr(draft, key, value) + # But we stick to the existing pattern for now. Draft.update(draft, draft_input) - # Set updated_at and updated_by from the authenticated user + + # Set updated timestamp and author current_time = int(time.time()) draft.updated_at = current_time - draft.updated_by = author_id + draft.updated_by = author_id # Assuming author_id is correctly fetched context session.commit() + # Invalidate cache related to this draft if necessary (consider adding) + # await invalidate_draft_cache(draft_id) return {"draft": draft}