def test_uuid(self):
     assert isinstance(FilePattern.get_uuid(),
                       uuid.UUID), "type uuid.UUID expected"
     assert FilePattern.get_uuid().hex[12] == "4", "UUID version 4 expected"
     assert (FixedUUIDFilePattern(filename_pattern="{uuid:x}{ext}")(
         instance=DefaultModel(title="best model"),
         filename="some_file.txt") == "522d6f3519204b0fb82ae8f558af2749.txt"
             )
 def test_destruct(self):
     assert FilePattern().deconstruct() == ("dynamic_filenames.FilePattern",
                                            [], {})
     assert FilePattern(filename_pattern="{name}{ext}").deconstruct() == (
         "dynamic_filenames.FilePattern",
         [],
         {
             "filename_pattern": "{name}{ext}"
         },
     )
     assert FilePattern(name="sth").deconstruct() == (
         "dynamic_filenames.FilePattern",
         [],
         {
             "name": "sth"
         },
     )
Exemplo n.º 3
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import

from django.db import models
from django.utils import timezone
from six import python_2_unicode_compatible
from stdimage.models import StdImageField
from dynamic_filenames import FilePattern

image_variations = {"home": {"width": 530, "height": 220, "crop": True}}
upload_to_pattern = FilePattern(
    filename_pattern="{model_name}/{instance.title:slug}{ext}")


@python_2_unicode_compatible
class Feed(models.Model):
    home_url = models.URLField(verbose_name="Site Home Page")
    feed_url = models.URLField(verbose_name="RSS Feed URL")
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255)
    tags = models.CharField(max_length=255, blank=True)
    image = StdImageField(
        upload_to=upload_to_pattern,
        blank=True,
        null=True,
        variations=image_variations,
    )
    enabled = models.BooleanField(default=True)

    def __str__(self):
        return self.title
Exemplo n.º 4
0
 def test_call__name_override(self):
     assert FilePattern(name='special_name')(
         instance=DefaultModel(), filename='some_file.txt'
     ) == 'special_name.txt'
Exemplo n.º 5
0
 def test_call__app_label(self):
     assert FilePattern(filename_pattern='{app_label}/{name}{ext}')(
         instance=DefaultModel(), filename='some_file.txt'
     ) == 'testapp/some_file.txt'
Exemplo n.º 6
0
 def test_call__full_path(self):
     assert FilePattern()(
         instance=DefaultModel(), filename='/var/www/index.html'
     ) == 'index.html'
Exemplo n.º 7
0
 def test_call__only_extension(self):
     assert FilePattern()(instance=DefaultModel(), filename='.htaccess') == '.htaccess'
Exemplo n.º 8
0
 def test_call__default(self):
     assert FilePattern()(instance=DefaultModel(), filename='test_file.txt') == 'test_file.txt'
Exemplo n.º 9
0
    FileExtensionValidator,
    MinValueValidator,
    MaxValueValidator,
)
from django.utils.translation import gettext_lazy as _

from dynamic_filenames import FilePattern
from io import BytesIO
from PIL import Image
from stdimage.models import StdImageField

__all__ = [
    "StaticMapImage",
]

static_map_image_path = FilePattern(
    filename_pattern="{app_label}/{model_name}/{uuid:base32}{ext}")
DEFAULT_MAP_WIDTH = 992
DEFAULT_MAP_HEIGHT = 300
DEFAULT_MAP_ZOOM = 11
DEFAULT_MAP_SCALE = 1


def download_static_map_image_from_jawg(
    center=None,
    zoom=DEFAULT_MAP_ZOOM,
    scale=DEFAULT_MAP_SCALE,
    width=DEFAULT_MAP_WIDTH,
    height=DEFAULT_MAP_HEIGHT,
):
    if not center:
        raise exceptions.ValidationError("Missing required property 'center'")
