Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #1

Merged
merged 20 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ebextensions/django.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
option_settings:
aws:elasticbeanstalk:application:environment:
DJANGO_SETTINGS_MODULE: "core.settings.local"
DJANGO_SETTINGS_MODULE: "core.settings.development"
PYTHONPATH: "/var/app/current:$PYTHONPATH"
aws:elasticbeanstalk:container:python:
WSGIPath: "core.wsgi:application"
Expand Down
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ DB_HOST=localhost
DB_PORT=5432

# Sentry
SENTRY_DSN=https://a99727fdc6779777b97708e7c204ef59@o1418275.ingest.sentry.io/4505790033756160
SENTRY_DSN=SENTRY_DSN
14 changes: 14 additions & 0 deletions .env.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# General
DEBUG=True
SECRET_KEY=django-insecure-4yhv*+)otu387820u@x)kts4$k%&evk&_j53^2q$#hmwte_wsc
API_KEY=API_KEY

# Database
DB_NAME=nodeme
DB_USER=postgres
DB_PASSWORD=posrgres
DB_HOST=localhost
DB_PORT=5432

# Sentry
SENTRY_DSN=SENTRY_DSN
2 changes: 1 addition & 1 deletion .env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ DB_HOST=localhost
DB_PORT=5432

# Sentry
SENTRY_DSN=https://a99727fdc6779777b97708e7c204ef59@o1418275.ingest.sentry.io/4505790033756160
SENTRY_DSN=SENTRY_DSN
14 changes: 14 additions & 0 deletions .env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# General
DEBUG=True
SECRET_KEY=django-insecure-4yhv*+)otu387820u@x)kts4$k%&evk&_j53^2q$#hmwte_wsc
API_KEY=API_KEY

# Database
DB_NAME=nodeme
DB_USER=postgres
DB_PASSWORD=posrgres
DB_HOST=localhost
DB_PORT=5432

# Sentry
SENTRY_DSN=SENTRY_DSN
2 changes: 1 addition & 1 deletion .env.prod
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ DB_HOST=localhost
DB_PORT=5432

# Sentry
SENTRY_DSN=https://a99727fdc6779777b97708e7c204ef59@o1418275.ingest.sentry.io/4505790033756160
SENTRY_DSN=SENTRY_DSN
Empty file removed .env.sample
Empty file.
43 changes: 43 additions & 0 deletions .github/workflows/dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## name of our workflow
#name: Django CI/CD Workflow
#
## triggers for our workflow
#on:
# push:
# branches: [ main ]
# pull_request:
# branches: [ main ]
#
#jobs:
# build:
# runs-on: ubuntu-latest
# services:
# postgres_main:
# image: postgres:12
# env:
# POSTGRES_USER: { secrets.POSTGRES_USER }
# POSTGRES_PASSWORD: { secrets.POSTGRES_PASSWORD }
# POSTGRES_DB: { secrets.POSTGRES_DB }
# ports:
# - 5432:5432
# options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
# steps:
# - name: Checkout code
# uses: actions/checkout@v2
# - name: Set up Python 3.6
# uses: actions/setup-python@v2
# with:
# python-version: 3.6
# - name: Install requirements
# run: pip install -r requirements.txt
# - name: Run Tests
# env:
# DJANGO_SECRET_KEY: { secrets.DJANGO_SECRET_KEY }
# POSTGRES_DB: { secrets.POSTGRES_DB }
# POSTGRES_HOST: { secrets.POSTGRES_HOST }
# POSTGRES_USER: { secrets.POSTGRES_USER }
# POSTGRES_PASSWORD: { secrets.POSTGRES_PASSWORD }
# POSTGRES_PORT: { secrets.POSTGRES_PORT }
# DEBUG: "0"
# run: |
# python manage.py test
16 changes: 0 additions & 16 deletions Dockerfile

This file was deleted.

83 changes: 76 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Tech Stack
# Social Link Project

