import streamlit as st import os import configparser import glob import shutil from datetime import datetime from pathlib import Path import re from utils import parse_winapp2_ini, scan_files, delete_files, get_file_size, format_size st.set_page_config( page_title="Windows Data Cleaner", page_icon="๐Ÿงน", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for better UI st.markdown(""" """, unsafe_allow_html=True) # Header with anycoder link st.markdown('
๐Ÿงน Windows Data Cleaner
', unsafe_allow_html=True) st.markdown('[Built with anycoder](https://huggingface.co/spaces/akhaliq/anycoder)', unsafe_allow_html=True) st.markdown("---") # Initialize session state if 'cleaning_results' not in st.session_state: st.session_state.cleaning_results = None if 'scanned_files' not in st.session_state: st.session_state.scanned_files = [] if 'ini_config' not in st.session_state: st.session_state.ini_config = None if 'scan_complete' not in st.session_state: st.session_state.scan_complete = False # Sidebar configuration with st.sidebar: st.header("โš™๏ธ Configuration") # INI File Upload st.subheader("WinApp2.ini File") ini_file = st.file_uploader( "Upload winapp2.ini", type=["ini", "txt"], help="Upload the winapp2.ini configuration file" ) # Base directory for cleaning st.subheader("Base Directory") base_dir = st.text_input( "Base Directory Path", value=os.getenv('USERPROFILE', 'C:/Users') or 'C:/Users', help="Root directory to scan for files" ) # Cleaning options st.subheader("Cleaning Options") dry_run = st.checkbox("Dry Run Mode", value=True, help="Preview files without deleting") confirm_delete = st.checkbox("Require Confirmation", value=True, help="Ask before deleting files") # Advanced options with st.expander("Advanced Options"): include_hidden = st.checkbox("Include Hidden Files", value=False) include_system = st.checkbox("Include System Files", value=False, help="Warning: May affect system stability") max_file_age_days = st.number_input("Max File Age (days)", min_value=0, value=365, help="Only clean files older than this") # Main content area st.header("๐Ÿ“‹ Configuration File") if ini_file: try: # Parse the INI file with st.spinner("Parsing winapp2.ini..."): config_content = ini_file.getvalue().decode('utf-8') st.session_state.ini_config = parse_winapp2_ini(config_content) if st.session_state.ini_config: st.success("โœ… Configuration file loaded successfully!") # Display configuration sections st.subheader("Available Cleaning Sections") for section_name, section_data in st.session_state.ini_config.items(): with st.expander(f"๐Ÿ“ {section_name}", expanded=False): st.code(f"Description: {section_data.get('description', 'No description')}") st.code(f"Warning: {section_data.get('warning', 'No warnings')}") if 'path' in section_data: st.code(f"Paths: {section_data['path']}") if 'file' in section_data: st.code(f"File Patterns: {section_data['file']}") if 'regex' in section_data: st.code(f"Regex Patterns: {section_data['regex']}") except Exception as e: st.error(f"โŒ Error parsing INI file: {str(e)}") else: st.info("๐Ÿ“„ Please upload a winapp2.ini configuration file to continue.") st.code(""" # Example winapp2.ini structure [SectionName] Description=Description of what this cleans Warning=Warning message path=C:\\Users\\*\\AppData\\Local\\Temp file=*.tmp; *.log regex=pattern_to_match """) # Scan and Preview Section st.header("๐Ÿ” Scan & Preview") if st.session_state.ini_config and base_dir: if st.button("๐Ÿ”Ž Scan for Files", type="primary", disabled=not st.session_state.ini_config): with st.spinner("Scanning directories..."): try: scanned_files = scan_files( st.session_state.ini_config, base_dir, include_hidden=include_hidden, include_system=include_system, max_age_days=max_file_age_days ) st.session_state.scanned_files = scanned_files st.session_state.scan_complete = True # Calculate totals total_files = len(scanned_files) total_size = sum(f['size'] for f in scanned_files) st.session_state.scan_summary = { 'total_files': total_files, 'total_size': total_size, 'sections': len(st.session_state.ini_config) } st.success(f"โœ… Scan complete! Found {total_files} files ({format_size(total_size)})") except Exception as e: st.error(f"โŒ Error during scan: {str(e)}") st.session_state.scan_complete = False # Display scan results if st.session_state.scan_complete and st.session_state.scanned_files: st.subheader("๐Ÿ“Š Scan Results") # Summary statistics col1, col2, col3 = st.columns(3) with col1: st.metric( label="Total Files", value=st.session_state.scan_summary['total_files'] ) with col2: st.metric( label="Total Size", value=format_size(st.session_state.scan_summary['total_size']) ) with col3: st.metric( label="Sections", value=st.session_state.scan_summary['sections'] ) # File list with selection st.subheader("๐Ÿ“ Files to Clean") # Create a table of files if st.session_state.scanned_files: # Display first 100 files in table display_files = st.session_state.scanned_files[:100] file_data = { 'Section': [f['section'] for f in display_files], 'Path': [f['path'] for f in display_files], 'Size': [format_size(f['size']) for f in display_files], 'Age (days)': [f['age_days'] for f in display_files] } st.table(file_data) if len(st.session_state.scanned_files) > 100: st.info(f"Showing first 100 of {len(st.session_state.scanned_files)} files") # Download full list if len(st.session_state.scanned_files) > 0: import json file_list_json = json.dumps(st.session_state.scanned_files, indent=2) st.download_button( label="๐Ÿ“ฅ Download Full File List", data=file_list_json, file_name="scan_results.json", mime="application/json" ) # Cleaning Execution Section st.header("๐Ÿงน Execute Cleaning") if st.session_state.scan_complete and st.session_state.scanned_files: warning_msg = """
โš ๏ธ WARNING: This operation will delete files from your system. Please review the file list carefully before proceeding. Make sure you have backups of important data.
""" st.markdown(warning_msg, unsafe_allow_html=True) # Execution controls col1, col2 = st.columns([3, 1]) with col1: execute_clean = st.button( "๐Ÿ—‘๏ธ Execute Clean Operation", type="primary", disabled=dry_run and not st.session_state.scanned_files ) with col2: reset_scan = st.button("๐Ÿ”„ Reset Scan") if reset_scan: st.session_state.scanned_files = [] st.session_state.scan_complete = False st.session_state.cleaning_results = None st.rerun() if execute_clean: if confirm_delete and not dry_run: if not st.checkbox("โœ… I confirm I want to delete these files"): st.warning("Please confirm before proceeding") st.stop() with st.spinner("Executing clean operation..."): try: results = delete_files( st.session_state.scanned_files, dry_run=dry_run ) st.session_state.cleaning_results = results if dry_run: success_msg = """
โœ… Dry Run Complete: No files were deleted. This was a preview of what would be cleaned.
""" else: success_msg = """
โœ… Cleaning Complete: Files have been deleted successfully.
""" st.markdown(success_msg, unsafe_allow_html=True) # Display results if results: st.subheader("๐Ÿ“Š Cleaning Results") result_col1, result_col2, result_col3 = st.columns(3) with result_col1: st.metric("Files Processed", results.get('processed', 0)) with result_col2: st.metric("Files Deleted", results.get('deleted', 0)) with result_col3: st.metric("Space Freed", format_size(results.get('size_freed', 0))) if results.get('errors', []): st.subheader("โš ๏ธ Errors") for error in results['errors']: st.error(error) except Exception as e: st.error(f"โŒ Error during cleaning: {str(e)}") import traceback st.code(traceback.format_exc()) # Help and Documentation st.header("โ“ Help & Documentation") with st.expander("How to Use winapp2.ini", expanded=False): st.markdown(""" **winapp2.ini** is a configuration file format used by cleaning tools like BleachBit. **Structure:** ```ini [SectionName] Description=What this section cleans Warning=Warning message for users path=C:\\path\\to\\directory file=*.ext; *.log regex=pattern_to_match **Common Sections:** - `Temp`: Temporary files - `Cache`: Browser and application caches - `Logs`: Application log files - `Recycle`: Recycle bin contents """) with st.expander("Safety Tips", expanded=False): st.markdown(""" **โš ๏ธ Important Safety Guidelines:** 1. **Always use Dry Run mode first** to preview what will be deleted 2. **Review the file list** before executing deletion 3. **Backup important data** before cleaning 4. **Don't clean system files** unless you know what they do 5. **Start with user data** (Temp, Cache, Logs) before system files 6. **Check application behavior** after cleaning to ensure nothing broke """) with st.expander("Troubleshooting", expanded=False): st.markdown(""" **Common Issues:** - **Permission Errors**: Run as administrator or check file permissions - **File Not Found**: Paths may be incorrect or files already deleted - **INI Parse Errors**: Check INI file format and encoding - **Slow Scanning**: Large directories or network drives can be slow ** Solutions:** - Use specific paths instead of wildcards - Exclude system directories if not needed - Run in dry run mode first - Check antivirus software isn't blocking access """) # Footer st.markdown("---") st.markdown("Made with โค๏ธ using Streamlit | [Built with anycoder](https://huggingface.co/spaces/akhaliq/anycoder)")