diff --git a/STATE.md b/STATE.md index 933411a..a059cb1 100644 --- a/STATE.md +++ b/STATE.md @@ -100,6 +100,11 @@ canonical git repository as FN-8. Code work for both projects must happen in - The editor textarea must show only clean editable text. - The list preview in `/editor` should show the publication preview, including composed hashtags. - `build_publication_text()` in `src/vk_parser_app/text_utils.py` is display/composition helper only. Do not use it before writing `final_text` to DB. +- `/raw` has a manual checkbox action to send rejected posts back to rewrite. + It resets stale rewrite/final fields and sets `rewrite_status='pending'`. +- VK/MAX successful publications also sync `raw_posts.publication_status` and + `editorial_status` to `published`; this keeps VK-only projects from leaving + posts forever in the editor's accepted tab. ## Recent Hotfix: Hashtags diff --git a/db/migrations/045_sync_publication_status_from_platforms.sql b/db/migrations/045_sync_publication_status_from_platforms.sql new file mode 100644 index 0000000..1ddfb34 --- /dev/null +++ b/db/migrations/045_sync_publication_status_from_platforms.sql @@ -0,0 +1,33 @@ +UPDATE raw_posts rp +SET publication_status='published', + editorial_status='published', + publication_error=NULL, + published_at=COALESCE(rp.published_at, pp.published_at, NOW()), + updated_at=NOW() +FROM ( + SELECT raw_post_id, MIN(published_at) AS published_at + FROM post_publications + WHERE status='published' + GROUP BY raw_post_id +) pp +WHERE rp.id=pp.raw_post_id + AND COALESCE(rp.editorial_status, 'review') IN ('accepted', 'publish_failed'); + +UPDATE raw_posts rp +SET publication_status='publish_failed', + editorial_status='publish_failed', + publication_error=COALESCE(pp.error, rp.publication_error), + updated_at=NOW() +FROM ( + SELECT DISTINCT ON (raw_post_id) raw_post_id, error + FROM post_publications + WHERE status='publish_failed' + ORDER BY raw_post_id, updated_at DESC NULLS LAST, id DESC +) pp +WHERE rp.id=pp.raw_post_id + AND COALESCE(rp.editorial_status, 'review')='accepted' + AND NOT EXISTS ( + SELECT 1 + FROM post_publications ok + WHERE ok.raw_post_id=rp.id AND ok.status='published' + ); diff --git a/src/vk_parser_app/admin.py b/src/vk_parser_app/admin.py index 78e943c..c36e762 100644 --- a/src/vk_parser_app/admin.py +++ b/src/vk_parser_app/admin.py @@ -2726,7 +2726,11 @@ async def raw_send_to_rewrite( FROM raw_posts WHERE id=ANY($1::bigint[]) AND status='storage_ready' - AND COALESCE(rewrite_status, 'pending') IN ('pending', 'failed') + AND ( + COALESCE(rewrite_status, 'pending') IN ('pending', 'failed') + OR COALESCE(qualification_status, 'pending')='rejected' + OR COALESCE(editorial_status, 'review')='rejected' + ) FOR UPDATE ) UPDATE raw_posts rp @@ -2737,8 +2741,19 @@ async def raw_send_to_rewrite( qualification_reject_tag=NULL, qualified_at=NOW(), rewrite_status='pending', + rewritten_text=NULL, rewrite_notes=NULL, rewrite_batch_id=NULL, + rewrite_category=NULL, + rewrite_category_tag=NULL, + rewrite_source_tag=NULL, + rewrite_category_id=NULL, + final_text=NULL, + final_category=NULL, + final_category_tag=NULL, + final_source_tag=NULL, + final_category_id=NULL, + editor_notes=NULL, editorial_status=NULL, updated_at=NOW() FROM selected diff --git a/src/vk_parser_app/templates/raw_posts_content.html b/src/vk_parser_app/templates/raw_posts_content.html index c4ce3eb..2ecff46 100644 --- a/src/vk_parser_app/templates/raw_posts_content.html +++ b/src/vk_parser_app/templates/raw_posts_content.html @@ -84,7 +84,11 @@ Всего: {{ pagination.total }} -
| # | Источник | Этап | @@ -146,8 +172,11 @@||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| + + | - #{{ p.id }} + #{{ p.id }} | {{ p.source_name }} @@ -171,9 +200,23 @@ {% endif %} |
-
- {{ p.raw_text }}
-
+
+
{% if p.posted_at_fmt %}
+ {{ p.raw_text }} + {{ p.raw_text }} ++ {% if p.media_items %} +
+ {% for m in p.media_items %}
+ {% if m.type == "photo" and m.url %}
+
+ {% endif %}
+ Опубликован: {{ p.posted_at_fmt }}
{% else %}
@@ -190,7 +233,7 @@
| |||||||
| + |
Нет данных по заданным фильтрам diff --git a/src/vk_parser_app/workers/max_poster.py b/src/vk_parser_app/workers/max_poster.py index 127af90..09ed552 100644 --- a/src/vk_parser_app/workers/max_poster.py +++ b/src/vk_parser_app/workers/max_poster.py @@ -661,6 +661,40 @@ class MAXPoster: json.dumps(attachments or [], ensure_ascii=False), PUBLICATION_STATUS_PUBLISHED, ) + if status == PUBLICATION_STATUS_PUBLISHED: + await self.pool.execute( + """ + UPDATE raw_posts + SET publication_status=$2, + editorial_status='published', + publication_error=NULL, + published_at=COALESCE(published_at, NOW()), + updated_at=NOW() + WHERE id=$1 + """, + post_id, + PUBLICATION_STATUS_PUBLISHED, + ) + elif status == PUBLICATION_STATUS_FAILED: + await self.pool.execute( + """ + UPDATE raw_posts rp + SET publication_status=$2, + editorial_status='publish_failed', + publication_error=$3, + updated_at=NOW() + WHERE rp.id=$1 + AND NOT EXISTS ( + SELECT 1 + FROM post_publications pp + WHERE pp.raw_post_id=rp.id AND pp.status=$4 + ) + """, + post_id, + PUBLICATION_STATUS_FAILED, + error[:1000] if error else None, + PUBLICATION_STATUS_PUBLISHED, + ) async def process_slot(self, slot: dict[str, Any]) -> int: count = int(slot["count"]) diff --git a/src/vk_parser_app/workers/vk_poster.py b/src/vk_parser_app/workers/vk_poster.py index 2c6e926..2aafbdd 100644 --- a/src/vk_parser_app/workers/vk_poster.py +++ b/src/vk_parser_app/workers/vk_poster.py @@ -381,6 +381,40 @@ class VKPoster: json.dumps(attachments or [], ensure_ascii=False), PUBLICATION_STATUS_PUBLISHED, ) + if status == PUBLICATION_STATUS_PUBLISHED: + await self.pool.execute( + """ + UPDATE raw_posts + SET publication_status=$2, + editorial_status='published', + publication_error=NULL, + published_at=COALESCE(published_at, NOW()), + updated_at=NOW() + WHERE id=$1 + """, + post_id, + PUBLICATION_STATUS_PUBLISHED, + ) + elif status == PUBLICATION_STATUS_FAILED: + await self.pool.execute( + """ + UPDATE raw_posts rp + SET publication_status=$2, + editorial_status='publish_failed', + publication_error=$3, + updated_at=NOW() + WHERE rp.id=$1 + AND NOT EXISTS ( + SELECT 1 + FROM post_publications pp + WHERE pp.raw_post_id=rp.id AND pp.status=$4 + ) + """, + post_id, + PUBLICATION_STATUS_FAILED, + error[:1000] if error else None, + PUBLICATION_STATUS_PUBLISHED, + ) async def process_slot(self, slot: dict[str, Any]) -> int: count = int(slot["count"]) | |||||||||