1 /**********************************************************************************************
2     Copyright (C) 2017 Norbert Truchsess <norbert.truchsess@t-online.de>
3 
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 **********************************************************************************************/
18 
19 #include "gis/rte/router/brouter/CRouterBRouterSetup.h"
20 
21 #include "helpers/CSettings.h"
22 #include "setup/IAppSetup.h"
23 #include <QJSEngine>
24 #include <QMessageBox>
25 #include <QNetworkReply>
26 #include <QWebEnginePage>
27 
CRouterBRouterSetup(QObject * parent)28 CRouterBRouterSetup::CRouterBRouterSetup(QObject* parent)
29     : QObject(parent)
30 {
31     networkAccessManager = new QNetworkAccessManager(this);
32     profilesWebPage = new QWebEnginePage(this);
33     connect(networkAccessManager, &QNetworkAccessManager::finished, this, &CRouterBRouterSetup::slotOnlineRequestFinished);
34     connect(profilesWebPage, &QWebEnginePage::loadFinished, this, &CRouterBRouterSetup::slotLoadOnlineProfilesRequestFinished);
35 }
36 
~CRouterBRouterSetup()37 CRouterBRouterSetup::~CRouterBRouterSetup()
38 {
39 }
40 
load()41 void CRouterBRouterSetup::load()
42 {
43     SETTINGS;
44     cfg.beginGroup("Route/brouter");
45     installMode = modeFromString(cfg.value("installMode", stringFromMode(defaultInstallMode)).toString());
46     expertMode = cfg.value("expertMode", defaultExpertMode).toBool();
47     expertConfigUrl = cfg.value("expertConfigUrl", defaultConfigUrl).toString();
48     onlineServiceUrl = cfg.value("onlineServiceUrl", defaultOnlineServiceUrl).toString();
49     onlineProfilesUrl = cfg.value("onlineProfilesUrl", defaultOnlineProfilesUrl).toString();
50     localDir = cfg.value("localDir", defaultLocalDir).toString();
51     localJavaExecutable = cfg.value("localJava", findJava()).toString();
52     localProfileDir = cfg.value("localProfileDir", defaultLocalProfileDir).toString();
53     localCustomProfileDir = cfg.value("localCustomProfileDir", defaultLocalCustomProfileDir).toString();
54     localSegmentsDir = cfg.value("localSegmentsDir", defaultLocalSegmentsDir).toString();
55     localHost = cfg.value("localHost", defaultLocalHost).toString();
56     localPort = cfg.value("localPort", defaultLocalPort).toString();
57     localBindLocalonly = cfg.value("localBindLocalonly", defaultLocalBindLocalonly).toBool();
58     localNumberThreads = cfg.value("localNumberThreads", defaultLocalNumberThreads).toString();
59     localMaxRunningTime = cfg.value("localMaxRunningTime", defaultLocalMaxRunningTime).toString();
60     localJavaOpts = cfg.value("localJavaOpts", defaultLocalJavaOpts).toString();
61     expertBinariesUrl = cfg.value("expertBinariesUrl", defaultBinariesUrl).toString();
62     expertSegmentsUrl = cfg.value("expertSegmentsUrl", defaultSegmentsUrl).toString();
63     onlineProfiles.clear();
64     int size = cfg.beginReadArray("online");
65     for (int i = 0; i < size; i++)
66     {
67         cfg.setArrayIndex(i);
68         onlineProfiles << cfg.value("profile").toString();
69     }
70     cfg.endArray();
71     localProfiles.clear();
72     size = cfg.beginReadArray("local");
73     for (int i = 0; i < size; i++)
74     {
75         cfg.setArrayIndex(i);
76         localProfiles << cfg.value("profile").toString();
77     }
78     cfg.endArray();
79     cfg.endGroup();
80 
81     if (installMode == eModeLocal)
82     {
83         readLocalProfiles();
84     }
85     else if (installMode == eModeOnline)
86     {
87         if (!expertMode)
88         {
89             loadOnlineConfig(true);
90         }
91     }
92     else
93     {
94         onInvalidSetup();
95     }
96 }
97 
save()98 void CRouterBRouterSetup::save()
99 {
100     SETTINGS;
101     cfg.beginGroup("Route/brouter");
102     cfg.setValue("expertMode", expertMode);
103     cfg.setValue("installMode", stringFromMode(installMode));
104     cfg.setValue("expertConfigUrl", expertConfigUrl);
105     cfg.setValue("onlineServiceUrl", onlineServiceUrl);
106     cfg.setValue("onlineProfilesUrl", onlineProfilesUrl);
107     cfg.setValue("localDir", localDir);
108     cfg.setValue("localJava", localJavaExecutable);
109     cfg.setValue("localProfileDir", localProfileDir);
110     cfg.setValue("localCustomProfileDir", localCustomProfileDir);
111     cfg.setValue("localSegmentsDir", localSegmentsDir);
112     cfg.setValue("localHost", localHost);
113     cfg.setValue("localPort", localPort);
114     cfg.setValue("localBindLocalonly", localBindLocalonly);
115     cfg.setValue("localNumberThreads", localNumberThreads);
116     cfg.setValue("localMaxRunningTime", localMaxRunningTime);
117     cfg.setValue("localJavaOpts", localJavaOpts);
118     cfg.setValue("expertBinariesUrl", expertBinariesUrl);
119     cfg.setValue("expertSegmentsUrl", expertSegmentsUrl);
120     cfg.beginWriteArray("online");
121     for (int i = 0; i < onlineProfiles.size(); i++)
122     {
123         cfg.setArrayIndex(i);
124         cfg.setValue("profile", onlineProfiles.at(i));
125     }
126     cfg.endArray();
127     cfg.beginWriteArray("local");
128     for (int i = 0; i < localProfiles.size(); i++)
129     {
130         cfg.setArrayIndex(i);
131         cfg.setValue("profile", localProfiles.at(i));
132     }
133     cfg.endArray();
134     cfg.endGroup();
135 }
136 
resetAll()137 void CRouterBRouterSetup::resetAll()
138 {
139     resetInstallMode();
140     resetOnlineConfigUrl();
141     resetOnlineServiceUrl();
142     resetOnlineProfilesUrl();
143     resetLocalProfileDir();
144     resetLocalCustomProfileDir();
145     resetLocalSegmentsDir();
146     resetLocalHost();
147     resetLocalPort();
148     resetLocalBindLocalonly();
149     resetLocalNumberThreads();
150     resetLocalMaxRunningTime();
151     resetLocalJavaOpts();
152     resetBinariesUrl();
153     resetSegmentsUrl();
154 }
155 
modeFromString(const QString & mode) const156 CRouterBRouterSetup::mode_e CRouterBRouterSetup::modeFromString(const QString& mode) const
157 {
158     if (mode == "online")
159     {
160         return eModeOnline;
161     }
162     else if (mode == "local")
163     {
164         return eModeLocal;
165     }
166     else
167     {
168         return eModeIllegal;
169     }
170 }
171 
stringFromMode(const mode_e mode) const172 QString CRouterBRouterSetup::stringFromMode(const mode_e mode) const
173 {
174     if (mode == eModeLocal)
175     {
176         return "local";
177     }
178     else
179     {
180         Q_ASSERT(mode == eModeOnline);
181         return "online";
182     }
183 }
184 
addProfile(const QString & profile)185 void CRouterBRouterSetup::addProfile(const QString& profile)
186 {
187     if (installMode == eModeLocal)
188     {
189         loadOnlineProfileAsync(profile, eProfileInstall);
190     }
191     else
192     {
193         Q_ASSERT(installMode == eModeOnline);
194         if (!onlineProfiles.contains(profile))
195         {
196             onlineProfiles << profile;
197             emit sigProfilesChanged();
198         }
199     }
200 }
201 
deleteProfile(const QString & profile)202 void CRouterBRouterSetup::deleteProfile(const QString& profile)
203 {
204     if (installMode == eModeLocal)
205     {
206         const QString& filename = getProfileDir(eModeLocal).absoluteFilePath(profile + ".brf");
207         QFile file(filename);
208         if (file.exists())
209         {
210             file.remove();
211         }
212         if (localProfiles.contains(profile))
213         {
214             localProfiles.removeAt(localProfiles.indexOf(profile));
215             emit sigProfilesChanged();
216         }
217     }
218     else
219     {
220         Q_ASSERT(installMode == eModeOnline);
221         onlineProfiles.removeAt(onlineProfiles.indexOf(profile));
222         emit sigProfilesChanged();
223     }
224 }
225 
profileUp(const QString & profile)226 void CRouterBRouterSetup::profileUp(const QString& profile)
227 {
228     if (installMode == eModeLocal)
229     {
230         int index = localProfiles.indexOf(profile);
231         if (index > 0)
232         {
233             localProfiles.removeAt(index);
234             localProfiles.insert(index - 1, profile);
235             emit sigProfilesChanged();
236         }
237     }
238     else
239     {
240         Q_ASSERT(installMode == eModeOnline);
241         int index = onlineProfiles.indexOf(profile);
242         if (index > 0)
243         {
244             onlineProfiles.removeAt(index);
245             onlineProfiles.insert(index - 1, profile);
246             emit sigProfilesChanged();
247         }
248     }
249 }
250 
profileDown(const QString & profile)251 void CRouterBRouterSetup::profileDown(const QString& profile)
252 {
253     if (installMode == eModeLocal)
254     {
255         int index = localProfiles.indexOf(profile);
256         if (index > -1 && index < localProfiles.size() - 1)
257         {
258             localProfiles.removeAt(index);
259             localProfiles.insert(index + 1, profile);
260             emit sigProfilesChanged();
261         }
262     }
263     else
264     {
265         Q_ASSERT(installMode == eModeOnline);
266         int index = onlineProfiles.indexOf(profile);
267         if (index > -1 && index < onlineProfiles.size() - 1)
268         {
269             onlineProfiles.removeAt(index);
270             onlineProfiles.insert(index + 1, profile);
271             emit sigProfilesChanged();
272         }
273     }
274 }
275 
readLocalProfiles()276 void CRouterBRouterSetup::readLocalProfiles()
277 {
278     bool changed(false);
279     const QDir& dir = getProfileDir(eModeLocal);
280     QStringList installedProfiles;
281     if (dir.exists())
282     {
283         const QStringList& profiles = dir.entryList();
284         for(const QString& profile : profiles)
285         {
286             if (profile.endsWith(".brf"))
287             {
288                 installedProfiles << profile.left(profile.length() - 4);
289             }
290         }
291     }
292     const QStringList localProfilesTmp(localProfiles);
293     for (const QString& profile : localProfilesTmp)
294     {
295         if (!installedProfiles.contains(profile))
296         {
297             localProfiles.removeAt(localProfiles.indexOf(profile));
298             changed = true;
299         }
300     }
301     for (const QString& profile : qAsConst(installedProfiles))
302     {
303         if (!localProfiles.contains(profile))
304         {
305             localProfiles << profile;
306             changed = true;
307         }
308     }
309     if (changed)
310     {
311         emit sigProfilesChanged();
312     }
313 }
314 
getProfileDir(const mode_e mode) const315 QDir CRouterBRouterSetup::getProfileDir(const mode_e mode) const
316 {
317     if (mode == eModeLocal)
318     {
319         return QDir(QDir(localDir).absoluteFilePath(localProfileDir));
320     }
321     else
322     {
323         Q_ASSERT(mode == eModeOnline);
324         QDir brouterDir(QDir(IAppSetup::getPlatformInstance()->defaultCachePath()).absoluteFilePath(onlineCacheDir));
325         if (!brouterDir.exists())
326         {
327             brouterDir.mkpath(brouterDir.absolutePath());
328         }
329         return brouterDir;
330     }
331 }
332 
getProfiles() const333 QStringList CRouterBRouterSetup::getProfiles() const
334 {
335     if (installMode == eModeLocal)
336     {
337         return localProfiles;
338     }
339     else
340     {
341         Q_ASSERT(installMode == eModeOnline);
342         return onlineProfiles;
343     }
344 }
345 
loadLocalOnlineProfiles(bool update) const346 void CRouterBRouterSetup::loadLocalOnlineProfiles(bool update) const
347 {
348     profilesWebPage->setProperty("update", update);
349     profilesWebPage->load(QUrl(onlineProfilesUrl));
350 }
351 
loadOnlineConfig(bool update) const352 void CRouterBRouterSetup::loadOnlineConfig(bool update) const
353 {
354     const QUrl configUrl(getConfigUrl());
355     const QString& configHost = configUrl.host();
356     const QString& configScheme = configUrl.scheme();
357 
358     QNetworkReply* reply = networkAccessManager->get(QNetworkRequest(configUrl));
359     reply->setProperty("configHost", configHost);
360     reply->setProperty("configScheme", configScheme);
361     reply->setProperty("type", eTypeConfig);
362     reply->setProperty("update", update);
363 }
364 
loadOnlineVersion() const365 void CRouterBRouterSetup::loadOnlineVersion() const
366 {
367     QUrl serviceUrl = getServiceUrl();
368     serviceUrl.setQuery(QUrlQuery("lonlats=11.138570,48.676961|11.138570,48.676961&profile=shortest&alternativeidx=0&format=gpx"));
369     QNetworkReply* reply = networkAccessManager->get(QNetworkRequest(serviceUrl));
370     reply->setProperty("type", eTypeVersion);
371 }
372 
loadExpertBinariesPage() const373 void CRouterBRouterSetup::loadExpertBinariesPage() const
374 {
375     QNetworkReply* reply = networkAccessManager->get(QNetworkRequest(expertBinariesUrl));
376     reply->setProperty("type", eTypeBinariesPage);
377 }
378 
loadExpertSegmentsPage() const379 void CRouterBRouterSetup::loadExpertSegmentsPage() const
380 {
381     QNetworkReply* reply = networkAccessManager->get(QNetworkRequest(expertSegmentsUrl));
382     reply->setProperty("type", eTypeSegmentsPage);
383 }
384 
slotOnlineRequestFinished(QNetworkReply * reply)385 void CRouterBRouterSetup::slotOnlineRequestFinished(QNetworkReply* reply)
386 {
387     reply->deleteLater();
388     const request_e type = request_e(reply->property("type").toInt());
389 
390     if (reply->error() != QNetworkReply::NoError && type != eTypeVersion)
391     {
392         emitNetworkError(reply->errorString());
393         return;
394     }
395 
396     switch (type)
397     {
398     case eTypeConfig:
399     {
400         loadOnlineConfigFinished(reply);
401         break;
402     }
403 
404     case eTypeProfile:
405     {
406         loadOnlineProfileFinished(reply);
407         break;
408     }
409 
410     case eTypeVersion:
411     {
412         loadOnlineVersionFinished(reply);
413         break;
414     }
415 
416     case eTypeBinariesPage:
417     {
418         emit sigBinariesPageLoaded();
419         break;
420     }
421 
422     case eTypeSegmentsPage:
423     {
424         emit sigSegmentsPageLoaded();
425         break;
426     }
427     }
428 }
429 
loadOnlineConfigFinished(QNetworkReply * reply)430 void CRouterBRouterSetup::loadOnlineConfigFinished(QNetworkReply* reply)
431 {
432     const QString& configHost = reply->property("configHost").toString();
433     const QString& configScheme = reply->property("configScheme").toString();
434     const bool update = reply->property("update").toBool();
435 
436     const QString jsConfig(reply->readAll());
437 
438     QJSEngine engine;
439 
440     const QString& jsSetup = QString( \
441         "(function(){\
442                    window = {};\
443                    window.location = {};\
444                    window.location.hostname = '%1';\
445                    window.location.protocol = '%2:';\
446                    window.location.search = {};\
447                    window.location.search.slice = function() {};\
448                    URLSearchParams = function() {};\
449                    BR = {};\
450                   })();").arg(configHost, configScheme);
451 
452     engine.evaluate(jsSetup);
453     const QJSValue& val = engine.evaluate(jsConfig);
454     if (val.isError())
455     {
456         emitOnlineConfigScriptError(val);
457         return;
458     }
459 
460     const QJSValue& br = engine.globalObject().property("BR");
461     if (!br.isObject() || br.isError())
462     {
463         emitOnlineConfigScriptError(br);
464         return;
465     }
466     const QJSValue& conf = br.property("conf");
467     if (!conf.isObject() || conf.isError())
468     {
469         emitOnlineConfigScriptError(conf);
470         return;
471     }
472 
473     const QJSValue& host = conf.property("host");
474     if (!host.isString() || host.isError())
475     {
476         emitOnlineConfigScriptError(host);
477         return;
478     }
479     if (update && onlineServiceUrl != host.toString())
480     {
481         onlineServiceUrl = host.toString();
482     }
483     const QJSValue& url = conf.property("profilesUrl");
484     if (!url.isString() || url.isError())
485     {
486         emitOnlineConfigScriptError(url);
487         return;
488     }
489     if (update && onlineProfilesUrl != url.toString())
490     {
491         onlineProfilesUrl = url.toString();
492     }
493 
494     if (update && !expertMode)
495     {
496         if  (installMode == eModeOnline)
497         {
498             const QJSValue& profiles = conf.property("profiles");
499             if (!profiles.isArray() || profiles.isError())
500             {
501                 emitOnlineConfigScriptError(profiles);
502                 return;
503             }
504             const qint32 len = profiles.property("length").toInt();
505 
506             QStringList onlineProfilesLoaded;
507             for(qint32 i = 0; i < len; i++)
508             {
509                 const QJSValue& profile = profiles.property(i);
510                 if (!profile.isString() || profile.isError())
511                 {
512                     emitOnlineConfigScriptError(profile);
513                     return;
514                 }
515                 onlineProfilesLoaded << profile.toString();
516             }
517 
518             mergeOnlineProfiles(onlineProfilesLoaded);
519 
520             const QStringList onlineProfilesTmp(onlineProfiles);
521             for (const QString& profile : onlineProfilesTmp)
522             {
523                 if (!onlineProfilesAvailable.contains(profile))
524                 {
525                     onlineProfiles.removeAt(onlineProfiles.indexOf(profile));
526                 }
527             }
528 
529             emit sigProfilesChanged();
530         }
531         else
532         {
533             loadLocalOnlineProfiles(true);
534         }
535     }
536     emit sigOnlineConfigLoaded();
537 }
538 
loadOnlineVersionFinished(QNetworkReply * reply)539 void CRouterBRouterSetup::loadOnlineVersionFinished(QNetworkReply* reply)
540 {
541     versionMajor = NOINT;
542     versionMinor = NOINT;
543     versionPatch = NOINT;
544 
545     if (reply->error() != QNetworkReply::NoError)
546     {
547         emitNetworkError(reply->errorString());
548         return;
549     }
550     const QString gpx(reply->readAll());
551     const QRegExp reVersion = QRegExp("^<\\?xml.+<gpx.+creator=\"(.*)\"");
552 
553     if (reVersion.indexIn(gpx) > -1)
554     {
555         parseBRouterVersion(reVersion.cap(1));
556         return;
557     }
558     emit sigError("invalid reply", "response is not brouter-gpx");
559 }
560 
parseBRouterVersion(const QString & text)561 void CRouterBRouterSetup::parseBRouterVersion(const QString& text)
562 {
563     // version string is either like "BRouter 1.4.9 / 24092017"
564     // or (without the date) like "BRouter-1.4.9"
565     QRegExp reVersion("\\bBRouter[- ](\\d+)\\.(\\d+)\\.(\\d+)\\b");
566     if (reVersion.indexIn(text) > -1)
567     {
568         bool ok;
569         versionMajor = reVersion.cap(1).toInt(&ok);
570         if (ok)
571         {
572             versionMinor = reVersion.cap(2).toInt(&ok);
573         }
574         if (ok)
575         {
576             versionPatch = reVersion.cap(3).toInt(&ok);
577         }
578         if (ok)
579         {
580             emit sigVersionChanged();
581             return;
582         }
583     }
584     versionMajor = NOINT;
585     versionMinor = NOINT;
586     versionPatch = NOINT;
587 
588     emit sigVersionChanged();
589 }
590 
591 
slotLoadOnlineProfilesRequestFinished(bool ok)592 void CRouterBRouterSetup::slotLoadOnlineProfilesRequestFinished(bool ok)
593 {
594     if (!ok)
595     {
596         emitNetworkError(tr("%1 not accessible").arg(onlineProfilesUrl));
597         return;
598     }
599     else
600     {
601         profilesWebPage->runJavaScript(
602             "var profiles = [];"
603             "var xpathResult = document.evaluate('.//@href',document.body,null,XPathResult.UNORDERED_NODE_ITERATOR_TYPE,null);"
604             "var href = xpathResult.iterateNext();"
605             "while(href) {"
606             "  var pmatch = href.value.match(/(\\S+)\\.brf/);"
607             "  if (pmatch != null) {"
608             "    profiles.push(pmatch[1]);"
609             "  }"
610             "  href = xpathResult.iterateNext();"
611             "}"
612             "profiles;",
613             [this](const QVariant& v) { afterSlotLoadOnlineProfilesRequestFinishedRunJavascript(v); }
614             );
615     }
616 }
617 
afterSlotLoadOnlineProfilesRequestFinishedRunJavascript(const QVariant & v)618 void CRouterBRouterSetup::afterSlotLoadOnlineProfilesRequestFinishedRunJavascript(const QVariant& v)
619 {
620     QStringList onlineProfilesLoaded = v.toStringList();
621 
622     if (onlineProfilesLoaded.size() == 0)
623     {
624         emitNetworkError(tr("%1 invalid result").arg(onlineProfilesUrl));
625     }
626     else
627     {
628         if (profilesWebPage->property("update").toBool())
629         {
630             mergeOnlineProfiles(onlineProfilesLoaded);
631         }
632         emit sigProfilesChanged();
633     }
634 }
635 
mergeOnlineProfiles(const QStringList & onlineProfilesLoaded)636 void CRouterBRouterSetup::mergeOnlineProfiles(const QStringList& onlineProfilesLoaded)
637 {
638     const QStringList onlineProfilesAvailableTmp(onlineProfilesAvailable);
639     for (const QString& profile : onlineProfilesAvailableTmp)
640     {
641         if (!onlineProfilesLoaded.contains(profile))
642         {
643             onlineProfilesAvailable.removeAt(onlineProfilesAvailable.indexOf(profile));
644         }
645     }
646     for (const QString& profile : onlineProfilesLoaded)
647     {
648         if (!onlineProfilesAvailable.contains(profile))
649         {
650             onlineProfilesAvailable << profile;
651         }
652     }
653 }
654 
emitOnlineConfigScriptError(const QJSValue & error)655 void CRouterBRouterSetup::emitOnlineConfigScriptError(const QJSValue& error)
656 {
657     emit sigError(tr("Error parsing online-config:"), error.toString());
658 }
659 
emitNetworkError(QString error)660 void CRouterBRouterSetup::emitNetworkError(QString error)
661 {
662     emit sigError(tr("Network error:"), error);
663 }
664 
displayProfileAsync(const QString & profile)665 void CRouterBRouterSetup::displayProfileAsync(const QString& profile)
666 {
667     if (installMode == eModeLocal)
668     {
669         QFile file(getProfileDir(eModeLocal).absoluteFilePath(profile + ".brf"));
670         if (file.exists())
671         {
672             file.open(QIODevice::ReadOnly);
673             const QByteArray& content = file.readAll();
674             file.close();
675             emit sigDisplayOnlineProfileFinished(profile, QString(content));
676         }
677     }
678     else
679     {
680         Q_ASSERT(installMode == eModeOnline);
681         loadOnlineProfileAsync(profile, eProfileDisplay);
682     }
683 }
684 
displayOnlineProfileAsync(const QString & profile) const685 void CRouterBRouterSetup::displayOnlineProfileAsync(const QString& profile) const
686 {
687     loadOnlineProfileAsync(profile, eProfileDisplay);
688 }
689 
loadOnlineProfileAsync(const QString & profile,const profileRequest_e mode) const690 void CRouterBRouterSetup::loadOnlineProfileAsync(const QString& profile, const profileRequest_e mode) const
691 {
692     QUrl url(onlineProfilesUrl);
693     QString path = url.path();
694     if (!path.endsWith('/'))
695     {
696         path.append("/");
697     }
698     path.append(profile).append(".brf");
699     url.setPath(path);
700     QNetworkReply* reply = networkAccessManager->get(QNetworkRequest(url));
701     reply->setProperty("type", eTypeProfile);
702     reply->setProperty("profile", profile);
703     reply->setProperty("request", mode);
704 }
705 
loadOnlineProfileFinished(QNetworkReply * reply)706 void CRouterBRouterSetup::loadOnlineProfileFinished(QNetworkReply* reply)
707 {
708     const QString& profile = reply->property("profile").toString();
709     const profileRequest_e mode = profileRequest_e(reply->property("request").toInt());
710 
711     const QByteArray& content = reply->readAll();
712     if (mode == eProfileInstall)
713     {
714         const QDir dir = getProfileDir(eModeLocal);
715         const QString filename = dir.absoluteFilePath(profile + ".brf");
716         QFile file(filename);
717         file.open(QIODevice::WriteOnly);
718         file.write(content);
719         file.close();
720         readLocalProfiles();
721     }
722     else
723     {
724         Q_ASSERT(mode == eProfileDisplay);
725         emit sigDisplayOnlineProfileFinished(profile, QString(content));
726     }
727 }
728 
isLocalBRouterInstalled() const729 bool CRouterBRouterSetup::isLocalBRouterInstalled() const
730 {
731     const QDir dir(localDir);
732     return QFile(dir.absoluteFilePath("brouter.jar")).exists() && QDir(dir.absoluteFilePath(localProfileDir)).exists();
733 }
734 
isLocalBRouterDefaultDir() const735 bool CRouterBRouterSetup::isLocalBRouterDefaultDir() const
736 {
737     return localDir == defaultLocalDir;
738 }
739 
740 
findJava() const741 QString CRouterBRouterSetup::findJava() const
742 {
743     return IAppSetup::getPlatformInstance()->findExecutable("java");
744 }
745 
onInvalidSetup()746 void CRouterBRouterSetup::onInvalidSetup()
747 {
748     QMessageBox msgBox;
749     msgBox.setIcon(QMessageBox::Warning);
750     msgBox.setText("BRouter config is inconsistent!");
751     msgBox.setInformativeText("Resetting to default values");
752     msgBox.setStandardButtons(QMessageBox::Ok);
753     msgBox.exec();
754     resetAll();
755 }
756 
getServiceUrl() const757 QUrl CRouterBRouterSetup::getServiceUrl() const
758 {
759     if (installMode == CRouterBRouterSetup::eModeLocal)
760     {
761         QUrl url(QString("http://"));
762         url.setHost(localHost);
763         url.setPort(localPort.toInt());
764         url.setPath("/brouter");
765         return url;
766     }
767     else
768     {
769         Q_ASSERT(installMode == CRouterBRouterSetup::eModeOnline);
770         QUrl url(onlineServiceUrl);
771         if (url.path() == "")
772         {
773             url.setPath("/brouter");
774         }
775         return url;
776     }
777 }
778 
getSegmentsUrl() const779 QString CRouterBRouterSetup::getSegmentsUrl() const
780 {
781     return expertMode ? expertSegmentsUrl : defaultSegmentsUrl;
782 }
783 
getBinariesUrl() const784 QString CRouterBRouterSetup::getBinariesUrl() const
785 {
786     return expertMode ? expertBinariesUrl : defaultBinariesUrl;
787 }
788 
getConfigUrl() const789 QString CRouterBRouterSetup::getConfigUrl() const
790 {
791     return expertMode ? expertConfigUrl : defaultConfigUrl;
792 }
793