MythTV  master
mythdirs.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <cstdlib>
3 
4 #include <QtGlobal>
5 #include <QDir>
6 #include <QCoreApplication>
7 
8 #if defined(Q_OS_ANDROID)
9 #include <QStandardPaths>
10 #include <sys/statfs.h>
11 #elif defined(Q_OS_WIN)
12 #include <QStandardPaths>
13 #endif
14 
15 #include "mythdirs.h"
16 #include "mythlogging.h"
17 
18 static QString installprefix;
19 static QString appbindir;
20 static QString sharedir;
21 static QString libdir;
22 static QString confdir;
23 static QString themedir;
24 static QString pluginsdir;
25 static QString translationsdir;
26 static QString filtersdir;
27 static QString cachedir;
28 static QString remotecachedir;
29 static QString themebasecachedir;
30 static QString thumbnaildir;
31 
33 {
34  installprefix = qgetenv( "MYTHTVDIR" );
35  confdir = qgetenv( "MYTHCONFDIR" );
36 
37  if (!confdir.isEmpty())
38  {
39  LOG(VB_GENERAL, LOG_NOTICE, QString("Read conf dir = %1").arg(confdir));
40  confdir.replace("$HOME", QDir::homePath());
41  }
42 
43 #ifdef _WIN32
44 
45  if (installprefix.isEmpty())
46  installprefix = QDir( qApp->applicationDirPath() )
47  .absolutePath();
48 
49  appbindir = installprefix + "/";
50  libdir = appbindir;
51 
52  // Turn into Canonical Path for consistent compares
53 
54  QDir sDir(qgetenv("ProgramData") + "/mythtv/");
55  if (sDir.exists())
56  sharedir = sDir.canonicalPath() + "/";
57 
58  if(sharedir.isEmpty())
59  {
60  sharedir = appbindir + "data/mythtv/";
61  }
62  if (confdir.isEmpty())
63  {
64  confdir = qgetenv( "LOCALAPPDATA" ) + "/mythtv";
65  confdir = QDir(confdir).canonicalPath() + "/";
66  }
67 
68  #if 0
69  // The following code only works for Qt 5.0 and above, but it may
70  // be a generic solution for both windows & linux.
71  // Re-evalute use oce min Qt == 5.0
72 
73  // QStringList sorted by least public to most.
74  // Assume first is private user data and last is shared program data.
75 
76  qApp->setOrganizationName( "mythtv" );
77 
78  QStringList lstPaths = QStandardPaths::standardLocations(
79  QStandardPaths::AppDataLocation);
80 
81  // Remove AppName from end of path
82 
83  QString sAppName = qApp->applicationName();
84  if (!lstPaths.isEmpty())
85  {
86  for (auto &path : lstPaths)
87  {
88  if (path.endsWith(sAppName))
89  path = path.left(path.length() - sAppName.length());
90  LOG(VB_GENERAL, LOG_DEBUG, QString("app data location: %1 (%2)")
91  .arg(path).arg(QDir(path).exists() ? "exists" : "doesn't exist"));
92  }
93 
94  sharedir = lstPaths.last();
95 
96  if (sharedir.endsWith( sAppName ))
97  sharedir = sharedir.left( sharedir.length() - sAppName.length());
98  }
99 
100  lstPaths = QStandardPaths::standardLocations(
101  QStandardPaths::AppConfigLocation);
102  if (!lstPaths.isEmpty())
103  {
104  for (auto &path : lstPaths)
105  {
106  if (path.endsWith(sAppName))
107  path = path.left(path.length() - sAppName.length());
108  LOG(VB_GENERAL, LOG_DEBUG, QString("app config location: %1 (%2)")
109  .arg(path).arg(QDir(path).exists() ? "exists" : "doesn't exist"));
110  }
111 
112  // Only use if user didn't override with env variable.
113  if (confdir.isEmpty())
114  {
115  confdir = lstPaths.first();
116 
117  if (confdir.endsWith( sAppName ))
118  confdir = confdir.left( confdir.length() - sAppName.length());
119  }
120  }
121 
122  #endif
123 
124  if (sharedir.isEmpty())
125  sharedir = confdir;
126  sharedir = QDir(sharedir).canonicalPath() + "/";
127 
128 #elif defined(Q_OS_ANDROID)
129  if (installprefix.isEmpty())
130  installprefix = QDir( qApp->applicationDirPath() )
131  .absolutePath();
132  QString extdir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/Mythtv";
133  if (!QDir(extdir).exists())
134  QDir(extdir).mkdir(".");
135 
136  if (confdir.isEmpty())
137  confdir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
138 
139 #if 0
140  // TODO allow choice of base fs or the SD card for data
141  QStringList appLocs = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
142  uint64_t maxFreeSpace = 0;
143  for(auto s : appLocs)
144  {
145  struct statfs statFs;
146  memset(&statFs, 0, sizeof(statFs));
147  int ret = statfs(s.toLocal8Bit().data(), &statFs);
148  if (ret == 0 && statFs.f_bavail >= maxFreeSpace)
149  {
150  maxFreeSpace = statFs.f_bavail;
151  confdir = s;
152  }
153  LOG(VB_GENERAL, LOG_NOTICE, QString(" appdatadir = %1 (%2, %3, %4)")
154  .arg(s)
155  .arg(statFs.f_bavail)
156  .arg(statFs.f_bfree)
157  .arg(statFs.f_bsize));
158  }
159  QStringList cacheLocs = QStandardPaths::standardLocations(QStandardPaths::CacheLocation);
160  maxFreeSpace = 0;
161  for(auto s : cacheLocs)
162  {
163  struct statfs statFs;
164  memset(&statFs, 0, sizeof(statFs));
165  int ret = statfs(s.toLocal8Bit().data(), &statFs);
166  if (ret == 0 && statFs.f_bavail >= maxFreeSpace)
167  {
168  maxFreeSpace = statFs.f_bavail;
169  //confdir = s;
170  }
171  LOG(VB_GENERAL, LOG_NOTICE, QString(" cachedir = %1 (%2, %3, %4)")
172  .arg(s)
173  .arg(statFs.f_bavail)
174  .arg(statFs.f_bfree)
175  .arg(statFs.f_bsize));
176  }
177 #endif
178 
179  appbindir = installprefix + "/";
180  sharedir = "assets:/mythtv/";
181  libdir = installprefix + "/";
182 
183 
184 #else
185 
186  if (installprefix.isEmpty())
187  installprefix = QString(RUNPREFIX);
188 
189  QDir prefixDir = qApp->applicationDirPath();
190 
191  if (QDir(installprefix).isRelative())
192  {
193  // If the PREFIX is relative, evaluate it relative to our
194  // executable directory. This can be fragile on Unix, so
195  // use relative PREFIX values with care.
196 
197  LOG(VB_GENERAL, LOG_DEBUG, QString("Relative PREFIX! (%1), appDir=%2")
198  .arg(installprefix, prefixDir.canonicalPath()));
199 
200  if (!prefixDir.cd(installprefix))
201  {
202  LOG(VB_GENERAL, LOG_ERR,
203  QString("Relative PREFIX does not resolve, using %1")
204  .arg(prefixDir.canonicalPath()));
205  }
206  installprefix = prefixDir.canonicalPath();
207  }
208 
209  appbindir = installprefix + "/bin/";
210  sharedir = installprefix + "/share/mythtv/";
211  libdir = installprefix + '/' + QString(LIBDIRNAME) + "/mythtv/";
212 
213 #endif
214 
215  if (confdir.isEmpty())
216  confdir = QDir::homePath() + "/.mythtv";
217  cachedir = confdir + "/cache";
218  remotecachedir = cachedir + "/remotecache";
219  themebasecachedir = cachedir + "/themecache";
220  thumbnaildir = cachedir + "/thumbnails";
221 
222 #if defined(Q_OS_ANDROID)
223  themedir = sharedir + "themes/";
224  pluginsdir = libdir;
225  translationsdir = sharedir + "i18n/";
226  filtersdir = libdir;
227 #else
228  themedir = sharedir + "themes/";
229  pluginsdir = libdir + "plugins/";
230  translationsdir = sharedir + "i18n/";
231  filtersdir = libdir + "filters/";
232 #endif
233 
234  LOG(VB_GENERAL, LOG_NOTICE, "Using runtime prefix = " + installprefix);
235  LOG(VB_GENERAL, LOG_NOTICE, QString("Using configuration directory = %1")
236  .arg(confdir));
237 
238  LOG(VB_GENERAL, LOG_DEBUG, "appbindir = "+ appbindir );
239  LOG(VB_GENERAL, LOG_DEBUG, "sharedir = "+ sharedir );
240  LOG(VB_GENERAL, LOG_DEBUG, "libdir = "+ libdir );
241  LOG(VB_GENERAL, LOG_DEBUG, "themedir = "+ themedir );
242  LOG(VB_GENERAL, LOG_DEBUG, "pluginsdir = "+ pluginsdir );
243  LOG(VB_GENERAL, LOG_DEBUG, "translationsdir = "+ translationsdir );
244  LOG(VB_GENERAL, LOG_DEBUG, "filtersdir = "+ filtersdir );
245  LOG(VB_GENERAL, LOG_DEBUG, "confdir = "+ confdir );
246  LOG(VB_GENERAL, LOG_DEBUG, "cachedir = "+ cachedir );
247  LOG(VB_GENERAL, LOG_DEBUG, "remotecachedir = "+ remotecachedir );
248  LOG(VB_GENERAL, LOG_DEBUG, "themebasecachedir = "+ themebasecachedir);
249  LOG(VB_GENERAL, LOG_DEBUG, "thumbnaildir = "+ thumbnaildir);
250 }
251 
252 QString GetInstallPrefix(void) { return installprefix; }
253 QString GetAppBinDir(void) { return appbindir; }
254 QString GetShareDir(void) { return sharedir; }
255 QString GetLibraryDir(void) { return libdir; }
256 QString GetConfDir(void) { return confdir; }
257 QString GetThemesParentDir(void) { return themedir; }
258 QString GetPluginsDir(void) { return pluginsdir; }
259 QString GetTranslationsDir(void) { return translationsdir; }
260 QString GetFiltersDir(void) { return filtersdir; }
261 
266 QString GetCacheDir(void) { return cachedir; }
267 
273 QString GetRemoteCacheDir(void) { return remotecachedir; }
274 
281 QString GetThumbnailDir(void) { return thumbnaildir; }
282 
289 QString GetThemeBaseCacheDir(void) { return themebasecachedir; }
290 
291 // These defines provide portability for different
292 // plugin file names.
293 #ifdef Q_OS_DARWIN
294 static const QString kPluginLibPrefix = "lib";
295 static const QString kPluginLibSuffix = ".dylib";
296 static const QString kFilterLibPrefix = "lib";
297 static const QString kFilterLibSuffix = ".dylib";
298 #elif defined(_WIN32)
299 static const QString kPluginLibPrefix = "lib";
300 static const QString kPluginLibSuffix = ".dll";
301 static const QString kFilterLibPrefix = "lib";
302 static const QString kFilterLibSuffix = ".dll";
303 #elif defined(Q_OS_ANDROID)
304 static const QString kPluginLibPrefix = "libmythplugin";
305 static const QString kPluginLibSuffix = ".so";
306 static const QString kFilterLibPrefix = "libmythfilter";
307 static const QString kFilterLibSuffix = ".so";
308 #else
309 static const QString kPluginLibPrefix = "lib";
310 static const QString kPluginLibSuffix = ".so";
311 static const QString kFilterLibPrefix = "lib";
312 static const QString kFilterLibSuffix = ".so";
313 #endif
314 
315 QString GetFiltersNameFilter(void)
316 {
317  return kFilterLibPrefix + '*' + kFilterLibSuffix;
318 }
319 
320 QString GetPluginsNameFilter(void)
321 {
322  return kPluginLibPrefix + '*' + kPluginLibSuffix;
323 }
324 
325 QString FindPluginName(const QString &plugname)
326 {
327  return GetPluginsDir() + kPluginLibPrefix + plugname + kPluginLibSuffix;
328 }
329 
331 {
332  return "mythfrontend_*.qm";
333 }
334 
335 QString FindTranslation(const QString &translation)
336 {
337  return GetTranslationsDir()
338  + "mythfrontend_" + translation.toLower() + ".qm";
339 }
340 
341 QString GetFontsDir(void)
342 {
343  return GetShareDir() + "fonts/";
344 }
GetThemesParentDir
QString GetThemesParentDir(void)
Definition: mythdirs.cpp:257
themedir
static QString themedir
Definition: mythdirs.cpp:23
libdir
static QString libdir
Definition: mythdirs.cpp:21
installprefix
static QString installprefix
Definition: mythdirs.cpp:18
kFilterLibSuffix
static const QString kFilterLibSuffix
Definition: mythdirs.cpp:302
GetLibraryDir
QString GetLibraryDir(void)
Definition: mythdirs.cpp:255
xbmcvfs.exists
bool exists(str path)
Definition: xbmcvfs.py:51
GetFontsDir
QString GetFontsDir(void)
Definition: mythdirs.cpp:341
kPluginLibPrefix
static const QString kPluginLibPrefix
Definition: mythdirs.cpp:299
confdir
static QString confdir
Definition: mythdirs.cpp:22
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
GetPluginsDir
QString GetPluginsDir(void)
Definition: mythdirs.cpp:258
GetCacheDir
QString GetCacheDir(void)
Returns the base directory for all cached files.
Definition: mythdirs.cpp:266
mythdirs.h
InitializeMythDirs
void InitializeMythDirs(void)
Definition: mythdirs.cpp:32
GetFiltersNameFilter
QString GetFiltersNameFilter(void)
Definition: mythdirs.cpp:315
GetInstallPrefix
QString GetInstallPrefix(void)
Definition: mythdirs.cpp:252
themebasecachedir
static QString themebasecachedir
Definition: mythdirs.cpp:29
GetPluginsNameFilter
QString GetPluginsNameFilter(void)
Definition: mythdirs.cpp:320
mythlogging.h
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:256
statfs
int statfs(const char *path, struct statfs *buffer)
Definition: compat.h:105
GetShareDir
QString GetShareDir(void)
Definition: mythdirs.cpp:254
GetThemeBaseCacheDir
QString GetThemeBaseCacheDir(void)
Returns the base directory where all theme related files should be cached.
Definition: mythdirs.cpp:289
translationsdir
static QString translationsdir
Definition: mythdirs.cpp:25
kFilterLibPrefix
static const QString kFilterLibPrefix
Definition: mythdirs.cpp:301
GetThumbnailDir
QString GetThumbnailDir(void)
Returns the directory where all non-theme thumbnail files should be cached.
Definition: mythdirs.cpp:281
GetRemoteCacheDir
QString GetRemoteCacheDir(void)
Returns the directory for all files cached from the backend.
Definition: mythdirs.cpp:273
GetFiltersDir
QString GetFiltersDir(void)
Definition: mythdirs.cpp:260
appbindir
static QString appbindir
Definition: mythdirs.cpp:19
remotecachedir
static QString remotecachedir
Definition: mythdirs.cpp:28
statfs
Definition: compat.h:93
statfs::f_bsize
long f_bsize
Definition: compat.h:95
GetAppBinDir
QString GetAppBinDir(void)
Definition: mythdirs.cpp:253
filtersdir
static QString filtersdir
Definition: mythdirs.cpp:26
statfs::f_bavail
long f_bavail
Definition: compat.h:98
pluginsdir
static QString pluginsdir
Definition: mythdirs.cpp:24
thumbnaildir
static QString thumbnaildir
Definition: mythdirs.cpp:30
kPluginLibSuffix
static const QString kPluginLibSuffix
Definition: mythdirs.cpp:300
GetTranslationsDir
QString GetTranslationsDir(void)
Definition: mythdirs.cpp:259
FindPluginName
QString FindPluginName(const QString &plugname)
Definition: mythdirs.cpp:325
sharedir
static QString sharedir
Definition: mythdirs.cpp:20
GetTranslationsNameFilter
QString GetTranslationsNameFilter(void)
Definition: mythdirs.cpp:330
FindTranslation
QString FindTranslation(const QString &translation)
Definition: mythdirs.cpp:335
cachedir
static QString cachedir
Definition: mythdirs.cpp:27