Skip to content

Commit 158902a

Browse files
authored
Merge pull request #23 from Kalgoc/feat/piggies
Piggies
2 parents 1c21d95 + a43d4cb commit 158902a

14 files changed

+248
-0
lines changed

Diff for: piggies/__init__.py

Whitespace-only changes.

Diff for: piggies/admin.py

Whitespace-only changes.

Diff for: piggies/apps.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class UserExpenseTypeConfig(AppConfig):
5+
default_auto_field = "django.db.models.BigAutoField"
6+
name = "piggies"

Diff for: piggies/migrations/0001_initial.py

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Generated by Django 5.0.6 on 2024-06-20 20:00
2+
3+
import django.db.models.deletion
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
initial = True
11+
12+
dependencies = [
13+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14+
]
15+
16+
operations = [
17+
migrations.CreateModel(
18+
name="Piggies",
19+
fields=[
20+
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
21+
(
22+
"piggy",
23+
models.ForeignKey(
24+
on_delete=django.db.models.deletion.CASCADE,
25+
related_name="friend",
26+
to=settings.AUTH_USER_MODEL,
27+
to_field="username",
28+
),
29+
),
30+
(
31+
"username",
32+
models.ForeignKey(
33+
on_delete=django.db.models.deletion.CASCADE,
34+
related_name="origin",
35+
to=settings.AUTH_USER_MODEL,
36+
to_field="username",
37+
),
38+
),
39+
],
40+
),
41+
]

Diff for: piggies/migrations/0002_alter_piggies_piggy.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Generated by Django 5.0.6 on 2024-06-20 20:37
2+
3+
import django.db.models.deletion
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
("piggies", "0001_initial"),
12+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
13+
]
14+
15+
operations = [
16+
migrations.AlterField(
17+
model_name="piggies",
18+
name="piggy",
19+
field=models.ForeignKey(
20+
on_delete=django.db.models.deletion.CASCADE,
21+
related_name="friend",
22+
to=settings.AUTH_USER_MODEL,
23+
to_field="user_id",
24+
),
25+
),
26+
]

Diff for: piggies/migrations/0003_alter_piggies_username.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Generated by Django 5.0.6 on 2024-06-20 20:58
2+
3+
import django.db.models.deletion
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
("piggies", "0002_alter_piggies_piggy"),
12+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
13+
]
14+
15+
operations = [
16+
migrations.AlterField(
17+
model_name="piggies",
18+
name="username",
19+
field=models.ForeignKey(
20+
on_delete=django.db.models.deletion.CASCADE,
21+
related_name="origin",
22+
to=settings.AUTH_USER_MODEL,
23+
to_field="user_id",
24+
),
25+
),
26+
]

Diff for: piggies/migrations/__init__.py

Whitespace-only changes.

Diff for: piggies/models.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from django.db import models
2+
from django.conf import settings
3+
4+
5+
class Piggies(models.Model):
6+
username = models.ForeignKey(
7+
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, to_field="user_id", related_name="origin"
8+
)
9+
piggy = models.ForeignKey(
10+
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, to_field="user_id", related_name="friend"
11+
)

Diff for: piggies/serializers.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from rest_framework import serializers
2+
from .models import Piggies
3+
4+
5+
class PiggiesSerializer(serializers.ModelSerializer):
6+
id = serializers.ReadOnlyField()
7+
8+
class Meta:
9+
model = Piggies
10+
fields = "__all__"
11+
12+
def create(self, validated_data):
13+
return Piggies.objects.create(**validated_data)

Diff for: piggies/tests.py

Whitespace-only changes.

Diff for: piggies/urls.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from django.urls import path
2+
from .views import PiggiesViewSet, NotPiggiesViewSet
3+
4+
urlpatterns = [
5+
path(
6+
"",
7+
PiggiesViewSet.as_view({"get": "list", "post": "create"}),
8+
name="piggies",
9+
),
10+
path(
11+
"users/",
12+
NotPiggiesViewSet.as_view({"get": "users"}),
13+
name="not_piggies",
14+
),
15+
]

