Skip to content

Commit e21c136

Browse files
committed
feat: map post with post id in file name
1 parent 461d380 commit e21c136

File tree

6 files changed

+110
-60
lines changed

6 files changed

+110
-60
lines changed

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@
242242
},
243243
{
244244
"command": "vscode-cnb.post.show-local-file-info",
245-
"title": "博客园关联博文",
245+
"title": "关联博客园博文",
246246
"enablement": "vscode-cnb.isAuthed"
247247
},
248248
{
@@ -616,7 +616,7 @@
616616
},
617617
"post-show-local-file-info": {
618618
"order": 3,
619-
"description": "博客园关联博文",
619+
"description": "关联博客园博文",
620620
"type": "boolean",
621621
"default": true
622622
},
@@ -677,7 +677,7 @@
677677
},
678678
"post-show-local-file-info": {
679679
"order": 3,
680-
"description": "博客园关联博文",
680+
"description": "关联博客园博文",
681681
"type": "boolean"
682682
},
683683
"post-open-in-blog-admin": {

src/cmd/post-list/open-post-in-vscode.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import { fsUtil } from '@/infra/fs/fsUtil'
1111

1212
export function buildLocalPostFileUri(post: Post, appendToFileName = ''): Uri {
1313
const workspaceUri = WorkspaceCfg.getWorkspaceUri()
14-
const ext = `.${post.isMarkdown ? 'md' : 'html'}`
15-
const postTitle = sanitizeFileName(post.title)
16-
return Uri.joinPath(workspaceUri, `${postTitle}${appendToFileName}.${post.id}${ext}`)
14+
const ext = `${post.isMarkdown ? 'md' : 'html'}`
15+
let postTitle = sanitizeFileName(post.title)
16+
if (/\.\d+$/.test(postTitle)) postTitle += '_'
17+
return Uri.joinPath(workspaceUri, `${postTitle}${appendToFileName}.${post.id}.${ext}`)
1718
}
1819

1920
export async function openPostInVscode(postId: number, forceUpdateLocalPostFile = false): Promise<Uri | false> {

src/cmd/post-list/post-pull.ts

+33-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { revealPostListItem } from '@/service/post/post-list-view'
99
import { PostTreeItem } from '@/tree-view/model/post-tree-item'
1010
import { MarkdownCfg } from '@/ctx/cfg/markdown'
1111
import { fsUtil } from '@/infra/fs/fsUtil'
12+
import { searchPostByTitle } from '@/service/post/search-post-by-title'
1213

1314
export async function postPull(input: Post | PostTreeItem | Uri | undefined | null, showConfirm = true, mute = false) {
1415
const ctxList: CmdCtx[] = []
@@ -30,7 +31,7 @@ export async function postPull(input: Post | PostTreeItem | Uri | undefined | nu
3031
}
3132
} else {
3233
const uri = parseUriInput(input)
33-
if (uri !== undefined) handleUriInput(uri, ctxList)
34+
if (uri != null) await handleUriInput(uri, ctxList)
3435
}
3536

3637
const fileName = resolveFileNames(ctxList)
@@ -77,9 +78,37 @@ function parseUriInput(input: InputType): Uri | undefined {
7778
if (doc !== undefined && !doc.isUntitled) return doc.uri
7879
}
7980

80-
function handleUriInput(fileUri: Uri, contexts: CmdCtx[]) {
81-
const postId = PostFileMapManager.getPostId(fileUri.path)
82-
if (postId === undefined) return Alert.fileNotLinkedToPost(fileUri)
81+
async function handleUriInput(fileUri: Uri, contexts: CmdCtx[]) {
82+
let postId = PostFileMapManager.getPostId(fileUri.path)
83+
if (postId == null) {
84+
const mapPost = '关联已有博文并拉取'
85+
const selected = await Alert.info(
86+
'本地文件尚未关联到博客园博文',
87+
{
88+
modal: true,
89+
detail: `您可以将当前本地文件关联到已有博客园博文`,
90+
},
91+
mapPost
92+
)
93+
94+
if (selected === mapPost) {
95+
const fsPath = fileUri.fsPath
96+
console.log('fsPath: ' + fsPath)
97+
const filenName = path.basename(fsPath, path.extname(fsPath))
98+
console.log('filenName: ' + filenName)
99+
postId = PostFileMapManager.extractPostId(filenName)
100+
console.log('postId: ' + postId)
101+
if (postId == null) {
102+
const selectedPost = await searchPostByTitle(filenName, '搜索要关联的博文')
103+
if (selectedPost == null) return Alert.info('未选择要关联的博文')
104+
postId = selectedPost.id
105+
}
106+
}
107+
108+
if (postId != null) await PostFileMapManager.updateOrCreate(postId, fileUri.path)
109+
}
110+
111+
if (postId == null) return Alert.fileNotLinkedToPost(fileUri)
83112

84113
contexts.push({ postId, fileUri })
85114
}

src/cmd/post-list/upload-post.ts

+35-35
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,17 @@ import { Workspace } from '@/cmd/workspace'
2121
import { fsUtil } from '@/infra/fs/fsUtil'
2222

2323
async function parseFileUri(fileUri?: Uri) {
24-
if (fileUri !== undefined && fileUri.scheme !== 'file') return undefined
24+
if (fileUri !== undefined && fileUri.scheme !== 'file') return
2525
if (fileUri !== undefined) return fileUri
2626

2727
const { activeTextEditor } = window
28-
if (activeTextEditor === undefined) return undefined
28+
if (activeTextEditor == null) return
2929

3030
const { document } = activeTextEditor
3131
if (document.languageId === 'markdown' && !document.isUntitled) {
3232
await document.save()
3333
return document.uri
3434
}
35-
36-
return undefined
3735
}
3836

3937
export async function saveLocalPost(localPost: LocalPost) {
@@ -202,43 +200,45 @@ export async function uploadPost(input?: Post | PostTreeItem | PostEditDto, conf
202200

203201
export async function uploadPostFile(fileUri?: Uri, confirm = true) {
204202
const parsedFileUri = await parseFileUri(fileUri)
205-
if (parsedFileUri === undefined) return
206-
207-
const { fsPath: filePath } = parsedFileUri
208-
const postId = PostFileMapManager.getPostId(parsedFileUri.path)
209-
210-
if (postId !== undefined && postId >= 0) {
211-
const dto = await PostService.getPostEditDto(postId)
212-
if (dto !== undefined) await uploadPost(dto, confirm)
213-
return
214-
}
203+
if (parsedFileUri == null) return
215204

216205
const fileContent = Buffer.from(await workspace.fs.readFile(parsedFileUri)).toString()
217206
if (isEmptyBody(fileContent)) return
218207

219-
const selected = await Alert.info(
220-
'本地文件尚未关联到博客园博文',
221-
{
222-
modal: true,
223-
detail: `您可以选择新建一篇博文或将本地文件关联到一篇博客园博文(您可以根据标题搜索您在博客园博文)`,
224-
},
225-
'新建博文',
226-
'关联已有博文'
227-
)
228-
if (selected === '关联已有博文') {
229-
const selectedPost = await searchPostByTitle(
230-
path.basename(filePath, path.extname(filePath)),
231-
'搜索要关联的博文'
208+
const { fsPath: fsPath } = parsedFileUri
209+
let postId = PostFileMapManager.getPostId(parsedFileUri.path)
210+
211+
if (postId == null) {
212+
const createPost = '新建博文'
213+
const mapPost = '关联已有博文并上传'
214+
const selected = await Alert.info(
215+
'本地文件尚未关联到博客园博文',
216+
{
217+
modal: true,
218+
detail: `您可以选择新建一篇博文或将当前本地文件关联到已有博客园博文`,
219+
},
220+
createPost,
221+
mapPost
232222
)
233-
if (selectedPost === undefined) return
234223

235-
await PostFileMapManager.updateOrCreate(selectedPost.id, parsedFileUri.path)
236-
const postEditDto = await PostService.getPostEditDto(selectedPost.id)
237-
if (postEditDto === undefined) return
238-
if (fileContent === '') await workspace.fs.writeFile(parsedFileUri, Buffer.from(postEditDto.post.postBody))
224+
if (selected === mapPost) {
225+
const filenName = path.basename(fsPath, path.extname(fsPath))
226+
postId = PostFileMapManager.extractPostId(filenName)
227+
if (postId == null) {
228+
const selectedPost = await searchPostByTitle(filenName, '搜索要关联的博文')
239229

240-
await uploadPost(postEditDto.post, confirm)
241-
} else if (selected === '新建博文') {
242-
await saveLocalPost(new LocalPost(filePath))
230+
if (selectedPost == null) return Alert.info('未选择要关联的博文')
231+
postId = selectedPost.id
232+
}
233+
if (postId != null) await PostFileMapManager.updateOrCreate(postId, parsedFileUri.path)
234+
} else if (selected === createPost) {
235+
await saveLocalPost(new LocalPost(fsPath))
236+
}
237+
}
238+
239+
if (postId != null) {
240+
const dto = await PostService.getPostEditDto(postId)
241+
if (dto == null) return Alert.err(`对应的博文不存在(Id: ${postId})`)
242+
await uploadPost(dto, confirm)
243243
}
244244
}

src/cmd/show-local-file-to-post-info.ts

+23-10
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ import format from 'date-fns/format'
1414
* @param {(Uri | number)} input
1515
* @returns {*} {Promise<void>}
1616
*/
17-
export async function showLocalFileToPostInfo(input: Uri | number): Promise<void> {
17+
export async function showLocalFileToPostInfo(input: Uri | number): Promise<number | undefined> {
1818
let filePath: string | undefined
1919
let postId: number | undefined
2020
if (input instanceof Uri && input.scheme === 'file') {
2121
postId = PostFileMapManager.getPostId(input.path)
2222
filePath = input.fsPath
23-
if (postId === undefined) {
23+
if (postId == null) {
2424
const options = ['现在去关联']
2525
const selected = await Alert.info(
2626
'本地文件尚未关联到博文',
@@ -31,14 +31,27 @@ export async function showLocalFileToPostInfo(input: Uri | number): Promise<void
3131
...options
3232
)
3333
if (selected === options[0]) {
34-
const selectedPost = await searchPostByTitle(
35-
path.basename(filePath, path.extname(filePath)),
36-
'搜索要关联的博文'
37-
)
38-
if (selectedPost !== undefined) {
39-
await PostFileMapManager.updateOrCreate(selectedPost.id, input.path)
40-
void Alert.info(`本地文件已与博文(${selectedPost.title}, Id: ${selectedPost.id})建立关联`)
34+
const filenName = path.basename(filePath, path.extname(filePath))
35+
postId = PostFileMapManager.extractPostId(filenName)
36+
if (postId == null) {
37+
const selectedPost = await searchPostByTitle(filenName, '搜索要关联的博文')
38+
39+
if (selectedPost == null) {
40+
void Alert.info('未选择要关联的博文')
41+
return
42+
}
43+
postId = selectedPost.id
44+
}
45+
46+
const dto = await PostService.getPostEditDto(postId)
47+
if (dto == null) {
48+
void Alert.err(`对应的博文不存在(Id: ${postId})`)
49+
return
4150
}
51+
52+
await PostFileMapManager.updateOrCreate(postId, input.path)
53+
void Alert.info(`本地文件已与博文(Id: ${postId})建立关联`)
54+
return postId
4255
}
4356
return
4457
}
@@ -74,6 +87,6 @@ export async function showLocalFileToPostInfo(input: Uri | number): Promise<void
7487
await viewPostOnline(post)
7588
} else if (selected === options[1]) {
7689
await PostFileMapManager.updateOrCreate(postId, '')
77-
void Alert.info(`博文 ${post.title} 已与 ${filePath} 取消关联`)
90+
void Alert.info(`本地文件已与博文(Id: ${postId})取消关联`)
7891
}
7992
}

src/service/post/post-file-map.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { postDataProvider } from '@/tree-view/provider/post-data-provider'
33
import { LocalState } from '@/ctx/local-state'
44
import { Uri } from 'vscode'
55

6+
const validFileExt = ['.md', '.html']
7+
const postIdInfileName = /\.(\d+)$/g
68
const validatePostFileMap = (map: PostFileMap) => map[0] >= 0 && map[1] !== ''
7-
89
export type PostFileMap = [postId: number, filePath: string]
9-
1010
const storageKey = 'postFileMaps'
1111

1212
function getMaps(): PostFileMap[] {
@@ -36,7 +36,6 @@ export namespace PostFileMapManager {
3636
}
3737

3838
export async function updateOrCreate(postId: number, filePath: string, { emitEvent = true } = {}) {
39-
const validFileExt = ['.md', '.html']
4039
if (filePath !== '' && !validFileExt.some(x => filePath.endsWith(x)))
4140
throw Error('Invalid filepath, file must have type markdown or html')
4241

@@ -72,9 +71,17 @@ export namespace PostFileMapManager {
7271
return path.startsWith('/') ? Uri.parse(path).fsPath : path
7372
}
7473

75-
export function getPostId(filePath: string) {
74+
export function getPostId(filePath: string): number | undefined {
7675
const map = findByFilePath(filePath)
77-
if (map === undefined) return
76+
if (map == null) return
7877
return map[0]
7978
}
79+
80+
export function extractPostId(fileNameWithoutExt: string): number | undefined {
81+
const match = postIdInfileName.exec(fileNameWithoutExt)
82+
console.log('match == null ? ' + (match == null))
83+
if (match == null) return
84+
console.log('match.length: ' + match.length)
85+
return Number(match[1])
86+
}
8087
}

0 commit comments

Comments
 (0)