{"action":"created","comment":{"url":"https://api.github.com/repos/google/makerspace-auth/pulls/comments/111444093","pull_request_review_id":32691440,"id":111444093,"diff_hunk":"@@ -0,0 +1,109 @@\n+#!/usr/bin/python\n+#\n+# Copyright 2017 Google Inc. All Rights Reserved.\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+\"\"\"Wrapper for pcProx RDR-6081AKU and compatible.\n+\"\"\"\n+\n+import evdev\n+\n+from authbox.api import BaseDerivedThread, NoMatchingDevice\n+\n+\n+class HIDKeystrokingReader(BaseDerivedThread):\n+  scancodes = {\n+      # Scancode: ASCIICode\n+      0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6',\n+      8: u'7', 9: u'8', 10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'BKSP',\n+      15: u'TAB', 16: u'q', 17: u'w', 18: u'e', 19: u'r', 20: u't', 21: u'y',\n+      22: u'u', 23: u'i', 24: u'o', 25: u'p', 26: u'[', 27: u']', 28: u'CRLF',\n+      29: u'LCTRL', 30: u'a', 31: u's', 32: u'd', 33: u'f', 34: u'g', 35: u'h',\n+      36: u'j', 37: u'k', 38: u'l', 39: u';', 40: u'\"', 41: u'`', 42: u'LSHFT',\n+      43: u'\\\\', 44: u'z', 45: u'x', 46: u'c', 47: u'v', 48: u'b', 49: u'n',\n+      50: u'm', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 56: u'LALT',\n+      100: u'RALT'\n+  }\n+\n+  # capscancodes are present to shift badge scans as necessary\n+\n+  capscancodes = {\n+      0: None, 1: u'ESC', 2: u'!', 3: u'@', 4: u'#', 5: u'$', 6: u'%', 7: u'^',\n+      8: u'&', 9: u'*', 10: u'(', 11: u')', 12: u'_', 13: u'+', 14: u'BKSP',\n+      15: u'TAB', 16: u'Q', 17: u'W', 18: u'E', 19: u'R', 20: u'T', 21: u'Y',\n+      22: u'U', 23: u'I', 24: u'O', 25: u'P', 26: u'{', 27: u'}', 28: u'CRLF',\n+      29: u'LCTRL', 30: u'A', 31: u'S', 32: u'D', 33: u'F', 34: u'G', 35: u'H',\n+      36: u'J', 37: u'K', 38: u'L', 39: u':', 40: u'\\'', 41: u'~', 42: u'LSHFT',\n+      43: u'|', 44: u'Z', 45: u'X', 46: u'C', 47: u'V', 48: u'B', 49: u'N',\n+      50: u'M', 51: u'<', 52: u'>', 53: u'?', 54: u'RSHFT', 56: u'LALT', 57: u' ',\n+      100: u'RALT'\n+  }\n+\n+  # TODO verify args/kwargs here is reasonable\n+  def __init__(self, event_queue, config_name, device_name='<USBBadgeScanner>', on_scan=None):\n+    super(HIDKeystrokingReader, self).__init__(event_queue, config_name)\n+    self._on_scan = on_scan\n+    self._device_name = device_name\n+    self.f = self.get_scanner_device()\n+\n+  def get_scanner_device(self):\n+    \"\"\"Finds connected device matching device_name.\n+\n+    Returns:\n+      The file for input events that read_input can listen to\n+    \"\"\"\n+\n+    device_name = '<USBBadgeScanner>'\n+    devices = [evdev.InputDevice(x) for x in evdev.list_devices()]\n+    device = None\n+    for dev in devices:\n+      if str(dev.name) == self._device_name:\n+        device = dev\n+        return device\n+\n+    raise NoMatchingDevice(self._device_name)\n+\n+  def read_input(self):\n+    \"\"\"Listens solely to the RFID keyboard and returns the scanned badge.\n+\n+    Args:\n+      device: input device to listen to\n+\n+    Returns:\n+      badge value as string\n+    \"\"\"\n+\n+    rfid = ''\n+    capitalized = 0\n+    device = self.f\n+    for event in device.read_loop():\n+      data = evdev.categorize(event)\n+      if event.type == evdev.ecodes.EV_KEY and data.keystate == 1:\n+      # detects if the keyboard uses \"LSHFT\"\n+        if data.scancode == 42:","path":"software/authbox/badgereader_hid_keystroking.py","position":94,"original_position":94,"commit_id":"15134eab78f71c3ed32612570c51d4bb4f80fd7b","original_commit_id":"15134eab78f71c3ed32612570c51d4bb4f80fd7b","user":{"login":"gmlewis","id":6598971,"avatar_url":"https://avatars2.githubusercontent.com/u/6598971?v=3","gravatar_id":"","url":"https://api.github.com/users/gmlewis","html_url":"https://github.com/gmlewis","followers_url":"https://api.github.com/users/gmlewis/followers","following_url":"https://api.github.com/users/gmlewis/following{/other_user}","gists_url":"https://api.github.com/users/gmlewis/gists{/gist_id}","starred_url":"https://api.github.com/users/gmlewis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gmlewis/subscriptions","organizations_url":"https://api.github.com/users/gmlewis/orgs","repos_url":"https://api.github.com/users/gmlewis/repos","events_url":"https://api.github.com/users/gmlewis/events{/privacy}","received_events_url":"https://api.github.com/users/gmlewis/received_events","type":"User","site_admin":false},"body":"nit: I would make these 42's constants at the top of the file with descriptive names... I think it is easier to read the code where it is used... your call.\r\n(Here and line 98 below.)","created_at":"2017-04-13T17:32:50Z","updated_at":"2017-04-13T17:38:44Z","html_url":"https://github.com/google/makerspace-auth/pull/3#discussion_r111444093","pull_request_url":"https://api.github.com/repos/google/makerspace-auth/pulls/3","_links":{"self":{"href":"https://api.github.com/repos/google/makerspace-auth/pulls/comments/111444093"},"html":{"href":"https://github.com/google/makerspace-auth/pull/3#discussion_r111444093"},"pull_request":{"href":"https://api.github.com/repos/google/makerspace-auth/pulls/3"}}},"pull_request":{"url":"https://api.github.com/repos/google/makerspace-auth/pulls/3","id":114967567,"html_url":"https://github.com/google/makerspace-auth/pull/3","diff_url":"https://github.com/google/makerspace-auth/pull/3.diff","patch_url":"https://github.com/google/makerspace-auth/pull/3.patch","issue_url":"https://api.github.com/repos/google/makerspace-auth/issues/3","number":3,"state":"open","locked":false,"title":"Add client Python code","user":{"login":"thatch","id":49834,"avatar_url":"https://avatars3.githubusercontent.com/u/49834?v=3","gravatar_id":"","url":"https://api.github.com/users/thatch","html_url":"https://github.com/thatch","followers_url":"https://api.github.com/users/thatch/followers","following_url":"https://api.github.com/users/thatch/following{/other_user}","gists_url":"https://api.github.com/users/thatch/gists{/gist_id}","starred_url":"https://api.github.com/users/thatch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thatch/subscriptions","organizations_url":"https://api.github.com/users/thatch/orgs","repos_url":"https://api.github.com/users/thatch/repos","events_url":"https://api.github.com/users/thatch/events{/privacy}","received_events_url":"https://api.github.com/users/thatch/received_events","type":"User","site_admin":false},"body":"It has TODOs and needs tests/testing both, but it's in a state ready to review (license/style both reasonable).  @precision can you take a look?","created_at":"2017-04-09T01:00:29Z","updated_at":"2017-04-13T17:38:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0d05c62add3656d42a24934bf86597da6b216e1d","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/google/makerspace-auth/pulls/3/commits","review_comments_url":"https://api.github.com/repos/google/makerspace-auth/pulls/3/comments","review_comment_url":"https://api.github.com/repos/google/makerspace-auth/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/makerspace-auth/issues/3/comments","statuses_url":"https://api.github.com/repos/google/makerspace-auth/statuses/15134eab78f71c3ed32612570c51d4bb4f80fd7b","head":{"label":"thatch:tmp-client-software","ref":"tmp-client-software","sha":"15134eab78f71c3ed32612570c51d4bb4f80fd7b","user":{"login":"thatch","id":49834,"avatar_url":"https://avatars3.githubusercontent.com/u/49834?v=3","gravatar_id":"","url":"https://api.github.com/users/thatch","html_url":"https://github.com/thatch","followers_url":"https://api.github.com/users/thatch/followers","following_url":"https://api.github.com/users/thatch/following{/other_user}","gists_url":"https://api.github.com/users/thatch/gists{/gist_id}","starred_url":"https://api.github.com/users/thatch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thatch/subscriptions","organizations_url":"https://api.github.com/users/thatch/orgs","repos_url":"https://api.github.com/users/thatch/repos","events_url":"https://api.github.com/users/thatch/events{/privacy}","received_events_url":"https://api.github.com/users/thatch/received_events","type":"User","site_admin":false},"repo":{"id":82348757,"name":"makerspace-auth","full_name":"thatch/makerspace-auth","owner":{"login":"thatch","id":49834,"avatar_url":"https://avatars3.githubusercontent.com/u/49834?v=3","gravatar_id":"","url":"https://api.github.com/users/thatch","html_url":"https://github.com/thatch","followers_url":"https://api.github.com/users/thatch/followers","following_url":"https://api.github.com/users/thatch/following{/other_user}","gists_url":"https://api.github.com/users/thatch/gists{/gist_id}","starred_url":"https://api.github.com/users/thatch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thatch/subscriptions","organizations_url":"https://api.github.com/users/thatch/orgs","repos_url":"https://api.github.com/users/thatch/repos","events_url":"https://api.github.com/users/thatch/events{/privacy}","received_events_url":"https://api.github.com/users/thatch/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/thatch/makerspace-auth","description":null,"fork":true,"url":"https://api.github.com/repos/thatch/makerspace-auth","forks_url":"https://api.github.com/repos/thatch/makerspace-auth/forks","keys_url":"https://api.github.com/repos/thatch/makerspace-auth/keys{/key_id}","collaborators_url":"https://api.github.com/repos/thatch/makerspace-auth/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/thatch/makerspace-auth/teams","hooks_url":"https://api.github.com/repos/thatch/makerspace-auth/hooks","issue_events_url":"https://api.github.com/repos/thatch/makerspace-auth/issues/events{/number}","events_url":"https://api.github.com/repos/thatch/makerspace-auth/events","assignees_url":"https://api.github.com/repos/thatch/makerspace-auth/assignees{/user}","branches_url":"https://api.github.com/repos/thatch/makerspace-auth/branches{/branch}","tags_url":"https://api.github.com/repos/thatch/makerspace-auth/tags","blobs_url":"https://api.github.com/repos/thatch/makerspace-auth/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/thatch/makerspace-auth/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/thatch/makerspace-auth/git/refs{/sha}","trees_url":"https://api.github.com/repos/thatch/makerspace-auth/git/trees{/sha}","statuses_url":"https://api.github.com/repos/thatch/makerspace-auth/statuses/{sha}","languages_url":"https://api.github.com/repos/thatch/makerspace-auth/languages","stargazers_url":"https://api.github.com/repos/thatch/makerspace-auth/stargazers","contributors_url":"https://api.github.com/repos/thatch/makerspace-auth/contributors","subscribers_url":"https://api.github.com/repos/thatch/makerspace-auth/subscribers","subscription_url":"https://api.github.com/repos/thatch/makerspace-auth/subscription","commits_url":"https://api.github.com/repos/thatch/makerspace-auth/commits{/sha}","git_commits_url":"https://api.github.com/repos/thatch/makerspace-auth/git/commits{/sha}","comments_url":"https://api.github.com/repos/thatch/makerspace-auth/comments{/number}","issue_comment_url":"https://api.github.com/repos/thatch/makerspace-auth/issues/comments{/number}","contents_url":"https://api.github.com/repos/thatch/makerspace-auth/contents/{+path}","compare_url":"https://api.github.com/repos/thatch/makerspace-auth/compare/{base}...{head}","merges_url":"https://api.github.com/repos/thatch/makerspace-auth/merges","archive_url":"https://api.github.com/repos/thatch/makerspace-auth/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/thatch/makerspace-auth/downloads","issues_url":"https://api.github.com/repos/thatch/makerspace-auth/issues{/number}","pulls_url":"https://api.github.com/repos/thatch/makerspace-auth/pulls{/number}","milestones_url":"https://api.github.com/repos/thatch/makerspace-auth/milestones{/number}","notifications_url":"https://api.github.com/repos/thatch/makerspace-auth/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/thatch/makerspace-auth/labels{/name}","releases_url":"https://api.github.com/repos/thatch/makerspace-auth/releases{/id}","deployments_url":"https://api.github.com/repos/thatch/makerspace-auth/deployments","created_at":"2017-02-18T00:06:48Z","updated_at":"2017-02-18T00:06:50Z","pushed_at":"2017-04-04T18:54:24Z","git_url":"git://github.com/thatch/makerspace-auth.git","ssh_url":"git@github.com:thatch/makerspace-auth.git","clone_url":"https://github.com/thatch/makerspace-auth.git","svn_url":"https://github.com/thatch/makerspace-auth","homepage":null,"size":757,"stargazers_count":0,"watchers_count":0,"language":"Eagle","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"24883b1fb81cf47844d72172162e8b6e89b1bc84","user":{"login":"google","id":1342004,"avatar_url":"https://avatars2.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":79934620,"name":"makerspace-auth","full_name":"google/makerspace-auth","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars2.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/makerspace-auth","description":"Designs for our makerspace access control devices","fork":false,"url":"https://api.github.com/repos/google/makerspace-auth","forks_url":"https://api.github.com/repos/google/makerspace-auth/forks","keys_url":"https://api.github.com/repos/google/makerspace-auth/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/makerspace-auth/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/makerspace-auth/teams","hooks_url":"https://api.github.com/repos/google/makerspace-auth/hooks","issue_events_url":"https://api.github.com/repos/google/makerspace-auth/issues/events{/number}","events_url":"https://api.github.com/repos/google/makerspace-auth/events","assignees_url":"https://api.github.com/repos/google/makerspace-auth/assignees{/user}","branches_url":"https://api.github.com/repos/google/makerspace-auth/branches{/branch}","tags_url":"https://api.github.com/repos/google/makerspace-auth/tags","blobs_url":"https://api.github.com/repos/google/makerspace-auth/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/makerspace-auth/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/makerspace-auth/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/makerspace-auth/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/makerspace-auth/statuses/{sha}","languages_url":"https://api.github.com/repos/google/makerspace-auth/languages","stargazers_url":"https://api.github.com/repos/google/makerspace-auth/stargazers","contributors_url":"https://api.github.com/repos/google/makerspace-auth/contributors","subscribers_url":"https://api.github.com/repos/google/makerspace-auth/subscribers","subscription_url":"https://api.github.com/repos/google/makerspace-auth/subscription","commits_url":"https://api.github.com/repos/google/makerspace-auth/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/makerspace-auth/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/makerspace-auth/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/makerspace-auth/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/makerspace-auth/contents/{+path}","compare_url":"https://api.github.com/repos/google/makerspace-auth/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/makerspace-auth/merges","archive_url":"https://api.github.com/repos/google/makerspace-auth/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/makerspace-auth/downloads","issues_url":"https://api.github.com/repos/google/makerspace-auth/issues{/number}","pulls_url":"https://api.github.com/repos/google/makerspace-auth/pulls{/number}","milestones_url":"https://api.github.com/repos/google/makerspace-auth/milestones{/number}","notifications_url":"https://api.github.com/repos/google/makerspace-auth/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/makerspace-auth/labels{/name}","releases_url":"https://api.github.com/repos/google/makerspace-auth/releases{/id}","deployments_url":"https://api.github.com/repos/google/makerspace-auth/deployments","created_at":"2017-01-24T17:19:08Z","updated_at":"2017-03-29T16:41:08Z","pushed_at":"2017-04-09T01:00:29Z","git_url":"git://github.com/google/makerspace-auth.git","ssh_url":"git@github.com:google/makerspace-auth.git","clone_url":"https://github.com/google/makerspace-auth.git","svn_url":"https://github.com/google/makerspace-auth","homepage":"","size":746,"stargazers_count":4,"watchers_count":4,"language":"Eagle","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":1,"forks":2,"open_issues":1,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/makerspace-auth/pulls/3"},"html":{"href":"https://github.com/google/makerspace-auth/pull/3"},"issue":{"href":"https://api.github.com/repos/google/makerspace-auth/issues/3"},"comments":{"href":"https://api.github.com/repos/google/makerspace-auth/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/google/makerspace-auth/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/google/makerspace-auth/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/makerspace-auth/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/google/makerspace-auth/statuses/15134eab78f71c3ed32612570c51d4bb4f80fd7b"}}}}
{"actor":{"display_login":"gmlewis"}}