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
1f2b9534
Commit
1f2b9534
authored
Dec 17, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
templates license and results bottom bar
parent
0a38c586
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
581 additions
and
271 deletions
+581
-271
=4.0.0
=4.0.0
+0
-12
player.py
mbetterclient/qt_player/player.py
+107
-0
default.html
mbetterclient/qt_player/templates/default.html
+119
-38
fixtures.html
mbetterclient/qt_player/templates/fixtures.html
+73
-49
match.html
mbetterclient/qt_player/templates/match.html
+109
-35
text.html
mbetterclient/qt_player/templates/text.html
+173
-27
test_api.py
test_api.py
+0
-110
No files found.
=4.0.0
deleted
100644 → 0
View file @
0a38c586
Collecting flask-cors
Using cached flask_cors-6.0.1-py3-none-any.whl.metadata (5.3 kB)
Requirement already satisfied: flask>=0.9 in ./venv/lib/python3.13/site-packages (from flask-cors) (3.1.2)
Requirement already satisfied: Werkzeug>=0.7 in ./venv/lib/python3.13/site-packages (from flask-cors) (3.1.3)
Requirement already satisfied: blinker>=1.9.0 in ./venv/lib/python3.13/site-packages (from flask>=0.9->flask-cors) (1.9.0)
Requirement already satisfied: click>=8.1.3 in ./venv/lib/python3.13/site-packages (from flask>=0.9->flask-cors) (8.3.1)
Requirement already satisfied: itsdangerous>=2.2.0 in ./venv/lib/python3.13/site-packages (from flask>=0.9->flask-cors) (2.2.0)
Requirement already satisfied: jinja2>=3.1.2 in ./venv/lib/python3.13/site-packages (from flask>=0.9->flask-cors) (3.1.6)
Requirement already satisfied: markupsafe>=2.1.1 in ./venv/lib/python3.13/site-packages (from flask>=0.9->flask-cors) (3.0.3)
Using cached flask_cors-6.0.1-py3-none-any.whl (13 kB)
Installing collected packages: flask-cors
Successfully installed flask-cors-6.0.1
mbetterclient/qt_player/player.py
View file @
1f2b9534
...
...
@@ -280,6 +280,113 @@ class OverlayWebChannel(QObject):
logger
.
error
(
f
"QtWebChannel: Full traceback: {traceback.format_exc()}"
)
return
json
.
dumps
([])
@
pyqtSlot
(
result
=
str
)
def
getLicenseText
(
self
)
->
str
:
"""Provide license text to JavaScript via WebChannel"""
try
:
logger
.
info
(
"QtWebChannel: Getting license text from database"
)
if
not
self
.
db_manager
:
logger
.
error
(
"QtWebChannel: Database manager not available"
)
return
json
.
dumps
({
"license_text"
:
"License text not available - database not connected"
})
# Get license text from database
license_text
=
self
.
_get_license_text_from_database
()
logger
.
debug
(
f
"QtWebChannel: Retrieved license text from database"
)
return
json
.
dumps
({
"license_text"
:
license_text
})
except
Exception
as
e
:
logger
.
error
(
f
"QtWebChannel: Failed to get license text: {e}"
)
return
json
.
dumps
({
"license_text"
:
"License text not available - error occurred"
})
@
pyqtSlot
(
result
=
str
)
def
getCompletedMatches
(
self
)
->
str
:
"""Provide last 3 completed matches to JavaScript via WebChannel"""
try
:
logger
.
info
(
"QtWebChannel: Getting completed matches from database"
)
if
not
self
.
db_manager
:
logger
.
error
(
"QtWebChannel: Database manager not available"
)
return
json
.
dumps
([])
# Get completed matches from database
completed_matches
=
self
.
_get_completed_matches_from_database
()
logger
.
debug
(
f
"QtWebChannel: Retrieved {len(completed_matches)} completed matches from database"
)
return
json
.
dumps
(
completed_matches
)
except
Exception
as
e
:
logger
.
error
(
f
"QtWebChannel: Failed to get completed matches: {e}"
)
return
json
.
dumps
([])
def
_get_license_text_from_database
(
self
)
->
str
:
"""Get license text from database configuration"""
try
:
if
not
self
.
db_manager
:
logger
.
error
(
"Database manager not available for getting license text"
)
return
"License text not available - database not connected"
# Get license text from configuration
license_text
=
self
.
db_manager
.
get_config_value
(
'license_text'
,
'License text not configured'
)
logger
.
debug
(
f
"Retrieved license text from database: {license_text}"
)
return
license_text
except
Exception
as
e
:
logger
.
error
(
f
"Failed to get license text from database: {e}"
)
return
"License text not available - database error"
def
_get_completed_matches_from_database
(
self
)
->
Optional
[
List
[
Dict
[
str
,
Any
]]]:
"""Get last 3 completed matches from database"""
try
:
from
..database.models
import
MatchModel
from
datetime
import
datetime
# Use the database manager passed to this channel
if
not
self
.
db_manager
:
logger
.
error
(
"Database manager not initialized"
)
return
[]
session
=
self
.
db_manager
.
get_session
()
try
:
# Get last 3 completed matches (status = 'done' and result is not null)
# Ordered by end_time descending (most recent first)
completed_matches
=
session
.
query
(
MatchModel
)
.
filter
(
MatchModel
.
status
==
'done'
,
MatchModel
.
result
.
isnot
(
None
),
MatchModel
.
end_time
.
isnot
(
None
)
)
.
order_by
(
MatchModel
.
end_time
.
desc
())
.
limit
(
3
)
.
all
()
if
not
completed_matches
:
logger
.
debug
(
"No completed matches found"
)
return
[]
matches_data
=
[]
for
match
in
completed_matches
:
match_data
=
{
'id'
:
match
.
id
,
'match_number'
:
match
.
match_number
,
'fighter1_township'
:
match
.
fighter1_township
,
'fighter2_township'
:
match
.
fighter2_township
,
'venue_kampala_township'
:
match
.
venue_kampala_township
,
'result'
:
match
.
result
,
'under_over_result'
:
match
.
under_over_result
,
'end_time'
:
match
.
end_time
.
isoformat
()
if
match
.
end_time
else
None
}
matches_data
.
append
(
match_data
)
logger
.
debug
(
f
"Retrieved {len(matches_data)} completed matches from database"
)
return
matches_data
finally
:
session
.
close
()
except
Exception
as
e
:
logger
.
error
(
f
"Failed to get completed matches from database: {e}"
)
return
[]
def
_get_fixture_data_from_games_thread
(
self
)
->
Optional
[
List
[
Dict
[
str
,
Any
]]]:
"""Get fixture data from the games thread"""
try
:
...
...
mbetterclient/qt_player/templates/default.html
View file @
1f2b9534
...
...
@@ -256,25 +256,41 @@
let
currentMessage
=
'Waiting for game to start...'
;
let
currentIcon
=
'🥊'
;
let
licenseText
=
'Loading license text...'
;
let
licenseTextFromData
=
''
;
// Function to update overlay data (called by Qt WebChannel)
function
updateOverlayData
(
data
)
{
console
.
log
(
'Received text overlay data:'
,
data
);
overlayData
=
data
||
{};
if
(
data
&&
data
.
title
)
{
let
contentChanged
=
false
;
if
(
data
&&
data
.
title
&&
data
.
title
!==
currentTitle
)
{
currentTitle
=
data
.
title
;
contentChanged
=
true
;
}
if
(
data
&&
data
.
message
)
{
if
(
data
&&
data
.
message
&&
data
.
message
!==
currentMessage
)
{
currentMessage
=
data
.
message
;
contentChanged
=
true
;
}
if
(
data
&&
data
.
icon
)
{
if
(
data
&&
data
.
icon
&&
data
.
icon
!==
currentIcon
)
{
currentIcon
=
data
.
icon
;
contentChanged
=
true
;
}
// Handle license text from overlay data
if
(
data
&&
data
.
license_text
)
{
licenseTextFromData
=
data
.
license_text
;
licenseText
=
licenseTextFromData
;
updateLicenseDisplay
();
}
// Only update message display and restart animations if content actually changed
if
(
contentChanged
)
{
updateMessageDisplay
();
}
updateMessageDisplay
();
}
// Update the message display
...
...
@@ -292,21 +308,35 @@
restartAnimations
();
}
// Fetch license text from
API
// Fetch license text from
WebChannel
async
function
fetchLicenseText
()
{
try
{
// Try to fetch from the web dashboard API
const
response
=
await
fetch
(
'http://127.0.0.1:5001/api/config/license-text'
);
if
(
response
.
ok
)
{
const
data
=
await
response
.
json
();
if
(
data
.
success
)
{
licenseText
=
data
.
license_text
||
''
;
updateLicenseDisplay
();
// Only fetch from WebChannel if we don't have license text from overlay data yet
if
(
!
licenseTextFromData
||
licenseTextFromData
.
trim
()
===
''
)
{
// Try to get license text from Qt WebChannel
if
(
window
.
overlay
&&
window
.
overlay
.
getLicenseText
)
{
const
licenseTextData
=
await
window
.
overlay
.
getLicenseText
();
if
(
licenseTextData
)
{
// Parse the JSON response to extract license_text
try
{
const
licenseData
=
JSON
.
parse
(
licenseTextData
);
if
(
licenseData
.
license_text
)
{
licenseText
=
licenseData
.
license_text
;
updateLicenseDisplay
();
console
.
log
(
'License text loaded from WebChannel:'
,
licenseText
);
}
else
{
console
.
log
(
'No license_text found in WebChannel response'
);
}
}
catch
(
parseError
)
{
console
.
log
(
'Failed to parse license text JSON from WebChannel:'
,
parseError
);
// Keep default text if parsing fails
}
}
}
}
}
catch
(
error
)
{
console
.
log
(
'Could not fetch license text from
API
, using default'
);
// Keep default text if
API
is not available
console
.
log
(
'Could not fetch license text from
WebChannel
, using default'
);
// Keep default text if
WebChannel
is not available
}
}
...
...
@@ -347,28 +377,79 @@
document
.
addEventListener
(
'DOMContentLoaded'
,
function
()
{
console
.
log
(
'Text message overlay initialized'
);
updateMessageDisplay
();
fetchLicenseText
();
// Setup WebChannel communication
setupWebChannel
();
});
// Qt WebChannel initialization (when available)
if
(
typeof
QWebChannel
!==
'undefined'
)
{
new
QWebChannel
(
qt
.
webChannelTransport
,
function
(
channel
)
{
console
.
log
(
'WebChannel initialized for text message overlay'
);
// Connect to overlay object if available
if
(
channel
.
objects
.
overlay
)
{
channel
.
objects
.
overlay
.
dataChanged
.
connect
(
function
(
data
)
{
// Setup WebChannel communication
function
setupWebChannel
()
{
// Check if WebChannel is already set up by overlay.js
if
(
window
.
overlay
)
{
console
.
log
(
'WebChannel already set up by overlay.js'
);
// Listen for data updates from Python
if
(
window
.
overlay
.
dataUpdated
)
{
window
.
overlay
.
dataUpdated
.
connect
(
function
(
data
)
{
console
.
log
(
'Received data update from Python:'
,
data
);
updateOverlayData
(
data
);
});
// Get initial data
if
(
channel
.
objects
.
overlay
.
getCurrentData
)
{
channel
.
objects
.
overlay
.
getCurrentData
(
function
(
data
)
{
updateOverlayData
(
data
);
}
// Wait for WebChannel to be ready before fetching license text
waitForWebChannelReady
(()
=>
{
fetchLicenseText
();
// Fetch license text now that WebChannel is ready
});
return
;
}
// Fallback: setup WebChannel if overlay.js didn't do it
if
(
typeof
qt
!==
'undefined'
&&
qt
.
webChannelTransport
)
{
try
{
new
QWebChannel
(
qt
.
webChannelTransport
,
function
(
channel
)
{
console
.
log
(
'WebChannel connected successfully (fallback)'
);
// Connect to overlay object
window
.
overlay
=
channel
.
objects
.
overlay
;
// Listen for data updates from Python
if
(
window
.
overlay
&&
window
.
overlay
.
dataUpdated
)
{
window
.
overlay
.
dataUpdated
.
connect
(
function
(
data
)
{
console
.
log
(
'Received data update from Python (fallback):'
,
data
);
updateOverlayData
(
data
);
});
}
// Wait for WebChannel to be ready before fetching license text
waitForWebChannelReady
(()
=>
{
fetchLicenseText
();
// Fetch license text now that WebChannel is ready
});
}
});
}
catch
(
e
)
{
console
.
log
(
'Failed to setup WebChannel:'
,
e
);
}
});
}
else
{
console
.
log
(
'WebChannel not available, using default settings'
);
}
}
// Wait for WebChannel to be ready
function
waitForWebChannelReady
(
callback
,
maxWait
=
10000
)
{
const
startTime
=
Date
.
now
();
const
checkReady
=
()
=>
{
if
(
window
.
overlay
&&
window
.
overlay
.
getLicenseText
)
{
console
.
log
(
'WebChannel ready for license text fetch'
);
callback
();
}
else
if
(
Date
.
now
()
-
startTime
>
maxWait
)
{
console
.
warn
(
'WebChannel not ready after max wait time, proceeding anyway'
);
callback
();
}
else
{
setTimeout
(
checkReady
,
100
);
}
};
checkReady
();
}
// Export functions for external use
...
...
@@ -377,13 +458,13 @@
</script>
<!--
IMPORTANT: When creating or editing custom templates, always maintain these
two
script tags:
IMPORTANT: When creating or editing custom templates, always maintain these script tags:
1. qrc:///qtwebchannel/qwebchannel.js - Required for Qt WebChannel communication
2. overlay://overlay.js - Required for overlay functionality and data updates
These scripts enable communication between the Qt application and the overlay template.
Without them, the template will not receive data updates or function properly.
NOTE: When editing this template or creating new ones, never remove these script sources!
The overlay:// custom scheme ensures JavaScript files work for both built-in and uploaded templates.
-->
...
...
mbetterclient/qt_player/templates/fixtures.html
View file @
1f2b9534
...
...
@@ -143,32 +143,23 @@
.results-bottom-bar
{
position
:
absolute
;
bottom
:
20px
;
left
:
50%
;
transform
:
translateX
(
-50%
)
;
left
:
20px
;
right
:
20px
;
background
:
rgba
(
0
,
123
,
255
,
0.85
);
border-radius
:
15px
;
padding
:
15px
20px
;
max-width
:
90%
;
box-shadow
:
0
4px
16px
rgba
(
0
,
0
,
0
,
0.3
);
backdrop-filter
:
blur
(
10px
);
border
:
2px
solid
rgba
(
255
,
255
,
255
,
0.1
);
color
:
white
;
font-size
:
24px
;
text-align
:
left
;
text-align
:
center
;
z-index
:
1001
;
white-space
:
nowrap
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
}
.results-title
{
font-weight
:
bold
;
margin-bottom
:
10px
;
text-shadow
:
1px
1px
2px
rgba
(
0
,
0
,
0
,
0.5
);
}
.match-result
{
font-size
:
20px
;
margin
:
5px
0
;
text-shadow
:
1px
1px
2px
rgba
(
0
,
0
,
0
,
0.5
);
}
.fixtures-title
{
color
:
white
;
...
...
@@ -417,7 +408,6 @@
<!-- Results Bottom Bar -->
<div
class=
"results-bottom-bar"
id=
"resultsBottomBar"
style=
"display: none;"
>
<div
class=
"results-title"
>
RESULTS of the last 3 matches:
</div>
<div
id=
"resultsContent"
>
<!-- Match results will be populated by JavaScript -->
</div>
...
...
@@ -822,21 +812,32 @@
];
}
// Fetch license text from
API
// Fetch license text from
WebChannel
async
function
fetchLicenseText
()
{
try
{
// Try to fetch from the web dashboard API
const
response
=
await
fetch
(
'http://127.0.0.1:5001/api/config/license-text'
);
if
(
response
.
ok
)
{
const
data
=
await
response
.
json
();
if
(
data
.
success
)
{
licenseText
=
data
.
license_text
||
''
;
updateLicenseDisplay
();
// Try to get license text from Qt WebChannel
if
(
window
.
overlay
&&
window
.
overlay
.
getLicenseText
)
{
const
licenseTextData
=
await
window
.
overlay
.
getLicenseText
();
if
(
licenseTextData
)
{
// Parse the JSON response to extract license_text
try
{
const
licenseData
=
JSON
.
parse
(
licenseTextData
);
if
(
licenseData
.
license_text
)
{
licenseText
=
licenseData
.
license_text
;
updateLicenseDisplay
();
console
.
log
(
'License text loaded from WebChannel:'
,
licenseText
);
}
else
{
console
.
log
(
'No license_text found in WebChannel response'
);
}
}
catch
(
parseError
)
{
console
.
log
(
'Failed to parse license text JSON from WebChannel:'
,
parseError
);
// Keep default text if parsing fails
}
}
}
}
catch
(
error
)
{
console
.
log
(
'Could not fetch license text from
API
, using default'
);
// Keep default text if
API
is not available
console
.
log
(
'Could not fetch license text from
WebChannel
, using default'
);
// Keep default text if
WebChannel
is not available
}
}
...
...
@@ -1090,7 +1091,19 @@
try {
debugTime('Fetching last match results');
// Try to fetch from web API if webServerBaseUrl is available
// Try WebChannel first (same as license text)
if (window.overlay && typeof window.overlay.getCompletedMatches === 'function') {
const completedMatchesJson = await window.overlay.getCompletedMatches();
const completedMatches = JSON.parse(completedMatchesJson);
if (completedMatches && completedMatches.length > 0) {
// Take last 3 matches (already ordered by end_time desc in WebChannel)
const lastMatches = completedMatches.slice(0, 3);
renderMatchResults(lastMatches);
return;
}
}
// Fallback: try to fetch from web API if webServerBaseUrl is available
if (webServerBaseUrl) {
const response = await fetch(`
$
{
webServerBaseUrl
}
/api/fixtures`
);
if
(
response
.
ok
)
{
...
...
@@ -1125,17 +1138,6 @@
}
}
// Fallback: try WebChannel if available
if
(
window
.
overlay
&&
typeof
window
.
overlay
.
getCompletedMatches
===
'function'
)
{
const
completedMatchesJson
=
await
window
.
overlay
.
getCompletedMatches
();
const
completedMatches
=
JSON
.
parse
(
completedMatchesJson
);
if
(
completedMatches
&&
completedMatches
.
length
>
0
)
{
const
lastMatches
=
completedMatches
.
slice
(
-
3
);
// Last 3 matches
renderMatchResults
(
lastMatches
);
return
;
}
}
// No results available
debugTime
(
'No match results available'
);
document
.
getElementById
(
'resultsBottomBar'
).
style
.
display
=
'none'
;
...
...
@@ -1151,9 +1153,9 @@
const
resultsContent
=
document
.
getElementById
(
'resultsContent'
);
if
(
!
resultsContent
)
return
;
let
results
HTML
=
'
'
;
let
results
Text
=
'RESULTS:
'
;
matches
.
forEach
(
match
=>
{
matches
.
forEach
(
(
match
,
index
)
=>
{
const
matchNumber
=
match
.
match_number
||
match
.
id
||
'N/A'
;
const
fighter1
=
match
.
fighter1_township
||
match
.
fighter1
||
'Fighter 1'
;
const
fighter2
=
match
.
fighter2_township
||
match
.
fighter2
||
'Fighter 2'
;
...
...
@@ -1162,10 +1164,13 @@
const
resultText
=
underOver
?
`
${
result
}
(
${
underOver
}
)`
:
result
;
resultsHTML
+=
`<div class="match-result">Match #
${
matchNumber
}
::
${
fighter1
}
vs
${
fighter2
}
:
${
resultText
}
</div>`
;
resultsText
+=
`Match #
${
matchNumber
}
:
${
fighter1
}
vs
${
fighter2
}
=
${
resultText
}
`
;
if
(
index
<
matches
.
length
-
1
)
{
resultsText
+=
' | '
;
}
});
resultsContent
.
innerHTML
=
resultsHTML
;
resultsContent
.
textContent
=
resultsText
;
document
.
getElementById
(
'resultsBottomBar'
).
style
.
display
=
'block'
;
debugTime
(
`Rendered
${
matches
.
length
}
match results`
);
...
...
@@ -1179,9 +1184,6 @@
// Setup WebChannel first
setupWebChannel
();
// Fetch license text
fetchLicenseText
();
// Show loading message initially
document
.
getElementById
(
'fixturesContent'
).
style
.
display
=
'none'
;
document
.
getElementById
(
'noMatches'
).
style
.
display
=
'none'
;
...
...
@@ -1190,9 +1192,12 @@
debugTime
(
'UI initialized - Loading message displayed'
);
// Wait briefly for WebChannel to connect
setTimeout
(()
=>
{
console
.
log
(
'🔍 DEBUG: Starting fixture data fetch via WebChannel'
);
// Wait for WebChannel to be ready before fetching data
waitForWebChannelReady
(()
=>
{
console
.
log
(
'🔍 DEBUG: WebChannel ready, starting data fetch'
);
// Fetch license text now that WebChannel is ready
fetchLicenseText
();
// Fetch fixtures data via WebChannel
debugTime
(
'Fetching fixtures data via WebChannel'
);
...
...
@@ -1213,8 +1218,27 @@
debugTime
(
'Data was received before 5 second timeout'
);
}
},
5000
);
}
,
50
);
// Wait 50ms for WebChannel setup
}
);
});
// Wait for WebChannel to be ready
function
waitForWebChannelReady
(
callback
,
maxWait
=
10000
)
{
const
startTime
=
Date
.
now
();
const
checkReady
=
()
=>
{
if
(
window
.
overlay
&&
window
.
overlay
.
getLicenseText
)
{
console
.
log
(
'🔍 DEBUG: WebChannel ready for license text fetch'
);
callback
();
}
else
if
(
Date
.
now
()
-
startTime
>
maxWait
)
{
console
.
warn
(
'🔍 DEBUG: WebChannel not ready after max wait time, proceeding anyway'
);
callback
();
}
else
{
setTimeout
(
checkReady
,
100
);
}
};
checkReady
();
}
</script>
...
...
mbetterclient/qt_player/templates/match.html
View file @
1f2b9534
This diff is collapsed.
Click to expand it.
mbetterclient/qt_player/templates/text.html
View file @
1f2b9534
This diff is collapsed.
Click to expand it.
test_api.py
deleted
100644 → 0
View file @
0a38c586
#!/usr/bin/env python3
"""
Test script to check API endpoints for debugging fixtures overlay
"""
import
requests
import
json
import
sys
from
pathlib
import
Path
def
test_fixtures_api
():
"""Test the fixtures API endpoint"""
print
(
"Testing fixtures API endpoint..."
)
# Try different possible URLs
urls_to_test
=
[
"http://127.0.0.1:5001/api/fixtures"
,
"http://localhost:5001/api/fixtures"
,
"http://127.0.0.1:5000/api/fixtures"
,
"http://localhost:5000/api/fixtures"
]
for
url
in
urls_to_test
:
print
(
f
"
\n
Trying URL: {url}"
)
try
:
response
=
requests
.
get
(
url
,
timeout
=
5
)
print
(
f
"Status Code: {response.status_code}"
)
if
response
.
status_code
==
200
:
try
:
data
=
response
.
json
()
print
(
"Response data:"
)
print
(
json
.
dumps
(
data
,
indent
=
2
))
if
'success'
in
data
and
data
[
'success'
]:
print
(
f
"✅ SUCCESS: Found {data.get('total', 0)} fixtures"
)
return
True
else
:
print
(
"❌ API returned success=false"
)
return
False
except
json
.
JSONDecodeError
as
e
:
print
(
f
"❌ Invalid JSON response: {e}"
)
print
(
f
"Raw response: {response.text[:500]}..."
)
return
False
else
:
print
(
f
"❌ HTTP Error: {response.status_code}"
)
print
(
f
"Response: {response.text[:200]}..."
)
except
requests
.
exceptions
.
ConnectionError
:
print
(
"❌ Connection refused - server not running"
)
except
requests
.
exceptions
.
Timeout
:
print
(
"❌ Request timed out"
)
except
Exception
as
e
:
print
(
f
"❌ Error: {e}"
)
print
(
"
\n
❌ All URLs failed - API server may not be running"
)
return
False
def
test_web_dashboard_status
():
"""Test if web dashboard is running"""
print
(
"
\n
Testing web dashboard status..."
)
urls_to_test
=
[
"http://127.0.0.1:5001/"
,
"http://localhost:5001/"
,
"http://127.0.0.1:5000/"
,
"http://localhost:5000/"
]
for
url
in
urls_to_test
:
print
(
f
"Trying URL: {url}"
)
try
:
response
=
requests
.
get
(
url
,
timeout
=
5
)
print
(
f
"Status Code: {response.status_code}"
)
if
response
.
status_code
==
200
:
print
(
"✅ Web dashboard is running"
)
return
True
except
Exception
as
e
:
print
(
f
"❌ Error: {e}"
)
print
(
"❌ Web dashboard not accessible"
)
return
False
def
main
():
print
(
"=== MbetterClient API Test ==="
)
# Test web dashboard first
web_running
=
test_web_dashboard_status
()
if
not
web_running
:
print
(
"
\n
⚠️ Web dashboard is not running. Make sure to start the web server first."
)
print
(
"Run: python main.py --web-only"
)
sys
.
exit
(
1
)
# Test fixtures API
api_working
=
test_fixtures_api
()
if
api_working
:
print
(
"
\n
✅ API test completed successfully"
)
else
:
print
(
"
\n
❌ API test failed"
)
print
(
"
\n
Troubleshooting tips:"
)
print
(
"1. Make sure the web server is running"
)
print
(
"2. Check if the database has fixture data"
)
print
(
"3. Check the web server logs for errors"
)
print
(
"4. Verify the fixtures endpoint is properly configured"
)
if
__name__
==
"__main__"
:
main
()
\ No newline at end of file
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