'update'
This commit is contained in:
@@ -51,6 +51,7 @@ class BookListManager:
|
|||||||
notes = annotations.get(bk_id, {})
|
notes = annotations.get(bk_id, {})
|
||||||
day_notes = {}
|
day_notes = {}
|
||||||
# 收集每本书所有笔记的创建时间,按天分组
|
# 收集每本书所有笔记的创建时间,按天分组
|
||||||
|
# day_notes: {date对象: [datetime对象, ...]},便于后续统计每天的阅读行为
|
||||||
for uuid, note in notes.items():
|
for uuid, note in notes.items():
|
||||||
raw_date = note.get('creationdate')
|
raw_date = note.get('creationdate')
|
||||||
try:
|
try:
|
||||||
@@ -64,58 +65,78 @@ class BookListManager:
|
|||||||
# 获取该书的打开时间戳(ZLASTOPENDATE),用于判断无笔记时是否有打开过书籍
|
# 获取该书的打开时间戳(ZLASTOPENDATE),用于判断无笔记时是否有打开过书籍
|
||||||
open_info = books_open.get(bk_id, {})
|
open_info = books_open.get(bk_id, {})
|
||||||
last_open_ts = open_info.get('last_open')
|
last_open_ts = open_info.get('last_open')
|
||||||
# 生成最近30天的阅读时长列表
|
# 生成最近30天的阅读时长列表(readtime30d),索引0为今天,索引29为30天前
|
||||||
readtime30d = []
|
readtime30d = []
|
||||||
for i in range(30):
|
for i in range(30):
|
||||||
day = today - datetime.timedelta(days=i)
|
day = today - datetime.timedelta(days=i)
|
||||||
times = day_notes.get(day, [])
|
times = day_notes.get(day, [])
|
||||||
|
# 统计当天阅读时长
|
||||||
if not times:
|
if not times:
|
||||||
|
# 没有笔记,判断当天是否有打开过书籍
|
||||||
opened = False
|
opened = False
|
||||||
if last_open_ts:
|
if last_open_ts:
|
||||||
open_dt = datetime.datetime(2001, 1, 1) + datetime.timedelta(seconds=last_open_ts)
|
open_dt = datetime.datetime(2001, 1, 1) + datetime.timedelta(seconds=last_open_ts)
|
||||||
if open_dt.date() == day:
|
if open_dt.date() == day:
|
||||||
opened = True
|
opened = True
|
||||||
|
# 无笔记但当天有打开书籍,阅读时间设为READ_TIME_OPEN_DAY
|
||||||
readtime = READ_TIME_OPEN_DAY if opened else 0
|
readtime = READ_TIME_OPEN_DAY if opened else 0
|
||||||
elif len(times) == 1:
|
elif len(times) == 1:
|
||||||
|
# 只有一条笔记,设为最小阅读时长
|
||||||
readtime = READ_TIME_DAY
|
readtime = READ_TIME_DAY
|
||||||
else:
|
else:
|
||||||
|
# 多条笔记,统计相邻笔记时间差(仅累加小于3小时的部分,单位分钟)
|
||||||
times_sorted = sorted(times)
|
times_sorted = sorted(times)
|
||||||
total_minutes = 0
|
total_minutes = 0
|
||||||
for idx in range(1, len(times_sorted)):
|
for idx in range(1, len(times_sorted)):
|
||||||
delta = (times_sorted[idx] - times_sorted[idx-1]).total_seconds() / 60
|
delta = (times_sorted[idx] - times_sorted[idx-1]).total_seconds() / 60
|
||||||
|
# 只统计相邻笔记间隔小于等于180分钟的部分
|
||||||
if 0 < delta <= 180:
|
if 0 < delta <= 180:
|
||||||
total_minutes += int(delta)
|
total_minutes += int(delta)
|
||||||
|
# 如果没有有效时间差,则用最小阅读时长
|
||||||
readtime = total_minutes if total_minutes > 0 else READ_TIME_DAY
|
readtime = total_minutes if total_minutes > 0 else READ_TIME_DAY
|
||||||
readtime30d.append(readtime)
|
readtime30d.append(readtime)
|
||||||
|
# 保存每本书的30天阅读时长列表
|
||||||
booksinfo[bk_id]['readtime30d'] = readtime30d
|
booksinfo[bk_id]['readtime30d'] = readtime30d
|
||||||
|
|
||||||
# 新增:统计今年每个月的阅读时长和年总阅读时长(遍历今年每一天)
|
# 新增:统计今年每月和全年阅读时长(遍历今年每一天,更精确)
|
||||||
readtime12m = [0] * 12 # 今年每月阅读时长
|
# readtime12m: 今年每月阅读时长列表(索引0为1月,索引11为12月)
|
||||||
readtime_year = 0 # 今年总阅读时长
|
# readtime_year: 今年总阅读时长(分钟)
|
||||||
|
readtime12m = [0] * 12
|
||||||
|
readtime_year = 0
|
||||||
first_day = datetime.date(this_year, 1, 1)
|
first_day = datetime.date(this_year, 1, 1)
|
||||||
days_in_year = (today - first_day).days + 1
|
days_in_year = (today - first_day).days + 1
|
||||||
for i in range(days_in_year):
|
for i in range(days_in_year):
|
||||||
day = first_day + datetime.timedelta(days=i)
|
day = first_day + datetime.timedelta(days=i)
|
||||||
times = day_notes.get(day, [])
|
times = day_notes.get(day, [])
|
||||||
|
# 统计当天阅读时长,逻辑与readtime30d一致
|
||||||
if not times:
|
if not times:
|
||||||
|
# 无笔记,判断当天是否有打开过书籍
|
||||||
opened = False
|
opened = False
|
||||||
if last_open_ts:
|
if last_open_ts:
|
||||||
open_dt = datetime.datetime(2001, 1, 1) + datetime.timedelta(seconds=last_open_ts)
|
open_dt = datetime.datetime(2001, 1, 1) + datetime.timedelta(seconds=last_open_ts)
|
||||||
if open_dt.date() == day:
|
if open_dt.date() == day:
|
||||||
opened = True
|
opened = True
|
||||||
|
# 无笔记但当天有打开书籍,阅读时间设为READ_TIME_OPEN_DAY
|
||||||
readtime = READ_TIME_OPEN_DAY if opened else 0
|
readtime = READ_TIME_OPEN_DAY if opened else 0
|
||||||
elif len(times) == 1:
|
elif len(times) == 1:
|
||||||
|
# 只有一条笔记,设为最小阅读时长
|
||||||
readtime = READ_TIME_DAY
|
readtime = READ_TIME_DAY
|
||||||
else:
|
else:
|
||||||
|
# 多条笔记,统计相邻笔记时间差(仅累加小于3小时的部分,单位分钟)
|
||||||
times_sorted = sorted(times)
|
times_sorted = sorted(times)
|
||||||
total_minutes = 0
|
total_minutes = 0
|
||||||
for idx in range(1, len(times_sorted)):
|
for idx in range(1, len(times_sorted)):
|
||||||
delta = (times_sorted[idx] - times_sorted[idx-1]).total_seconds() / 60
|
delta = (times_sorted[idx] - times_sorted[idx-1]).total_seconds() / 60
|
||||||
|
# 只统计相邻笔记间隔小于等于180分钟的部分
|
||||||
if 0 < delta <= 180:
|
if 0 < delta <= 180:
|
||||||
total_minutes += int(delta)
|
total_minutes += int(delta)
|
||||||
|
# 如果没有有效时间差,则用最小阅读时长
|
||||||
readtime = total_minutes if total_minutes > 0 else READ_TIME_DAY
|
readtime = total_minutes if total_minutes > 0 else READ_TIME_DAY
|
||||||
|
# 按月累计到readtime12m
|
||||||
readtime12m[day.month-1] += readtime
|
readtime12m[day.month-1] += readtime
|
||||||
|
# 全年累计到readtime_year
|
||||||
readtime_year += readtime
|
readtime_year += readtime
|
||||||
|
# 保存到booksinfo
|
||||||
booksinfo[bk_id]['readtime12m'] = readtime12m
|
booksinfo[bk_id]['readtime12m'] = readtime12m
|
||||||
booksinfo[bk_id]['readtime_year'] = readtime_year
|
booksinfo[bk_id]['readtime_year'] = readtime_year
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -1,3 +1,24 @@
|
|||||||
|
# 2025年阅读统计功能设计补充
|
||||||
|
|
||||||
|
## 书籍阅读时长统计
|
||||||
|
|
||||||
|
1. `readtime30d`:每本书最近30天每天的阅读时长(分钟),索引0为今天,索引29为30天前。
|
||||||
|
2. `readtime12m`:每本书今年每月的累计阅读时长(分钟),索引0为1月,索引11为12月。统计逻辑为遍历今年每一天,按月累计。
|
||||||
|
3. `readtime_year`:每本书今年总阅读时长(分钟),为`readtime12m`各月之和。
|
||||||
|
4. 支持无笔记但当天有打开书籍时,阅读时长设为`READ_TIME_OPEN_DAY`(config.py配置,默认30分钟)。
|
||||||
|
5. 多条笔记时,统计相邻笔记时间差(仅累加小于3小时的部分),更真实反映实际阅读行为。
|
||||||
|
|
||||||
|
## 全局统计函数
|
||||||
|
|
||||||
|
1. `get_total_readtime_year()`:返回全年所有书的累计阅读时间(分钟)。
|
||||||
|
2. `get_total_readtime12m()`:返回全年所有书的月度累计阅读时间(长度12的列表,单位:分钟)。
|
||||||
|
3. `get_total_readtime(days=30)`:返回最近days天每天所有书籍的总阅读时间(分钟),索引0为今天。
|
||||||
|
|
||||||
|
## 设计说明
|
||||||
|
|
||||||
|
- 所有统计均以“分钟”为单位,便于可视化和分析。
|
||||||
|
- 年度统计遍历今年每一天,保证月度和年度数据完整。
|
||||||
|
- 统计逻辑与实际阅读行为高度贴合,支持无笔记但有打开书籍的场景。
|
||||||
# iBooks 笔记导出工具 详细设计文档
|
# iBooks 笔记导出工具 详细设计文档
|
||||||
|
|
||||||
## 1. 概述
|
## 1. 概述
|
||||||
|
|||||||
Reference in New Issue
Block a user