Audacity 3.2.0
Public Member Functions | Private Member Functions | List of all members
cloud::audiocom::UserService Class Referencefinal

Service for providing information about the user profile. More...

#include <UserService.h>

Inheritance diagram for cloud::audiocom::UserService:
[legend]
Collaboration diagram for cloud::audiocom::UserService:
[legend]

Public Member Functions

void UpdateUserData ()
 Request the service to update the data. More...
 
void ClearUserData ()
 Reset the user profile data. More...
 
wxString GetUserSlug () const
 "Slug" used to construct shareable URLs More...
 
wxString GetDisplayName () const
 Get the user name to display in the dialog. More...
 
wxString GetAvatarPath () const
 Gets a path to the avatar. More...
 
- Public Member Functions inherited from Observer::Publisher< UserDataChanged >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 

Private Member Functions

void DownloadAvatar (std::string_view url)
 

Additional Inherited Members

- Public Types inherited from Observer::Publisher< UserDataChanged >
using message_type = UserDataChanged
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const UserDataChanged &) >
 Type of functions that can be connected to the Publisher. More...
 
- Static Public Attributes inherited from Observer::Publisher< UserDataChanged >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from Observer::Publisher< UserDataChanged >
CallbackReturn Publish (const UserDataChanged &message)
 Send a message to connected callbacks. More...
 

Detailed Description

Service for providing information about the user profile.

Definition at line 26 of file UserService.h.

Member Function Documentation

◆ ClearUserData()

void cloud::audiocom::UserService::ClearUserData ( )

Reset the user profile data.

Definition at line 120 of file UserService.cpp.

121{
123 [this]()
124 {
125 // No valid data was present, do not spam Publish()
126 if (GetUserSlug().empty())
127 return;
128
129 userName.Write({});
130 displayName.Write({});
131 avatarEtag.Write({});
132
133 gPrefs->Flush();
134
135 Publish({});
136 });
137}
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
CallbackReturn Publish(const UserDataChanged &message)
Send a message to connected callbacks.
Definition: Observer.h:207
bool Write(const T &value)
Write value to config and return true if successful.
Definition: Prefs.h:259
virtual bool Flush() noexcept=0
wxString GetUserSlug() const
"Slug" used to construct shareable URLs
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
Definition: BasicUI.cpp:208

References cloud::audiocom::anonymous_namespace{UserService.cpp}::avatarEtag, BasicUI::CallAfter(), cloud::audiocom::anonymous_namespace{UserService.cpp}::displayName, audacity::BasicSettings::Flush(), GetUserSlug(), gPrefs, Observer::Publisher< UserDataChanged >::Publish(), cloud::audiocom::anonymous_namespace{UserService.cpp}::userName, and Setting< T >::Write().

Here is the call graph for this function:

◆ DownloadAvatar()

void cloud::audiocom::UserService::DownloadAvatar ( std::string_view  url)
private

Definition at line 145 of file UserService.cpp.

146{
147 const auto avatarPath = MakeAvatarPath();
148 const auto avatarTempPath = avatarPath + ".tmp";
149
150 if (url.empty())
151 {
152 if (wxFileExists(avatarPath))
153 wxRemoveFile(avatarPath);
154
155 return;
156 }
157
158 std::shared_ptr<wxFile> avatarFile = std::make_shared<wxFile>();
159
160 if (!avatarFile->Create(avatarTempPath, true))
161 return;
162
163 using namespace audacity::network_manager;
164
165 auto request = Request(std::string(url));
166
167 const auto etag = audacity::ToUTF8(avatarEtag.Read());
168
169 // If ETag is present - use it to prevent re-downloading the same file
170 if (!etag.empty() && wxFileExists(avatarPath))
171 request.setHeader(common_headers::IfNoneMatch, etag);
172
173 auto response = NetworkManager::GetInstance().doGet(request);
174
175 response->setOnDataReceivedCallback(
176 [response, avatarFile](auto)
177 {
178 std::vector<char> buffer(response->getBytesAvailable());
179
180 size_t bytes = response->readData(buffer.data(), buffer.size());
181
182 avatarFile->Write(buffer.data(), buffer.size());
183 });
184
185 response->setRequestFinishedCallback(
186 [response, avatarFile, avatarPath, avatarTempPath, this](auto)
187 {
188 avatarFile->Close();
189
190 const auto httpCode = response->getHTTPCode();
191
192 if (httpCode != 200)
193 {
194 // For any response except 200 just remove the temp file
195 wxRemoveFile(avatarTempPath);
196 return;
197 }
198
199 const auto etag = response->getHeader("ETag");
200 const auto oldPath = avatarPath + ".old";
201
202 if (wxFileExists(avatarPath))
203 if (!wxRenameFile(avatarPath, oldPath))
204 return;
205
206 if (!wxRenameFile(avatarTempPath, avatarPath))
207 {
208 // Try at least to get it back...
209 wxRenameFile(oldPath, avatarPath);
210 return;
211 }
212
213 if (wxFileExists(oldPath))
214 wxRemoveFile(oldPath);
215
217 [this, etag]()
218 {
219 avatarEtag.Write(etag);
220 gPrefs->Flush();
221
222 Publish({});
223 });
224 });
225}
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:207
FrameStatistics & GetInstance() noexcept
std::string ToUTF8(const std::wstring &wstr)

