Fixes to NetSparkle
authorPanagiotis Kanavos <pkanavos@gmail.com>
Mon, 12 Mar 2012 14:26:58 +0000 (16:26 +0200)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Mon, 12 Mar 2012 14:26:58 +0000 (16:26 +0200)
Fixes to IfModifiedSince calculation
Added console window

33 files changed:
trunk/NetSparkle/NetSparkleAppCaseItem.cs
trunk/NetSparkle/NetSparkleAppCast.cs
trunk/NetSparkle/NetSparkleDownloadProgress.cs
trunk/NetSparkle/NetSparkleForm.cs
trunk/Pithos.AppCast/versioninfo.xml
trunk/Pithos.Client.WPF/App.xaml.cs
trunk/Pithos.Client.WPF/Configuration/PithosSettings.cs
trunk/Pithos.Client.WPF/FileProperties/ContainerPropertiesView.xaml
trunk/Pithos.Client.WPF/FileProperties/FilePropertiesView.xaml
trunk/Pithos.Client.WPF/LogConsole/LogConsoleView.xaml [new file with mode: 0644]
trunk/Pithos.Client.WPF/LogConsole/LogConsoleView.xaml.cs [new file with mode: 0644]
trunk/Pithos.Client.WPF/LogConsole/LogConsoleViewModel.cs [new file with mode: 0644]
trunk/Pithos.Client.WPF/Pithos.Client.WPF.csproj
trunk/Pithos.Client.WPF/Preferences/PreferencesView.xaml
trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
trunk/Pithos.Client.WPF/Properties/AssemblyInfo.cs
trunk/Pithos.Client.WPF/Properties/Settings.Designer.cs
trunk/Pithos.Client.WPF/Properties/Settings.settings
trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchView.xaml
trunk/Pithos.Client.WPF/Shell/AboutView.xaml
trunk/Pithos.Client.WPF/Shell/BalloonIconConverter.cs
trunk/Pithos.Client.WPF/Shell/FeedbackView.xaml
trunk/Pithos.Client.WPF/Shell/MessageView.xaml
trunk/Pithos.Client.WPF/Shell/ShellView.xaml
trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
trunk/Pithos.Client.WPF/app.config
trunk/Pithos.Core/Agents/NetworkAgent.cs
trunk/Pithos.Core/Agents/PollAgent.cs
trunk/Pithos.Core/Agents/StatusAgent.cs
trunk/Pithos.Network/CloudFilesClient.cs
trunk/Pithos.Network/RestClient.cs
trunk/Pithos.Setup.x64/Pithos.Setup.x64.vdproj
trunk/Pithos.Setup.x86/Pithos.Setup.x86.vdproj

index efd5297..d93a6c2 100644 (file)
@@ -16,6 +16,8 @@ namespace AppLimit.NetSparkle
 
         public String DSASignature;
 
+        public String Summary;
+
         #region IComparable<NetSparkleAppCastItem> Members
 
         public int CompareTo(NetSparkleAppCastItem other)
index 40afc93..a1f836c 100644 (file)
@@ -14,6 +14,7 @@ namespace AppLimit.NetSparkle
         private String _castUrl;
 
         private const String itemNode = "item";
+        private const String descriptionNode = "description";
         private const String enclosureNode = "enclosure";
         private const String releaseNotesLinkNode = "sparkle:releaseNotesLink";
         private const String versionAttribute = "sparkle:version";
