@@ -14,6 +14,32 @@ import { DialogOptions, openUrl } from "./utils/uiUtils";
14
14
import * as wsl from "./utils/wslUtils" ;
15
15
import { toWslPath , useWsl } from "./utils/wslUtils" ;
16
16
17
+ interface IDescription {
18
+ title : string ;
19
+ url : string ;
20
+ tags : string [ ] ;
21
+ companies : string [ ] ;
22
+ category : string ;
23
+ difficulty : string ;
24
+ likes : string ;
25
+ dislikes : string ;
26
+ body : string ;
27
+ }
28
+
29
+ const promiseWithTimeout = ( promise , timeout ) => {
30
+ let timeoutId ;
31
+ const timeoutPromise = new Promise ( ( _ , reject ) => {
32
+ timeoutId = setTimeout ( ( ) => {
33
+ reject ( new Error ( `Operation timed out after ${ timeout } milliseconds` ) ) ;
34
+ } , timeout ) ;
35
+ } ) ;
36
+
37
+ return Promise . race ( [ promise , timeoutPromise ] ) . then ( ( result ) => {
38
+ clearTimeout ( timeoutId ) ;
39
+ return result ;
40
+ } ) ;
41
+ } ;
42
+
17
43
class LeetCodeExecutor implements Disposable {
18
44
private leetCodeRootPath : string ;
19
45
private nodeExecutable : string ;
@@ -100,6 +126,77 @@ class LeetCodeExecutor implements Disposable {
100
126
return await this . executeCommandEx ( this . nodeExecutable , cmd ) ;
101
127
}
102
128
129
+ private parseDescription ( descString : string , problem : IProblem ) : IDescription {
130
+ const [
131
+ /* title */ , ,
132
+ url , ,
133
+ /* tags */ , ,
134
+ /* langs */ , ,
135
+ category ,
136
+ difficulty ,
137
+ likes ,
138
+ dislikes ,
139
+ /* accepted */ ,
140
+ /* submissions */ ,
141
+ /* testcase */ , ,
142
+ ...body
143
+ ] = descString . split ( "\n" ) ;
144
+ return {
145
+ title : problem . name ,
146
+ url,
147
+ tags : problem . tags ,
148
+ companies : problem . companies ,
149
+ category : category . slice ( 2 ) ,
150
+ difficulty : difficulty . slice ( 2 ) ,
151
+ likes : likes . split ( ": " ) [ 1 ] . trim ( ) ,
152
+ dislikes : dislikes . split ( ": " ) [ 1 ] . trim ( ) ,
153
+ body : body . join ( "\n" ) . replace ( / < p r e > [ \r \n ] * ( [ ^ ] + ?) [ \r \n ] * < \/ p r e > / g, "<pre><code>$1</code></pre>" ) ,
154
+ } ;
155
+ }
156
+
157
+ public async showDocumentationInternal ( problemNode : IProblem , filePath : string ) : Promise < void > {
158
+
159
+ const descString : string = await this . getDescription ( problemNode . id , false ) ;
160
+ const description = this . parseDescription ( descString , problemNode ) ;
161
+ const { title, url, category, difficulty, likes, dislikes, body } = description ;
162
+
163
+ const head : string = `# [${ problemNode . id } . ${ title } ](${ url } )` ;
164
+ const info : string = [
165
+ `| Category | Difficulty | Likes | Dislikes |` ,
166
+ `| :------: | :--------: | :---: | :------: |` ,
167
+ `| ${ category } | ${ difficulty } | ${ likes } | ${ dislikes } |` ,
168
+ ] . join ( "\n" ) ;
169
+ const tags = "**Tags**: " + description . tags . join ( "," ) ;
170
+ const companies = "**Companies**: " + description . companies . join ( "," ) ;
171
+
172
+ const md_content = [
173
+ head ,
174
+ '' ,
175
+ "## Description" ,
176
+ '' ,
177
+ tags ,
178
+ '' ,
179
+ companies ,
180
+ '' ,
181
+ info ,
182
+ '' ,
183
+ body . replace ( / \t / g, " " ) ,
184
+ "## Solution\n" ,
185
+ "**题目描述**\n" ,
186
+ "**解题思路**\n" ,
187
+ ] . join ( "\n" ) ;
188
+
189
+ // console.log("md_content", md_content);
190
+
191
+ if ( ! await fse . pathExists ( filePath ) ) {
192
+ await fse . createFile ( filePath ) ;
193
+ await fse . writeFile ( filePath , md_content ) ;
194
+ workspace . openTextDocument ( filePath ) . then ( ( document ) => {
195
+ window . showTextDocument ( document ) ;
196
+ } ) ;
197
+ }
198
+ }
199
+
103
200
public async showProblem ( problemNode : IProblem , language : string , filePath : string , showDescriptionInComment : boolean = false , needTranslation : boolean ) : Promise < void > {
104
201
const templateType : string = showDescriptionInComment ? "-cx" : "-c" ;
105
202
const cmd : string [ ] = [ await this . getLeetCodeBinaryPath ( ) , "show" , problemNode . id , templateType , "-l" , language ] ;
@@ -164,7 +261,8 @@ class LeetCodeExecutor implements Disposable {
164
261
165
262
public async submitSolution ( filePath : string ) : Promise < string > {
166
263
try {
167
- return await this . executeCommandWithProgressEx ( "Submitting to LeetCode..." , this . nodeExecutable , [ await this . getLeetCodeBinaryPath ( ) , "submit" , `"${ filePath } "` ] ) ;
264
+ return promiseWithTimeout ( this . executeCommandWithProgressEx ( "Submitting to LeetCode..." , this . nodeExecutable , [ await this . getLeetCodeBinaryPath ( ) , "submit" , `"${ filePath } "` ] ) , 10000 ) ;
265
+ // return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "submit", `"${filePath}"`]);
168
266
} catch ( error ) {
169
267
if ( error . result ) {
170
268
return error . result ;
@@ -175,9 +273,11 @@ class LeetCodeExecutor implements Disposable {
175
273
176
274
public async testSolution ( filePath : string , testString ?: string ) : Promise < string > {
177
275
if ( testString ) {
178
- return await this . executeCommandWithProgressEx ( "Submitting to LeetCode..." , this . nodeExecutable , [ await this . getLeetCodeBinaryPath ( ) , "test" , `"${ filePath } "` , "-t" , `${ testString } ` ] ) ;
276
+ return promiseWithTimeout ( this . executeCommandWithProgressEx ( "Submitting to LeetCode..." , this . nodeExecutable , [ await this . getLeetCodeBinaryPath ( ) , "test" , `"${ filePath } "` , "-t" , `${ testString } ` ] ) , 10000 ) ;
277
+ // return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-t", `${testString}`]);
179
278
}
180
- return await this . executeCommandWithProgressEx ( "Submitting to LeetCode..." , this . nodeExecutable , [ await this . getLeetCodeBinaryPath ( ) , "test" , `"${ filePath } "` ] ) ;
279
+ return promiseWithTimeout ( this . executeCommandWithProgressEx ( "Submitting to LeetCode..." , this . nodeExecutable , [ await this . getLeetCodeBinaryPath ( ) , "test" , `"${ filePath } "` ] ) , 10000 ) ;
280
+ // return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`]);
181
281
}
182
282
183
283
public async switchEndpoint ( endpoint : string ) : Promise < string > {
0 commit comments