Diff for: piggies/views.py

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
from rest_framework import viewsets, status
2+
from rest_framework.response import Response
3+
import jwt
4+
from django.contrib.auth import get_user_model
5+
6+
from authentication.decorators import cognito_authenticated
7+
8+
from .models import Piggies
9+
from .serializers import PiggiesSerializer
10+
11+
12+
class PiggiesViewSet(viewsets.ViewSet):
13+
def get_user_id_from_token(self, request):
14+
try:
15+
authorization_header = request.headers.get("Authorization")
16+
if not authorization_header:
17+
raise Exception("Authorization header not found")
18+
19+
token = authorization_header.split()[1]
20+
decoded_token = jwt.decode(token, options={"verify_signature": False})
21+
username = decoded_token.get("username")
22+
if not username:
23+
raise Exception("User ID not found in token")
24+
return username
25+
except jwt.DecodeError:
26+
raise Exception("Invalid token")
27+
except jwt.ExpiredSignatureError:
28+
raise Exception("Expired token")
29+
except Exception as e:
30+
raise Exception(f"Error decoding token: {e}")
31+
32+
@cognito_authenticated
33+
def list(self, request):
34+
try:
35+
username = self.get_user_id_from_token(request)
36+
piggies = Piggies.objects.filter(username=username)
37+
serializer = PiggiesSerializer(piggies, many=True)
38+
return Response(data=serializer.data)
39+
except Piggies.DoesNotExist:
40+
return Response({"error": "Piggies not found"}, status=status.HTTP_404_NOT_FOUND)
41+
except Exception as e:
42+
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
43+
44+
@cognito_authenticated
45+
def create(self, request):
46+
try:
47+
username = self.get_user_id_from_token(request)
48+
data = request.data.copy()
49+
data["username"] = username
50+
51+
serializer = PiggiesSerializer(data=data)
52+
if serializer.is_valid():
53+
serializer.save()
54+
response = {
55+
"username": serializer.data["username"],
56+
"piggy": serializer.data["piggy"],
57+
}
58+
return Response(data=response, status=status.HTTP_201_CREATED)
59+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
60+
except Exception as e:
61+
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
62+
63+
64+
class NotPiggiesViewSet(viewsets.ViewSet):
65+
def get_user_id_from_token(self, request):
66+
try:
67+
authorization_header = request.headers.get("Authorization")
68+
if not authorization_header:
69+
raise Exception("Authorization header not found")
70+
71+
token = authorization_header.split()[1]
72+
decoded_token = jwt.decode(token, options={"verify_signature": False})
73+
username = decoded_token.get("username")
74+
if not username:
75+
raise Exception("User ID not found in token")
76+
return username
77+
except jwt.DecodeError:
78+
raise Exception("Invalid token")
79+
except jwt.ExpiredSignatureError:
80+
raise Exception("Expired token")
81+
except Exception as e:
82+
raise Exception(f"Error decoding token: {e}")
83+
84+
def users(self, request):
85+
try:
86+
username = self.get_user_id_from_token(request)
87+
User = get_user_model()
88+
users = [{"user_id": str(x.user_id), "first_name": x.first_name} for x in User.objects.all()]
89+
90+
filtered_users = []
91+
92+
for user in users:
93+
if user["user_id"] != username:
94+
filtered_users.append(user)
95+
96+
piggies = Piggies.objects.filter(username=username)
97+
serializer = PiggiesSerializer(piggies, many=True)
98+
99+
final_users = []
100+
101+
for pig in serializer.data:
102+
for user in filtered_users:
103+
if str(pig["piggy"]) != user["user_id"]:
104+
final_users.append(user)
105+
106+
return Response(data=final_users)
107+
except Exception as e:
108+
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

Diff for: piggywallet/settings/base.py

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"debt",
5050
"user_expense_type",
5151
"categories",
52+
"piggies",
5253
]
5354

5455
REST_FRAMEWORK = {

Diff for: piggywallet/urls.py

+1
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@
2626
path("debt/", include("debt.urls")),
2727
path("user_expense_type/", include("user_expense_type.urls")),
2828
path("categories/", include("categories.urls")),
29+
path("piggies/", include("piggies.urls")),
2930
]

0 commit comments

Comments
 (0)