-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
31 changed files
with
828 additions
and
282 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from apps.notion.admin.file import NotionMaterialFileAdmin | ||
from apps.notion.admin.material import NotionMaterialAdmin | ||
from apps.notion.admin.video import NotionVideoAdmin | ||
|
||
__all__ = [ | ||
"NotionMaterialAdmin", | ||
"NotionMaterialFileAdmin", | ||
"NotionVideoAdmin", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from apps.notion.models import MaterialFile | ||
from core.admin import ModelAdmin, admin | ||
|
||
|
||
@admin.register(MaterialFile) | ||
class NotionMaterialFileAdmin(ModelAdmin): ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from typing import no_type_check | ||
|
||
from django import forms | ||
from django.utils.safestring import mark_safe | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from apps.notion import helpers | ||
from apps.notion.models import Video | ||
from core.admin import ModelAdmin, admin | ||
|
||
|
||
class NotionVideoForm(forms.ModelForm): | ||
class Meta: | ||
model = Video | ||
fields = "__all__" | ||
|
||
@no_type_check | ||
def clean_rutube_id(self) -> str: | ||
return helpers.get_rutube_video_id(self.cleaned_data["rutube_id"]) | ||
|
||
@no_type_check | ||
def clean_youtube_id(self) -> str: | ||
return helpers.get_youtube_video_id(self.cleaned_data["youtube_id"]) | ||
|
||
|
||
@admin.register(Video) | ||
class NotionVideoAdmin(ModelAdmin): | ||
form = NotionVideoForm | ||
|
||
list_display = [ | ||
"id", | ||
"youtube", | ||
"rutube", | ||
] | ||
fields = [ | ||
"youtube_id", | ||
"rutube_id", | ||
] | ||
|
||
@admin.display(description=_("Youtube")) | ||
@mark_safe | ||
def youtube(self, obj: Video) -> str: | ||
return f"""<a target="_blank" href="{ obj.get_youtube_url() }"> | ||
<img class="notion-youtube-logo" src="/static/logo/youtube.png" /> | ||
{obj.youtube_id}</a>""" | ||
|
||
@admin.display(description=_("RuTube")) | ||
@mark_safe | ||
def rutube(self, obj: Video) -> str: | ||
if obj.rutube_id is not None: | ||
return f"""<a target="_blank" href="{ obj.get_rutube_url() }"> | ||
<img class="notion-rutube-logo" src="/static/logo/rutube.png" /> | ||
{obj.rutube_id}</a>""" | ||
|
||
return "—" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Generated by Django 4.2.15 on 2024-09-04 07:38 | ||
|
||
from django.db import migrations, models | ||
|
||
import core.models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("notion", "0009_notion_slug_field_translation"), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="Video", | ||
fields=[ | ||
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), | ||
("created", models.DateTimeField(auto_now_add=True, db_index=True)), | ||
("modified", models.DateTimeField(blank=True, db_index=True, null=True)), | ||
("youtube_id", models.CharField(db_index=True, max_length=32, unique=True)), | ||
("rutube_id", models.CharField(blank=True, db_index=True, max_length=32, null=True)), | ||
], | ||
options={ | ||
"verbose_name": "Notion video", | ||
"verbose_name_plural": "Notion videos", | ||
}, | ||
bases=(core.models.TestUtilsMixin, models.Model), | ||
), | ||
] |
22 changes: 22 additions & 0 deletions
22
src/apps/notion/migrations/0011_notion_video_fields_and_description.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Generated by Django 4.2.15 on 2024-09-04 18:19 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("notion", "0010_notion_video"), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name="video", | ||
name="rutube_id", | ||
field=models.CharField(blank=True, db_index=True, help_text="Paste it from the address bar", max_length=256, null=True), | ||
), | ||
migrations.AlterField( | ||
model_name="video", | ||
name="youtube_id", | ||
field=models.CharField(db_index=True, help_text="Paste it from the address bar", max_length=256, unique=True), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from core.models import TimestampedModel, models | ||
|
||
|
||
class Video(TimestampedModel): | ||
"""Video mapping for multiple videohostings""" | ||
|
||
youtube_id = models.CharField(max_length=256, unique=True, db_index=True, help_text=_("Paste it from the address bar")) | ||
rutube_id = models.CharField(max_length=256, blank=True, null=True, db_index=True, help_text=_("Paste it from the address bar")) | ||
|
||
class Meta: | ||
verbose_name = _("Notion video") | ||
verbose_name_plural = _("Notion videos") | ||
|
||
def __str__(self) -> str: | ||
return self.youtube_id | ||
|
||
def get_youtube_embed_src(self) -> str: | ||
return f"https://www.youtube.com/embed/{ self.youtube_id }?rel=0" | ||
|
||
def get_youtube_url(self) -> str: | ||
return f"https://youtu.be/{ self.youtube_id }" | ||
|
||
def get_rutube_embed_src(self) -> str: | ||
return f"https://rutube.ru/play/embed/{self.rutube_id }/" | ||
|
||
def get_rutube_url(self) -> str: | ||
return f"https://rutube.ru/video/{ self.rutube_id }/" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from typing import Mapping | ||
|
||
from django.core.cache import cache | ||
|
||
from apps.notion.helpers import get_youtube_video_id | ||
from apps.notion.models import Video | ||
from apps.notion.types import BlockData as NotionBlockData | ||
|
||
|
||
def get_video_mapping() -> Mapping[str, Mapping[str, str]]: | ||
cached = cache.get("notion-video-mapping") | ||
if cached is not None: | ||
return cached | ||
|
||
mapping = dict() | ||
|
||
for video in Video.objects.all().iterator(): | ||
mapping[video.youtube_id] = { | ||
"youtube_embed": video.get_youtube_embed_src(), | ||
"rutube_embed": video.get_rutube_embed_src(), | ||
"rutube_url": video.get_rutube_url(), | ||
"youtube_url": video.get_youtube_url(), | ||
} | ||
|
||
cache.set(key="notion-video-mapping", value=mapping, timeout=60) | ||
|
||
return mapping | ||
|
||
|
||
def rewrite_video(block_data: NotionBlockData) -> NotionBlockData: | ||
if "type" not in block_data.get("value", {}): # skip rewrite for untyped blocks | ||
return block_data | ||
|
||
if block_data["value"]["type"] != "video": | ||
return block_data | ||
|
||
video_id = get_youtube_video_id(block_data["value"]["properties"]["source"][0][0]) | ||
|
||
if video_id is None: # skip rewrite for non-youtube videos | ||
return block_data | ||
|
||
video_mapping = get_video_mapping() | ||
|
||
if video_id in video_mapping: | ||
block_data["value"]["properties"]["source"] = [[video_mapping[video_id]["rutube_url"]]] | ||
block_data["value"]["format"]["link_provider"] = "RuTube" | ||
block_data["value"]["format"]["display_source"] = video_mapping[video_id]["rutube_embed"] | ||
|
||
return block_data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import pytest | ||
|
||
pytestmark = [ | ||
pytest.mark.django_db, | ||
pytest.mark.single_thread, | ||
pytest.mark.usefixtures( | ||
"mock_notion_response", | ||
"_cdn_dev_storage", | ||
), | ||
] | ||
|
||
|
||
@pytest.mark.parametrize("material_id", ["0e5693d2-173a-4f77-ae81-06813b6e5329", "0e5693d2173a4f77ae8106813b6e5329"]) | ||
def test_both_formats_work_with_id(api, material_id, mock_notion_response): | ||
api.get(f"/api/v2/notion/materials/{material_id}/") | ||
|
||
mock_notion_response.assert_called_once_with("0e5693d2173a4f77ae8106813b6e5329") | ||
|
||
|
||
@pytest.mark.parametrize("material_slug", ["4d5726e8-ee52-4448-b8f9-7be4c7f8e632", "4d5726e8ee524448b8f97be4c7f8e632"]) | ||
def test_both_formats_work_with_slug(api, material_slug, mock_notion_response): | ||
api.get(f"/api/v2/notion/materials/{material_slug}/") | ||
|
||
mock_notion_response.assert_called_once_with("0e5693d2173a4f77ae8106813b6e5329") # original material id | ||
|
||
|
||
def test_content_is_passed_from_notion_client(api, material): | ||
got = api.get(f"/api/v2/notion/materials/{material.page_id}/") | ||
|
||
assert got["block-1"]["value"]["parent_id"] == "100500" | ||
assert got["block-2"]["value"]["parent_id"] == "100600" | ||
|
||
|
||
def test_404_for_non_existant_materials(api, mock_notion_response): | ||
api.get("/api/v2/notion/materials/nonexistant/", expected_status_code=404) | ||
|
||
mock_notion_response.assert_not_called() | ||
|
||
|
||
def test_404_for_inactive_materials(api, mock_notion_response, material): | ||
material.update(active=False) | ||
|
||
api.get(f"/api/v2/notion/materials/{material.page_id}/", expected_status_code=404) | ||
|
||
mock_notion_response.assert_not_called() |
File renamed without changes.
File renamed without changes.
Oops, something went wrong.