# Technology Stack - Backend, DevOps
# Github: https://github.com/features/, https://docs.github.com/en
* Programs: Chrome, Discord, Figma, Postman, Slack, Trello
* Cloud Platform: Digital Ocean App Platform
* IDE: PyCharm -> https://www.jetbrains.com/pycharm/
* Admin Panel: Django Admin, Postman
* Programming Language: Python
* Web Framework: Django
* REST Framework: Django Rest Framework -> https://www.django-rest-framework.org/
Expand All @@ -13,7 +20,7 @@
* Other: OAuth2, Auth Token, Basic Authentication, Session Authentication, Token Authentication, JWT Authentication, RemoteUserAuthentication, SessionAuthentication, CustomAuthentication
* Package Installer -> PIP
* Dependency Management -> Virtualenv
* Protecting Resources -> .env
* Protecting Resources -> .env by Local, Dev, Prod
* Dependencies -> requirements.txt
* Project Description -> README.md
* LICENSE
Expand Down Expand Up @@ -54,6 +61,63 @@
)
* Exception Handler, Error Handling -> https://www.django-rest-framework.org/api-guide/exceptions/, https://medium.com/turkcell/request-validation-and-custom-exception-handling-in-django-rest-framework-649fddecb415

# Technology Stack - Frontend
* Language -> JavaScript
* Framework -> React
* State Management -> Redux
* UI Framework -> Material UI
* UI Components -> React Bootstrap
* UI Design -> Figma
* AI -> Locofy
* IDE -> WebStorm - https://www.jetbrains.com/webstorm/
* .env By Local, Dev, Prod
* .gitignore
* Package Installer -> NPM

# Technology Stack - Mobile
* Language -> JavaScript
* Framework -> React, React Native
* State Management -> Redux
* Mobile Platform -> Expo to iOS, Android
* Design -> Figma
* AI -> Locofy
* IDE -> WebStorm - https://www.jetbrains.com/webstorm/
* .env By Local, Dev, Prod
* .gitignore

# Technology Stack - Project Management
* Project Management -> Trello
* Project Management Approach -> Agile in Trello
* Agile Framework -> Scrum, Kanban
* Agile Methodology -> Sprint
* Agile Ceremonies -> Sprint Planning, Daily Scrum, Sprint Review, Sprint Retrospective
* Agile Artifacts -> Product Backlog, Sprint Backlog, Burndown Chart
* Agile Roles -> Product Owner, Scrum Master, Development Team
* Communication -> Discord, Slack
* Notification -> Slack
* File Sharing -> Google Drive
* Documentation -> Notion
* Design & Boards -> Figma
* Version Control -> Git
* Githost -> GitHub

## About Product
Link in Profile Apps like linktr.ee, linkme, heylink

## Design Samples
* https://www.figma.com/community/file/1187422022288947321/devlinks-projeto-discover
* https://www.figma.com/community/file/1279164071673230245/linktree-ui-free-ui-kit-recreated
* https://www.figma.com/community/file/1140170887273934289/links-ui-design
* https://www.figma.com/community/file/1289786610304060562/cardu
* https://www.figma.com/community/file/1192950040338521792/figtree-social-links
* https://www.figma.com/community/file/846568099968305613/littlelink-template
* https://www.figma.com/community/file/867431645276958703/build-a-link-in-bio-for-free-community
* https://www.figma.com/community/file/1135234747622451930/personal-linktree
* https://www.figma.com/community/file/1063388536323425656/social-network-app-freebies

## Features
* Health Check

## Sources
### Core
* https://hevodata.com/learn/rest-api-best-practices/
Expand Down Expand Up @@ -232,11 +296,16 @@ myproject_website/

