Files
Pinry/core/models.py
winkidney e216e5a6f2 Feature: Use char-field instead of url-field to fit strange types of url
Now Pinry will not care type of url, if it could be input, it could be
saved.
This may cause xss issue but Pinry is a private pin-board replacement,
so be it.
2019-07-15 17:12:18 +08:00

98 lines
2.9 KiB
Python

import requests
from io import BytesIO
from django.conf import settings
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.db import models
from django.dispatch import receiver
from django_images.models import Image as BaseImage, Thumbnail
from taggit.managers import TaggableManager
from users.models import User
class ImageManager(models.Manager):
_default_ua = {
'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/48.0.2564.82 Safari/537.36',
}
# FIXME: Move this into an asynchronous task
def create_for_url(self, url, referer=None):
file_name = url.split("/")[-1].split('#')[0].split('?')[0]
buf = BytesIO()
headers = dict(self._default_ua)
if referer is not None:
headers["Referer"] = referer
response = requests.get(url, headers=headers)
buf.write(response.content)
obj = InMemoryUploadedFile(buf, 'image', file_name,
None, buf.tell(), None)
# create the image and its thumbnails in one transaction, removing
# a chance of getting Database into a inconsistent state when we
# try to create thumbnails one by one later
image = self.create(image=obj)
for size in settings.IMAGE_SIZES.keys():
Thumbnail.objects.get_or_create_at_size(image.pk, size)
return image
class Image(BaseImage):
objects = ImageManager()
class Sizes:
standard = "standard"
thumbnail = "thumbnail"
square = "square"
class Meta:
proxy = True
@property
def standard(self):
return Thumbnail.objects.get(
original=self, size=self.Sizes.standard
)
@property
def thumbnail(self):
return Thumbnail.objects.get(
original=self, size=self.Sizes.thumbnail
)
@property
def square(self):
return Thumbnail.objects.get(
original=self, size=self.Sizes.square
)
class Pin(models.Model):
submitter = models.ForeignKey(User)
url = models.CharField(null=True, blank=True, max_length=256)
# origin is tha same as referer but not work,
# should be removed some day
origin = models.CharField(null=True, blank=True, max_length=256)
referer = models.CharField(null=True, blank=True, max_length=256)
description = models.TextField(blank=True, null=True)
image = models.ForeignKey(Image, related_name='pin')
published = models.DateTimeField(auto_now_add=True)
tags = TaggableManager()
def tag_list(self):
return self.tags.all()
def __unicode__(self):
return '%s - %s' % (self.submitter, self.published)
@receiver(models.signals.post_delete, sender=Pin)
def delete_pin_images(sender, instance, **kwargs):
try:
instance.image.delete()
except Image.DoesNotExist:
pass