예제 #1
0
파일: Repository.cs 프로젝트: niv/catflap
        private Task<long> RunAllSyncItems(CancellationTokenSource cts)
        {
            string basePath = RootPath;

            /* Cleanup leftover files from a forced abort. */
            if (Directory.Exists(TmpPath))
            {
                var di = new DirectoryInfo(TmpPath).GetFiles("*", SearchOption.TopDirectoryOnly);
                foreach (var tmpfile in di)
                {
                    OnDownloadMessage(Text.t("sync_deleting_leftovers_tmp", tmpfile.Name), true);
                    File.Delete(tmpfile.FullName);
                }
            }
            Directory.CreateDirectory(TmpPath);

            var updaterBinaryLastWriteTimeBefore = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime;

            var info = new DownloadStatusInfo();

            info.globalFileTotal = Status.directoryCountToVerify + Status.fileCountToVerify;
            info.globalFileCurrent = 0;
            info.globalBytesTotal = Status.maxBytesToVerify;

            var toCheck = verifyUpdateFull ?
                LatestManifest.sync.Where((syncItem) => !(syncItem.ignoreExisting.GetValueOrDefault() && (File.Exists(syncItem.name) || Directory.Exists(syncItem.name)))) :
                (Status.filesToVerify.Concat(Status.directoriesToVerify));

            /*var globalFileTotalStart = verifyUpdateFull ?
                LatestManifest.sync.Select(syncItem => syncItem.count > 0 ? syncItem.count : 1).Sum() :
                Status.fileCountToVerify;*/

            var globalBytesTotalStart = verifyUpdateFull ?
                LatestManifest.sync.Select(syncItem => syncItem.size).Sum() :
                info.globalBytesTotal;

            return Task<long>.Factory.StartNew(delegate()
            {
                long bytesTotalPrev = 0;

                foreach (Manifest.SyncItem f in toCheck)
                {
                    info.currentFile = f.name;

                    bool lastHashFailed = false;
                    string lastHashFileFailed = "";
                    string lastHashFailedMessage = "";

                    var t = RunSyncItem(f, verifyUpdateFull, Simulate, delegate(string fname, int percentage,
                        long bytesReceived, long bytesTotal, long bytesPerSecond, string details)
                    {
                        if (bytesReceived > -1) info.currentBytes = bytesReceived;
                        if (bytesTotal > -1) info.currentTotalBytes = bytesTotal;
                        if (bytesPerSecond > -1) info.currentBps = bytesPerSecond;
                        info.currentPercentage = ((float)percentage) / 100.0;
                        info.currentPercentage = info.currentPercentage.Clamp(0, 1);

                        info.details = details;

                        if (fname != info.currentFile)
                        {
                            info.globalBytesCurrent += bytesTotalPrev;
                            bytesTotalPrev = bytesTotal;
                            info.globalFileCurrent++;
                            info.currentFile = fname;
                        }
                        UpdateStatus(true);

                        info.globalFileTotal = Status.fileCountToVerify;

                        var bytesDone = info.globalBytesCurrent + bytesReceived;
                        info.globalPercentage = globalBytesTotalStart > 0 ? (bytesDone / (globalBytesTotalStart / 100.0)) / 100 : 1;

                        info.globalPercentage = info.globalPercentage.Clamp(0, 1);

                        OnDownloadStatusInfoChanged(info);

                    }, delegate(bool wasError, string str, long bytesOnNetwork)
                    {
                        if (wasError)
                        {
                            throw new Exception(str);
                        }
                        UpdateStatus();

                        info.currentFile = null;
                        info.currentBytesOnNetwork += bytesOnNetwork;

                        OnDownloadStatusInfoChanged(info);

                    }, delegate(string message, bool show)
                    {
                        OnDownloadMessage(message, show);

                    }, delegate(string file, string hash)
                    {
                        if (lastHashFailed)
                            return false;

                        lastHashFileFailed = file;

                        // Do not error hard on missing manifest hashes, since that can be trusted
                        // due to gpg signing.
                        if (f.hashes == null || !f.hashes.ContainsKey(file.ToLowerInvariant()))
                        {
                            OnDownloadMessage(Text.t("sync_hash_no_hash", file), false);
                            return true;
                        }

                        if (hash != f.hashes[file.ToLowerInvariant()])
                        {
                            lastHashFailed = true;
                            lastHashFailedMessage = Text.t("sync_hash_comparison_failed",
                                file.ToLowerInvariant(),
                                f.hashes[file.ToLowerInvariant()],
                                hash);
                            OnDownloadMessage(lastHashFailedMessage, false);
                            return false;
                        }

                        OnDownloadMessage(Text.t("sync_hash_ok", file, f.hashes[file.ToLowerInvariant()]), false);

                        return true;
                    }, cts);

                    try
                    {
                        t.Wait();
                    }
                    catch (System.AggregateException x)
                    {
                        if (lastHashFailed)
                        {
                            OnDownloadMessage(Text.t("sync_hash_failed"), true);

                            throw new Exception(Text.t("sync_hash_failed_long", lastHashFileFailed,
                                lastHashFailedMessage));

                        }

                        if (x.InnerException is TaskCanceledException)
                        {
                            OnDownloadMessage(Text.t("status_cancelled"), true);
                            break;
                        }

                        else
                            throw x;
                    }
                    var ret = t.Result;

                    // Verify hashes
                    // Security.VerifyHashes(f.hashes)
                    /*foreach (KeyValuePair<string, string> entry in f.hashes)
                    {
                        // key = filename, value = md5 hash string
                        OnDownloadMessage("Verifying checksum of " + entry.Key, false);
                        var ourHash = Security.HashMD5(rootPath + "/" + entry.Key);
                        if (ourHash.ToLowerInvariant() != entry.Value.ToLowerInvariant())
                            throw new Exception("verify: " + entry.Key + "=" + entry.Value + " vs " + ourHash);
                    }*/

                    if (cts.IsCancellationRequested)
                    {
                        OnDownloadMessage(Text.t("status_cancelled"), true);
                        break;
                    }

                    // This is a really ugly hackyhack to check if running binary was touched while we were upating.
                    // We just ASSUME that the binary was touched by the sync itself.
                    var updaterBinaryLastWriteTimeAfter = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime;
                    if (Math.Abs((updaterBinaryLastWriteTimeAfter - updaterBinaryLastWriteTimeBefore).TotalSeconds) > 1)
                    {
                        RequireRestart = true;
                        break;
                    }

                    info.globalPercentage = globalBytesTotalStart > 0 ? (info.globalBytesCurrent / (globalBytesTotalStart / 100.0)) / 100 : 1;
                    info.globalPercentage = info.globalPercentage.Clamp(0, 1);

                    OnDownloadStatusInfoChanged(info);
                }

                return info.currentBytesOnNetwork;
            }, cts.Token);
        }
