Commit ·
b2ce10c
1
Parent(s): 0e86ce6
not counting bozos
Browse files- app.py +18 -17
- requirements.txt +1 -0
- templates/index.html +2 -2
app.py
CHANGED
|
@@ -95,34 +95,35 @@ async def analyze_selected_achievements(request_data: AnalyzeAchievementsRequest
|
|
| 95 |
print(f"Fetching achievement status for {len(selected_characters)} selected characters...")
|
| 96 |
for char_name in selected_characters:
|
| 97 |
print(f" Fetching data for: {char_name}...")
|
| 98 |
-
# Util.api.get_char_achievements returns a list on success, or a dict with 'error':True on failure.
|
| 99 |
-
# If it fails, it should still contain an 'achievements_list' key with the default (all incomplete) data.
|
| 100 |
ach_status_result = blizzard_api.get_char_achievements(ACCESS_TOKEN, realm_slug, char_name)
|
| 101 |
|
| 102 |
if isinstance(ach_status_result, dict) and ach_status_result.get('error'):
|
| 103 |
print(f" Warning/Error for {char_name}: {ach_status_result.get('message', 'Unknown error')}")
|
| 104 |
errored_character_names.append(char_name)
|
| 105 |
-
#
|
| 106 |
-
|
| 107 |
-
ach_data_by_character[char_name] = ach_status_result['achievements_list']
|
| 108 |
-
else:
|
| 109 |
-
# This case should ideally not happen if get_char_achievements is consistent
|
| 110 |
-
# but as a fallback, create an empty list for this char to avoid breaking later logic,
|
| 111 |
-
# though they won't contribute to completion stats correctly.
|
| 112 |
-
print(f" Critical: No 'achievements_list' in error response for {char_name}. They will have no data.")
|
| 113 |
-
ach_data_by_character[char_name] = []
|
| 114 |
elif isinstance(ach_status_result, list): # Successful fetch
|
| 115 |
ach_data_by_character[char_name] = ach_status_result
|
| 116 |
else:
|
| 117 |
# Unexpected format from get_char_achievements
|
| 118 |
print(f" Error: Unexpected data format received for {char_name}. Skipping.")
|
| 119 |
errored_character_names.append(char_name) # Also count as errored
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
completion_summary = blizzard_api.calculate_achievement_completion_percentages(ach_data_by_character)
|
| 127 |
|
| 128 |
if not completion_summary and not errored_character_names: # If summary is empty AND no specific char errors were reported
|
|
|
|
| 95 |
print(f"Fetching achievement status for {len(selected_characters)} selected characters...")
|
| 96 |
for char_name in selected_characters:
|
| 97 |
print(f" Fetching data for: {char_name}...")
|
|
|
|
|
|
|
| 98 |
ach_status_result = blizzard_api.get_char_achievements(ACCESS_TOKEN, realm_slug, char_name)
|
| 99 |
|
| 100 |
if isinstance(ach_status_result, dict) and ach_status_result.get('error'):
|
| 101 |
print(f" Warning/Error for {char_name}: {ach_status_result.get('message', 'Unknown error')}")
|
| 102 |
errored_character_names.append(char_name)
|
| 103 |
+
# DO NOT add this character's data to ach_data_by_character
|
| 104 |
+
# as per new requirement to exclude them from calculations.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
elif isinstance(ach_status_result, list): # Successful fetch
|
| 106 |
ach_data_by_character[char_name] = ach_status_result
|
| 107 |
else:
|
| 108 |
# Unexpected format from get_char_achievements
|
| 109 |
print(f" Error: Unexpected data format received for {char_name}. Skipping.")
|
| 110 |
errored_character_names.append(char_name) # Also count as errored
|
| 111 |
+
# DO NOT add to ach_data_by_character here either
|
| 112 |
+
|
| 113 |
+
# If all selected characters resulted in an error, ach_data_by_character might be empty.
|
| 114 |
+
# The frontend will show the errored_character_names.
|
| 115 |
+
# If ach_data_by_character is empty, calculate_achievement_completion_percentages will likely return empty or handle it.
|
| 116 |
+
|
| 117 |
+
if not ach_data_by_character and errored_character_names:
|
| 118 |
+
# This means all selected characters had errors, but we have the list of who errored.
|
| 119 |
+
# Return the list of errored characters, but summary will be empty/None.
|
| 120 |
+
print("All selected characters resulted in API errors. No data to summarize.")
|
| 121 |
+
return {"error": "Could not retrieve achievement data for any selected character.", "summary": [], "errored_characters": errored_character_names}
|
| 122 |
+
elif not ach_data_by_character:
|
| 123 |
+
# This case means no characters were selected initially or some other edge case where both are empty.
|
| 124 |
+
return {"error": "No valid achievement data could be collected (no characters processed or all failed without specific error tracking).", "summary": None, "errored_characters": errored_character_names}
|
| 125 |
+
|
| 126 |
+
print(f"\nCalculating achievement completion percentages for {len(ach_data_by_character)} successfully processed character(s)...")
|
| 127 |
completion_summary = blizzard_api.calculate_achievement_completion_percentages(ach_data_by_character)
|
| 128 |
|
| 129 |
if not completion_summary and not errored_character_names: # If summary is empty AND no specific char errors were reported
|
requirements.txt
CHANGED
|
@@ -4,3 +4,4 @@ requests
|
|
| 4 |
python-dotenv
|
| 5 |
jinja2
|
| 6 |
pandas
|
|
|
|
|
|
| 4 |
python-dotenv
|
| 5 |
jinja2
|
| 6 |
pandas
|
| 7 |
+
pydantic
|
templates/index.html
CHANGED
|
@@ -219,7 +219,7 @@
|
|
| 219 |
</head>
|
| 220 |
<body>
|
| 221 |
<div class="container">
|
| 222 |
-
<h1 class="shit">faygan's shitty achievo tracker</h1>
|
| 223 |
|
| 224 |
<div class="form-row">
|
| 225 |
<div class="form-group col-md-6">
|
|
@@ -501,7 +501,7 @@
|
|
| 501 |
// Display character-specific API errors if any
|
| 502 |
if (data.errored_characters && Array.isArray(data.errored_characters) && data.errored_characters.length > 0) {
|
| 503 |
const erroredNames = data.errored_characters.map(name => escapeHtml(name)).join(', ');
|
| 504 |
-
charApiErrorsDiv.innerHTML = `<p><strong>
|
| 505 |
charApiErrorsDiv.style.display = 'block';
|
| 506 |
} else {
|
| 507 |
charApiErrorsDiv.style.display = 'none';
|
|
|
|
| 219 |
</head>
|
| 220 |
<body>
|
| 221 |
<div class="container">
|
| 222 |
+
<h1 class="shit">faygan's shitty group achievo tracker</h1>
|
| 223 |
|
| 224 |
<div class="form-row">
|
| 225 |
<div class="form-group col-md-6">
|
|
|
|
| 501 |
// Display character-specific API errors if any
|
| 502 |
if (data.errored_characters && Array.isArray(data.errored_characters) && data.errored_characters.length > 0) {
|
| 503 |
const erroredNames = data.errored_characters.map(name => escapeHtml(name)).join(', ');
|
| 504 |
+
charApiErrorsDiv.innerHTML = `<p><strong>Oops:</strong> I coudn't find data for: ${erroredNames}. They're being excluded from the selection because it's easier .¯\_(ツ)_/¯</p>`;
|
| 505 |
charApiErrorsDiv.style.display = 'block';
|
| 506 |
} else {
|
| 507 |
charApiErrorsDiv.style.display = 'none';
|