Skip to content

Conversation

@lysdgit
Copy link

@lysdgit lysdgit commented Oct 15, 2025

1.修改服务端 “待处理” 截图数量
2.优化去重打印的日志
3.在服务端聊天页面添加回首页按钮

Summary by Sourcery

Optimize screenshot deduplication logging, fix pending screenshot count, and add a Home button to the chat page

Enhancements:

  • Track duplicate status per screen and log only when the state changes to reduce log noise
  • Correct the "pending tasks" count to use unprocessed screenshots instead of the ProcessingQueue
  • Add a Home button to the server-side chat page header for easy navigation

@sourcery-ai
Copy link

sourcery-ai bot commented Oct 15, 2025

Reviewer's Guide

Implements stateful deduplication logging for screenshots, fixes the pending task count to use unprocessed screenshots, and adds a homepage navigation button to the chat interface.

Entity relationship diagram for updated pending screenshot statistics

erDiagram
SCREENSHOT {
  int id
  bool is_processed
}
PROCESSINGQUEUE {
  int id
  string status
}
SCREENSHOT ||--o{ PROCESSINGQUEUE : "related to"
Loading

Class diagram for updated screenshot deduplication logic

classDiagram
class Recorder {
  last_hashes: Dict[int, str]
  _last_duplicate_status: Dict[int, bool]
  hash_threshold: int
  _is_duplicate(screen_id: int, image_hash: str) -> bool
}
Recorder : +_is_duplicate(screen_id, image_hash)
Recorder : +last_hashes
Recorder : +_last_duplicate_status
Recorder : +hash_threshold
Loading

File-Level Changes

Change Details Files
Enhanced screenshot deduplication logging logic
  • Introduce per-screen _last_duplicate_status tracking
  • Print log messages only when duplicate state changes
  • Initialize status on first snapshot and handle transitions
  • Update last_hashes and status after each comparison
lifetrace_backend/recorder.py
Corrected pending task count query
  • Replace ProcessingQueue query with Screenshot filter on is_processed=False
lifetrace_backend/storage.py
Added homepage button in chat UI
  • Insert a link to “/” with btn-outline styling in the header controls
lifetrace_backend/templates/chat.html

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • The deduplication logic currently uses both print and logger calls—consider removing prints and relying solely on structured logging with appropriate levels.
  • You repeatedly check and initialize _last_duplicate_status inside _is_duplicate; moving that initialization into the class constructor would simplify the method and avoid repeated hasattr checks.
  • Switching pending_tasks to count Screenshot entries instead of using the ProcessingQueue model could change the intended behavior—double-check that this still reflects the correct number of pending jobs.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The deduplication logic currently uses both print and logger calls—consider removing prints and relying solely on structured logging with appropriate levels.
- You repeatedly check and initialize _last_duplicate_status inside _is_duplicate; moving that initialization into the class constructor would simplify the method and avoid repeated hasattr checks.
- Switching pending_tasks to count Screenshot entries instead of using the ProcessingQueue model could change the intended behavior—double-check that this still reflects the correct number of pending jobs.

## Individual Comments

### Comment 1
<location> `lifetrace_backend/recorder.py:358-366` </location>
<code_context>
    def _is_duplicate(self, screen_id: int, image_hash: str) -> bool:
        """检查是否为重复图像"""
        if not self.deduplicate:
            return False

        is_duplicate = False

        if screen_id not in self.last_hashes:
            # 第一次截图,不是重复
            self.last_hashes[screen_id] = image_hash
            # 初始化状态跟踪
            if not hasattr(self, '_last_duplicate_status'):
                self._last_duplicate_status = {}
            self._last_duplicate_status[screen_id] = False
            return False

        try:
            # 计算汉明距离
            current = imagehash.hex_to_hash(image_hash)
            previous = imagehash.hex_to_hash(self.last_hashes[screen_id])
            distance = current - previous

            is_duplicate = distance <= self.hash_threshold

            # 检查状态是否发生变化
            if not hasattr(self, '_last_duplicate_status'):
                self._last_duplicate_status = {}

            last_status = self._last_duplicate_status.get(screen_id, False)

            # 只有状态发生变化时才打印日志
            if is_duplicate and not last_status:
                logger.info(f"屏幕 {screen_id}: 开始重复截图")
                print(f"[去重] 屏幕 {screen_id}: 开始重复截图")
            elif not is_duplicate and last_status:
                logger.info(f"屏幕 {screen_id}: 重复结束,恢复截图")
                print(f"[去重] 屏幕 {screen_id}: 重复结束,恢复截图")
            elif is_duplicate and last_status:
                # 连续重复,可以选择性地每N次打印一次或者完全不打印
                pass

            # 更新状态记录
            self._last_duplicate_status[screen_id] = is_duplicate
            self.last_hashes[screen_id] = image_hash

        except Exception as e:
            logger.error(f"比较图像哈希失败: {e}")
            is_duplicate = False

        return is_duplicate

</code_context>

<issue_to_address>
**issue (code-quality):** We've found these issues:

- Remove redundant conditional ([`remove-redundant-if`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/remove-redundant-if/))
- Remove empty elif clause ([`remove-pass-elif`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/remove-pass-elif/))
</issue_to_address>

### Comment 2
<location> `lifetrace_backend/storage.py:664` </location>
<code_context>
    def get_statistics(self) -> Dict[str, Any]:
        """获取统计信息"""
        try:
            with self.get_session() as session:
                total_screenshots = session.query(Screenshot).count()
                processed_screenshots = session.query(Screenshot).filter_by(is_processed=True).count()
                pending_tasks = session.query(Screenshot).filter_by(is_processed=False).count()

                # 今日统计
                today = datetime.now().date()
                today_start = datetime.combine(today, datetime.min.time())
                today_screenshots = session.query(Screenshot).filter(
                    Screenshot.created_at >= today_start
                ).count()

                return {
                    'total_screenshots': total_screenshots,
                    'processed_screenshots': processed_screenshots,
                    'pending_tasks': pending_tasks,
                    'today_screenshots': today_screenshots,
                    'processing_rate': processed_screenshots / max(total_screenshots, 1) * 100
                }

        except SQLAlchemyError as e:
            logging.error(f"获取统计信息失败: {e}")
            return {}

</code_context>

<issue_to_address>
**issue (code-quality):** Extract code out into method ([`extract-method`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/extract-method/))
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +358 to +366
if is_duplicate and not last_status:
logger.info(f"屏幕 {screen_id}: 开始重复截图")
print(f"[去重] 屏幕 {screen_id}: 开始重复截图")
elif not is_duplicate and last_status:
logger.info(f"屏幕 {screen_id}: 重复结束,恢复截图")
print(f"[去重] 屏幕 {screen_id}: 重复结束,恢复截图")
elif is_duplicate and last_status:
# 连续重复,可以选择性地每N次打印一次或者完全不打印
pass
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): We've found these issues:

"""获取统计信息"""
try:
with self.get_session() as session:
total_screenshots = session.query(Screenshot).count()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Extract code out into method (extract-method)

@Royce17 Royce17 self-requested a review November 3, 2025 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant