Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Description: R API client for the 'Redmine' project management system.
URL: https://github.com/openanalytics/redmineR, http://www.redmine.org/projects/redmine/wiki/Rest_api
License: GPL-3 + file LICENSE
RoxygenNote: 6.1.1
Imports: httr, jsonlite, mime
Imports: httr, jsonlite, mime, tidyr
Suggests: knitr
VignetteBuilder: knitr
Encoding: UTF-8
74 changes: 41 additions & 33 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -1,100 +1,108 @@
##
##

removeNULL <- function(x) {
x[!sapply(x, is.null)]
}

redmine_get_all_pages <- function(endpoint, query = NULL, maxLimit = 100) {

nameEndpoint <- gsub(".*/([^/.]*).*$", "\\1", endpoint)
limit <- maxLimit
offset <- 0
pageQuery <- paste0("limit=", limit, "&offset=", offset, "&", query)

res <- redmine_get(endpoint = endpoint, query = pageQuery)
resList <- res$content[[nameEndpoint]]

N <- res$content$total_count

if (!is.null(N) && N > limit) {

offsets <- seq(from = limit, to = N, by = limit)

for (iPage in seq_along(offsets)) {
pageQuery <- paste0("limit=", limit, "&offset=", offsets[iPage], "&", query)
res <- redmine_get(endpoint = endpoint, query = pageQuery)
resList <- c(resList, res$content[[nameEndpoint]])
}
}

# implement 'fill' manually
allNames <- Reduce(union, lapply(resList, function(x) names(x)))
allNames <- Reduce(union, lapply(resList, function(x) names(x)))

vectors <- lapply(resList, function(x) {
res <- x
namesToAdd <- setdiff(allNames, names(res))
res[namesToAdd] <- NA
res[allNames]
})

res_df <- as.data.frame(do.call(rbind, vectors), stringsAsFactors = FALSE)

# unlist columns that are actually atomic
atomicCols <- names(res_df)[vapply(res_df, function(col) !is.list(col) || !is.list(unlist(col, recursive = F)), logical(1))]
res_df[atomicCols] <- lapply(res_df[atomicCols], unlist)
# atomicCols <- names(res_df)[vapply(res_df, function(col) !is.list(col) || !is.list(unlist(col, recursive = F)), logical(1))]
# res_df[atomicCols] <- lapply(res_df[atomicCols], unlist)

getNonAtomicCols <- function(df) names(df)[!vapply(df, function(col) !is.list(col) || !is.list(unlist(col, recursive = F)), logical(1))]

res_df <- res_df %>%
tidyr::unnest_wider(col = all_of(getNonAtomicCols(.)), names_sep = "_") %>%
tidyr::unnest_wider(col = all_of(getNonAtomicCols(.)), names_sep = "_")

res_df <- as.data.frame(res_df)

attr(res_df, "endpoint") <- endpoint
attr(res_df, "query") <- query
class(res_df) <- append("redminer_df", class(res_df))

res_df

}

#' @export
print.redminer_df <- function(x, cut = 20, ...) {
if (!is.null(x$description) && is.character(x$description))
if ('description' %in% names(x) && !is.null(x$description) && is.character(x$description))
x$description <- ifelse(nchar(x$description) > cut,
paste0(substr(x$description, 1, cut), " ..."), x$description)
# TODO: show list columns nicer

# TODO: show list columns nicer
listCols <- names(x)[vapply(x, is.list, logical(1))]
# print.data.frame(x[, grep("\\.id$", names(x), value = TRUE, invert = TRUE)])

cat("redmineR listing",
if (!is.null(attr(x, "endpoint"))) paste0(" for '", attr(x, "endpoint"), "'"),
if (!is.null(attr(x, "endpoint"))) paste0(" for '", attr(x, "endpoint"), "'"),
if (!is.null(attr(x, "query"))) paste0(" [query = ", attr(x, "query"), "]"),
":\n", sep = "")

print.data.frame(x)
}


#' Search id by name
#'
#' Search happens inside the 'subject' field for issues and 'name' for other
#'
#' Search happens inside the 'subject' field for issues and 'name' for other
#' endpoints.
#' @param name string to search for
#' @param endpoint endpoint where to search ("projects", "issues", ...)
#' @param query extra query arguments
#' @return id(s) found invisibly, in addition summary of search results is
#' printed
#'
#' @param query extra query arguments
#' @return id(s) found invisibly, in addition summary of search results is
#' printed
#'
#' @author Maxim Nazarov
#' @export
redmine_search_id <- function(name = NULL, endpoint = "projects", query = NULL) {
enumerations <- c("issue_priorities", "time_entry_activities",

enumerations <- c("issue_priorities", "time_entry_activities",
"document_categories")
if (endpoint %in% enumerations)
endpoint <- paste0("enumerations/", endpoint)

res <- redmine_get_all_pages(endpoint = endpoint, query = query)

colSearch <- if (endpoint == "issues") "subject" else "name"
ans <- if (!is.null(name))
ans <- if (!is.null(name))
res[grepl(name, res[[colSearch]], ignore.case = TRUE), ] else res

if (nrow(ans) == 0)
stop("No id found")
print(ans)
Expand Down