Skip to content

Commit

Permalink
Eliminate django-enumchoicefield dependency
Browse files Browse the repository at this point in the history
Replace EnumChoiceField with Django's built-in enum types[^1]. The DB
representation (column type or values) is not effected.

[^1]: https://docs.djangoproject.com/en/5.0/ref/models/fields/#enumeration-types
  • Loading branch information
crgwbr committed May 15, 2024
1 parent 4e10d7a commit 9e33328
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 49 deletions.
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
install_requires=[
"wagtail>=5.2",
"Django>=3.2",
"django-enumchoicefield>=1.1.0",
"bcp47==0.0.4",
"wagtail-modeladmin>=2.0.0"
],
Expand Down
20 changes: 17 additions & 3 deletions tests/app/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import enumchoicefield.fields
import modelcluster.fields
import taggit.managers
import wagtail.fields
Expand Down Expand Up @@ -89,8 +88,23 @@ class Migration(migrations.Migration):
name='CustomVideoTranscode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('media_format', enumchoicefield.fields.EnumChoiceField(enum_class=wagtailvideos.models.MediaFormats, max_length=4)),
('quality', enumchoicefield.fields.EnumChoiceField(default=wagtailvideos.models.VideoQuality(1), enum_class=wagtailvideos.models.VideoQuality, max_length=7)),
('media_format', models.CharField(
choices=[
("webm", "VP8 and Vorbis in WebM"),
("mp4", "H.264 and AAC in Mp4"),
("ogg", "Theora and Vorbis in Ogg"),
],
max_length=4,
)),
('quality', models.CharField(
choices=[
("default", "Default"),
("lowest", "Low"),
("highest", "High"),
],
default="default",
max_length=7,
)),
('processing', models.BooleanField(default=False)),
('file', models.FileField(blank=True, null=True, upload_to=wagtailvideos.models.get_upload_to, verbose_name='file')),
('error_message', models.TextField(blank=True)),
Expand Down
5 changes: 2 additions & 3 deletions wagtailvideos/forms.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django import forms
from django.forms.models import modelform_factory
from django.utils.translation import gettext as _
from enumchoicefield.forms import EnumField
from wagtail.admin import widgets
from wagtail.admin.forms.collections import (
BaseCollectionMemberForm, collection_member_permission_formset_factory)
Expand Down Expand Up @@ -59,8 +58,8 @@ def get_video_form(model):


class VideoTranscodeAdminForm(forms.Form):
media_format = EnumField(MediaFormats)
quality = EnumField(VideoQuality)
media_format = forms.ChoiceField(choices=MediaFormats.choices)
quality = forms.ChoiceField(choices=VideoQuality.choices)

def __init__(self, video, data=None, **kwargs):
super(VideoTranscodeAdminForm, self).__init__(data=data, **kwargs)
Expand Down
10 changes: 8 additions & 2 deletions wagtailvideos/migrations/0003_auto_20160705_1646.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from __future__ import absolute_import, print_function, unicode_literals

import django.db.models.deletion
import enumchoicefield.fields
from django.db import migrations, models

import wagtailvideos.models
Expand All @@ -20,7 +19,14 @@ class Migration(migrations.Migration):
name='VideoTranscode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('media_format', enumchoicefield.fields.EnumChoiceField(enum_class=wagtailvideos.models.MediaFormats, max_length=4)),
('media_format', models.CharField(
choices=[
("webm", "VP8 and Vorbis in WebM"),
("mp4", "H.264 and AAC in Mp4"),
("ogg", "Theora and Vorbis in Ogg"),
],
max_length=4,
)),
('processing', models.BooleanField(default=False)),
('file', models.FileField(null=True, upload_to=wagtailvideos.models.get_upload_to, verbose_name='file')),
('video', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transcodes', to='wagtailvideos.Video')),
Expand Down
14 changes: 10 additions & 4 deletions wagtailvideos/migrations/0009_videotranscode_quality.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
# Generated by Django 1.9.7 on 2016-08-01 04:35
from __future__ import unicode_literals

from django.db import migrations
import enumchoicefield.fields
import wagtailvideos.models
from django.db import migrations, models


class Migration(migrations.Migration):
Expand All @@ -17,6 +15,14 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='videotranscode',
name='quality',
field=enumchoicefield.fields.EnumChoiceField(default=wagtailvideos.models.VideoQuality(1), enum_class=wagtailvideos.models.VideoQuality, max_length=7),
field=models.CharField(
choices=[
("default", "Default"),
("lowest", "Low"),
("highest", "High"),
],
default="default",
max_length=7,
),
),
]
80 changes: 44 additions & 36 deletions wagtailvideos/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from enumchoicefield import ChoiceEnum, EnumChoiceField
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from taggit.managers import TaggableManager
Expand All @@ -28,38 +27,56 @@
logger = logging.getLogger(__name__)


