Compare commits

..

14 Commits

Author SHA1 Message Date
c55237d09c 10.91.1 2019-03-03 08:49:53 +09:00
ed698b7b82 New Crowdin translations (#4398)
* New translations ja-JP.yml (Catalan)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Japanese, Kansai)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)
2019-03-03 08:48:17 +09:00
d4ff19f013 Fix SVG detection (#4401)
* Fix SVG detection

* remove unnecessary import
2019-03-03 08:48:02 +09:00
972fb8eb40 Hide some components 2019-03-03 08:46:42 +09:00
4de75448b6 テーマの切り替えをなめらかに 2019-03-03 08:43:51 +09:00
e8ef8f0004 Improve log view 2019-03-03 08:35:30 +09:00
a319b30382 Increase log limit 2019-03-03 08:28:35 +09:00
8278616eeb Fix log order 2019-03-03 08:28:12 +09:00
771f011506 Better log 2019-03-03 08:27:30 +09:00
826865869a Improve usability 2019-03-03 08:23:06 +09:00
3c77ae7b62 Improve log api 2019-03-03 08:13:49 +09:00
60c30ece10 Better logs 2019-03-03 08:00:39 +09:00
76a0d0fee9 Use dot 2019-03-03 07:48:25 +09:00
d50624f0a0 Better logs 2019-03-03 07:47:58 +09:00
29 changed files with 144 additions and 29 deletions

View File

@ -1,6 +1,12 @@
ChangeLog
=========
10.91.1
----------
* ログビューを強化
* テーマの切り替えをなめらかに
* SVGの判定を修正
10.91.0
----------
* ログを管理画面で見れるように

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "ハッシュタグ"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "ハッシュタグ"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -972,7 +972,7 @@ desktop/views/components/timeline.vue:
messages: "Messages"
list: "Lists"
hashtag: "Hashtag"
add-tag-timeline: "Add hashtag tl"
add-tag-timeline: "Add hashtag cloud"
add-list: "Add list"
list-name: "List name"
desktop/views/components/ui.header.vue:
@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "Hashtags"
abuse: "Abuse"
queue: "Job Queue"
logs: "Logs"
back-to-misskey: "Back to Misskey"
admin/views/dashboard.vue:
dashboard: "Dashboard"
@ -1558,8 +1559,8 @@ deck:
stack-left: "Stack to the left"
pop-right: "Dock on the right"
disabled-timeline:
title: "Timeline has been disabled"
description: "Timeline has been disabled by the administrator."
title: "The timeline has been disabled"
description: "This timeline has been disabled by the server's administrator."
deck/deck.tl-column.vue:
is-media-only: "Only media posts"
edit: "Options"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "Hashtags"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Volver a Misskey"
admin/views/dashboard.vue:
dashboard: "Panel de Control"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "Hashtags"
abuse: "Abus"
queue: "File dattente"
logs: "ログ"
back-to-misskey: "Retour vers Misskey"
admin/views/dashboard.vue:
dashboard: "Tableau de bord"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "ハッシュタグ"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "ハッシュタグ"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "해시태그"
abuse: "스팸 신고"
queue: "작업 대기열"
logs: "로그"
back-to-misskey: "Misskey로 돌아가기"
admin/views/dashboard.vue:
dashboard: "대시보드"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "ハッシュタグ"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "ハッシュタグ"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -30,9 +30,9 @@ common:
2fa: "Uwierzytelnienie dwuetapowe"
customize-home: "Dostosuj stronę główną"
featured-notes: "ハイライト"
dark-mode: "ダークモード"
signin: "ログイン"
signup: "新規登録"
dark-mode: "Tryb ciemny"
signin: "Zaloguj się"
signup: "Rejestracja"
signout: "ログアウト"
reload-to-apply-the-setting: "この設定を反映するにはページをリロードする必要があります。今すぐリロードしますか?"
got-it: "Rozumiem!"
@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "Hashtagi"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "ハッシュタグ"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "ハッシュタグ"
abuse: "スパム報告"
queue: "ジョブキュー"
logs: "ログ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"

View File

@ -1023,6 +1023,7 @@ admin/views/index.vue:
hashtags: "标签"
abuse: "举报垃圾信息"
queue: "作业队列"
logs: "登录"
back-to-misskey: "返回 Misskey"
admin/views/dashboard.vue:
dashboard: "Dashboard"

View File

@ -1,7 +1,7 @@
{
"name": "misskey",
"author": "syuilo <i@syuilo.com>",
"version": "10.91.0",
"version": "10.91.1",
"codename": "nighthike",
"repository": {
"type": "git",
@ -227,6 +227,7 @@
"url-loader": "1.1.2",
"uuid": "3.3.2",
"v-animate-css": "0.0.3",
"v-debounce": "0.1.2",
"video-thumbnail-generator": "1.1.3",
"vue": "2.6.8",
"vue-color": "2.7.0",
@ -234,6 +235,7 @@
"vue-cropperjs": "3.0.0",
"vue-i18n": "8.8.2",
"vue-js-modal": "1.3.28",
"vue-json-viewer": "2.0.6",
"vue-loader": "15.7.0",
"vue-marquee-text-component": "1.1.1",
"vue-prism-component": "1.1.1",

View File

@ -4,7 +4,7 @@
<template #title><fa :icon="faStream"/> {{ $t('logs') }}</template>
<section class="fit-top">
<ui-horizon-group inputs>
<ui-input v-model="domain">
<ui-input v-model="domain" debounce>
<span>{{ $t('domain') }}</span>
</ui-input>
<ui-select v-model="level">
@ -20,7 +20,10 @@
<div class="nqjzuvev">
<code v-for="log in logs" :key="log._id" :class="log.level">
<mk-time :time="log.createdAt"/> [{{ log.domain.join(' ') }}] {{ log.message }}
<details>
<summary><mk-time :time="log.createdAt"/> [{{ log.domain.join('.') }}] {{ log.message }}</summary>
<json-viewer v-if="log.data" :value="log.data"></json-viewer>
</details>
</code>
</div>
</section>
@ -32,10 +35,15 @@
import Vue from 'vue';
import i18n from '../../i18n';
import { faStream } from '@fortawesome/free-solid-svg-icons';
import JsonViewer from 'vue-json-viewer';
export default Vue.extend({
i18n: i18n('admin/views/logs.vue'),
components: {
JsonViewer
},
data() {
return {
logs: [],
@ -66,9 +74,9 @@ export default Vue.extend({
this.$root.api('admin/logs', {
level: this.level === 'all' ? null : this.level,
domain: this.domain === '' ? null : this.domain,
limit: 50
limit: 100
}).then(logs => {
this.logs = logs;
this.logs = logs.reverse();
});
}
}

View File

@ -179,6 +179,7 @@
<x-mute-and-block/>
</template>
<!--
<template v-if="page == null || page == 'apps'">
<ui-card>
<template #title><fa icon="puzzle-piece"/> {{ $t('@._settings.apps') }}</template>
@ -187,6 +188,7 @@
</section>
</ui-card>
</template>
-->
<template v-if="page == null || page == 'security'">
<ui-card>
@ -203,12 +205,14 @@
</section>
</ui-card>
<!--
<ui-card>
<template #title><fa icon="sign-in-alt"/> {{ $t('@._settings.signin') }}</template>
<section>
<x-signins/>
</section>
</ui-card>
-->
</template>
<template v-if="page == null || page == 'api'">

View File

@ -9,7 +9,22 @@
<span class="title" ref="title"><slot name="title"></slot></span>
<div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
<template v-if="type != 'file'">
<input ref="input"
<input v-if="debounce" ref="input"
v-debounce="500"
:type="type"
v-model.lazy="v"
:disabled="disabled"
:required="required"
:readonly="readonly"
:placeholder="placeholder"
:pattern="pattern"
:autocomplete="autocomplete"
:spellcheck="spellcheck"
@focus="focused = true"
@blur="focused = false"
@keydown="$emit('keydown', $event)"
>
<input v-else ref="input"
:type="type"
v-model="v"
:disabled="disabled"
@ -51,9 +66,13 @@
<script lang="ts">
import Vue from 'vue';
import debounce from 'v-debounce';
const getPasswordStrength = require('syuilo-password-strength');
export default Vue.extend({
directives: {
debounce
},
inject: {
horizonGrouped: {
default: false
@ -98,6 +117,9 @@ export default Vue.extend({
spellcheck: {
required: false
},
debounce: {
required: false
},
withPasswordMeter: {
type: Boolean,
required: false,

View File

@ -389,7 +389,7 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS], os: MiOS)
});
//#endregion
// Reapply current theme
/*// Reapply current theme
try {
const themeName = os.store.state.device.darkmode ? os.store.state.device.darkTheme : os.store.state.device.lightTheme;
const themes = os.store.state.device.themes.concat(builtinThemes);
@ -399,7 +399,7 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS], os: MiOS)
}
} catch (e) {
console.log(`Cannot reapply theme. ${e}`);
}
}*/
//#region line width
document.documentElement.style.setProperty('--lineWidth', `${os.store.state.device.lineWidth}px`);

View File

@ -43,6 +43,12 @@ export const builtinThemes = [
];
export function applyTheme(theme: Theme, persisted = true) {
document.documentElement.classList.add('change-theme');
setTimeout(() => {
document.documentElement.classList.remove('change-theme');
}, 500);
// Deep copy
const _theme = JSON.parse(JSON.stringify(theme));

View File

@ -20,6 +20,12 @@ html, body
text-size-adjust 100%
font-family sans-serif
html.change-theme
&, *
transition-property all
transition-duration 0.5s
transition-timing-function ease
a
text-decoration none
color var(--link)

12
src/misc/check-svg.ts Normal file
View File

@ -0,0 +1,12 @@
import * as fs from 'fs';
import * as isSvg from 'is-svg';
export default function(path: string) {
try {
const size = fs.statSync(path).size;
if (size > 1 * 1024 * 1024) return false;
return isSvg(fs.readFileSync(path));
} catch {
return false;
}
}

View File

@ -49,7 +49,7 @@ export default class Resolver {
}
if (this.history.has(value)) {
logger.error(`cannot resolve already resolved one`);
logger.error(`cannot resolve already resolved one: ${value}`);
throw new Error('cannot resolve already resolved one');
}
@ -65,7 +65,10 @@ export default class Resolver {
},
json: true
}).catch(e => {
logger.error(`request error: ${e.message}`);
logger.error(`request error: ${value}: ${e.message}`, {
url: value,
e: e
});
throw new Error(`request error: ${e.message}`);
});
@ -74,7 +77,10 @@ export default class Resolver {
!object['@context'].includes('https://www.w3.org/ns/activitystreams') :
object['@context'] !== 'https://www.w3.org/ns/activitystreams'
)) {
logger.error(`invalid response: ${value}`);
logger.error(`invalid response: ${value}`, {
url: value,
object: object
});
throw new Error('invalid response');
}

View File

@ -75,7 +75,11 @@ export default async (endpoint: string, user: IUser, app: IApp, data: any, file?
if (e instanceof ApiError) {
throw e;
} else {
apiLogger.error(e);
apiLogger.error(`Internal error occurred in ${ep.name}`, {
ep: ep.name,
ps: data,
e: e
});
throw new ApiError(null, {
e: {
message: e.message,

View File

@ -34,11 +34,27 @@ export default define(meta, async (ps) => {
if (ps.level) query.level = ps.level;
if (ps.domain) {
let i = 0;
for (const d of ps.domain.split(' ')) {
query[`domain.${i}`] = d;
const qs: any[] = [];
let i = 0;
for (const sd of (d.startsWith('-') ? d.substr(1) : d).split('.')) {
qs.push({
[`domain.${i}`]: d.startsWith('-') ? { $ne: sd } : sd
});
i++;
}
if (d.startsWith('-')) {
if (query['$and'] == null) query['$and'] = [];
query['$and'].push({
$and: qs
});
} else {
if (query['$or'] == null) query['$or'] = [];
query['$or'].push({
$and: qs
});
}
}
}
const logs = await Log

View File

@ -4,10 +4,10 @@ import * as tmp from 'tmp';
import * as Koa from 'koa';
import * as request from 'request';
import * as fileType from 'file-type';
import * as isSvg from 'is-svg';
import { serverLogger } from '..';
import config from '../../config';
import { IImage, ConvertToPng } from '../../services/drive/image-processor';
import checkSvg from '../../misc/check-svg';
export async function proxyMedia(ctx: Koa.BaseContext) {
const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url;
@ -102,7 +102,7 @@ async function detectMine(path: string) {
const type = fileType(buffer);
if (type) {
res([type.mime, type.ext]);
} else if (isSvg(buffer)) {
} else if (checkSvg(path)) {
res(['image/svg+xml', 'svg']);
} else {
// 種類が同定できなかったら application/octet-stream にする

View File

@ -7,7 +7,6 @@ import * as Minio from 'minio';
import * as uuid from 'uuid';
import * as sharp from 'sharp';
import * as fileType from 'file-type';
import * as isSvg from 'is-svg';
import DriveFile, { IMetadata, getDriveFileBucket, IDriveFile } from '../../models/drive-file';
import DriveFolder from '../../models/drive-folder';
@ -26,6 +25,7 @@ import { GenerateVideoThumbnail } from './generate-video-thumbnail';
import { driveLogger } from './logger';
import { IImage, ConvertToJpeg, ConvertToWebp, ConvertToPng } from './image-processor';
import Instance from '../../models/instance';
import checkSvg from '../../misc/check-svg';
const logger = driveLogger.createSubLogger('register', 'yellow');
@ -311,7 +311,7 @@ export default async function(
const type = fileType(buffer);
if (type) {
res([type.mime, type.ext]);
} else if (isSvg(buffer)) {
} else if (checkSvg(path)) {
res(['image/svg+xml', 'svg']);
} else {
// 種類が同定できなかったら application/octet-stream にする
@ -378,7 +378,7 @@ export default async function(
return 0;
});
logger.info(`drive usage is ${usage}`);
logger.debug(`drive usage is ${usage}`);
const instance = await fetchMeta();
const driveCapacity = 1024 * 1024 * (isLocalUser(user) ? instance.localDriveCapacityMb : instance.remoteDriveCapacityMb);

View File

@ -47,7 +47,10 @@ export default async (
});
writable.on('error', error => {
logger.error(error);
logger.error(`Download failed: ${chalk.cyan(url)}: ${error}`, {
url: url,
e: error
});
rej(error);
});
@ -73,7 +76,10 @@ export default async (
});
req.on('error', error => {
logger.error(error);
logger.error(`Failed to start download: ${chalk.cyan(url)}: ${error}`, {
url: url,
e: error
});
writable.close();
rej(error);
});
@ -87,7 +93,10 @@ export default async (
logger.succ(`Got: ${driveFile._id}`);
} catch (e) {
error = e;
logger.error(`Failed: ${e}`);
logger.error(`Failed to create drive file: ${e}`, {
url: url,
e: e
});
}
// clean-up