summaryrefslogtreecommitdiff
path: root/src/misc
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2019-04-14 20:38:55 +0900
committersyuilo <syuilotan@yahoo.co.jp>2019-04-14 20:38:55 +0900
commitd66e4b7ff97d512e2a2523815e2eef170456b37f (patch)
tree59ae1a102d88b5c2c2236b734ea4a584b4f9ba46 /src/misc
parent10.100.0 (diff)
parent11.0.0 (diff)
downloadmisskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.tar.gz
misskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.tar.bz2
misskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.zip
Merge branch 'develop'
Diffstat (limited to 'src/misc')
-rw-r--r--src/misc/acct/render.ts2
-rw-r--r--src/misc/acct/type.ts2
-rw-r--r--src/misc/cafy-id.ts29
-rw-r--r--src/misc/check-mongodb.ts37
-rw-r--r--src/misc/convert-host.ts17
-rw-r--r--src/misc/detect-mine.ts2
-rw-r--r--src/misc/donwload-url.ts3
-rw-r--r--src/misc/fetch-meta.ts42
-rw-r--r--src/misc/fetch-proxy-account.ts9
-rw-r--r--src/misc/gen-id.ts19
-rw-r--r--src/misc/get-drive-file-url.ts31
-rw-r--r--src/misc/get-notification-summary.ts2
-rw-r--r--src/misc/get-user-name.ts4
-rw-r--r--src/misc/get-user-summary.ts18
-rw-r--r--src/misc/id/aid.ts23
-rw-r--r--src/misc/id/meid.ts26
-rw-r--r--src/misc/id/object-id.ts26
-rw-r--r--src/misc/identifiable-error.ts2
-rw-r--r--src/misc/is-duplicate-key-value-error.ts3
-rw-r--r--src/misc/is-objectid.ts5
-rw-r--r--src/misc/is-quote.ts6
-rw-r--r--src/misc/nyaize.ts9
-rw-r--r--src/misc/reaction-lib.ts6
-rw-r--r--src/misc/schema.ts4
-rw-r--r--src/misc/should-mute-this-note.ts13
25 files changed, 156 insertions, 184 deletions
diff --git a/src/misc/acct/render.ts b/src/misc/acct/render.ts
index 67e063fcb3..094eceffe9 100644
--- a/src/misc/acct/render.ts
+++ b/src/misc/acct/render.ts
@@ -1,5 +1,5 @@
import Acct from './type';
export default (user: Acct) => {
- return user.host === null ? user.username : `${user.username}@${user.host}`;
+ return user.host == null ? user.username : `${user.username}@${user.host}`;
};
diff --git a/src/misc/acct/type.ts b/src/misc/acct/type.ts
index c88a920c69..7f31257400 100644
--- a/src/misc/acct/type.ts
+++ b/src/misc/acct/type.ts
@@ -1,6 +1,6 @@
type Acct = {
username: string;
- host: string;
+ host: string | null;
};
export default Acct;
diff --git a/src/misc/cafy-id.ts b/src/misc/cafy-id.ts
index bc8fe4ea2b..39886611e1 100644
--- a/src/misc/cafy-id.ts
+++ b/src/misc/cafy-id.ts
@@ -1,38 +1,13 @@
-import * as mongo from 'mongodb';
import { Context } from 'cafy';
-import isObjectId from './is-objectid';
-export const isAnId = (x: any) => mongo.ObjectID.isValid(x);
-export const isNotAnId = (x: any) => !isAnId(x);
-export const transform = (x: string | mongo.ObjectID): mongo.ObjectID => {
- if (x === undefined) return undefined;
- if (x === null) return null;
-
- if (isAnId(x) && !isObjectId(x)) {
- return new mongo.ObjectID(x);
- } else {
- return x as mongo.ObjectID;
- }
-};
-export const transformMany = (xs: (string | mongo.ObjectID)[]): mongo.ObjectID[] => {
- if (xs == null) return null;
-
- return xs.map(x => transform(x));
-};
-
-export type ObjectId = mongo.ObjectID;
-
-/**
- * ID
- */
-export default class ID<Maybe = string> extends Context<string | Maybe> {
+export class ID<Maybe = string> extends Context<string | (Maybe extends {} ? string : Maybe)> {
public readonly name = 'ID';
constructor(optional = false, nullable = false) {
super(optional, nullable);
this.push((v: any) => {
- if (!isObjectId(v) && isNotAnId(v)) {
+ if (typeof v !== 'string') {
return new Error('must-be-an-id');
}
return true;
diff --git a/src/misc/check-mongodb.ts b/src/misc/check-mongodb.ts
deleted file mode 100644
index 8e03db5d42..0000000000
--- a/src/misc/check-mongodb.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { nativeDbConn } from '../db/mongodb';
-import { Config } from '../config/types';
-import Logger from '../services/logger';
-import { lessThan } from '../prelude/array';
-
-const requiredMongoDBVersion = [3, 6];
-
-export function checkMongoDB(config: Config, logger: Logger) {
- return new Promise((res, rej) => {
- const mongoDBLogger = logger.createSubLogger('db');
- const u = config.mongodb.user ? encodeURIComponent(config.mongodb.user) : null;
- const p = config.mongodb.pass ? encodeURIComponent(config.mongodb.pass) : null;
- const uri = `mongodb://${u && p ? `${u}:****@` : ''}${config.mongodb.host}:${config.mongodb.port}/${config.mongodb.db}`;
- mongoDBLogger.info(`Connecting to ${uri} ...`);
-
- nativeDbConn().then(db => {
- mongoDBLogger.succ('Connectivity confirmed');
-
- db.admin().serverInfo().then(x => {
- const version = x.version as string;
- mongoDBLogger.info(`Version: ${version}`);
- if (lessThan(version.split('.').map(x => parseInt(x, 10)), requiredMongoDBVersion)) {
- mongoDBLogger.error(`MongoDB version is less than ${requiredMongoDBVersion.join('.')}. Please upgrade it.`);
- rej('outdated version');
- } else {
- res();
- }
- }).catch(err => {
- mongoDBLogger.error(`Failed to fetch server info: ${err.message}`);
- rej(err);
- });
- }).catch(err => {
- mongoDBLogger.error(err.message);
- rej(err);
- });
- });
-}
diff --git a/src/misc/convert-host.ts b/src/misc/convert-host.ts
index 8f2f1c7aba..a5fb15c66f 100644
--- a/src/misc/convert-host.ts
+++ b/src/misc/convert-host.ts
@@ -1,27 +1,26 @@
import config from '../config';
-import { toUnicode, toASCII } from 'punycode';
+import { toASCII } from 'punycode';
import { URL } from 'url';
-export function getFullApAccount(username: string, host: string) {
- return host ? `${username}@${toApHost(host)}` : `${username}@${toApHost(config.host)}`;
+export function getFullApAccount(username: string, host: string | null) {
+ return host ? `${username}@${toPuny(host)}` : `${username}@${toPuny(config.host)}`;
}
export function isSelfHost(host: string) {
if (host == null) return true;
- return toApHost(config.host) === toApHost(host);
+ return toPuny(config.host) === toPuny(host);
}
export function extractDbHost(uri: string) {
const url = new URL(uri);
- return toDbHost(url.hostname);
+ return toPuny(url.hostname);
}
-export function toDbHost(host: string) {
- if (host == null) return null;
- return toUnicode(host.toLowerCase());
+export function toPuny(host: string) {
+ return toASCII(host.toLowerCase());
}
-export function toApHost(host: string) {
+export function toPunyNullable(host: string | null | undefined): string | null {
if (host == null) return null;
return toASCII(host.toLowerCase());
}
diff --git a/src/misc/detect-mine.ts b/src/misc/detect-mine.ts
index bbf49efc10..70d58ffe21 100644
--- a/src/misc/detect-mine.ts
+++ b/src/misc/detect-mine.ts
@@ -3,7 +3,7 @@ import fileType from 'file-type';
import checkSvg from '../misc/check-svg';
export async function detectMine(path: string) {
- return new Promise<[string, string]>((res, rej) => {
+ return new Promise<[string, string | null]>((res, rej) => {
const readable = fs.createReadStream(path);
readable
.on('error', rej)
diff --git a/src/misc/donwload-url.ts b/src/misc/donwload-url.ts
index 0dd4e4ef5d..167e01fdd1 100644
--- a/src/misc/donwload-url.ts
+++ b/src/misc/donwload-url.ts
@@ -1,5 +1,4 @@
import * as fs from 'fs';
-import * as URL from 'url';
import * as request from 'request';
import config from '../config';
import chalk from 'chalk';
@@ -26,7 +25,7 @@ export async function downloadUrl(url: string, path: string) {
rej(error);
});
- const requestUrl = URL.parse(url).pathname.match(/[^\u0021-\u00ff]/) ? encodeURI(url) : url;
+ const requestUrl = new URL(url).pathname.match(/[^\u0021-\u00ff]/) ? encodeURI(url) : url;
const req = request({
url: requestUrl,
diff --git a/src/misc/fetch-meta.ts b/src/misc/fetch-meta.ts
index 3584a819bf..cf1fc474ce 100644
--- a/src/misc/fetch-meta.ts
+++ b/src/misc/fetch-meta.ts
@@ -1,32 +1,14 @@
-import Meta, { IMeta } from '../models/meta';
+import { Meta } from '../models/entities/meta';
+import { Metas } from '../models';
+import { genId } from './gen-id';
-const defaultMeta: any = {
- name: 'Misskey',
- maintainer: {},
- langs: [],
- cacheRemoteFiles: true,
- localDriveCapacityMb: 256,
- remoteDriveCapacityMb: 8,
- hidedTags: [],
- stats: {
- originalNotesCount: 0,
- originalUsersCount: 0
- },
- maxNoteTextLength: 1000,
- enableEmojiReaction: true,
- enableTwitterIntegration: false,
- enableGithubIntegration: false,
- enableDiscordIntegration: false,
- enableExternalUserRecommendation: false,
- externalUserRecommendationEngine: 'https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}',
- externalUserRecommendationTimeout: 300000,
- mascotImageUrl: '/assets/ai.png',
- errorImageUrl: 'https://ai.misskey.xyz/aiart/yubitun.png',
- enableServiceWorker: false
-};
-
-export default async function(): Promise<IMeta> {
- const meta = await Meta.findOne({});
-
- return Object.assign({}, defaultMeta, meta);
+export default async function(): Promise<Meta> {
+ const meta = await Metas.findOne();
+ if (meta) {
+ return meta;
+ } else {
+ return Metas.save({
+ id: genId(),
+ } as Meta);
+ }
}
diff --git a/src/misc/fetch-proxy-account.ts b/src/misc/fetch-proxy-account.ts
new file mode 100644
index 0000000000..17b021e91e
--- /dev/null
+++ b/src/misc/fetch-proxy-account.ts
@@ -0,0 +1,9 @@
+import fetchMeta from './fetch-meta';
+import { ILocalUser } from '../models/entities/user';
+import { Users } from '../models';
+import { ensure } from '../prelude/ensure';
+
+export async function fetchProxyAccount(): Promise<ILocalUser> {
+ const meta = await fetchMeta();
+ return await Users.findOne({ username: meta.proxyAccount!, host: null }).then(ensure) as ILocalUser;
+}
diff --git a/src/misc/gen-id.ts b/src/misc/gen-id.ts
new file mode 100644
index 0000000000..99cb70b3fb
--- /dev/null
+++ b/src/misc/gen-id.ts
@@ -0,0 +1,19 @@
+import { ulid } from 'ulid';
+import { genAid } from './id/aid';
+import { genMeid } from './id/meid';
+import { genObjectId } from './id/object-id';
+import config from '../config';
+
+const metohd = config.id.toLowerCase();
+
+export function genId(date?: Date): string {
+ if (!date || (date > new Date())) date = new Date();
+
+ switch (metohd) {
+ case 'aid': return genAid(date);
+ case 'meid': return genMeid(date);
+ case 'ulid': return ulid(date.getTime());
+ case 'objectid': return genObjectId(date);
+ default: throw new Error('unknown id generation method');
+ }
+}
diff --git a/src/misc/get-drive-file-url.ts b/src/misc/get-drive-file-url.ts
deleted file mode 100644
index f2b0f8b001..0000000000
--- a/src/misc/get-drive-file-url.ts
+++ /dev/null
@@ -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 : '/assets/thumbnail-not-available.png');
- } 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 : ''}`;
-}
diff --git a/src/misc/get-notification-summary.ts b/src/misc/get-notification-summary.ts
index 71d4973ce9..b20711c605 100644
--- a/src/misc/get-notification-summary.ts
+++ b/src/misc/get-notification-summary.ts
@@ -20,7 +20,7 @@ export default function(notification: any): string {
return `引用されました:\n${getUserName(notification.user)}「${getNoteSummary(notification.note)}」`;
case 'reaction':
return `リアクションされました:\n${getUserName(notification.user)} <${getReactionEmoji(notification.reaction)}>「${getNoteSummary(notification.note)}」`;
- case 'poll_vote':
+ case 'pollVote':
return `投票されました:\n${getUserName(notification.user)}「${getNoteSummary(notification.note)}」`;
default:
return `<不明な通知タイプ: ${notification.type}>`;
diff --git a/src/misc/get-user-name.ts b/src/misc/get-user-name.ts
index eab9f87ef0..b6b45118b0 100644
--- a/src/misc/get-user-name.ts
+++ b/src/misc/get-user-name.ts
@@ -1,5 +1,5 @@
-import { IUser } from '../models/user';
+import { User } from '../models/entities/user';
-export default function(user: IUser): string {
+export default function(user: User): string {
return user.name || user.username;
}
diff --git a/src/misc/get-user-summary.ts b/src/misc/get-user-summary.ts
deleted file mode 100644
index 09cf5ebadc..0000000000
--- a/src/misc/get-user-summary.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { IUser, isLocalUser } from '../models/user';
-import getAcct from './acct/render';
-import getUserName from './get-user-name';
-
-/**
- * ユーザーを表す文字列を取得します。
- * @param user ユーザー
- */
-export default function(user: IUser): string {
- let string = `${getUserName(user)} (@${getAcct(user)})\n` +
- `${user.notesCount}投稿、${user.followingCount}フォロー、${user.followersCount}フォロワー\n`;
-
- if (isLocalUser(user)) {
- string += `場所: ${user.profile.location}、誕生日: ${user.profile.birthday}\n`;
- }
-
- return string + `「${user.description}」`;
-}
diff --git a/src/misc/id/aid.ts b/src/misc/id/aid.ts
new file mode 100644
index 0000000000..530d84e582
--- /dev/null
+++ b/src/misc/id/aid.ts
@@ -0,0 +1,23 @@
+// AID
+// 長さ8の[2000年1月1日からの経過ミリ秒をbase36でエンコードしたもの] + 長さ2の[ノイズ文字列]
+
+import * as cluster from 'cluster';
+
+const TIME2000 = 946684800000;
+let counter = process.pid + (cluster.isMaster ? 0 : cluster.worker.id);
+
+function getTime(time: number) {
+ time = time - TIME2000;
+ if (time < 0) time = 0;
+
+ return time.toString(36).padStart(8, '0');
+}
+
+function getNoise() {
+ return counter.toString(36).padStart(2, '0').slice(-2);
+}
+
+export function genAid(date: Date): string {
+ counter++;
+ return getTime(date.getTime()) + getNoise();
+}
diff --git a/src/misc/id/meid.ts b/src/misc/id/meid.ts
new file mode 100644
index 0000000000..d4dc73b4f1
--- /dev/null
+++ b/src/misc/id/meid.ts
@@ -0,0 +1,26 @@
+const CHARS = '0123456789abcdef';
+
+function getTime(time: number) {
+ if (time < 0) time = 0;
+ if (time === 0) {
+ return CHARS[0];
+ }
+
+ time += 0x800000000000;
+
+ return time.toString(16).padStart(12, CHARS[0]);
+}
+
+function getRandom() {
+ let str = '';
+
+ for (let i = 0; i < 12; i++) {
+ str += CHARS[Math.floor(Math.random() * CHARS.length)];
+ }
+
+ return str;
+}
+
+export function genMeid(date: Date): string {
+ return 'f' + getTime(date.getTime()) + getRandom();
+}
diff --git a/src/misc/id/object-id.ts b/src/misc/id/object-id.ts
new file mode 100644
index 0000000000..392ea43301
--- /dev/null
+++ b/src/misc/id/object-id.ts
@@ -0,0 +1,26 @@
+const CHARS = '0123456789abcdef';
+
+function getTime(time: number) {
+ if (time < 0) time = 0;
+ if (time === 0) {
+ return CHARS[0];
+ }
+
+ time = Math.floor(time / 1000);
+
+ return time.toString(16).padStart(8, CHARS[0]);
+}
+
+function getRandom() {
+ let str = '';
+
+ for (let i = 0; i < 16; i++) {
+ str += CHARS[Math.floor(Math.random() * CHARS.length)];
+ }
+
+ return str;
+}
+
+export function genObjectId(date: Date): string {
+ return getTime(date.getTime()) + getRandom();
+}
diff --git a/src/misc/identifiable-error.ts b/src/misc/identifiable-error.ts
index 1edd26cd18..2d7c6bd0c6 100644
--- a/src/misc/identifiable-error.ts
+++ b/src/misc/identifiable-error.ts
@@ -7,7 +7,7 @@ export class IdentifiableError extends Error {
constructor(id: string, message?: string) {
super(message);
- this.message = message;
+ this.message = message || '';
this.id = id;
}
}
diff --git a/src/misc/is-duplicate-key-value-error.ts b/src/misc/is-duplicate-key-value-error.ts
new file mode 100644
index 0000000000..23d8ceb1b7
--- /dev/null
+++ b/src/misc/is-duplicate-key-value-error.ts
@@ -0,0 +1,3 @@
+export function isDuplicateKeyValueError(e: Error): boolean {
+ return e.message.startsWith('duplicate key value');
+}
diff --git a/src/misc/is-objectid.ts b/src/misc/is-objectid.ts
deleted file mode 100644
index a77c4ee2d5..0000000000
--- a/src/misc/is-objectid.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { ObjectID } from 'mongodb';
-
-export default function(x: any): x is ObjectID {
- return x && typeof x === 'object' && (x.hasOwnProperty('toHexString') || x.hasOwnProperty('_bsontype'));
-}
diff --git a/src/misc/is-quote.ts b/src/misc/is-quote.ts
index a99b8f6434..0a2a72f4a0 100644
--- a/src/misc/is-quote.ts
+++ b/src/misc/is-quote.ts
@@ -1,5 +1,5 @@
-import { INote } from '../models/note';
+import { Note } from '../models/entities/note';
-export default function(note: INote): boolean {
- return note.renoteId != null && (note.text != null || note.poll != null || (note.fileIds != null && note.fileIds.length > 0));
+export default function(note: Note): boolean {
+ return note.renoteId != null && (note.text != null || note.hasPoll || (note.fileIds != null && note.fileIds.length > 0));
}
diff --git a/src/misc/nyaize.ts b/src/misc/nyaize.ts
new file mode 100644
index 0000000000..918e7d63fd
--- /dev/null
+++ b/src/misc/nyaize.ts
@@ -0,0 +1,9 @@
+export function nyaize(text: string): string {
+ return text
+ // ja-JP
+ .replace(/な/g, 'にゃ').replace(/ナ/g, 'ニャ').replace(/ナ/g, 'ニャ')
+ // ko-KR
+ .replace(/[나-낳]/g, match => String.fromCharCode(
+ match.codePointAt(0)! + '냐'.charCodeAt(0) - '나'.charCodeAt(0)
+ ));
+}
diff --git a/src/misc/reaction-lib.ts b/src/misc/reaction-lib.ts
index 7e5a1b0bc0..008991454b 100644
--- a/src/misc/reaction-lib.ts
+++ b/src/misc/reaction-lib.ts
@@ -1,6 +1,6 @@
-import Emoji from '../models/emoji';
import { emojiRegex } from './emoji-regex';
import fetchMeta from './fetch-meta';
+import { Emojis } from '../models';
const basic10: Record<string, string> = {
'👍': 'like',
@@ -20,7 +20,7 @@ export async function getFallbackReaction(): Promise<string> {
return meta.useStarForReactionFallback ? 'star' : 'like';
}
-export async function toDbReaction(reaction: string, enableEmoji = true): Promise<string> {
+export async function toDbReaction(reaction?: string | null, enableEmoji = true): Promise<string> {
if (reaction == null) return await getFallbackReaction();
// 既存の文字列リアクションはそのまま
@@ -49,7 +49,7 @@ export async function toDbReaction(reaction: string, enableEmoji = true): Promis
const custom = reaction.match(/^:([\w+-]+):$/);
if (custom) {
- const emoji = await Emoji.findOne({
+ const emoji = await Emojis.findOne({
host: null,
name: custom[1],
});
diff --git a/src/misc/schema.ts b/src/misc/schema.ts
index e5c24dd468..7c17953d97 100644
--- a/src/misc/schema.ts
+++ b/src/misc/schema.ts
@@ -19,8 +19,8 @@ type MyType<T extends Schema> = {
export type SchemaType<p extends Schema> =
p['type'] extends 'number' ? number :
p['type'] extends 'string' ? string :
- p['type'] extends 'array' ? MyType<p['items']>[] :
- p['type'] extends 'object' ? ObjType<p['properties']> :
+ p['type'] extends 'array' ? MyType<NonNullable<p['items']>>[] :
+ p['type'] extends 'object' ? ObjType<NonNullable<p['properties']>> :
any;
export function convertOpenApiSchema(schema: Schema) {
diff --git a/src/misc/should-mute-this-note.ts b/src/misc/should-mute-this-note.ts
index b1d29c6a28..8f606a2943 100644
--- a/src/misc/should-mute-this-note.ts
+++ b/src/misc/should-mute-this-note.ts
@@ -1,20 +1,13 @@
-import * as mongo from 'mongodb';
-import isObjectId from './is-objectid';
-
-function toString(id: any) {
- return isObjectId(id) ? (id as mongo.ObjectID).toHexString() : id;
-}
-
export default function(note: any, mutedUserIds: string[]): boolean {
- if (mutedUserIds.includes(toString(note.userId))) {
+ if (mutedUserIds.includes(note.userId)) {
return true;
}
- if (note.reply != null && mutedUserIds.includes(toString(note.reply.userId))) {
+ if (note.reply != null && mutedUserIds.includes(note.reply.userId)) {
return true;
}
- if (note.renote != null && mutedUserIds.includes(toString(note.renote.userId))) {
+ if (note.renote != null && mutedUserIds.includes(note.renote.userId)) {
return true;
}