Revision 2edb4807

b/trunk/Pithos.Client.WPF/Properties/AssemblyInfo.cs
53 53
// by using the '*' as shown below:
54 54
// [assembly: AssemblyVersion("1.0.*")]
55 55
[assembly: AssemblyVersion("0.1.0.0")]
56
[assembly: AssemblyFileVersionAttribute("0.1.20206.1972")]
56
[assembly: AssemblyFileVersionAttribute("0.1.20209.1999")]
b/trunk/Pithos.Core/Agents/CloudTransferAction.cs
44 44
            Contract.Invariant(AccountInfo!=null);
45 45
        }
46 46

  
47
        public bool IsShared
48
        {
49
            get { return  CloudFile!=null && AccountInfo.UserName != CloudFile.Account; }
50
        }
51

  
47 52
        protected CloudAction(AccountInfo accountInfo,CloudActionType action)
48 53
        {
49 54
            if (accountInfo==null)
b/trunk/Pithos.Core/Agents/NetworkAgent.cs
642 642
            }
643 643
        }
644 644

  
645
        internal class ObjectInfoComparer:EqualityComparer<ObjectInfo>
646
        {
647
            public override bool Equals(ObjectInfo x, ObjectInfo y)
648
            {
649
                return (x.Account == y.Account &&
650
                        x.Container == y.Container &&
651
                        x.Name == y.Name);
652
            }
653

  
654
            public override int GetHashCode(ObjectInfo obj)
655
            {
656
                return String.Join("/",obj.Account,obj.Container,obj.Name).GetHashCode();
657
            }
658
        }
659

  
660
        Dictionary<string, List<ObjectInfo>> _currentSnapshot = new Dictionary<string, List<ObjectInfo>>();
661
        Dictionary<string, List<ObjectInfo>> _previousSnapshot = new Dictionary<string, List<ObjectInfo>>();
662

  
645 663
        /// <summary>
646 664
        /// Deletes local files that are not found in the list of cloud files
647 665
        /// </summary>
......
658 676
                throw new ArgumentNullException("cloudFiles");
659 677
            Contract.EndContractBlock();
660 678

  
661
            //Check the Modified date to ensure that were just created and haven't been uploaded yet
662
            //NOTE: The NHibernate LINQ provider doesn't support custom functions so we need to break the query 
663
            //in two steps
664
            //NOTE: DON'T return files that are already in conflict. The first poll would mark them as 
665
            //"In Conflict" but subsequent polls would delete them
666
/*            var t=FileState.Find(new Guid("{cd664c9a-5f17-47c9-b27f-3bcbcb0595ff}"));
679
            if (_previousSnapshot.ContainsKey(accountInfo.UserName) && _currentSnapshot.ContainsKey(accountInfo.UserName))
680
                _previousSnapshot[accountInfo.UserName] = _currentSnapshot[accountInfo.UserName] ?? new List<ObjectInfo>();
681
            else
682
            {
683
                _previousSnapshot[accountInfo.UserName]=new List<ObjectInfo>();
684
            }
667 685

  
668
            var d0 = FileState.Queryable
669
                .Where(state => 
670
                            state.FilePath.StartsWith(accountInfo.AccountPath)).ToList();
671
            
672
            var d1 = FileState.Queryable
673
                .Where(state => state.Modified <= pollTime).ToList();
674
            var d2= FileState.Queryable
675
                .Where(state => state.Modified <= pollTime
676
                            &&
677
                            state.FilePath.StartsWith(accountInfo.AccountPath)).ToList();*/
678

  
679
            //Consider for deleteion only files modified before the PREVIOUS poll
680
            //A user may perform a file creation or rename at roughly the same time as a poll. In such a case
681
            //the new file will appear as deleted
682
            var previousPollTime = pollTime.Subtract(TimeSpan.FromMilliseconds(Settings.PollingInterval));                       
683

  
684
            //Only consider files that are not being modified, ie they are in the Unchanged state            
685
            var deleteCandidates = FileState.Queryable.Where(state => 
686
                state.Modified <= previousPollTime
687
                && state.FilePath.StartsWith(accountInfo.AccountPath)                
688
                && state.FileStatus == FileStatus.Unchanged).ToList();
689

  
690
            //TODO: filesToDelete must take into account the Others container            
