|
import streamlit as st |
|
import sqlite3 |
|
import hashlib |
|
import os |
|
import zipfile |
|
from git import Repo |
|
|
|
|
|
|
|
DB_FILE = "users.db" |
|
|
|
def create_user_table(): |
|
conn = sqlite3.connect(DB_FILE) |
|
cursor = conn.cursor() |
|
cursor.execute(""" |
|
CREATE TABLE IF NOT EXISTS users ( |
|
username TEXT PRIMARY KEY, |
|
password TEXT |
|
) |
|
""") |
|
conn.commit() |
|
conn.close() |
|
|
|
def add_user(username, password): |
|
conn = sqlite3.connect(DB_FILE) |
|
cursor = conn.cursor() |
|
hashed_password = hashlib.sha256(password.encode()).hexdigest() |
|
try: |
|
cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, hashed_password)) |
|
conn.commit() |
|
except sqlite3.IntegrityError: |
|
st.error("Username already exists. Please choose a different username.") |
|
conn.close() |
|
|
|
def authenticate_user(username, password): |
|
conn = sqlite3.connect(DB_FILE) |
|
cursor = conn.cursor() |
|
hashed_password = hashlib.sha256(password.encode()).hexdigest() |
|
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, hashed_password)) |
|
user = cursor.fetchone() |
|
conn.close() |
|
return user |
|
|
|
def initialize_session_state(): |
|
if "authenticated" not in st.session_state: |
|
st.session_state.authenticated = False |
|
if "username" not in st.session_state: |
|
st.session_state.username = None |
|
if "page" not in st.session_state: |
|
st.session_state.page = "login" |
|
if "current_project" not in st.session_state: |
|
st.session_state.current_project = None |
|
if "project_uploaded" not in st.session_state: |
|
st.session_state.project_uploaded = False |
|
|
|
def main(): |
|
st.title("SimplifAI") |
|
|
|
|
|
initialize_session_state() |
|
|
|
|
|
create_user_table() |
|
|
|
|
|
if st.session_state.page == "login": |
|
login_page() |
|
elif st.session_state.page == "workspace": |
|
workspace_page() |
|
elif st.session_state.page == "project_view": |
|
project_view_page() |
|
|
|
def login_page(): |
|
st.subheader("Please Log In or Register to Continue") |
|
auth_mode = st.radio("Choose an Option", ["Log In", "Register"], horizontal=True) |
|
|
|
if auth_mode == "Log In": |
|
st.subheader("Log In") |
|
username = st.text_input("Username", key="login_username") |
|
password = st.text_input("Password", type="password", key="login_password") |
|
|
|
|
|
if st.button("Log In"): |
|
if authenticate_user(username, password): |
|
st.session_state.authenticated = True |
|
st.session_state.username = username |
|
st.session_state.page = "workspace" |
|
else: |
|
st.error("Invalid username or password. Please try again.") |
|
|
|
elif auth_mode == "Register": |
|
st.subheader("Register") |
|
username = st.text_input("Create Username", key="register_username") |
|
password = st.text_input("Create Password", type="password", key="register_password") |
|
|
|
|
|
if st.button("Register"): |
|
if username and password: |
|
add_user(username, password) |
|
st.success("Account created successfully! You can now log in.") |
|
else: |
|
st.error("Please fill in all fields.") |
|
|
|
|
|
def workspace_page(): |
|
|
|
st.sidebar.title(f"Hello, {st.session_state.username}!") |
|
if st.sidebar.button("Log Out"): |
|
st.session_state.authenticated = False |
|
st.session_state.username = None |
|
st.session_state.page = "login" |
|
|
|
|
|
user_folder = os.path.join("user_projects", st.session_state.username) |
|
os.makedirs(user_folder, exist_ok=True) |
|
|
|
|
|
projects = [d for d in os.listdir(user_folder) if os.path.isdir(os.path.join(user_folder, d))] |
|
|
|
|
|
selected_project = st.sidebar.selectbox("Projects", ["Select a project"] + projects) |
|
|
|
if selected_project != "Select a project": |
|
st.session_state.current_project = selected_project |
|
st.session_state.page = "project_view" |
|
|
|
|
|
if st.session_state.project_uploaded: |
|
st.success(f"Project '{st.session_state.current_project}' uploaded successfully!") |
|
st.session_state.project_uploaded = False |
|
|
|
|
|
st.subheader("Workspace") |
|
st.write("You can create a new project by uploading files or folders, or by cloning a GitHub repository.") |
|
|
|
|
|
action = st.radio("Choose an action", ["Upload Files or Folders", "Clone GitHub Repository"], horizontal=True) |
|
|
|
project_name = st.text_input("Enter a project name") |
|
|
|
if action == "Upload Files or Folders": |
|
st.subheader("Upload Files or Folders") |
|
uploaded_files = st.file_uploader( |
|
"Upload one or more files or a .zip archive for folders", accept_multiple_files=True |
|
) |
|
|
|
if uploaded_files and project_name: |
|
if st.button("Upload Project"): |
|
project_folder = os.path.join(user_folder, project_name) |
|
os.makedirs(project_folder, exist_ok=True) |
|
|
|
for uploaded_file in uploaded_files: |
|
|
|
file_path = os.path.join(project_folder, uploaded_file.name) |
|
|
|
with open(file_path, "wb") as f: |
|
f.write(uploaded_file.getbuffer()) |
|
|
|
|
|
if uploaded_file.name.endswith(".zip"): |
|
try: |
|
with zipfile.ZipFile(file_path, "r") as zip_ref: |
|
zip_ref.extractall(project_folder) |
|
os.remove(file_path) |
|
st.success(f"Folder from {uploaded_file.name} extracted successfully!") |
|
except zipfile.BadZipFile: |
|
st.error(f"File {uploaded_file.name} is not a valid .zip file.") |
|
else: |
|
st.success(f"File {uploaded_file.name} saved successfully!") |
|
|
|
|
|
st.session_state.current_project = project_name |
|
st.session_state.project_uploaded = True |
|
st.rerun() |
|
|
|
elif action == "Clone GitHub Repository": |
|
st.subheader("Clone GitHub Repository") |
|
repo_url = st.text_input("Enter the GitHub repository URL") |
|
|
|
if repo_url and project_name: |
|
if st.button("Upload Project"): |
|
project_folder = os.path.join(user_folder, project_name) |
|
os.makedirs(project_folder, exist_ok=True) |
|
|
|
try: |
|
Repo.clone_from(repo_url, project_folder) |
|
|
|
st.session_state.current_project = project_name |
|
st.session_state.project_uploaded = True |
|
st.rerun() |
|
except Exception as e: |
|
st.error(f"Failed to clone repository: {e}") |
|
|
|
def project_view_page(): |
|
|
|
st.sidebar.title(f"Project: {st.session_state.current_project}") |
|
if st.sidebar.button("Back to Workspace"): |
|
st.session_state.page = "workspace" |
|
if st.sidebar.button("Log Out"): |
|
st.session_state.authenticated = False |
|
st.session_state.username = None |
|
st.session_state.page = "login" |
|
|
|
|
|
st.subheader(f"Project: {st.session_state.current_project}") |
|
st.write("Manage your project and explore its files.") |
|
|
|
|
|
if st.button("Show File Structure"): |
|
user_folder = os.path.join("user_projects", st.session_state.username) |
|
project_folder = os.path.join(user_folder, st.session_state.current_project) |
|
|
|
st.write("File structure:") |
|
|
|
for root, dirs, files in os.walk(project_folder): |
|
level = root.replace(project_folder, "").count(os.sep) |
|
indent = " " * 4 * level |
|
|
|
|
|
if level == 0: |
|
st.write(f"π {os.path.basename(root)}") |
|
else: |
|
with st.expander(f"{indent}π {os.path.basename(root)}"): |
|
sub_indent = " " * 4 * (level + 1) |
|
|
|
|
|
for file in files: |
|
st.write(f"{sub_indent}π {file}") |
|
|
|
if __name__ == "__main__": |
|
main() |
|
|
|
|
|
|