25#include <wx/stdpaths.h>
26#include <wx/filename.h>
30#define UPDATE_LOCAL_TESTING 0
37using Clock = std::chrono::system_clock;
41#if UPDATE_LOCAL_TESTING == 1
80 static std::once_flag
flag;
81 std::call_once(
flag, [&instance] {
82 instance.mTimer.SetOwner(&instance,
ID_TIMER);
83 instance.mTimer.StartOnce(1);
94#if AUDACITY_BUILD_LEVEL == 0
95 const auto url =
"https://updates.audacityteam.org/builds/alpha.xml";
96#elif AUDACITY_BUILD_LEVEL == 1
97 const auto url =
"https://updates.audacityteam.org/builds/beta.xml";
99 const auto url =
"https://updates.audacityteam.org/feed/latest.xml";
122 if (!ignoreNetworkErrors)
125 XC(
"Error checking for update",
"update dialog"),
126 XC(
"Unable to connect to Audacity update server.",
"update dialog"),
138 if (!ignoreNetworkErrors)
141 XC(
"Error checking for update",
"update dialog"),
142 XC(
"Update data was corrupted.",
"update dialog"),
152#if UPDATE_LOCAL_TESTING == 0
156 gAudioIO->CallAfterRecording([
this, ignoreNetworkErrors, configurableNotification] {
158 const int code = dlg.ShowModal();
160 if (code == wxID_YES)
175 if (!ignoreNetworkErrors)
177 wxTheApp->CallAfter([] {ShowErrorDialog( {},
178 XC(
"Error downloading update",
"update dialog"),
179 XC(
"Can't open the Audacity download link.",
"update dialog"),
181 ErrorDialogOptions{ ErrorDialogType::ModalErrorReport });
190 if ((info.GetOperatingSystemId() & wxOS_WINDOWS) ||
191 info.GetOperatingSystemId() & wxOS_MAC)
196 wxTheApp->CallAfter([cmd] { wxExecute(cmd, wxEXEC_ASYNC); });
209 wxString installerExtension;
211 if (info.GetOperatingSystemId() & wxOS_WINDOWS)
212 installerExtension =
"exe";
213 else if(info.GetOperatingSystemId() & wxOS_MAC)
214 installerExtension =
"dmg";
217 wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Downloads), audacityPatchFilename, installerExtension)
224 downloadResponse->setDownloadProgressCallback(
225 [
this](int64_t current, int64_t expected) {
227 wxTheApp->CallAfter([
this, current, expected]{
238 std::vector<char> buffer(downloadResponse->getBytesAvailable());
240 size_t bytes = downloadResponse->readData(buffer.data(), buffer.size());
242 if (mAudacityInstaller.is_open())
243 mAudacityInstaller.write(buffer.data(), buffer.size());
249 else if (code == wxID_NO)
255#if UPDATE_LOCAL_TESTING == 0
259 if (!configurableNotification)
261 gAudioIO->CallAfterRecording([] {
276#if UPDATE_LOCAL_TESTING == 0
283 mTimer.StartOnce(std::chrono::duration_cast<std::chrono::milliseconds>(
293 const TimePoint nextUpdatesCheckingTime(std::chrono::milliseconds(
297 const TimePoint currentTime = Clock::now();
301 if (nextUpdatesCheckingTime < currentTime)
308 std::chrono::duration<int32_t, std::ratio<60 * 60 * 24>>;
310 const auto postponeUpdateUntil =
311 std::chrono::time_point_cast<DayDuration>(
312 currentTime) + DayDuration(1);
314 const std::chrono::milliseconds postponeUpdateUntilMS(
315 postponeUpdateUntil.time_since_epoch());
319 wxString(std::to_string(postponeUpdateUntilMS.count())));
Toolkit-neutral facade for basic user interface services.
Declare an interface for HTTP response.
Declare a class for performing HTTP requests.
StickySetting< BoolSetting > DefaultUpdatesCheckingFlag
audacity::BasicSettings * gPrefs
Declare a class for constructing HTTP requests.
std::chrono::system_clock Clock
static const char * prefsUpdateScheduledTime
Clock::time_point TimePoint
TimePoint::duration Duration
constexpr Duration updatesCheckInterval
static BoolSetting prefUpdatesNoticeShown(wxT("/Update/UpdateNoticeShown"), false)
Declare a class that handles managing of updates.
Define a dialog to notify the user about automatic update checking.
static VersionId CurrentBuildVersion()
Return version (VersionId) object with current Audacity build version.
This specialization of Setting for bool adds a Toggle method to negate the saved value.
Information dialog about no updates available, that allows to navigate to settings quickly.
bool Write(const T &value)
Write value to config and return true if successful.
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined */
bool Parse(const VersionPatch::UpdateDataFormat &updateData, VersionPatch *versionPatch)
Parsing from update data format to VersionPatch fields.
A class that managing of updates.
void GetUpdates(bool ignoreNetworkErrors, bool configurableNotification)
std::unique_ptr< BasicUI::ProgressDialog > mProgressDialog
static UpdateManager & GetInstance()
std::string mAudacityInstallerPath
static void Start(bool suppressModal)
void OnTimer(wxTimerEvent &event)
UpdateDataParser mUpdateDataParser
std::ofstream mAudacityInstaller
VersionPatch GetVersionPatch() const
VersionPatch mVersionPatch
bool IsTimeForUpdatesChecking()
Scheduling update time for avoiding multiplying update notifications.
Dialog, that notifies the users about automatic updates checking.
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
Interface, that provides access to the data from the HTTP response.
static NetworkManager & GetInstance()
ResponsePtr doGet(const Request &request)
void ShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options={})
Show an error dialog with a link to the manual for further help.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
std::unique_ptr< ProgressDialog > MakeProgress(const TranslatableString &title, const TranslatableString &message, unsigned flags=(ProgressShowStop|ProgressShowCancel), const TranslatableString &remainingLabelText={})
Create and display a progress dialog.
FrameStatistics & GetInstance() noexcept
Options for variations of error dialogs; the default is for modal dialogs.
A structure that describes patch fields.
std::string UpdateDataFormat