#ifndef __HWS_CLIENT_H__ #define __HWS_CLIENT_H__ #include <QObject> #include <QSettings> #include <QSharedPointer> #include <QUrl> #include "Session.h" #include "RequestError.h" #include "SyncProject.h" namespace hws { /// The ProjectUpdate struct represents notifications regarding ongoing /// changes to the files of Helix Sync projects. typedef struct ProjectUpdate { /// The SyncProject's id QString projectId; /// The latest change on the project int change; /// The project version. Updates here may indicate new project structures. int version; } ProjectUpdate; /// Front end to making requests against the Phoenix web services API. class Client : public QObject { Q_OBJECT public: /// The QSettings key we store our values under. static const QString DEFAULT_SETTINGS_KEY; /// Most applications are assumed to use this variation, where the /// client's session is automatically fetched from settings. /// /// The Client will cache the handle to QSettings, and /// for any subsequent login, will cache the Session in a JSON object. Client(QObject *parent, QSettings *settings, QUrl url); /// A variation of the constructor that will use a different settings /// key than the default. Client(QObject *parent, QSettings *settings, QUrl url, QString settingsKey); /// A basic empty client that should be updated Client(QObject *parent); /// Destroy the client. Any open connections for updates will get /// automatically disconnected. ~Client(); /// The Helix Web Services URL const QUrl & url() const; /// The Helix Web Services URL void setUrl(const QUrl & url); /// When true, this should have a session instance that was known to /// work at some point. bool hasSession() const; /// The session instance is required before making any remote call. const Session & session() const; /// If you have stored a previously used session, you can just assign it /// to this client instance. void setSession(const Session & session); /// This is a leading path to almost every request in the system. It's /// configurable since some development environment setups don't have /// a nice way to handle creating DNS entries, which leads to services /// sometimes getting mounted locally under subpaths. const QString & hwsPrefixPath() const; /// This is a leading path to almost every request in the system. It's /// configurable since some development environment setups don't have /// a nice way to handle creating DNS entries, which leads to services /// sometimes getting mounted locally under subpaths. void setHWSPrefixPath(const QString & path); /// Path to the notifications web-socket instance, which is often /// different from the main prefix path const QString & updatesPath() const; /// Path to the notifications web-socket instance, which is often /// different from the main prefix path void setUpdatesPath(const QString & path); /// All stored sessions are saved as a JSON object under this settings /// key, which is defaulted to "HelixWebServicesSettings". /// /// This should be set on construction only. const QString & settingsKey() const; /// Returns the current settings handle for the client. If it exists, /// The settings will store the session data by URL under a particular /// key. const QSharedPointer<QSettings> settings() const; /// The current settings handle for the client. void setSettings(QSharedPointer<QSettings> settings); public slots: /// Trigger a remote call to the web services instance to validate that /// the session (and ticket) is still valid. /// /// Even if this client has no session, we'll still double check that /// we can call back to the server. void validateSession(); /// This should attempt a login as the user and password to the url /// that's been configured on this client. /// /// IMPORTANT: this will attempt to resolve the hostname of the client /// itself, which we'll use to generate a host locked ticket. void logIn(const QString & user, const QString & password); /// Triggers a request to load all SyncProjects accessible to the user /// /// Emits a fetchProjectsDone signal when completed. void fetchAllProjects(); /// Triggers a request to load SyncProjects the user is a member or /// is the owner of. /// /// Emits a fetchProjectsDone signal when completed. void fetchMyProjects(); /// Triggers a request just to load the indicated SyncProject void fetchProject(const QString & id); /// Create a new SyncProject in the system void createProject(const SyncProject & project); /// Creates a new Perforce client workspace for the user on the client. /// /// Right now, Helix Sync projects can only have one branch, so we /// do not require specifying a branch. /// /// All other fields are determined by the web service. /// /// \param projectId The project ID to create the client for. /// \param hostname The Host field to use in the Client specification /// \param root The local directory to use for the Root field void createClientForProject(const QString & projectId, const QString & hostname, const QString & root); /// Remove the client indicated by the name. /// /// This is intended to be a client created by the user on the local /// machine. /// /// \param clientName The 'Client' field which should be returned by /// the createClientForProject method. void deleteClient(const QString & clientName); /// Add a new project to be monitored in the system. /// /// Every time you say, create a new project, you should notify the /// services that the client now has this project. The services will /// not automatically know that the client is ready for updates. void watchProject(const QString & projectId); /// List of projects to be monitored in the system. /// /// This should probably be the last step of a typical startup process /// for client applications. When called, this will start a session with /// the services layer that will start sending projectUpdated signals. /// /// This *does* require a valid session for use. void watchProjects(const QList<QString> & projectIds); /// Tell the server to unwatch a list of project IDs. void unwatchProjects(const QList<QString> & projectIds); /// In case the user has just removed a local project reference, let the /// server know your client is no longer interested in receiving updates. void unwatchProject(const QString & projectId); signals: /// Callback after validating a session. /// /// The error value indicates a networking or remote system problem. /// /// If the session is invalid, the error will not be set. Instead, you /// should double check the output of `client.hasSession()`. If that is /// false, you'll need to sign in again. /// /// At this point, if the session is invalid, it will be cleared from /// any QSettings cachce as well, if the client was initialized with a /// settings handle. void validateSessionDone(RequestErrorPtr error); /// When the login request has resolved this is called. /// /// Authentication errors will result in no session being created. void logInDone(RequestErrorPtr error, SessionPtr session); /// The list of sync projects is now available. void fetchProjectsDone(RequestErrorPtr error, QSharedPointer< QList<SyncProjectPtr> > projects); /// The information about a single project is available void fetchProjectDone(RequestErrorPtr error, SyncProjectPtr project); /// The request to create a project is done. void createProjectDone(RequestErrorPtr error, SyncProjectPtr project); /// Returns the new client name to be used for the project locally. /// /// \param error Not null if there was a problem with the command. /// \param clientName The temporary client to use. void clientCreated(RequestErrorPtr error, const QString & clientName); /// Callback from deleteClient. /// /// \param error If this is null, the client was correctly deleted. void clientDeleted(RequestErrorPtr error); /// The request to change a project is ready. void projectUpdated(QSharedPointer<ProjectUpdate> change); /// A problem resulted from connecting with the notifications system void updateError(RequestErrorPtr error); // Implementation is hidden using PIMPL technique. // I'm hiding the direct include dependencies on Qt5Network and // Qt5WebSockets. private: class Impl; class LogInFinished; Impl *mImpl; // Disabled methods private: void init(QSettings * settings, QUrl url, const QString & settingsKey); Client(const Client &); Client & operator=(const Client &); }; typedef QSharedPointer<Client> ClientPtr; } #endif /* __HWS_CLIENT_H__ */
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#9 | 15622 | tjuricek |
Move source code to 'source/' subdirectory of branch. build/ will remain where it is. |
||
#8 | 15578 | tjuricek |
Removing QSettings* usage from hws::Client. The way QSettings was being used only is relevant for one connection at a time, and, it didn't seem to work on windows nicely anyway. |
||
#7 | 15544 | tjuricek | Explain that the QSettings handle for hws::Client should only be used on connections you don't specify a P4PORT for. | ||
#6 | 15521 | tjuricek | Call client.ignoreSslErrors(true) to bypass self-signed cert problems. | ||
#5 | 15445 | tjuricek | Allow per-request overrides to be set via addRequestConfig | ||
#4 | 15423 | tjuricek |
Revised HWS Qt API. This is a major revision of the API, which removes most of the "typed" data, replacing it with a more generic "executeMethodDone" callback. The main benefit here is to allow the API to interop with different versions of p4d, and not restrict the methods it can call. We may add more helpers in the future. |
||
#3 | 14054 | tjuricek |
Allowing the Qt client to select 'all' vs 'my' projects. Right now, it should default to using "my" projects as a rule. |
||
#2 | 14049 | tjuricek |
Add methods to generate client workspaces for a user. The Qt SDK was updated based on immediate need. Also, add Ruby client SDK documentation to the docs site. Everything is early, but there's *some* reference available at least. |
||
#1 | 14025 | tjuricek |
Revise Qt SDK to a single 'helix_web_services_client' project. Most references to "Phoenix" have now been removed. Additionally, this is more similar to the other platform client SDKs in Ruby and JavaScript. Documentation via Doxygen is now available, and will be how much of the SDK reference should occur. |
||
//guest/perforce_software/helix-web-services/main/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.h | |||||
#10 | 13532 | tjuricek |
Qt SDK: Add constructor that uses an application's QSettings for caching Sessions for each URL Added a simple validateSession remote call to ping the services instance to see if the session is indeed usable. Also, removing puma configuraiton that is automatically generated in the (shared) development instance. |
||
#9 | 13506 | tjuricek |
Change to a C++03 build. Major changes: 1. QSharedPointer::create(...) is much more restricted than in C++11, so just use the .reset() method unless you're passing in a single const reference argument to the constructor. 2. Using Qt's foreach. 3. Replace lambdas with simpler helper methods. This seems to work, but we may have subtle memory issues I'm not 100% on top of yet. |
||
#8 | 13501 | tjuricek |
Adding a space to separate out the template declaration parameters. Doesn't seem to be an issue with gcc, this must be a visual studio issue. |
||
#7 | 13497 | tjuricek | Follow QObject memory management conventions for the PhoenixServicesClient. | ||
#6 | 13483 | tjuricek | Typedef that struct. | ||
#5 | 13471 | tjuricek |
Define some JSON messages for Qt API's websocket interaction. Not tested... yet. |
||
#4 | 13470 | tjuricek |
Phoenix notification services, client API, including new phoenix_updater This is an interim commit containing a first pass implementation of the phoenix_updater. Notably missing parts: - The Qt API doesn't yet actually interact with the phoenix_updater - The phoenix_services web service doesn't filter out notifications I *may* end up creating another web application *just* to filter out notifications, since this may end up taking up a lot of background workers. |
||
#3 | 13459 | tjuricek |
Return the created project when creating a new project, since default values will often be filled out. Allow new projects to be created only with names set. We'll generate an ID at the moment, when I have better indexing, I'll double check for uniqueness. |
||
#2 | 13458 | tjuricek |
Revising P4 Web API docbook documentation to become the Perforce Web Services guide. Right now this is just focused on the Qt SDK. The remaining protocol documentation, etc, will happen eventually. |
||
#1 | 13443 | tjuricek |
Reorganized the Qt libraries into a separate part of the tree, to make it easier for CMake configuration. Added 'qt_build' and 'qt_test' tasks to at least execute tests and fail the build if they don't pass. Started the implementation of the project library interaction. Change: 1018651 Date: 3/4/15 11:43 AM Client: tjuricek_dhcp-141-n100_5959 User: tjuricek Status: pending Type: public Description: Reorganized the Qt libraries into a separate part of the tree, to make it easier for CMake configuration. Added 'qt_build' and 'qt_test' tasks to at least execute tests and fail the build if they don't pass. Started the implementation of the project library interaction. JobStatus: Jobs: Files: //web-services/p4ws-main/Rakefile //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/CMakeLists.txt //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/PhoenixIntegrationTests.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/README //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixProject.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixProject.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/RequestError.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/RequestError.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/Session.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/Session.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/test/PhoenixServicesClientTests.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/test/PhoenixServicesClientTests.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/test/SessionTests.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/test/SessionTests.h //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/CMakeLists.txt //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services.h //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/Branch.cpp //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/Branch.h //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/Project.cpp //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/Project.h //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/View.cpp //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/View.h //web-services/p4ws-main/qt/CMakeLists.txt //web-services/p4ws-main/qt/p4_phoenix_services_client/CMakeLists.txt //web-services/p4ws-main/qt/p4_phoenix_services_client/PhoenixIntegrationTests.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/README //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix.h //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/PhoenixProject.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/PhoenixProject.h //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.h //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/RequestError.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/RequestError.h //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/Session.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/Session.h //web-services/p4ws-main/qt/p4_phoenix_services_client/test/PhoenixServicesClientTests.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/test/PhoenixServicesClientTests.h //web-services/p4ws-main/qt/p4_phoenix_services_client/test/SessionTests.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/test/SessionTests.h //web-services/p4ws-main/qt/p4_project_services_client/CMakeLists.txt //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeCache.txt //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeCCompiler.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeCXXCompiler.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeDetermineCompilerABI_C.bin //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeDetermineCompilerABI_CXX.bin //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeSystem.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CompilerIdC/CMakeCCompilerId.c //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CompilerIdC/a.out //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CompilerIdCXX/CMakeCXXCompilerId.cpp //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CompilerIdCXX/a.out //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/CMakeDirectoryInformation.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/CMakeOutput.log //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/Makefile.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/Makefile2 //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/TargetDirectories.txt //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/cmake.check_cache //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/DependInfo.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/build.make //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/cmake_clean.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/cmake_clean_target.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/depend.make //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/flags.make //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/link.txt //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/progress.make //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/progress.marks //web-services/p4ws-main/qt/p4_project_services_client/build/Makefile //web-services/p4ws-main/qt/p4_project_services_client/build/cmake_install.cmake //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services.h //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/Branch.cpp //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/Branch.h //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/Project.cpp //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/Project.h //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/View.cpp //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/View.h |
||
//guest/perforce_software/helix-web-services/main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.h | |||||
#4 | 13439 | tjuricek |
Added a *very trivial* logIn implementation. This just makes the *current* POST request to /p4_phoenix_services/v1/sessions, which *does not* include the ability to create a host locked P4 ticket for the user. So it's not quite usable yet. But, I've made several tweaks to the API which should be stablizing. |
||
#3 | 13435 | tjuricek |
Added framework for QtTest to the p4_phoenix_services qt client (and fixing stupid compile errors). Also, ignoring .DS_Store. |
||
#2 | 13425 | tjuricek | Fixing crappy-ass whitespace | ||
#1 | 13424 | tjuricek |
First-pass at Qt Client API for Phoenix web services. The underlying project data is organized as the basic 'p4_project_services' API, which is then used by the higher-level 'phoenix' API, just to cut down on a lot of potential boiler plate. The base project model should allow for custom extensions, but it's aniticpated that the product-specific stuff doesn't really need to care too much about this. We just need to make sure that if new product extensions exist that the C++ API doesn't know about, they: a.) don't explode on read because there's something new, and b.) don't just delete the extension code. These are *just headers* to get the ball rolling on the needs of the Phoenix engine. Things like 'sessions' are interesting and may have been overlooked. |