summaryrefslogtreecommitdiff
path: root/src/util/directory.cpp
blob: c307066d23b4f3316226c57f9cc3c451c0155f10 (plain)
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/*********
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
* Copyright 1999-2008 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/

#include "util/directory.h"

#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QFileInfoList>
#include <QLocale>


namespace util {
namespace directory {

namespace {

QDir cachedIconDir;
QDir cachedJavascriptDir;
QDir cachedLicenseDir;
QDir cachedPicsDir;
QDir cachedLocaleDir;
QDir cachedHandbookDir;
QDir cachedHowtoDir;
QDir cachedDisplayTemplatesDir;
QDir cachedUserDisplayTemplatesDir;
QDir cachedUserBaseDir;
QDir cachedUserHomeDir;
QDir cachedUserHomeSwordDir;
QDir cachedUserHomeSwordModsDir;
QDir cachedUserSessionsDir;
QDir cachedUserCacheDir;
QDir cachedUserIndexDir;
#ifdef Q_WS_WIN
QDir cachedApplicationSwordDir; // Only Windows installs the sword directory which contains locales.d
QDir cachedSharedSwordDir;
#endif

#ifdef Q_WS_WIN
static const char* BIBLETIME = "Bibletime";
static const char* SWORD_DIR = "Sword";
#else
static const char* BIBLETIME =".bibletime";
static const char* SWORD_DIR = ".sword";
#endif
} // anonymous namespace

bool initDirectoryCache() {
    QDir wDir(QCoreApplication::applicationDirPath());
    wDir.makeAbsolute();

    if (!wDir.cdUp()) { // Installation prefix
        qWarning() << "Cannot cd up from directory " << QCoreApplication::applicationDirPath();
        return false;
    }

#ifdef Q_WS_WIN

    cachedApplicationSwordDir = wDir; // application sword dir for Windows only
    if (!cachedApplicationSwordDir.cd("share/sword") || !cachedApplicationSwordDir.isReadable()) {
        qWarning() << "Cannot find sword directory relative to" << QCoreApplication::applicationDirPath();
        return false;
    }

	cachedSharedSwordDir = QDir(getenv("ALLUSERSPROFILE")); // sword dir for Windows only
    if (!cachedSharedSwordDir.cd("Application Data")) {
        qWarning() << "Cannot find ALLUSERSPROFILE\\Application Data";
        return false;
	}
    if (!cachedSharedSwordDir.cd(SWORD_DIR)) {
        if (!cachedSharedSwordDir.mkdir(SWORD_DIR) || !cachedSharedSwordDir.cd(SWORD_DIR)) {
			qWarning() << "Cannot find ALLUSERSPROFILE\\Application Data\\Sword";
			return false;
		}
    }
#endif

    cachedIconDir = wDir; // Icon dir
    if (!cachedIconDir.cd("share/bibletime/icons") || !cachedIconDir.isReadable()) {
        qWarning() << "Cannot find icon directory relative to" << QCoreApplication::applicationDirPath();
        return false;
    }

    cachedJavascriptDir = wDir;
    if (!cachedJavascriptDir.cd("share/bibletime/javascript") || !cachedJavascriptDir.isReadable()) {
        qWarning() << "Cannot find javascript directory relative to" << QCoreApplication::applicationDirPath();
        return false;
    }

    cachedLicenseDir = wDir;
    if (!cachedLicenseDir.cd("share/bibletime/license") || !cachedLicenseDir.isReadable()) {
        qWarning() << "Cannot find license directory relative to" << QCoreApplication::applicationDirPath();
        return false;
    }

    cachedPicsDir = wDir; //icon dir
    if (!cachedPicsDir.cd("share/bibletime/pics") || !cachedPicsDir.isReadable()) {
        qWarning() << "Cannot find icon directory relative to" << QCoreApplication::applicationDirPath();
        return false;
    }

    cachedLocaleDir = wDir;
    if (!cachedLocaleDir.cd("share/bibletime/locale")) {
        qWarning() << "Cannot find locale directory relative to" << QCoreApplication::applicationDirPath();
        return false;
    }

    QString localeName(QLocale::system().name());
    QString langCode(localeName.section('_', 0, 0));

    cachedHandbookDir = wDir;
    if (!cachedHandbookDir.cd("share/bibletime/docs/handbook/" + localeName)) {
        if (!cachedHandbookDir.cd("share/bibletime/docs/handbook/" + langCode)) {
            if (!cachedHandbookDir.cd("share/bibletime/docs/handbook/en/")) {
                qWarning() << "Cannot find handbook directory relative to" << QCoreApplication::applicationDirPath();
                return false;
            }
        }
    }

    cachedHowtoDir = wDir;
    if (!cachedHowtoDir.cd("share/bibletime/docs/howto/" + localeName)) {
        if (!cachedHowtoDir.cd("share/bibletime/docs/howto/" + langCode)) {
            if (!cachedHowtoDir.cd("share/bibletime/docs/howto/en/")) {
                qWarning() << "Cannot find handbook directory relative to" << QCoreApplication::applicationDirPath();
                return false;
            }
        }
    }

    cachedDisplayTemplatesDir = wDir; //display templates dir
    if (!cachedDisplayTemplatesDir.cd("share/bibletime/display-templates/")) {
        qWarning() << "Cannot find display template directory relative to" << QCoreApplication::applicationDirPath();
        return false;
    }

    cachedUserHomeDir = QDir(getenv("HOME"));

    cachedUserBaseDir = cachedUserHomeDir;
    if (!cachedUserBaseDir.cd(BIBLETIME)) {
        if (!cachedUserBaseDir.mkdir(BIBLETIME) || !cachedUserBaseDir.cd(BIBLETIME)) {
            qWarning() << "Could not create user setting directory.";
            return false;
        }
    }

    cachedUserHomeSwordDir = cachedUserHomeDir;
    if (!cachedUserHomeSwordDir.cd(SWORD_DIR)) {
        if (!cachedUserHomeSwordDir.mkdir(SWORD_DIR) || !cachedUserHomeSwordDir.cd(SWORD_DIR)) {
            qWarning() << "Could not create user home " << SWORD_DIR << " directory.";
            return false;
        }
    }

    cachedUserHomeSwordModsDir = cachedUserHomeSwordDir;
    if (!cachedUserHomeSwordModsDir.cd("mods.d")) {
        if (!cachedUserHomeSwordModsDir.mkdir("mods.d") || !cachedUserHomeSwordModsDir.cd("mods.d")) {
            qWarning() << "Could not create user home " << SWORD_DIR << " mods.d directory.";
            return false;
        }
    }

    cachedUserSessionsDir = cachedUserBaseDir;
    if (!cachedUserSessionsDir.cd("sessions")) {
        if (!cachedUserSessionsDir.mkdir("sessions") || !cachedUserSessionsDir.cd("sessions")) {
            qWarning() << "Could not create user sessions directory.";
            return false;
        }
    }

    cachedUserCacheDir = cachedUserBaseDir;
    if (!cachedUserCacheDir.cd("cache")) {
        if (!cachedUserCacheDir.mkdir("cache") || !cachedUserCacheDir.cd("cache")) {
            qWarning() << "Could not create user cache directory.";
            return false;
        }
    }

    cachedUserIndexDir = cachedUserBaseDir;
    if (!cachedUserIndexDir.cd("indices")) {
        if (!cachedUserIndexDir.mkdir("indices") || !cachedUserIndexDir.cd("indices")) {
            qWarning() << "Could not create user indices directory.";
        }
    }

    cachedUserDisplayTemplatesDir = cachedUserBaseDir;
    if (!cachedUserDisplayTemplatesDir.cd("display-templates")) {
        if (!cachedUserDisplayTemplatesDir.mkdir("display-templates") || !cachedUserDisplayTemplatesDir.cd("display-templates")) {
            qWarning() << "Could not create user display templates directory.";
        }
    }

    return true;
} // bool initDirectoryCache();

void removeRecursive(const QString &dir) {
    //Check for validity of argument
    if (dir.isEmpty()) return;
    QDir d(dir);
    if (!d.exists()) return;

    //remove all files in this dir
    d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
    const QFileInfoList fileList = d.entryInfoList();
    for (QFileInfoList::const_iterator it_file = fileList.begin(); it_file != fileList.end(); it_file++) {
        d.remove( it_file->fileName() );
    }

    //remove all subdirs recursively
    d.setFilter( QDir::Dirs | QDir::NoSymLinks );
    const QFileInfoList dirList = d.entryInfoList();
    for (QFileInfoList::const_iterator it_dir = dirList.begin(); it_dir != dirList.end(); it_dir++) {
        if ( !it_dir->isDir() || it_dir->fileName() == "." || it_dir->fileName() == ".." ) {
            continue;
        }
        removeRecursive( it_dir->absoluteFilePath() );
    }
    d.rmdir(dir);
}

/** Returns the size of the directory including the size of all it's files and it's subdirs.
 */
