From 4647314b9dbb6eb5fab2d641e87d33f0bb914f83 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Tue, 2 Dec 2025 16:01:28 +0000 Subject: [PATCH] Auto commit: 2025-12-02T16:01:28.239Z --- ai/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 404 bytes ai/__pycache__/local_ai_api.cpython-311.pyc | Bin 0 -> 19874 bytes core/__pycache__/forms.cpython-311.pyc | Bin 1190 -> 2234 bytes core/__pycache__/models.cpython-311.pyc | Bin 209 -> 1847 bytes core/__pycache__/urls.cpython-311.pyc | Bin 444 -> 545 bytes core/__pycache__/views.cpython-311.pyc | Bin 2129 -> 5671 bytes core/forms.py | 15 ++++- core/migrations/0001_initial.py | 27 ++++++++ core/migrations/0002_reflection.py | 26 ++++++++ .../__pycache__/0001_initial.cpython-311.pyc | Bin 0 -> 1520 bytes .../0002_reflection.cpython-311.pyc | Bin 0 -> 1524 bytes core/models.py | 19 +++++- core/templates/core/article_list.html | 11 ++++ core/templates/core/reflection.html | 38 +++++++++++ core/urls.py | 1 + core/views.py | 61 +++++++++++++++++- 16 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 ai/__pycache__/__init__.cpython-311.pyc create mode 100644 ai/__pycache__/local_ai_api.cpython-311.pyc create mode 100644 core/migrations/0001_initial.py create mode 100644 core/migrations/0002_reflection.py create mode 100644 core/migrations/__pycache__/0001_initial.cpython-311.pyc create mode 100644 core/migrations/__pycache__/0002_reflection.cpython-311.pyc create mode 100644 core/templates/core/article_list.html create mode 100644 core/templates/core/reflection.html diff --git a/ai/__pycache__/__init__.cpython-311.pyc b/ai/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8bcb2fbacced8a64c23d6a403697ca4fcbf18d9a GIT binary patch literal 404 zcma)(ze__g5XbX=w3XW8>=xX*yf^72LP5n+adGl3Atu*0^}Qq}d9?K(adQ>_0RNAU z@+QH_P3YFi1k~B%_}m@b_wL}H`~5ER_H?u>UVZ!s#jnLb$>zW(kBFlJ@rcJ|RK-PH zB}G!DMOw9rR)lzRjRxt%*#(pujKvdWu#gT6WlqQ`UI;hCZU*?gq^?v`!SHZ|wNc9z zo)}f((>aw>g_+`zeMWxYAZ@yriqUd78fww(F$2^AF<`Zl7MhNM`x>lk_BjL7X?UczE z%G_B^8RS&tga|1dA(>uncaAH?>k>{(&&$K<_R!-iiK6HYjn`=Wj&9cfa}%EN4X0ar Ad;kCd literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fa9977d8c7f6a3dd70fe97b8027d3793d79129e6 GIT binary patch literal 19874 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 literal 0 HcmV?d00001 diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc index ea4a46cf17813a05ff70cec50f195b80a88d84a6..4f35edeef79dfe552c317074e5fdc2fb661ee92c 100644 GIT binary patch literal 2234 zcmb_d&2Jk;6rb5IukEBs8a`Uor~xHujHt~C2~;5vh@R>LC6~Rdw!7nW-Tg>sca?&2 z$e|KGP?STV`~j#?^}=6*jFf}55+_c*IdTptC*GU&dgHZ0RmJZ3w=?r*-n{pF?~Q+1 zT&xjz{#ud6F+1GW2Cf@f2S*R9`bRN+fcV zIO;>*<)0MtO7Ef(XO7)msVB9sw%9i{l}`BQ@>3b3olSfgQjXH3(%P4-<1riMc5VWGC;om8gKxoOMhxl@LlX8- zut#EYSIM`OtX6uYLml~{Zm2!-fEpTDr=+#p?ryNNhjvVzg*M?cx(HC5)0%1ep_6#nUog%4iRFzYTE}Ic6Fnm% zJo4;%>u%_?R&pl^;-tkMFguAu-r5iOy=c#}S<4PNYY9G^dtavtp3dvAvjV?p72t64 z4pz2$8onIo`Rf37?i=(4r%Ui1c>q7qCy*WSIe82@mp=#ODU6;^X1bH!0d>iN^fUb) zGmjpS?j)le>2kiEn3Kpj1Q~39#TP-?P*XKZ_88|?7$IM7;KruOSHzIB`-#h$15_#z z^E#>Ajl zNL~)IRKU}xQa%sQXd5I&$`{2o9eyYTS(H$HT(|#TLvKteWU`?^9jW6wT0XZuFC;Z~ zW4H(^b{NDgh}#XV%r#P$s!&hN6N$pHPBX_u_%YG>I{+A&2$LZv7NWlVW=|cgY?ce7 z{Y)tzBh-{suY)p z%?hG@#^;0rZymmgfE7D85buHjshkPKTNsEdGlAe+b2MREas&+U9NyQE_c9>wYsh<9 zknxV{+KqauIbAE*4LM$1>E&$D#O&klou-wgUwQik or%wynMVUf&&ce~=1T#8PUMqdw3?_ctIovW&XB^~!jQs}%D9Y~fnhZeLqHTu z3TrTfCfiF8cj5&RPEE#JtZDg0xy73pwHR4BfTFCE^_gVY1c0m}p~-oU>3N|AZa^dTV2U^4w&oTaM81dxW=0V| zhy^wSWcV)*o80`A(wtPgA~_%zWNUF8kodsN$jEqu!R!Jmy1^hJc!5Cz8GT@xti_?l O$H2y@`vF9N%?1D!eqN0L diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 9aa598b9d5171b2bb0d207f045e07f9fbbb95a64..9f32394aa5e20b9f91817638d4675934c8a5656d 100644 GIT binary patch literal 1847 zcmaJ>J#5=X6uu*=e^II&*JxbXmIn_)3@Jd3!h>PJu;Uaqs-bZ+XedF8CtD6hCP&J4 zgtpL-K|_WNEgT>ykRfm#SVP7R-P@4@I0#%jWpm+7nfe|n*_Q0)#QSvb?!CMB-hJJQHMU~ohuB^EV(K5k|^X zBV|D#OuTeLqaERxf+Ns_hK_(ncpx9c;B+96a>QSa4klO(bo~V3Oh-J16rDm3S~=ls zCkL`7bwVSj$y)dsDW`(4yvPc-YZaZn{~Jsos(4*JRCH$S*t>737c&h7!eutw0x79B zY*R7J14Y%e%7y=6h+|Cb`DXw}lZx`Bq3Xd3N9VoR>aNPyYfRU8%9pp;q3z3F zq+%L2Gi)!u4j$EZj7|2G<9&OP)s+XUD{J?>Fl1-fqs5T!1 zgSUj=f0PTN`H*4Nabr>kznv z-rP)Rq~!k*nuV^Cw?jt=IYQqNa>s_rtqGcNjnZ*nCjl<_4K$Y$?Cm9W0=eX4neKGq!eec2mUKM(kzZVo$LLbTR&+;N7#Gbuu$)UHFj`dt4P=RaI7jzuVjcr(73_$7-5n-nc>((_aC9~fkv A$^ZZW delta 150 zcmdnacabrDIWI340}!mp_?2M^q#uJgFu(+5d=>&SrZc24q%h_%Y=G)Yb5iY! aIDle|KwK<4c@~=#_XP$SASz-5iU0rSsO#(vLwL7+{AoKKD&jPt{{$NM%gnOl8hugUP3Gtzlcn z%)qc3h#?@IIf^}nJD5R}XW}#)nJVt0)U=$`UM<>Vm7DD@jG91SiVvNKq(Na$|xxxnIhk;U-}i{l4&7JjA%ZV)Wu H2dV}D{1P!b delta 105 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 delta 536 zcmZurze^lJ6rQ=;U$^U?r@25>#MQ)u4d!B#!XPP46M}HqOcO4*$n(WfjQ(py|Teq)3x4q_pzQTqQWny!UKv*g)JTC7;Fhwdd!n8)-v1{z6@Akup?$<$U?;K z5n=7b!#JDJ0f}3Gwe8!O*1?#U?>=xS(madli`o|XIL+cl?Ez0x;G?p3fM*E@Z1&1j z@=tlj5&MI5ob63^a*!7_{n}V`abn%f@{cg5kv9>;av!TOuTHEe=%NT69TwCN>x~^D z3@$?Z52ca%@AMr{*B+~$yZ&@p!zUPOt157}Cc-F+U`0z#fyUJYVkFC|a*tP55yc%? z!UT(^B{>*o;~exqm{Z>$Z0*)FQ>|Z>sVKlK>yL8aeZ6A=#y!&gdhRy@dZ;nH@wR22 yRD!>PP1Gp9;*_ZK?t;4P_Fg`_BKO>1WcBLq{e72WRUJND>yQ?GP5+r_EN=mTGKWb3 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 0000000000000000000000000000000000000000..2afa2f470d35c7b690eb75f0c1adf2f0219c398a GIT binary patch literal 1520 zcmZt`J#X7q@R5=zl9Fu6QJ_Y0s}=|v%TOh^0cyZ4+N!qYe#CB2J3t{IASk|PnF>Et zl9H`X9y)Z)7XJdZg*9a8(6M7i3gBS8DL|HHQ{YUQdL%{FL2~3f-uKOhzu3!~TKgN+#2WFoH-5a$ttK%WZq3y}yj?m2*-m1-___@Gk;hp$ksK9vqwXKjWW#b)MI)3|ag(y& zZdKwmE%zN$QY<1n1k+T{QgzuHN)O183O2D+SyO)@G(8|z+q8*f$U313M|Cvv{0S5Q zXD#aTiKG#u;~deXVj2!H94gKtO0okcVG_eUmSl`62PuzC3r0gQ4GHFfI8c&ff*>Bm z=MGh(VSBG~o$^wUQj(}BNiaNpjR2jNq@Vk;<{JZ-R1MXELM{JHY2H4Tdp)@ghM4q- zfr+6EEq_$$V&mSyH`2ZR?H{GxAGWsd(Dd9wB{ofM23^?oN7VACj;6m>I}PYh)31jL zn@6%WBM-=l6Ox%N=-h#-laLjgrbX0_@jWzDS2#Q6RfjKQ^rgc28DFU4iKJ|1VU1ZEfviX}14b zZ)o`!G(bEM_P>Bm=g-rHrPG}$hlG{iM32Aq2k)(XHQ^f`-9$Dk7om>)yM_ z6`$s=yM@(<1Fx|9cl^mswSM(%ZcK_BUU9?C zeg@9&a`mj~EmtSYHE+4*X6qNZcir;svw>H>{ZHO4Hz(z$S8lr5or~NJw^Tj*)GJjV z5B?f@>pR~1U2pv-_dfCN_ubN9QW|)rftx*^rnvmVG$9D$3k2w;kEXHI5_kHY|5zVI zTd(l+M%eipZr8#;PAzJ`bqmaBYNm&AJq%|HuA5GN^-A}Pt1T(^QCsA>QMj+|O_6Sz}RRI;t~BX)~eF;Hb7D7|NuGDRx< zu;X^|(4k|t`Y%vh*h7X689Nr8D1d|TrUG5kO@T9I>OE3a<2H|ck9Y6xes}Ng9)HSa zWd_C{8Abmt!7zVOCLa8ZxcUl+9~s0T)?nH!d^v*~B-#mG#ah1h+jD*R2^y(&vY2fMCr_M9q5xk#^(kLn)G7%f=+Lv9a-i zs++p2YX*_;<3j^?X?+N%qgIn}pKVu@B%^t*rFLzsxfqf3(AEc-UBtbKs6KsP|zGGX4Eq4TDH6{Me1i>^5Ymr4Mk#%1y|z-ZQ^|Lt@{2}eS3$< z))3Eb#xKkjE%vL1@{KjXir4W>*HiFg+y$4ma$?y>&QR-Og;r4c_eLpD%iF3wFJWzX zYST*^F7!S)&tW;6KU0B`ZcN10ALKw>{aFldeliy8fmomNiDlvJ-ZaBV6)Jmok}v<6 zf7>stJvj~vYtNFuulQ}%H*LS*j0;XsaQvJ*$(Q`{`uRanULTj0pse`0jY+=fmu{VZ z7?f^3U3u2>OO0`<5tJH!ZVMp&%AND$pmOK8WxvuKSDHbk>F4fF@&&)RcK%LKTzh)( z>({~NPO!NbY##UzyTL=pFS_HR8x&nX=S|bX^1_stB>4pc%S*aU6X_-4>~s3q>+#X6 zA}L16uc1yY`s>u<3fQZlM$$8R*D?>Io{;7iVf%!2kFxnb#SOu0K)n(_in{J&`!=xj zN94G$OcN~2LWbEJKJ#AmPGaJ08m literal 0 HcmV?d00001 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})