示例#1
0
        /// <summary>
        /// Generate the sync preview containing actions to be executed.
        /// The returned SyncPreviewResult can then be passed to Synchronize method
        /// as an argument for the actions to be executed.
        /// </summary>
        /// <exception cref="DirectoryNotFoundException"></exception>
        public SyncPreviewResult GenerateSyncPreview(StatusCallbackDelegate statusCallback)
        {
            OnStatusChanged(new SyncStatusChangedEventArgs(m_ResourceManager.GetString("lbl_peparingToSync")));

            // Load actions to be executed.
            IList <SyncAction> actions = actProvider.Load(_job.SyncSource.ID, SourceOption.SOURCE_ID_NOT_EQUALS);

            // Generate current folder's metadata
            FileMetaData currentItems = MetaDataProvider.GenerateFileMetadata(_job.SyncSource.Path, _job.SyncSource.ID, false, statusCallback);

            // Load current folder metadata from database
            FileMetaData oldCurrentItems = mdProvider.LoadFileMetadata(_job.SyncSource.ID, SourceOption.SOURCE_ID_EQUALS);

            // Load the other folder metadata from database
            FileMetaData oldOtherItems = mdProvider.LoadFileMetadata(_job.SyncSource.ID, SourceOption.SOURCE_ID_NOT_EQUALS);

            return(new SyncPreviewResult(actions, currentItems, oldCurrentItems, oldOtherItems));
        }
示例#2
0
        private void SaveActionsAndDirtyFiles(IList <SyncAction> actions)
        {
            FileMetaData fileMetaData = MetaDataProvider.GenerateFileMetadata(_job.IntermediaryStorage.DirtyFolderPath,
                                                                              "", false, true);
            int totalProgress = actions.Count;
            int currProgress  = 0;

            foreach (SyncAction a in actions)
            {
                if (!Validator.SyncJobParamsValidated(_job.Name, _job.IntermediaryStorage.Path, _job.SyncSource.Path, null))
                {
                    return;
                }

                try
                {
                    OnProgressChanged(new SyncProgressChangedEventArgs(++currProgress, totalProgress));
                    OnSyncFileChanged(new SyncFileChangedEventArgs(a.ChangeType, a.RelativeFilePath));

                    FileMetaDataItem item = new FileMetaDataItem("", a.RelativeFilePath, a.FileHash, DateTime.Now, 0, 0);

                    if (a.ChangeType == ChangeType.NEWLY_CREATED && !fileMetaData.MetaDataItems.Contains(item, new FileMetaDataItemComparer()))
                    {
                        SyncExecutor.CopyToDirtyFolderAndUpdateActionTable(a, _job);
                    }
                    else
                    {
                        actProvider.Add(a);
                    }

                    log.Add(new LogActivity(a.RelativeFilePath, a.ChangeType.ToString(), "SUCCESS"));
                }
                catch (OutOfDiskSpaceException)
                {
                    log.Add(new LogActivity(a.RelativeFilePath, a.ChangeType.ToString(), "FAIL"));
                    throw;
                }
                catch (Exception)
                {
                    log.Add(new LogActivity(a.RelativeFilePath, a.ChangeType.ToString(), "FAIL"));
                    throw;
                }
            }
        }
示例#3
0
        public static FileMetaData GenerateFileMetadata(string fromPath, string id, bool excludeHidden, StatusCallbackDelegate statusCallback)
        {
            FileMetaData fileMetadata = new FileMetaData(id, fromPath);

            DirectoryInfo di = new DirectoryInfo(fromPath);

            AddDirectorySecurity(fromPath);

            FileInfo[] files = null;

            if (statusCallback != null)
            {
                statusCallback("Reading files from: " + fromPath);
            }

            files = di.GetFiles("*.*", SearchOption.AllDirectories);

            if (files == null)
            {
                return(new FileMetaData(id, fromPath));
            }
            IEnumerable <FileInfo> noHiddenFiles = from file in files
                                                   where excludeHidden ? !Files.FileUtils.IsFileHidden(file.FullName) : true
                                                   select file;

            files = noHiddenFiles.ToArray <FileInfo>();

            foreach (FileInfo f in files)
            {
                try
                {
                    if (statusCallback != null)
                    {
                        statusCallback(string.Format("Processing file: {0}", f.FullName));
                    }

                    fileMetadata.MetaDataItems.Add(new FileMetaDataItem(id,
                                                                        OneSync.Files.FileUtils.GetRelativePath(fromPath, f.FullName), Files.FileUtils.GetFileHash(f.FullName),
                                                                        f.LastWriteTime, (uint)0, (uint)0));
                }catch (Exception) { }
            }
            return(fileMetadata);
        }
