Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions boon_tube_daemon/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ def check_platforms(self):
logger.info(f" ⏱ Waiting {multi_video_delay}s before posting next video...")
time.sleep(multi_video_delay)
self.notify_new_video(platform, video_data)
# Persist progress after each video so an interrupted batch
# resumes from the next unposted video instead of skipping
# the remainder if the process is killed mid-batch.
if hasattr(platform, 'mark_posted'):
platform.mark_posted(video_data)
else:
# Legacy single-video path (TikTok etc.)
is_new, video_data = platform.check_for_new_video()
Expand Down
19 changes: 16 additions & 3 deletions boon_tube_daemon/media/youtube_videos.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ def _save_state(self):
logger.debug(f"💾 Saved YouTube state to {state_file}")
except Exception as e:
logger.warning("⚠ Could not save YouTube state")

def mark_posted(self, video_data: dict):
"""Advance and persist the last-posted marker after a video is posted.

Called by the daemon after each video is successfully handled so that an
interrupted batch resumes from the next unposted video rather than
silently skipping the remainder.
"""
video_id = video_data.get('video_id')
if video_id:
self.last_video_id = video_id
self._save_state()

def authenticate(self) -> bool:
"""Authenticate with YouTube API."""
Expand Down Expand Up @@ -444,9 +456,10 @@ def check_for_new_videos(self, username: Optional[str] = None) -> List[dict]:
if len(new_videos) > 1:
logger.info(f"📦 YouTube: {len(new_videos)} new videos detected since last check")

# Update state to newest
self.last_video_id = newest_id
self._save_state()
# NOTE: Do NOT advance last_video_id here. State is advanced per-video via
# mark_posted() after each video is successfully posted, so an interrupted
# batch (e.g. container restart) resumes from the next unposted video
# instead of silently skipping the remainder.
return new_videos

def _resolve_channel_id(self, username: str) -> Optional[str]:
Expand Down
Loading