OneDrive Backup
OneDrive Backup
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
using hassio_onedrive_backup.Contracts;
|
||||
using hassio_onedrive_backup.Hass.Events;
|
||||
using hassio_onedrive_backup.Storage;
|
||||
using Newtonsoft.Json;
|
||||
using onedrive_backup.Contracts;
|
||||
using System.Globalization;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using static hassio_onedrive_backup.Contracts.HassAddonsResponse;
|
||||
using static hassio_onedrive_backup.Contracts.HassBackupsResponse;
|
||||
|
||||
namespace hassio_onedrive_backup.Hass
|
||||
{
|
||||
internal class HassioClient : IHassioClient
|
||||
{
|
||||
private const string Supervisor_Base_Uri_Str = "http://supervisor";
|
||||
private const string Hass_Base_Uri_Str = "http://supervisor/core/api";
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public HassioClient(string token, int hassioTimeout)
|
||||
{
|
||||
_httpClient = new HttpClient();
|
||||
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
_httpClient.Timeout = TimeSpan.FromMinutes(hassioTimeout);
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteBackupAsync(Backup backup)
|
||||
{
|
||||
try
|
||||
{
|
||||
Uri uri = new Uri(Supervisor_Base_Uri_Str + $"/backups/{backup.Slug}");
|
||||
await _httpClient.DeleteAsync(uri);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ConsoleLogger.LogError($"Error deleting backup {backup.Slug}. {ex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<List<Backup>> GetBackupsAsync(Predicate<Backup> filter)
|
||||
{
|
||||
Uri uri = new Uri(Supervisor_Base_Uri_Str + "/backups");
|
||||
var response = await GetJsonResponseAsync<HassBackupsResponse>(uri);
|
||||
if (response.Result.Equals("ok", StringComparison.OrdinalIgnoreCase) == false)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed getting Backups from Supervisor. Result: {response.Result}");
|
||||
}
|
||||
|
||||
var backups = response.DataProperty.Backups;
|
||||
|
||||
return filter != null ? backups.Where(backup => filter(backup)).ToList() : backups.ToList();
|
||||
}
|
||||
|
||||
public async Task<bool> CreateBackupAsync(string backupName, bool appendTimestamp = true, bool compressed = true, string? password = null, IEnumerable<string>? folders = null, IEnumerable<string>? addons = null)
|
||||
{
|
||||
DateTime timeStamp = DateTimeHelper.Instance!.Now;
|
||||
const string dt_format = "yyyy-MM-dd-HH-mm";
|
||||
|
||||
string? payloadStr;
|
||||
Uri? uri;
|
||||
|
||||
string finalBackupName = appendTimestamp ? $"{backupName}_{timeStamp.ToString(dt_format, CultureInfo.CurrentCulture)}" : backupName;
|
||||
|
||||
// Full Backup
|
||||
if (folders == null && addons == null)
|
||||
{
|
||||
uri = new Uri(Supervisor_Base_Uri_Str + "/backups/new/full");
|
||||
var fullPayload = new
|
||||
{
|
||||
name = finalBackupName,
|
||||
compressed = compressed,
|
||||
password = password
|
||||
};
|
||||
|
||||
payloadStr = JsonConvert.SerializeObject(fullPayload, new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
});
|
||||
|
||||
ConsoleLogger.LogInfo("Starting full local backup");
|
||||
}
|
||||
// Partial Backup
|
||||
else
|
||||
{
|
||||
uri = new Uri(Supervisor_Base_Uri_Str + "/backups/new/partial");
|
||||
var partialPayload = new
|
||||
{
|
||||
name = finalBackupName,
|
||||
compressed = compressed,
|
||||
password = password,
|
||||
homeassistant = true,
|
||||
addons = addons,
|
||||
folders = folders
|
||||
};
|
||||
|
||||
payloadStr = JsonConvert.SerializeObject(partialPayload, new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
});
|
||||
|
||||
ConsoleLogger.LogInfo("Starting partial local backup");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _httpClient.PostAsync(uri, new StringContent(payloadStr, Encoding.UTF8, "application/json"));
|
||||
ConsoleLogger.LogInfo("Backup complete");
|
||||
}
|
||||
catch (TaskCanceledException tce)
|
||||
{
|
||||
if (tce.InnerException is TimeoutException)
|
||||
{
|
||||
ConsoleLogger.LogError($"Backup request timed out. {tce}");
|
||||
ConsoleLogger.LogError($"Increase the timeout value in configuration");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ConsoleLogger.LogError($"Failed creating new backup. {ex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UploadBackupAsync(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
Uri uri = new Uri(Supervisor_Base_Uri_Str + "/backups/new/upload");
|
||||
using var multiPartFormContent = new MultipartFormDataContent();
|
||||
var fsContent = new StreamContent(System.IO.File.OpenRead(filePath));
|
||||
multiPartFormContent.Add(fsContent, name: "file", fileName: filePath);
|
||||
var response = await _httpClient.PostAsync(uri, multiPartFormContent);
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ConsoleLogger.LogError($"Error uploading backup to Home Assistant. {ex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task SendPersistentNotificationAsync(string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
Uri uri = new Uri(Hass_Base_Uri_Str + "/services/notify/persistent_notification");
|
||||
var payload = new
|
||||
{
|
||||
message = message,
|
||||
title = "hassio-onedrive-backup"
|
||||
};
|
||||
|
||||
string payloadStr = JsonConvert.SerializeObject(payload);
|
||||
await _httpClient.PostAsync(uri, new StringContent(payloadStr, Encoding.UTF8, "application/json"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ConsoleLogger.LogError($"Failed sending persistent notification. {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<Addon>> GetAddonsAsync()
|
||||
{
|
||||
Uri uri = new Uri(Supervisor_Base_Uri_Str + "/addons");
|
||||
var response = await GetJsonResponseAsync<HassAddonsResponse>(uri);
|
||||
var ret = response.DataProperty.Addons.ToList();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public async Task UpdateHassEntityStateAsync(string entityId, string payload)
|
||||
{
|
||||
Uri uri = new Uri(Hass_Base_Uri_Str + $"/states/{entityId}");
|
||||
await _httpClient.PostAsync(uri, new StringContent(payload, Encoding.UTF8, "application/json"));
|
||||
}
|
||||
|
||||
public async Task PublishEventAsync(OneDriveEvents eventType, string payload = "")
|
||||
{
|
||||
Uri uri = new Uri(Hass_Base_Uri_Str + $"/events/onedrive.{eventType}");
|
||||
await _httpClient.PostAsync(uri, new StringContent(payload, Encoding.UTF8, "application/json"));
|
||||
}
|
||||
|
||||
public async Task<string> DownloadBackupAsync(string backupSlug)
|
||||
{
|
||||
ConsoleLogger.LogInfo($"Fetching Local Backup (Slug:{backupSlug})");
|
||||
Uri uri = new Uri(Supervisor_Base_Uri_Str + $"/backups/{backupSlug}/download");
|
||||
var fileInfo = new FileInfo($"{LocalStorage.TempFolder}/{backupSlug}.tar");
|
||||
await using var memStream = await _httpClient.GetStreamAsync(uri);
|
||||
using var fileStream = System.IO.File.Create(fileInfo.FullName);
|
||||
await memStream.CopyToAsync(fileStream);
|
||||
ConsoleLogger.LogInfo($"Backup ({backupSlug}) fetched successfully");
|
||||
return fileInfo.FullName;
|
||||
}
|
||||
|
||||
public async Task<string> GetTimeZoneAsync()
|
||||
{
|
||||
Uri uri = new Uri(Supervisor_Base_Uri_Str + "/supervisor/info");
|
||||
var response = await GetJsonResponseAsync<HassSupervisorInfoResponse>(uri);
|
||||
var ret = response.DataProperty.Timezone;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private async Task<T> GetJsonResponseAsync<T>(Uri uri)
|
||||
{
|
||||
string response = await _httpClient.GetStringAsync(uri);
|
||||
T ret = JsonConvert.DeserializeObject<T>(response)!;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public async Task<HassAddonInfoResponse> GetAddonInfo(string slug)
|
||||
{
|
||||
Uri uri = new Uri(Supervisor_Base_Uri_Str + $"/addons/{slug}/info");
|
||||
var response = await GetJsonResponseAsync<HassAddonInfoResponse>(uri);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user