Spaces:
Running
Running
# app.py | |
import streamlit as st | |
import sqlite3 | |
from passlib.hash import pbkdf2_sha256 | |
from flask import Flask, jsonify, request | |
import uuid | |
import threading | |
# Initialize Flask app | |
flask_app = Flask(__name__) | |
flask_app.secret_key = str(uuid.uuid4()) | |
# Database setup | |
def init_db(): | |
conn = sqlite3.connect('conntribe.db') | |
c = conn.cursor() | |
# Create users table | |
c.execute('''CREATE TABLE IF NOT EXISTS users | |
(id INTEGER PRIMARY KEY AUTOINCREMENT, | |
name TEXT NOT NULL, | |
email TEXT UNIQUE NOT NULL, | |
whatsapp TEXT UNIQUE NOT NULL, | |
sem INTEGER NOT NULL, | |
password TEXT NOT NULL)''') | |
# Create projects table | |
c.execute('''CREATE TABLE IF NOT EXISTS projects | |
(id INTEGER PRIMARY KEY AUTOINCREMENT, | |
title TEXT NOT NULL, | |
description TEXT, | |
members_needed INTEGER NOT NULL, | |
whatsapp TEXT NOT NULL, | |
user_id INTEGER NOT NULL, | |
FOREIGN KEY(user_id) REFERENCES users(id))''') | |
conn.commit() | |
conn.close() | |
init_db() | |
# Flask API Endpoints | |
def signup(): | |
data = request.json | |
try: | |
conn = sqlite3.connect('conntribe.db') | |
c = conn.cursor() | |
hashed_password = pbkdf2_sha256.hash(data['password']) | |
c.execute('INSERT INTO users (name, email, whatsapp, sem, password) VALUES (?, ?, ?, ?, ?)', | |
(data['name'], data['email'], data['whatsapp'], data['sem'], hashed_password)) | |
conn.commit() | |
return jsonify({'message': 'User created successfully'}), 201 | |
except sqlite3.IntegrityError: | |
return jsonify({'error': 'Email or WhatsApp number already exists'}), 400 | |
finally: | |
conn.close() | |
def login(): | |
data = request.json | |
conn = sqlite3.connect('conntribe.db') | |
c = conn.cursor() | |
c.execute('SELECT * FROM users WHERE email = ? OR whatsapp = ?', (data['username'], data['username'])) | |
user = c.fetchone() | |
conn.close() | |
if user and pbkdf2_sha256.verify(data['password'], user[5]): | |
return jsonify({ | |
'id': user[0], | |
'name': user[1], | |
'email': user[2], | |
'whatsapp': user[3] | |
}), 200 | |
return jsonify({'error': 'Invalid credentials'}), 401 | |
def projects(): | |
if request.method == 'GET': | |
conn = sqlite3.connect('conntribe.db') | |
c = conn.cursor() | |
c.execute('SELECT projects.*, users.name FROM projects JOIN users ON projects.user_id = users.id') | |
projects = c.fetchall() | |
conn.close() | |
return jsonify([{ | |
'id': p[0], | |
'title': p[1], | |
'description': p[2], | |
'members_needed': p[3], | |
'whatsapp': p[4], | |
'author': p[6] | |
} for p in projects]), 200 | |
elif request.method == 'POST': | |
data = request.json | |
try: | |
conn = sqlite3.connect('conntribe.db') | |
c = conn.cursor() | |
c.execute('INSERT INTO projects (title, description, members_needed, whatsapp, user_id) VALUES (?, ?, ?, ?, ?)', | |
(data['title'], data.get('description'), data['members_needed'], data['whatsapp'], data['user_id'])) | |
conn.commit() | |
return jsonify({'message': 'Project created successfully'}), 201 | |
finally: | |
conn.close() | |
# Streamlit UI | |
def main(): | |
st.set_page_config(page_title="ConnTribe", page_icon="π€", layout="wide") | |
if 'user' not in st.session_state: | |
st.session_state.user = None | |
# Navigation | |
if st.session_state.user: | |
tabs = st.sidebar.radio("Navigation", ["Home", "Projects"]) | |
else: | |
tabs = st.sidebar.radio("Navigation", ["Login", "Sign Up"]) | |
# Authentication Pages | |
if not st.session_state.user: | |
if tabs == "Login": | |
with st.form("Login"): | |
st.header("Login to ConnTribe") | |
username = st.text_input("Email/WhatsApp Number") | |
password = st.text_input("Password", type="password") | |
if st.form_submit_button("Login"): | |
response = requests.post('http://localhost:5000/api/login', | |
json={'username': username, 'password': password}) | |
if response.status_code == 200: | |
st.session_state.user = response.json() | |
st.experimental_rerun() | |
else: | |
st.error("Invalid credentials") | |
elif tabs == "Sign Up": | |
with st.form("Sign Up"): | |
st.header("Create New Account") | |
name = st.text_input("Full Name") | |
email = st.text_input("Email") | |
whatsapp = st.text_input("WhatsApp Number") | |
sem = st.number_input("Current Semester", min_value=1, max_value=8) | |
password = st.text_input("Password", type="password") | |
confirm_password = st.text_input("Confirm Password", type="password") | |
if st.form_submit_button("Sign Up"): | |
if password != confirm_password: | |
st.error("Passwords do not match") | |
else: | |
response = requests.post('http://localhost:5000/api/signup', | |
json={'name': name, 'email': email, | |
'whatsapp': whatsapp, 'sem': sem, | |
'password': password}) | |
if response.status_code == 201: | |
st.success("Account created successfully! Please login.") | |
else: | |
st.error(response.json().get('error', 'Registration failed')) | |
# Authenticated Pages | |
else: | |
st.sidebar.header(f"Welcome, {st.session_state.user['name']}") | |
if st.sidebar.button("Logout"): | |
st.session_state.user = None | |
st.experimental_rerun() | |
if tabs == "Home": | |
st.header("Welcome to ConnTribe π") | |
st.markdown(""" | |
### Your Project Collaboration Hub | |
**ConnTribe** helps you connect with fellow students to collaborate on projects. Here's how to use it: | |
1. **Create a Project**: Share your project details and required team members | |
2. **Browse Projects**: Explore existing projects looking for collaborators | |
3. **Join Projects**: Connect with project owners directly via WhatsApp | |
Start collaborating today and build amazing things together! π | |
""") | |
elif tabs == "Projects": | |
st.header("Project Marketplace") | |
# Create Project | |
with st.expander("Create New Project"): | |
with st.form("New Project"): | |
title = st.text_input("Project Title*") | |
description = st.text_area("Description") | |
members_needed = st.number_input("Members Needed*", min_value=1) | |
whatsapp = st.text_input("Contact WhatsApp*", value=st.session_state.user['whatsapp']) | |
if st.form_submit_button("Post Project"): | |
if title and members_needed and whatsapp: | |
response = requests.post('http://localhost:5000/api/projects', | |
json={'title': title, 'description': description, | |
'members_needed': members_needed, | |
'whatsapp': whatsapp, | |
'user_id': st.session_state.user['id']}) | |
if response.status_code == 201: | |
st.success("Project posted successfully!") | |
else: | |
st.error("Failed to post project") | |
# Display Projects | |
st.subheader("Available Projects") | |
response = requests.get('http://localhost:5000/api/projects') | |
if response.status_code == 200: | |
projects = response.json() | |
for project in projects: | |
with st.container(): | |
st.markdown(f""" | |
### {project['title']} | |
**By**: {project['author']} | |
**Members Needed**: {project['members_needed']} | |
**Description**: {project['description'] or 'No description provided'} | |
""") | |
if st.button(f"Join {project['title']}", key=project['id']): | |
st.markdown(f"[Contact on WhatsApp](https://wa.me/{project['whatsapp']})") | |
st.markdown("---") | |
else: | |
st.warning("No projects available yet. Be the first to post one!") | |
# Run Flask in background | |
def run_flask(): | |
flask_app.run(host='0.0.0.0', port=5000, threaded=True) | |
if __name__ == "__main__": | |
threading.Thread(target=run_flask, daemon=True).start() | |
main() |