Skip to content

Commit

Permalink
2.3.8 (#278)
Browse files Browse the repository at this point in the history
  • Loading branch information
lavinir authored Dec 22, 2024
1 parent 102f626 commit 9a957f5
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 29 deletions.
12 changes: 12 additions & 0 deletions onedrive-backup/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## v2.3.8 [December 15th 2024] (Preview Channel)
### 🐞 Fixed
* Updated backup file naming in OneDrive to include the backup slug to avoid potential duplicates with upgrade backups
* Fixed issue when only the first 200 backups are fetched from OneDrive and the rest are ignored, also causing repeated uploads.

### 🆕 Added
* Additional debugging logs

## v2.3.7 [December 8th 2024] (Preview Channel)
### 🆕 Added
* Additional debugging logs

## v2.3.6 [November 24th 2024]
### 🐞 Fixed
* Backups File Upload Failures - Removed dependency on OneDrive File descriptions that seem to have been causing many Upload failures for some users. The metadata for the OneDrive Backups will now be stored locally instead
Expand Down
10 changes: 8 additions & 2 deletions onedrive-backup/ConsoleLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ public void LogError(string msg)
}

public void LogError(string msg, Exception ex = null, TelemetryManager telemetryManager = null)

Check warning on line 21 in onedrive-backup/ConsoleLogger.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 21 in onedrive-backup/ConsoleLogger.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.
{
WriteLog(LogLevel.Error, msg);
{
string formattedMsg = msg;
if (ex != null)
{
formattedMsg += ". " + ex.ToString();
}

WriteLog(LogLevel.Error, formattedMsg);
telemetryManager?.SendError(msg, ex);
}

Expand Down
2 changes: 1 addition & 1 deletion onedrive-backup/Contracts/AddonOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace hassio_onedrive_backup.Contracts
{
public class AddonOptions : IEqualityComparer<AddonOptions>

Check warning on line 10 in onedrive-backup/Contracts/AddonOptions.cs

View workflow job for this annotation

GitHub Actions / build

'AddonOptions' overrides Object.Equals(object o) but does not override Object.GetHashCode()
{
public const string AddonVersion = "2.3.6";
public const string AddonVersion = "2.3.8";

public event Action OnOptionsChanged;

Expand Down
57 changes: 51 additions & 6 deletions onedrive-backup/Graph/GraphHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ public async Task GetAndCacheUserTokenAsync()

if (subPath == "/")
{
item = await _userClient.Drives[driveId].Items[appFolder.Id].GetAsync(config => config.QueryParameters.Expand = new string[] { "children" });
item = await _userClient.Drives[driveId].Items[appFolder.Id].GetAsync();
}
else
{
item = await _userClient.Drives[driveId].Items[appFolder.Id].ItemWithPath(subPath).GetAsync(config => config.QueryParameters.Expand = new string[] { "children" });
item = await _userClient.Drives[driveId].Items[appFolder.Id].ItemWithPath(subPath).GetAsync();
}

return item;
Expand All @@ -147,14 +147,59 @@ public async Task GetAndCacheUserTokenAsync()
_logger.LogError($"{oe.Error.Code}: {oe.Error.Message}", oe, _telemetryManager);
return null;
}


}

public async Task<List<DriveItem>?> GetItemsInAppFolderAsync(string subPath = "/")

Check warning on line 152 in onedrive-backup/Graph/GraphHelper.cs

View workflow job for this annotation

GitHub Actions / build

Nullability of reference types in return type of 'Task<List<DriveItem>?> GraphHelper.GetItemsInAppFolderAsync(string subPath = "/")' doesn't match implicitly implemented member 'Task<List<DriveItem>> IGraphHelper.GetItemsInAppFolderAsync(string subPath = "/")'.
{
var parent = await GetItemInAppFolderAsync(subPath);
return parent?.Children?.ToList();
int pageSize = 100;
var items = new List<DriveItem>();

try
{
string driveId = await GetDriveIdFromAppFolder();
IsAuthenticated = true;
var appFolder = await _userClient.Drives[driveId].Special["approot"].GetAsync();
DriveItemCollectionResponse childrenPage;
_logger.LogVerbose($"Fetching OneDrive files in AppFolder{subPath}");
if (subPath == "/")
{
childrenPage = await _userClient.Drives[driveId].Items[appFolder.Id]
.Children
.GetAsync(config => config.QueryParameters.Top = pageSize);
}
else
{
childrenPage = await _userClient.Drives[driveId].Items[appFolder.Id]
.ItemWithPath(subPath)
.Children
.GetAsync(config => config.QueryParameters.Top = pageSize);
}

// Process the first page of items
items.AddRange(childrenPage.Value);
_logger.LogVerbose($"Fetched {items.Count} out of {childrenPage.OdataCount} items in folder");

// Handle pagination
while (childrenPage.OdataNextLink != null)
{
childrenPage = await _userClient.Drives[driveId].Items[appFolder.Id]
.Children
.WithUrl(childrenPage.OdataNextLink)
.GetAsync();
items.AddRange(childrenPage.Value);
_logger.LogVerbose($"Fetched {items.Count} out of {childrenPage.OdataCount} items in folder");
}
}
catch (ODataError oe) when (oe.Error?.Code == "itemNotFound")
{
_logger.LogInfo($"Item {subPath} not found");
}
catch (ODataError oe)
{
_logger.LogError($"{oe.Error.Code}: {oe.Error.Message}", oe, _telemetryManager);
}

return items;
}

public async Task<bool> DeleteItemFromAppFolderAsync(string itemPath)
Expand Down
9 changes: 7 additions & 2 deletions onedrive-backup/Hass/BackupManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,17 @@ public async Task PerformBackupsAsync()
var uploadCandidates = GetBackupsToUploadBasedOnRetentionPolicy(onlineBackupCandiates, onlineBackups);

// Get Online Backups Candidates that have not yet been uploaded
_logger.LogVerbose($"Online Backup Slugs: {string.Join(",", onlineBackups.Select(bckup => bckup.Slug))}");
var backupsToUpload = new List<Backup>();
foreach (var backupId in uploadCandidates)
{
if (onlineBackups.Any(ob => ob.Slug == backupId))
{
_logger.LogVerbose($"Skpping Upload Candidate: {backupId}. (Already exists)");
continue;
}

_logger.LogVerbose($"Adding Upload Candidate: {backupId}.");
backupsToUpload.Add(onlineBackupCandiates.Single(bc => bc.Slug == backupId));
}

Expand Down Expand Up @@ -388,7 +391,7 @@ public async Task<bool> UploadLocalBackupToOneDrive(Backup backup, Action<int?,

_logger.LogInfo($"Uploading {backup.Name} ({backup.Date})");
string? instanceSuffix = _addonOptions.InstanceName == null ? null : $".{_addonOptions.InstanceName.Substring(0, Math.Min(InstanceNameMaxLength, _addonOptions.InstanceName.Length))}";
string destinationFileName = $"{backup.Name}{instanceSuffix}.tar";
string destinationFileName = $"{backup.Name}_{backup.Slug}{instanceSuffix}.tar";
tempBackupFilePath = await _hassIoClient.DownloadBackupAsync(backup.Slug);
var uploadSuccessful = await _graphHelper.UploadFileAsync(tempBackupFilePath, backup.Date, _addonOptions.InstanceName, new TransferSpeedHelper(null), destinationFileName,
async (prog, speed) =>
Expand All @@ -404,6 +407,7 @@ public async Task<bool> UploadLocalBackupToOneDrive(Backup backup, Action<int?,
},
description: SerializeBackupDescription(tempBackupFilePath, backup)
);

if (uploadSuccessful == false)
{
await _hassIoClient.PublishEventAsync(Events.OneDriveEvents.BackupUploadFailed);
Expand Down Expand Up @@ -609,7 +613,8 @@ public async Task RefreshBackupsAndUpdateHassEntity()

try
{
ret = await LocalStorage.GetOneDriveBackup(item.Name);
_logger.LogVerbose($"Checking if file {item.Name} is known backup");
ret = await LocalStorage.GetOneDriveBackup(item.Name, _logger);
if (ret == null)
{
_logger.LogVerbose("Attempting to read legacy backup description");
Expand Down
18 changes: 7 additions & 11 deletions onedrive-backup/Pages/_Host.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,19 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="rnotesModalLabel">Version 2.3.6 Notes</h5>
<h5 class="modal-title" id="rnotesModalLabel">Version 2.3.8 Notes</h5>
</div>
<div class="modal-body">
<h5>❗Important Notes from 2.3.5</h5>
<p>The OneDrive Entra App was created as a Multi Tenant app (to enable future Business account
support). Earlier this month due to a new MS policy, these apps required Verified Publishers
(Microsoft Partners) otherwise it will not allow users to grant consent. I've updated the App to
only allow Personal Accounts. This also required code changes. Please make sure authentication
goes through properly after the update and if you have any issues with this please consolidate
them around the <a href="https://github.com/lavinir/hassio-onedrive-backup/issues/247"
target="_blank">opened Github issue</a></p>
<h6>🎉 New Preview Channel</h6>
<p><A> new Preview Channel is Available for the additional to try and test new versions and fixes. See details in the Readme's</A> <a href="https://github.com/lavinir/hassio-onedrive-backup?tab=readme-ov-file#installation-instructions"
<p><A>A new Preview Channel is available to try and test new versions and fixes. See details in the Readme's'</A> <a href="https://github.com/lavinir/hassio-onedrive-backup?tab=readme-ov-file#installation-instructions"
target="_blank">Installation Instructions</a></p>
<h6>🐞 Fixed</h6>
<li>Updated backup file naming in OneDrive to include the backup slug to avoid potential duplicates with upgrade backups</li>>
<li>Fixed issue when only the first 200 backups are fetched from OneDrive and the rest are ignored, also causing repeated uploads.</li>>
<h6>🆕 Added</h6>
<ul>
<li>Backups File Upload Failures - Removed dependency on OneDrive File descriptions that seem to have been causing many Upload failures for some users. The metadata for the OneDrive Backups will now be stored locally instead</li>
<li>Additional debugging logs</li>
<li>Updated backup file naming in OneDrive to include the backup slug to avoid potential duplicates with upgrade backups</li>
</ul>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion onedrive-backup/Shared/MainLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
{
if (firstRender)
{
if (LocalStorage.CheckAndMarkFlag(LocalStorage.Flag.ReleaseNotes_2_3_6) == false)
if (LocalStorage.CheckAndMarkFlag(LocalStorage.Flag.ReleaseNotes_2_3_8) == false)
{
await Task.Delay(1000);
await JS.InvokeVoidAsync("showReleaseNotes");
Expand Down
16 changes: 12 additions & 4 deletions onedrive-backup/Storage/LocalStorage.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using hassio_onedrive_backup.Contracts;
using Microsoft.Extensions.Logging;
using onedrive_backup.Contracts;
using System.Text.Json;

Expand Down Expand Up @@ -80,17 +81,24 @@ public async static Task StoreBackupData(BackupAdditionalData additionalData)
}
}

public async static Task<OnedriveBackup?> GetOneDriveBackup(string fileName)
public async static Task<OnedriveBackup?> GetOneDriveBackup(string fileName, ConsoleLogger logger)
{
string filePath = Path.Combine(configFolder, onlineBackupsDataFolder, ConvertBackFileNameToMetadataFileName(fileName));
try
{
logger.LogVerbose($"Checking metadata for backup file: {fileName}");
string filePath = Path.Combine(configFolder, onlineBackupsDataFolder, ConvertBackFileNameToMetadataFileName(fileName));
string serializedData = await File.ReadAllTextAsync(filePath);
OnedriveBackup onedriveBackup = JsonSerializer.Deserialize<OnedriveBackup>(serializedData);
return onedriveBackup;
}
catch (Exception)
catch (FileNotFoundException)
{
logger.LogVerbose($"Metadata file for {fileName} not found");
return null;
}
catch (Exception ex)
{
logger.LogError($"Error loading metadata for file: {fileName}", ex);
return null;
}
}
Expand Down Expand Up @@ -139,7 +147,7 @@ public static bool CheckAndMarkFlag(Flag flag)

public enum Flag
{
ReleaseNotes_2_3_6,
ReleaseNotes_2_3_8,
}

private static string ConvertBackFileNameToMetadataFileName(string fileName)
Expand Down
2 changes: 1 addition & 1 deletion onedrive-backup/config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: "OneDrive Backup"
version: "2.3.6"
version: "2.3.8"
slug: hassio_onedrive_backup
description: >-
Automatic backups from Home Assistant to OneDrive
Expand Down
2 changes: 1 addition & 1 deletion repository.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "Home Assistant Onedrive Backup Repository",
"name": "Home Assistant Onedrive Backup Repository (Preview)",
"url": "https://github.com/lavinir/hassio-onedrive-backup",
"maintainer": "Nir Lavi <snirlavi@gmail.com>"
}

0 comments on commit 9a957f5

Please sign in to comment.