diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-12-04 10:34:40 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-12-04 10:34:40 +0100 |
commit | 2295ce6c4e7ba805cc100ff961527bebc2cd89e5 (patch) | |
tree | fce0a24074ac119aad730ef5c73c680500ff9578 /server | |
parent | 202f6b6c9dcc9b0aec4b0c1b15e455c22a7952a7 (diff) | |
download | PeerTube-2295ce6c4e7ba805cc100ff961527bebc2cd89e5.tar.gz PeerTube-2295ce6c4e7ba805cc100ff961527bebc2cd89e5.tar.zst PeerTube-2295ce6c4e7ba805cc100ff961527bebc2cd89e5.zip |
Add account avatar
Diffstat (limited to 'server')
-rw-r--r-- | server/initializers/constants.ts | 7 | ||||
-rw-r--r-- | server/initializers/database.ts | 2 | ||||
-rw-r--r-- | server/initializers/migrations/0115-account-avatar.ts | 31 | ||||
-rw-r--r-- | server/models/account/account-interface.ts | 3 | ||||
-rw-r--r-- | server/models/account/account.ts | 27 | ||||
-rw-r--r-- | server/models/account/user.ts | 5 | ||||
-rw-r--r-- | server/models/avatar/avatar-interface.ts | 16 | ||||
-rw-r--r-- | server/models/avatar/avatar.ts | 24 | ||||
-rw-r--r-- | server/models/avatar/index.ts | 1 | ||||
-rw-r--r-- | server/models/index.ts | 1 |
10 files changed, 111 insertions, 6 deletions
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index e3d779456..144a4edbf 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -14,7 +14,7 @@ import { FollowState } from '../../shared/models/accounts/follow.model' | |||
14 | 14 | ||
15 | // --------------------------------------------------------------------------- | 15 | // --------------------------------------------------------------------------- |
16 | 16 | ||
17 | const LAST_MIGRATION_VERSION = 110 | 17 | const LAST_MIGRATION_VERSION = 115 |
18 | 18 | ||
19 | // --------------------------------------------------------------------------- | 19 | // --------------------------------------------------------------------------- |
20 | 20 | ||
@@ -60,6 +60,7 @@ const CONFIG = { | |||
60 | PASSWORD: config.get<string>('database.password') | 60 | PASSWORD: config.get<string>('database.password') |
61 | }, | 61 | }, |
62 | STORAGE: { | 62 | STORAGE: { |
63 | AVATARS_DIR: join(root(), config.get<string>('storage.avatars')), | ||
63 | LOG_DIR: join(root(), config.get<string>('storage.logs')), | 64 | LOG_DIR: join(root(), config.get<string>('storage.logs')), |
64 | VIDEOS_DIR: join(root(), config.get<string>('storage.videos')), | 65 | VIDEOS_DIR: join(root(), config.get<string>('storage.videos')), |
65 | THUMBNAILS_DIR: join(root(), config.get<string>('storage.thumbnails')), | 66 | THUMBNAILS_DIR: join(root(), config.get<string>('storage.thumbnails')), |
@@ -105,6 +106,9 @@ const CONFIG = { | |||
105 | CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT | 106 | CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT |
106 | CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT | 107 | CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT |
107 | 108 | ||
109 | const AVATARS_DIR = { | ||
110 | ACCOUNT: join(CONFIG.STORAGE.AVATARS_DIR, 'account') | ||
111 | } | ||
108 | // --------------------------------------------------------------------------- | 112 | // --------------------------------------------------------------------------- |
109 | 113 | ||
110 | const CONSTRAINTS_FIELDS = { | 114 | const CONSTRAINTS_FIELDS = { |
@@ -356,6 +360,7 @@ export { | |||
356 | PREVIEWS_SIZE, | 360 | PREVIEWS_SIZE, |
357 | REMOTE_SCHEME, | 361 | REMOTE_SCHEME, |
358 | FOLLOW_STATES, | 362 | FOLLOW_STATES, |
363 | AVATARS_DIR, | ||
359 | SEARCHABLE_COLUMNS, | 364 | SEARCHABLE_COLUMNS, |
360 | SERVER_ACCOUNT_NAME, | 365 | SERVER_ACCOUNT_NAME, |
361 | PRIVATE_RSA_KEY_SIZE, | 366 | PRIVATE_RSA_KEY_SIZE, |
diff --git a/server/initializers/database.ts b/server/initializers/database.ts index 90dbba5b9..bb95992e1 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts | |||
@@ -2,6 +2,7 @@ import { join } from 'path' | |||
2 | import { flattenDepth } from 'lodash' | 2 | import { flattenDepth } from 'lodash' |
3 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string | 3 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string |
4 | import * as Sequelize from 'sequelize' | 4 | import * as Sequelize from 'sequelize' |
5 | import { AvatarModel } from '../models/avatar' | ||
5 | 6 | ||
6 | import { CONFIG } from './constants' | 7 | import { CONFIG } from './constants' |
7 | // Do not use barrel, we need to load database first | 8 | // Do not use barrel, we need to load database first |
@@ -36,6 +37,7 @@ export type PeerTubeDatabase = { | |||
36 | init?: (silent: boolean) => Promise<void>, | 37 | init?: (silent: boolean) => Promise<void>, |
37 | 38 | ||
38 | Application?: ApplicationModel, | 39 | Application?: ApplicationModel, |
40 | Avatar?: AvatarModel, | ||
39 | Account?: AccountModel, | 41 | Account?: AccountModel, |
40 | Job?: JobModel, | 42 | Job?: JobModel, |
41 | OAuthClient?: OAuthClientModel, | 43 | OAuthClient?: OAuthClientModel, |
diff --git a/server/initializers/migrations/0115-account-avatar.ts b/server/initializers/migrations/0115-account-avatar.ts new file mode 100644 index 000000000..e3531f5ce --- /dev/null +++ b/server/initializers/migrations/0115-account-avatar.ts | |||
@@ -0,0 +1,31 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | import { PeerTubeDatabase } from '../database' | ||
3 | |||
4 | async function up (utils: { | ||
5 | transaction: Sequelize.Transaction, | ||
6 | queryInterface: Sequelize.QueryInterface, | ||
7 | sequelize: Sequelize.Sequelize, | ||
8 | db: PeerTubeDatabase | ||
9 | }): Promise<void> { | ||
10 | await db.Avatar.sync() | ||
11 | |||
12 | const data = { | ||
13 | type: Sequelize.INTEGER, | ||
14 | allowNull: true, | ||
15 | references: { | ||
16 | model: 'Avatars', | ||
17 | key: 'id' | ||
18 | }, | ||
19 | onDelete: 'CASCADE' | ||
20 | } | ||
21 | await utils.queryInterface.addColumn('Accounts', 'avatarId', data) | ||
22 | } | ||
23 | |||
24 | function down (options) { | ||
25 | throw new Error('Not implemented.') | ||
26 | } | ||
27 | |||
28 | export { | ||
29 | up, | ||
30 | down | ||
31 | } | ||
diff --git a/server/models/account/account-interface.ts b/server/models/account/account-interface.ts index b369766dc..46fe068e3 100644 --- a/server/models/account/account-interface.ts +++ b/server/models/account/account-interface.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import * as Sequelize from 'sequelize' | 2 | import * as Sequelize from 'sequelize' |
3 | import { Account as FormattedAccount, ActivityPubActor } from '../../../shared' | 3 | import { Account as FormattedAccount, ActivityPubActor } from '../../../shared' |
4 | import { AvatarInstance } from '../avatar' | ||
4 | import { ServerInstance } from '../server/server-interface' | 5 | import { ServerInstance } from '../server/server-interface' |
5 | import { VideoChannelInstance } from '../video/video-channel-interface' | 6 | import { VideoChannelInstance } from '../video/video-channel-interface' |
6 | 7 | ||
@@ -51,6 +52,7 @@ export interface AccountAttributes { | |||
51 | serverId?: number | 52 | serverId?: number |
52 | userId?: number | 53 | userId?: number |
53 | applicationId?: number | 54 | applicationId?: number |
55 | avatarId?: number | ||
54 | } | 56 | } |
55 | 57 | ||
56 | export interface AccountInstance extends AccountClass, AccountAttributes, Sequelize.Instance<AccountAttributes> { | 58 | export interface AccountInstance extends AccountClass, AccountAttributes, Sequelize.Instance<AccountAttributes> { |
@@ -68,6 +70,7 @@ export interface AccountInstance extends AccountClass, AccountAttributes, Sequel | |||
68 | 70 | ||
69 | Server: ServerInstance | 71 | Server: ServerInstance |
70 | VideoChannels: VideoChannelInstance[] | 72 | VideoChannels: VideoChannelInstance[] |
73 | Avatar: AvatarInstance | ||
71 | } | 74 | } |
72 | 75 | ||
73 | export interface AccountModel extends AccountClass, Sequelize.Model<AccountInstance, AccountAttributes> {} | 76 | export interface AccountModel extends AccountClass, Sequelize.Model<AccountInstance, AccountAttributes> {} |
diff --git a/server/models/account/account.ts b/server/models/account/account.ts index 61a88524c..15be1126b 100644 --- a/server/models/account/account.ts +++ b/server/models/account/account.ts | |||
@@ -1,4 +1,6 @@ | |||
1 | import { join } from 'path' | ||
1 | import * as Sequelize from 'sequelize' | 2 | import * as Sequelize from 'sequelize' |
3 | import { Avatar } from '../../../shared/models/avatars/avatar.model' | ||
2 | import { | 4 | import { |
3 | activityPubContextify, | 5 | activityPubContextify, |
4 | isAccountFollowersCountValid, | 6 | isAccountFollowersCountValid, |
@@ -8,8 +10,10 @@ import { | |||
8 | isUserUsernameValid | 10 | isUserUsernameValid |
9 | } from '../../helpers' | 11 | } from '../../helpers' |
10 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' | 12 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' |
13 | import { AVATARS_DIR } from '../../initializers' | ||
11 | import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants' | 14 | import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants' |
12 | import { sendDeleteAccount } from '../../lib/activitypub/send/send-delete' | 15 | import { sendDeleteAccount } from '../../lib/activitypub/send/send-delete' |
16 | import { AvatarModel } from '../avatar' | ||
13 | import { addMethodsToModel } from '../utils' | 17 | import { addMethodsToModel } from '../utils' |
14 | import { AccountAttributes, AccountInstance, AccountMethods } from './account-interface' | 18 | import { AccountAttributes, AccountInstance, AccountMethods } from './account-interface' |
15 | 19 | ||
@@ -252,6 +256,14 @@ function associate (models) { | |||
252 | as: 'followers', | 256 | as: 'followers', |
253 | onDelete: 'cascade' | 257 | onDelete: 'cascade' |
254 | }) | 258 | }) |
259 | |||
260 | Account.hasOne(models.Avatar, { | ||
261 | foreignKey: { | ||
262 | name: 'avatarId', | ||
263 | allowNull: true | ||
264 | }, | ||
265 | onDelete: 'cascade' | ||
266 | }) | ||
255 | } | 267 | } |
256 | 268 | ||
257 | function afterDestroy (account: AccountInstance) { | 269 | function afterDestroy (account: AccountInstance) { |
@@ -265,6 +277,15 @@ function afterDestroy (account: AccountInstance) { | |||
265 | toFormattedJSON = function (this: AccountInstance) { | 277 | toFormattedJSON = function (this: AccountInstance) { |
266 | let host = CONFIG.WEBSERVER.HOST | 278 | let host = CONFIG.WEBSERVER.HOST |
267 | let score: number | 279 | let score: number |
280 | let avatar: Avatar = null | ||
281 | |||
282 | if (this.Avatar) { | ||
283 | avatar = { | ||
284 | path: join(AVATARS_DIR.ACCOUNT, this.Avatar.filename), | ||
285 | createdAt: this.Avatar.createdAt, | ||
286 | updatedAt: this.Avatar.updatedAt | ||
287 | } | ||
288 | } | ||
268 | 289 | ||
269 | if (this.Server) { | 290 | if (this.Server) { |
270 | host = this.Server.host | 291 | host = this.Server.host |
@@ -273,11 +294,15 @@ toFormattedJSON = function (this: AccountInstance) { | |||
273 | 294 | ||
274 | const json = { | 295 | const json = { |
275 | id: this.id, | 296 | id: this.id, |
297 | uuid: this.uuid, | ||
276 | host, | 298 | host, |
277 | score, | 299 | score, |
278 | name: this.name, | 300 | name: this.name, |
301 | followingCount: this.followingCount, | ||
302 | followersCount: this.followersCount, | ||
279 | createdAt: this.createdAt, | 303 | createdAt: this.createdAt, |
280 | updatedAt: this.updatedAt | 304 | updatedAt: this.updatedAt, |
305 | avatar | ||
281 | } | 306 | } |
282 | 307 | ||
283 | return json | 308 | return json |
diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 8f7c9b013..3705947c0 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts | |||
@@ -157,10 +157,7 @@ toFormattedJSON = function (this: UserInstance) { | |||
157 | roleLabel: USER_ROLE_LABELS[this.role], | 157 | roleLabel: USER_ROLE_LABELS[this.role], |
158 | videoQuota: this.videoQuota, | 158 | videoQuota: this.videoQuota, |
159 | createdAt: this.createdAt, | 159 | createdAt: this.createdAt, |
160 | account: { | 160 | account: this.Account.toFormattedJSON() |
161 | id: this.Account.id, | ||
162 | uuid: this.Account.uuid | ||
163 | } | ||
164 | } | 161 | } |
165 | 162 | ||
166 | if (Array.isArray(this.Account.VideoChannels) === true) { | 163 | if (Array.isArray(this.Account.VideoChannels) === true) { |
diff --git a/server/models/avatar/avatar-interface.ts b/server/models/avatar/avatar-interface.ts new file mode 100644 index 000000000..4af2b87b7 --- /dev/null +++ b/server/models/avatar/avatar-interface.ts | |||
@@ -0,0 +1,16 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | |||
3 | export namespace AvatarMethods {} | ||
4 | |||
5 | export interface AvatarClass {} | ||
6 | |||
7 | export interface AvatarAttributes { | ||
8 | filename: string | ||
9 | } | ||
10 | |||
11 | export interface AvatarInstance extends AvatarClass, AvatarAttributes, Sequelize.Instance<AvatarAttributes> { | ||
12 | createdAt: Date | ||
13 | updatedAt: Date | ||
14 | } | ||
15 | |||
16 | export interface AvatarModel extends AvatarClass, Sequelize.Model<AvatarInstance, AvatarAttributes> {} | ||
diff --git a/server/models/avatar/avatar.ts b/server/models/avatar/avatar.ts new file mode 100644 index 000000000..3d329d888 --- /dev/null +++ b/server/models/avatar/avatar.ts | |||
@@ -0,0 +1,24 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | import { addMethodsToModel } from '../utils' | ||
3 | import { AvatarAttributes, AvatarInstance, AvatarMethods } from './avatar-interface' | ||
4 | |||
5 | let Avatar: Sequelize.Model<AvatarInstance, AvatarAttributes> | ||
6 | |||
7 | export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { | ||
8 | Avatar = sequelize.define<AvatarInstance, AvatarAttributes>('Avatar', | ||
9 | { | ||
10 | filename: { | ||
11 | type: DataTypes.STRING, | ||
12 | allowNull: false | ||
13 | } | ||
14 | }, | ||
15 | {} | ||
16 | ) | ||
17 | |||
18 | const classMethods = [] | ||
19 | addMethodsToModel(Avatar, classMethods) | ||
20 | |||
21 | return Avatar | ||
22 | } | ||
23 | |||
24 | // ------------------------------ Statics ------------------------------ | ||
diff --git a/server/models/avatar/index.ts b/server/models/avatar/index.ts new file mode 100644 index 000000000..877aed1ce --- /dev/null +++ b/server/models/avatar/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './avatar-interface' | |||
diff --git a/server/models/index.ts b/server/models/index.ts index 65faa5294..fedd97dd1 100644 --- a/server/models/index.ts +++ b/server/models/index.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | export * from './application' | 1 | export * from './application' |
2 | export * from './avatar' | ||
2 | export * from './job' | 3 | export * from './job' |
3 | export * from './oauth' | 4 | export * from './oauth' |
4 | export * from './server' | 5 | export * from './server' |