vault backup: 2025-11-22 08:14:07
This commit is contained in:
303
Personal/Areas/Tasker/standardize_tasker_v2.py
Normal file
303
Personal/Areas/Tasker/standardize_tasker_v2.py
Normal file
@@ -0,0 +1,303 @@
|
||||
#!/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'<nme>{old}</nme>', f'<nme>{new}</nme>')
|
||||
|
||||
# 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'<config_notification_command>{variant}</config_notification_command>',
|
||||
f'<config_notification_command>{new}</config_notification_command>'
|
||||
)
|
||||
# Replace in button actions
|
||||
content = content.replace(
|
||||
f'<config_notification_action_button1>{variant}</config_notification_action_button1>',
|
||||
f'<config_notification_action_button1>{new}</config_notification_action_button1>'
|
||||
)
|
||||
content = content.replace(
|
||||
f'<config_notification_action_button2>{variant}</config_notification_action_button2>',
|
||||
f'<config_notification_action_button2>{new}</config_notification_action_button2>'
|
||||
)
|
||||
content = content.replace(
|
||||
f'<config_notification_action>{variant}</config_notification_action>',
|
||||
f'<config_notification_action>{new}</config_notification_action>'
|
||||
)
|
||||
|
||||
# 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'<notificaitionid>{old}</notificaitionid>',
|
||||
f'<notificaitionid>{new}</notificaitionid>'
|
||||
)
|
||||
# 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'<config_notification_title>([^<]+?) +</config_notification_title>',
|
||||
r'<config_notification_title>\1</config_notification_title>',
|
||||
content
|
||||
)
|
||||
content = re.sub(
|
||||
r'<config_notification_text>([^<]+?) +</config_notification_text>',
|
||||
r'<config_notification_text>\1</config_notification_text>',
|
||||
content
|
||||
)
|
||||
|
||||
# Update project name
|
||||
content = content.replace(
|
||||
'<name>Skincare Demo</name>',
|
||||
'<name>Routine Reminders</name>'
|
||||
)
|
||||
|
||||
# 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 </TaskerData>)
|
||||
insert_point = content.rfind('</TaskerData>')
|
||||
|
||||
# Check if profiles already exist
|
||||
missing_profiles = []
|
||||
if 'Event: Open Skincare Note' not in content:
|
||||
missing_profiles.append('''
|
||||
<Profile sr="prof150" ve="2">
|
||||
<cdate>1762862939813</cdate>
|
||||
<edate>1762935050872</edate>
|
||||
<flags>8</flags>
|
||||
<id>150</id>
|
||||
<mid0>82</mid0>
|
||||
<nme>Event: Open Skincare Note</nme>
|
||||
<Event sr="con0" ve="2">
|
||||
<code>1825107102</code>
|
||||
<pri>0</pri>
|
||||
<Bundle sr="arg0">
|
||||
<Vals sr="val">
|
||||
<com.twofortyfouram.locale.intent.extra.BLURB>Event Behaviour
|
||||
Filter: cmd_open_skincare_note</com.twofortyfouram.locale.intent.extra.BLURB>
|
||||
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
|
||||
<command_params_var>anpar</command_params_var>
|
||||
<command_params_var-type>java.lang.String</command_params_var-type>
|
||||
<command_var>ancomm</command_var>
|
||||
<command_var-type>java.lang.String</command_var-type>
|
||||
<config_notification_command>cmd_open_skincare_note</config_notification_command>
|
||||
<config_notification_command-type>java.lang.String</config_notification_command-type>
|
||||
<message_single_case_insensitive>false</message_single_case_insensitive>
|
||||
<message_single_case_insensitive-type>java.lang.Boolean</message_single_case_insensitive-type>
|
||||
<message_single_exact>false</message_single_exact>
|
||||
<message_single_exact-type>java.lang.Boolean</message_single_exact-type>
|
||||
<message_single_regex>false</message_single_regex>
|
||||
<message_single_regex-type>java.lang.Boolean</message_single_regex-type>
|
||||
<message_var>anmessage</message_var>
|
||||
<message_var-type>java.lang.String</message_var-type>
|
||||
<net.dinglisch.android.tasker.EXTRA_NSR_DEPRECATED>true</net.dinglisch.android.tasker.EXTRA_NSR_DEPRECATED>
|
||||
<net.dinglisch.android.tasker.EXTRA_NSR_DEPRECATED-type>java.lang.Boolean</net.dinglisch.android.tasker.EXTRA_NSR_DEPRECATED-type>
|
||||
<net.dinglisch.android.tasker.RELEVANT_VARIABLES><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></net.dinglisch.android.tasker.RELEVANT_VARIABLES>
|
||||
<net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
|
||||
<net.dinglisch.android.tasker.extras.REQUESTED_TIMEOUT>10000</net.dinglisch.android.tasker.extras.REQUESTED_TIMEOUT>
|
||||
<net.dinglisch.android.tasker.extras.REQUESTED_TIMEOUT-type>java.lang.Integer</net.dinglisch.android.tasker.extras.REQUESTED_TIMEOUT-type>
|
||||
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>message_var command_var command_params_var config_notification_command plugininstanceid plugintypeid </net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
|
||||
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
|
||||
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
|
||||
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
|
||||
<plugininstanceid>e1a87f0a-2e17-4b02-ab14-479198b7aea9</plugininstanceid>
|
||||
<plugininstanceid-type>java.lang.String</plugininstanceid-type>
|
||||
<plugintypeid>com.joaomgcd.autonotification.intent.IntentCommandEvent</plugintypeid>
|
||||
<plugintypeid-type>java.lang.String</plugintypeid-type>
|
||||
</Vals>
|
||||
</Bundle>
|
||||
<Str sr="arg1" ve="3">com.joaomgcd.autonotification</Str>
|
||||
<Str sr="arg2" ve="3">com.joaomgcd.autonotification.activity.ActivityConfigConditionTaskerEvent</Str>
|
||||
<Int sr="arg3" val="1"/>
|
||||
</Event>
|
||||
</Profile>''')
|
||||
|
||||
if 'Event: Open Exercise Note' not in content:
|
||||
missing_profiles.append('''
|
||||
<Profile sr="prof151" ve="2">
|
||||
<cdate>1762862939813</cdate>
|
||||
<edate>1762935050872</edate>
|
||||
<flags>8</flags>
|
||||
<id>151</id>
|
||||
<mid0>141</mid0>
|
||||
<nme>Event: Open Exercise Note</nme>
|
||||
<Event sr="con0" ve="2">
|
||||
<code>1825107102</code>
|
||||
<pri>0</pri>
|
||||
<Bundle sr="arg0">
|
||||
<Vals sr="val">
|
||||
<com.twofortyfouram.locale.intent.extra.BLURB>Event Behaviour
|
||||
Filter: cmd_open_exercise_note</com.twofortyfouram.locale.intent.extra.BLURB>
|
||||
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
|
||||
<command_params_var>anpar</command_params_var>
|
||||
<command_params_var-type>java.lang.String</command_params_var-type>
|
||||
<command_var>ancomm</command_var>
|
||||
<command_var-type>java.lang.String</command_var-type>
|
||||
<config_notification_command>cmd_open_exercise_note</config_notification_command>
|
||||
<config_notification_command-type>java.lang.String</config_notification_command-type>
|
||||
<message_single_case_insensitive>false</message_single_case_insensitive>
|
||||
<message_single_case_insensitive-type>java.lang.Boolean</message_single_case_insensitive-type>
|
||||
<message_single_exact>false</message_single_exact>
|
||||
<message_single_exact-type>java.lang.Boolean</message_single_exact-type>
|
||||
<message_single_regex>false</message_single_regex>
|
||||
<message_single_regex-type>java.lang.Boolean</message_single_regex-type>
|
||||
<message_var>anmessage</message_var>
|
||||
<message_var-type>java.lang.String</message_var-type>
|
||||
<net.dinglisch.android.tasker.EXTRA_NSR_DEPRECATED>true</net.dinglisch.android.tasker.EXTRA_NSR_DEPRECATED>
|
||||
<net.dinglisch.android.tasker.EXTRA_NSR_DEPRECATED-type>java.lang.Boolean</net.dinglisch.android.tasker.EXTRA_NSR_DEPRECATED-type>
|
||||
<net.dinglisch.android.tasker.RELEVANT_VARIABLES><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></net.dinglisch.android.tasker.RELEVANT_VARIABLES>
|
||||
<net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
|
||||
<net.dinglisch.android.tasker.extras.REQUESTED_TIMEOUT>10000</net.dinglisch.android.tasker.extras.REQUESTED_TIMEOUT>
|
||||
<net.dinglisch.android.tasker.extras.REQUESTED_TIMEOUT-type>java.lang.Integer</net.dinglisch.android.tasker.extras.REQUESTED_TIMEOUT-type>
|
||||
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>message_var command_var command_params_var config_notification_command plugininstanceid plugintypeid </net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
|
||||
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
|
||||
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
|
||||
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
|
||||
<plugininstanceid>e1a87f0a-2e17-4b02-ab14-479198b7aea0</plugininstanceid>
|
||||
<plugininstanceid-type>java.lang.String</plugininstanceid-type>
|
||||
<plugintypeid>com.joaomgcd.autonotification.intent.IntentCommandEvent</plugintypeid>
|
||||
<plugintypeid-type>java.lang.String</plugintypeid-type>
|
||||
</Vals>
|
||||
</Bundle>
|
||||
<Str sr="arg1" ve="3">com.joaomgcd.autonotification</Str>
|
||||
<Str sr="arg2" ve="3">com.joaomgcd.autonotification.activity.ActivityConfigConditionTaskerEvent</Str>
|
||||
<Int sr="arg3" val="1"/>
|
||||
</Event>
|
||||
</Profile>''')
|
||||
|
||||
# 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'<pids>([^<]+)</pids>',
|
||||
lambda m: f'<pids>{m.group(1)},150</pids>',
|
||||
content,
|
||||
count=1
|
||||
)
|
||||
if 'prof151' in profiles_text:
|
||||
content = re.sub(
|
||||
r'<pids>([^<]+)</pids>',
|
||||
lambda m: f'<pids>{m.group(1)},151</pids>',
|
||||
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)
|
||||
Reference in New Issue
Block a user