unsigned long getDirSizeRecursive(const QString &dir) {
    //Check for validity of argument
    QDir d(dir);
    if (!d.exists()) return 0;

    unsigned long size = 0;

    //First get the size of all files int this folder
    d.setFilter(QDir::Files);
    const QFileInfoList infoList = d.entryInfoList();
    for (QFileInfoList::const_iterator it = infoList.begin(); it != infoList.end(); it++) {
        size += it->size();
    }

    //Then add the sizes of all subdirectories
    d.setFilter(QDir::Dirs);
    const QFileInfoList dirInfoList = d.entryInfoList();
    for (QFileInfoList::const_iterator it_dir = dirInfoList.begin(); it_dir != dirInfoList.end(); it_dir++) {
        if ( !it_dir->isDir() || it_dir->fileName() == "." || it_dir->fileName() == ".." ) {
            continue;
        }
        size += getDirSizeRecursive( it_dir->absoluteFilePath() );
    }
    return size;
}

/**Recursively copies a directory, overwriting existing files*/
void copyRecursive(const QString &src, const QString &dest) {
    QDir srcDir(src);
    QDir destDir(dest);
    //Copy files
    QStringList files = srcDir.entryList(QDir::Files);
    for (QStringList::iterator it = files.begin(); it != files.end(); ++it) {
        QFile currFile(src + "/" + *it);
        QString newFileLoc = dest + "/" + *it;
        QFile newFile(newFileLoc);
        newFile.remove();
        currFile.copy(newFileLoc);
    }
    QStringList dirs = srcDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
    for (QStringList::iterator it = dirs.begin(); it != dirs.end(); ++it) {
        QString temp = *it;
        if (!destDir.cd(*it)) {
            destDir.mkdir(*it);
        }
        copyRecursive(src + "/" + *it, dest + "/" + *it);
    }
}

