<p-table
[value]="videoImports" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
+ [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
>
<ng-template pTemplate="header">
<tr>
+ <th style="width: 40px;"></th>
<th i18n>URL</th>
<th i18n>Video</th>
<th i18n style="width: 150px">State</th>
</tr>
</ng-template>
- <ng-template pTemplate="body" let-videoImport>
+ <ng-template pTemplate="body" let-expanded="expanded" let-videoImport>
<tr>
+ <td>
+ <span *ngIf="videoImport.error" class="expander" [pRowToggler]="videoImport">
+ <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
+ </span>
+ </td>
+
<td>
<a [href]="videoImport.targetUrl" target="_blank" rel="noopener noreferrer">{{ videoImport.targetUrl }}</a>
</td>
</td>
</tr>
</ng-template>
+
+ <ng-template pTemplate="rowexpansion" let-videoImport>
+ <tr class="video-import-error" *ngIf="videoImport.error">
+ <td colspan="6">
+ <pre>{{ videoImport.error }}</pre>
+ </td>
+ </tr>
+ </ng-template>
</p-table>
@import '_variables';
@import '_mixins';
+
+pre {
+ font-size: 11px;
+}
+
+.video-import-error {
+ color: red;
+}
\ No newline at end of file
<label i18n for="targetUrl">URL</label>
<my-help
helpType="custom" i18n-customHtml
- customHtml="You can import any URL <a href='https://rg3.github.io/youtube-dl/supportedsites.html'>supported by youtube-dl</a> or URL that points to a raw MP4 file. Failure to secure these rights could cause legal trouble to yourself and your instance."
+ customHtml="You can import any URL <a href='https://rg3.github.io/youtube-dl/supportedsites.html' target='_blank' rel='noopener noreferrer'>supported by youtube-dl</a> or URL that points to a raw MP4 file. Failure to secure these rights could cause legal trouble to yourself and your instance."
></my-help>
<input type="text" id="targetUrl" [(ngModel)]="targetUrl" />
// Get information about this video
const { videoFileResolution } = await getVideoFileResolution(tempVideoPath)
- const fps = await getVideoFileFPS(tempVideoPath + 's')
+ const fps = await getVideoFileFPS(tempVideoPath)
const stats = await statPromise(tempVideoPath)
const duration = await getDurationFromVideoFile(tempVideoPath)
logger.error('Cannot cleanup files after a video import error.', { err: errUnlink })
}
+ videoImport.error = err.message
videoImport.state = VideoImportState.FAILED
await videoImport.save()
const handler = handlers[handlerName]
queue.process(JOB_CONCURRENCY[handlerName], handler)
- .catch(err => logger.error('Cannot execute job queue %s.', handlerName, { err }))
+
+ queue.on('failed', (job, err) => {
+ logger.error('Cannot execute job %d in queue %s.', job.id, handlerName, { payload: job.data, err })
+ })
queue.on('error', err => {
logger.error('Error in job queue %s.', handlerName, { err })
include: [
{
model: () => VideoModel,
- required: true,
+ required: false,
include: [
{
model: () => VideoChannelModel,
include: [
{
model: VideoModel,
- required: true,
+ required: false,
include: [
{
model: VideoChannelModel,
: undefined
return {
+ id: this.id,
targetUrl: this.targetUrl,
state: {
id: this.state,
label: VideoImportModel.getStateLabel(this.state)
},
+ error: this.error,
updatedAt: this.updatedAt.toISOString(),
createdAt: this.createdAt.toISOString(),
video
import { VideoImportState } from '../../index'
export interface VideoImport {
+ id: number
targetUrl: string
createdAt: string
updatedAt: string
state: VideoConstant<VideoImportState>
+ error?: string
video?: Video & { tags: string[] }
}