Skip to content

Commit

Permalink
Update readme, improvements of code.
Browse files Browse the repository at this point in the history
  • Loading branch information
pmlynarek committed Apr 17, 2020
1 parent 6737a7c commit 4fd0a82
Show file tree
Hide file tree
Showing 13 changed files with 111 additions and 25 deletions.
3 changes: 2 additions & 1 deletion .isort.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
line_length = 88
multi_line_output = 3
include_trailing_comma = True
known_third_party = django,django_filters,djchoices,factory,moviewarehouse,requests,rest_framework
known_first_party = moviewarehouse
known_third_party = django,django_filters,djchoices,drf_yasg,factory,requests,rest_framework
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,45 @@
# movie-warehouse
# Welcome to movie-warehouse

Simple test application to storing and looking for data about movies. You can also add some comments to your downloaded movies and get top movies(ranking is determined by count of comments).

## Requirements

* Docker
* Docker Compose

## Setup
* Clone the repository
* Go to project directory
* mv example.env to .env and replace `xxx` values for your own(OMDB_API_KEY you can get from http://www.omdbapi.com/)
* make up

## Quickstart guide

Start the project:

make up

Bring project down:

make down

To test the project run:

make test

To build project:

make build

## Documentation

You can easily review all endpoints using these links:

* /swagger/ - http://localhost:8000/swagger/
* /redoc/ - http://localhost:8000/redoc/

### Additional packages

* django-choices - Choices are much cleaner, than standard - some additional functions
* factory-boy - Transparent fixtures, speeding up writing tests
* drf-yasg - Complex documentation without any effor
1 change: 1 addition & 0 deletions app/moviewarehouse/movies/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.contrib import admin
from django.template.defaultfilters import truncatechars
from django.utils.translation import gettext as _

from moviewarehouse.movies.models import Comment, Movie


Expand Down
1 change: 1 addition & 0 deletions app/moviewarehouse/movies/filters.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django_filters import rest_framework as filters

from moviewarehouse.movies.models import Movie


Expand Down
1 change: 1 addition & 0 deletions app/moviewarehouse/movies/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.db import models
from django.template.defaultfilters import truncatechars
from django.utils.translation import gettext as _

from moviewarehouse.movies.choices import RatingChoices


Expand Down
3 changes: 2 additions & 1 deletion app/moviewarehouse/movies/serializers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import re

from moviewarehouse.movies.models import Comment, Movie
from rest_framework import serializers

from moviewarehouse.movies.models import Comment, Movie

NUMBER_PATTERN = re.compile(r"\d+")
FLOAT_NUMBER_PATTERN = re.compile(r"\d+\.\d+")

Expand Down
7 changes: 4 additions & 3 deletions app/moviewarehouse/movies/tests/test_endpoints.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from datetime import datetime, timedelta
from unittest.mock import patch

from rest_framework import status
from rest_framework.reverse import reverse
from rest_framework.test import APITestCase

from moviewarehouse.movies.models import Comment, Movie
from moviewarehouse.movies.tests.factories import (
CommentFactory,
Expand All @@ -9,9 +13,6 @@
mocked_movie_full_data,
mocked_movie_not_found,
)
from rest_framework import status
from rest_framework.reverse import reverse
from rest_framework.test import APITestCase


class MovieViewSetTest(APITestCase):
Expand Down
6 changes: 4 additions & 2 deletions app/moviewarehouse/movies/utils.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import logging
from typing import Tuple

import requests
from django.conf import settings
from rest_framework import status

from moviewarehouse.movies.models import Movie
from moviewarehouse.movies.serializers import MovieSerializer
from rest_framework import status

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


def get_movie_details(title: str) -> [dict, int]:
def get_movie_details(title: str) -> Tuple[dict, int]:
try:
movie = Movie.objects.get(title__iexact=title)
return MovieSerializer(instance=movie).data, status.HTTP_200_OK
Expand Down
24 changes: 10 additions & 14 deletions app/moviewarehouse/movies/viewsets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from django.db.models import Count, F, Q, Window
from django.db.models.functions.window import DenseRank
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status as rest_status
from rest_framework.mixins import CreateModelMixin, ListModelMixin
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet

from moviewarehouse.movies.filters import MovieFilter
from moviewarehouse.movies.models import Comment, Movie
from moviewarehouse.movies.serializers import (
Expand All @@ -11,21 +16,18 @@
TopMovieSerializer,
)
from moviewarehouse.movies.utils import get_movie_details
from rest_framework import status as rest_status
from rest_framework.mixins import CreateModelMixin, ListModelMixin
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet


class TopMovieViewSet(ListModelMixin, GenericViewSet):
queryset = Movie.objects.all()
serializer_class = TopMovieSerializer

def list(self, request, *args, **kwargs):
serializer = TopMovieSearchSerializer(data=request.GET)
def get_queryset(self):
queryset = super().get_queryset()

serializer = TopMovieSearchSerializer(data=self.request.GET)
serializer.is_valid(raise_exception=True)

queryset = self.filter_queryset(self.get_queryset())
queryset = queryset.annotate(
total_comments=Count(
"comments",
Expand All @@ -39,13 +41,7 @@ def list(self, request, *args, **kwargs):
rank=Window(expression=DenseRank(), order_by=F("total_comments").desc()),
)

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
return queryset


class MovieViewSet(ListModelMixin, CreateModelMixin, GenericViewSet):
Expand Down
33 changes: 30 additions & 3 deletions app/moviewarehouse/urls.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
from django.contrib import admin
from django.urls import path
from moviewarehouse.movies.viewsets import CommentViewSet, MovieViewSet, TopMovieViewSet
from django.urls import path, re_path
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
from rest_framework import permissions
from rest_framework.routers import DefaultRouter

from moviewarehouse.movies.viewsets import CommentViewSet, MovieViewSet, TopMovieViewSet

schema_view = get_schema_view(
openapi.Info(
title="Snippets API",
default_version="v1",
contact=openapi.Contact(email="pmlynarek1@gmail.com"),
license=openapi.License(name="MIT License"),
),
public=True,
permission_classes=(permissions.AllowAny,),
)
router = DefaultRouter()
router.register(r"top", TopMovieViewSet, basename="top_movie")
router.register(r"movies", MovieViewSet, basename="movie")
router.register(r"comments", CommentViewSet, basename="comment")


urlpatterns = [path("admin/", admin.site.urls)]
urlpatterns = [
path("admin/", admin.site.urls),
re_path(
r"^swagger(?P<format>\.json|\.yaml)$",
schema_view.without_ui(cache_timeout=0),
name="schema-json",
),
path(
"swagger/",
schema_view.with_ui("swagger", cache_timeout=0),
name="schema-swagger-ui",
),
path("redoc/", schema_view.with_ui("redoc", cache_timeout=0), name="schema-redoc"),
]
urlpatterns += router.urls
1 change: 1 addition & 0 deletions app/requirements/staging.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ django-extensions==2.2.9
ipython==7.11.1
django-filter==2.2.0
factory-boy==2.12.0
drf-yasg==1.17.1
1 change: 1 addition & 0 deletions app/settings/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
# Third party
"django_extensions",
"django_filters",
"drf_yasg",
# Local
"moviewarehouse.movies",
]
Expand Down
9 changes: 9 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DJANGO_SETTINGS_MODULE=settings.dev
DJANGO_SECRET_KEY=xxx

POSTGRES_HOST=db
POSTGRES_DB=moviewarehouse_dev_db
POSTGRES_USER=moviewarehouse_dev_db_user
POSTGRES_PASSWORD=xxx

OMDB_API_KEY=xxx

0 comments on commit 4fd0a82

Please sign in to comment.