Example #1
0
        /// <summary>
        /// When overridden in the derived class, handles synchronizing the given version.
        /// </summary>
        /// <param name="fu">The <see cref="IFileUploader"/> to use.</param>
        /// <param name="v">The version to synchronize.</param>
        /// <param name="reEnqueue">True if the <paramref name="v"/> should be re-enqueued so it can be re-attempted.
        /// If the method throws an <see cref="Exception"/>, the <paramref name="v"/> will be re-enqueued no matter what.</param>
        /// <returns>
        /// The error string, or null if the synchronization was successful.
        /// </returns>
        protected override string DoSync(IFileUploader fu, int v, out bool reEnqueue)
        {
            reEnqueue = false;

            // Load the VersionFileList for the version to check
            var vflPath = VersionHelper.GetVersionFileListPath(v);
            if (!File.Exists(vflPath))
            {
                // Version doesn't exist at all
                return null;
            }

            var vfl = VersionFileList.CreateFromFile(vflPath);

            // Try to download the version's file list hash
            var fileListHashPath = GetVersionRemoteFilePath(v, PathHelper.RemoteFileListHashFileName);
            var vflHash = fu.DownloadAsString(fileListHashPath);

            // Check if the hash file exists on the server
            if (vflHash != null)
            {
                // Check if the hash matches the current version's hash
                var expectedVflHash = File.ReadAllText(VersionHelper.GetVersionFileListHashPath(v));
                if (vflHash != expectedVflHash)
                {
                    // Delete the whole version folder first
                    fu.DeleteDirectory(GetVersionRemoteFilePath(v, null));
                }
                else
                {
                    // Hash existed and was correct - good enough for us!
                    return null;
                }
            }
            else
            {
                // Hash didn't exist at all, so we will have to update. As long as SkipIfExists is set to true, files
                // that already exist will be skipped, so we will only end up uploading the new files. In any case, its
                // the same process either way.
            }

            // Check the hashes of the local files
            foreach (var f in vfl.Files)
            {
                // Get the local file path
                var localPath = VersionHelper.GetVersionFile(v, f.FilePath);

                // Confirm the hash of the file
                var fileHash = Hasher.GetFileHash(localPath);
                if (fileHash != f.Hash)
                {
                    const string errmsg =
                        "The cached hash ({0}) of file `{1}` does not match the real hash ({2}) for version {3}." +
                        " Possible version corruption.";
                    return string.Format(errmsg, f.Hash, f.FilePath, fileHash, v);
                }
            }

            // Hashes check out, start uploading
            foreach (var f in vfl.Files)
            {
                // Get the local file path
                var localPath = VersionHelper.GetVersionFile(v, f.FilePath);

                var remotePath = GetVersionRemoteFilePath(v, f.FilePath);
                fu.UploadAsync(localPath, remotePath);
            }

            // Wait for uploads to finish
            while (fu.IsBusy)
            {
                Thread.Sleep(1000);
            }

            // All uploads have finished, so upload the VersionFileList hash
            fu.UploadAsync(VersionHelper.GetVersionFileListHashPath(v), fileListHashPath);

            // All done! That was easy enough, eh? *sigh*
            return null;
        }
Example #2
0
        /// <summary>
        /// When overridden in the derived class, handles synchronizing the given version.
        /// </summary>
        /// <param name="fu">The <see cref="IFileUploader"/> to use.</param>
        /// <param name="v">The version to synchronize.</param>
        /// <param name="reEnqueue">True if the <paramref name="v"/> should be re-enqueued so it can be re-attempted.
        /// If the method throws an <see cref="Exception"/>, the <paramref name="v"/> will be re-enqueued no matter what.</param>
        /// <returns>
        /// The error string, or null if the synchronization was successful.
        /// </returns>
        protected override string DoSync(IFileUploader fu, int v, out bool reEnqueue)
        {
            reEnqueue = false;

            // Load the VersionFileList for the version to check
            var vflPath = VersionHelper.GetVersionFileListPath(v);

            if (!File.Exists(vflPath))
            {
                // Version doesn't exist at all
                return(null);
            }

            var vfl = VersionFileList.CreateFromFile(vflPath);

            // Try to download the version's file list hash
            var fileListHashPath = GetVersionRemoteFilePath(v, PathHelper.RemoteFileListHashFileName);
            var vflHash          = fu.DownloadAsString(fileListHashPath);

            // Check if the hash file exists on the server
            if (vflHash != null)
            {
                // Check if the hash matches the current version's hash
                var expectedVflHash = File.ReadAllText(VersionHelper.GetVersionFileListHashPath(v));
                if (vflHash != expectedVflHash)
                {
                    // Delete the whole version folder first
                    fu.DeleteDirectory(GetVersionRemoteFilePath(v, null));
                }
                else
                {
                    // Hash existed and was correct - good enough for us!
                    return(null);
                }
            }
            else
            {
                // Hash didn't exist at all, so we will have to update. As long as SkipIfExists is set to true, files
                // that already exist will be skipped, so we will only end up uploading the new files. In any case, its
                // the same process either way.
            }

            // Check the hashes of the local files
            foreach (var f in vfl.Files)
            {
                // Get the local file path
                var localPath = VersionHelper.GetVersionFile(v, f.FilePath);

                // Confirm the hash of the file
                var fileHash = Hasher.GetFileHash(localPath);
                if (fileHash != f.Hash)
                {
                    const string errmsg =
                        "The cached hash ({0}) of file `{1}` does not match the real hash ({2}) for version {3}." +
                        " Possible version corruption.";
                    return(string.Format(errmsg, f.Hash, f.FilePath, fileHash, v));
                }
            }

            // Hashes check out, start uploading
            foreach (var f in vfl.Files)
            {
                // Get the local file path
                var localPath = VersionHelper.GetVersionFile(v, f.FilePath);

                var remotePath = GetVersionRemoteFilePath(v, f.FilePath);
                fu.UploadAsync(localPath, remotePath);
            }

            // Wait for uploads to finish
            while (fu.IsBusy)
            {
                Thread.Sleep(1000);
            }

            // All uploads have finished, so upload the VersionFileList hash
            fu.UploadAsync(VersionHelper.GetVersionFileListHashPath(v), fileListHashPath);

            // All done! That was easy enough, eh? *sigh*
            return(null);
        }