import sys import re def replace_func_in_content(content, func_name, new_func_content): # Match from optional decorators up to the start of the next top-level definition or end of file # We use re.MULTILINE so ^ matches start of line # We use re.DOTALL so . matches newline # We use a non-greedy match for the body but stop before another top-level def/class/@ # This regex finds the function including its decorators # and everything until the next function/class starts at the beginning of a line pattern = re.compile( r'(^(@.*? )*def ' + func_name + r'\(.*\):.*?)(\n+(?=@|def |class )|\Z)', re.MULTILINE | re.DOTALL ) if pattern.search(content): return pattern.sub(new_func_content.strip() + '\n\n', content) else: # Fallback if there's something slightly different (e.g. no decorators but regex expected them) pattern = re.compile( r'(^def ' + func_name + r'\(.*\):.*?)(\n+(?=@|def |class )|\Z)', re.MULTILINE | re.DOTALL ) if pattern.search(content): return pattern.sub(new_func_content.strip() + '\n\n', content) else: print(f"Warning: Could not find function {func_name}") return content file_path = 'core/views.py' with open(file_path, 'r') as f: content = f.read() # Add helper before voter_advanced_search if not exists with open('core/filter_helper.py', 'r') as f: helper = f.read().strip() if 'def get_filtered_voter_queryset' not in content: content = content.replace('def voter_advanced_search', helper + '\n\n' + 'def voter_advanced_search') with open('core/views_new.py', 'r') as f: voter_advanced_search_new = f.read().strip() with open('core/bulk_sms_new.py', 'r') as f: bulk_send_sms_new = f.read().strip() with open('core/bulk_email_new.py', 'r') as f: voter_bulk_send_email_new = f.read().strip() with open('core/export_new.py', 'r') as f: export_voters_csv_new = f.read().strip() content = replace_func_in_content(content, 'voter_advanced_search', voter_advanced_search_new) content = replace_func_in_content(content, 'bulk_send_sms', bulk_send_sms_new) content = replace_func_in_content(content, 'voter_bulk_send_email', voter_bulk_send_email_new) content = replace_func_in_content(content, 'export_voters_csv', export_voters_csv_new) with open(file_path, 'w') as f: f.write(content)