691
            var filesToDelete = (from deleteCandidate in deleteCandidates 
692
                         let localFile = FileInfoExtensions.FromPath(deleteCandidate.FilePath) 
693
                         let relativeFilePath = localFile.AsRelativeTo(accountInfo.AccountPath) 
694
                         let agentActions = _agent.GetEnumerable()
695
                         where 
696
                                 !_lastSeen.ContainsKey(localFile.FullName)
697
                         && !cloudFiles.Any(r => r.RelativeUrlToFilePath(accountInfo.UserName) == relativeFilePath ) 
698
                         //Exclude files enqueued for uploading
699
                         //Large files will not appear on the server for multiple polls. They must not be marked as deleted
700
                         && !agentActions.Any(action => action.LocalFile.WithProperCapitalization().FullName == localFile.FullName)
701
                         //Do NOT delete files modified since the previous poll
702
                                && localFile.LastAccessTime < previousPollTime
703
                         select localFile).ToList();
704
            
686
            _currentSnapshot[accountInfo.UserName] = cloudFiles.ToList();
687

  
688
            var deletedObjects = _previousSnapshot[accountInfo.UserName].Except(_currentSnapshot[accountInfo.UserName], new ObjectInfoComparer()).ToList();
705 689

  
690
            
706 691
            //On the first run
707 692
            if (_firstPoll)
708 693
            {
694
                //Only consider files that are not being modified, ie they are in the Unchanged state            
695
                var deleteCandidates = FileState.Queryable.Where(state =>
696
                    state.FilePath.StartsWith(accountInfo.AccountPath)
697
                    && state.FileStatus == FileStatus.Unchanged).ToList();
698

  
699

  
700
                //TODO: filesToDelete must take into account the Others container            
701
                var filesToDelete = (from deleteCandidate in deleteCandidates
702
                                         let localFile = FileInfoExtensions.FromPath(deleteCandidate.FilePath)
703
                                         let relativeFilePath = localFile.AsRelativeTo(accountInfo.AccountPath)
704
                                     where
705
                                         !cloudFiles.Any(r => r.RelativeUrlToFilePath(accountInfo.UserName) == relativeFilePath)
706
                                     select localFile).ToList();
707
            
708

  
709

  
709 710
                //Set the status of missing files to Conflict
710 711
                foreach (var item in filesToDelete)
711 712
                {
......
720 721
                }
721 722
                UpdateStatus(PithosStatus.HasConflicts);
722 723
                StatusNotification.NotifyConflicts(filesToDelete, String.Format("{0} local files are missing from Pithos, possibly because they were deleted",filesToDelete.Count));
724
                StatusNotification.NotifyForFiles(filesToDelete, String.Format("{0} files were deleted", filesToDelete.Count), TraceLevel.Info);
723 725
            }
724 726
            else
725 727
            {
726
                foreach (var item in filesToDelete)
728
                var deletedFiles = new List<FileSystemInfo>();
729
                foreach (var objectInfo in deletedObjects)
727 730
                {
731
                    var relativePath = objectInfo.RelativeUrlToFilePath(accountInfo.UserName);
732
                    var item = GetFileAgent(accountInfo).GetFileSystemInfo(relativePath);
728 733
                    if (item.Exists)
729 734
                    {
730 735
                        //Try to acquire a gate on the file, to take into account files that have been dequeued
731 736
                        //and are being processed
732 737
                        //TODO: The gate is not enough. Perhaps we need to keep a journal of processed files and check against
733 738
                        //that as well.
739
/*
734 740
                        using (var gate = NetworkGate.Acquire(item.FullName, NetworkOperation.Deleting))
735 741
                        {
736 742
                            if (gate.Failed)
737 743
                                continue;
744
*/
738 745
                            if ((item.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
739 746
                            {
740 747
                                item.Attributes = item.Attributes & ~FileAttributes.ReadOnly;
741 748

  
742 749
                            }
743 750
                            item.Delete();
751
                            DateTime lastDate;
752
                            _lastSeen.TryRemove(item.FullName, out lastDate);
753
                            deletedFiles.Add(item);
754
/*
744 755
                        }
756
*/
745 757
                    }
746 758
                    StatusKeeper.ClearFileStatus(item.FullName);
759
                    
747 760
                }
748
                StatusNotification.NotifyForFiles(filesToDelete, String.Format("{0} files were deleted",filesToDelete.Count),TraceLevel.Info);
761
                StatusNotification.NotifyForFiles(deletedFiles, String.Format("{0} files were deleted", deletedFiles.Count), TraceLevel.Info);
749 762
            }
750 763

  
751 764
        }
......
1236 1249

  
1237 1250
        }
1238 1251

  
1252
        //Returns true if an action concerns a file that was deleted
1239 1253
        private bool IsDeletedFile(CloudAction action)
1240
        {            
1254
        {
1255
            //Doesn't work for actions targeting shared files
1256
            if (action.IsShared)
1257
                return false;
1241 1258
            var key = GetFileKey(action.CloudFile);
1242 1259
            DateTime entryDate;
1243 1260
            if (_deletedFiles.TryGetValue(key, out entryDate))

Also available in: Unified diff