1 /*
2  * Copyright 2017 CodiLime
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #include "util/settings/connection_client.h"
18 
19 #include <QApplication>
20 #include <QDir>
21 #include <QFileInfo>
22 #include <QSettings>
23 #include <QStandardPaths>
24 
25 #include "util/random.h"
26 
27 namespace veles {
28 namespace util {
29 namespace settings {
30 namespace connection {
31 
32 bool default_run_server = true;
33 QString localhost("127.0.0.1");
34 QString default_database_file("veles.vdb");
35 int default_server_port = 3135;
36 QString default_default_profile("local server");
37 QString current_profile;
38 
setDefaultProfile(const QString & profile)39 void setDefaultProfile(const QString& profile) {
40   QSettings settings;
41   settings.setValue("default_profile", profile);
42 }
43 
currentProfile()44 QString currentProfile() {
45   if (current_profile.isEmpty()) {
46     QSettings settings;
47     current_profile =
48         settings.value("default_profile", default_default_profile).toString();
49   }
50   return current_profile;
51 }
52 
setCurrentProfile(const QString & profile)53 void setCurrentProfile(const QString& profile) { current_profile = profile; }
54 
removeProfile(const QString & profile)55 void removeProfile(const QString& profile) {
56   QSettings settings;
57   QMap<QString, QVariant> profiles = settings.value("profiles").toMap();
58   profiles.remove(profile);
59   if (profiles.empty()) {
60     settings.remove("profiles");
61   } else {
62     settings.setValue("profiles", profiles);
63   }
64   if (profile == currentProfile()) {
65     auto profiles = profileList();
66     if (profiles.empty()) {
67       setCurrentProfile(default_default_profile);
68     } else {
69       setCurrentProfile(profiles[0]);
70     }
71   }
72 
73   if (profile == settings.value("default_profile")) {
74     settings.remove("default_profile");
75   }
76 }
77 
profileList()78 QStringList profileList() {
79   QSettings settings;
80   QMap<QString, QVariant> default_profiles;
81   default_profiles[default_default_profile] = QSettings::SettingsMap();
82   QMap<QString, QVariant> profiles =
83       settings.value("profiles", default_profiles).toMap();
84   return profiles.keys();
85 }
86 
profileSettings(const QString & key,const QVariant & defaultValue)87 QVariant profileSettings(const QString& key, const QVariant& defaultValue) {
88   QSettings settings;
89   QMap<QString, QVariant> profiles =
90       settings.value("profiles", QSettings::SettingsMap()).toMap();
91   QSettings::SettingsMap profile_settings =
92       profiles.value(currentProfile(), QSettings::SettingsMap()).toMap();
93   return profile_settings.value(key, defaultValue);
94 }
95 
setProfileSettings(const QString & key,const QVariant & value)96 void setProfileSettings(const QString& key, const QVariant& value) {
97   QSettings settings;
98   QMap<QString, QVariant> profiles = settings.value("profiles").toMap();
99   QSettings::SettingsMap profile = profiles[currentProfile()].toMap();
100   profile[key] = value;
101   profiles[currentProfile()] = profile;
102   settings.setValue("profiles", profiles);
103 }
104 
uniqueProfileName(const QString & prefix)105 QString uniqueProfileName(const QString& prefix) {
106   auto profile_list = profileList();
107   int next_id = 0;
108   QString suffix;
109   while (profile_list.contains(prefix + suffix)) {
110     suffix = " (" + QString::number(next_id++) + ")";
111   }
112   return prefix + suffix;
113 }
114 
runServerDefault()115 bool runServerDefault() { return default_run_server; }
116 
runServer()117 bool runServer() {
118   return profileSettings("connection.run_server", runServerDefault()).toBool();
119 }
120 
setRunServer(bool run_server)121 void setRunServer(bool run_server) {
122   setProfileSettings("connection.run_server", run_server);
123 }
124 
serverHostDefault()125 QString serverHostDefault() { return localhost; }
126 
serverHost()127 QString serverHost() {
128   return profileSettings("connection.server", serverHostDefault()).toString();
129 }
130 
setServerHost(const QString & server_host)131 void setServerHost(const QString& server_host) {
132   setProfileSettings("connection.server", server_host);
133 }
134 
serverPortDefault()135 int serverPortDefault() { return default_server_port; }
136 
serverPort()137 int serverPort() {
138   return profileSettings("connection.server_port", serverPortDefault()).toInt();
139 }
140 
setServerPort(int server_port)141 void setServerPort(int server_port) {
142   setProfileSettings("connection.server_port", server_port);
143 }
144 
clientName()145 QString clientName() {
146   return profileSettings("connection.client_name", clientNameDefault())
147       .toString();
148 }
149 
clientNameDefault()150 QString clientNameDefault() {
151   QString user_name;
152 #if defined(Q_OS_LINUX) || defined(Q_OS_MAC)
153   user_name = qgetenv("USER");
154 #elif defined(Q_OS_WIN)
155   user_name = qgetenv("USERNAME");
156 #else
157   user_name = "Veles UI";
158 #endif
159 
160   if (user_name.length() == 0) {
161     user_name = "Veles UI";
162   }
163 
164   return user_name;
165 }
166 
setClientName(const QString & client_name)167 void setClientName(const QString& client_name) {
168   setProfileSettings("connection.client_name", client_name);
169 }
170 
connectionKeyDefault()171 QString connectionKeyDefault() {
172   return util::generateSecureRandomConnectionKey();
173 }
174 
connectionKey()175 QString connectionKey() {
176   return profileSettings("connection.key", connectionKeyDefault()).toString();
177 }
178 
setConnectionKey(const QString & connection_key)179 void setConnectionKey(const QString& connection_key) {
180   QSettings settings;
181   setProfileSettings("connection.key", connection_key);
182 }
183 
databaseNameDefault()184 QString databaseNameDefault() {
185   return QStandardPaths::writableLocation(
186              QStandardPaths::AppLocalDataLocation) +
187          "/" + default_database_file;
188 }
189 
databaseName()190 QString databaseName() {
191   return profileSettings("connection.database", databaseNameDefault())
192       .toString();
193 }
194 
setDatabaseName(const QString & database_name)195 void setDatabaseName(const QString& database_name) {
196   setProfileSettings("connection.database", database_name);
197 }
198 
serverScriptDefault()199 QString serverScriptDefault() {
200   QString server_script;
201 #if defined(Q_OS_WIN)
202   server_script = qApp->applicationDirPath() + "/../veles-server/srv.py";
203 #elif defined(Q_OS_LINUX)
204   server_script = qApp->applicationDirPath() + "/../share/veles-server/srv.py";
205 #elif defined(Q_OS_FREEBSD)
206   server_script = qApp->applicationDirPath() + "/veles-server";
207 #elif defined(Q_OS_MAC)
208   server_script =
209       qApp->applicationDirPath() + "/../Resources/veles-server/srv.py";
210 #else
211 #warning \
212     "This OS is not officially supported, you may need to set this path manually."
213 #endif
214   QFileInfo check_file(server_script);
215   if (!check_file.exists()) {
216     server_script = qApp->applicationDirPath() + "/python/srv.py";
217   }
218   return QDir::cleanPath(server_script);
219 }
220 
serverScript()221 QString serverScript() {
222   return profileSettings("connection.server_script", serverScriptDefault())
223       .toString();
224 }
225 
setServerScript(const QString & server_script)226 void setServerScript(const QString& server_script) {
227   setProfileSettings("connection.server_script", server_script);
228 }
229 
certDirectoryDefault()230 QString certDirectoryDefault() {
231   return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
232 }
233 
certDirectory()234 QString certDirectory() {
235   return profileSettings("connection.cert_dir", certDirectoryDefault())
236       .toString();
237 }
238 
setCertDirectory(const QString & cert_directory)239 void setCertDirectory(const QString& cert_directory) {
240   setProfileSettings("connection.cert_dir", cert_directory);
241 }
242 
serverUrlDefault()243 QString serverUrlDefault() { return ""; }
244 
serverUrl()245 QString serverUrl() {
246   return profileSettings("connection.server_url", serverUrlDefault())
247       .toString();
248 }
249 
setServerUrl(const QString & server_url)250 void setServerUrl(const QString& server_url) {
251   setProfileSettings("connection.server_url", server_url);
252 }
253 
sslEnabledDefault()254 bool sslEnabledDefault() { return true; }
255 
sslEnabled()256 bool sslEnabled() {
257   return profileSettings("connection.ssl_enabled", sslEnabledDefault())
258       .toBool();
259 }
260 
setSslEnabled(bool ssl_enabled)261 void setSslEnabled(bool ssl_enabled) {
262   setProfileSettings("connection.ssl_enabled", ssl_enabled);
263 }
264 
265 }  // namespace connection
266 }  // namespace settings
267 }  // namespace util
268 }  // namespace veles
269