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