<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>CODE_ANALYSIS;DEBUG;TRACE</DefineConstants>
+ <DocumentationFile>bin\Debug\Net\Newtonsoft.Json.xml</DocumentationFile>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <CodeAnalysisLogFile>bin\Debug\Net\Newtonsoft.Json.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+ <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly />
+ <CodeContractsCustomRewriterClass />
+ <CodeContractsLibPaths />
+ <CodeContractsExtraRewriteOptions />
+ <CodeContractsExtraAnalysisOptions />
+ <CodeContractsBaseLineFile />
+ <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+ <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<PropertyGroup>
<AssemblyOriginatorKeyFile>pithos.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\ParallelExtensionsExtras.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+ <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly />
+ <CodeContractsCustomRewriterClass />
+ <CodeContractsLibPaths />
+ <CodeContractsExtraRewriteOptions />
+ <CodeContractsExtraAnalysisOptions />
+ <CodeContractsBaseLineFile />
+ <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+ <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<PropertyGroup>
<AssemblyOriginatorKeyFile>pithos.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Hardcodet.Wpf.TaskbarNotification.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.Client.Test.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+ <CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll</HintPath>
using System.Windows;
using System.Windows.Navigation;
+using Caliburn.Micro;
using Caliburn.Micro.Logging;
+using Pithos.Client.WPF.Caliburn.Micro.Logging;
using Pithos.Core;
using Pithos.Network;
+using log4net.Appender;
+using log4net.Config;
+using log4net.Filter;
+using log4net.Layout;
namespace Pithos.Client.WPF
{
public AppBootstrapper()
{
- LogManager.GetLog = type => new DebugLogger(type);
+ ConfigureLogging();
+
+ LogManager.GetLog = type => new log4netLogger(type);
}
+ private static void ConfigureLogging()
+ {
+ var patternLayout = new PatternLayout();
+ patternLayout.ConversionPattern = "%logger (%property{myContext}) [%level]- %message%newline";
+ patternLayout.ActivateOptions();
+ var appender = new TraceAppender { Layout = patternLayout };
+ appender.AddFilter(new LevelRangeFilter{LevelMin=log4net.Core.Level.Info,LevelMax=log4net.Core.Level.Fatal});
+ appender.ActivateOptions();
+
+ BasicConfigurator.Configure(appender);
+ }
+
/// <summary>
/// By default, we are configured to use MEF
/// </summary>
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Caliburn.Micro;
+
+namespace Pithos.Client.WPF.Caliburn.Micro.Logging
+{
+ class log4netLogger : ILog
+ {
+ private log4net.ILog _log = null;
+
+ public log4netLogger(Type type)
+ {
+ _log = log4net.LogManager.GetLogger(type);
+ }
+ public void Info(string format, params object[] args)
+ {
+ _log.InfoFormat(format,args);
+ }
+
+ public void Warn(string format, params object[] args)
+ {
+ _log.WarnFormat(format, args);
+ }
+
+ public void Error(Exception exception)
+ {
+ _log.Error("",exception);
+ }
+ }
+}
<PropertyGroup>
<ApplicationIcon>Images\Tray.ico</ApplicationIcon>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.Client.WPF.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.Client.WPF.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="Caliburn.Micro, Version=1.2.0.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
<HintPath>..\Libraries\Caliburn.Micro.dll</HintPath>
</Reference>
+ <Reference Include="log4net">
+ <HintPath>..\Libraries\log4net.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Configuration.Install" />
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Caliburn\Micro\Logging\DebugLogger.cs" />
+ <Compile Include="Caliburn\Micro\Logging\log4netLogger.cs" />
<Compile Include="Configuration\PithosSettings.cs" />
<Compile Include="FileEntry.cs" />
<Compile Include="FilePropertiesView.xaml.cs">
}
};
- agent.CloudClient.Authenticate("890329@vho.grnet.gr", "24989dce4e0fcb072f8cb60c8922be19");
+ var account = "890329@vho.grnet.gr";
+ agent.CloudClient.Authenticate(account, "24989dce4e0fcb072f8cb60c8922be19");
var fileName = "012345.dump";
var filePath = Path.Combine(@"e:\pithos\", fileName);
}
- agent.CloudClient.DeleteObject(agent.PithosContainer, fileName);
+ agent.CloudClient.DeleteObject(null, agent.PithosContainer, fileName,agent.TrashContainer);
var task = Signature.CalculateTreeHashAsync(filePath, agent.BlockSize, agent.BlockHash);
- agent.UploadWithHashMap(new FileInfo(filePath),fileName,task);
+ agent.UploadWithHashMap(account,"pithos",new FileInfo(filePath),fileName,task);
- var newHash = agent.CloudClient.GetHashMap(agent.PithosContainer, fileName).Result;
+ var newHash = agent.CloudClient.GetHashMap(null, agent.PithosContainer, fileName).Result;
var treeHash = task.Result;
FileAgent=fileAgent
};
- agent.CloudClient.Authenticate("890329@vho.grnet.gr", "24989dce4e0fcb072f8cb60c8922be19");
+ var account = "890329@vho.grnet.gr";
+ agent.CloudClient.Authenticate(account, "24989dce4e0fcb072f8cb60c8922be19");
var fileName = @"AccessDatabaseEngine_x64.exe";
if (File.Exists(filePath))
File.Delete(filePath);
- var newHash = agent.CloudClient.GetHashMap(agent.PithosContainer, fileName).Result;
- agent.DownloadWithBlocks(agent.PithosContainer,new Uri(fileName,UriKind.Relative),filePath,newHash)
+ var newHash = agent.CloudClient.GetHashMap(null, agent.PithosContainer, fileName).Result;
+ agent.DownloadWithBlocks(account,agent.PithosContainer,new Uri(fileName,UriKind.Relative),filePath,newHash)
.Wait();
Assert.IsTrue(File.Exists(filePath));
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.Core.Test.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="Castle.ActiveRecord, Version=3.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL" />
<Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading;
public void DoAsync(Action action)
{
+ Contract.Requires(action!=null);
Task.Factory.StartNew(action, CancellationToken);
}
public Task LoopAsync(Task process, Action loop,Action<Exception> onError=null)
{
+ Contract.Requires(process!=null);
+ Contract.Requires(loop!=null);
+
return process.ContinueWith(t =>
{
public string TempPath { get; private set; }
+ readonly ConcurrentDictionary<int, string> _blocks = new ConcurrentDictionary<int, string>();
+ readonly ConcurrentDictionary<string, string> _orphanBlocks = new ConcurrentDictionary<string, string>();
+
+ [ContractInvariantMethod]
+ private void Invariants()
+ {
+ Contract.Invariant(Path.IsPathRooted(FragmentsPath));
+ Contract.Invariant(Path.IsPathRooted(FilePath));
+ Contract.Invariant(Path.IsPathRooted(TempPath));
+ Contract.Invariant(!Path.IsPathRooted(RelativePath));
+ Contract.Invariant(_blocks!=null);
+ Contract.Invariant(_orphanBlocks!=null);
+ Contract.Invariant(ServerHash!=null);
+ }
public BlockUpdater(string fragmentsPath, string filePath, string relativePath,TreeHash serverHash)
{
ServerHash = serverHash;
//The file will be stored in a temporary location while downloading with an extension .download
TempPath = Path.Combine(FragmentsPath, RelativePath + ".download");
-
- var directoryPath = Path.GetDirectoryName(TempPath);
+
+ //Need to calculate the directory path because RelativePath may include folders
+ var directoryPath = Path.GetDirectoryName(TempPath);
+ //directoryPath CAN be null if TempPath is a root path
+ if (String.IsNullOrWhiteSpace(directoryPath))
+ throw new ArgumentException("TempPath");
+ //FragmentsPath was absolute so directoryPath is absolute too
+ Contract.Assume(Path.IsPathRooted(directoryPath));
+
if (!Directory.Exists(directoryPath))
Directory.CreateDirectory(directoryPath);
throw new ArgumentNullException("directoryPath");
if (!Path.IsPathRooted(directoryPath))
throw new ArgumentException("The directoryPath must be rooted", "directoryPath");
+ if (ServerHash==null)
+ throw new InvalidOperationException("ServerHash wasn't initialized");
Contract.EndContractBlock();
var fileNamename = Path.GetFileName(FilePath);
//The server truncates nulls before calculating hashes, have to do the same
//Find the last non-null byte, starting from the end
var lastByteIndex = Array.FindLastIndex(buffer, buffer.Length-1, aByte => aByte != 0);
- var binHash = hasher.ComputeHash(buffer,0,lastByteIndex);
- var hash = binHash.ToHashString();
- _orphanBlocks[hash] = orphan;
+ //lastByteIndex may be -1 if the file was empty. We don't want to use that block file
+ if (lastByteIndex >= 0)
+ {
+ var binHash = hasher.ComputeHash(buffer, 0, lastByteIndex);
+ var hash = binHash.ToHashString();
+ _orphanBlocks[hash] = orphan;
+ }
}
}
}
File.Copy(FilePath, TempPath, true);
//Set the size of the file to the size specified in the treehash
- //This will also create an empty file if the file doesn't exist
+ //This will also create an empty file if the file doesn't exist
+
+
SetFileSize(TempPath, ServerHash.Bytes);
//Update the temporary file with the data from the blocks
return (tempLastWrite < localLastWrite);
}*/
- ConcurrentDictionary<int,string> _blocks=new ConcurrentDictionary<int, string>();
- ConcurrentDictionary<string, string> _orphanBlocks = new ConcurrentDictionary<string, string>();
public bool UseOrphan(int blockIndex, string blockHash)
{
public FileInfo LocalFile { get; set; }
public ObjectInfo CloudFile { get; set; }
public FileState FileState { get; set; }
+ public string Container { get; set; }
- public Lazy<string> LocalHash { get; private set; }
- public Lazy<string> TopHash { get; set; }
- public string OldFileName { get; set; }
- public string OldPath { get; set; }
- public string NewFileName { get; set; }
- public string NewPath { get; set; }
+ public Lazy<string> LocalHash { get; protected set; }
+ private Lazy<string> _topHash;
+ public Lazy<string> TopHash
+ {
+ get { return _topHash; }
+ set { _topHash = value; }
+ }
- public CloudAction(CloudActionType action, string oldPath, string oldFileName, string newFileName, string newPath)
+ protected CloudAction(CloudActionType action)
{
Action = action;
- OldFileName = oldFileName;
- OldPath = oldPath;
- NewFileName = newFileName;
- NewPath = newPath;
- //This is a rename operation, a hash will not be used
- LocalHash = new Lazy<string>(() => String.Empty, LazyThreadSafetyMode.ExecutionAndPublication);
}
- public CloudAction(CloudActionType action, FileInfo localFile, ObjectInfo cloudFile,FileState state,int blockSize, string algorithm)
+ public CloudAction(CloudActionType action, FileInfo localFile, ObjectInfo cloudFile,FileState state,int blockSize, string algorithm) : this(action)
{
- Action = action;
LocalFile = localFile;
CloudFile = cloudFile;
FileState = state;
}
}
+
//Constructor for downloading files
public CloudAction(CloudActionType action, ObjectInfo cloudFile)
{
CloudFile = cloudFile;
}
+ }
+
+ public class CloudMoveAction:CloudAction
+ {
+ public string OldFileName { get; set; }
+ public string OldPath { get; set; }
+ public string NewFileName { get; set; }
+ public string NewPath { get; set; }
+
+ public CloudMoveAction(CloudActionType action, string oldPath, string oldFileName, string newFileName, string newPath)
+ :base(action)
+ {
+ OldFileName = oldFileName;
+ OldPath = oldPath;
+ NewFileName = newFileName;
+ NewPath = newPath;
+ //This is a rename operation, a hash will not be used
+ LocalHash = new Lazy<string>(() => String.Empty, LazyThreadSafetyMode.ExecutionAndPublication);
+ }
+
+
}
+
}
\ No newline at end of file
public string RootPath { get; private set; }
+
public void Start(string rootPath)
{
+ if (String.IsNullOrWhiteSpace(rootPath))
+ throw new ArgumentNullException("rootPath");
+ if (!Path.IsPathRooted(rootPath))
+ throw new ArgumentException("rootPath must be an absolute path","rootPath");
+ Contract.EndContractBlock();
+
RootPath = rootPath;
_watcher = new FileSystemWatcher(rootPath);
+ _watcher.IncludeSubdirectories = true;
_watcher.Changed += OnFileEvent;
_watcher.Created += OnFileEvent;
_watcher.Deleted += OnFileEvent;
private Task<object> Process(WorkflowState state)
{
+ if (state==null)
+ throw new ArgumentNullException("state");
+ Contract.EndContractBlock();
+
Debug.Assert(!Ignore(state.Path));
var networkState = NetworkGate.GetNetworkState(state.Path);
public void Post(WorkflowState workflowState)
{
+ if (workflowState == null)
+ throw new ArgumentNullException("workflowState");
+ Contract.EndContractBlock();
+
_agent.Post(workflowState);
}
}
_watcher = null;
- _agent.Stop();
+ if (_agent!=null)
+ _agent.Stop();
}
// Enumerate all files in the Pithos directory except those in the Fragment folder
private WorkflowState UpdateFileStatus(WorkflowState state)
{
- Debug.Assert(!state.Path.Contains("fragments"));
- Debug.Assert(!state.Path.EndsWith(".ignore", StringComparison.InvariantCultureIgnoreCase));
+ if (state==null)
+ throw new ArgumentNullException("state");
+ if (String.IsNullOrWhiteSpace(state.Path))
+ throw new ArgumentException("The state's Path can't be empty","state");
+ Contract.EndContractBlock();
- string path = state.Path;
- FileStatus status = _statusDict[state.TriggeringChange];
+ var path = state.Path;
+ var status = _statusDict[state.TriggeringChange];
var oldStatus = Workflow.StatusKeeper.GetFileStatus(path);
if (status == oldStatus)
{
private WorkflowState UpdateOverlayStatus(WorkflowState state)
{
+ if (state==null)
+ throw new ArgumentNullException("state");
+ Contract.EndContractBlock();
+
if (state.Skip)
return state;
this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified);
break;
case FileStatus.Deleted:
- //this.StatusKeeper.RemoveFileOverlayStatus(state.Path);
+ //this.StatusAgent.RemoveFileOverlayStatus(state.Path);
break;
case FileStatus.Renamed:
- this.StatusKeeper.RemoveFileOverlayStatus(state.OldPath);
+ this.StatusKeeper.ClearFileStatus(state.OldPath);
this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified);
break;
case FileStatus.Unchanged:
Contract.EndContractBlock();
var absolutePath = Path.Combine(RootPath, relativePath);
- Debug.Assert(File.Exists(absolutePath),String.Format("Path {0} doesn't exist",absolutePath));
+// Debug.Assert(File.Exists(absolutePath),String.Format("Path {0} doesn't exist",absolutePath));
return new FileInfo(absolutePath);
using System;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.IO;
{
public static string AsRelativeTo(this FileInfo fileInfo,string path )
{
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ Contract.EndContractBlock();
+
+
if (!path.EndsWith("\\"))
path=path.ToLower() + "\\";
int pathLength = path.Length;
public static string AsRelativeUrlTo(this FileInfo fileInfo,string path )
{
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ Contract.EndContractBlock();
var relativePath = fileInfo.AsRelativeTo(path);
var replacedSlashes = relativePath.Replace("\\","/");
public static string RelativeUriToFilePath(this Uri uri)
{
- return RelativeUrlToFilePath(uri.ToString());
- }
-
- public static string RelativeUrlToFilePath(this string url)
- {
- var unescaped=Uri.UnescapeDataString(url);
+ var unescaped = Uri.UnescapeDataString(uri.ToString());
var path = unescaped.Replace("/", "\\");
return path;
}
+
public static int Read(this FileInfo fileInfo,byte[] buffer,int offset,int count)
{
//Open the stream only long enough to read a block
public static string CalculateHash(this FileInfo info,int blockSize,string algorithm)
{
+ if (info==null)
+ throw new ArgumentNullException("info");
+ if (String.IsNullOrWhiteSpace(info.FullName))
+ throw new ArgumentException("info");
+ if (blockSize<=0)
+ throw new ArgumentOutOfRangeException("blockSize",blockSize,"blockSize must be greater than 0");
+ if (String.IsNullOrWhiteSpace(algorithm))
+ throw new ArgumentNullException("algorithm");
+ Contract.EndContractBlock();
+
if (info.Length <= blockSize)
return Signature.CalculateMD5(info.FullName);
else
using System.Threading.Tasks;
using Pithos.Interfaces;
using Pithos.Network;
+using log4net;
namespace Pithos.Core.Agents
{
public string PithosContainer { get; set; }
public string TrashContainer { get; private set; }
+ public IList<string> Containers { get; private set; }
public int BlockSize { get; set; }
public string BlockHash { get; set; }
+ private static readonly ILog Log = LogManager.GetLogger(typeof(NetworkAgent));
+
public void Start(string pithosContainer, string trashContainer, int blockSize, string blockHash)
{
throw new ArgumentNullException("action");
Contract.EndContractBlock();
- Trace.TraceInformation("[ACTION] Start Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
+ using (log4net.LogicalThreadContext.Stacks["NETWORK"].Push("PROCESS"))
+ {
+ Log.InfoFormat("[ACTION] Start Processing {0}:{1}->{2}", action.Action, action.LocalFile,
+ action.CloudFile.Name);
+
+ var localFile = action.LocalFile;
+ var cloudFile = action.CloudFile;
+ var downloadPath = (cloudFile == null)
+ ? String.Empty
+ : Path.Combine(FileAgent.RootPath, cloudFile.RelativeUrlToFilePath(CloudClient.UserName));
+
+ try
+ {
+ var account = action.CloudFile.Account ?? CloudClient.UserName;
+ var container = action.CloudFile.Container ?? PithosContainer;
+
+ switch (action.Action)
+ {
+ case CloudActionType.UploadUnconditional:
+ UploadCloudFile(account, container, localFile, action.LocalHash.Value, action.TopHash.Value);
+ break;
+ case CloudActionType.DownloadUnconditional:
+
+ DownloadCloudFile(account, container, new Uri(cloudFile.Name, UriKind.Relative),
+ downloadPath);
+ break;
+ case CloudActionType.DeleteCloud:
+ DeleteCloudFile(account, container, cloudFile.Name);
+ break;
+ case CloudActionType.RenameCloud:
+ var moveAction = (CloudMoveAction)action;
+ RenameCloudFile(account, container, moveAction.OldFileName, moveAction.NewPath,
+ moveAction.NewFileName);
+ break;
+ case CloudActionType.MustSynch:
+
+ if (!File.Exists(downloadPath))
+ {
+ var cloudUri = new Uri(action.CloudFile.Name, UriKind.Relative);
+ DownloadCloudFile(account, container, cloudUri, downloadPath);
+ }
+ else
+ {
+ SyncFiles(action);
+ }
+ break;
+ }
+ Log.InfoFormat("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile,
+ action.CloudFile.Name);
+ }
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
+ catch (System.IO.FileNotFoundException exc)
+ {
+ Log.ErrorFormat("{0} : {1} -> {2} failed because the file was not found.\n Rescheduling a delete",
+ action.Action, action.LocalFile, action.CloudFile, exc);
+ Post(new CloudAction(CloudActionType.DeleteCloud,action.CloudFile));
+ }
+ catch (Exception exc)
+ {
+ Log.ErrorFormat("[REQUEUE] {0} : {1} -> {2} due to exception\r\n{3}",
+ action.Action, action.LocalFile, action.CloudFile, exc);
+
+ _agent.Post(action);
+ }
+ return CompletedTask<object>.Default;
+ }
+ }
+
+ private void SyncFiles(CloudAction action)
+ {
+ if (action==null)
+ throw new ArgumentNullException("action");
+ if (action.LocalFile==null)
+ throw new ArgumentException("The action's local file is not specified","action");
+ if (!Path.IsPathRooted(action.LocalFile.FullName))
+ throw new ArgumentException("The action's local file path must be absolute","action");
+ if (action.CloudFile== null)
+ throw new ArgumentException("The action's cloud file is not specified", "action");
+ Contract.EndContractBlock();
+
var localFile = action.LocalFile;
var cloudFile = action.CloudFile;
- var downloadPath = (cloudFile == null) ? String.Empty
- : Path.Combine(FileAgent.RootPath, cloudFile.Name.RelativeUrlToFilePath());
+ var downloadPath=action.LocalFile.FullName.ToLower();
- try
+ var account = cloudFile.Account;
+ //Use "pithos" by default if no container is specified
+ var container = cloudFile.Container ?? PithosContainer;
+
+ var cloudUri = new Uri(cloudFile.Name, UriKind.Relative);
+ var cloudHash = cloudFile.Hash.ToLower();
+ var localHash = action.LocalHash.Value.ToLower();
+ var topHash = action.TopHash.Value.ToLower();
+
+ //Not enough to compare only the local hashes, also have to compare the tophashes
+
+ //If any of the hashes match, we are done
+ if ((cloudHash == localHash || cloudHash == topHash))
{
- switch (action.Action)
+ Log.InfoFormat("Skipping {0}, hashes match",downloadPath);
+ return;
+ }
+
+ //The hashes DON'T match. We need to sync
+ var lastLocalTime = localFile.LastWriteTime;
+ var lastUpTime = cloudFile.Last_Modified;
+
+ //If the local file is newer upload it
+ if (lastUpTime <= lastLocalTime)
+ {
+ //It probably means it was changed while the app was down
+ UploadCloudFile(account, container, localFile, action.LocalHash.Value,
+ action.TopHash.Value);
+ }
+ else
+ {
+ //It the cloud file has a later date, it was modified by another user or computer.
+ //We need to check the local file's status
+ var status = StatusKeeper.GetFileStatus(downloadPath);
+ switch (status)
{
- case CloudActionType.UploadUnconditional:
- UploadCloudFile(localFile, action.LocalHash.Value, action.TopHash.Value);
+ case FileStatus.Unchanged:
+ //If the local file's status is Unchanged, we can go on and download the newer cloud file
+ DownloadCloudFile(account, container,cloudUri,downloadPath);
break;
- case CloudActionType.DownloadUnconditional:
- DownloadCloudFile(PithosContainer, new Uri(cloudFile.Name, UriKind.Relative), downloadPath);
+ case FileStatus.Modified:
+ //If the local file is Modified, we may have a conflict. In this case we should mark the file as Conflict
+ //We can't ensure that a file modified online since the last time will appear as Modified, unless we
+ //index all files before we start listening.
+ case FileStatus.Created:
+ //If the local file is Created, it means that the local and cloud files aren't related,
+ // yet they have the same name.
+
+ //In both cases we must mark the file as in conflict
+ ReportConflict(downloadPath);
break;
- case CloudActionType.DeleteCloud:
- DeleteCloudFile(cloudFile.Name);
- break;
- case CloudActionType.RenameCloud:
- RenameCloudFile(action.OldFileName, action.NewPath, action.NewFileName);
- break;
- case CloudActionType.MustSynch:
- if (File.Exists(downloadPath))
- {
- var cloudHash = cloudFile.Hash;
- var localHash = action.LocalHash.Value;
- var topHash = action.TopHash.Value;
- //Not enough to compare only the local hashes, also have to compare the tophashes
- if (!cloudHash.Equals(localHash, StringComparison.InvariantCultureIgnoreCase) &&
- !cloudHash.Equals(topHash, StringComparison.InvariantCultureIgnoreCase))
- {
- var lastLocalTime = localFile.LastWriteTime;
- var lastUpTime = cloudFile.Last_Modified;
- if (lastUpTime <= lastLocalTime)
- {
- //Local change while the app was down or Files in conflict
- //Maybe need to store version as well, to check who has the latest version
-
- //StatusKeeper.SetFileOverlayStatus(downloadPath, FileOverlayStatus.Conflict);
- UploadCloudFile(localFile, action.LocalHash.Value, action.TopHash.Value);
- }
- else
- {
- var status = StatusKeeper.GetFileStatus(downloadPath);
- switch (status)
- {
- case FileStatus.Unchanged:
- //It he cloud file has a later date, it was modified by another user or computer.
- //If the local file's status is Unchanged, we should go on and download the cloud file
- DownloadCloudFile(PithosContainer, new Uri(action.CloudFile.Name, UriKind.Relative), downloadPath);
- break;
- case FileStatus.Modified:
- //If the local file is Modified, we may have a conflict. In this case we should mark the file as Conflict
- //We can't ensure that a file modified online since the last time will appear as Modified, unless we
- //index all files before we start listening.
- StatusKeeper.SetFileOverlayStatus(downloadPath, FileOverlayStatus.Conflict);
- break;
- case FileStatus.Created:
- //If the local file is Created, it means that the local and cloud files aren't related yet have the same name
- //In this case we must mark the file as in conflict
- //Other cases should never occur. Mark them as Conflict as well but log a warning
- StatusKeeper.SetFileOverlayStatus(downloadPath, FileOverlayStatus.Conflict);
- break;
- default:
- //If the local file is Created, it means that the local and cloud files aren't related yet have the same name
- //In this case we must mark the file as in conflict
- //Other cases should never occur. Mark them as Conflict as well but log a warning
- StatusKeeper.SetFileOverlayStatus(downloadPath, FileOverlayStatus.Conflict);
- Trace.TraceWarning("Unexcepted status {0} for file {1}->{2}", status, downloadPath, action.CloudFile.Name);
- break;
- }
- }
- }
- }
- else
- DownloadCloudFile(PithosContainer, new Uri(action.CloudFile.Name, UriKind.Relative), downloadPath);
+ default:
+ //Other cases should never occur. Mark them as Conflict as well but log a warning
+ ReportConflict(downloadPath);
+ Log.WarnFormat("Unexcepted status {0} for file {1}->{2}", status,
+ downloadPath, action.CloudFile.Name);
break;
}
+ }
+ }
+
+ private void ReportConflict(string downloadPath)
+ {
+ if (String.IsNullOrWhiteSpace(downloadPath))
+ throw new ArgumentNullException("downloadPath");
+ Contract.EndContractBlock();
+
+ StatusKeeper.SetFileOverlayStatus(downloadPath, FileOverlayStatus.Conflict);
+ var message = String.Format("Conflict detected for file {0}", downloadPath);
+ Log.Warn(message);
+ StatusNotification.NotifyChange(message, TraceLevel.Warning);
+ }
+
+/*
+ private Task<object> Process(CloudMoveAction action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ Contract.EndContractBlock();
+
+ Trace.TraceInformation("[ACTION] Start Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
+
+ try
+ {
+ RenameCloudFile(action.OldFileName, action.NewPath, action.NewFileName);
Trace.TraceInformation("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
}
catch (OperationCanceledException)
catch (Exception exc)
{
Trace.TraceError("[REQUEUE] {0} : {1} -> {2} due to exception\r\n{3}",
- action.Action, action.LocalFile, action.CloudFile, exc);
+ action.Action, action.OldFileName, action.NewFileName, exc);
_agent.Post(action);
}
return CompletedTask<object>.Default;
}
+*/
public void Post(CloudAction cloudAction)
//If the action targets a local file, add a treehash calculation
if (cloudAction.LocalFile != null)
{
- cloudAction.TopHash = new Lazy<string>(() => Signature.CalculateTreeHashAsync(cloudAction.LocalFile,
+
+ if (cloudAction.LocalFile.Length>BlockSize)
+ cloudAction.TopHash = new Lazy<string>(() => Signature.CalculateTreeHashAsync(cloudAction.LocalFile,
BlockSize, BlockHash).Result
.TopHash.ToHashString());
+ else
+ {
+ cloudAction.TopHash=new Lazy<string>(()=> cloudAction.LocalHash.Value);
+ }
}
_agent.Post(cloudAction);
throw new ArgumentNullException(accountPath);
Contract.EndContractBlock();
- Trace.CorrelationManager.StartLogicalOperation();
- Trace.TraceInformation("[LISTENER] Scheduled");
-
- //Get the list of server objects changed since the last check
- var listObjects = Task<IList<ObjectInfo>>.Factory.StartNewDelayed(10000,()=>
- CloudClient.ListObjects(PithosContainer,since));
- //Get the list of deleted objects since the last check
- var listTrash= Task<IList<ObjectInfo>>.Factory.StartNewDelayed(10000,()=>
- CloudClient.ListObjects(TrashContainer,since));
+ using (log4net.LogicalThreadContext.Stacks["SCHEDULE"].Push("Retrieve Remote"))
+ {
+ Log.Info("[LISTENER] Scheduled");
- var listAll = Task.Factory.TrackedSequence(() => listObjects, () => listTrash);
+ //Get the list of server objects changed since the last check
+ var listObjects = Task<IList<ObjectInfo>>.Factory.StartNewDelayed(10000, () =>
+ CloudClient.ListObjects(CloudClient.UserName, PithosContainer, since));
+ //Get the list of deleted objects since the last check
+ var listTrash = Task<IList<ObjectInfo>>.Factory.StartNewDelayed(10000, () =>
+ CloudClient.ListObjects(CloudClient.UserName, TrashContainer, since));
- //Next time we will check for all changes since the current check minus 1 second
- //This is done to ensure there are no discrepancies due to clock differences
- DateTime nextSince = DateTime.Now.AddSeconds(-1);
+ var listShared = Task<IList<ObjectInfo>>.Factory.StartNewDelayed(10000, () =>
+ CloudClient.ListSharedObjects(since));
+ var listAll = Task.Factory.TrackedSequence(
+ () => listObjects,
+ () => listTrash,
+ () => listShared);
+ //Next time we will check for all changes since the current check minus 1 second
+ //This is done to ensure there are no discrepancies due to clock differences
+ DateTime nextSince = DateTime.Now.AddSeconds(-1);
-
-
- var enqueueFiles = listAll.ContinueWith(task =>
- {
- if (task.IsFaulted)
+ var enqueueFiles = listAll.ContinueWith(task =>
{
- //ListObjects failed at this point, need to reschedule
- Trace.TraceError("[FAIL] ListObjects in ProcessRemoteFiles with {0}", task.Exception);
- ProcessRemoteFiles(accountPath, since);
- return;
- }
- Trace.CorrelationManager.StartLogicalOperation("Listener");
- Trace.TraceInformation("[LISTENER] Start Processing");
+ if (task.IsFaulted)
+ {
+ //ListObjects failed at this point, need to reschedule
+ Log.ErrorFormat("[FAIL] ListObjects in ProcessRemoteFiles with {0}", task.Exception);
+ ProcessRemoteFiles(accountPath, since);
+ return;
+ }
+ using (log4net.LogicalThreadContext.Stacks["SCHEDULE"].Push("Process Results"))
+ {
+ var remoteObjects = ((Task<IList<ObjectInfo>>) task.Result[0]).Result;
+ var trashObjects = ((Task<IList<ObjectInfo>>) task.Result[1]).Result;
+ var sharedObjects = ((Task<IList<ObjectInfo>>) task.Result[2]).Result;
+
+ //Items with the same name, hash may be both in the container and the trash
+ //Don't delete items that exist in the container
+ var realTrash = from trash in trashObjects
+ where !remoteObjects.Any(info => info.Hash == trash.Hash)
+ select trash;
+ ProcessDeletedFiles(realTrash);
+
+
+ var remote = from info in remoteObjects.Union(sharedObjects)
+ let name = info.Name
+ where !name.EndsWith(".ignore", StringComparison.InvariantCultureIgnoreCase) &&
+ !name.StartsWith("fragments/", StringComparison.InvariantCultureIgnoreCase)
+ select info;
+
+ //Create a list of actions from the remote files
+ var allActions = ObjectsToActions(remote);
+
+ //And remove those that are already being processed by the agent
+ var distinctActions = allActions
+ .Except(_agent.GetEnumerable(), new PithosMonitor.LocalFileComparer())
+ .ToList();
+
+ //Queue all the actions
+ foreach (var message in distinctActions)
+ {
+ Post(message);
+ }
- var trashObjects = ((Task<IList<ObjectInfo>>)task.Result[1]).Result;
- var remoteObjects = ((Task<IList<ObjectInfo>>)task.Result[0]).Result;
+ //Report the number of new files
+ var remoteCount = distinctActions.Count(action=>
+ action.Action==CloudActionType.DownloadUnconditional);
+ if ( remoteCount > 0)
+ StatusNotification.NotifyChange(String.Format("Processing {0} new files", remoteCount));
-
- //Items with the same name, hash may be both in the container and the trash
- //Don't delete items that exist in the container
- var realTrash = from trash in trashObjects
- where !remoteObjects.Any(info => info.Hash == trash.Hash)
- select trash;
- ProcessDeletedFiles(realTrash);
-
-
- var remote=from info in remoteObjects
- let name=info.Name
- where !name.EndsWith(".ignore",StringComparison.InvariantCultureIgnoreCase) &&
- !name.StartsWith("fragments/",StringComparison.InvariantCultureIgnoreCase)
- select info;
-
- var commonObjects = new List<Tuple<ObjectInfo, FileInfo,FileState>>();
- var remoteOnly = new List<ObjectInfo>();
-
- //In order to avoid multiple iterations over the files, we iterate only once
- //over the remote files
- foreach (var objectInfo in remote)
- {
- var relativePath= objectInfo.Name.RelativeUrlToFilePath();
- //and remove any matching objects from the list, adding them to the commonObjects list
- if (FileAgent.Exists(relativePath))
+ Log.Info("[LISTENER] End Processing");
+ }
+ });
+
+ var loop = enqueueFiles.ContinueWith(t =>
+ {
+ if (t.IsFaulted)
{
- var localFile = FileAgent.GetFileInfo(relativePath);
- var state = FileState.FindByFilePath(localFile.FullName);
- commonObjects.Add(Tuple.Create(objectInfo, localFile, state));
+ Log.Error("[LISTENER] Exception", t.Exception);
}
else
{
- //If there is no match we add them to the localFiles list
- //but only if the file is not marked for deletion
- var targetFile = Path.Combine(FileAgent.RootPath, relativePath);
- var fileStatus = StatusKeeper.GetFileStatus(targetFile);
- if (fileStatus!=FileStatus.Deleted)
- remoteOnly.Add(objectInfo);
-
-
+ Log.Info("[LISTENER] Finished");
}
- }
-
- //At the end of the iteration, the *remote* list will contain the files that exist
- //only on the server
-
- //Remote files should be downloaded
- var actionsForRemote = from upFile in remoteOnly
- select new CloudAction(CloudActionType.DownloadUnconditional,upFile);
-
- //Common files should be checked on a per-case basis to detect differences, which is newer
- var actionsForCommon = from pair in commonObjects
- let objectInfo = pair.Item1
- let localFile = pair.Item2
- let state=pair.Item3
- select new CloudAction(CloudActionType.MustSynch,
- localFile, objectInfo,state,BlockSize,BlockHash);
-
-
-
-
-
- //Collect all the actions
- var allActions = actionsForRemote.Union(actionsForCommon);
-
- //And remove those that are already being processed by the agent
- var distinctActions =allActions
- .Except(_agent.GetEnumerable(), new PithosMonitor.LocalFileComparer())
- .ToList();
-
- //Queue all the actions
- foreach (var message in distinctActions)
- {
- Post(message);
- }
-
-
- if(remoteOnly.Count>0)
- StatusNotification.NotifyChange(String.Format("Processing {0} new files", remoteOnly.Count));
+ ProcessRemoteFiles(accountPath, nextSince);
- Trace.TraceInformation("[LISTENER] End Processing");
- Trace.CorrelationManager.StopLogicalOperation();
+ });
+ return loop;
+ }
+ }
- });
+ //Creates an appropriate action for each server file
+ private IEnumerable<CloudAction> ObjectsToActions(IEnumerable<ObjectInfo> remote)
+ {
+ if (remote==null)
+ throw new ArgumentNullException();
+ Contract.EndContractBlock();
- var loop = enqueueFiles.ContinueWith(t =>
+ //In order to avoid multiple iterations over the files, we iterate only once
+ //over the remote files
+ foreach (var objectInfo in remote)
{
- if (t.IsFaulted)
+ var relativePath = objectInfo.RelativeUrlToFilePath(CloudClient.UserName);
+ //and remove any matching objects from the list, adding them to the commonObjects list
+ if (FileAgent.Exists(relativePath))
{
- Trace.TraceError("[LISTENER] Exception: {0}", t.Exception);
+ var localFile = FileAgent.GetFileInfo(relativePath);
+ var state = FileState.FindByFilePath(localFile.FullName);
+ //Common files should be checked on a per-case basis to detect differences, which is newer
+
+ yield return new CloudAction(CloudActionType.MustSynch,
+ localFile, objectInfo, state, BlockSize, BlockHash);
}
else
{
- Trace.TraceInformation("[LISTENER] Finished");
+ //If there is no match we add them to the localFiles list
+ //but only if the file is not marked for deletion
+ var targetFile = Path.Combine(FileAgent.RootPath, relativePath);
+ var fileStatus = StatusKeeper.GetFileStatus(targetFile);
+ if (fileStatus != FileStatus.Deleted)
+ {
+ //Remote files should be downloaded
+ yield return new CloudAction(CloudActionType.DownloadUnconditional, objectInfo);
+ }
}
- ProcessRemoteFiles(accountPath, nextSince);
-
- });
- return loop;
+ }
}
private void ProcessDeletedFiles(IEnumerable<ObjectInfo> trashObjects)
{
foreach (var trashObject in trashObjects)
{
- var relativePath = trashObject.Name.RelativeUrlToFilePath();
+ var relativePath = trashObject.RelativeUrlToFilePath(CloudClient.UserName);
//and remove any matching objects from the list, adding them to the commonObjects list
FileAgent.Delete(relativePath);
}
}
- private void RenameCloudFile(string oldFileName, string newPath, string newFileName)
+ private void RenameCloudFile(string account, string container,string oldFileName, string newPath, string newFileName)
{
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
+ if (String.IsNullOrWhiteSpace(container))
+ throw new ArgumentNullException("container");
if (String.IsNullOrWhiteSpace(oldFileName))
throw new ArgumentNullException("oldFileName");
if (String.IsNullOrWhiteSpace(oldFileName))
//The local file is already renamed
this.StatusKeeper.SetFileOverlayStatus(newPath, FileOverlayStatus.Modified);
- CloudClient.MoveObject(PithosContainer, oldFileName, PithosContainer, newFileName);
+ CloudClient.MoveObject(account, container, oldFileName, container, newFileName);
this.StatusKeeper.SetFileStatus(newPath, FileStatus.Unchanged);
this.StatusKeeper.SetFileOverlayStatus(newPath, FileOverlayStatus.Normal);
NativeMethods.RaiseChangeNotification(newPath);
}
- private void DeleteCloudFile(string fileName)
- {
+ private void DeleteCloudFile(string account,string container, string fileName)
+ {
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
+ if (String.IsNullOrWhiteSpace(container))
+ throw new ArgumentNullException("container");
+ if (String.IsNullOrWhiteSpace(container))
+ throw new ArgumentNullException("container");
+
if (String.IsNullOrWhiteSpace(fileName))
throw new ArgumentNullException("fileName");
if (Path.IsPathRooted(fileName))
throw new ArgumentException("The fileName should not be rooted","fileName");
Contract.EndContractBlock();
- this.StatusKeeper.SetFileOverlayStatus(fileName, FileOverlayStatus.Modified);
- CloudClient.DeleteObject(PithosContainer, fileName, TrashContainer);
+ using ( log4net.LogicalThreadContext.Stacks["DeleteCloudFile"].Push("Delete"))
+ {
+ var info = FileAgent.GetFileInfo(fileName);
+ var path = info.FullName.ToLower();
+ this.StatusKeeper.SetFileOverlayStatus(path, FileOverlayStatus.Modified);
+
+ CloudClient.DeleteObject(account, container, fileName, TrashContainer);
- this.StatusKeeper.ClearFileStatus(fileName);
- this.StatusKeeper.RemoveFileOverlayStatus(fileName);
+ this.StatusKeeper.ClearFileStatus(path);
+ }
}
//Download a file.
- private void DownloadCloudFile(string container, Uri relativeUrl, string localPath)
+ private void DownloadCloudFile(string account,string container, Uri relativeUrl, string localPath)
{
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
if (relativeUrl == null)
throw new ArgumentException("The localPath must be rooted", "localPath");
Contract.EndContractBlock();
- var download=Task.Factory.Iterate(DownloadIterator(container, relativeUrl, localPath));
+ var download=Task.Factory.Iterate(DownloadIterator(account,container, relativeUrl, localPath));
download.Wait();
}
- private IEnumerable<Task> DownloadIterator(string container, Uri relativeUrl, string localPath)
+ private IEnumerable<Task> DownloadIterator(string account,string container, Uri relativeUrl, string localPath)
{
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
if (relativeUrl==null)
//var hashPath = Path.Combine(FileAgent.FragmentsPath, relativePath + ".hashmap");
//Retrieve the hashmap from the server
- var getHashMap = CloudClient.GetHashMap(container,url);
+ var getHashMap = CloudClient.GetHashMap(account, container, url);
yield return getHashMap;
var serverHash=getHashMap.Result;
//If it's a small file
var downloadTask=(serverHash.Hashes.Count == 1 )
//Download it in one go
- ? DownloadEntireFile(container, relativeUrl, localPath)
+ ? DownloadEntireFile(account,container, relativeUrl, localPath)
//Otherwise download it block by block
- : DownloadWithBlocks(container, relativeUrl, localPath, serverHash);
+ : DownloadWithBlocks(account,container, relativeUrl, localPath, serverHash);
yield return downloadTask;
//Retrieve the object's metadata
- var info=CloudClient.GetObjectInfo(container, url);
+ var info=CloudClient.GetObjectInfo(account, container, url);
//And store it
StatusKeeper.StoreInfo(localPath, info);
}
//Download a small file with a single GET operation
- private Task DownloadEntireFile(string container, Uri relativeUrl, string localPath)
+ private Task DownloadEntireFile(string account,string container, Uri relativeUrl, string localPath)
{
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
if (relativeUrl == null)
Directory.CreateDirectory(directoryPath);
//Download the object to the temporary location
- var getObject = CloudClient.GetObject(container, relativeUrl.ToString(), tempPath).ContinueWith(t =>
+ var getObject = CloudClient.GetObject(account, container, relativeUrl.ToString(), tempPath).ContinueWith(t =>
{
t.PropagateExceptions();
//And move it to its actual location once downloading is finished
}
//Download a file asynchronously using blocks
- public Task DownloadWithBlocks(string container, Uri relativeUrl, string localPath, TreeHash serverHash)
+ public Task DownloadWithBlocks(string account,string container, Uri relativeUrl, string localPath, TreeHash serverHash)
{
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
if (relativeUrl == null)
throw new ArgumentNullException("serverHash");
Contract.EndContractBlock();
- return Task.Factory.Iterate(BlockDownloadIterator(container, relativeUrl, localPath, serverHash));
+ return Task.Factory.Iterate(BlockDownloadIterator(account,container, relativeUrl, localPath, serverHash));
}
- private IEnumerable<Task> BlockDownloadIterator(string container,Uri relativeUrl, string localPath,TreeHash serverHash)
+ private IEnumerable<Task> BlockDownloadIterator(string account,string container,Uri relativeUrl, string localPath,TreeHash serverHash)
{
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
if (relativeUrl == null)
{
if (blockUpdater.UseOrphan(i, upHash))
{
- Trace.TraceInformation("[BLOCK GET] ORPHAN FOUND for {0} of {1} for {2}", i, upHashes.Length, localPath);
+ Log.InfoFormat("[BLOCK GET] ORPHAN FOUND for {0} of {1} for {2}", i, upHashes.Length, localPath);
continue;
}
- Trace.TraceInformation("[BLOCK GET] START {0} of {1} for {2}",i,upHashes.Length,localPath);
+ Log.InfoFormat("[BLOCK GET] START {0} of {1} for {2}", i, upHashes.Length, localPath);
var start = i*BlockSize;
//To download the last block just pass a null for the end of the range
long? end = null;
end= ((i + 1)*BlockSize) ;
//Download the missing block
- var getBlock = CloudClient.GetBlock(container, relativeUrl, start, end);
+ var getBlock = CloudClient.GetBlock(account, container, relativeUrl, start, end);
yield return getBlock;
var block = getBlock.Result;
//and store it
yield return blockUpdater.StoreBlock(i, block);
-
- Trace.TraceInformation("[BLOCK GET] FINISH {0} of {1} for {2}", i, upHashes.Length, localPath);
+
+ Log.InfoFormat("[BLOCK GET] FINISH {0} of {1} for {2}", i, upHashes.Length, localPath);
}
}
blockUpdater.Commit();
- Trace.TraceInformation("[BLOCK GET] COMPLETE {0}", localPath);
+ Log.InfoFormat("[BLOCK GET] COMPLETE {0}", localPath);
}
- private void UploadCloudFile(FileInfo fileInfo, string hash,string topHash)
+ private void UploadCloudFile(string account,string container,FileInfo fileInfo, string hash,string topHash)
{
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
+ if (String.IsNullOrWhiteSpace(container))
+ throw new ArgumentNullException("container");
if (fileInfo == null)
throw new ArgumentNullException("fileInfo");
if (String.IsNullOrWhiteSpace(hash))
throw new ArgumentNullException("topHash");
Contract.EndContractBlock();
- var upload = Task.Factory.Iterate(UploadIterator(fileInfo, hash, topHash));
+ var upload = Task.Factory.Iterate(UploadIterator(account,container,fileInfo, hash, topHash));
upload.Wait();
}
- private IEnumerable<Task> UploadIterator(FileInfo fileInfo, string hash,string topHash)
+ private IEnumerable<Task> UploadIterator(string account,string container,FileInfo fileInfo, string hash,string topHash)
{
- if (fileInfo==null)
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
+ if (String.IsNullOrWhiteSpace(container))
+ throw new ArgumentNullException("container");
+ if (fileInfo == null)
throw new ArgumentNullException("fileInfo");
if (String.IsNullOrWhiteSpace(hash))
throw new ArgumentNullException("hash");
//Even if GetObjectInfo times out, we can proceed with the upload
- var info = CloudClient.GetObjectInfo(PithosContainer, url);
+ var info = CloudClient.GetObjectInfo(account, container, url);
//If the file hashes match, abort the upload
if (hash.Equals(info.Hash, StringComparison.InvariantCultureIgnoreCase) ||
{
//but store any metadata changes
this.StatusKeeper.StoreInfo(fullFileName, info);
- Trace.TraceInformation("Skip upload of {0}, hashes match", fullFileName);
+ Log.InfoFormat("Skip upload of {0}, hashes match", fullFileName);
yield break;
}
var treeHash = Signature.CalculateTreeHashAsync(fileInfo.FullName, BlockSize, BlockHash);
yield return treeHash;
- yield return Task.Factory.Iterate(UploadWithHashMap(fileInfo,url,treeHash));
+ yield return Task.Factory.Iterate(UploadWithHashMap(account,container,fileInfo,url,treeHash));
}
else
{
//Otherwise do a regular PUT
- yield return CloudClient.PutObject(PithosContainer,url,fullFileName,hash);
+ yield return CloudClient.PutObject(account, container, url, fullFileName, hash);
}
//If everything succeeds, change the file and overlay status to normal
this.StatusKeeper.SetFileState(fullFileName, FileStatus.Unchanged, FileOverlayStatus.Normal);
StatusNotification.NotifyChangedFile(fullFileName);
}
- public IEnumerable<Task> UploadWithHashMap(FileInfo fileInfo,string url,Task<TreeHash> treeHash)
+ public IEnumerable<Task> UploadWithHashMap(string account,string container,FileInfo fileInfo,string url,Task<TreeHash> treeHash)
{
- if(fileInfo==null)
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
+ if (String.IsNullOrWhiteSpace(container))
+ throw new ArgumentNullException("container");
+ if (fileInfo == null)
throw new ArgumentNullException("fileInfo");
if (String.IsNullOrWhiteSpace(url))
throw new ArgumentNullException(url);
var fullFileName = fileInfo.FullName;
//Send the hashmap to the server
- var hashPut = CloudClient.PutHashMap(PithosContainer, url, treeHash.Result);
+ var hashPut = CloudClient.PutHashMap(account, container, url, treeHash.Result);
yield return hashPut;
var missingHashes = hashPut.Result;
var read = fileInfo.Read(buffer, offset, BlockSize);
//And upload the block
- var postBlock = CloudClient.PostBlock(PithosContainer, buffer, 0, read);
+ var postBlock = CloudClient.PostBlock(account, container, buffer, 0, read);
//We have to handle possible exceptions in a continuation because
//*yield return* can't appear inside a try block
yield return postBlock.ContinueWith(t =>
t.ReportExceptions(
- exc=>Trace.TraceError("[ERROR] uploading block {0} of {1}\n{2}",blockIndex, fullFileName, exc),
- ()=>Trace.TraceInformation("[BLOCK] Block {0} of {1} uploaded", blockIndex,fullFileName)));
+ exc => Log.ErrorFormat("[ERROR] uploading block {0} of {1}\n{2}", blockIndex, fullFileName, exc),
+ ()=>Log.InfoFormat("[BLOCK] Block {0} of {1} uploaded", blockIndex,fullFileName)));
}
//Repeat until there are no more missing hashes
- hashPut = CloudClient.PutHashMap(PithosContainer, url, treeHash.Result);
+ hashPut = CloudClient.PutHashMap(account, container, url, treeHash.Result);
yield return hashPut;
missingHashes = hashPut.Result;
}
using System;
-using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
-using System.Linq.Expressions;
-using System.Security.Cryptography;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
-using NHibernate.Criterion;
-using NHibernate.Impl;
-using Pithos.Core.Agents;
using Pithos.Interfaces;
-using Pithos.Network;
+using log4net;
+using log4net.Appender;
+using log4net.Config;
+using log4net.Layout;
-namespace Pithos.Core
+namespace Pithos.Core.Agents
{
[Export(typeof(IStatusChecker)),Export(typeof(IStatusKeeper))]
- public class StatusKeeper:IStatusChecker,IStatusKeeper
+ public class StatusAgent:IStatusChecker,IStatusKeeper
{
[System.ComponentModel.Composition.Import]
public IPithosSettings Settings { get; set; }
private Agent<Action> _persistenceAgent;
- public StatusKeeper()
+
+ private static readonly ILog log = LogManager.GetLogger(typeof(StatusAgent));
+
+ public StatusAgent()
{
var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
_pithosDataPath = Path.Combine(appDataPath , "Pithos");
Directory.CreateDirectory(_pithosDataPath);
//File.Delete(Path.Combine(_pithosDataPath, "pithos.db"));
+
var source = GetConfiguration(_pithosDataPath);
ActiveRecordStarter.Initialize(source,typeof(FileState),typeof(FileTag));
+ ActiveRecordStarter.UpdateSchema();
;
if (!File.Exists(Path.Combine(_pithosDataPath ,"pithos.db")))
ActiveRecordStarter.CreateSchema();
+
+
CleanupStaleStates();
- }
+ }
private void CleanupStaleStates()
{
if(existingFiles ==null)
throw new ArgumentNullException("existingFiles");
Contract.EndContractBlock();
- Dictionary<int, int> j;
//Find new or matching files with a left join to the stored states
var fileStates = FileState.Queryable;
throw new ArgumentNullException("path");
if (!Path.IsPathRooted(path))
throw new ArgumentException("path must be a rooted path", "path");
+ if (getter == null)
+ throw new ArgumentNullException("getter");
Contract.EndContractBlock();
{
if (String.IsNullOrWhiteSpace(path))
throw new ArgumentNullException("path", "path can't be empty");
-
if (setter==null)
throw new ArgumentNullException("setter", "setter can't be empty");
+ Contract.EndContractBlock();
_persistenceAgent.Post(() =>
{
/// <param name="setter"></param>
private void UpdateStatus(string path, Action<FileState> setter)
{
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ if (setter == null)
+ throw new ArgumentNullException("setter");
+ Contract.EndContractBlock();
+
Debug.Assert(!path.Contains("fragments"));
Debug.Assert(!path.EndsWith(".ignore"));
/// <param name="setter"></param>
private void UpdateStatus(Guid stateID, Action<FileState> setter)
{
+ if (setter == null)
+ throw new ArgumentNullException("setter");
+ Contract.EndContractBlock();
+
+
_persistenceAgent.Post(() =>
{
using (new SessionScope())
public FileOverlayStatus GetFileOverlayStatus(string path)
{
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ Contract.EndContractBlock();
+
try
{
var state = FileState.FindByFilePath(path);
public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus)
{
- SetStatus(path,s=>s.OverlayStatus=overlayStatus);
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted","path");
+ Contract.EndContractBlock();
+
+ SetStatus(path.ToLower(),s=>s.OverlayStatus=overlayStatus);
}
- public void RemoveFileOverlayStatus(string path)
+ /*public void RemoveFileOverlayStatus(string path)
{
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ Contract.EndContractBlock();
+
_persistenceAgent.Post(() =>
InnerRemoveFileOverlayStatus(path));
}
private static void InnerRemoveFileOverlayStatus(string path)
{
- FileState.DeleteAll(String.Format("FilePath = '{0}'",path));
- }
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ Contract.EndContractBlock();
+
+ FileState.DeleteByFilePath(path);
+ }*/
public void RenameFileOverlayStatus(string oldPath, string newPath)
{
+ if (String.IsNullOrWhiteSpace(oldPath))
+ throw new ArgumentNullException("oldPath");
+ if (!Path.IsPathRooted(oldPath))
+ throw new ArgumentException("The oldPath must be rooted", "oldPath");
+ if (String.IsNullOrWhiteSpace(newPath))
+ throw new ArgumentNullException("newPath");
+ if (!Path.IsPathRooted(newPath))
+ throw new ArgumentException("The newPath must be rooted", "newPath");
+ Contract.EndContractBlock();
+
_persistenceAgent.Post(() =>
InnerRenameFileOverlayStatus(oldPath, newPath));
}
private static void InnerRenameFileOverlayStatus(string oldPath, string newPath)
{
+ if (String.IsNullOrWhiteSpace(oldPath))
+ throw new ArgumentNullException("oldPath");
+ if (!Path.IsPathRooted(oldPath))
+ throw new ArgumentException("The oldPath must be rooted", "oldPath");
+ if (String.IsNullOrWhiteSpace(newPath))
+ throw new ArgumentNullException("newPath");
+ if (!Path.IsPathRooted(newPath))
+ throw new ArgumentException("The newPath must be rooted", "newPath");
+ Contract.EndContractBlock();
+
var state = FileState.FindByFilePath(oldPath);
if (state == null)
public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus)
{
if (String.IsNullOrWhiteSpace(path))
- throw new ArgumentNullException("path", "path can't be empty");
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
Contract.EndContractBlock();
- UpdateStatus(path,state=>
+ UpdateStatus(path.ToLower(),state=>
{
state.FileStatus = fileStatus;
state.OverlayStatus = overlayStatus;
public void StoreInfo(string path,ObjectInfo objectInfo)
{
if (String.IsNullOrWhiteSpace(path))
- throw new ArgumentNullException("path", "path can't be empty");
- if (objectInfo==null)
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ if (objectInfo == null)
throw new ArgumentNullException("objectInfo", "objectInfo can't be empty");
Contract.EndContractBlock();
public void SetFileStatus(string path, FileStatus status)
{
- UpdateStatus(path, state=>state.FileStatus = status);
+ UpdateStatus(path.ToLower(), state=>state.FileStatus = status);
}
public FileStatus GetFileStatus(string path)
{
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ Contract.EndContractBlock();
+
var state = FileState.FindByFilePath(path);
return (state==null)?FileStatus.Missing:state.FileStatus ;
}
public void ClearFileStatus(string path)
{
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ Contract.EndContractBlock();
+
//TODO:SHOULDN'T need both clear file status and remove overlay status
- _persistenceAgent.Post(()=> FileState.DeleteByFilePath(path));
+ _persistenceAgent.Post(() =>
+ {
+ using (new SessionScope())
+ {
+ FileState.DeleteByFilePath(path);
+ }
+ });
}
public void UpdateFileChecksum(string path, string checksum)
- {
- _persistenceAgent.Post(()=>
+ {
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ Contract.EndContractBlock();
+
+ _persistenceAgent.Post(() =>
{
using (new SessionScope())
{
{
if (state.Skip)
return CompletedTask<object>.Default;
- string path = state.Path.ToLower();
- string fileName = Path.GetFileName(path);
+ string path = state.Path.ToLower();
//Bypass deleted files, unless the status is Deleted
if (!File.Exists(path) && state.Status != FileStatus.Deleted)
{
state.Skip = true;
- this.StatusKeeper.RemoveFileOverlayStatus(path);
+ this.StatusKeeper.ClearFileStatus(path);
return CompletedTask<object>.Default;
}
var fileState = FileState.FindByFilePath(path);
var blockHash = NetworkAgent.BlockHash;
var blockSize = NetworkAgent.BlockSize;
+ var info = new FileInfo(path);
switch (state.Status)
{
case FileStatus.Created:
case FileStatus.Modified:
- var info = new FileInfo(path);
NetworkAgent.Post(new CloudAction(CloudActionType.UploadUnconditional, info, ObjectInfo.Empty, fileState,blockSize,blockHash));
break;
case FileStatus.Deleted:
+ string fileName = info.AsRelativeUrlTo(NetworkAgent.FileAgent.RootPath);
NetworkAgent.Post(new CloudAction(CloudActionType.DeleteCloud, null, new ObjectInfo { Name = fileName }, fileState, blockSize, blockHash));
break;
case FileStatus.Renamed:
- NetworkAgent.Post(new CloudAction(CloudActionType.RenameCloud, state.OldFileName, state.OldPath, state.FileName, state.Path));
+ NetworkAgent.Post(new CloudMoveAction(CloudActionType.RenameCloud, state.OldFileName, state.OldPath, state.FileName, state.Path));
break;
}
<?xml version="1.0" encoding="utf-8" ?>
<activerecord>
-
<config>
<add key="connection.driver_class" value="NHibernate.Driver.SQLite20Driver" />
<add key="dialect" value="NHibernate.Dialect.SQLiteDialect" />
using System.Threading.Tasks;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework;
+using Castle.ActiveRecord.Queries;
using NHibernate.Engine;
using Pithos.Core.Agents;
using Pithos.Interfaces;
[Property]
public DateTime? VersionTimeStamp { get; set; }
-
+
+
+ [Property]
+ public bool IsShared { get; set; }
+
+ [Property]
+ public string SharedBy { get; set; }
+
+ [Property]
+ public bool ShareWrite { get; set; }
+
[HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true,Inverse=true)]
public IList<FileTag> Tags
throw new ArgumentNullException("absolutePath");
Contract.EndContractBlock();
- var stateKeys = from state in FileState.Queryable
- where state.FilePath == absolutePath.ToLower()
- select state.Id;
- DeleteAll(stateKeys);
+ FileState.Execute((session, instance) =>
+ {
+ const string hqlDelete = "delete FileState where FilePath = :path";
+ var deletedEntities = session.CreateQuery(hqlDelete)
+ .SetString("path", absolutePath.ToLower())
+ .ExecuteUpdate();
+ return null;
+ },null);
+
}
public static Task<FileState> CreateForAsync(string filePath,int blockSize,string algorithm)
{
void SetFileOverlayStatus(string path,FileOverlayStatus status);
void UpdateFileChecksum(string path, string checksum);
- void RemoveFileOverlayStatus(string path);
void SetFileStatus(string path, FileStatus status);
FileStatus GetFileStatus(string path);
void ClearFileStatus(string path);
public void SetFileOverlayStatus(string path, FileOverlayStatus status)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
+ Contract.Requires(Path.IsPathRooted(path));
}
public void UpdateFileChecksum(string path, string checksum)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
Contract.Requires(checksum!=null);
+ Contract.Requires(Path.IsPathRooted(path));
}
- public void RemoveFileOverlayStatus(string path)
+ /* public void RemoveFileOverlayStatus(string path)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
- }
+ Contract.Requires(Path.IsPathRooted(path));
+ }*/
public void RenameFileOverlayStatus(string oldPath, string newPath)
{
Contract.Requires(!String.IsNullOrWhiteSpace(oldPath));
+ Contract.Requires(Path.IsPathRooted(oldPath));
Contract.Requires(!String.IsNullOrWhiteSpace(newPath));
+ Contract.Requires(Path.IsPathRooted(newPath));
}
public void SetFileStatus(string path, FileStatus status)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
+ Contract.Requires(Path.IsPathRooted(path));
}
public FileStatus GetFileStatus(string path)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
+ Contract.Requires(Path.IsPathRooted(path));
return default(FileStatus);
}
public FileOverlayStatus GetFileOverlayStatus(string path)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
+ Contract.Requires(Path.IsPathRooted(path));
return default(FileOverlayStatus);
}
public void ProcessExistingFiles(IEnumerable<FileInfo> paths)
{
Contract.Requires(paths!=null);
-
}
public void Stop()
public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
+ Contract.Requires(Path.IsPathRooted(path));
}
public void StoreInfo(string path, ObjectInfo objectInfo)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
- Contract.Requires(objectInfo!=null);
+ Contract.Requires(objectInfo!=null);
+ Contract.Requires(Path.IsPathRooted(path));
}
public T GetStatus<T>(string path, Func<FileState, T> getter, T defaultValue)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
Contract.Requires(getter!=null);
+ Contract.Requires(Path.IsPathRooted(path));
return default(T);
}
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
Contract.Requires(setter != null);
+ Contract.Requires(Path.IsPathRooted(path));
}
public void SetNetworkState(string path, NetworkOperation operation)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
- Contract.Requires(Path.IsPathRooted(path));
+ Contract.Requires(Path.IsPathRooted(path));
+ Contract.Requires(Path.IsPathRooted(path));
}
public NetworkOperation GetNetworkState(string path)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
+ Contract.Requires(Path.IsPathRooted(path));
return default(NetworkOperation);
}
public void ClearFileStatus(string path)
{
Contract.Requires(!String.IsNullOrWhiteSpace(path));
+ Contract.Requires(Path.IsPathRooted(path));
}
public void SetPithosStatus(PithosStatus status)
//uploading.
public class NetworkGate:IDisposable
{
+ public string FilePath { get; private set; }
+ public NetworkOperation Operation { get; private set; }
+
+ [ContractInvariantMethod]
+ private void Invariants()
+ {
+ Contract.Invariant(!String.IsNullOrWhiteSpace(FilePath));
+ Contract.Invariant(Path.IsPathRooted(FilePath));
+ }
+
//The state of each file is stored in a thread-safe dictionary
static readonly ConcurrentDictionary<string, NetworkOperation> NetworkState = new ConcurrentDictionary<string, NetworkOperation>();
- public string FilePath { get; private set; }
- public NetworkOperation Operation { get; private set; }
+
+
private NetworkGate(string path,NetworkOperation operation)
{
if (String.IsNullOrWhiteSpace(path))
throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("path must be rooted","path");
Contract.EndContractBlock();
Operation = operation;
- FilePath = path.ToLower();
+ FilePath = path.ToLower();
//Skip dummy operations (those with Operation == None)
if (Operation != NetworkOperation.None)
<AssemblyName>Pithos.Core</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+ <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PropertyGroup>
<AssemblyOriginatorKeyFile>pithos.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.Core.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+ <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>True</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>True</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>True</CodeContractsArithmeticObligations>
+ <CodeContractsEnumObligations>True</CodeContractsEnumObligations>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly />
+ <CodeContractsCustomRewriterClass />
+ <CodeContractsLibPaths />
+ <CodeContractsExtraRewriteOptions />
+ <CodeContractsExtraAnalysisOptions />
+ <CodeContractsBaseLineFile />
+ <CodeContractsCacheAnalysisResults>True</CodeContractsCacheAnalysisResults>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+ <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="Caliburn.Micro, Version=1.2.0.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
<HintPath>..\Libraries\Caliburn.Micro.dll</HintPath>
<ItemGroup>
<Compile Include="Agents\Agent.cs" />
<Compile Include="Agents\BlockUpdater.cs" />
- <Compile Include="Agents\CloudAction.cs" />
+ <Compile Include="Agents\CloudTransferAction.cs" />
<Compile Include="Agents\FileAgent.cs" />
<Compile Include="Agents\FileInfoExtensions.cs" />
<Compile Include="Agents\NetworkAgent.cs" />
<Compile Include="IStatusService.cs" />
<Compile Include="JobQueue.cs" />
<Compile Include="NetworkGate.cs" />
- <Compile Include="StatusKeeper.cs" />
+ <Compile Include="Agents\StatusAgent.cs" />
<Compile Include="IPithosWorkflow.cs" />
<Compile Include="IStatusKeeper.cs" />
<Compile Include="NativeMethods.cs" />
[Import]
public ICloudClient CloudClient { get; set; }
- [Import]
- public ICloudClient CloudListeningClient { get; set; }
-
public IStatusNotification StatusNotification { get; set; }
[Import]
CloudClient.AuthenticationUrl = this.AuthenticationUrl;
CloudClient.Authenticate(UserName, ApiKey);
- var pithosContainers = new[] { TrashContainer,PithosContainer};
+ //Create the two default containers if they are missing
+ var pithosContainers = new List<string>{ TrashContainer,PithosContainer};
foreach (var container in pithosContainers)
- {
- var info=CloudClient.GetContainerInfo(container);
+ {
+ var info=CloudClient.GetContainerInfo(this.UserName, container);
if (info == ContainerInfo.Empty)
{
- CloudClient.CreateContainer(container);
- info = CloudClient.GetContainerInfo(container);
+ CloudClient.CreateContainer(this.UserName, container);
+ info = CloudClient.GetContainerInfo(this.UserName, container);
}
_blockSize = info.BlockSize;
_blockHash = info.BlockHash;
}
- var allContainers= CloudClient.ListContainers();
+/*
+ //Create folders for any other containers
+ var allContainers = CloudClient.ListContainers();
+ pithosContainers.AddRange(new[]{"shared","others"});
+
var extraContainers = from container in allContainers
where !pithosContainers.Contains(container.Name.ToLower())
- select container;
+ select container;
+
+ foreach (var container in extraContainers)
+ {
+ var containerPath = Path.Combine(this.RootPath, container.Name);
+ if (!Directory.Exists(containerPath))
+ Directory.CreateDirectory(containerPath);
+ }
+*/
public override int GetHashCode(CloudAction obj)
{
var hash1 = (obj.LocalFile == null) ? int.MaxValue : obj.LocalFile.FullName.GetHashCode();
- var hash2 = (obj.CloudFile == null) ? int.MaxValue : (obj.CloudFile.Hash ?? obj.CloudFile.Name).GetHashCode();
+ var hash2 = (obj.CloudFile == null) ? int.MaxValue : (obj.CloudFile.Hash ?? obj.CloudFile.Name??"").GetHashCode();
var hash3 = obj.Action.GetHashCode();
return hash1 ^ hash2 & hash3;
}
if (String.IsNullOrWhiteSpace(path))
throw new ArgumentNullException("path", "The path parameter must not be emtpy");
- StatusKeeper.ClearFileStatus(path);
+ StatusKeeper.ClearFileStatus(path.ToLower());
}
using System;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading;
{
public static Task<T2> Then<T1, T2>(this Task<T1> first, Func<T1, Task<T2>> next)
{
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (next == null)
+ throw new ArgumentNullException("next");
+ Contract.EndContractBlock();
return Then(first, next, CancellationToken.None);
}
public static Task Then<T1>(this Task<T1> first, Func<T1, Task> next)
{
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (next == null)
+ throw new ArgumentNullException("next");
+ Contract.EndContractBlock();
return Then(first, next, CancellationToken.None);
}
public static Task<T2> Then<T1, T2>(this Task<T1> first, Func<T1, Task<T2>> next, CancellationToken cancellationToken)
{
- if (first == null) throw new ArgumentNullException("first");
- if (next == null) throw new ArgumentNullException("next");
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (next == null)
+ throw new ArgumentNullException("next");
+ Contract.EndContractBlock();
+ Contract.Assume(TaskScheduler.Current!=null);
var tcs = new TaskCompletionSource<T2>();
first.ContinueWith(delegate
public static Task Then<T1>(this Task<T1> first, Func<T1, Task> next, CancellationToken cancellationToken)
{
- if (first == null) throw new ArgumentNullException("first");
- if (next == null) throw new ArgumentNullException("next");
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (next == null)
+ throw new ArgumentNullException("next");
+ Contract.EndContractBlock();
+ Contract.Assume(TaskScheduler.Current != null);
var tcs = new TaskCompletionSource<object>();
first.ContinueWith(delegate
using System;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
{
public class ObjectInfo
{
+ private List<string> _knownContainers= new List<string>{"pithos","trash"};
public string Name { get; set; }
public string Hash { get; set; }
public long Bytes { get; set; }
get { return _version; }
set { _version = value; }
}
+
+ private string _allowedTo;
+ public string AllowedTo
+ {
+ get { return _allowedTo; }
+ set { _allowedTo = value; }
+ }
+
+ //Object permissions for Json deserialization, can be Read or Write
+ public string x_object_allowed_to
+ {
+ get { return _allowedTo; }
+ set { _allowedTo = value; }
+ }
+
+ //Object permissions for HEAD deserialization, can be Read or Write
+ public string X_Object_Allowed_To
+ {
+ get { return _allowedTo; }
+ set { _allowedTo = value; }
+ }
+
//Alias for VersionTimestamp, for Json deserialization purposes
- //The x_object_version_timestamp returned by GET on a container is
- //a float, probably due to a bug.
+ //The x_object_version_timestamp is a unix timestamp.
public double? X_Object_Version_Timestamp
{
get
public Stream Stream { get; set; }
+ public string Account { get; set; }
+
+ public string Container { get; set; }
+
private void ExtractKnownExtensions()
{
private string _modifiedBy;
private DateTime _epoch = new DateTime(1970, 1, 1);
+
+
+
+ public string RelativeUrlToFilePath(string currentAccount)
+ {
+ if (this.Name==null)
+ throw new InvalidOperationException("Name can't be null");
+ if (String.IsNullOrWhiteSpace(currentAccount))
+ throw new ArgumentNullException("currentAccount");
+ Contract.EndContractBlock();
+
+ if (this == Empty)
+ return String.Empty;
+
+ var unescaped = Uri.UnescapeDataString(this.Name);
+ var path = unescaped.Replace("/", "\\");
+ var pathParts=new Stack<string>();
+ pathParts.Push(path);
+ if (!String.IsNullOrWhiteSpace(Container) && !_knownContainers.Contains(Container))
+ pathParts.Push(Container);
+ if (!currentAccount.Equals(Account, StringComparison.InvariantCultureIgnoreCase))
+ {
+ if (Account != null)
+ {
+ pathParts.Push(Account);
+ pathParts.Push("others");
+ }
+ }
+ var finalPath=Path.Combine(pathParts.ToArray());
+ return finalPath;
+ }
+
}
}
\ No newline at end of file
<AssemblyName>Pithos.Interfaces</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+ <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.Interfaces.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+ <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>True</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>True</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>True</CodeContractsArithmeticObligations>
+ <CodeContractsEnumObligations>True</CodeContractsEnumObligations>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly />
+ <CodeContractsCustomRewriterClass />
+ <CodeContractsLibPaths />
+ <CodeContractsExtraRewriteOptions />
+ <CodeContractsExtraAnalysisOptions />
+ <CodeContractsBaseLineFile />
+ <CodeContractsCacheAnalysisResults>True</CodeContractsCacheAnalysisResults>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+ <CodeContractsAnalysisWarningLevel>2</CodeContractsAnalysisWarningLevel>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
// </copyright>
// -----------------------------------------------------------------------
+using System.Diagnostics.Contracts;
+
namespace Pithos.Interfaces
{
using System;
}
public PithosSettingsData(IPithosSettings other)
{
+ if (other == null)
+ throw new ArgumentNullException("other");
+ Contract.EndContractBlock();
+
PithosPath = other.PithosPath;
PithosSite = other.PithosSite;
IconsPath = other.IconsPath;
var hash = CalculateHash(filePath);
- client.PutObject("Shares", info.Name, filePath);
+ client.PutObject(null, "Shares", info.Name, filePath);
- var meta = client.GetObjectInfo("Shares", "DeveloperGuide.pdf");
+ var meta = client.GetObjectInfo(null, "Shares", "DeveloperGuide.pdf");
Assert.IsNotEmpty(meta.Hash);
AuthenticationUrl = @"https://pithos.dev.grnet.gr",
UsePithos = true
};
- client.Authenticate("890329@vho.grnet.gr", "24989dce4e0fcb072f8cb60c8922be19");
+ var account = "890329@vho.grnet.gr";
+ client.Authenticate(account, "24989dce4e0fcb072f8cb60c8922be19");
var fileName = @"vlc-1.1.11-win32.exe";
var treeHash=Signature.CalculateTreeHashAsync(Path.Combine(@"e:\pithos\" ,fileName), 4*1024*1024 , "sha256").Result;
- var result=client.PutHashMap("pithos", fileName, treeHash).Result;
+ var result = client.PutHashMap(account, "pithos", fileName, treeHash).Result;
Assert.AreEqual(0,result.Count);
}
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Pithos");
+ client.CreateContainer(null, "Pithos");
- client.CreateFolder("Pithos", "RootFolder");
+ client.CreateFolder(null, "Pithos", "RootFolder");
- Assert.IsTrue(client.ObjectExists("Pithos","RootFolder"));
- var info = client.GetObjectInfo("Pithos", "RootFolder");
+ Assert.IsTrue(client.ObjectExists(null, "Pithos","RootFolder"));
+ var info = client.GetObjectInfo(null, "Pithos", "RootFolder");
Assert.AreEqual(@"application/directory",info.Content_Type);
}
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Pithos");
+ client.CreateContainer(null, "Pithos");
- client.CreateFolder("Pithos", "RootFolder");
- client.CreateFolder("Pithos", "RootFolder/Folder1");
- client.PutObject("Pithos","RootFolder/Folder1/test.txt","test.txt");
+ client.CreateFolder(null, "Pithos", "RootFolder");
+ client.CreateFolder(null, "Pithos", "RootFolder/Folder1");
+ client.PutObject(null, "Pithos","RootFolder/Folder1/test.txt","test.txt");
- Assert.IsTrue(client.ObjectExists("Pithos", "RootFolder/Folder1"));
- var folderInfo = client.GetObjectInfo("Pithos", "RootFolder/Folder1");
+ Assert.IsTrue(client.ObjectExists(null, "Pithos", "RootFolder/Folder1"));
+ var folderInfo = client.GetObjectInfo(null, "Pithos", "RootFolder/Folder1");
Assert.AreEqual(@"application/directory",folderInfo.Content_Type);
- Assert.IsTrue(client.ObjectExists("Pithos", "RootFolder/Folder1/test.txt"));
- var fileInfo = client.GetObjectInfo("Pithos", "RootFolder/Folder1/test.txt");
+ Assert.IsTrue(client.ObjectExists(null, "Pithos", "RootFolder/Folder1/test.txt"));
+ var fileInfo = client.GetObjectInfo(null, "Pithos", "RootFolder/Folder1/test.txt");
Assert.AreEqual(@"application/octet-stream", fileInfo.Content_Type);
}
[Test]
public void TestDeleteSubFolders([Values(true, false)]bool usePithos)
{
- throw new NotImplementedException();
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Pithos");
+ client.CreateContainer(null, "Pithos");
- client.CreateFolder("Pithos", "RootFolder");
- client.CreateFolder("Pithos", "RootFolder/Folder1");
+ client.CreateFolder(null, "Pithos", "RootFolder");
+ client.CreateFolder(null, "Pithos", "RootFolder/Folder1");
var localInfo = new FileInfo("test.txt");
- client.PutObject("Pithos","RootFolder/Folder1/test.txt","test.txt");
+ client.PutObject(null, "Pithos","RootFolder/Folder1/test.txt","test.txt");
- client.DeleteObject("Pithos", "RootFolder/Folder1");
+ client.DeleteObject(null, "pithos", "RootFolder/Folder1","trash");
- Assert.IsTrue(client.ObjectExists("Pithos", "RootFolder/Folder1"));
- var folderInfo = client.GetObjectInfo("Pithos", "RootFolder/Folder1");
+ Assert.IsTrue(client.ObjectExists(null, "Pithos", "RootFolder/Folder1"));
+ var folderInfo = client.GetObjectInfo(null, "Pithos", "RootFolder/Folder1");
Assert.AreEqual(@"application/directory",folderInfo.Content_Type);
- Assert.IsTrue(client.ObjectExists("Pithos", "RootFolder/Folder1/test.txt"));
- var fileInfo = client.GetObjectInfo("Pithos", "RootFolder/Folder1/test.txt");
+ Assert.IsTrue(client.ObjectExists(null, "Pithos", "RootFolder/Folder1/test.txt"));
+ var fileInfo = client.GetObjectInfo(null, "Pithos", "RootFolder/Folder1/test.txt");
Assert.AreEqual(@"application/octet-stream", fileInfo.Content_Type);
}
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Pithos");
- client.CreateFolder("Pithos", "RootFolder3");
- client.CreateFolder("Pithos", "RootFolder3/Folder1");
+ client.CreateContainer(null, "Pithos");
+ client.CreateFolder(null, "Pithos", "RootFolder3");
+ client.CreateFolder(null, "Pithos", "RootFolder3/Folder1");
- client.PutObject("Pithos", "RootFolder3/test1.txt", "test.txt");
- client.PutObject("Pithos", "RootFolder3/test2.txt", "test.txt");
- client.PutObject("Pithos", "RootFolder3/Folder1/test2.txt", "test.txt");
+ client.PutObject(null, "Pithos", "RootFolder3/test1.txt", "test.txt");
+ client.PutObject(null, "Pithos", "RootFolder3/test2.txt", "test.txt");
+ client.PutObject(null, "Pithos", "RootFolder3/Folder1/test2.txt", "test.txt");
var files=client.ListObjects("Pithos", "RootFolder3");
Assert.AreEqual(3,files.Count,"Unexpected number of root items");
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Pithos");
+ client.CreateContainer(null, "Pithos");
- client.CreateFolder("Pithos", "RootFolder2/Folder1");
+ client.CreateFolder(null, "Pithos", "RootFolder2/Folder1");
- Assert.IsTrue(client.ObjectExists("Pithos", "RootFolder2/Folder1"));
- var folderInfo = client.GetObjectInfo("Pithos", "RootFolder2/Folder1");
+ Assert.IsTrue(client.ObjectExists(null, "Pithos", "RootFolder2/Folder1"));
+ var folderInfo = client.GetObjectInfo(null, "Pithos", "RootFolder2/Folder1");
Assert.AreEqual(@"application/directory",folderInfo.Content_Type);
- Assert.IsTrue(client.ObjectExists("Pithos", "RootFolder2"));
- folderInfo = client.GetObjectInfo("Pithos", "RootFolder2");
+ Assert.IsTrue(client.ObjectExists(null, "Pithos", "RootFolder2"));
+ folderInfo = client.GetObjectInfo(null, "Pithos", "RootFolder2");
Assert.AreEqual(@"application/directory", folderInfo.Content_Type);
- Assert.IsTrue(client.ObjectExists("Pithos", "RootFolder2/Folder1/test.txt"));
- var fileInfo = client.GetObjectInfo("Pithos", "RootFolder2/Folder1/test.txt");
+ Assert.IsTrue(client.ObjectExists(null, "Pithos", "RootFolder2/Folder1/test.txt"));
+ var fileInfo = client.GetObjectInfo(null, "Pithos", "RootFolder2/Folder1/test.txt");
Assert.AreEqual(@"application/octet-stream", fileInfo.Content_Type);
}
{
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("PITHOS");
+ client.CreateContainer(null, "PITHOS");
IList<ContainerInfo> containers=client.ListContainers();
Assert.IsTrue(containers.Count()>1);
{
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("PITHOS");
- client.PutObject("PITHOS","devguide.pdf","devguide.pdf");
+ client.CreateContainer(null, "PITHOS");
+ client.PutObject(null, "PITHOS","devguide.pdf","devguide.pdf");
- IList<ObjectInfo> objects=client.ListObjects("PITHOS");
+ IList<ObjectInfo> objects=client.ListObjects(null, "PITHOS");
Assert.IsTrue(objects.Count()>=1);
}
{
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("TestContainer");
- bool dnzExists=client.ContainerExists("TestContainer");
+ client.CreateContainer(null, "TestContainer");
+ bool dnzExists=client.ContainerExists(null, "TestContainer");
- bool mooExists = client.ContainerExists("Moo");
+ bool mooExists = client.ContainerExists(null, "Moo");
Assert.IsTrue(dnzExists);
Assert.IsFalse(mooExists);
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("PITHOS");
- client.CreateContainer("DotNetZone");
+ client.CreateContainer(null, "PITHOS");
+ client.CreateContainer(null, "DotNetZone");
- var dnzInfo =client.GetContainerInfo("DotNetZone");
+ var dnzInfo =client.GetContainerInfo(null, "DotNetZone");
Assert.AreNotEqual(ContainerInfo.Empty, dnzInfo,"Expected DotNetZone container not found");
- var pithosInfo = client.GetContainerInfo("PITHOS");
+ var pithosInfo = client.GetContainerInfo(null, "PITHOS");
Assert.AreNotEqual(ContainerInfo.Empty, pithosInfo,"Expected PITHOS container not found");
- var mooInfo = client.GetContainerInfo("moo");
+ var mooInfo = client.GetContainerInfo(null, "moo");
Assert.AreEqual(ContainerInfo.Empty, mooInfo);
}
ICloudClient client = new CloudFilesClient{UsePithos=usePithos};
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Shares2");
- Assert.IsTrue(client.ContainerExists("Shares2"));
- client.DeleteContainer("Shares2");
+ client.CreateContainer(null, "Shares2");
+ Assert.IsTrue(client.ContainerExists(null, "Shares2"));
+ client.DeleteContainer(null, "Shares2");
- client.CreateContainer("Shares");
- Assert.IsTrue(client.ContainerExists("Shares"));
- client.CreateContainer("DotNetZone");
- Assert.IsTrue(client.ContainerExists("DotNetZone"));
+ client.CreateContainer(null, "Shares");
+ Assert.IsTrue(client.ContainerExists(null, "Shares"));
+ client.CreateContainer(null, "DotNetZone");
+ Assert.IsTrue(client.ContainerExists(null, "DotNetZone"));
});
}
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
//Prepare test file
- client.CreateContainer("Shares");
+ client.CreateContainer(null, "Shares");
string testFileName = "test.txt";
var info = new FileInfo(testFileName);
- client.PutObject("Shares",testFileName,testFileName);
+ client.PutObject(null, "Shares",testFileName,testFileName);
string downloadFile = "test2.txt";
- client.GetObject("Shares", testFileName, downloadFile)
+ client.GetObject(null, "Shares", testFileName, downloadFile)
.Wait();
Assert.IsTrue(File.Exists(downloadFile));
ICloudClient client = new CloudFilesClient {UsePithos = usePithos};
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Shares");
- Assert.IsTrue(client.ContainerExists("Shares"));
+ client.CreateContainer(null, "Shares");
+ Assert.IsTrue(client.ContainerExists(null, "Shares"));
var filePath = "devguide.pdf";
FileInfo info = new FileInfo(filePath);
- client.PutObject("Shares", info.Name, filePath);
+ client.PutObject(null, "Shares", info.Name, filePath);
});
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Shares");
- Assert.IsTrue(client.ContainerExists("Shares"));
+ client.CreateContainer(null, "Shares");
+ Assert.IsTrue(client.ContainerExists(null, "Shares"));
var filePath = "devguide.pdf";
FileInfo info = new FileInfo(filePath);
- client.PutObject("Shares", info.Name, filePath);
+ client.PutObject(null, "Shares", info.Name, filePath);
- var meta=client.GetObjectInfo("Shares", filePath);
+ var meta=client.GetObjectInfo(null, "Shares", filePath);
Assert.IsNotEmpty(meta.Hash);
Assert.AreEqual(meta.Name,filePath);
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Shares");
- Assert.IsTrue(client.ContainerExists("Shares"),"Container Exists");
+ client.CreateContainer(null, "Shares");
+ Assert.IsTrue(client.ContainerExists(null, "Shares"),"Container Exists");
var filePath = "devguide.pdf";
FileInfo info=new FileInfo(filePath);
- client.PutObject("Shares",info.Name, filePath);
+ client.PutObject(null, "Shares",info.Name, filePath);
- Assert.IsTrue(client.ObjectExists("Shares",info.Name),"File Created");
+ Assert.IsTrue(client.ObjectExists(null, "Shares",info.Name),"File Created");
- client.DeleteObject("Shares/devguide.pdf",info.Name);
+ client.DeleteObject(null, "Shares/devguide.pdf",info.Name,"trash");
});
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Shares");
- Assert.IsTrue(client.ContainerExists("Shares"),"Container Exists");
+ client.CreateContainer(null, "Shares");
+ Assert.IsTrue(client.ContainerExists(null, "Shares"),"Container Exists");
var filePath = "devguide.pdf";
FileInfo info=new FileInfo(filePath);
- client.PutObject("Shares",info.Name, filePath );
+ client.PutObject(null, "Shares",info.Name, filePath );
- Assert.IsTrue(client.ObjectExists("Shares",info.Name),"File Created");
+ Assert.IsTrue(client.ObjectExists(null, "Shares",info.Name),"File Created");
- client.DeleteObject("Shares",info.Name);
- Assert.IsFalse(client.ObjectExists("Shares", info.Name),"Container Deleted");
+ client.DeleteObject(null, "Shares",info.Name,"trash");
+ Assert.IsFalse(client.ObjectExists(null, "Shares", info.Name),"Container Deleted");
- client.DeleteObject("Moo",info.Name);
- Assert.IsFalse(client.ObjectExists("Moo", info.Name),"Container Deleted");
+ client.DeleteObject(null, "Moo",info.Name,"trash");
+ Assert.IsFalse(client.ObjectExists(null, "Moo", info.Name),"Container Deleted");
});
ICloudClient client = new CloudFilesClient { UsePithos = usePithos };
client.Authenticate(_userName, _apiKey);
- client.CreateContainer("Shares");
- Assert.IsTrue(client.ContainerExists("Shares"),"Container Exists");
+ client.CreateContainer(null, "Shares");
+ Assert.IsTrue(client.ContainerExists(null, "Shares"),"Container Exists");
var filePath = "devguide.pdf";
FileInfo info=new FileInfo(filePath);
- client.PutObject("Shares",info.Name, filePath);
+ client.PutObject(null, "Shares",info.Name, filePath);
- Assert.IsTrue(client.ObjectExists("Shares",info.Name),"File Created");
+ Assert.IsTrue(client.ObjectExists(null, "Shares",info.Name),"File Created");
- client.MoveObject("Shares",info.Name,"Shares","smoo.pdf");
- Assert.IsFalse(client.ObjectExists("Shares", info.Name),"Original File Deleted");
- Assert.IsTrue(client.ObjectExists("Shares", "smoo.pdf"), "Target File Created");
+ client.MoveObject(null, "Shares",info.Name,"Shares","smoo.pdf");
+ Assert.IsFalse(client.ObjectExists(null, "Shares", info.Name),"Original File Deleted");
+ Assert.IsTrue(client.ObjectExists(null, "Shares", "smoo.pdf"), "Target File Created");
});
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Pithos.Interfaces;
+
+namespace Pithos.Network.Test
+{
+ [TestFixture]
+ class ObjectInfoTest
+ {
+ [Test]
+ public void RelativeUrlToFilePath()
+ {
+
+ var info1 = new ObjectInfo {Account = "pkanavos", Container = "pithos", Name = "somefolder/file1.txt"};
+ var path1=info1.RelativeUrlToFilePath("PKANAVOS");
+ Assert.AreEqual(@"somefolder\file1.txt",path1);
+ var path2 = info1.RelativeUrlToFilePath("user1");
+ Assert.AreEqual(@"others\pkanavos\somefolder\file1.txt", path2);
+ var info3 = new ObjectInfo { Account = "pkanavos", Name = "somefolder/file1.txt" };
+ var path3 = info1.RelativeUrlToFilePath("PKANAVOS");
+ Assert.AreEqual(@"somefolder\file1.txt", path1);
+
+ }
+ }
+}
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.Network.Test.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b9a188c8922137c6, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<Compile Include="CloudFilesClientTest.cs" />
<Compile Include="FolderTests.cs" />
<Compile Include="NetworkOpsTest.cs" />
+ <Compile Include="ObjectInfoTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SignatureTest.cs" />
</ItemGroup>
CloudFilesClient client = new CloudFilesClient();
client.AuthenticationUrl = @"https://pithos.dev.grnet.gr";
client.UsePithos = true;
- client.Authenticate("890329@vho.grnet.gr", "24989dce4e0fcb072f8cb60c8922be19");
+ var account = "890329@vho.grnet.gr";
+ client.Authenticate(account, "24989dce4e0fcb072f8cb60c8922be19");
var fileName = @"vlc-1.1.11-win32.exe";
var localHash= Signature.CalculateTreeHashAsync(Path.Combine(@"e:\pithos\", fileName), 4 * 1024 * 1024, "sha256").Result;
- var upHash= client.GetHashMap("pithos", fileName).Result;
+ var upHash= client.GetHashMap(fileName, account, "pithos").Result;
Assert.AreEqual(upHash.TopHash, localHash.TopHash);
//RestClient provides a REST-friendly interface over the standard WebClient.
private RestClient _baseClient;
- //Some operations can specify a Timeout. The default value of all timeouts is 10 seconds
- private readonly TimeSpan _shortTimeout = TimeSpan.FromSeconds(10);
-
- //Some operations can be retried before failing. The default number of retries is 5
- private readonly int _retries = 5;
-
//During authentication the client provides a UserName
public string UserName { get; set; }
//The client also receives a StorageUrl after authentication. All subsequent operations must
//use this url
public Uri StorageUrl { get; set; }
-
+
+ protected Uri RootAddressUri { get; set; }
+
public Uri Proxy { get; set; }
public double DownloadPercentLimit { get; set; }
//
public void Authenticate(string userName,string apiKey)
{
- Trace.TraceInformation("[AUTHENTICATE] Start for {0}", userName);
if (String.IsNullOrWhiteSpace(userName))
throw new ArgumentNullException("userName", "The userName property can't be empty");
if (String.IsNullOrWhiteSpace(apiKey))
throw new ArgumentNullException("apiKey", "The apiKey property can't be empty");
+ Contract.Ensures(_baseClient != null);
+ Contract.EndContractBlock();
+
+ Trace.TraceInformation("[AUTHENTICATE] Start for {0}", userName);
if (_authenticated)
return;
if (Proxy != null)
authClient.Proxy = new WebProxy(Proxy);
+ Contract.Assume(authClient.Headers!=null);
+
authClient.Headers.Add("X-Auth-User", UserName);
authClient.Headers.Add("X-Auth-Key", ApiKey);
throw new InvalidOperationException("Failed to obtain storage url");
StorageUrl = new Uri(storageUrl);
+ //Get the root address (StorageUrl without the account)
+ var usernameIndex=storageUrl.LastIndexOf(UserName);
+ var rootUrl = storageUrl.Substring(0, usernameIndex);
+ RootAddressUri = new Uri(rootUrl);
+
var token = authClient.GetHeaderValue("X-Auth-Token");
if (String.IsNullOrWhiteSpace(token))
throw new InvalidOperationException("Failed to obtain token url");
if (Proxy!=null)
_baseClient.Proxy = new WebProxy(Proxy);
+
+
+ Contract.Assume(_baseClient.Headers!=null);
_baseClient.Headers.Add("X-Auth-Token", Token);
Trace.TraceInformation("[AUTHENTICATE] End for {0}", userName);
}
- public IList<ContainerInfo> ListContainers()
+
+ public IList<ContainerInfo> ListContainers(string account)
{
+
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Parameters.Clear();
client.Parameters.Add("format", "json");
var content = client.DownloadStringWithRetry("", 3);
}
+ private string GetAccountUrl(string account)
+ {
+ return new Uri(this.RootAddressUri, new Uri(account,UriKind.Relative)).AbsoluteUri;
+ }
+
+ public IList<ShareAccountInfo> ListSharingAccounts(DateTime? since=null)
+ {
+ Trace.TraceInformation("[START] ListSharingAccounts");
+
+ using (var client = new RestClient(_baseClient))
+ {
+ client.Parameters.Clear();
+ client.Parameters.Add("format", "json");
+ client.IfModifiedSince = since;
+
+ //Extract the username from the base address
+ client.BaseAddress = RootAddressUri.AbsoluteUri;
+
+ var content = client.DownloadStringWithRetry(@"", 3);
+
+ client.AssertStatusOK("ListSharingAccounts failed");
+
+ //If the result is empty, return an empty list,
+ var infos = String.IsNullOrWhiteSpace(content)
+ ? new List<ShareAccountInfo>()
+ //Otherwise deserialize the account list into a list of ShareAccountInfos
+ : JsonConvert.DeserializeObject<IList<ShareAccountInfo>>(content);
+
+ Trace.TraceInformation("[END] ListSharingAccounts");
+ return infos;
+ }
+ }
+
//Request listing of all objects in a container modified since a specific time.
//If the *since* value is missing, return all objects
- public IList<ObjectInfo> ListObjects(string container, DateTime? since = null)
+ public IList<ObjectInfo> ListSharedObjects(DateTime? since = null)
+ {
+
+ Trace.TraceInformation("[START] ListSharedObjects");
+
+ var objects=new List<ObjectInfo>();
+ var accounts=ListSharingAccounts(since);
+ foreach (var account in accounts)
+ {
+ var containers=ListContainers(account.name);
+ foreach (var container in containers)
+ {
+ var containerObjects=ListObjects(account.name, container.Name, account.last_modified);
+ objects.AddRange(containerObjects);
+ }
+ }
+ return objects;
+ }
+
+ public void ShareObject(string account, string container, string objectName, string shareTo, bool read, bool write)
+ {
+ if (String.IsNullOrWhiteSpace(Token))
+ throw new InvalidOperationException("The Token is not set");
+ if (StorageUrl==null)
+ throw new InvalidOperationException("The StorageUrl is not set");
+ if (String.IsNullOrWhiteSpace(container))
+ throw new ArgumentNullException("container");
+ if (String.IsNullOrWhiteSpace(objectName))
+ throw new ArgumentNullException("objectName");
+ if (String.IsNullOrWhiteSpace(account))
+ throw new ArgumentNullException("account");
+ if (String.IsNullOrWhiteSpace(shareTo))
+ throw new ArgumentNullException("shareTo");
+ Contract.EndContractBlock();
+
+ using (var client = new RestClient(_baseClient))
+ {
+
+ client.BaseAddress = GetAccountUrl(account);
+
+ client.Parameters.Clear();
+ client.Parameters.Add("format", "json");
+
+ string permission = "";
+ if (write)
+ permission = String.Format("write={0}", shareTo);
+ else if (read)
+ permission=String.Format("read={0}", shareTo);
+ client.Headers.Add("X-Object-Sharing",permission);
+
+ var content = client.DownloadStringWithRetry(container, 3);
+
+ client.AssertStatusOK("ShareObject failed");
+
+ //If the result is empty, return an empty list,
+ var infos = String.IsNullOrWhiteSpace(content)
+ ? new List<ObjectInfo>()
+ //Otherwise deserialize the object list into a list of ObjectInfos
+ : JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
+
+ Trace.TraceInformation("[END] ListObjects");
+ }
+
+
+ }
+
+
+ public IList<ObjectInfo> ListObjects(string account, string container, DateTime? since = null)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Parameters.Clear();
client.Parameters.Add("format", "json");
client.IfModifiedSince = since;
//Otherwise deserialize the object list into a list of ObjectInfos
: JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
+ foreach (var info in infos)
+ {
+ info.Container = container;
+ info.Account = account;
+ }
Trace.TraceInformation("[END] ListObjects");
return infos;
}
- public IList<ObjectInfo> ListObjects(string container, string folder, DateTime? since = null)
+ public IList<ObjectInfo> ListObjects(string account, string container, string folder, DateTime? since = null)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Parameters.Clear();
client.Parameters.Add("format", "json");
client.Parameters.Add("path", folder);
}
- public bool ContainerExists(string container)
+ public bool ContainerExists(string account, string container)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
+ Contract.EndContractBlock();
+
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Parameters.Clear();
client.Head(container, 3);
}
}
- public bool ObjectExists(string container,string objectName)
+ public bool ObjectExists(string account, string container, string objectName)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
if (String.IsNullOrWhiteSpace(objectName))
throw new ArgumentNullException("objectName", "The objectName property can't be empty");
+ Contract.EndContractBlock();
+
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Parameters.Clear();
client.Head(container + "/" + objectName, 3);
}
- public ObjectInfo GetObjectInfo(string container, string objectName)
+ public ObjectInfo GetObjectInfo(string account, string container, string objectName)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
if (String.IsNullOrWhiteSpace(objectName))
throw new ArgumentNullException("objectName", "The objectName property can't be empty");
+ Contract.EndContractBlock();
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
try
{
client.Parameters.Clear();
}
- public void CreateFolder(string container, string folder)
+ public void CreateFolder(string account, string container, string folder)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
if (String.IsNullOrWhiteSpace(folder))
throw new ArgumentNullException("folder", "The folder property can't be empty");
+ Contract.EndContractBlock();
var folderUrl=String.Format("{0}/{1}",container,folder);
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Parameters.Clear();
client.Headers.Add("Content-Type", @"application/directory");
client.Headers.Add("Content-Length", "0");
}
}
- public ContainerInfo GetContainerInfo(string container)
+ public ContainerInfo GetContainerInfo(string account, string container)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
+ Contract.EndContractBlock();
+
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Head(container);
switch (client.StatusCode)
{
}
}
- public void CreateContainer(string container)
- {
+ public void CreateContainer(string account, string container)
+ {
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
+ Contract.EndContractBlock();
+
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.PutWithRetry(container, 3);
var expectedCodes = new[] {HttpStatusCode.Created, HttpStatusCode.Accepted, HttpStatusCode.OK};
if (!expectedCodes.Contains(client.StatusCode))
}
}
- public void DeleteContainer(string container)
+ public void DeleteContainer(string account, string container)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
+ Contract.EndContractBlock();
+
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.DeleteWithRetry(container, 3);
var expectedCodes = new[] {HttpStatusCode.NotFound, HttpStatusCode.NoContent};
if (!expectedCodes.Contains(client.StatusCode))
/// <summary>
///
/// </summary>
+ /// <param name="account"></param>
/// <param name="container"></param>
/// <param name="objectName"></param>
/// <param name="fileName"></param>
/// <remarks>This method should have no timeout or a very long one</remarks>
//Asynchronously download the object specified by *objectName* in a specific *container* to
// a local file
- public Task GetObject(string container, string objectName, string fileName)
+ public Task GetObject(string account, string container, string objectName, string fileName)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
try
{
- //The container and objectName are relative names. They are joined with the client's
- //BaseAddress to create the object's absolute address
- var builder = GetAddressBuilder(container, objectName);
- var uri = builder.Uri;
//WebClient, and by extension RestClient, are not thread-safe. Create a new RestClient
//object to avoid concurrency errors.
//
//Download operations take a long time therefore they have no timeout.
var client = new RestClient(_baseClient) { Timeout = 0 };
-
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
+ //The container and objectName are relative names. They are joined with the client's
+ //BaseAddress to create the object's absolute address
+ var builder = client.GetAddressBuilder(container, objectName);
+ var uri = builder.Uri;
+
//Download progress is reported to the Trace log
Trace.TraceInformation("[GET] START {0}", objectName);
client.DownloadProgressChanged += (sender, args) =>
}
- public Task<IList<string>> PutHashMap(string container, string objectName, TreeHash hash)
+ public Task<IList<string>> PutHashMap(string account, string container, string objectName, TreeHash hash)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
if (StorageUrl == null)
throw new InvalidOperationException("Invalid Storage Url");
Contract.EndContractBlock();
+
+
+ //Don't use a timeout because putting the hashmap may be a long process
+ var client = new RestClient(_baseClient) { Timeout = 0 };
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
//The container and objectName are relative names. They are joined with the client's
//BaseAddress to create the object's absolute address
- var builder = GetAddressBuilder(container, objectName);
+ var builder = client.GetAddressBuilder(container, objectName);
builder.Query = "format=json&hashmap";
var uri = builder.Uri;
- //Don't use a timeout because putting the hashmap may be a long process
- var client = new RestClient(_baseClient) { Timeout = 0 };
//Send the tree hash as Json to the server
client.Headers[HttpRequestHeader.ContentType] = "application/octet-stream";
}
- public Task<byte[]> GetBlock(string container, Uri relativeUrl, long start, long? end=null)
+ public Task<byte[]> GetBlock(string account, string container, Uri relativeUrl, long start, long? end)
{
if (String.IsNullOrWhiteSpace(Token))
throw new InvalidOperationException("Invalid Token");
throw new ArgumentOutOfRangeException("start");
Contract.EndContractBlock();
- var builder = GetAddressBuilder(container, relativeUrl.ToString());
-
- var uri = builder.Uri;
//Don't use a timeout because putting the hashmap may be a long process
var client = new RestClient(_baseClient) {Timeout = 0, RangeFrom = start, RangeTo = end};
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
+ var builder = client.GetAddressBuilder(container, relativeUrl.ToString());
+ var uri = builder.Uri;
+
return client.DownloadDataTask(uri)
.ContinueWith(t=>
{
}
- public Task PostBlock(string container,byte[] block,int offset,int count)
+ public Task PostBlock(string account, string container, byte[] block, int offset, int count)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
throw new InvalidOperationException("Invalid Storage Url");
Contract.EndContractBlock();
- var builder = GetAddressBuilder(container, "");
+
+ //Don't use a timeout because putting the hashmap may be a long process
+ var client = new RestClient(_baseClient) { Timeout = 0 };
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
+ var builder = client.GetAddressBuilder(container, "");
//We are doing an update
builder.Query = "update";
var uri = builder.Uri;
-
- //Don't use a timeout because putting the hashmap may be a long process
- var client = new RestClient(_baseClient) { Timeout = 0 };
+
client.Headers[HttpRequestHeader.ContentType] = "application/octet-stream";
Trace.TraceInformation("[BLOCK POST] START");
}
- public Task<TreeHash> GetHashMap(string container, string objectName)
+ public Task<TreeHash> GetHashMap(string account, string container, string objectName)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
try
{
- //The container and objectName are relative names. They are joined with the client's
- //BaseAddress to create the object's absolute address
- var builder = GetAddressBuilder(container, objectName);
- builder.Query="format=json&hashmap";
- var uri = builder.Uri;
//WebClient, and by extension RestClient, are not thread-safe. Create a new RestClient
//object to avoid concurrency errors.
//
//Download operations take a long time therefore they have no timeout.
//TODO: Do we really? this is a hashmap operation, not a download
var client = new RestClient(_baseClient) { Timeout = 0 };
-
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
+ //The container and objectName are relative names. They are joined with the client's
+ //BaseAddress to create the object's absolute address
+ var builder = client.GetAddressBuilder(container, objectName);
+ builder.Query = "format=json&hashmap";
+ var uri = builder.Uri;
+
//Start downloading the object asynchronously
var downloadTask = client.DownloadStringTask(uri);
}
- private UriBuilder GetAddressBuilder(string container, string objectName)
- {
- var builder = new UriBuilder(String.Join("/", _baseClient.BaseAddress, container, objectName));
- return builder;
- }
-
/// <summary>
///
/// </summary>
+ /// <param name="account"></param>
/// <param name="container"></param>
/// <param name="objectName"></param>
/// <param name="fileName"></param>
/// <param name="hash">Optional hash value for the file. If no hash is provided, the method calculates a new hash</param>
/// <remarks>>This method should have no timeout or a very long one</remarks>
- public Task PutObject(string container, string objectName, string fileName, string hash = null)
+ public Task PutObject(string account, string container, string objectName, string fileName, string hash = null)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
throw new ArgumentNullException("fileName", "The fileName property can't be empty");
if (!File.Exists(fileName))
throw new FileNotFoundException("The file does not exist",fileName);
-
+ Contract.EndContractBlock();
try
{
- var builder= GetAddressBuilder(container,objectName);
+
+ var client = new RestClient(_baseClient){Timeout=0};
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
+ var builder = client.GetAddressBuilder(container, objectName);
var uri = builder.Uri;
- var client = new RestClient(_baseClient){Timeout=0};
string etag = hash ?? CalculateHash(fileName);
client.Headers.Add("Content-Type", "application/octet-stream");
return hash;
}
- public void DeleteObject(string container, string objectName)
+ /* public void DeleteObject(string container, string objectName,string account)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container", "The container property can't be empty");
if (String.IsNullOrWhiteSpace(objectName))
throw new ArgumentNullException("objectName", "The objectName property can't be empty");
+ Contract.EndContractBlock();
+
using (var client = new RestClient(_baseClient))
{
-
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+ );
client.DeleteWithRetry(container + "/" + objectName, 3);
var expectedCodes = new[] {HttpStatusCode.NotFound, HttpStatusCode.NoContent};
throw CreateWebException("DeleteObject", client.StatusCode);
}
- }
+ }*/
- public void MoveObject(string sourceContainer, string oldObjectName, string targetContainer,string newObjectName)
+ public void MoveObject(string account, string sourceContainer, string oldObjectName, string targetContainer, string newObjectName)
{
if (String.IsNullOrWhiteSpace(sourceContainer))
throw new ArgumentNullException("sourceContainer", "The container property can't be empty");
throw new ArgumentNullException("targetContainer", "The container property can't be empty");
if (String.IsNullOrWhiteSpace(newObjectName))
throw new ArgumentNullException("newObjectName", "The newObjectName property can't be empty");
+ Contract.EndContractBlock();
var targetUrl = targetContainer + "/" + newObjectName;
var sourceUrl = String.Format("/{0}/{1}", sourceContainer, oldObjectName);
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Headers.Add("X-Move-From", sourceUrl);
client.PutWithRetry(targetUrl, 3);
}
}
- public void DeleteObject(string sourceContainer, string objectName, string targetContainer)
+ public void DeleteObject(string account, string sourceContainer, string objectName, string targetContainer)
{
if (String.IsNullOrWhiteSpace(sourceContainer))
throw new ArgumentNullException("sourceContainer", "The container property can't be empty");
throw new ArgumentNullException("objectName", "The oldObjectName property can't be empty");
if (String.IsNullOrWhiteSpace(targetContainer))
throw new ArgumentNullException("targetContainer", "The container property can't be empty");
+ Contract.EndContractBlock();
var targetUrl = targetContainer + "/" + objectName;
var sourceUrl = String.Format("/{0}/{1}", sourceContainer, objectName);
using (var client = new RestClient(_baseClient))
{
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
client.Headers.Add("X-Move-From", sourceUrl);
client.PutWithRetry(targetUrl, 3);
}
+
+ public class ShareAccountInfo
+ {
+ public DateTime? last_modified { get; set; }
+ public string name { get; set; }
+ }
}
--- /dev/null
+namespace Pithos.Network
+{
+ public class ContainerInfo
+ {
+ public string Name { get; set; }
+ public long Count { get; set; }
+ public long Bytes { get; set; }
+ public string BlockHash { get; set; }
+ public int BlockSize { get; set; }
+
+ public static ContainerInfo Empty=new ContainerInfo();
+ }
+}
\ No newline at end of file
double UploadPercentLimit { get; set; }
string AuthenticationUrl { get; set; }
-
- IList<ContainerInfo> ListContainers();
- IList<ObjectInfo> ListObjects(string container,DateTime? since=null);
- IList<ObjectInfo> ListObjects(string container, string folder, DateTime? since = null);
- bool ContainerExists(string container);
- ContainerInfo GetContainerInfo(string container);
- void CreateContainer(string container);
- void DeleteContainer(string container);
+ #region Container operations
- Task GetObject(string container, string objectName, string fileName);
- Task PutObject(string container, string objectName, string fileName, string hash = null);
- void DeleteObject(string container, string objectName, string trashContainer);
- void DeleteObject(string container, string objectName);
- void MoveObject(string sourceContainer, string oldObjectName, string targetContainer,string newObjectName);
- bool ObjectExists(string container,string objectName);
- ObjectInfo GetObjectInfo(string container, string objectName);
- void CreateFolder(string container, string folder);
-
-
- Task<TreeHash> GetHashMap(string container, string objectName);
- Task<IList<string>> PutHashMap(string container, string objectName, TreeHash hash);
- Task PostBlock(string container,byte[] block,int offset,int count);
- Task<byte[]> GetBlock(string container, Uri relativeUrl, long start, long? end);
+ IList<ContainerInfo> ListContainers(string account=null);
+ IList<ObjectInfo> ListObjects(string account, string container, DateTime? since = null);
+ IList<ObjectInfo> ListObjects(string account, string container, string folder, DateTime? since = null);
+ bool ContainerExists(string account, string container);
+ ContainerInfo GetContainerInfo(string account, string container);
+ void CreateContainer(string account, string container);
+ void DeleteContainer(string account, string container);
+ #endregion
+
+ #region Object operations
+ Task GetObject(string account, string container, string objectName, string fileName);
+ Task PutObject(string account, string container, string objectName, string fileName, string hash = null);
+ void DeleteObject(string account, string container, string objectName, string trashContainer);
+ //void DeleteObject(string container, string objectName, string account = null);
+ void MoveObject(string account, string sourceContainer, string oldObjectName, string targetContainer, string newObjectName);
+ bool ObjectExists(string account, string container, string objectName);
+ ObjectInfo GetObjectInfo(string account, string container, string objectName);
+ void CreateFolder(string account, string container, string folder);
+ #endregion
+
+ #region Hashmap operations
+ Task<TreeHash> GetHashMap(string account, string container, string objectName);
+ Task<IList<string>> PutHashMap(string account, string container, string objectName, TreeHash hash);
+ Task PostBlock(string account, string container, byte[] block, int offset, int count);
+ Task<byte[]> GetBlock(string account, string container, Uri relativeUrl, long start, long? end);
+ #endregion
+
+ #region Sharing operations
+ IList<ObjectInfo> ListSharedObjects(DateTime? since);
+ void ShareObject(string account, string container, string objectName, string shareTo, bool read, bool write);
+
+ #endregion
}
}
- public IList<ContainerInfo> ListContainers()
+ public IList<ContainerInfo> ListContainers(string account=null)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
return default(IList<ContainerInfo>);
}
- public IList<ObjectInfo> ListObjects(string container, DateTime? since = null)
+ public IList<ObjectInfo> ListSharedObjects(DateTime? since)
+ {
+ Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+ Contract.Requires(StorageUrl != null);
+
+ return default(IList<ObjectInfo>);
+ }
+
+ public void ShareObject(string account, string container, string objectName, string shareTo, bool read, bool write)
+ {
+ Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+ Contract.Requires(StorageUrl != null);
+ Contract.Requires(!String.IsNullOrWhiteSpace(container));
+ Contract.Requires(!String.IsNullOrWhiteSpace(objectName));
+ Contract.Requires(!String.IsNullOrWhiteSpace(account));
+ Contract.Requires(!String.IsNullOrWhiteSpace(shareTo));
+
+ }
+
+
+ public IList<ObjectInfo> ListObjects(string account, string container, DateTime? since = null)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl != null);
return default(IList<ObjectInfo>);
}
- public IList<ObjectInfo> ListObjects(string container, string folder, DateTime? since = null)
+ public IList<ObjectInfo> ListObjects(string account, string container, string folder, DateTime? since = null)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl != null);
return default(IList<ObjectInfo>);
}
- public bool ContainerExists(string container)
+ public bool ContainerExists(string account, string container)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
return default(bool);
}
- public ContainerInfo GetContainerInfo(string container)
+ public ContainerInfo GetContainerInfo(string account, string container)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
return default(ContainerInfo);
}
- public void CreateContainer(string container)
+ public void CreateContainer(string account, string container)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
Contract.Requires(!String.IsNullOrWhiteSpace(container));
}
- public void DeleteContainer(string container)
+ public void DeleteContainer(string account, string container)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
Contract.Requires(!String.IsNullOrWhiteSpace(container));
}
- public Task GetObject(string container, string objectName, string fileName)
+ public Task GetObject(string account, string container, string objectName, string fileName)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
return default(Task);
}
- public Task PutObject(string container, string objectName, string fileName, string hash = null)
+ public Task PutObject(string account, string container, string objectName, string fileName, string hash = null)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
return default(Task);
}
- public void DeleteObject(string container, string objectName, string trashContainer)
+ public void DeleteObject(string account, string container, string objectName, string trashContainer)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
Contract.Requires(!String.IsNullOrWhiteSpace(trashContainer));
}
- public void DeleteObject(string container, string objectName)
+ public void DeleteObject(string container, string objectName, string account = null)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
Contract.Requires(!String.IsNullOrWhiteSpace(objectName));
}
- public void MoveObject(string sourceContainer, string oldObjectName, string targetContainer,string newObjectName)
+ public void MoveObject(string account, string sourceContainer, string oldObjectName, string targetContainer, string newObjectName)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
Contract.Requires(!String.IsNullOrWhiteSpace(newObjectName));
}
- public bool ObjectExists(string container,string objectName)
+ public bool ObjectExists(string account, string container, string objectName)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
return default(bool);
}
- public ObjectInfo GetObjectInfo(string container,string objectName)
+ public ObjectInfo GetObjectInfo(string account, string container, string objectName)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl!=null);
return default(ObjectInfo);
}
- public void CreateFolder(string container, string folder)
+ public void CreateFolder(string account, string container, string folder)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl != null);
Contract.Requires(!String.IsNullOrWhiteSpace(folder));
}
- public Task<TreeHash> GetHashMap(string container, string objectName)
+ public Task<TreeHash> GetHashMap(string account, string container, string objectName)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl != null);
return default(Task<TreeHash>);
}
- public Task<IList<string>> PutHashMap(string container, string objectName, TreeHash hash)
+ public Task<IList<string>> PutHashMap(string account, string container, string objectName, TreeHash hash)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl != null);
return default(Task<IList<string>>);
}
- public Task PostBlock(string container,byte[] block,int offset,int count)
+ public Task PostBlock(string account, string container, byte[] block, int offset, int count)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl != null);
return default(Task);
}
- public Task<byte[]> GetBlock(string container, Uri relativeUrl, long start, long? end)
+ public Task<byte[]> GetBlock(string account, string container, Uri relativeUrl, long start, long? end)
{
Contract.Requires(!String.IsNullOrWhiteSpace(Token));
Contract.Requires(StorageUrl != null);
return default(Task<byte[]>);
}
- }
-
- public class ContainerInfo
- {
- public string Name { get; set; }
- public long Count { get; set; }
- public long Bytes { get; set; }
- public string BlockHash { get; set; }
- public int BlockSize { get; set; }
- public static ContainerInfo Empty=new ContainerInfo();
}
}
<AssemblyName>Pithos.Network</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+ <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PropertyGroup>
<AssemblyOriginatorKeyFile>pithos.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.Network.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+ <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>True</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>True</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>True</CodeContractsArithmeticObligations>
+ <CodeContractsEnumObligations>True</CodeContractsEnumObligations>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly />
+ <CodeContractsCustomRewriterClass />
+ <CodeContractsLibPaths />
+ <CodeContractsExtraRewriteOptions />
+ <CodeContractsExtraAnalysisOptions />
+ <CodeContractsBaseLineFile />
+ <CodeContractsCacheAnalysisResults>True</CodeContractsCacheAnalysisResults>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+ <CodeContractsAnalysisWarningLevel>2</CodeContractsAnalysisWarningLevel>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
</ItemGroup>
<ItemGroup>
<Compile Include="CloudFilesClient.cs" />
+ <Compile Include="ContainerInfo.cs" />
<Compile Include="ICloudClient.cs" />
<Compile Include="RestClient.cs">
<SubType>Component</SubType>
private readonly Dictionary<string, string> _parameters=new Dictionary<string, string>();
public Dictionary<string, string> Parameters
{
- get { return _parameters; }
+ get
+ {
+ Contract.Ensures(_parameters!=null);
+ return _parameters;
+ }
+ }
+
+ [ContractInvariantMethod]
+ private void Invariants()
+ {
+ Contract.Invariant(Headers!=null);
}
public RestClient():base()
public RestClient(RestClient other)
: base()
{
+ if (other==null)
+ throw new ArgumentNullException("other");
+ Contract.EndContractBlock();
+
CopyHeaders(other);
Timeout = other.Timeout;
Retries = other.Retries;
{
TimedOut = false;
var webRequest = base.GetWebRequest(address);
- var request = webRequest as HttpWebRequest;
+ var request = (HttpWebRequest)webRequest;
if (IfModifiedSince.HasValue)
request.IfModifiedSince = IfModifiedSince.Value;
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
return response;
}
-
+ private readonly List<HttpStatusCode> _allowedStatusCodes=new List<HttpStatusCode>{HttpStatusCode.NotModified};
+ public List<HttpStatusCode> AllowedStatusCodes
+ {
+ get
+ {
+ return _allowedStatusCodes;
+ }
+ }
protected override WebResponse GetWebResponse(WebRequest request)
{
if (exc.Response!=null)
{
var response = (exc.Response as HttpWebResponse);
- if (response.StatusCode == HttpStatusCode.NotModified)
+ if (AllowedStatusCodes.Contains(response.StatusCode))
+ {
+ StatusCode = response.StatusCode;
+ LastModified = response.LastModified;
+ StatusDescription = response.StatusDescription;
+
return response;
+ }
if (exc.Response.ContentLength > 0)
{
string content = GetContent(exc.Response);
private static string GetContent(WebResponse webResponse)
{
+ if (webResponse == null)
+ throw new ArgumentNullException("webResponse");
+ Contract.EndContractBlock();
+
string content;
using (var stream = webResponse.GetResponseStream())
using (var reader = new StreamReader(stream))
public void Head(string address,int retries=0)
{
+ AllowedStatusCodes.Add(HttpStatusCode.NotFound);
RetryWithoutContent(address, retries, "HEAD");
}
public string GetHeaderValue(string headerName)
{
+ if (this.ResponseHeaders==null)
+ throw new InvalidOperationException("ResponseHeaders are null");
+ Contract.EndContractBlock();
+
var values=this.ResponseHeaders.GetValues(headerName);
if (values == null)
throw new WebException(String.Format("The {0} header is missing", headerName));
/// <param name="source">The RestClient from which the headers are copied</param>
public void CopyHeaders(RestClient source)
{
- Contract.Requires(source != null, "source can't be null");
if (source == null)
throw new ArgumentNullException("source", "source can't be null");
+ Contract.EndContractBlock();
+ //The Headers getter initializes the property, it is never null
+ Contract.Assume(Headers!=null);
+
CopyHeaders(source.Headers,Headers);
}
/// <param name="target">The target collection to which the headers are copied</param>
public static void CopyHeaders(WebHeaderCollection source,WebHeaderCollection target)
{
- Contract.Requires(source != null, "source can't be null");
- Contract.Requires(target != null, "target can't be null");
if (source == null)
throw new ArgumentNullException("source", "source can't be null");
if (target == null)
throw new ArgumentNullException("target", "target can't be null");
+ Contract.EndContractBlock();
+
for (int i = 0; i < source.Count; i++)
{
target.Add(source.GetKey(i), source[i]);
private Task<T> Retry<T>(Func<T> original, int retryCount, TaskCompletionSource<T> tcs = null)
{
+ if (original==null)
+ throw new ArgumentNullException("original");
+ Contract.EndContractBlock();
+
if (tcs == null)
tcs = new TaskCompletionSource<T>();
Task.Factory.StartNew(original).ContinueWith(_original =>
private HttpStatusCode GetStatusCode(WebException we)
{
+ if (we==null)
+ throw new ArgumentNullException("we");
var statusCode = HttpStatusCode.RequestTimeout;
if (we.Response != null)
{
}
return statusCode;
}
+
+ public UriBuilder GetAddressBuilder(string container, string objectName)
+ {
+ var builder = new UriBuilder(String.Join("/", BaseAddress, container, objectName));
+ return builder;
+ }
}
public class RetryException:Exception
{
if (info==null)
throw new ArgumentNullException("info");
+ if (String.IsNullOrWhiteSpace(info.FullName))
+ throw new ArgumentException("info.FullName is empty","info");
Contract.EndContractBlock();
return CalculateMD5(info.FullName);
{
if (fileInfo==null)
throw new ArgumentNullException("fileInfo");
+ if (String.IsNullOrWhiteSpace(fileInfo.FullName))
+ throw new ArgumentException("fileInfo.FullName is empty","fileInfo");
if (blockSize <= 0)
throw new ArgumentOutOfRangeException("blockSize", "blockSize must be a value greater than zero ");
if (String.IsNullOrWhiteSpace(algorithm))
{
if (fileInfo == null)
throw new ArgumentNullException("fileInfo");
+ if (String.IsNullOrWhiteSpace(fileInfo.FullName))
+ throw new ArgumentNullException("fileInfo.FullName is empty","fileInfo");
if (blockSize <= 0)
throw new ArgumentOutOfRangeException("blockSize", "blockSize must be a value greater than zero ");
if (String.IsNullOrWhiteSpace(algorithm))
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.IO;
using System.Text;
using System.Threading.Tasks;
private const int DEFAULT_BLOCK_SIZE = 4*1024*1024;
public string BlockHash { get; set; }
public int BlockSize { get; set; }
- public long Bytes { get; set; }
+
+ private long _bytes;
+ public long Bytes
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<long>() >= 0);
+ return _bytes;
+ }
+ set
+ {
+ if (value<0)
+ throw new ArgumentOutOfRangeException("Bytes");
+ Contract.Requires(value >= 0);
+ Contract.EndContractBlock();
+
+ _bytes = value;
+ }
+ }
+
+
public Guid FileId { get; set; }
}
private IList<byte[]> _hashes;
+
public IList<byte[]> Hashes
{
get { return _hashes; }
set
{
_hashes = value;
- _topHash.Force();
+ _topHash.Force();
}
}
- public TreeHash(string algorithm)
+ [ContractInvariantMethod]
+ private void Invariants()
+ {
+ Contract.Invariant(_bytes>=0);
+ }
+
+
+ public TreeHash(string algorithm)
{
BlockHash = algorithm;
_topHash = new Lazy<byte[]>(() =>
//Saves the Json representation to a file
public Task Save(string filePath)
{
+ if (String.IsNullOrWhiteSpace(filePath))
+ throw new ArgumentNullException("filePath");
+ Contract.EndContractBlock();
+
var fileName = FileId.ToString("N");
var path = Path.Combine(filePath, fileName);
if (!Directory.Exists(filePath))
public static TreeHash Parse(string json)
{
if (String.IsNullOrWhiteSpace(json))
- return Empty;
+ return Empty;
var value = JsonConvert.DeserializeObject<JObject>(json);
+ if (value==null)
+ throw new ArgumentException("The json parameter doesn't contain any json data","json");
+ Contract.Assume(value!=null);
var blockHash = (string) value["block_hash"];
var size = value.Value<int>("block_size");
{
"Entry"
{
- "MsmKey" = "8:_04BA020DDB8E799F1B05E41389C33CDB"
- "OwnerKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
- "MsmSig" = "8:_UNDEFINED"
- }
- "Entry"
- {
- "MsmKey" = "8:_04BA020DDB8E799F1B05E41389C33CDB"
+ "MsmKey" = "8:_0E4F95BDB07F23F411C53FB6C2E602F7"
"OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_04BA020DDB8E799F1B05E41389C33CDB"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_19A1385E2CA0B02EAB082C45FB563106"
+ "OwnerKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_08C5DBFDA002573955C5E1E5397AA883"
+ "MsmKey" = "8:_19A1385E2CA0B02EAB082C45FB563106"
"OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_290CB87DCCB9F0FC2F8645677EA05D8F"
+ "MsmKey" = "8:_19A1385E2CA0B02EAB082C45FB563106"
"OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_290CB87DCCB9F0FC2F8645677EA05D8F"
- "OwnerKey" = "8:_DEDA5BD2F233F0A42AFD96D4F704B4DF"
+ "MsmKey" = "8:_2837CB1EABE794B2B8C0028FDCFEA1C0"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_290CB87DCCB9F0FC2F8645677EA05D8F"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_290CB87DCCB9F0FC2F8645677EA05D8F"
- "OwnerKey" = "8:_D1664994F2882FF26943EB0063AB1E2D"
+ "MsmKey" = "8:_379682952A41C4DD701D113A41CD0ACC"
+ "OwnerKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_290CB87DCCB9F0FC2F8645677EA05D8F"
- "OwnerKey" = "8:_BBBEFA365EAA4B09B277CBDBED99E839"
+ "MsmKey" = "8:_379682952A41C4DD701D113A41CD0ACC"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_290CB87DCCB9F0FC2F8645677EA05D8F"
- "OwnerKey" = "8:_BAA515E0FCDE402CBF2A6FF3D94A0B83"
+ "MsmKey" = "8:_379682952A41C4DD701D113A41CD0ACC"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_290CB87DCCB9F0FC2F8645677EA05D8F"
- "OwnerKey" = "8:_B032B8B884C0A6A2E9CA650FCAC16970"
+ "MsmKey" = "8:_412610FA5B854CE1B90857177A4DF634"
+ "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_311197E10704448D93A69A8EC39C3C80"
- "OwnerKey" = "8:_UNDEFINED"
+ "MsmKey" = "8:_413A3C9A9C848F0F0E34C29B1C919557"
+ "OwnerKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_412610FA5B854CE1B90857177A4DF634"
- "OwnerKey" = "8:_UNDEFINED"
+ "MsmKey" = "8:_413A3C9A9C848F0F0E34C29B1C919557"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_52E458D5C0305865B4E25CD0FDD3644B"
+ "MsmKey" = "8:_413A3C9A9C848F0F0E34C29B1C919557"
"OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_52E458D5C0305865B4E25CD0FDD3644B"
- "OwnerKey" = "8:_D1664994F2882FF26943EB0063AB1E2D"
+ "MsmKey" = "8:_413A3C9A9C848F0F0E34C29B1C919557"
+ "OwnerKey" = "8:_476D990A74530772679162FBBFE0FCF4"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_52E458D5C0305865B4E25CD0FDD3644B"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_413A3C9A9C848F0F0E34C29B1C919557"
+ "OwnerKey" = "8:_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_52E458D5C0305865B4E25CD0FDD3644B"
- "OwnerKey" = "8:_BBBEFA365EAA4B09B277CBDBED99E839"
+ "MsmKey" = "8:_4414524BD941C2AB1F7C50E315B4C9EF"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_52E458D5C0305865B4E25CD0FDD3644B"
- "OwnerKey" = "8:_B032B8B884C0A6A2E9CA650FCAC16970"
+ "MsmKey" = "8:_4414524BD941C2AB1F7C50E315B4C9EF"
+ "OwnerKey" = "8:_8046A0650A0FDBD7044C0059B48CB6EA"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_53268E13E9741B866CCEC4CAAB6F7CC0"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_4414524BD941C2AB1F7C50E315B4C9EF"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_53268E13E9741B866CCEC4CAAB6F7CC0"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_4414524BD941C2AB1F7C50E315B4C9EF"
+ "OwnerKey" = "8:_BBBEFA365EAA4B09B277CBDBED99E839"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_53268E13E9741B866CCEC4CAAB6F7CC0"
- "OwnerKey" = "8:_BBBEFA365EAA4B09B277CBDBED99E839"
+ "MsmKey" = "8:_4414524BD941C2AB1F7C50E315B4C9EF"
+ "OwnerKey" = "8:_8B189FCC1135DE71AFEBE665EBC98E1E"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_53268E13E9741B866CCEC4CAAB6F7CC0"
- "OwnerKey" = "8:_B032B8B884C0A6A2E9CA650FCAC16970"
+ "MsmKey" = "8:_476D990A74530772679162FBBFE0FCF4"
+ "OwnerKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_54F1D51175D73ACE29F26142CAE00C3A"
- "OwnerKey" = "8:_DEDA5BD2F233F0A42AFD96D4F704B4DF"
+ "MsmKey" = "8:_476D990A74530772679162FBBFE0FCF4"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_5550CCC7F6A61F45C1B9E5259AD0933E"
+ "MsmKey" = "8:_476D990A74530772679162FBBFE0FCF4"
"OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_5999946716C03EF42A7E7AB943915D64"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
+ "OwnerKey" = "8:_379682952A41C4DD701D113A41CD0ACC"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_5999946716C03EF42A7E7AB943915D64"
- "OwnerKey" = "8:_D1664994F2882FF26943EB0063AB1E2D"
+ "MsmKey" = "8:_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_5999946716C03EF42A7E7AB943915D64"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_5999946716C03EF42A7E7AB943915D64"
- "OwnerKey" = "8:_5550CCC7F6A61F45C1B9E5259AD0933E"
+ "MsmKey" = "8:_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
+ "OwnerKey" = "8:_476D990A74530772679162FBBFE0FCF4"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_74535AE0FDD2421E81F24E0DB0554D26"
- "OwnerKey" = "8:_UNDEFINED"
+ "MsmKey" = "8:_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
+ "OwnerKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_77F82E591A29D6C19B7A7CDE824B968C"
- "OwnerKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
+ "MsmKey" = "8:_71AB7BB89699C43F04EFBBD41DFF976E"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_77F82E591A29D6C19B7A7CDE824B968C"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_71AB7BB89699C43F04EFBBD41DFF976E"
+ "OwnerKey" = "8:_8046A0650A0FDBD7044C0059B48CB6EA"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_77F82E591A29D6C19B7A7CDE824B968C"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_71AB7BB89699C43F04EFBBD41DFF976E"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_77F82E591A29D6C19B7A7CDE824B968C"
- "OwnerKey" = "8:_04BA020DDB8E799F1B05E41389C33CDB"
+ "MsmKey" = "8:_71AB7BB89699C43F04EFBBD41DFF976E"
+ "OwnerKey" = "8:_2837CB1EABE794B2B8C0028FDCFEA1C0"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_77F82E591A29D6C19B7A7CDE824B968C"
- "OwnerKey" = "8:_91362F1FE448D304981DEE4A2E25926E"
+ "MsmKey" = "8:_74535AE0FDD2421E81F24E0DB0554D26"
+ "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_7F0D4FC20A3B3B6E7819390C3E74A983"
+ "MsmKey" = "8:_8046A0650A0FDBD7044C0059B48CB6EA"
"OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_8201861880C6B87DFDD8A70B2B580914"
- "OwnerKey" = "8:_8C512BF6FF06B9F7518CBE310877E479"
+ "OwnerKey" = "8:_C9615BA8AC66AC373BB153F8A95E9DA8"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_856286C42763F5D5F644D3E450795653"
+ "MsmKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
"OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_856286C42763F5D5F644D3E450795653"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
+ "OwnerKey" = "8:_8046A0650A0FDBD7044C0059B48CB6EA"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_8C512BF6FF06B9F7518CBE310877E479"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_8C512BF6FF06B9F7518CBE310877E479"
- "OwnerKey" = "8:_D1664994F2882FF26943EB0063AB1E2D"
+ "MsmKey" = "8:_8B189FCC1135DE71AFEBE665EBC98E1E"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_8C512BF6FF06B9F7518CBE310877E479"
+ "MsmKey" = "8:_8B189FCC1135DE71AFEBE665EBC98E1E"
"OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_91362F1FE448D304981DEE4A2E25926E"
- "OwnerKey" = "8:_A68ECCEBE87AD544F44B6E7734EBD621"
+ "MsmKey" = "8:_8B189FCC1135DE71AFEBE665EBC98E1E"
+ "OwnerKey" = "8:_8046A0650A0FDBD7044C0059B48CB6EA"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_91362F1FE448D304981DEE4A2E25926E"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
- "MsmSig" = "8:_UNDEFINED"
- }
- "Entry"
- {
- "MsmKey" = "8:_91362F1FE448D304981DEE4A2E25926E"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_9419C61DF5F3441099A56E07565699F0"
+ "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_91362F1FE448D304981DEE4A2E25926E"
- "OwnerKey" = "8:_04BA020DDB8E799F1B05E41389C33CDB"
+ "MsmKey" = "8:_9F55CE39394926A083741C3E2824DE59"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_91362F1FE448D304981DEE4A2E25926E"
- "OwnerKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
+ "MsmKey" = "8:_BAA515E0FCDE402CBF2A6FF3D94A0B83"
+ "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_9419C61DF5F3441099A56E07565699F0"
+ "MsmKey" = "8:_BBBEFA365EAA4B09B277CBDBED99E839"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_A68ECCEBE87AD544F44B6E7734EBD621"
- "OwnerKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
+ "MsmKey" = "8:_C017F2E6E691B9F1814D8EDA1C80C44E"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_A68ECCEBE87AD544F44B6E7734EBD621"
+ "MsmKey" = "8:_C017F2E6E691B9F1814D8EDA1C80C44E"
"OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_A68ECCEBE87AD544F44B6E7734EBD621"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_C017F2E6E691B9F1814D8EDA1C80C44E"
+ "OwnerKey" = "8:_BBBEFA365EAA4B09B277CBDBED99E839"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_B032B8B884C0A6A2E9CA650FCAC16970"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_C017F2E6E691B9F1814D8EDA1C80C44E"
+ "OwnerKey" = "8:_8B189FCC1135DE71AFEBE665EBC98E1E"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_B032B8B884C0A6A2E9CA650FCAC16970"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_B03A075A5CDF3E0434B54DAB685A5E8D"
- "OwnerKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
+ "MsmKey" = "8:_C7FAC6DF0866992BDABC6B70456C92F1"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_B03A075A5CDF3E0434B54DAB685A5E8D"
+ "MsmKey" = "8:_C7FAC6DF0866992BDABC6B70456C92F1"
"OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_B03A075A5CDF3E0434B54DAB685A5E8D"
+ "MsmKey" = "8:_C9615BA8AC66AC373BB153F8A95E9DA8"
"OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_B03A075A5CDF3E0434B54DAB685A5E8D"
- "OwnerKey" = "8:_A68ECCEBE87AD544F44B6E7734EBD621"
+ "MsmKey" = "8:_C9615BA8AC66AC373BB153F8A95E9DA8"
+ "OwnerKey" = "8:_8046A0650A0FDBD7044C0059B48CB6EA"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_BAA515E0FCDE402CBF2A6FF3D94A0B83"
- "OwnerKey" = "8:_UNDEFINED"
+ "MsmKey" = "8:_C9615BA8AC66AC373BB153F8A95E9DA8"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_BBBEFA365EAA4B09B277CBDBED99E839"
+ "MsmKey" = "8:_CE1C7673CEC14F70AFCF2B48FF8B3D37"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_C4EB6477683944848E47C160C41EA94A"
- "OwnerKey" = "8:_UNDEFINED"
+ "MsmKey" = "8:_D27724C0B9E9EA480E1B445116EB2A8B"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_CE1C7673CEC14F70AFCF2B48FF8B3D37"
- "OwnerKey" = "8:_UNDEFINED"
+ "MsmKey" = "8:_D27724C0B9E9EA480E1B445116EB2A8B"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_D1664994F2882FF26943EB0063AB1E2D"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_D27724C0B9E9EA480E1B445116EB2A8B"
+ "OwnerKey" = "8:_8046A0650A0FDBD7044C0059B48CB6EA"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_DEDA5BD2F233F0A42AFD96D4F704B4DF"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_D27724C0B9E9EA480E1B445116EB2A8B"
+ "OwnerKey" = "8:_BBBEFA365EAA4B09B277CBDBED99E839"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_E800F1D1BBBD8589A3E9175B06D71A0F"
- "OwnerKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
+ "MsmKey" = "8:_D27724C0B9E9EA480E1B445116EB2A8B"
+ "OwnerKey" = "8:_BAA515E0FCDE402CBF2A6FF3D94A0B83"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_E800F1D1BBBD8589A3E9175B06D71A0F"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_D27724C0B9E9EA480E1B445116EB2A8B"
+ "OwnerKey" = "8:_8B189FCC1135DE71AFEBE665EBC98E1E"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_E800F1D1BBBD8589A3E9175B06D71A0F"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_E5247C57FCF8FDC4526119494C9CA91D"
+ "OwnerKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
- "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
+ "MsmKey" = "8:_E5247C57FCF8FDC4526119494C9CA91D"
+ "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
- "OwnerKey" = "8:_D1664994F2882FF26943EB0063AB1E2D"
+ "MsmKey" = "8:_E5247C57FCF8FDC4526119494C9CA91D"
+ "OwnerKey" = "8:_311197E10704448D93A69A8EC39C3C80"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
- "MsmKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
- "OwnerKey" = "8:_C4EB6477683944848E47C160C41EA94A"
+ "MsmKey" = "8:_E5247C57FCF8FDC4526119494C9CA91D"
+ "OwnerKey" = "8:_379682952A41C4DD701D113A41CD0ACC"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_DEDA5BD2F233F0A42AFD96D4F704B4DF"
- "MsmSig" = "8:_UNDEFINED"
- }
- "Entry"
- {
- "MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_D1664994F2882FF26943EB0063AB1E2D"
+ "OwnerKey" = "8:_8046A0650A0FDBD7044C0059B48CB6EA"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_7F0D4FC20A3B3B6E7819390C3E74A983"
+ "OwnerKey" = "8:_0E4F95BDB07F23F411C53FB6C2E602F7"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_08C5DBFDA002573955C5E1E5397AA883"
+ "OwnerKey" = "8:_9F55CE39394926A083741C3E2824DE59"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_B032B8B884C0A6A2E9CA650FCAC16970"
+ "OwnerKey" = "8:_8B189FCC1135DE71AFEBE665EBC98E1E"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_53268E13E9741B866CCEC4CAAB6F7CC0"
+ "OwnerKey" = "8:_D27724C0B9E9EA480E1B445116EB2A8B"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_290CB87DCCB9F0FC2F8645677EA05D8F"
+ "OwnerKey" = "8:_C7FAC6DF0866992BDABC6B70456C92F1"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_856286C42763F5D5F644D3E450795653"
+ "OwnerKey" = "8:_4414524BD941C2AB1F7C50E315B4C9EF"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_52E458D5C0305865B4E25CD0FDD3644B"
+ "OwnerKey" = "8:_2837CB1EABE794B2B8C0028FDCFEA1C0"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_5550CCC7F6A61F45C1B9E5259AD0933E"
+ "OwnerKey" = "8:_71AB7BB89699C43F04EFBBD41DFF976E"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_5999946716C03EF42A7E7AB943915D64"
+ "OwnerKey" = "8:_C017F2E6E691B9F1814D8EDA1C80C44E"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_EDB900CFF8D60A69C698930CF318E12F"
+ "OwnerKey" = "8:_8202743C43C25F5033105429DB6BB9A3"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_04BA020DDB8E799F1B05E41389C33CDB"
+ "OwnerKey" = "8:_476D990A74530772679162FBBFE0FCF4"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_A68ECCEBE87AD544F44B6E7734EBD621"
+ "OwnerKey" = "8:_379682952A41C4DD701D113A41CD0ACC"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_91362F1FE448D304981DEE4A2E25926E"
+ "OwnerKey" = "8:_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_77F82E591A29D6C19B7A7CDE824B968C"
+ "OwnerKey" = "8:_413A3C9A9C848F0F0E34C29B1C919557"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_B03A075A5CDF3E0434B54DAB685A5E8D"
+ "OwnerKey" = "8:_E5247C57FCF8FDC4526119494C9CA91D"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_E800F1D1BBBD8589A3E9175B06D71A0F"
+ "OwnerKey" = "8:_19A1385E2CA0B02EAB082C45FB563106"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_8C512BF6FF06B9F7518CBE310877E479"
+ "OwnerKey" = "8:_C9615BA8AC66AC373BB153F8A95E9DA8"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
}
}
}
+ "Premium Debug"
+ {
+ "DisplayName" = "8:Premium Debug"
+ "IsDebugOnly" = "11:FALSE"
+ "IsReleaseOnly" = "11:FALSE"
+ "OutputFilename" = "8:Premium Debug\\Pithos.Setup.x64.msi"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:2"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:TRUE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:"
+ "ComponentsUrl" = "8:"
+ "Items"
+ {
+ "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.0,Profile=Client"
+ {
+ "Name" = "8:Microsoft .NET Framework 4 Client Profile (x86 and x64)"
+ "ProductCode" = "8:.NETFramework,Version=v4.0,Profile=Client"
+ }
+ "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.3.1"
+ {
+ "Name" = "8:Windows Installer 3.1"
+ "ProductCode" = "8:Microsoft.Windows.Installer.3.1"
+ }
+ }
+ }
+ }
"Release"
{
"DisplayName" = "8:Release"
}
"File"
{
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_04BA020DDB8E799F1B05E41389C33CDB"
- {
- "AssemblyRegister" = "3:1"
- "AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:NHibernate.Search, Version=0.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"
- "ScatterAssemblies"
- {
- "_04BA020DDB8E799F1B05E41389C33CDB"
- {
- "Name" = "8:NHibernate.Search.dll"
- "Attributes" = "3:512"
- }
- }
- "SourcePath" = "8:NHibernate.Search.dll"
- "TargetName" = "8:"
- "Tag" = "8:"
- "Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
- "Condition" = "8:"
- "Transitive" = "11:FALSE"
- "Vital" = "11:TRUE"
- "ReadOnly" = "11:FALSE"
- "Hidden" = "11:FALSE"
- "System" = "11:FALSE"
- "Permanent" = "11:FALSE"
- "SharedLegacy" = "11:FALSE"
- "PackageAs" = "3:1"
- "Register" = "3:1"
- "Exclude" = "11:FALSE"
- "IsDependency" = "11:TRUE"
- "IsolateTo" = "8:"
- }
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_08C5DBFDA002573955C5E1E5397AA883"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_0E4F95BDB07F23F411C53FB6C2E602F7"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Hardcodet.Wpf.TaskbarNotification, Version=1.0.4.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:WPF.Themes, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_08C5DBFDA002573955C5E1E5397AA883"
+ "_0E4F95BDB07F23F411C53FB6C2E602F7"
{
- "Name" = "8:Hardcodet.Wpf.TaskbarNotification.dll"
+ "Name" = "8:WPF.Themes.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Hardcodet.Wpf.TaskbarNotification.dll"
+ "SourcePath" = "8:WPF.Themes.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_290CB87DCCB9F0FC2F8645677EA05D8F"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_19A1385E2CA0B02EAB082C45FB563106"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Pithos.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Castle.Components.Validator, Version=2.5.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_290CB87DCCB9F0FC2F8645677EA05D8F"
+ "_19A1385E2CA0B02EAB082C45FB563106"
{
- "Name" = "8:Pithos.Interfaces.dll"
+ "Name" = "8:Castle.Components.Validator.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Pithos.Interfaces.dll"
+ "SourcePath" = "8:Castle.Components.Validator.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_52E458D5C0305865B4E25CD0FDD3644B"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_2837CB1EABE794B2B8C0028FDCFEA1C0"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:ParallelExtensionsExtras, Version=1.2.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Microsoft.WindowsAPICodePack.Shell, Version=1.1.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_52E458D5C0305865B4E25CD0FDD3644B"
+ "_2837CB1EABE794B2B8C0028FDCFEA1C0"
{
- "Name" = "8:ParallelExtensionsExtras.dll"
+ "Name" = "8:Microsoft.WindowsAPICodePack.Shell.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:ParallelExtensionsExtras.dll"
+ "SourcePath" = "8:Microsoft.WindowsAPICodePack.Shell.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_53268E13E9741B866CCEC4CAAB6F7CC0"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_379682952A41C4DD701D113A41CD0ACC"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Newtonsoft.Json, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b9a188c8922137c6, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:NHibernate.ByteCode.Castle, Version=3.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_53268E13E9741B866CCEC4CAAB6F7CC0"
+ "_379682952A41C4DD701D113A41CD0ACC"
{
- "Name" = "8:Newtonsoft.Json.dll"
+ "Name" = "8:NHibernate.ByteCode.Castle.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Newtonsoft.Json.dll"
+ "SourcePath" = "8:NHibernate.ByteCode.Castle.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_54F1D51175D73ACE29F26142CAE00C3A"
- {
- "SourcePath" = "8:Pithos.ShellExtensions.tlb"
- "TargetName" = "8:Pithos.ShellExtensions.tlb"
- "Tag" = "8:"
- "Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
- "Condition" = "8:"
- "Transitive" = "11:FALSE"
- "Vital" = "11:TRUE"
- "ReadOnly" = "11:FALSE"
- "Hidden" = "11:FALSE"
- "System" = "11:FALSE"
- "Permanent" = "11:FALSE"
- "SharedLegacy" = "11:FALSE"
- "PackageAs" = "3:1"
- "Register" = "3:2"
- "Exclude" = "11:FALSE"
- "IsDependency" = "11:TRUE"
- "IsolateTo" = "8:"
- }
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_5550CCC7F6A61F45C1B9E5259AD0933E"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_413A3C9A9C848F0F0E34C29B1C919557"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Microsoft.WindowsAPICodePack.Shell, Version=1.1.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Iesi.Collections, Version=1.0.1.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_5550CCC7F6A61F45C1B9E5259AD0933E"
+ "_413A3C9A9C848F0F0E34C29B1C919557"
{
- "Name" = "8:Microsoft.WindowsAPICodePack.Shell.dll"
+ "Name" = "8:Iesi.Collections.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Microsoft.WindowsAPICodePack.Shell.dll"
+ "SourcePath" = "8:Iesi.Collections.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_5999946716C03EF42A7E7AB943915D64"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_4414524BD941C2AB1F7C50E315B4C9EF"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Microsoft.WindowsAPICodePack, Version=1.1.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:ParallelExtensionsExtras, Version=1.2.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_5999946716C03EF42A7E7AB943915D64"
+ "_4414524BD941C2AB1F7C50E315B4C9EF"
{
- "Name" = "8:Microsoft.WindowsAPICodePack.dll"
+ "Name" = "8:ParallelExtensionsExtras.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Microsoft.WindowsAPICodePack.dll"
+ "SourcePath" = "8:ParallelExtensionsExtras.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_77F82E591A29D6C19B7A7CDE824B968C"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_476D990A74530772679162FBBFE0FCF4"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Iesi.Collections, Version=1.0.1.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:NHibernate.Search, Version=0.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_77F82E591A29D6C19B7A7CDE824B968C"
+ "_476D990A74530772679162FBBFE0FCF4"
{
- "Name" = "8:Iesi.Collections.dll"
+ "Name" = "8:NHibernate.Search.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Iesi.Collections.dll"
+ "SourcePath" = "8:NHibernate.Search.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_7F0D4FC20A3B3B6E7819390C3E74A983"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:WPF.Themes, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:NHibernate, Version=3.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_7F0D4FC20A3B3B6E7819390C3E74A983"
+ "_4CFFEFA8D3F3865F15FEA354C6BF4ECC"
{
- "Name" = "8:WPF.Themes.dll"
+ "Name" = "8:NHibernate.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:WPF.Themes.dll"
+ "SourcePath" = "8:NHibernate.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8201861880C6B87DFDD8A70B2B580914"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_71AB7BB89699C43F04EFBBD41DFF976E"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Microsoft.WindowsAPICodePack, Version=1.1.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_8201861880C6B87DFDD8A70B2B580914"
+ "_71AB7BB89699C43F04EFBBD41DFF976E"
{
- "Name" = "8:System.Windows.Interactivity.dll"
+ "Name" = "8:Microsoft.WindowsAPICodePack.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:System.Windows.Interactivity.dll"
+ "SourcePath" = "8:Microsoft.WindowsAPICodePack.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_856286C42763F5D5F644D3E450795653"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8046A0650A0FDBD7044C0059B48CB6EA"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:System.Data.SQLite, Version=1.0.74.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Pithos.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_856286C42763F5D5F644D3E450795653"
+ "_8046A0650A0FDBD7044C0059B48CB6EA"
{
- "Name" = "8:System.Data.SQLite.dll"
+ "Name" = "8:Pithos.Core.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:System.Data.SQLite.dll"
+ "SourcePath" = "8:Pithos.Core.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8C512BF6FF06B9F7518CBE310877E479"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8201861880C6B87DFDD8A70B2B580914"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Caliburn.Micro, Version=1.2.0.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_8C512BF6FF06B9F7518CBE310877E479"
+ "_8201861880C6B87DFDD8A70B2B580914"
{
- "Name" = "8:Caliburn.Micro.dll"
+ "Name" = "8:System.Windows.Interactivity.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Caliburn.Micro.dll"
+ "SourcePath" = "8:System.Windows.Interactivity.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_91362F1FE448D304981DEE4A2E25926E"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8202743C43C25F5033105429DB6BB9A3"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:NHibernate, Version=3.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Castle.ActiveRecord, Version=3.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_91362F1FE448D304981DEE4A2E25926E"
+ "_8202743C43C25F5033105429DB6BB9A3"
{
- "Name" = "8:NHibernate.dll"
+ "Name" = "8:Castle.ActiveRecord.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:NHibernate.dll"
+ "SourcePath" = "8:Castle.ActiveRecord.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_A68ECCEBE87AD544F44B6E7734EBD621"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8B189FCC1135DE71AFEBE665EBC98E1E"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:NHibernate.ByteCode.Castle, Version=3.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Pithos.Network, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_A68ECCEBE87AD544F44B6E7734EBD621"
+ "_8B189FCC1135DE71AFEBE665EBC98E1E"
{
- "Name" = "8:NHibernate.ByteCode.Castle.dll"
+ "Name" = "8:Pithos.Network.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:NHibernate.ByteCode.Castle.dll"
+ "SourcePath" = "8:Pithos.Network.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_B032B8B884C0A6A2E9CA650FCAC16970"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_9F55CE39394926A083741C3E2824DE59"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Pithos.Network, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Hardcodet.Wpf.TaskbarNotification, Version=1.0.4.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_B032B8B884C0A6A2E9CA650FCAC16970"
+ "_9F55CE39394926A083741C3E2824DE59"
{
- "Name" = "8:Pithos.Network.dll"
+ "Name" = "8:Hardcodet.Wpf.TaskbarNotification.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Pithos.Network.dll"
+ "SourcePath" = "8:Hardcodet.Wpf.TaskbarNotification.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_B03A075A5CDF3E0434B54DAB685A5E8D"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_C017F2E6E691B9F1814D8EDA1C80C44E"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Castle.Core, Version=2.5.1.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Newtonsoft.Json, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b9a188c8922137c6, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_B03A075A5CDF3E0434B54DAB685A5E8D"
+ "_C017F2E6E691B9F1814D8EDA1C80C44E"
{
- "Name" = "8:Castle.Core.dll"
+ "Name" = "8:Newtonsoft.Json.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Castle.Core.dll"
+ "SourcePath" = "8:Newtonsoft.Json.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_D1664994F2882FF26943EB0063AB1E2D"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_C7FAC6DF0866992BDABC6B70456C92F1"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Pithos.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:System.Data.SQLite, Version=1.0.74.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_D1664994F2882FF26943EB0063AB1E2D"
+ "_C7FAC6DF0866992BDABC6B70456C92F1"
{
- "Name" = "8:Pithos.Core.dll"
+ "Name" = "8:System.Data.SQLite.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Pithos.Core.dll"
+ "SourcePath" = "8:System.Data.SQLite.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_DEDA5BD2F233F0A42AFD96D4F704B4DF"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_C9615BA8AC66AC373BB153F8A95E9DA8"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Pithos.ShellExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Caliburn.Micro, Version=1.2.0.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_DEDA5BD2F233F0A42AFD96D4F704B4DF"
+ "_C9615BA8AC66AC373BB153F8A95E9DA8"
{
- "Name" = "8:Pithos.ShellExtensions.dll"
+ "Name" = "8:Caliburn.Micro.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Pithos.ShellExtensions.dll"
+ "SourcePath" = "8:Caliburn.Micro.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_E800F1D1BBBD8589A3E9175B06D71A0F"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_D27724C0B9E9EA480E1B445116EB2A8B"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Castle.Components.Validator, Version=2.5.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Pithos.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cc55badaa91f4de, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_E800F1D1BBBD8589A3E9175B06D71A0F"
+ "_D27724C0B9E9EA480E1B445116EB2A8B"
{
- "Name" = "8:Castle.Components.Validator.dll"
+ "Name" = "8:Pithos.Interfaces.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Castle.Components.Validator.dll"
+ "SourcePath" = "8:Pithos.Interfaces.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
- "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_EDB900CFF8D60A69C698930CF318E12F"
+ "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_E5247C57FCF8FDC4526119494C9CA91D"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
- "AssemblyAsmDisplayName" = "8:Castle.ActiveRecord, Version=3.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"
+ "AssemblyAsmDisplayName" = "8:Castle.Core, Version=2.5.1.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"
"ScatterAssemblies"
{
- "_EDB900CFF8D60A69C698930CF318E12F"
+ "_E5247C57FCF8FDC4526119494C9CA91D"
{
- "Name" = "8:Castle.ActiveRecord.dll"
+ "Name" = "8:Castle.Core.dll"
"Attributes" = "3:512"
}
}
- "SourcePath" = "8:Castle.ActiveRecord.dll"
+ "SourcePath" = "8:Castle.Core.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
}
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_311197E10704448D93A69A8EC39C3C80"
{
- "SourcePath" = "8:..\\Pithos.Core\\obj\\Debug\\Pithos.Core.dll"
+ "SourcePath" = "8:..\\Pithos.Core\\obj\\Premium Debug\\Pithos.Core.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
}
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_74535AE0FDD2421E81F24E0DB0554D26"
{
- "SourcePath" = "8:..\\Libraries\\Json40r2\\Source\\Src\\Newtonsoft.Json\\obj\\Debug\\Newtonsoft.Json.dll"
+ "SourcePath" = "8:..\\Libraries\\Json40r2\\Source\\Src\\Newtonsoft.Json\\obj\\Premium Debug\\Newtonsoft.Json.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
}
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_9419C61DF5F3441099A56E07565699F0"
{
- "SourcePath" = "8:..\\Libraries\\ParallelExtensionsExtras\\obj\\Debug\\ParallelExtensionsExtras.dll"
+ "SourcePath" = "8:..\\Libraries\\ParallelExtensionsExtras\\obj\\Premium Debug\\ParallelExtensionsExtras.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
}
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_BAA515E0FCDE402CBF2A6FF3D94A0B83"
{
- "SourcePath" = "8:..\\Pithos.ShellExtensions\\obj\\Debug\\Pithos.ShellExtensions.dll"
+ "SourcePath" = "8:..\\Pithos.ShellExtensions\\obj\\Premium Debug\\Pithos.ShellExtensions.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
}
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_BBBEFA365EAA4B09B277CBDBED99E839"
{
- "SourcePath" = "8:..\\Pithos.Network\\obj\\Debug\\Pithos.Network.dll"
+ "SourcePath" = "8:..\\Pithos.Network\\obj\\Premium Debug\\Pithos.Network.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
}
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_C4EB6477683944848E47C160C41EA94A"
{
- "SourcePath" = "8:..\\Pithos.Client.WPF\\obj\\Debug\\Pithos.Client.WPF.exe"
+ "SourcePath" = "8:..\\Pithos.Client.WPF\\obj\\Premium Debug\\Pithos.Client.WPF.exe"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
}
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_CE1C7673CEC14F70AFCF2B48FF8B3D37"
{
- "SourcePath" = "8:..\\Pithos.Interfaces\\obj\\Debug\\Pithos.Interfaces.dll"
+ "SourcePath" = "8:..\\Pithos.Interfaces\\obj\\Premium Debug\\Pithos.Interfaces.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
}
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_F65AE860659D453AAFD4D6F068DAC541"
{
- "SourcePath" = "8:..\\NotifyIconWpf\\obj\\Debug\\Hardcodet.Wpf.TaskbarNotification.dll"
+ "SourcePath" = "8:..\\NotifyIconWpf\\obj\\Premium Debug\\Hardcodet.Wpf.TaskbarNotification.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_2E4412A903CE41838ECE5DCF9470F71C"
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.ShellExtensions.Test.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll</HintPath>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Premium Debug|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Premium Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <RegisterForComInterop>true</RegisterForComInterop>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisLogFile>bin\Debug\Pithos.ShellExtensions.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x86 = Debug|x86
+ Premium Debug|Any CPU = Premium Debug|Any CPU
+ Premium Debug|Mixed Platforms = Premium Debug|Mixed Platforms
+ Premium Debug|x86 = Premium Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x86 = Release|x86
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {240B432F-1030-4623-BCC3-FF351D6C1B63}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {240B432F-1030-4623-BCC3-FF351D6C1B63}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {240B432F-1030-4623-BCC3-FF351D6C1B63}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {240B432F-1030-4623-BCC3-FF351D6C1B63}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Any CPU.Build.0 = Release|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Any CPU.Build.0 = Release|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Release|Any CPU.Build.0 = Release|Any CPU
{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{822F885B-83E8-4A9A-B02E-0FEAE444D960}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{822F885B-83E8-4A9A-B02E-0FEAE444D960}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{822F885B-83E8-4A9A-B02E-0FEAE444D960}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{822F885B-83E8-4A9A-B02E-0FEAE444D960}.Release|Any CPU.ActiveCfg = Release|Any CPU
{822F885B-83E8-4A9A-B02E-0FEAE444D960}.Release|Any CPU.Build.0 = Release|Any CPU
{822F885B-83E8-4A9A-B02E-0FEAE444D960}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Any CPU.Build.0 = Release|Any CPU
{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{142AF135-DF30-4563-B0AC-B604235AE874}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{142AF135-DF30-4563-B0AC-B604235AE874}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{142AF135-DF30-4563-B0AC-B604235AE874}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {142AF135-DF30-4563-B0AC-B604235AE874}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {142AF135-DF30-4563-B0AC-B604235AE874}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {142AF135-DF30-4563-B0AC-B604235AE874}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {142AF135-DF30-4563-B0AC-B604235AE874}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {142AF135-DF30-4563-B0AC-B604235AE874}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{142AF135-DF30-4563-B0AC-B604235AE874}.Release|Any CPU.ActiveCfg = Release|Any CPU
{142AF135-DF30-4563-B0AC-B604235AE874}.Release|Any CPU.Build.0 = Release|Any CPU
{142AF135-DF30-4563-B0AC-B604235AE874}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Release|Any CPU.Build.0 = Release|Any CPU
{E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Release|Any CPU.Build.0 = Release|Any CPU
{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Release|Any CPU.Build.0 = Release|Any CPU
{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.Build.0 = Release|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Debug|x86.ActiveCfg = Debug|Any CPU
{4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Debug|x86.Build.0 = Debug|Any CPU
+ {4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Premium Debug|x86.ActiveCfg = Premium Debug|x86
+ {4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Premium Debug|x86.Build.0 = Premium Debug|x86
{4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Release|Any CPU.ActiveCfg = Release|x86
{4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Release|Mixed Platforms.ActiveCfg = Release|x86
{4D9406A3-50ED-4672-BB97-A0B3EA4946FE}.Release|Mixed Platforms.Build.0 = Release|x86
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7AC63864-7638-41C4-969C-D3197EF2BED9}.Premium Debug|Any CPU.ActiveCfg = Premium Debug|Any CPU
+ {7AC63864-7638-41C4-969C-D3197EF2BED9}.Premium Debug|Any CPU.Build.0 = Premium Debug|Any CPU
+ {7AC63864-7638-41C4-969C-D3197EF2BED9}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug|Any CPU
+ {7AC63864-7638-41C4-969C-D3197EF2BED9}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug|Any CPU
+ {7AC63864-7638-41C4-969C-D3197EF2BED9}.Premium Debug|x86.ActiveCfg = Premium Debug|Any CPU
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Release|Any CPU.Build.0 = Release|Any CPU
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C6251981-3C49-404B-BB5B-9732887388D2}.Debug|Any CPU.ActiveCfg = Debug
{C6251981-3C49-404B-BB5B-9732887388D2}.Debug|Mixed Platforms.ActiveCfg = Debug
{C6251981-3C49-404B-BB5B-9732887388D2}.Debug|x86.ActiveCfg = Debug
+ {C6251981-3C49-404B-BB5B-9732887388D2}.Premium Debug|Any CPU.ActiveCfg = Premium Debug
+ {C6251981-3C49-404B-BB5B-9732887388D2}.Premium Debug|Mixed Platforms.ActiveCfg = Premium Debug
+ {C6251981-3C49-404B-BB5B-9732887388D2}.Premium Debug|Mixed Platforms.Build.0 = Premium Debug
+ {C6251981-3C49-404B-BB5B-9732887388D2}.Premium Debug|x86.ActiveCfg = Premium Debug
+ {C6251981-3C49-404B-BB5B-9732887388D2}.Premium Debug|x86.Build.0 = Premium Debug
{C6251981-3C49-404B-BB5B-9732887388D2}.Release|Any CPU.ActiveCfg = Release
{C6251981-3C49-404B-BB5B-9732887388D2}.Release|Mixed Platforms.ActiveCfg = Release
{C6251981-3C49-404B-BB5B-9732887388D2}.Release|x86.ActiveCfg = Release