diff options
author | Chocobozzz <me@florianbigard.com> | 2019-02-11 11:52:34 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-02-11 11:52:34 +0100 |
commit | 88108880bbdba473cfe36ecbebc1c3c4f972e102 (patch) | |
tree | b242efb3b4f0d7e49d88f2d1f2063b5b3b0489c0 /shared/models | |
parent | 53a94c7cfa8368da4cd248d65df8346905938f0c (diff) | |
parent | 9b712a2017e4ab3cf12cd6bd58278905520159d0 (diff) | |
download | PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.tar.gz PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.tar.zst PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.zip |
Merge branch 'develop' into pr/1217
Diffstat (limited to 'shared/models')
37 files changed, 380 insertions, 37 deletions
diff --git a/shared/models/activitypub/activity.ts b/shared/models/activitypub/activity.ts index 44cb99efb..89994f665 100644 --- a/shared/models/activitypub/activity.ts +++ b/shared/models/activitypub/activity.ts | |||
@@ -5,12 +5,14 @@ import { DislikeObject } from './objects/dislike-object' | |||
5 | import { VideoAbuseObject } from './objects/video-abuse-object' | 5 | import { VideoAbuseObject } from './objects/video-abuse-object' |
6 | import { VideoCommentObject } from './objects/video-comment-object' | 6 | import { VideoCommentObject } from './objects/video-comment-object' |
7 | import { ViewObject } from './objects/view-object' | 7 | import { ViewObject } from './objects/view-object' |
8 | import { APObject } from './objects/object.model' | ||
8 | 9 | ||
9 | export type Activity = ActivityCreate | ActivityUpdate | | 10 | export type Activity = ActivityCreate | ActivityUpdate | |
10 | ActivityDelete | ActivityFollow | ActivityAccept | ActivityAnnounce | | 11 | ActivityDelete | ActivityFollow | ActivityAccept | ActivityAnnounce | |
11 | ActivityUndo | ActivityLike | ActivityReject | 12 | ActivityUndo | ActivityLike | ActivityReject | ActivityView | ActivityDislike | ActivityFlag |
12 | 13 | ||
13 | export type ActivityType = 'Create' | 'Update' | 'Delete' | 'Follow' | 'Accept' | 'Announce' | 'Undo' | 'Like' | 'Reject' | 14 | export type ActivityType = 'Create' | 'Update' | 'Delete' | 'Follow' | 'Accept' | 'Announce' | 'Undo' | 'Like' | 'Reject' | |
15 | 'View' | 'Dislike' | 'Flag' | ||
14 | 16 | ||
15 | export interface ActivityAudience { | 17 | export interface ActivityAudience { |
16 | to: string[] | 18 | to: string[] |
@@ -59,15 +61,34 @@ export interface ActivityReject extends BaseActivity { | |||
59 | 61 | ||
60 | export interface ActivityAnnounce extends BaseActivity { | 62 | export interface ActivityAnnounce extends BaseActivity { |
61 | type: 'Announce' | 63 | type: 'Announce' |
62 | object: string | { id: string } | 64 | object: APObject |
63 | } | 65 | } |
64 | 66 | ||
65 | export interface ActivityUndo extends BaseActivity { | 67 | export interface ActivityUndo extends BaseActivity { |
66 | type: 'Undo', | 68 | type: 'Undo', |
67 | object: ActivityFollow | ActivityLike | ActivityCreate | ActivityAnnounce | 69 | object: ActivityFollow | ActivityLike | ActivityDislike | ActivityCreate | ActivityAnnounce |
68 | } | 70 | } |
69 | 71 | ||
70 | export interface ActivityLike extends BaseActivity { | 72 | export interface ActivityLike extends BaseActivity { |
71 | type: 'Like', | 73 | type: 'Like', |
72 | object: string | 74 | object: APObject |
75 | } | ||
76 | |||
77 | export interface ActivityView extends BaseActivity { | ||
78 | type: 'View', | ||
79 | actor: string | ||
80 | object: APObject | ||
81 | } | ||
82 | |||
83 | export interface ActivityDislike extends BaseActivity { | ||
84 | id: string | ||
85 | type: 'Dislike' | ||
86 | actor: string | ||
87 | object: APObject | ||
88 | } | ||
89 | |||
90 | export interface ActivityFlag extends BaseActivity { | ||
91 | type: 'Flag', | ||
92 | content: string, | ||
93 | object: APObject | ||
73 | } | 94 | } |
diff --git a/shared/models/activitypub/activitypub-ordered-collection.ts b/shared/models/activitypub/activitypub-ordered-collection.ts index dfec0bb76..3de0890bb 100644 --- a/shared/models/activitypub/activitypub-ordered-collection.ts +++ b/shared/models/activitypub/activitypub-ordered-collection.ts | |||
@@ -2,6 +2,9 @@ export interface ActivityPubOrderedCollection<T> { | |||
2 | '@context': string[] | 2 | '@context': string[] |
3 | type: 'OrderedCollection' | 'OrderedCollectionPage' | 3 | type: 'OrderedCollection' | 'OrderedCollectionPage' |
4 | totalItems: number | 4 | totalItems: number |
5 | partOf?: string | ||
6 | orderedItems: T[] | 5 | orderedItems: T[] |
6 | |||
7 | partOf?: string | ||
8 | next?: string | ||
9 | first?: string | ||
7 | } | 10 | } |
diff --git a/shared/models/activitypub/objects/cache-file-object.ts b/shared/models/activitypub/objects/cache-file-object.ts index 0a5125f5b..4b0a3a724 100644 --- a/shared/models/activitypub/objects/cache-file-object.ts +++ b/shared/models/activitypub/objects/cache-file-object.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import { ActivityVideoUrlObject } from './common-objects' | 1 | import { ActivityVideoUrlObject, ActivityPlaylistUrlObject } from './common-objects' |
2 | 2 | ||
3 | export interface CacheFileObject { | 3 | export interface CacheFileObject { |
4 | id: string | 4 | id: string |
5 | type: 'CacheFile', | 5 | type: 'CacheFile', |
6 | object: string | 6 | object: string |
7 | expires: string | 7 | expires: string |
8 | url: ActivityVideoUrlObject | 8 | url: ActivityVideoUrlObject | ActivityPlaylistUrlObject |
9 | } | 9 | } |
diff --git a/shared/models/activitypub/objects/common-objects.ts b/shared/models/activitypub/objects/common-objects.ts index 1de60da94..8c89810d6 100644 --- a/shared/models/activitypub/objects/common-objects.ts +++ b/shared/models/activitypub/objects/common-objects.ts | |||
@@ -19,28 +19,56 @@ export interface ActivityIconObject { | |||
19 | 19 | ||
20 | export type ActivityVideoUrlObject = { | 20 | export type ActivityVideoUrlObject = { |
21 | type: 'Link' | 21 | type: 'Link' |
22 | mimeType: 'video/mp4' | 'video/webm' | 'video/ogg' | 22 | // TODO: remove mimeType (backward compatibility, introduced in v1.1.0) |
23 | mimeType?: 'video/mp4' | 'video/webm' | 'video/ogg' | ||
24 | mediaType: 'video/mp4' | 'video/webm' | 'video/ogg' | ||
23 | href: string | 25 | href: string |
24 | height: number | 26 | height: number |
25 | size: number | 27 | size: number |
26 | fps: number | 28 | fps: number |
27 | } | 29 | } |
28 | 30 | ||
29 | export type ActivityUrlObject = | 31 | export type ActivityPlaylistSegmentHashesObject = { |
30 | ActivityVideoUrlObject | 32 | type: 'Link' |
31 | | | 33 | name: 'sha256' |
32 | { | 34 | // TODO: remove mimeType (backward compatibility, introduced in v1.1.0) |
33 | type: 'Link' | 35 | mimeType?: 'application/json' |
34 | mimeType: 'application/x-bittorrent' | 'application/x-bittorrent;x-scheme-handler/magnet' | 36 | mediaType: 'application/json' |
35 | href: string | 37 | href: string |
36 | height: number | 38 | } |
37 | } | 39 | |
38 | | | 40 | export type ActivityPlaylistInfohashesObject = { |
39 | { | 41 | type: 'Infohash' |
40 | type: 'Link' | 42 | name: string |
41 | mimeType: 'text/html' | 43 | } |
42 | href: string | 44 | |
43 | } | 45 | export type ActivityPlaylistUrlObject = { |
46 | type: 'Link' | ||
47 | // TODO: remove mimeType (backward compatibility, introduced in v1.1.0) | ||
48 | mimeType?: 'application/x-mpegURL' | ||
49 | mediaType: 'application/x-mpegURL' | ||
50 | href: string | ||
51 | tag?: (ActivityPlaylistSegmentHashesObject | ActivityPlaylistInfohashesObject)[] | ||
52 | } | ||
53 | |||
54 | export type ActivityBitTorrentUrlObject = { | ||
55 | type: 'Link' | ||
56 | // TODO: remove mimeType (backward compatibility, introduced in v1.1.0) | ||
57 | mimeType?: 'application/x-bittorrent' | 'application/x-bittorrent;x-scheme-handler/magnet' | ||
58 | mediaType: 'application/x-bittorrent' | 'application/x-bittorrent;x-scheme-handler/magnet' | ||
59 | href: string | ||
60 | height: number | ||
61 | } | ||
62 | |||
63 | export type ActivityHtmlUrlObject = { | ||
64 | type: 'Link' | ||
65 | // TODO: remove mimeType (backward compatibility, introduced in v1.1.0) | ||
66 | mimeType?: 'text/html' | ||
67 | mediaType: 'text/html' | ||
68 | href: string | ||
69 | } | ||
70 | |||
71 | export type ActivityUrlObject = ActivityVideoUrlObject | ActivityPlaylistUrlObject | ActivityBitTorrentUrlObject | ActivityHtmlUrlObject | ||
44 | 72 | ||
45 | export interface ActivityPubAttributedTo { | 73 | export interface ActivityPubAttributedTo { |
46 | type: 'Group' | 'Person' | 74 | type: 'Group' | 'Person' |
diff --git a/shared/models/activitypub/objects/dislike-object.ts b/shared/models/activitypub/objects/dislike-object.ts index 295175774..7218fb784 100644 --- a/shared/models/activitypub/objects/dislike-object.ts +++ b/shared/models/activitypub/objects/dislike-object.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | export interface DislikeObject { | 1 | export interface DislikeObject { |
2 | type: 'Dislike', | 2 | id: string |
3 | type: 'Dislike' | ||
3 | actor: string | 4 | actor: string |
4 | object: string | 5 | object: string |
5 | } | 6 | } |
diff --git a/shared/models/activitypub/objects/object.model.ts b/shared/models/activitypub/objects/object.model.ts new file mode 100644 index 000000000..3fd33800a --- /dev/null +++ b/shared/models/activitypub/objects/object.model.ts | |||
@@ -0,0 +1 @@ | |||
export type APObject = string | { id: string } | |||
diff --git a/shared/models/actors/actor.model.ts b/shared/models/actors/actor.model.ts index 6b3b1b47c..a3953874d 100644 --- a/shared/models/actors/actor.model.ts +++ b/shared/models/actors/actor.model.ts | |||
@@ -10,5 +10,5 @@ export interface Actor { | |||
10 | followersCount: number | 10 | followersCount: number |
11 | createdAt: Date | string | 11 | createdAt: Date | string |
12 | updatedAt: Date | string | 12 | updatedAt: Date | string |
13 | avatar: Avatar | 13 | avatar?: Avatar |
14 | } | 14 | } |
diff --git a/shared/models/blocklist/account-block.model.ts b/shared/models/blocklist/account-block.model.ts new file mode 100644 index 000000000..a942ed614 --- /dev/null +++ b/shared/models/blocklist/account-block.model.ts | |||
@@ -0,0 +1,7 @@ | |||
1 | import { Account } from '../actors' | ||
2 | |||
3 | export interface AccountBlock { | ||
4 | byAccount: Account | ||
5 | blockedAccount: Account | ||
6 | createdAt: Date | string | ||
7 | } | ||
diff --git a/shared/models/blocklist/index.ts b/shared/models/blocklist/index.ts new file mode 100644 index 000000000..fc7873270 --- /dev/null +++ b/shared/models/blocklist/index.ts | |||
@@ -0,0 +1,2 @@ | |||
1 | export * from './account-block.model' | ||
2 | export * from './server-block.model' | ||
diff --git a/shared/models/blocklist/server-block.model.ts b/shared/models/blocklist/server-block.model.ts new file mode 100644 index 000000000..a8b8af0b7 --- /dev/null +++ b/shared/models/blocklist/server-block.model.ts | |||
@@ -0,0 +1,9 @@ | |||
1 | import { Account } from '../actors' | ||
2 | |||
3 | export interface ServerBlock { | ||
4 | byAccount: Account | ||
5 | blockedServer: { | ||
6 | host: string | ||
7 | } | ||
8 | createdAt: Date | string | ||
9 | } | ||
diff --git a/shared/models/i18n/i18n.ts b/shared/models/i18n/i18n.ts index 5c3249452..d7164b73f 100644 --- a/shared/models/i18n/i18n.ts +++ b/shared/models/i18n/i18n.ts | |||
@@ -8,12 +8,14 @@ export const I18N_LOCALES = { | |||
8 | 'cs-CZ': 'Čeština', | 8 | 'cs-CZ': 'Čeština', |
9 | 'eo': 'Esperanto', | 9 | 'eo': 'Esperanto', |
10 | 'de-DE': 'Deutsch', | 10 | 'de-DE': 'Deutsch', |
11 | 'it-IT': 'Italiano', | ||
11 | 'es-ES': 'Español', | 12 | 'es-ES': 'Español', |
12 | 'oc': 'Occitan', | 13 | 'oc': 'Occitan', |
13 | 'zh-Hant-TW': '繁體中文(台灣)', | 14 | 'zh-Hant-TW': '繁體中文(台灣)', |
14 | 'pt-BR': 'Português (Brasil)', | 15 | 'pt-BR': 'Português (Brasil)', |
15 | 'sv-SE': 'svenska', | 16 | 'sv-SE': 'svenska', |
16 | // 'pl-PL': 'Polski' | 17 | 'pl-PL': 'Polski', |
18 | 'ru-RU': 'русский', | ||
17 | 'zh-Hans-CN': '简体中文(中国)' | 19 | 'zh-Hans-CN': '简体中文(中国)' |
18 | } | 20 | } |
19 | 21 | ||
@@ -26,8 +28,9 @@ const I18N_LOCALE_ALIAS = { | |||
26 | 'de': 'de-DE', | 28 | 'de': 'de-DE', |
27 | 'es': 'es-ES', | 29 | 'es': 'es-ES', |
28 | 'pt': 'pt-BR', | 30 | 'pt': 'pt-BR', |
29 | 'sv': 'sv-SE' | 31 | 'sv': 'sv-SE', |
30 | // 'pl': 'pl-PL' | 32 | 'pl': 'pl-PL', |
33 | 'ru': 'ru-RU' | ||
31 | } | 34 | } |
32 | 35 | ||
33 | export const POSSIBLE_LOCALES = Object.keys(I18N_LOCALES) | 36 | export const POSSIBLE_LOCALES = Object.keys(I18N_LOCALES) |
diff --git a/shared/models/index.ts b/shared/models/index.ts index e61d6cbdc..062533834 100644 --- a/shared/models/index.ts +++ b/shared/models/index.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | export * from './activitypub' | 1 | export * from './activitypub' |
2 | export * from './actors' | 2 | export * from './actors' |
3 | export * from './avatars' | 3 | export * from './avatars' |
4 | export * from './blocklist' | ||
4 | export * from './redundancy' | 5 | export * from './redundancy' |
5 | export * from './users' | 6 | export * from './users' |
6 | export * from './videos' | 7 | export * from './videos' |
diff --git a/shared/models/search/videos-search-query.model.ts b/shared/models/search/videos-search-query.model.ts index 29aa5c100..0db220758 100644 --- a/shared/models/search/videos-search-query.model.ts +++ b/shared/models/search/videos-search-query.model.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | import { NSFWQuery } from './nsfw-query.model' | 1 | import { NSFWQuery } from './nsfw-query.model' |
2 | import { VideoFilter } from '../videos' | ||
2 | 3 | ||
3 | export interface VideosSearchQuery { | 4 | export interface VideosSearchQuery { |
4 | search?: string | 5 | search?: string |
@@ -23,4 +24,6 @@ export interface VideosSearchQuery { | |||
23 | 24 | ||
24 | durationMin?: number // seconds | 25 | durationMin?: number // seconds |
25 | durationMax?: number // seconds | 26 | durationMax?: number // seconds |
27 | |||
28 | filter?: VideoFilter | ||
26 | } | 29 | } |
diff --git a/shared/models/server/contact-form.model.ts b/shared/models/server/contact-form.model.ts new file mode 100644 index 000000000..0696be8b4 --- /dev/null +++ b/shared/models/server/contact-form.model.ts | |||
@@ -0,0 +1,5 @@ | |||
1 | export interface ContactForm { | ||
2 | fromEmail: string | ||
3 | fromName: string | ||
4 | body: string | ||
5 | } | ||
diff --git a/shared/models/server/custom-config.model.ts b/shared/models/server/custom-config.model.ts index 3afd36fcd..b42ff90c6 100644 --- a/shared/models/server/custom-config.model.ts +++ b/shared/models/server/custom-config.model.ts | |||
@@ -41,6 +41,10 @@ export interface CustomConfig { | |||
41 | email: string | 41 | email: string |
42 | } | 42 | } |
43 | 43 | ||
44 | contactForm: { | ||
45 | enabled: boolean | ||
46 | } | ||
47 | |||
44 | user: { | 48 | user: { |
45 | videoQuota: number | 49 | videoQuota: number |
46 | videoQuotaDaily: number | 50 | videoQuotaDaily: number |
@@ -48,6 +52,7 @@ export interface CustomConfig { | |||
48 | 52 | ||
49 | transcoding: { | 53 | transcoding: { |
50 | enabled: boolean | 54 | enabled: boolean |
55 | allowAdditionalExtensions: boolean | ||
51 | threads: number | 56 | threads: number |
52 | resolutions: { | 57 | resolutions: { |
53 | '240p': boolean | 58 | '240p': boolean |
@@ -56,6 +61,9 @@ export interface CustomConfig { | |||
56 | '720p': boolean | 61 | '720p': boolean |
57 | '1080p': boolean | 62 | '1080p': boolean |
58 | } | 63 | } |
64 | hls: { | ||
65 | enabled: boolean | ||
66 | } | ||
59 | } | 67 | } |
60 | 68 | ||
61 | import: { | 69 | import: { |
diff --git a/shared/models/server/index.ts b/shared/models/server/index.ts new file mode 100644 index 000000000..c42f6f67f --- /dev/null +++ b/shared/models/server/index.ts | |||
@@ -0,0 +1,6 @@ | |||
1 | export * from './about.model' | ||
2 | export * from './contact-form.model' | ||
3 | export * from './custom-config.model' | ||
4 | export * from './job.model' | ||
5 | export * from './server-config.model' | ||
6 | export * from './server-stats.model' | ||
diff --git a/shared/models/server/job.model.ts b/shared/models/server/job.model.ts index 4046297c4..85bc9541b 100644 --- a/shared/models/server/job.model.ts +++ b/shared/models/server/job.model.ts | |||
@@ -8,7 +8,8 @@ export type JobType = 'activitypub-http-unicast' | | |||
8 | 'video-file' | | 8 | 'video-file' | |
9 | 'email' | | 9 | 'email' | |
10 | 'video-import' | | 10 | 'video-import' | |
11 | 'videos-views' | 11 | 'videos-views' | |
12 | 'activitypub-refresher' | ||
12 | 13 | ||
13 | export interface Job { | 14 | export interface Job { |
14 | id: number | 15 | id: number |
diff --git a/shared/models/server/server-config.model.ts b/shared/models/server/server-config.model.ts index 91196c1eb..baafed31f 100644 --- a/shared/models/server/server-config.model.ts +++ b/shared/models/server/server-config.model.ts | |||
@@ -15,13 +15,25 @@ export interface ServerConfig { | |||
15 | } | 15 | } |
16 | } | 16 | } |
17 | 17 | ||
18 | email: { | ||
19 | enabled: boolean | ||
20 | } | ||
21 | |||
22 | contactForm: { | ||
23 | enabled: boolean | ||
24 | } | ||
25 | |||
18 | signup: { | 26 | signup: { |
19 | allowed: boolean, | 27 | allowed: boolean, |
20 | allowedForCurrentIP: boolean, | 28 | allowedForCurrentIP: boolean |
21 | requiresEmailVerification: boolean | 29 | requiresEmailVerification: boolean |
22 | } | 30 | } |
23 | 31 | ||
24 | transcoding: { | 32 | transcoding: { |
33 | hls: { | ||
34 | enabled: boolean | ||
35 | } | ||
36 | |||
25 | enabledResolutions: number[] | 37 | enabledResolutions: number[] |
26 | } | 38 | } |
27 | 39 | ||
@@ -40,7 +52,7 @@ export interface ServerConfig { | |||
40 | file: { | 52 | file: { |
41 | size: { | 53 | size: { |
42 | max: number | 54 | max: number |
43 | }, | 55 | } |
44 | extensions: string[] | 56 | extensions: string[] |
45 | } | 57 | } |
46 | } | 58 | } |
@@ -70,4 +82,10 @@ export interface ServerConfig { | |||
70 | videoQuota: number | 82 | videoQuota: number |
71 | videoQuotaDaily: number | 83 | videoQuotaDaily: number |
72 | } | 84 | } |
85 | |||
86 | trending: { | ||
87 | videos: { | ||
88 | intervalDays: number | ||
89 | } | ||
90 | } | ||
73 | } | 91 | } |
diff --git a/shared/models/server/server-stats.model.ts b/shared/models/server/server-stats.model.ts index a6bd2d4d3..74f3de5d3 100644 --- a/shared/models/server/server-stats.model.ts +++ b/shared/models/server/server-stats.model.ts | |||
@@ -5,6 +5,7 @@ export interface ServerStats { | |||
5 | totalLocalVideos: number | 5 | totalLocalVideos: number |
6 | totalLocalVideoViews: number | 6 | totalLocalVideoViews: number |
7 | totalLocalVideoComments: number | 7 | totalLocalVideoComments: number |
8 | totalLocalVideoFilesSize: number | ||
8 | 9 | ||
9 | totalVideos: number | 10 | totalVideos: number |
10 | totalVideoComments: number | 11 | totalVideoComments: number |
diff --git a/shared/models/users/index.ts b/shared/models/users/index.ts index 7114741e0..cd07cf320 100644 --- a/shared/models/users/index.ts +++ b/shared/models/users/index.ts | |||
@@ -1,6 +1,8 @@ | |||
1 | export * from './user.model' | 1 | export * from './user.model' |
2 | export * from './user-create.model' | 2 | export * from './user-create.model' |
3 | export * from './user-login.model' | 3 | export * from './user-login.model' |
4 | export * from './user-notification.model' | ||
5 | export * from './user-notification-setting.model' | ||
4 | export * from './user-refresh-token.model' | 6 | export * from './user-refresh-token.model' |
5 | export * from './user-update.model' | 7 | export * from './user-update.model' |
6 | export * from './user-update-me.model' | 8 | export * from './user-update-me.model' |
diff --git a/shared/models/users/user-notification-setting.model.ts b/shared/models/users/user-notification-setting.model.ts new file mode 100644 index 000000000..531e12bba --- /dev/null +++ b/shared/models/users/user-notification-setting.model.ts | |||
@@ -0,0 +1,17 @@ | |||
1 | export enum UserNotificationSettingValue { | ||
2 | NONE = 0, | ||
3 | WEB = 1 << 0, | ||
4 | EMAIL = 1 << 1 | ||
5 | } | ||
6 | |||
7 | export interface UserNotificationSetting { | ||
8 | newVideoFromSubscription: UserNotificationSettingValue | ||
9 | newCommentOnMyVideo: UserNotificationSettingValue | ||
10 | videoAbuseAsModerator: UserNotificationSettingValue | ||
11 | blacklistOnMyVideo: UserNotificationSettingValue | ||
12 | myVideoPublished: UserNotificationSettingValue | ||
13 | myVideoImportFinished: UserNotificationSettingValue | ||
14 | newUserRegistration: UserNotificationSettingValue | ||
15 | newFollow: UserNotificationSettingValue | ||
16 | commentMention: UserNotificationSettingValue | ||
17 | } | ||
diff --git a/shared/models/users/user-notification.model.ts b/shared/models/users/user-notification.model.ts new file mode 100644 index 000000000..186b62612 --- /dev/null +++ b/shared/models/users/user-notification.model.ts | |||
@@ -0,0 +1,83 @@ | |||
1 | export enum UserNotificationType { | ||
2 | NEW_VIDEO_FROM_SUBSCRIPTION = 1, | ||
3 | NEW_COMMENT_ON_MY_VIDEO = 2, | ||
4 | NEW_VIDEO_ABUSE_FOR_MODERATORS = 3, | ||
5 | |||
6 | BLACKLIST_ON_MY_VIDEO = 4, | ||
7 | UNBLACKLIST_ON_MY_VIDEO = 5, | ||
8 | |||
9 | MY_VIDEO_PUBLISHED = 6, | ||
10 | |||
11 | MY_VIDEO_IMPORT_SUCCESS = 7, | ||
12 | MY_VIDEO_IMPORT_ERROR = 8, | ||
13 | |||
14 | NEW_USER_REGISTRATION = 9, | ||
15 | NEW_FOLLOW = 10, | ||
16 | COMMENT_MENTION = 11 | ||
17 | } | ||
18 | |||
19 | export interface VideoInfo { | ||
20 | id: number | ||
21 | uuid: string | ||
22 | name: string | ||
23 | } | ||
24 | |||
25 | export interface ActorInfo { | ||
26 | id: number | ||
27 | displayName: string | ||
28 | name: string | ||
29 | host: string | ||
30 | avatar?: { | ||
31 | path: string | ||
32 | } | ||
33 | } | ||
34 | |||
35 | export interface UserNotification { | ||
36 | id: number | ||
37 | type: UserNotificationType | ||
38 | read: boolean | ||
39 | |||
40 | video?: VideoInfo & { | ||
41 | channel: ActorInfo | ||
42 | } | ||
43 | |||
44 | videoImport?: { | ||
45 | id: number | ||
46 | video?: VideoInfo | ||
47 | torrentName?: string | ||
48 | magnetUri?: string | ||
49 | targetUrl?: string | ||
50 | } | ||
51 | |||
52 | comment?: { | ||
53 | id: number | ||
54 | threadId: number | ||
55 | account: ActorInfo | ||
56 | video: VideoInfo | ||
57 | } | ||
58 | |||
59 | videoAbuse?: { | ||
60 | id: number | ||
61 | video: VideoInfo | ||
62 | } | ||
63 | |||
64 | videoBlacklist?: { | ||
65 | id: number | ||
66 | video: VideoInfo | ||
67 | } | ||
68 | |||
69 | account?: ActorInfo | ||
70 | |||
71 | actorFollow?: { | ||
72 | id: number | ||
73 | follower: ActorInfo | ||
74 | following: { | ||
75 | type: 'account' | 'channel' | ||
76 | name: string | ||
77 | displayName: string | ||
78 | } | ||
79 | } | ||
80 | |||
81 | createdAt: string | ||
82 | updatedAt: string | ||
83 | } | ||
diff --git a/shared/models/users/user-right.enum.ts b/shared/models/users/user-right.enum.ts index c4ccd632f..090256bca 100644 --- a/shared/models/users/user-right.enum.ts +++ b/shared/models/users/user-right.enum.ts | |||
@@ -2,17 +2,26 @@ export enum UserRight { | |||
2 | ALL, | 2 | ALL, |
3 | 3 | ||
4 | MANAGE_USERS, | 4 | MANAGE_USERS, |
5 | |||
5 | MANAGE_SERVER_FOLLOW, | 6 | MANAGE_SERVER_FOLLOW, |
7 | |||
6 | MANAGE_SERVER_REDUNDANCY, | 8 | MANAGE_SERVER_REDUNDANCY, |
9 | |||
7 | MANAGE_VIDEO_ABUSES, | 10 | MANAGE_VIDEO_ABUSES, |
11 | |||
8 | MANAGE_JOBS, | 12 | MANAGE_JOBS, |
13 | |||
9 | MANAGE_CONFIGURATION, | 14 | MANAGE_CONFIGURATION, |
10 | 15 | ||
16 | MANAGE_ACCOUNTS_BLOCKLIST, | ||
17 | MANAGE_SERVERS_BLOCKLIST, | ||
18 | |||
11 | MANAGE_VIDEO_BLACKLIST, | 19 | MANAGE_VIDEO_BLACKLIST, |
12 | 20 | ||
13 | REMOVE_ANY_VIDEO, | 21 | REMOVE_ANY_VIDEO, |
14 | REMOVE_ANY_VIDEO_CHANNEL, | 22 | REMOVE_ANY_VIDEO_CHANNEL, |
15 | REMOVE_ANY_VIDEO_COMMENT, | 23 | REMOVE_ANY_VIDEO_COMMENT, |
16 | UPDATE_ANY_VIDEO, | 24 | UPDATE_ANY_VIDEO, |
25 | SEE_ALL_VIDEOS, | ||
17 | CHANGE_VIDEO_OWNERSHIP | 26 | CHANGE_VIDEO_OWNERSHIP |
18 | } | 27 | } |
diff --git a/shared/models/users/user-role.ts b/shared/models/users/user-role.ts index 552aad999..59c2ba106 100644 --- a/shared/models/users/user-role.ts +++ b/shared/models/users/user-role.ts | |||
@@ -26,7 +26,11 @@ const userRoleRights: { [ id: number ]: UserRight[] } = { | |||
26 | UserRight.REMOVE_ANY_VIDEO, | 26 | UserRight.REMOVE_ANY_VIDEO, |
27 | UserRight.REMOVE_ANY_VIDEO_CHANNEL, | 27 | UserRight.REMOVE_ANY_VIDEO_CHANNEL, |
28 | UserRight.REMOVE_ANY_VIDEO_COMMENT, | 28 | UserRight.REMOVE_ANY_VIDEO_COMMENT, |
29 | UserRight.UPDATE_ANY_VIDEO | 29 | UserRight.UPDATE_ANY_VIDEO, |
30 | UserRight.SEE_ALL_VIDEOS, | ||
31 | UserRight.MANAGE_ACCOUNTS_BLOCKLIST, | ||
32 | UserRight.MANAGE_SERVERS_BLOCKLIST, | ||
33 | UserRight.MANAGE_USERS | ||
30 | ], | 34 | ], |
31 | 35 | ||
32 | [UserRole.USER]: [] | 36 | [UserRole.USER]: [] |
diff --git a/shared/models/users/user-update-me.model.ts b/shared/models/users/user-update-me.model.ts index bbffe1487..e24afab94 100644 --- a/shared/models/users/user-update-me.model.ts +++ b/shared/models/users/user-update-me.model.ts | |||
@@ -4,7 +4,11 @@ export interface UserUpdateMe { | |||
4 | displayName?: string | 4 | displayName?: string |
5 | description?: string | 5 | description?: string |
6 | nsfwPolicy?: NSFWPolicyType | 6 | nsfwPolicy?: NSFWPolicyType |
7 | |||
8 | webTorrentEnabled?: boolean | ||
7 | autoPlayVideo?: boolean | 9 | autoPlayVideo?: boolean |
10 | videosHistoryEnabled?: boolean | ||
11 | |||
8 | email?: string | 12 | email?: string |
9 | currentPassword?: string | 13 | currentPassword?: string |
10 | password?: string | 14 | password?: string |
diff --git a/shared/models/users/user-update.model.ts b/shared/models/users/user-update.model.ts index ce866fb18..cd215bab3 100644 --- a/shared/models/users/user-update.model.ts +++ b/shared/models/users/user-update.model.ts | |||
@@ -1,7 +1,9 @@ | |||
1 | import { UserRole } from './user-role' | 1 | import { UserRole } from './user-role' |
2 | 2 | ||
3 | export interface UserUpdate { | 3 | export interface UserUpdate { |
4 | password?: string | ||
4 | email?: string | 5 | email?: string |
6 | emailVerified?: boolean | ||
5 | videoQuota?: number | 7 | videoQuota?: number |
6 | videoQuotaDaily?: number | 8 | videoQuotaDaily?: number |
7 | role?: UserRole | 9 | role?: UserRole |
diff --git a/shared/models/users/user.model.ts b/shared/models/users/user.model.ts index 8147dc48e..af783d389 100644 --- a/shared/models/users/user.model.ts +++ b/shared/models/users/user.model.ts | |||
@@ -2,18 +2,25 @@ import { Account } from '../actors' | |||
2 | import { VideoChannel } from '../videos/channel/video-channel.model' | 2 | import { VideoChannel } from '../videos/channel/video-channel.model' |
3 | import { UserRole } from './user-role' | 3 | import { UserRole } from './user-role' |
4 | import { NSFWPolicyType } from '../videos/nsfw-policy.type' | 4 | import { NSFWPolicyType } from '../videos/nsfw-policy.type' |
5 | import { UserNotificationSetting } from './user-notification-setting.model' | ||
5 | 6 | ||
6 | export interface User { | 7 | export interface User { |
7 | id: number | 8 | id: number |
8 | username: string | 9 | username: string |
9 | email: string | 10 | email: string |
11 | emailVerified: boolean | ||
10 | nsfwPolicy: NSFWPolicyType | 12 | nsfwPolicy: NSFWPolicyType |
13 | |||
11 | autoPlayVideo: boolean | 14 | autoPlayVideo: boolean |
15 | webTorrentEnabled: boolean | ||
16 | videosHistoryEnabled: boolean | ||
17 | |||
12 | role: UserRole | 18 | role: UserRole |
13 | videoQuota: number | 19 | videoQuota: number |
14 | videoQuotaDaily: number | 20 | videoQuotaDaily: number |
15 | createdAt: Date | 21 | createdAt: Date |
16 | account: Account | 22 | account: Account |
23 | notificationSettings?: UserNotificationSetting | ||
17 | videoChannels?: VideoChannel[] | 24 | videoChannels?: VideoChannel[] |
18 | 25 | ||
19 | blocked: boolean | 26 | blocked: boolean |
diff --git a/shared/models/videos/blacklist/video-blacklist-create.model.ts b/shared/models/videos/blacklist/video-blacklist-create.model.ts index 89c69cb56..6e7d36421 100644 --- a/shared/models/videos/blacklist/video-blacklist-create.model.ts +++ b/shared/models/videos/blacklist/video-blacklist-create.model.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export interface VideoBlacklistCreate { | 1 | export interface VideoBlacklistCreate { |
2 | reason?: string | 2 | reason?: string |
3 | unfederate?: boolean | ||
3 | } | 4 | } |
diff --git a/shared/models/videos/blacklist/video-blacklist.model.ts b/shared/models/videos/blacklist/video-blacklist.model.ts index ef4e5e3a2..4bd976190 100644 --- a/shared/models/videos/blacklist/video-blacklist.model.ts +++ b/shared/models/videos/blacklist/video-blacklist.model.ts | |||
@@ -2,6 +2,7 @@ export interface VideoBlacklist { | |||
2 | id: number | 2 | id: number |
3 | createdAt: Date | 3 | createdAt: Date |
4 | updatedAt: Date | 4 | updatedAt: Date |
5 | unfederated: boolean | ||
5 | reason?: string | 6 | reason?: string |
6 | 7 | ||
7 | video: { | 8 | video: { |
diff --git a/shared/models/videos/index.ts b/shared/models/videos/index.ts index 90a0e3053..056ae06da 100644 --- a/shared/models/videos/index.ts +++ b/shared/models/videos/index.ts | |||
@@ -21,6 +21,7 @@ export * from './video-update.model' | |||
21 | export * from './video.model' | 21 | export * from './video.model' |
22 | export * from './video-query.type' | 22 | export * from './video-query.type' |
23 | export * from './video-state.enum' | 23 | export * from './video-state.enum' |
24 | export * from './video-transcoding-fps.model' | ||
24 | export * from './caption/video-caption.model' | 25 | export * from './caption/video-caption.model' |
25 | export * from './caption/video-caption-update.model' | 26 | export * from './caption/video-caption-update.model' |
26 | export * from './import/video-import-create.model' | 27 | export * from './import/video-import-create.model' |
diff --git a/shared/models/videos/video-query.type.ts b/shared/models/videos/video-query.type.ts index ff0f527f3..f76a91aad 100644 --- a/shared/models/videos/video-query.type.ts +++ b/shared/models/videos/video-query.type.ts | |||
@@ -1 +1 @@ | |||
export type VideoFilter = 'local' | export type VideoFilter = 'local' | 'all-local' | ||
diff --git a/shared/models/videos/video-rate.type.ts b/shared/models/videos/video-rate.type.ts index 17aaba5a5..d48774a4b 100644 --- a/shared/models/videos/video-rate.type.ts +++ b/shared/models/videos/video-rate.type.ts | |||
@@ -1 +1 @@ | |||
export type VideoRateType = 'like' | 'dislike' | 'none' | export type VideoRateType = 'like' | 'dislike' | ||
diff --git a/shared/models/videos/video-resolution.enum.ts b/shared/models/videos/video-resolution.enum.ts index 100fc0e6e..7da5e7100 100644 --- a/shared/models/videos/video-resolution.enum.ts +++ b/shared/models/videos/video-resolution.enum.ts | |||
@@ -1,3 +1,5 @@ | |||
1 | import { VideoTranscodingFPS } from './video-transcoding-fps.model' | ||
2 | |||
1 | export enum VideoResolution { | 3 | export enum VideoResolution { |
2 | H_240P = 240, | 4 | H_240P = 240, |
3 | H_360P = 360, | 5 | H_360P = 360, |
@@ -5,3 +7,69 @@ export enum VideoResolution { | |||
5 | H_720P = 720, | 7 | H_720P = 720, |
6 | H_1080P = 1080 | 8 | H_1080P = 1080 |
7 | } | 9 | } |
10 | |||
11 | /** | ||
12 | * Bitrate targets for different resolutions, at VideoTranscodingFPS.AVERAGE. | ||
13 | * | ||
14 | * Sources for individual quality levels: | ||
15 | * Google Live Encoder: https://support.google.com/youtube/answer/2853702?hl=en | ||
16 | * YouTube Video Info (tested with random music video): https://www.h3xed.com/blogmedia/youtube-info.php | ||
17 | */ | ||
18 | function getBaseBitrate (resolution: VideoResolution) { | ||
19 | switch (resolution) { | ||
20 | case VideoResolution.H_240P: | ||
21 | // quality according to Google Live Encoder: 300 - 700 Kbps | ||
22 | // Quality according to YouTube Video Info: 186 Kbps | ||
23 | return 250 * 1000 | ||
24 | case VideoResolution.H_360P: | ||
25 | // quality according to Google Live Encoder: 400 - 1,000 Kbps | ||
26 | // Quality according to YouTube Video Info: 480 Kbps | ||
27 | return 500 * 1000 | ||
28 | case VideoResolution.H_480P: | ||
29 | // quality according to Google Live Encoder: 500 - 2,000 Kbps | ||
30 | // Quality according to YouTube Video Info: 879 Kbps | ||
31 | return 900 * 1000 | ||
32 | case VideoResolution.H_720P: | ||
33 | // quality according to Google Live Encoder: 1,500 - 4,000 Kbps | ||
34 | // Quality according to YouTube Video Info: 1752 Kbps | ||
35 | return 1750 * 1000 | ||
36 | case VideoResolution.H_1080P: // fallthrough | ||
37 | default: | ||
38 | // quality according to Google Live Encoder: 3000 - 6000 Kbps | ||
39 | // Quality according to YouTube Video Info: 3277 Kbps | ||
40 | return 3300 * 1000 | ||
41 | } | ||
42 | } | ||
43 | |||
44 | /** | ||
45 | * Calculate the target bitrate based on video resolution and FPS. | ||
46 | * | ||
47 | * The calculation is based on two values: | ||
48 | * Bitrate at VideoTranscodingFPS.AVERAGE is always the same as | ||
49 | * getBaseBitrate(). Bitrate at VideoTranscodingFPS.MAX is always | ||
50 | * getBaseBitrate() * 1.4. All other values are calculated linearly | ||
51 | * between these two points. | ||
52 | */ | ||
53 | export function getTargetBitrate (resolution: VideoResolution, fps: number, fpsTranscodingConstants: VideoTranscodingFPS) { | ||
54 | const baseBitrate = getBaseBitrate(resolution) | ||
55 | // The maximum bitrate, used when fps === VideoTranscodingFPS.MAX | ||
56 | // Based on numbers from Youtube, 60 fps bitrate divided by 30 fps bitrate: | ||
57 | // 720p: 2600 / 1750 = 1.49 | ||
58 | // 1080p: 4400 / 3300 = 1.33 | ||
59 | const maxBitrate = baseBitrate * 1.4 | ||
60 | const maxBitrateDifference = maxBitrate - baseBitrate | ||
61 | const maxFpsDifference = fpsTranscodingConstants.MAX - fpsTranscodingConstants.AVERAGE | ||
62 | // For 1080p video with default settings, this results in the following formula: | ||
63 | // 3300 + (x - 30) * (1320/30) | ||
64 | // Example outputs: | ||
65 | // 1080p10: 2420 kbps, 1080p30: 3300 kbps, 1080p60: 4620 kbps | ||
66 | // 720p10: 1283 kbps, 720p30: 1750 kbps, 720p60: 2450 kbps | ||
67 | return baseBitrate + (fps - fpsTranscodingConstants.AVERAGE) * (maxBitrateDifference / maxFpsDifference) | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * The maximum bitrate we expect to see on a transcoded video in bytes per second. | ||
72 | */ | ||
73 | export function getMaxBitrate (resolution: VideoResolution, fps: number, fpsTranscodingConstants: VideoTranscodingFPS) { | ||
74 | return getTargetBitrate(resolution, fps, fpsTranscodingConstants) * 2 | ||
75 | } | ||
diff --git a/shared/models/videos/video-streaming-playlist.model.ts b/shared/models/videos/video-streaming-playlist.model.ts new file mode 100644 index 000000000..17f8fe865 --- /dev/null +++ b/shared/models/videos/video-streaming-playlist.model.ts | |||
@@ -0,0 +1,12 @@ | |||
1 | import { VideoStreamingPlaylistType } from './video-streaming-playlist.type' | ||
2 | |||
3 | export class VideoStreamingPlaylist { | ||
4 | id: number | ||
5 | type: VideoStreamingPlaylistType | ||
6 | playlistUrl: string | ||
7 | segmentsSha256Url: string | ||
8 | |||
9 | redundancies: { | ||
10 | baseUrl: string | ||
11 | }[] | ||
12 | } | ||
diff --git a/shared/models/videos/video-streaming-playlist.type.ts b/shared/models/videos/video-streaming-playlist.type.ts new file mode 100644 index 000000000..3b403f295 --- /dev/null +++ b/shared/models/videos/video-streaming-playlist.type.ts | |||
@@ -0,0 +1,3 @@ | |||
1 | export enum VideoStreamingPlaylistType { | ||
2 | HLS = 1 | ||
3 | } | ||
diff --git a/shared/models/videos/video-transcoding-fps.model.ts b/shared/models/videos/video-transcoding-fps.model.ts new file mode 100644 index 000000000..82022d2f1 --- /dev/null +++ b/shared/models/videos/video-transcoding-fps.model.ts | |||
@@ -0,0 +1,6 @@ | |||
1 | export type VideoTranscodingFPS = { | ||
2 | MIN: number, | ||
3 | AVERAGE: number, | ||
4 | MAX: number, | ||
5 | KEEP_ORIGIN_FPS_RESOLUTION_MIN: number | ||
6 | } | ||
diff --git a/shared/models/videos/video.model.ts b/shared/models/videos/video.model.ts index 4a792fcbc..891831a9e 100644 --- a/shared/models/videos/video.model.ts +++ b/shared/models/videos/video.model.ts | |||
@@ -5,6 +5,7 @@ import { VideoChannel } from './channel/video-channel.model' | |||
5 | import { VideoPrivacy } from './video-privacy.enum' | 5 | import { VideoPrivacy } from './video-privacy.enum' |
6 | import { VideoScheduleUpdate } from './video-schedule-update.model' | 6 | import { VideoScheduleUpdate } from './video-schedule-update.model' |
7 | import { VideoConstant } from './video-constant.model' | 7 | import { VideoConstant } from './video-constant.model' |
8 | import { VideoStreamingPlaylist } from './video-streaming-playlist.model' | ||
8 | 9 | ||
9 | export interface VideoFile { | 10 | export interface VideoFile { |
10 | magnetUri: string | 11 | magnetUri: string |
@@ -24,7 +25,7 @@ export interface VideoChannelAttribute { | |||
24 | displayName: string | 25 | displayName: string |
25 | url: string | 26 | url: string |
26 | host: string | 27 | host: string |
27 | avatar: Avatar | 28 | avatar?: Avatar |
28 | } | 29 | } |
29 | 30 | ||
30 | export interface AccountAttribute { | 31 | export interface AccountAttribute { |
@@ -34,7 +35,7 @@ export interface AccountAttribute { | |||
34 | displayName: string | 35 | displayName: string |
35 | url: string | 36 | url: string |
36 | host: string | 37 | host: string |
37 | avatar: Avatar | 38 | avatar?: Avatar |
38 | } | 39 | } |
39 | 40 | ||
40 | export interface Video { | 41 | export interface Video { |
@@ -87,4 +88,8 @@ export interface VideoDetails extends Video { | |||
87 | // Not optional in details (unlike in Video) | 88 | // Not optional in details (unlike in Video) |
88 | waitTranscoding: boolean | 89 | waitTranscoding: boolean |
89 | state: VideoConstant<VideoState> | 90 | state: VideoConstant<VideoState> |
91 | |||
92 | trackerUrls: string[] | ||
93 | |||
94 | streamingPlaylists: VideoStreamingPlaylist[] | ||
90 | } | 95 | } |