Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added __pycache__/app.cpython-312.pyc
Binary file not shown.
Binary file added __pycache__/config.cpython-312.pyc
Binary file not shown.
216 changes: 133 additions & 83 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,141 +1,191 @@
from flask import Flask, render_template, request, redirect, url_for
import csv
import os
import json
import logging
from datetime import datetime, timezone
from typing import List, Dict, Any, Optional
from flask import Flask, request, render_template, redirect, url_for
from config import DATA_FILE_PATH

app = Flask(__name__)

def load_data():
if os.path.exists('data/streaks.csv'):
with open('data/streaks.csv', mode='r') as f:
reader = csv.DictReader(f)
return sorted(list(reader), key=lambda x: datetime.strptime(x['Date'], '%Y-%m-%d'), reverse=True)
logging.basicConfig(level=logging.INFO)

USERS_FILE_PATH = 'data/users.json'

def load_users() -> List[str]:
try:
if os.path.exists(USERS_FILE_PATH):
with open(USERS_FILE_PATH, 'r') as f:
users = json.load(f)
return users
except Exception as e:
logging.error(f"Error loading users: {e}")
return []

def save_data(data):
with open('data/streaks.csv', mode='w', newline='') as f:
fieldnames = ['Date', 'Saketh', 'Saketh_Difficulty', 'Aditya', 'Aditya_Difficulty', 'Kushagra', 'Kushagra_Difficulty']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
def save_users(users: List[str]) -> None:
try:
with open(USERS_FILE_PATH, 'w') as f:
json.dump(users, f, indent=4)
except Exception as e:
logging.error(f"Error saving users: {e}")

def convert_to_leetcode_url(question_text):
def convert_to_leetcode_url(question_text: str) -> Optional[str]:
if ". " in question_text:
question_title = question_text.split(". ", 1)[1].strip().lower().replace(" ", "-")
question_title = question_text.split(". ", 1)[1]
question_title = question_title.strip().lower().replace(" ", "-")
return f"https://leetcode.com/problems/{question_title}"
return None
return None

def load_data() -> List[Dict[str, Any]]:
try:
if os.path.exists(DATA_FILE_PATH):
with open(DATA_FILE_PATH, 'r') as f:
data = json.load(f)
data = sorted(
data,
key=lambda x: datetime.strptime(x['Date'], '%Y-%m-%d'),
reverse=True
)
return data
except Exception as e:
logging.error(f"Error loading data: {e}")
return []

def save_data(data: List[Dict[str, Any]]) -> None:
try:
with open(DATA_FILE_PATH, 'w') as f:
json.dump(data, f, indent=4)
except Exception as e:
logging.error(f"Error saving data: {e}")

def add_default_entry_if_new_day(data):
def add_default_entry_if_new_day(data: List[Dict[str, Any]]) -> None:
today = datetime.now(timezone.utc).date()
today_str = today.strftime('%Y-%m-%d')
existing_dates = {entry['Date'] for entry in data}

# If today is not in the existing dates, add a new entry
if today_str not in existing_dates:
users = load_users()
user_data = {
user: {
'Questions': [],
'Difficulties': []
} for user in users
}
data.append({
'Date': today_str,
'Saketh': '',
'Saketh_Difficulty': None,
'Aditya': '',
'Aditya_Difficulty': None,
'Kushagra': '',
'Kushagra_Difficulty': None
'Users': user_data
})
save_data(data) # Save the new entry to the CSV file
save_data(data)

@app.route('/')
def index():
def index() -> str:
data = load_data()
add_default_entry_if_new_day(data) # Check and add default entry for today
add_default_entry_if_new_day(data)
users = load_users()

# Generate links and structure question data
for entry in data:
entry['Saketh_questions'] = []
entry['Aditya_questions'] = []
entry['Kushagra_questions'] = []

for q, d in zip(entry['Saketh'].split(','), entry['Saketh_Difficulty'].split(',')):
if entry['Saketh']:
question_url = convert_to_leetcode_url(q)
entry['Saketh_questions'].append((q.strip(), question_url, d.strip()))

for q, d in zip(entry['Aditya'].split(','), entry['Aditya_Difficulty'].split(',')):
if entry['Aditya']:
question_url = convert_to_leetcode_url(q)
entry['Aditya_questions'].append((q.strip(), question_url, d.strip()))

for q, d in zip(entry['Kushagra'].split(','), entry['Kushagra_Difficulty'].split(',')):
if entry['Kushagra']:
entry['User_questions'] = {}
for user in users:
entry['User_questions'][user] = []
user_data = entry['Users'].get(user, {'Questions': [], 'Difficulties': []})
questions = user_data['Questions']
difficulties = user_data['Difficulties']
for q, d in zip(questions, difficulties):
question_url = convert_to_leetcode_url(q)
entry['Kushagra_questions'].append((q.strip(), question_url, d.strip()))
entry['User_questions'][user].append((q.strip(), question_url, d.strip()))

return render_template('index5.html', data=data)
return render_template('index.html', data=data, users=users)

@app.route('/add', methods=['POST'])
def add():
def add() -> Any:
date = datetime.now().date().strftime('%Y-%m-%d')
saketh = request.form.get('saketh', '').strip()
saketh_difficulty = request.form.get('saketh_difficulty', None)
aditya = request.form.get('aditya', '').strip()
aditya_difficulty = request.form.get('aditya_difficulty', None)
kushagra = request.form.get('kushagra', '').strip()
kushagra_difficulty = request.form.get('kushagra_difficulty', None)

