dirutils.cpp 4.23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm

#include "libvideostitch/dirutils.hpp"

#include <sys/types.h>  // For stat().
#include <sys/stat.h>   // For stat().

#ifdef _MSC_VER
#include <algorithm>
#include <direct.h>
#include <io.h>  // For access().
#include <windows.h>
#include <Lmcons.h>
#else
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <cstdlib>
#endif

namespace VideoStitch {
namespace Util {

std::mutex mutexCreateDirectory;
const std::string VIDEOSTITCH_SUB_FOLDER = "VideoStitch";
const std::string CACHE_SUB_FOLDER = "cache";

#ifdef _MSC_VER
const std::string HOME_VAR = "USERPROFILE";
#else
const std::string HOME_VAR = "HOME";
#endif

bool directoryExists(const std::string& absolutePath) {
#ifdef _MSC_VER
  if (_access(absolutePath.c_str(), 0) == 0) {
#endif
    struct stat status;
    return stat(absolutePath.c_str(), &status) == 0 && (status.st_mode & S_IFDIR) != 0;
#ifdef _MSC_VER
  }
  return false;
#endif
}

bool createDirectory(const std::string& absolutePath) {
  int err = 0;
  mutexCreateDirectory.lock();
#if defined(_MSC_VER)
  err = _mkdir(absolutePath.c_str());  // can be used on Windows
#elif defined(__ANDROID__)
  std::string command = "mkdir -p " + absolutePath;
  err = system(command.c_str());  // create subdirectories
#else
  err = mkdir(absolutePath.c_str(), 0700);  // can be used on non-Windows
#endif
  mutexCreateDirectory.unlock();
  return err == 0;
}

std::string getHomeLocation() {
  char const* homeCh = getenv(HOME_VAR.c_str());
  if (!homeCh) {
    return "";
  }
  std::string home = std::string(homeCh);
#if defined(_MSC_VER)
  std::replace(home.begin(), home.end(), '\\', '/');
#endif
  return home;
}

std::string getGenericCacheLocation() {
  const std::string& home = getHomeLocation();
  if (home.empty()) {
    return home;
  }
#if defined(_MSC_VER)
  return home + "/AppData/Local/cache";
#elif defined(__APPLE__)
  return home + "/Library/Caches";
#else  // linux
  return home + "/.cache";
#endif
}

PotentialValue<std::string> getGenericCacheLocation(const std::string& companyName) {
  if (companyName.empty()) {
    return PotentialValue<std::string>({Origin::Output, ErrType::InvalidConfiguration, "Invalid company name"});
  }

  PotentialValue<std::string> companyDataLocation = getGenericDataLocation(companyName);
  if (!companyDataLocation.ok()) {
    return companyDataLocation;
  }

  const std::string& companyCacheLocation = companyDataLocation.value() + "/" + CACHE_SUB_FOLDER;
  if (!directoryExists(companyCacheLocation)) {
    if (!createDirectory(companyCacheLocation)) {
      return PotentialValue<std::string>(
          {Origin::Output, ErrType::RuntimeError,
           "Error creating folder " + companyCacheLocation + ", " + std::string(strerror(errno))});
    }
  }

  return std::string(companyCacheLocation);
}

PotentialValue<std::string> getVSCacheLocation() { return getGenericCacheLocation(VIDEOSTITCH_SUB_FOLDER); }

std::string getGenericDataLocation() {
  const std::string& home = getHomeLocation();
  if (home.empty()) {
    return "";
  }
#if defined(_MSC_VER)
  return home + "/AppData/Local";
#elif defined(__APPLE__)
  return home + "/Library/Application Support";
#else  // linux
  return home + "/.local/share";
#endif
}

PotentialValue<std::string> getGenericDataLocation(const std::string& companyName) {
  if (companyName.empty()) {
    return PotentialValue<std::string>({Origin::Output, ErrType::RuntimeError, "Invalid company name"});
  }

  const std::string& genericDataLocation = getGenericDataLocation();

  if (genericDataLocation.empty()) {
    return PotentialValue<std::string>({Origin::Output, ErrType::RuntimeError, "Invalid generic data location"});
  }

  const std::string& companyDataLocation = genericDataLocation + "/" + companyName;

  if (!directoryExists(companyDataLocation)) {
    if (!createDirectory(companyDataLocation)) {
      return PotentialValue<std::string>(
          {Origin::Output, ErrType::RuntimeError,
           "Error creating folder " + companyDataLocation + ", " + std::string(strerror(errno))});
    }
  }

  return std::string(companyDataLocation);
}

PotentialValue<std::string> getVSDataLocation() { return getGenericDataLocation(VIDEOSTITCH_SUB_FOLDER); }

}  // namespace Util
}  // namespace VideoStitch