1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
#ifndef USERDATABASE_HH
#define USERDATABASE_HH
#include <QObject>
#include <QVector>
#include <QHash>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QAbstractTableModel>
#include <QSortFilterProxyModel>
#include <QGeoPositionInfoSource>
#include <QFuture>
/** Auto-updating DMR user database.
*
* This class represents the complete DMR user database. The user database gets downloaded from
* https://www.radioid.net/static/users.json and kept up-to-date by re-downloading it
* periodically (by default every 30 days). This user database gets used in the GUI application
* to help assemble private call contacts and to assemble so-called CSV callsign databases, that
* are programmable to some DMR radios to resolve the DMR ID to callsigns and names.
*
* @ingroup util */
class UserDatabase : public QAbstractTableModel
{
Q_OBJECT
/** Get notification, once the database has been loaded. */
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged FINAL)
public:
/** Represents the user information within the @c UserDatabase. */
class User {
public:
/** Empty constructor. */
User();
/** Constructs entry from JSON object. */
User(const QJsonObject &obj);
/** Returns @c true if the entry is valid. */
inline bool isValid() const { return 0 != id; }
/** Returns the "distance" between this user and the given ID. */
unsigned distance(unsigned id) const;
/** The DMR ID of the user. */
unsigned id;
/** The callsign of the user. */
QString call;
/** The name of the user. */
QString name;
/** The surname of the user. */
QString surname;
/** The city of the user. */
QString city;
/** The state of the user. */
QString state;
/** The country of the user. */
QString country;
/** Some arbitrary comment or text. */
QString comment;
};
public:
/** Constructs the user-database.
* The constructor will download the current user database if it was not downloaded yet or
* if the downloaded version is older than @c updatePeriodDays days. */
explicit UserDatabase(bool parallel, unsigned updatePeriodDays=30, QObject *parent=nullptr);
/** Returns the number of users. */
qint64 count() const;
/** Retruns @c true, if the user database file exists. */
bool exists() const;
/** Loads all entries from the downloaded user database. */
bool load();
/** Loads all entries from the downloaded user database at the specified location. */
bool load(const QString &filename);
/** Returns @c true, if the database has been loaded. */
bool ready() const;
/** Sorts users with respect to the distance to the given ID. */
void sortUsers(unsigned id);
/** Sorts users with respect to the minimum distance to the given IDs. */
void sortUsers(const QSet<unsigned> &ids);
/** Returns the user with index @c idx. */
const User &user(int idx) const;
/** Returns the age of the database in days. */
unsigned dbAge() const;
/** Implements the QAbstractTableModel interface, returns the number of rows (number of entries). */
int rowCount(const QModelIndex &parent=QModelIndex()) const;
/** Implements the QAbstractTableModel interface, returns the number of columns. */
int columnCount(const QModelIndex &parent=QModelIndex()) const;
/** Implements the QAbstractTableModel interface, return the entry data. */
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
signals:
/** Gets emitted once the call-sign database has been loaded. */
void loaded();
/** Gets emitted if the loading of the call-sign database fails. */
void error(const QString &msg);
/** Gets emitted, once the database has been loaded or cleard.
* @warning This event might be emitted by another thread. */
void readyChanged(bool ready);
public slots:
/** Starts the download of the user database. */
void download();
private slots:
/** Gets called whenever the download is complete. */
void downloadFinished(QNetworkReply *reply);
/** Parses cache and stores all users in given result list. */
bool parse(QList<User> &users);
/** Parses the given file and stores all users in given result list. */
bool parse(const QString &filename, QList<User> &users);
/** Loads all entries from the parsed file. */
bool load(const QList<User> &users);
private:
/** Holds all users sorted by their ID. */
QVector<User> _user;
/** The network access used for downloading. */
QNetworkAccessManager _network;
/** The current parallel task of parsing the database. */
QFuture<bool> _parsing;
};
#endif // USERDATABASE_HH
|