@@ -45,19 +46,29 @@ namespace AppLimit.NetSparkle
             {
                 if ( reader.NodeType == XmlNodeType.Element)
                 {
-                    switch(reader.Name)
+                    switch (reader.Name)
                     {
                         case itemNode:
                             {
                                 currentItem = new NetSparkleAppCastItem();
                                 break;
                             }
+/*
+                        case descriptionNode:
+                            {
+                                if (currentItem != null)
+                                {
+                                    currentItem.Summary = reader.ReadElementContentAsString();
+                                }
+                                break;
+                            }
+*/
                         case releaseNotesLinkNode:
                             {
                                 currentItem.ReleaseNotesLink = reader.ReadString();
                                 currentItem.ReleaseNotesLink = currentItem.ReleaseNotesLink.Trim('\n');
                                 break;
-                            }                            
+                            }
                         case enclosureNode:
                             {
                                 currentItem.Version = reader.GetAttribute(versionAttribute);
index 393d8cd..de012b0 100644 (file)
@@ -11,11 +11,14 @@ using System.Net;
 using System.IO;
 using System.Diagnostics;
 using System.Reflection;
+using log4net;
 
 namespace AppLimit.NetSparkle
 {
     public partial class NetSparkleDownloadProgress : Form
     {
+        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
         private String _tempName;
         private NetSparkleAppCastItem _item;
         private String _referencedAssembly;
@@ -69,7 +72,22 @@ namespace AppLimit.NetSparkle
         private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
         {
             progressDownload.Visible = false;
-            btnInstallAndReLaunch.Visible = true;            
+            btnInstallAndReLaunch.Visible = true;
+
+            if (e.Error != null)
+            {
+                Log.Error("Update download failed ",e.Error);
+                Size = new Size(Size.Width, 137);
+                lblSecurityHint.Text = "An error occured while downloading the update. Please try again later.";
+                lblSecurityHint.Visible = true;
+                BackColor = Color.Tomato;
+                _sparkle.ReportDiagnosticMessage("Failed downloading file to: " + _tempName);
+                btnInstallAndReLaunch.Click-=btnInstallAndReLaunch_Click;
+                btnInstallAndReLaunch.Text = "Close";
+                btnInstallAndReLaunch.Click+=(s,args)=> Close();
+                btnInstallAndReLaunch.Visible = true;
+                return;
+            }
 
             // report message            
             _sparkle.ReportDiagnosticMessage("Finished downloading file to: " + _tempName);
@@ -129,53 +147,64 @@ namespace AppLimit.NetSparkle
 
         private void btnInstallAndReLaunch_Click(object sender, EventArgs e)
         {
-            // get the commandline 
-            String cmdLine = Environment.CommandLine;
-            String workingDir = Environment.CurrentDirectory;
+            try
+            {
 
-            // generate the batch file path
-            
-            String cmd = Environment.ExpandEnvironmentVariables("%temp%\\" + Guid.NewGuid() + ".cmd");
-            String installerCMD;
+                // get the commandline 
+                String cmdLine = Environment.CommandLine;
+                String workingDir = Environment.CurrentDirectory;
 
-            // get the file type
-            var extension = Path.GetExtension(_tempName).ToLower();
-            switch (extension)
-            {
-                case ".exe":
-                    installerCMD = _tempName;
-                    break;
-                case ".msi":
-                    installerCMD = String.Format("msiexec /i \"{0}\"",_tempName);
-                    break;
-                default:
-                    MessageBox.Show("Updater not supported, please execute " + _tempName + " manually", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
-                    Environment.Exit(-1);
-                    return;
-            }
+                // generate the batch file path
 
-            // generate the batch file                
-            _sparkle.ReportDiagnosticMessage("Generating MSI batch in " + Path.GetFullPath(cmd));
+                String cmd = Environment.ExpandEnvironmentVariables("%temp%\\" + Guid.NewGuid() + ".cmd");
+                String installerCMD;
 
-            using (var write = new StreamWriter(cmd))
-            {
-                write.WriteLine(installerCMD);
-                write.WriteLine("cd " + workingDir);
-                write.WriteLine(cmdLine);
-                write.Close();
-            }
+                // get the file type
+                var extension = Path.GetExtension(_tempName).ToLower();
+                switch (extension)
+                {
+                    case ".exe":
+                        installerCMD = _tempName;
+                        break;
+                    case ".msi":
+                        installerCMD = String.Format("msiexec /i \"{0}\"", _tempName);
+                        break;
+                    default:
+                        MessageBox.Show("Updater not supported, please execute " + _tempName + " manually", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+                        Environment.Exit(-1);
+                        return;
+                }
 
-            // report
-            _sparkle.ReportDiagnosticMessage("Going to execute batch: " + cmd);
+                // generate the batch file                
+                _sparkle.ReportDiagnosticMessage("Generating MSI batch in " + Path.GetFullPath(cmd));
 
-            // start the installer helper
-            var process = new Process();
-            process.StartInfo.FileName = cmd;
-            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;                        
-            process.Start();                        
+                using (var write = new StreamWriter(cmd))
+                {
+                    write.WriteLine(installerCMD);
+                    write.WriteLine("cd " + workingDir);
+                    write.WriteLine(cmdLine);
+                    write.Close();
+                }
 
-            // quit the app
-            Environment.Exit(0);
+                // report
+                _sparkle.ReportDiagnosticMessage("Going to execute batch: " + cmd);
+
+                // start the installer helper
+                var process = new Process();
+                process.StartInfo.FileName = cmd;
+                process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
+                process.Start();
+
+                // quit the app
+                Environment.Exit(0);
+            }
+            catch (Exception exc)
+            {
+                
+                Log.Error("Error while launching the update", exc);
+                this.DialogResult = DialogResult.Cancel;
+                MessageBox.Show("An error occured while executing the update.", "Update failed", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
+            }
         }
     }
 }
index 8406f3a..3d0f42a 100644 (file)
@@ -28,10 +28,17 @@ namespace AppLimit.NetSparkle
             lblInfoText.Text = lblInfoText.Text.Replace("APP", item.AppName + " " + item.Version);
             lblInfoText.Text = lblInfoText.Text.Replace("OLDVERSION", item.AppVersionInstalled);
 
-            if (item.ReleaseNotesLink != null && item.ReleaseNotesLink.Length > 0 )
-                NetSparkleBrowser.Navigate(item.ReleaseNotesLink);
-            else            
-                RemoveReleaseNotesControls();            
+            if (!String.IsNullOrWhiteSpace(item.Summary))
+            {
+                NetSparkleBrowser.DocumentText = "<html><body>" + item.Summary + "</html></body>";
+            }
+            else
+            {
+                if (item.ReleaseNotesLink != null && item.ReleaseNotesLink.Length > 0)
+                    NetSparkleBrowser.Navigate(item.ReleaseNotesLink);
+                else
+                    RemoveReleaseNotesControls();
+            }
 
             if (appIcon != null)
                 imgAppIcon.Image = appIcon;
index 8c57f4a..bdc94dd 100644 (file)
@@ -8,6 +8,7 @@
                <language>en</language>               \r
                <item>            \r
                        <title>Version 0.7.20305</title>\r
+                       <description>Looo</description>\r
                        <sparkle:releaseNotesLink>https://code.grnet.gr/attachments/download/965/rnotes.0.7.20305.html</sparkle:releaseNotesLink>\r
                        <pubDate>Sun, 05 Mar 2012 10:21:11 +0000</pubDate>\r
                        <enclosure \r
index 4105bfe..5f45904 100644 (file)
@@ -51,6 +51,7 @@ using System.Windows;
 using Caliburn.Micro;
 using Pithos.Client.WPF.Properties;
 using log4net.Appender;
+using log4net.Core;
 using log4net.Repository.Hierarchy;
 
 
@@ -100,18 +101,32 @@ namespace Pithos.Client.WPF
             try
             {
                 var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
-                var pithosDataPath= Path.Combine(appDataPath , "GRNET");
+                var pithosDataPath = Path.Combine(appDataPath, "GRNET");
                 if (!Directory.Exists(pithosDataPath))
                     Directory.CreateDirectory(pithosDataPath);
 
                 var loggerRepository = (Hierarchy)log4net.LogManager.GetRepository();
-                
+
                 var appenders = loggerRepository.GetAppenders();
+                
                 var lossyAppender = appenders.OfType<BufferingForwardingAppender>()
-                    .First(appender => appender.Name == "LossyFileAppender");
-                var dumpAppender = lossyAppender.Appenders.OfType<RollingFileAppender>().First();                
-                dumpAppender.File = Path.Combine(pithosDataPath, "errorlog.txt");
-                dumpAppender.ActivateOptions();
+                    .FirstOrDefault(appender => appender.Name == "LossyFileAppender");
+                if (lossyAppender!=null)
+                {
+                    var dumpAppender = lossyAppender.Appenders.OfType<RollingFileAppender>().First();
+                    dumpAppender.File = Path.Combine(pithosDataPath, "errorlog.xml");
+                    dumpAppender.ActivateOptions();
+                }
+                
+                var debugAppender =appenders.OfType<RollingFileAppender>()
+                    .FirstOrDefault(a => a.Name == "DebugFileAppender");
+                if (debugAppender != null)
+                {
+                    debugAppender.File = Path.Combine(pithosDataPath, "debuglog.xml");
+                    if (!Settings.Default.DebugLoggingEnabled)
+                        debugAppender.Threshold = Level.Off;
+                    debugAppender.ActivateOptions();
+                }
             }
             catch (Exception exc)
             {
index 22ecf36..426fc36 100644 (file)
 #endregion
 using System.ComponentModel.Composition;
 using System.Diagnostics;
+using System.IO;
+using System.Linq;
 using Pithos.Client.WPF.Properties;
 using Pithos.Interfaces;
+using log4net.Appender;
+using log4net.Core;
+using log4net.Repository.Hierarchy;
 
 namespace Pithos.Client.WPF.Configuration
 {
@@ -236,6 +241,35 @@ namespace Pithos.Client.WPF.Configuration
             get { return _settings.UpdateForceCheck; }
         }
 
+        public bool DebugLoggingEnabled
+        {
+            get { return _settings.DebugLoggingEnabled; }
+            set
+            {
+                _settings.DebugLoggingEnabled = value;
+
+                SetDebugLevel();
+            }
+        }
+
+        private static void SetDebugLevel()
+        {
+            var loggerRepository = (Hierarchy) log4net.LogManager.GetRepository();
+
+            var appenders = loggerRepository.GetAppenders();
+
+            var debugAppender = appenders.OfType<RollingFileAppender>()
+                .FirstOrDefault(a => a.Name == "DebugFileAppender");
+            if (debugAppender != null)
+            {
+                var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+                var pithosDataPath = Path.Combine(appDataPath, "GRNET");
+                debugAppender.File = Path.Combine(pithosDataPath, "debuglog.xml");
+                debugAppender.Threshold = !Settings.Default.DebugLoggingEnabled ? Level.Off : Level.All;
+                debugAppender.ActivateOptions();
+            }
+        }
+
         public void Save()
         {
             _settings.Save();
index b62f118..f0297a7 100644 (file)
@@ -3,7 +3,7 @@
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cal="http://www.caliburnproject.org"
         xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
         Title="ContainerPropertiesView" Height="500" Width="300"
-        Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png"
+        Icon="/Pithos;component/Images/PithosTaskbar.png"
         Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}">
     <Window.Resources>
         <ResourceDictionary>
@@ -25,7 +25,7 @@
                 <ColumnDefinition Width="*"/>
                 <ColumnDefinition Width="Auto"/>
             </Grid.ColumnDefinitions>
-            <Image x:Name="FileIcon" Margin="5" Grid.Column="0" Stretch="None" Source="/Pithos.Client.WPF;component/Images/Container.png" />
+            <Image x:Name="FileIcon" Margin="5" Grid.Column="0" Stretch="None" Source="/Pithos;component/Images/Container.png" />
             <TextBlock x:Name="ContainerName" Margin="5" Grid.Column="1" Text="Container Name" FontSize="16" FontWeight="Bold"/>
             <TextBlock x:Name="ShortSize" Margin="5" Text="345 KB" FontWeight="Bold" FontSize="14" Grid.Column="2" />
         </Grid>
index 0ccaf27..ad9998b 100644 (file)
@@ -5,7 +5,7 @@
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:cal="http://www.caliburnproject.org"
         xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended" mc:Ignorable="d" 
              d:DesignHeight="300" d:DesignWidth="400"  Width="400"
-         Height="400" Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png"
+         Height="400" Icon="/Pithos;component/Images/PithosTaskbar.png"
         Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}" WindowStartupLocation="CenterScreen" Topmost="False">
     <Window.Resources>
         <ResourceDictionary>
diff --git a/trunk/Pithos.Client.WPF/LogConsole/LogConsoleView.xaml b/trunk/Pithos.Client.WPF/LogConsole/LogConsoleView.xaml
new file mode 100644 (file)
index 0000000..609768b
--- /dev/null
@@ -0,0 +1,20 @@
+<Window x:Class="Pithos.Client.WPF.LogConsole.LogConsoleView"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        Title="LogConsoleView" Height="300" Width="300">
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto"/>
+            <RowDefinition />
+        </Grid.RowDefinitions>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition />
+            <ColumnDefinition Width="Auto"/>
+        </Grid.ColumnDefinitions>
+
+        <Button x:Name="RefreshEvents" Grid.Row="0" Grid.Column="1" Content="Refresh" Margin="5"/>
+        <ListBox x:Name="Events" Grid.Row="1" Grid.ColumnSpan="2" Margin="5">
+            
+        </ListBox>
+    </Grid>
+</Window>
diff --git a/trunk/Pithos.Client.WPF/LogConsole/LogConsoleView.xaml.cs b/trunk/Pithos.Client.WPF/LogConsole/LogConsoleView.xaml.cs
new file mode 100644 (file)
index 0000000..747f198
--- /dev/null
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace Pithos.Client.WPF.LogConsole
+{
+    /// <summary>
+    /// Interaction logic for LogConsoleView.xaml
+    /// </summary>
+    public partial class LogConsoleView : Window
+    {
+        public LogConsoleView()
+        {
+            InitializeComponent();
+        }
+    }
+}
diff --git a/trunk/Pithos.Client.WPF/LogConsole/LogConsoleViewModel.cs b/trunk/Pithos.Client.WPF/LogConsole/LogConsoleViewModel.cs
new file mode 100644 (file)
index 0000000..ce1f568
--- /dev/null
@@ -0,0 +1,65 @@
+// -----------------------------------------------------------------------
+// <copyright file="LogConsoleViewModel.cs" company="Microsoft">
+// TODO: Update copyright text.
+// </copyright>
+// -----------------------------------------------------------------------
+
+using System.ComponentModel.Composition;
+using System.Reflection;
+using Caliburn.Micro;
+using log4net.Appender;
+using log4net.Core;
+using log4net.Repository.Hierarchy;
+
+namespace Pithos.Client.WPF.LogConsole
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Text;
+
+    /// <summary>
+    /// TODO: Update summary.
+    /// </summary>
+    [Export(typeof(LogConsoleViewModel))]
+    public class LogConsoleViewModel:Screen
+    {
+        private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private readonly MemoryAppender _memoryAppender;
+        private IObservableCollection<LoggingEvent> _events;
+
+        public LogConsoleViewModel()
+        {
+            var loggerRepository = (Hierarchy)log4net.LogManager.GetRepository();
+
+            var appenders = loggerRepository.GetAppenders();
+            
+            _memoryAppender= appenders.OfType<MemoryAppender>().FirstOrDefault();
+            if (_memoryAppender == null)
+            {
+                _memoryAppender = new MemoryAppender{Name="MemoryAppender"};
+                _memoryAppender.ActivateOptions();
+                loggerRepository.Root.AddAppender(_memoryAppender);
+                loggerRepository.RaiseConfigurationChanged(EventArgs.Empty);
+            }
+            RefreshEvents();
+        }
+
+        private void RefreshEvents()
+        {
+            Events =new BindableCollection<LoggingEvent>(_memoryAppender.GetEvents());
+        }
+
+        protected IObservableCollection<LoggingEvent> Events
+        {
+            get {
+                return _events;
+            }
+            set {
+                _events = value;
+                NotifyOfPropertyChange(()=>Events);
+            }
+        }
+    }
+}
index f9d9689..9205e4c 100644 (file)
@@ -9,7 +9,7 @@
     <OutputType>WinExe</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>Pithos.Client.WPF</RootNamespace>
-    <AssemblyName>Pithos.Client.WPF</AssemblyName>
+    <AssemblyName>Pithos</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <TargetFrameworkProfile>Client</TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
       <DependentUpon>NewContainerView.xaml</DependentUpon>
     </Compile>
     <Compile Include="FileProperties\NewContainerViewModel.cs" />
+    <Compile Include="LogConsole\LogConsoleView.xaml.cs">
+      <DependentUpon>LogConsoleView.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="LogConsole\LogConsoleViewModel.cs" />
     <Compile Include="PithosException.cs" />
     <Compile Include="Preferences\AccountViewModel.cs" />
     <Compile Include="Preferences\AddAccountView.xaml.cs">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="LogConsole\LogConsoleView.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Preferences\AddAccountView.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
       <Install>true</Install>
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
index 15779f8..ddca716 100644 (file)
@@ -8,7 +8,7 @@
         Title="Pithos Preferences" Height="436" Width="600" 
         ShowInTaskbar="true"
         WindowStartupLocation="CenterScreen"
-        Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png"
+        Icon="/Pithos;component/Images/PithosTaskbar.png"
         Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}">
         
     <Window.Resources>
@@ -40,7 +40,7 @@
             <TabItem VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" x:Name="GeneralTab">
                 <TabItem.Header>
                     <StackPanel>
-                        <Image Source="/Pithos.Client.WPF;component/Images/General.png" Stretch="Uniform" Height="32"/>
+                        <Image Source="/Pithos;component/Images/General.png" Stretch="Uniform" Height="32"/>
                         <TextBlock Text="General"/>
                     </StackPanel>
                 </TabItem.Header>
@@ -54,7 +54,7 @@
             <TabItem VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" x:Name="AccountTab" IsSelected="{Binding AccountTabSelected,Mode=OneWay}">
                 <TabItem.Header>
                     <StackPanel>
-                        <Image Source="/Pithos.Client.WPF;component/Images/Accounts.png" Stretch="Uniform" Height="32"/>
+                        <Image Source="/Pithos;component/Images/Accounts.png" Stretch="Uniform" Height="32"/>
                         <TextBlock Text="Accounts"/>
                     </StackPanel>
                 </TabItem.Header>
@@ -72,7 +72,7 @@
                             <ListBox.ItemTemplate>
                                 <DataTemplate>
                                     <StackPanel Orientation="Horizontal">
-                                    <Image Visibility="{Binding Converter={StaticResource BoolToVisible}, Path=IsExpired,Mode=OneWay}" Source="/Pithos.Client.WPF;component/Images/SmallWarning.png" Margin="2,0"/>
+                                    <Image Visibility="{Binding Converter={StaticResource BoolToVisible}, Path=IsExpired,Mode=OneWay}" Source="/Pithos;component/Images/SmallWarning.png" Margin="2,0"/>
                                     <TextBlock Text="{Binding AccountName}" />
                                     </StackPanel>
                                 </DataTemplate>
             <TabItem VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Visibility="Collapsed" x:Name="RateTab">
                 <TabItem.Header>
                     <StackPanel>
-                        <Image Source="/Pithos.Client.WPF;component/Images/Bandwidth.png" Stretch="Uniform" Height="32"/>
+                        <Image Source="/Pithos;component/Images/Bandwidth.png" Stretch="Uniform" Height="32"/>
                         <TextBlock Text="Bandwidth"/>
                     </StackPanel>
                 </TabItem.Header>
             <TabItem VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" x:Name="ProxyTab">
                 <TabItem.Header>
                     <StackPanel>
-                        <Image Source="/Pithos.Client.WPF;component/Images/Network.png" Stretch="Uniform" Height="32"/>
+                        <Image Source="/Pithos;component/Images/Network.png" Stretch="Uniform" Height="32"/>
                         <TextBlock Text="Proxy"/>
                     </StackPanel>
                 </TabItem.Header>
             <TabItem VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" x:Name="AdvancedTab">
                 <TabItem.Header>
                     <StackPanel>
-                        <Image Source="/Pithos.Client.WPF;component/Images/Advanced.png" Stretch="Uniform" Height="32"/>
+                        <Image Source="/Pithos;component/Images/Advanced.png" Stretch="Uniform" Height="32"/>
                         <TextBlock Text="Advanced"/>                        
                     </StackPanel>
                 </TabItem.Header>
-                <StackPanel>
+                <WrapPanel Orientation="Vertical">
                     <CheckBox Content="Activate Shell Extensions" Height="16" HorizontalAlignment="Left" Margin="5" Name="ExtensionsActivated" VerticalAlignment="Top" />
                     <Button Content="Refresh Overlays" Name="RefreshOverlays" HorizontalAlignment="Left" Margin="5" Style="{StaticResource ButtonStyle}" Width="Auto" />
                     <TextBlock Text="Polling Interval (secs)" Margin="5"/>
                     <extToolkit:IntegerUpDown x:Name="Settings_HashingParallelism" HorizontalAlignment="Left" Width="100" Margin="5,0" Watermark="Enter number of tasks" Minimum="1" />                    
                     <TextBlock Text="Startup Delay (minutes)" Margin="5"/>
                     <extToolkit:IntegerUpDown x:Name="StartupDelay" HorizontalAlignment="Left" Width="100" Margin="5,0" Watermark="Enter number of tasks" Minimum="0" />
+                    <CheckBox Content="Enable Debug Logging" Height="16" HorizontalAlignment="Left" Margin="5,10,5,5" Name="DebugLoggingEnabled" VerticalAlignment="Top"/>
                     <Button x:Name="OpenLogPath" Content="Open Log Path" HorizontalAlignment="Left" Margin="5" Style="{StaticResource ButtonStyle}" Width="Auto"/>
-                </StackPanel>
+                    <Button x:Name="OpenLogConsole" Content="Open Log Console" HorizontalAlignment="Left" Margin="5" Style="{StaticResource ButtonStyle}" Width="Auto" Visibility="Hidden"/>
+                </WrapPanel>
             </TabItem>
         </TabControl>
 
index ef32110..1028e7f 100644 (file)
@@ -264,6 +264,13 @@ namespace Pithos.Client.WPF.Preferences
         {
             Shell.OpenLogPath();
         }
+
+        public void OpenLogConsole()
+        {
+            var logView=IoC.Get<LogConsole.LogConsoleViewModel>();            
+            _windowManager.ShowWindow(logView);
+        }
+
         public void SaveChanges()
         {
             DoSave();
@@ -447,6 +454,14 @@ namespace Pithos.Client.WPF.Preferences
             }
         }
 
+        public bool DebugLoggingEnabled
+        {
+            get { return Settings.DebugLoggingEnabled; }
+            set { 
+                Settings.DebugLoggingEnabled = value;
+                NotifyOfPropertyChange(()=>DebugLoggingEnabled);
+            }
+        }
        
         #endregion
 
index c99192f..bad699e 100644 (file)
@@ -56,7 +56,7 @@ using System.Windows;
 [assembly: AssemblyCopyright("Copyright Â© GRNet 2011-2012")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
-[assembly: AssemblyInformationalVersion("2012-03-07")]
+[assembly: AssemblyInformationalVersion("2012-03-12")]
 
 // Setting ComVisible to false makes the types in this assembly not visible 
 // to COM components.  If you need to access a type in this assembly from 
@@ -93,5 +93,5 @@ using System.Windows;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.7.20305.1")]
-[assembly: AssemblyFileVersionAttribute("0.7.20305.1")]
+[assembly: AssemblyVersion("0.7.20307.0")]
+[assembly: AssemblyFileVersionAttribute("0.7.20307.0")]
index 3037f90..d1baaed 100644 (file)
@@ -322,7 +322,7 @@ namespace Pithos.Client.WPF.Properties {
         [global::System.Configuration.ApplicationScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.WebServiceUrl)]
-        [global::System.Configuration.DefaultSettingValueAttribute("https://github.com/pkanavos/PithosUpdateTest/raw/master/versioninfo.xml")]
+        [global::System.Configuration.DefaultSettingValueAttribute("https://raw.github.com/pkanavos/PithosUpdateTest/master/versioninfo.xml")]
         public string UpdateUrl {
             get {
                 return ((string)(this["UpdateUrl"]));
@@ -370,5 +370,17 @@ namespace Pithos.Client.WPF.Properties {
                 return ((bool)(this["UpdateForceCheck"]));
             }
         }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("False")]
+        public bool DebugLoggingEnabled {
+            get {
+                return ((bool)(this["DebugLoggingEnabled"]));
+            }
+            set {
+                this["DebugLoggingEnabled"] = value;
+            }
+        }
     }
 }
index cb30908..f649008 100644 (file)
@@ -81,7 +81,7 @@
       <Value Profile="(Default)">00:01:00</Value>
     </Setting>
     <Setting Name="UpdateUrl" Type="(Web Service URL)" Scope="Application">
-      <Value Profile="(Default)">https://github.com/pkanavos/PithosUpdateTest/raw/master/versioninfo.xml</Value>
+      <Value Profile="(Default)">https://raw.github.com/pkanavos/PithosUpdateTest/master/versioninfo.xml</Value>
     </Setting>
     <Setting Name="UpdateDiagnostics" Type="System.Boolean" Scope="User">
       <Value Profile="(Default)">False</Value>
@@ -95,5 +95,8 @@
     <Setting Name="UpdateForceCheck" Type="System.Boolean" Scope="Application">
       <Value Profile="(Default)">True</Value>
     </Setting>
+    <Setting Name="DebugLoggingEnabled" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">False</Value>
+    </Setting>
   </Settings>
 </SettingsFile>
\ No newline at end of file
index dd3d6db..9167e89 100644 (file)
@@ -7,7 +7,7 @@
         Title="Selective Synch" Height="300" Width="300" 
         ShowInTaskbar="true"
         WindowStartupLocation="CenterScreen"
-        Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png"
+        Icon="/Pithos;component/Images/PithosTaskbar.png"
         Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}">
     <Window.Resources>
         <ResourceDictionary>
index 724d8ed..af745f2 100644 (file)
@@ -1,7 +1,7 @@
 ï»¿<Window x:Class="Pithos.Client.WPF.Shell.AboutView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-        Title="AboutView" Height="300" Width="300" Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png">
+        Title="AboutView" Height="300" Width="300" Icon="/Pithos;component/Images/PithosTaskbar.png">
     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto"/>
@@ -10,7 +10,7 @@
             <RowDefinition Height="*"/>
             <RowDefinition Height="Auto"/>
         </Grid.RowDefinitions>
-        <Image Grid.Row="0" Source="/Pithos.Client.WPF;component/Images/SmallLogo.png" />
+        <Image Grid.Row="0" Source="/Pithos;component/Images/SmallLogo.png" />
         <TextBlock Grid.Row="0" Text="Pithos " HorizontalAlignment="Center" FontSize="28" FontWeight="Bold" FontFamily="Segoe UI" Width="200" TextWrapping="WrapWithOverflow" TextAlignment="Center" VerticalAlignment="Center"/>
         <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10,0">
             <TextBlock Text="Version" VerticalAlignment="Center"/>
index 7095ca8..3af9f07 100644 (file)
@@ -63,7 +63,7 @@ namespace Pithos.Client.WPF.Shell
 \r
             if (!_iconCache.TryGetValue(icon, out image))\r
             {\r
-                var imagePath = String.Format("/Pithos.Client.WPF;component/Images/{0}.png", Enum.GetName(typeof(BalloonIcon), value));\r
+                var imagePath = String.Format("/Pithos;component/Images/{0}.png", Enum.GetName(typeof(BalloonIcon), value));\r
                 var uri = new Uri(imagePath, UriKind.Relative);\r
                 image=new BitmapImage(uri);\r
                 _iconCache[icon] = image;\r
index fe4c90f..3bcb112 100644 (file)
@@ -1,7 +1,7 @@
 ï»¿<Window x:Class="Pithos.Client.WPF.Shell.FeedbackView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-        Title="FeedbackView" Height="389" Width="455" xmlns:my="clr-namespace:Pithos.Client.WPF.Converters" Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png">
+        Title="FeedbackView" Height="389" Width="455" xmlns:my="clr-namespace:Pithos.Client.WPF.Converters" Icon="/Pithos;component/Images/PithosTaskbar.png">
     <Window.Resources>
         <my:EmptyToVisibilityConverter x:Key="EmptyToVisible" />
     </Window.Resources>
index 013cdc1..dcb8601 100644 (file)
@@ -4,7 +4,7 @@
         Title="MessageView" Height="Auto" Width="500" 
         Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}" 
         WindowStartupLocation="CenterScreen" 
-        Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png"
+        Icon="/Pithos;component/Images/PithosTaskbar.png"
         SizeToContent="Height" xmlns:my="clr-namespace:Microsoft.Windows.Controls.Core.Converters;assembly=WPFToolkit.Extended">
     <Window.CommandBindings>
         <CommandBinding Command="ApplicationCommands.Close"
index 02fa881..485a7f2 100644 (file)
@@ -5,7 +5,7 @@
         xmlns:cal="http://www.caliburnproject.org"
         x:Name="TheView" WindowStartupLocation="CenterScreen" WindowStyle="None"
         Visibility="Collapsed"
-        Width="700" Height="200" SizeToContent="Width" WindowState="Minimized" Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png" xmlns:my="clr-namespace:Pithos.Client.WPF.Converters">
+        Width="700" Height="200" SizeToContent="Width" WindowState="Minimized" Icon="/Pithos;component/Images/PithosTaskbar.png" xmlns:my="clr-namespace:Pithos.Client.WPF.Converters">
 
 <!--
     <Window.Background>
@@ -46,7 +46,7 @@
                             </DataTemplate>
                         </MenuItem.ItemTemplate>                        
                         <MenuItem.Icon>
-                            <Image Source="/Pithos.Client.WPF;component/Images/Folder.ico" />
+                            <Image Source="/Pithos;component/Images/Folder.ico" />
                         </MenuItem.Icon>
                     </MenuItem>
                     <MenuItem Header="Go to Account Site" x:Name="GoToSiteMenu" ItemsSource="{Binding Accounts}" Visibility="{Binding Path=HasAccounts, Converter={StaticResource BooleanToVisible}}" >
@@ -57,7 +57,7 @@
                             </DataTemplate>
                         </MenuItem.ItemTemplate>
                         <MenuItem.Icon>
-                            <Image Source="/Pithos.Client.WPF;component/Images/Web.ico" />
+                            <Image Source="/Pithos;component/Images/Web.ico" />
                         </MenuItem.Icon>
                     </MenuItem>
 
                     <Separator  />
                     <MenuItem  Header="Send Feedback" x:Name="SendFeedback" cal:Message.Attach="SendFeedback">
                         <MenuItem.Icon>
-                            <Image Source="/Pithos.Client.WPF;component/Images/Feedback.ico" />
+                            <Image Source="/Pithos;component/Images/Feedback.ico" />
                         </MenuItem.Icon>
                     </MenuItem>
                     <MenuItem  Header="About Pithos" x:Name="AboutPithos" cal:Message.Attach="AboutPithos">
                         <MenuItem.Icon>
-                            <Image Source="/Pithos.Client.WPF;component/Images/About.ico" />
+                            <Image Source="/Pithos;component/Images/About.ico" />
                         </MenuItem.Icon>
                     </MenuItem>
                     <MenuItem  Header="Check For Upgrade" x:Name="CheckForUpgrade" cal:Message.Attach="CheckForUpgrade"/>
                             </DataTemplate>
                         </MenuItem.HeaderTemplate>
                         <MenuItem.Icon>
-                            <Image Source="/Pithos.Client.WPF;component/Images/Web.ico" />
+                            <Image Source="/Pithos;component/Images/Web.ico" />
                         </MenuItem.Icon>
                     </MenuItem>
                     <Separator  />
             </tb:TaskbarIcon.TrayToolTip>
         </tb:TaskbarIcon>
 <!--
-        <Image Margin="0,0,10,5" Source="/Pithos.Client.WPF;component/Images/logo.png" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="None"/>
+        <Image Margin="0,0,10,5" Source="/Pithos;component/Images/logo.png" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="None"/>
 -->
     </Grid>
 </Window>
index 44be087..54089af 100644 (file)
@@ -200,6 +200,7 @@ namespace Pithos.Client.WPF {
 
         public void CheckForUpgrade()
         {
+            Log.Error("Test Error message");
             _sparkle.StopLoop();
             _sparkle.Dispose();
             _sparkle=new Sparkle(Settings.UpdateUrl);
index 7317223..d8182e7 100644 (file)
                        </dependentAssembly>
                </assemblyBinding>
        </runtime>
+       <!--<appSettings>
+               <add key="log4net.Internal.Debug" value="true" />
+       </appSettings>
+       <system.diagnostics>
+               <trace autoflush="true">
+                       <listeners>
+                               <add name="textWriterTraceListener"
+                                type="System.Diagnostics.TextWriterTraceListener"
+                                initializeData="e:\\temp\\log4net.txt" />
+                       </listeners>
+               </trace>
+       </system.diagnostics>-->
        <userSettings>
                <Pithos.Client.WPF.Properties.Settings>
    <setting name="PithosPath" serializeAs="String">
    <setting name="UpdateCheckInterval" serializeAs="String">
     <value>24.00:00:00</value>
    </setting>
+   <setting name="DebugLoggingEnabled" serializeAs="String">
+    <value>False</value>
+   </setting>
   </Pithos.Client.WPF.Properties.Settings>
        </userSettings>
        <connectionStrings>
     <value>https://pithos.dev.grnet.gr</value>
    </setting>
    <setting name="UpdateUrl" serializeAs="String">
-    <value>https://github.com/pkanavos/PithosUpdateTest/raw/master/versioninfo.xml</value>
+    <value>https://raw.github.com/pkanavos/PithosUpdateTest/master/versioninfo.xml</value>
    </setting>
    <setting name="FileIdleTimeout" serializeAs="String">
     <value>00:00:10</value>
                        <layout type="log4net.Layout.XMLLayout"/>
                </appender>
 
+               <appender name="DebugFileAppender" type="log4net.Appender.RollingFileAppender">
+                       <file value="debuglog.xml" />
+                       <appendToFile value="true" />
+                       <rollingStyle value="Size" />
+                       <maxSizeRollBackups value="10" />
+                       <maximumFileSize value="2MB" />
+                       <staticLogFileName value="true" />
+                       <layout type="log4net.Layout.XMLLayout"/>
+               </appender>
+
                <appender name="OutputDebugStringAppender" type="log4net.Appender.OutputDebugStringAppender" >
                        <layout type="log4net.Layout.PatternLayout">
                                <conversionPattern value="%logger (%property{Operation}) [%level]- %message%newline" />
                                <threshold value="ERROR" />
                        </evaluator>
                        <appender-ref ref="DumpFileAppender" />
+               </appender>
 
+<!--
+               <appender name="LossySmtpAppender" type="log4net.Appender.SmtpAppender">
+                       <to value="pkanavos@gmail.com" />
+                       <from value="pkpithos@gmail.com" />
+                       <subject value="Some subject" />
+                       <smtpHost value="smtp.gmail.com" />
+                       <authentication value="Basic" />
+                       <port value="587" />
+                       <bufferSize value="30" />
+                       <EnableSsl value="true"/>
+                       <lossy value="true" />
+                       <evaluator type="log4net.Core.LevelEvaluator">
+                               <threshold value="ERROR"/>
+                       </evaluator>
+                       <layout type="log4net.Layout.PatternLayout">
+                               <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{Operation}] - %message%newline%newline%newline" />
+                       </layout>
                </appender>
+-->
 
                <logger name="NHibernate" additivity="false">
                        <level value="WARN"/>
                        <appender-ref ref="TraceAppender"/>
                </logger>
 
+<!--
                <logger name="Caliburn" additivity="false">
                        <level value="WARN"/>
                        <appender-ref ref="TraceAppender"/>
                </logger>
+-->
 
                <logger name="Pithos" additivity="false">
                        <level value="DEBUG"/>
 
                <root>
                        <level value="DEBUG" />
+                       <appender-ref ref="DebugFileAppender" />
+<!--
                        <appender-ref ref="LossyFileAppender" />
+                       <appender-ref ref="LossySmtpAppender" />
+-->
                        <appender-ref ref="TraceAppender" />
                        <appender-ref ref="OutputDebugStringAppender" />
                </root>
index 97e5b57..9522521 100644 (file)
@@ -503,7 +503,24 @@ namespace Pithos.Core.Agents
                     if (cloudFile.Content_Type == @"application/directory")
                     {
                         if (!Directory.Exists(localPath))
-                            Directory.CreateDirectory(localPath);
+                            try
+                            {
+                                Directory.CreateDirectory(localPath);
+                                if (Log.IsDebugEnabled)
+                                    Log.DebugFormat("Created Directory [{0}]",localPath);
+                            }
+                            catch (IOException)
+                            {
+                                var localInfo = new FileInfo(localPath);
+                                if (localInfo.Exists && localInfo.Length == 0)
+                                {
+                                    Log.WarnFormat("Malformed directory object detected for [{0}]",localPath);
+                                    localInfo.Delete();
+                                    Directory.CreateDirectory(localPath);
+                                    if (Log.IsDebugEnabled)
+                                        Log.DebugFormat("Created Directory [{0}]", localPath);
+                                }
+                            }
                     }
                     else
                     {
@@ -518,7 +535,7 @@ namespace Pithos.Core.Agents
                                 await
                                     DownloadEntireFileAsync(accountInfo, client, cloudFile, relativeUrl, localPath,
                                                             serverHash);
-                                //Otherwise download it block by block
+                            //Otherwise download it block by block
                             else
                                 await
                                     DownloadWithBlocks(accountInfo, client, cloudFile, relativeUrl, localPath,
@@ -596,7 +613,23 @@ namespace Pithos.Core.Agents
             //Create the local folder if it doesn't exist (necessary for shared objects)
             var localFolder = Path.GetDirectoryName(localPath);
             if (!Directory.Exists(localFolder))
-                Directory.CreateDirectory(localFolder);            
+                try
+                {
+                    Directory.CreateDirectory(localFolder);
+                }
+                catch (IOException)
+                {
+                    //A file may already exist that has the same name as the new folder.
+                    //This may be an artifact of the way Pithos handles directories
+                    var fileInfo = new FileInfo(localFolder);
+                    if (fileInfo.Exists && fileInfo.Length == 0)
+                    {
+                        fileInfo.Delete();
+                        Directory.CreateDirectory(localFolder);
+                    }
+                    else 
+                        throw;
+                }
             //And move it to its actual location once downloading is finished
             if (File.Exists(localPath))
                 File.Replace(tempPath,localPath,null,true);
@@ -705,6 +738,11 @@ namespace Pithos.Core.Agents
                     //
                     if (action.FileState == null)
                         action.FileState = StatusKeeper.GetStateByFilePath(fileInfo.FullName);
+                    if (action.FileState == null)
+                    {
+                        Log.WarnFormat("File [{0}] has no local state. It was probably created by a download action",fileInfo.FullName);
+                        return;
+                    }
                     //Do not upload files in conflict
                     if (action.FileState.FileStatus == FileStatus.Conflict )
                     {
index 23b39b7..3d3cb1b 100644 (file)
@@ -119,18 +119,18 @@ namespace Pithos.Core.Agents
                 {\r
                     UpdateStatus(PithosStatus.PollSyncing);\r
 \r
-                    //Next time we will check for all changes since the current check minus 1 second\r
-                    //This is done to ensure there are no discrepancies due to clock differences\r
-                    var current = DateTime.Now.AddSeconds(-1);\r
-\r
                     var tasks = from accountInfo in _accounts.Values\r
                                 select ProcessAccountFiles(accountInfo, since);\r
 \r
-                    await TaskEx.WhenAll(tasks.ToList());\r
+                    var nextTimes=await TaskEx.WhenAll(tasks.ToList());\r
 \r
                     _firstPoll = false;\r
                     //Reschedule the poll with the current timestamp as a "since" value\r
-                    nextSince = current;\r
+\r
+                    if (nextTimes.Length>0)\r
+                        nextSince = nextTimes.Min();\r
+                    if (Log.IsDebugEnabled)\r
+                        Log.DebugFormat("Next Poll at [{0}]",nextSince);\r
                 }\r
                 catch (Exception ex)\r
                 {\r
@@ -180,7 +180,7 @@ namespace Pithos.Core.Agents
             return since;\r
         }\r
 \r
-        public async Task ProcessAccountFiles(AccountInfo accountInfo, DateTime? since = null)\r
+        public async Task<DateTime?> ProcessAccountFiles(AccountInfo accountInfo, DateTime? since = null)\r
         {\r
             if (accountInfo == null)\r
                 throw new ArgumentNullException("accountInfo");\r
@@ -191,6 +191,7 @@ namespace Pithos.Core.Agents
 \r
             using (log4net.ThreadContext.Stacks["Retrieve Remote"].Push(accountInfo.UserName))\r
             {\r
+\r
                 await NetworkAgent.GetDeleteAwaiter();\r
 \r
                 Log.Info("Scheduled");\r
@@ -204,6 +205,11 @@ namespace Pithos.Core.Agents
 \r
                 CreateContainerFolders(accountInfo, containers);\r
 \r
+                //The nextSince time fallback time is the same as the current.\r
+                //If polling succeeds, the next Since time will be the smallest of the maximum modification times\r
+                //of the shared and account objects\r
+                var nextSince = since;\r
+\r
                 try\r
                 {\r
                     //Wait for any deletions to finish\r
@@ -227,12 +233,17 @@ namespace Pithos.Core.Agents
                         var dict = listTasks.ToDictionary(t => t.AsyncState);\r
 \r
                         //Get all non-trash objects. Remember, the container name is stored in AsyncState\r
-                        var remoteObjects = from objectList in listTasks\r
+                        var remoteObjects = (from objectList in listTasks\r
                                             where (string)objectList.AsyncState != "trash"\r
                                             from obj in objectList.Result\r
-                                            select obj;\r
+                                            select obj).ToList();\r
+                        \r
+                        //Get the latest remote object modification date, only if it is after\r
+                        //the original since date\r
+                        nextSince = GetLatestDateAfter(nextSince, remoteObjects);\r
 \r
                         var sharedObjects = dict["shared"].Result;\r
+                        nextSince = GetLatestDateBefore(nextSince, sharedObjects);\r
 \r
                         //DON'T process trashed files\r
                         //If some files are deleted and added again to a folder, they will be deleted\r
@@ -289,14 +300,52 @@ namespace Pithos.Core.Agents
                 catch (Exception ex)\r
                 {\r
                     Log.ErrorFormat("[FAIL] ListObjects for{0} in ProcessRemoteFiles with {1}", accountInfo.UserName, ex);\r
-                    return;\r
+                    return nextSince;\r
                 }\r
 \r
                 Log.Info("[LISTENER] Finished");\r
-\r
+                return nextSince;\r
             }\r
         }\r
 \r
+        /// <summary>\r
+        /// Returns the latest LastModified date from the list of objects, but only if it is before\r
+        /// than the threshold value\r
+        /// </summary>\r
+        /// <param name="threshold"></param>\r
+        /// <param name="cloudObjects"></param>\r
+        /// <returns></returns>\r
+        private static DateTime? GetLatestDateBefore(DateTime? threshold, IList<ObjectInfo> cloudObjects)\r
+        {\r
+            DateTime? maxDate = null;\r
+            if (cloudObjects!=null &&  cloudObjects.Count > 0)\r
+                maxDate = cloudObjects.Max(obj => obj.Last_Modified);\r
+            if (maxDate == null || maxDate == DateTime.MinValue)\r
+                return threshold;\r
+            if (threshold == null || threshold == DateTime.MinValue || threshold > maxDate)\r
+                return maxDate;\r
+            return threshold;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Returns the latest LastModified date from the list of objects, but only if it is after\r
+        /// the threshold value\r
+        /// </summary>\r
+        /// <param name="threshold"></param>\r
+        /// <param name="cloudObjects"></param>\r
+        /// <returns></returns>\r
+        private static DateTime? GetLatestDateAfter(DateTime? threshold, IList<ObjectInfo> cloudObjects)\r
+        {\r
+            DateTime? maxDate = null;\r
+            if (cloudObjects!=null &&  cloudObjects.Count > 0)\r
+                maxDate = cloudObjects.Max(obj => obj.Last_Modified);\r
+            if (maxDate == null || maxDate == DateTime.MinValue)\r
+                return threshold;\r
+            if (threshold == null || threshold == DateTime.MinValue || threshold < maxDate)\r
+                return maxDate;\r
+            return threshold;\r
+        }\r
+\r
         readonly AccountsDifferencer _differencer = new AccountsDifferencer();\r
         private List<Uri> _selectiveUris=new List<Uri>();\r
 \r
index 27b92b7..df52b11 100644 (file)
@@ -55,9 +55,14 @@ using System.Threading.Tasks;
 using Castle.ActiveRecord;
 using Castle.ActiveRecord.Framework;
 using Castle.ActiveRecord.Framework.Config;
+using NHibernate.ByteCode.Castle;
+using NHibernate.Cfg;
+using NHibernate.Cfg.Loquacious;
+using NHibernate.Dialect;
 using Pithos.Interfaces;
 using Pithos.Network;
 using log4net;
+using Environment = System.Environment;
 
 namespace Pithos.Core.Agents
 {
@@ -76,8 +81,6 @@ namespace Pithos.Core.Agents
         public StatusAgent()
         {            
             var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
-            
-
 
             _pithosDataPath = Path.Combine(appDataPath , "GRNET");
             if (!Directory.Exists(_pithosDataPath))
@@ -87,8 +90,10 @@ namespace Pithos.Core.Agents
 
             MigrateOldDb(dbPath, appDataPath);
 
+
             var source = GetConfiguration(_pithosDataPath);
             ActiveRecordStarter.Initialize(source,typeof(FileState),typeof(FileTag));
+            
             ActiveRecordStarter.UpdateSchema();
 
 
index bd22abb..eb4e615 100644 (file)
@@ -1364,6 +1364,7 @@ namespace Pithos.Network
 
                 client.Headers.Add("X-Move-From", sourceUrl);
                 client.AllowedStatusCodes.Add(HttpStatusCode.NotFound);
+                Log.InfoFormat("[TRASH] [{0}] to [{1}]",sourceUrl,targetUrl);
                 client.PutWithRetry(targetUrl, 3);
 
                 var expectedCodes = new[] {HttpStatusCode.OK, HttpStatusCode.NoContent, HttpStatusCode.Created,HttpStatusCode.NotFound};
index ac96cd6..70b5740 100644 (file)
@@ -157,8 +157,7 @@ namespace Pithos.Network
             }
             catch (WebException exc)
             {
-                Log.WarnFormat("[{0}] {1} {2}", request.Method, exc.Status, request.RequestUri);      
-                if (!TryGetResponse(exc, out response))
+                if (!TryGetResponse(exc, request,out response))
                     throw;
             }
 
@@ -181,8 +180,7 @@ namespace Pithos.Network
             }
             catch (WebException exc)
             {
-                Log.WarnFormat("[{0}] {1} {2}", request.Method, exc.Status,  request.RequestUri);     
-                if (!TryGetResponse(exc, out response))
+                if (!TryGetResponse(exc, request,out response))
                     throw;
             }
 
@@ -192,17 +190,27 @@ namespace Pithos.Network
             return response;
         }
 
-        private bool TryGetResponse(WebException exc, out HttpWebResponse response)
+        private bool TryGetResponse(WebException exc, WebRequest request,out HttpWebResponse response)
         {
             response = null;
             //Fail on empty response
             if (exc.Response == null)
+            {
+                Log.WarnFormat("[{0}] {1} {2}", request.Method, exc.Status, request.RequestUri);     
                 return false;
+            }
 
             response = (exc.Response as HttpWebResponse);
+            var statusCode = (int)response.StatusCode;
             //Succeed on allowed status codes
             if (AllowedStatusCodes.Contains(response.StatusCode))
+            {
+                if (Log.IsDebugEnabled)
+                    Log.DebugFormat("[{0}] {1} {2}", request.Method, statusCode, request.RequestUri);     
                 return true;
+            }
+            
+            Log.WarnFormat("[{0}] {1} {2}", request.Method, statusCode, request.RequestUri);
 
             //Does the response have any content to log?
             if (exc.Response.ContentLength > 0)
index 54fedc8..f58037f 100644 (file)
         }
         "Entry"
         {
-        "MsmKey" = "8:_A952570414DA4B8547D9CD8FEE174CD1"
-        "OwnerKey" = "8:_1BD6A9CD577C40098C968C8B464A03BC"
-        "MsmSig" = "8:_UNDEFINED"
-        }
-        "Entry"
-        {
         "MsmKey" = "8:_B998E7FC1F540278910B0D58694455C2"
         "OwnerKey" = "8:_4C5B93BC82FE5E63E01458A8DA46B4D6"
         "MsmSig" = "8:_UNDEFINED"
             "IsDependency" = "11:TRUE"
             "IsolateTo" = "8:"
             }
-            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A952570414DA4B8547D9CD8FEE174CD1"
-            {
-            "SourcePath" = "8:Pithos.ShellExtensions.tlb"
-            "TargetName" = "8:Pithos.ShellExtensions.tlb"
-            "Tag" = "8:"
-            "Folder" = "8:_FA3E4362540D4C76A5914763C178A3BD"
-            "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}:_B998E7FC1F540278910B0D58694455C2"
             {
             "AssemblyRegister" = "3:1"
         "Name" = "8:Microsoft Visual Studio"
         "ProductName" = "8:Pithos"
         "ProductCode" = "8:{B83227E8-A064-475F-9BC8-38BBFBC55AB8}"
-        "PackageCode" = "8:{7FE3E24C-8949-4EE2-9401-B9E36F09697E}"
+        "PackageCode" = "8:{B73DD858-2392-40D4-96FE-28CEFF8F6F42}"
         "UpgradeCode" = "8:{205365D1-28AA-4322-A46C-FCB37502C6EF}"
         "AspNetVersion" = "8:4.0.30319.0"
         "RestartWWWService" = "11:FALSE"
             "Name" = "8:Uninstall Pithos"
             "Arguments" = "8:[ProductCode]"
             "Description" = "8:"
-            "ShowCmd" = "3:1"
+            "ShowCmd" = "3:7"
             "IconIndex" = "3:32512"
             "Transitive" = "11:FALSE"
             "Target" = "8:_220D09CEABB240EFBF5BB44F9D29E4C7"
index aeff57c..1f50167 100644 (file)
             "Name" = "8:Uninstall Pithos"
             "Arguments" = "8:[ProductCode]"
             "Description" = "8:"
-            "ShowCmd" = "3:1"
+            "ShowCmd" = "3:7"
             "IconIndex" = "3:32512"
             "Transitive" = "11:FALSE"
             "Target" = "8:_F73E036AFAC54F8DB99B8194DE4F11A9"