diff --git a/src/models/drive-file.ts b/src/models/drive-file.ts index 0f8101445..c9fdb6156 100644 --- a/src/models/drive-file.ts +++ b/src/models/drive-file.ts @@ -42,6 +42,11 @@ export type IMetadata = { storageProps?: any; isSensitive?: boolean; + /** + * このファイルが添付された投稿のID一覧 + */ + attachedNoteIds?: mongo.ObjectID[]; + /** * 外部の(信頼されていない)URLへの直リンクか否か */ diff --git a/src/server/api/endpoints/drive/files/attached_notes.ts b/src/server/api/endpoints/drive/files/attached_notes.ts new file mode 100644 index 000000000..1187169c6 --- /dev/null +++ b/src/server/api/endpoints/drive/files/attached_notes.ts @@ -0,0 +1,48 @@ +import $ from 'cafy'; import ID from '../../../../../misc/cafy-id'; +import DriveFile from '../../../../../models/drive-file'; +import { ILocalUser } from '../../../../../models/user'; +import getParams from '../../../get-params'; +import { packMany } from '../../../../../models/note'; + +export const meta = { + stability: 'stable', + + desc: { + 'ja-JP': '指定したドライブのファイルが添付されている投稿一覧を取得します。', + 'en-US': 'Get the notes that specified file of drive attached.' + }, + + requireCredential: true, + + kind: 'drive-read', + + params: { + fileId: $.type(ID).note({ + desc: { + 'ja-JP': '対象のファイルID', + 'en-US': 'Target file ID' + } + }) + } +}; + +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); + + // Fetch file + const file = await DriveFile + .findOne({ + _id: ps.fileId, + 'metadata.userId': user._id, + 'metadata.deletedAt': { $exists: false } + }); + + if (file === null) { + return rej('file-not-found'); + } + + res(await packMany(file.metadata.attachedNoteIds || [], user, { + detail: true + })); +}); diff --git a/src/services/note/create.ts b/src/services/note/create.ts index ac6cc8651..401543b48 100644 --- a/src/services/note/create.ts +++ b/src/services/note/create.ts @@ -8,7 +8,7 @@ import renderNote from '../../remote/activitypub/renderer/note'; import renderCreate from '../../remote/activitypub/renderer/create'; import renderAnnounce from '../../remote/activitypub/renderer/announce'; import packAp from '../../remote/activitypub/renderer'; -import { IDriveFile } from '../../models/drive-file'; +import DriveFile, { IDriveFile } from '../../models/drive-file'; import notify from '../../notify'; import NoteWatching from '../../models/note-watching'; import watch from './watch'; @@ -173,6 +173,17 @@ export default async (user: IUser, data: Option, silent = false) => new Promise< // ハッシュタグ登録 tags.map(tag => registerHashtag(user, tag)); + // ファイルが添付されていた場合ドライブのファイルの「このファイルが添付された投稿一覧」プロパティにこの投稿を追加 + if (data.files) { + data.files.forEach(file => { + DriveFile.update({ _id: file._id }, { + $push: { + 'metadata.attachedNoteIds': note._id + } + }); + }); + } + // Increment notes count incNotesCount(user); diff --git a/src/services/note/delete.ts b/src/services/note/delete.ts index d86ca6e50..599525ac8 100644 --- a/src/services/note/delete.ts +++ b/src/services/note/delete.ts @@ -11,6 +11,7 @@ import perUserNotesChart from '../../chart/per-user-notes'; import config from '../../config'; import NoteUnread from '../../models/note-unread'; import read from './read'; +import DriveFile from '../../models/drive-file'; /** * 投稿を削除します。 @@ -48,6 +49,17 @@ export default async function(user: IUser, note: INote) { }); }); + // ファイルが添付されていた場合ドライブのファイルの「このファイルが添付された投稿一覧」プロパティからこの投稿を削除 + if (note.fileIds) { + note.fileIds.forEach(fileId => { + DriveFile.update({ _id: fileId }, { + $pull: { + 'metadata.attachedNoteIds': note._id + } + }); + }); + } + //#region ローカルの投稿なら削除アクティビティを配送 if (isLocalUser(user)) { const content = pack(renderDelete(renderTombstone(`${config.url}/notes/${note._id}`), user));