Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
MBetterc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Mbetter
MBetterc
Commits
ca38e0be
Commit
ca38e0be
authored
Nov 25, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Match creation in bet mode
parent
7eef9732
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
63 additions
and
61 deletions
+63
-61
games_thread.py
mbetterclient/core/games_thread.py
+53
-43
match_timer.py
mbetterclient/core/match_timer.py
+10
-18
No files found.
mbetterclient/core/games_thread.py
View file @
ca38e0be
...
...
@@ -2884,9 +2884,11 @@ class GamesThread(ThreadedComponent):
def
_select_random_completed_matches
(
self
,
count
:
int
,
session
)
->
List
[
MatchModel
]:
"""Select random completed matches from the database (including cancelled and failed)"""
try
:
from
sqlalchemy.orm
import
joinedload
# Get all completed matches (status = 'done', 'cancelled', or 'failed')
# Exclude matches from fixtures that contain "_recycle_" in the fixture name
completed_matches
=
session
.
query
(
MatchModel
)
.
filter
(
completed_matches
=
session
.
query
(
MatchModel
)
.
options
(
joinedload
(
MatchModel
.
outcomes
))
.
filter
(
MatchModel
.
status
.
in_
([
'done'
,
'end'
,
'cancelled'
,
'failed'
]),
MatchModel
.
active_status
==
True
,
~
MatchModel
.
fixture_id
.
like
(
'
%
_recycle_
%
'
)
...
...
@@ -2976,6 +2978,9 @@ class GamesThread(ThreadedComponent):
fixture_id
=
f
"recycle_{uuid.uuid4().hex[:8]}"
now
=
datetime
.
utcnow
()
# Determine the status for new matches based on system state
new_match_status
=
self
.
_determine_new_match_status
(
fixture_id
,
session
)
# For a new fixture, start match_number from 1
match_number
=
1
for
old_match
in
old_matches
:
...
...
@@ -2986,7 +2991,7 @@ class GamesThread(ThreadedComponent):
fighter2_township
=
old_match
.
fighter2_township
,
venue_kampala_township
=
old_match
.
venue_kampala_township
,
start_time
=
now
,
status
=
'scheduled'
,
status
=
new_match_status
,
fixture_id
=
fixture_id
,
filename
=
old_match
.
filename
,
file_sha1sum
=
old_match
.
file_sha1sum
,
...
...
@@ -3018,7 +3023,7 @@ class GamesThread(ThreadedComponent):
match_number
+=
1
session
.
commit
()
logger
.
info
(
f
"Created new fixture {fixture_id} with {len(old_matches)} matches from old completed matches"
)
logger
.
info
(
f
"Created new fixture {fixture_id} with {len(old_matches)} matches from old completed matches
(status: {new_match_status})
"
)
return
fixture_id
except
Exception
as
e
:
...
...
@@ -3241,8 +3246,10 @@ class GamesThread(ThreadedComponent):
continue
# Final fallback: return whatever matches are available
try
:
logger
.
warning
(
f
"🚨 All {max_attempts} attempts failed - returning all available matches"
)
all_matches
=
session
.
query
(
MatchModel
)
.
filter
(
from
sqlalchemy.orm
import
joinedload
all_matches
=
session
.
query
(
MatchModel
)
.
options
(
joinedload
(
MatchModel
.
outcomes
))
.
filter
(
MatchModel
.
status
.
in_
([
'done'
,
'end'
,
'cancelled'
,
'failed'
]),
MatchModel
.
active_status
==
True
,
~
MatchModel
.
fixture_id
.
like
(
'
%
_recycle_
%
'
)
...
...
@@ -3255,7 +3262,8 @@ class GamesThread(ThreadedComponent):
else
:
# If no matches found with exclusions, recycle the oldest match from database
logger
.
warning
(
"🚨 No matches available after exclusions - recycling the oldest match from database"
)
oldest_match
=
session
.
query
(
MatchModel
)
.
filter
(
from
sqlalchemy.orm
import
joinedload
oldest_match
=
session
.
query
(
MatchModel
)
.
options
(
joinedload
(
MatchModel
.
outcomes
))
.
filter
(
MatchModel
.
status
.
in_
([
'done'
,
'end'
,
'cancelled'
,
'failed'
]),
MatchModel
.
active_status
==
True
)
.
order_by
(
MatchModel
.
created_at
.
asc
())
.
first
()
...
...
@@ -3266,6 +3274,9 @@ class GamesThread(ThreadedComponent):
else
:
logger
.
error
(
"🚨 No completed matches found in database at all"
)
return
[]
except
Exception
as
e
:
logger
.
error
(
f
"Failed to select random completed matches with fallback: {e}"
)
return
[]
def
_get_available_matches_excluding_recent
(
self
,
fixture_id
:
Optional
[
str
],
exclude_last_n
:
int
,
fighters_only
:
bool
,
session
)
->
List
[
MatchModel
]:
"""Get available matches excluding the last N recent matches in the fixture"""
...
...
@@ -3302,7 +3313,8 @@ class GamesThread(ThreadedComponent):
)
# Query available matches with exclusions
query
=
session
.
query
(
MatchModel
)
.
filter
(
from
sqlalchemy.orm
import
joinedload
query
=
session
.
query
(
MatchModel
)
.
options
(
joinedload
(
MatchModel
.
outcomes
))
.
filter
(
MatchModel
.
status
.
in_
([
'done'
,
'end'
,
'cancelled'
,
'failed'
]),
MatchModel
.
active_status
==
True
,
~
MatchModel
.
fixture_id
.
like
(
'
%
_recycle_
%
'
),
...
...
@@ -3320,27 +3332,25 @@ class GamesThread(ThreadedComponent):
def
_determine_new_match_status
(
self
,
fixture_id
:
str
,
session
)
->
str
:
"""Determine the status for new matches based on system state"""
try
:
# Check if system is ingame (has any match with status 'ingame')
ingame_match
=
session
.
query
(
MatchModel
)
.
filter
(
MatchModel
.
status
==
'ingame'
,
MatchModel
.
active_status
==
True
)
.
first
()
# Get betting mode configuration
betting_mode
=
self
.
_get_betting_mode_config
()
if
ingame_match
:
# System is ingame, check if last 4 matches in the fixture are in 'bet' status
last_4_matches
=
session
.
query
(
MatchModel
)
.
filter
(
# If betting mode is "all_bets_on_start", new matches should be 'bet'
if
betting_mode
==
"all_bets_on_start"
:
logger
.
info
(
f
"Betting mode is 'all_bets_on_start' - new matches will be in bet status"
)
return
'bet'
# Check if the last match in the fixture is in 'bet' status
last_match
=
session
.
query
(
MatchModel
)
.
filter
(
MatchModel
.
fixture_id
==
fixture_id
,
MatchModel
.
active_status
==
True
)
.
order_by
(
MatchModel
.
match_number
.
desc
())
.
limit
(
4
)
.
all
()
)
.
order_by
(
MatchModel
.
match_number
.
desc
())
.
first
()
if
len
(
last_4_matches
)
>=
4
:
# Check if all last 4 matches are in 'bet' status
if
all
(
match
.
status
==
'bet'
for
match
in
last_4_matches
):
logger
.
info
(
f
"System is ingame and last 4 matches in fixture {fixture_id} are in bet status - new matches will be in bet status"
)
if
last_match
and
last_match
.
status
==
'bet'
:
logger
.
info
(
f
"Last match in fixture {fixture_id} is in bet status - new matches will be in bet status"
)
return
'bet'
# Default status
logger
.
info
(
f
"New matches will be in scheduled status (system not ingame or last 4 matches not all in bet status)"
)
return
'scheduled'
except
Exception
as
e
:
...
...
mbetterclient/core/match_timer.py
View file @
ca38e0be
...
...
@@ -556,10 +556,11 @@ class MatchTimerComponent(ThreadedComponent):
"""Select random completed matches from the database, excluding matches with same fighters as the last played match"""
try
:
from
..database.models
import
MatchModel
from
sqlalchemy.orm
import
joinedload
# Build query for completed matches
# Exclude matches from fixtures that contain "_recycle_" in the fixture name
query
=
session
.
query
(
MatchModel
)
.
filter
(
query
=
session
.
query
(
MatchModel
)
.
options
(
joinedload
(
MatchModel
.
outcomes
))
.
filter
(
MatchModel
.
status
.
in_
([
'done'
,
'end'
,
'cancelled'
,
'failed'
]),
MatchModel
.
active_status
==
True
,
~
MatchModel
.
fixture_id
.
like
(
'
%
_recycle_
%
'
)
...
...
@@ -680,23 +681,14 @@ class MatchTimerComponent(ThreadedComponent):
logger
.
info
(
f
"Betting mode is 'all_bets_on_start' - new matches will be in bet status"
)
return
'bet'
# Check if system is ingame (has any match with status 'ingame')
ingame_match
=
session
.
query
(
MatchModel
)
.
filter
(
MatchModel
.
status
==
'ingame'
,
MatchModel
.
active_status
==
True
)
.
first
()
if
ingame_match
:
# System is ingame, check if last 4 matches in the fixture are in 'bet' status
last_4_matches
=
session
.
query
(
MatchModel
)
.
filter
(
# Check if the last match in the fixture is in 'bet' status
last_match
=
session
.
query
(
MatchModel
)
.
filter
(
MatchModel
.
fixture_id
==
fixture_id
,
MatchModel
.
active_status
==
True
)
.
order_by
(
MatchModel
.
match_number
.
desc
())
.
limit
(
4
)
.
all
()
)
.
order_by
(
MatchModel
.
match_number
.
desc
())
.
first
()
if
len
(
last_4_matches
)
>=
4
:
# Check if all last 4 matches are in 'bet' status
if
all
(
match
.
status
==
'bet'
for
match
in
last_4_matches
):
logger
.
info
(
f
"System is ingame and last 4 matches in fixture {fixture_id} are in bet status - new matches will be in bet status"
)
if
last_match
and
last_match
.
status
==
'bet'
:
logger
.
info
(
f
"Last match in fixture {fixture_id} is in bet status - new matches will be in bet status"
)
return
'bet'
# Default status
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment