import streamlit as st import base64 import datetime from io import StringIO # Import the code smell detector backend from smell_detector import CodeSmellDetector # Set page configuration st.set_page_config(layout="wide", page_title="Code Smell Detector") st.title("🐍 Code Smell Detector") st.write("Upload a Python file to detect basic code smells like long functions, too many parameters, and duplicate code blocks.") # Move settings to sidebar with st.sidebar: st.header("Settings") st.subheader("⚙️ Code Smell Detection Settings") function_length_limit = st.slider( "Max function length (lines)", min_value=5, max_value=50, value=10, help="Functions longer than this will be flagged as code smells" ) param_limit = st.slider( "Max parameters per function", min_value=2, max_value=10, value=5, help="Functions with more parameters than this will be flagged" ) st.subheader("⚙️ Duplicate Detection Settings") block_size = st.slider( "Block size for duplicate detection (lines)", min_value=2, max_value=10, value=3, help="Number of consecutive lines that constitute a duplicate block" ) # Upload section uploaded_file = st.file_uploader("Choose a Python file", type=["py"]) if uploaded_file: # Read and display the uploaded code code = uploaded_file.read().decode("utf-8") with st.expander("View Source Code", expanded=True): st.code(code, language="python") # Initialize the detector with current settings detector = CodeSmellDetector( function_length_limit=function_length_limit, param_limit=param_limit ) # Run the analysis results = detector.analyze_code(code, block_size=block_size) # Check for syntax errors if "error" in results: st.error(results["error"]) else: # Display results in two columns col1, col2 = st.columns(2) with col1: st.subheader("🚨 Code Smells Detected:") if results["function_smells"]: for smell in results["function_smells"]: st.write(smell) else: st.success("✅ No function-level code smells detected!") with col2: st.subheader("📦 Duplicate Code Blocks:") if results["duplicate_blocks"]: for dup in results["duplicate_blocks"]: st.error(f"🔁 Duplicate block found at lines {dup[0]} and {dup[1]}") with st.expander("Show Duplicate Block"): st.code(dup[2]) else: st.success("✅ No duplicate blocks detected!") # Add download button to sidebar with st.sidebar: st.subheader("📊 Report") if st.button("Generate Download Report"): report_content = detector.generate_report(uploaded_file.name, results) b64 = base64.b64encode(report_content.encode()).decode() filename = f"code_smell_report_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.md" href = f'Download Report (Markdown)' st.markdown(href, unsafe_allow_html=True) st.success("Report generated! Click the link above to download.") else: with st.sidebar: st.info("Upload a Python file to see analysis options and download report.")