#!/usr/bin/env python3 """ Standardize Tasker XML project file v2 - Consistent naming conventions - Link notification buttons to correct tasks via AutoNotification commands - Add missing event profiles for button commands - Remove trailing spaces and inconsistencies """ import re def standardize_tasker_xml(input_file, output_file): with open(input_file, 'r', encoding='utf-8') as f: content = f.read() # Standardize Profile names profile_replacements = { 'Launch Skincare Notification': 'Trigger Skincare Notification', 'Launch Prepare For Exercise Notification': 'Trigger Exercise Notification', 'Open Skincare Notification': 'Show Skincare Notification', 'Open Prepare Exercise Notification': 'Show Exercise Notification', 'Dismiss Exercise Notification': 'Mark Exercise Done', } for old, new in profile_replacements.items(): content = content.replace(f'{old}', f'{new}') # Standardize command names (used in AutoNotification event filters and button actions) command_replacements = { 'Open morning skincare': 'cmd_open_skincare_note', 'open skincare note': 'cmd_open_skincare_note', 'mark skincare done': 'cmd_mark_skincare_done', 'open exercise note': 'cmd_open_exercise_note', 'mark exercise done': 'cmd_mark_exercise_done', 'open diet note': 'cmd_open_diet_note', } for old, new in command_replacements.items(): # Remove trailing spaces from old commands old_variants = [old, old + ' ', old + ' '] for variant in old_variants: # Replace in command filters content = content.replace( f'{variant}', f'{new}' ) # Replace in button actions content = content.replace( f'{variant}', f'{new}' ) content = content.replace( f'{variant}', f'{new}' ) content = content.replace( f'{variant}', f'{new}' ) # Standardize notification IDs notif_id_replacements = { 'skincare morning': 'notif_skincare_morning', 'skincare morning ': 'notif_skincare_morning', 'prepare for exercise': 'notif_exercise_prep', } for old, new in notif_id_replacements.items(): content = content.replace( f'{old}', f'{new}' ) # Also update in BLURB text content = re.sub( f'Id: {re.escape(old)}([\\n<])', f'Id: {new}\\1', content ) # Standardize notification titles and texts (remove trailing spaces) content = re.sub( r'([^<]+?) +', r'\1', content ) content = re.sub( r'([^<]+?) +', r'\1', content ) # Update project name content = content.replace( 'Skincare Demo', 'Routine Reminders' ) # Fix BLURB descriptions to reflect standardized commands content = re.sub( r'Filter: mark skincare done[ ]*', 'Filter: cmd_mark_skincare_done', content ) content = re.sub( r'Filter: mark exercise done[ ]*', 'Filter: cmd_mark_exercise_done', content ) content = re.sub( r'Button 1: open skincare note', 'Button 1: cmd_open_skincare_note', content ) content = re.sub( r'Button 2: mark skincare done', 'Button 2: cmd_mark_skincare_done', content ) content = re.sub( r'Button 1: open exercise note', 'Button 1: cmd_open_exercise_note', content ) content = re.sub( r'Button 2: mark exercise done', 'Button 2: cmd_mark_exercise_done', content ) content = re.sub( r'Button 1: open diet note', 'Button 1: cmd_open_diet_note', content ) content = re.sub( r'Action on Touch: Open morning skincare[ ]*', 'Action on Touch: cmd_open_skincare_note', content ) # Add missing event profiles for "open note" commands # Find where to insert (before ) insert_point = content.rfind('') # Check if profiles already exist missing_profiles = [] if 'Event: Open Skincare Note' not in content: missing_profiles.append(''' 1762862939813 1762935050872 8 150 82 Event: Open Skincare Note 1825107102 0 Event Behaviour Filter: cmd_open_skincare_note java.lang.String anpar java.lang.String ancomm java.lang.String cmd_open_skincare_note java.lang.String false java.lang.Boolean false java.lang.Boolean false java.lang.Boolean anmessage java.lang.String true java.lang.Boolean <StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%ancomm Everything to the right of =:= Everything to the right of =:=</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%anmessage Whole AutoNotification Message Whole AutoNotification Message</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2>%anpar() Array of single words to the left of =:= Array of single words to the left of =:=</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2></StringArray> [Ljava.lang.String; 10000 java.lang.Integer message_var command_var command_params_var config_notification_command plugininstanceid plugintypeid java.lang.String true java.lang.Boolean e1a87f0a-2e17-4b02-ab14-479198b7aea9 java.lang.String com.joaomgcd.autonotification.intent.IntentCommandEvent java.lang.String com.joaomgcd.autonotification com.joaomgcd.autonotification.activity.ActivityConfigConditionTaskerEvent ''') if 'Event: Open Exercise Note' not in content: missing_profiles.append(''' 1762862939813 1762935050872 8 151 141 Event: Open Exercise Note 1825107102 0 Event Behaviour Filter: cmd_open_exercise_note java.lang.String anpar java.lang.String ancomm java.lang.String cmd_open_exercise_note java.lang.String false java.lang.Boolean false java.lang.Boolean false java.lang.Boolean anmessage java.lang.String true java.lang.Boolean <StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%ancomm Everything to the right of =:= Everything to the right of =:=</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%anmessage Whole AutoNotification Message Whole AutoNotification Message</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2>%anpar() Array of single words to the left of =:= Array of single words to the left of =:=</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2></StringArray> [Ljava.lang.String; 10000 java.lang.Integer message_var command_var command_params_var config_notification_command plugininstanceid plugintypeid java.lang.String true java.lang.Boolean e1a87f0a-2e17-4b02-ab14-479198b7aea0 java.lang.String com.joaomgcd.autonotification.intent.IntentCommandEvent java.lang.String com.joaomgcd.autonotification com.joaomgcd.autonotification.activity.ActivityConfigConditionTaskerEvent ''') # Insert missing profiles if missing_profiles: profiles_text = ''.join(missing_profiles) content = content[:insert_point] + profiles_text + '\n' + content[insert_point:] # Update project profile IDs (pids) to include new profiles if 'prof150' in profiles_text: content = re.sub( r'([^<]+)', lambda m: f'{m.group(1)},150', content, count=1 ) if 'prof151' in profiles_text: content = re.sub( r'([^<]+)', lambda m: f'{m.group(1)},151', content, count=1 ) # Write output with open(output_file, 'w', encoding='utf-8') as f: f.write(content) print(f"✓ Standardized {input_file}") if missing_profiles: print(f"✓ Added {len(missing_profiles)} missing event profile(s) to link buttons to actions") print(f"✓ Output written to {output_file}") print("\nStandardization complete!") print("- All command names use 'cmd_' prefix") print("- All notification IDs use 'notif_' prefix") print("- Profile/task names are consistent") print("- Button actions are linked to event profiles") if __name__ == '__main__': input_file = '/Users/vincentverbruggen/Personal/Personal/Areas/Tasker/Skincare_Demo_Standardized.prj.xml' output_file = '/Users/vincentverbruggen/Personal/Personal/Areas/Tasker/Routine_Reminders.prj.xml' standardize_tasker_xml(input_file, output_file)