Skip to content

Commit bbe99d2

Browse files
committed
shared task structure
1 parent 1e35b04 commit bbe99d2

3 files changed

Lines changed: 197 additions & 79 deletions

File tree

task_database.py

Lines changed: 122 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,17 @@ def add_task_account(username, is_official, lms_enabled):
9494
"username": str(username),
9595
"isOfficial": bool(is_official),
9696
"lmsEnabled": bool(lms_enabled),
97+
"completedTasks": [],
98+
"recordedItemIdsByTask": {},
9799
'tiers': {
98-
'easy': {"completedTasks" : []},
99-
'medium': {"completedTasks" : []},
100-
'hard': {"completedTasks" : []},
101-
'elite': {"completedTasks" : []},
102-
'master' : {"completedTasks" : []},
103-
'passive': {"completedTasks" : []},
104-
'extra': {"completedTasks" : []},
105-
'pets': {"completedTasks" : []},
100+
'easy': {},
101+
'medium': {},
102+
'hard': {},
103+
'elite': {},
104+
'master' : {},
105+
'passive': {},
106+
'extra': {},
107+
'pets': {},
106108
}
107109
})
108110

@@ -280,15 +282,14 @@ def __set_task_complete(username: str, tier: str, task_id: str, complete: bool,
280282
completed_at_iso: str | None = None,
281283
completed_item_ids: list[int] | None = None):
282284
task_coll = mydb['taskLists']
283-
cleaned_tier = tier.replace("Tasks", "")
284285
if complete:
285286
completed_date = __parse_completed_iso(completed_at_iso) or datetime.now(timezone.utc)
286287
safe_completed_item_ids = __sanitize_item_ids(completed_item_ids)
287288
task_coll.update_one(
288289
{"username": username},
289290
{
290291
"$pull": {
291-
f"tiers.{cleaned_tier}.completedTasks": {
292+
"completedTasks": {
292293
"id": task_id
293294
}
294295
}
@@ -298,10 +299,10 @@ def __set_task_complete(username: str, tier: str, task_id: str, complete: bool,
298299
{"username": username},
299300
{
300301
"$push": {
301-
f"tiers.{cleaned_tier}.completedTasks": {
302+
"completedTasks": {
302303
"id": task_id,
303304
"completedDate": completed_date,
304-
"completedItemIds": safe_completed_item_ids
305+
"retainedItemIds": safe_completed_item_ids
305306
}
306307
}
307308
}
@@ -310,7 +311,7 @@ def __set_task_complete(username: str, tier: str, task_id: str, complete: bool,
310311
{"username": username},
311312
{
312313
"$set": {
313-
f"tiers.{cleaned_tier}.recordedItemIdsByTask.{task_id}": safe_completed_item_ids
314+
f"recordedItemIdsByTask.{task_id}": safe_completed_item_ids
314315
}
315316
}
316317
)
@@ -322,7 +323,7 @@ def __set_task_complete(username: str, tier: str, task_id: str, complete: bool,
322323
},
323324
{
324325
"$pull" : {
325-
f"tiers.{cleaned_tier}.completedTasks" : {"id" : task_id}
326+
"completedTasks" : {"id" : task_id}
326327
}
327328
})
328329
return None, []
@@ -742,6 +743,8 @@ def update_imported_tasks(username: str, all_tasks: list, username2: str,
742743

743744
diaries = coll.find_one({'username': username}, {
744745
'_id': 0,
746+
'completedTasks': 1,
747+
'recordedItemIdsByTask': 1,
745748
'tiers.easy.completedTasks': 1,
746749
'tiers.medium.completedTasks': 1,
747750
'tiers.hard.completedTasks': 1,
@@ -752,22 +755,74 @@ def update_imported_tasks(username: str, all_tasks: list, username2: str,
752755
'tiers.elite.recordedItemIdsByTask': 1,
753756
})
754757

758+
if not diaries:
759+
return
760+
755761
def sanitize_recorded_map(value):
756762
if not isinstance(value, dict):
757763
return {}
758764
return {str(task_id): __sanitize_item_ids(item_ids) for task_id, item_ids in value.items()}
759765

760-
existing_recorded_easy = sanitize_recorded_map(diaries['tiers']['easy'].get('recordedItemIdsByTask', {}))
761-
existing_recorded_medium = sanitize_recorded_map(diaries['tiers']['medium'].get('recordedItemIdsByTask', {}))
762-
existing_recorded_hard = sanitize_recorded_map(diaries['tiers']['hard'].get('recordedItemIdsByTask', {}))
763-
existing_recorded_elite = sanitize_recorded_map(diaries['tiers']['elite'].get('recordedItemIdsByTask', {}))
766+
tiers_data = diaries.get('tiers', {}) if isinstance(diaries.get('tiers', {}), dict) else {}
764767

765-
def existing_completed_date_map(completed_tasks):
766-
output = {}
767-
for entry in completed_tasks:
768+
existing_root_recorded = sanitize_recorded_map(diaries.get('recordedItemIdsByTask', {}))
769+
770+
existing_recorded_easy = sanitize_recorded_map(tiers_data.get('easy', {}).get('recordedItemIdsByTask', {}))
771+
existing_recorded_medium = sanitize_recorded_map(tiers_data.get('medium', {}).get('recordedItemIdsByTask', {}))
772+
existing_recorded_hard = sanitize_recorded_map(tiers_data.get('hard', {}).get('recordedItemIdsByTask', {}))
773+
existing_recorded_elite = sanitize_recorded_map(tiers_data.get('elite', {}).get('recordedItemIdsByTask', {}))
774+
if not existing_root_recorded:
775+
existing_root_recorded = {
776+
**existing_recorded_easy,
777+
**existing_recorded_medium,
778+
**existing_recorded_hard,
779+
**existing_recorded_elite,
780+
}
781+
782+
lms_enabled = get_user(username).lms_enabled
783+
tier_task_ids = {
784+
'easy': {task.id for task in tasklists.list_for_tier('easy', lms_enabled)},
785+
'medium': {task.id for task in tasklists.list_for_tier('medium', lms_enabled)},
786+
'hard': {task.id for task in tasklists.list_for_tier('hard', lms_enabled)},
787+
'elite': {task.id for task in tasklists.list_for_tier('elite', lms_enabled)},
788+
}
789+
790+
def normalize_completed_entries(value):
791+
if not isinstance(value, list):
792+
return []
793+
output = []
794+
for entry in value:
795+
if not isinstance(entry, dict):
796+
continue
768797
task_id = entry.get('id')
769798
if not task_id:
770799
continue
800+
retained_item_ids = entry.get('retainedItemIds')
801+
if retained_item_ids is None:
802+
retained_item_ids = entry.get('completedItemIds', [])
803+
output.append({
804+
'id': str(task_id),
805+
'completedDate': entry.get('completedDate'),
806+
'retainedItemIds': __sanitize_item_ids(retained_item_ids),
807+
})
808+
return output
809+
810+
existing_root_completed = normalize_completed_entries(diaries.get('completedTasks', []))
811+
if not existing_root_completed:
812+
existing_root_completed = (
813+
normalize_completed_entries(tiers_data.get('easy', {}).get('completedTasks', [])) +
814+
normalize_completed_entries(tiers_data.get('medium', {}).get('completedTasks', [])) +
815+
normalize_completed_entries(tiers_data.get('hard', {}).get('completedTasks', [])) +
816+
normalize_completed_entries(tiers_data.get('elite', {}).get('completedTasks', []))
817+
)
818+
819+
def existing_completed_date_map(tier_name):
820+
output = {}
821+
valid_ids = tier_task_ids[tier_name]
822+
for entry in existing_root_completed:
823+
task_id = entry.get('id')
824+
if not task_id or task_id not in valid_ids:
825+
continue
771826
completed_date = entry.get('completedDate')
772827
if completed_date is None:
773828
continue
@@ -776,10 +831,10 @@ def existing_completed_date_map(completed_tasks):
776831
output[task_id] = normalized_date
777832
return output
778833

779-
existing_completed_dates_easy = existing_completed_date_map(diaries['tiers']['easy'].get('completedTasks', []))
780-
existing_completed_dates_medium = existing_completed_date_map(diaries['tiers']['medium'].get('completedTasks', []))
781-
existing_completed_dates_hard = existing_completed_date_map(diaries['tiers']['hard'].get('completedTasks', []))
782-
existing_completed_dates_elite = existing_completed_date_map(diaries['tiers']['elite'].get('completedTasks', []))
834+
existing_completed_dates_easy = existing_completed_date_map('easy')
835+
existing_completed_dates_medium = existing_completed_date_map('medium')
836+
existing_completed_dates_hard = existing_completed_date_map('hard')
837+
existing_completed_dates_elite = existing_completed_date_map('elite')
783838

784839
if overwrite_temple_timestamps:
785840
tier_existing_dates = [
@@ -805,77 +860,91 @@ def existing_completed_date_map(completed_tasks):
805860
imported_recorded_hard = sanitize_recorded_map(recorded_item_ids_by_tier.get('hard', {}))
806861
imported_recorded_elite = sanitize_recorded_map(recorded_item_ids_by_tier.get('elite', {}))
807862

808-
merged_recorded_easy = {**existing_recorded_easy, **imported_recorded_easy}
809-
merged_recorded_medium = {**existing_recorded_medium, **imported_recorded_medium}
810-
merged_recorded_hard = {**existing_recorded_hard, **imported_recorded_hard}
811-
merged_recorded_elite = {**existing_recorded_elite, **imported_recorded_elite}
863+
merged_root_recorded = {
864+
**existing_root_recorded,
865+
**imported_recorded_easy,
866+
**imported_recorded_medium,
867+
**imported_recorded_hard,
868+
**imported_recorded_elite,
869+
}
812870

813-
coll.update_one({'username': username}, {
814-
'$set': {
815-
'tiers.easy.completedTasks': [],
816-
'tiers.medium.completedTasks': [],
817-
'tiers.hard.completedTasks': [],
818-
'tiers.elite.completedTasks': [],
819-
}
820-
})
871+
imported_root_completed = []
872+
for tier_tasks in all_tasks:
873+
for imported_task in tier_tasks:
874+
task_id = imported_task.get('id')
875+
if not task_id:
876+
continue
877+
imported_root_completed.append({
878+
'id': str(task_id),
879+
'completedDate': imported_task.get('completedDate'),
880+
'retainedItemIds': [],
881+
})
882+
883+
import_tier_task_ids = set().union(
884+
tier_task_ids['easy'],
885+
tier_task_ids['medium'],
886+
tier_task_ids['hard'],
887+
tier_task_ids['elite'],
888+
)
889+
890+
preserved_non_import_entries = []
891+
for entry in existing_root_completed:
892+
if entry['id'] not in import_tier_task_ids:
893+
preserved_non_import_entries.append(entry)
894+
895+
merged_root_completed = preserved_non_import_entries + imported_root_completed
821896

822897
coll.update_one({'username': username}, {
823898
'$set': {
824-
'tiers.easy.completedTasks': all_tasks[0],
825-
'tiers.medium.completedTasks': all_tasks[1],
826-
'tiers.hard.completedTasks': all_tasks[2],
827-
'tiers.elite.completedTasks': all_tasks[3],
828-
'tiers.easy.recordedItemIdsByTask': merged_recorded_easy,
829-
'tiers.medium.recordedItemIdsByTask': merged_recorded_medium,
830-
'tiers.hard.recordedItemIdsByTask': merged_recorded_hard,
831-
'tiers.elite.recordedItemIdsByTask': merged_recorded_elite,
899+
'completedTasks': merged_root_completed,
900+
'recordedItemIdsByTask': merged_root_recorded,
832901
}
833902
})
834903

835904
coll.update_one({'username': username}, {'$set': {'ign': username2}})
836905

837-
for diary in diaries['tiers']['easy']['completedTasks']:
906+
for diary in existing_root_completed:
838907
if diary['id'] in easy_diaries:
839908
__set_task_complete(
840909
username,
841910
'easyTasks',
842911
diary['id'],
843912
True,
844913
__datetime_to_iso(diary.get('completedDate')),
845-
diary.get('completedItemIds', []),
914+
diary.get('retainedItemIds', []),
846915
)
847916

848-
for diary in diaries['tiers']['medium']['completedTasks']:
917+
for diary in existing_root_completed:
849918
if diary['id'] in medium_diaries:
850919
__set_task_complete(
851920
username,
852921
'mediumTasks',
853922
diary['id'],
854923
True,
855924
__datetime_to_iso(diary.get('completedDate')),
856-
diary.get('completedItemIds', []),
925+
diary.get('retainedItemIds', []),
857926
)
858927

859-
for diary in diaries['tiers']['hard']['completedTasks']:
928+
for diary in existing_root_completed:
860929
if diary['id'] in hard_diaries:
861930
__set_task_complete(
862931
username,
863932
'hardTasks',
864933
diary['id'],
865934
True,
866935
__datetime_to_iso(diary.get('completedDate')),
867-
diary.get('completedItemIds', []),
936+
diary.get('retainedItemIds', []),
868937
)
869938

870-
for diary in diaries['tiers']['elite']['completedTasks']:
939+
for diary in existing_root_completed:
871940
if diary['id'] in elite_diaries:
872941
__set_task_complete(
873942
username,
874943
'eliteTasks',
875944
diary['id'],
876945
True,
877946
__datetime_to_iso(diary.get('completedDate')),
878-
diary.get('completedItemIds', []),
947+
diary.get('retainedItemIds', []),
879948
)
880949

881950

taskapp.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,16 +573,22 @@ def collection_log_import():
573573
medium_import_result = import_logs(rs_username, tasklists.list_for_tier('medium'), 'import-recorded')
574574
hard_import_result = import_logs(rs_username, tasklists.list_for_tier('hard'), 'import-recorded')
575575
elite_import_result = import_logs(rs_username, tasklists.list_for_tier('elite'), 'import-recorded')
576+
master_import_result = import_logs(rs_username, tasklists.list_for_tier('master'), 'import-recorded')
577+
pets_import_result = import_logs(rs_username, tasklists.list_for_tier('pets'), 'import-recorded')
576578
easy_import = easy_import_result.get('completedTasks', [])
577579
medium_import = medium_import_result.get('completedTasks', [])
578580
hard_import = hard_import_result.get('completedTasks', [])
579581
elite_import = elite_import_result.get('completedTasks', [])
580-
all_tasks = [easy_import, medium_import, hard_import, elite_import]
582+
master_import = master_import_result.get('completedTasks', [])
583+
pets_import = pets_import_result.get('completedTasks', [])
584+
all_tasks = [easy_import, medium_import, hard_import, elite_import, master_import, pets_import]
581585
recorded_item_ids_by_tier = {
582586
'easy': easy_import_result.get('recordedItemIdsByTask', {}),
583587
'medium': medium_import_result.get('recordedItemIdsByTask', {}),
584588
'hard': hard_import_result.get('recordedItemIdsByTask', {}),
585589
'elite': elite_import_result.get('recordedItemIdsByTask', {}),
590+
'master': master_import_result.get('recordedItemIdsByTask', {}),
591+
'pets': pets_import_result.get('recordedItemIdsByTask', {}),
586592
}
587593
update = update_imported_tasks(
588594
session['username'],
@@ -597,7 +603,9 @@ def collection_log_import():
597603
easy = len(easy_import),
598604
medium = len(medium_import),
599605
hard = len(hard_import),
600-
elite = len(elite_import))
606+
elite = len(elite_import),
607+
master = len(master_import),
608+
pets = len(pets_import))
601609

602610
# AJAX route for generating a task.
603611
@app.route('/generate/', methods=['POST'])

0 commit comments

Comments
 (0)