users = load_users()
data = load_data()
entry_found = False

for entry in data:
if entry['Date'] == date:
entry_found = True
if saketh:
entry['Saketh'] = f"{entry['Saketh']}, {saketh}" if entry['Saketh'] else saketh
entry['Saketh_Difficulty'] = f"{entry['Saketh_Difficulty']}, {saketh_difficulty}" if entry['Saketh_Difficulty'] and saketh_difficulty != None else saketh_difficulty
if aditya:
entry['Aditya'] = f"{entry['Aditya']}, {aditya}" if entry['Aditya'] else aditya
entry['Aditya_Difficulty'] = f"{entry['Aditya_Difficulty']}, {aditya_difficulty}" if entry['Aditya_Difficulty'] and aditya_difficulty != None else aditya_difficulty
if kushagra:
entry['Kushagra'] = f"{entry['Kushagra']}, {kushagra}" if entry['Kushagra'] else kushagra
entry['Kushagra_Difficulty'] = f"{entry['Kushagra_Difficulty']}, {kushagra_difficulty}" if entry['Kushagra_Difficulty'] and kushagra_difficulty != None else kushagra_difficulty
for user in users:
question = request.form.get(f'{user.lower()}', '').strip()
difficulty = request.form.get(f'{user.lower()}_difficulty', '')
if question:
user_data = entry['Users'].setdefault(user, {'Questions': [], 'Difficulties': []})
user_data['Questions'].append(question)
user_data['Difficulties'].append(difficulty)
break

if not entry_found:
user_data = {}
for user in users:
question = request.form.get(f'{user.lower()}', '').strip()
difficulty = request.form.get(f'{user.lower()}_difficulty', '')
user_data[user] = {
'Questions': [question] if question else [],
'Difficulties': [difficulty] if difficulty else []
}

data.append({
'Date': date,
'Saketh': saketh,
'Saketh_Difficulty': saketh_difficulty,
'Aditya': aditya,
'Aditya_Difficulty': aditya_difficulty,
'Kushagra': kushagra,
'Kushagra_Difficulty': kushagra_difficulty
'Users': user_data
})

save_data(data)
return redirect(url_for('index'))

@app.route('/delete_question', methods=['POST'])
def delete_question():
def delete_question() -> Any:
date = request.form['date']
question = request.form['question']
role = request.form['role']
user = request.form['user']

data = load_data()

for entry in data:
if entry['Date'] == date:
# Remove the specific question from the appropriate list
questions = entry[role].split(',')
difficulties = entry[f'{role}_Difficulty'].split(',')
if question in questions:
index = questions.index(question)
questions.pop(index)
difficulties.pop(index)

entry[role] = ', '.join(questions)
entry[f'{role}_Difficulty'] = ', '.join(difficulties) if difficulties else None
user_data = entry['Users'].get(user, {'Questions': [], 'Difficulties': []})
if question in user_data['Questions']:
index = user_data['Questions'].index(question)
user_data['Questions'].pop(index)
user_data['Difficulties'].pop(index)
break

save_data(data)
return redirect(url_for('index'))

@app.route('/add_user', methods=['POST'])
def add_user() -> Any:
new_user = request.form.get('new_user', '').strip()
if new_user:
users = load_users()
if new_user not in users:
users.append(new_user)
save_users(users)

data = load_data()
for entry in data:
entry['Users'][new_user] = {
'Questions': [],
'Difficulties': []
}
save_data(data)
return redirect(url_for('index'))

@app.route('/delete_user', methods=['POST'])
def delete_user() -> Any:
user_to_delete = request.form.get('user_to_delete', '').strip()
if user_to_delete:
users = load_users()
if user_to_delete in users:
users.remove(user_to_delete)
save_users(users)

data = load_data()
for entry in data:
if user_to_delete in entry['Users']:
del entry['Users'][user_to_delete]
save_data(data)
return redirect(url_for('index'))

if __name__ == '__main__':
app.run(debug=True)
app.run()
3 changes: 3 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import os

DATA_FILE_PATH = os.getenv('DATA_FILE_PATH', 'data/streaks.json')
18 changes: 0 additions & 18 deletions data/streaks.csv

This file was deleted.

19 changes: 19 additions & 0 deletions data/streaks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"Date": "2024-11-05",
"Users": {
"Aditya": {
"Questions": [],
"Difficulties": []
},
"Kushagra": {
"Questions": [],
"Difficulties": []
},
"Saketh": {
"Questions": [],
"Difficulties": []
}
}
}
]
5 changes: 5 additions & 0 deletions data/users.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"Aditya",
"Kushagra",
"Saketh"
]
5 changes: 4 additions & 1 deletion static/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ h1 {
.container {
display: flex;
max-width: 1200px;
margin: 0 auto;
margin: 20px auto;
gap: 20px;
align-items: flex-start;
padding: 20px;
background-color: #1f1f1f;
border-radius: 12px;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5);
justify-content: space-around;
}

.table-section {
Expand Down Expand Up @@ -115,9 +116,11 @@ option.hard {
.form-container {
background-color: #2b2b2b;
padding: 20px;
margin: 20px auto;
border: 1px solid #555555;
border-radius: 12px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
justify-content: space-around;
}

input[type="text"],
Expand Down
Loading