diff --git a/frontend/src/components/LessonContent.vue b/frontend/src/components/LessonContent.vue index 2bb686c4..b29c94b8 100644 --- a/frontend/src/components/LessonContent.vue +++ b/frontend/src/components/LessonContent.vue @@ -9,6 +9,16 @@ allowfullscreen > +
+ +
+
+ +
@@ -97,6 +117,13 @@ const getYouTubeVideoSource = (block) => { return `https://www.youtube.com/embed/${block}` } +const getRutubeVideoSource = (block) => { + if (block.includes('{{')) { + block = getId(block) + } + return `https://rutube.ru/play/embed/${block}` +} + const getPDFSource = (block) => { return `${getId(block)}#toolbar=0` } @@ -105,3 +132,11 @@ const getId = (block) => { return block.match(/\(["']([^"']+?)["']\)/)[1] } + + diff --git a/frontend/src/pages/Lesson.vue b/frontend/src/pages/Lesson.vue index 23e0249a..b99ba6f7 100644 --- a/frontend/src/pages/Lesson.vue +++ b/frontend/src/pages/Lesson.vue @@ -258,6 +258,7 @@ v-if="lesson.data?.body" :content="lesson.data.body" :youtube="lesson.data.youtube" + :rutube="lesson.data.rutube" :quizId="lesson.data.quiz_id" />
diff --git a/frontend/src/pages/LessonForm.vue b/frontend/src/pages/LessonForm.vue index b3a3f8a8..6d3baa64 100644 --- a/frontend/src/pages/LessonForm.vue +++ b/frontend/src/pages/LessonForm.vue @@ -272,6 +272,7 @@ const lessonReference = createResource({ const convertToJSON = (lessonData) => { let blocks = [] + if (lessonData.youtube) { let youtubeID = lessonData.youtube.split('/').pop() blocks.push({ @@ -282,6 +283,20 @@ const convertToJSON = (lessonData) => { }, }) } + + if (lessonData.rutube) { + let rutubeID = lessonData.rutube.includes('rutube.ru') + ? lessonData.rutube.split('/').pop() + : lessonData.rutube; + blocks.push({ + type: 'embed', + data: { + service: 'rutube', + embed: `https://rutube.ru/play/embed/${rutubeID}`, + }, + }); + } + lessonData.body.split('\n').forEach((block) => { if (block.includes('{{ YouTubeVideo')) { let youtubeID = block.match(/\(["']([^"']+?)["']\)/)[1] @@ -294,6 +309,18 @@ const convertToJSON = (lessonData) => { embed: youtubeID, }, }) + } else if (block.includes('{{ RutubeVideo')) { + let rutubeID = block.match(/\(["']([^"']+?)["']\)/)[1]; + if (rutubeID.includes('rutube.ru')) { + rutubeID = rutubeID.split('/').pop(); + } + blocks.push({ + type: 'embed', + data: { + service: 'rutube', + embed: `https://rutube.ru/play/embed/${rutubeID}`, + }, + }); } else if (block.includes('{{ Quiz')) { let quiz = block.match(/\(["']([^"']+?)["']\)/)[1] blocks.push({ diff --git a/frontend/src/utils/index.js b/frontend/src/utils/index.js index fb24c9f7..16af365f 100644 --- a/frontend/src/utils/index.js +++ b/frontend/src/utils/index.js @@ -239,6 +239,15 @@ export function getEditorTools() { 'https://codesandbox.io/embed/<%= remote_id %>?view=editor+%2B+preview&module=%2Findex.html', html: "", }, + rutube: { + regex: /(?:https?:\/\/)?(?:www\.)?rutube\.ru\/(?:video\/|play\/embed\/)([^#&?=]*)/, + embedUrl: + 'https://rutube.ru/play/embed/<%= remote_id %>', + html: '', + height: 320, + width: 580, + id: ([id]) => id, + }, }, }, }, diff --git a/lms/hooks.py b/lms/hooks.py index 038eee9d..06573095 100644 --- a/lms/hooks.py +++ b/lms/hooks.py @@ -222,6 +222,7 @@ lms_markdown_macro_renderers = { "Exercise": "lms.plugins.exercise_renderer", "Quiz": "lms.plugins.quiz_renderer", "YouTubeVideo": "lms.plugins.youtube_video_renderer", + "RuTubeVideo": "lms.plugins.rutube_video_renderer", "Video": "lms.plugins.video_renderer", "Assignment": "lms.plugins.assignment_renderer", "Embed": "lms.plugins.embed_renderer", diff --git a/lms/lms/doctype/course_lesson/course_lesson.json b/lms/lms/doctype/course_lesson/course_lesson.json index 8cd0bcc5..93b4c2ec 100644 --- a/lms/lms/doctype/course_lesson/course_lesson.json +++ b/lms/lms/doctype/course_lesson/course_lesson.json @@ -22,6 +22,7 @@ "instructor_notes", "section_break_6", "youtube", + "rutube", "column_break_9", "quiz_id", "section_break_16", @@ -104,6 +105,12 @@ "fieldtype": "Data", "label": "YouTube Video URL" }, + { + "description": "RuTube Video will appear at the top of the lesson.", + "fieldname": "rutube", + "fieldtype": "Data", + "label": "RuTube Video URL" + }, { "fieldname": "section_break_16", "fieldtype": "Section Break", diff --git a/lms/lms/md.py b/lms/lms/md.py index 382d679c..87acdd52 100644 --- a/lms/lms/md.py +++ b/lms/lms/md.py @@ -35,6 +35,7 @@ def find_macros(text): >>> find_macros(text) [ ('YouTubeVideo': 'abcd1234') + ('RuTubeVideo': 'abcd1234') ('Exercise', 'two-circles'), ('Exercise', 'four-circles') ] @@ -119,5 +120,7 @@ def sanitize_html(html, macro): classname = "" if macro == "YouTubeVideo": classname = "lesson-video" + elif macro == "RutubeVideo": # Добавлено + classname = "rutube-video" return "
" + "\n".join(str(node) for node in nodes) + "
" diff --git a/lms/lms/utils.py b/lms/lms/utils.py index 0ef57451..d9d6a69d 100644 --- a/lms/lms/utils.py +++ b/lms/lms/utils.py @@ -145,6 +145,7 @@ def get_lesson_details(chapter, progress=False): "body", "creation", "youtube", + "rutube", "quiz_id", "question", "file_type", @@ -334,12 +335,17 @@ def render_html(lesson): youtube = lesson.youtube quiz_id = lesson.quiz_id body = lesson.body + rutube = lesson.get("rutube") if youtube and "/" in youtube: youtube = youtube.split("/")[-1] + if rutube and "/" in rutube: + rutube = rutube.split("/")[-1] + quiz_id = "{{ Quiz('" + quiz_id + "') }}" if quiz_id else "" youtube = "{{ YouTubeVideo('" + youtube + "') }}" if youtube else "" + rutube = "{{ RutubeVideo('" + rutube + "') }}" if rutube else "" text = youtube + body + quiz_id if lesson.question: @@ -1276,6 +1282,7 @@ def get_lesson(course, chapter, lesson): "body", "creation", "youtube", + "rutube", "quiz_id", "question", "file_type", @@ -1815,6 +1822,7 @@ def get_lesson_creation_details(course, chapter, lesson): "instructor_notes", "instructor_content", "youtube", + "rutube", "quiz_id", ], as_dict=1, diff --git a/lms/plugins.py b/lms/plugins.py index 11086e13..b6dece6a 100644 --- a/lms/plugins.py +++ b/lms/plugins.py @@ -174,6 +174,17 @@ def youtube_video_renderer(video_id): """ +def rutube_video_renderer(video_id): + return f""" + + """ def embed_renderer(details): type = details.split("|||")[0]