GitHub PullRequestReviewCommentEvent at 2014-10-03 08:18:02
Repository: bbfs
Actor: bbfsdev
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/bbfsdev/bbfs/pulls/comments/18385152","id":18385152,"diff_hunk":"@@ -0,0 +1,489 @@\n+# NOTE Code Coverage block must be issued before any of your application code is required\n+if ENV['BBFS_COVERAGE']\n+  require_relative '../spec_helper.rb'\n+  SimpleCov.command_name 'content_server'\n+end\n+\n+require 'rspec'\n+require 'tmpdir'\n+require 'params'\n+require 'log'\n+\n+require_relative '../../lib/content_server/content_data_db.rb'\n+\n+module ContentServer\n+  module Spec\n+    describe 'ContentDataDb' do\n+\n+      # Workaround to test singleton\n+      # Creates classes that behaves like a DB class.\n+      def get_db_instance\n+        base = 'DbWrapper'\n+\n+        classname = String.new\n+        free_index = 1.upto(100).find do |i|\n+          classname = base + i.to_s\n+          eval(\"defined?(#{classname}) && #{classname}.is_a?(Class)\").nil?\n+        end\n+\n+        if free_index.nil?\n+          raise 'No free index found. Can not create a DB test class.'\n+        end\n+        klass = Class.new(ContentServer::ContentDataDb) {}\n+        Object.const_set(classname, klass)\n+        klass.instance\n+      end\n+\n+      def is_snapshot?(mtime)\n+        (mtime - BASE_DATETIME)%365 == 0\n+      end\n+\n+      before :all do\n+        Params.init []\n+        Log.init\n+\n+        SIZE = 1000\n+        SERVER = \"server\"\n+        CHECKSUM = \"1000\"\n+        BASE_TIMESTAMP = '2010-11-29T04:01+03:00'\n+        BASE_DATETIME = DateTime.iso8601(BASE_TIMESTAMP)\n+        BASE_MTIME = BASE_DATETIME.strftime('%s').to_i\n+\n+        @base = ContentData::ContentData.new\n+        @base.add_instance(CHECKSUM, SIZE, SERVER, \"unchanged_1\", BASE_MTIME, BASE_MTIME)\n+        @base.add_instance(CHECKSUM, SIZE, SERVER, \"unchanged_2\", BASE_MTIME, BASE_MTIME)\n+\n+        @init_content_datas = {}\n+        @init_content_datas[BASE_DATETIME] = @base\n+        @removed_diffs = {}\n+        @added_diffs = {}\n+        @added_diffs[BASE_DATETIME] = ContentData::ContentData.new(@base)\n+\n+        # Simulates indexation\n+        # @param mtime [DateTime]\n+        add_diff = Proc.new do |mtime|\n+          idx = @init_content_datas.size\n+          mtime_epoch = mtime.strftime('%s').to_i\n+\n+          added_cd_diff = ContentData::ContentData.new\n+          added_cd_diff.add_instance(CHECKSUM+\"#{idx}\", SIZE+idx, SERVER, \"changed_#{idx}\", mtime_epoch, mtime_epoch)\n+          added_cd_diff.add_instance(CHECKSUM, SIZE, SERVER, \"added_#{idx}\", mtime_epoch, mtime_epoch)\n+          @added_diffs[mtime] = added_cd_diff\n+\n+          removed_cd_diff = ContentData::ContentData.new\n+          removed_cd_diff.add_instance(CHECKSUM, SIZE, SERVER, \"changed_#{idx}\", BASE_MTIME, BASE_MTIME)\n+          removed_cd_diff.add_instance(CHECKSUM, SIZE, SERVER, \"removed_#{idx}\", BASE_MTIME, BASE_MTIME)\n+          @removed_diffs[mtime] = removed_cd_diff\n+          # suppose that changed_idx and removed_idx locations\n+          # were indexed first time at BASE_DATETIME\n+          @added_diffs[BASE_DATETIME].merge!(removed_cd_diff)\n+\n+          prev_mtime = @init_content_datas.keys.sort.last\n+          prev_cd = @init_content_datas[prev_mtime]\n+          # prev_cd still do not contain removed_cd_diff instances,\n+          # we add them later\n+          #cd_new = prev_cd.remove_instances(removed_cd_diff)\n+          cd_new = prev_cd.merge(added_cd_diff)\n+\n+          # suppose that changed_idx and removed_idx were indexed before,\n+          # therefore need to update appropriately content data files.\n+          @init_content_datas.each_value do |cd|\n+            cd.merge!(removed_cd_diff)\n+          end\n+\n+          @init_content_datas[mtime] = cd_new\n+        end\n+\n+\n+        [1, 2, 3, 365, 366, 367].each do |supplement|\n+          add_diff.call(BASE_DATETIME + supplement)\n+        end\n+      end\n+\n+      before :each do\n+        @db_dir = Dir.mktmpdir\n+        Params['content_data_db_path'] = @db_dir\n+        @db_instance = get_db_instance\n+\n+        @init_content_datas.keys.sort.each do |mtime|\n+          $local_content_data = @init_content_datas[mtime]\n+          @db_instance.add(is_snapshot?(mtime))\n+        end\n+      end\n+\n+      after :each do\n+        FileUtils.remove_entry_secure @db_dir\n+      end\n+\n+      describe \"Init\" do\n+        it 'create storage directories lazily' do\n+          # Given\n+          FileUtils.rm_rf @db_dir\n+\n+          # check that test environment is correct\n+          Dir.exist?(@db_dir).should be_false\n+          @db_instance = get_db_instance\n+\n+          # When\n+          $local_content_data = @base\n+          @db_instance.add true\n+\n+          # Then\n+          Dir.exist?(@db_dir).should be_true\n+          Dir.exist?(@db_instance.diffs_path).should be_true\n+          Dir.exist?(@db_instance.snapshots_path).should be_true\n+        end\n+\n+        it 'pick a latest timestamp from exist entries in DB' do\n+          # When\n+          @db_instance = get_db_instance\n+\n+          # Then\n+          expected_timestamp = @init_content_datas.keys.sort.last\n+          @db_instance.latest_timestamp.should == expected_timestamp\n+        end\n+      end\n+\n+      describe 'Add' do\n+        before :all do\n+          # new folder for the next year should be created\n+          DATETIME_NEW = @init_content_datas.keys.sort.last + 365\n+          mtime_epoch = DATETIME_NEW.strftime('%s').to_i\n+\n+          @added_cd_diff = ContentData::ContentData.new\n+          @added_cd_diff.add_instance(CHECKSUM+\"a\", SIZE+365*2, SERVER, \"added_new\", mtime_epoch, mtime_epoch)\n+\n+          prev_mtime = @init_content_datas.keys.sort.last\n+          prev_cd = @init_content_datas[prev_mtime]\n+          @removed_cd_diff = @added_diffs[prev_mtime]\n+\n+          @cd_new = prev_cd.remove_instances(@removed_cd_diff)\n+          @cd_new.merge!(@added_cd_diff)\n+        end\n+\n+        before :each do\n+          $local_content_data = @cd_new\n+        end\n+\n+        context 'Snapshot' do\n+          it 'adds a snapshot entry' do\n+            # Given\n+            exist_snapshot_files = @db_instance.snapshot_files\n+\n+            # When\n+            @db_instance.add true\n+\n+            # Then\n+            snapshot_db = @db_instance.get DATETIME_NEW\n+            snapshot_db.should == $local_content_data\n+\n+            current_snapshot_files = @db_instance.snapshot_files\n+            expect(current_snapshot_files.size - exist_snapshot_files.size).to eq(1)\n+          end\n+\n+          it 'adds a diff entries' do\n+            # Given\n+            exist_diff_files = @db_instance.diff_files\n+\n+            # When\n+            @db_instance.add true\n+\n+            #Then\n+            current_diff_files = @db_instance.diff_files\n+            expect(current_diff_files.size - exist_diff_files.size).to eq(2)\n+          end\n+        end\n+\n+        context 'Diff' do\n+          it 'adds removed and added entires (files)' do\n+            # Given\n+            exist_diff_files = @db_instance.diff_files\n+\n+            # When\n+            @db_instance.add false\n+\n+            # Then\n+            current_diff_files = @db_instance.diff_files\n+            expect(current_diff_files.size - exist_diff_files.size).to eq(2)\n+\n+            new_diff_files = current_diff_files.reject do |df|\n+              exist_diff_files.include?(df)\n+            end\n+\n+            new_diff_files.each do |df|\n+              cd = ContentData::ContentData.new\n+              cd.from_file(df.filename)\n+              if df.type == ContentDataDb::DiffFile::ADDED_TYPE\n+                cd.should == @added_cd_diff\n+              elsif df.type == ContentDataDb::DiffFile::REMOVED_TYPE\n+                cd.should == @removed_cd_diff\n+              end\n+            end\n+          end\n+        end\n+\n+        shared_examples 'Empty diff' do\n+          it \"do not add DB entry (file) for this type\" do\n+            # Given\n+            exist_diff_files = @db_instance.diff_files\n+            exist_type_fnames = exist_diff_files.inject([]) do |fnames, df|\n+                                  if df.type == type\n+                                    fnames << df.filename\n+                                  end\n+                                  fnames\n+                                end\n+\n+            # When\n+            $local_content_data = cd_new\n+            @db_instance.add false\n+\n+            # Then\n+            current_diff_files = @db_instance.diff_files\n+            expect(current_diff_files.size - exist_diff_files.size).to eq(1)\n+\n+            new_diff_file = current_diff_files.first do |df|\n+              df.type == type &&\n+                !exist_added_fnames.include?(df.filename)\n+            end\n+            expect(new_diff_file).not_to be nil\n+          end\n+        end\n+\n+        context 'No added instances' do\n+          let(:type) { ContentDataDb::DiffFile::ADDED_TYPE }\n+          let(:cd_new) { @init_content_datas[@init_content_datas.keys.sort.last].\n+                           merge(@added_cd_diff) }\n+          include_examples 'Empty diff'\n+        end\n+\n+        context 'No removed instances' do\n+          let(:type) { ContentDataDb::DiffFile::REMOVED_TYPE }\n+          let(:cd_new) { @init_content_datas[@init_content_datas.keys.sort.last].\n+                           remove_instances(@removed_cd_diff) }\n+          include_examples 'Empty diff'\n+        end\n+\n+        # Examples:\n+        #   1. snapshot file for the '20141129T010100' will be saved as\n+        #      <content_data_db_path>/snapshots/2014/20141129T010100.snapshot\n+        #   1. snapshot file for the '20151129T010100' will be saved as\n+        #      <content_data_db_path>/snapshots/2015/20141129T010100.snapshot\n+        it 'save entries by year' do\n+          pending 'TODO'\n+        end\n+      end\n+\n+      describe 'Diff' do\n+        shared_examples 'diff spec' do\n+          describe 'returns instances with index times' do\n+            it \"later than 'from' and not earlier than 'till'\" do\n+              # When\n+              diff = @db_instance.diff(from, till)\n+\n+              # Then\n+              expected_removed_size = 0\n+              @removed_diffs.each do |timestamp, diff_cd|\n+                if (timestamp <=> from) == 1 && (timestamp <=> till) != 1\n+                  expected_removed_size += diff_cd.instances_size\n+                  diff_cd.each_instance do |checksum,_,_,_,server,path,_|\n+                    diff[ContentDataDb::DiffFile::REMOVED_TYPE].\n+                      content_has_instance?(checksum, server, path).\n+                      should be_true\n+                  end\n+                end\n+              end\n+              diff[ContentDataDb::DiffFile::REMOVED_TYPE].\n+                instances_size.should == expected_removed_size\n+\n+              expected_added_size = 0\n+              @added_diffs.each do |timestamp, diff_cd|\n+                if (timestamp <=> from) == 1 && (timestamp <=> till) != 1\n+                  expected_added_size += diff_cd.instances_size\n+                  diff_cd.each_instance do |checksum,_,_,_,server,path,_|\n+                    diff[ContentDataDb::DiffFile::ADDED_TYPE].\n+                      content_has_instance?(checksum, server, path).\n+                      should be_true\n+                  end\n+                end\n+              end\n+              diff[ContentDataDb::DiffFile::ADDED_TYPE].\n+                instances_size.should == expected_added_size\n+            end\n+\n+            it 'latest if there were few for the location' do\n+              # Given\n+              # prepare input where:\n+              # file was few times changed (old revision removed, new added)\n+              latest_index_time = @init_content_datas.keys.sort.last\n+              latest_cd = @init_content_datas[latest_index_time]\n+              changed_fname = \"changed_new\"\n+              expected_checksum = nil\n+              1.upto(4) do |i|\n+                cd_new = ContentData::ContentData.new(latest_cd)\n+                if cd_new.instance_exists(SERVER, changed_fname)\n+                  cd_new.remove_instance(SERVER, changed_fname)\n+                end\n+                mtime = latest_index_time + 1\n+                mtime_epoch = mtime.strftime('%s').to_i\n+                expected_checksum = CHECKSUM + \"#{i}\"\n+                cd_new.add_instance(expected_checksum,\n+                                    SIZE + i,\n+                                    SERVER,\n+                                    changed_fname,\n+                                    mtime_epoch,\n+                                    mtime_epoch)\n+                latest_index_time = mtime\n+                latest_cd = cd_new\n+                $local_content_data = cd_new\n+                @db_instance.add false\n+              end\n+              expected_added_time = latest_index_time\n+              # and finally removed\n+              cd_new = ContentData::ContentData.new(latest_cd)\n+              cd_new.remove_instance(SERVER, changed_fname)\n+              $local_content_data = cd_new\n+              @db_instance.add false\n+\n+              # When\n+              diff = @db_instance.diff(from, @db_instance.latest_timestamp)\n+\n+              # Then\n+              diff[ContentDataDb::DiffFile::ADDED_TYPE].\n+                each_instance do |checksum,_,_,_,_,path,index_time|\n+                  if (path == changed_fname)\n+                    index_time.should == expected_added_time.strftime('%s').to_i\n+                    checksum.should == expected_checksum\n+                  end\n+                end\n+              diff[ContentDataDb::DiffFile::REMOVED_TYPE].\n+                each_instance do |checksum,_,_,_,_,path,index_time|\n+                  if (path == changed_fname)\n+                    # Was removed instance that was indexed at expected_added_time\n+                    index_time.should == expected_added_time.strftime('%s').to_i\n+                    checksum.should == expected_checksum\n+                  end\n+                end\n+            end\n+          end\n+        end\n+\n+        context \"diffs between two timestamps from same year\" do","path":"spec/content_server/content_data_db_spec.rb","position":370,"original_position":370,"commit_id":"078ccad378bec6511f2eec471f6c965485d0a031","original_commit_id":"078ccad378bec6511f2eec471f6c965485d0a031","user":{"login":"bbfsdev","id":1877419,"avatar_url":"https://avatars.githubusercontent.com/u/1877419?v=2","gravatar_id":"","url":"https://api.github.com/users/bbfsdev","html_url":"https://github.com/bbfsdev","followers_url":"https://api.github.com/users/bbfsdev/followers","following_url":"https://api.github.com/users/bbfsdev/following{/other_user}","gists_url":"https://api.github.com/users/bbfsdev/gists{/gist_id}","starred_url":"https://api.github.com/users/bbfsdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bbfsdev/subscriptions","organizations_url":"https://api.github.com/users/bbfsdev/orgs","repos_url":"https://api.github.com/users/bbfsdev/repos","events_url":"https://api.github.com/users/bbfsdev/events{/privacy}","received_events_url":"https://api.github.com/users/bbfsdev/received_events","type":"User","site_admin":false},"body":"Nice.","created_at":"2014-10-03T08:18:02Z","updated_at":"2014-10-03T08:18:02Z","html_url":"https://github.com/bbfsdev/bbfs/pull/273#discussion_r18385152","pull_request_url":"https://api.github.com/repos/bbfsdev/bbfs/pulls/273","_links":{"self":{"href":"https://api.github.com/repos/bbfsdev/bbfs/pulls/comments/18385152"},"html":{"href":"https://github.com/bbfsdev/bbfs/pull/273#discussion_r18385152"},"pull_request":{"href":"https://api.github.com/repos/bbfsdev/bbfs/pulls/273"}}},"pull_request":{"url":"https://api.github.com/repos/bbfsdev/bbfs/pulls/273","id":19262499,"html_url":"https://github.com/bbfsdev/bbfs/pull/273","diff_url":"https://github.com/bbfsdev/bbfs/pull/273.diff","patch_url":"https://github.com/bbfsdev/bbfs/pull/273.patch","issue_url":"https://api.github.com/repos/bbfsdev/bbfs/issues/273","number":273,"state":"open","locked":false,"title":"issue270_incremental_diff","user":{"login":"bbfsdev","id":1877419,"avatar_url":"https://avatars.githubusercontent.com/u/1877419?v=2","gravatar_id":"","url":"https://api.github.com/users/bbfsdev","html_url":"https://github.com/bbfsdev","followers_url":"https://api.github.com/users/bbfsdev/followers","following_url":"https://api.github.com/users/bbfsdev/following{/other_user}","gists_url":"https://api.github.com/users/bbfsdev/gists{/gist_id}","starred_url":"https://api.github.com/users/bbfsdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bbfsdev/subscriptions","organizations_url":"https://api.github.com/users/bbfsdev/orgs","repos_url":"https://api.github.com/users/bbfsdev/repos","events_url":"https://api.github.com/users/bbfsdev/events{/privacy}","received_events_url":"https://api.github.com/users/bbfsdev/received_events","type":"User","site_admin":false},"body":"","created_at":"2014-08-04T02:10:33Z","updated_at":"2014-10-03T08:18:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d665303d00466888aa601925655fd9adf7654375","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/bbfsdev/bbfs/pulls/273/commits","review_comments_url":"https://api.github.com/repos/bbfsdev/bbfs/pulls/273/comments","review_comment_url":"https://api.github.com/repos/bbfsdev/bbfs/pulls/comments/{number}","comments_url":"https://api.github.com/repos/bbfsdev/bbfs/issues/273/comments","statuses_url":"https://api.github.com/repos/bbfsdev/bbfs/statuses/078ccad378bec6511f2eec471f6c965485d0a031","head":{"label":"bbfsdev:issue270_incremental_diff","ref":"issue270_incremental_diff","sha":"078ccad378bec6511f2eec471f6c965485d0a031","user":{"login":"bbfsdev","id":1877419,"avatar_url":"https://avatars.githubusercontent.com/u/1877419?v=2","gravatar_id":"","url":"https://api.github.com/users/bbfsdev","html_url":"https://github.com/bbfsdev","followers_url":"https://api.github.com/users/bbfsdev/followers","following_url":"https://api.github.com/users/bbfsdev/following{/other_user}","gists_url":"https://api.github.com/users/bbfsdev/gists{/gist_id}","starred_url":"https://api.github.com/users/bbfsdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bbfsdev/subscriptions","organizations_url":"https://api.github.com/users/bbfsdev/orgs","repos_url":"https://api.github.com/users/bbfsdev/repos","events_url":"https://api.github.com/users/bbfsdev/events{/privacy}","received_events_url":"https://api.github.com/users/bbfsdev/received_events","type":"User","site_admin":false},"repo":{"id":1909546,"name":"bbfs","full_name":"bbfsdev/bbfs","owner":{"login":"bbfsdev","id":1877419,"avatar_url":"https://avatars.githubusercontent.com/u/1877419?v=2","gravatar_id":"","url":"https://api.github.com/users/bbfsdev","html_url":"https://github.com/bbfsdev","followers_url":"https://api.github.com/users/bbfsdev/followers","following_url":"https://api.github.com/users/bbfsdev/following{/other_user}","gists_url":"https://api.github.com/users/bbfsdev/gists{/gist_id}","starred_url":"https://api.github.com/users/bbfsdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bbfsdev/subscriptions","organizations_url":"https://api.github.com/users/bbfsdev/orgs","repos_url":"https://api.github.com/users/bbfsdev/repos","events_url":"https://api.github.com/users/bbfsdev/events{/privacy}","received_events_url":"https://api.github.com/users/bbfsdev/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bbfsdev/bbfs","description":"Big brother file system (distributed file system)","fork":false,"url":"https://api.github.com/repos/bbfsdev/bbfs","forks_url":"https://api.github.com/repos/bbfsdev/bbfs/forks","keys_url":"https://api.github.com/repos/bbfsdev/bbfs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bbfsdev/bbfs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bbfsdev/bbfs/teams","hooks_url":"https://api.github.com/repos/bbfsdev/bbfs/hooks","issue_events_url":"https://api.github.com/repos/bbfsdev/bbfs/issues/events{/number}","events_url":"https://api.github.com/repos/bbfsdev/bbfs/events","assignees_url":"https://api.github.com/repos/bbfsdev/bbfs/assignees{/user}","branches_url":"https://api.github.com/repos/bbfsdev/bbfs/branches{/branch}","tags_url":"https://api.github.com/repos/bbfsdev/bbfs/tags","blobs_url":"https://api.github.com/repos/bbfsdev/bbfs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bbfsdev/bbfs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bbfsdev/bbfs/git/refs{/sha}","trees_url":"https://api.github.com/repos/bbfsdev/bbfs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bbfsdev/bbfs/statuses/{sha}","languages_url":"https://api.github.com/repos/bbfsdev/bbfs/languages","stargazers_url":"https://api.github.com/repos/bbfsdev/bbfs/stargazers","contributors_url":"https://api.github.com/repos/bbfsdev/bbfs/contributors","subscribers_url":"https://api.github.com/repos/bbfsdev/bbfs/subscribers","subscription_url":"https://api.github.com/repos/bbfsdev/bbfs/subscription","commits_url":"https://api.github.com/repos/bbfsdev/bbfs/commits{/sha}","git_commits_url":"https://api.github.com/repos/bbfsdev/bbfs/git/commits{/sha}","comments_url":"https://api.github.com/repos/bbfsdev/bbfs/comments{/number}","issue_comment_url":"https://api.github.com/repos/bbfsdev/bbfs/issues/comments/{number}","contents_url":"https://api.github.com/repos/bbfsdev/bbfs/contents/{+path}","compare_url":"https://api.github.com/repos/bbfsdev/bbfs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bbfsdev/bbfs/merges","archive_url":"https://api.github.com/repos/bbfsdev/bbfs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bbfsdev/bbfs/downloads","issues_url":"https://api.github.com/repos/bbfsdev/bbfs/issues{/number}","pulls_url":"https://api.github.com/repos/bbfsdev/bbfs/pulls{/number}","milestones_url":"https://api.github.com/repos/bbfsdev/bbfs/milestones{/number}","notifications_url":"https://api.github.com/repos/bbfsdev/bbfs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bbfsdev/bbfs/labels{/name}","releases_url":"https://api.github.com/repos/bbfsdev/bbfs/releases{/id}","created_at":"2011-06-17T05:30:02Z","updated_at":"2014-07-19T11:56:29Z","pushed_at":"2014-09-28T06:26:34Z","git_url":"git://github.com/bbfsdev/bbfs.git","ssh_url":"git@github.com:bbfsdev/bbfs.git","clone_url":"https://github.com/bbfsdev/bbfs.git","svn_url":"https://github.com/bbfsdev/bbfs","homepage":"","size":8380,"stargazers_count":8,"watchers_count":8,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":36,"forks":4,"open_issues":36,"watchers":8,"default_branch":"master"}},"base":{"label":"bbfsdev:master","ref":"master","sha":"c91334d35af4c86be6fd9fe096419ed319418d51","user":{"login":"bbfsdev","id":1877419,"avatar_url":"https://avatars.githubusercontent.com/u/1877419?v=2","gravatar_id":"","url":"https://api.github.com/users/bbfsdev","html_url":"https://github.com/bbfsdev","followers_url":"https://api.github.com/users/bbfsdev/followers","following_url":"https://api.github.com/users/bbfsdev/following{/other_user}","gists_url":"https://api.github.com/users/bbfsdev/gists{/gist_id}","starred_url":"https://api.github.com/users/bbfsdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bbfsdev/subscriptions","organizations_url":"https://api.github.com/users/bbfsdev/orgs","repos_url":"https://api.github.com/users/bbfsdev/repos","events_url":"https://api.github.com/users/bbfsdev/events{/privacy}","received_events_url":"https://api.github.com/users/bbfsdev/received_events","type":"User","site_admin":false},"repo":{"id":1909546,"name":"bbfs","full_name":"bbfsdev/bbfs","owner":{"login":"bbfsdev","id":1877419,"avatar_url":"https://avatars.githubusercontent.com/u/1877419?v=2","gravatar_id":"","url":"https://api.github.com/users/bbfsdev","html_url":"https://github.com/bbfsdev","followers_url":"https://api.github.com/users/bbfsdev/followers","following_url":"https://api.github.com/users/bbfsdev/following{/other_user}","gists_url":"https://api.github.com/users/bbfsdev/gists{/gist_id}","starred_url":"https://api.github.com/users/bbfsdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bbfsdev/subscriptions","organizations_url":"https://api.github.com/users/bbfsdev/orgs","repos_url":"https://api.github.com/users/bbfsdev/repos","events_url":"https://api.github.com/users/bbfsdev/events{/privacy}","received_events_url":"https://api.github.com/users/bbfsdev/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bbfsdev/bbfs","description":"Big brother file system (distributed file system)","fork":false,"url":"https://api.github.com/repos/bbfsdev/bbfs","forks_url":"https://api.github.com/repos/bbfsdev/bbfs/forks","keys_url":"https://api.github.com/repos/bbfsdev/bbfs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bbfsdev/bbfs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bbfsdev/bbfs/teams","hooks_url":"https://api.github.com/repos/bbfsdev/bbfs/hooks","issue_events_url":"https://api.github.com/repos/bbfsdev/bbfs/issues/events{/number}","events_url":"https://api.github.com/repos/bbfsdev/bbfs/events","assignees_url":"https://api.github.com/repos/bbfsdev/bbfs/assignees{/user}","branches_url":"https://api.github.com/repos/bbfsdev/bbfs/branches{/branch}","tags_url":"https://api.github.com/repos/bbfsdev/bbfs/tags","blobs_url":"https://api.github.com/repos/bbfsdev/bbfs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bbfsdev/bbfs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bbfsdev/bbfs/git/refs{/sha}","trees_url":"https://api.github.com/repos/bbfsdev/bbfs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bbfsdev/bbfs/statuses/{sha}","languages_url":"https://api.github.com/repos/bbfsdev/bbfs/languages","stargazers_url":"https://api.github.com/repos/bbfsdev/bbfs/stargazers","contributors_url":"https://api.github.com/repos/bbfsdev/bbfs/contributors","subscribers_url":"https://api.github.com/repos/bbfsdev/bbfs/subscribers","subscription_url":"https://api.github.com/repos/bbfsdev/bbfs/subscription","commits_url":"https://api.github.com/repos/bbfsdev/bbfs/commits{/sha}","git_commits_url":"https://api.github.com/repos/bbfsdev/bbfs/git/commits{/sha}","comments_url":"https://api.github.com/repos/bbfsdev/bbfs/comments{/number}","issue_comment_url":"https://api.github.com/repos/bbfsdev/bbfs/issues/comments/{number}","contents_url":"https://api.github.com/repos/bbfsdev/bbfs/contents/{+path}","compare_url":"https://api.github.com/repos/bbfsdev/bbfs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bbfsdev/bbfs/merges","archive_url":"https://api.github.com/repos/bbfsdev/bbfs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bbfsdev/bbfs/downloads","issues_url":"https://api.github.com/repos/bbfsdev/bbfs/issues{/number}","pulls_url":"https://api.github.com/repos/bbfsdev/bbfs/pulls{/number}","milestones_url":"https://api.github.com/repos/bbfsdev/bbfs/milestones{/number}","notifications_url":"https://api.github.com/repos/bbfsdev/bbfs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bbfsdev/bbfs/labels{/name}","releases_url":"https://api.github.com/repos/bbfsdev/bbfs/releases{/id}","created_at":"2011-06-17T05:30:02Z","updated_at":"2014-07-19T11:56:29Z","pushed_at":"2014-09-28T06:26:34Z","git_url":"git://github.com/bbfsdev/bbfs.git","ssh_url":"git@github.com:bbfsdev/bbfs.git","clone_url":"https://github.com/bbfsdev/bbfs.git","svn_url":"https://github.com/bbfsdev/bbfs","homepage":"","size":8380,"stargazers_count":8,"watchers_count":8,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":36,"forks":4,"open_issues":36,"watchers":8,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bbfsdev/bbfs/pulls/273"},"html":{"href":"https://github.com/bbfsdev/bbfs/pull/273"},"issue":{"href":"https://api.github.com/repos/bbfsdev/bbfs/issues/273"},"comments":{"href":"https://api.github.com/repos/bbfsdev/bbfs/issues/273/comments"},"review_comments":{"href":"https://api.github.com/repos/bbfsdev/bbfs/pulls/273/comments"},"review_comment":{"href":"https://api.github.com/repos/bbfsdev/bbfs/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/bbfsdev/bbfs/pulls/273/commits"},"statuses":{"href":"https://api.github.com/repos/bbfsdev/bbfs/statuses/078ccad378bec6511f2eec471f6c965485d0a031"}}}}