Fix cross-day fixture handling: don't add matches to yesterday's fixture,...

Fix cross-day fixture handling: don't add matches to yesterday's fixture, finalize pending matches with results, bump version to 1.0.16
parent d942c701
......@@ -14,7 +14,7 @@ from typing import List, Dict, Any
# Build configuration
BUILD_CONFIG = {
'app_name': 'MbetterClient',
'app_version': '1.0.15',
'app_version': '1.0.16',
'description': 'Cross-platform multimedia client application',
'author': 'MBetter Team',
'entry_point': 'main.py',
......
......@@ -211,7 +211,7 @@ Examples:
parser.add_argument(
'--version',
action='version',
version='MbetterClient 1.0.15'
version='MbetterClient 1.0.16'
)
# Timer options
......
......@@ -4,7 +4,7 @@ MbetterClient - Cross-platform multimedia client application
A multi-threaded application with video playback, web dashboard, and REST API integration.
"""
__version__ = "1.0.15"
__version__ = "1.0.16"
__author__ = "MBetter Project"
__email__ = "dev@mbetter.net"
__description__ = "Cross-platform multimedia client with video overlay and web dashboard"
......
......@@ -262,7 +262,7 @@ class ApiConfig:
# Request settings
verify_ssl: bool = True
user_agent: str = "MbetterClient/1.0r15"
user_agent: str = "MbetterClient/1.0r16"
max_response_size_mb: int = 100
# Additional API client settings
......@@ -403,7 +403,7 @@ class AppSettings:
timer: TimerConfig = field(default_factory=TimerConfig)
# Application settings
version: str = "1.0.15"
version: str = "1.0.16"
debug_mode: bool = False
dev_message: bool = False # Enable debug mode showing only message bus messages
debug_messages: bool = False # Show all messages passing through the message bus on screen
......
......@@ -464,6 +464,73 @@ class GamesThread(ThreadedComponent):
logger.error(f"Failed to get yesterday's incomplete matches: {e}")
return []
def _finalize_matches_with_results(self) -> int:
"""Finalize matches that have results set but are still in pending status.
This handles matches from yesterday or today that:
- Are in 'pending' status
- Have start_time set but no end_time
- Have results and/or winning_outcomes already set
For such matches:
- Set end_time to now
- Set status to 'done'
- Resolve associated bets based on the results
Returns count of matches finalized.
"""
try:
session = self.db_manager.get_session()
try:
# Find matches that have results but are still pending
# Check for matches with result or winning_outcomes set
pending_with_results = session.query(MatchModel).filter(
MatchModel.status == 'pending',
MatchModel.active_status == True,
MatchModel.start_time.isnot(None),
MatchModel.end_time.is_(None),
(MatchModel.result.isnot(None) | MatchModel.winning_outcomes.isnot(None))
).all()
if not pending_with_results:
logger.info("No pending matches with results found to finalize")
return 0
logger.info(f"🔍 Found {len(pending_with_results)} pending matches with results - finalizing them")
finalized_count = 0
for match in pending_with_results:
logger.info(f"🔍 Finalizing match {match.match_number} (fixture: {match.fixture_id})")
logger.info(f" - result: {match.result}, winning_outcomes: {match.winning_outcomes}")
logger.info(f" - under_over_result: {match.under_over_result}")
# Set end_time to now
match.end_time = datetime.utcnow()
# Set status to done
match.status = 'done'
# Resolve associated bets
self._resolve_match_bets(match, session)
finalized_count += 1
logger.info(f"✅ Match {match.match_number} finalized as 'done'")
if finalized_count > 0:
session.commit()
logger.info(f"✅ Finalized {finalized_count} pending matches with results")
return finalized_count
finally:
session.close()
except Exception as e:
logger.error(f"Failed to finalize matches with results: {e}")
import traceback
logger.error(f"Traceback: {traceback.format_exc()}")
return 0
def _process_today_pending_matches(self) -> List[MatchModel]:
"""Process pending matches in today's fixture.
......@@ -910,6 +977,13 @@ class GamesThread(ThreadedComponent):
logger.info("🧹 Step 3: Checking for orphaned pending bets from previous sessions...")
self._cleanup_orphaned_pending_bets()
# STEP 3.5: Finalize pending matches that already have results set
# This handles matches from yesterday or today that have results but weren't finalized
logger.info("🧹 Step 3.5: Finalizing pending matches with results...")
finalized_count = self._finalize_matches_with_results()
if finalized_count > 0:
logger.info(f"✅ Finalized {finalized_count} pending matches with results")
# STEP 4: Check for yesterday's incomplete matches and prepare for continuation
logger.info("🧹 Step 4: Checking for yesterday's incomplete matches...")
yesterday_incomplete = self._get_yesterday_incomplete_matches()
......@@ -2545,7 +2619,13 @@ class GamesThread(ThreadedComponent):
logger.error(f"Failed to start match timer: {e}")
def _dispatch_start_intro(self, fixture_id: str):
"""Dispatch START_INTRO message to trigger intro content"""
"""Dispatch START_INTRO message to trigger intro content
IMPORTANT: When yesterday's fixture has incomplete matches:
- Do NOT create any new matches in yesterday's fixture
- Ensure today's fixture exists with matches ready
- When yesterday's matches complete, seamlessly transition to today's fixture
"""
try:
from .message_bus import MessageBuilder
......@@ -2560,6 +2640,27 @@ class GamesThread(ThreadedComponent):
logger.info(f"🎬 Fixture {fixture_id} is from yesterday - will play remaining matches without adding new ones")
remaining_matches = self._count_remaining_matches_in_fixture(fixture_id)
logger.info(f"🎬 Yesterday fixture {fixture_id} has {remaining_matches} remaining matches")
# IMPORTANT: Do NOT add matches to yesterday's fixture
# Instead, ensure today's fixture exists and has matches ready for seamless transition
logger.info(f"🎬 Ensuring today's fixture exists with matches ready for after yesterday's matches complete")
today_fixture_id = self._get_or_create_today_fixture()
if today_fixture_id:
# Check if today's fixture has enough matches
today_remaining = self._count_remaining_matches_in_fixture(today_fixture_id)
logger.info(f"🎬 Today fixture {today_fixture_id} has {today_remaining} matches")
if today_remaining < 5:
logger.info(f"🚨 Today fixture needs {5 - today_remaining} more matches - creating them now")
self._ensure_minimum_matches_in_fixture(today_fixture_id, 5 - today_remaining)
today_remaining = self._count_remaining_matches_in_fixture(today_fixture_id)
logger.info(f"✅ Today fixture {today_fixture_id} now has {today_remaining} matches ready")
# Store the today fixture ID for seamless transition
self.pending_today_fixture_id = today_fixture_id
logger.info(f"🎬 Today fixture {today_fixture_id} ready for seamless transition after yesterday's matches")
else:
logger.warning("⚠️ Could not get or create today's fixture - will continue with yesterday's matches only")
else:
# Check if there are at least 5 matches remaining in the fixture
logger.info(f"🎬 Checking minimum match count for fixture {fixture_id} before playing INTRO.mp4")
......
......@@ -230,7 +230,7 @@ class WebDashboard(ThreadedComponent):
def inject_globals():
return {
'app_name': 'MbetterClient',
'app_version': '1.0.15',
'app_version': '1.0.16',
'current_time': time.time(),
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment