Initial commit, 90% there
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Remove duplicate/old stop modal HTML from inside scrap modal
|
||||
|
||||
The first fix moved the stop modal but left an old fragment inside scrap modal.
|
||||
This script removes that old fragment.
|
||||
|
||||
Author: Claude Code
|
||||
Date: 2025-11-23
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
def find_old_stop_fragment(content, scrap_start, scrap_end):
|
||||
"""Find the old stop modal fragment inside scrap modal."""
|
||||
|
||||
# Look for the comment that marks the old stop modal
|
||||
pattern = r'<!-- Stop Reason Modal -->'
|
||||
match = re.search(pattern, content[scrap_start:scrap_end])
|
||||
|
||||
if match:
|
||||
# Position relative to whole content
|
||||
fragment_start = scrap_start + match.start()
|
||||
print(f" Found '<!-- Stop Reason Modal -->' comment at position {fragment_start}")
|
||||
|
||||
# Find where this fragment ends - look for the end of the modal structure
|
||||
# The fragment appears to be missing opening <div> tags, so find where it connects back to scrap modal
|
||||
|
||||
# Strategy: Find the next "</div>" that closes the scrap modal after this fragment
|
||||
# We need to find where the fragment HTML ends
|
||||
|
||||
# Look for the submit button that's part of the old fragment
|
||||
search_area = content[fragment_start:scrap_end]
|
||||
submit_pattern = r'<button[^>]*id="submitStopReason"[^>]*>.*?</button>'
|
||||
submit_match = re.search(submit_pattern, search_area, re.DOTALL)
|
||||
|
||||
if submit_match:
|
||||
fragment_end = fragment_start + submit_match.end()
|
||||
|
||||
# Extend to include the closing divs that belong to this fragment
|
||||
# Look for the pattern: </div>\n </div>\n </div>
|
||||
search_after = content[fragment_end:fragment_end+500]
|
||||
closing_pattern = r'(\s*</div>\s*</div>\s*</div>)'
|
||||
closing_match = re.search(closing_pattern, search_after)
|
||||
|
||||
if closing_match:
|
||||
fragment_end = fragment_end + closing_match.end()
|
||||
|
||||
print(f" Fragment ends at position {fragment_end}")
|
||||
print(f" Fragment size: {fragment_end - fragment_start} characters")
|
||||
|
||||
return fragment_start, fragment_end
|
||||
|
||||
return None, None
|
||||
|
||||
def remove_old_stop_modal(flows_data):
|
||||
"""Remove the old stop modal fragment from inside scrap modal."""
|
||||
|
||||
# Find the Home Template node
|
||||
home_node = None
|
||||
home_index = None
|
||||
|
||||
for idx, node in enumerate(flows_data):
|
||||
if node.get('id') == '1821c4842945ecd8':
|
||||
home_node = node
|
||||
home_index = idx
|
||||
break
|
||||
|
||||
if not home_node:
|
||||
print("❌ ERROR: Home Template node not found!")
|
||||
return False
|
||||
|
||||
print(f"✅ Found Home Template node at index {home_index}")
|
||||
|
||||
format_content = home_node.get('format', '')
|
||||
original_length = len(format_content)
|
||||
|
||||
print(f"📏 Original format length: {original_length:,} characters")
|
||||
|
||||
# Find scrap modal boundaries
|
||||
scrap_start = format_content.find('<div id="scrap-modal"')
|
||||
if scrap_start == -1:
|
||||
print("❌ ERROR: Could not find scrap modal")
|
||||
return False
|
||||
|
||||
# Count divs to find scrap modal end
|
||||
pos = scrap_start
|
||||
div_count = 0
|
||||
scrap_end = None
|
||||
|
||||
while pos < len(format_content):
|
||||
if format_content[pos:pos+4] == '<div':
|
||||
div_count += 1
|
||||
elif format_content[pos:pos+6] == '</div>':
|
||||
div_count -= 1
|
||||
if div_count == 0:
|
||||
scrap_end = pos + 6
|
||||
break
|
||||
pos += 1
|
||||
|
||||
if not scrap_end:
|
||||
print("❌ ERROR: Could not find scrap modal end")
|
||||
return False
|
||||
|
||||
print(f"\n🔍 Scrap modal boundaries:")
|
||||
print(f" Start: {scrap_start}")
|
||||
print(f" End: {scrap_end}")
|
||||
|
||||
# Find the old stop modal fragment
|
||||
print("\n🔧 Searching for old stop modal fragment inside scrap modal...")
|
||||
|
||||
fragment_start, fragment_end = find_old_stop_fragment(format_content, scrap_start, scrap_end)
|
||||
|
||||
if fragment_start is None:
|
||||
print("⚠️ Could not find old stop modal fragment with standard method")
|
||||
print(" Trying alternative search...")
|
||||
|
||||
# Alternative: search for "Why are you stopping production?"
|
||||
search_text = "Why are you stopping production?"
|
||||
alt_pos = format_content.find(search_text, scrap_start, scrap_end)
|
||||
|
||||
if alt_pos > 0:
|
||||
print(f" Found '{search_text}' at position {alt_pos}")
|
||||
|
||||
# Backtrack to find the start (likely the comment or a div)
|
||||
fragment_start = format_content.rfind('<!-- Stop Reason Modal -->', scrap_start, alt_pos)
|
||||
if fragment_start == -1:
|
||||
# Try to find a reasonable start point
|
||||
fragment_start = format_content.rfind('</button>', scrap_start, alt_pos) + 10
|
||||
# Skip whitespace
|
||||
while fragment_start < alt_pos and format_content[fragment_start].isspace():
|
||||
fragment_start += 1
|
||||
|
||||
# Find the end - look for the submit button
|
||||
submit_pos = format_content.find('id="submitStopReason"', alt_pos, scrap_end)
|
||||
if submit_pos > 0:
|
||||
# Find the closing </button> after this
|
||||
button_close = format_content.find('</button>', submit_pos, scrap_end)
|
||||
if button_close > 0:
|
||||
fragment_end = button_close + 9
|
||||
|
||||
# Look for closing divs
|
||||
temp_end = fragment_end
|
||||
while temp_end < scrap_end and format_content[temp_end:temp_end+6] == '</div>':
|
||||
fragment_end = temp_end + 6
|
||||
temp_end = fragment_end
|
||||
# Skip whitespace
|
||||
while temp_end < scrap_end and format_content[temp_end] in ' \n\t':
|
||||
temp_end += 1
|
||||
|
||||
if fragment_start is None or fragment_end is None:
|
||||
print("❌ ERROR: Could not locate old stop modal fragment")
|
||||
return False
|
||||
|
||||
print(f"\n✅ Found old stop modal fragment:")
|
||||
print(f" Start: {fragment_start}")
|
||||
print(f" End: {fragment_end}")
|
||||
print(f" Size: {fragment_end - fragment_start} characters")
|
||||
|
||||
# Show a preview
|
||||
print(f"\n📄 Preview of content to remove:")
|
||||
preview = format_content[fragment_start:fragment_start+200]
|
||||
print(f" {preview}...")
|
||||
|
||||
# Remove the fragment
|
||||
print(f"\n🗑️ Removing old stop modal fragment...")
|
||||
format_content_fixed = format_content[:fragment_start] + format_content[fragment_end:]
|
||||
|
||||
print(f" ✅ Removed {fragment_end - fragment_start} characters")
|
||||
print(f" 📏 New format length: {len(format_content_fixed):,} characters")
|
||||
|
||||
# Update the node
|
||||
flows_data[home_index]['format'] = format_content_fixed
|
||||
|
||||
print(f"\n📊 SUMMARY:")
|
||||
print(f" Original: {original_length:,} characters")
|
||||
print(f" Final: {len(format_content_fixed):,} characters")
|
||||
print(f" Removed: {original_length - len(format_content_fixed):,} characters")
|
||||
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""Main execution function."""
|
||||
|
||||
flows_path = '/home/mdares/.node-red/flows.json'
|
||||
|
||||
print("=" * 70)
|
||||
print("Remove Duplicate Stop Modal Fragment")
|
||||
print("=" * 70)
|
||||
|
||||
# Load flows.json
|
||||
print(f"\n📂 Loading {flows_path}...")
|
||||
try:
|
||||
with open(flows_path, 'r') as f:
|
||||
flows_data = json.load(f)
|
||||
print(f" ✅ Loaded {len(flows_data)} nodes")
|
||||
except Exception as e:
|
||||
print(f" ❌ ERROR: {e}")
|
||||
return 1
|
||||
|
||||
# Apply fix
|
||||
if not remove_old_stop_modal(flows_data):
|
||||
print("\n❌ FAILED to remove old stop modal")
|
||||
return 1
|
||||
|
||||
# Validate JSON
|
||||
print("\n🔍 Validating JSON structure...")
|
||||
try:
|
||||
json_output = json.dumps(flows_data, indent=2)
|
||||
print(" ✅ JSON structure is valid")
|
||||
except Exception as e:
|
||||
print(f" ❌ ERROR: Invalid JSON structure: {e}")
|
||||
return 1
|
||||
|
||||
# Write back to file
|
||||
print(f"\n💾 Writing fixed flows to {flows_path}...")
|
||||
try:
|
||||
with open(flows_path, 'w') as f:
|
||||
f.write(json_output)
|
||||
print(" ✅ Successfully wrote flows.json")
|
||||
except Exception as e:
|
||||
print(f" ❌ ERROR: {e}")
|
||||
return 1
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("✅ OLD STOP MODAL FRAGMENT REMOVED!")
|
||||
print("=" * 70)
|
||||
print("\n📋 Next steps:")
|
||||
print(" 1. Restart Node-RED")
|
||||
print(" 2. Test scrap prompt - should NOT show stop prompt inside")
|
||||
print(" 3. Test stop prompt - should work independently")
|
||||
print(" 4. Verify you can submit scrap entries")
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user