Skip to content

Add support for Synology Drive Client #9188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion src/Files.Shared/CloudProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public enum CloudProviders
Nextcloud,
Yandex,
Box,
Jottacloud
Jottacloud,
SynologyDrive
}
}
1 change: 1 addition & 0 deletions src/Files.Uwp/Files.Uwp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
<Compile Include="Extensions\EnumExtensions.cs" />
<Compile Include="Extensions\ImageSourceExtensions.cs" />
<Compile Include="Extensions\KeyboardAcceleratorExtensions.cs" />
<Compile Include="Filesystem\Cloud\Providers\SynologyDriveCloudProvider.cs" />
<Compile Include="Filesystem\FilesystemOperations\ShellFilesystemOperations.cs" />
<Compile Include="Filesystem\FileTagsHelper.cs" />
<Compile Include="Filesystem\FileTagsManager.cs" />
Expand Down
3 changes: 2 additions & 1 deletion src/Files.Uwp/Filesystem/Cloud/CloudProviderController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public class CloudProviderController
new DropBoxCloudProvider(),
new BoxCloudProvider(),
new AppleCloudProvider(),
new GenericCloudProvider()
new GenericCloudProvider(),
new SynologyDriveCloudProvider()
};

public async Task<List<CloudProvider>> DetectInstalledCloudProvidersAsync()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Files.Shared;
using Microsoft.Data.Sqlite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Windows.Storage;

namespace Files.Uwp.Filesystem.Cloud.Providers
{
public class SynologyDriveCloudProvider : ICloudProviderDetector
{
public async Task<IList<CloudProvider>> DetectAsync()
{
/* Synology Drive stores its information on some files, but we only need sys.sqlite, which is placed on %LocalAppData%\SynologyDrive\data\db
* In this database we need "connection_table" and "session_table" tables:
* connection_table has the ids of each connection in the field "id", and the type of connection in the field "conn_type" (1 for sync tasks and 2 for backups)
* Also it has "host_name" field where it's placed the name of each server.
* session_table has the next fields:
* "conn_id", which has the id that we check on connection_table to see if it's a sync or backup task
* "remote_path", which has the server folder. Currently it's not needed, just adding in case in the future is needed.
* "sync_folder", which has the local folder to sync.
*/
try
{
string appDataPath = UserDataPaths.GetDefault().LocalAppData;
string dbPath = @"SynologyDrive\data\db\sys.sqlite";
var configFile = await StorageFile.GetFileFromPathAsync(Path.Combine(appDataPath, dbPath));
await configFile.CopyAsync(ApplicationData.Current.TemporaryFolder, "synology_drive.db", NameCollisionOption.ReplaceExisting);
var syncDbPath = Path.Combine(ApplicationData.Current.TemporaryFolder.Path, "synology_drive.db");

// Build the connection and sql command
SQLitePCL.Batteries_V2.Init();
using (var con = new SqliteConnection($"Data Source='{syncDbPath}'"))
using (var cmd = new SqliteCommand("select * from connection_table", con))
using (var cmd2 = new SqliteCommand("select * from session_table", con))
{
// Open the connection and execute the command
con.Open();
var reader = cmd.ExecuteReader();
var connections = new Dictionary<string, (string ConnectionType, string HostName)>();

while (reader.Read())
{
var connection = (
ConnectionType: reader["conn_type"]?.ToString(),
HostName: reader["host_name"]?.ToString());

connections.Add(reader["id"]?.ToString(), connection);
}

var reader2 = cmd2.ExecuteReader();
var results = new List<CloudProvider>();

while (reader2.Read())
{
// Extract the data from the reader
if (connections[reader2["conn_id"]?.ToString()].ConnectionType == "1")
{
string path = reader2["sync_folder"]?.ToString();
if (string.IsNullOrWhiteSpace(path))
{
continue;
}

var folder = await StorageFolder.GetFolderFromPathAsync(path);
var synologyDriveCloud = new CloudProvider()
{
ID = CloudProviders.SynologyDrive,
SyncFolder = path,
Name = $"Synology Drive - {connections[reader2["conn_id"]?.ToString()].HostName} ({folder.Name})"
};

results.Add(synologyDriveCloud);
}
}

return results;
}
}
catch
{
// Not detected
return Array.Empty<CloudProvider>();
}
}
}
}