Skip to content
This repository has been archived by the owner on Jan 22, 2018. It is now read-only.

Commit

Permalink
Refactored synchronization code.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tran Ngoc Van committed Nov 12, 2011
1 parent 2808300 commit ee58d7c
Show file tree
Hide file tree
Showing 17 changed files with 614 additions and 457 deletions.
9 changes: 4 additions & 5 deletions KeePass/Analytics/TrackInfo.cs
@@ -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";
}
}
}
11 changes: 9 additions & 2 deletions KeePass/KeePass.csproj
Expand Up @@ -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>
Expand All @@ -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>
Expand Down
3 changes: 1 addition & 2 deletions KeePass/MainPage.xaml.cs
Expand Up @@ -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);
}

Expand Down
56 changes: 10 additions & 46 deletions KeePass/Sources/DatabaseUpdater.cs
@@ -1,5 +1,4 @@
using System;
using System.IO;
using KeePass.Sources.DropBox;
using KeePass.Sources.Web;
using KeePass.Sources.WebDav;
Expand All @@ -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:
Expand All @@ -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);
}
}
}
124 changes: 124 additions & 0 deletions KeePass/Sources/DropBox/DropBoxAdapter.cs
@@ -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);
}
}
}
17 changes: 14 additions & 3 deletions KeePass/Sources/DropBox/DropBoxInfo.cs
@@ -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";

Expand All @@ -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);
}
}
}

0 comments on commit ee58d7c

Please sign in to comment.