Exemplo n.º 10
0
class Talk(models.Model):
    title = models.CharField(max_length=300, null=False)
    description = HTMLField(null=True)
    audio_original = models.FileField(
        null=True,
        blank=True,
        upload_to=FilePattern(
            filename_pattern='audio/original/tmi-archive-{uuid:.12base32}.mp3'
        ),
        validators=[FileExtensionValidator(['mp3'])])
    audio_cleaned = models.FileField(
        null=True,
        blank=True,
        upload_to=FilePattern(
            filename_pattern='audio/cleaned/tmi-archive-{uuid:.12base32}.mp3'),
        validators=[FileExtensionValidator(['mp3'])])

    audio_filename = models.CharField(max_length=300, blank=True, null=True)
    original_file_name = models.CharField(max_length=300,
                                          blank=True,
                                          null=True)

    created_by = models.ForeignKey(get_user_model(),
                                   on_delete=models.CASCADE,
                                   related_name='created_by')
    updated_by = models.ForeignKey(get_user_model(),
                                   on_delete=models.CASCADE,
                                   related_name='updated_by')

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    auto_add_user_data = True

    transcription = models.TextField(
        null=True,
        help_text=
        'The transcription of the audio is formatted in a specific way:'
        '"[timestamp @speaker_name] all text of paragraph (new line)". For example: <br>'
        '[0:00:00.0 @student] Some question.<br>'
        '[0:00:10.4 @culadasa] Answer to question.')
    transcription_deepgram = models.TextField(null=True)

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if self.auto_add_user_data:
            if self.pk is None:
                self.created_by = get_current_user()
            self.updated_by = get_current_user()

        res = super(Talk, self).save(*args, **kwargs)
        return res

    def get_absolute_url(self):
        return reverse('talk_view', kwargs={'pk': self.id})

    @property
    def mp3_url_clean(self):
        if self.audio_cleaned is None:
            return None
        try:
            file_name = str(self.audio_cleaned)
        except ValueError:
            return None
        file_name = file_name.split('/')[-1]
        return f'https://mp3.tmi-archive.com/{file_name}'

    @property
    def transcription_text(self):
        if self.transcription is None:
            return '(no transcription available)'
        sentences = self.transcription.split('\r\n')
        sentences = [s.split(']')[1] if ']' in s else s for s in sentences]
        paragraphs = []
        paragraph = ''
        for sentence in sentences:
            if len(paragraph) > 500:
                paragraphs.append(copy.copy(paragraph))
                paragraph = ''
            paragraph += str(sentence)

        paragraphs.append(paragraph)
        return "<br><br>".join(paragraphs)

    @property
    def transcription_for_audio(self):
        transcription = self.transcription
        for i in range(10):
            transcription = transcription.replace(f'@speaker_{i}', '')
        transcription = transcription.replace(' ]', ' -]')
        # the player needs very specific lines:
        # [00:00:03.6-] So anybody has on?
        sentences = transcription.split('\r\n')
        paragraphs = []
        paragraph = ''
        for sentence in sentences:
            if len(paragraph) > 500:
                paragraphs.append(paragraph)
                paragraph = ''
            if len(paragraph) > 0:
                sentence = sentence.split(']')[1]
            paragraph += str(sentence)
        paragraphs.append(paragraph)
        return "\r\n".join(paragraphs)
Exemplo n.º 11
0
from .model_fields import MandatesField, ValidatedPhoneNumberField
from .person_forms.models import *
from ..elus.models import StatutMandat
from ..lib.display import genrer
from ..lib.model_fields import ChoiceArrayField

__all__ = [
    "Person",
    "PersonEmail",
    "PersonTag",
    "PersonForm",
    "PersonFormSubmission",
    "PersonValidationSMS",
]

person_image_path = FilePattern(
    filename_pattern="{app_label}/{model_name}/{instance.id}/{uuid:s}{ext}")


