Пример #1
0
FilePath projectFromDirectory(const FilePath& directoryPath)
{
   // first use simple heuristic of a case sentitive match between
   // directory name and project file name
   FilePath projectFile = directoryPath.childPath(
                                       directoryPath.filename() + ".Rproj");
   if (projectFile.exists())
      return projectFile;

   // didn't satisfy it with simple check so do scan of directory
   std::vector<FilePath> children;
   Error error = directoryPath.children(&children);
   if (error)
   {
      LOG_ERROR(error);
      return FilePath();
   }

   // build a vector of children with .rproj extensions. at the same
   // time allow for a case insensitive match with dir name and return that
   std::string projFileLower = string_utils::toLower(projectFile.filename());
   std::vector<FilePath> rprojFiles;
   for (std::vector<FilePath>::const_iterator it = children.begin();
        it != children.end();
        ++it)
   {
      if (!it->isDirectory() && (it->extensionLowerCase() == ".rproj"))
      {
         if (string_utils::toLower(it->filename()) == projFileLower)
            return *it;
         else
            rprojFiles.push_back(*it);
      }
   }

   // if we found only one rproj file then return it
   if (rprojFiles.size() == 1)
   {
      return rprojFiles.at(0);
   }
   // more than one, take most recent
   else if (rprojFiles.size() > 1 )
   {
      projectFile = rprojFiles.at(0);
      for (std::vector<FilePath>::const_iterator it = rprojFiles.begin();
           it != rprojFiles.end();
           ++it)
      {
         if (it->lastWriteTime() > projectFile.lastWriteTime())
            projectFile = *it;
      }

      return projectFile;
   }
   // didn't find one
   else
   {
      return FilePath();
   }
}
Пример #2
0
Error enqueueChunkOutput(
      const std::string& docPath, const std::string& docId,
      const std::string& chunkId, const std::string& contextId)
{
   FilePath outputPath = chunkOutputPath(docPath, docId, chunkId, contextId);

   // scan the directory for output
   std::vector<FilePath> outputPaths;
   Error error = outputPath.children(&outputPaths);

   // non-fatal: if we can't list we'll safely return an empty array
   if (error) 
      LOG_ERROR(error);

   // arrange by filename (use FilePath's < operator)
   std::sort(outputPaths.begin(), outputPaths.end());

   // loop through each and build an array of the outputs
   json::Array outputs;
   BOOST_FOREACH(const FilePath& outputPath, outputPaths)
   {
      json::Object output;

      // ascertain chunk output type from file extension; skip if extension 
      // unknown
      int outputType = chunkOutputType(outputPath);
      if (outputType == kChunkOutputNone)
         continue;

      // format/parse chunk output for client consumption
      output[kChunkOutputType] = outputType;
      if (outputType == kChunkOutputText)
      {
         json::Array consoleOutput;
         error = chunkConsoleContents(outputPath, &consoleOutput);
         output[kChunkOutputValue] = consoleOutput;
      }
      else if (outputType == kChunkOutputPlot ||
               outputType == kChunkOutputHtml)
      {
         output[kChunkOutputValue] = kChunkOutputPath "/" + docId + "/" +
            chunkId + "/" + outputPath.filename();
      }

      outputs.push_back(output);
   }
Пример #3
0
// IN: String path
// OUT: Array<FileEntry> files
core::Error listFiles(const json::JsonRpcRequest& request, 
                      json::JsonRpcResponse* pResponse)
{
   // get path
   std::string path;
   bool monitor;
   Error error = json::readParams(request.params, &path, &monitor);
   if (error)
      return error ;
   
   // retreive list of files
   FilePath targetPath = module_context::resolveAliasedPath(path) ;
   std::vector<FilePath> files ;
   Error listingError = targetPath.children(&files) ;
   if (listingError)
      return listingError ;

   // sort the files by name
   std::sort(files.begin(), files.end(), compareAbsolutePathNoCase);
   
   // produce json listing
   json::Array jsonFiles ;
   BOOST_FOREACH( FilePath& filePath, files )
   {
      // files which may have been deleted after the listing or which
      // are not end-user visible
      if (filePath.exists() && isVisible(filePath))
      {
         json::Object fileObject = module_context::createFileSystemItem(filePath);
         jsonFiles.push_back(fileObject) ;
      }
   }

   // return listing
   pResponse->setResult(jsonFiles) ;
   
   // setup monitoring if requested (merely log errors so if something
   // unexpected happens the user still gets the file listing)
   if (monitor)
      startMonitoring(targetPath.absolutePath());
   
   // success
   return Success();
}
Пример #4
0
std::vector<boost::shared_ptr<GlobalActiveSession> >
GlobalActiveSessions::list() const
{
   std::vector<boost::shared_ptr<GlobalActiveSession> > sessions;

   // get all active sessions for the system
   FilePath activeSessionsDir = rootPath_;
   if (!activeSessionsDir.exists())
      return sessions; // no active sessions exist

   std::vector<FilePath> sessionFiles;
   Error error = activeSessionsDir.children(&sessionFiles);
   if (error)
   {
      LOG_ERROR(error);
      return sessions;
   }

   BOOST_FOREACH(const FilePath& sessionFile, sessionFiles)
   {
      sessions.push_back(boost::shared_ptr<GlobalActiveSession>(new GlobalActiveSession(sessionFile)));
   }
Пример #5
0
void onDocSaved(FilePath &path)
{
   Error error;
   // ignore non-R Markdown saves
   if (!path.hasExtensionLowerCase(".rmd"))
      return;

   // find cache folder (bail out if it doesn't exist)
   FilePath cache = chunkCacheFolder(path, "", notebookCtxId());
   if (!cache.exists())
      return;

   FilePath saved = chunkCacheFolder(path, "", kSavedCtx);
   if (saved.exists())
   {
      // tidy up: remove any saved chunks that no longer exist
      error = removeStaleSavedChunks(path, saved);
      if (error)
         LOG_ERROR(error);
   }
   else
   {
      // no saved context yet; ensure we have a place to put it
      saved.ensureDirectory();
   }

   // move all the chunk definitions over to the saved context
   std::vector<FilePath> children;
   error = cache.children(&children);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }
   BOOST_FOREACH(const FilePath source, children)
   {
      // compute the target path 
      FilePath target = saved.complete(source.filename());

      if (source.filename() == kNotebookChunkDefFilename) 
      {
         // the definitions should be copied (we always want them in both
         // contexts)
         error = target.removeIfExists();
         if (!error)
            error = source.copy(target);
      }
      else if (source.isDirectory())
      {
         // library folders should be merged and then removed, so we don't
         // lose library contents 
         if (source.filename() == kChunkLibDir)
         {
            error = mergeLib(source, target);
            if (!error)
               error = source.remove();
         }
         else
         {
            // the chunk output folders should be moved; destroy the old copy
            error = target.removeIfExists();
            if (!error)
               error = source.move(target);
         }
      }
      else
      {
         // nothing besides the chunks.json and chunk folders should be here,
         // so ignore other files/content
         continue;
      }

      if (error)
         LOG_ERROR(error);
   }