|
import os |
|
import logging |
|
import zipfile |
|
import tempfile |
|
from datetime import datetime |
|
from pathlib import Path |
|
from app_utils import get_db |
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
def create_markdown_content(submissions): |
|
"""Generate markdown content from a list of submissions""" |
|
content = "# Student Submissions\n\n" |
|
|
|
|
|
if submissions: |
|
content += f"**Student Name**: {submissions[0]['name']}\n" |
|
content += f"**Email**: {submissions[0]['email']}\n\n" |
|
content += "---\n\n" |
|
|
|
|
|
sorted_submissions = sorted( |
|
submissions, |
|
key=lambda x: datetime.fromisoformat(x['timestamp']), |
|
reverse=True |
|
) |
|
|
|
for submission in sorted_submissions: |
|
|
|
content += f"## Problem: {submission['problem_id']}\n\n" |
|
|
|
|
|
timestamp = datetime.fromisoformat(submission['timestamp']) |
|
content += f"**Submitted**: {timestamp.strftime('%Y-%m-%d %H:%M:%S')}\n" |
|
content += f"**Hint Used**: {'Yes' if submission['hint_requested'] else 'No'}\n\n" |
|
|
|
|
|
content += "### Code Submission\n" |
|
content += "```python\n" |
|
content += submission['student_code'] |
|
content += "\n```\n\n" |
|
|
|
content += "---\n\n" |
|
|
|
return content |
|
|
|
def group_submissions_by_student(submissions): |
|
"""Group submissions by student name""" |
|
student_submissions = {} |
|
for submission in submissions: |
|
name = submission['name'] |
|
if name not in student_submissions: |
|
student_submissions[name] = [] |
|
student_submissions[name].append(submission) |
|
return student_submissions |
|
|
|
def create_markdown_files(student_submissions, output_dir): |
|
"""Create markdown files for each student in the specified directory""" |
|
output_dir = Path(output_dir) |
|
output_dir.mkdir(exist_ok=True) |
|
created_files = [] |
|
|
|
for name, submissions in student_submissions.items(): |
|
|
|
safe_filename = "".join(x for x in name if x.isalnum() or x in "- ").strip() |
|
safe_filename = safe_filename.replace(" ", "_") + ".md" |
|
|
|
|
|
content = create_markdown_content(submissions) |
|
|
|
|
|
file_path = output_dir / safe_filename |
|
with open(file_path, 'w', encoding='utf-8') as f: |
|
f.write(content) |
|
|
|
created_files.append(file_path) |
|
logger.info(f"Created markdown file for {name}: {file_path}") |
|
|
|
return created_files |
|
|
|
def create_markdown_zip(): |
|
"""Create a zip file containing markdown files for all submissions""" |
|
try: |
|
|
|
_, submissions_table = get_db() |
|
all_submissions = submissions_table.all() |
|
|
|
if not all_submissions: |
|
logger.warning("No submissions found in database") |
|
return None |
|
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
|
|
student_submissions = group_submissions_by_student(all_submissions) |
|
markdown_files = create_markdown_files(student_submissions, temp_dir) |
|
|
|
|
|
zip_path = tempfile.mktemp(suffix='.zip') |
|
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: |
|
for file_path in markdown_files: |
|
zipf.write(file_path, file_path.name) |
|
|
|
logger.info(f"Created zip file with {len(markdown_files)} markdown files") |
|
return zip_path |
|
|
|
except Exception as e: |
|
logger.error(f"Error creating markdown zip: {str(e)}") |
|
return None |
|
|
|
def main(): |
|
"""Main function for command-line usage""" |
|
output_dir = Path("db_dump") |
|
try: |
|
|
|
_, submissions_table = get_db() |
|
all_submissions = submissions_table.all() |
|
|
|
if not all_submissions: |
|
logger.warning("No submissions found in database") |
|
return |
|
|
|
|
|
student_submissions = group_submissions_by_student(all_submissions) |
|
create_markdown_files(student_submissions, output_dir) |
|
|
|
logger.info(f"Successfully created markdown files in {output_dir}") |
|
logger.info(f"Total number of students: {len(student_submissions)}") |
|
|
|
except Exception as e: |
|
logger.error(f"Error occurred: {str(e)}") |
|
|
|
if __name__ == "__main__": |
|
main() |