Skip to content
This repository has been archived by the owner on Jun 16, 2024. It is now read-only.

Commit

Permalink
feat: 支持附件导出
Browse files Browse the repository at this point in the history
  • Loading branch information
eightHundreds committed Jul 30, 2023
1 parent 552b5b1 commit d25b131
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 45 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
"obsidian": "^1.3.5",
"obsidian-plugin-cli": "^0.9.0",
"tslib": "2.4.0",
"typescript": "4.7.4"
"typescript": "4.7.4",
"unified": "^10.1.2"
},
"dependencies": {
"@total-typescript/ts-reset": "^0.4.2",
"@types/debug": "^4.1.7",
"dayjs": "^1.11.7",
"debug": "^4.3.4",
Expand Down
18 changes: 8 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 45 additions & 10 deletions src/dida.ts → src/core/dida.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
/* eslint-disable @typescript-eslint/naming-convention */
import dayjs from 'dayjs';
import {requestUrl} from 'obsidian';
import path from 'path';
import {Tasks, requestUrl} from 'obsidian';
import qs from 'querystring';
import {DidaFrontMatter, ServeType} from './types';
import {TaskStatus} from './constants';
import {DidaFrontMatter, ServeType} from '../types';
import {TaskStatus} from '../constants';
import debug from 'debug';

type DiDa365APIOptions = {
username: string;
password: string;
apiHost?: string;
host?: string;
loginHost?: string;
};

export type Item = {
Expand All @@ -32,7 +33,14 @@ export type Item = {
status: number;
items: any[];
progress: number;
attachments: any[];
attachments: Array<{
createdTime: string;
fileName: string;
fileType: string;
id: string;
path: string;
size: number;
}>;
dueDate?: string;
modifiedTime: string;
etag: string;
Expand All @@ -57,7 +65,8 @@ export class DiDa365API implements IDiDa365API {
private readonly log: (...args: any[]) => any;
constructor(options: DiDa365APIOptions) {
this.options = {
host: 'https://api.dida365.com',
apiHost: 'https://api.dida365.com',
host: 'https://dida365.com',
...options,
};
this.log = debug('dida365:api');
Expand Down Expand Up @@ -149,8 +158,25 @@ export class DiDa365API implements IDiDa365API {
return allTask;
}

public async downloadAttachment(item: Item) {
const result = item.attachments.map(async attachment => {
const url = `${this.options.apiHost}/api/v1/attachment/${item.projectId}/${item.id}/${attachment.id}${path.extname(attachment.path)}`;
return requestUrl({
url,
headers: {
Cookie: this.cookieHeader,
},
method: 'GET',
}).then(res => ({
...attachment,
arrayBuffer: res.arrayBuffer,
}));
});
return Promise.allSettled(result);
}

private async getAllUnCompleted() {
const url = `${this.options.host}/api/v2/batch/check/0`;
const url = `${this.options.apiHost}/api/v2/batch/check/0`;
const result = await requestUrl({
url,
headers: {
Expand All @@ -163,7 +189,7 @@ export class DiDa365API implements IDiDa365API {
}

private async getAllCompleted(startData: number) {
const url = `${this.options.host}/api/v2/project/all/completed`;
const url = `${this.options.apiHost}/api/v2/project/all/completed`;
const params = {
from: dayjs(startData).format('YYYY-MM-DD%20HH:mm:ss'),
to: dayjs().format('YYYY-MM-DD%20HH:mm:ss'),
Expand Down Expand Up @@ -200,7 +226,7 @@ export class DiDa365API implements IDiDa365API {
return;
}

const url = `${this.options.host}/api/v2/user/signon?wc=true&remember=true`;
const url = `${this.options.apiHost}/api/v2/user/signon?wc=true&remember=true`;

const options = {
username: this.options.username,
Expand Down Expand Up @@ -240,7 +266,8 @@ export class TodoAppClientFacade {
});
this.ttClient = new DiDa365API({
...options,
host: 'https://api.ticktick.com',
apiHost: 'https://api.ticktick.com',
host: 'https://ticktick.com',
});
}

Expand All @@ -251,4 +278,12 @@ export class TodoAppClientFacade {

return this.ttClient.getItems(filterOptions);
}

async downloadAttachment(item: Item, type: ServeType) {
if (type === ServeType.Dida) {
return this.didaClient.downloadAttachment(item);
}

return this.ttClient.downloadAttachment(item);
}
}
79 changes: 79 additions & 0 deletions src/core/markdownGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import dayjs from 'dayjs';
import {remark} from 'remark';
import type DiDaSyncPlugin from '../main';
import {Item} from './dida';
import {TaskStatus} from '../constants';
import {TFile} from 'obsidian';

class MarkdownGenerator {
constructor(private readonly plugin: DiDaSyncPlugin) {
}

public taskToMarkdown(item: Item, attachments: TFile[]) {
const format = (v: string) => {
if (!v) {
return '';
}

return dayjs(v).format('YYYY-MM-DD HH:mm:ss');
};

const remarker = remark().use(() => tree => {
// Heading 添加一级
tree.children.forEach(node => {
if (node.type === 'heading') {
node.depth += 1;
}
});
}).use(() => tree => {
tree.children.forEach(node => {
if (node.type !== 'paragraph') {
return;
}

node.children.forEach(child => {
if (child.type === 'image') {
const idInUrl = child.url.split('/')[0];
const attachment = attachments.find(a => a.basename === idInUrl);
if (!attachment) {
return;
}

child.url = attachment.path;

if (child.alt === 'file') {
// @ts-expect-error
child.type = 'link';
// @ts-expect-error
child.children = [{
type: 'text',
value: attachment.name,
}];
}
}
});
});
return tree;
});

return `# ${item.title}
^dida-${item.id}
> [!meta]-
> - createdTime: ${format(item.createdTime)}${
item.dueDate
? `> - dueDate: ${format(item.dueDate)}`
: ''
}
> - status: ${TaskStatus[item.status].toString()}
${remarker.processSync(item.content).toString()}
${item.items
.map(
i => `- [${i.status === TaskStatus.Completed ? 'X' : ' '}] ${i.title}`,
)
.join('\n')}
`;
}
}
export default MarkdownGenerator;
1 change: 1 addition & 0 deletions src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"inputPassword":"Please input your password",
"debugMode":"Debug Mode",
"syncSuccess":"Sync Success",
"syncFailed": "Sync Failed",
"syncToDoList":"Sync ToDo List",
"disablePageHeaderAction": "Disable Page Header Action"
}
Expand Down
1 change: 1 addition & 0 deletions src/locale/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"inputPassword": "请输入您的密码",
"debugMode": "调试模式",
"syncSuccess": "同步成功",
"syncFailed": "同步失败",
"syncToDoList": "同步待办",
"disablePageHeaderAction": "隐藏页面头部快捷操作"
}
Expand Down
Loading

0 comments on commit d25b131

Please sign in to comment.