References cloud::audiocom::anonymous_namespace{UserService.cpp}::avatarEtag, BasicUI::CallAfter(), audacity::BasicSettings::Flush(), anonymous_namespace{FrameStatistics.cpp}::GetInstance(), gPrefs, audacity::network_manager::common_headers::IfNoneMatch, cloud::audiocom::anonymous_namespace{UserService.cpp}::MakeAvatarPath(), Observer::Publisher< UserDataChanged >::Publish(), Setting< T >::Read(), audacity::ToUTF8(), and Setting< T >::Write().

Referenced by UpdateUserData().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetAvatarPath()

wxString cloud::audiocom::UserService::GetAvatarPath ( ) const

Gets a path to the avatar.

Definition at line 237 of file UserService.cpp.

238{
239 auto path = MakeAvatarPath();
240
241 if (!wxFileExists(path))
242 return {};
243
244 return path;
245}

References cloud::audiocom::anonymous_namespace{UserService.cpp}::MakeAvatarPath().

Here is the call graph for this function:

◆ GetDisplayName()

wxString cloud::audiocom::UserService::GetDisplayName ( ) const

Get the user name to display in the dialog.

Definition at line 227 of file UserService.cpp.

228{
229 return displayName.Read();
230}

References cloud::audiocom::anonymous_namespace{UserService.cpp}::displayName, and Setting< T >::Read().

Here is the call graph for this function:

◆ GetUserSlug()

wxString cloud::audiocom::UserService::GetUserSlug ( ) const

"Slug" used to construct shareable URLs

Definition at line 232 of file UserService.cpp.

233{
234 return userName.Read();
235}

References Setting< T >::Read(), and cloud::audiocom::anonymous_namespace{UserService.cpp}::userName.

Referenced by ClearUserData().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateUserData()

void cloud::audiocom::UserService::UpdateUserData ( )

Request the service to update the data.

Definition at line 61 of file UserService.cpp.

62{
63 auto& oauthService = GetOAuthService();
64
65 if (!oauthService.HasAccessToken())
66 return;
67
68 using namespace audacity::network_manager;
69
70 Request request(GetServiceConfig().GetAPIUrl("/me"));
71
72 request.setHeader(
74 std::string(oauthService.GetAccessToken()));
75
76 request.setHeader(
78
79 auto response = NetworkManager::GetInstance().doGet(request);
80
81 response->setRequestFinishedCallback(
82 [response, this](auto)
83 {
84 const auto httpCode = response->getHTTPCode();
85
86 if (httpCode != 200)
87 return;
88
89 const auto body = response->readAll<std::string>();
90
91 using namespace rapidjson;
92
93 Document document;
94 document.Parse(body.data(), body.size());
95
96 if (!document.IsObject())
97 return;
98
99 const auto username = document["username"].GetString();
100 const auto avatar = document["avatar"].GetString();
101 const auto profileName = document["profile"]["name"].GetString();
102
104 [this, username = std::string(username),
105 profileName = std::string(profileName),
106 avatar = std::string(avatar)]()
107 {
110
111 gPrefs->Flush();
112
113 DownloadAvatar(avatar);
114
115 Publish({});
116 });
117 });
118}
void DownloadAvatar(std::string_view url)
wxString ToWXString(const std::string &str)
const ServiceConfig & GetServiceConfig()
Returns the instance of the ServiceConfig.
OAuthService & GetOAuthService()
Returns the instance of the OAuthService.

References audacity::network_manager::common_headers::Accept, audacity::network_manager::common_content_types::ApplicationJson, audacity::network_manager::common_headers::Authorization, BasicUI::CallAfter(), cloud::audiocom::anonymous_namespace{UserService.cpp}::displayName, DownloadAvatar(), audacity::BasicSettings::Flush(), anonymous_namespace{FrameStatistics.cpp}::GetInstance(), cloud::audiocom::GetOAuthService(), cloud::audiocom::GetServiceConfig(), gPrefs, Observer::Publisher< UserDataChanged >::Publish(), audacity::network_manager::Request::setHeader(), audacity::ToWXString(), cloud::audiocom::anonymous_namespace{UserService.cpp}::userName, and Setting< T >::Write().

Here is the call graph for this function:

The documentation for this class was generated from the following files: