1/*
2 * Copyright (C) by Klaas Freitag <freitag@owncloud.com>
3 * Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef UTILITY_H
21#define UTILITY_H
22
23#include "ocsynclib.h"
24#include <QString>
25#include <QByteArray>
26#include <QDateTime>
27#include <QElapsedTimer>
28#include <QLoggingCategory>
29#include <QMap>
30#include <QUrl>
31#include <QUrlQuery>
32#include <functional>
33#include <memory>
34
35#ifdef Q_OS_WIN
36#include <windows.h>
37#endif
38
39class QSettings;
40
41namespace OCC {
42
43Q_DECLARE_LOGGING_CATEGORY(lcUtility)
44
45/** \addtogroup libsync
46 * @{
47 */
48namespace Utility {
49 OCSYNC_EXPORT void sleep(int sec);
50 OCSYNC_EXPORT void usleep(int usec);
51 OCSYNC_EXPORT QString formatFingerprint(const QByteArray &, bool colonSeparated = true);
52 OCSYNC_EXPORT void setupFavLink(const QString &folder);
53 OCSYNC_EXPORT bool writeRandomFile(const QString &fname, int size = -1);
54 OCSYNC_EXPORT QString octetsToString(qint64 octets);
55 OCSYNC_EXPORT QByteArray userAgentString();
56 OCSYNC_EXPORT bool hasLaunchOnStartup(const QString &appName);
57 OCSYNC_EXPORT void setLaunchOnStartup(const QString &appName, const QString &guiName, bool launch);
58
59 /**
60 * Return the amount of free space available.
61 *
62 * \a path must point to a directory
63 */
64 OCSYNC_EXPORT qint64 freeDiskSpace(const QString &path);
65
66 /**
67 * @brief compactFormatDouble - formats a double value human readable.
68 *
69 * @param value the value to format.
70 * @param prec the precision.
71 * @param unit an optional unit that is appended if present.
72 * @return the formatted string.
73 */
74 OCSYNC_EXPORT QString compactFormatDouble(double value, int prec, const QString &unit = QString());
75
76 // porting methods
77 OCSYNC_EXPORT QString escape(const QString &);
78
79 // conversion function QDateTime <-> time_t (because the ones builtin work on only unsigned 32bit)
80 OCSYNC_EXPORT QDateTime qDateTimeFromTime_t(qint64 t);
81 OCSYNC_EXPORT qint64 qDateTimeToTime_t(const QDateTime &t);
82
83 /**
84 * @brief Convert milliseconds duration to human readable string.
85 * @param quint64 msecs the milliseconds to convert to string.
86 * @return an HMS representation of the milliseconds value.
87 *
88 * durationToDescriptiveString1 describes the duration in a single
89 * unit, like "5 minutes" or "2 days".
90 *
91 * durationToDescriptiveString2 uses two units where possible, so
92 * "5 minutes 43 seconds" or "1 month 3 days".
93 */
94 OCSYNC_EXPORT QString durationToDescriptiveString1(quint64 msecs);
95 OCSYNC_EXPORT QString durationToDescriptiveString2(quint64 msecs);
96
97 /**
98 * @brief hasDarkSystray - determines whether the systray is dark or light.
99 *
100 * Use this to check if the OS has a dark or a light systray.
101 *
102 * The value might change during the execution of the program
103 * (e.g. on OS X 10.10).
104 *
105 * @return bool which is true for systems with dark systray.
106 */
107 OCSYNC_EXPORT bool hasDarkSystray();
108
109 // convenience OS detection methods
110 inline bool isWindows();
111 inline bool isMac();
112 inline bool isUnix();
113 inline bool isLinux(); // use with care
114 inline bool isBSD(); // use with care, does not match OS X
115
116 OCSYNC_EXPORT QString platformName();
117 // crash helper for --debug
118 OCSYNC_EXPORT void crash();
119
120 // Case preserving file system underneath?
121 // if this function returns true, the file system is case preserving,
122 // that means "test" means the same as "TEST" for filenames.
123 // if false, the two cases are two different files.
124 OCSYNC_EXPORT bool fsCasePreserving();
125
126 // Check if two pathes that MUST exist are equal. This function
127 // uses QDir::canonicalPath() to judge and cares for the systems
128 // case sensitivity.
129 OCSYNC_EXPORT bool fileNamesEqual(const QString &fn1, const QString &fn2);
130
131 // Call the given command with the switch --version and rerun the first line
132 // of the output.
133 // If command is empty, the function calls the running application which, on
134 // Linux, might have changed while this one is running.
135 // For Mac and Windows, it returns QString()
136 OCSYNC_EXPORT QByteArray versionOfInstalledBinary(const QString &command = QString());
137
138 OCSYNC_EXPORT QString fileNameForGuiUse(const QString &fName);
139
140 OCSYNC_EXPORT QByteArray normalizeEtag(QByteArray etag);
141
142 /**
143 * @brief timeAgoInWords - human readable time span
144 *
145 * Use this to get a string that describes the timespan between the first and
146 * the second timestamp in a human readable and understandable form.
147 *
148 * If the second parameter is ommitted, the current time is used.
149 */
150 OCSYNC_EXPORT QString timeAgoInWords(const QDateTime &dt, const QDateTime &from = QDateTime());
151
152 class OCSYNC_EXPORT StopWatch
153 {
154 private:
155 QMap<QString, quint64> _lapTimes;
156 QDateTime _startTime;
157 QElapsedTimer _timer;
158
159 public:
160 void start();
161 quint64 stop();
162 quint64 addLapTime(const QString &lapName);
163 void reset();
164
165 // out helpers, return the measured times.
166 QDateTime startTime() const;
167 QDateTime timeOfLap(const QString &lapName) const;
168 quint64 durationOfLap(const QString &lapName) const;
169 };
170
171 /**
172 * @brief Sort a QStringList in a way that's appropriate for filenames
173 */
174 OCSYNC_EXPORT void sortFilenames(QStringList &fileNames);
175
176 /** Appends concatPath and queryItems to the url */
177 OCSYNC_EXPORT QUrl concatUrlPath(
178 const QUrl &url, const QString &concatPath,
179 const QUrlQuery &queryItems = {});
180
181 /** Returns a new settings pre-set in a specific group. The Settings will be created
182 with the given parent. If no parent is specified, the caller must destroy the settings */
183 OCSYNC_EXPORT std::unique_ptr<QSettings> settingsWithGroup(const QString &group, QObject *parent = 0);
184
185 /** Sanitizes a string that shall become part of a filename.
186 *
187 * Filters out reserved characters like
188 * - unicode control and format characters
189 * - reserved characters: /, ?, <, >, \, :, *, |, and "
190 *
191 * Warning: This does not sanitize the whole resulting string, so
192 * - unix reserved filenames ('.', '..')
193 * - trailing periods and spaces
194 * - windows reserved filenames ('CON' etc)
195 * will pass unchanged.
196 */
197 OCSYNC_EXPORT QString sanitizeForFileName(const QString &name);
198
199 /** Returns a file name based on \a fn that's suitable for a conflict.
200 */
201 OCSYNC_EXPORT QString makeConflictFileName(
202 const QString &fn, const QDateTime &dt, const QString &user);
203
204 /** Returns whether a file name indicates a conflict file
205 */
206 OCSYNC_EXPORT bool isConflictFile(const char *name);
207 OCSYNC_EXPORT bool isConflictFile(const QString &name);
208
209 /** Find the base name for a conflict file name
210 *
211 * Will return an empty string if it's not a conflict file.
212 *
213 * Prefer to use the data from the conflicts table in the journal to determine
214 * a conflict's base file.
215 */
216 OCSYNC_EXPORT QByteArray conflictFileBaseName(const QByteArray &conflictName);
217
218#ifdef Q_OS_WIN
219 OCSYNC_EXPORT QVariant registryGetKeyValue(HKEY hRootKey, const QString &subKey, const QString &valueName);
220 OCSYNC_EXPORT bool registrySetKeyValue(HKEY hRootKey, const QString &subKey, const QString &valueName, DWORD type, const QVariant &value);
221 OCSYNC_EXPORT bool registryDeleteKeyTree(HKEY hRootKey, const QString &subKey);
222 OCSYNC_EXPORT bool registryDeleteKeyValue(HKEY hRootKey, const QString &subKey, const QString &valueName);
223 OCSYNC_EXPORT bool registryWalkSubKeys(HKEY hRootKey, const QString &subKey, const std::function<void(HKEY, const QString &)> &callback);
224#endif
225}
226/** @} */ // \addtogroup
227
228inline bool Utility::isWindows()
229{
230#ifdef Q_OS_WIN
231 return true;
232#else
233 return false;
234#endif
235}
236
237inline bool Utility::isMac()
238{
239#ifdef Q_OS_MAC
240 return true;
241#else
242 return false;
243#endif
244}
245
246inline bool Utility::isUnix()
247{
248#ifdef Q_OS_UNIX
249 return true;
250#else
251 return false;
252#endif
253}
254
255inline bool Utility::isLinux()
256{
257#if defined(Q_OS_LINUX)
258 return true;
259#else
260 return false;
261#endif
262}
263
264inline bool Utility::isBSD()
265{
266#if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD)
267 return true;
268#else
269 return false;
270#endif
271}
272
273}
274#endif // UTILITY_H
275