Compare commits

...

5 commits

6 changed files with 72 additions and 7 deletions

54
Cargo.lock generated
View file

@ -74,6 +74,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"reqwest", "reqwest",
"serde", "serde",
"time",
"tokio", "tokio",
] ]
@ -108,6 +109,16 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
"serde",
]
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
version = "0.8.34" version = "0.8.34"
@ -488,6 +499,12 @@ dependencies = [
"tempfile", "tempfile",
] ]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.4" version = "0.36.4"
@ -614,6 +631,12 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.86" version = "1.0.86"
@ -952,6 +975,37 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "time"
version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
"num-conv",
"time-core",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.8.0" version = "1.8.0"

View file

@ -7,3 +7,4 @@ edition = "2021"
reqwest = { version = "0.12.7", features = ["json"] } reqwest = { version = "0.12.7", features = ["json"] }
tokio = { version = "1.15", features = ["full"] } tokio = { version = "1.15", features = ["full"] }
serde = { version = "1.0.210", features = ["derive"] } serde = { version = "1.0.210", features = ["derive"] }
time = { version = "0.3.36", features = ["serde", "parsing", "formatting"] }

View file

@ -3,6 +3,10 @@
An alternative TUI-based frontend for the Canvas LMS. Also implements An alternative TUI-based frontend for the Canvas LMS. Also implements
`libcanvas`, a Rust library that wraps common Canvas API actions. `libcanvas`, a Rust library that wraps common Canvas API actions.
It is built for use by students/enrollees in courses, not instructors. There
are no plans to support features specifically for instructors, but feel free to
open a pull request to add them.
## Building ## Building
Install Nix with flakes. Install Nix with flakes.
@ -26,7 +30,7 @@ officially supported. Use the latest stable Rust toolchain. You must have
You can enter a development shell with all of the required dependencies You can enter a development shell with all of the required dependencies
(including `openssl`) with (including `openssl`) with
```bash ```sh
nix develop nix develop
``` ```

View file

@ -41,6 +41,7 @@
pkg-config pkg-config
openssl openssl
fenix.packages.${system}.stable.completeToolchain fenix.packages.${system}.stable.completeToolchain
cargo-audit
]; ];
}; };
packages = { packages = {

View file

@ -32,7 +32,8 @@ impl CanvasClient {
Ok(CanvasClient { client, api_url }) Ok(CanvasClient { client, api_url })
} }
/// Call an API endpoint. Expects the relative path of the endpoint after the base API URL. /// Call an API endpoint on the provided Canvas API with the authorization token. Expects the
/// relative path of the endpoint after the base API URL.
/// Returns the response as plaintext in a String regardless of its serialization format. /// Returns the response as plaintext in a String regardless of its serialization format.
/// ///
/// # Example /// # Example

View file

@ -1,7 +1,10 @@
use super::CanvasClient; use super::CanvasClient;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use time::serde::iso8601;
use time::OffsetDateTime;
impl CanvasClient { impl CanvasClient {
/// Get a list of courses the current user is enrolled in.
pub async fn get_courses(&self) -> Result<Vec<Course>, reqwest::Error> { pub async fn get_courses(&self) -> Result<Vec<Course>, reqwest::Error> {
let response = self let response = self
.client .client
@ -13,8 +16,6 @@ impl CanvasClient {
} }
} }
// Some time options are ISO 8601 standard times but they are parsed as Strings for now for
// simplicity
/// Represents a response from the `/courses` API endpoint. Some strings are plaintext and some are /// Represents a response from the `/courses` API endpoint. Some strings are plaintext and some are
/// HTML. Some JSON objects which have not yet been typed are deserialized into plaintext instead. /// HTML. Some JSON objects which have not yet been typed are deserialized into plaintext instead.
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
@ -23,10 +24,12 @@ pub struct Course {
pub name: String, pub name: String,
pub account_id: u32, pub account_id: u32,
pub uuid: String, pub uuid: String,
pub start_at: Option<String>, #[serde(with = "iso8601::option")]
pub start_at: Option<OffsetDateTime>,
pub grading_standard_id: Option<u32>, pub grading_standard_id: Option<u32>,
pub is_public: bool, pub is_public: bool,
pub created_at: String, #[serde(with = "iso8601")]
pub created_at: OffsetDateTime,
pub course_code: String, pub course_code: String,
pub default_view: Option<String>, pub default_view: Option<String>,
pub root_account_id: u32, pub root_account_id: u32,
@ -42,7 +45,8 @@ pub struct Course {
pub syllabus_body: Option<String>, pub syllabus_body: Option<String>,
pub needs_grading_count: Option<u32>, pub needs_grading_count: Option<u32>,
pub grade_passback_setting: Option<String>, pub grade_passback_setting: Option<String>,
pub end_at: Option<String>, #[serde(with = "iso8601::option")]
pub end_at: Option<OffsetDateTime>,
pub public_syllabus: bool, pub public_syllabus: bool,
pub public_syllabus_to_auth: bool, pub public_syllabus_to_auth: bool,
pub storage_quota_mb: usize, pub storage_quota_mb: usize,