### Django
#### Local
* python manage.py makemigrations
* python manage.py migrate
* python manage.py collectstatic
* python manage.py createsuperuser
* python manage.py runserver
* python -m venv venv
* source venv/bin/activate
* pip install -r requirements.txt
* python manage.py makemigrations
* python manage.py migrate
* python manage.py collectstatic
* python manage.py createsuperuser
* python manage.py runserver
* Create .env file from env.base
* Edit manage.py, wsgi.py, asgi.py for your environment

#### DEV in AWS Elastic Beanstalk
* deactivate
Expand Down
4 changes: 3 additions & 1 deletion apps/common/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ def trigger_error(request):
division_by_zero = 1 / 0


@api_view(['GET'])
def health_check(request):
return HttpResponse("Health Check Status: Stable", status=200)
return Response({'message': 'Hello, world!'}, status=200)
#return HttpResponse("Health Check Status: Stable", status=200)


def trigger_error_exception(request):
Expand Down
5 changes: 4 additions & 1 deletion apps/links/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
TagView,
)
from apps.links.api.views import (
GenericCustomLinkView,
ListCustomLinkView,
ListCreateCustomLinkView
)


Expand All @@ -12,5 +14,6 @@

urlpatterns = [
path('tags', TagView.as_view(), name='list'),
path('custom-links', ListCustomLinkView.as_view(), name='custom-link-list'),
path('custom-links', GenericCustomLinkView.as_view(), name='custom-link-generics'),
path('custom-links-generics', ListCreateCustomLinkView.as_view(), name='custom-link-generics'),
]
81 changes: 80 additions & 1 deletion apps/links/api/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from apps.tags.models import Tag
from apps.links.models import CustomLink
from rest_framework.generics import get_object_or_404, ListAPIView
from rest_framework.generics import get_object_or_404, ListAPIView, ListCreateAPIView
from rest_framework.views import APIView
from rest_framework import authentication, permissions
from rest_framework.response import Response
from rest_framework import status
from rest_framework.decorators import api_view

from apps.tags.api.serializers import TagSerializer
from apps.links.api.serializers import CustomLinkSerializer
Expand All @@ -16,9 +21,83 @@ def get_queryset(self):


class ListCustomLinkView(ListAPIView):
queryset = CustomLink.objects.all()
serializer_class = CustomLinkSerializer
ordering_fields = ['created_at']

def get_queryset(self):
return CustomLink.objects.filter(user=self.request.user)

def create(self, request, *args, **kwargs):
serializer = CustomLinkSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=self.request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class GenericCustomLinkView(ListCreateAPIView):
queryset = CustomLink.objects.all()
serializer_class = CustomLinkSerializer
ordering_fields = ['created_at']

def get_queryset(self):
return CustomLink.objects.filter(user=self.request.user)


# Class Based API Views
class ListCreateCustomLinkView(APIView):
"""
View to list all users in the system.

* Requires token authentication.
* Only authenticated users are able to access this view.
"""
authentication_classes = [authentication.TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]

def get(self, request, format=None):
"""
Return a list of all custom links.
"""
custom_links = CustomLink.objects.filter(user=self.request.user)
serializer = CustomLinkSerializer(custom_links, many=True)
return Response(serializer.data)

def post(self, request, format=None):
"""
Create a new custom link.
"""
serializer = CustomLinkSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=self.request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def custom_link_detail(request, pk):
"""
Retrieve, update or delete a custom link.
"""
custom_link = get_object_or_404(CustomLink, pk=pk)
# OR
# try:
# custom_link = CustomLink.objects.get(pk=pk)
# except CustomLink.DoesNotExist:
# return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = CustomLinkSerializer(custom_link)
return Response(serializer.data)

elif request.method == 'PUT':
serializer = CustomLinkSerializer(custom_link, data=request.data)
if serializer.is_valid():
serializer.save(user=request.user)
return Response(serializer.data, status=status.HTTP_200_OK)
# return Response(status=status.HTTP_204_NO_CONTENT
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

elif request.method == 'DELETE':
custom_link.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Loading