示例#4
0
        private void GeneratePreview(FileMetaData currentMetadata, FileMetaData oldCurrentMetadata)
        {
            //By comparing current metadata and the old metadata from previous sync of a sync folder
            //we could know the dirty items of the folder.
            var comparerCurrent     = new FileMetaDataComparer(currentMetadata, oldCurrentMetadata);
            var dirtyItemsInCurrent = new List <FileMetaDataItem>();

            dirtyItemsInCurrent.AddRange(comparerCurrent.LeftOnly);
            dirtyItemsInCurrent.AddRange(comparerCurrent.BothModified);

            //Compare the _actions and dirty items in current folder. Collision is detected when
            //2 items in 2 collection have same relative path but different hashes.
            IEnumerable <SyncAction> conflictItems = from action in _actions
                                                     join dirtyInCurrent in dirtyItemsInCurrent on
                                                     action.RelativeFilePath equals dirtyInCurrent.RelativePath
                                                     where !action.FileHash.Equals(dirtyInCurrent.HashCode)
                                                     select action;

            foreach (SyncAction action in conflictItems)
            {
                action.ConflictResolution = ConflictResolution.DUPLICATE_RENAME;
            }

            IEnumerable <SyncAction> itemsToDelete = from action in _actions
                                                     where action.ChangeType == ChangeType.DELETED
                                                     select action;

            IEnumerable <SyncAction> itemsToCopyOver = from action in _actions
                                                       where action.ChangeType == ChangeType.NEWLY_CREATED &&
                                                       !conflictItems.Contains(action)
                                                       select action;

            IEnumerable <SyncAction> itemsToRename = from action in _actions
                                                     where action.ChangeType == ChangeType.RENAMED &&
                                                     !conflictItems.Contains(action)
                                                     select action;

            ConflictItems   = conflictItems.ToList();
            ItemsToCopyOver = itemsToCopyOver.ToList();
            ItemsToDelete   = itemsToDelete.ToList();
            ItemsToRename   = itemsToRename.ToList();
        }
示例#5
0
        /// <summary>
        /// Generates SyncActions to be executed by other PC by comparing the metadata
        /// of current SyncSource and the metadata of other PC.
        /// </summary>
        private IList <SyncAction> GenerateActions()
        {
            //Metadata mdCurrent = UpdateSyncSourceMetadata();
            //Metadata mdOther = mdProvider.Load(_job.SyncSource.ID, SourceOption.SOURCE_ID_NOT_EQUALS);
            FileMetaData mdCurrent = MetaDataProvider.GenerateFileMetadata(
                _job.SyncSource.Path, _job.SyncSource.ID, false, false);

            FileMetaData mdOldCurrent = mdProvider.LoadFileMetadata(_job.SyncSource.ID, SourceOption.SOURCE_ID_EQUALS);

            mdProvider.UpdateFileMetadata(mdOldCurrent, mdCurrent);

            FileMetaData mdOther = mdProvider.LoadFileMetadata(_job.SyncSource.ID, SourceOption.SOURCE_ID_NOT_EQUALS);
            //generate list of sync actions by comparing 2 metadata
            var differences = new FileMetaDataComparer(mdCurrent, mdOther);

            return(actProvider.Generate(mdCurrent.SourceId,
                                        differences.LeftOnly,
                                        differences.RightOnly,
                                        differences.BothModified));
        }