class VideoQuality(ChoiceEnum):
default = 'Default'
lowest = 'Low'
highest = 'High'
class VideoQuality(models.TextChoices):
DEFAULT = "default", _("Default")
LOWEST = "lowest", _("Low")
HIGHEST = "highest", _("High")


class MediaFormats(ChoiceEnum):
webm = 'VP8 and Vorbis in WebM'
mp4 = 'H.264 and AAC in Mp4'
ogg = 'Theora and Vorbis in Ogg'
class MediaFormats(models.TextChoices):
WEBM = "webm", _("VP8 and Vorbis in WebM")
MP4 = "mp4", _("H.264 and AAC in Mp4")
OGG = "ogg", _("Theora and Vorbis in Ogg")

def get_quality_param(self, quality):
if self is MediaFormats.webm:
if self is MediaFormats.WEBM:
return {
VideoQuality.lowest: '50',
VideoQuality.default: '22',
VideoQuality.highest: '4'
VideoQuality.LOWEST: '50',
VideoQuality.DEFAULT: '22',
VideoQuality.HIGHEST: '4'
}[quality]
elif self is MediaFormats.mp4:
elif self is MediaFormats.MP4:
return {
VideoQuality.lowest: '28',
VideoQuality.default: '24',
VideoQuality.highest: '18'
VideoQuality.LOWEST: '28',
VideoQuality.DEFAULT: '24',
VideoQuality.HIGHEST: '18'
}[quality]
elif self is MediaFormats.ogg:
elif self is MediaFormats.OGG:
return {
VideoQuality.lowest: '5',
VideoQuality.default: '7',
VideoQuality.highest: '9'
VideoQuality.LOWEST: '5',
VideoQuality.DEFAULT: '7',
VideoQuality.HIGHEST: '9'
}[quality]


class VideoTrackKind(models.TextChoices):
SUBTITLES = 'subtitles', _('Subtitles')
CAPTIONS = 'captions', _('Captions')
DESCRIPTIONS = 'descriptions', _('Descriptions')
CHAPTERS = 'chapters', _('Chapters')
METADATA = 'metadata', _('Metadata')


def _choices(text_choices, max_length=None):
"""Return a kwargs dict for adding choices and max_length to a CharField"""
if max_length is None:
max_length = max([len(choice) for choice in text_choices.values])
return {
"choices": text_choices.choices,
"max_length": max_length,
}


class VideoQuerySet(SearchableQuerySetMixin, models.QuerySet):
pass

Expand Down Expand Up @@ -289,23 +306,23 @@ def run(self):
quality_param = media_format.get_quality_param(self.transcode.quality)
args = ['ffmpeg', '-hide_banner', '-i', input_file]
try:
if media_format is MediaFormats.ogg:
if media_format is MediaFormats.OGG:
subprocess.check_output(args + [
'-codec:v', 'libtheora',
'-qscale:v', quality_param,
'-codec:a', 'libvorbis',
'-qscale:a', '5',
output_file,
], stdin=FNULL, stderr=subprocess.STDOUT)
elif media_format is MediaFormats.mp4:
elif media_format is MediaFormats.MP4:
subprocess.check_output(args + [
'-codec:v', 'libx264',
'-preset', 'slow', # TODO Checkout other presets
'-crf', quality_param,
'-codec:a', 'aac',
output_file,
], stdin=FNULL, stderr=subprocess.STDOUT)
elif media_format is MediaFormats.webm:
elif media_format is MediaFormats.WEBM:
subprocess.check_output(args + [
'-codec:v', 'libvpx',
'-crf', quality_param,
Expand All @@ -325,8 +342,8 @@ def run(self):


class AbstractVideoTranscode(models.Model):
media_format = EnumChoiceField(MediaFormats)
quality = EnumChoiceField(VideoQuality, default=VideoQuality.default)
media_format = models.CharField(**_choices(MediaFormats))
quality = models.CharField(**_choices(VideoQuality), default=VideoQuality.DEFAULT)
processing = models.BooleanField(default=False)
file = models.FileField(null=True, blank=True, verbose_name=_('file'),
upload_to=get_upload_to)
Expand Down Expand Up @@ -371,20 +388,11 @@ class TrackListing(AbstractTrackListing):


class AbstractVideoTrack(Orderable):
# TODO move to TextChoices once django < 3 is dropped
track_kinds = [
('subtitles', _('Subtitles')),
('captions', _('Captions')),
('descriptions', _('Descriptions')),
('chapters', _('Chapters')),
('metadata', _('Metadata')),
]

file = models.FileField(
verbose_name=_('File'),
upload_to=get_upload_to
)
kind = models.CharField(max_length=50, choices=track_kinds, default=track_kinds[0][0], verbose_name=_('Kind'))
kind = models.CharField(**_choices(VideoTrackKind, max_length=50), default=VideoTrackKind.SUBTITLES, verbose_name=_('Kind'))
label = models.CharField(
max_length=255, blank=True,
help_text=_('A user-readable title of the text track.'),
Expand Down

0 comments on commit 9e33328

Please sign in to comment.