Skip to content

Commit

Permalink
Merge pull request #6 from Pogchamp-company/develop
Browse files Browse the repository at this point in the history
Create beta version
  • Loading branch information
AlexandrovRoman committed May 24, 2021
2 parents 3bd07f8 + 0a1df0c commit 6fbcddb
Show file tree
Hide file tree
Showing 99 changed files with 14,520 additions and 532 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,12 @@ dmypy.json


.idea/

src/parser/assets/
src/parser/movies.json
src/parser/persons.json
src/static/ckeditor/
src/static/admin/
src/static/rest_framework/
/src/seed/movies.json
/src/seed/persons.json
84 changes: 73 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Kinopoisk on Django

* [Description](#description)
* [Short](#short)
* [Full](#full)
* [Getting Started](#getting-started)
* [Prerequisites](#prerequisites)
* [Install & Run project](#install--run-project)
* [Seed data](#seed-data)
* [Base (Top 250 kinopoisk movies)](#base-top-250-kinopoisk-movies)
* [Add movie from kinopoisk](#add-movie-from-kinopoisk)
* [Generate movie score](#generate-movie-score)
* [Built With](#built-with)
* [Contributing](#contributing)
* [Code Style](#code-style)
* [Tasks](#tasks)
* [Branch naming](#branch-naming)
* [Authors](#authors)
* [License](#license)
* [Environment variables](#environment-variables)

## Description

### Short
Expand All @@ -14,11 +33,11 @@ watch news

### Prerequisites

1. Python3 [Docs](https://www.python.org)
2. PostgreSQL [Docs](https://www.postgresql.org)
3. Minio [Docs](https://docs.min.io)
1. [Python3](https://www.python.org)
2. [PostgreSQL](https://www.postgresql.org)
3. [Minio](https://docs.min.io)

### Installing
### Install & Run project

1. Clone repo
```shell
Expand All @@ -30,28 +49,66 @@ git clone https://github.com/Pogchamp-company/kinopoisk_on_django.git
pip install -r requirements.txt
```
4. Create PostgreSQL database
5. Set env variables ([Vars](#environment-variables))
5. Set [env variables](#environment-variables)
6. Migrate database
```shell
cd src
# cd src
manage.py migrate
```
7. Run minio
```shell
# cd ..
docker-compose up -d minio
```
8. Initialize Minio buckets
```shell
manage.py initialize_buckets
```
9. Optional: run seeds (generate this (check src/parser/README.md) or download from release)
9. Collect static files
```shell
manage.py collectstatic
```
10. Optional: [run seeds](#seed-data)
11. Run project
```shell
manage.py runserver
```


### Seed data
#### Base (Top 250 kinopoisk movies)
1. [Generate seeders json](https://github.com/Pogchamp-company/kinopoisk_on_django/tree/develop/src/parser#generate-seeds) or download this in [release](https://github.com/Pogchamp-company/kinopoisk_on_django/releases/tag/v0.1-alpha)
2. Run
```shell
manage.py loaddata seed/movies.json
manage.py loaddata seed/persons.json
```
10. Run project
```
3. [Get posters](https://github.com/Pogchamp-company/kinopoisk_on_django/tree/develop/src/parser#collect-images)
4. Run
```shell
manage.py runserver
manage.py load_posters
manage.py load_photos
```
#### Add movie from kinopoisk
[YOUR_API_KEY](https://kinopoiskapiunofficial.tech/)

Run
```shell
manage.py add_kp_movie {movie_id} --api-key {YOUR_API_KEY}
```
#### Generate movie score
Run
```shell
manage.py seed_users {users_count}
manage.py seed_scores
```

## Run tests

<b>!Warning:</b> [seed data](#seed-data) before running tests

```shell
bash run_tests.sh
```


Expand All @@ -62,6 +119,11 @@ manage.py runserver

## Contributing

### Code style
[pep8](https://www.python.org/dev/peps/pep-0008/)

### Tasks

* [Trello Desk](https://trello.com/b/fju3vs7M/kinopoisk-on-django)

### Branch naming
Expand All @@ -78,7 +140,7 @@ manage.py runserver

## License

This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/Pogchamp-company/kinopoisk_on_django/blob/main/LICENSE.md) file for details
This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/Pogchamp-company/kinopoisk_on_django/blob/master/LICENSE.md) file for details


## Environment variables
Expand Down
6 changes: 6 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[pytest]
addopts = -v -p no:warnings --nomigrations
DJANGO_SETTINGS_MODULE = config.settings
testpaths = tests
python_classes = Test*
python_files = test_*.py
6 changes: 5 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ django==3.1.5
djangorestframework==3.12.2
psycopg2-binary==2.8.6
django-minio-backend==2.5.1
Pillow==8.1.2
Pillow==8.1.2
django-ckeditor==6.0.0
WhiteNoise==5.2.0
pytest-django==4.3.0
gunicorn
6 changes: 6 additions & 0 deletions run_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env sh

# Required database env variables
# shellcheck disable=SC2164
cd ./src
pytest
Empty file added src/__init__.py
Empty file.
27 changes: 22 additions & 5 deletions src/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
import os
import sys
from pathlib import Path
from os import getenv
from datetime import timedelta
Expand All @@ -25,7 +26,7 @@
SECRET_KEY = '@oowa+)%q57uxhffto99*-b+mt%63!@r&*#17mqstv&%fr9*2*'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
DEBUG = bool(getenv('DEBUG', False))

ALLOWED_HOSTS = ["*"]

Expand All @@ -38,13 +39,17 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',

'rest_framework',
'django_minio_backend',
'ckeditor',

'movies.apps.MoviesConfig',
'news.apps.NewsConfig',
'person.apps.PersonConfig',
'users.apps.UsersConfig',
'index.apps.IndexConfig'
]

MIDDLEWARE = [
Expand All @@ -57,6 +62,9 @@
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

if not DEBUG:
MIDDLEWARE.append('whitenoise.middleware.WhiteNoiseMiddleware')

ROOT_URLCONF = 'config.urls'

TEMPLATES = [
Expand Down Expand Up @@ -121,13 +129,20 @@

USE_L10N = True

USE_TZ = True
USE_TZ = False

IGNORE_SCORE_PERIOD = timedelta(hours=12)
MIN_SCORE_COUNT_FOR_AVERAGE = 100
MIN_SCORE_COUNT_FOR_TOP_250 = 500

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

if 'collectstatic' in sys.argv or not DEBUG:
STATIC_ROOT = os.path.join(BASE_DIR, "static")
else:
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]

# #################### #
# django_minio_backend #
Expand Down Expand Up @@ -163,13 +178,15 @@
MINIO_SECRET_KEY = getenv('MINIO_SECRET_KEY', 'minio123')
MINIO_USE_HTTPS = False
MINIO_PRIVATE_BUCKETS = [
'gachi'
'images',
'news-images'
]
MINIO_PUBLIC_BUCKETS = [
'images',
'avatars'
]
MINIO_URL_EXPIRY_HOURS = timedelta(days=1) # Default is 7 days (longest) if not defined
MINIO_CONSISTENCY_CHECK_ON_START = True
MINIO_POLICY_HOOKS: List[Tuple[str, dict]] = [
# ('django-backend-dev-private', dummy_policy)
]
LOGIN_URL = '/users/login/'
9 changes: 7 additions & 2 deletions src/config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@


urlpatterns = [
path('', include('index.urls')),
path('admin/', admin.site.urls),
path('', include('news.urls')),
path('news/', include('news.urls')),
path('movie/', include('movies.urls')),
path('person/', include('person.urls'))
path('person/', include('person.urls')),
path('users/', include('users.urls'))
]

handler404 = 'errors_handlers.views.http404_page_not_found'
handler500 = 'errors_handlers.views.http500_internal_server_error'
4 changes: 4 additions & 0 deletions src/config/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@

import os

from django.conf import settings
from django.core.wsgi import get_wsgi_application
from whitenoise import WhiteNoise

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

application = get_wsgi_application()
if not settings.DEBUG:
application = WhiteNoise(application, root=settings.STATIC_ROOT)
Empty file added src/errors_handlers/__init__.py
Empty file.
18 changes: 18 additions & 0 deletions src/errors_handlers/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.shortcuts import render
from django.templatetags.static import static


def http404_page_not_found(request, *args, **kwargs):
return render(request,
'errors/base_error.html',
context=dict(video=static('media/errors/404.mp4'),
error_message='Error 404: Page not found'),
status=404)


def http500_internal_server_error(request, *args, **kwargs):
return render(request,
'errors/base_error.html',
context=dict(video=static('media/errors/500.mp4'),
error_message='Error 500: Internal Server Error'),
status=500)
Empty file added src/index/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions src/index/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class IndexConfig(AppConfig):
name = 'index'
Empty file.
7 changes: 7 additions & 0 deletions src/index/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.urls import path
from .views import SearchView, index

urlpatterns = [
path('', index),
path('search/', SearchView.as_view(), name="search"),
]
43 changes: 43 additions & 0 deletions src/index/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from django.db.models import Q
from django.shortcuts import render
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response

from movies.models import Movie
from movies.serializers import MovieSerializer
from news.models import News
from person.models import Person
from person.serializers import PersonSerializer


def index(request):
context = dict(
preview=Movie.objects.order_by("-id")[:3],
news=News.objects.order_by("-id")[:3]
)

return render(request, 'index/home_page.html', context)


class SearchView(APIView):
movie_serializer_class = MovieSerializer
person_serializer_class = PersonSerializer

def get(self, request: Request):
query_filter = request.GET.get('query')
if not query_filter:
return Response({}, status=status.HTTP_400_BAD_REQUEST)
movies = Movie.objects.filter(
Q(title__icontains=query_filter) | Q(original_title__icontains=query_filter))[:3]
persons = Person.objects.filter(
Q(fullname__icontains=query_filter) | Q(ru_fullname__icontains=query_filter))[:3]

response = {
# 'topResult': {},
'movies': [self.movie_serializer_class(movie).data for movie in movies],
'persons': [self.person_serializer_class(person).data for person in persons]
}

return Response(response, status=status.HTTP_200_OK)
13 changes: 12 additions & 1 deletion src/movies/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
from django.contrib import admin
from .models import Genre, Movie, MovieType, Poster
from .models import Genre, Movie, MovieType, Poster, MovieTrailer

admin.site.register(Genre)
admin.site.register(Movie)
admin.site.register(MovieType)
admin.site.register(Poster)


class MovieTrailerAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
if not form.base_fields['link'].initial:
form.base_fields['link'].initial = 'https://www.youtube.com/embed/'
return form


admin.site.register(MovieTrailer, MovieTrailerAdmin)
Loading

0 comments on commit 6fbcddb

Please sign in to comment.