### ----------------------------------------------------------------- ###
### FILE ----
### ----------------------------------------------------------------- ###
# APIS ----
#' Write note into disk
#' @noRd
writeNoteIntoDisk <- function(note, file, type = "json") {
stopifnot(isNote(note))
writeLines(note, file)
invisible(NULL)
}
#' Read note from notes folder
#'
#' Does not read malformed note files.
#'
#' @param note file name or hash (as relative).
#' @details
#' Input argument can either be provided as a json path or just the name of path
#' without json extension.
#' @importFrom jsonlite fromJSON
#' @export
readNote <- function(note) {
stopifnot(is.character(note))
stopifnot(length(note) == 1L)
if (!grepl("\\.json$", note)) {
note.sans.ext <- note
note.avec.ext <- paste(note, ".json", sep = "")
} else {
note.sans.ext <- tools::file_path_sans_ext(note)
note.avec.ext <- note
}
if (!is_note_exist(note.avec.ext)) {
event_message(
paste(
"Note cannot be found!",
"This message appears if you deleted it from the system.",
sep = "\n"
)
)
return()
}
dir <- get_notes_folder_path()
path <- file.path(dir, note.avec.ext)
read.note <- readLines(path)
if (!length(read.note) >= 1) {
stop("cannot read empty note", call. = FALSE)
}
read.json.note <- jsonlite::fromJSON(read.note)
## validate note that has valid fields:
valid <- names(read.json.note) %in% c("dateCreated", "title", "content", "isStarred", "isArchived")
if (!all(valid)) {
stop(
paste(
"cannot read note with malformed fields:",
paste(paste0("\"", names(read.json.note)[!valid], "\""), collapse = ", ")
),
call. = FALSE)
}
read.json.note
}
#' Write a new note
#'
#' @param title Title of the note.
#' @param content Note content.
#'
#' @export
new_note <- function(title, content) {
dir <- get_notes_folder_path()
if (!dir.exists(dir)) {
stop(paste(
"\nFolder to keep notes not exists.",
"Please run `create_notes_folder()` first.",
sep = "\n"
))
}
note <- create_note(title, content)
file <- create_note_file()
writeNoteIntoDisk(note, file)
event_message("A new note created: ", file)
invisible(NULL)
}
#' Create a note
create_note <- function(title, content) {
## input validation:
inputs <- list(title, content)
stopifnot(all(sapply(inputs, is.character)))
stopifnot(all(sapply(inputs, length) == 1))
details <- note_schema(
title = title,
content = content,
isStarred = FALSE,
isArchived = FALSE
)
json.format <- jsonlite::toJSON(details, pretty = TRUE)
structure(json.format, class = "Note")
}
#' Edit note
#'
#' @param overwrite default is \code{FALSE}. By default, the original note is not
#' edited. A new entry will be added to the note file. To edit chose this variable
#' as \code{TRUE}.
# edit_note <- function()
#' Change note status as deleted
#'
#' This is surely a soft delete. You need to delete the note from system if you really want to delete it.
# delete_note <- function()
#' Change note status as archived
# archive_note <- function()
#' Change note status as starred
# star_note
#' A generic solution to change note status in a field
# change_note_status <- function(note, status)
#' Creates a new note file in the notes folder
#'
#' @return The note path.
#' @noRd
create_note_file <- function() {
dir <- get_notes_folder_path()
note.name <- create_note_name()
pat <- file.path(dir, note.name)
file.create(pat)
pat
}
#' Create note name
#'
#' It's not an UUID, and a new hash will be generated (in a recursive way) if
#' the hash code exists in the notes directory.
#'
#' @noRd
create_note_name <- function() {
rand.str <- random_string()
filename <- paste(rand.str, ".json", sep = "")
if (!filename_exists_in_folder(filename)) {
filename
} else {
event_message("Filename exists! Creating new one.")
create_note_name()
}
}
#' Checks if a file exists in notes folder:
filename_exists_in_folder <- function(filename) {
stopifnot(is.character(filename))
folder.list <- list_folder_notes()
if (filename %in% folder.list) {
TRUE
} else {
FALSE
}
}
### ----------------------------------------------------------------- ###
### SCHEMAS ----
### ----------------------------------------------------------------- ###
#' Note schema structure
note_schema <- function(title, content, isStarred, isArchived) {
stopifnot(is.character(title))
stopifnot(is.character(content))
stopifnot(is.logical(isStarred))
stopifnot(is.logical(isArchived))
ret <- list(
dateCreated = Timestamp(),
title = title,
content = content,
isStarred = isStarred,
isArchived = isArchived
)
ret
}
### ----------------------------------------------------------------- ###
### TYPE CHECKERS ----
### ----------------------------------------------------------------- ###
isNote <- function(x) {
inherits(x, "Note")
}
### ----------------------------------------------------------------- ###
### FOLDER ----
### ----------------------------------------------------------------- ###
#' See all notes in data frame form
#'
#' @importFrom jsonlite fromJSON
#' @noRd
notes_as_data_frame <- function() {
dir <- get_notes_folder_path()
list <- list_folder_notes()
res <- do.call(rbind, lapply(seq_along(list), function(i) {
note <- list[i]
## ignore note that cannot be read (instead of stopping execution):
vec <- try(readNote(note))
if (inherits(vec, "try-error")) {
return(NULL)
}
df <- as.data.frame(vec)
cbind(note, df)
}))
res
}
#' Does note exist in the notes folder?
#' @noRd
is_note_exist <- function(note) {
stopifnot(is.character(note))
stopifnot(length(note) == 1L)
list <- list_folder_notes()
mat <- match(note, list)
if (is.na(mat)) {
FALSE
} else {
TRUE
}
}
#' List JSON files in notes folder
#'
#' @importFrom tools file_path_sans_ext
#' @noRd
list_folder_notes <- function() {
dir <- get_notes_folder_path()
list <- list.files(dir, pattern = "\\.json$")
## exclude dots:
list <- setdiff(list, c(".", ".."))
list
}
#' Create a folder to keep note files (if folder not exists)
#'
#' As default option indicates, the notes folder will be created in the current
#' directory.
#'
#' @export
create_notes_folder <- function() {
set_notes_folder_path()
dir <- get_notes_folder_path()
## creating directory:
if (!dir.exists(dir)) {
dir.create(dir)
event_message("Folder has been created ", dir)
} else {
event_message("Folder already exists in ", dir)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.