diff --git a/src/cache/mod.rs b/src/cache/mod.rs index 5c15277..a0f862b 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -93,6 +93,18 @@ impl Cache { Ok(p) } + /// Get daily problem + pub async fn get_daily_problem_id(&self) -> Result { + 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, Error> { Ok(problems.load::(&self.conn()?)?) diff --git a/src/cache/parser.rs b/src/cache/parser.rs index 5a6f521..f60476d 100644 --- a/src/cache/parser.rs +++ b/src/cache/parser.rs @@ -77,6 +77,17 @@ pub fn tags(v: Value) -> Option> { Some(res) } +/// daily parser +pub fn daily(v: Value) -> Option { + 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 { diff --git a/src/cmds/pick.rs b/src/cmds/pick.rs index 4771733..79d2751 100644 --- a/src/cmds/pick.rs +++ b/src/cmds/pick.rs @@ -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 @@ -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::().ok()) + .or(daily_id) .unwrap_or_else(|| { // Pick random without specify id let problem = &problems[rand::thread_rng().gen_range(0, problems.len())]; diff --git a/src/plugins/leetcode.rs b/src/plugins/leetcode.rs index 7143d6c..d98f4a8 100644 --- a/src/plugins/leetcode.rs +++ b/src/plugins/leetcode.rs @@ -121,6 +121,39 @@ impl LeetCode { .await } + /// Get daily problem + pub async fn get_question_daily(self) -> Result { + 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 { trace!("Requesting {} detail...", &slug);