Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a7590995e4 | |||
| d7b4b48cc7 | |||
| 3f5284e067 | |||
| 50d2e62694 | |||
| 70dee494f3 | |||
| 4b2a94002b | |||
| 9eb872391e | |||
| 784830bd62 | |||
| 252bda696f | |||
| ef822d0eba | |||
| cc54fd52c6 | |||
| e4115b8baa | |||
| b99e3e88c9 | |||
| 35198a8edb | |||
| c9142c3f8a | |||
| 9797ddf3f7 | |||
| b92239fb1b | |||
| 105f4d5492 | |||
| e92349e111 | |||
| 0912d658b8 | |||
| 8e63db4424 | |||
| 0335937312 | |||
| 6a0f8d7196 | |||
| 407a63f3cf | |||
| eec8b477be | |||
| 489e95d677 | |||
| 47cbcb25bc | |||
| 527c411d87 | |||
| c8aecaeb03 | |||
| bf63610510 | |||
| 7af3a7f21d | |||
| 4783e9d88e | |||
| ccbd24be11 | |||
| 16ed5459fa | |||
| ca7dc10e92 | |||
| 94efc524c6 | |||
| 436f897711 | |||
| 9d6cea0453 | |||
| c9433a5e98 | |||
| 7d3c5c2ae1 | |||
| 51c76ebd24 | |||
| facf39e778 | |||
| 51cecf1f4e | |||
| 79e4eb4de0 | |||
| 70b40cb90b | |||
| 22c32a9f3d | |||
| c3791ce961 | |||
| 27e24e2a86 | |||
| 0864c99b75 | |||
| 0c6057de28 | |||
| 6f20e5978d | |||
| 56ff1e8163 | |||
| 9ec479415a | |||
| 7652718803 | |||
| d2f64f98a1 | |||
| 161b93f368 | |||
| 31f2d8b428 | |||
| 5d6dd10dfa | |||
| d0f7b07260 | |||
| 0be768ca8e | |||
| 68ecb16303 | |||
| 82d928f497 | |||
| c99eca35f0 | |||
| 47b195ed1c | |||
| 1f1528979c | |||
| bcb24e474d | |||
| a19b260ef7 | |||
| 1d8ce5cfb9 | |||
| cb2cbd4c6b | |||
| c0d221c2a3 | |||
| 6b775c99f9 | |||
| 061bfa3b55 | |||
| 2eccc11369 | |||
| d874577458 | |||
| bc59fb39db | |||
| fba2c1290d | |||
| 6490ceff08 | |||
| e13fa0e337 | |||
| 3eae1595aa | |||
| 6f0905d83a | |||
| 033b7509d7 | |||
| 8f9a8d2ad5 | |||
| ffe7adcad2 | |||
| 963dd1846b | |||
| ad6d369069 | |||
| 68411813b3 | |||
| d8780b9000 | |||
| 196bfaf213 | |||
| 2675edb695 | |||
| 1f9d0a7ea2 | |||
| 4642a278a5 | |||
| 598a86b32d | |||
| ae27641b6d | |||
| 7ab6647c32 |
77
README.md
77
README.md
@@ -96,6 +96,11 @@ API端点:
|
||||
| `/api/tags` | GET | 列出标签 |
|
||||
| `/api/tags` | POST | 创建标签 |
|
||||
| `/api/tags/<id>` | DELETE | 删除标签 |
|
||||
| `/api/emails` | GET | 列出邮箱 |
|
||||
| `/api/emails` | POST | 创建邮箱 |
|
||||
| `/api/emails/<id>` | PUT | 更新邮箱 |
|
||||
| `/api/emails/<id>` | DELETE | 删除邮箱 |
|
||||
| `/api/send-email` | POST | 发送收藏到邮箱 |
|
||||
| `/api/stats` | GET | 统计信息 |
|
||||
| `/api/search` | GET | 搜索 (参数 q=关键词) |
|
||||
|
||||
@@ -136,6 +141,78 @@ xian-favor/
|
||||
|
||||
## 版本历史
|
||||
|
||||
- **v2.4.0** (2026-04-16): 数据库备份机制
|
||||
- 自动备份:每天 04:00 执行
|
||||
- 手动备份:页面一键操作
|
||||
- 备份清理规则:保留30天 + 每月第一天永久保留
|
||||
- 手动备份最多保留10个
|
||||
- 支持恢复备份和删除备份
|
||||
- 备份管理页面入口在侧边栏
|
||||
- **v2.3.2** (2026-04-16): 搜索功能修复
|
||||
- 修复 debounce 函数定义顺序问题
|
||||
- 搜索框输入后可正常过滤列表
|
||||
- **v2.3.1** (2026-04-16): 日期放到标题后面,不增加卡片高度
|
||||
- 日期紧跟标题,同一行显示
|
||||
- 格式紧凑:`04-16 11:09→04-16 12:00`
|
||||
- **v2.3.0** (2026-04-16): 卡片显示创建和更新日期
|
||||
- 每个收藏卡片底部显示日期
|
||||
- 格式:04-16 11:09(月-日 时:分)
|
||||
- 有更新时显示:创建 → 更新
|
||||
- 字体更小更淡,不影响卡片高度
|
||||
- **v2.2.0** (2026-04-16): 快捷添加按钮,一键选择类型
|
||||
- 顶部按钮栏分离为4个快捷添加按钮(文本、链接、待办、专栏)
|
||||
- 点击直接进入对应类型的添加弹窗
|
||||
- 弹窗标题显示类型图标和名称
|
||||
- 不再需要下拉选择类型,操作更快捷
|
||||
- **v2.1.0** (2026-04-16): 待办截止时间支持日期+时间
|
||||
- 截止日期改为日期时间选择器
|
||||
- 列表显示友好格式:今天 18:30、明天 09:00 等
|
||||
- 详情页显示完整格式:2026年4月16日 18:30
|
||||
- 后端支持多种日期格式解析
|
||||
- 只有日期的待办视为当天 23:59 到期
|
||||
- **v2.0.1** (2026-04-16): 转换弹窗优化
|
||||
- 内容预览保留换行格式,提高可读性
|
||||
- 转换方式默认改为复制创建
|
||||
- **v2.0.0** (2026-04-16): 收藏转待办功能(大版本更新)
|
||||
- 新增 `/api/items/<id>/convert` API
|
||||
- **直接转换**:原收藏变为待办,数据合并
|
||||
- **复制创建**:保留原收藏,新建待办任务
|
||||
- 文本/链接/专栏类型可转换
|
||||
- 内容自动合并到待办备注
|
||||
- 前端列表和详情页添加转换按钮
|
||||
- 弹窗配置:标题、状态、优先级、截止日期
|
||||
- v1.11.0 (2026-04-16): 已完成待办可重新打开
|
||||
- 新增 `/api/items/<id>/reopen` 接口
|
||||
- 前端列表已完成待办显示重新打开按钮(↻图标)
|
||||
- 可恢复为 pending 或 in_progress 状态
|
||||
- v1.10.0 (2026-04-16): 网页端待办到期提醒功能
|
||||
- 新增提醒 API `/api/reminders`
|
||||
- 获取已过期、今天到期、即将到期的待办
|
||||
- 前端顶部提醒栏显示提醒数量和概要
|
||||
- 弹窗详情支持快速完成待办
|
||||
- 每5分钟自动刷新提醒
|
||||
- v1.9.2 (2026-04-14): 邮件发送历史记录
|
||||
- 详情页面显示邮件发送记录(发送邮箱、时间)
|
||||
- 支持多次发送,显示多条记录
|
||||
- 发送成功/失败状态标记
|
||||
- v1.9.0 (2026-04-14): 发送邮件功能 + 邮箱管理
|
||||
- 每个收藏卡片添加"发送邮件"按钮
|
||||
- 选择已有邮箱或输入新邮箱发送
|
||||
- 新邮箱自动保存到邮箱管理
|
||||
- 邮箱管理页面:添加、编辑、删除邮箱
|
||||
- SMTP配置支持环境变量(SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS)
|
||||
- v1.8.0 (2026-04-13): AI自动添加功能,智能识别文本类型并整理数据
|
||||
- 首页新增"AI添加"按钮
|
||||
- 粘贴文本/链接/笔记等,AI自动识别类型并提取关键信息
|
||||
- 支持文本、链接、专栏、待办四种类型自动识别
|
||||
- 自动生成标签和标题
|
||||
- v1.7.0 (2026-04-13): 编辑收藏时支持更改类型,动态显示对应字段
|
||||
- v1.6.0 (2026-04-13): 标签管理添加编辑功能,支持修改标签名称
|
||||
- v1.5.1 (2026-04-13): 标签管理添加搜索功能,实时过滤标签列表
|
||||
- v1.5.0 (2026-04-13): 首页添加分页功能,每页20条记录
|
||||
- v1.4.0 (2026-04-13): 首页添加导出按钮,一键导出所有收藏为JSON文件
|
||||
- v1.3.2 (2026-04-13): 编辑和添加模态框改为大尺寸(modal-lg)
|
||||
- v1.3.1 (2026-04-13): 备注改名为详情,支持换行显示,扩大输入框
|
||||
- v1.3.0 (2026-04-13): 标签管理功能和输入自动提示
|
||||
- 侧边栏新增"标签管理"入口
|
||||
- 标签管理页面:显示所有标签、使用条目数、创建/删除标签
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,12 +2,17 @@
|
||||
|
||||
import sqlite3
|
||||
import json
|
||||
from datetime import datetime
|
||||
import shutil
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional, List, Dict, Any
|
||||
from contextlib import contextmanager
|
||||
|
||||
from .config import DATABASE_URL, TODO_STATUS, PRIORITY_LEVELS
|
||||
|
||||
# 备份目录
|
||||
BACKUP_DIR = os.path.join(os.path.dirname(DATABASE_URL), 'backups')
|
||||
|
||||
|
||||
class Database:
|
||||
"""SQLite数据库管理"""
|
||||
@@ -80,6 +85,28 @@ class Database:
|
||||
)
|
||||
""")
|
||||
|
||||
# 邮箱表
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS emails (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
name TEXT,
|
||||
created_at TEXT NOT NULL
|
||||
)
|
||||
""")
|
||||
|
||||
# 邮件发送记录表
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS email_logs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
item_id INTEGER NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
sent_at TEXT NOT NULL,
|
||||
success INTEGER DEFAULT 1,
|
||||
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE
|
||||
)
|
||||
""")
|
||||
|
||||
# 创建索引
|
||||
cursor.execute("CREATE INDEX IF NOT EXISTS idx_items_type ON items(type)")
|
||||
cursor.execute("CREATE INDEX IF NOT EXISTS idx_items_status ON items(status)")
|
||||
@@ -177,6 +204,41 @@ class Database:
|
||||
|
||||
return items
|
||||
|
||||
def count_items(self, type: str = None, status: str = None, tag: str = None,
|
||||
keyword: str = None) -> int:
|
||||
"""计算符合条件的条目总数"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
query = "SELECT COUNT(DISTINCT i.id) as count FROM items i"
|
||||
params = []
|
||||
conditions = []
|
||||
|
||||
# 标签过滤需要JOIN
|
||||
if tag:
|
||||
query += " JOIN item_tags it ON i.id = it.item_id JOIN tags t ON it.tag_id = t.id"
|
||||
conditions.append("t.name = ?")
|
||||
params.append(tag)
|
||||
|
||||
if type:
|
||||
conditions.append("i.type = ?")
|
||||
params.append(type)
|
||||
|
||||
if status:
|
||||
conditions.append("i.status = ?")
|
||||
params.append(status)
|
||||
|
||||
if keyword:
|
||||
conditions.append("(i.title LIKE ? OR i.content LIKE ? OR i.note LIKE ?)")
|
||||
keyword_pattern = f"%{keyword}%"
|
||||
params.extend([keyword_pattern, keyword_pattern, keyword_pattern])
|
||||
|
||||
if conditions:
|
||||
query += " WHERE " + " AND ".join(conditions)
|
||||
|
||||
cursor.execute(query, params)
|
||||
return cursor.fetchone()['count']
|
||||
|
||||
def update_item(self, item_id: int, **kwargs) -> bool:
|
||||
"""更新条目"""
|
||||
allowed_fields = ['type', 'title', 'content', 'url', 'source', 'status', 'priority', 'due_date', 'note']
|
||||
@@ -244,6 +306,18 @@ class Database:
|
||||
""")
|
||||
return [dict(row) for row in cursor.fetchall()]
|
||||
|
||||
def update_tag(self, tag_id: int, name: str) -> bool:
|
||||
"""更新标签名称"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
# 检查名称是否已存在(排除自己)
|
||||
cursor.execute("SELECT id FROM tags WHERE name = ? AND id != ?", (name, tag_id))
|
||||
if cursor.fetchone():
|
||||
return False # 名称已存在
|
||||
cursor.execute("UPDATE tags SET name = ? WHERE id = ?", (name, tag_id))
|
||||
conn.commit()
|
||||
return cursor.rowcount > 0
|
||||
|
||||
def delete_tag(self, tag_id: int = None, name: str = None) -> bool:
|
||||
"""删除标签"""
|
||||
with self.get_conn() as conn:
|
||||
@@ -290,6 +364,90 @@ class Database:
|
||||
""", (item_id,))
|
||||
return [row['name'] for row in cursor.fetchall()]
|
||||
|
||||
# ============ Email 操作 ============
|
||||
|
||||
def create_email(self, email: str, name: str = None) -> int:
|
||||
"""创建邮箱"""
|
||||
now = datetime.now().isoformat()
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
try:
|
||||
cursor.execute("INSERT INTO emails (email, name, created_at) VALUES (?, ?, ?)",
|
||||
(email, name, now))
|
||||
conn.commit()
|
||||
return cursor.lastrowid
|
||||
except sqlite3.IntegrityError:
|
||||
# 邮箱已存在,返回已有ID
|
||||
cursor.execute("SELECT id FROM emails WHERE email = ?", (email,))
|
||||
return cursor.fetchone()['id']
|
||||
|
||||
def list_emails(self) -> List[Dict[str, Any]]:
|
||||
"""列出所有邮箱"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT * FROM emails ORDER BY created_at DESC")
|
||||
return [dict(row) for row in cursor.fetchall()]
|
||||
|
||||
def get_email(self, email_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""获取单个邮箱"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT * FROM emails WHERE id = ?", (email_id,))
|
||||
row = cursor.fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def update_email(self, email_id: int, email: str = None, name: str = None) -> bool:
|
||||
"""更新邮箱"""
|
||||
now = datetime.now().isoformat()
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
if email:
|
||||
# 检查邮箱是否已存在(排除自己)
|
||||
cursor.execute("SELECT id FROM emails WHERE email = ? AND id != ?", (email, email_id))
|
||||
if cursor.fetchone():
|
||||
return False # 邎箱已存在
|
||||
if email and name:
|
||||
cursor.execute("UPDATE emails SET email = ?, name = ? WHERE id = ?", (email, name, email_id))
|
||||
elif email:
|
||||
cursor.execute("UPDATE emails SET email = ? WHERE id = ?", (email, email_id))
|
||||
elif name:
|
||||
cursor.execute("UPDATE emails SET name = ? WHERE id = ?", (name, email_id))
|
||||
conn.commit()
|
||||
return cursor.rowcount > 0
|
||||
|
||||
def delete_email(self, email_id: int) -> bool:
|
||||
"""删除邮箱"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM emails WHERE id = ?", (email_id,))
|
||||
conn.commit()
|
||||
return cursor.rowcount > 0
|
||||
|
||||
# ============ 邮件日志 操作 ============
|
||||
|
||||
def log_email_send(self, item_id: int, email: str, success: bool = True) -> int:
|
||||
"""记录邮件发送"""
|
||||
now = datetime.now().isoformat()
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
INSERT INTO email_logs (item_id, email, sent_at, success)
|
||||
VALUES (?, ?, ?, ?)
|
||||
""", (item_id, email, now, 1 if success else 0))
|
||||
conn.commit()
|
||||
return cursor.lastrowid
|
||||
|
||||
def get_email_logs(self, item_id: int) -> List[Dict[str, Any]]:
|
||||
"""获取收藏的邮件发送记录"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
SELECT * FROM email_logs
|
||||
WHERE item_id = ?
|
||||
ORDER BY sent_at DESC
|
||||
""", (item_id,))
|
||||
return [dict(row) for row in cursor.fetchall()]
|
||||
|
||||
def stats(self) -> Dict[str, Any]:
|
||||
"""获取统计信息"""
|
||||
self._ensure_init()
|
||||
@@ -315,6 +473,252 @@ class Database:
|
||||
stats['tags'] = cursor.fetchone()['count']
|
||||
|
||||
return stats
|
||||
|
||||
# ============ 提醒相关 ============
|
||||
|
||||
def get_reminders(self) -> Dict[str, Any]:
|
||||
"""获取提醒信息:即将到期和已过期的待办"""
|
||||
self._ensure_init()
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
now = datetime.now()
|
||||
|
||||
reminders = {
|
||||
'overdue': [], # 已过期
|
||||
'due_today': [], # 今天到期
|
||||
'due_soon': [] # 24小时内到期(不含今天)
|
||||
}
|
||||
|
||||
# 查询未完成的待办(有截止日期的)
|
||||
cursor.execute("""
|
||||
SELECT * FROM items
|
||||
WHERE type = 'todo'
|
||||
AND status != 'completed'
|
||||
AND due_date IS NOT NULL
|
||||
AND due_date != ''
|
||||
ORDER BY due_date ASC
|
||||
""")
|
||||
|
||||
for row in cursor.fetchall():
|
||||
item = dict(row)
|
||||
item['tags'] = self._get_item_tags(conn, item['id'])
|
||||
|
||||
try:
|
||||
due_date_str = item['due_date']
|
||||
# 支持多种日期格式
|
||||
if 'T' in due_date_str:
|
||||
# ISO 格式:2026-04-16T14:30
|
||||
due_date = datetime.strptime(due_date_str[:16], '%Y-%m-%dT%H:%M')
|
||||
elif len(due_date_str) == 10:
|
||||
# 只有日期:2026-04-16,视为当天 23:59:59
|
||||
due_date = datetime.strptime(due_date_str, '%Y-%m-%d').replace(hour=23, minute=59, second=59)
|
||||
else:
|
||||
# 其他格式,尝试解析
|
||||
due_date = datetime.strptime(due_date_str.split('.')[0], '%Y-%m-%dT%H:%M:%S')
|
||||
|
||||
# 计算距离到期的时间
|
||||
time_left = due_date - now
|
||||
|
||||
if time_left.total_seconds() < 0:
|
||||
# 已过期
|
||||
days_overdue = abs(int(time_left.total_seconds() / 86400))
|
||||
item['days_overdue'] = days_overdue
|
||||
reminders['overdue'].append(item)
|
||||
elif time_left.total_seconds() < 86400: # 24小时内
|
||||
# 判断是今天还是明天
|
||||
if due_date.date() == now.date():
|
||||
reminders['due_today'].append(item)
|
||||
else:
|
||||
reminders['due_soon'].append(item)
|
||||
elif due_date.date() == now.date():
|
||||
# 今天到期(超过24小时的情况,比如现在凌晨,截止时间是晚上)
|
||||
reminders['due_today'].append(item)
|
||||
except (ValueError, AttributeError) as e:
|
||||
# 日期格式错误,跳过
|
||||
continue
|
||||
|
||||
# 统计总数
|
||||
reminders['total'] = len(reminders['overdue']) + len(reminders['due_today']) + len(reminders['due_soon'])
|
||||
|
||||
return reminders
|
||||
|
||||
# ============ 备份操作 ============
|
||||
|
||||
def create_backup(self, manual: bool = False) -> Dict[str, Any]:
|
||||
"""创建数据库备份"""
|
||||
import os
|
||||
|
||||
# 确保备份目录存在
|
||||
os.makedirs(BACKUP_DIR, exist_ok=True)
|
||||
|
||||
now = datetime.now()
|
||||
backup_name = now.strftime('%Y-%m-%d_%H%M%S')
|
||||
if manual:
|
||||
backup_name += '_manual'
|
||||
backup_path = os.path.join(BACKUP_DIR, f'{backup_name}.db')
|
||||
|
||||
# 复制数据库文件
|
||||
shutil.copy2(self.db_path, backup_path)
|
||||
|
||||
# 获取备份信息
|
||||
backup_info = {
|
||||
'name': backup_name,
|
||||
'path': backup_path,
|
||||
'size': os.path.getsize(backup_path),
|
||||
'created_at': now.isoformat(),
|
||||
'manual': manual,
|
||||
'is_first_of_month': now.day == 1
|
||||
}
|
||||
|
||||
# 保存备份元数据
|
||||
self._save_backup_meta(backup_info)
|
||||
|
||||
# 清理旧备份
|
||||
self._cleanup_old_backups()
|
||||
|
||||
return backup_info
|
||||
|
||||
def list_backups(self) -> List[Dict[str, Any]]:
|
||||
"""列出所有备份"""
|
||||
import os
|
||||
|
||||
if not os.path.exists(BACKUP_DIR):
|
||||
return []
|
||||
|
||||
# 读取备份元数据
|
||||
meta_path = os.path.join(BACKUP_DIR, 'backup_meta.json')
|
||||
if os.path.exists(meta_path):
|
||||
with open(meta_path, 'r') as f:
|
||||
backups = json.load(f)
|
||||
else:
|
||||
# 从文件重建元数据
|
||||
backups = []
|
||||
for f in os.listdir(BACKUP_DIR):
|
||||
if f.endswith('.db'):
|
||||
path = os.path.join(BACKUP_DIR, f)
|
||||
backups.append({
|
||||
'name': f.replace('.db', ''),
|
||||
'path': path,
|
||||
'size': os.path.getsize(path),
|
||||
'created_at': datetime.fromtimestamp(os.path.getmtime(path)).isoformat(),
|
||||
'manual': '_manual' in f,
|
||||
'is_first_of_month': self._is_first_of_month_filename(f)
|
||||
})
|
||||
|
||||
# 按时间倒序排列
|
||||
backups.sort(key=lambda x: x['created_at'], reverse=True)
|
||||
|
||||
return backups
|
||||
|
||||
def restore_backup(self, backup_name: str) -> bool:
|
||||
"""恢复备份"""
|
||||
import os
|
||||
|
||||
backup_path = os.path.join(BACKUP_DIR, f'{backup_name}.db')
|
||||
if not os.path.exists(backup_path):
|
||||
return False
|
||||
|
||||
# 先备份当前数据库(以防万一)
|
||||
current_backup = self.db_path + '.before_restore'
|
||||
shutil.copy2(self.db_path, current_backup)
|
||||
|
||||
# 恢复备份
|
||||
shutil.copy2(backup_path, self.db_path)
|
||||
|
||||
return True
|
||||
|
||||
def delete_backup(self, backup_name: str) -> bool:
|
||||
"""删除备份"""
|
||||
import os
|
||||
|
||||
backup_path = os.path.join(BACKUP_DIR, f'{backup_name}.db')
|
||||
if not os.path.exists(backup_path):
|
||||
return False
|
||||
|
||||
os.remove(backup_path)
|
||||
|
||||
# 更新元数据
|
||||
self._remove_backup_meta(backup_name)
|
||||
|
||||
return True
|
||||
|
||||
def _save_backup_meta(self, backup_info: Dict[str, Any]):
|
||||
"""保存备份元数据"""
|
||||
import os
|
||||
|
||||
meta_path = os.path.join(BACKUP_DIR, 'backup_meta.json')
|
||||
|
||||
# 读取现有元数据
|
||||
backups = []
|
||||
if os.path.exists(meta_path):
|
||||
with open(meta_path, 'r') as f:
|
||||
backups = json.load(f)
|
||||
|
||||
# 添加新备份
|
||||
backups.append(backup_info)
|
||||
|
||||
# 保存
|
||||
with open(meta_path, 'w') as f:
|
||||
json.dump(backups, f, indent=2)
|
||||
|
||||
def _remove_backup_meta(self, backup_name: str):
|
||||
"""从元数据中删除备份"""
|
||||
import os
|
||||
|
||||
meta_path = os.path.join(BACKUP_DIR, 'backup_meta.json')
|
||||
if not os.path.exists(meta_path):
|
||||
return
|
||||
|
||||
with open(meta_path, 'r') as f:
|
||||
backups = json.load(f)
|
||||
|
||||
backups = [b for b in backups if b['name'] != backup_name]
|
||||
|
||||
with open(meta_path, 'w') as f:
|
||||
json.dump(backups, f, indent=2)
|
||||
|
||||
def _is_first_of_month_filename(self, filename: str) -> bool:
|
||||
"""判断是否是每月第一天的备份"""
|
||||
# 格式:2026-04-01_040000.db 或 2026-05-01_...
|
||||
try:
|
||||
date_part = filename.split('_')[0]
|
||||
day = int(date_part.split('-')[2])
|
||||
return day == 1
|
||||
except:
|
||||
return False
|
||||
|
||||
def _cleanup_old_backups(self):
|
||||
"""清理旧备份:保留30天 + 每月第一天"""
|
||||
import os
|
||||
|
||||
backups = self.list_backups()
|
||||
now = datetime.now()
|
||||
keep_paths = []
|
||||
|
||||
for backup in backups:
|
||||
backup_date = datetime.fromisoformat(backup['created_at'])
|
||||
days_old = (now - backup_date).days
|
||||
|
||||
# 保留条件:
|
||||
# 1. 手动备份永久保留(最多10个)
|
||||
# 2. 30天内的备份
|
||||
# 3. 每月第一天的备份
|
||||
|
||||
if backup['manual']:
|
||||
# 手动备份保留,但最多10个
|
||||
manual_backups = [b for b in backups if b['manual']]
|
||||
if manual_backups.index(backup) < 10:
|
||||
keep_paths.append(backup['path'])
|
||||
else:
|
||||
self.delete_backup(backup['name'])
|
||||
elif days_old <= 30:
|
||||
keep_paths.append(backup['path'])
|
||||
elif backup['is_first_of_month']:
|
||||
# 每月第一天永久保留
|
||||
keep_paths.append(backup['path'])
|
||||
else:
|
||||
# 删除
|
||||
self.delete_backup(backup['name'])
|
||||
|
||||
|
||||
# 全局数据库实例
|
||||
|
||||
0
data/xian_favor.db
Normal file
0
data/xian_favor.db
Normal file
402
logs/api.log
Normal file
402
logs/api.log
Normal file
@@ -0,0 +1,402 @@
|
||||
* Serving Flask app 'xian_favor.api'
|
||||
* Debug mode: off
|
||||
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:19014
|
||||
* Running on http://192.168.2.17:19014
|
||||
Press CTRL+C to quit
|
||||
127.0.0.1 - - [19/Apr/2026 10:06:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:04] "GET /api/items?limit=2&sort_by=updated_at&sort_order=desc HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:07:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:06] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:08:15] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:08:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:33] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.8 - - [19/Apr/2026 10:09:33] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:09:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:10:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:11:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:12:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:06] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:13:16] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:13:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:33] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.8 - - [19/Apr/2026 10:14:33] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:38] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:14:44] "GET / HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:14:44] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:14:44] "GET /api/reminders HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:14:44] "GET /api/tags HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:14:44] "GET /api/items?limit=20&offset=0 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:14:58] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:01] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:08] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:16] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:15:16] "GET /api/items?limit=20&offset=0&sort_by=updated_at&sort_order=desc HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:18] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:15:21] "GET /api/items?limit=20&offset=0&sort_order=desc HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:15:24] "GET /api/items?limit=20&offset=0&sort_by=created_at&sort_order=desc HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:26] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:15:27] "GET /api/items?limit=20&offset=0&sort_by=updated_at&sort_order=desc HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:28] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:31] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:15:34] "GET /api/items?limit=20&offset=0&sort_order=desc HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:15:56] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:15:56] "GET /api/items/59 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:16:00] "GET /api/items/59 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:29] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:32] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:16:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:17:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:36] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:46] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:18:56] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:06] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:16] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:17] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:26] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:33] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.8 - - [19/Apr/2026 10:19:33] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:36] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:19:44] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:47] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:19:58] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:08] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:19] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:29] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:39] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:49] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:20:59] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:09] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:19] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:29] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:39] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:21:49] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:22:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:23:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:33] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.8 - - [19/Apr/2026 10:24:37] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:40] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:24:44] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:24:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:25:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:26:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:27:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:28:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:33] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.8 - - [19/Apr/2026 10:29:37] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:40] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:29:44] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:29:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:30:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:31:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:32:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:33:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:33] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.8 - - [19/Apr/2026 10:34:37] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:40] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:34:44] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:34:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:35:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:36:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:37:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:38:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:33] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.8 - - [19/Apr/2026 10:39:37] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:40] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:39:44] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:39:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:00] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:40:05] "PUT /api/items/59 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:40:05] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:40:05] "GET /api/items?limit=20&offset=0&sort_order=desc HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:40:50] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:40:57] "GET /api/items/68 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:00] "GET /api/health HTTP/1.1" 404 -
|
||||
192.168.2.10 - - [19/Apr/2026 10:41:01] "GET /api/items/68 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:33] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:40] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:48] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:41:50] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:42:00] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:42:10] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:42:18] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:42:20] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:42:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:42:30] "GET /api/health HTTP/1.1" 404 -
|
||||
127.0.0.1 - - [19/Apr/2026 10:42:33] "GET /api/health HTTP/1.1" 404 -
|
||||
156
logs/app.log
Normal file
156
logs/app.log
Normal file
@@ -0,0 +1,156 @@
|
||||
🚀 启动API服务: http://0.0.0.0:19014
|
||||
* Serving Flask app 'xian_favor.api'
|
||||
* Debug mode: off
|
||||
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:19014
|
||||
* Running on http://192.168.2.17:19014
|
||||
Press CTRL+C to quit
|
||||
127.0.0.1 - - [20/Apr/2026 18:16:59] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:06] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:09] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:18] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:19] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:23] "GET / HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:29] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:32] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:36] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:37] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:39] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:49] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:17:59] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:06] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:09] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:10] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:15] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:19] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:19] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:27] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:31] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:33] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:37] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:39] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:41] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:45] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:51] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:18:52] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:00] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:01] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:06] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:07] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:11] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:12] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:20] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:21] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:30] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:31] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:36] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:37] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:41] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:42] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:19:51] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.8 - - [20/Apr/2026 18:19:55] "GET /api/reminders HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:19:55] "GET /api/reminders HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:01] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:07] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:11] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:21] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:31] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:34] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:37] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:40] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:41] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:42] "GET / HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:42] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:42] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:42] "GET /api/reminders HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:42] "GET /api/tags HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:42] "GET /api/items?limit=20&offset=0 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:47] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:20:51] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:52] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:53] "GET / HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:53] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:53] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:54] "GET /api/reminders HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:54] "GET /api/items?limit=20&offset=0 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:54] "GET /api/tags HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:20:58] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:01] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:03] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:07] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:08] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:11] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:13] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:18] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:21] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:23] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:28] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:32] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:33] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:34] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:37] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:38] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:40] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:42] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:43] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:48] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:21:52] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:53] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:21:58] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:02] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:03] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:07] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:08] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:12] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:13] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:18] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:22] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:23] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:28] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:31] "GET /api/items?limit=20&offset=20 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:32] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:33] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:34] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:37] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:38] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:40] "GET /api/items?limit=20&offset=0 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:40] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:42] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:43] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:48] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:22:52] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:53] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:22:58] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:02] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:03] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:07] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:08] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:12] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:13] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:18] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:22] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:23] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:28] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:32] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:33] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:34] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:37] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:39] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:40] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:42] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:44] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:48] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:23:52] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:53] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:23:58] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:24:02] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:24:04] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:24:07] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:24:08] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:24:12] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:24:14] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:24:19] "GET /api/stats HTTP/1.1" 200 -
|
||||
127.0.0.1 - - [20/Apr/2026 18:24:22] "GET /api/items?limit=1 HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:24:24] "GET /api/stats HTTP/1.1" 200 -
|
||||
192.168.2.10 - - [20/Apr/2026 18:24:28] "GET /api/stats HTTP/1.1" 200 -
|
||||
9709
logs/server.log
Normal file
9709
logs/server.log
Normal file
File diff suppressed because it is too large
Load Diff
35
scripts/auto_backup.py
Executable file
35
scripts/auto_backup.py
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Xian Favor 自动备份脚本
|
||||
定时任务调用此脚本进行自动备份
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加项目路径
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from xian_favor.db import db
|
||||
|
||||
def main():
|
||||
"""执行自动备份"""
|
||||
print(f"[{datetime.now().isoformat()}] 开始自动备份...")
|
||||
|
||||
try:
|
||||
backup_info = db.create_backup(manual=False)
|
||||
print(f"备份成功: {backup_info['name']}")
|
||||
print(f"大小: {backup_info['size']} bytes")
|
||||
print(f"位置: {backup_info['path']}")
|
||||
|
||||
# 清理旧备份
|
||||
db._cleanup_old_backups()
|
||||
print("旧备份清理完成")
|
||||
|
||||
except Exception as e:
|
||||
print(f"备份失败: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from datetime import datetime
|
||||
main()
|
||||
BIN
xian_favor/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
xian_favor/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
xian_favor/__pycache__/__main__.cpython-310.pyc
Normal file
BIN
xian_favor/__pycache__/__main__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
xian_favor/__pycache__/api.cpython-310.pyc
Normal file
BIN
xian_favor/__pycache__/api.cpython-310.pyc
Normal file
Binary file not shown.
BIN
xian_favor/__pycache__/cli.cpython-310.pyc
Normal file
BIN
xian_favor/__pycache__/cli.cpython-310.pyc
Normal file
Binary file not shown.
BIN
xian_favor/__pycache__/config.cpython-310.pyc
Normal file
BIN
xian_favor/__pycache__/config.cpython-310.pyc
Normal file
Binary file not shown.
BIN
xian_favor/__pycache__/db.cpython-310.pyc
Normal file
BIN
xian_favor/__pycache__/db.cpython-310.pyc
Normal file
Binary file not shown.
4943
xian_favor/api.py
4943
xian_favor/api.py
File diff suppressed because it is too large
Load Diff
1039
xian_favor/db.py
1039
xian_favor/db.py
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user