#!/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)