diff --git a/.github/workflows/server_deploy.yaml b/.github/workflows/server_deploy.yaml new file mode 100644 index 00000000..28f0bb9f --- /dev/null +++ b/.github/workflows/server_deploy.yaml @@ -0,0 +1,31 @@ +name: Webserver deploy + +on: + push: + paths: + - 'django-server/**' + - '.github/workflows/server_deploy.yaml' + +jobs: + build: + name: Checkout and deploy + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@master + with: + ref: ${{ github.ref }} # checkout to branch which was pushed + - name: Deploy to Heroku + if: job.status == 'success' + run: | + rm -rf .git + git clone https://heroku:${{ secrets.HEROKU_API_KEY }}@git.heroku.com/eaterslab.git # clone repo from heroku server + cd eaterslab # folder on deploy server + find . -maxdepth 1 ! -path './.git' ! -path '.' -exec rm -rf {} + # remove all files excluding git repo info and current path + git config --global user.email "${{ secrets.HEROKU_DEPLOY_EMAIL }}" # deploy as specified user + git config --global user.name "${{ secrets.HEROKU_DEPLOY_NAME }}" + git commit . -m "cleaned local repo" # commit and push all files + cp -r ../django-server/server/* ./ # copy new version of server + git add . + git commit . -m "deploy full refresh from ${{ github.ref }}" # commit and push all files + git push diff --git a/.gitignore b/.gitignore index 0fc5eabb..0dca1bef 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ __pycache__/ django-server/server/db.sqlite3 .env django-server/serverenv/* +django-server/server/static/ # IDEs .vscode diff --git a/django-server/server-env-setup.sh b/django-server/server-env-setup.sh old mode 100644 new mode 100755 index c4c5b765..08d16342 --- a/django-server/server-env-setup.sh +++ b/django-server/server-env-setup.sh @@ -1,12 +1,9 @@ #!/bin/bash -# This script assumes you have python3, pip and virtualenv installed -# (Sometimes you have to apt-get install python3-venv) -# https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/ -echo "Starting installation" -python3 -m venv serverenv -source serverenv/bin/activate -pip install django -pip install django-environ -pip install djangorestframework +# This script assumes you have python3, pip and pipenv installed +# you can install pipenv using pip3 install pipenv +echo "Starting installation of virtual environment" +cd server +pipenv install +pipenv shell echo "Done" diff --git a/django-server/server/server/.env.sample b/django-server/server/.env.sample similarity index 100% rename from django-server/server/server/.env.sample rename to django-server/server/.env.sample diff --git a/django-server/server/Pipfile b/django-server/server/Pipfile new file mode 100644 index 00000000..88f8caaa --- /dev/null +++ b/django-server/server/Pipfile @@ -0,0 +1,19 @@ +[[source]] + +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[requires] + +python_version = "3" + +[packages] + +psycopg2-binary = "*" +django-heroku = "*" +gunicorn = "*" +django = "*" +django-environ = "*" +djangorestframework = "*" +whitenoise = "*" diff --git a/django-server/server/Procfile b/django-server/server/Procfile new file mode 100644 index 00000000..05aeb4cf --- /dev/null +++ b/django-server/server/Procfile @@ -0,0 +1,2 @@ +release: python manage.py makemigrations; python manage.py migrate --no-input +web: gunicorn server.wsgi diff --git a/django-server/server/api/__init__.py b/django-server/server/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django-server/server/api/admin.py b/django-server/server/api/admin.py new file mode 100644 index 00000000..7e5f003a --- /dev/null +++ b/django-server/server/api/admin.py @@ -0,0 +1,4 @@ +from django.contrib import admin +from .models import Cafeteria + +admin.site.register(Cafeteria) diff --git a/django-server/server/api/apps.py b/django-server/server/api/apps.py new file mode 100644 index 00000000..d87006dd --- /dev/null +++ b/django-server/server/api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + name = 'api' diff --git a/django-server/server/api/migrations/__init__.py b/django-server/server/api/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django-server/server/api/models.py b/django-server/server/api/models.py new file mode 100644 index 00000000..9311dd8c --- /dev/null +++ b/django-server/server/api/models.py @@ -0,0 +1,14 @@ +from django.db import models +from django.core.validators import MinValueValidator, MaxValueValidator + + +class Cafeteria(models.Model): + name = models.CharField(max_length=128) + description = models.CharField(max_length=256) + sub_description = models.CharField(max_length=512) + latitude = models.FloatField(validators=[MinValueValidator(-90.0), MaxValueValidator(90.0)]) + longitude = models.FloatField(validators=[MinValueValidator(-180.0), MaxValueValidator(180.0)]) + capacity = models.IntegerField(validators=[MinValueValidator(1)]) + + def __str__(self): + return self.name diff --git a/django-server/server/api/serializers.py b/django-server/server/api/serializers.py new file mode 100644 index 00000000..9e73765f --- /dev/null +++ b/django-server/server/api/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from .models import Cafeteria + + +class CafeteriaSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Cafeteria + fields = ['id', 'name', 'description', 'sub_description', 'longitude', 'latitude', 'capacity'] diff --git a/django-server/server/api/tests.py b/django-server/server/api/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/django-server/server/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/django-server/server/api/urls.py b/django-server/server/api/urls.py new file mode 100644 index 00000000..cb764f70 --- /dev/null +++ b/django-server/server/api/urls.py @@ -0,0 +1,10 @@ +from django.urls import include, path +from rest_framework import routers +from . import views + +router = routers.DefaultRouter() +router.register(r'cafeteria', views.CafeteriaViewSet) + +urlpatterns = [ + path('', include(router.urls)) +] diff --git a/django-server/server/api/views.py b/django-server/server/api/views.py new file mode 100644 index 00000000..3d6f0e4b --- /dev/null +++ b/django-server/server/api/views.py @@ -0,0 +1,12 @@ +from rest_framework import viewsets + +from .serializers import CafeteriaSerializer + +from .models import Cafeteria + + +# TODO: handle different roles for API views + +class CafeteriaViewSet(viewsets.ModelViewSet): + queryset = Cafeteria.objects.all().order_by('id') + serializer_class = CafeteriaSerializer diff --git a/django-server/server/server/settings.py b/django-server/server/server/settings.py index 99cf7b02..39c7fd6a 100644 --- a/django-server/server/server/settings.py +++ b/django-server/server/server/settings.py @@ -43,10 +43,12 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'rest_framework', + 'api.apps.ApiConfig', # API app ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', + 'whitenoise.middleware.WhiteNoiseMiddleware', # for static files handling on deploy 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -76,12 +78,23 @@ WSGI_APPLICATION = 'server.wsgi.application' +# Configuration for rest_framework to get only the json data +# from the api calls to specified urls as default + +REST_FRAMEWORK = { + 'DEFAULT_RENDERER_CLASSES': [ + 'rest_framework.renderers.JSONRenderer', + # Uncomment to get the API renderer for browser view + # 'rest_framework.renderers.BrowsableAPIRenderer', + ] +} + + # Database # https://docs.djangoproject.com/en/3.0/ref/settings/#databases - def select_database(): - if env.bool('USE_POSTGRES', default=False): + if env.bool('DB_DEPLOY', default=False): return env.db() return { 'ENGINE': 'django.db.backends.sqlite3', @@ -127,7 +140,9 @@ def select_database(): USE_TZ = True -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/3.0/howto/static-files/ +# Heroku static files configuration to get it working on deploy +STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATIC_URL = '/static/' +STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' +os.makedirs(STATIC_ROOT, exist_ok=True) diff --git a/django-server/server/server/urls.py b/django-server/server/server/urls.py index e729eb60..5d6d7d0c 100644 --- a/django-server/server/server/urls.py +++ b/django-server/server/server/urls.py @@ -16,7 +16,9 @@ from django.contrib import admin from django.urls import include, path + urlpatterns = [ path('', include('home.urls')), path('admin/', admin.site.urls), + path('api/beta/', include('api.urls')), ]