예제 #2
0
        private Task<long> RunAllSyncItems(CancellationTokenSource cts)
        {
            string basePath = RootPath;

            /* Cleanup leftover files from a forced abort. */
            if (Directory.Exists(TmpPath))
            {
                var di = new DirectoryInfo(TmpPath).GetFiles("*", SearchOption.TopDirectoryOnly);
                foreach (var tmpfile in di)
                {
                    OnDownloadMessage("<apagando restos de um cancelamento: " + tmpfile.Name + ">", true);
                    File.Delete(tmpfile.FullName);
                }
            }
            Directory.CreateDirectory(TmpPath);

            var updaterBinaryLastWriteTimeBefore = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime;

            var info = new DownloadStatusInfo();

            info.globalFileTotal = Status.directoryCountToVerify + Status.fileCountToVerify;
            info.globalFileCurrent = 0;
            info.globalBytesTotal = Status.maxBytesToVerify;

            var toCheck = verifyUpdateFull ?
                LatestManifest.sync.Where((syncItem) => !(syncItem.ignoreExisting.GetValueOrDefault() && (File.Exists(syncItem.name) || Directory.Exists(syncItem.name)))) :
                (Status.filesToVerify.Concat(Status.directoriesToVerify));

            /*var globalFileTotalStart = verifyUpdateFull ?
                LatestManifest.sync.Select(syncItem => syncItem.count > 0 ? syncItem.count : 1).Sum() :
                Status.fileCountToVerify;*/

            var globalBytesTotalStart = verifyUpdateFull ?
                LatestManifest.sync.Select(syncItem => syncItem.size).Sum() :
                info.globalBytesTotal;

            return Task<long>.Factory.StartNew(delegate()
            {
                long bytesTotalPrev = 0;

                foreach (Manifest.SyncItem f in toCheck)
                {
                    info.currentFile = f.name;

                    // Hacky: Make sure we can write to our target. This is mostly due to rsync
                    // sometimes setting "ReadOnly" on .exe files when the remote is configured
                    // not quite correctly and only affects updating the updater itself.
                    try
                    {
                        // new FileInfo(rootPath + "/" + f.name) {IsReadOnly = false}.Refresh();
                        EnsureWriteable(RootPath + "/" + f.name);
                    }
                    catch (Exception e)
                    {
                    }

                    var t = RunSyncItem(f, verifyUpdateFull, Simulate, delegate(string fname, int percentage, long bytesReceived, long bytesTotal, long bytesPerSecond)
                    {
                        if (bytesReceived > -1) info.currentBytes = bytesReceived;
                        if (bytesTotal > -1) info.currentTotalBytes = bytesTotal;
                        if (bytesPerSecond > -1) info.currentBps = bytesPerSecond;
                        info.currentPercentage = bytesTotal > 0 ? (bytesReceived / (bytesTotal / 100.0)) / 100 : 0;

                        if (fname != info.currentFile)
                        {
                            info.globalBytesCurrent += bytesTotalPrev;
                            bytesTotalPrev = bytesTotal;
                            info.globalFileCurrent++;
                            info.currentFile = fname;
                        }
                        UpdateStatus(true);

                        info.globalFileTotal = Status.fileCountToVerify;

                        var bytesDone = info.globalBytesCurrent + bytesReceived;
                        info.globalPercentage = globalBytesTotalStart > 0 ? (bytesDone / (globalBytesTotalStart / 100.0)) / 100 : 1;

                        info.globalPercentage = info.globalPercentage.Clamp(0, 1);

                        OnDownloadStatusInfoChanged(info);

                    }, delegate(bool wasError, string str, long bytesOnNetwork)
                    {
                        if (wasError)
                        {
                            throw new Exception(str);
                        }
                        UpdateStatus();

                        info.currentFile = null;
                        info.currentBytesOnNetwork += bytesOnNetwork;

                        OnDownloadStatusInfoChanged(info);

                    }, delegate(string message, bool show)
                    {
                        OnDownloadMessage(message, show);
                    }, cts);

                    try
                    {
                        t.Wait();
                    }
                    catch (System.AggregateException x)
                    {
                        if (x.InnerException is TaskCanceledException)
                        {
                            break;
                        }

                        else
                            throw x;
                    }
                    var ret = t.Result;

                    if (cts.IsCancellationRequested)
                        break;

                    // This is a really ugly hackyhack to check if running binary was touched while we were upating.
                    // We just ASSUME that the binary was touched by the sync itself.
                    var updaterBinaryLastWriteTimeAfter = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime;
                    if (Math.Abs((updaterBinaryLastWriteTimeAfter - updaterBinaryLastWriteTimeBefore).TotalSeconds) > 1)
                    {
                        RequireRestart = true;
                        break;
                    }

                    info.globalPercentage = globalBytesTotalStart > 0 ? (info.globalBytesCurrent / (globalBytesTotalStart / 100.0)) / 100 : 1;
                    info.globalPercentage = info.globalPercentage.Clamp(0, 1);

                    OnDownloadStatusInfoChanged(info);
                }

                return info.currentBytesOnNetwork;
            }, cts.Token);
        }
