forked from Silverfish/proton-bridge
chore: merge release/perth_narrows into devel
This commit is contained in:
@ -156,16 +156,6 @@ QString userDataDir() {
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return user logs directory used by bridge.
|
||||
//****************************************************************************************************************************************************
|
||||
QString userLogsDir() {
|
||||
QString const path = QDir(userDataDir()).absoluteFilePath("logs");
|
||||
QDir().mkpath(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return sentry cache directory used by bridge.
|
||||
//****************************************************************************************************************************************************
|
||||
|
||||
@ -38,7 +38,7 @@ enum class OS {
|
||||
|
||||
QString userConfigDir(); ///< Get the path of the user configuration folder.
|
||||
QString userCacheDir(); ///< Get the path of the user cache folder.
|
||||
QString userLogsDir(); ///< Get the path of the user logs folder.
|
||||
QString userDataDir(); ///< Get the path of the user data folder.
|
||||
QString sentryCacheDir(); ///< Get the path of the sentry cache folder.
|
||||
QString goos(); ///< return the value of Go's GOOS for the current platform ("darwin", "linux" and "windows" are supported).
|
||||
qint64 randN(qint64 n); ///< return a random integer in the half open range [0,n)
|
||||
|
||||
@ -29,7 +29,6 @@ namespace {
|
||||
|
||||
|
||||
Empty empty; ///< Empty protobuf message, re-used across calls.
|
||||
qint64 const port = 1042; ///< The port for the focus service.
|
||||
QString const hostname = "127.0.0.1"; ///< The hostname of the focus service.
|
||||
|
||||
|
||||
@ -39,12 +38,43 @@ QString const hostname = "127.0.0.1"; ///< The hostname of the focus service.
|
||||
namespace bridgepp {
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return the gRPC Focus server config file name
|
||||
//****************************************************************************************************************************************************
|
||||
QString grpcFocusServerConfigFilename() {
|
||||
return "grpcFocusServerConfig.json";
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return The absolute path of the focus service config path.
|
||||
//****************************************************************************************************************************************************
|
||||
QString FocusGRPCClient::grpcFocusServerConfigPath(QString const &configDir) {
|
||||
return QDir(configDir).absoluteFilePath(grpcFocusServerConfigFilename());
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
//
|
||||
//****************************************************************************************************************************************************
|
||||
void FocusGRPCClient::removeServiceConfigFile(QString const &configDir) {
|
||||
QString const path = grpcFocusServerConfigPath(configDir);
|
||||
if (!QFile(path).exists()) {
|
||||
return;
|
||||
}
|
||||
if (!QFile().remove(path)) {
|
||||
throw Exception("Could not remove gRPC focus service config file.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] timeoutMs The timeout for the connexion.
|
||||
/// \param[in] port The gRPC server port.
|
||||
/// \param[out] outError if not null and the function returns false.
|
||||
/// \return true iff the connexion was successfully established.
|
||||
//****************************************************************************************************************************************************
|
||||
bool FocusGRPCClient::connectToServer(qint64 timeoutMs, QString *outError) {
|
||||
bool FocusGRPCClient::connectToServer(qint64 timeoutMs, quint16 port, QString *outError) {
|
||||
try {
|
||||
QString const address = QString("%1:%2").arg(hostname).arg(port);
|
||||
channel_ = grpc::CreateChannel(address.toStdString(), grpc::InsecureChannelCredentials());
|
||||
|
||||
@ -27,10 +27,14 @@
|
||||
namespace bridgepp {
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//****************************************************************************************************************************************************
|
||||
/// \brief Focus GRPC client class
|
||||
//**********************************************************************************************************************
|
||||
//****************************************************************************************************************************************************
|
||||
class FocusGRPCClient {
|
||||
public: // static member functions
|
||||
static void removeServiceConfigFile(QString const &configDir); ///< Delete the service config file.
|
||||
static QString grpcFocusServerConfigPath(QString const &configDir); ///< Return the path of the gRPC Focus server config file.
|
||||
|
||||
public: // member functions.
|
||||
FocusGRPCClient() = default; ///< Default constructor.
|
||||
FocusGRPCClient(FocusGRPCClient const &) = delete; ///< Disabled copy-constructor.
|
||||
@ -38,8 +42,8 @@ public: // member functions.
|
||||
~FocusGRPCClient() = default; ///< Destructor.
|
||||
FocusGRPCClient &operator=(FocusGRPCClient const &) = delete; ///< Disabled assignment operator.
|
||||
FocusGRPCClient &operator=(FocusGRPCClient &&) = delete; ///< Disabled move assignment operator.
|
||||
bool connectToServer(qint64 timeoutMs, QString *outError = nullptr); ///< Connect to the focus server
|
||||
|
||||
bool connectToServer(qint64 timeoutMs, quint16 port, QString *outError = nullptr); ///< Connect to the focus server
|
||||
grpc::Status raise(); ///< Performs the 'raise' call.
|
||||
grpc::Status version(QString &outVersion); ///< Performs the 'version' call.
|
||||
|
||||
|
||||
@ -574,6 +574,78 @@ SPStreamEvent newUserBadEvent(QString const &userID, QString const &errorMessage
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] userID The userID.
|
||||
/// \param[in] usedBytes The number of used bytes.
|
||||
//****************************************************************************************************************************************************
|
||||
SPStreamEvent newUsedBytesChangedEvent(QString const &userID, qint64 usedBytes) {
|
||||
auto event = new grpc::UsedBytesChangedEvent;
|
||||
event->set_userid(userID.toStdString());
|
||||
event->set_usedbytes(usedBytes);
|
||||
auto userEvent = new grpc::UserEvent;
|
||||
userEvent->set_allocated_usedbyteschangedevent(event);
|
||||
return wrapUserEvent(userEvent);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] username The username that was provided for the failed IMAP login attempt.
|
||||
/// \return The event.
|
||||
//****************************************************************************************************************************************************
|
||||
SPStreamEvent newIMAPLoginFailedEvent(QString const &username) {
|
||||
auto event = new grpc::ImapLoginFailedEvent;
|
||||
event->set_username(username.toStdString());
|
||||
auto userEvent = new grpc::UserEvent;
|
||||
userEvent->set_allocated_imaploginfailedevent(event);
|
||||
return wrapUserEvent(userEvent);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] userID The userID.
|
||||
/// \return The event.
|
||||
//****************************************************************************************************************************************************
|
||||
SPStreamEvent newSyncStartedEvent(QString const &userID) {
|
||||
auto event = new grpc::SyncStartedEvent;
|
||||
event->set_userid(userID.toStdString());
|
||||
auto userEvent = new grpc::UserEvent;
|
||||
userEvent->set_allocated_syncstartedevent(event);
|
||||
return wrapUserEvent(userEvent);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] userID The userID.
|
||||
/// \return The event.
|
||||
//****************************************************************************************************************************************************
|
||||
SPStreamEvent newSyncFinishedEvent(QString const &userID) {
|
||||
auto event = new grpc::SyncFinishedEvent;
|
||||
event->set_userid(userID.toStdString());
|
||||
auto userEvent = new grpc::UserEvent;
|
||||
userEvent->set_allocated_syncfinishedevent(event);
|
||||
return wrapUserEvent(userEvent);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] userID The userID.
|
||||
/// \param[in] progress The progress ratio.
|
||||
/// \param[in] elapsedMs The elapsed time in milliseconds.
|
||||
/// \param[in] remainingMs The remaining time in milliseconds.
|
||||
/// \return The event.
|
||||
//****************************************************************************************************************************************************
|
||||
SPStreamEvent newSyncProgressEvent(QString const &userID, double progress, qint64 elapsedMs, qint64 remainingMs) {
|
||||
auto event = new grpc::SyncProgressEvent;
|
||||
event->set_userid(userID.toStdString());
|
||||
event->set_progress(progress);
|
||||
event->set_elapsedms(elapsedMs);
|
||||
event->set_remainingms(remainingMs);
|
||||
auto userEvent = new grpc::UserEvent;
|
||||
userEvent->set_allocated_syncprogressevent(event);
|
||||
return wrapUserEvent(userEvent);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] errorCode The error errorCode.
|
||||
/// \return The event.
|
||||
|
||||
@ -78,6 +78,11 @@ SPStreamEvent newToggleSplitModeFinishedEvent(QString const &userID); ///< Creat
|
||||
SPStreamEvent newUserDisconnectedEvent(QString const &username); ///< Create a new UserDisconnectedEvent event.
|
||||
SPStreamEvent newUserChangedEvent(QString const &userID); ///< Create a new UserChangedEvent event.
|
||||
SPStreamEvent newUserBadEvent(QString const &userID, QString const& errorMessage); ///< Create a new UserBadEvent event.
|
||||
SPStreamEvent newUsedBytesChangedEvent(QString const &userID, qint64 usedBytes); ///< Create a new UsedBytesChangedEvent event.
|
||||
SPStreamEvent newIMAPLoginFailedEvent(QString const &username); ///< Create a new ImapLoginFailedEvent event.
|
||||
SPStreamEvent newSyncStartedEvent(QString const &userID); ///< Create a new SyncStarted event.
|
||||
SPStreamEvent newSyncFinishedEvent(QString const &userID); ///< Create a new SyncFinished event.
|
||||
SPStreamEvent newSyncProgressEvent(QString const &userID, double progress, qint64 elapsedMs, qint64 remainingMs); ///< Create a new SyncFinished event.
|
||||
|
||||
// Generic error event
|
||||
SPStreamEvent newGenericErrorEvent(grpc::ErrorCode errorCode); ///< Create a new GenericErrrorEvent event.
|
||||
|
||||
@ -45,8 +45,8 @@ qint64 const grpcConnectionRetryDelayMs = 10000; ///< Retry delay for the gRPC c
|
||||
//****************************************************************************************************************************************************
|
||||
//
|
||||
//****************************************************************************************************************************************************
|
||||
void GRPCClient::removeServiceConfigFile() {
|
||||
QString const path = grpcServerConfigPath();
|
||||
void GRPCClient::removeServiceConfigFile(QString const &configDir) {
|
||||
QString const path = grpcServerConfigPath(configDir);
|
||||
if (!QFile(path).exists()) {
|
||||
return;
|
||||
}
|
||||
@ -61,8 +61,8 @@ void GRPCClient::removeServiceConfigFile() {
|
||||
/// \param[in] serverProcess An optional server process to monitor. If the process it, no need and retry, as connexion cannot be established. Ignored if null.
|
||||
/// \return The service config.
|
||||
//****************************************************************************************************************************************************
|
||||
GRPCConfig GRPCClient::waitAndRetrieveServiceConfig(qint64 timeoutMs, ProcessMonitor *serverProcess) {
|
||||
QString const path = grpcServerConfigPath();
|
||||
GRPCConfig GRPCClient::waitAndRetrieveServiceConfig(QString const &configDir, qint64 timeoutMs, ProcessMonitor *serverProcess) {
|
||||
QString const path = grpcServerConfigPath(configDir);
|
||||
QFile file(path);
|
||||
|
||||
QElapsedTimer timer;
|
||||
@ -109,7 +109,7 @@ void GRPCClient::setLog(Log *log) {
|
||||
/// \param[in] serverProcess An optional server process to monitor. If the process it, no need and retry, as connexion cannot be established. Ignored if null.
|
||||
/// \return true iff the connection was successful.
|
||||
//****************************************************************************************************************************************************
|
||||
void GRPCClient::connectToServer(GRPCConfig const &config, ProcessMonitor *serverProcess) {
|
||||
void GRPCClient::connectToServer(QString const &configDir, GRPCConfig const &config, ProcessMonitor *serverProcess) {
|
||||
try {
|
||||
serverToken_ = config.token.toStdString();
|
||||
QString address;
|
||||
@ -147,8 +147,9 @@ void GRPCClient::connectToServer(GRPCConfig const &config, ProcessMonitor *serve
|
||||
break;
|
||||
} // connection established.
|
||||
|
||||
if (QDateTime::currentDateTime() > giveUpTime)
|
||||
if (QDateTime::currentDateTime() > giveUpTime) {
|
||||
throw Exception("Connection to the RPC server failed.");
|
||||
}
|
||||
}
|
||||
|
||||
if (channel_->GetState(true) != GRPC_CHANNEL_READY) {
|
||||
@ -159,7 +160,7 @@ void GRPCClient::connectToServer(GRPCConfig const &config, ProcessMonitor *serve
|
||||
|
||||
QString const clientToken = QUuid::createUuid().toString();
|
||||
QString error;
|
||||
QString clientConfigPath = createClientConfigFile(clientToken, &error);
|
||||
QString clientConfigPath = createClientConfigFile(configDir, clientToken, &error);
|
||||
if (clientConfigPath.isEmpty()) {
|
||||
throw Exception("gRPC client config could not be saved.", error);
|
||||
}
|
||||
@ -184,6 +185,14 @@ void GRPCClient::connectToServer(GRPCConfig const &config, ProcessMonitor *serve
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return true if the gRPC client is connected to the server.
|
||||
//****************************************************************************************************************************************************
|
||||
bool GRPCClient::isConnected() const {
|
||||
return stub_.get();
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] clientConfigPath The path to the gRPC client config path.-
|
||||
/// \param[in] serverToken The token obtained from the server config file.
|
||||
@ -223,8 +232,9 @@ grpc::Status GRPCClient::addLogEntry(Log::Level level, QString const &package, Q
|
||||
grpc::Status GRPCClient::guiReady(bool &outShowSplashScreen) {
|
||||
GuiReadyResponse response;
|
||||
Status status = this->logGRPCCallStatus(stub_->GuiReady(this->clientContext().get(), empty, &response), __FUNCTION__);
|
||||
if (status.ok())
|
||||
if (status.ok()) {
|
||||
outShowSplashScreen = response.showsplashscreen();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -395,6 +405,8 @@ grpc::Status GRPCClient::setIsDoHEnabled(bool enabled) {
|
||||
//****************************************************************************************************************************************************
|
||||
grpc::Status GRPCClient::quit() {
|
||||
// quitting will shut down the gRPC service, to we may get an 'Unavailable' response for the call
|
||||
if (!this->isConnected())
|
||||
return Status::OK; // We're not even connected, we return OK. This maybe be an attempt to do 'a proper' shutdown after an unrecoverable error.
|
||||
return this->logGRPCCallStatus(stub_->Quit(this->clientContext().get(), empty, &empty), __FUNCTION__, { StatusCode::UNAVAILABLE });
|
||||
}
|
||||
|
||||
@ -458,15 +470,6 @@ grpc::Status GRPCClient::showOnStartup(bool &outValue) {
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[out] outGoos The value for the property.
|
||||
/// \return The status for the gRPC call.
|
||||
//****************************************************************************************************************************************************
|
||||
grpc::Status GRPCClient::goos(QString &outGoos) {
|
||||
return this->logGRPCCallStatus(this->getString(&Bridge::Stub::GoOs, outGoos), __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[out] outPath The value for the property.
|
||||
/// \return The status for the gRPC call.
|
||||
@ -476,6 +479,15 @@ grpc::Status GRPCClient::logsPath(QUrl &outPath) {
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[out] outGoos The value for the property.
|
||||
/// \return The status for the gRPC call.
|
||||
//****************************************************************************************************************************************************
|
||||
grpc::Status GRPCClient::goos(QString &outGoos) {
|
||||
return this->logGRPCCallStatus(this->getString(&Bridge::Stub::GoOs, outGoos), __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[out] outPath The value for the property.
|
||||
/// \return The status for the gRPC call.
|
||||
@ -1377,13 +1389,50 @@ void GRPCClient::processUserEvent(UserEvent const &event) {
|
||||
break;
|
||||
}
|
||||
case UserEvent::kUserBadEvent: {
|
||||
UserBadEvent const& e = event.userbadevent();
|
||||
UserBadEvent const &e = event.userbadevent();
|
||||
QString const userID = QString::fromStdString(e.userid());
|
||||
QString const errorMessage = QString::fromStdString(e.errormessage());
|
||||
this->logTrace(QString("User event received: UserBadEvent (userID = %1, errorMessage = %2).").arg(userID, errorMessage));
|
||||
emit userBadEvent(userID, errorMessage);
|
||||
break;
|
||||
}
|
||||
case UserEvent::kUsedBytesChangedEvent: {
|
||||
UsedBytesChangedEvent const &e = event.usedbyteschangedevent();
|
||||
QString const userID = QString::fromStdString(e.userid());
|
||||
qint64 const usedBytes = e.usedbytes();
|
||||
this->logTrace(QString("User event received: UsedBytesChangedEvent (userID = %1, usedBytes = %2).").arg(userID).arg(usedBytes));
|
||||
emit usedBytesChanged(userID, usedBytes);
|
||||
break;
|
||||
}
|
||||
case UserEvent::kImapLoginFailedEvent: {
|
||||
ImapLoginFailedEvent const &e = event.imaploginfailedevent();
|
||||
QString const username = QString::fromStdString(e.username());
|
||||
this->logTrace(QString("User event received: IMAPLoginFailed (username = %1).:").arg(username));
|
||||
emit imapLoginFailed(username);
|
||||
break;
|
||||
}
|
||||
case UserEvent::kSyncStartedEvent: {
|
||||
SyncStartedEvent const &e = event.syncstartedevent();
|
||||
QString const &userID = QString::fromStdString(e.userid());
|
||||
this->logTrace(QString("User event received: SyncStarted (userID = %1).:").arg(userID));
|
||||
emit syncStarted(userID);
|
||||
break;
|
||||
}
|
||||
case UserEvent::kSyncFinishedEvent: {
|
||||
SyncFinishedEvent const &e = event.syncfinishedevent();
|
||||
QString const &userID = QString::fromStdString(e.userid());
|
||||
this->logTrace(QString("User event received: SyncFinished (userID = %1).:").arg(userID));
|
||||
emit syncFinished(userID);
|
||||
break;
|
||||
}
|
||||
case UserEvent::kSyncProgressEvent: {
|
||||
SyncProgressEvent const &e = event.syncprogressevent();
|
||||
QString const &userID = QString::fromStdString(e.userid());
|
||||
this->logTrace(QString("User event received SyncProgress (userID = %1, progress = %2, elapsedMs = %3, remainingMs = %4).").arg(userID)
|
||||
.arg(e.progress()).arg(e.elapsedms()).arg(e.remainingms()));
|
||||
emit syncProgress(userID, e.progress(), e.elapsedms(), e.remainingms());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
this->logError("Unknown User event received.");
|
||||
}
|
||||
|
||||
@ -48,8 +48,8 @@ typedef std::unique_ptr<grpc::ClientContext> UPClientContext;
|
||||
class GRPCClient : public QObject {
|
||||
Q_OBJECT
|
||||
public: // static member functions
|
||||
static void removeServiceConfigFile(); ///< Delete the service config file.
|
||||
static GRPCConfig waitAndRetrieveServiceConfig(qint64 timeoutMs, class ProcessMonitor *serverProcess); ///< Wait and retrieve the service configuration.
|
||||
static void removeServiceConfigFile(QString const &configDir); ///< Delete the service config file.
|
||||
static GRPCConfig waitAndRetrieveServiceConfig(QString const &configDir, qint64 timeoutMs, class ProcessMonitor *serverProcess); ///< Wait and retrieve the service configuration.
|
||||
|
||||
public: // member functions.
|
||||
GRPCClient() = default; ///< Default constructor.
|
||||
@ -59,7 +59,8 @@ public: // member functions.
|
||||
GRPCClient &operator=(GRPCClient const &) = delete; ///< Disabled assignment operator.
|
||||
GRPCClient &operator=(GRPCClient &&) = delete; ///< Disabled move assignment operator.
|
||||
void setLog(Log *log); ///< Set the log for the client.
|
||||
void connectToServer(GRPCConfig const &config, class ProcessMonitor *serverProcess); ///< Establish connection to the gRPC server.
|
||||
void connectToServer(QString const &configDir, GRPCConfig const &config, class ProcessMonitor *serverProcess); ///< Establish connection to the gRPC server.
|
||||
bool isConnected() const; ///< Check whether the gRPC client is connected to the server.
|
||||
|
||||
grpc::Status checkTokens(QString const &clientConfigPath, QString &outReturnedClientToken); ///< Performs a token check.
|
||||
grpc::Status addLogEntry(Log::Level level, QString const &package, QString const &message); ///< Performs the "AddLogEntry" gRPC call.
|
||||
@ -180,6 +181,11 @@ signals:
|
||||
void userDisconnected(QString const &username);
|
||||
void userChanged(QString const &userID);
|
||||
void userBadEvent(QString const &userID, QString const& errorMessage);
|
||||
void usedBytesChanged(QString const &userID, qint64 usedBytes);
|
||||
void imapLoginFailed(QString const& username);
|
||||
void syncStarted(QString const &userID);
|
||||
void syncFinished(QString const &userID);
|
||||
void syncProgress(QString const &userID, double progress, qint64 elapsedMs, qint64 remainingMs);
|
||||
|
||||
public: // keychain related calls
|
||||
grpc::Status availableKeychains(QStringList &outKeychains);
|
||||
|
||||
@ -59,18 +59,19 @@ bool useFileSocketForGRPC() {
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] configDir The folder containing the configuration files.
|
||||
/// \return The absolute path of the service config path.
|
||||
//****************************************************************************************************************************************************
|
||||
QString grpcServerConfigPath() {
|
||||
return QDir(userConfigDir()).absoluteFilePath(grpcServerConfigFilename());
|
||||
QString grpcServerConfigPath(QString const &configDir) {
|
||||
return QDir(configDir).absoluteFilePath(grpcServerConfigFilename());
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return The absolute path of the service config path.
|
||||
//****************************************************************************************************************************************************
|
||||
QString grpcClientConfigBasePath() {
|
||||
return QDir(userConfigDir()).absoluteFilePath(grpcClientConfigBaseFilename());
|
||||
QString grpcClientConfigBasePath(QString const &configDir) {
|
||||
return QDir(configDir).absoluteFilePath(grpcClientConfigBaseFilename());
|
||||
}
|
||||
|
||||
|
||||
@ -81,8 +82,8 @@ QString grpcClientConfigBasePath() {
|
||||
/// \return The path of the created file.
|
||||
/// \return A null string if the file could not be saved.
|
||||
//****************************************************************************************************************************************************
|
||||
QString createClientConfigFile(QString const &token, QString *outError) {
|
||||
QString const basePath = grpcClientConfigBasePath();
|
||||
QString createClientConfigFile(QString const &configDir, QString const &token, QString *outError) {
|
||||
QString const basePath = grpcClientConfigBasePath(configDir);
|
||||
QString path, error;
|
||||
for (qint32 i = 0; i < 1000; ++i) // we try a decent amount of times
|
||||
{
|
||||
@ -255,4 +256,4 @@ QString getAvailableFileSocketPath() {
|
||||
}
|
||||
|
||||
|
||||
} // namespace bridgepp
|
||||
} // namespace bridgepp
|
||||
|
||||
@ -34,9 +34,9 @@ extern std::string const grpcMetadataServerTokenKey; ///< The key for the server
|
||||
typedef std::shared_ptr<grpc::StreamEvent> SPStreamEvent; ///< Type definition for shared pointer to grpc::StreamEvent.
|
||||
|
||||
|
||||
QString grpcServerConfigPath(); ///< Return the path of the gRPC server config file.
|
||||
QString grpcClientConfigBasePath(); ///< Return the path of the gRPC client config file.
|
||||
QString createClientConfigFile(QString const &token, QString *outError); ///< Create the client config file the server will retrieve and return its path.
|
||||
QString grpcServerConfigPath(QString const &configDir); ///< Return the path of the gRPC server config file.
|
||||
QString grpcClientConfigBasePath(QString const &configDir); ///< Return the path of the gRPC client config file.
|
||||
QString createClientConfigFile(QString const &configDir, QString const &token, QString *outError); ///< Create the client config file the server will retrieve and return its path.
|
||||
grpc::LogLevel logLevelToGRPC(Log::Level level); ///< Convert a Log::Level to gRPC enum value.
|
||||
Log::Level logLevelFromGRPC(grpc::LogLevel level); ///< Convert a grpc::LogLevel to a Log::Level.
|
||||
grpc::UserState userStateToGRPC(UserState state); ///< Convert a bridgepp::UserState to a grpc::UserState.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,8 @@ SPUser User::newUser(QObject *parent) {
|
||||
/// \param[in] parent The parent object.
|
||||
//****************************************************************************************************************************************************
|
||||
User::User(QObject *parent)
|
||||
: QObject(parent) {
|
||||
: QObject(parent)
|
||||
, imapFailureCooldownEndTime_(QDateTime::currentDateTime()) {
|
||||
|
||||
}
|
||||
|
||||
@ -293,6 +294,48 @@ void User::setTotalBytes(float totalBytes) {
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return true iff a sync is in progress.
|
||||
//****************************************************************************************************************************************************
|
||||
bool User::isSyncing() const {
|
||||
return isSyncing_;
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] syncing The new value for the sync state.
|
||||
//****************************************************************************************************************************************************
|
||||
void User::setIsSyncing(bool syncing) {
|
||||
if (isSyncing_ == syncing) {
|
||||
return;
|
||||
}
|
||||
|
||||
isSyncing_ = syncing;
|
||||
emit isSyncingChanged(syncing);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return The sync progress ratio
|
||||
//****************************************************************************************************************************************************
|
||||
float User::syncProgress() const {
|
||||
return syncProgress_;
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] progress The progress ratio.
|
||||
//****************************************************************************************************************************************************
|
||||
void User::setSyncProgress(float progress) {
|
||||
if (qAbs(syncProgress_ - progress) < 0.00001) {
|
||||
return;
|
||||
}
|
||||
|
||||
syncProgress_ = progress;
|
||||
emit syncProgressChanged(progress);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] state The user state.
|
||||
/// \return A string describing the state.
|
||||
@ -311,4 +354,24 @@ QString User::stateToString(UserState state) {
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// We display a notification and pop the application window if an IMAP client tries to connect to a signed out account, but we do not want to
|
||||
/// do it repeatedly, as it's an intrusive action. This function let's you define a period of time during which the notification should not be
|
||||
/// displayed.
|
||||
///
|
||||
/// \param durationMSecs The duration of the period in milliseconds.
|
||||
//****************************************************************************************************************************************************
|
||||
void User::startImapLoginFailureCooldown(qint64 durationMSecs) {
|
||||
imapFailureCooldownEndTime_ = QDateTime::currentDateTime().addMSecs(durationMSecs);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return true if we currently are in a cooldown period for the notification
|
||||
//****************************************************************************************************************************************************
|
||||
bool User::isInIMAPLoginFailureCooldown() const {
|
||||
return QDateTime::currentDateTime() < imapFailureCooldownEndTime_;
|
||||
}
|
||||
|
||||
|
||||
} // namespace bridgepp
|
||||
|
||||
@ -74,6 +74,8 @@ public: // member functions.
|
||||
User &operator=(User &&) = delete; ///< Disabled move assignment operator.
|
||||
void update(User const &user); ///< Update the user.
|
||||
Q_INVOKABLE QString primaryEmailOrUsername() const; ///< Return the user primary email, or, if unknown its username.
|
||||
void startImapLoginFailureCooldown(qint64 durationMSecs); ///< Start the user cooldown period for the IMAP login attempt while signed-out notification.
|
||||
bool isInIMAPLoginFailureCooldown() const; ///< Check if the user in a IMAP login failure notification.
|
||||
|
||||
public slots:
|
||||
// slots for QML generated calls
|
||||
@ -99,6 +101,8 @@ public:
|
||||
Q_PROPERTY(bool splitMode READ splitMode WRITE setSplitMode NOTIFY splitModeChanged)
|
||||
Q_PROPERTY(float usedBytes READ usedBytes WRITE setUsedBytes NOTIFY usedBytesChanged)
|
||||
Q_PROPERTY(float totalBytes READ totalBytes WRITE setTotalBytes NOTIFY totalBytesChanged)
|
||||
Q_PROPERTY(bool isSyncing READ isSyncing WRITE setIsSyncing NOTIFY isSyncingChanged)
|
||||
Q_PROPERTY(float syncProgress READ syncProgress WRITE setSyncProgress NOTIFY syncProgressChanged)
|
||||
|
||||
QString id() const;
|
||||
void setID(QString const &id);
|
||||
@ -118,6 +122,10 @@ public:
|
||||
void setUsedBytes(float usedBytes);
|
||||
float totalBytes() const;
|
||||
void setTotalBytes(float totalBytes);
|
||||
bool isSyncing() const;
|
||||
void setIsSyncing(bool syncing);
|
||||
float syncProgress() const;
|
||||
void setSyncProgress(float progress);
|
||||
|
||||
signals:
|
||||
// signals used for Qt properties
|
||||
@ -132,11 +140,14 @@ signals:
|
||||
void usedBytesChanged(float byteCount);
|
||||
void totalBytesChanged(float byteCount);
|
||||
void toggleSplitModeFinished();
|
||||
void isSyncingChanged(bool syncing);
|
||||
void syncProgressChanged(float syncProgress);
|
||||
|
||||
private: // member functions.
|
||||
User(QObject *parent); ///< Default constructor.
|
||||
|
||||
private: // data members.
|
||||
QDateTime imapFailureCooldownEndTime_; ///< The end date/time for the IMAP login failure notification cooldown period.
|
||||
QString id_; ///< The userID.
|
||||
QString username_; ///< The username
|
||||
QString password_; ///< The IMAP password of the user.
|
||||
@ -146,6 +157,8 @@ private: // data members.
|
||||
bool splitMode_ { false }; ///< Is split mode active.
|
||||
float usedBytes_ { 0.0f }; ///< The storage used by the user.
|
||||
float totalBytes_ { 1.0f }; ///< The storage quota of the user.
|
||||
bool isSyncing_ { false }; ///< Is a sync in progress for the user.
|
||||
float syncProgress_ { 0.0f }; ///< The sync progress.
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -84,7 +84,8 @@ void Overseer::releaseWorker() {
|
||||
if (thread_) {
|
||||
if (!thread_->isFinished()) {
|
||||
thread_->quit();
|
||||
thread_->wait();
|
||||
if (!thread_->wait(maxTerminationWaitTimeMs))
|
||||
thread_->terminate();
|
||||
}
|
||||
thread_->deleteLater();
|
||||
thread_ = nullptr;
|
||||
|
||||
@ -46,6 +46,9 @@ public slots:
|
||||
void startWorker(bool autorelease) const; ///< Run the worker.
|
||||
void releaseWorker(); ///< Delete the worker and its thread.
|
||||
|
||||
public: // static data members
|
||||
static qint64 const maxTerminationWaitTimeMs { 10000 }; ///< The maximum wait time for the termination of a thread
|
||||
|
||||
public: // data members.
|
||||
QThread *thread_ { nullptr }; ///< The thread.
|
||||
Worker *worker_ { nullptr }; ///< The worker.
|
||||
|
||||
Reference in New Issue
Block a user