aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-12-04 10:34:40 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-12-04 10:34:40 +0100
commit2295ce6c4e7ba805cc100ff961527bebc2cd89e5 (patch)
treefce0a24074ac119aad730ef5c73c680500ff9578 /server
parent202f6b6c9dcc9b0aec4b0c1b15e455c22a7952a7 (diff)
downloadPeerTube-2295ce6c4e7ba805cc100ff961527bebc2cd89e5.tar.gz
PeerTube-2295ce6c4e7ba805cc100ff961527bebc2cd89e5.tar.zst
PeerTube-2295ce6c4e7ba805cc100ff961527bebc2cd89e5.zip
Add account avatar
Diffstat (limited to 'server')
-rw-r--r--server/initializers/constants.ts7
-rw-r--r--server/initializers/database.ts2
-rw-r--r--server/initializers/migrations/0115-account-avatar.ts31
-rw-r--r--server/models/account/account-interface.ts3
-rw-r--r--server/models/account/account.ts27
-rw-r--r--server/models/account/user.ts5
-rw-r--r--server/models/avatar/avatar-interface.ts16
-rw-r--r--server/models/avatar/avatar.ts24
-rw-r--r--server/models/avatar/index.ts1
-rw-r--r--server/models/index.ts1
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
17const LAST_MIGRATION_VERSION = 110 17const 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 = {
105CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT 106CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
106CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT 107CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
107 108
109const AVATARS_DIR = {
110 ACCOUNT: join(CONFIG.STORAGE.AVATARS_DIR, 'account')
111}
108// --------------------------------------------------------------------------- 112// ---------------------------------------------------------------------------
109 113
110const CONSTRAINTS_FIELDS = { 114const 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'
2import { flattenDepth } from 'lodash' 2import { flattenDepth } from 'lodash'
3require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string 3require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string
4import * as Sequelize from 'sequelize' 4import * as Sequelize from 'sequelize'
5import { AvatarModel } from '../models/avatar'
5 6
6import { CONFIG } from './constants' 7import { 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 @@
1import * as Sequelize from 'sequelize'
2import { PeerTubeDatabase } from '../database'
3
4async 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
24function down (options) {
25 throw new Error('Not implemented.')
26}
27
28export {
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 @@
1import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
2import * as Sequelize from 'sequelize' 2import * as Sequelize from 'sequelize'
3import { Account as FormattedAccount, ActivityPubActor } from '../../../shared' 3import { Account as FormattedAccount, ActivityPubActor } from '../../../shared'
4import { AvatarInstance } from '../avatar'
4import { ServerInstance } from '../server/server-interface' 5import { ServerInstance } from '../server/server-interface'
5import { VideoChannelInstance } from '../video/video-channel-interface' 6import { 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
56export interface AccountInstance extends AccountClass, AccountAttributes, Sequelize.Instance<AccountAttributes> { 58export 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
73export interface AccountModel extends AccountClass, Sequelize.Model<AccountInstance, AccountAttributes> {} 76export 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 @@
1import { join } from 'path'
1import * as Sequelize from 'sequelize' 2import * as Sequelize from 'sequelize'
3import { Avatar } from '../../../shared/models/avatars/avatar.model'
2import { 4import {
3 activityPubContextify, 5 activityPubContextify,
4 isAccountFollowersCountValid, 6 isAccountFollowersCountValid,
@@ -8,8 +10,10 @@ import {
8 isUserUsernameValid 10 isUserUsernameValid
9} from '../../helpers' 11} from '../../helpers'
10import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 12import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
13import { AVATARS_DIR } from '../../initializers'
11import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants' 14import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants'
12import { sendDeleteAccount } from '../../lib/activitypub/send/send-delete' 15import { sendDeleteAccount } from '../../lib/activitypub/send/send-delete'
16import { AvatarModel } from '../avatar'
13import { addMethodsToModel } from '../utils' 17import { addMethodsToModel } from '../utils'
14import { AccountAttributes, AccountInstance, AccountMethods } from './account-interface' 18import { 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
257function afterDestroy (account: AccountInstance) { 269function afterDestroy (account: AccountInstance) {
@@ -265,6 +277,15 @@ function afterDestroy (account: AccountInstance) {
265toFormattedJSON = function (this: AccountInstance) { 277toFormattedJSON = 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 @@
1import * as Sequelize from 'sequelize'
2
3export namespace AvatarMethods {}
4
5export interface AvatarClass {}
6
7export interface AvatarAttributes {
8 filename: string
9}
10
11export interface AvatarInstance extends AvatarClass, AvatarAttributes, Sequelize.Instance<AvatarAttributes> {
12 createdAt: Date
13 updatedAt: Date
14}
15
16export 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 @@
1import * as Sequelize from 'sequelize'
2import { addMethodsToModel } from '../utils'
3import { AvatarAttributes, AvatarInstance, AvatarMethods } from './avatar-interface'
4
5let Avatar: Sequelize.Model<AvatarInstance, AvatarAttributes>
6
7export 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 @@
1export * from './application' 1export * from './application'
2export * from './avatar'
2export * from './job' 3export * from './job'
3export * from './oauth' 4export * from './oauth'
4export * from './server' 5export * from './server'