{"action":"created","comment":{"url":"https://api.github.com/repos/google/personfinder/pulls/comments/32102219","id":32102219,"diff_hunk":"@@ -0,0 +1,108 @@\n+#!/usr/bin/python2.7\n+# -*- coding: utf-8 -*-\n+# Copyright 2015 Google Inc.\n+#\n+# Licensed under the Apache License, Version 2.0 (the \"License\");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+# http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+\n+\"\"\"\n+Command-line utility: generate XML note files that can be posted to the\n+API to add a note to all the person records in a repo.  (We use the API\n+to do this rather than the import mechanism so that subscribers will get\n+notified; see the call to importer.import_records in api.Write.post.)\n+\n+To use:\n+\n+    REPO='2015-nepal-earthquake'\n+    /usr/bin/python tools/download_feed.py \\\n+      --format=csv \\\n+      --out=persons.csv \\\n+      --min_entry_date=2010-10-01 \\\n+      --key=$PF_KEY \\\n+      https://www.google.org/personfinder/$REPO/feeds/person\n+    tools/notes_for_all_persons \\\n+      google.org/personfinder $USER@google.com persons.csv \\\n+      /tmp/nepal-notes 2015-nepal-earthquake '2015-05-12T06:50:00Z' \\\n+      information_sought note_body.txt\n+    Password: <enter your ASP>\n+\n+The result will be a series of files prefixed with /tmp/nepal-notes that you can\n+then post to the Person Finder API to write the notes to the datastore like this:\n+\n+    for i in `seq 0 100 10200`; do\n+      echo $i\n+      curl -X POST -H 'Content-type: application/xml' --data-binary @/tmp/nepal-notes.${i}.xml \\\n+           https://www.google.org/personfinder/2015-nepal-earthquake/api/write?key=$PF_KEY\n+    done\n+\n+\"\"\"\n+\n+from model import *\n+import atom\n+import datetime\n+import logging\n+import csv\n+import remote_api\n+import sys\n+\n+logging.basicConfig()\n+logging.getLogger().setLevel(logging.INFO)\n+\n+\n+def all_person_record_ids(persons_feed_file_name, batch_size=100):\n+    \"\"\"Generates all the record IDs of persons in the given persons feed CSV file.\"\"\"\n+    with open(persons_feed_file_name) as f:\n+        reader = csv.DictReader(f)\n+        for row in reader:\n+            print row['person_record_id']\n+            yield row['person_record_id']\n+\n+def write_notes_for_all_persons(\n+        persons_feed_file_name, basename, date, status, text, batch_size=100):\n+    \"\"\"Writes XML Atom feeds of notes, one for every person in the persons feed file.\"\"\"\n+    note_dicts = []\n+    for person_record_id in all_person_record_ids(persons_feed_file_name):\n+        # Generate a note record ID that (a) can never collide with a future\n+        # generated note record ID and (b) is a function of the person record\n+        # ID to ensure that at most one note is created per person regardless\n+        # of how many times this function is executed.\n+        domain, id = person_record_id.split('/', 1)\n+        note_record_id = domain + '/note.system01-' + id","path":"tools/notes_for_all_persons.py","position":null,"original_position":79,"commit_id":"f0ed64e0df4b98ec3eb254180b3bc4a7e84d3e0f","original_commit_id":"d5ceda333f0ce164b7e565e35a5466a96295c05a","user":{"login":"gimite","id":15363,"avatar_url":"https://avatars.githubusercontent.com/u/15363?v=3","gravatar_id":"","url":"https://api.github.com/users/gimite","html_url":"https://github.com/gimite","followers_url":"https://api.github.com/users/gimite/followers","following_url":"https://api.github.com/users/gimite/following{/other_user}","gists_url":"https://api.github.com/users/gimite/gists{/gist_id}","starred_url":"https://api.github.com/users/gimite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gimite/subscriptions","organizations_url":"https://api.github.com/users/gimite/orgs","repos_url":"https://api.github.com/users/gimite/repos","events_url":"https://api.github.com/users/gimite/events{/privacy}","received_events_url":"https://api.github.com/users/gimite/received_events","type":"User","site_admin":false},"body":"Modified slightly.","created_at":"2015-06-10T09:44:20Z","updated_at":"2015-06-10T09:44:20Z","html_url":"https://github.com/google/personfinder/pull/53#discussion_r32102219","pull_request_url":"https://api.github.com/repos/google/personfinder/pulls/53","_links":{"self":{"href":"https://api.github.com/repos/google/personfinder/pulls/comments/32102219"},"html":{"href":"https://github.com/google/personfinder/pull/53#discussion_r32102219"},"pull_request":{"href":"https://api.github.com/repos/google/personfinder/pulls/53"}}},"pull_request":{"url":"https://api.github.com/repos/google/personfinder/pulls/53","id":35803974,"html_url":"https://github.com/google/personfinder/pull/53","diff_url":"https://github.com/google/personfinder/pull/53.diff","patch_url":"https://github.com/google/personfinder/pull/53.patch","issue_url":"https://api.github.com/repos/google/personfinder/issues/53","number":53,"state":"open","locked":false,"title":"Script to generate notes for all person records","user":{"login":"gimite","id":15363,"avatar_url":"https://avatars.githubusercontent.com/u/15363?v=3","gravatar_id":"","url":"https://api.github.com/users/gimite","html_url":"https://github.com/gimite","followers_url":"https://api.github.com/users/gimite/followers","following_url":"https://api.github.com/users/gimite/following{/other_user}","gists_url":"https://api.github.com/users/gimite/gists{/gist_id}","starred_url":"https://api.github.com/users/gimite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gimite/subscriptions","organizations_url":"https://api.github.com/users/gimite/orgs","repos_url":"https://api.github.com/users/gimite/repos","events_url":"https://api.github.com/users/gimite/events{/privacy}","received_events_url":"https://api.github.com/users/gimite/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-05-20T07:16:56Z","updated_at":"2015-06-10T09:44:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e01c9c9648f567c228f1457dc19c9a452ae84f1d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/google/personfinder/pulls/53/commits","review_comments_url":"https://api.github.com/repos/google/personfinder/pulls/53/comments","review_comment_url":"https://api.github.com/repos/google/personfinder/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/personfinder/issues/53/comments","statuses_url":"https://api.github.com/repos/google/personfinder/statuses/f0ed64e0df4b98ec3eb254180b3bc4a7e84d3e0f","head":{"label":"google:ichikawa-batch-note","ref":"ichikawa-batch-note","sha":"f0ed64e0df4b98ec3eb254180b3bc4a7e84d3e0f","user":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":25369506,"name":"personfinder","full_name":"google/personfinder","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/personfinder","description":"Person Finder is a searchable missing person database written in Python and hosted on App Engine.","fork":false,"url":"https://api.github.com/repos/google/personfinder","forks_url":"https://api.github.com/repos/google/personfinder/forks","keys_url":"https://api.github.com/repos/google/personfinder/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/personfinder/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/personfinder/teams","hooks_url":"https://api.github.com/repos/google/personfinder/hooks","issue_events_url":"https://api.github.com/repos/google/personfinder/issues/events{/number}","events_url":"https://api.github.com/repos/google/personfinder/events","assignees_url":"https://api.github.com/repos/google/personfinder/assignees{/user}","branches_url":"https://api.github.com/repos/google/personfinder/branches{/branch}","tags_url":"https://api.github.com/repos/google/personfinder/tags","blobs_url":"https://api.github.com/repos/google/personfinder/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/personfinder/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/personfinder/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/personfinder/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/personfinder/statuses/{sha}","languages_url":"https://api.github.com/repos/google/personfinder/languages","stargazers_url":"https://api.github.com/repos/google/personfinder/stargazers","contributors_url":"https://api.github.com/repos/google/personfinder/contributors","subscribers_url":"https://api.github.com/repos/google/personfinder/subscribers","subscription_url":"https://api.github.com/repos/google/personfinder/subscription","commits_url":"https://api.github.com/repos/google/personfinder/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/personfinder/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/personfinder/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/personfinder/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/personfinder/contents/{+path}","compare_url":"https://api.github.com/repos/google/personfinder/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/personfinder/merges","archive_url":"https://api.github.com/repos/google/personfinder/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/personfinder/downloads","issues_url":"https://api.github.com/repos/google/personfinder/issues{/number}","pulls_url":"https://api.github.com/repos/google/personfinder/pulls{/number}","milestones_url":"https://api.github.com/repos/google/personfinder/milestones{/number}","notifications_url":"https://api.github.com/repos/google/personfinder/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/personfinder/labels{/name}","releases_url":"https://api.github.com/repos/google/personfinder/releases{/id}","created_at":"2014-10-17T17:36:25Z","updated_at":"2015-06-08T21:21:42Z","pushed_at":"2015-06-10T09:43:33Z","git_url":"git://github.com/google/personfinder.git","ssh_url":"git@github.com:google/personfinder.git","clone_url":"https://github.com/google/personfinder.git","svn_url":"https://github.com/google/personfinder","homepage":"https://google.org/personfinder","size":234356,"stargazers_count":73,"watchers_count":73,"language":"Python","has_issues":true,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":31,"mirror_url":null,"open_issues_count":27,"forks":31,"open_issues":27,"watchers":73,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"044cf2a74c82a0eb2ea458cf4978ec7da9b2feb5","user":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":25369506,"name":"personfinder","full_name":"google/personfinder","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/personfinder","description":"Person Finder is a searchable missing person database written in Python and hosted on App Engine.","fork":false,"url":"https://api.github.com/repos/google/personfinder","forks_url":"https://api.github.com/repos/google/personfinder/forks","keys_url":"https://api.github.com/repos/google/personfinder/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/personfinder/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/personfinder/teams","hooks_url":"https://api.github.com/repos/google/personfinder/hooks","issue_events_url":"https://api.github.com/repos/google/personfinder/issues/events{/number}","events_url":"https://api.github.com/repos/google/personfinder/events","assignees_url":"https://api.github.com/repos/google/personfinder/assignees{/user}","branches_url":"https://api.github.com/repos/google/personfinder/branches{/branch}","tags_url":"https://api.github.com/repos/google/personfinder/tags","blobs_url":"https://api.github.com/repos/google/personfinder/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/personfinder/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/personfinder/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/personfinder/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/personfinder/statuses/{sha}","languages_url":"https://api.github.com/repos/google/personfinder/languages","stargazers_url":"https://api.github.com/repos/google/personfinder/stargazers","contributors_url":"https://api.github.com/repos/google/personfinder/contributors","subscribers_url":"https://api.github.com/repos/google/personfinder/subscribers","subscription_url":"https://api.github.com/repos/google/personfinder/subscription","commits_url":"https://api.github.com/repos/google/personfinder/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/personfinder/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/personfinder/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/personfinder/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/personfinder/contents/{+path}","compare_url":"https://api.github.com/repos/google/personfinder/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/personfinder/merges","archive_url":"https://api.github.com/repos/google/personfinder/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/personfinder/downloads","issues_url":"https://api.github.com/repos/google/personfinder/issues{/number}","pulls_url":"https://api.github.com/repos/google/personfinder/pulls{/number}","milestones_url":"https://api.github.com/repos/google/personfinder/milestones{/number}","notifications_url":"https://api.github.com/repos/google/personfinder/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/personfinder/labels{/name}","releases_url":"https://api.github.com/repos/google/personfinder/releases{/id}","created_at":"2014-10-17T17:36:25Z","updated_at":"2015-06-08T21:21:42Z","pushed_at":"2015-06-10T09:43:33Z","git_url":"git://github.com/google/personfinder.git","ssh_url":"git@github.com:google/personfinder.git","clone_url":"https://github.com/google/personfinder.git","svn_url":"https://github.com/google/personfinder","homepage":"https://google.org/personfinder","size":234356,"stargazers_count":73,"watchers_count":73,"language":"Python","has_issues":true,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":31,"mirror_url":null,"open_issues_count":27,"forks":31,"open_issues":27,"watchers":73,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/personfinder/pulls/53"},"html":{"href":"https://github.com/google/personfinder/pull/53"},"issue":{"href":"https://api.github.com/repos/google/personfinder/issues/53"},"comments":{"href":"https://api.github.com/repos/google/personfinder/issues/53/comments"},"review_comments":{"href":"https://api.github.com/repos/google/personfinder/pulls/53/comments"},"review_comment":{"href":"https://api.github.com/repos/google/personfinder/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/personfinder/pulls/53/commits"},"statuses":{"href":"https://api.github.com/repos/google/personfinder/statuses/f0ed64e0df4b98ec3eb254180b3bc4a7e84d3e0f"}}}}