1 /** @file updatersettings.cpp Persistent settings for automatic updates.
2  * @ingroup updater
3  *
4  * @authors Copyright © 2012-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
5  * @authors Copyright © 2013 Daniel Swanson <danij@dengine.net>
6  *
7  * @par License
8  * GPL: http://www.gnu.org/licenses/gpl.html
9  *
10  * <small>This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by the
12  * Free Software Foundation; either version 2 of the License, or (at your
13  * option) any later version. This program is distributed in the hope that it
14  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details. You should have received a copy of the GNU
17  * General Public License along with this program; if not, write to the Free
18  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19  * 02110-1301 USA</small>
20  */
21 
22 #include "updater/updatersettings.h"
23 #include <QDateTime>
24 #include <QDesktopServices>
25 #include <de/Record>
26 #include <de/Config>
27 #include <de/TextValue>
28 #include <de/NumberValue>
29 #include <de/TimeValue>
30 
31 using namespace de;
32 
33 static String const VAR_FREQUENCY     ("updater.frequency");
34 static String const VAR_CHANNEL       ("updater.channel");
35 static String const VAR_LAST_CHECKED  ("updater.lastChecked");
36 static String const VAR_ONLY_MANUAL   ("updater.onlyManually");
37 static String const VAR_DELETE        ("updater.delete");
38 static String const VAR_DOWNLOAD_PATH ("updater.downloadPath");
39 static String const VAR_DELETE_PATH   ("updater.deleteAtStartup");
40 static String const VAR_AUTO_DOWNLOAD ("updater.autoDownload");
41 
42 static String const SYMBOL_DEFAULT_DOWNLOAD("${DEFAULT}");
43 
UpdaterSettings()44 UpdaterSettings::UpdaterSettings()
45 {}
46 
frequency() const47 UpdaterSettings::Frequency UpdaterSettings::frequency() const
48 {
49     return Frequency(Config::get().geti(VAR_FREQUENCY));
50 }
51 
channel() const52 UpdaterSettings::Channel UpdaterSettings::channel() const
53 {
54     return Channel(Config::get().geti(VAR_CHANNEL));
55 }
56 
lastCheckTime() const57 de::Time UpdaterSettings::lastCheckTime() const
58 {
59     // Note that the variable has only AllowTime as the mode.
60     return Config::get().getAs<TimeValue>(VAR_LAST_CHECKED).time();
61 }
62 
onlyCheckManually() const63 bool UpdaterSettings::onlyCheckManually() const
64 {
65     return Config::get().getb(VAR_ONLY_MANUAL);
66 }
67 
autoDownload() const68 bool UpdaterSettings::autoDownload() const
69 {
70     return Config::get().getb(VAR_AUTO_DOWNLOAD);
71 }
72 
deleteAfterUpdate() const73 bool UpdaterSettings::deleteAfterUpdate() const
74 {
75     return Config::get().getb(VAR_DELETE);
76 }
77 
pathToDeleteAtStartup() const78 de::NativePath UpdaterSettings::pathToDeleteAtStartup() const
79 {
80     de::NativePath p = Config::get().gets(VAR_DELETE_PATH);
81     de::String ext = p.toString().fileNameExtension();
82     if (p.fileName().startsWith("doomsday") && (ext == ".exe" || ext == ".deb" || ext == ".dmg"))
83     {
84         return p;
85     }
86     // Doesn't look valid.
87     return "";
88 }
89 
isDefaultDownloadPath() const90 bool UpdaterSettings::isDefaultDownloadPath() const
91 {
92     return downloadPath() == defaultDownloadPath();
93 }
94 
downloadPath() const95 de::NativePath UpdaterSettings::downloadPath() const
96 {
97     de::NativePath dir = Config::get().gets(VAR_DOWNLOAD_PATH);
98     if (dir.toString() == SYMBOL_DEFAULT_DOWNLOAD)
99     {
100         dir = defaultDownloadPath();
101     }
102     return dir;
103 }
104 
setDownloadPath(de::NativePath downloadPath)105 void UpdaterSettings::setDownloadPath(de::NativePath downloadPath)
106 {
107     if (downloadPath == defaultDownloadPath())
108     {
109         downloadPath = SYMBOL_DEFAULT_DOWNLOAD;
110     }
111     Config::get().set(VAR_DOWNLOAD_PATH, downloadPath.toString());
112 }
113 
setFrequency(UpdaterSettings::Frequency freq)114 void UpdaterSettings::setFrequency(UpdaterSettings::Frequency freq)
115 {
116     Config::get().set(VAR_FREQUENCY, dint(freq));
117 }
118 
setChannel(UpdaterSettings::Channel channel)119 void UpdaterSettings::setChannel(UpdaterSettings::Channel channel)
120 {
121     Config::get().set(VAR_CHANNEL, dint(channel));
122 }
123 
setLastCheckTime(de::Time const & time)124 void UpdaterSettings::setLastCheckTime(de::Time const &time)
125 {
126     Config::get(VAR_LAST_CHECKED) = new TimeValue(time);
127 }
128 
setOnlyCheckManually(bool onlyManually)129 void UpdaterSettings::setOnlyCheckManually(bool onlyManually)
130 {
131     Config::get().set(VAR_ONLY_MANUAL, onlyManually);
132 }
133 
setAutoDownload(bool autoDl)134 void UpdaterSettings::setAutoDownload(bool autoDl)
135 {
136     Config::get().set(VAR_AUTO_DOWNLOAD, autoDl);
137 }
138 
setDeleteAfterUpdate(bool deleteAfter)139 void UpdaterSettings::setDeleteAfterUpdate(bool deleteAfter)
140 {
141     Config::get().set(VAR_DELETE, deleteAfter);
142 }
143 
useDefaultDownloadPath()144 void UpdaterSettings::useDefaultDownloadPath()
145 {
146     setDownloadPath(defaultDownloadPath());
147 }
148 
setPathToDeleteAtStartup(de::NativePath deletePath)149 void UpdaterSettings::setPathToDeleteAtStartup(de::NativePath deletePath)
150 {
151     Config::get().set(VAR_DELETE_PATH, deletePath.toString());
152 }
153 
defaultDownloadPath()154 de::NativePath UpdaterSettings::defaultDownloadPath()
155 {
156 #ifdef DENG2_QT_5_0_OR_NEWER
157     return QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
158 #else
159     return QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
160 #endif
161 }
162 
lastCheckAgo() const163 de::String UpdaterSettings::lastCheckAgo() const
164 {
165     de::Time when = lastCheckTime();
166     if (!when.isValid()) return ""; // Never checked.
167 
168     de::TimeSpan delta = when.since();
169     if (delta < 0.0) return "";
170 
171     int t;
172     if (delta < 60.0)
173     {
174         t = delta.asMilliSeconds() / 1000;
175         return de::String(QObject::tr("%1 %2 ago")).arg(t).
176                           arg(t != 1? QObject::tr("seconds") : QObject::tr("second"));
177     }
178 
179     t = delta.asMinutes();
180     if (t <= 60)
181     {
182         return de::String(QObject::tr("%1 %2 ago")).arg(t).
183                 arg(t != 1? QObject::tr("minutes") : QObject::tr("minute"));
184     }
185 
186     t = delta.asHours();
187     if (t <= 24)
188     {
189         return de::String(QObject::tr("%1 %2 ago")).arg(t).
190                 arg(t != 1? QObject::tr("hours") : QObject::tr("hour"));
191     }
192 
193     t = delta.asDays();
194     if (t <= 7)
195     {
196         return de::String(QObject::tr("%1 %2 ago")).arg(t).
197                 arg(t != 1? QObject::tr("days") : QObject::tr("day"));
198     }
199 
200     return de::String("on " + when.asText(de::Time::FriendlyFormat));
201 }
202