{"action":"created","comment":{"url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/comments/192813088","pull_request_review_id":125649105,"id":192813088,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5MjgxMzA4OA==","diff_hunk":"@@ -155,6 +156,79 @@ class CosmasGoogleCloudService(private val bucketName: String,\n         responseObserver.onCompleted()\n     }\n \n+    override fun getTextWithoutPatch(request: CosmasProto.getTextWithoutPatchRequest,\n+                              responseObserver: StreamObserver<CosmasProto.getTextWithoutPatchResponse>) {\n+        var askedVersion = request.getVersionRequest.version\n+        val blobRequestVersion: Blob? = try {\n+            this.storage.get(BlobInfo.newBuilder(this.bucketName, request.getVersionRequest.fileId).build().blobId,\n+                    Storage.BlobGetOption.generationMatch(askedVersion))\n+        } catch (e: StorageException) {\n+            handleStorageException(e, responseObserver)\n+            return\n+        }\n+        if (blobRequestVersion == null) {\n+            val requestStatus = Status.NOT_FOUND.withDescription(\n+                    \"Can't delete patch. There is no such file version in storage\")\n+            responseObserver.onError(StatusException(requestStatus))\n+            return\n+        }\n+        val blobPreviousVersion: Blob?  = try {\n+            this.storage.get(BlobInfo.newBuilder(this.bucketName, request.getVersionRequest.fileId).build().blobId,\n+                    Storage.BlobGetOption.generationMatch(askedVersion - 1))\n+        } catch (e: StorageException) {\n+            handleStorageException(e, responseObserver)\n+            return\n+        }\n+        if (blobPreviousVersion == null && askedVersion > 0) {\n+            val requestStatus = Status.NOT_FOUND.withDescription(\n+                    \"Can't delete patch. There is no such file version in storage\")\n+            responseObserver.onError(StatusException(requestStatus))\n+            return\n+        }\n+        val fileVersion1 = CosmasProto.FileVersion.parseFrom(blobRequestVersion.getContent())\n+        val fileVersion2 = if (blobPreviousVersion != null) { CosmasProto.FileVersion.parseFrom(blobPreviousVersion.getContent()) } else { null }\n+        val text = if (fileVersion2 != null) { fileVersion2.content.toStringUtf8() } else {\"\"}\n+        val patchList = mutableListOf<CosmasProto.Patch>()\n+        patchList.addAll(fileVersion1.patchesList)\n+        var indexCandidateDeletePatch = -1\n+        for ((patchIndex, patch) in patchList.withIndex()) {\n+            if (patch.timeStamp == request.patchTimeStamp) {\n+                indexCandidateDeletePatch = patchIndex\n+            }\n+        }\n+        if (indexCandidateDeletePatch == -1) {\n+            val requestStatus = Status.NOT_FOUND.withDescription(\n+                    \"Can't delete patch. There is no such patch in storage\")\n+            responseObserver.onError(StatusException(requestStatus))\n+            return\n+        }\n+        while (true) {\n+            askedVersion++\n+            val blob: Blob = try {\n+                this.storage.get(BlobInfo.newBuilder(this.bucketName, request.getVersionRequest.fileId).build().blobId,\n+                        Storage.BlobGetOption.generationMatch(askedVersion))\n+            } catch (e: StorageException) {\n+                handleStorageException(e, responseObserver)\n+                return\n+            } ?: break\n+            val fileVersion = CosmasProto.FileVersion.parseFrom(blob.getContent())\n+            patchList.addAll(fileVersion.patchesList)\n+        }\n+        val textBeforeCandidateDelete = PatchCorrector.applyPatch(patchList.subList(0, indexCandidateDeletePatch), text)\n+        val finishText = PatchCorrector.applyPatch(patchList, text)","path":"src/main/kotlin/com/bardsoftware/papeeria/backend/cosmas/CosmasGoogleCloudService.kt","position":null,"original_position":71,"commit_id":"ee165b61bf1b681e9210fb5f57c7fb688c721a87","original_commit_id":"c536329f154b4219f12db7920c878a1fd5c0038e","user":{"login":"dbarashev","id":2028330,"node_id":"MDQ6VXNlcjIwMjgzMzA=","avatar_url":"https://avatars2.githubusercontent.com/u/2028330?v=4","gravatar_id":"","url":"https://api.github.com/users/dbarashev","html_url":"https://github.com/dbarashev","followers_url":"https://api.github.com/users/dbarashev/followers","following_url":"https://api.github.com/users/dbarashev/following{/other_user}","gists_url":"https://api.github.com/users/dbarashev/gists{/gist_id}","starred_url":"https://api.github.com/users/dbarashev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dbarashev/subscriptions","organizations_url":"https://api.github.com/users/dbarashev/orgs","repos_url":"https://api.github.com/users/dbarashev/repos","events_url":"https://api.github.com/users/dbarashev/events{/privacy}","received_events_url":"https://api.github.com/users/dbarashev/received_events","type":"User","site_admin":false},"body":"You don't burn CPU cycles on applying patches to get what is already available to you in the list of all object versions.\r\n","created_at":"2018-06-04T17:01:16Z","updated_at":"2018-06-04T17:12:18Z","html_url":"https://github.com/bardsoftware/papeeria-edit-history/pull/28#discussion_r192813088","pull_request_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/28","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/comments/192813088"},"html":{"href":"https://github.com/bardsoftware/papeeria-edit-history/pull/28#discussion_r192813088"},"pull_request":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/28"}},"in_reply_to_id":191444098},"pull_request":{"url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/28","id":190503341,"node_id":"MDExOlB1bGxSZXF1ZXN0MTkwNTAzMzQx","html_url":"https://github.com/bardsoftware/papeeria-edit-history/pull/28","diff_url":"https://github.com/bardsoftware/papeeria-edit-history/pull/28.diff","patch_url":"https://github.com/bardsoftware/papeeria-edit-history/pull/28.patch","issue_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues/28","number":28,"state":"open","locked":false,"title":"add opportunity delete patch from storage","user":{"login":"SashaOrlova","id":22060110,"node_id":"MDQ6VXNlcjIyMDYwMTEw","avatar_url":"https://avatars1.githubusercontent.com/u/22060110?v=4","gravatar_id":"","url":"https://api.github.com/users/SashaOrlova","html_url":"https://github.com/SashaOrlova","followers_url":"https://api.github.com/users/SashaOrlova/followers","following_url":"https://api.github.com/users/SashaOrlova/following{/other_user}","gists_url":"https://api.github.com/users/SashaOrlova/gists{/gist_id}","starred_url":"https://api.github.com/users/SashaOrlova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SashaOrlova/subscriptions","organizations_url":"https://api.github.com/users/SashaOrlova/orgs","repos_url":"https://api.github.com/users/SashaOrlova/repos","events_url":"https://api.github.com/users/SashaOrlova/events{/privacy}","received_events_url":"https://api.github.com/users/SashaOrlova/received_events","type":"User","site_admin":false},"body":"#27 ","created_at":"2018-05-25T07:30:35Z","updated_at":"2018-06-04T17:12:18Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f2acbd234530087bcf7ac360e85673022d20e326","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/28/commits","review_comments_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/28/comments","review_comment_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues/28/comments","statuses_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/statuses/ee165b61bf1b681e9210fb5f57c7fb688c721a87","head":{"label":"bardsoftware:tkt-27-delete_patch_GRPC","ref":"tkt-27-delete_patch_GRPC","sha":"ee165b61bf1b681e9210fb5f57c7fb688c721a87","user":{"login":"bardsoftware","id":2625618,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2MjU2MTg=","avatar_url":"https://avatars1.githubusercontent.com/u/2625618?v=4","gravatar_id":"","url":"https://api.github.com/users/bardsoftware","html_url":"https://github.com/bardsoftware","followers_url":"https://api.github.com/users/bardsoftware/followers","following_url":"https://api.github.com/users/bardsoftware/following{/other_user}","gists_url":"https://api.github.com/users/bardsoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/bardsoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bardsoftware/subscriptions","organizations_url":"https://api.github.com/users/bardsoftware/orgs","repos_url":"https://api.github.com/users/bardsoftware/repos","events_url":"https://api.github.com/users/bardsoftware/events{/privacy}","received_events_url":"https://api.github.com/users/bardsoftware/received_events","type":"Organization","site_admin":false},"repo":{"id":123581121,"node_id":"MDEwOlJlcG9zaXRvcnkxMjM1ODExMjE=","name":"papeeria-edit-history","full_name":"bardsoftware/papeeria-edit-history","owner":{"login":"bardsoftware","id":2625618,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2MjU2MTg=","avatar_url":"https://avatars1.githubusercontent.com/u/2625618?v=4","gravatar_id":"","url":"https://api.github.com/users/bardsoftware","html_url":"https://github.com/bardsoftware","followers_url":"https://api.github.com/users/bardsoftware/followers","following_url":"https://api.github.com/users/bardsoftware/following{/other_user}","gists_url":"https://api.github.com/users/bardsoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/bardsoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bardsoftware/subscriptions","organizations_url":"https://api.github.com/users/bardsoftware/orgs","repos_url":"https://api.github.com/users/bardsoftware/repos","events_url":"https://api.github.com/users/bardsoftware/events{/privacy}","received_events_url":"https://api.github.com/users/bardsoftware/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bardsoftware/papeeria-edit-history","description":null,"fork":false,"url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history","forks_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/forks","keys_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/teams","hooks_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/hooks","issue_events_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues/events{/number}","events_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/events","assignees_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/assignees{/user}","branches_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/branches{/branch}","tags_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/tags","blobs_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/refs{/sha}","trees_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/statuses/{sha}","languages_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/languages","stargazers_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/stargazers","contributors_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/contributors","subscribers_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/subscribers","subscription_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/subscription","commits_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/commits{/sha}","git_commits_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/commits{/sha}","comments_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/comments{/number}","issue_comment_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues/comments{/number}","contents_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/contents/{+path}","compare_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/merges","archive_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/downloads","issues_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues{/number}","pulls_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls{/number}","milestones_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/milestones{/number}","notifications_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/labels{/name}","releases_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/releases{/id}","deployments_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/deployments","created_at":"2018-03-02T13:16:07Z","updated_at":"2018-05-25T16:46:22Z","pushed_at":"2018-05-30T07:09:59Z","git_url":"git://github.com/bardsoftware/papeeria-edit-history.git","ssh_url":"git@github.com:bardsoftware/papeeria-edit-history.git","clone_url":"https://github.com/bardsoftware/papeeria-edit-history.git","svn_url":"https://github.com/bardsoftware/papeeria-edit-history","homepage":null,"size":369,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":3,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":3,"watchers":0,"default_branch":"master"}},"base":{"label":"bardsoftware:master","ref":"master","sha":"978d7f04d8ab7a730ec2a881ff4af5ac8965daa5","user":{"login":"bardsoftware","id":2625618,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2MjU2MTg=","avatar_url":"https://avatars1.githubusercontent.com/u/2625618?v=4","gravatar_id":"","url":"https://api.github.com/users/bardsoftware","html_url":"https://github.com/bardsoftware","followers_url":"https://api.github.com/users/bardsoftware/followers","following_url":"https://api.github.com/users/bardsoftware/following{/other_user}","gists_url":"https://api.github.com/users/bardsoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/bardsoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bardsoftware/subscriptions","organizations_url":"https://api.github.com/users/bardsoftware/orgs","repos_url":"https://api.github.com/users/bardsoftware/repos","events_url":"https://api.github.com/users/bardsoftware/events{/privacy}","received_events_url":"https://api.github.com/users/bardsoftware/received_events","type":"Organization","site_admin":false},"repo":{"id":123581121,"node_id":"MDEwOlJlcG9zaXRvcnkxMjM1ODExMjE=","name":"papeeria-edit-history","full_name":"bardsoftware/papeeria-edit-history","owner":{"login":"bardsoftware","id":2625618,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2MjU2MTg=","avatar_url":"https://avatars1.githubusercontent.com/u/2625618?v=4","gravatar_id":"","url":"https://api.github.com/users/bardsoftware","html_url":"https://github.com/bardsoftware","followers_url":"https://api.github.com/users/bardsoftware/followers","following_url":"https://api.github.com/users/bardsoftware/following{/other_user}","gists_url":"https://api.github.com/users/bardsoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/bardsoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bardsoftware/subscriptions","organizations_url":"https://api.github.com/users/bardsoftware/orgs","repos_url":"https://api.github.com/users/bardsoftware/repos","events_url":"https://api.github.com/users/bardsoftware/events{/privacy}","received_events_url":"https://api.github.com/users/bardsoftware/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bardsoftware/papeeria-edit-history","description":null,"fork":false,"url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history","forks_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/forks","keys_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/teams","hooks_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/hooks","issue_events_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues/events{/number}","events_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/events","assignees_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/assignees{/user}","branches_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/branches{/branch}","tags_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/tags","blobs_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/refs{/sha}","trees_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/statuses/{sha}","languages_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/languages","stargazers_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/stargazers","contributors_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/contributors","subscribers_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/subscribers","subscription_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/subscription","commits_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/commits{/sha}","git_commits_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/git/commits{/sha}","comments_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/comments{/number}","issue_comment_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues/comments{/number}","contents_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/contents/{+path}","compare_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/merges","archive_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/downloads","issues_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues{/number}","pulls_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls{/number}","milestones_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/milestones{/number}","notifications_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/labels{/name}","releases_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/releases{/id}","deployments_url":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/deployments","created_at":"2018-03-02T13:16:07Z","updated_at":"2018-05-25T16:46:22Z","pushed_at":"2018-05-30T07:09:59Z","git_url":"git://github.com/bardsoftware/papeeria-edit-history.git","ssh_url":"git@github.com:bardsoftware/papeeria-edit-history.git","clone_url":"https://github.com/bardsoftware/papeeria-edit-history.git","svn_url":"https://github.com/bardsoftware/papeeria-edit-history","homepage":null,"size":369,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":3,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":3,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/28"},"html":{"href":"https://github.com/bardsoftware/papeeria-edit-history/pull/28"},"issue":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues/28"},"comments":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/issues/28/comments"},"review_comments":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/28/comments"},"review_comment":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/pulls/28/commits"},"statuses":{"href":"https://api.github.com/repos/bardsoftware/papeeria-edit-history/statuses/ee165b61bf1b681e9210fb5f57c7fb688c721a87"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"dbarashev"}}