1 /*****************************************************************************
2 ** QNapi
3 ** Copyright (C) 2008-2017 Piotr Krzemiński <pio.krzeminski@gmail.com>
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12 **
13 *****************************************************************************/
14
15 #include "configreader.h"
16 #include <QCoreApplication>
17 #include <QDir>
18 #include <QFileInfo>
19 #include <QLocale>
20 #include <QProcess>
21 #include "subtitlelanguage.h"
22
ConfigReader(const QString & appExecutableDir,const QSharedPointer<const StaticConfig> & staticConfig,const QSharedPointer<const SubtitleDownloadEnginesRegistry> enginesRegistry)23 ConfigReader::ConfigReader(
24 const QString& appExecutableDir,
25 const QSharedPointer<const StaticConfig>& staticConfig,
26 const QSharedPointer<const SubtitleDownloadEnginesRegistry> enginesRegistry)
27 : appExecutableDir(appExecutableDir),
28 staticConfig(staticConfig),
29 enginesRegistry(enginesRegistry) {}
30
readUserConfig() const31 const QNapiConfig ConfigReader::readUserConfig() const {
32 return readConfig(
33 QSettings(QSettings::IniFormat, QSettings::UserScope, "qnapi"));
34 }
35
readPortableConfig(const QString & configFilePath) const36 const QNapiConfig ConfigReader::readPortableConfig(
37 const QString& configFilePath) const {
38 return readConfig(QSettings(configFilePath, QSettings::IniFormat));
39 }
40
readConfig(const QSettings & settings) const41 const QNapiConfig ConfigReader::readConfig(const QSettings& settings) const {
42 return QNapiConfig(settings.value("qnapi/firstrun", true).toBool(),
43 settings.value("qnapi/version", "").toString(),
44 readGeneralConfig(settings), readEnabledEngines(settings),
45 readEnginesConfig(settings),
46 readPostProcessingConfig(settings),
47 readScanConfig(settings),
48 settings.value("qnapi/last_opened_dir", "").toString());
49 }
50
readGeneralConfig(const QSettings & settings) const51 const GeneralConfig ConfigReader::readGeneralConfig(
52 const QSettings& settings) const {
53 QString sysLangCode = QLocale::system().name().left(2);
54 QString preferredLangCode =
55 SubtitleLanguage().listLanguageTwoLetterCodes().contains(sysLangCode)
56 ? sysLangCode
57 : "en";
58 QString backupLangCode = (preferredLangCode != "en") ? "en" : "";
59
60 auto cfg = GeneralConfig(
61 settings.value("qnapi/ui_language", "").toString(),
62 settings.value("qnapi/7z_path", "").toString(),
63 settings.value("qnapi/tmp_path", "").toString(),
64 settings.value("qnapi/language", preferredLangCode).toString(),
65 settings.value("qnapi/language_backup", backupLangCode).toString(),
66 settings.value("qnapi/no_backup", false).toBool(),
67 settings.value("qnapi/quiet_batch", false).toBool(),
68 static_cast<SearchPolicy>(
69 settings.value("qnapi/search_policy", SP_BREAK_IF_FOUND).toInt()),
70 static_cast<DownloadPolicy>(
71 settings.value("qnapi/download_policy", DP_SHOW_LIST_IF_NEEDED)
72 .toInt()),
73 settings.value("qnapi/change_permissions", false).toBool(),
74 settings.value("qnapi/permissions", "644").toString());
75
76 auto cfg1 = resolveP7zipPath(cfg);
77 auto cfg2 = resolveTmpPath(cfg1);
78 return cfg2;
79 }
80
readEnabledEngines(const QSettings & settings) const81 const QList<QPair<QString, bool>> ConfigReader::readEnabledEngines(
82 const QSettings& settings) const {
83 QList<QPair<QString, bool>> defaultEnabledEngines;
84 foreach (QString engineName, enginesRegistry->listEngineNames()) {
85 defaultEnabledEngines << qMakePair(engineName, true);
86 }
87
88 QStringList enabledEnginesStr =
89 settings.value("qnapi/engines", QStringList()).toStringList();
90
91 if (enabledEnginesStr.size() != enginesRegistry->listEngineNames().size()) {
92 return defaultEnabledEngines;
93 } else {
94 QList<QPair<QString, bool>> enabledEngines;
95 foreach (QString engineEnableStr, enabledEnginesStr) {
96 QStringList engineParts =
97 engineEnableStr.split(":", QString::SkipEmptyParts);
98 if (engineParts.size() != 2) {
99 return defaultEnabledEngines;
100 }
101 enabledEngines << qMakePair(engineParts[0], engineParts[1] == "on");
102 }
103 return enabledEngines;
104 }
105 }
106
readEnginesConfig(const QSettings & settings) const107 const QMap<QString, EngineConfig> ConfigReader::readEnginesConfig(
108 const QSettings& settings) const {
109 QMap<QString, EngineConfig> engineConfigurations;
110 foreach (QString engineName, enginesRegistry->listEngineNames()) {
111 engineConfigurations.insert(engineName,
112 readEngineConfig(engineName, settings));
113 }
114 return engineConfigurations;
115 }
116
readEngineConfig(QString engineName,const QSettings & settings) const117 const EngineConfig ConfigReader::readEngineConfig(
118 QString engineName, const QSettings& settings) const {
119 return EngineConfig(settings.value(engineName + "/nick", "").toString(),
120 settings.value(engineName + "/password", "").toString());
121 }
122
readPostProcessingConfig(const QSettings & settings) const123 const PostProcessingConfig ConfigReader::readPostProcessingConfig(
124 const QSettings& settings) const {
125 return PostProcessingConfig(
126 settings.value("qnapi/post_processing", true).toBool(),
127 static_cast<EncodingChangeMethod>(
128 settings.value("qnapi/encoding_method", ECM_CHANGE).toInt()),
129 settings.value("qnapi/enc_from", "windows-1250").toString(),
130 settings.value("qnapi/auto_detect_encoding", true).toBool(),
131 settings.value("qnapi/enc_to", "UTF-8").toString(),
132 settings.value("qnapi/show_all_encodings", false).toBool(),
133 settings.value("qnapi/sub_format", "srt").toString(),
134 settings.value("qnapi/sub_ext", "").toString(),
135 settings.value("qnapi/skip_convert_ads", false).toBool(),
136 settings.value("qnapi/remove_lines", false).toBool(),
137 settings
138 .value("qnapi/remove_words", QStringList() << "movie info"
139 << "synchro")
140 .toStringList());
141 }
142
readScanConfig(const QSettings & settings) const143 const ScanConfig ConfigReader::readScanConfig(const QSettings& settings) const {
144 return ScanConfig(
145 settings.value("scan/last_scan_dir", "").toString(),
146 settings.value("scan/skip_if_subtitles_exist", false).toBool(),
147 settings.value("scan/filters", QStringList()).toStringList(),
148 settings.value("scan/skip_filters", "PL dubbing").toString());
149 }
150
resolveP7zipPath(const GeneralConfig & config) const151 const GeneralConfig ConfigReader::resolveP7zipPath(
152 const GeneralConfig& config) const {
153 if (QFileInfo(config.p7zipPath()).isExecutable()) {
154 return config;
155 } else {
156 QString p7zipPath = "";
157
158 #if defined(Q_OS_MAC)
159 p7zipPath =
160 QFileInfo(appExecutableDir + "/../Resources/7za").absoluteFilePath();
161 #elif defined(Q_OS_WIN)
162 p7zipPath = QFileInfo(appExecutableDir + "/7za.exe").absoluteFilePath();
163 #else
164 QString pathEnv =
165 QProcess::systemEnvironment().filter(QRegExp("^PATH=(.*)$")).value(0);
166 QStringList sysPaths = pathEnv.mid(5).split(":");
167 sysPaths.removeAll("");
168 sysPaths.append(".");
169
170 if (sysPaths.isEmpty()) {
171 sysPaths << "/bin"
172 << "/usr/bin"
173 << "/usr/local/bin";
174 }
175
176 sysPaths << appExecutableDir;
177
178 QStringList p7zipBinaries = {"7z", "7za"};
179
180 foreach (const QString sysPath, sysPaths) {
181 foreach (const QString p7zipBinary, p7zipBinaries) {
182 QFileInfo fi(sysPath + QDir::separator() + p7zipBinary);
183 if (fi.isExecutable()) {
184 p7zipPath = fi.absoluteFilePath();
185 break;
186 }
187 }
188
189 if (!p7zipPath.isEmpty()) {
190 break;
191 }
192 }
193
194 if (p7zipPath.isEmpty()) {
195 p7zipPath = "7z";
196 }
197 #endif
198
199 return config.setP7zipPath(p7zipPath);
200 }
201 }
202
resolveTmpPath(const GeneralConfig & config) const203 const GeneralConfig ConfigReader::resolveTmpPath(
204 const GeneralConfig& config) const {
205 QFileInfo fi(config.tmpPath());
206
207 if (fi.isDir() && fi.isWritable()) {
208 return config;
209 } else {
210 return config.setTmpPath(QDir::tempPath());
211 }
212 }
213