Skip to content

Commit 898328f

Browse files
committed
added code pack to directory feature
1 parent a4b6a65 commit 898328f

File tree

4 files changed

+94
-30
lines changed

4 files changed

+94
-30
lines changed

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ leetcode-runner-cli [FLAGS] [OPTIONS <option>]
5555
| `-rt, run-custom` | Execute file with custom testcases | [testcase_file] [file_to_run] |
5656
| `-s, submit` | Submit solution to leetcode after passing testcases | [file_to_submit] |
5757
| `-fs, fast-submit` | Submit solution to leetcode | [file_to_submit] |
58+
| `-p, pack` | Pack your solution and question in a directory | [file_to_consider] |
5859
5960
### File changes
6061
@@ -104,27 +105,33 @@ fn main() {
104105
- Run src/main.rs with default testcases for question [koko-eating-bananas](https://leetcode.com/problems/koko-eating-bananas/)
105106

106107
```bash
107-
leetcode-runner-cli -r ./src/main.rs
108+
leetcode-runner-cli -r /src/main.rs
108109
```
109110

110111
- Run src/main.rs with custom testcase file
111112

112113
```bash
113-
leetcode-runner-cli -rt ./testcase.txt ./src/main.rs
114+
leetcode-runner-cli -rt testcase.txt /src/main.rs
114115
```
115116

116117
- Submit src/main.rs to leetcode
117118

118119
```bash
119-
leetcode-runner-cli -s ./src/main.rs
120+
leetcode-runner-cli -s /src/main.rs
120121
```
121122

122123
Note : This will first execute the default testcases and then submit the solution to leetcode only if the testcases pass as a preventive measure to avoid submitting wrong solution.
123124

124125
- Submit src/main.rs to leetcode without running testcases
125126

126127
```bash
127-
leetcode-runner-cli -fs ./src/main.rs
128+
leetcode-runner-cli -fs /src/main.rs
129+
```
130+
131+
- Pack your code and question into a directory to maintain your progress or upload on Git
132+
133+
```bash
134+
leetcode-runner-cli -p /src/main.rs
128135
```
129136

130137
#### Note
@@ -139,6 +146,7 @@ So, in the above examples, you can simply do `cd ./src` and then run the followi
139146
- Execute with default testcases : `leetcode-runner-cli -r`
140147
- Submit : `leetcode-runner-cli -s`
141148
- Submit without running testcases : `leetcode-runner-cli -fs`
149+
- Pack code : `leetcode-runner-cli -p`
142150
143151
---
144152

src/args.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ pub enum Commands {
5252
/// Save today's daily challenge as HTML
5353
#[command(visible_alias = "-d")]
5454
DailyChallenge,
55+
/// Packs the solution with the question into a directory
56+
#[command(visible_alias = "-p")]
57+
Pack {
58+
/// File to pack
59+
file: Option<PathBuf>,
60+
},
5561
}
5662

5763
#[derive(Subcommand)]

src/handlers/leetcode/api/question.rs

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use crate::handlers::leetcode::*;
22

3+
use colored::Colorize;
34
use eyre::{bail, Context, Result};
45

6+
const GRAPHQL_URL: &str = "https://leetcode.com/graphql";
7+
58
impl LeetCode<Authorized> {
69
pub fn get_daily_challenge(&self) -> Result<DailyChallenge> {
7-
let url = "https://leetcode.com/graphql";
810
let client = &self.client;
911
let query = GraphqlRequest {
1012
query: r#"
@@ -38,7 +40,7 @@ impl LeetCode<Authorized> {
3840
variables: "{}".to_string(),
3941
};
4042

41-
let data = client.post(url).json(&query).send()?;
43+
let data = client.post(GRAPHQL_URL).json(&query).send()?;
4244

4345
// println!("{:?}", data.text());
4446
// todo!();
@@ -77,7 +79,6 @@ impl LeetCode<Authorized> {
7779

7880
pub fn question_content(&self, title_slug: &str) -> Result<LeetcodeQuestion> {
7981
let client = &self.client;
80-
let url = "https://leetcode.com/graphql";
8182
let query = GraphqlRequest {
8283
query: r#"
8384
query questionContent($titleSlug: String!) {
@@ -92,7 +93,7 @@ impl LeetCode<Authorized> {
9293
})?,
9394
};
9495

95-
let data = client.post(url).json(&query).send()?;
96+
let data = client.post(GRAPHQL_URL).json(&query).send()?;
9697

9798
#[derive(Deserialize)]
9899
struct QuestionWrapper {
@@ -103,29 +104,33 @@ impl LeetCode<Authorized> {
103104
data: QuestionWrapper,
104105
}
105106

107+
Ok(data.json::<Data>().map(|op| op.data.question)?)
108+
}
109+
pub fn save_boiler_code(&self, title_slug: &str) -> Result<()> {
110+
let client = &self.client;
106111
let query = r#"
107-
query questionEditorData($titleSlug: String!) {
108-
question(titleSlug: $titleSlug) {
109-
questionId
110-
questionFrontendId
111-
codeSnippets {
112-
lang
113-
langSlug
114-
code
112+
query questionEditorData($titleSlug: String!) {
113+
question(titleSlug: $titleSlug) {
114+
questionId
115+
questionFrontendId
116+
codeSnippets {
117+
lang
118+
langSlug
119+
code
120+
}
121+
envInfo
122+
enableRunCode
115123
}
116-
envInfo
117-
enableRunCode
118124
}
119-
}
120125
"#;
121-
let varibales = serde_json::to_string(&Variables {
126+
let variables = serde_json::to_string(&Variables {
122127
titleSlug: title_slug.to_string(),
123128
})?;
124129
let boiler_code = client
125-
.post(url)
130+
.post(GRAPHQL_URL)
126131
.json(&GraphqlRequest {
127132
query: query.to_string(),
128-
variables: varibales,
133+
variables,
129134
})
130135
.send()?;
131136

@@ -142,27 +147,30 @@ impl LeetCode<Authorized> {
142147
struct Wrapper {
143148
data: WrapperData,
144149
}
145-
146150
let boiler_code_vector = boiler_code.json::<Wrapper>()?.data.question.codeSnippets;
147151

148152
let mut boiler_code_vector = boiler_code_vector
149153
.into_iter()
150154
.filter(|code| code.is_supported())
151155
.collect::<Vec<_>>();
152156

153-
// ask user to specify language among these options without using external lib
157+
// ask user to specify language among these options
154158
let boiler_code = match boiler_code_vector.len() {
155159
0 => bail!("No boiler plate code available in supported language!"),
156160
1 => boiler_code_vector.swap_remove(0),
157161
_ => {
158162
let mut input = String::new();
159-
println!("\nPlease select a language from the following options :");
163+
println!(
164+
"{}",
165+
"\nPlease select a language from the following options :".yellow()
166+
);
160167
for (i, code) in boiler_code_vector.iter().enumerate() {
161168
println!("{}: {}", i, code.langSlug);
162169
}
163170
println!(
164171
"\nFor example : Input \"{}\" for {}",
165-
0, &boiler_code_vector[0].langSlug
172+
"0".cyan(),
173+
&boiler_code_vector[0].langSlug.cyan()
166174
);
167175
std::io::stdin().read_line(&mut input)?;
168176
let input = input.trim().parse::<usize>()?;
@@ -180,13 +188,11 @@ impl LeetCode<Authorized> {
180188
input.to_string()
181189
};
182190
boiler_code.save_code(&filename, &title_slug)?;
183-
184-
Ok(data.json::<Data>().map(|op| op.data.question)?)
191+
Ok(())
185192
}
186193

187194
pub fn question_metadata(&self, title_slug: &str) -> Result<Question> {
188195
let client = &self.client;
189-
let url = "https://leetcode.com/graphql";
190196

191197
let query = GraphqlRequest {
192198
query: r#"
@@ -210,7 +216,7 @@ impl LeetCode<Authorized> {
210216
})?,
211217
};
212218
let data = client
213-
.post(url)
219+
.post(GRAPHQL_URL)
214220
.json(&query)
215221
.send()
216222
.wrap_err("Failed to fetch question id from LeetCode")?;

src/main.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ mod handlers;
1414
mod utils;
1515

1616
const LC_COOKIE_ENV_KEY: &str = "LC_COOKIE";
17+
const GIT_README: &str = "README.md";
1718

1819
fn main() -> Result<()> {
1920
let cli = Cli::parse();
@@ -35,6 +36,7 @@ fn main() -> Result<()> {
3536
println!("Today's Daily Challenge:\n{}", daily_challenge);
3637
let title = daily_challenge.question.titleSlug;
3738
let question = lc.question_content(&title)?;
39+
lc.save_boiler_code(&title)?;
3840

3941
let filename = "daily_challenge.html";
4042
std::fs::write(filename, question.content)?;
@@ -56,6 +58,7 @@ fn main() -> Result<()> {
5658
&question_name
5759
};
5860
let question = lc.question_content(question_name)?;
61+
lc.save_boiler_code(question_name)?;
5962
let filename = format!("{}.html", question_name);
6063

6164
// save to filename
@@ -87,6 +90,47 @@ fn main() -> Result<()> {
8790
bail!("Aborting submission due to failed testcase(s)".red().bold());
8891
}
8992
}
93+
Some(Commands::Pack { file }) => {
94+
let code_file = if let Some(path) = file {
95+
CodeFile::from_file(&path)?
96+
} else {
97+
CodeFile::from_dir(".")?
98+
};
99+
let question = lc.question_content(&code_file.question_title)?;
100+
101+
// create a directory if it doesn't exists with name of question
102+
// create a README.md file with the question description
103+
// create a file with the code
104+
std::fs::create_dir_all(&code_file.question_title.replace(' ', ""))?;
105+
106+
std::fs::write(
107+
format!(
108+
"{}/main.{}",
109+
&code_file.question_title,
110+
code_file.language.extension()
111+
),
112+
code_file.code,
113+
)?;
114+
115+
// dont create readme if it exists
116+
if let Ok(mut readme_file) = std::fs::OpenOptions::new()
117+
.create_new(true)
118+
.write(true)
119+
.open(format!("{}/{}", &code_file.question_title, GIT_README))
120+
{
121+
println!(
122+
"You can write your notes about question in {}/README.md",
123+
&code_file.question_title
124+
);
125+
std::io::Write::write_all(
126+
&mut readme_file,
127+
format!("# {}\n", code_file.question_title).as_bytes(),
128+
)?;
129+
std::io::Write::write_all(&mut readme_file, question.content.as_bytes())?;
130+
} else {
131+
println!("{} already exists, skipping creation.", GIT_README);
132+
};
133+
}
90134
None => {}
91135
};
92136

0 commit comments

Comments
 (0)