+ return ModelCache.Instance.doCache({
+ cacheType: 'local-actor-name',
+ key: preferredUsername,
+ // The server actor never change, so we can easily cache it
+ whitelist: () => preferredUsername === SERVER_ACTOR_NAME,
+ fun
+ })
+ }
+
+ static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Promise<MActorUrl> {
+ const fun = () => {
+ const query = {
+ attributes: [ 'url' ],
+ where: {
+ preferredUsername,
+ serverId: null
+ },
+ transaction
+ }
+
+ return ActorModel.unscoped()
+ .findOne(query)
+ }
+
+ return ModelCache.Instance.doCache({
+ cacheType: 'local-actor-name',
+ key: preferredUsername,
+ // The server actor never change, so we can easily cache it
+ whitelist: () => preferredUsername === SERVER_ACTOR_NAME,
+ fun
+ })
+ }
+
+ static loadByNameAndHost (preferredUsername: string, host: string): Promise<MActorFull> {
+ const query = {
+ where: {
+ preferredUsername
+ },
+ include: [
+ {
+ model: ServerModel,
+ required: true,
+ where: {
+ host
+ }
+ }
+ ]
+ }
+
+ return ActorModel.scope(ScopeNames.FULL).findOne(query)
+ }
+
+ static loadByUrl (url: string, transaction?: Transaction): Promise<MActorAccountChannelId> {
+ const query = {
+ where: {
+ url
+ },
+ transaction,
+ include: [
+ {
+ attributes: [ 'id' ],
+ model: AccountModel.unscoped(),
+ required: false
+ },
+ {
+ attributes: [ 'id' ],
+ model: VideoChannelModel.unscoped(),
+ required: false
+ }
+ ]
+ }
+
+ return ActorModel.unscoped().findOne(query)
+ }
+
+ static loadByUrlAndPopulateAccountAndChannel (url: string, transaction?: Transaction): Promise<MActorFull> {
+ const query = {
+ where: {
+ url
+ },
+ transaction
+ }
+
+ return ActorModel.scope(ScopeNames.FULL).findOne(query)
+ }
+
+ static rebuildFollowsCount (ofId: number, type: 'followers' | 'following', transaction?: Transaction) {
+ const sanitizedOfId = parseInt(ofId + '', 10)
+ const where = { id: sanitizedOfId }
+
+ let columnToUpdate: string
+ let columnOfCount: string
+
+ if (type === 'followers') {
+ columnToUpdate = 'followersCount'
+ columnOfCount = 'targetActorId'
+ } else {
+ columnToUpdate = 'followingCount'
+ columnOfCount = 'actorId'
+ }
+
+ return ActorModel.update({
+ [columnToUpdate]: literal(`(SELECT COUNT(*) FROM "actorFollow" WHERE "${columnOfCount}" = ${sanitizedOfId})`)
+ }, { where, transaction })
+ }
+
+ static loadAccountActorByVideoId (videoId: number): Promise<MActor> {
+ const query = {
+ include: [
+ {
+ attributes: [ 'id' ],
+ model: AccountModel.unscoped(),
+ required: true,
+ include: [
+ {
+ attributes: [ 'id', 'accountId' ],
+ model: VideoChannelModel.unscoped(),
+ required: true,
+ include: [
+ {
+ attributes: [ 'id', 'channelId' ],
+ model: VideoModel.unscoped(),
+ where: {
+ id: videoId
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+
+ return ActorModel.unscoped().findOne(query)
+ }
+
+ getSharedInbox (this: MActorWithInboxes) {
+ return this.sharedInboxUrl || this.inboxUrl
+ }
+
+ toFormattedSummaryJSON (this: MActorSummaryFormattable) {
+ let avatar: ActorImage = null
+ if (this.Avatar) {
+ avatar = this.Avatar.toFormattedJSON()