Skip to content

Commit

Permalink
Merge pull request #40 from mpadge/fs
Browse files Browse the repository at this point in the history
Use fs for file path manipulations; closes #38
  • Loading branch information
polettif authored Oct 11, 2024
2 parents b8403b3 + cd0381f commit f2620a0
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 48 deletions.
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ URL: https://r-transit.github.io/gtfsio/,
BugReports: https://github.com/r-transit/gtfsio/issues
Imports:
data.table,
fs,
utils,
zip,
jsonlite
Expand All @@ -51,7 +52,7 @@ VignetteBuilder:
knitr
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2
Collate:
'gtfsio_error.R'
'assert_gtfs.R'
Expand All @@ -65,6 +66,7 @@ Collate:
'gtfsio.R'
'import_gtfs.R'
'new_gtfs.R'
'utils.R'
LazyData: true
Depends:
R (>= 3.1.0)
22 changes: 13 additions & 9 deletions R/export_gtfs.R
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ export_gtfs <- function(gtfs,

# input checks that depend on more than one argument

if (file.exists(path) & !overwrite) error_cannot_overwrite()
if (!as_dir & !grepl("\\.zip$", path)) error_ext_must_be_zip()
if (as_dir & grepl("\\.zip$", path)) error_path_must_be_dir()
if (fs::file_exists(path) & !overwrite) error_cannot_overwrite()
if (!as_dir & !has_file_ext(path, "zip")) error_ext_must_be_zip()
if (as_dir & has_file_ext(path, "zip")) error_path_must_be_dir()

extra_files <- setdiff(files, names(gtfsio::gtfs_reference))
if (standard_only & !is.null(files) & !identical(extra_files, character(0))) {
Expand Down Expand Up @@ -107,18 +107,20 @@ export_gtfs <- function(gtfs,
if (as_dir) {
tmpd <- path
} else {
tmpd <- tempfile(pattern = "gtfsio")
tmpd <- fs::file_temp(pattern = "gtfsio")
}

unlink(tmpd, recursive = TRUE)
dir.create(tmpd)
if (fs::dir_exists(tmpd)) {
fs::dir_delete(tmpd)
}
fs::dir_create(tmpd, recurse = TRUE)

# write files to 'tmpd'

if (!quiet) message("Writing text files to ", tmpd)

filenames <- append_file_ext(files)
filepaths <- file.path(tmpd, filenames)
filepaths <- fs::path(tmpd, filenames)

for (i in seq_along(files)) {

Expand All @@ -130,7 +132,7 @@ export_gtfs <- function(gtfs,

dt <- gtfs[[file]]

if(endsWith(filename, ".geojson")) {
if (has_file_ext(filename, "geojson")) {
jsonlite::write_json(dt, filepath, pretty = FALSE, auto_unbox = TRUE, digits = 8)
} else {

Expand Down Expand Up @@ -165,7 +167,9 @@ export_gtfs <- function(gtfs,

if (!as_dir) {

unlink(path, recursive = TRUE)
if (fs::dir_exists(path)) {
fs::dir_delete(path)
}

zip::zip(
path,
Expand Down
51 changes: 13 additions & 38 deletions R/import_gtfs.R
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ import_gtfs <- function(path,

path_is_url <- grepl("^http[s]?\\:\\/\\/\\.*", path)

if (!path_is_url && !file.exists(path)) error_non_existent_file(path)
if (!path_is_url && !fs::file_exists(path)) error_non_existent_file(path)
if (!is.null(files) && !is.null(skip)) error_files_and_skip_provided()

for (input_types in extra_spec) {
Expand All @@ -98,7 +98,7 @@ import_gtfs <- function(path,
# if 'path' is an URL, download it and save path to downloaded file to 'path'

if (path_is_url) {
tmp <- tempfile(pattern = "gtfs", fileext = ".zip")
tmp <- fs::file_temp(pattern = "gtfs", ext = ".zip")
utils::download.file(path, tmp, method = "auto", quiet = quiet)

if (!quiet) message("File downloaded to ", tmp, ".")
Expand All @@ -117,7 +117,7 @@ import_gtfs <- function(path,
)
if (inherits(filenames_in_gtfs, "error")) error_path_must_be_zip()

non_standard_file_ext <- filenames_in_gtfs[!(grepl("\\.txt$", filenames_in_gtfs) | grepl("\\.geojson$", filenames_in_gtfs))]
non_standard_file_ext <- filenames_in_gtfs[!(has_file_ext(filenames_in_gtfs, "txt") | has_file_ext(filenames_in_gtfs, "geojson"))]

if (!identical(non_standard_file_ext, character(0))) {
warning(
Expand Down Expand Up @@ -159,8 +159,10 @@ import_gtfs <- function(path,
# extract text files to temporary folder to later read them
# 'unlink()' makes sure that previous imports don't interfere with current one

tmpdir <- file.path(tempdir(), "gtfsio")
unlink(tmpdir, recursive = TRUE, force = TRUE)
tmpdir <- fs::path(fs::path_temp(), "gtfsio")
if (fs::dir_exists(tmpdir)) {
fs::dir_delete(tmpdir)
}

zip::unzip(
path,
Expand Down Expand Up @@ -190,12 +192,7 @@ import_gtfs <- function(path,
# assign names to 'gtfs', noting that zip_list may return full paths, which
# need to be stripped here

file_names <- vapply(
filenames_to_read,
function(i) utils::tail(strsplit(i, .Platform$file.sep)[[1]], 1),
character(1),
USE.NAMES = FALSE
)
file_names <- basename(filenames_to_read)

names(gtfs) <- remove_file_ext(file_names)

Expand Down Expand Up @@ -241,19 +238,17 @@ read_files <- function(file,
encoding) {

# create object to hold the file with '.txt' extension
stopifnot(length(file) == 1L)

filename <- file
file_type <- "txt" # TODO get file ext as function
if(grepl("\\.geojson$", file)) {
file_type <- "geojson"
}
file_type <- ifelse(has_file_ext(file, "txt"), "txt", "geojson")
file <- remove_file_ext(file)

if (!quiet) message("Reading ", file)

# read geojson and return
if (file_type == "geojson") {
return(read_geojson(file.path(tmpdir, filename)))
return(read_geojson(fs::path(tmpdir, filename)))
}

# get standards for reading and fields to be read from the given 'file'
Expand Down Expand Up @@ -283,7 +278,7 @@ read_files <- function(file,
withCallingHandlers(
{
sample_dt <- data.table::fread(
file.path(tmpdir, filename),
fs::path(tmpdir, filename),
nrows = 1,
colClasses = "character"
)
Expand Down Expand Up @@ -357,7 +352,7 @@ read_files <- function(file,
withCallingHandlers(
{
full_dt <- data.table::fread(
file.path(tmpdir, filename),
fs::path(tmpdir, filename),
select = fields_classes,
encoding = encoding
)
Expand All @@ -379,26 +374,6 @@ read_geojson <- function(file.geojson) {
read_json(file.geojson)
}

remove_file_ext = function(file) {
tools::file_path_sans_ext(file)
}

append_file_ext = function(file) {
vapply(file, function(.f) {
file_ext <- gtfsio::gtfs_reference[[remove_file_ext(.f)]][["file_ext"]]
if (is.null(file_ext)) {
# use default for argument-specified non-standard files,
# behaviour defined in test_import_gtfs.R#292
file_ext <- "txt"
}
if(endsWith(.f, paste0(".", file_ext))) {
return(.f) # file extension already present
} else {
return(paste0(.f, ".", file_ext))
}
}, ".txt", USE.NAMES = FALSE)
}

# errors ------------------------------------------------------------------


Expand Down
31 changes: 31 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
remove_file_ext = function(file) {
fs::path_ext_remove(file)
}

append_file_ext = function(file) {
vapply(file, function(.f) {
file_ext <- gtfsio::gtfs_reference[[remove_file_ext(.f)]][["file_ext"]]
if (is.null(file_ext)) {
# use default for argument-specified non-standard files,
# behaviour defined in test_import_gtfs.R#292
file_ext <- "txt"
}
if (!has_file_ext(.f, file_ext)) {
.f <- fs::path_ext_set(.f, file_ext)
}
return(.f)
}, ".txt", USE.NAMES = FALSE)
}

#' Vectorized assertion of path extensions
#'
#' @param path Vector of file paths
#' @param ext File extension to be asserted for each `path`
#'
#' @return Logical vector of same length as `path`, with `TRUE` for each element
#' with specified extension, `FALSE` otherwise.
#'
#' @noRd
has_file_ext <- function(path, ext = "zip") {
fs::path_ext(path) == ext
}

0 comments on commit f2620a0

Please sign in to comment.