From c3b3b9b9a6c05ce529bad388d96e0416b601ebb8 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 25 Jul 2018 00:29:18 +0900 Subject: [PATCH] #1955 --- docker/Dockerfile | 2 +- docs/setup.en.md | 1 - docs/setup.ja.md | 1 - package.json | 5 ++--- src/drive/gen-thumbnail.ts | 25 ---------------------- src/misc/dependencyInfo.ts | 1 - src/models/drive-file.ts | 3 ++- src/services/drive/add-file.ts | 39 ++++++++++++++-------------------- 8 files changed, 21 insertions(+), 56 deletions(-) delete mode 100644 src/drive/gen-thumbnail.ts diff --git a/docker/Dockerfile b/docker/Dockerfile index 7cee650de..f089c0254 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,7 +14,7 @@ RUN pacman -S --noconfirm pacman RUN pacman-db-upgrade RUN pacman -S --noconfirm archlinux-keyring RUN pacman -Syyu --noconfirm -RUN pacman -S --noconfirm git nodejs npm mongodb redis imagemagick +RUN pacman -S --noconfirm git nodejs npm mongodb redis COPY misskey.sh /root/misskey.sh RUN chmod u+x /root/misskey.sh diff --git a/docs/setup.en.md b/docs/setup.en.md index 2ae017478..1de64a54c 100644 --- a/docs/setup.en.md +++ b/docs/setup.en.md @@ -25,7 +25,6 @@ Please install and setup these softwares: * *Node.js* and *npm* * **[MongoDB](https://www.mongodb.com/)** >= 3.6 * **[Redis](https://redis.io/)** -* **[ImageMagick](http://www.imagemagick.org/script/index.php)** >= 7.0 ##### Optional * [Elasticsearch](https://www.elastic.co/) - used to provide searching feature instead of MongoDB diff --git a/docs/setup.ja.md b/docs/setup.ja.md index 75997cfbc..831894e1d 100644 --- a/docs/setup.ja.md +++ b/docs/setup.ja.md @@ -25,7 +25,6 @@ adduser --disabled-password --disabled-login misskey * *Node.js* と *npm* * **[MongoDB](https://www.mongodb.com/)** (3.6以上) * **[Redis](https://redis.io/)** -* **[ImageMagick](http://www.imagemagick.org/script/index.php)** ##### オプション * [Elasticsearch](https://www.elastic.co/) - 検索機能を向上させるために用います。 diff --git a/package.json b/package.json index bdf5c6364..0b1060824 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "@types/deep-equal": "1.0.1", "@types/elasticsearch": "5.0.25", "@types/file-type": "5.2.1", - "@types/gm": "1.18.0", "@types/gulp": "3.8.36", "@types/gulp-htmlmin": "1.3.32", "@types/gulp-mocha": "0.0.32", @@ -73,6 +72,7 @@ "@types/request-promise-native": "1.0.15", "@types/rimraf": "2.0.2", "@types/seedrandom": "2.4.27", + "@types/sharp": "0.17.9", "@types/showdown": "1.7.5", "@types/single-line-log": "1.1.0", "@types/speakeasy": "2.0.2", @@ -108,7 +108,6 @@ "file-loader": "1.1.11", "file-type": "8.1.0", "fuckadblock": "3.2.1", - "gm": "1.23.1", "gulp": "3.9.1", "gulp-cssnano": "2.1.3", "gulp-htmlmin": "4.0.0", @@ -165,7 +164,6 @@ "parse5": "5.0.0", "portscanner": "2.2.0", "progress-bar-webpack-plugin": "1.11.0", - "prominence": "0.2.0", "promise-sequential": "1.1.1", "pug": "2.0.3", "punycode": "2.1.1", @@ -181,6 +179,7 @@ "s-age": "1.1.2", "sass-loader": "7.0.3", "seedrandom": "2.4.3", + "sharp": "0.20.5", "showdown": "1.8.6", "showdown-highlightjs-extension": "0.1.2", "single-line-log": "1.1.2", diff --git a/src/drive/gen-thumbnail.ts b/src/drive/gen-thumbnail.ts deleted file mode 100644 index 455705cd3..000000000 --- a/src/drive/gen-thumbnail.ts +++ /dev/null @@ -1,25 +0,0 @@ -import * as stream from 'stream'; -import * as Gm from 'gm'; -import { IDriveFile, getDriveFileBucket } from '../models/drive-file'; - -const gm = Gm.subClass({ - imageMagick: true -}); - -export default async function(file: IDriveFile): Promise { - if (!/^image\/.*$/.test(file.contentType)) return null; - - const bucket = await getDriveFileBucket(); - const readable = bucket.openDownloadStream(file._id); - - const g = gm(readable); - - const stream = g - .resize(256, 256) - .compress('jpeg') - .quality(70) - .interlace('line') - .stream(); - - return stream; -} diff --git a/src/misc/dependencyInfo.ts b/src/misc/dependencyInfo.ts index 527056751..09d282822 100644 --- a/src/misc/dependencyInfo.ts +++ b/src/misc/dependencyInfo.ts @@ -11,7 +11,6 @@ export default class { public showAll(): void { this.show('MongoDB', 'mongo --version', x => x.match(/^MongoDB shell version:? v(.*)\r?\n/)); this.show('Redis', 'redis-server --version', x => x.match(/v=([0-9\.]*)/)); - this.show('ImageMagick', 'magick -version', x => x.match(/^Version: ImageMagick ([^ ]*)/)); } public show(serviceName: string, command: string, transform: (x: string) => RegExpMatchArray): void { diff --git a/src/models/drive-file.ts b/src/models/drive-file.ts index f197f86d4..e3da5a1c6 100644 --- a/src/models/drive-file.ts +++ b/src/models/drive-file.ts @@ -37,6 +37,7 @@ export type IMetadata = { storage?: string; storageProps?: any; isSensitive?: boolean; + isRemote?: boolean; }; export type IDriveFile = { @@ -160,7 +161,7 @@ export const pack = ( _target.url = _file.metadata.url ? _file.metadata.url : `${config.drive_url}/${_target.id}/${encodeURIComponent(_target.name)}`; _target.src = _file.metadata.url; - _target.isRemote = _file.metadata.withoutChunks; + _target.isRemote = _file.metadata.isRemote; if (_target.properties == null) _target.properties = {}; diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts index ab9353c9f..4d14325db 100644 --- a/src/services/drive/add-file.ts +++ b/src/services/drive/add-file.ts @@ -4,12 +4,11 @@ import * as stream from 'stream'; import * as mongodb from 'mongodb'; import * as crypto from 'crypto'; -import * as _gm from 'gm'; import * as debug from 'debug'; import fileType = require('file-type'); -const prominence = require('prominence'); import * as Minio from 'minio'; import * as uuid from 'uuid'; +import * as sharp from 'sharp'; import DriveFile, { IMetadata, getDriveFileBucket, IDriveFile } from '../../models/drive-file'; import DriveFolder from '../../models/drive-folder'; @@ -19,10 +18,6 @@ import { isLocalUser, IUser, IRemoteUser } from '../../models/user'; import delFile from './delete-file'; import config from '../../config'; -const gm = _gm.subClass({ - imageMagick: true -}); - const log = debug('misskey:drive:add-file'); async function save(readable: stream.Readable, name: string, type: string, hash: string, size: number, metadata: any): Promise { @@ -53,6 +48,8 @@ async function save(readable: stream.Readable, name: string, type: string, hash: }); return file; + } else { + throw 'unknown storage type'; } } else { // Get MongoDB GridFS bucket @@ -228,42 +225,37 @@ export default async function( let propPromises: Array> = []; - const isImage = ['image/jpeg', 'image/gif', 'image/png'].includes(mime); + const isImage = ['image/jpeg', 'image/gif', 'image/png', 'image/webp'].includes(mime); if (isImage) { + const img = sharp(path); + // Calc width and height const calcWh = async () => { log('calculate image width and height...'); // Calculate width and height - const g = gm(fs.createReadStream(path), name); - const size = await prominence(g).size(); + const meta = await img.metadata(); - log(`image width and height is calculated: ${size.width}, ${size.height}`); + log(`image width and height is calculated: ${meta.width}, ${meta.height}`); - properties['width'] = size.width; - properties['height'] = size.height; + properties['width'] = meta.width; + properties['height'] = meta.height; }; // Calc average color const calcAvg = async () => { log('calculate average color...'); - const info = await prominence(gm(fs.createReadStream(path), name)).identify(); - const isTransparent = info ? info['Channel depth'].Alpha != null : false; + const info = await (img as any).stats(); - const buffer = await prominence(gm(fs.createReadStream(path), name) - .setFormat('ppm') - .resize(1, 1)) // 1pxのサイズに縮小して平均色を取得するというハック - .toBuffer(); - - const r = buffer.readUInt8(buffer.length - 3); - const g = buffer.readUInt8(buffer.length - 2); - const b = buffer.readUInt8(buffer.length - 1); + const r = Math.round(info.channels[0].mean); + const g = Math.round(info.channels[1].mean); + const b = Math.round(info.channels[2].mean); log(`average color is calculated: ${r}, ${g}, ${b}`); - const value = isTransparent ? [r, g, b, 255] : [r, g, b]; + const value = info.isOpaque ? [r, g, b] : [r, g, b, 255]; properties['avgColor'] = value; }; @@ -282,6 +274,7 @@ export default async function( comment: comment, properties: properties, withoutChunks: isLink, + isRemote: isLink, isSensitive: sensitive } as IMetadata;