示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
            }
        }
示例#4
0
            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;
                    }
                }
            }
示例#5
0
        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);
        }
示例#6
0
        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).");
            }
        }
示例#7
0
            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);
                        }
                    }
            }
示例#8
0
            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);
            }