import os import re import time import subprocess import xml.etree.ElementTree as ET # Configuration OUTPUT_TXT = "live_blocked_numbers.txt" OUTPUT_VCF = "live_spam_block.vcf" # Adjust based on how long your list is (e.g., 100 screens deep) MAX_SCROLL_ATTEMPTS = 100 ADB_PATH = "adb" # Update with your absolute platform-tools path if needed def run_adb(command): if command.startswith("adb "): command = command.replace("adb ", f'"{ADB_PATH}" ', 1) process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _ = process.communicate() return stdout.decode('utf-8', errors='ignore') def extract_numbers_from_xml(xml_path): numbers = set() if not os.path.exists(xml_path): return numbers try: tree = ET.parse(xml_path) root = tree.getroot() num_pattern = re.compile(r'\+?[\d\s\-\(\)]{5,20}') for elem in root.iter(): text = elem.get('text', '') if text and num_pattern.match(text.strip()): cleaned = text.strip() if cleaned: numbers.add(cleaned) except Exception: pass return numbers def main(): print("Starting LIVE streaming extraction... Press Ctrl+C at any time to safely exit.") # Track duplicates in memory to avoid writing the same number twice seen_numbers = set() # Initialize the VCF file with standard headers with open(OUTPUT_VCF, "w", encoding="utf-8", newline='\r\n') as vcf: vcf.write("BEGIN:VCARD\n") vcf.write("VERSION:3.0\n") vcf.write("FN:Spam Block\n") vcf.write("N:Block;Spam;;;\n") # Clear out any old text logs from previous runs if os.path.exists(OUTPUT_TXT): os.remove(OUTPUT_TXT) try: for i in range(MAX_SCROLL_ATTEMPTS): # 1. Dump and pull the screen layout run_adb("adb shell uiautomator dump /sdcard/window_dump.xml") run_adb("adb pull /sdcard/window_dump.xml local_dump.xml") # 2. Extract numbers visible right now current_screen_numbers = extract_numbers_from_xml("local_dump.xml") # 3. Stream NEW numbers instantly to files new_additions = 0 with open(OUTPUT_TXT, "a", encoding="utf-8") as txt_file, \ open(OUTPUT_VCF, "a", encoding="utf-8", newline='\r\n') as vcf_file: for number in current_screen_numbers: if number not in seen_numbers: seen_numbers.add(number) new_additions += 1 # Append immediately to files txt_file.write(f"{number}\n") vcf_file.write(f"TEL;TYPE=CELL:{number}\n") print(f"Screen {i+1}: Found {len(current_screen_numbers)} numbers ({new_additions} new). Total saved: {len(seen_numbers)}") # 4. Swipe down run_adb("adb shell input swipe 500 1500 500 500 400") time.sleep(1.2) except KeyboardInterrupt: print("\n[!] Execution interrupted by user. Finalizing files safely...") finally: # 5. Clean up local files and cap the VCF file layout properly if os.path.exists("local_dump.xml"): os.remove("local_dump.xml") with open(OUTPUT_VCF, "a", encoding="utf-8", newline='\r\n') as vcf_file: vcf_file.write("END:VCARD\n") print(f"\nDone! Streams finalized.") print(f"-> TXT File: {os.path.abspath(OUTPUT_TXT)}") print(f"-> VCF File: {os.path.abspath(OUTPUT_VCF)}") if __name__ == "__main__": main()