Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
63 changed files
with
3,080 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__version__ = '0.1.0' | ||
__version__ = "0.1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import logging | ||
|
||
from django.contrib import admin | ||
|
||
from .models import Blog, Post, File, Image, Video, Gallery | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class AdminUserMixin: | ||
def get_changeform_initial_data(self, request): | ||
return {"user": request.user, "author": request.user} | ||
|
||
|
||
class BlogModelAdmin(AdminUserMixin, admin.ModelAdmin): | ||
list_display = ("title", "user") | ||
|
||
|
||
admin.site.register(Blog, BlogModelAdmin) | ||
|
||
|
||
class PostModelAdmin(AdminUserMixin, admin.ModelAdmin): | ||
list_display = ("title", "author", "blog") | ||
|
||
class Media: | ||
js = ("js/cast/ckeditor_fix.js",) | ||
|
||
|
||
admin.site.register(Post, PostModelAdmin) | ||
|
||
|
||
class ImageModelAdmin(AdminUserMixin, admin.ModelAdmin): | ||
list_display = ("pk", "original", "user") | ||
fields = ("user", "original") | ||
|
||
|
||
admin.site.register(Image, ImageModelAdmin) | ||
|
||
|
||
class FileAdmin(AdminUserMixin, admin.ModelAdmin): | ||
list_display = ("original", "user") | ||
fields = ("user", "original") | ||
|
||
|
||
admin.site.register(File, FileAdmin) | ||
|
||
|
||
class VideoModelAdmin(AdminUserMixin, admin.ModelAdmin): | ||
list_display = ("pk", "user") | ||
|
||
def save_model(self, request, obj, form, change): | ||
logger.info("poster: {}".format(obj.poster)) | ||
logger.info("form: {}".format(form.cleaned_data)) | ||
if change and not form.cleaned_data["poster"]: | ||
logger.info("poster was cleared") | ||
obj.calc_poster = False | ||
super().save_model(request, obj, form, change) | ||
|
||
|
||
admin.site.register(Video, VideoModelAdmin) | ||
|
||
|
||
class GalleryModelAdmin(AdminUserMixin, admin.ModelAdmin): | ||
list_display = ("pk",) | ||
fields = ("user", "images") | ||
|
||
|
||
admin.site.register(Gallery, GalleryModelAdmin) |
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import logging | ||
|
||
from rest_framework import serializers | ||
|
||
from ..models import Image, Video, Gallery | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ImageSerializer(serializers.HyperlinkedModelSerializer): | ||
url = serializers.HyperlinkedIdentityField(view_name="cast:api:image_detail") | ||
srcset = serializers.ReadOnlyField() | ||
thumbnail_src = serializers.ReadOnlyField() | ||
full_src = serializers.ReadOnlyField() | ||
|
||
class Meta: | ||
model = Image | ||
fields = ("id", "url", "original", "srcset", "thumbnail_src", "full_src") | ||
|
||
|
||
class VideoSerializer(serializers.HyperlinkedModelSerializer): | ||
url = serializers.HyperlinkedIdentityField(view_name="cast:api:video_detail") | ||
poster = serializers.ImageField(read_only=True, allow_empty_file=True) | ||
poster_thumbnail = serializers.ImageField(read_only=True, allow_empty_file=True) | ||
|
||
class Meta: | ||
model = Video | ||
fields = ("id", "url", "original", "poster", "poster_thumbnail") | ||
|
||
|
||
class GallerySerializer(serializers.HyperlinkedModelSerializer): | ||
url = serializers.HyperlinkedIdentityField(view_name="cast:api:gallery_detail") | ||
images = serializers.PrimaryKeyRelatedField(many=True, queryset=Image.objects.all()) | ||
|
||
def create(self, validated_data): | ||
user = self.context["request"].user | ||
gallery = Gallery.objects.create(user=user) | ||
for image in validated_data["images"]: | ||
gallery.images.add(image) | ||
return gallery | ||
|
||
class Meta: | ||
model = Gallery | ||
fields = ("id", "url", "images") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from django.conf.urls import url | ||
|
||
from rest_framework.schemas import get_schema_view | ||
|
||
from . import views | ||
|
||
app_name = "api" | ||
schema_view = get_schema_view(title="Cast API") | ||
|
||
urlpatterns = [ | ||
url(r"^schema/$", schema_view), | ||
url(r"^$", views.api_root, name="root"), | ||
# image | ||
url(r"^images/?$", views.ImageListView.as_view(), name="image_list"), | ||
url( | ||
r"^images/(?P<pk>\d+)/?$", views.ImageDetailView.as_view(), name="image_detail" | ||
), | ||
url( | ||
regex=r"^upload_image/$", | ||
view=views.ImageCreateView.as_view(), | ||
name="upload_image", | ||
), | ||
# gallery | ||
url(r"^gallery/?$", views.GalleryListView.as_view(), name="gallery_list"), | ||
url( | ||
r"^gallery/(?P<pk>\d+)/?$", | ||
views.GalleryDetailView.as_view(), | ||
name="gallery_detail", | ||
), | ||
# video | ||
url(r"^videos/?$", views.VideoListView.as_view(), name="video_list"), | ||
url( | ||
r"^videos/(?P<pk>\d+)/?$", views.VideoDetailView.as_view(), name="video_detail" | ||
), | ||
url( | ||
regex=r"^upload_video/$", | ||
view=views.VideoCreateView.as_view(), | ||
name="upload_video", | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import logging | ||
|
||
from django.http import HttpResponse | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class FileUploadResponseMixin: | ||
def get_success_url(self): | ||
return None | ||
|
||
def form_valid(self, form): | ||
model = form.save(commit=False) | ||
super().form_valid(form) | ||
return HttpResponse("{}".format(model.pk), status=201) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import logging | ||
|
||
from collections import OrderedDict | ||
|
||
from django.views.generic import CreateView | ||
|
||
from django.contrib.auth.mixins import LoginRequiredMixin | ||
|
||
from django.urls import reverse | ||
|
||
from rest_framework import generics | ||
from rest_framework.response import Response | ||
from rest_framework.decorators import api_view | ||
from rest_framework.permissions import IsAuthenticated | ||
from rest_framework.pagination import PageNumberPagination | ||
|
||
from .serializers import ImageSerializer, VideoSerializer, GallerySerializer | ||
|
||
from ..forms import ImageForm, VideoForm | ||
|
||
from ..viewmixins import AddRequestUserMixin | ||
from .viewmixins import FileUploadResponseMixin | ||
|
||
from ..models import Image, Video, Gallery | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
@api_view(["GET"]) | ||
def api_root(request): | ||
""" | ||
Show API contents. | ||
If you add any object types, add them here! | ||
""" | ||
root_api_urls = ( | ||
("images", request.build_absolute_uri(reverse("cast:api:image_list"))), | ||
("galleries", request.build_absolute_uri(reverse("cast:api:gallery_list"))), | ||
("videos", request.build_absolute_uri(reverse("cast:api:video_list"))), | ||
) | ||
return Response(OrderedDict(root_api_urls)) | ||
|
||
|
||
class ImageCreateView( | ||
LoginRequiredMixin, AddRequestUserMixin, FileUploadResponseMixin, CreateView | ||
): | ||
model = Image | ||
form_class = ImageForm | ||
user_field_name = "user" | ||
|
||
|
||
class VideoCreateView( | ||
LoginRequiredMixin, AddRequestUserMixin, FileUploadResponseMixin, CreateView | ||
): | ||
model = Video | ||
form_class = VideoForm | ||
user_field_name = "user" | ||
|
||
|
||
class StandardResultsSetPagination(PageNumberPagination): | ||
page_size = 20 | ||
page_size_query_param = "pageSize" | ||
max_page_size = 10000 | ||
|
||
|
||
class ImageListView(generics.ListCreateAPIView): | ||
serializer_class = ImageSerializer | ||
pagination_class = StandardResultsSetPagination | ||
permission_classes = (IsAuthenticated,) | ||
|
||
def get_queryset(self): | ||
user = self.request.user | ||
qs = Image.objects.all().filter(user=user) | ||
return qs.order_by("-created") | ||
|
||
|
||
class ImageDetailView(generics.RetrieveDestroyAPIView): | ||
queryset = Image.objects.all() | ||
serializer_class = ImageSerializer | ||
permission_classes = (IsAuthenticated,) | ||
|
||
|
||
class VideoListView(generics.ListCreateAPIView): | ||
serializer_class = VideoSerializer | ||
pagination_class = StandardResultsSetPagination | ||
permission_classes = (IsAuthenticated,) | ||
|
||
def get_queryset(self): | ||
user = self.request.user | ||
qs = Video.objects.all().filter(user=user) | ||
return qs.order_by("-created") | ||
|
||
|
||
class VideoDetailView(generics.RetrieveDestroyAPIView): | ||
queryset = Video.objects.all() | ||
serializer_class = VideoSerializer | ||
permission_classes = (IsAuthenticated,) | ||
|
||
|
||
class GalleryListView(generics.ListCreateAPIView): | ||
serializer_class = GallerySerializer | ||
pagination_class = StandardResultsSetPagination | ||
permission_classes = (IsAuthenticated,) | ||
|
||
def get_queryset(self): | ||
user = self.request.user | ||
qs = Gallery.objects.all().filter(user=user) | ||
return qs.order_by("-created") | ||
|
||
|
||
class GalleryDetailView(generics.RetrieveDestroyAPIView): | ||
queryset = Gallery.objects.all() | ||
serializer_class = GallerySerializer | ||
permission_classes = (IsAuthenticated,) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,4 @@ | |
|
||
|
||
class CastConfig(AppConfig): | ||
name = 'cast' | ||
name = "cast" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
from __future__ import absolute_import | ||
|
||
from django import forms | ||
from django.utils import timezone | ||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
from .models import Post, Image, Video | ||
|
||
|
||
class PostForm(forms.ModelForm): | ||
is_published = forms.BooleanField(required=False) | ||
pub_date = forms.DateTimeField(input_formats=["%Y-%m-%dT%H:%M"]) | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.fields["slug"].required = False | ||
self.fields["title"].widget.attrs["size"] = 80 | ||
self.fields["pub_date"].required = False | ||
self.fields["pub_date"].widget = forms.DateTimeInput( | ||
attrs={"type": "datetime-local"} | ||
) | ||
self.fields["pub_date"].label = _("Publication date") | ||
self.fields["pub_date"].help_text = _( | ||
"Article will be published after this date/time." | ||
) | ||
self.fields["visible_date"].required = False | ||
self.fields["visible_date"].widget = forms.DateInput(attrs={"type": "date"}) | ||
self.fields["visible_date"].label = _("Visible date") | ||
self.fields["visible_date"].help_text = _("Date to be shown above article.") | ||
|
||
def _set_pub_date(self, cleaned_data): | ||
pub_date = cleaned_data.get("pub_date") | ||
is_published = cleaned_data.get("is_published") | ||
if pub_date is None and is_published: | ||
cleaned_data["pub_date"] = timezone.now() | ||
return cleaned_data | ||
|
||
def clean(self): | ||
cleaned_data = super().clean() | ||
cleaned_data = self._set_pub_date(cleaned_data) | ||
return cleaned_data | ||
|
||
class Meta: | ||
model = Post | ||
fields = [ | ||
"title", | ||
"content", | ||
"pub_date", | ||
"visible_date", | ||
"is_published", | ||
"slug", | ||
] | ||
|
||
|
||
class ImageForm(forms.ModelForm): | ||
class Meta: | ||
model = Image | ||
fields = ["original"] | ||
|
||
|
||
class VideoForm(forms.ModelForm): | ||
class Meta: | ||
model = Video | ||
fields = ["original"] |
Binary file not shown.
Binary file not shown.
Empty file.
Oops, something went wrong.