diff --git a/admin/pages/generation.py b/admin/pages/generation.py index 25b1d55..7111fd4 100644 --- a/admin/pages/generation.py +++ b/admin/pages/generation.py @@ -2,13 +2,7 @@ import streamlit as st -from scheduler import ( - DATA_DIR, - get_next_run, - get_state, - publish_latest_post, - start_generation, -) +from scheduler import DATA_DIR, get_next_run, get_state, start_generation OUTPUT_DIR = DATA_DIR / "output" @@ -53,7 +47,9 @@ log_path.write_text("".join(lines), encoding="utf-8") if process.returncode == 0: - publish_latest_post() - status.update(label="Пост сгенерирован!", state="complete") + status.update( + label="Пост сгенерирован! Опубликуйте его на странице Посты", + state="complete", + ) else: status.update(label="Ошибка генерации", state="error") diff --git a/admin/pages/posts.py b/admin/pages/posts.py index c4d6bb2..cb44cea 100644 --- a/admin/pages/posts.py +++ b/admin/pages/posts.py @@ -38,27 +38,27 @@ parts = content.split("---", 2) st.markdown(parts[2] if len(parts) >= 3 else content) + published = POSTS_DIR / md_file.name + is_published = published.exists() + if st.button( + "Опубликовано" if is_published else "Опубликовать", + disabled=is_published, + type="primary", + ): + POSTS_DIR.mkdir(parents=True, exist_ok=True) + shutil.copy2(md_file, published) + st.success("Пост опубликован в блог!") + st.rerun() + with tab_edit: edited = st.text_area("Редактировать пост", value=content, height=400) - col1, col2 = st.columns(2) - with col1: - if st.button("Сохранить"): - md_file.write_text(edited, encoding="utf-8") - st.success("Сохранено!") - with col2: - published = POSTS_DIR / md_file.name - is_published = published.exists() - if st.button( - "Опубликовано" if is_published else "Опубликовать", - disabled=is_published, - ): - POSTS_DIR.mkdir(parents=True, exist_ok=True) - shutil.copy2(md_file, published) - st.success("Пост опубликован в блог!") - st.rerun() + if st.button("Сохранить"): + md_file.write_text(edited, encoding="utf-8") + st.success("Сохранено!") with tab_files: for f in sorted(run_dir.iterdir()): + if f.suffix == ".md": + continue with st.expander(f.name): - lang = "markdown" if f.suffix == ".md" else "text" - st.code(f.read_text(encoding="utf-8"), language=lang) + st.code(f.read_text(encoding="utf-8"), language="text") diff --git a/admin/pages/prompts.py b/admin/pages/prompts.py index b987ce5..3e450d6 100644 --- a/admin/pages/prompts.py +++ b/admin/pages/prompts.py @@ -28,10 +28,10 @@ def _read_prompt(filename: str) -> str: pvc_path = PROMPTS_DIR / filename if pvc_path.exists(): - return pvc_path.read_text(encoding="utf-8") + return str(pvc_path.read_text(encoding="utf-8")) default_path = DEFAULT_PROMPTS_DIR / filename if default_path.exists(): - return default_path.read_text(encoding="utf-8") + return str(default_path.read_text(encoding="utf-8")) return "" @@ -58,8 +58,9 @@ def _save_prompt(filename: str, content: str) -> None: if st.button("Сбросить к дефолту", key=f"reset_{filename}"): default = DEFAULT_PROMPTS_DIR / filename if default.exists(): - _save_prompt(filename, default.read_text(encoding="utf-8")) - st.success("Сброшено к значению по умолчанию!") + content = default.read_text(encoding="utf-8") + _save_prompt(filename, content) + st.session_state[f"prompt_{filename}"] = content st.rerun() else: st.warning("Дефолтный промпт не найден") diff --git a/admin/pages/schedule.py b/admin/pages/schedule.py index 733fed0..8d56b5d 100644 --- a/admin/pages/schedule.py +++ b/admin/pages/schedule.py @@ -24,6 +24,13 @@ placeholder="0 10 * * 1", ) +auto_publish = st.checkbox( + "Автопубликация после генерации", + value=state.get("auto_publish", False), + help="Если включено — пост сразу публикуется в блог. " + "Иначе — нужно опубликовать вручную на странице Посты", +) + col1, col2 = st.columns(2) with col1: @@ -32,7 +39,7 @@ st.error("Введите cron-выражение") else: try: - set_schedule(cron_input.strip()) + set_schedule(cron_input.strip(), auto_publish) st.success(f"Расписание установлено: `{cron_input}`") st.rerun() except ValueError as e: diff --git a/admin/scheduler.py b/admin/scheduler.py index b106ac0..101d9a1 100644 --- a/admin/scheduler.py +++ b/admin/scheduler.py @@ -69,7 +69,11 @@ def _run_generation() -> None: return logger.info("Генерация завершена успешно") - publish_latest_post() + state = get_state() + if state.get("auto_publish", False): + publish_latest_post() + else: + logger.info("Автопубликация отключена, пост не опубликован") def publish_latest_post() -> None: @@ -104,10 +108,16 @@ def get_scheduler() -> BackgroundScheduler: return _scheduler -def _save_state(cron_expr: str, enabled: bool) -> None: +def _save_state(cron_expr: str, enabled: bool, auto_publish: bool = False) -> None: DATA_DIR.mkdir(parents=True, exist_ok=True) STATE_FILE.write_text( - json.dumps({"cron": cron_expr, "enabled": enabled}), + json.dumps( + { + "cron": cron_expr, + "enabled": enabled, + "auto_publish": auto_publish, + } + ), encoding="utf-8", ) @@ -123,7 +133,7 @@ def _restore_schedule() -> None: logger.exception("Не удалось восстановить расписание") -def set_schedule(cron_expr: str) -> None: +def set_schedule(cron_expr: str, auto_publish: bool = False) -> None: """Устанавливает расписание. Формат cron: '0 10 * * 1'.""" sched = get_scheduler() diff --git a/app/post_builder.py b/app/post_builder.py index 9321b7f..b5d20c0 100644 --- a/app/post_builder.py +++ b/app/post_builder.py @@ -69,9 +69,10 @@ def write_post(content: str, config: AppConfig) -> Path: title, body = _parse_title_and_body(content) + safe_title = title.replace('"', '\\"') front_matter_lines = [f"date: {today}"] if title: - front_matter_lines.append(f"title: {title}") + front_matter_lines.append(f'title: "{safe_title}"') front_matter = "---\n" + "\n".join(front_matter_lines) + "\n---\n\n"