예제 #3
0
        private Task <long> RunAllSyncItems(CancellationTokenSource cts)
        {
            string basePath = RootPath;

            /* Cleanup leftover files from a forced abort. */
            if (Directory.Exists(TmpPath))
            {
                var di = new DirectoryInfo(TmpPath).GetFiles("*", SearchOption.TopDirectoryOnly);
                foreach (var tmpfile in di)
                {
                    OnDownloadMessage("<apagando restos de um cancelamento: " + tmpfile.Name + ">", true);
                    File.Delete(tmpfile.FullName);
                }
            }
            Directory.CreateDirectory(TmpPath);

            var updaterBinaryLastWriteTimeBefore = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime;

            var info = new DownloadStatusInfo();

            info.globalFileTotal   = Status.directoryCountToVerify + Status.fileCountToVerify;
            info.globalFileCurrent = 0;
            info.globalBytesTotal  = Status.maxBytesToVerify;

            var toCheck = verifyUpdateFull ?
                          LatestManifest.sync.Where((syncItem) => !(syncItem.ignoreExisting.GetValueOrDefault() && (File.Exists(syncItem.name) || Directory.Exists(syncItem.name)))) :
                          (Status.filesToVerify.Concat(Status.directoriesToVerify));

            /*var globalFileTotalStart = verifyUpdateFull ?
             *  LatestManifest.sync.Select(syncItem => syncItem.count > 0 ? syncItem.count : 1).Sum() :
             *  Status.fileCountToVerify;*/

            var globalBytesTotalStart = verifyUpdateFull ?
                                        LatestManifest.sync.Select(syncItem => syncItem.size).Sum() :
                                        info.globalBytesTotal;


            return(Task <long> .Factory.StartNew(delegate()
            {
                long bytesTotalPrev = 0;

                foreach (Manifest.SyncItem f in toCheck)
                {
                    info.currentFile = f.name;

                    // Hacky: Make sure we can write to our target. This is mostly due to rsync
                    // sometimes setting "ReadOnly" on .exe files when the remote is configured
                    // not quite correctly and only affects updating the updater itself.
                    try
                    {
                        // new FileInfo(rootPath + "/" + f.name) {IsReadOnly = false}.Refresh();
                        EnsureWriteable(RootPath + "/" + f.name);
                    }
                    catch (Exception e)
                    {
                    }

                    var t = RunSyncItem(f, verifyUpdateFull, Simulate, delegate(string fname, int percentage, long bytesReceived, long bytesTotal, long bytesPerSecond)
                    {
                        if (bytesReceived > -1)
                        {
                            info.currentBytes = bytesReceived;
                        }
                        if (bytesTotal > -1)
                        {
                            info.currentTotalBytes = bytesTotal;
                        }
                        if (bytesPerSecond > -1)
                        {
                            info.currentBps = bytesPerSecond;
                        }
                        info.currentPercentage = bytesTotal > 0 ? (bytesReceived / (bytesTotal / 100.0)) / 100 : 0;

                        if (fname != info.currentFile)
                        {
                            info.globalBytesCurrent += bytesTotalPrev;
                            bytesTotalPrev = bytesTotal;
                            info.globalFileCurrent++;
                            info.currentFile = fname;
                        }
                        UpdateStatus(true);

                        info.globalFileTotal = Status.fileCountToVerify;

                        var bytesDone = info.globalBytesCurrent + bytesReceived;
                        info.globalPercentage = globalBytesTotalStart > 0 ? (bytesDone / (globalBytesTotalStart / 100.0)) / 100 : 1;

                        info.globalPercentage = info.globalPercentage.Clamp(0, 1);

                        OnDownloadStatusInfoChanged(info);
                    }, delegate(bool wasError, string str, long bytesOnNetwork)
                    {
                        if (wasError)
                        {
                            throw new Exception(str);
                        }
                        UpdateStatus();

                        info.currentFile = null;
                        info.currentBytesOnNetwork += bytesOnNetwork;

                        OnDownloadStatusInfoChanged(info);
                    }, delegate(string message, bool show)
                    {
                        OnDownloadMessage(message, show);
                    }, cts);

                    try
                    {
                        t.Wait();
                    }
                    catch (System.AggregateException x)
                    {
                        if (x.InnerException is TaskCanceledException)
                        {
                            break;
                        }

                        else
                        {
                            throw x;
                        }
                    }
                    var ret = t.Result;

                    if (cts.IsCancellationRequested)
                    {
                        break;
                    }

                    // This is a really ugly hackyhack to check if running binary was touched while we were upating.
                    // We just ASSUME that the binary was touched by the sync itself.
                    var updaterBinaryLastWriteTimeAfter = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime;
                    if (Math.Abs((updaterBinaryLastWriteTimeAfter - updaterBinaryLastWriteTimeBefore).TotalSeconds) > 1)
                    {
                        RequireRestart = true;
                        break;
                    }

                    info.globalPercentage = globalBytesTotalStart > 0 ? (info.globalBytesCurrent / (globalBytesTotalStart / 100.0)) / 100 : 1;
                    info.globalPercentage = info.globalPercentage.Clamp(0, 1);

                    OnDownloadStatusInfoChanged(info);
                }

                return info.currentBytesOnNetwork;
            }, cts.Token));
        }