示例#6
0
        private void Compare(FileMetaData left, FileMetaData right)
        {
            FileMetaDataItemComparer comparer = new FileMetaDataItemComparer();

            var rightOnly = from i in right.MetaDataItems
                            where !left.MetaDataItems.Contains(i, comparer)
                            select i;

            var leftOnly = from i in left.MetaDataItems
                           where !right.MetaDataItems.Contains(i, comparer)
                           select i;

            var both = from l in left.MetaDataItems
                       join r in right.MetaDataItems
                       on l.RelativePath equals r.RelativePath
                       where l.HashCode != r.HashCode
                       select l;

            this.LeftOnly = new List<FileMetaDataItem>(leftOnly);
            this.RightOnly = new List<FileMetaDataItem>(rightOnly);
            this.BothModified = new List<FileMetaDataItem>(both);
        }
示例#7
0
        private void GeneratePreview(FileMetaData currentMetadata, FileMetaData oldCurrentMetadata)
        {
            //By comparing current metadata and the old metadata from previous sync of a sync folder
            //we could know the dirty items of the folder.
            var comparerCurrent = new FileMetaDataComparer(currentMetadata, oldCurrentMetadata);
            var dirtyItemsInCurrent = new List<FileMetaDataItem>();
            dirtyItemsInCurrent.AddRange(comparerCurrent.LeftOnly);
            dirtyItemsInCurrent.AddRange(comparerCurrent.BothModified);

            //Compare the _actions and dirty items in current folder. Collision is detected when
            //2 items in 2 collection have same relative path but different hashes.
            IEnumerable<SyncAction> conflictItems = from action in _actions
                                                    join dirtyInCurrent in dirtyItemsInCurrent on
                                                        action.RelativeFilePath equals dirtyInCurrent.RelativePath
                                                    where !action.FileHash.Equals(dirtyInCurrent.HashCode)
                                                    select action;

            foreach (SyncAction action in conflictItems)
                action.ConflictResolution = ConflictResolution.DUPLICATE_RENAME;

            IEnumerable<SyncAction> itemsToDelete = from action in _actions
                                                    where action.ChangeType == ChangeType.DELETED
                                                    select action;

            IEnumerable<SyncAction> itemsToCopyOver = from action in _actions
                                                      where action.ChangeType == ChangeType.NEWLY_CREATED
                                                      && !conflictItems.Contains(action)
                                                      select action;

            IEnumerable<SyncAction> itemsToRename = from action in _actions
                                                    where action.ChangeType == ChangeType.RENAMED
                                                    && !conflictItems.Contains(action)
                                                    select action;

            ConflictItems = conflictItems.ToList();
            ItemsToCopyOver = itemsToCopyOver.ToList();
            ItemsToDelete = itemsToDelete.ToList();
            ItemsToRename = itemsToRename.ToList();
        }
示例#8
0
        private void Compare(FileMetaData left, FileMetaData right)
        {
            FileMetaDataItemComparer comparer = new FileMetaDataItemComparer();

            var rightOnly = from i in right.MetaDataItems
                            where !left.MetaDataItems.Contains(i, comparer)
                            select i;


            var leftOnly = from i in left.MetaDataItems
                           where !right.MetaDataItems.Contains(i, comparer)
                           select i;

            var both = from l in left.MetaDataItems
                       join r in right.MetaDataItems
                       on l.RelativePath equals r.RelativePath
                       where l.HashCode != r.HashCode
                       select l;

            this.LeftOnly     = new List <FileMetaDataItem>(leftOnly);
            this.RightOnly    = new List <FileMetaDataItem>(rightOnly);
            this.BothModified = new List <FileMetaDataItem>(both);
        }
示例#9
0
 public FileMetaDataComparer(FileMetaData left, FileMetaData right)
 {
     Compare(left, right);
 }
