This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Refactored synchronization code.

  • Loading branch information...
7Pass committed Nov 12, 2011
1 parent 2808300 commit ee58d7cd1b1309687ce7a2042b56badbbb909b44
@@ -1,11 +1,10 @@
-using System;
+using System;
namespace KeePass.Analytics
{
internal static class TrackInfo
{
-#warning Your MixPanel token is needed
- public const string TOKEN =
- "YOUR_TOKEN";
+ // Your MixPanel token is needed
+ public const string TOKEN = "YOUR_TOKEN";
}
-}
+}
View
@@ -243,8 +243,16 @@
<DependentUpon>Settings.xaml</DependentUpon>
</Compile>
<Compile Include="Sources\DatabaseUpdater.cs" />
+ <Compile Include="Sources\DropBox\DropBoxAdapter.cs" />
+ <Compile Include="Sources\IServiceAdapter.cs" />
+ <Compile Include="Sources\ListItem.cs" />
+ <Compile Include="Sources\ServiceAdapterBase.cs" />
<Compile Include="Sources\SourceCapabilityUpdater.cs" />
- <Compile Include="Sources\WebDav\WebDavUpdater.cs" />
+ <Compile Include="Sources\SynchronizeErrorEventArgs.cs" />
+ <Compile Include="Sources\SynchronizeErrorEventHandler.cs" />
+ <Compile Include="Sources\SynchronizeException.cs" />
+ <Compile Include="Sources\Synchronizer.cs" />
+ <Compile Include="Sources\WebDav\WebDavAdapter.cs" />
<Compile Include="Sources\WebDav\WebDavResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
@@ -258,7 +266,6 @@
<Compile Include="Sources\DropBox\DropBox.xaml.cs">
<DependentUpon>DropBox.xaml</DependentUpon>
</Compile>
- <Compile Include="Sources\DropBox\DropBoxUpdater.cs" />
<Compile Include="Sources\DropBox\List.xaml.cs">
<DependentUpon>List.xaml</DependentUpon>
</Compile>
View
@@ -213,8 +213,7 @@ private void Update(DatabaseItem item)
item.IsUpdating = true;
var database = (DatabaseInfo)item.Info;
- DatabaseUpdater.Update(database,
- _ => item.IsUpdating,
+ database.Update(_ => item.IsUpdating,
DatabaseUpdated);
}
@@ -1,5 +1,4 @@
using System;
-using System.IO;
using KeePass.Sources.DropBox;
using KeePass.Sources.Web;
using KeePass.Sources.WebDav;
@@ -10,23 +9,27 @@ namespace KeePass.Sources
internal static class DatabaseUpdater
{
public const string DROPBOX_UPDATER = "DropBox";
- public const string WEB_UPDATER = "Web";
public const string WEBDAV_UPDATER = "WebDAV";
+ public const string WEB_UPDATER = "Web";
- public static void Update(DatabaseInfo info,
+ public static void Update(this DatabaseInfo info,
Func<DatabaseInfo, bool> queryUpdate,
ReportUpdateResult report)
{
switch (info.Details.Source)
{
case DROPBOX_UPDATER:
- DropBoxUpdater.Update(info, queryUpdate,
- x => Report(info, x, report));
+ var dropbox = new Synchronizer(info,
+ new DropBoxAdapter(), queryUpdate);
+
+ dropbox.Synchronize(report);
break;
case WEBDAV_UPDATER:
- WebDavUpdater.Update(info, queryUpdate,
- x => Report(info, x, report));
+ var webdav = new Synchronizer(info,
+ new WebDavAdapter(), queryUpdate);
+
+ webdav.Synchronize(report);
break;
case WEB_UPDATER:
@@ -35,44 +38,5 @@ internal static class DatabaseUpdater
break;
}
}
-
- private static void Report(DatabaseInfo info,
- SyncCompleteInfo result, ReportUpdateResult report)
- {
- string msg = null;
- var details = info.Details;
-
- switch (result.Result)
- {
- case SyncResults.Downloaded:
- using (var buffer = new MemoryStream(result.Database))
- info.SetDatabase(buffer, details);
- break;
-
- case SyncResults.Uploaded:
- details.HasLocalChanges = false;
- details.Modified = result.Modified;
- info.SaveDetails();
- break;
-
- case SyncResults.Conflict:
- details.Url = result.Path;
- details.HasLocalChanges = false;
- details.Modified = result.Modified;
- info.SaveDetails();
-
- msg = string.Format(
- Properties.Resources.Conflict,
- new Uri(result.Path).LocalPath);
- break;
-
- case SyncResults.Failed:
- msg = Properties.Resources
- .DownloadError;
- break;
- }
-
- report(info, result.Result, msg);
- }
}
}
@@ -0,0 +1,124 @@
+using System;
+using System.IO;
+using DropNet;
+using DropNet.Models;
+using KeePass.IO.Utils;
+using KeePass.Storage;
+
+namespace KeePass.Sources.DropBox
+{
+ internal class DropBoxAdapter : ServiceAdapterBase
+ {
+ private DropNetClient _client;
+ private SyncInfo _info;
+
+ public override void Conflict(ListItem item,
+ Action<ListItem, string> uploaded)
+ {
+ var path = GetNonConflictPath();
+
+ UploadFileAsync(path, x => uploaded(
+ Translate(x), _client.GetUrl(path)));
+ }
+
+ public override void Download(ListItem item,
+ Action<ListItem, byte[]> downloaded)
+ {
+ _client.GetFileAsync(_info.Path,
+ x => downloaded(item, x.RawBytes),
+ OnError);
+ }
+
+ public override SyncInfo Initialize(DatabaseInfo info)
+ {
+ if (info == null)
+ throw new ArgumentNullException("info");
+
+ var details = info.Details;
+ var url = new Uri(details.Url);
+ _client = CreateClient(url.UserInfo);
+
+ _info = new SyncInfo
+ {
+ Path = url.LocalPath,
+ Modified = details.Modified,
+ HasLocalChanges = details.HasLocalChanges,
+ };
+
+ info.OpenDatabaseFile(x =>
+ {
+ using (var buffer = new MemoryStream())
+ {
+ BufferEx.CopyStream(x, buffer);
+ _info.Database = buffer.ToArray();
+ }
+ });
+
+ return _info;
+ }
+
+ public override void List(Action<ListItem> ready)
+ {
+ _client.GetMetaDataAsync(_info.Path,
+ meta => ready(Translate(meta)),
+ OnError);
+ }
+
+ public override void Upload(ListItem item,
+ Action<ListItem> uploaded)
+ {
+ UploadFileAsync(_info.Path,
+ meta => uploaded(Translate(meta)));
+ }
+
+ private static DropNetClient CreateClient(string userInfo)
+ {
+ var parts = userInfo.Split(':');
+
+ return new DropNetClient(
+ DropBoxInfo.KEY, DropBoxInfo.SECRET,
+ parts[0], parts[1]);
+ }
+
+ private string GetNonConflictPath()
+ {
+ var path = _info.Path;
+ var dir = Path.GetDirectoryName(path);
+ var extension = Path.GetExtension(path);
+ var fileName = Path.GetFileNameWithoutExtension(path);
+
+ fileName = string.Concat(fileName,
+ " (7Pass' conflicted copy ",
+ DateTime.Today.ToString("yyyy-MM-dd"),
+ ")", extension);
+
+ return Path.Combine(dir, fileName)
+ .Replace('\\', '/');
+ }
+
+ private static ListItem Translate(MetaData meta)
+ {
+ return new ListItem
+ {
+ Tag = meta,
+ Timestamp = meta.Modified,
+ };
+ }
+
+ private void UploadFileAsync(string path,
+ Action<MetaData> completed)
+ {
+ var orgPath = path;
+
+ var fileName = Path.GetFileName(path);
+ path = Path.GetDirectoryName(path)
+ .Replace('\\', '/');
+
+ _client.UploadFileAsync(path,
+ fileName, _info.Database,
+ x => _client.GetMetaDataAsync(
+ orgPath, completed, OnError),
+ OnError);
+ }
+ }
+}
@@ -1,11 +1,11 @@
-using System;
+using System;
using DropNet;
namespace KeePass.Sources.DropBox
{
- internal class DropBoxInfo
+ internal static class DropBoxInfo
{
-#warning Your DropBox info is needed
+ // Your DropBox info is needed
public const string KEY = "YOUR_KEY";
public const string SECRET = "YOUR_SECRET";
@@ -20,5 +20,16 @@ public static DropNetClient Create()
return new DropNetClient(
KEY, SECRET, token, secret);
}
+
+ public static string GetUrl(
+ this DropNetClient client,
+ string path)
+ {
+ var login = client.UserLogin;
+
+ return string.Format(
+ "dropbox://{0}:{1}@dropbox.com{2}",
+ login.Token, login.Secret, path);
+ }
}
}
Oops, something went wrong.

0 comments on commit ee58d7c

Please sign in to comment.