QString convertDirSeparators(const QString& path)
{
	QString result = path;
#ifdef Q_WS_WIN
	result.replace("/", "\\");
#else
	result.replace("\\", "/");
#endif
	return result;
}

#ifdef Q_WS_WIN
QDir getApplicationSwordDir() {
    return cachedApplicationSwordDir;
}

QDir getSharedSwordDir() {
    return cachedSharedSwordDir;
}

#endif

QDir getIconDir() {
    return cachedIconDir;
}

QDir getJavascriptDir() {
    return cachedJavascriptDir;
}

QDir getLicenseDir() {
    return cachedLicenseDir;
}

QIcon getIcon(const QString &name) {
    static QMap<QString, QIcon> iconCache;
    //error if trying to use name directly...
    QString name2(name);
    QString plainName = name2.remove(".svg", Qt::CaseInsensitive);
    if (iconCache.contains(plainName)) {
        return iconCache.value(plainName);
    }

    QString iconDir = getIconDir().canonicalPath();
    QString iconFileName = iconDir + "/" + plainName + ".svg";
    if (QFile(iconFileName).exists()) {
        QIcon ic = QIcon(iconFileName);
        iconCache.insert(plainName, ic);
        return ic;
    }
    else {
        iconFileName = iconDir + "/" + plainName + ".png";
        if (QFile(iconFileName).exists()) {
            QIcon ic = QIcon(iconFileName);
            iconCache.insert(plainName, ic);
            return ic;
        }
        else {
            qWarning() << "Cannot find icon file" << iconFileName << ", using default icon.";
            iconFileName = iconDir + "/" + "/default.svg";
            if (QFile(iconFileName).exists()) {
                return QIcon(iconDir + "/default.svg");
            }
            else {
                return QIcon(iconDir + "default.png");
            }
        }
    }
}

QDir getPicsDir() {
    return cachedPicsDir;
}

QDir getLocaleDir() {
    return cachedLocaleDir;
}

QDir getHandbookDir() {
    return cachedHandbookDir;
}

QDir getHowtoDir() {
    return cachedHowtoDir;
}

QDir getDisplayTemplatesDir() {
    return cachedDisplayTemplatesDir;
}

QDir getUserBaseDir() {
    return cachedUserBaseDir;
}

QDir getUserHomeDir() {
    return cachedUserHomeDir;
}

QDir getUserHomeSwordDir() {
    return cachedUserHomeSwordDir;
}

QDir getUserHomeSwordModsDir() {
    return cachedUserHomeSwordModsDir;
}

QDir getUserSessionsDir() {
    return cachedUserSessionsDir;
}

QDir getUserCacheDir() {
    return cachedUserCacheDir;
}

QDir getUserIndexDir() {
    return cachedUserIndexDir;
}

QDir getUserDisplayTemplatesDir() {
    return cachedUserDisplayTemplatesDir;
}

} // namespace directory
} // namespace util