Skip to content

Commit

Permalink
Pick daily leetcode problem (#66)
Browse files Browse the repository at this point in the history
* add graphql query for getting the Daily Problem

* add wrapper code in `cache` module for getting the Daily Problem id

* add --daily cli option for `pick` subcommand
  • Loading branch information
152334H authored May 17, 2022
1 parent 60a9e88 commit b00b252
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ impl Cache {
Ok(p)
}

/// Get daily problem
pub async fn get_daily_problem_id(&self) -> Result<i32, Error> {
parser::daily(
self.clone()
.0
.get_question_daily()
.await?
.json()
.await?
).ok_or(Error::NoneError)
}

/// Get problems from cache
pub fn get_problems(&self) -> Result<Vec<Problem>, Error> {
Ok(problems.load::<Problem>(&self.conn()?)?)
Expand Down
11 changes: 11 additions & 0 deletions src/cache/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ pub fn tags(v: Value) -> Option<Vec<String>> {
Some(res)
}

/// daily parser
pub fn daily(v: Value) -> Option<i32> {
trace!("Parse daily...");
v.as_object()?
.get("data")?.as_object()?
.get("activeDailyCodingChallengeQuestion")?.as_object()?
.get("question")?.as_object()?
.get("questionFrontendId")?.as_str()?
.parse().ok()
}

pub use ss::ssr;
/// string or squence
mod ss {
Expand Down
12 changes: 12 additions & 0 deletions src/cmds/pick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ impl Command for PickCommand {
.takes_value(true)
.help("Filter questions by tag"),
)
.arg(
Arg::with_name("daily")
.short("d")
.long("daily")
.takes_value(false)
.help("Pick today's daily challenge"),
)
}

/// `pick` handler
Expand Down Expand Up @@ -109,9 +116,14 @@ impl Command for PickCommand {
crate::helper::filter(&mut problems, query.to_string());
}

let daily_id = if m.is_present("daily") {
Some(cache.get_daily_problem_id().await?)
} else { None };

let fid = m
.value_of("id")
.and_then(|id| id.parse::<i32>().ok())
.or(daily_id)
.unwrap_or_else(|| {
// Pick random without specify id
let problem = &problems[rand::thread_rng().gen_range(0, problems.len())];
Expand Down
33 changes: 33 additions & 0 deletions src/plugins/leetcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,39 @@ impl LeetCode {
.await
}

/// Get daily problem
pub async fn get_question_daily(self) -> Result<Response, Error> {
trace!("Requesting daily problem...");
let url = &self.conf.sys.urls.get("graphql").ok_or(Error::NoneError)?;
let mut json: Json = HashMap::new();
json.insert("operationName", "daily".to_string());
json.insert(
"query",
vec![
"query daily {",
" activeDailyCodingChallengeQuestion {",
" question {",
" questionFrontendId",
" }",
" }",
"}",
]
.join("\n"),
);

Req {
default_headers: self.default_headers,
refer: None,
info: false,
json: Some(json),
mode: Mode::Post,
name: "get_question_daily",
url: (*url).to_string(),
}
.send(&self.client)
.await
}

/// Get specific problem detail
pub async fn get_question_detail(self, slug: &str) -> Result<Response, Error> {
trace!("Requesting {} detail...", &slug);
Expand Down

0 comments on commit b00b252

Please sign in to comment.