mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	
							parent
							
								
									0005de6a98
								
							
						
					
					
						commit
						bc19cd77ad
					
				
					 8 changed files with 314 additions and 8 deletions
				
			
		| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
- クライアント: 新しいライトテーマを追加
 | 
					- クライアント: 新しいライトテーマを追加
 | 
				
			||||||
- API: ユーザーのリアクション一覧を取得する users/reactions を追加
 | 
					- API: ユーザーのリアクション一覧を取得する users/reactions を追加
 | 
				
			||||||
- API: users/search および users/search-by-username-and-host を強化
 | 
					- API: users/search および users/search-by-username-and-host を強化
 | 
				
			||||||
 | 
					- ミュート及びブロックのインポートを行えるように
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Bugfixes
 | 
					### Bugfixes
 | 
				
			||||||
- クライアント: テーマの管理が行えない問題を修正
 | 
					- クライアント: テーマの管理が行えない問題を修正
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,11 +16,13 @@
 | 
				
			||||||
	</FormSection>
 | 
						</FormSection>
 | 
				
			||||||
	<FormSection>
 | 
						<FormSection>
 | 
				
			||||||
		<template #label>{{ $ts._exportOrImport.muteList }}</template>
 | 
							<template #label>{{ $ts._exportOrImport.muteList }}</template>
 | 
				
			||||||
		<MkButton :class="$style.button" inline @click="doExport('mute')"><i class="fas fa-download"></i> {{ $ts.export }}</MkButton>
 | 
							<MkButton :class="$style.button" inline @click="doExport('muting')"><i class="fas fa-download"></i> {{ $ts.export }}</MkButton>
 | 
				
			||||||
 | 
							<MkButton :class="$style.button" inline @click="doImport('muting', $event)"><i class="fas fa-upload"></i> {{ $ts.import }}</MkButton>
 | 
				
			||||||
	</FormSection>
 | 
						</FormSection>
 | 
				
			||||||
	<FormSection>
 | 
						<FormSection>
 | 
				
			||||||
		<template #label>{{ $ts._exportOrImport.blockingList }}</template>
 | 
							<template #label>{{ $ts._exportOrImport.blockingList }}</template>
 | 
				
			||||||
		<MkButton :class="$style.button" inline @click="doExport('blocking')"><i class="fas fa-download"></i> {{ $ts.export }}</MkButton>
 | 
							<MkButton :class="$style.button" inline @click="doExport('blocking')"><i class="fas fa-download"></i> {{ $ts.export }}</MkButton>
 | 
				
			||||||
 | 
							<MkButton :class="$style.button" inline @click="doImport('blocking', $event)"><i class="fas fa-upload"></i> {{ $ts.import }}</MkButton>
 | 
				
			||||||
	</FormSection>
 | 
						</FormSection>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					@ -58,11 +60,11 @@ export default defineComponent({
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		doExport(target) {
 | 
							doExport(target) {
 | 
				
			||||||
			os.api(
 | 
								os.api(
 | 
				
			||||||
				target == 'notes' ? 'i/export-notes' :
 | 
									target === 'notes' ? 'i/export-notes' :
 | 
				
			||||||
				target == 'following' ? 'i/export-following' :
 | 
									target === 'following' ? 'i/export-following' :
 | 
				
			||||||
				target == 'blocking' ? 'i/export-blocking' :
 | 
									target === 'blocking' ? 'i/export-blocking' :
 | 
				
			||||||
				target == 'user-lists' ? 'i/export-user-lists' :
 | 
									target === 'user-lists' ? 'i/export-user-lists' :
 | 
				
			||||||
				target == 'mute' ? 'i/export-mute' :
 | 
									target === 'muting' ? 'i/export-mute' :
 | 
				
			||||||
				null, {})
 | 
									null, {})
 | 
				
			||||||
			.then(() => {
 | 
								.then(() => {
 | 
				
			||||||
				os.dialog({
 | 
									os.dialog({
 | 
				
			||||||
| 
						 | 
					@ -81,8 +83,10 @@ export default defineComponent({
 | 
				
			||||||
			const file = await selectFile(e.currentTarget || e.target);
 | 
								const file = await selectFile(e.currentTarget || e.target);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			os.api(
 | 
								os.api(
 | 
				
			||||||
				target == 'following' ? 'i/import-following' :
 | 
									target === 'following' ? 'i/import-following' :
 | 
				
			||||||
				target == 'user-lists' ? 'i/import-user-lists' :
 | 
									target === 'user-lists' ? 'i/import-user-lists' :
 | 
				
			||||||
 | 
									target === 'muting' ? 'i/import-muting' :
 | 
				
			||||||
 | 
									target === 'blocking' ? 'i/import-blocking' :
 | 
				
			||||||
				null, {
 | 
									null, {
 | 
				
			||||||
					fileId: file.id
 | 
										fileId: file.id
 | 
				
			||||||
			}).then(() => {
 | 
								}).then(() => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -163,6 +163,26 @@ export function createImportFollowingJob(user: ThinUser, fileId: DriveFile['id']
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function createImportMutingJob(user: ThinUser, fileId: DriveFile['id']) {
 | 
				
			||||||
 | 
						return dbQueue.add('importMuting', {
 | 
				
			||||||
 | 
							user: user,
 | 
				
			||||||
 | 
							fileId: fileId
 | 
				
			||||||
 | 
						}, {
 | 
				
			||||||
 | 
							removeOnComplete: true,
 | 
				
			||||||
 | 
							removeOnFail: true
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function createImportBlockingJob(user: ThinUser, fileId: DriveFile['id']) {
 | 
				
			||||||
 | 
						return dbQueue.add('importBlocking', {
 | 
				
			||||||
 | 
							user: user,
 | 
				
			||||||
 | 
							fileId: fileId
 | 
				
			||||||
 | 
						}, {
 | 
				
			||||||
 | 
							removeOnComplete: true,
 | 
				
			||||||
 | 
							removeOnFail: true
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function createImportUserListsJob(user: ThinUser, fileId: DriveFile['id']) {
 | 
					export function createImportUserListsJob(user: ThinUser, fileId: DriveFile['id']) {
 | 
				
			||||||
	return dbQueue.add('importUserLists', {
 | 
						return dbQueue.add('importUserLists', {
 | 
				
			||||||
		user: user,
 | 
							user: user,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										74
									
								
								src/queue/processors/db/import-blocking.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/queue/processors/db/import-blocking.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,74 @@
 | 
				
			||||||
 | 
					import * as Bull from 'bull';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { queueLogger } from '../../logger';
 | 
				
			||||||
 | 
					import { parseAcct } from '@/misc/acct';
 | 
				
			||||||
 | 
					import { resolveUser } from '@/remote/resolve-user';
 | 
				
			||||||
 | 
					import { downloadTextFile } from '@/misc/download-text-file';
 | 
				
			||||||
 | 
					import { isSelfHost, toPuny } from '@/misc/convert-host';
 | 
				
			||||||
 | 
					import { Users, DriveFiles, Blockings } from '@/models/index';
 | 
				
			||||||
 | 
					import { DbUserImportJobData } from '@/queue/types';
 | 
				
			||||||
 | 
					import block from '@/services/blocking/create';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const logger = queueLogger.createSubLogger('import-blocking');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function importBlocking(job: Bull.Job<DbUserImportJobData>, done: any): Promise<void> {
 | 
				
			||||||
 | 
						logger.info(`Importing blocking of ${job.data.user.id} ...`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const user = await Users.findOne(job.data.user.id);
 | 
				
			||||||
 | 
						if (user == null) {
 | 
				
			||||||
 | 
							done();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const file = await DriveFiles.findOne({
 | 
				
			||||||
 | 
							id: job.data.fileId
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						if (file == null) {
 | 
				
			||||||
 | 
							done();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const csv = await downloadTextFile(file.url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let linenum = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (const line of csv.trim().split('\n')) {
 | 
				
			||||||
 | 
							linenum++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								const acct = line.split(',')[0].trim();
 | 
				
			||||||
 | 
								const { username, host } = parseAcct(acct);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								let target = isSelfHost(host!) ? await Users.findOne({
 | 
				
			||||||
 | 
									host: null,
 | 
				
			||||||
 | 
									usernameLower: username.toLowerCase()
 | 
				
			||||||
 | 
								}) : await Users.findOne({
 | 
				
			||||||
 | 
									host: toPuny(host!),
 | 
				
			||||||
 | 
									usernameLower: username.toLowerCase()
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (host == null && target == null) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (target == null) {
 | 
				
			||||||
 | 
									target = await resolveUser(username, host);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (target == null) {
 | 
				
			||||||
 | 
									throw `cannot resolve user: @${username}@${host}`;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// skip myself
 | 
				
			||||||
 | 
								if (target.id === job.data.user.id) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logger.info(`Mute[${linenum}] ${target.id} ...`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								await block(user, target);
 | 
				
			||||||
 | 
							} catch (e) {
 | 
				
			||||||
 | 
								logger.warn(`Error in line:${linenum} ${e}`);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger.succ('Imported');
 | 
				
			||||||
 | 
						done();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										83
									
								
								src/queue/processors/db/import-muting.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/queue/processors/db/import-muting.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,83 @@
 | 
				
			||||||
 | 
					import * as Bull from 'bull';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { queueLogger } from '../../logger';
 | 
				
			||||||
 | 
					import { parseAcct } from '@/misc/acct';
 | 
				
			||||||
 | 
					import { resolveUser } from '@/remote/resolve-user';
 | 
				
			||||||
 | 
					import { downloadTextFile } from '@/misc/download-text-file';
 | 
				
			||||||
 | 
					import { isSelfHost, toPuny } from '@/misc/convert-host';
 | 
				
			||||||
 | 
					import { Users, DriveFiles, Mutings } from '@/models/index';
 | 
				
			||||||
 | 
					import { DbUserImportJobData } from '@/queue/types';
 | 
				
			||||||
 | 
					import { User } from '@/models/entities/user';
 | 
				
			||||||
 | 
					import { genId } from '@/misc/gen-id';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const logger = queueLogger.createSubLogger('import-muting');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function importMuting(job: Bull.Job<DbUserImportJobData>, done: any): Promise<void> {
 | 
				
			||||||
 | 
						logger.info(`Importing muting of ${job.data.user.id} ...`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const user = await Users.findOne(job.data.user.id);
 | 
				
			||||||
 | 
						if (user == null) {
 | 
				
			||||||
 | 
							done();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const file = await DriveFiles.findOne({
 | 
				
			||||||
 | 
							id: job.data.fileId
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						if (file == null) {
 | 
				
			||||||
 | 
							done();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const csv = await downloadTextFile(file.url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let linenum = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (const line of csv.trim().split('\n')) {
 | 
				
			||||||
 | 
							linenum++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								const acct = line.split(',')[0].trim();
 | 
				
			||||||
 | 
								const { username, host } = parseAcct(acct);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								let target = isSelfHost(host!) ? await Users.findOne({
 | 
				
			||||||
 | 
									host: null,
 | 
				
			||||||
 | 
									usernameLower: username.toLowerCase()
 | 
				
			||||||
 | 
								}) : await Users.findOne({
 | 
				
			||||||
 | 
									host: toPuny(host!),
 | 
				
			||||||
 | 
									usernameLower: username.toLowerCase()
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (host == null && target == null) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (target == null) {
 | 
				
			||||||
 | 
									target = await resolveUser(username, host);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (target == null) {
 | 
				
			||||||
 | 
									throw `cannot resolve user: @${username}@${host}`;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// skip myself
 | 
				
			||||||
 | 
								if (target.id === job.data.user.id) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logger.info(`Mute[${linenum}] ${target.id} ...`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								await mute(user, target);
 | 
				
			||||||
 | 
							} catch (e) {
 | 
				
			||||||
 | 
								logger.warn(`Error in line:${linenum} ${e}`);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger.succ('Imported');
 | 
				
			||||||
 | 
						done();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function mute(user: User, target: User) {
 | 
				
			||||||
 | 
						await Mutings.insert({
 | 
				
			||||||
 | 
							id: genId(),
 | 
				
			||||||
 | 
							createdAt: new Date(),
 | 
				
			||||||
 | 
							muterId: user.id,
 | 
				
			||||||
 | 
							muteeId: target.id,
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,8 @@ import { exportUserLists } from './export-user-lists';
 | 
				
			||||||
import { importFollowing } from './import-following';
 | 
					import { importFollowing } from './import-following';
 | 
				
			||||||
import { importUserLists } from './import-user-lists';
 | 
					import { importUserLists } from './import-user-lists';
 | 
				
			||||||
import { deleteAccount } from './delete-account';
 | 
					import { deleteAccount } from './delete-account';
 | 
				
			||||||
 | 
					import { importMuting } from './import-muting';
 | 
				
			||||||
 | 
					import { importBlocking } from './import-blocking';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const jobs = {
 | 
					const jobs = {
 | 
				
			||||||
	deleteDriveFiles,
 | 
						deleteDriveFiles,
 | 
				
			||||||
| 
						 | 
					@ -18,6 +20,8 @@ const jobs = {
 | 
				
			||||||
	exportBlocking,
 | 
						exportBlocking,
 | 
				
			||||||
	exportUserLists,
 | 
						exportUserLists,
 | 
				
			||||||
	importFollowing,
 | 
						importFollowing,
 | 
				
			||||||
 | 
						importMuting,
 | 
				
			||||||
 | 
						importBlocking,
 | 
				
			||||||
	importUserLists,
 | 
						importUserLists,
 | 
				
			||||||
	deleteAccount,
 | 
						deleteAccount,
 | 
				
			||||||
} as Record<string, Bull.ProcessCallbackFunction<DbJobData> | Bull.ProcessPromiseFunction<DbJobData>>;
 | 
					} as Record<string, Bull.ProcessCallbackFunction<DbJobData> | Bull.ProcessPromiseFunction<DbJobData>>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										60
									
								
								src/server/api/endpoints/i/import-blocking.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/server/api/endpoints/i/import-blocking.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					import $ from 'cafy';
 | 
				
			||||||
 | 
					import { ID } from '@/misc/cafy-id';
 | 
				
			||||||
 | 
					import define from '../../define';
 | 
				
			||||||
 | 
					import { createImportBlockingJob } from '@/queue/index';
 | 
				
			||||||
 | 
					import * as ms from 'ms';
 | 
				
			||||||
 | 
					import { ApiError } from '../../error';
 | 
				
			||||||
 | 
					import { DriveFiles } from '@/models/index';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const meta = {
 | 
				
			||||||
 | 
						secure: true,
 | 
				
			||||||
 | 
						requireCredential: true as const,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						limit: {
 | 
				
			||||||
 | 
							duration: ms('1hour'),
 | 
				
			||||||
 | 
							max: 1,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params: {
 | 
				
			||||||
 | 
							fileId: {
 | 
				
			||||||
 | 
								validator: $.type(ID),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errors: {
 | 
				
			||||||
 | 
							noSuchFile: {
 | 
				
			||||||
 | 
								message: 'No such file.',
 | 
				
			||||||
 | 
								code: 'NO_SUCH_FILE',
 | 
				
			||||||
 | 
								id: 'ebb53e5f-6574-9c0c-0b92-7ca6def56d7e'
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unexpectedFileType: {
 | 
				
			||||||
 | 
								message: 'We need csv file.',
 | 
				
			||||||
 | 
								code: 'UNEXPECTED_FILE_TYPE',
 | 
				
			||||||
 | 
								id: 'b6fab7d6-d945-d67c-dfdb-32da1cd12cfe'
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tooBigFile: {
 | 
				
			||||||
 | 
								message: 'That file is too big.',
 | 
				
			||||||
 | 
								code: 'TOO_BIG_FILE',
 | 
				
			||||||
 | 
								id: 'b7fbf0b1-aeef-3b21-29ef-fadd4cb72ccf'
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							emptyFile: {
 | 
				
			||||||
 | 
								message: 'That file is empty.',
 | 
				
			||||||
 | 
								code: 'EMPTY_FILE',
 | 
				
			||||||
 | 
								id: '6f3a4dcc-f060-a707-4950-806fbdbe60d6'
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default define(meta, async (ps, user) => {
 | 
				
			||||||
 | 
						const file = await DriveFiles.findOne(ps.fileId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (file == null) throw new ApiError(meta.errors.noSuchFile);
 | 
				
			||||||
 | 
						//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
 | 
				
			||||||
 | 
						if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
 | 
				
			||||||
 | 
						if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						createImportBlockingJob(user, file.id);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										60
									
								
								src/server/api/endpoints/i/import-muting.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/server/api/endpoints/i/import-muting.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					import $ from 'cafy';
 | 
				
			||||||
 | 
					import { ID } from '@/misc/cafy-id';
 | 
				
			||||||
 | 
					import define from '../../define';
 | 
				
			||||||
 | 
					import { createImportMutingJob } from '@/queue/index';
 | 
				
			||||||
 | 
					import * as ms from 'ms';
 | 
				
			||||||
 | 
					import { ApiError } from '../../error';
 | 
				
			||||||
 | 
					import { DriveFiles } from '@/models/index';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const meta = {
 | 
				
			||||||
 | 
						secure: true,
 | 
				
			||||||
 | 
						requireCredential: true as const,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						limit: {
 | 
				
			||||||
 | 
							duration: ms('1hour'),
 | 
				
			||||||
 | 
							max: 1,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params: {
 | 
				
			||||||
 | 
							fileId: {
 | 
				
			||||||
 | 
								validator: $.type(ID),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errors: {
 | 
				
			||||||
 | 
							noSuchFile: {
 | 
				
			||||||
 | 
								message: 'No such file.',
 | 
				
			||||||
 | 
								code: 'NO_SUCH_FILE',
 | 
				
			||||||
 | 
								id: 'e674141e-bd2a-ba85-e616-aefb187c9c2a'
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unexpectedFileType: {
 | 
				
			||||||
 | 
								message: 'We need csv file.',
 | 
				
			||||||
 | 
								code: 'UNEXPECTED_FILE_TYPE',
 | 
				
			||||||
 | 
								id: '568c6e42-c86c-ba09-c004-517f83f9f1a8'
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tooBigFile: {
 | 
				
			||||||
 | 
								message: 'That file is too big.',
 | 
				
			||||||
 | 
								code: 'TOO_BIG_FILE',
 | 
				
			||||||
 | 
								id: '9b4ada6d-d7f7-0472-0713-4f558bd1ec9c'
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							emptyFile: {
 | 
				
			||||||
 | 
								message: 'That file is empty.',
 | 
				
			||||||
 | 
								code: 'EMPTY_FILE',
 | 
				
			||||||
 | 
								id: 'd2f12af1-e7b4-feac-86a3-519548f2728e'
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default define(meta, async (ps, user) => {
 | 
				
			||||||
 | 
						const file = await DriveFiles.findOne(ps.fileId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (file == null) throw new ApiError(meta.errors.noSuchFile);
 | 
				
			||||||
 | 
						//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
 | 
				
			||||||
 | 
						if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
 | 
				
			||||||
 | 
						if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						createImportMutingJob(user, file.id);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue