Skip to content

Commit e2e57f9

Browse files
authored
Merge pull request #181 from import-ai/fix/attachments
fix(attachemnts): Fix chinese attachments name
2 parents 8b13fa4 + 71999f5 commit e2e57f9

File tree

5 files changed

+112
-28
lines changed

5 files changed

+112
-28
lines changed

src/minio/minio.service.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Readable } from 'stream';
55
import generateId from 'omniboxd/utils/generate-id';
66
import {
77
decodeFileName,
8+
encodeFileName,
89
getOriginalFileName,
910
} from 'omniboxd/utils/encode-filename';
1011
import { UploadedObjectInfo } from 'minio/dist/main/internal/type';
@@ -155,8 +156,12 @@ export class MinioService {
155156
const uuid = generateId(length);
156157
// Get the original filename to extract the proper extension
157158
const originalFilename = getOriginalFileName(filename);
159+
const extIndex = originalFilename.lastIndexOf('.');
160+
if (extIndex === -1) {
161+
return uuid;
162+
}
158163
const ext: string = originalFilename.substring(
159-
originalFilename.lastIndexOf('.'),
164+
extIndex,
160165
originalFilename.length,
161166
);
162167
return `${uuid}${ext}`;
@@ -181,7 +186,7 @@ export class MinioService {
181186
buffer.length,
182187
{
183188
'Content-Type': mimetype,
184-
filename,
189+
filename: encodeFileName(filename),
185190
// Minio would convert metadata keys to lowercase
186191
metadata_string: JSON.stringify(metadata),
187192
},
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface FetchTaskRequest {
2+
namespace_id?: string;
3+
function?: string;
4+
}

src/wizard/internal.wizard.controller.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { transformKeysToSnakeCase } from 'omniboxd/interceptor/utils';
55
import { TaskCallbackDto } from 'omniboxd/wizard/dto/task-callback.dto';
66
import { ChunkCallbackDto } from 'omniboxd/wizard/dto/chunk-callback.dto';
77
import { ChunkManagerService } from 'omniboxd/wizard/chunk-manager.service';
8-
import { Body, Controller, Get, Post, Res } from '@nestjs/common';
8+
import { Body, Controller, Get, Post, Query, Res } from '@nestjs/common';
9+
import { FetchTaskRequest } from 'omniboxd/wizard/dto/fetch-task-request.dto';
910

1011
@Controller('internal/api/v1/wizard')
1112
export class InternalWizardController {
@@ -16,8 +17,11 @@ export class InternalWizardController {
1617

1718
@Public()
1819
@Get('task')
19-
async fetchTask(@Res() res: Response): Promise<void> {
20-
const task = await this.wizardService.fetchTask();
20+
async fetchTask(
21+
@Res() res: Response,
22+
@Query() query: FetchTaskRequest,
23+
): Promise<void> {
24+
const task = await this.wizardService.fetchTask(query);
2125
res.status(task ? 200 : 204).json(transformKeysToSnakeCase(task));
2226
}
2327

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { TestClient } from 'test/test-client';
2+
import { HttpStatus } from '@nestjs/common';
3+
import { Image } from 'omniboxd/wizard/types/wizard.types';
4+
5+
describe('InternalWizardController (e2e)', () => {
6+
let client: TestClient;
7+
8+
beforeAll(async () => {
9+
client = await TestClient.create();
10+
});
11+
12+
afterAll(async () => {
13+
await client.close();
14+
});
15+
16+
it('collect_callback', async () => {
17+
const collectData = {
18+
html: '<html><body><h1>Test Page</h1><p>This is test content.</p></body></html>',
19+
url: 'https://example.com/test-page',
20+
title: 'Test Page Title',
21+
namespace_id: client.namespace.id,
22+
parentId: client.namespace.root_resource_id,
23+
};
24+
25+
const taskCreateResponse = await client
26+
.post('/api/v1/wizard/collect')
27+
.send(collectData)
28+
.expect(HttpStatus.CREATED);
29+
30+
const taskId = taskCreateResponse.body.task_id;
31+
32+
await client
33+
.get(`/internal/api/v1/wizard/task?namespace_id=${client.namespace.id}`)
34+
.expect(HttpStatus.OK);
35+
36+
const response = await client
37+
.post('/internal/api/v1/wizard/callback')
38+
.send({
39+
id: taskId,
40+
output: {
41+
title: 'Test Page Title',
42+
markdown: '![图片](http://example.com/image.png)',
43+
images: [
44+
{
45+
name: '图片',
46+
link: 'http://example.com/image.png',
47+
data: 'iVBORw0KGgoAAAANSUhEUgAAAAUA',
48+
mimetype: 'image/png',
49+
},
50+
] as Image[],
51+
},
52+
});
53+
expect(response.status).toBe(HttpStatus.CREATED);
54+
});
55+
});

src/wizard/wizard.service.ts

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { WizardTaskService } from 'omniboxd/tasks/wizard-task.service';
2121
import { Image, ProcessedImage } from 'omniboxd/wizard/types/wizard.types';
2222
import { InternalTaskDto } from 'omniboxd/tasks/dto/task.dto';
2323
import { isEmpty } from 'omniboxd/utils/is-empty';
24+
import { FetchTaskRequest } from 'omniboxd/wizard/dto/fetch-task-request.dto';
2425

2526
@Injectable()
2627
export class WizardService {
@@ -241,30 +242,45 @@ export class WizardService {
241242
task.output.images = processedImages;
242243
}
243244

244-
async fetchTask(): Promise<InternalTaskDto | null> {
245+
async fetchTask(query: FetchTaskRequest): Promise<InternalTaskDto | null> {
246+
const andConditions: string[] = [];
247+
if (query.namespace_id) {
248+
andConditions.push(`tasks.namespace_id = '${query.namespace_id}'`);
249+
}
250+
if (query.function) {
251+
andConditions.push(`tasks.function = '${query.function}'`);
252+
}
253+
const andCondition: string = andConditions.map((x) => `AND ${x}`).join(' ');
245254
const rawQuery = `
246-
WITH running_tasks_sub_query AS (SELECT namespace_id,
247-
COUNT(id) AS running_count
248-
FROM tasks
249-
WHERE started_at IS NOT NULL
250-
AND ended_at IS NULL
251-
AND canceled_at IS NULL
252-
AND deleted_at IS NULL
253-
GROUP BY namespace_id),
254-
id_subquery AS (SELECT tasks.id
255-
FROM tasks
256-
LEFT OUTER JOIN running_tasks_sub_query
257-
ON tasks.namespace_id = running_tasks_sub_query.namespace_id
258-
LEFT OUTER JOIN namespaces
259-
ON tasks.namespace_id = namespaces.id
260-
WHERE tasks.started_at IS NULL
261-
AND tasks.canceled_at IS NULL
262-
AND tasks.deleted_at IS NULL
263-
AND COALESCE(running_tasks_sub_query.running_count, 0) <
264-
COALESCE(namespaces.max_running_tasks, 0)
265-
ORDER BY priority DESC,
266-
tasks.created_at
267-
LIMIT 1)
255+
WITH
256+
running_tasks_sub_query AS (
257+
SELECT
258+
namespace_id,
259+
COUNT(id) AS running_count
260+
FROM tasks
261+
WHERE started_at IS NOT NULL
262+
AND ended_at IS NULL
263+
AND canceled_at IS NULL
264+
AND deleted_at IS NULL
265+
GROUP BY namespace_id
266+
),
267+
id_subquery AS (
268+
SELECT tasks.id
269+
FROM tasks
270+
LEFT OUTER JOIN running_tasks_sub_query
271+
ON tasks.namespace_id = running_tasks_sub_query.namespace_id
272+
LEFT OUTER JOIN namespaces
273+
ON tasks.namespace_id = namespaces.id
274+
WHERE tasks.started_at IS NULL
275+
AND tasks.canceled_at IS NULL
276+
AND tasks.deleted_at IS NULL
277+
AND COALESCE(running_tasks_sub_query.running_count, 0) < COALESCE(namespaces.max_running_tasks, 0)
278+
${andCondition}
279+
ORDER BY
280+
priority DESC,
281+
tasks.created_at
282+
LIMIT 1
283+
)
268284
SELECT *
269285
FROM tasks
270286
WHERE id IN (SELECT id FROM id_subquery)

0 commit comments

Comments
 (0)