Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Parallel.Cli/Commands/CleanCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2025 Kyle Ebbinga

using System.CommandLine;
using System.Runtime.InteropServices;
using Parallel.Cli.Utils;
using Parallel.Core.IO.Scanning;
using Parallel.Core.IO.Syncing;
Expand Down
12 changes: 6 additions & 6 deletions Parallel.Cli/Commands/DiskCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public DiskCommand() : base("disk", "Shows the current disk usage.")
private async Task DisplayDiskInformationAsync(LocalVaultConfig vault)
{
CommandLine.WriteLine($"Retrieving vault information...", ConsoleColor.DarkGray);
ISyncManager syncManager = SyncManager.CreateNew(vault);
if (!await syncManager.ConnectAsync())
ISyncManager? syncManager = SyncManager.CreateNew(vault);
if (syncManager == null || !await syncManager.ConnectAsync())
{
CommandLine.WriteLine(vault, $"Failed to connect to vault '{vault.Name}'!", ConsoleColor.Red);
return;
Expand All @@ -50,17 +50,17 @@ private async Task DisplayDiskInformationAsync(LocalVaultConfig vault)
long totalObjects = await db.GetTotalObjectsAsync();

CommandLine.WriteLine($"Using vault '{vault.Name}' ({vault.Id}):");
CommandLine.WriteLine($"Service Type: {vault.FileSystem.Service}");
CommandLine.WriteLine($"Root Directory: {vault.FileSystem.RootDirectory}");
CommandLine.WriteLine($"Service Type: {vault.Credentials.Service}");
CommandLine.WriteLine($"Root Directory: {vault.Credentials.RootDirectory}");
CommandLine.WriteLine($"Managed Files: {(totalLocalFiles + totalDeletedFiles):N0}");
CommandLine.WriteLine($"Local Files: {totalLocalFiles:N0}");
CommandLine.WriteLine($"Deleted Files: {totalDeletedFiles:N0}");
CommandLine.WriteLine($"Total Objects: {totalObjects:N0}");
CommandLine.WriteLine($"Local Size: {Formatter.FromBytes(localSize)}");

if (vault.FileSystem.Service.Equals(FileService.Local))
if (vault.Credentials.Service.Equals(FileService.Local))
{
DriveInfo drive = new(vault.FileSystem.RootDirectory);
DriveInfo drive = new(vault.Credentials.RootDirectory);
long diskUsage = drive.TotalSize - drive.TotalFreeSpace;
CommandLine.WriteLine($"Total Usage: {Formatter.FromBytes(diskUsage)} ({Math.Round(diskUsage / (double)drive.TotalSize * 100, 1)}%)");
CommandLine.WriteLine($"Disk Free: {Formatter.FromBytes(drive.TotalFreeSpace)} ({Math.Round(drive.TotalFreeSpace / (double)drive.TotalSize * 100, 1)}%)");
Expand Down
2 changes: 1 addition & 1 deletion Parallel.Cli/Commands/DuplicatesCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Parallel.Cli.Commands
{
public class DuplicatesCommand : Command
{
private Argument<string> sourceArg = new("path", "The directory to scan.");
private readonly Argument<string> sourceArg = new("path", "The directory to scan.");

public DuplicatesCommand() : base("duplicates", "Scans a directory for duplicate files.")
{
Expand Down
8 changes: 4 additions & 4 deletions Parallel.Cli/Commands/PullCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public PullCommand() : base("pull", "Pulls changes from a vault.")
private async Task PullPathAsync(LocalVaultConfig vault, string path, bool force)
{
CommandLine.WriteLine($"Retrieving vault information...", ConsoleColor.DarkGray);
ISyncManager syncManager = SyncManager.CreateNew(vault);
if (!await syncManager.ConnectAsync())
ISyncManager? syncManager = SyncManager.CreateNew(vault);
if (syncManager == null || !await syncManager.ConnectAsync())
{
CommandLine.WriteLine(vault, $"Failed to connect to vault '{vault.Name}'!", ConsoleColor.Red);
return;
Expand Down Expand Up @@ -71,7 +71,7 @@ private async Task PullPathAsync(LocalVaultConfig vault, string path, bool force

Log.Debug($"Pulling {pullFiles.Count} files...");
await syncManager.PullFilesAsync(pullFiles.ToArray(), new ProgressReport(vault, files.Count()));
CommandLine.WriteLine(vault, $"Successfully pulled {pullFiles.Count:N0} files from '{vault.FileSystem.RootDirectory}'.", ConsoleColor.Green);
CommandLine.WriteLine(vault, $"Successfully pulled {pullFiles.Count:N0} files from '{vault.Credentials.RootDirectory}'.", ConsoleColor.Green);
}

private async Task PullFileAsync(ISyncManager syncManager, string fullPath, bool force)
Expand All @@ -95,7 +95,7 @@ private async Task PullFileAsync(ISyncManager syncManager, string fullPath, bool
await syncManager.PullFilesAsync([remoteFile], new ProgressLogger());
await syncManager.DisconnectAsync();

CommandLine.WriteLine(syncManager.RemoteVault, $"Successfully pulled file from '{syncManager.RemoteVault.FileSystem.RootDirectory}'.", ConsoleColor.Green);
CommandLine.WriteLine(syncManager.RemoteVault, $"Successfully pulled file from '{syncManager.RemoteVault.Credentials.RootDirectory}'.", ConsoleColor.Green);
}
}
}
27 changes: 16 additions & 11 deletions Parallel.Cli/Commands/PushCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2025 Kyle Ebbinga

using System.CommandLine;
using System.Diagnostics;
using Parallel.Cli.Utils;
using Parallel.Core.Diagnostics;
using Parallel.Core.IO;
Expand All @@ -13,45 +14,48 @@ namespace Parallel.Cli.Commands
{
public class PushCommand : Command
{
private Stopwatch _sw = new Stopwatch();

private Command addCmd = new("add", "Adds a new directory to the sync list.");
private Command listCmd = new("list", "Shows all directories in the sync list.");
private Command removeCmd = new("remove", "Removes a directory from the sync list.");

private readonly Option<string> _sourceArg = new(["--path", "-p"], "The source path to sync.");
private readonly Option<string> _configOpt = new(["--config", "-c"], "The vault configuration to use.");
private readonly Option<bool> _verboseOpt = new(["--verbose", "-v"], "Shows verbose output.");
private readonly Option<bool> _forceOpt = new(["--force", "-f"], "Forces the pull overwriting any files.");

public PushCommand() : base("push", "Pushes changed files to vaults.")
{
this.AddOption(_sourceArg);
this.AddOption(_configOpt);
this.AddOption(_verboseOpt);
this.SetHandler(async (path, config, verbose) =>
this.AddOption(_forceOpt);
this.SetHandler(async (path, config, force) =>
{
_sw = Stopwatch.StartNew();
if (string.IsNullOrEmpty(path))
{
await SyncSystemAsync();
}
else
{
await SyncPathAsync(path);
await SyncPathAsync(path, force);
}

}, _sourceArg, _configOpt, _verboseOpt);
}, _sourceArg, _configOpt, _forceOpt);
}

private Task SyncSystemAsync()
{
throw new NotImplementedException();
}

private async Task SyncPathAsync(string path)
private async Task SyncPathAsync(string path, bool force)
{
CommandLine.WriteLine($"Retrieving vault information...", ConsoleColor.DarkGray);
await Program.Settings.ForEachVaultAsync(async vault =>
{
ISyncManager syncManager = SyncManager.CreateNew(vault);
if (!await syncManager.ConnectAsync())
ISyncManager? syncManager = SyncManager.CreateNew(vault);
if (syncManager == null || !await syncManager.ConnectAsync())
{
CommandLine.WriteLine(vault, $"Failed to connect to vault '{vault.Name}'!", ConsoleColor.Red);
return;
Expand Down Expand Up @@ -79,7 +83,7 @@ await Program.Settings.ForEachVaultAsync(async vault =>

CommandLine.WriteLine(vault, $"Scanning for file changes in {path}...", ConsoleColor.DarkGray);
FileScanner scanner = new FileScanner(syncManager);
SystemFile[] files = await scanner.GetFileChangesAsync(path, ignoredFolders);
SystemFile[] files = await scanner.GetFileChangesAsync(path, ignoredFolders, force);
int successFiles = files.Length;
if (successFiles == 0)
{
Expand All @@ -89,10 +93,11 @@ await Program.Settings.ForEachVaultAsync(async vault =>
}

CommandLine.WriteLine(vault, $"Backing up {files.Length.ToString("N0")} files...", ConsoleColor.DarkGray);
await syncManager.PushFilesAsync(files, new ProgressReport(vault, successFiles));
await syncManager.PushFilesAsync(files, force, new ProgressReport(vault, successFiles));
//await syncManager.PushFilesAsync(files, new ProgressBarReporter());
await syncManager.DisconnectAsync();

CommandLine.WriteLine(vault, $"Successfully pushed {successFiles.ToString("N0")} files to '{vault.FileSystem.RootDirectory}'.", ConsoleColor.Green);
CommandLine.WriteLine(vault, $"Successfully pushed {successFiles.ToString("N0")} files in {_sw.Elapsed}.", ConsoleColor.Green);
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions Parallel.Cli/Commands/RemapCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public RemapCommand() : base("remap", "Remaps paths in the vault.")

private async Task RemapPathAsync(LocalVaultConfig vault, string source, string target)
{
ISyncManager syncManager = SyncManager.CreateNew(vault);
if (!await syncManager.ConnectAsync())
ISyncManager? syncManager = SyncManager.CreateNew(vault);
if (syncManager == null || !await syncManager.ConnectAsync())
{
CommandLine.WriteLine(vault, $"Failed to connect to vault '{vault.Name}'!", ConsoleColor.Red);
return;
Expand Down
66 changes: 36 additions & 30 deletions Parallel.Cli/Commands/VaultsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ public class VaultsCommand : Command
private readonly Argument<string> configArg = new("config", "The vault configuration to use.");
private readonly Option<string> configOpt = new(["--config", "-c"], "The vault configuration to use.");

private Command addCmd = new("add", "Adds a new vault configuration.");
private Command editCmd = new("edit", "Edits a vault configuration.");
private readonly Command addCmd = new("add", "Adds a new vault configuration.");
private readonly Command editCmd = new("edit", "Edits a vault configuration.");
private readonly Command findCmd = new("find", "Finds vault configurations in a location.");
private Command viewCmd = new("view", "Shows the vault configuration.");
private Command setCmd = new("set", "Sets a new vault configuration.");
private Command delCmd = new("delete", "Deletes a vault configuration.");
private readonly Command viewCmd = new("view", "Shows the vault configuration.");
private readonly Command setCmd = new("set", "Sets a new vault configuration.");
private readonly Command delCmd = new("delete", "Deletes a vault configuration.");

public VaultsCommand() : base("vaults", "View or edit the vaults.")
{
Expand All @@ -39,31 +39,37 @@ public VaultsCommand() : base("vaults", "View or edit the vaults.")
addCmd.SetHandler(() =>
{
CommandLine.WriteLine("Creating new storage vault...", ConsoleColor.DarkGray);
FileSystemCredentials fsc = new FileSystemCredentials();
fsc.Service = Enum.Parse<FileService>(CommandLine.ReadString($"Service ({string.Join(", ", Enum.GetNames(typeof(FileService)))})"), true);
if (fsc.Service == FileService.Local)
StorageCredentials spc = new StorageCredentials
{
fsc.RootDirectory = CommandLine.ReadString("Root");
Service = Enum.Parse<FileService>(CommandLine.ReadString($"Service ({string.Join(", ", Enum.GetNames(typeof(FileService)))})") ?? string.Empty, true)
};

if (spc.Service == FileService.Local)
{
CommandLine.WriteLine("It is NOT RECOMMENDED to use a network drive!", ConsoleColor.Yellow);
spc.RootDirectory = CommandLine.ReadString("Root") ?? string.Empty;
}
else if (fsc.Service == FileService.Cloud)
else if (spc.Service == FileService.Cloud)
{
fsc.Address = CommandLine.ReadString("Bucket Name");
fsc.Username = CommandLine.ReadString("Access Key");
fsc.Password = CommandLine.ReadPassword("Secret Key");
spc.Address = CommandLine.ReadString("Bucket Name");
spc.Username = CommandLine.ReadString("Access Key");
spc.Password = CommandLine.ReadPassword("Secret Key");
}
else
{
fsc.RootDirectory = CommandLine.ReadString("Root");
fsc.Address = CommandLine.ReadString("Address");
fsc.Username = CommandLine.ReadString("Username");
fsc.Password = CommandLine.ReadPassword("Password");
spc.RootDirectory = CommandLine.ReadString("Root") ?? string.Empty;
spc.Address = CommandLine.ReadString("Address");
spc.Username = CommandLine.ReadString("Username");
spc.Password = CommandLine.ReadPassword("Password");
}

//fsc.Encrypt = CommandLine.ReadBool("Encrypt files? (y/n)", false);
//fsc.EncryptionKey = HashGenerator.GenerateHash(32, true);
string profileId = CommandLine.ReadString("Id") ?? HashGenerator.GenerateHash(8, true);
string profileName = CommandLine.ReadString("Name") ?? "Default";

spc.Encrypt = CommandLine.ReadBool("Encrypt files? (y/n)", false);
spc.EncryptionKey = spc.Encrypt ? HashGenerator.GenerateHash(32, true) : null;

string? profileName = CommandLine.ReadString("Profile Name");
LocalVaultConfig localVault = new LocalVaultConfig(profileName, fsc);
LocalVaultConfig localVault = new(profileId, profileName, spc);
Program.Settings.Vaults.Add(localVault);
Program.Settings.Save();

Expand All @@ -78,28 +84,28 @@ public VaultsCommand() : base("vaults", "View or edit the vaults.")

this.AddCommand(viewCmd);
viewCmd.AddArgument(configArg);
viewCmd.SetHandler(async (vault) =>
viewCmd.SetHandler(async (config) =>
{
CommandLine.WriteLine($"Retrieving vault information...", ConsoleColor.DarkGray);
LocalVaultConfig? config = ParallelConfig.GetVault(vault);
if (config == null)
LocalVaultConfig? vault = ParallelConfig.GetVault(config);
if (vault == null)
{
CommandLine.WriteLine($"Unable to find vault with name: '{vault}'", ConsoleColor.Yellow);
return;
}

ISyncManager syncManager = SyncManager.CreateNew(config);
if (!await syncManager.ConnectAsync())
ISyncManager? syncManager = SyncManager.CreateNew(vault);
if (syncManager == null || !await syncManager.ConnectAsync())
{
CommandLine.WriteLine(config, $"Failed to connect to vault '{config.Name}'!", ConsoleColor.Red);
CommandLine.WriteLine(vault, $"Failed to connect to vault '{vault.Name}'!", ConsoleColor.Red);
return;
}

RemoteVaultConfig remoteVault = syncManager.RemoteVault;
CommandLine.WriteLine($"'{remoteVault.Name}' ({remoteVault.Id}):");
CommandLine.WriteArray($"Backup Directories", remoteVault.BackupDirectories);
CommandLine.WriteArray($"Ignore Directories", remoteVault.IgnoreDirectories);
CommandLine.WriteArray($"Prune Directories", remoteVault.PruneDirectories);
CommandLine.WriteArray("Backup Directories", remoteVault.BackupDirectories);
CommandLine.WriteArray("Ignore Directories", remoteVault.IgnoreDirectories);
CommandLine.WriteArray("Prune Directories", remoteVault.PruneDirectories);
CommandLine.WriteLine($"Prune Period: {remoteVault.PrunePeriod} days");

await syncManager.DisconnectAsync();
Expand Down
20 changes: 8 additions & 12 deletions Parallel.Cli/Parallel.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>Parallel</AssemblyName>
<AssemblyVersion>1.0.0</AssemblyVersion>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
<Company>Kyle Ebbinga</Company>
<Copyright>Copyright $(Company). All Rights Reserved.</Copyright>
<FileVersion>$(AssemblyVersion)</FileVersion>
Expand All @@ -35,23 +35,19 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0"/>
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0"/>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1"/>
</ItemGroup>

<ItemGroup>
<Using Include="Newtonsoft.Json" />
<Using Include="Serilog" />
<Using Include="Newtonsoft.Json"/>
<Using Include="Serilog"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Parallel.Core\Parallel.Core.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Utils\" />
<ProjectReference Include="..\Parallel.Core\Parallel.Core.csproj"/>
</ItemGroup>

</Project>
6 changes: 3 additions & 3 deletions Parallel.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ public static async Task Main(string[] args)
Settings = ParallelConfig.Load();
string logFile = Path.Combine(PathBuilder.ProgramData, "Logs", "latest.txt");
if (File.Exists(logFile)) File.Delete(logFile);
#if DEBUG
#if DEBUG
Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().CreateLogger();
#else
#else
Log.Logger = new LoggerConfiguration().MinimumLevel.Warning().WriteTo.File(logFile).CreateLogger();
#endif
#endif

AssemblyName assembly = Assembly.GetExecutingAssembly().GetName();
Log.Information($"{assembly.Name} [Version {assembly.Version}]");
Expand Down
Loading
Loading