feat: target channel context history, custom website extraction needs, and categorized main menu
This commit is contained in:
+2
-1
@@ -170,8 +170,9 @@ ALTER TABLE targets ADD COLUMN IF NOT EXISTS sleep_end_hour INT DEFAULT 0;
|
||||
ALTER TABLE targets ADD COLUMN IF NOT EXISTS is_sleep_enabled BOOLEAN DEFAULT FALSE;
|
||||
ALTER TABLE targets ADD COLUMN IF NOT EXISTS auto_source_ids BIGINT[] DEFAULT '{}';
|
||||
ALTER TABLE targets ADD COLUMN IF NOT EXISTS language VARCHAR(32) DEFAULT 'fa';
|
||||
ALTER TABLE targets ADD COLUMN IF NOT EXISTS custom_prompt TEXT DEFAULT '';
|
||||
ALTER TABLE targets ADD COLUMN IF NOT EXISTS dispatch_order VARCHAR(32) DEFAULT 'order';
|
||||
ALTER TABLE targets ADD COLUMN IF NOT EXISTS context_message_count INT DEFAULT 0;
|
||||
ALTER TABLE source_websites ADD COLUMN IF NOT EXISTS custom_instructions TEXT DEFAULT '';
|
||||
ALTER TABLE sources ADD COLUMN IF NOT EXISTS context_message_count INT DEFAULT 0;
|
||||
ALTER TABLE posts ADD COLUMN IF NOT EXISTS source_created_at TIMESTAMPTZ;
|
||||
CREATE INDEX IF NOT EXISTS idx_posts_source_created ON posts(source_channel_id, source_created_at DESC);
|
||||
|
||||
@@ -31,6 +31,7 @@ class SourceWebsite:
|
||||
last_reanalyzed_at: Optional[str] = None
|
||||
last_fetched_at: Optional[str] = None
|
||||
api_config: Dict[str, Any] = field(default_factory=dict)
|
||||
custom_instructions: str = ""
|
||||
last_error: Optional[str] = None
|
||||
last_error_at: Optional[str] = None
|
||||
is_active: bool = True
|
||||
@@ -54,6 +55,7 @@ class TargetChannel:
|
||||
auto_source_ids: List[int] = field(default_factory=list)
|
||||
language: str = "fa"
|
||||
dispatch_order: str = "order" # "order" (FIFO) or "random"
|
||||
context_message_count: int = 0
|
||||
last_post_time: Optional[str] = None
|
||||
is_active: bool = True
|
||||
created_at: Optional[str] = None
|
||||
|
||||
+45
-4
@@ -92,22 +92,24 @@ class Repository:
|
||||
category_id: Optional[int] = None,
|
||||
check_interval_min: int = 30,
|
||||
auto_reanalyze_hours: int = 24,
|
||||
api_config: Optional[Dict[str, Any]] = None
|
||||
api_config: Optional[Dict[str, Any]] = None,
|
||||
custom_instructions: str = ""
|
||||
) -> int:
|
||||
pool = await self._get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
cfg_json = json.dumps(api_config or {})
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
INSERT INTO source_websites (name, url, category_id, check_interval_min, auto_reanalyze_hours, api_config)
|
||||
VALUES ($1, $2, $3, $4, $5, $6::jsonb)
|
||||
INSERT INTO source_websites (name, url, category_id, check_interval_min, auto_reanalyze_hours, api_config, custom_instructions)
|
||||
VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7)
|
||||
ON CONFLICT(url) DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
category_id = COALESCE(EXCLUDED.category_id, source_websites.category_id),
|
||||
custom_instructions = COALESCE(NULLIF(EXCLUDED.custom_instructions, ''), source_websites.custom_instructions),
|
||||
is_active = TRUE
|
||||
RETURNING id;
|
||||
""",
|
||||
name, url, category_id, check_interval_min, auto_reanalyze_hours, cfg_json
|
||||
name, url, category_id, check_interval_min, auto_reanalyze_hours, cfg_json, custom_instructions
|
||||
)
|
||||
return row["id"]
|
||||
|
||||
@@ -190,11 +192,50 @@ class Repository:
|
||||
async with pool.acquire() as conn:
|
||||
await conn.execute("UPDATE source_websites SET auto_reanalyze_hours = $1 WHERE id = $2;", max(0, hours), site_id)
|
||||
|
||||
async def update_source_website_custom_instructions(self, site_id: int, instructions: str) -> None:
|
||||
pool = await self._get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
await conn.execute("UPDATE source_websites SET custom_instructions = $1 WHERE id = $2;", instructions.strip(), site_id)
|
||||
|
||||
async def delete_source_website(self, site_id: int) -> None:
|
||||
pool = await self._get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
await conn.execute("UPDATE source_websites SET is_active = FALSE WHERE id = $1;", site_id)
|
||||
|
||||
async def update_target_context_count(self, target_id: int, count: int) -> None:
|
||||
pool = await self._get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
await conn.execute("UPDATE targets SET context_message_count = $1 WHERE id = $2;", max(0, count), target_id)
|
||||
|
||||
async def get_recent_target_posts(
|
||||
self,
|
||||
target_id: int,
|
||||
limit: int = 10,
|
||||
exclude_post_id: Optional[int] = None
|
||||
) -> List[Post]:
|
||||
if limit <= 0:
|
||||
return []
|
||||
pool = await self._get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
rows = await conn.fetch(
|
||||
"""
|
||||
SELECT * FROM posts
|
||||
WHERE (
|
||||
status = 'published'
|
||||
OR target_channel_id = $1
|
||||
OR published_to::text LIKE '%"target_id": ' || $1 || '%'
|
||||
)
|
||||
AND ($2::BIGINT IS NULL OR id != $2)
|
||||
AND is_deleted = FALSE
|
||||
ORDER BY COALESCE(published_at, created_at) DESC, id DESC
|
||||
LIMIT $3;
|
||||
""",
|
||||
target_id, exclude_post_id, limit
|
||||
)
|
||||
posts = [_parse_post_row(r) for r in rows]
|
||||
posts.reverse()
|
||||
return posts
|
||||
|
||||
async def delete_target(self, target_id: int) -> None:
|
||||
pool = await self._get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
|
||||
Reference in New Issue
Block a user