diff options
Diffstat (limited to 'src/api/common')
23 files changed, 0 insertions, 1204 deletions
diff --git a/src/api/common/drive/add-file.ts b/src/api/common/drive/add-file.ts deleted file mode 100644 index c4f2f212ac..0000000000 --- a/src/api/common/drive/add-file.ts +++ /dev/null @@ -1,307 +0,0 @@ -import { Buffer } from 'buffer'; -import * as fs from 'fs'; -import * as tmp from 'tmp'; -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'); -import prominence = require('prominence'); - -import DriveFile, { getGridFSBucket } from '../../models/drive-file'; -import DriveFolder from '../../models/drive-folder'; -import { pack } from '../../models/drive-file'; -import event, { publishDriveStream } from '../../event'; -import getAcct from '../../../common/user/get-acct'; -import config from '../../../conf'; - -const gm = _gm.subClass({ - imageMagick: true -}); - -const log = debug('misskey:drive:add-file'); - -const tmpFile = (): Promise<string> => new Promise((resolve, reject) => { - tmp.file((e, path) => { - if (e) return reject(e); - resolve(path); - }); -}); - -const addToGridFS = (name: string, readable: stream.Readable, type: string, metadata: any): Promise<any> => - getGridFSBucket() - .then(bucket => new Promise((resolve, reject) => { - const writeStream = bucket.openUploadStream(name, { contentType: type, metadata }); - writeStream.once('finish', (doc) => { resolve(doc); }); - writeStream.on('error', reject); - readable.pipe(writeStream); - })); - -const addFile = async ( - user: any, - path: string, - name: string = null, - comment: string = null, - folderId: mongodb.ObjectID = null, - force: boolean = false -) => { - log(`registering ${name} (user: ${getAcct(user)}, path: ${path})`); - - // Calculate hash, get content type and get file size - const [hash, [mime, ext], size] = await Promise.all([ - // hash - ((): Promise<string> => new Promise((res, rej) => { - const readable = fs.createReadStream(path); - const hash = crypto.createHash('md5'); - const chunks = []; - readable - .on('error', rej) - .pipe(hash) - .on('error', rej) - .on('data', (chunk) => chunks.push(chunk)) - .on('end', () => { - const buffer = Buffer.concat(chunks); - res(buffer.toString('hex')); - }); - }))(), - // mime - ((): Promise<[string, string | null]> => new Promise((res, rej) => { - const readable = fs.createReadStream(path); - readable - .on('error', rej) - .once('data', (buffer: Buffer) => { - readable.destroy(); - const type = fileType(buffer); - if (type) { - return res([type.mime, type.ext]); - } else { - // 種類が同定できなかったら application/octet-stream にする - return res(['application/octet-stream', null]); - } - }); - }))(), - // size - ((): Promise<number> => new Promise((res, rej) => { - fs.stat(path, (err, stats) => { - if (err) return rej(err); - res(stats.size); - }); - }))() - ]); - - log(`hash: ${hash}, mime: ${mime}, ext: ${ext}, size: ${size}`); - - // detect name - const detectedName: string = name || (ext ? `untitled.${ext}` : 'untitled'); - - if (!force) { - // Check if there is a file with the same hash - const much = await DriveFile.findOne({ - md5: hash, - 'metadata.user_id': user._id - }); - - if (much !== null) { - log('file with same hash is found'); - return much; - } else { - log('file with same hash is not found'); - } - } - - const [wh, averageColor, folder] = await Promise.all([ - // Width and height (when image) - (async () => { - // 画像かどうか - if (!/^image\/.*$/.test(mime)) { - return null; - } - - const imageType = mime.split('/')[1]; - - // 画像でもPNGかJPEGかGIFでないならスキップ - if (imageType != 'png' && imageType != 'jpeg' && imageType != 'gif') { - return null; - } - - log('calculate image width and height...'); - - // Calculate width and height - const g = gm(fs.createReadStream(path), name); - const size = await prominence(g).size(); - - log(`image width and height is calculated: ${size.width}, ${size.height}`); - - return [size.width, size.height]; - })(), - // average color (when image) - (async () => { - // 画像かどうか - if (!/^image\/.*$/.test(mime)) { - return null; - } - - const imageType = mime.split('/')[1]; - - // 画像でもPNGかJPEGでないならスキップ - if (imageType != 'png' && imageType != 'jpeg') { - return null; - } - - log('calculate average color...'); - - 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); - - log(`average color is calculated: ${r}, ${g}, ${b}`); - - return [r, g, b]; - })(), - // folder - (async () => { - if (!folderId) { - return null; - } - const driveFolder = await DriveFolder.findOne({ - _id: folderId, - user_id: user._id - }); - if (!driveFolder) { - throw 'folder-not-found'; - } - return driveFolder; - })(), - // usage checker - (async () => { - // Calculate drive usage - const usage = await DriveFile - .aggregate([{ - $match: { 'metadata.user_id': user._id } - }, { - $project: { - length: true - } - }, { - $group: { - _id: null, - usage: { $sum: '$length' } - } - }]) - .then((aggregates: any[]) => { - if (aggregates.length > 0) { - return aggregates[0].usage; - } - return 0; - }); - - log(`drive usage is ${usage}`); - - // If usage limit exceeded - if (usage + size > user.drive_capacity) { - throw 'no-free-space'; - } - })() - ]); - - const readable = fs.createReadStream(path); - - const properties = {}; - - if (wh) { - properties['width'] = wh[0]; - properties['height'] = wh[1]; - } - - if (averageColor) { - properties['average_color'] = averageColor; - } - - return addToGridFS(detectedName, readable, mime, { - user_id: user._id, - folder_id: folder !== null ? folder._id : null, - comment: comment, - properties: properties - }); -}; - -/** - * Add file to drive - * - * @param user User who wish to add file - * @param file File path or readableStream - * @param comment Comment - * @param type File type - * @param folderId Folder ID - * @param force If set to true, forcibly upload the file even if there is a file with the same hash. - * @return Object that represents added file - */ -export default (user: any, file: string | stream.Readable, ...args) => new Promise<any>((resolve, reject) => { - // Get file path - new Promise((res: (v: [string, boolean]) => void, rej) => { - if (typeof file === 'string') { - res([file, false]); - return; - } - if (typeof file === 'object' && typeof file.read === 'function') { - tmpFile() - .then(path => { - const readable: stream.Readable = file; - const writable = fs.createWriteStream(path); - readable - .on('error', rej) - .on('end', () => { - res([path, true]); - }) - .pipe(writable) - .on('error', rej); - }) - .catch(rej); - } - rej(new Error('un-compatible file.')); - }) - .then(([path, shouldCleanup]): Promise<any> => new Promise((res, rej) => { - addFile(user, path, ...args) - .then(file => { - res(file); - if (shouldCleanup) { - fs.unlink(path, (e) => { - if (e) log(e.stack); - }); - } - }) - .catch(rej); - })) - .then(file => { - log(`drive file has been created ${file._id}`); - resolve(file); - - pack(file).then(serializedFile => { - // Publish drive_file_created event - event(user._id, 'drive_file_created', serializedFile); - publishDriveStream(user._id, 'file_created', serializedFile); - - // Register to search database - if (config.elasticsearch.enable) { - const es = require('../../db/elasticsearch'); - es.index({ - index: 'misskey', - type: 'drive_file', - id: file._id.toString(), - body: { - name: file.name, - user_id: user._id.toString() - } - }); - } - }); - }) - .catch(reject); -}); diff --git a/src/api/common/drive/upload_from_url.ts b/src/api/common/drive/upload_from_url.ts deleted file mode 100644 index 5dd9695936..0000000000 --- a/src/api/common/drive/upload_from_url.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as URL from 'url'; -import { IDriveFile, validateFileName } from '../../models/drive-file'; -import create from './add-file'; -import * as debug from 'debug'; -import * as tmp from 'tmp'; -import * as fs from 'fs'; -import * as request from 'request'; - -const log = debug('misskey:common:drive:upload_from_url'); - -export default async (url, user, folderId = null): Promise<IDriveFile> => { - let name = URL.parse(url).pathname.split('/').pop(); - if (!validateFileName(name)) { - name = null; - } - - // Create temp file - const path = await new Promise((res: (string) => void, rej) => { - tmp.file((e, path) => { - if (e) return rej(e); - res(path); - }); - }); - - // write content at URL to temp file - await new Promise((res, rej) => { - const writable = fs.createWriteStream(path); - request(url) - .on('error', rej) - .on('end', () => { - writable.close(); - res(path); - }) - .pipe(writable) - .on('error', rej); - }); - - const driveFile = await create(user, path, name, null, folderId); - - // clean-up - fs.unlink(path, (e) => { - if (e) log(e.stack); - }); - - return driveFile; -}; diff --git a/src/api/common/generate-native-user-token.ts b/src/api/common/generate-native-user-token.ts deleted file mode 100644 index 2082b89a5a..0000000000 --- a/src/api/common/generate-native-user-token.ts +++ /dev/null @@ -1,3 +0,0 @@ -import rndstr from 'rndstr'; - -export default () => `!${rndstr('a-zA-Z0-9', 32)}`; diff --git a/src/api/common/get-friends.ts b/src/api/common/get-friends.ts deleted file mode 100644 index db6313816d..0000000000 --- a/src/api/common/get-friends.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as mongodb from 'mongodb'; -import Following from '../models/following'; - -export default async (me: mongodb.ObjectID, includeMe: boolean = true) => { - // Fetch relation to other users who the I follows - // SELECT followee - const myfollowing = await Following - .find({ - follower_id: me, - // 削除されたドキュメントは除く - deleted_at: { $exists: false } - }, { - fields: { - followee_id: true - } - }); - - // ID list of other users who the I follows - const myfollowingIds = myfollowing.map(follow => follow.followee_id); - - if (includeMe) { - myfollowingIds.push(me); - } - - return myfollowingIds; -}; diff --git a/src/api/common/get-host-lower.ts b/src/api/common/get-host-lower.ts deleted file mode 100644 index fc4b30439e..0000000000 --- a/src/api/common/get-host-lower.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { toUnicode } from 'punycode'; - -export default host => { - return toUnicode(host).replace(/[A-Z]+/, match => match.toLowerCase()); -}; diff --git a/src/api/common/is-native-token.ts b/src/api/common/is-native-token.ts deleted file mode 100644 index 0769a4812e..0000000000 --- a/src/api/common/is-native-token.ts +++ /dev/null @@ -1 +0,0 @@ -export default (token: string) => token[0] == '!'; diff --git a/src/api/common/notify.ts b/src/api/common/notify.ts deleted file mode 100644 index ae5669b84c..0000000000 --- a/src/api/common/notify.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as mongo from 'mongodb'; -import Notification from '../models/notification'; -import Mute from '../models/mute'; -import event from '../event'; -import { pack } from '../models/notification'; - -export default ( - notifiee: mongo.ObjectID, - notifier: mongo.ObjectID, - type: string, - content?: any -) => new Promise<any>(async (resolve, reject) => { - if (notifiee.equals(notifier)) { - return resolve(); - } - - // Create notification - const notification = await Notification.insert(Object.assign({ - created_at: new Date(), - notifiee_id: notifiee, - notifier_id: notifier, - type: type, - is_read: false - }, content)); - - resolve(notification); - - // Publish notification event - event(notifiee, 'notification', - await pack(notification)); - - // 3秒経っても(今回作成した)通知が既読にならなかったら「未読の通知がありますよ」イベントを発行する - setTimeout(async () => { - const fresh = await Notification.findOne({ _id: notification._id }, { is_read: true }); - if (!fresh.is_read) { - //#region ただしミュートしているユーザーからの通知なら無視 - const mute = await Mute.find({ - muter_id: notifiee, - deleted_at: { $exists: false } - }); - const mutedUserIds = mute.map(m => m.mutee_id.toString()); - if (mutedUserIds.indexOf(notifier.toString()) != -1) { - return; - } - //#endregion - - event(notifiee, 'unread_notification', await pack(notification)); - } - }, 3000); -}); diff --git a/src/api/common/push-sw.ts b/src/api/common/push-sw.ts deleted file mode 100644 index 2993c760ee..0000000000 --- a/src/api/common/push-sw.ts +++ /dev/null @@ -1,52 +0,0 @@ -const push = require('web-push'); -import * as mongo from 'mongodb'; -import Subscription from '../models/sw-subscription'; -import config from '../../conf'; - -if (config.sw) { - // アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録 - push.setVapidDetails( - config.maintainer.url, - config.sw.public_key, - config.sw.private_key); -} - -export default async function(userId: mongo.ObjectID | string, type, body?) { - if (!config.sw) return; - - if (typeof userId === 'string') { - userId = new mongo.ObjectID(userId); - } - - // Fetch - const subscriptions = await Subscription.find({ - user_id: userId - }); - - subscriptions.forEach(subscription => { - const pushSubscription = { - endpoint: subscription.endpoint, - keys: { - auth: subscription.auth, - p256dh: subscription.publickey - } - }; - - push.sendNotification(pushSubscription, JSON.stringify({ - type, body - })).catch(err => { - //console.log(err.statusCode); - //console.log(err.headers); - //console.log(err.body); - - if (err.statusCode == 410) { - Subscription.remove({ - user_id: userId, - endpoint: subscription.endpoint, - auth: subscription.auth, - publickey: subscription.publickey - }); - } - }); - }); -} diff --git a/src/api/common/read-messaging-message.ts b/src/api/common/read-messaging-message.ts deleted file mode 100644 index 8e5e5b2b68..0000000000 --- a/src/api/common/read-messaging-message.ts +++ /dev/null @@ -1,66 +0,0 @@ -import * as mongo from 'mongodb'; -import Message from '../models/messaging-message'; -import { IMessagingMessage as IMessage } from '../models/messaging-message'; -import publishUserStream from '../event'; -import { publishMessagingStream } from '../event'; -import { publishMessagingIndexStream } from '../event'; - -/** - * Mark as read message(s) - */ -export default ( - user: string | mongo.ObjectID, - otherparty: string | mongo.ObjectID, - message: string | string[] | IMessage | IMessage[] | mongo.ObjectID | mongo.ObjectID[] -) => new Promise<any>(async (resolve, reject) => { - - const userId = mongo.ObjectID.prototype.isPrototypeOf(user) - ? user - : new mongo.ObjectID(user); - - const otherpartyId = mongo.ObjectID.prototype.isPrototypeOf(otherparty) - ? otherparty - : new mongo.ObjectID(otherparty); - - const ids: mongo.ObjectID[] = Array.isArray(message) - ? mongo.ObjectID.prototype.isPrototypeOf(message[0]) - ? (message as mongo.ObjectID[]) - : typeof message[0] === 'string' - ? (message as string[]).map(m => new mongo.ObjectID(m)) - : (message as IMessage[]).map(m => m._id) - : mongo.ObjectID.prototype.isPrototypeOf(message) - ? [(message as mongo.ObjectID)] - : typeof message === 'string' - ? [new mongo.ObjectID(message)] - : [(message as IMessage)._id]; - - // Update documents - await Message.update({ - _id: { $in: ids }, - user_id: otherpartyId, - recipient_id: userId, - is_read: false - }, { - $set: { - is_read: true - } - }, { - multi: true - }); - - // Publish event - publishMessagingStream(otherpartyId, userId, 'read', ids.map(id => id.toString())); - publishMessagingIndexStream(userId, 'read', ids.map(id => id.toString())); - - // Calc count of my unread messages - const count = await Message - .count({ - recipient_id: userId, - is_read: false - }); - - if (count == 0) { - // 全ての(いままで未読だった)自分宛てのメッセージを(これで)読みましたよというイベントを発行 - publishUserStream(userId, 'read_all_messaging_messages'); - } -}); diff --git a/src/api/common/read-notification.ts b/src/api/common/read-notification.ts deleted file mode 100644 index 3009cc5d08..0000000000 --- a/src/api/common/read-notification.ts +++ /dev/null @@ -1,52 +0,0 @@ -import * as mongo from 'mongodb'; -import { default as Notification, INotification } from '../models/notification'; -import publishUserStream from '../event'; - -/** - * Mark as read notification(s) - */ -export default ( - user: string | mongo.ObjectID, - message: string | string[] | INotification | INotification[] | mongo.ObjectID | mongo.ObjectID[] -) => new Promise<any>(async (resolve, reject) => { - - const userId = mongo.ObjectID.prototype.isPrototypeOf(user) - ? user - : new mongo.ObjectID(user); - - const ids: mongo.ObjectID[] = Array.isArray(message) - ? mongo.ObjectID.prototype.isPrototypeOf(message[0]) - ? (message as mongo.ObjectID[]) - : typeof message[0] === 'string' - ? (message as string[]).map(m => new mongo.ObjectID(m)) - : (message as INotification[]).map(m => m._id) - : mongo.ObjectID.prototype.isPrototypeOf(message) - ? [(message as mongo.ObjectID)] - : typeof message === 'string' - ? [new mongo.ObjectID(message)] - : [(message as INotification)._id]; - - // Update documents - await Notification.update({ - _id: { $in: ids }, - is_read: false - }, { - $set: { - is_read: true - } - }, { - multi: true - }); - - // Calc count of my unread notifications - const count = await Notification - .count({ - notifiee_id: userId, - is_read: false - }); - - if (count == 0) { - // 全ての(いままで未読だった)通知を(これで)読みましたよというイベントを発行 - publishUserStream(userId, 'read_all_notifications'); - } -}); diff --git a/src/api/common/signin.ts b/src/api/common/signin.ts deleted file mode 100644 index 04c2cdac81..0000000000 --- a/src/api/common/signin.ts +++ /dev/null @@ -1,19 +0,0 @@ -import config from '../../conf'; - -export default function(res, user, redirect: boolean) { - const expires = 1000 * 60 * 60 * 24 * 365; // One Year - res.cookie('i', user.account.token, { - path: '/', - domain: `.${config.hostname}`, - secure: config.url.substr(0, 5) === 'https', - httpOnly: false, - expires: new Date(Date.now() + expires), - maxAge: expires - }); - - if (redirect) { - res.redirect(config.url); - } else { - res.sendStatus(204); - } -} diff --git a/src/api/common/text/core/syntax-highlighter.ts b/src/api/common/text/core/syntax-highlighter.ts deleted file mode 100644 index c0396b1fc6..0000000000 --- a/src/api/common/text/core/syntax-highlighter.ts +++ /dev/null @@ -1,334 +0,0 @@ -function escape(text) { - return text - .replace(/>/g, '>') - .replace(/</g, '<'); -} - -// 文字数が多い順にソートします -// そうしないと、「function」という文字列が与えられたときに「func」が先にマッチしてしまう可能性があるためです -const _keywords = [ - 'true', - 'false', - 'null', - 'nil', - 'undefined', - 'void', - 'var', - 'const', - 'let', - 'mut', - 'dim', - 'if', - 'then', - 'else', - 'switch', - 'match', - 'case', - 'default', - 'for', - 'each', - 'in', - 'while', - 'loop', - 'continue', - 'break', - 'do', - 'goto', - 'next', - 'end', - 'sub', - 'throw', - 'try', - 'catch', - 'finally', - 'enum', - 'delegate', - 'function', - 'func', - 'fun', - 'fn', - 'return', - 'yield', - 'async', - 'await', - 'require', - 'include', - 'import', - 'imports', - 'export', - 'exports', - 'from', - 'as', - 'using', - 'use', - 'internal', - 'module', - 'namespace', - 'where', - 'select', - 'struct', - 'union', - 'new', - 'delete', - 'this', - 'super', - 'base', - 'class', - 'interface', - 'abstract', - 'static', - 'public', - 'private', - 'protected', - 'virtual', - 'partial', - 'override', - 'extends', - 'implements', - 'constructor' -]; - -const keywords = _keywords - .concat(_keywords.map(k => k[0].toUpperCase() + k.substr(1))) - .concat(_keywords.map(k => k.toUpperCase())) - .sort((a, b) => b.length - a.length); - -const symbols = [ - '=', - '+', - '-', - '*', - '/', - '%', - '~', - '^', - '&', - '|', - '>', - '<', - '!', - '?' -]; - -const elements = [ - // comment - code => { - if (code.substr(0, 2) != '//') return null; - const match = code.match(/^\/\/(.+?)(\n|$)/); - if (!match) return null; - const comment = match[0]; - return { - html: `<span class="comment">${escape(comment)}</span>`, - next: comment.length - }; - }, - - // block comment - code => { - const match = code.match(/^\/\*([\s\S]+?)\*\//); - if (!match) return null; - return { - html: `<span class="comment">${escape(match[0])}</span>`, - next: match[0].length - }; - }, - - // string - code => { - if (!/^['"`]/.test(code)) return null; - const begin = code[0]; - let str = begin; - let thisIsNotAString = false; - for (let i = 1; i < code.length; i++) { - const char = code[i]; - if (char == '\\') { - str += char; - str += code[i + 1] || ''; - i++; - continue; - } else if (char == begin) { - str += char; - break; - } else if (char == '\n' || i == (code.length - 1)) { - thisIsNotAString = true; - break; - } else { - str += char; - } - } - if (thisIsNotAString) { - return null; - } else { - return { - html: `<span class="string">${escape(str)}</span>`, - next: str.length - }; - } - }, - - // regexp - code => { - if (code[0] != '/') return null; - let regexp = ''; - let thisIsNotARegexp = false; - for (let i = 1; i < code.length; i++) { - const char = code[i]; - if (char == '\\') { - regexp += char; - regexp += code[i + 1] || ''; - i++; - continue; - } else if (char == '/') { - break; - } else if (char == '\n' || i == (code.length - 1)) { - thisIsNotARegexp = true; - break; - } else { - regexp += char; - } - } - - if (thisIsNotARegexp) return null; - if (regexp == '') return null; - if (regexp[0] == ' ' && regexp[regexp.length - 1] == ' ') return null; - - return { - html: `<span class="regexp">/${escape(regexp)}/</span>`, - next: regexp.length + 2 - }; - }, - - // label - code => { - if (code[0] != '@') return null; - const match = code.match(/^@([a-zA-Z_-]+?)\n/); - if (!match) return null; - const label = match[0]; - return { - html: `<span class="label">${label}</span>`, - next: label.length - }; - }, - - // number - (code, i, source) => { - const prev = source[i - 1]; - if (prev && /[a-zA-Z]/.test(prev)) return null; - if (!/^[\-\+]?[0-9\.]+/.test(code)) return null; - const match = code.match(/^[\-\+]?[0-9\.]+/)[0]; - if (match) { - return { - html: `<span class="number">${match}</span>`, - next: match.length - }; - } else { - return null; - } - }, - - // nan - (code, i, source) => { - const prev = source[i - 1]; - if (prev && /[a-zA-Z]/.test(prev)) return null; - if (code.substr(0, 3) == 'NaN') { - return { - html: `<span class="nan">NaN</span>`, - next: 3 - }; - } else { - return null; - } - }, - - // method - code => { - const match = code.match(/^([a-zA-Z_-]+?)\(/); - if (!match) return null; - - if (match[1] == '-') return null; - - return { - html: `<span class="method">${match[1]}</span>`, - next: match[1].length - }; - }, - - // property - (code, i, source) => { - const prev = source[i - 1]; - if (prev != '.') return null; - - const match = code.match(/^[a-zA-Z0-9_-]+/); - if (!match) return null; - - return { - html: `<span class="property">${match[0]}</span>`, - next: match[0].length - }; - }, - - // keyword - (code, i, source) => { - const prev = source[i - 1]; - if (prev && /[a-zA-Z]/.test(prev)) return null; - - const match = keywords.filter(k => code.substr(0, k.length) == k)[0]; - if (match) { - if (/^[a-zA-Z]/.test(code.substr(match.length))) return null; - return { - html: `<span class="keyword ${match}">${match}</span>`, - next: match.length - }; - } else { - return null; - } - }, - - // symbol - code => { - const match = symbols.filter(s => code[0] == s)[0]; - if (match) { - return { - html: `<span class="symbol">${match}</span>`, - next: 1 - }; - } else { - return null; - } - } -]; - -// specify lang is todo -export default (source: string, lang?: string) => { - let code = source; - let html = ''; - - let i = 0; - - function push(token) { - html += token.html; - code = code.substr(token.next); - i += token.next; - } - - while (code != '') { - const parsed = elements.some(el => { - const e = el(code, i, source); - if (e) { - push(e); - return true; - } else { - return false; - } - }); - - if (!parsed) { - push({ - html: escape(code[0]), - next: 1 - }); - } - } - - return html; -}; diff --git a/src/api/common/text/elements/bold.ts b/src/api/common/text/elements/bold.ts deleted file mode 100644 index ce25764457..0000000000 --- a/src/api/common/text/elements/bold.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Bold - */ - -module.exports = text => { - const match = text.match(/^\*\*(.+?)\*\*/); - if (!match) return null; - const bold = match[0]; - return { - type: 'bold', - content: bold, - bold: bold.substr(2, bold.length - 4) - }; -}; diff --git a/src/api/common/text/elements/code.ts b/src/api/common/text/elements/code.ts deleted file mode 100644 index 4821e95fe2..0000000000 --- a/src/api/common/text/elements/code.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Code (block) - */ - -import genHtml from '../core/syntax-highlighter'; - -module.exports = text => { - const match = text.match(/^```([\s\S]+?)```/); - if (!match) return null; - const code = match[0]; - return { - type: 'code', - content: code, - code: code.substr(3, code.length - 6).trim(), - html: genHtml(code.substr(3, code.length - 6).trim()) - }; -}; diff --git a/src/api/common/text/elements/emoji.ts b/src/api/common/text/elements/emoji.ts deleted file mode 100644 index e24231a223..0000000000 --- a/src/api/common/text/elements/emoji.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Emoji - */ - -module.exports = text => { - const match = text.match(/^:[a-zA-Z0-9+-_]+:/); - if (!match) return null; - const emoji = match[0]; - return { - type: 'emoji', - content: emoji, - emoji: emoji.substr(1, emoji.length - 2) - }; -}; diff --git a/src/api/common/text/elements/hashtag.ts b/src/api/common/text/elements/hashtag.ts deleted file mode 100644 index ee57b140b8..0000000000 --- a/src/api/common/text/elements/hashtag.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Hashtag - */ - -module.exports = (text, i) => { - if (!(/^\s#[^\s]+/.test(text) || (i == 0 && /^#[^\s]+/.test(text)))) return null; - const isHead = text[0] == '#'; - const hashtag = text.match(/^\s?#[^\s]+/)[0]; - const res: any[] = !isHead ? [{ - type: 'text', - content: text[0] - }] : []; - res.push({ - type: 'hashtag', - content: isHead ? hashtag : hashtag.substr(1), - hashtag: isHead ? hashtag.substr(1) : hashtag.substr(2) - }); - return res; -}; diff --git a/src/api/common/text/elements/inline-code.ts b/src/api/common/text/elements/inline-code.ts deleted file mode 100644 index 9f9ef51a2b..0000000000 --- a/src/api/common/text/elements/inline-code.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Code (inline) - */ - -import genHtml from '../core/syntax-highlighter'; - -module.exports = text => { - const match = text.match(/^`(.+?)`/); - if (!match) return null; - const code = match[0]; - return { - type: 'inline-code', - content: code, - code: code.substr(1, code.length - 2).trim(), - html: genHtml(code.substr(1, code.length - 2).trim()) - }; -}; diff --git a/src/api/common/text/elements/link.ts b/src/api/common/text/elements/link.ts deleted file mode 100644 index 35563ddc3d..0000000000 --- a/src/api/common/text/elements/link.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Link - */ - -module.exports = text => { - const match = text.match(/^\??\[([^\[\]]+?)\]\((https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+?)\)/); - if (!match) return null; - const silent = text[0] == '?'; - const link = match[0]; - const title = match[1]; - const url = match[2]; - return { - type: 'link', - content: link, - title: title, - url: url, - silent: silent - }; -}; diff --git a/src/api/common/text/elements/mention.ts b/src/api/common/text/elements/mention.ts deleted file mode 100644 index 2025dfdaad..0000000000 --- a/src/api/common/text/elements/mention.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Mention - */ -import parseAcct from '../../../../common/user/parse-acct'; - -module.exports = text => { - const match = text.match(/^(?:@[a-zA-Z0-9\-]+){1,2}/); - if (!match) return null; - const mention = match[0]; - const { username, host } = parseAcct(mention.substr(1)); - return { - type: 'mention', - content: mention, - username, - host - }; -}; diff --git a/src/api/common/text/elements/quote.ts b/src/api/common/text/elements/quote.ts deleted file mode 100644 index cc8cfffdc4..0000000000 --- a/src/api/common/text/elements/quote.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Quoted text - */ - -module.exports = text => { - const match = text.match(/^"([\s\S]+?)\n"/); - if (!match) return null; - const quote = match[0]; - return { - type: 'quote', - content: quote, - quote: quote.substr(1, quote.length - 2).trim(), - }; -}; diff --git a/src/api/common/text/elements/url.ts b/src/api/common/text/elements/url.ts deleted file mode 100644 index 1003aff9c3..0000000000 --- a/src/api/common/text/elements/url.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * URL - */ - -module.exports = text => { - const match = text.match(/^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+/); - if (!match) return null; - const url = match[0]; - return { - type: 'url', - content: url, - url: url - }; -}; diff --git a/src/api/common/text/index.ts b/src/api/common/text/index.ts deleted file mode 100644 index 1e2398dc38..0000000000 --- a/src/api/common/text/index.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Misskey Text Analyzer - */ - -const elements = [ - require('./elements/bold'), - require('./elements/url'), - require('./elements/link'), - require('./elements/mention'), - require('./elements/hashtag'), - require('./elements/code'), - require('./elements/inline-code'), - require('./elements/quote'), - require('./elements/emoji') -]; - -export default (source: string) => { - - if (source == '') { - return null; - } - - const tokens = []; - - function push(token) { - if (token != null) { - tokens.push(token); - source = source.substr(token.content.length); - } - } - - let i = 0; - - // パース - while (source != '') { - const parsed = elements.some(el => { - let _tokens = el(source, i); - if (_tokens) { - if (!Array.isArray(_tokens)) { - _tokens = [_tokens]; - } - _tokens.forEach(push); - return true; - } else { - return false; - } - }); - - if (!parsed) { - push({ - type: 'text', - content: source[0] - }); - } - - i++; - } - - // テキストを纏める - tokens[0] = [tokens[0]]; - return tokens.reduce((a, b) => { - if (a[a.length - 1].type == 'text' && b.type == 'text') { - const tail = a.pop(); - return a.concat({ - type: 'text', - content: tail.content + b.content - }); - } else { - return a.concat(b); - } - }); -}; diff --git a/src/api/common/watch-post.ts b/src/api/common/watch-post.ts deleted file mode 100644 index 1a50f0edaa..0000000000 --- a/src/api/common/watch-post.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as mongodb from 'mongodb'; -import Watching from '../models/post-watching'; - -export default async (me: mongodb.ObjectID, post: object) => { - // 自分の投稿はwatchできない - if (me.equals((post as any).user_id)) { - return; - } - - // if watching now - const exist = await Watching.findOne({ - post_id: (post as any)._id, - user_id: me, - deleted_at: { $exists: false } - }); - - if (exist !== null) { - return; - } - - await Watching.insert({ - created_at: new Date(), - post_id: (post as any)._id, - user_id: me - }); -}; |