Skip to content

Commit 2a96d01

Browse files
committed
Add the ability to fetch all available packages
1 parent 489894f commit 2a96d01

3 files changed

Lines changed: 87 additions & 64 deletions

File tree

src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@
113113
x:Name="BackupToGitHubButton"
114114
ButtonText="Backup settings and packages"
115115
Click="BackupToGitHubButton_Click"
116-
CornerRadius="8"
116+
CornerRadius="8,8,0,0"
117117
IsEnabled="False"
118118
Text="Backup your settings and packages to a private GitHub Gist">
119119
<widgets:ButtonCard.Description>
120120
<widgets:TranslatedTextBlock Text="Requires you to be logged in with your GitHub account." />
121121
</widgets:ButtonCard.Description>
122122
</widgets:ButtonCard>
123123

124-
<widgets:ButtonCard
124+
<!--widgets:ButtonCard
125125
x:Name="RestoreSettingsFromGitHubButton"
126126
ButtonText="Restore settings"
127127
Click="RestoreSettingsFromGitHubButton_Click"
@@ -131,13 +131,14 @@
131131
<widgets:ButtonCard.Description>
132132
<widgets:TranslatedTextBlock Text="This will overwrite your current settings. A restart may be required." />
133133
</widgets:ButtonCard.Description>
134-
</widgets:ButtonCard>
134+
</widgets:ButtonCard-->
135135

136136
<widgets:ButtonCard
137137
x:Name="RestorePackagesFromGitHubButton"
138138
ButtonText="Restore packages"
139139
Click="RestorePackagesFromGitHubButton_Click"
140-
CornerRadius="8"
140+
CornerRadius="0,0,8,8"
141+
BorderThickness="1,0,1,1"
141142
IsEnabled="False"
142143
Text="Restore your packages from a private GitHub Gist">
143144
<widgets:ButtonCard.Description>
@@ -147,4 +148,4 @@
147148

148149
</StackPanel>
149150
</ScrollViewer>
150-
</Page>
151+
</Page>

src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ private async void UpdateBackupToGitHubButtonStatus()
9090
UpdateGitHubLoginStatus();
9191
bool isAuthenticated = await _authService.IsAuthenticatedAsync();
9292
BackupToGitHubButton.IsEnabled = isAuthenticated;
93-
RestoreSettingsFromGitHubButton.IsEnabled = isAuthenticated;
93+
// nRestoreSettingsFromGitHubButton.IsEnabled = isAuthenticated;
9494
RestorePackagesFromGitHubButton.IsEnabled = isAuthenticated;
9595
}
9696

97-
private async void RestoreSettingsFromGitHubButton_Click(object sender, EventArgs e)
97+
/*private async void RestoreSettingsFromGitHubButton_Click(object sender, EventArgs e)
9898
{
9999
RestoreSettingsFromGitHubButton.IsEnabled = false;
100100
var confirmDialog = DialogHelper.DialogFactory.Create();
@@ -112,7 +112,7 @@ private async void RestoreSettingsFromGitHubButton_Click(object sender, EventArg
112112
}
113113
114114
DialogHelper.ShowLoadingDialog(CoreTools.Translate("Restoring settings from GitHub Gist..."));
115-
var settingsContent = await _backupService.RetrieveFileAsync("unigetui.settings.json");
115+
var settingsContent = "";//await _backupService.RetrieveFileAsync("unigetui.settings.json");
116116
if (settingsContent != null)
117117
{
118118
await Task.Run(() => Settings.ImportFromString_JSON(settingsContent));
@@ -134,21 +134,33 @@ private async void RestoreSettingsFromGitHubButton_Click(object sender, EventArg
134134
_ = DialogHelper.Window.ShowDialogAsync(errorDialog);
135135
}
136136
UpdateBackupToGitHubButtonStatus();
137-
}
137+
}*/
138138