示例#10
0
 public SyncPreviewResult(IList <SyncAction> actions, FileMetaData currentMetadata,
                          FileMetaData oldCurrentMetadata, FileMetaData oldOtherMetadata)
 {
     this._actions = actions;
     GeneratePreview(currentMetadata, oldCurrentMetadata);
 }
示例#11
0
        public override bool UpdateFileMetadata(FileMetaData oldMetadata, FileMetaData newMetadata)
        {
            //Sort list of metadata items before search using linq
            oldMetadata.MetaDataItems.ToList().Sort(new FileMetaDataItemComparer());
            newMetadata.MetaDataItems.ToList().Sort(new FileMetaDataItemComparer());

            var mdComparer = new FileMetaDataComparer(oldMetadata, newMetadata);

            var db = new SQLiteAccess(Path.Combine(this.StoragePath, Configuration.DATABASE_NAME),false);
            using (SqliteConnection con = db.NewSQLiteConnection())
            {
                if (con == null)
                    throw new DatabaseException(String.Format(m_ResourceManager.GetString("err_somethingNotFound"), Path.Combine(this.StoragePath, Configuration.DATABASE_NAME)));
                var transaction = (SqliteTransaction)con.BeginTransaction();
                try
                {
                    this.Add(mdComparer.RightOnly.ToList(), con);
                    this.Delete(mdComparer.LeftOnly.ToList(), con);
                    this.Update(mdComparer.BothModified.ToList(), con);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    return false;
                }
            }
            return true;
        }
示例#12
0
 /// <summary>
 /// Add metadata infomation.
 /// </summary>
 /// <param name="mData">Metadata to be added.</param>
 /// <returns>true if added and saved successfully.</returns>
 public abstract bool Add(FileMetaData mData);
示例#13
0
 public override bool Add(FileMetaData mData)
 {
     return this.Add(mData.MetaDataItems);
 }
示例#14
0
 /// <summary>
 /// Add metadata infomation.
 /// </summary>
 /// <param name="mData">Metadata to be added.</param>
 /// <returns>true if added and saved successfully.</returns>
 public abstract bool Add(FileMetaData mData);
示例#15
0
 public SyncPreviewResult(IList<SyncAction> actions, FileMetaData currentMetadata,
     FileMetaData oldCurrentMetadata, FileMetaData oldOtherMetadata)
 {
     this._actions = actions;
     GeneratePreview(currentMetadata, oldCurrentMetadata);
 }
示例#16
0
文件: Metadata.cs 项目: mbsky/onesync
 public Metadata(FileMetaData fileMetadata, FolderMetadata folderMetadata)
 {
     this.FileMetadata   = fileMetadata;
     this.FolderMetadata = folderMetadata;
 }
示例#17
0
        public static FileMetaData GenerateFileMetadata(string fromPath, string id, bool excludeHidden, StatusCallbackDelegate statusCallback)
        {
            FileMetaData fileMetadata = new FileMetaData(id, fromPath);

            DirectoryInfo di = new DirectoryInfo(fromPath);

            AddDirectorySecurity(fromPath);

            FileInfo[] files = null;

            if (statusCallback != null) statusCallback("Reading files from: " + fromPath);

            files = di.GetFiles("*.*", SearchOption.AllDirectories);

            if (files == null) return new FileMetaData(id, fromPath);
            IEnumerable<FileInfo> noHiddenFiles = from file in files
                                                  where excludeHidden ? !Files.FileUtils.IsFileHidden(file.FullName) : true
                                                  select file;
            files = noHiddenFiles.ToArray<FileInfo>();

            foreach (FileInfo f in files)
            {
                try
                {
                    if (statusCallback != null) statusCallback(string.Format("Processing file: {0}", f.FullName));

                    fileMetadata.MetaDataItems.Add(new FileMetaDataItem(id,
                        OneSync.Files.FileUtils.GetRelativePath(fromPath, f.FullName), Files.FileUtils.GetFileHash(f.FullName),
                        f.LastWriteTime, (uint)0, (uint)0));
                }catch(Exception){ }
            }
            return fileMetadata;
        }
