private bool TryGetExtendedAttribute(IFileSystemInfo fsInfo, out Guid guid) { string ea = fsInfo.GetExtendedAttribute(MappedObject.ExtendedAttributeKey); if (!string.IsNullOrEmpty(ea) && Guid.TryParse(ea, out guid)) { return(true); } else { guid = Guid.Empty; return(false); } }
private Guid WriteOrUseUuidIfSupported(IFileSystemInfo localFile) { Guid uuid = Guid.Empty; if (localFile.IsExtendedAttributeAvailable()) { try { string ea = localFile.GetExtendedAttribute(MappedObject.ExtendedAttributeKey); if (ea == null || !Guid.TryParse(ea, out uuid) || this.Storage.GetObjectByGuid(uuid) != null) { uuid = Guid.NewGuid(); localFile.SetExtendedAttribute(MappedObject.ExtendedAttributeKey, uuid.ToString(), true); } } catch (ExtendedAttributeException ex) { throw new RetryException(ex.Message, ex); } } return(uuid); }
private bool DeleteLocalObjectIfHasBeenSyncedBefore(IMetaDataStorage storage, IFileSystemInfo fsInfo) { bool delete = true; string reason; Guid uuid; IMappedObject obj = null; if (Guid.TryParse(fsInfo.GetExtendedAttribute(MappedObject.ExtendedAttributeKey), out uuid)) { obj = storage.GetObjectByGuid(uuid); } else { obj = storage.GetObjectByLocalPath(fsInfo); } if (fsInfo is IFileInfo) { if (obj != null && fsInfo.LastWriteTimeUtc.Equals(obj.LastLocalWriteTimeUtc)) { (fsInfo as IFileInfo).Delete(); OperationsLogger.Info(string.Format("Deleted local file {0} because the mapped remote object {0} has been deleted", fsInfo.FullName, obj.RemoteObjectId)); } else { fsInfo.SetExtendedAttribute(MappedObject.ExtendedAttributeKey, null, true); return(false); } } else if (fsInfo is IDirectoryInfo) { var dir = fsInfo as IDirectoryInfo; if (!this.filters.FolderNamesFilter.CheckFolderName(dir.Name, out reason)) { foreach (var folder in dir.GetDirectories()) { if (!this.DeleteLocalObjectIfHasBeenSyncedBefore(storage, folder)) { delete = false; } } foreach (var file in dir.GetFiles()) { if (!this.filters.FileNamesFilter.CheckFile(file.Name, out reason)) { if (!this.DeleteLocalObjectIfHasBeenSyncedBefore(storage, file)) { delete = false; } } else { file.Delete(); OperationsLogger.Info(string.Format("Deleted local ignored file {0} because the mapped remote parent object {0} has been deleted", fsInfo.FullName, obj.RemoteObjectId)); } } if (delete) { try { (fsInfo as IDirectoryInfo).Delete(false); OperationsLogger.Info(string.Format("Deleted local folder {0} because the mapped remote folder has been deleted", fsInfo.FullName)); } catch (IOException) { fsInfo.SetExtendedAttribute(MappedObject.ExtendedAttributeKey, null, true); return(false); } } else { fsInfo.SetExtendedAttribute(MappedObject.ExtendedAttributeKey, null, true); } } else { try { (fsInfo as IDirectoryInfo).Delete(true); OperationsLogger.Info(string.Format("Deleted locally ignored folder {0} because the parent mapped remote folder has been deleted", fsInfo.FullName)); } catch (IOException e) { OperationsLogger.Info(string.Format("Deletion of locally ignored folder {0} failed", fsInfo.FullName), e); return(false); } } } return(delete); }
/// <summary> /// Solve the specified situation by using the storage, localFile and remoteId. /// Uploads the file content if content has been changed. Otherwise simply saves the /// last modification date. /// </summary> /// <param name="localFileSystemInfo">Local filesystem info instance.</param> /// <param name="remoteId">Remote identifier or object.</param> /// <param name="localContent">Hint if the local content has been changed.</param> /// <param name="remoteContent">Information if the remote content has been changed.</param> public override void Solve( IFileSystemInfo localFileSystemInfo, IObjectId remoteId, ContentChangeType localContent = ContentChangeType.NONE, ContentChangeType remoteContent = ContentChangeType.NONE) { if (!localFileSystemInfo.Exists) { throw new ArgumentException("Given local path does not exists: " + localFileSystemInfo.FullName); } // Match local changes to remote changes and updated them remotely IMappedObject mappedObject = null; try { string ea = localFileSystemInfo.GetExtendedAttribute(MappedObject.ExtendedAttributeKey); Guid guid; if (Guid.TryParse(ea, out guid)) { mappedObject = this.Storage.GetObjectByGuid(guid); } } catch (Exception) { } if (mappedObject == null) { mappedObject = this.Storage.GetObjectByLocalPath(localFileSystemInfo); } if (mappedObject == null) { throw new ArgumentException(string.Format("Could not find db entry for {0} => invoke crawl sync", localFileSystemInfo.FullName)); } IFileInfo localFile = localFileSystemInfo as IFileInfo; if (localFile != null && localFile.IsContentChangedTo(mappedObject, scanOnlyIfModificationDateDiffers: true)) { Logger.Debug(string.Format("\"{0}\" is different from {1}", localFile.FullName, mappedObject.ToString())); OperationsLogger.Debug(string.Format("Local file \"{0}\" has been changed", localFile.FullName)); IFileUploader uploader = FileTransmission.ContentTaskUtils.CreateUploader(); var doc = remoteId as IDocument; FileTransmissionEvent transmissionEvent = new FileTransmissionEvent(FileTransmissionType.UPLOAD_MODIFIED_FILE, localFile.FullName); this.transmissionManager.AddTransmission(transmissionEvent); transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { Started = true }); using (var hashAlg = new SHA1Managed()) using (var file = localFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { try { uploader.UploadFile(doc, file, transmissionEvent, hashAlg); } catch (Exception ex) { transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { FailedException = ex }); if (ex.InnerException is CmisPermissionDeniedException) { OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has been not been uploaded: PermissionDenied", localFile.FullName)); return; } throw; } mappedObject.LastChecksum = hashAlg.Hash; } mappedObject.LastChangeToken = doc.ChangeToken; mappedObject.LastRemoteWriteTimeUtc = doc.LastModificationDate; mappedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc; mappedObject.LastContentSize = localFile.Length; OperationsLogger.Info(string.Format("Local changed file \"{0}\" has been uploaded", localFile.FullName)); transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { Completed = true }); } if (this.ServerCanModifyDateTimes) { try { if (remoteId is IDocument) { (remoteId as IDocument).UpdateLastWriteTimeUtc(localFileSystemInfo.LastWriteTimeUtc); mappedObject.LastRemoteWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; } else if (remoteId is IFolder) { (remoteId as IFolder).UpdateLastWriteTimeUtc(localFileSystemInfo.LastWriteTimeUtc); mappedObject.LastRemoteWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; } } catch (CmisPermissionDeniedException) { Logger.Debug(string.Format("Locally changed modification date \"{0}\"is not uploaded to the server: PermissionDenied", localFileSystemInfo.LastWriteTimeUtc)); } } mappedObject.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; this.Storage.SaveMappedObject(mappedObject); }