Compare commits
10 commits
develop
...
refactor-d
Author | SHA1 | Date | |
---|---|---|---|
|
f87232178a | ||
|
3cfcb89c04 | ||
|
b9b81e6665 | ||
|
7945224a74 | ||
|
1eece5ab3d | ||
|
1d3342e641 | ||
|
7cd2a9c9f2 | ||
|
528be133ff | ||
|
d6db5e46e8 | ||
|
b5c235f837 |
18 changed files with 150 additions and 139 deletions
|
@ -1,31 +0,0 @@
|
||||||
import { IDriveFile } from '../models/drive-file';
|
|
||||||
import config from '../config';
|
|
||||||
|
|
||||||
export default function(file: IDriveFile, thumbnail = false): string {
|
|
||||||
if (file == null) return null;
|
|
||||||
|
|
||||||
const isImage = file.contentType && file.contentType.startsWith('image/');
|
|
||||||
|
|
||||||
if (file.metadata.withoutChunks) {
|
|
||||||
if (thumbnail) {
|
|
||||||
return file.metadata.thumbnailUrl || file.metadata.webpublicUrl || (isImage ? file.metadata.url : null);
|
|
||||||
} else {
|
|
||||||
return file.metadata.webpublicUrl || file.metadata.url;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (thumbnail) {
|
|
||||||
return `${config.driveUrl}/${file._id}?thumbnail`;
|
|
||||||
} else {
|
|
||||||
return `${config.driveUrl}/${file._id}?web`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getOriginalUrl(file: IDriveFile) {
|
|
||||||
if (file.metadata && file.metadata.url) {
|
|
||||||
return file.metadata.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
const accessKey = file.metadata ? file.metadata.accessKey : null;
|
|
||||||
return `${config.driveUrl}/${file._id}${accessKey ? '?original=' + accessKey : ''}`;
|
|
||||||
}
|
|
|
@ -4,16 +4,57 @@ import { pack as packFolder } from './drive-folder';
|
||||||
import { pack as packUser } from './user';
|
import { pack as packUser } from './user';
|
||||||
import monkDb, { nativeDbConn, dbLogger } from '../db/mongodb';
|
import monkDb, { nativeDbConn, dbLogger } from '../db/mongodb';
|
||||||
import isObjectId from '../misc/is-objectid';
|
import isObjectId from '../misc/is-objectid';
|
||||||
import getDriveFileUrl, { getOriginalUrl } from '../misc/get-drive-file-url';
|
import config from '../config';
|
||||||
|
import uuid = require('uuid');
|
||||||
|
|
||||||
const DriveFile = monkDb.get<IDriveFile>('driveFiles.files');
|
const DriveFile = monkDb.get<IDriveFile>('driveFiles.files');
|
||||||
DriveFile.createIndex('md5');
|
DriveFile.createIndex('md5');
|
||||||
DriveFile.createIndex('metadata.uri');
|
DriveFile.createIndex('metadata.uri');
|
||||||
|
DriveFile.createIndex('metadata.url');
|
||||||
|
DriveFile.createIndex('metadata.webpublicUrl');
|
||||||
|
DriveFile.createIndex('metadata.thumbnailUrl');
|
||||||
DriveFile.createIndex('metadata.userId');
|
DriveFile.createIndex('metadata.userId');
|
||||||
DriveFile.createIndex('metadata.folderId');
|
DriveFile.createIndex('metadata.folderId');
|
||||||
DriveFile.createIndex('metadata._user.host');
|
DriveFile.createIndex('metadata._user.host');
|
||||||
export default DriveFile;
|
export default DriveFile;
|
||||||
|
|
||||||
|
// 後方互換性のため
|
||||||
|
DriveFile.findOne({
|
||||||
|
$or: [{
|
||||||
|
'metadata.url': { $exists: false }
|
||||||
|
}, {
|
||||||
|
'metadata.url': null
|
||||||
|
}]
|
||||||
|
}).then(x => {
|
||||||
|
if (x != null) {
|
||||||
|
DriveFile.find({
|
||||||
|
$or: [{
|
||||||
|
'metadata.url': { $exists: false }
|
||||||
|
}, {
|
||||||
|
'metadata.url': null
|
||||||
|
}]
|
||||||
|
}, { fields: { _id: true, filename: true, contentType: true } }).then(xs => {
|
||||||
|
for (const x of xs) {
|
||||||
|
let [ext] = (x.filename.match(/\.([a-zA-Z0-9_-]+)$/) || ['']);
|
||||||
|
|
||||||
|
if (ext === '') {
|
||||||
|
if (x.contentType === 'image/jpeg') ext = '.jpg';
|
||||||
|
if (x.contentType === 'image/png') ext = '.png';
|
||||||
|
if (x.contentType === 'image/webp') ext = '.webp';
|
||||||
|
}
|
||||||
|
|
||||||
|
DriveFile.update({ _id: x._id }, {
|
||||||
|
$set: {
|
||||||
|
'metadata.url': `${config.driveUrl}/${uuid.v4()}${ext}`,
|
||||||
|
'metadata.webpublicUrl': `${config.driveUrl}/${uuid.v4()}${ext}`,
|
||||||
|
'metadata.thumbnailUrl': `${config.driveUrl}/${uuid.v4()}.jpg`,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export const DriveFileChunk = monkDb.get('driveFiles.chunks');
|
export const DriveFileChunk = monkDb.get('driveFiles.chunks');
|
||||||
|
|
||||||
export const getDriveFileBucket = async (): Promise<mongo.GridFSBucket> => {
|
export const getDriveFileBucket = async (): Promise<mongo.GridFSBucket> => {
|
||||||
|
@ -36,26 +77,10 @@ export type IMetadata = {
|
||||||
*/
|
*/
|
||||||
uri?: string;
|
uri?: string;
|
||||||
|
|
||||||
/**
|
url: string;
|
||||||
* URL for web(生成されている場合) or original
|
|
||||||
* * オブジェクトストレージを利用している or リモートサーバーへの直リンクである 場合のみ
|
|
||||||
*/
|
|
||||||
url?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URL for thumbnail (thumbnailがなければなし)
|
|
||||||
* * オブジェクトストレージを利用している or リモートサーバーへの直リンクである 場合のみ
|
|
||||||
*/
|
|
||||||
thumbnailUrl?: string;
|
thumbnailUrl?: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* URL for original (web用が生成されてない場合はurlがoriginalを指す)
|
|
||||||
* * オブジェクトストレージを利用している or リモートサーバーへの直リンクである 場合のみ
|
|
||||||
*/
|
|
||||||
webpublicUrl?: string;
|
webpublicUrl?: string;
|
||||||
|
|
||||||
accessKey?: string;
|
|
||||||
|
|
||||||
src?: string;
|
src?: string;
|
||||||
deletedAt?: Date;
|
deletedAt?: Date;
|
||||||
|
|
||||||
|
@ -188,8 +213,10 @@ export const pack = (
|
||||||
|
|
||||||
_target = Object.assign(_target, _file.metadata);
|
_target = Object.assign(_target, _file.metadata);
|
||||||
|
|
||||||
_target.url = getDriveFileUrl(_file);
|
const isImage = file.contentType && file.contentType.startsWith('image/');
|
||||||
_target.thumbnailUrl = getDriveFileUrl(_file, true);
|
|
||||||
|
_target.url = _file.metadata.webpublicUrl || _file.metadata.url;
|
||||||
|
_target.thumbnailUrl = _file.metadata.thumbnailUrl || _file.metadata.webpublicUrl || (isImage ? _file.metadata.url : '/files/thumbnail-not-available.png');
|
||||||
_target.isRemote = _file.metadata.isRemote;
|
_target.isRemote = _file.metadata.isRemote;
|
||||||
|
|
||||||
if (_target.properties == null) _target.properties = {};
|
if (_target.properties == null) _target.properties = {};
|
||||||
|
@ -224,7 +251,7 @@ export const pack = (
|
||||||
delete _target._user;
|
delete _target._user;
|
||||||
|
|
||||||
if (opts.self) {
|
if (opts.self) {
|
||||||
_target.url = getOriginalUrl(_file);
|
_target.url = _file.metadata.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(_target);
|
resolve(_target);
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as fs from 'fs';
|
||||||
import * as mongo from 'mongodb';
|
import * as mongo from 'mongodb';
|
||||||
|
|
||||||
import { queueLogger } from '../logger';
|
import { queueLogger } from '../logger';
|
||||||
import addFile from '../../services/drive/add-file';
|
import { addDriveFile } from '../../services/drive/add-file';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import dateFormat = require('dateformat');
|
import dateFormat = require('dateformat');
|
||||||
import Blocking from '../../models/blocking';
|
import Blocking from '../../models/blocking';
|
||||||
|
@ -81,7 +81,7 @@ export async function exportBlocking(job: bq.Job, done: any): Promise<void> {
|
||||||
logger.succ(`Exported to: ${path}`);
|
logger.succ(`Exported to: ${path}`);
|
||||||
|
|
||||||
const fileName = 'blocking-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
|
const fileName = 'blocking-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
|
||||||
const driveFile = await addFile(user, path, fileName);
|
const driveFile = await addDriveFile(user, path, fileName);
|
||||||
|
|
||||||
logger.succ(`Exported to: ${driveFile._id}`);
|
logger.succ(`Exported to: ${driveFile._id}`);
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as fs from 'fs';
|
||||||
import * as mongo from 'mongodb';
|
import * as mongo from 'mongodb';
|
||||||
|
|
||||||
import { queueLogger } from '../logger';
|
import { queueLogger } from '../logger';
|
||||||
import addFile from '../../services/drive/add-file';
|
import { addDriveFile } from '../../services/drive/add-file';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import dateFormat = require('dateformat');
|
import dateFormat = require('dateformat');
|
||||||
import Following from '../../models/following';
|
import Following from '../../models/following';
|
||||||
|
@ -81,7 +81,7 @@ export async function exportFollowing(job: bq.Job, done: any): Promise<void> {
|
||||||
logger.succ(`Exported to: ${path}`);
|
logger.succ(`Exported to: ${path}`);
|
||||||
|
|
||||||
const fileName = 'following-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
|
const fileName = 'following-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
|
||||||
const driveFile = await addFile(user, path, fileName);
|
const driveFile = await addDriveFile(user, path, fileName);
|
||||||
|
|
||||||
logger.succ(`Exported to: ${driveFile._id}`);
|
logger.succ(`Exported to: ${driveFile._id}`);
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as fs from 'fs';
|
||||||
import * as mongo from 'mongodb';
|
import * as mongo from 'mongodb';
|
||||||
|
|
||||||
import { queueLogger } from '../logger';
|
import { queueLogger } from '../logger';
|
||||||
import addFile from '../../services/drive/add-file';
|
import { addDriveFile } from '../../services/drive/add-file';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import dateFormat = require('dateformat');
|
import dateFormat = require('dateformat');
|
||||||
import Mute from '../../models/mute';
|
import Mute from '../../models/mute';
|
||||||
|
@ -81,7 +81,7 @@ export async function exportMute(job: bq.Job, done: any): Promise<void> {
|
||||||
logger.succ(`Exported to: ${path}`);
|
logger.succ(`Exported to: ${path}`);
|
||||||
|
|
||||||
const fileName = 'mute-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
|
const fileName = 'mute-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
|
||||||
const driveFile = await addFile(user, path, fileName);
|
const driveFile = await addDriveFile(user, path, fileName);
|
||||||
|
|
||||||
logger.succ(`Exported to: ${driveFile._id}`);
|
logger.succ(`Exported to: ${driveFile._id}`);
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
|
@ -5,7 +5,7 @@ import * as mongo from 'mongodb';
|
||||||
|
|
||||||
import { queueLogger } from '../logger';
|
import { queueLogger } from '../logger';
|
||||||
import Note, { INote } from '../../models/note';
|
import Note, { INote } from '../../models/note';
|
||||||
import addFile from '../../services/drive/add-file';
|
import { addDriveFile } from '../../services/drive/add-file';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import dateFormat = require('dateformat');
|
import dateFormat = require('dateformat');
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ export async function exportNotes(job: bq.Job, done: any): Promise<void> {
|
||||||
logger.succ(`Exported to: ${path}`);
|
logger.succ(`Exported to: ${path}`);
|
||||||
|
|
||||||
const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.json';
|
const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.json';
|
||||||
const driveFile = await addFile(user, path, fileName);
|
const driveFile = await addDriveFile(user, path, fileName);
|
||||||
|
|
||||||
logger.succ(`Exported to: ${driveFile._id}`);
|
logger.succ(`Exported to: ${driveFile._id}`);
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { URL } from 'url';
|
||||||
import { resolveNote, extractEmojis } from './note';
|
import { resolveNote, extractEmojis } from './note';
|
||||||
import { registerOrFetchInstanceDoc } from '../../../services/register-or-fetch-instance-doc';
|
import { registerOrFetchInstanceDoc } from '../../../services/register-or-fetch-instance-doc';
|
||||||
import Instance from '../../../models/instance';
|
import Instance from '../../../models/instance';
|
||||||
import getDriveFileUrl from '../../../misc/get-drive-file-url';
|
|
||||||
import { IEmoji } from '../../../models/emoji';
|
import { IEmoji } from '../../../models/emoji';
|
||||||
import { ITag, extractHashtags } from './tag';
|
import { ITag, extractHashtags } from './tag';
|
||||||
import Following from '../../../models/following';
|
import Following from '../../../models/following';
|
||||||
|
@ -227,8 +226,8 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
|
||||||
|
|
||||||
const avatarId = avatar ? avatar._id : null;
|
const avatarId = avatar ? avatar._id : null;
|
||||||
const bannerId = banner ? banner._id : null;
|
const bannerId = banner ? banner._id : null;
|
||||||
const avatarUrl = getDriveFileUrl(avatar, true);
|
const avatarUrl = avatar.metadata.thumbnailUrl;
|
||||||
const bannerUrl = getDriveFileUrl(banner, false);
|
const bannerUrl = banner.metadata.webpublicUrl;
|
||||||
const avatarColor = avatar && avatar.metadata.properties.avgColor ? avatar.metadata.properties.avgColor : null;
|
const avatarColor = avatar && avatar.metadata.properties.avgColor ? avatar.metadata.properties.avgColor : null;
|
||||||
const bannerColor = banner && avatar.metadata.properties.avgColor ? banner.metadata.properties.avgColor : null;
|
const bannerColor = banner && avatar.metadata.properties.avgColor ? banner.metadata.properties.avgColor : null;
|
||||||
|
|
||||||
|
@ -373,13 +372,13 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
|
||||||
|
|
||||||
if (avatar) {
|
if (avatar) {
|
||||||
updates.avatarId = avatar._id;
|
updates.avatarId = avatar._id;
|
||||||
updates.avatarUrl = getDriveFileUrl(avatar, true);
|
updates.avatarUrl = avatar.metadata.thumbnailUrl;
|
||||||
updates.avatarColor = avatar.metadata.properties.avgColor ? avatar.metadata.properties.avgColor : null;
|
updates.avatarColor = avatar.metadata.properties.avgColor ? avatar.metadata.properties.avgColor : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (banner) {
|
if (banner) {
|
||||||
updates.bannerId = banner._id;
|
updates.bannerId = banner._id;
|
||||||
updates.bannerUrl = getDriveFileUrl(banner, true);
|
updates.bannerUrl = banner.metadata.webpublicUrl;
|
||||||
updates.bannerColor = banner.metadata.properties.avgColor ? banner.metadata.properties.avgColor : null;
|
updates.bannerColor = banner.metadata.properties.avgColor ? banner.metadata.properties.avgColor : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { IDriveFile } from '../../../models/drive-file';
|
import { IDriveFile } from '../../../models/drive-file';
|
||||||
import getDriveFileUrl from '../../../misc/get-drive-file-url';
|
|
||||||
|
|
||||||
export default (file: IDriveFile) => ({
|
export default (file: IDriveFile) => ({
|
||||||
type: 'Document',
|
type: 'Document',
|
||||||
mediaType: file.contentType,
|
mediaType: file.contentType,
|
||||||
url: getDriveFileUrl(file)
|
url: file.metadata.webpublicUrl
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { IDriveFile } from '../../../models/drive-file';
|
import { IDriveFile } from '../../../models/drive-file';
|
||||||
import getDriveFileUrl from '../../../misc/get-drive-file-url';
|
|
||||||
|
|
||||||
export default (file: IDriveFile) => ({
|
export default (file: IDriveFile) => ({
|
||||||
type: 'Image',
|
type: 'Image',
|
||||||
url: getDriveFileUrl(file),
|
url: file.metadata.webpublicUrl,
|
||||||
sensitive: file.metadata.isSensitive
|
sensitive: file.metadata.isSensitive
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as ms from 'ms';
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import ID, { transform } from '../../../../../misc/cafy-id';
|
import ID, { transform } from '../../../../../misc/cafy-id';
|
||||||
import { validateFileName, pack } from '../../../../../models/drive-file';
|
import { validateFileName, pack } from '../../../../../models/drive-file';
|
||||||
import create from '../../../../../services/drive/add-file';
|
import { addDriveFile } from '../../../../../services/drive/add-file';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import { apiLogger } from '../../../logger';
|
import { apiLogger } from '../../../logger';
|
||||||
import { ApiError } from '../../../error';
|
import { ApiError } from '../../../error';
|
||||||
|
@ -87,7 +87,7 @@ export default define(meta, async (ps, user, app, file, cleanup) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Create file
|
// Create file
|
||||||
const driveFile = await create(user, file.path, name, null, ps.folderId, ps.force, false, null, null, ps.isSensitive);
|
const driveFile = await addDriveFile(user, file.path, name, null, ps.folderId, ps.force, false, null, null, ps.isSensitive);
|
||||||
return pack(driveFile, { self: true });
|
return pack(driveFile, { self: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
apiLogger.error(e);
|
apiLogger.error(e);
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as mongo from 'mongodb';
|
|
||||||
import ID, { transform } from '../../../../../misc/cafy-id';
|
import ID, { transform } from '../../../../../misc/cafy-id';
|
||||||
import DriveFile, { pack, IDriveFile } from '../../../../../models/drive-file';
|
import DriveFile, { pack, IDriveFile } from '../../../../../models/drive-file';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import config from '../../../../../config';
|
|
||||||
import { ApiError } from '../../../error';
|
import { ApiError } from '../../../error';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
@ -73,28 +71,16 @@ export default define(meta, async (ps, user) => {
|
||||||
'metadata.deletedAt': { $exists: false }
|
'metadata.deletedAt': { $exists: false }
|
||||||
});
|
});
|
||||||
} else if (ps.url) {
|
} else if (ps.url) {
|
||||||
const isInternalStorageUrl = ps.url.startsWith(config.driveUrl);
|
file = await DriveFile.findOne({
|
||||||
if (isInternalStorageUrl) {
|
$or: [{
|
||||||
// Extract file ID from url
|
'metadata.url': ps.url
|
||||||
// e.g.
|
}, {
|
||||||
// http://misskey.local/files/foo?original=bar --> foo
|
'metadata.webpublicUrl': ps.url
|
||||||
const fileId = new mongo.ObjectID(ps.url.replace(config.driveUrl, '').replace(/\?(.*)$/, '').replace(/\//g, ''));
|
}, {
|
||||||
file = await DriveFile.findOne({
|
'metadata.thumbnailUrl': ps.url
|
||||||
_id: fileId,
|
}],
|
||||||
'metadata.deletedAt': { $exists: false }
|
'metadata.deletedAt': { $exists: false }
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
file = await DriveFile.findOne({
|
|
||||||
$or: [{
|
|
||||||
'metadata.url': ps.url
|
|
||||||
}, {
|
|
||||||
'metadata.webpublicUrl': ps.url
|
|
||||||
}, {
|
|
||||||
'metadata.thumbnailUrl': ps.url
|
|
||||||
}],
|
|
||||||
'metadata.deletedAt': { $exists: false }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw new ApiError(meta.errors.fileIdOrUrlRequired);
|
throw new ApiError(meta.errors.fileIdOrUrlRequired);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import DriveFile from '../../../../models/drive-file';
|
||||||
import acceptAllFollowRequests from '../../../../services/following/requests/accept-all';
|
import acceptAllFollowRequests from '../../../../services/following/requests/accept-all';
|
||||||
import { publishToFollowers } from '../../../../services/i/update';
|
import { publishToFollowers } from '../../../../services/i/update';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import getDriveFileUrl from '../../../../misc/get-drive-file-url';
|
|
||||||
import { parse, parsePlain } from '../../../../mfm/parse';
|
import { parse, parsePlain } from '../../../../mfm/parse';
|
||||||
import extractEmojis from '../../../../misc/extract-emojis';
|
import extractEmojis from '../../../../misc/extract-emojis';
|
||||||
import extractHashtags from '../../../../misc/extract-hashtags';
|
import extractHashtags from '../../../../misc/extract-hashtags';
|
||||||
|
@ -195,7 +194,7 @@ export default define(meta, async (ps, user, app) => {
|
||||||
if (avatar.metadata.deletedAt) {
|
if (avatar.metadata.deletedAt) {
|
||||||
updates.avatarUrl = null;
|
updates.avatarUrl = null;
|
||||||
} else {
|
} else {
|
||||||
updates.avatarUrl = getDriveFileUrl(avatar, true);
|
updates.avatarUrl = avatar.metadata.thumbnailUrl;
|
||||||
|
|
||||||
if (avatar.metadata.properties.avgColor) {
|
if (avatar.metadata.properties.avgColor) {
|
||||||
updates.avatarColor = avatar.metadata.properties.avgColor;
|
updates.avatarColor = avatar.metadata.properties.avgColor;
|
||||||
|
@ -214,7 +213,7 @@ export default define(meta, async (ps, user, app) => {
|
||||||
if (banner.metadata.deletedAt) {
|
if (banner.metadata.deletedAt) {
|
||||||
updates.bannerUrl = null;
|
updates.bannerUrl = null;
|
||||||
} else {
|
} else {
|
||||||
updates.bannerUrl = getDriveFileUrl(banner, false);
|
updates.bannerUrl = banner.metadata.webpublicUrl;
|
||||||
|
|
||||||
if (banner.metadata.properties.avgColor) {
|
if (banner.metadata.properties.avgColor) {
|
||||||
updates.bannerColor = banner.metadata.properties.avgColor;
|
updates.bannerColor = banner.metadata.properties.avgColor;
|
||||||
|
@ -236,7 +235,7 @@ export default define(meta, async (ps, user, app) => {
|
||||||
if (wallpaper.metadata.deletedAt) {
|
if (wallpaper.metadata.deletedAt) {
|
||||||
updates.wallpaperUrl = null;
|
updates.wallpaperUrl = null;
|
||||||
} else {
|
} else {
|
||||||
updates.wallpaperUrl = getDriveFileUrl(wallpaper);
|
updates.wallpaperUrl = wallpaper.metadata.webpublicUrl;
|
||||||
|
|
||||||
if (wallpaper.metadata.properties.avgColor) {
|
if (wallpaper.metadata.properties.avgColor) {
|
||||||
updates.wallpaperColor = wallpaper.metadata.properties.avgColor;
|
updates.wallpaperColor = wallpaper.metadata.properties.avgColor;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import resolveRemoteUser from '../../../../remote/resolve-user';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { apiLogger } from '../../logger';
|
import { apiLogger } from '../../logger';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
|
import DriveFile from '../../../../models/drive-file';
|
||||||
|
|
||||||
const cursorOption = { fields: { data: false } };
|
const cursorOption = { fields: { data: false } };
|
||||||
|
|
||||||
|
@ -103,6 +104,33 @@ export default define(meta, async (ps, me) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 後方互換性のため
|
||||||
|
// TODO: そのうち削除
|
||||||
|
if (user.avatarId) {
|
||||||
|
const avatar = await DriveFile.findOne({ _id: user.avatarId });
|
||||||
|
User.update({ _id: user._id }, {
|
||||||
|
$set: {
|
||||||
|
avatarUrl: avatar.metadata.thumbnailUrl,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (user.bannerId) {
|
||||||
|
const banner = await DriveFile.findOne({ _id: user.bannerId });
|
||||||
|
User.update({ _id: user._id }, {
|
||||||
|
$set: {
|
||||||
|
bannerUrl: banner.metadata.webpublicUrl,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (user.wallpaperId) {
|
||||||
|
const wallpaper = await DriveFile.findOne({ _id: user.wallpaperId });
|
||||||
|
User.update({ _id: user._id }, {
|
||||||
|
$set: {
|
||||||
|
wallpaperUrl: wallpaper.metadata.webpublicUrl,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return await pack(user, me, {
|
return await pack(user, me, {
|
||||||
detail: true
|
detail: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,12 +29,17 @@ router.get('/default-avatar.jpg', ctx => {
|
||||||
|
|
||||||
router.get('/app-default.jpg', ctx => {
|
router.get('/app-default.jpg', ctx => {
|
||||||
const file = fs.createReadStream(`${__dirname}/assets/dummy.png`);
|
const file = fs.createReadStream(`${__dirname}/assets/dummy.png`);
|
||||||
ctx.set('Content-Type', 'image/jpeg');
|
ctx.set('Content-Type', 'image/png');
|
||||||
ctx.body = file;
|
ctx.body = file;
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/:id', sendDriveFile);
|
router.get('/thumbnail-not-available.png', ctx => {
|
||||||
router.get('/:id/*', sendDriveFile);
|
const file = fs.createReadStream(`${__dirname}/assets/thumbnail-not-available.png`);
|
||||||
|
ctx.set('Content-Type', 'image/png');
|
||||||
|
ctx.body = file;
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/*', sendDriveFile);
|
||||||
|
|
||||||
// Register router
|
// Register router
|
||||||
app.use(router.routes());
|
app.use(router.routes());
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import * as Koa from 'koa';
|
import * as Koa from 'koa';
|
||||||
import * as send from 'koa-send';
|
import * as send from 'koa-send';
|
||||||
import * as mongodb from 'mongodb';
|
|
||||||
import DriveFile, { getDriveFileBucket } from '../../models/drive-file';
|
import DriveFile, { getDriveFileBucket } from '../../models/drive-file';
|
||||||
import DriveFileThumbnail, { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail';
|
import DriveFileThumbnail, { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail';
|
||||||
import DriveFileWebpublic, { getDriveFileWebpublicBucket } from '../../models/drive-file-webpublic';
|
import DriveFileWebpublic, { getDriveFileWebpublicBucket } from '../../models/drive-file-webpublic';
|
||||||
import { serverLogger } from '..';
|
import { serverLogger } from '..';
|
||||||
|
import config from '../../config';
|
||||||
|
|
||||||
const assets = `${__dirname}/../../server/file/assets/`;
|
const assets = `${__dirname}/../../server/file/assets/`;
|
||||||
|
|
||||||
|
@ -14,16 +14,19 @@ const commonReadableHandlerGenerator = (ctx: Koa.BaseContext) => (e: Error): voi
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function(ctx: Koa.BaseContext) {
|
export default async function(ctx: Koa.BaseContext) {
|
||||||
// Validate id
|
let url = ctx.href;
|
||||||
if (!mongodb.ObjectID.isValid(ctx.params.id)) {
|
if (url.startsWith('http://') && config.url.startsWith('https://')) url = url.replace('http://', 'https://');
|
||||||
ctx.throw(400, 'incorrect id');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileId = new mongodb.ObjectID(ctx.params.id);
|
|
||||||
|
|
||||||
// Fetch drive file
|
// Fetch drive file
|
||||||
const file = await DriveFile.findOne({ _id: fileId });
|
const file = await DriveFile.findOne({
|
||||||
|
$or: [{
|
||||||
|
'metadata.url': url
|
||||||
|
}, {
|
||||||
|
'metadata.webpublicUrl': url
|
||||||
|
}, {
|
||||||
|
'metadata.thumbnailUrl': url
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
ctx.status = 404;
|
ctx.status = 404;
|
||||||
|
@ -43,21 +46,16 @@ export default async function(ctx: Koa.BaseContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendRaw = async () => {
|
const sendRaw = async () => {
|
||||||
if (file.metadata && file.metadata.accessKey && file.metadata.accessKey != ctx.query['original']) {
|
|
||||||
ctx.status = 403;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bucket = await getDriveFileBucket();
|
const bucket = await getDriveFileBucket();
|
||||||
const readable = bucket.openDownloadStream(fileId);
|
const readable = bucket.openDownloadStream(file._id);
|
||||||
readable.on('error', commonReadableHandlerGenerator(ctx));
|
readable.on('error', commonReadableHandlerGenerator(ctx));
|
||||||
ctx.set('Content-Type', file.contentType);
|
ctx.set('Content-Type', file.contentType);
|
||||||
ctx.body = readable;
|
ctx.body = readable;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ('thumbnail' in ctx.query) {
|
if (file.metadata.thumbnailUrl === url) {
|
||||||
const thumb = await DriveFileThumbnail.findOne({
|
const thumb = await DriveFileThumbnail.findOne({
|
||||||
'metadata.originalId': fileId
|
'metadata.originalId': file._id
|
||||||
});
|
});
|
||||||
|
|
||||||
if (thumb != null) {
|
if (thumb != null) {
|
||||||
|
@ -69,12 +67,12 @@ export default async function(ctx: Koa.BaseContext) {
|
||||||
await sendRaw();
|
await sendRaw();
|
||||||
} else {
|
} else {
|
||||||
ctx.status = 404;
|
ctx.status = 404;
|
||||||
await send(ctx as any, '/dummy.png', { root: assets });
|
await send(ctx as any, '/thumbnail-not-available.png', { root: assets });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ('web' in ctx.query) {
|
} else if (file.metadata.webpublicUrl === url) {
|
||||||
const web = await DriveFileWebpublic.findOne({
|
const web = await DriveFileWebpublic.findOne({
|
||||||
'metadata.originalId': fileId
|
'metadata.originalId': file._id
|
||||||
});
|
});
|
||||||
|
|
||||||
if (web != null) {
|
if (web != null) {
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { Feed } from 'feed';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import Note from '../../models/note';
|
import Note from '../../models/note';
|
||||||
import { IUser } from '../../models/user';
|
import { IUser } from '../../models/user';
|
||||||
import { getOriginalUrl } from '../../misc/get-drive-file-url';
|
|
||||||
|
|
||||||
export default async function(user: IUser) {
|
export default async function(user: IUser) {
|
||||||
const author: Author = {
|
const author: Author = {
|
||||||
|
@ -38,7 +37,7 @@ export default async function(user: IUser) {
|
||||||
} as FeedOptions);
|
} as FeedOptions);
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
const file = note._files && note._files.find(file => file.contentType.startsWith('image/'));
|
const file = note._files ? note._files.find(file => file.contentType.startsWith('image/')) : null;
|
||||||
|
|
||||||
feed.addItem({
|
feed.addItem({
|
||||||
title: `New note by ${author.name}`,
|
title: `New note by ${author.name}`,
|
||||||
|
@ -46,7 +45,7 @@ export default async function(user: IUser) {
|
||||||
date: note.createdAt,
|
date: note.createdAt,
|
||||||
description: note.cw,
|
description: note.cw,
|
||||||
content: note.text,
|
content: note.text,
|
||||||
image: file && getOriginalUrl(file)
|
image: file ? file.metadata.webpublicUrl : null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,16 +42,16 @@ async function save(path: string, name: string, type: string, hash: string, size
|
||||||
// thunbnail, webpublic を必要なら生成
|
// thunbnail, webpublic を必要なら生成
|
||||||
const alts = await generateAlts(path, type, !metadata.uri);
|
const alts = await generateAlts(path, type, !metadata.uri);
|
||||||
|
|
||||||
|
let [ext] = (name.match(/\.([a-zA-Z0-9_-]+)$/) || ['']);
|
||||||
|
|
||||||
|
if (ext === '') {
|
||||||
|
if (type === 'image/jpeg') ext = '.jpg';
|
||||||
|
if (type === 'image/png') ext = '.png';
|
||||||
|
if (type === 'image/webp') ext = '.webp';
|
||||||
|
}
|
||||||
|
|
||||||
if (config.drive && config.drive.storage == 'minio') {
|
if (config.drive && config.drive.storage == 'minio') {
|
||||||
//#region ObjectStorage params
|
//#region ObjectStorage params
|
||||||
let [ext] = (name.match(/\.([a-zA-Z0-9_-]+)$/) || ['']);
|
|
||||||
|
|
||||||
if (ext === '') {
|
|
||||||
if (type === 'image/jpeg') ext = '.jpg';
|
|
||||||
if (type === 'image/png') ext = '.png';
|
|
||||||
if (type === 'image/webp') ext = '.webp';
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseUrl = config.drive.baseUrl
|
const baseUrl = config.drive.baseUrl
|
||||||
|| `${ config.drive.config.useSSL ? 'https' : 'http' }://${ config.drive.config.endPoint }${ config.drive.config.port ? `:${config.drive.config.port}` : '' }/${ config.drive.bucket }`;
|
|| `${ config.drive.config.useSSL ? 'https' : 'http' }://${ config.drive.config.endPoint }${ config.drive.config.port ? `:${config.drive.config.port}` : '' }/${ config.drive.bucket }`;
|
||||||
|
|
||||||
|
@ -117,12 +117,15 @@ async function save(path: string, name: string, type: string, hash: string, size
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
} else { // use MongoDB GridFS
|
} else { // use MongoDB GridFS
|
||||||
|
Object.assign(metadata, {
|
||||||
|
url: `${config.driveUrl}/${uuid.v4()}${ext}`,
|
||||||
|
webpublicUrl: `${config.driveUrl}/${uuid.v4()}.${alts.webpublic.ext}`,
|
||||||
|
thumbnailUrl: `${config.driveUrl}/${uuid.v4()}.${alts.thumbnail.ext}`,
|
||||||
|
} as IMetadata);
|
||||||
|
|
||||||
// #region store original
|
// #region store original
|
||||||
const originalDst = await getDriveFileBucket();
|
const originalDst = await getDriveFileBucket();
|
||||||
|
|
||||||
// web用(Exif削除済み)がある場合はオリジナルにアクセス制限
|
|
||||||
if (alts.webpublic) metadata.accessKey = uuid.v4();
|
|
||||||
|
|
||||||
const originalFile = await storeOriginal(originalDst, name, path, type, metadata);
|
const originalFile = await storeOriginal(originalDst, name, path, type, metadata);
|
||||||
|
|
||||||
logger.info(`original stored to ${originalFile._id}`);
|
logger.info(`original stored to ${originalFile._id}`);
|
||||||
|
@ -273,7 +276,7 @@ async function deleteOldFile(user: IRemoteUser) {
|
||||||
* @param sensitive Mark file as sensitive
|
* @param sensitive Mark file as sensitive
|
||||||
* @return Created drive file
|
* @return Created drive file
|
||||||
*/
|
*/
|
||||||
export default async function(
|
export async function addDriveFile(
|
||||||
user: IUser,
|
user: IUser,
|
||||||
path: string,
|
path: string,
|
||||||
name: string = null,
|
name: string = null,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as tmp from 'tmp';
|
||||||
import * as request from 'request';
|
import * as request from 'request';
|
||||||
|
|
||||||
import { IDriveFile, validateFileName } from '../../models/drive-file';
|
import { IDriveFile, validateFileName } from '../../models/drive-file';
|
||||||
import create from './add-file';
|
import { addDriveFile } from './add-file';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import { IUser } from '../../models/user';
|
import { IUser } from '../../models/user';
|
||||||
import * as mongodb from 'mongodb';
|
import * as mongodb from 'mongodb';
|
||||||
|
@ -83,7 +83,7 @@ export default async (
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
driveFile = await create(user, path, name, null, folderId, force, link, url, uri, sensitive);
|
driveFile = await addDriveFile(user, path, name, null, folderId, force, link, url, uri, sensitive);
|
||||||
logger.succ(`Got: ${driveFile._id}`);
|
logger.succ(`Got: ${driveFile._id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
error = e;
|
||||||
|
|
Loading…
Reference in a new issue