示例#18
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="oldItems"></param>
 /// <param name="newItems"></param>
 /// <returns></returns>
 public abstract bool UpdateFileMetadata(FileMetaData oldItems, FileMetaData newItems);
示例#19
0
 public FileMetaDataComparer(FileMetaData left, FileMetaData right)
 {
     Compare(left, right);
 }
示例#20
0
 public override bool Add(FileMetaData mData)
 {
     return(this.Add(mData.MetaDataItems));
 }
示例#21
0
        private bool UpdateFileMetadata(FileMetaData oldMetadata, FileMetaData newMetadata, SqliteConnection con)
        {
            //Sort list of metadata items before search using linq
            oldMetadata.MetaDataItems.ToList().Sort(new FileMetaDataItemComparer());
            newMetadata.MetaDataItems.ToList().Sort(new FileMetaDataItemComparer());

            //Get newly created items by comparing relative paths
            //newOnly is metadata item in current metadata but not in old one
            IEnumerable<FileMetaDataItem> newOnly =
                newMetadata.MetaDataItems.Where(
                    @new => !oldMetadata.MetaDataItems.Contains(@new, new FileMetaDataItemComparer()));

            //Get deleted items
            IEnumerable<FileMetaDataItem> oldOnly =
                oldMetadata.MetaDataItems.Where(
                    old => !newMetadata.MetaDataItems.Contains(old, new FileMetaDataItemComparer()));

            //get the items from 2 metadata with same relative paths but different hashes.
            IEnumerable<FileMetaDataItem> bothModified = newMetadata.MetaDataItems.SelectMany(
                @new => oldMetadata.MetaDataItems, (@new, old) => new {@new, old}).Where(
                @t => @[email protected]((@t.old).RelativePath)
                      && !@[email protected](@t.old.HashCode)).Select(@t => @t.@new);

            try
            {
                this.Add(newOnly.ToList(), con);
                this.Delete(oldOnly.ToList(), con);
                this.Update(bothModified.ToList(), con);
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }
示例#22
0
 public Metadata(FileMetaData fileMetadata, FolderMetadata folderMetadata)
 {
     this.FileMetadata = fileMetadata;
     this.FolderMetadata = folderMetadata;
 }
示例#23
0
        public override FileMetaData LoadFileMetadata(string currId, SourceOption option)
        {
            string opt = (option == SourceOption.SOURCE_ID_NOT_EQUALS) ? " <> " : " = ";
            var mData = new FileMetaData(currId, RootPath);

            var db = new SQLiteAccess(Path.Combine(this.StoragePath, Configuration.DATABASE_NAME),false);
            using (SqliteConnection con = db.NewSQLiteConnection())
            {
                if (con == null)
                    throw new DatabaseException(String.Format(m_ResourceManager.GetString("err_somethingNotFound"), Path.Combine(this.StoragePath, Configuration.DATABASE_NAME)));

                string cmdText = string.Format("SELECT * FROM {0} WHERE {1}{2} @sourceId", Configuration.TBL_METADATA, Configuration.COL_SOURCE_ID, opt);

                var paramList = new SqliteParameterCollection
                                                          {
                                                              new SqliteParameter("@sourceId", DbType.String)
                                                                  {Value = currId}
                                                          };

                db.ExecuteReader(cmdText, paramList, reader => mData.MetaDataItems.Add(new FileMetaDataItem(
                                                                                           (string) reader[Configuration.COL_SOURCE_ID],
                                                                                           (string) reader[Configuration.COL_RELATIVE_PATH],
                                                                                           (string) reader[Configuration.COL_HASH_CODE],
                                                                                           (DateTime) reader[Configuration.COL_LAST_MODIFIED_TIME],
                                                                                           Convert.ToUInt32(reader[Configuration.COL_NTFS_ID1]),
                                                                                           Convert.ToUInt32(reader[Configuration.COL_NTFS_ID2]))));
            }
            return mData;
        }