Exemplo n.º 1
0
        public IList <Commit> ProcessCommits(string urlString)
        {
            IList <Commit> commits = new List <Commit>();

            try
            {
                if (!string.IsNullOrEmpty(urlString))
                {
                    var stringTask = client.GetStringAsync(urlString).Result;

                    commits = Commit.FromJson(stringTask);
                }

                return(commits);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Discard selected files.
        /// </summary>
        /// <param name="files">Files selected for discard.</param>
        /// <param name="onProgress">This is called when there is some progress made.</param>
        public void Discard(Filemap.FileDiff[] files, Action <string> onProgress)
        {
            var dataJson = new PullInput
            {
                Authority = Authority
            };
            var lastCommitId = -1;

            Request.Send(ServerAddress + "getcommit", dataJson.ToJson(), stream =>
            {
                using (var reader = new BinaryReader(stream))
                {
                    var message = reader.ReadString();

                    if (message == "Done")
                    {
                        lastCommitId = reader.ReadInt32();
                    }
                    else
                    {
                        throw new Exception("Cannot discard, Error: <br>" + message);
                    }
                }
            });

            // select current commit id
            var commitInfo      = RootDir + ".mysync/commit_info.txt";
            var currentCommitId = File.Exists(commitInfo) ? int.Parse(File.ReadAllText(commitInfo)) : -1;

            if (lastCommitId > currentCommitId)
            {
                throw new Exception("Cannot discard, project is not up-to-date!");
            }

            // select all files that are not 'created'
            var filesToDownload = new List <Filemap.File>();

            foreach (var file in files)
            {
                if (file.DiffType != Filemap.FileDiff.Type.Created)
                {
                    filesToDownload.Add(new Filemap.File
                    {
                        FileName = file.FileName
                    });
                }
            }

            var input = new DiscardInput
            {
                Authority = Authority,
                Files     = filesToDownload.ToArray()
            };

            // remove new files
            var toDelete = 0;

            foreach (var file in files)
            {
                if (file.DiffType == Filemap.FileDiff.Type.Created) // delete all 'created' files
                {
                    var fileName = RootDir + file.FileName;

                    // delete file
                    File.Delete(fileName);
                    DirectoryHelper.DeleteIfEmpty(fileName);

                    toDelete++;
                }
            }

            // check if there are files only for delete
            if (toDelete == files.Length)
            {
                return;
            }

            // download original files from server
            Request.Send(ServerAddress + "discard", input.ToJson(), stream =>
            {
                using (var reader = new BinaryReader(stream))
                {
                    var commitJson = reader.ReadString();

                    while (true)
                    {
                        var state = reader.ReadBoolean();

                        if (state)
                        {
                            break;
                        }

                        var progress = reader.ReadInt32();

                        if (progress >= 0)
                        {
                            onProgress("Building commit...");
                        }
                    }

                    // download
                    var dataFile = RootDir + ".mysync/commit_recv.zip";

                    // send commit diff data file
                    using (var nfs = new NetFileStream(dataFile,
                                                       onError: delegate {
                        // throw error
                        throw new Exception("Error when downloading commit data file");
                    }))
                    {
                        nfs.Download(stream, delegate(long bytes, long sentBytes)
                        {
                            // show progress
                            var prc = (sentBytes / (float)bytes) * 100;
                            onProgress?.Invoke(prc.ToString("f1") + "%");
                        });
                    }

                    var commit = Commit.FromJson(commitJson);

                    try
                    {
                        // downloaded
                        // now apply changes
                        commit.Apply(RootDir, dataFile, true);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error when applying commit data file");
                    }
                }
            });
        }
Exemplo n.º 3
0
        /// <summary>
        /// Pull commits from server and apply.
        /// </summary>
        /// <param name="onProgress">This is called when there is some progress made.</param>
        public void Pull(Action <string> onProgress)
        {
            var commitInfo = RootDir + ".mysync/commit_info.txt";

            // select current commit id
            var currentCommitId = File.Exists(commitInfo) ? int.Parse(File.ReadAllText(commitInfo)) : -1;

            // construct pull input data
            var dataJson = new PullInput
            {
                Authority = Authority,
                CommitId  = currentCommitId
            };

            // send pull request
            Request.Send(ServerAddress + "pull", dataJson.ToJson(), stream =>
            {
                using (var reader = new BinaryReader(stream))
                {
                    if (!reader.ReadBoolean())
                    {
                        // error!
                        throw new WarningException(reader.ReadString());
                    }

                    while (!reader.ReadBoolean())
                    {
                        var progress = reader.ReadInt32();

                        if (progress >= 0)
                        {
                            onProgress(progress + "%");
                        }
                    }

                    var body = reader.ReadString();

                    Console.WriteLine(body);

                    Commit commit; // try convert commit data
                    try
                    {
                        commit = Commit.FromJson(body);
                    }
                    catch
                    {
                        throw new WarningException("There is no any changes to download.");
                    }

                    var commitId = reader.ReadInt32();
                    Console.WriteLine(@"commit id: " + commitId);

                    var hasFile = reader.ReadBoolean();

                    var dataFile = RootDir + ".mysync/commit_recv.zip";

                    if (hasFile)
                    {
                        using (var fs = File.Create(dataFile))
                        {
                            var totalbytes = reader.ReadInt64();

                            var readbytes = 0;
                            int read;
                            var buffer = new byte[64 * 1024];
                            while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                fs.Write(buffer, 0, read);

                                readbytes += read;
                                var prc    = (float)readbytes / totalbytes;
                                prc       *= 100.0f;

                                if (prc >= 0)
                                {
                                    onProgress(prc.ToString("f1") + "%");
                                }
                            }
                        }
                    }

                    // apply the commit
                    commit.Apply(RootDir, dataFile, hasFile);

                    // remove data file
                    if (hasFile)
                    {
                        File.Delete(dataFile);
                    }

                    // update filemap
                    _lastFilemap.AddChanges(RootDir, commit.Files);
                    File.WriteAllText(RootDir + ".mysync/last_filemap.json", _lastFilemap.ToJson());

                    // save commit id
                    File.WriteAllText(commitInfo, commitId.ToString());

                    // refresh
                    Refresh();
                }
            });
        }
Exemplo n.º 4
0
        public static void Push(HttpListenerRequest request, HttpListenerResponse response)
        {
            var projectName = "";

            try
            {
                using (var reader = new BinaryReader(request.InputStream))
                {
                    using (var writer = new BinaryWriter(response.OutputStream))
                    {
                        try
                        {
                            var authority = ProjectAuthority.FromJson(Encoding.UTF8.GetString(
                                                                          reader.ReadBytes(reader.ReadInt32())
                                                                          ));

                            projectName = authority.ProjectName;

                            // validate project name, password and check permisions from clientData
                            if (!Authorization.HasAuthority(authority.AccessToken, projectName))
                            {
                                writer.Write("Failed - project not found!");
                                return;
                            }

                            // request project lock
                            if (ProjectLock.TryLock(projectName, ProjectLock.LockMode.Upload) !=
                                ProjectLock.LockMode.None)
                            {
                                writer.Write("Failed - project is locked!");
                                return;
                            }

                            // read commit
                            var commitData = reader.ReadBytes(reader.ReadInt32());
                            var commit     = Commit.FromJson(Encoding.UTF8.GetString(commitData));

                            var hasFile = reader.ReadBoolean();

                            if (hasFile)
                            {
                                Console.WriteLine("Receiving file...");
                                try
                                {
                                    // read data file
                                    using (var fs = File.Create("temp_recv.zip"))
                                    {
                                        try
                                        {
                                            int read;
                                            var buffer = new byte[64 * 1024];
                                            while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
                                            {
                                                fs.Write(buffer, 0, read);
                                            }
                                        }
                                        catch
                                        {
                                            // user lost connection or closed the client
                                            // before the whole data file arrived
                                            Console.WriteLine("User '" + authority.Username + "' canceled commit upload.");
                                            ProjectLock.Unlock(projectName);
                                            return;
                                        }
                                    }
                                }
                                catch
                                {
                                    // user lost connection or closed the client
                                    // before the whole data file arrived
                                    Console.WriteLine("User '" + authority.Username + "' commit upload failed.");
                                    ProjectLock.Unlock(projectName);
                                    return;
                                }
                            }

                            // --- from now - this part CAN'T fail, if so, the whole project may be incorrect after this!

                            var projectDir = "data/" + projectName;

                            // make commited files backup
                            commit.Backup(projectDir);

                            int commitId;
                            try
                            {
                                // downloaded
                                // now apply changes
                                commit.Apply(projectDir, "temp_recv.zip", hasFile);

                                // add commit to projects database
                                var projectCollection =
                                    ServerCore.Database.GetCollection <CommitModel>(projectName);
                                commitId = (int)projectCollection.Count(FilterDefinition <CommitModel> .Empty) + 1;

                                // build commit
                                var commitModel = new CommitModel
                                {
                                    CommitId          = commitId,
                                    CommitDescription = commit.Description,
                                    Files             = new CommitModel.FileDiff[commit.Files.Length]
                                };

                                for (var i = 0; i < commit.Files.Length; i++)
                                {
                                    var file = commit.Files[i];

                                    commitModel.Files[i] = new CommitModel.FileDiff
                                    {
                                        Name      = file.FileName,
                                        Version   = file.Version,
                                        Operation = (int)file.DiffType
                                    };
                                }

                                // insert
                                projectCollection.InsertOne(commitModel);

                                // delete zip file if exists
                                if (hasFile)
                                {
                                    File.Delete("temp_recv.zip");
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("Failed to apply commit from user '" + authority.Username + "'");
                                writer.Write("#RESTORE Failed - error when updating project! Error: " + ex);

                                // restore backup
                                commit.RestoreBackup(projectDir);

                                // UNLOCK
                                ProjectLock.Unlock(projectName);
                                return;
                            }

                            // ok, we are out of the danger zone.

                            // return message
                            writer.Write("Done!");
                            writer.Write(commitId);

                            // clean backups
                            commit.CleanBackups(projectDir);

                            Console.WriteLine("User '" + authority.Username + "' pushed changes!");
                        }
                        catch (Exception ex)
                        {
                            writer.Write("Failed - invalid protocol/connection error! Error: " + ex);
                            Console.WriteLine("PUSH failed");
                            ProjectLock.Unlock(projectName);
                        }
                    }
                }
            }
            catch
            {
                // this shouldn't be possible,
                // but anyway handle exceptions here
                Console.WriteLine("PUSH failed");
                ProjectLock.Unlock(projectName);
            }

            Console.WriteLine("Push done");
            ProjectLock.Unlock(projectName);
        }