Skip to content

Commit

Permalink
2.3 (#172)
Browse files Browse the repository at this point in the history
2.3 Release
  • Loading branch information
lavinir authored Feb 7, 2024
1 parent 3c98720 commit 322d24e
Show file tree
Hide file tree
Showing 110 changed files with 2,738 additions and 2,206 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This addon enables easy Home Assistant backup creation and sync to OneDrive.
- Syncs backups to OneDrive **(Personal Account only. OneDrive for business not currently supported)**
- Additional File Sync to OneDrive
- Supports standard backup retention / Generational backup mode
- Retain backups indefinitely
- Supports multiple Home Assistant instances
- Supports Home Assistant Persistent Notifications
- Supports Home Assistant Events
Expand Down Expand Up @@ -135,6 +136,9 @@ This allows you to specify a list of paths for the addon to sync to OneDrive so
> * /share
> * /media
> * /addons
> * /addon_configs
> * /homeassistant

**Example**:

Expand Down Expand Up @@ -176,6 +180,10 @@ A random Guid is generated when you run your addon for the first time (not persi
* Ignore Allowed Hours for File Sync Enabled Flag
* Addon Version
* Notify On Error Enabled Flag
* Error Reporting Enabled Flag

### Enable Anonymous Error Reporting
Sends anonymous error messages (with exceptions) to help identify issues with the addon

### Dark Mode
Use Dark mode for Addon UI
Expand All @@ -185,6 +193,11 @@ The add-on has specific permissions to a single folder in your OneDrive known as

The App Folder for the add-on is mapped to : <kbd>**[onedriveroot]/Apps/hassio-onedrive-backup**</kbd>

## Retaining Backups Indefinitely (Prevent Deletion)
You can choose to 'pin' specific backups so that they stop counting against the set backup quotas and are never deleted by the addon. This can be set individually for both local and OneDrive through
dedicated buttons in the main Dashboard for each backup.
> Note - As any 'retained' backup will not count towards your maximum backup quota you could for example, have a maximum of 3 local backups set but chose to retain 2 Local backups. The addon will ignore the retained backups for the quota and will store a maximum of 3 addtional local backups
## OneDrive free space Sensor
The add-on creates a native Home Assistant Sensor entity <kbd>sensor.onedrivefreespace</kbd> that will show you the amount of free space in your OneDrive account.

Expand Down
2 changes: 2 additions & 0 deletions onedrive-backup/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,5 @@ record.auth*
.NativeSettings
.clientId
settings.json
additionalBackupData.json
.*
11 changes: 11 additions & 0 deletions onedrive-backup/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## v2.3 [Febuary 7th 2024]
### 🆕 Added
* Added ability to retain backups indefinitely
* New details in overview page - Total backup sizes, next backup date
* Updated folder support for File Sync - /homeassistant, /addon_configs
* New optional Error reporting (opt in)
* Upgraded core libraries (Azure.Identity, Microsoft.Graph, Bootstrap)
### 🐞 Fixed
* If not enough space is available in OneDrive, the addon will no longer attempt to upload the backup and fail repeatedly.
* Addons in partial backups were only refreshed on addon start (if another addon was installed after the addon has started it would not appear in a partial backup)

## v2.2.4 [November 10th 2023]
### 🐞 Fixed
* Allowed hours requires restart - Fixed a bug where changing the allowed hours wouldn't take effect until addon was restarted.
Expand Down
7 changes: 7 additions & 0 deletions onedrive-backup/ConsoleLogger.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using onedrive_backup;
using onedrive_backup.Telemetry;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -17,6 +18,12 @@ public void LogError(string msg)
WriteLog(LogLevel.Error, 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);
telemetryManager?.SendError(msg, ex);
}

public void LogWarning(string msg)
{
WriteLog(LogLevel.Warning, msg);
Expand Down
5 changes: 4 additions & 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.2.4";
public const string AddonVersion = "2.3";

public event Action OnOptionsChanged;

Expand Down Expand Up @@ -86,6 +86,9 @@ public class AddonOptions : IEqualityComparer<AddonOptions>
[JsonProperty("enable_anonymous_telemetry")]
public bool EnableAnonymousTelemetry { get; set; } = false;

[JsonProperty("enable_anonymous_error_reporting")]
public bool EnableAnonymousErrorReporting { get; set; } = false;

[JsonProperty("ignore_allowed_hours_for_file_sync")]
public bool IgnoreAllowedHoursForFileSync { get; set; } = false;

Expand Down
68 changes: 68 additions & 0 deletions onedrive-backup/Contracts/BackupAdditionalData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Microsoft.Graph.Models;

namespace onedrive_backup.Contracts
{
public class BackupAdditionalData
{
public BackupAdditionalData()
{
Backups = new();
}

public List<BackupData> Backups { get; set; }

public bool IsRetainedLocally(string slug)
{
var backup = Backups.FirstOrDefault(backupData => backupData.Slug == slug);
return (backup != null && backup.RetainLocal);
}

public bool IsRetainedOneDrive(string slug)
{
var backup = Backups.FirstOrDefault(backupData => backupData.Slug == slug);
return (backup != null && backup.RetainOneDrive);
}

public int PruneAdditionalBackupData(params string[] existingSlugs)
{
return Backups.RemoveAll(backup => !existingSlugs.Contains(backup.Slug));
}

public void UpdateRetainLocally(string slug, bool retain)
{
var backup = GetOrCreateBackupData(slug);
backup.RetainLocal = retain;
}

public void UpdateRetainOneDrive(string slug, bool retain)
{
var backup = GetOrCreateBackupData(slug);
backup.RetainOneDrive = retain;
}

private BackupData GetOrCreateBackupData(string slug)
{
var backup = Backups.FirstOrDefault(backupData => backupData.Slug == slug);
if (backup == null)
{
backup = new BackupData
{
Slug = slug
};

Backups.Add(backup);
}

return backup;
}

public class BackupData
{
public string Slug { get; set; }

public bool RetainLocal { get; set; }

public bool RetainOneDrive { get; set; }
}
}
}
53 changes: 20 additions & 33 deletions onedrive-backup/Extensions/BackupExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace onedrive_backup.Extensions
{
public static class BackupExtensions
{
public static BackupModel ToBackupModel(this Backup backup, HassContext hassContext)
public static BackupModel ToBackupModel(this Backup backup, HassContext hassContext, BackupAdditionalData backupAdditionalData)
{
return new BackupModel
{
Expand All @@ -24,11 +24,13 @@ public static BackupModel ToBackupModel(this Backup backup, HassContext hassCont
IsProtected = backup.Protected,
Location = BackupModel.BackupLocation.Local,
Addons = backup.Content?.Addons?.Select(slug => new Addon { Slug = slug, Name = GetAddonNameFromSlug(hassContext.Addons, slug) }).ToList() ?? Enumerable.Empty<Addon>(),
Folders = backup.Content?.Folders ?? Enumerable.Empty<string>()
Folders = backup.Content?.Folders ?? Enumerable.Empty<string>(),
RetainLocal = backupAdditionalData.IsRetainedLocally(backup.Slug),
RetainOneDrive = backupAdditionalData.IsRetainedOneDrive(backup.Slug)
};
}

public static BackupModel ToBackupModel(this OnedriveBackup onedriveBackup, HassContext hassContext)
public static BackupModel ToBackupModel(this OnedriveBackup onedriveBackup, HassContext hassContext, BackupAdditionalData backupAdditionalData)
{
return new BackupModel
{
Expand All @@ -40,8 +42,10 @@ public static BackupModel ToBackupModel(this OnedriveBackup onedriveBackup, Hass
IsProtected = onedriveBackup.IsProtected,
Location = BackupModel.BackupLocation.OneDrive,
Addons = onedriveBackup.Addons?.Select(slug => new Addon { Slug = slug, Name = GetAddonNameFromSlug(hassContext.Addons, slug) }) ?? Enumerable.Empty<Addon>(),
Folders = onedriveBackup.Folders ?? Enumerable.Empty<string>()
};
Folders = onedriveBackup.Folders ?? Enumerable.Empty<string>(),
RetainLocal = backupAdditionalData.IsRetainedLocally(onedriveBackup.Slug),
RetainOneDrive = backupAdditionalData.IsRetainedOneDrive(onedriveBackup.Slug)
};
}

public static OnedriveBackup ToOneDriveBackup(this BackupModel backupModel)
Expand Down Expand Up @@ -118,15 +122,6 @@ public static IList<IBackup> GetWeeklyGenerations(this IEnumerable<IBackup> back
{
ret.Add(weeklyBackup);
}
//else
//{
// var weekCutoffDate = DateTimeHelper.GetStartDateByWeekAndYear(year, week, firstDayOfWeek);
// var nextCandidateBackup = backups.OrderByDescending(b => b.BackupDate).FirstOrDefault(b => b.BackupDate <= weekCutoffDate);
// if (nextCandidateBackup != null)
// {
// ret.Add(nextCandidateBackup);
// }
//}
}

return ret.Distinct().ToList();
Expand Down Expand Up @@ -163,15 +158,6 @@ public static IList<IBackup> GetMonthlyGenerations(this IEnumerable<IBackup> bac
{
ret.Add(monthlyBackup);
}
// else
// {
// var cutoffDate = new DateTime(year, month, 1);
// var nextCandidateBackup = backups.OrderByDescending(b => b.BackupDate).FirstOrDefault(b => b.BackupDate >= cutoffDate);
// if (nextCandidateBackup != null)
// {
// ret.Add(nextCandidateBackup);
// }
//}
}

return ret.Distinct().ToList();
Expand Down Expand Up @@ -200,21 +186,22 @@ public static IList<IBackup> GetYearlyGenerations(this IEnumerable<IBackup> back
{
ret.Add(yearlyBackup);
}
//else
//{
// var cutoffDate = new DateTime(currentYear, 1, 1);
// var nextCandidateBackup = backups.OrderByDescending(b => b.BackupDate).FirstOrDefault(b => b.BackupDate >= cutoffDate);
// if (nextCandidateBackup != null)
// {
// ret.Add(nextCandidateBackup);
// }
//}
}

return ret.Distinct().ToList();
}

private static string GetAddonNameFromSlug(IEnumerable<Addon> addons, string slug)
public static bool IsRetainedLocally(this IBackup backup, BackupAdditionalData additionalData)
{
return additionalData.IsRetainedLocally(backup.Slug);
}

public static bool IsRetainedOneDrive(this IBackup backup, BackupAdditionalData additionalData)
{
return additionalData.IsRetainedOneDrive(backup.Slug);
}

private static string GetAddonNameFromSlug(IEnumerable<Addon> addons, string slug)
{
string name = addons.FirstOrDefault(addon => addon.Slug.Equals(slug, StringComparison.OrdinalIgnoreCase))?.Name;
return name ?? string.Empty;
Expand Down
Loading

0 comments on commit 322d24e

Please sign in to comment.