import mimetypes from django.conf import settings from django.db import models as dbmodels from PyPDF2 import PdfFileReader from PyPDF2.utils import PdfReadError from ..utils.rest_api import FileField, ModelSerializer, SerializerMethodField from .models import Mediafile class AngularCompatibleFileField(FileField): def to_internal_value(self, data): if data == '': return None return super(AngularCompatibleFileField, self).to_internal_value(data) def to_representation(self, value): if value is None: return None filetype = mimetypes.guess_type(value.path)[0] result = { 'name': value.name, 'type': filetype } if filetype == 'application/pdf': try: result['pages'] = PdfFileReader(open(value.path, 'rb')).getNumPages() except FileNotFoundError: # File was deleted from server. Set 'pages' to 0. result['pages'] = 0 except PdfReadError: # File could be encrypted but not be detected by PyPDF. result['pages'] = 0 result['encrypted'] = True return result class MediafileSerializer(ModelSerializer): """ Serializer for mediafile.models.Mediafile objects. """ media_url_prefix = SerializerMethodField() filesize = SerializerMethodField() def __init__(self, *args, **kwargs): """ This constructor overwrites the FileField field serializer to return the file meta data in a way that the angualarjs upload module likes """ super(MediafileSerializer, self).__init__(*args, **kwargs) self.serializer_field_mapping[dbmodels.FileField] = AngularCompatibleFileField if self.instance is not None: self.fields['mediafile'].read_only = True class Meta: model = Mediafile fields = ( 'id', 'title', 'mediafile', 'media_url_prefix', 'uploader', 'filesize', 'hidden', 'timestamp',) def get_filesize(self, mediafile): return mediafile.get_filesize() def get_media_url_prefix(self, mediafile): return settings.MEDIA_URL