--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Windows.Data;
+
+namespace Pithos.Client.WPF.Converters
+{
+ public class DummyConverter:IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+ }
+}
<extToolkit:Wizard FinishButtonClosesWindow="True" Name="AccountWizard" PageChanged="AccountWizard_PageChanged">
<extToolkit:WizardPage x:Name="IntroPage"
Title="Add new Pithos Account"
- Description="This Wizard will walk you through adding a new Pithos account and retrieving an authentication token" />
+ Description="This Wizard will walk you through adding a new Pithos account and retrieving an authentication token"
+ BackButtonVisibility="Collapsed"
+ FinishButtonVisibility="Collapsed"/>
<extToolkit:WizardPage x:Name="ChooseServer" PageType="Interior"
Title="Where do you want to connect?"
Description="You can connect to the production or development server, or enter your own server URL"
+ FinishButtonVisibility="Collapsed"
CanSelectNextPage="{Binding IsValidServer}"
>
<StackPanel >
<extToolkit:WizardPage x:Name="ChooseMethodPage" PageType="Interior"
Title="How do you want to add the account?"
Description="You can add an account either by logging in the Pithos Web Site or by entering your username and password manually"
+ FinishButtonVisibility="Collapsed"
CanSelectNextPage="False">
<StackPanel >
<RadioButton x:Name="Automatic" Content="By logging to Pithos" Checked="Automatic_Checked" Margin="5"/>
Title="Add an account manually"
Description="Please enter the account credentials and press "Validate Credentials""
NextPage="{Binding ElementName=AccountPathPage}"
+ FinishButtonVisibility="Collapsed"
CanSelectNextPage="{Binding HasValidCredentials}"
>
<extToolkit:BusyIndicator x:Name="ManualBusyIndicator" IsBusy="{Binding IsWorking,NotifyOnSourceUpdated=true}" DisplayAfter="0" >
<Label Content="API Key" Grid.Column="0" Grid.Row="1" Margin="0,5" HorizontalAlignment="Left"/>
<TextBox Name="Token" Grid.Column="1" Grid.Row="1" Margin="5"/>
<Button x:Name="TestManualAccount" Content="Validate Credentials" IsEnabled="{Binding HasCredentials}" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" cal:Message.Attach="TestAccount" Margin="5"/>
+ <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding ValidationMessage}" Margin="10" HorizontalAlignment="Center"/>
</Grid>
</extToolkit:BusyIndicator.Content>
</extToolkit:BusyIndicator>
Title="Add an account automatically"
Description="By clicking on the button below you will be taken to the Pithos web site where you can login with your username and password."
NextPage="{Binding ElementName=AutoConfirmedPage}"
+ FinishButtonVisibility="Collapsed"
CanSelectNextPage="{Binding HasValidCredentials}"
>
<extToolkit:BusyIndicator x:Name="AutoBusyIndicator" IsBusy="{Binding IsWorking}" DisplayAfter="0">
Title="Select Account Path"
Description="Please select the roor path for your account"
NextPage="{Binding ElementName=LastPage}"
+ FinishButtonVisibility="Collapsed"
CanSelectNextPage="{Binding HasAccountPath}"
>
<StackPanel>
}
}
+ private string _validationMessage;
+ public string ValidationMessage
+ {
+ get { return _validationMessage; }
+ set
+ {
+ _validationMessage = value;
+ NotifyOfPropertyChange(()=>ValidationMessage);
+ }
+ }
private bool _isWorking;
public bool IsWorking
{
try
{
- SetBusy("Validating Credentials","");
- var client = new CloudFilesClient(AccountName, Token) {AuthenticationUrl = CurrentServer};
- var containers = await TaskEx.Run(()=>
+ SetBusy("Validating Credentials", "");
+ var client = new CloudFilesClient(AccountName, Token) { AuthenticationUrl = CurrentServer };
+ var containers = await TaskEx.Run(() =>
{
client.Authenticate();
return client.ListContainers(AccountName);
});
- HasValidCredentials = true;
+ HasValidCredentials = true;
+ ValidationMessage = "Credentials Validated";
+ }
+/*
+ catch (AggregateException exc)
+ {
+ exc.Handle(ex=>
+ {
+ HasValidCredentials = false;
+ MessageBox.Show("The account is not valid", "Account Error", MessageBoxButton.OK, MessageBoxImage.Stop);
+ });
}
+*/
catch (Exception ex)
{
HasValidCredentials = false;
MessageBox.Show("The account is not valid", "Account Error", MessageBoxButton.OK, MessageBoxImage.Stop);
- throw;
+ ValidationMessage = "Credentials validation failed";
}
finally
{
{
if (account== null)
return;
-
+ //TODO: What happens to an existing account whose Token has changed?
account.SiteUri= String.Format("{0}/ui/?token={1}&user={2}",
account.SiteUri, account.Token,
account.UserName);
- IProducerConsumerCollection<AccountInfo> accounts = Accounts;
- for (var i = 0; i < _accounts.Count; i++)
- {
- AccountInfo item;
- if (accounts.TryTake(out item))
- {
- if (item.UserName!=account.UserName)
- {
- accounts.TryAdd(item);
- }
- }
- }
+ if (Accounts.All(item => item.UserName != account.UserName))
+ Accounts.TryAdd(account);
- accounts.TryAdd(account);
}
<acceptOnMatch value="false" />
</filter>
</appender>
+ <logger name="NHibernate.SQL" additivity="false">
+ <level value="DEBUG"/>
+ <appender-ref ref="TraceAppender" />
+ </logger>
+
<root>
<level value="DEBUG" />
<appender-ref ref="TraceAppender" />
if (!Directory.Exists(_pithosDataPath))
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()
- {
- /*var stales = from state in FileState.Queryable
- where state.FilePath.StartsWith(@"e:\pithos\cache")
- select state.Id;*/
-/*
- FileState.DeleteAll(@"FilePath like 'e:\pithos\.pithos.cache%'");
- ;
-*/
- }
-
private static InPlaceConfigurationSource GetConfiguration(string pithosDbPath)
{
if (String.IsNullOrWhiteSpace(pithosDbPath))
return false;
}
+ public static bool TryAdd<T>(this ObservableConcurrentCollection<T> collection,T item) where T:class
+ {
+ if (collection==null)
+ throw new ArgumentNullException("collection");
+ Contract.EndContractBlock();
+
+ if (item == null)
+ return false;
+
+ IProducerConsumerCollection<T> items= collection;
+ return items.TryAdd(item);
+ }
+
}
}
\ No newline at end of file
{
private readonly List<string> _knownContainers= new List<string>{"trash"};
public string Name { get; set; }
+
+
public string Hash { get; set; }
+
+ public string X_Object_Hash { get { return Hash; } set { Hash = value; } }
+
+ [JsonProperty("x_object_uuid")]
+ public string UUID { get; set; }
+
public long Bytes { get; set; }
public string Content_Type { get; set; }
public DateTime Last_Modified { get; set; }
public string ContentEncoding { get; set; }
public string Manifest { get; set; }
-
+
public bool IsPublic
{
get { return !String.IsNullOrWhiteSpace(PublicUrl); }
}
}
+ [JsonProperty("X_Object_Public")]
public string PublicUrl { get; set; }
public ObjectInfo()
this.Proxy = other.Proxy;
}
+
+ private WebHeaderCollection _responseHeaders;
+
+ public new WebHeaderCollection ResponseHeaders
+ {
+ get
+ {
+ if (base.ResponseHeaders==null)
+ {
+ return _responseHeaders;
+ }
+ else
+ {
+ _responseHeaders = null;
+ return base.ResponseHeaders;
+ }
+
+ }
+
+ set { _responseHeaders = value; }
+ }
protected override WebRequest GetWebRequest(Uri address)
{
TimedOut = false;
- var webRequest = base.GetWebRequest(address);
+ var webRequest = base.GetWebRequest(address);
var request = (HttpWebRequest)webRequest;
if (IfModifiedSince.HasValue)
request.IfModifiedSince = IfModifiedSince.Value;
public DateTime? IfModifiedSince { get; set; }
+ //Asynchronous version
protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
{
- return ProcessResponse(()=>base.GetWebResponse(request, result));
- }
+ Log.InfoFormat("ASYNC [{0}] {1}",request.Method, request.RequestUri);
+ HttpWebResponse response = null;
+
+ try
+ {
+ response = (HttpWebResponse)base.GetWebResponse(request, result);
+ }
+ catch (WebException exc)
+ {
+ if (!TryGetResponse(exc, out response))
+ throw;
+ }
+
+ StatusCode = response.StatusCode;
+ LastModified = response.LastModified;
+ StatusDescription = response.StatusDescription;
+ return response;
- protected override WebResponse GetWebResponse(WebRequest request)
- {
- return ProcessResponse(() => base.GetWebResponse(request));
}
+
- private WebResponse ProcessResponse(Func<WebResponse> getResponse)
+ //Synchronous version
+ protected override WebResponse GetWebResponse(WebRequest request)
{
+ HttpWebResponse response = null;
try
- {
- var response = (HttpWebResponse)getResponse();
- StatusCode = response.StatusCode;
- LastModified = response.LastModified;
- StatusDescription = response.StatusDescription;
- return response;
+ {
+ response = (HttpWebResponse)base.GetWebResponse(request);
}
catch (WebException exc)
{
- if (exc.Response != null)
- {
- var response = (exc.Response as HttpWebResponse);
- if (AllowedStatusCodes.Contains(response.StatusCode))
- {
- StatusCode = response.StatusCode;
- LastModified = response.LastModified;
- StatusDescription = response.StatusDescription;
+ if (!TryGetResponse(exc, out response))
+ throw;
+ }
- return response;
- }
- if (exc.Response.ContentLength > 0)
- {
- string content = GetContent(exc.Response);
- Log.ErrorFormat(content);
- }
- }
- throw;
+ StatusCode = response.StatusCode;
+ LastModified = response.LastModified;
+ StatusDescription = response.StatusDescription;
+ return response;
+ }
+
+ private bool TryGetResponse(WebException exc, out HttpWebResponse response)
+ {
+ response = null;
+ //Fail on empty response
+ if (exc.Response == null)
+ return false;
+
+ response = (exc.Response as HttpWebResponse);
+ //Succeed on allowed status codes
+ if (AllowedStatusCodes.Contains(response.StatusCode))
+ return true;
+
+ //Does the response have any content to log?
+ if (exc.Response.ContentLength > 0)
+ {
+ var content = GetContent(exc.Response);
+ Log.ErrorFormat(content);
}
+ return false;
}
- private readonly List<HttpStatusCode> _allowedStatusCodes=new List<HttpStatusCode>{HttpStatusCode.NotModified};
+ private readonly List<HttpStatusCode> _allowedStatusCodes=new List<HttpStatusCode>{HttpStatusCode.NotModified};
+
public List<HttpStatusCode> AllowedStatusCodes
{
get
TraceStart(method, uriString);
if (method == "PUT")
request.ContentLength = 0;
+
var response = (HttpWebResponse)GetWebResponse(request);
- StatusCode = response.StatusCode;
- StatusDescription = response.StatusDescription;
+ //var response = (HttpWebResponse)request.GetResponse();
+ //ResponseHeaders= response.Headers;
+
+ LastModified = response.LastModified;
+ StatusCode = response.StatusCode;
+ StatusDescription = response.StatusDescription;
+ response.Close();
return 0;
}, actualRetries);
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Pithos.Setup.x86", "Pithos.Setup.x86\Pithos.Setup.x86.vdproj", "{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetworkTests", "Tests\NetworkTests\NetworkTests.csproj", "{052D04DA-28FE-471F-96FD-BC1E92BF2A54}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug All|Any CPU = Debug All|Any CPU
{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|Mixed Platforms.ActiveCfg = Release
{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|x64.ActiveCfg = Release
{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|x86.ActiveCfg = Release
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Any CPU.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Mixed Platforms.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Mixed Platforms.Build.0 = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x64.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x86.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x86.Build.0 = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x64.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x86.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x86.Build.0 = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Any CPU.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Mixed Platforms.Build.0 = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x64.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x86.ActiveCfg = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x86.Build.0 = Debug|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Any CPU.ActiveCfg = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Mixed Platforms.Build.0 = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x64.ActiveCfg = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x86.ActiveCfg = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x86.Build.0 = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Any CPU.ActiveCfg = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Mixed Platforms.ActiveCfg = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Mixed Platforms.Build.0 = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x64.ActiveCfg = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x86.ActiveCfg = Release|x86
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
{E027200B-C26A-4877-BFD9-1A18CF5DF2F4} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
+ {052D04DA-28FE-471F-96FD-BC1E92BF2A54} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
EndGlobalSection
EndGlobal