public LocalPath Download(string src) { src = EncodePath(LexicalPath.Combine(_rootPath, src)); var res = new LocalPath(LocalUtils.GetTempFileName()); var downloaded = false; for (var i = 0; i < RETRIES; ++i) { try { using (var stream = _graphServiceClient.Drive.Root.ItemWithPath(src).Content.Request().GetAsync().Result) using (var outputStream = System.IO.File.OpenWrite(res.Path)) stream.CopyTo(outputStream); downloaded = true; break; } catch (Exception) { LocalUtils.TryDeleteFile(res.Path); } } if (!downloaded) { throw new StorageException($"Failed to download '{src}' ({RETRIES} attempts)."); } return(res); }
public LocalPath Download(string src) { src = LexicalPath.Combine(_rootPath, src); string id = GetId(src); var req = service.Files.Get(id); LocalPath res = new LocalPath(LocalUtils.GetTempFileName()); var downloaded = false; for (var i = 0; i < RETRIES && !downloaded; ++i) { try { using (var stream = File.OpenWrite(res.Path)) req.Download(stream); downloaded = true; break; } catch (Exception) { LocalUtils.TryDeleteFile(res.Path); } } if (!downloaded) { throw new StorageException($"Failed to download '{src}' ({RETRIES} attempts)."); } return(res); }
public void CreateRoot(ref Context context) { context.Storage.CreateDirectory(ObjectsDir); BaseDir baseDir = new Core.BaseDir { Eyecatcher = EyeCatcher }; // Serialize to a temp file using (var path = new LocalPath(LocalUtils.GetTempFileName(suffix: ".dir"))) using (var encodedPath = new LocalPath(LocalUtils.GetTempFileName(suffix: ".edir"))) { FileStream output = File.OpenWrite(path.Path); // Write the directory to a file baseDir.WriteTo(output); output.Close(); byte[] hash = new byte[32]; CodecHelper.EncodeFile(ref context, path.Path, encodedPath.Path, ref hash); // Upload the file. It's removed by Upload. Upload(ref context, encodedPath.Path, RootId); } // Write the config using (var configPath = new LocalPath(LocalUtils.GetTempFileName(suffix: ".config"))) { context.RepoCfg.Save(configPath.Path); Upload(ref context, configPath.Path, RepoConfig.ConfigFile); } }
public void Write() { using (var rawContent = new LocalPath(LocalUtils.GetTempFileName(suffix: ".dir"))) { using (FileStream fs = File.OpenWrite(rawContent.Path)) { // Serialize the content _data.WriteTo(fs); } if (!File.Exists(rawContent.Path)) { throw new Exception($"The temporary file {rawContent.Path} disappeared!"); } // Use another temp file to encode the content using (var encodedPath = new LocalPath(LocalUtils.GetTempFileName(prefix: "cync", suffix: ".edir"))) { byte[] hash = new byte[32]; CodecHelper.EncodeFile(ref _context, rawContent.Path, encodedPath.Path, ref hash); // Make sure the target directory exists _context.Storage.CreateDirectory(_fid.DirectoryPath); // Upload the encoded file _context.Storage.Upload(encodedPath.Path, _fid.FullPath, true); _dirty = false; } } }
public LocalPath Download(string src) { var path = string.IsNullOrWhiteSpace(_rootPath) ? src : LexicalPath.Combine(_rootPath, src); LocalPath res = new LocalPath(LocalUtils.GetTempFileName()); using (var stream = File.OpenWrite(res.Path)) _client.DownloadFile(path, stream); return(res); }
public void Download(string src, string dest) { var downloaded = false; for (var i = 0; i < RETRIES && !downloaded; ++i) { try { DownloadAction(src, dest); downloaded = true; break; } catch (Exception) { } LocalUtils.TryDeleteFile(dest); } if (!downloaded) { throw new StorageException($"Failed to download '{src}' ({RETRIES} attempts)."); } }
public void Read() { // Download the directory file using (var localPath = _context.Storage.Download(_fid.FullPath)) using (var decodedPath = new LocalPath(LocalUtils.GetTempFileName(suffix: ".dir"))) { var fi = new FileInfo(localPath.Path); if (fi.Length < 4) { throw new Exception($"The downloaded file is too short, only {fi.Length} bytes. Minimum is 4."); } byte[] hash = new byte[32]; byte[] expectedHash = new byte[32]; CodecHelper.DecodeFile(ref _context, localPath.Path, decodedPath.Path, ref hash, ref expectedHash); // Read the directory content using (Stream ss = OpenTempFileForReading(decodedPath.Path)) { MessageParser <BaseDir> parser = new MessageParser <BaseDir>(() => new BaseDir()); _data = parser.ParseFrom(ss); } } }
public bool PushFile(string src, string dest, bool force) { if (dest == null || dest.Length == 0) { dest = Path.GetFileName(src); } DirEntry de; FileInfo fi = new FileInfo(src); bool exists = TryGetEntry(dest, out de); if (exists) { bool changeDetected = force; if (!changeDetected) { VersionEntry ve = de.Versions[de.Latest]; // Compare the file time if (fi.LastWriteTimeUtc.Ticks > ve.LastWriteTime) { // Compare the size if ((ulong)fi.Length != ve.Length) { changeDetected = true; } else if (_context.UseChecksums) { // Checksum check byte[] sha256 = new byte[32]; ComputeHashParams bb = new ComputeHashParams { }; bb.Hash = "sha256"; bb.Path = src; using (MemoryStream ms = new MemoryStream()) { bb.WriteTo(ms); CodecDll.ComputeHash(ms.GetBuffer(), (uint)ms.Length, sha256, (uint)sha256.Length); } // Compare the hash changeDetected = !sha256.SequenceEqual(ve.Checksum); } if (!changeDetected) { // Update the timestamp only de.Versions[de.Latest].LastWriteTime = fi.LastWriteTimeUtc.Ticks; return(true); } } } if (!changeDetected) { return(false); } } else { de = new DirEntry { Type = DirEntryType.File, Latest = 0 }; AddEntry(dest, de); } VersionEntry versionToRemove = null; // Encode the file to a temp location using (var lp = new LocalPath(LocalUtils.GetTempFileName())) { var hash = new byte[32]; CodecHelper.EncodeFile(ref _context, src, lp.Path, ref hash); var newVersionEntry = new VersionEntry { Uuid = Guid.NewGuid().ToString("N"), LastWriteTime = fi.LastWriteTimeUtc.Ticks, LastAccessTime = fi.LastAccessTimeUtc.Ticks, CreationTime = fi.CreationTimeUtc.Ticks, Attributes = (int)fi.Attributes, Length = (ulong)fi.Length }; newVersionEntry.Checksum = ByteString.CopyFrom(hash); if (de.Versions.Count == 0) { // The very first version addition de.Versions.Add(newVersionEntry); Debug.Assert(de.Latest == 0); } else if (de.Versions.Count > 0 && de.Versions.Count >= _context.RepoCfg.MaxVersions) { de.Latest = (de.Latest + 1) % _context.RepoCfg.MaxVersions; versionToRemove = de.Versions[de.Latest]; de.Versions[de.Latest] = newVersionEntry; } else { de.Versions.Add(newVersionEntry); ++de.Latest; } // The in-memory directory is updated, perform the file operations FileId fid = new FileId(newVersionEntry.Uuid); _context.Storage.CreateDirectory(fid.DirectoryPath); _context.Storage.Upload(lp.Path, fid.FullPath); } // Remove the previous version if necessary if (versionToRemove != null) { _context.Storage.RemoveFile((new FileId(versionToRemove.Uuid)).FullPath); } Write(); return(true); }