mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
* Data model * little crud * SubEventItemForm etc * Drop SubEventItem.active, quota editor * Fix failing tests * First frontend stuff * Addons form stuff * Quota calculation * net price display on EventIndex * Add tests, solve some bugs * Correct quota selection in more places, consolidate pricing logic * Fix failing quota tests * Fix TypeError * Add tests for checkout * Fixed a bug in QuotaForm * Prevent immutable cart if a quota was removed from an item * Add tests for pricing * Handle waiting list * Filter in check-in list * Fixed import lost in rebase * Fix waiting list widget * Voucher management * Voucher redemption * Fix broken tests * Add subevents to OrderChangeManager * Create a subevent during event creation * Fix bulk voucher creation * Introduce subevent.active * Copy from for subevents * Show active in list * ICal download for subevents * Check start and end of presale * Failing tests / show cart logic * Test * Rebase migrations * REST API integration of sub-events * Integrate quota calculation into the traditional quota form * Make subevent argument to add_position optional * Log-display foo * pretixdroid and subevents * Filter by subevent * Add more tests * Some mor tests * Rebase fixes * More tests * Relative dates * Restrict selection in relative datetime widgets * Filter subevent list * Re-label has_subevents * Rebase fixes, subevents in calendar view * Performance and caching issues * Refactor calendar templates * Permission tests * Calendar fixes and month selection * subevent selection * Rename subevents to dates * Add tests for calendar views
78 lines
2.3 KiB
Python
78 lines
2.3 KiB
Python
import json
|
|
import uuid
|
|
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.db import models
|
|
from django.db.models.signals import post_delete
|
|
from django.dispatch import receiver
|
|
from django.utils.crypto import get_random_string
|
|
|
|
from pretix.helpers.json import CustomJSONEncoder
|
|
|
|
|
|
def cachedfile_name(instance, filename: str) -> str:
|
|
secret = get_random_string(length=12)
|
|
return 'cachedfiles/%s.%s.%s' % (instance.id, secret, filename.split('.')[-1])
|
|
|
|
|
|
class CachedFile(models.Model):
|
|
"""
|
|
An uploaded file, with an optional expiry date.
|
|
"""
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
|
|
expires = models.DateTimeField(null=True, blank=True)
|
|
date = models.DateTimeField(null=True, blank=True)
|
|
filename = models.CharField(max_length=255)
|
|
type = models.CharField(max_length=255)
|
|
file = models.FileField(null=True, blank=True, upload_to=cachedfile_name)
|
|
|
|
|
|
@receiver(post_delete, sender=CachedFile)
|
|
def cached_file_delete(sender, instance, **kwargs):
|
|
if instance.file:
|
|
# Pass false so FileField doesn't save the model.
|
|
instance.file.delete(False)
|
|
|
|
|
|
class LoggingMixin:
|
|
|
|
def log_action(self, action, data=None, user=None):
|
|
"""
|
|
Create a LogEntry object that is related to this object.
|
|
See the LogEntry documentation for details.
|
|
|
|
:param action: The namespaced action code
|
|
:param data: Any JSON-serializable object
|
|
:param user: The user performing the action (optional)
|
|
"""
|
|
from .log import LogEntry
|
|
from .event import Event
|
|
|
|
event = None
|
|
if isinstance(self, Event):
|
|
event = self
|
|
elif hasattr(self, 'event'):
|
|
event = self.event
|
|
l = LogEntry(content_object=self, user=user, action_type=action, event=event)
|
|
if data:
|
|
l.data = json.dumps(data, cls=CustomJSONEncoder)
|
|
l.save()
|
|
|
|
|
|
class LoggedModel(models.Model, LoggingMixin):
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
def all_logentries(self):
|
|
"""
|
|
Returns all log entries that are attached to this object.
|
|
|
|
:return: A QuerySet of LogEntry objects
|
|
"""
|
|
from .log import LogEntry
|
|
|
|
return LogEntry.objects.filter(
|
|
content_type=ContentType.objects.get_for_model(type(self)), object_id=self.pk
|
|
).select_related('user', 'event')
|