diff --git a/src/open_inwoner/cms/plugins/__init__.py b/src/open_inwoner/cms/plugins/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/open_inwoner/cms/plugins/cms_plugins/__init__.py b/src/open_inwoner/cms/plugins/cms_plugins/__init__.py new file mode 100644 index 0000000000..7bddc35454 --- /dev/null +++ b/src/open_inwoner/cms/plugins/cms_plugins/__init__.py @@ -0,0 +1 @@ +from .videoplayer import VideoPlayerPlugin diff --git a/src/open_inwoner/cms/plugins/cms_plugins/videoplayer.py b/src/open_inwoner/cms/plugins/cms_plugins/videoplayer.py new file mode 100644 index 0000000000..4c431fe136 --- /dev/null +++ b/src/open_inwoner/cms/plugins/cms_plugins/videoplayer.py @@ -0,0 +1,18 @@ +from django.utils.translation import gettext as _ + +from cms.plugin_base import CMSPluginBase +from cms.plugin_pool import plugin_pool + +from open_inwoner.cms.plugins.models.videoplayer import VideoPlayer + + +@plugin_pool.register_plugin +class VideoPlayerPlugin(CMSPluginBase): + model = VideoPlayer + module = _("Media") + name = _("Video Player") + render_template = "cms/plugins/videoplayer/videoplayer.html" + + def render(self, context, instance, placeholder): + context.update({"instance": instance}) + return context diff --git a/src/open_inwoner/cms/plugins/migrations/0001_initial.py b/src/open_inwoner/cms/plugins/migrations/0001_initial.py new file mode 100644 index 0000000000..8a840d05be --- /dev/null +++ b/src/open_inwoner/cms/plugins/migrations/0001_initial.py @@ -0,0 +1,46 @@ +# Generated by Django 3.2.20 on 2023-09-19 13:04 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ("media", "0001_initial"), + ("cms", "0022_auto_20180620_1551"), + ] + + operations = [ + migrations.CreateModel( + name="VideoPlayer", + fields=[ + ( + "cmsplugin_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + related_name="plugins_videoplayer", + serialize=False, + to="cms.cmsplugin", + ), + ), + ( + "video", + models.ForeignKey( + help_text="The video from the catalog.", + on_delete=django.db.models.deletion.PROTECT, + to="media.video", + ), + ), + ], + options={ + "abstract": False, + }, + bases=("cms.cmsplugin",), + ), + ] diff --git a/src/open_inwoner/cms/plugins/migrations/__init__.py b/src/open_inwoner/cms/plugins/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/open_inwoner/cms/plugins/models/__init__.py b/src/open_inwoner/cms/plugins/models/__init__.py new file mode 100644 index 0000000000..5c2207220c --- /dev/null +++ b/src/open_inwoner/cms/plugins/models/__init__.py @@ -0,0 +1 @@ +from .videoplayer import VideoPlayer diff --git a/src/open_inwoner/cms/plugins/models/videoplayer.py b/src/open_inwoner/cms/plugins/models/videoplayer.py new file mode 100644 index 0000000000..7d3b8a69b0 --- /dev/null +++ b/src/open_inwoner/cms/plugins/models/videoplayer.py @@ -0,0 +1,20 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from cms.models import CMSPlugin + +from open_inwoner.media.models import Video + + +class VideoPlayer(CMSPlugin): + video = models.ForeignKey( + Video, + help_text=_("The video from the catalog."), + on_delete=models.PROTECT, + ) + + def __str__(self): + if self.video_id: + return str(self.video) + else: + return super().__str__() diff --git a/src/open_inwoner/cms/plugins/tests/__init__.py b/src/open_inwoner/cms/plugins/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/open_inwoner/cms/plugins/tests/test_videoplayer.py b/src/open_inwoner/cms/plugins/tests/test_videoplayer.py new file mode 100644 index 0000000000..d63becf3b8 --- /dev/null +++ b/src/open_inwoner/cms/plugins/tests/test_videoplayer.py @@ -0,0 +1,16 @@ +from django.test import TestCase + +from open_inwoner.cms.tests import cms_tools +from open_inwoner.media.tests.factories import VideoFactory + +from ..cms_plugins import VideoPlayerPlugin + + +class TestVideoPlayerPlugin(TestCase): + def test_plugin(self): + video = VideoFactory() + html, context = cms_tools.render_plugin( + VideoPlayerPlugin, plugin_data={"video": video} + ) + self.assertIn(video.player_url, html) + self.assertIn(" + + + diff --git a/src/open_inwoner/templates/pages/product/detail.html b/src/open_inwoner/templates/pages/product/detail.html index 82ccfeef5e..186b9cf8ca 100644 --- a/src/open_inwoner/templates/pages/product/detail.html +++ b/src/open_inwoner/templates/pages/product/detail.html @@ -36,6 +36,11 @@

{{ object.summary }}

{{ object|product_ckeditor_content|safe }} + {% if object.video %} + {# duck-type the fact the videoplayer plugin also uses .video for the Video #} + {% include "cms/plugins/videoplayer/videoplayer.html" with instance=object %} + {% endif %} + {% if object.question_set.exists or object.files.exists or object.conditions.exists or object.locations.exists or product_links.exists or object.related_products.published.exists or object.contacts.exists %}
{% endif %} diff --git a/src/open_inwoner/utils/tests/test_text.py b/src/open_inwoner/utils/tests/test_text.py new file mode 100644 index 0000000000..28024fa657 --- /dev/null +++ b/src/open_inwoner/utils/tests/test_text.py @@ -0,0 +1,11 @@ +from django.test import TestCase + +from open_inwoner.utils.text import middle_truncate + + +class TextTestCase(TestCase): + def test_middle_truncate(self): + self.assertEqual(middle_truncate("abc", 5), "abc") + self.assertEqual( + middle_truncate("a_pretty_long_file_name.jpg", 23), "a_pretty...le_name.jpg" + ) diff --git a/src/open_inwoner/utils/text.py b/src/open_inwoner/utils/text.py new file mode 100644 index 0000000000..1dfe0c4d4a --- /dev/null +++ b/src/open_inwoner/utils/text.py @@ -0,0 +1,5 @@ +def middle_truncate(value: str, length: int, dots="...") -> str: + if len(value) <= length: + return value + half = int(length / 2) + return f"{value[: half - len(dots)]}{dots}{value[-half:]}"