pyazo core: rename upload to object

parent 5e499667
"""pyazo admin"""
from django.contrib import admin
from pyazo.core.models import Collection, Upload, UploadView
from pyazo.core.models import Collection, Object, ObjectView
admin.site.register(Upload)
admin.site.register(UploadView)
admin.site.register(Object)
admin.site.register(ObjectView)
admin.site.register(Collection)
......@@ -7,7 +7,7 @@ from glob import glob
from django.conf import settings
from django.core.management.base import BaseCommand
from pyazo.core.models import Upload
from pyazo.core.models import Object
BUF_SIZE = 65536
LOGGER = logging.getLogger(__name__)
......@@ -36,13 +36,13 @@ class Command(BaseCommand):
# Get hash to compare with
sha512 = Command._file_get_sha_512(file)
# Check if that hash exists
matching = Upload.objects.filter(sha512=sha512)
matching = Object.objects.filter(sha512=sha512)
if matching.exists():
upload = matching.first()
upload.file.name = file
upload.save()
LOGGER.info("File %s is in DB already, updating path", file)
else:
Upload.objects.create(file=file)
Object.objects.create(file=file)
LOGGER.info("Imported %s into DB", file)
return 0
......@@ -13,7 +13,7 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterField(
model_name='uploadview',
model_name='UploadView',
name='viewee',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
......
# Generated by Django 2.1.4 on 2018-12-21 19:19
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):
atomic = False
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('pyazo_core', '0013_auto_20181221_1841'),
]
operations = [
migrations.RenameModel(
old_name='Upload',
new_name='Object',
),
migrations.RenameModel(
old_name='UploadView',
new_name='ObjectView',
),
migrations.RenameField(
model_name='objectview',
old_name='upload',
new_name='obj',
),
]
......@@ -7,8 +7,8 @@ from user_agents import parse
from pyazo.utils.files import generate_hashes, get_mime_type
class Upload(models.Model):
"""Store data about a single upload"""
class Object(models.Model):
"""Store data about a single obj"""
file = models.FileField(max_length=512)
thumbnail = models.FileField(blank=True, upload_to='thumbnail/', max_length=512)
......@@ -50,7 +50,7 @@ class Upload(models.Model):
@property
def get_initial_view(self):
"""Returns the initial view"""
return UploadView.objects.filter(upload=self).earliest()
return ObjectView.objects.filter(obj=self).earliest()
@property
def filename(self):
......@@ -60,9 +60,9 @@ class Upload(models.Model):
def __str__(self):
return self.sha512
class UploadView(models.Model):
class ObjectView(models.Model):
"""Store information about a single view"""
upload = models.ForeignKey('Upload', on_delete=models.CASCADE)
obj = models.ForeignKey('Object', on_delete=models.CASCADE)
viewee = models.ForeignKey(User, blank=True, null=True, default=None, on_delete=models.CASCADE)
viewee_ip = models.GenericIPAddressField(blank=True, null=True)
viewee_dns = models.TextField(blank=True)
......@@ -79,7 +79,7 @@ class UploadView(models.Model):
return self._ua_inst
class Collection(models.Model):
"""Collection to group Uploads together"""
"""Collection to group Objects together"""
name = models.CharField(max_length=255)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
......
......@@ -7,7 +7,7 @@ from django.shortcuts import get_object_or_404
from PIL import Image
from pyazo.core.celery import CELERY_APP
from pyazo.core.models import Upload
from pyazo.core.models import Object
from pyazo.utils.files import generate_ext_thumb
LOGGER = getLogger(__name__)
......@@ -18,7 +18,7 @@ def make_thumbnail(self, upload_pk: int):
"""Create 200x200 thumbnail for upload.
If upload is non-image, return thumbnail with filetype"""
path = ''
upload = get_object_or_404(Upload, pk=upload_pk)
upload = get_object_or_404(Object, pk=upload_pk)
if upload.mime_type.startswith('image/'):
LOGGER.debug('Creating thumbnail of upload...')
# Upload is an image, so we create a resized version
......
......@@ -5,7 +5,7 @@ from django.conf import settings
from django.test import TestCase
from pyazo.core.management.commands.reindex import Command as ReindexCommand
from pyazo.core.models import Upload
from pyazo.core.models import Object
from pyazo.core.tests.utils import call_command_ret
......@@ -18,11 +18,11 @@ class ManagementTests(TestCase):
_file.write('test')
with open(settings.MEDIA_ROOT + 'test2.txt', 'w') as _file:
_file.write('updating existing upload')
Upload.objects.create(file=settings.MEDIA_ROOT + 'test2.txt')
count_before = len(Upload.objects.all())
Object.objects.create(file=settings.MEDIA_ROOT + 'test2.txt')
count_before = len(Object.objects.all())
self.assertEqual(ReindexCommand().handle(), 0)
# We expect reindex to create one new upload
self.assertEqual(len(Upload.objects.all()), count_before + 1)
self.assertEqual(len(Object.objects.all()), count_before + 1)
# Cleanup
os.unlink(settings.MEDIA_ROOT + 'test.txt')
os.unlink(settings.MEDIA_ROOT + 'test2.txt')
......
......@@ -5,7 +5,7 @@ import os
from django.conf import settings
from django.test import TestCase
from pyazo.core.models import Upload
from pyazo.core.models import Object
from pyazo.core.tasks import make_thumbnail
......@@ -16,7 +16,7 @@ class TaskTests(TestCase):
super().setUp()
with open(settings.MEDIA_ROOT + 'test2.txt', 'w') as _file:
_file.write('updating existing upload')
self.upload = Upload.objects.create(file=settings.MEDIA_ROOT + 'test2.txt')
self.upload = Object.objects.create(file=settings.MEDIA_ROOT + 'test2.txt')
def tearDown(self):
super().tearDown()
......
......@@ -7,18 +7,18 @@ from django.contrib.auth.models import User
from django.shortcuts import reverse
from django.test import TestCase, override_settings
from pyazo.core.models import Collection, Upload
from pyazo.core.models import Collection, Object
from pyazo.core.tests.utils import test_auth
class UploadViewTests(TestCase):
class ObjectViewTests(TestCase):
"""Test all client upload views"""
def setUp(self):
super().setUp()
with open(settings.MEDIA_ROOT + 'test2.txt', 'w') as _file:
_file.write('updating existing upload')
self.upload = Upload.objects.create(file=settings.MEDIA_ROOT + 'test2.txt')
self.upload = Object.objects.create(file=settings.MEDIA_ROOT + 'test2.txt')
with open(settings.MEDIA_ROOT + 'test3.txt', 'w') as _file:
_file.write('updating qwerqwerqwer upload')
......@@ -31,13 +31,13 @@ class UploadViewTests(TestCase):
os.remove(file)
def test_upload_view(self):
"""Test UploadView"""
"""Test ObjectView"""
self.client.login(**test_auth())
response = self.client.get(reverse('upload_view', kwargs={'file_hash': self.upload.sha512}))
self.assertEqual(response.status_code, 200)
def test_upload_view_post(self):
"""Test UploadView's post"""
"""Test ObjectView's post"""
auth = test_auth()
self.client.login(**auth)
test_user = User.objects.get(username=auth.get('username'))
......
......@@ -5,10 +5,10 @@ from django.conf import settings
from django.shortcuts import reverse
from django.test import TestCase
from pyazo.core.models import Upload
from pyazo.core.models import Object
class UploadViewTests(TestCase):
class ObjectViewTests(TestCase):
"""Test upload views"""
def setUp(self):
......@@ -17,7 +17,7 @@ class UploadViewTests(TestCase):
with open(self.test_file_path, 'w') as _file:
self._test_data = 'testdatafewrqwer'
_file.write(self._test_data)
self.upload = Upload.objects.create(file=self.test_file_path)
self.upload = Object.objects.create(file=self.test_file_path)
def tearDown(self):
super().tearDown()
......
......@@ -7,7 +7,7 @@ from django.db.models import Q
from django.http import Http404
from django.views.generic import TemplateView
from pyazo.core.models import Collection, Upload
from pyazo.core.models import Collection, Object
LOGGER = logging.getLogger(__name__)
......@@ -32,7 +32,7 @@ class IndexView(LoginRequiredMixin, TemplateView):
# Set collection name so we can show in the template
context['collection'] = self.request.GET.get('collection')
# Per Default, on a 1080p screen, there are 7 rows with 12 tiles => 84
images = Paginator(Upload.objects.filter(upload_filter).order_by('-id'), 84)
images = Paginator(Object.objects.filter(upload_filter).order_by('-id'), 84)
page = self.request.GET.get('page')
try:
......
......@@ -17,24 +17,25 @@ from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView, View
from pyazo.core.forms.view import CollectionSelectForm
from pyazo.core.models import Collection, Upload
from pyazo.core.models import Collection, Object
from pyazo.core.views.view import ObjectViewFile
from pyazo.utils.config import CONFIG
from pyazo.utils.files import generate_hashes, save_from_post
from pyazo.core.views.view import UploadViewFile
LOGGER = getLogger(__name__)
class UploadView(LoginRequiredMixin, TemplateView):
class ObjectView(LoginRequiredMixin, TemplateView):
"""Show statistics about upload and allow user to manage it."""
template_name = 'upload/view.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
upload = get_object_or_404(Upload, sha512=self.kwargs.get('file_hash'))
upload = get_object_or_404(Object, sha512=self.kwargs.get('file_hash'))
context['upload'] = upload
context['url_prefix'] = self.request.build_absolute_uri('/')
context['views'] = context['upload'].uploadview_set.order_by('-viewee_date')[:10]
context['views'] = context['upload'].objectview_set.order_by('-viewee_date')[:10]
context['forms'] = {
'collection': CollectionSelectForm(
prefix='collection',
......@@ -53,7 +54,7 @@ class UploadView(LoginRequiredMixin, TemplateView):
def post(self, request: HttpRequest, file_hash: str) -> HttpResponse:
"""handle form"""
context = self.get_context_data()
upload = get_object_or_404(Upload, sha512=file_hash)
upload = get_object_or_404(Object, sha512=file_hash)
form = context.get('forms').get('collection')
if form.is_valid():
upload.collection = form.cleaned_data.get('collection')
......@@ -61,14 +62,14 @@ class UploadView(LoginRequiredMixin, TemplateView):
return redirect(reverse('upload_view', kwargs={'file_hash': file_hash}))
class ClaimUploadView(LoginRequiredMixin, TemplateView):
class ClaimObjectView(LoginRequiredMixin, TemplateView):
"""Claim an upload"""
template_name = 'core/generic_delete.html'
def post(self, request: HttpRequest, file_hash: str) -> HttpResponse:
"""Claim upload to user (only if upload has no owner yet or user is superuser)"""
upload = get_object_or_404(Upload, sha512=file_hash)
upload = get_object_or_404(Object, sha512=file_hash)
if request.user.is_superuser or not upload.user:
upload.user = request.user
upload.save()
......@@ -79,7 +80,7 @@ class ClaimUploadView(LoginRequiredMixin, TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
upload = get_object_or_404(Upload, sha512=self.kwargs.get('file_hash'))
upload = get_object_or_404(Object, sha512=self.kwargs.get('file_hash'))
context['object'] = 'Upload %s' % upload.md5
context['delete_url'] = reverse('upload_claim', kwargs={
'file_hash': self.kwargs.get('file_hash')
......@@ -89,14 +90,14 @@ class ClaimUploadView(LoginRequiredMixin, TemplateView):
return context
class DeleteUploadView(LoginRequiredMixin, TemplateView):
class DeleteObjectView(LoginRequiredMixin, TemplateView):
"""Delete Upload"""
template_name = 'core/generic_delete.html'
def post(self, request: HttpRequest, file_hash: str) -> HttpResponse:
"""Delete upload"""
upload = get_object_or_404(Upload, sha512=file_hash)
upload = get_object_or_404(Object, sha512=file_hash)
if request.user.is_superuser or upload.user == request.user:
upload.delete()
messages.success(request, _('Upload successfully deleted'))
......@@ -106,7 +107,7 @@ class DeleteUploadView(LoginRequiredMixin, TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
upload = get_object_or_404(Upload, sha512=self.kwargs.get('file_hash'))
upload = get_object_or_404(Object, sha512=self.kwargs.get('file_hash'))
context['object'] = 'Upload %s' % upload.md5
context['delete_url'] = reverse('upload_delete', kwargs={
'file_hash': self.kwargs.get('file_hash')
......@@ -115,14 +116,14 @@ class DeleteUploadView(LoginRequiredMixin, TemplateView):
@method_decorator(csrf_exempt, name='dispatch')
class LegacyUploadView(View):
class LegacyObjectView(View):
"""Legacy Upload (for gyazo-based clients)"""
def post(self, request: HttpRequest) -> HttpResponse:
"""Main upload handler. Fully gyazo compatible."""
if 'id' in request.POST and 'imagedata' in request.FILES:
# Instantiate BrowserUploadView to use handle_post_file
upload_view = BrowserUploadView()
# Instantiate BrowserObjectView to use handle_post_file
upload_view = BrowserObjectView()
upload, created = upload_view.handle_post_file(request.FILES['imagedata'])
if created:
# Run auto-claim
......@@ -134,23 +135,23 @@ class LegacyUploadView(View):
request.POST.get('username'))
upload.save()
# Count initial view
UploadViewFile.count_view(upload, request)
ObjectViewFile.count_view(upload, request)
LOGGER.info("Uploaded %s", upload.filename)
# Generate url for client to open
upload_prop = settings.DEFAULT_RETURN_VIEW.replace('view_', '')
upload_prop = CONFIG.get('default_return_view').replace('view_', '')
upload_hash = getattr(upload, upload_prop, 'sha256')
url = reverse(settings.DEFAULT_RETURN_VIEW, kwargs={'file_hash': upload_hash})
full_url = urljoin(settings.EXTERNAL_URL, url)
url = reverse(CONFIG.get('default_return_view'), kwargs={'file_hash': upload_hash})
full_url = urljoin(CONFIG.get('external_url'), url)
return HttpResponse(full_url)
return HttpResponse(status=400)
class BrowserUploadView(LoginRequiredMixin, TemplateView):
class BrowserObjectView(LoginRequiredMixin, TemplateView):
"""Handle uploads from browser"""
template_name = 'upload/upload.html'
def handle_post_file(self, post_file) -> Tuple[Upload, bool]:
def handle_post_file(self, post_file) -> Tuple[Object, bool]:
"""Handle upload of a single file, computes hashes and returns existing Upload instance and
False as tuple if file was uploaded already.
Otherwise, new Upload instance is created and returned in a tuple with True."""
......@@ -162,12 +163,12 @@ class BrowserUploadView(LoginRequiredMixin, TemplateView):
# Reset reading position so we can read the file again
post_file.seek(0)
# Check if hashes already exists
existing = Upload.objects.filter(sha512=hashes.get('sha512'))
existing = Object.objects.filter(sha512=hashes.get('sha512'))
if existing.exists():
LOGGER.debug("De-duped existing upload %s", existing.first().filename)
return existing.first(), False
# Create new upload object
new_upload = Upload(
new_upload = Object(
file=save_from_post(post_file.read(), extension=ext))
new_upload.save()
LOGGER.info("Uploaded %s", new_upload.filename)
......@@ -180,6 +181,6 @@ class BrowserUploadView(LoginRequiredMixin, TemplateView):
new_upload.user = request.user
new_upload.save()
# Count initial view
UploadViewFile.count_view(new_upload, request)
ObjectViewFile.count_view(new_upload, request)
LOGGER.info("Uploaded %s", new_upload.filename)
return HttpResponse(status=204)
......@@ -7,8 +7,7 @@ from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control
from django.views.generic import View
from pyazo.core.models import Upload
from pyazo.core.models import UploadView as UploadViewObject
from pyazo.core.models import Object, ObjectView
from pyazo.core.tasks import make_thumbnail
from pyazo.utils import get_remote_ip, get_reverse_dns
from pyazo.utils.files import get_mime_type
......@@ -16,17 +15,17 @@ from pyazo.utils.files import get_mime_type
LOGGER = getLogger(__name__)
@method_decorator(cache_control(max_age=3600), name='dispatch')
class UploadViewFile(View):
class ObjectViewFile(View):
"""View to show upload"""
@staticmethod
def count_view(upload: Upload, request: HttpRequest):
"""Create UploadView entry from request"""
def count_view(upload: Object, request: HttpRequest):
"""Create ObjectView entry from request"""
client_ip = get_remote_ip(request)
client_dns = get_reverse_dns(client_ip)
user_agent = request.META['HTTP_USER_AGENT'] if 'HTTP_USER_AGENT' in request.META else ''
UploadViewObject.objects.create(
upload=upload,
ObjectView.objects.create(
obj=upload,
viewee_ip=client_ip,
viewee_dns=client_dns,
viewee_user_agent=user_agent)
......@@ -44,7 +43,7 @@ class UploadViewFile(View):
query &= Q(sha256=file_hash)
elif hash_length == 128: # SHA512
query &= Q(sha512=file_hash)
return Upload.objects.filter(query)
return Object.objects.filter(query)
@cache_control(max_age=3600)
def dispatch(self, request: HttpRequest, **kwargs) -> HttpResponse:
......
......@@ -29,7 +29,7 @@ error_report_enabled: false
# Set this to the server's external address.
# This is used to generate external URLs
external_url: http://image.example.com
external_url: http://localhost
# This dictates how the Path is generated
# can be either of:
......@@ -39,10 +39,6 @@ external_url: http://image.example.com
# - view_sha512
default_return_view: view_sha256
# Set this to this server's hostname or the external domain if behind a reverse proxy
# domains:
# - image.example.com
# Set this to true if you only want to use external authentication
external_auth_only: false
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment