Skip to content

Commit 90d57d1

Browse files
authored
Merge pull request #87 from UNLV-CS472-672/pomodoro_endpoints
Added Pomodoro API Endpoints + CRUD
2 parents 50220c1 + 03722e5 commit 90d57d1

File tree

7 files changed

+161
-3
lines changed

7 files changed

+161
-3
lines changed

backend/apps/pomodoro/managers.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from django.db import models
2+
from django.utils import timezone
3+
4+
class PomodoroSessionManager(models.Manager):
5+
def start_session(self, session_id):
6+
session = self.get(id=session_id)
7+
session.start_time = timezone.now()
8+
session.save()
9+
10+
def pause_session(self, session_id):
11+
session = self.get(id=session_id)
12+
session.is_paused = True
13+
session.save()
14+
15+
def resume_session(self, session_id):
16+
session = self.get(id=session_id)
17+
session.is_paused = False
18+
session.save()
19+
20+
def complete_session(self, session_id):
21+
session = self.get(id=session_id)
22+
session.is_completed = True
23+
session.end_time = timezone.now()
24+
session.save()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.1.6 on 2025-03-26 18:04
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('pomodoro', '0002_alter_petcatalog_image'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='pomodorosession',
15+
name='is_paused',
16+
field=models.BooleanField(default=False),
17+
),
18+
]

backend/apps/pomodoro/models.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from django.db import models
22

3-
# Create your models here.
43
from django.conf import settings
54
from django.utils import timezone
5+
from .managers import PomodoroSessionManager
66

77
class PomodoroSession(models.Model):
88
student = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
@@ -12,6 +12,31 @@ class PomodoroSession(models.Model):
1212
pet_earned = models.BooleanField(default=False)
1313
start_time = models.DateTimeField(auto_now_add=True)
1414
end_time = models.DateTimeField(null=True, blank=True)
15+
is_paused = models.BooleanField(default=False)
16+
17+
objects = PomodoroSessionManager() # Use custom manager
18+
19+
def start(self):
20+
self.start_time = timezone.now()
21+
self.save()
22+
23+
def pause(self):
24+
if not self.is_completed:
25+
self.is_paused = True
26+
self.save()
27+
28+
def resume(self):
29+
if self.is_paused:
30+
self.is_paused = False
31+
self.save()
32+
33+
def cancel(self):
34+
self.delete()
35+
36+
def complete(self):
37+
self.is_completed = True
38+
self.end_time = timezone.now()
39+
self.save()
1540

1641
def __str__(self):
1742
return f"Pomodoro Session ({self.start_time}) - {self.end_time}"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from rest_framework import serializers
2+
from .models import PomodoroSession
3+
4+
5+
class PomodoroSessionSerializer(serializers.ModelSerializer):
6+
class Meta:
7+
model = PomodoroSession
8+
fields = '__all__'

backend/apps/pomodoro/urls.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from django.urls import path
2+
from .views import (
3+
StartPomodoroSession,
4+
PausePomodoroSession,
5+
ResumePomodoroSession,
6+
CancelPomodoroSession,
7+
CompletePomodoroSession,
8+
GetPomodoroSessionStatus,
9+
GetPomodoroSessionHistory,
10+
)
11+
12+
urlpatterns = [
13+
path('api/pomodoro-session/<int:id>/start/', StartPomodoroSession.as_view(), name="start_pomodoro"),
14+
path('api/pomodoro-session/<int:id>/pause/', PausePomodoroSession.as_view(), name="pause_pomodoro"),
15+
path('api/pomodoro-session/<int:id>/resume/', ResumePomodoroSession.as_view(), name="resume_pomodoro"),
16+
path('api/pomodoro-session/<int:id>/cancel/', CancelPomodoroSession.as_view(), name="cancel_pomodoro"),
17+
path('api/pomodoro-session/<int:id>/complete/', CompletePomodoroSession.as_view(), name="complete_pomodoro"),
18+
path('api/pomodoro-session/<int:id>/status/', GetPomodoroSessionStatus.as_view(), name="pomodoro_status"),
19+
path('api/pomodoro-session/history/', GetPomodoroSessionHistory.as_view(), name="pomodoro_history"),
20+
]

backend/apps/pomodoro/views.py

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,65 @@
11
from django.shortcuts import render
22

3-
# Create your views here.
3+
from rest_framework import generics, status
4+
from rest_framework.response import Response
5+
from rest_framework.views import APIView
6+
from .models import PomodoroSession
7+
from .serializers import PomodoroSessionSerializer
8+
9+
class StartPomodoroSession(APIView):
10+
def post(self, request, id):
11+
session = PomodoroSession.objects.filter(id=id).first()
12+
if not session:
13+
return Response({"error": "Pomodoro session not found"}, status=status.HTTP_404_NOT_FOUND)
14+
15+
session.start()
16+
return Response({"message": "Pomodoro session started"}, status=status.HTTP_200_OK)
17+
18+
class PausePomodoroSession(APIView):
19+
def post(self, request, id):
20+
session = PomodoroSession.objects.filter(id=id).first()
21+
if not session:
22+
return Response({"error": "Pomodoro session not found"}, status=status.HTTP_404_NOT_FOUND)
23+
24+
session.pause()
25+
return Response({"message": "Pomodoro session paused"}, status=status.HTTP_200_OK)
26+
27+
class ResumePomodoroSession(APIView):
28+
def post(self, request, id):
29+
session = PomodoroSession.objects.filter(id=id).first()
30+
if not session:
31+
return Response({"error": "Pomodoro session not found"}, status=status.HTTP_404_NOT_FOUND)
32+
33+
session.resume()
34+
return Response({"message": "Pomodoro session resumed"}, status=status.HTTP_200_OK)
35+
36+
class CancelPomodoroSession(APIView):
37+
def post(self, request, id):
38+
session = PomodoroSession.objects.filter(id=id).first()
39+
if not session:
40+
return Response({"error": "Pomodoro session not found"}, status=status.HTTP_404_NOT_FOUND)
41+
42+
session.cancel()
43+
return Response({"message": "Pomodoro session canceled"}, status=status.HTTP_200_OK)
44+
45+
class CompletePomodoroSession(APIView):
46+
def post(self, request, id):
47+
session = PomodoroSession.objects.filter(id=id).first()
48+
if not session:
49+
return Response({"error": "Pomodoro session not found"}, status=status.HTTP_404_NOT_FOUND)
50+
51+
session.complete()
52+
return Response({"message": "Pomodoro session completed"}, status=status.HTTP_200_OK)
53+
54+
class GetPomodoroSessionStatus(APIView):
55+
def get(self, request, id):
56+
session = PomodoroSession.objects.filter(id=id).first()
57+
if not session:
58+
return Response({"error": "Pomodoro session not found"}, status=status.HTTP_404_NOT_FOUND)
59+
60+
serializer = PomodoroSessionSerializer(session)
61+
return Response(serializer.data, status=status.HTTP_200_OK)
62+
63+
class GetPomodoroSessionHistory(generics.ListAPIView):
64+
queryset = PomodoroSession.objects.all()
65+
serializer_class = PomodoroSessionSerializer

backend/backend/urls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
3030
path('notifications/', include('apps.notifications.urls')),
3131
path('lessons/', include('apps.lessons.urls')),
32-
path('submissions/', include('apps.submissions.urls'))
32+
path('submissions/', include('apps.submissions.urls')),
33+
path('pomodoro/', include('apps.pomodoro.urls')),
3334
]
3435

0 commit comments

Comments
 (0)