void getLogEntries(const FilePath& texPath, const rnw_concordance::Concordances& concordances, core::tex::LogEntries* pLogEntries) { // latex log file FilePath logPath = latexLogPath(texPath); if (logPath.exists()) { core::tex::LogEntries logEntries; Error error = core::tex::parseLatexLog(logPath, &logEntries); if (error) LOG_ERROR(error); filterLatexLog(logEntries, pLogEntries); } // bibtex log file core::tex::LogEntries bibtexLogEntries; logPath = bibtexLogPath(texPath); if (logPath.exists()) { Error error = core::tex::parseBibtexLog(logPath, &bibtexLogEntries); if (error) LOG_ERROR(error); } // concatenate them together std::copy(bibtexLogEntries.begin(), bibtexLogEntries.end(), std::back_inserter(*pLogEntries)); }
bool validate(const FilePath& userHomePath, bool projectSharingEnabled) const { // ensure the scratch path and properties paths exist if (!scratchPath_.exists() || !propertiesPath_.exists()) return false; // ensure the properties are there if (project().empty() || workingDir().empty() || (lastUsed() == 0)) return false; // for projects validate that the base directory still exists std::string theProject = project(); if (theProject != kProjectNone) { FilePath projectDir = FilePath::resolveAliasedPath(theProject, userHomePath); if (!projectDir.exists()) return false; // check for project file FilePath projectPath = r_util::projectFromDirectory(projectDir); if (!projectPath.exists()) return false; // if we got this far the scope is valid, do one final check for // trying to open a shared project if sharing is disabled if (!projectSharingEnabled && r_util::isSharedPath(projectPath.absolutePath(), userHomePath)) return false; } // validated! return true; }
bool readPresentation(SlideDeck* pSlideDeck, std::string* pSlides, std::string* pInitActions, std::string* pSlideActions, std::map<std::string,std::string>* pVars, std::string* pErrMsg) { // look for slides and knit if we need to FilePath rmdFile = presentation::state::filePath(); std::string ext = rmdFile.extensionLowerCase(); if (rmdFile.exists() && (ext != ".md")) { if (!performKnit(rmdFile, pErrMsg)) return false; } // look for slides markdown FilePath slidesFile = rmdFile.parent().childPath(rmdFile.stem() + ".md"); if (!slidesFile.exists()) { *pErrMsg = slidesFile.absolutePath() + " not found"; return false; } // parse the slides Error error = pSlideDeck->readSlides(slidesFile); if (error) { LOG_ERROR(error); *pErrMsg = error.summary(); return false; } // render the slides std::string revealConfig; error = presentation::renderSlides(*pSlideDeck, pSlides, &revealConfig, pInitActions, pSlideActions); if (error) { LOG_ERROR(error); *pErrMsg = error.summary(); return false; } // build template variables std::map<std::string,std::string>& vars = *pVars; vars["title"] = pSlideDeck->title(); vars["slides"] = *pSlides; vars["slides_css"] = resourceFiles().get("presentation/slides.css"); vars["r_highlight"] = resourceFiles().get("r_highlight.html"); vars["reveal_config"] = revealConfig; vars["preamble"] = pSlideDeck->preamble(); return true; }
FilePath Options::wwwDocsPath() const { FilePath supportingFilePath = desktop::options().supportingFilePath(); FilePath wwwDocsPath = supportingFilePath.complete("www/docs"); if (!wwwDocsPath.exists()) wwwDocsPath = supportingFilePath.complete("../gwt/www/docs"); #ifdef __APPLE__ if (!wwwDocsPath.exists()) wwwDocsPath = supportingFilePath.complete("../../../../../gwt/www/docs"); #endif return wwwDocsPath; }
Error getChunkDefs(const std::string& docPath, const std::string& docId, time_t *pDocTime, core::json::Value* pDefs) { // try local context first FilePath defs = chunkDefinitionsPath(docPath, docId, notebookCtxId()); if (!defs.exists()) { // if no definitions, try the saved context defs = chunkDefinitionsPath(docPath, docId, kSavedCtx); if (!defs.exists()) return Success(); } return getChunkDefs(defs, pDocTime, pDefs); }
// determines the icon data; this could be either a path on disk (if we have // a suitable icon locally), base64-encoded icon data (if the icon is embedded // in an R package), or nothing (if we cannot determine an icon at all) std::string iconData(const std::string& iconGroup, const std::string& iconName, const std::string& iconPath) { if (iconPath.empty()) { // convert the icon name into the format of our shipped icons, which is // all lowercase with no whitespace (e.g. "SQL Server" => "sqlserver.png") std::string iconFilename(string_utils::toLower(iconName)); iconFilename = boost::regex_replace(iconFilename, boost::regex("\\s"), "") + ".png"; // the package did not supply an icon; see if there's one baked in FilePath path = options().rResourcesPath().childPath("connections") .childPath(iconGroup) .childPath(iconFilename); if (path.exists()) return std::string("connections/") + iconGroup + "/" + iconFilename; if (iconGroup == "drivers") return std::string("connections/drivers/odbc.png"); // didn't find anything return std::string(); } // expand the path FilePath icon = module_context::resolveAliasedPath(iconPath); std::string iconData; // ensure that the icon file exists and is a small GIF, JPG, or PNG image if (icon.exists() && icon.size() < kMaxIconSize && (icon.hasExtensionLowerCase(".gif") || icon.hasExtensionLowerCase(".png") || icon.hasExtensionLowerCase(".jpg") || icon.hasExtensionLowerCase(".jpeg"))) { Error error = base64::encode(icon, &iconData); if (error) LOG_ERROR(error); else { iconData = "data:" + icon.mimeContentType("image/png") + ";base64," + iconData; } } return iconData; }
Error detectZipFileOverwrites(const FilePath& uploadedZipFile, const FilePath& destDir, json::Array* pOverwritesJson) { // query for all of the paths in the zip file std::vector<std::string> zipFileListing; r::exec::RFunction listZipFile(".rs.listZipFile", uploadedZipFile.absolutePath()); Error unzipError = listZipFile.call(&zipFileListing); if (unzipError) return unzipError; // check for overwrites for (std::vector<std::string>::const_iterator it = zipFileListing.begin(); it != zipFileListing.end(); ++it) { FilePath filePath = destDir.complete(*it); if (filePath.exists()) pOverwritesJson->push_back(module_context::createFileSystemItem(filePath)); } return Success(); }
// IN: String path, String targetPath core::Error renameFile(const core::json::JsonRpcRequest& request, json::JsonRpcResponse* pResponse) { // read params std::string path, targetPath; Error error = json::readParams(request.params, &path, &targetPath); if (error) return error ; // if the destination already exists then send back file exists FilePath destPath = module_context::resolveAliasedPath(targetPath) ; if (destPath.exists()) return fileExistsError(ERROR_LOCATION); // create file info now before we remove FilePath sourcePath = module_context::resolveAliasedPath(path); FileInfo sourceFileInfo(sourcePath); // move the file Error renameError = sourcePath.move(destPath); if (renameError) return renameError ; // generate delete event for folders (inotify doesn't do this right now) if (sourceFileInfo.isDirectory()) enqueFileRemovedEvent(sourceFileInfo); return Success() ; }
// IN: String path core::Error createFile(const core::json::JsonRpcRequest& request, json::JsonRpcResponse* pResponse) { std::string path; Error error = json::readParam(request.params, 0, &path); if (error) return error ; // calculate file path FilePath filePath = module_context::resolveAliasedPath(path) ; if (filePath.exists()) { return fileExistsError(ERROR_LOCATION); } else { // create the file boost::shared_ptr<std::ostream> pOfs; error = filePath.open_w(&pOfs); if (error) return error; } return Success() ; }
void reportHistoryAccessError(const std::string& context, const FilePath& historyFilePath, const Error& error) { // always log LOG_ERROR(error); // default summary std::string summary = error.summary(); // if the file exists and we still got no such file or directory // then it is almost always permission denied. this seems to happen // somewhat frequently on linux systems where the user was root for // an operation and ended up writing a .Rhistory if (historyFilePath.exists() && (error.code() == boost::system::errc::no_such_file_or_directory)) { summary = "permission denied (is the .Rhistory file owned by root?)"; } // notify the user std::string path = createAliasedPath(historyFilePath); std::string errmsg = context + " " + path + ": " + summary; REprintf(("Error attempting to " + errmsg + "\n").c_str()); }
std::string Base64ImageFilter::toBase64Image(const boost::cmatch& match) { // extract image reference std::string imgRef = match[3]; // see if this is an image within the base directory. if it is then // base64 encode it FilePath imagePath = basePath_.childPath(imgRef); if (imagePath.exists() && boost::algorithm::starts_with(imagePath.mimeContentType(), "image/")) { std::string imageBase64; Error error = core::base64::encode(imagePath, &imageBase64); if (!error) { imgRef = "data:" + imagePath.mimeContentType() + ";base64,"; imgRef.append(imageBase64); } else { LOG_ERROR(error); } } // return the filtered result return match[1] + match[2] + imgRef + match[4]; }
Error UserSettings::initialize() { // calculate settings file path FilePath settingsDir = module_context::registerMonitoredUserScratchDir( "user-settings", boost::bind(&UserSettings::onSettingsFileChanged, this, _1)); settingsFilePath_ = settingsDir.complete("user-settings"); // if it doesn't exist see if we can migrate an old user settings if (!settingsFilePath_.exists()) { FilePath oldSettingsPath = module_context::userScratchPath().complete("user-settings"); if (oldSettingsPath.exists()) oldSettingsPath.move(settingsFilePath_); } // read the settings Error error = settings_.initialize(settingsFilePath_); if (error) return error; // make sure we have a context id if (contextId().empty()) setContextId(core::system::generateUuid()); return Success(); }
FilePath getDefaultWorkingDirectory() { // calculate using user settings FilePath defaultWorkingDir = userSettings().initialWorkingDirectory(); FilePath sessionDefaultWorkingDir = FilePath(session::options().defaultWorkingDir()); // return it if it exists, otherwise use the // session specified value if it exists // otherwise, use the default user home path if (defaultWorkingDir.exists() && defaultWorkingDir.isDirectory()) return defaultWorkingDir; else if (sessionDefaultWorkingDir.exists() && sessionDefaultWorkingDir.isDirectory()) return sessionDefaultWorkingDir; else return session::options().userHomePath(); }
void setCacheableFile(const FilePath& filePath, const Request& request, const Filter& filter) { // ensure that the file exists if (!filePath.exists()) { setError(http::status::NotFound, request.uri() + " not found"); return; } // set Last-Modified using namespace boost::posix_time; ptime lastModifiedDate = from_time_t(filePath.lastWriteTime()); setHeader("Last-Modified", util::httpDate(lastModifiedDate)); // compare file modified time to If-Modified-Since if (lastModifiedDate == request.ifModifiedSince()) { removeHeader("Content-Type"); // upstream code may have set this setStatusCode(status::NotModified); } else { setFile(filePath, request, filter); } }
void handleFileExportRequest(const http::Request& request, http::Response* pResponse) { // see if this is a single or multiple file request std::string file = request.queryParamValue("file"); if (!file.empty()) { // resolve alias and ensure that it exists FilePath filePath = module_context::resolveAliasedPath(file); if (!filePath.exists()) { pResponse->setError(http::status::NotFound, "file doesn't exist"); return; } // get the name std::string name = request.queryParamValue("name"); if (name.empty()) { pResponse->setError(http::status::BadRequest, "name not specified"); return; } // download as attachment setAttachmentResponse(request, name, filePath, pResponse); } else { handleMultipleFileExportRequest(request, pResponse); } }
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(); } }
std::vector<std::string> collectFirstRunDocs(const FilePath& projectFile) { // docs to return std::vector<std::string> docs; // get the scratch path FilePath scratchPath; Error error = computeScratchPaths(projectFile, &scratchPath, nullptr); if (error) { LOG_ERROR(error); return docs; } // check for first run file FilePath firstRunDocsPath = scratchPath.childPath(kFirstRunDocs); if (firstRunDocsPath.exists()) { Error error = core::readStringVectorFromFile(firstRunDocsPath, &docs); if (error) LOG_ERROR(error); // remove since this is a one-time only thing firstRunDocsPath.remove(); } return docs; }
void ProjectContext::augmentRbuildignore() { if (r_util::isPackageDirectory(directory())) { // constants const char * const kIgnoreRproj = "^.*\\.Rproj$"; const char * const kIgnoreRprojUser = "******"; // create the file if it doesn't exists FilePath rbuildIgnorePath = directory().childPath(".Rbuildignore"); if (!rbuildIgnorePath.exists()) { Error error = writeStringToFile(rbuildIgnorePath, kIgnoreRproj + std::string("\n") + kIgnoreRprojUser + std::string("\n"), string_utils::LineEndingNative); if (error) LOG_ERROR(error); } else { // if .Rbuildignore exists, add *.Rproj and .Rproj.user unless // they are already there std::string strIgnore; Error error = core::readStringFromFile( rbuildIgnorePath, &strIgnore, string_utils::LineEndingPosix); if (error) { LOG_ERROR(error); return; } // NOTE: we don't search for the full kIgnoreRproj to account // for previous less precisely specified .Rproj entries bool hasRProj = strIgnore.find("\\.Rproj$") != std::string::npos; bool hasRProjUser = strIgnore.find(kIgnoreRprojUser) != std::string::npos; if (hasRProj && hasRProjUser) return; bool addExtraNewline = strIgnore.size() > 0 && strIgnore[strIgnore.size() - 1] != '\n'; if (addExtraNewline) strIgnore += "\n"; if (!hasRProj) strIgnore += kIgnoreRproj + std::string("\n"); if (!hasRProjUser) strIgnore += kIgnoreRprojUser + std::string("\n"); error = core::writeStringToFile(rbuildIgnorePath, strIgnore, string_utils::LineEndingNative); if (error) LOG_ERROR(error); } } }
Error RPackageInfo::read(const FilePath& packageDir) { // parse DCF file FilePath descFilePath = packageDir.childPath("DESCRIPTION"); if (!descFilePath.exists()) return core::fileNotFoundError(descFilePath, ERROR_LOCATION); std::string errMsg; std::map<std::string,std::string> fields; Error error = text::parseDcfFile(descFilePath, true, &fields, &errMsg); if (error) return error; // Package field std::map<std::string,std::string>::const_iterator it; it = fields.find("Package"); if (it != fields.end()) name_ = it->second; else return fieldNotFoundError(descFilePath, "Package", ERROR_LOCATION); // Version field it = fields.find("Version"); if (it != fields.end()) version_ = it->second; else return fieldNotFoundError(descFilePath, "Version", ERROR_LOCATION); // Linking to field it = fields.find("LinkingTo"); if (it != fields.end()) linkingTo_ = it->second; return Success(); }
bool isSharedPath(const std::string& projectPath, const core::FilePath& userHomePath) { #ifndef _WIN32 // ensure this is a real path FilePath projectDir = FilePath::resolveAliasedPath(projectPath, userHomePath); if (!projectDir.exists()) return false; struct stat st; if (::stat(projectDir.absolutePath().c_str(), &st) == 0) { // consider this project to be shared if we aren't the owner if (st.st_uid != ::geteuid()) { return true; } } else { Error error = systemError(errno, ERROR_LOCATION); error.addProperty("path", projectDir.absolutePath()); LOG_ERROR(error); } #endif return false; }
FilePath getInitialWorkingDirectory() { // check for a project if (projects::projectContext().hasProject()) { return projects::projectContext().directory(); } // check for working dir in project none else if (options().sessionScope().isProjectNone()) { return getActiveSessionInitialWorkingDirectory(); } // see if there is an override from the environment (perhaps based // on a folder drag and drop or other file association) FilePath workingDirPath = session::options().initialWorkingDirOverride(); if (workingDirPath.exists() && workingDirPath.isDirectory()) { return workingDirPath; } else { return getActiveSessionInitialWorkingDirectory(); } }
Error RPackageInfo::read(const FilePath& packageDir) { // parse DCF file FilePath descFilePath = packageDir.childPath("DESCRIPTION"); if (!descFilePath.exists()) return core::fileNotFoundError(descFilePath, ERROR_LOCATION); std::string errMsg; std::map<std::string,std::string> fields; Error error = text::parseDcfFile(descFilePath, true, &fields, &errMsg); if (error) return error; error = readField(fields, "Package", &name_, descFilePath, ERROR_LOCATION); if (error) return error; error = readField(fields, "Version", &version_, descFilePath, ERROR_LOCATION); if (error) return error; readField(fields, "Depends", &depends_); readField(fields, "Imports", &imports_); readField(fields, "Suggests", &suggests_); readField(fields, "LinkingTo", &linkingTo_); readField(fields, "SystemRequirements", &systemRequirements_); readField(fields, "Type", &type_, kPackageType); return Success(); }
FilePath getProjectUserDataDir(const ErrorLocation& location) { // get the project directory FilePath projectDir = projects::projectContext().directory(); // presume that the project dir is the data dir then check // for a .Ruserdata directory as an alternative FilePath dataDir = projectDir; FilePath ruserdataDir = projectDir.childPath(".Ruserdata"); if (ruserdataDir.exists()) { // create user-specific subdirectory if necessary FilePath userDir = ruserdataDir.childPath(core::system::username()); Error error = userDir.ensureDirectory(); if (!error) { dataDir = userDir; } else { core::log::logError(error, location); } } // return the data dir return dataDir; }
// IN: String path, String targetPath core::Error renameFile(const core::json::JsonRpcRequest& request, json::JsonRpcResponse* pResponse) { // read params std::string path, targetPath; Error error = json::readParams(request.params, &path, &targetPath); if (error) return error ; // if the destination already exists then send back file exists FilePath destPath = module_context::resolveAliasedPath(targetPath) ; if (destPath.exists()) return fileExistsError(ERROR_LOCATION); // move the file FilePath sourcePath = module_context::resolveAliasedPath(path); Error renameError = sourcePath.move(destPath); if (renameError) return renameError ; // propagate rename to source database (non fatal if this fails) error = source_database::rename(sourcePath, destPath); if (error) LOG_ERROR(error); return Success() ; }
void enqueFileEditEvent(const std::string& file) { // ignore if no file passed if (file.empty()) return; // calculate full path FilePath filePath = module_context::safeCurrentPath().complete(file); // if it doesn't exist then create it if (!filePath.exists()) { Error error = core::writeStringToFile(filePath, "", options().sourcePersistLineEnding()); if (error) { LOG_ERROR(error); return; } } // fire event json::Object fileJson = module_context::createFileSystemItem(filePath); ClientEvent event(client_events::kFileEdit, fileJson); module_context::enqueClientEvent(event); }
Error restoreDefaultGlobalEnvironment() { // restore the default global environment if there is one FilePath globalEnvPath = s_options.startupEnvironmentFilePath; if (globalEnvPath.exists()) { // notify client of serialization status SerializationCallbackScope cb(kSerializationActionLoadDefaultWorkspace, globalEnvPath); // ignore interrupts which occur during restoring of the global env // the restoration will run to completion in any case and then the // next thing the user does will be "interrupted" -- clearly not // what they intended r::exec::IgnoreInterruptsScope ignoreInterrupts; Error error = r::exec::executeSafely(boost::bind( R_RestoreGlobalEnvFromFile, globalEnvPath.absolutePath().c_str(), TRUE)); if (error) return error; // print path to console std::string aliasedPath = createAliasedPath(globalEnvPath); Rprintf(("[Workspace loaded from " + aliasedPath + "]\n\n").c_str()); } // mark image clean (we need to do this due to our delayed handling // of workspace restoration) markImageClean(); return Success(); }
FilePath FilePath::safeCurrentPath(const FilePath& revertToPath) { try { #ifdef _WIN32 return FilePath(boost::filesystem::current_path().wstring()) ; #elif defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION != 2 return FilePath(boost::filesystem::current_path().string()) ; #else return FilePath(boost::filesystem::current_path<path_t>().string()) ; #endif } catch(const boost::filesystem::filesystem_error& e) { if (e.code() != boost::system::errc::no_such_file_or_directory) LOG_ERROR(Error(e.code(), ERROR_LOCATION)); } CATCH_UNEXPECTED_EXCEPTION // revert to the specified path if it exists, otherwise // take the user home path from the system FilePath safePath = revertToPath; if (!safePath.exists()) safePath = core::system::userHomePath(); Error error = safePath.makeCurrentPath(); if (error) LOG_ERROR(error); return safePath; }
bool RVersionsScanner::detectSystemRVersion(core::r_util::RVersion* pVersion, std::string* pErrMsg) { // return cached version if we have it if (!systemVersion_.empty()) { *pVersion = systemVersion_; return true; } // check for which R override FilePath rWhichRPath; if (!whichROverride_.empty()) rWhichRPath = FilePath(whichROverride_); // if it's a directory then see if we can find the script if (rWhichRPath.isDirectory()) { FilePath rScriptPath = rWhichRPath.childPath("bin/R"); if (rScriptPath.exists()) rWhichRPath = rScriptPath; } // attempt to detect R version bool result = detectRVersion(rWhichRPath, pVersion, pErrMsg); // if we detected it then cache it if (result) systemVersion_ = *pVersion; // return result return result; }
std::string CssUrlFilter::toBase64Url(const boost::cmatch& match) { // is this a local file? std::string urlRef = match[1]; FilePath urlPath = basePath_.childPath(urlRef); std::string ext = urlPath.extensionLowerCase(); if (urlPath.exists() && (ext == ".ttf" || ext == ".otf")) { std::string fontBase64; Error error = core::base64::encode(urlPath, &fontBase64); if (!error) { // return base64 encoded font std::string type = (ext == ".ttf") ? "truetype" : "opentype"; boost::format fmt("url(data:font/%1%;base64,%2%)"); return boost::str(fmt % type % fontBase64); } else { LOG_ERROR(error); return match[0]; } } else { return match[0]; } }
Error createSessionDirFromOldSourceDatabase(FilePath* pSessionDir) { // move properties (if any) into new source database root FilePath propsPath = oldSourceDatabaseRoot().complete("properties"); if (propsPath.exists()) { FilePath newPropsPath = sourceDatabaseRoot().complete("prop"); Error error = propsPath.move(newPropsPath); if (error) LOG_ERROR(error); } // move the old source database into a new dir *pSessionDir = generateSessionDirPath(); Error error = oldSourceDatabaseRoot().move(*pSessionDir); if (error) LOG_ERROR(error); // if that failed we might still need to call ensureDirectory error = pSessionDir->ensureDirectory(); if (error) return error; // attempt to acquire the lock. if we can't then we still continue // so we can support filesystems that don't have file locks. error = sessionDirLock().acquire(sessionLockFilePath(*pSessionDir)); if (error) LOG_ERROR(error); return Success(); }