class PersonQueryset(models.QuerySet):
    def with_contact_phone(self):
        return self.exclude(contact_phone="")

    def verified(self):
        return self.filter(contact_phone_status=Person.CONTACT_PHONE_VERIFIED)

    def search(self, query, *or_query):
        q = reduce(
            lambda a, b: a | Q(search=PrefixSearchQuery(
                b, config="simple_unaccented")),
            or_query,
            Q(search=PrefixSearchQuery(query, config="simple_unaccented")),
 def test_call__name_override(self):
     assert (FilePattern(name="special_name")(
         instance=DefaultModel(),
         filename="some_file.txt") == "special_name.txt")
 def test_call__model_name(self):
     assert (FilePattern(filename_pattern="{model_name}/{name}{ext}")(
         instance=DefaultModel(),
         filename="some_file.txt") == "defaultmodel/some_file.txt")
 def test_call__app_label(self):
     assert (FilePattern(filename_pattern="{app_label}/{name}{ext}")(
         instance=DefaultModel(),
         filename="some_file.txt") == "testapp/some_file.txt")
 def test_call__override_pattern(self):
     assert (FilePattern(filename_pattern="my_file{ext}")(
         instance=DefaultModel(),
         filename="other_file.txt") == "my_file.txt")
Exemplo n.º 16
0
 def test_destruct(self):
     assert FilePattern().deconstruct() == ('dynamic_filenames.FilePattern', [], {})
     assert FilePattern(filename_pattern='{name}{ext}').deconstruct() == (
         'dynamic_filenames.FilePattern', [], {'filename_pattern': '{name}{ext}'})
     assert FilePattern(name='sth').deconstruct() == (
         'dynamic_filenames.FilePattern', [], {'name': 'sth'})
Exemplo n.º 17
0
    def test_init(self):
        assert FilePattern().kwargs == {}
        assert FilePattern().override_values == {}

        assert FilePattern(path='sth').kwargs == {'path': 'sth'}
        assert FilePattern(path='sth').override_values == {'path': 'sth'}
Exemplo n.º 18
0
        # cas spécifique : si on revient à "attente d'informations supplémentaires suite à une modification par un non admin
        # c'est forcément une modification
        if (new_status == cls.STATUS_AWAITING_SUPPLEMENTARY_INFORMATION
                and person is not None):
            res["title"] = "Modification de la demande"
        # some couples (old_status, new_status)
        elif (old_status, new_status) in cls.HISTORY_MESSAGES:
            res["title"] = cls.HISTORY_MESSAGES[(old_status, new_status)]
        else:
            res["title"] = cls.HISTORY_MESSAGES.get(
                new_status, "[Modification non identifiée]")

        return res


document_path = FilePattern(
    filename_pattern="financement/request/{instance.request_id}/{uuid:s}{ext}")


@reversion.register()
class Document(models.Model):
    TYPE_INVOICE = "I"
    TYPE_PICTURE = "P"
    TYPE_OTHER = "O"
    TYPE_CHOICES = (
        (TYPE_INVOICE, _("Facture")),
        (
            TYPE_PICTURE,
            _("Photo ou illustration de l'événement, de la salle, du matériel"
              ),
        ),
        (TYPE_OTHER, _("Autre type de justificatif")),
Exemplo n.º 19
0
 def test_call__no_extension(self):
     assert FilePattern()(instance=DefaultModel(), filename='test_file') == 'test_file'
Exemplo n.º 20
0
            "form_class": CustomDateTimeFormField,
        }
        defaults.update(kwargs)
        return super().formfield(**defaults)


def get_default_subtype():
    subtype = (EventSubtype.objects.filter(
        type=EventSubtype.TYPE_PUBLIC_ACTION).order_by("created").values(
            "id").first())

    return subtype and subtype["id"]


report_image_path = FilePattern(
    filename_pattern="{app_label}/{model_name}/{instance.id}/report_banner{ext}"
)


class EventManager(models.Manager.from_queryset(EventQuerySet)):
    def create(self, *args, **kwargs):
        subtype = kwargs.get("subtype", None)
        if subtype:
            kwargs["description"] = kwargs.get("description",
                                               subtype.default_description)
            kwargs["image"] = kwargs.get("image", subtype.default_image)
        return self.create_event(*args, **kwargs)

    def create_event(self,
                     organizer_person=None,
                     organizer_group=None,
Exemplo n.º 21
0
 def test_call__dot_file(self):
     assert FilePattern()(
         instance=DefaultModel(), filename='.hidden-truth.txt'
     ) == '.hidden-truth.txt'
Exemplo n.º 22
0
class Calendar(ImageMixin):
    objects = CalendarManager()

    name = models.CharField(_("titre"), max_length=255)
    slug = models.SlugField(_("slug"), unique=True)
    archived = models.BooleanField("Calendrier archivé", default=False)

    parent = models.ForeignKey(
        "Calendar",
        on_delete=models.SET_NULL,
        related_name="children",
        related_query_name="child",
        null=True,
        blank=True,
    )
    events = models.ManyToManyField("Event",
                                    related_name="calendars",
                                    through="CalendarItem")

    user_contributed = models.BooleanField(
        _("Les utilisateurs peuvent ajouter des événements"), default=False)

    description = models.TextField(
        _("description"),
        blank=True,
        help_text=_("Saisissez une description (HTML accepté)"),
    )

    image = StdImageField(
        _("bannière"),
        upload_to=FilePattern(
            filename_pattern=
            "{app_label}/{model_name}/{instance.name:slug}{ext}"),
        variations={
            "thumbnail": (400, 250),
            "banner": (1200, 400)
        },
        blank=True,
    )

    class Meta:
        verbose_name = _("Agenda")

    def __str__(self):
        return self.name

    def clean_fields(self, exclude=None):
        super().clean_fields()

        if exclude is None:
            exclude = []

        if "parent" not in exclude:
            calendar = self
            for i in range(settings.CALENDAR_MAXIMAL_DEPTH):
                calendar = calendar.parent

                if calendar is None:
                    break
            else:
                raise ValidationError({
                    "parent":
                    ValidationError(
                        _("Impossible d'utiliser ce calendrier comme parent :"
                          " cela excéderait la profondeur maximale autorisée.")
                    )
                })
Exemplo n.º 23
0
 def test_call__override_pattern(self):
     assert FilePattern(filename_pattern='my_file{ext}')(
         instance=DefaultModel(), filename='other_file.txt'
     ) == 'my_file.txt'
Exemplo n.º 24
0
    """

    objects = AbstractLabelManager()

    label = models.CharField(_("nom"), max_length=50, unique=True, blank=False)
    description = models.TextField(_("description"), blank=True)

    class Meta:
        abstract = True

    def __str__(self):
        return self.label


icon_path = FilePattern(
    filename_pattern="{app_label}/{model_name}/{instance.id}/icon{ext}"
)


class BaseSubtype(TimeStampedModel, AbstractLabel):
    """
    Abstract class for event and group labels which should have special appearance on map
    """

    VISIBILITY_NONE = "N"
    VISIBILITY_ADMIN = "D"
    VISIBILITY_ALL = "A"
    VISIBILITY_CHOICES = (
        (VISIBILITY_NONE, _("Personne (plus utilisé)")),
        (VISIBILITY_ADMIN, _("Seulement depuis l'administration")),
        (VISIBILITY_ALL, _("N'importe qui")),
Exemplo n.º 25
0
 def test_call__model_name(self):
     assert FilePattern(filename_pattern='{model_name}/{name}{ext}')(
         instance=DefaultModel(), filename='some_file.txt'
     ) == 'defaultmodel/some_file.txt'
Exemplo n.º 26
0
from unicodedata import normalize
from io import BytesIO
from django.db import models
from django.shortcuts import resolve_url
from django.conf import settings
from django.utils.safestring import SafeText
from stdimage.models import StdImageField
from dynamic_filenames import FilePattern
from django.core.files.base import ContentFile
from stdimage.utils import render_variations
from PIL import Image

from .enums import MAKES, COUNTRIES, FUEL_TYPES, BODY_STYLES

upload_to_pattern = FilePattern(
    filename_pattern='{model_name}/{uuid:.16base32}{ext}')


def slug(text):
    clean_text = text.strip().replace(' ', '-').replace(',', '-')
    while '--' in clean_text:
        clean_text = clean_text.replace('--', '-')
    ascii_text = normalize('NFKD', clean_text).encode('ascii', 'ignore')
    return ascii_text.lower().decode()


def resize_and_autorotate(file_name, variations, storage):
    with storage.open(file_name) as f:
        with Image.open(f) as image:
            file_format = image.format
            exif = image._getexif()
Exemplo n.º 27
0
from django.db import models

from dynamic_filenames import FilePattern

upload_to_pattern = FilePattern(
    filename_pattern="{instance.title:slug}{ext}", )


class DefaultModel(models.Model):
    title = models.CharField(max_length=100, default="hello goodby")
    file_field = models.FileField(upload_to=upload_to_pattern)
Exemplo n.º 28
0
 def test_call__slug(self):
     assert FilePattern(filename_pattern='{instance.title:slug}{ext}')(
         instance=DefaultModel(title='best model with ünicode'), filename='some_file.txt'
     ) == 'best-model-with-unicode.txt'
Exemplo n.º 29
0
from dynamic_filenames import FilePattern

upload_to_pattern = FilePattern(
    filename_pattern='{app_label:.25}/{model_name:.30}/{uuid:base32}{ext}'
)

Exemplo n.º 30
0
 def test_call__slug_precision(self):
     assert FilePattern(filename_pattern='{instance.title:.4slug}{ext}')(
         instance=DefaultModel(title='best model'), filename='some_file.txt'
     ) == 'best.txt'