139139
private async void RestorePackagesFromGitHubButton_Click(object sender, EventArgs e)
140140
{
141141
RestorePackagesFromGitHubButton.IsEnabled = false;
142-
var packagesContent = await _backupService.RetrieveFileAsync("unigetui.packages.ubundle");
143-
if (packagesContent != null)
142+
try
144143
{
145-
MainApp.Instance.MainWindow.NavigationPage.LoadBundleFromString(packagesContent, BundleFormatType.UBUNDLE, "GitHub Gist");
144+
var b = await _backupService.GetAvailableBackups();
145+
146+
var errorDialog = DialogHelper.DialogFactory.Create();
147+
errorDialog.Title = CoreTools.Translate("Select backup:");
148+
errorDialog.Content = CoreTools.Translate(" - " + (string.Join("\n - ", b)));
149+
errorDialog.PrimaryButtonText = CoreTools.Translate("OK");
150+
errorDialog.DefaultButton = ContentDialogButton.Primary;
151+
await DialogHelper.Window.ShowDialogAsync(errorDialog);
152+
RestorePackagesFromGitHubButton.IsEnabled = true;
153+
return;
154+
155+
156+
MainApp.Instance.MainWindow.NavigationPage.LoadBundleFromString("", BundleFormatType.UBUNDLE, "GitHub Gist");
157+
146158
Logger.Info("Successfully loaded package bundle from GitHub Gist.");
147159
DialogHelper.ShowDismissableBalloon(
148-
CoreTools.Translate("Backup retrieved successfully!"),
160+
CoreTools.Translate("Backup loaded successfully!"),
149161
CoreTools.Translate("The package bundle has been loaded into the Package Bundles page."));
150162
}
151-
else
163+
catch (Exception ex)
152164
{
153165
DialogHelper.HideLoadingDialog();
154166
Logger.Error("Failed to restore packages from GitHub Gist.");
@@ -157,45 +169,40 @@ private async void RestorePackagesFromGitHubButton_Click(object sender, EventArg
157169
errorDialog.Content = CoreTools.Translate("Could not restore packages from GitHub Gist. Please check the logs for more details, or ensure a backup exists.");
158170
errorDialog.PrimaryButtonText = CoreTools.Translate("OK");
159171
errorDialog.DefaultButton = ContentDialogButton.Primary;
160-
_ = DialogHelper.Window.ShowDialogAsync(errorDialog);
172+
await DialogHelper.Window.ShowDialogAsync(errorDialog);
161173
}
162174
UpdateBackupToGitHubButtonStatus();
163175
}
164176

165177
private async void BackupToGitHubButton_Click(object sender, EventArgs e)
166178
{
167179
BackupToGitHubButton.IsEnabled = false;
168-
DialogHelper.ShowLoadingDialog(CoreTools.Translate("Backing up settings and packages to GitHub Gist..."));
180+
DialogHelper.ShowLoadingDialog(CoreTools.Translate("Backing up packages to GitHub Gist..."));
169181

170-
// var settingsContent = await Task.Run(Settings.ExportToString_JSON);
171182
var packagesContent = await InstalledPackagesPage.GenerateBackupContents();
172183

173-
/*var filesToBackup = new Dictionary<string, string>
174-
{
175-
{ "unigetui.settings.json", settingsContent },
176-
{ "unigetui.packages.ubundle", packagesContent }
177-
};*/
178-
179-
bool success = await _backupService.UploadPackageBundle(packagesContent);
180-
181-
DialogHelper.HideLoadingDialog();
182-
183-
if (success)
184+
try
184185
{
186+
await _backupService.UploadPackageBundle(packagesContent);
187+
DialogHelper.HideLoadingDialog();
185188
Logger.Info("Successfully backed up settings and packages to GitHub Gist.");
186189
DialogHelper.ShowDismissableBalloon(
187190
CoreTools.Translate("Backup Successful"),
188191
CoreTools.Translate("Your settings and packages have been successfully backed up to GitHub Gist."));
189192
}
190-
else
193+
catch (Exception ex)
191194
{
192-
Logger.Error("Failed to backup settings or packages to GitHub Gist.");
195+
DialogHelper.HideLoadingDialog();
196+
197+
Logger.Error("An error occurred while uploading the backup:");
198+
Logger.Error(ex);
199+
193200
var dialog = DialogHelper.DialogFactory.Create();
194201
dialog.Title = CoreTools.Translate("Backup Failed");
195-
dialog.Content = CoreTools.Translate("Could not back up settings and/or packages to GitHub Gist. Please check the logs for more details.");
202+
dialog.Content = CoreTools.Translate("Could not back up packages to GitHub Gist: ") + ex.Message;
196203
dialog.PrimaryButtonText = CoreTools.Translate("OK");
197204
dialog.DefaultButton = ContentDialogButton.Primary;
198-
_ = DialogHelper.Window.ShowDialogAsync(dialog);
205+
await DialogHelper.Window.ShowDialogAsync(dialog);
199206
}
200207
UpdateBackupToGitHubButtonStatus();
201208
}

src/UniGetUI/Services/GitHubBackupService.cs

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,33 @@
66
using UniGetUI.Core.Data;
77
using UniGetUI.Core.Logging;
88
using UniGetUI.Core.SettingsEngine;
9+
using UniGetUI.Core.Tools;
910

1011
namespace UniGetUI.Services
1112
{
1213
public class GitHubBackupService
1314
{
14-
private const string GistDescriptionEndingKey = "#[UNIGETUI_BUNDLE_BACKUP_V1]";
15-
private readonly GitHubAuthService _authService;
16-
private const string GistDescription = $"UniGetUI package backups - DO NOT RENAME OR MODIFY {GistDescriptionEndingKey}";
15+
private const string GistDescription_EndingKey = "#[UNIGETUI_BACKUP_V1]";
16+
private const string PackageBackup_StartingKey = "#[PACKAGES]";
1717

18+
private const string GistDescription = $"UniGetUI package backups - DO NOT RENAME OR MODIFY {GistDescription_EndingKey}";
1819
private const string ReadMeContents = "" +
1920
"This special Gist is used by UniGetUI to store your package backups. \n" +
2021
"Please DO NOT EDIT the contents or the description of this gist, or unexpected behaviours may occur.\n" +
2122
"Learn more about UniGetUI at https://github.com/marticliment/UniGetUI\n";
2223

2324

25+
26+
private readonly GitHubAuthService _authService;
27+
2428
private readonly string DeviceUserUniqueIdentifier;
2529
private readonly string GistFileKey;
2630

2731
public GitHubBackupService(GitHubAuthService authService)
2832
{
2933
_authService = authService;
3034
DeviceUserUniqueIdentifier = $"{Environment.MachineName}\\{Environment.UserName}".Replace(" ", "");
31-
GistFileKey = $"PACKAGES {DeviceUserUniqueIdentifier}";
35+
GistFileKey = $"{PackageBackup_StartingKey} {DeviceUserUniqueIdentifier}";
3236
}
3337

3438
private async Task<GitHubClient?> CreateClientAsync()
@@ -52,42 +56,30 @@ public GitHubBackupService(GitHubAuthService authService)
5256
/// </summary>
5357
/// <param name="bundleContents"></param>
5458
/// <returns>A boolean representing the success of the operation</returns>
55-
public async Task<bool> UploadPackageBundle(string bundleContents)
59+
public async Task UploadPackageBundle(string bundleContents)
5660
{
5761
var GHClient = await CreateClientAsync();
58-
if (GHClient == null)
59-
{
60-
Logger.Error("Upload of backup has been aborted since the user is not authenticated");
61-
return false;
62-
}
63-
User user = await GHClient.User.Current();
62+
if (GHClient is null)
63+
throw new Exception("The GitHub user is not authenticated");
6464

65-
try
66-
{
67-
var candidates = await GHClient.Gist.GetAllForUser(user.Login);
68-
Gist? existingBackup = candidates.FirstOrDefault(g => g.Description.EndsWith(GistDescriptionEndingKey));
65+
User user = await GHClient.User.Current();
6966

70-
if (existingBackup is null)
71-
{
72-
Logger.Warn($"No matching gist was found as a valid backup, a new gist will be created...");
73-
existingBackup = await _createBackupGistAsync(GHClient);
74-
}
67+
var candidates = await GHClient.Gist.GetAllForUser(user.Login);
68+
Gist? existingBackup = candidates.FirstOrDefault(g => g.Description.EndsWith(GistDescription_EndingKey));
7569

76-
await _updateBackupGistAsync(GHClient, existingBackup, bundleContents);
77-
Logger.Info($"Cloud backup completed successfully to gist {user.Login}/{existingBackup.Id}");
78-
return true;
79-
}
80-
catch (Exception ex)
70+
if (existingBackup is null)
8171
{
82-
Logger.Error("An error occurred while attempting to upload backup to GitHub:");
83-
Logger.Error(ex);
84-
return false;
72+
Logger.Warn($"No matching gist was found as a valid backup, a new gist will be created...");
73+
existingBackup = await _createBackupGistAsync(GHClient);
8574
}
75+
76+
await _updateBackupGistAsync(GHClient, existingBackup, bundleContents);
77+
Logger.Info($"Cloud backup completed successfully to gist {user.Login}/{existingBackup.Id}");
8678
}
8779

8880
/// <summary>
8981
/// Upload the given payload to the given gist.
90-
/// Updates the existing file if GistFileKey exists, creates a new one otherwhise
82+
/// Updates the existing file if GistFileKey exists, creates a new one otherwhise.
9183
/// </summary>
9284
/// <param name="client"></param>
9385
/// <param name="gist"></param>
@@ -108,7 +100,7 @@ private async Task _updateBackupGistAsync(GitHubClient client, Gist gist, string
108100
}
109101

110102
/// <summary>
111-
/// Creates a new Gist, prepared to be detectable by UniGetUI
103+
/// Creates a new Gist, prepared to be detectable by UniGetUI, and with the base readme file
112104
/// </summary>
113105
/// <param name="client"></param>
114106
/// <returns></returns>
@@ -123,7 +115,30 @@ private static Task<Gist> _createBackupGistAsync(GitHubClient client)
123115
return client.Gist.Create(newGist);
124116
}
125117

126-
public async Task<string?> RetrieveFileAsync(string fileName)
118+
/// <summary>
119+
/// Retrieves a list of available backups to import
120+
/// </summary>
121+
/// <param name="client"></param>
122+
/// <returns></returns>
123+
public async Task<IEnumerable<string>> GetAvailableBackups()
124+
{
125+
var GHClient = await CreateClientAsync();
126+
if (GHClient is null)
127+
throw new Exception("The GitHub user is not authenticated");
128+
129+
130+
User user = await GHClient.User.Current();
131+
132+
var candidates = await GHClient.Gist.GetAllForUser(user.Login);
133+
Gist? existingBackup = candidates.FirstOrDefault(g => g.Description.EndsWith(GistDescription_EndingKey));
134+
135+
return existingBackup?.Files
136+
.Where(f => f.Key.StartsWith(PackageBackup_StartingKey))
137+
.Select(f => $"{f.Key.Split(' ')[^1]} ({CoreTools.FormatAsSize(f.Value.Size)})") ?? [];
138+
}
139+
140+
141+
/*public async Task<string?> RetrieveFileAsync(string fileName)
127142
{
128143
var client = await CreateClientAsync();
129144
if (client == null) return null;
@@ -203,6 +218,6 @@ private static Task<Gist> _createBackupGistAsync(GitHubClient client)
203218
Logger.Error(ex);
204219
return null;
205220
}
206-
}
221+
}*/
207222
}
208223
}

0 commit comments

Comments
 (0)