File size: 10,427 Bytes
fd40f81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import json
import os

SETTINGS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "settings.json")

DEFAULT_SETTINGS = {
    # Расписание
    "MORNING_SLOT_START": "08:30",
    "MORNING_SLOT_END": "10:00",
    "EVENING_SLOT_START": "18:30",
    "EVENING_SLOT_END": "20:00",
    "DAILY_CAROUSELS_LIMIT": 1,
    "DAILY_SINGLE_POSTS_LIMIT": 1,
    "CAROUSEL_SLIDE_COUNT": 5,
    
    # Промпты
    "PROMPT_SINGLE": """Використовуючи наступний новинний контекст:
\"\"\"{news_context}\"\"\"
{exclude_str}

Створи 1 одиночний пост для Threads українською мовою. Вибери одну найцікавішу новину з фокусом на одну з тем: ІІ-безпека/етика, DeFi/криптовалюти, або стартапи/тех-сектор.

⚡ ТВОЇ СУПЕРСИЛИ (SKILLS) & КРИТИЧНІ ПРАВИЛА:

1. РОЛЬ: SENIOR SOCIAL MEDIA COPYWRITER (Текст посту)
- Психологія: Пиши максимально живим, людським стилем (як реальний експерт у Threads), уникаючи будь-якого ШІ-жаргону. Тон: {tone}.
- Позиція та думка: КАТЕГОРИЧНО ЗАБОРОНЕНО використовувати шаблон "[Факт]. [Риторичний вопрос]. Деталі...". Замість цього додай власну чітку експертну думку/позицію перед будь-яким запитанням (наприклад: "Я вважаю X, тому що Y. А як до цього ставитесь ви?"). Позиція має бути до запитання, а не замість неї. Уникай пустих риторичних питань.
- Самодостатність: Пост має бути повністю самодостатнім і нести цінність одразу в тексті. Посилання або картинка — лише доповнення, а не привід клікати.
- Заголовки: Пиши заголовки-крючки (hook), що чіпляють увагу, а не нудні заголовки-новини.
- Посилання: КАТЕГОРИЧНО ЗАБОРОНЕНО вставляти будь-які URL або посилання в полі description. Посилання на джерело має повертатися виключно окремо в ключі source_url.
- Хештеги: КАТЕГОРИЧНО ЗАБОРОНЕНО використовувати масові теги (#AI, #Crypto, #ШІ, #Технології). Використовуй лише 1-2 вузьких тега максимум (наприклад, #DeFiУкраїна, #LLMбезпека, #ХарківTech). Розташовуй теги строго в самому кінці тексту.

2. РОЛЬ: ART DIRECTOR & UI/UX DESIGNER (Візуал)
- Дизайн фону: Ти створюєш преміальні промпти для генерації зображень (Flux.1). Ти ідеально відчуваєш композицію, тому завжди вимагаєш "clean negative space" для читабельності тексту.
- Копірайт для карток: Заголовок картки — до 4 слів (punchy). Тези — до 8 слів, тільки саме "м'ясо".

Поверни результат строго у форматі JSON із наступними ключами:
{
  "category": "одна з трьох категорій: 'AI', 'Business' або 'Crypto'",
  "bg_prompt": "англійською мовою детальний промпт для генерації фону (Flux.1). Premium dark aesthetics, volumetric lighting, glowing elements, background only, smooth clean negative space, absolutely no text",
  "card_title": "короткий заголовок (до 4 слів, без води)",
  "card_bullets": [
    "теза 1 (чіткий факт до 8 слів)",
    "теза 2 (висновок або інсайт до 8 слів)"
  ],
  "description": "Супровідний текст посту (до 400 символів). Жива мова з власною позицією, без шаблонів. Жодних посилань/URL у цьому тексті! Строго 1-2 вузьких тега в самому кінці.",
  "source_url": "коротке посилання на першоджерело новини (обов'язково)"
}

Повертай ТІЛЬКИ чистий JSON-об'єкт.""",

    "PROMPT_CAROUSEL": """Використовуючи наступний новинний контекст:
\"\"\"{news_context}\"\"\"
{exclude_str}

Створи глибокий розбір однієї з новин у вигляді каруселі з {slide_count} слайдів для Threads українською мовою з фокусом на теми: безпека/етика ІІ, DeFi/криптовалюти, або стартапи/тех-сфера.

⚡ ТВОЇ СУПЕРСИЛИ (SKILLS) & КРИТИЧНІ ПРАВИЛА:

1. РОЛЬ: SENIOR SOCIAL MEDIA COPYWRITER
- Сюжет: Будуй карусель як історію (Curiosity Gap). Кожен слайд змушує свайпнути далі. Тон: {tone}.
- Текст посту: Напиши коментар автора до каруселі. Він має бути повністю самодостатнім, нести самостійну цінність та містити твою чітку експертну думку/позицію перед питанням до аудиторії.
- Заборонені шаблони: КАТЕГОРИЧНО ЗАБОРОНЕНО використовувати шаблони на кшталт "[Факт]. [Риторичне питання]. Деталі в каруселі. Джерело". Натомість використовуй заголовок-крючок (hook).
- Заборонені фрази: Уникай типових ШІ-фразочок ("безумовно", "у сучасному світі", "у світі технологій"). Пиши як реальний живий експерт.
- Посилання: КАТЕГОРИЧНО ЗАБОРОНЕНО вставляти будь-які URL або посилання в полі description. Посилання на джерело має повертатися виключно окремо в ключі source_url.
- Хештеги: КАТЕГОРИЧНО ЗАБОРОНЕНО використовувати масові теги (#AI, #Crypto, #ШІ, #Технології). Використовуй лише 1-2 вузьких тега максимум. Розташовуй теги строго в самому кінці тексту.

2. РОЛЬ: ART DIRECTOR & UI/UX DESIGNER
- Фонова динаміка: Ти пишеш промпти для фонів так, щоб вони еволюціонували від слайду до слайду, зберігаючи загальну кінематографічную стилістику (premium dark aesthetics, neon, volumetric lighting).
- Читабельність: Завжди гарантуй вільний простір для тексту ('smooth clean negative space, absolutely no text').

Поверни результат строго у форматі JSON із наступними ключами:
{
  "category": "одна з трьох категорій: 'AI', 'Business' або 'Crypto'",
  "description": "Супровідний текст посту (до 350 символів). Жива людська мова, що виражає твою позицію та інтригує переглянути карусель. Жодних посилань/URL у цьому полі! Строго 1-2 вузьких тега в самому кінці.",
  "source_url": "коротке посилання на першоджерело новини (обов'язково)",
  "slides": [ масив з {slide_count} об'єктів слайдів: { "title": "...", "bullets": ["...", "..."], "bg_prompt": "..." } ]
}

Повертай ТІЛЬКИ чистий JSON-об'єкт.""",

    "PROMPT_PREDICTOR": """Ты — AI-редактор и эксперт по виральному контенту в соцсетях.
Твоя задача — оценить черновик поста для Threads перед его публикацией.
{context}
Черновик поста:
--- {post_text} ---

Оцени потенциал этого поста по 10-балльной шкале (где 10 — абсолютный хит, а 1 — скучная новостная сводка, которую никто не лайкнет).
Пост должен иметь мощный 'крючок' (hook) в первом предложении, вызывать эмоции (шок, интерес, несогласие) и стимулировать дискуссию в комментариях.

Верни СТРОГО JSON:
{
  "score": 8,
  "criticism": "оставь пустым, если балл >= 7, иначе напиши 1-2 предложения, что именно изменить"
}
Возвращай только чистый JSON без markdown."""
}

def load_settings():
    if not os.path.exists(SETTINGS_PATH):
        return DEFAULT_SETTINGS.copy()
    try:
        with open(SETTINGS_PATH, "r", encoding="utf-8") as f:
            data = json.load(f)
            # Merge with defaults to ensure all keys exist
            merged = DEFAULT_SETTINGS.copy()
            merged.update(data)
            return merged
    except Exception as e:
        print(f"[SettingsManager] Ошибка чтения settings.json: {e}")
        return DEFAULT_SETTINGS.copy()

def save_settings(new_settings):
    try:
        current = load_settings()
        current.update(new_settings)
        with open(SETTINGS_PATH, "w", encoding="utf-8") as f:
            json.dump(current, f, ensure_ascii=False, indent=2)
        return True
    except Exception as e:
        print(f"[SettingsManager] Ошибка записи settings.json: {e}")
        return False