feat: upload video lesson via src link

This commit is contained in:
Sergey Yarkov 2022-06-12 19:55:13 +03:00
parent cc36a77912
commit 4c0377d234
6 changed files with 31 additions and 32 deletions

View File

@ -37,6 +37,9 @@ export default class Lesson extends BaseModel {
@column() @column()
public description: string; public description: string;
@column()
public linked_video_url: string | null;
@column() @column()
public duration: string; public duration: string;

View File

@ -106,6 +106,7 @@ export default class LessonRepository {
duration: data.duration.toFormat('HH:mm:ss'), duration: data.duration.toFormat('HH:mm:ss'),
display_order: Number.parseInt(course.$extras.lessons_count, 10) + 1, display_order: Number.parseInt(course.$extras.lessons_count, 10) + 1,
course_id: course.id, course_id: course.id,
linked_video_url: !data.video ? data.linked_video_url : null,
}); });
/** /**
@ -116,7 +117,9 @@ export default class LessonRepository {
/** /**
* Move video file to disk and save to database * Move video file to disk and save to database
*/ */
if (data.video) {
await this.createVideo(lesson, data.video); await this.createVideo(lesson, data.video);
}
/** /**
* Create materials * Create materials
@ -154,22 +157,28 @@ export default class LessonRepository {
}); });
/** /**
* Update video * Update linked video url
*/
if (data.video) {
/**
* Delete video from drive and database
*/ */
if (data.linked_video_url && !data.video) {
if (lesson.video) { if (lesson.video) {
await this.Drive.delete(`videos/${lesson.video.name}`); await this.Drive.delete(`videos/${lesson.video.name}`);
} }
await lesson.related('video').query().delete(); await lesson.related('video').query().delete();
lesson.merge({ linked_video_url: data.linked_video_url });
}
/** /**
* Upload new video to drive and save to database * Update file video
*/ */
if (data.video) {
if (lesson.video) {
await this.Drive.delete(`videos/${lesson.video.name}`);
}
await lesson.related('video').query().delete();
await this.createVideo(lesson, data.video); await this.createVideo(lesson, data.video);
lesson.merge({ linked_video_url: null });
} }
/** /**

View File

@ -312,23 +312,7 @@ export default class CourseService {
}; };
} }
/** await this.deleteAllFiles([course]);
* Collect all file names from lessons in course and delete files
*/
const videos: string[] = course.lessons.map(lesson => lesson.video.name);
const materials: string[] = course.lessons.map(lesson => lesson.materials.map(m => m.name)).flat();
await Promise.all(
videos.map(async name => {
await Drive.delete(`videos/${name}`);
})
);
await Promise.all(
materials.map(async name => {
await Drive.delete(`materials/${name}`);
})
);
return { return {
success: true, success: true,
@ -377,13 +361,13 @@ export default class CourseService {
await teacher.load('roles'); await teacher.load('roles');
const isTeacher = RoleHelper.userContainRoles(teacher.roles, [RoleEnum.TEACHER]); const isTeacherOrAdmin = RoleHelper.userContainRoles(teacher.roles, [RoleEnum.ADMIN, RoleEnum.TEACHER]);
if (!isTeacher) { if (!isTeacherOrAdmin) {
return { return {
success: false, success: false,
status: HttpStatusEnum.BAD_REQUEST, status: HttpStatusEnum.BAD_REQUEST,
message: 'Author is not a teacher.', message: 'Author is not a teacher or admin.',
data: {}, data: {},
error: { error: {
code: 'E_BAD_REQUEST', code: 'E_BAD_REQUEST',
@ -392,13 +376,13 @@ export default class CourseService {
} }
} }
await this.courseRepository.update(id, data); const updated = await this.courseRepository.update(id, data);
return { return {
success: true, success: true,
status: HttpStatusEnum.OK, status: HttpStatusEnum.OK,
message: 'Course updated.', message: 'Course updated.',
data: course, data: updated || {},
}; };
} }

View File

@ -9,10 +9,11 @@ export default class CreateLessonValidator {
title: schema.string({}, [rules.maxLength(255)]), title: schema.string({}, [rules.maxLength(255)]),
description: schema.string(), description: schema.string(),
duration: schema.date({ format: 'HH:mm:ss' }), duration: schema.date({ format: 'HH:mm:ss' }),
video: schema.file({ video: schema.file.optional({
size: '5000mb', size: '5000mb',
extnames: ['mp4', 'mov', 'avi', 'wmv', 'webm', 'flv'], extnames: ['mp4', 'mov', 'avi', 'wmv', 'webm', 'flv'],
}), }),
linked_video_url: schema.string.optional([rules.regex(new RegExp('^(http|https|ftp)://'))]),
materials: schema.array.optional().members( materials: schema.array.optional().members(
schema.file({ schema.file({
size: '100mb', size: '100mb',

View File

@ -13,6 +13,7 @@ export default class UpdateLessonValidator {
size: '5000mb', size: '5000mb',
extnames: ['mp4', 'mov', 'avi', 'wmv', 'webm', 'flv'], extnames: ['mp4', 'mov', 'avi', 'wmv', 'webm', 'flv'],
}), }),
linked_video_url: schema.string.optional([rules.regex(new RegExp('^(http|https|ftp)://'))]),
materials: schema.array.nullableAndOptional().members( materials: schema.array.nullableAndOptional().members(
schema.file({ schema.file({
size: '100mb', size: '100mb',

View File

@ -11,6 +11,7 @@ export default class Lessons extends BaseSchema {
table.integer('display_order').notNullable(); table.integer('display_order').notNullable();
table.integer('color_id').unsigned().references('colors.id'); table.integer('color_id').unsigned().references('colors.id');
table.string('description'); table.string('description');
table.text('linked_video_url').nullable();
table.time('duration').notNullable(); table.time('duration').notNullable();
table.timestamp('created_at', { useTz: true }); table.timestamp('created_at', { useTz: true });
table.timestamp('updated_at', { useTz: true }); table.timestamp('updated_at', { useTz: true });