using System.Net; using System.Net.Http.Json; using System.Text.Json.Serialization; using TessesDedupWeb; using Tesses.VirtualFilesystem; public class DedupClient { public DedupClient(HttpClient client) { this.client = client; } public string DataPath=>$"{(client.BaseAddress?.ToString() ?? "").TrimEnd('/')}/data/"; HttpClient client; public async Task IsRegisteredAsync() { return await client.GetStringAsync("/api/v1/Registered") == "true"; } public async Task GetStatsAsync(string key) { //"blocks":0,"bytes":0,"backups":0,"label":"0 bytes" var res= await client.GetFromJsonAsync($"/api/v1/Stats?access_key={WebUtility.UrlEncode(key)}"); if(res != null) return res; return new Stats(); } public async Task LogoutAsync(string key) { Dictionary dictionary= new Dictionary { { "access_key", key } }; FormUrlEncodedContent formUrlEncodedContent=new FormUrlEncodedContent(dictionary); using(var resp=await client.PostAsync("/api/v1/Logout",formUrlEncodedContent)) { } } public async Task AccessKeyDeleteAsync(string key, long id) { var res= await client.DeleteFromJsonAsync($"/api/v1/AccessKey?id={id}&access_key={WebUtility.UrlEncode(key)}"); return res ?? new AccessKeyDeleteReason(); } public async IAsyncEnumerable GetAccessKeysAsync(string key) { var res= await client.GetFromJsonAsync>($"/api/v1/AccessKey?access_key={WebUtility.UrlEncode(key)}"); if(res != null) { foreach(var item in res) { yield return item; } } } public async Task GetBackupAsync(string key,long id) { var res= await client.GetFromJsonAsync($"/api/v1/Backup?id={id}&access_key={WebUtility.UrlEncode(key)}&noHashes=true"); return res ?? new Backup(); } public async IAsyncEnumerable GetBackupsAsync(string key) { var res= await client.GetFromJsonAsync>($"/api/v1/Backup?access_key={WebUtility.UrlEncode(key)}"); if(res != null) { foreach(var item in res) { yield return item; } } } public async Task LoginAsync(string username,string password, string device_name) { Dictionary dictionary= new Dictionary { { "username", username }, { "password", password }, { "device_name", device_name } }; FormUrlEncodedContent formUrlEncodedContent=new FormUrlEncodedContent(dictionary); using(var resp=await client.PostAsync("/api/v1/Login",formUrlEncodedContent)) { if(resp.IsSuccessStatusCode) { return await resp.Content.ReadFromJsonAsync() ?? new LoginResult(); } else { return new LoginResult(); } } } } public class AccessKeyDeleteReason { [JsonPropertyName("success")] public bool Success {get;set;}=false; [JsonPropertyName("reason")] public string Reason {get;set;}="The response was null"; } public class AccessKey { [JsonPropertyName("creation_date")] public DateTime Created {get;set;} [JsonPropertyName("id")] public long Id {get;set;} [JsonPropertyName("device_name")] public string DeviceName {get;set;}=""; } public class Stats { [JsonPropertyName("blocks")] public long Blocks {get;set;}=0; [JsonPropertyName("bytes")] public long Bytes {get;set;}=0; [JsonPropertyName("backups")] public long Backups {get;set;}=0; [JsonPropertyName("label")] public string Label {get;set;}=""; } public class LoginResult { [JsonPropertyName("success")] public bool Success {get;set;}=false; [JsonPropertyName("key")] public string Key {get;set;}=""; } public class Backup { [JsonPropertyName("id")] public long Id {get;set;} [JsonPropertyName("account_id")] public long AccountId {get;set;} [JsonPropertyName("root")] public FilesystemEntry? Root {get;set;} [JsonPropertyName("device_name")] public string DeviceName {get;set;}=""; [JsonPropertyName("tag")] public string Tag {get;set;}=""; [JsonPropertyName("creation_date")] public DateTime CreationDate {get;set;} public Backup WithoutRoot() { Backup b=new Backup(); b.AccountId = AccountId; b.Id = Id; b.CreationDate = CreationDate; b.DeviceName = DeviceName; b.Tag = Tag; b.Root=null; return b; } public FilesystemEntry GetEntryFromPath(UnixPath path) { if(path.Path == "/" || path.Path.Length == 0) return Root ?? new FilesystemEntry(); var gefp=GetEntryFromPath(path.Parent); if(gefp.Type != "dir") throw new DirectoryNotFoundException(path.Parent.Path); foreach(var item in gefp.Entries) { if(item.Name == path.Name) { switch(item.Type) { case "dir": case "file": return item; case "symlink": { if(item.PointsTo.StartsWith("/")) { UnixPath _path = path.Parent; foreach(var _item in item.PointsTo.Split('/')) { if(_item == "..") { _path = _path.Parent; } else if(_item != ".") { _path /= _item; } } return GetEntryFromPath(_path); } else { UnixPath _path = Special.Root; foreach(var _item in item.PointsTo.Split('/')) { if(_item == "..") { _path = _path.Parent; } else if(_item != ".") { _path /= _item; } } return GetEntryFromPath(_path); } } } } } throw new FileNotFoundException(path.Path); } } public class FilesystemEntry { [JsonPropertyName("name")] public string Name {get;set;}=""; [JsonPropertyName("type")] public string Type {get;set;}=""; [JsonPropertyName("entries")] public List Entries {get;set;}=new List(); [JsonPropertyName("hashes")] public List Hashes {get;set;}=new List(); [JsonPropertyName("length")] public long Length {get;set;} [JsonPropertyName("points_to")] public string PointsTo {get;set;}=""; }