mindlessgreen
mindlessgreen

Reputation: 12102

R shiny-server: User specific directory for each session

My shiny app is on a server and generates some text files (different content, same filename) in the local app folder each time a user uses the app. I am concerned that when multiple users use the app, the exported text files may conflict since the location and filename of the text files are same.

To avoid this possibility, I am thinking along the direction of creating a directory when a user starts a session, all working files are exported to that directory and when the session is closed, the directory must be deleted.

Any ideas on how to go about with this? Are there better solutons? How do I detect when the a session has closed? How do I figure out the number of active sessions?

Upvotes: 1

Views: 1194

Answers (1)

mindlessgreen
mindlessgreen

Reputation: 12102

This works correctly in a shiny-server environment as well as on shinyapps.io. A working example by Tareef Kawaf.

ui.R

#ui.R
shinyUI(fluidPage(
  headerPanel("New directory issue"),
  wellPanel(
  helpText("I would like a new directory to be created each time a new connection is made to the app OR anytime new files are uploaded."),
  helpText("This app uploads one text file, creates a new directory, extracts first 5 lines and exports a text file with the contents."),
  helpText("Upload one text file with minimum 5 lines of content."),
  fileInput('upload', label=h4('Upload file(s):'), multiple=FALSE)
  ),
  mainPanel(
    tags$h3("Str of uploaded content"),
    verbatimTextOutput('display')
  )
))

server.R

#server.R

#Get current wd and print
currwd <- getwd()

#FUNCTION - new directory
fn_dir <- function(currwd=NULL)
{
  if(is.null(currwd)) stop("Argument 'currwd' is empty.\n")

  #Create new working directory
  newwd <- paste0(currwd,"/",format(Sys.time(),"%Y%m%d%H%M%S"))
  dir.create(newwd)
  newwd
}

shinyServer(function(input, output) {

  #REACTIVE - store
  store <- reactiveValues(currwd = currwd)

  #REACTIVE - complete input
  fn_getfilenames <- reactive({
    inputdata <- input$upload

    if (!is.null(inputdata))
    {
      store$newwd <- fn_dir(store$currwd)
      return(inputdata)
    }else{
      return(NULL)
    }
  })

  #OUTPUT
  output$display <- renderPrint({
    if (is.null(fn_getfilenames())) return(NULL)

    inputdata <- fn_getfilenames()

    #some stuff to export to working directory

    rcontent <- as.vector(scan(file = inputdata$datapath,what = "text",n = 10))

    full_file_path <- file.path(store$newwd,inputdata$name)
    write(x = rcontent, file = paste0(full_file_path,"-test.txt"))

    return(str(inputdata))
  })
})

Upvotes: 1

Related Questions