diff --git a/ai/__pycache__/__init__.cpython-311.pyc b/ai/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..8bcb2fb Binary files /dev/null and b/ai/__pycache__/__init__.cpython-311.pyc differ diff --git a/ai/__pycache__/local_ai_api.cpython-311.pyc b/ai/__pycache__/local_ai_api.cpython-311.pyc new file mode 100644 index 0000000..fa9977d Binary files /dev/null and b/ai/__pycache__/local_ai_api.cpython-311.pyc differ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc index ea4a46c..4f35ede 100644 Binary files a/core/__pycache__/forms.cpython-311.pyc and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 9aa598b..9f32394 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index d62225f..7c24991 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 455ad96..c095085 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/forms.py b/core/forms.py index 1037e18..5eac4b0 100644 --- a/core/forms.py +++ b/core/forms.py @@ -1,5 +1,7 @@ -from django.contrib.auth.forms import UserCreationForm from django import forms +from django.contrib.auth.forms import UserCreationForm +from .models import Article, Reflection + class SignUpForm(UserCreationForm): class Meta(UserCreationForm.Meta): @@ -8,3 +10,14 @@ class SignUpForm(UserCreationForm): def __init__(self, *args, **kwargs): super(SignUpForm, self).__init__(*args, **kwargs) self.fields['email'].required = True + + +class ArticleForm(forms.ModelForm): + class Meta: + model = Article + fields = ('title', 'content') + +class ReflectionForm(forms.ModelForm): + class Meta: + model = Reflection + fields = ('answer',) diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..b125a7a --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,27 @@ +# Generated by Django 5.2.7 on 2025-12-02 15:53 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Article', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=200)), + ('content', models.TextField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/0002_reflection.py b/core/migrations/0002_reflection.py new file mode 100644 index 0000000..3aac6d4 --- /dev/null +++ b/core/migrations/0002_reflection.py @@ -0,0 +1,26 @@ +# Generated by Django 5.2.7 on 2025-12-02 15:59 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Reflection', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('question', models.TextField()), + ('answer', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..2afa2f4 Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0002_reflection.cpython-311.pyc b/core/migrations/__pycache__/0002_reflection.cpython-311.pyc new file mode 100644 index 0000000..d6f885b Binary files /dev/null and b/core/migrations/__pycache__/0002_reflection.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 71a8362..3e7ed9c 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,20 @@ from django.db import models +from django.contrib.auth.models import User -# Create your models here. +class Article(models.Model): + title = models.CharField(max_length=200) + content = models.TextField() + author = models.ForeignKey(User, on_delete=models.CASCADE) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.title + +class Reflection(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE) + question = models.TextField() + answer = models.TextField(blank=True, null=True) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"Reflection for {self.user.username} at {self.created_at}" diff --git a/core/templates/core/article_list.html b/core/templates/core/article_list.html new file mode 100644 index 0000000..0a663b4 --- /dev/null +++ b/core/templates/core/article_list.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} + +{% block content %} +

Articles

+ + New Article +{% endblock %} diff --git a/core/templates/core/reflection.html b/core/templates/core/reflection.html new file mode 100644 index 0000000..3e8fdbd --- /dev/null +++ b/core/templates/core/reflection.html @@ -0,0 +1,38 @@ +{% extends "base.html" %} +{% block content %} +
+

AI Reflection

+
+
+
+
+
This week's question:
+

{{ question }}

+
+ {% csrf_token %} + + {{ form.as_p }} + +
+
+
+
+
+
+
+
Previous Reflections
+
    + {% for reflection in reflections %} +
  • + {{ reflection.question }}
    + {{ reflection.answer }}
    + {{ reflection.created_at|date:"F d, Y" }} +
  • + {% endfor %} +
+
+
+
+
+
+{% endblock %} diff --git a/core/urls.py b/core/urls.py index 46aedb3..a74aa34 100644 --- a/core/urls.py +++ b/core/urls.py @@ -5,4 +5,5 @@ from . import views urlpatterns = [ path("", views.home, name="home"), path('signup/', views.signup, name='signup'), + path('reflection/', views.reflection_view, name='reflection'), ] diff --git a/core/views.py b/core/views.py index 33eef23..184fb79 100644 --- a/core/views.py +++ b/core/views.py @@ -1,12 +1,16 @@ import os import platform +import json from django import get_version as django_version from django.contrib.auth import login -from django.shortcuts import redirect, render +from django.shortcuts import redirect, render, get_object_or_404 from django.utils import timezone +from django.contrib.auth.decorators import login_required -from core.forms import SignUpForm +from .models import Article, Reflection +from .forms import SignUpForm, ArticleForm, ReflectionForm +from ai.local_ai_api import LocalAIApi def home(request): """Render the landing screen with loader and environment details.""" @@ -36,3 +40,56 @@ def signup(request): else: form = SignUpForm() return render(request, 'registration/signup.html', {'form': form}) + +@login_required +def article_list(request): + articles = Article.objects.filter(author=request.user) + return render(request, 'core/article_list.html', {'articles': articles}) + +@login_required +def article_detail(request, pk): + article = get_object_or_404(Article, pk=pk, author=request.user) + return render(request, 'core/article_detail.html', {'article': article}) + +@login_required +def article_create(request): + if request.method == 'POST': + form = ArticleForm(request.POST) + if form.is_valid(): + article = form.save(commit=False) + article.author = request.user + article.save() + return redirect('article_detail', pk=article.pk) + else: + form = ArticleForm() + return render(request, 'core/article_form.html', {'form': form}) + + +@login_required +def reflection_view(request): + # AI-generated question + response = LocalAIApi.create_response({ + "input": [ + {"role": "system", "content": "You are a helpful assistant. Your task is to ask a single, short, thought-provoking question to help a user reflect on their week. The question should be suitable for a professional in the tech industry. The question should be no more than 20 words."}, + {"role": "user", "content": "Ask me a question."}, + ], + }) + + if response.get("success"): + question = LocalAIApi.extract_text(response) + else: + question = "What is your biggest challenge this week?" # Fallback question + + if request.method == 'POST': + form = ReflectionForm(request.POST) + if form.is_valid(): + reflection = form.save(commit=False) + reflection.user = request.user + reflection.question = request.POST.get('question') # Get question from hidden input + reflection.save() + return redirect('reflection') + else: + form = ReflectionForm() + + reflections = Reflection.objects.filter(user=request.user).order_by('-created_at') + return render(request, 'core/reflection.html', {'form': form, 'question': question, 'reflections': reflections})