Skip to content

Commit

Permalink
PR to address #51 (#57)
Browse files Browse the repository at this point in the history
* My ad-hoc fixes to get_course_gradebook.R

* Updated documentation

* Added HEAD to @importFrom for canvas_query

* Update NAMESPACE

Co-authored-by: rmtrane <[email protected]>
  • Loading branch information
dhicks and rmtrane authored Apr 27, 2021
1 parent 623b3a8 commit 805a5bd
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 30 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export(update_wpage)
export(upload_assignment_file)
export(upload_course_file)
importFrom(httr,GET)
importFrom(httr,HEAD)
importFrom(httr,POST)
importFrom(httr,PUT)
importFrom(magrittr,"%>%")
Expand Down
12 changes: 10 additions & 2 deletions R/get_course_gradebook.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,28 @@
#' @importFrom magrittr %>%
#'
#' @param course_id A valid course id
#' @param progress logical; print page numbers as we go? (Defaults to FALSE)
#'
#' @return A gradebook (in long format)
#'
#' @examples
#' get_course_gradebook(20)
#'
#' @export
get_course_gradebook <- function(course_id) {
get_course_gradebook <- function(course_id, progress = FALSE) {
course_assignments <- get_course_items(course_id, "assignments")

students <- get_course_items(course_id, "enrollments") %>%
dplyr::select(user.name, user_id, grades.final_score, course_id)
dplyr::filter(role == "StudentEnrollment", user.name != "Test Student") %>%
dplyr::select(user.name, user_id, grades.final_score, course_id) %>%
unique()

n_pages <- ceiling(nrow(students)/100)

gradebook <- purrr::map_df(seq_len(n_pages), function(page) {
if(progress)
cat(page, "of", n_pages, "\n")

submissions <- purrr::pmap_dfr(list(course_id, course_assignments$id, page),
get_assignment_submissions)
gradebook_page <- dplyr::left_join(submissions, students, by = "user_id") %>%
Expand Down
67 changes: 42 additions & 25 deletions R/process_response.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ process_response <- function(url, args) {

resp <- canvas_query(url, args, "GET")

paginate(resp) %>%
d <- paginate(resp) %>%
purrr::map(httr::content, "text") %>%
purrr::map(jsonlite::fromJSON, flatten = TRUE) ->
d
purrr::map(jsonlite::fromJSON, flatten = TRUE)

# flatten to data.frame if able, otherwise return as is
d <- tryCatch(purrr::map_df(d, purrr::flatten_df),
error = function(e) d)
d
#d <- tryCatch(purrr::map_df(d, purrr::flatten_df),
# error = function(e) d)
dplyr::bind_rows(d)
}

#' Get responses from Canvas API pages
Expand Down Expand Up @@ -52,38 +51,56 @@ paginate <- function(x, showProgress=T) {
first_response <- list(x)
stopifnot(httr::status_code(x) == 200) # OK status
pages <- httr::headers(x)$link

if (is.null(pages)) return(first_response)

should_continue <- TRUE
inc <- 2

if (has_rel(pages, "last")) {
last_page <- get_page(x, "last")
n_pages <- readr::parse_number(stringr::str_extract(last_page, "page=[0-9]{1,}"))
if (n_pages == 1) return(first_response)

if (n_pages == 1){
return(first_response)
}

pages <- increment_pages(last_page, 2:n_pages)
if (showProgress) bar = txtProgressBar(max=n_pages, style = 3)
if (showProgress){
bar = txtProgressBar(max=n_pages, style = 3)
}

queryfunc = function(...) {if (showProgress) bar$up(bar$getVal()+1); canvas_query(...)}
responses <- pages %>%
purrr::map(queryfunc, args = list(access_token = check_token()))
responses <- c(first_response, responses)

return(responses)
} else if (has_rel(httr::headers(x)$link, "next")) {
# edge case for if there is no 'last' header, see:
# https://canvas.instructure.com/doc/api/file.pagination.html
# https://github.com/daranzolin/rcanvas/issues/4
while (should_continue) {
page_temp <- get_page(x, "next")
pages[[inc]] <- page_temp
x <- canvas_query(page_temp,
args = list(access_token = check_token()),
type = "HEAD")
if (!has_rel(httr::headers(x)$link, "next")) {
should_continue <- FALSE
} else {
inc <- inc + 1
} else {
if (has_rel(httr::headers(x)$link, "next")) {
pages[[1]] <- get_page(x, "current")

inc <- 2

# edge case for if there is no 'last' header, see:
# https://canvas.instructure.com/doc/api/file.pagination.html
# https://github.com/daranzolin/rcanvas/issues/4
while (should_continue) {
page_temp <- get_page(x, "next")
pages[[inc]] <- page_temp
x <- canvas_query(page_temp,
args = list(access_token = check_token()),
type = "HEAD")
if (!has_rel(httr::headers(x)$link, "next")) {
should_continue <- FALSE
} else {
inc <- inc + 1
}
}


responses <- pages %>%
purrr::map(canvas_query, args = list(access_token = check_token()))
}
responses <- pages %>%
purrr::map(canvas_query, args = list(access_token = check_token()))
}
}

Expand Down
2 changes: 1 addition & 1 deletion R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ canvas_url <- function() paste0(get("rcanvas_CANVAS_DOMAIN", envir = cdenv), "/a

make_canvas_url <- function(...) paste(canvas_url(), ..., sep = "/")

#' @importFrom httr GET POST PUT
#' @importFrom httr GET POST PUT HEAD
canvas_query <- function(urlx, args = NULL, type = "GET") {

args <- sc(args)
Expand Down
4 changes: 3 additions & 1 deletion man/get_course_gradebook.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/rcanvas.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 805a5bd

Please sign in to comment.