{"action":"created","comment":{"url":"https://api.github.com/repos/acm-uiuc/beats/pulls/comments/39114569","id":39114569,"diff_hunk":"@@ -148,6 +148,76 @@ def add_songs_in_dir(path, store_checksum=False):\n     conn.close()\n     return num_songs\n \n+def recover_art(path):\n+    \"\"\"Recovers missing artwork for songs already in database.\n+\n+    Useful for disaster recovery.\n+    \"\"\"\n+    table = Song.__table__\n+    conn = engine.connect()\n+    num_songs = 0\n+    for root, _, files in walk(path):\n+        for f in files:\n+            ext = splitext(f)[1]\n+            filepath = join(root, f).decode('utf-8')\n+            if ext in {'.mp3', '.flac', '.ogg', '.m4a', '.mp4'}:\n+                try:\n+                    if ext == '.mp3':\n+                        song = EasyMP3(filepath)\n+                    elif ext == '.flac':\n+                        song = FLAC(filepath)\n+                    elif ext == '.ogg':\n+                        song = OggVorbis(filepath)\n+                    elif ext in {'.m4a', '.mp4'}:\n+                        song = MP4(filepath)\n+                except IOError, e:\n+                    print e\n+                    continue\n+\n+                # Required tags\n+                try:\n+                    if ext in {'.m4a', '.mp4'}:\n+                        title = song.tags['\\xa9nam'][0]\n+                        artist = song.tags['\\xa9ART'][0]\n+                    else:\n+                        title = song.tags['title'][0]\n+                        artist = song.tags['artist'][0]\n+                except Exception:\n+                    print 'Missing tags: ' + filepath\n+                    continue\n+\n+                song_obj = {\n+                    'title': title,","path":"song.py","position":43,"original_position":43,"commit_id":"891f8fd8eb8831d7b6c7d7d1740316825439ed9c","original_commit_id":"891f8fd8eb8831d7b6c7d7d1740316825439ed9c","user":{"login":"kevinwang","id":424214,"avatar_url":"https://avatars.githubusercontent.com/u/424214?v=3","gravatar_id":"","url":"https://api.github.com/users/kevinwang","html_url":"https://github.com/kevinwang","followers_url":"https://api.github.com/users/kevinwang/followers","following_url":"https://api.github.com/users/kevinwang/following{/other_user}","gists_url":"https://api.github.com/users/kevinwang/gists{/gist_id}","starred_url":"https://api.github.com/users/kevinwang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kevinwang/subscriptions","organizations_url":"https://api.github.com/users/kevinwang/orgs","repos_url":"https://api.github.com/users/kevinwang/repos","events_url":"https://api.github.com/users/kevinwang/events{/privacy}","received_events_url":"https://api.github.com/users/kevinwang/received_events","type":"User","site_admin":false},"body":"Can you remove unused values like title, length, track number, etc.?","created_at":"2015-09-10T00:47:19Z","updated_at":"2015-09-10T00:47:19Z","html_url":"https://github.com/acm-uiuc/beats/pull/64#discussion_r39114569","pull_request_url":"https://api.github.com/repos/acm-uiuc/beats/pulls/64","_links":{"self":{"href":"https://api.github.com/repos/acm-uiuc/beats/pulls/comments/39114569"},"html":{"href":"https://github.com/acm-uiuc/beats/pull/64#discussion_r39114569"},"pull_request":{"href":"https://api.github.com/repos/acm-uiuc/beats/pulls/64"}}},"pull_request":{"url":"https://api.github.com/repos/acm-uiuc/beats/pulls/64","id":44615601,"html_url":"https://github.com/acm-uiuc/beats/pull/64","diff_url":"https://github.com/acm-uiuc/beats/pull/64.diff","patch_url":"https://github.com/acm-uiuc/beats/pull/64.patch","issue_url":"https://api.github.com/repos/acm-uiuc/beats/issues/64","number":64,"state":"open","locked":false,"title":"added art recovery function","user":{"login":"Ruin0x11","id":6700637,"avatar_url":"https://avatars.githubusercontent.com/u/6700637?v=3","gravatar_id":"","url":"https://api.github.com/users/Ruin0x11","html_url":"https://github.com/Ruin0x11","followers_url":"https://api.github.com/users/Ruin0x11/followers","following_url":"https://api.github.com/users/Ruin0x11/following{/other_user}","gists_url":"https://api.github.com/users/Ruin0x11/gists{/gist_id}","starred_url":"https://api.github.com/users/Ruin0x11/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ruin0x11/subscriptions","organizations_url":"https://api.github.com/users/Ruin0x11/orgs","repos_url":"https://api.github.com/users/Ruin0x11/repos","events_url":"https://api.github.com/users/Ruin0x11/events{/privacy}","received_events_url":"https://api.github.com/users/Ruin0x11/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-09-10T00:11:31Z","updated_at":"2015-09-10T00:47:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2b63a55bee9176468db72af264e2e365581da5f2","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/acm-uiuc/beats/pulls/64/commits","review_comments_url":"https://api.github.com/repos/acm-uiuc/beats/pulls/64/comments","review_comment_url":"https://api.github.com/repos/acm-uiuc/beats/pulls/comments{/number}","comments_url":"https://api.github.com/repos/acm-uiuc/beats/issues/64/comments","statuses_url":"https://api.github.com/repos/acm-uiuc/beats/statuses/891f8fd8eb8831d7b6c7d7d1740316825439ed9c","head":{"label":"Ruin0x11:art-recovery","ref":"art-recovery","sha":"891f8fd8eb8831d7b6c7d7d1740316825439ed9c","user":{"login":"Ruin0x11","id":6700637,"avatar_url":"https://avatars.githubusercontent.com/u/6700637?v=3","gravatar_id":"","url":"https://api.github.com/users/Ruin0x11","html_url":"https://github.com/Ruin0x11","followers_url":"https://api.github.com/users/Ruin0x11/followers","following_url":"https://api.github.com/users/Ruin0x11/following{/other_user}","gists_url":"https://api.github.com/users/Ruin0x11/gists{/gist_id}","starred_url":"https://api.github.com/users/Ruin0x11/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ruin0x11/subscriptions","organizations_url":"https://api.github.com/users/Ruin0x11/orgs","repos_url":"https://api.github.com/users/Ruin0x11/repos","events_url":"https://api.github.com/users/Ruin0x11/events{/privacy}","received_events_url":"https://api.github.com/users/Ruin0x11/received_events","type":"User","site_admin":false},"repo":{"id":23896248,"name":"beats","full_name":"Ruin0x11/beats","owner":{"login":"Ruin0x11","id":6700637,"avatar_url":"https://avatars.githubusercontent.com/u/6700637?v=3","gravatar_id":"","url":"https://api.github.com/users/Ruin0x11","html_url":"https://github.com/Ruin0x11","followers_url":"https://api.github.com/users/Ruin0x11/followers","following_url":"https://api.github.com/users/Ruin0x11/following{/other_user}","gists_url":"https://api.github.com/users/Ruin0x11/gists{/gist_id}","starred_url":"https://api.github.com/users/Ruin0x11/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ruin0x11/subscriptions","organizations_url":"https://api.github.com/users/Ruin0x11/orgs","repos_url":"https://api.github.com/users/Ruin0x11/repos","events_url":"https://api.github.com/users/Ruin0x11/events{/privacy}","received_events_url":"https://api.github.com/users/Ruin0x11/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Ruin0x11/beats","description":"Beats by ACM","fork":true,"url":"https://api.github.com/repos/Ruin0x11/beats","forks_url":"https://api.github.com/repos/Ruin0x11/beats/forks","keys_url":"https://api.github.com/repos/Ruin0x11/beats/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Ruin0x11/beats/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Ruin0x11/beats/teams","hooks_url":"https://api.github.com/repos/Ruin0x11/beats/hooks","issue_events_url":"https://api.github.com/repos/Ruin0x11/beats/issues/events{/number}","events_url":"https://api.github.com/repos/Ruin0x11/beats/events","assignees_url":"https://api.github.com/repos/Ruin0x11/beats/assignees{/user}","branches_url":"https://api.github.com/repos/Ruin0x11/beats/branches{/branch}","tags_url":"https://api.github.com/repos/Ruin0x11/beats/tags","blobs_url":"https://api.github.com/repos/Ruin0x11/beats/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Ruin0x11/beats/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Ruin0x11/beats/git/refs{/sha}","trees_url":"https://api.github.com/repos/Ruin0x11/beats/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Ruin0x11/beats/statuses/{sha}","languages_url":"https://api.github.com/repos/Ruin0x11/beats/languages","stargazers_url":"https://api.github.com/repos/Ruin0x11/beats/stargazers","contributors_url":"https://api.github.com/repos/Ruin0x11/beats/contributors","subscribers_url":"https://api.github.com/repos/Ruin0x11/beats/subscribers","subscription_url":"https://api.github.com/repos/Ruin0x11/beats/subscription","commits_url":"https://api.github.com/repos/Ruin0x11/beats/commits{/sha}","git_commits_url":"https://api.github.com/repos/Ruin0x11/beats/git/commits{/sha}","comments_url":"https://api.github.com/repos/Ruin0x11/beats/comments{/number}","issue_comment_url":"https://api.github.com/repos/Ruin0x11/beats/issues/comments{/number}","contents_url":"https://api.github.com/repos/Ruin0x11/beats/contents/{+path}","compare_url":"https://api.github.com/repos/Ruin0x11/beats/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Ruin0x11/beats/merges","archive_url":"https://api.github.com/repos/Ruin0x11/beats/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Ruin0x11/beats/downloads","issues_url":"https://api.github.com/repos/Ruin0x11/beats/issues{/number}","pulls_url":"https://api.github.com/repos/Ruin0x11/beats/pulls{/number}","milestones_url":"https://api.github.com/repos/Ruin0x11/beats/milestones{/number}","notifications_url":"https://api.github.com/repos/Ruin0x11/beats/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Ruin0x11/beats/labels{/name}","releases_url":"https://api.github.com/repos/Ruin0x11/beats/releases{/id}","created_at":"2014-09-10T23:27:38Z","updated_at":"2015-02-10T01:03:01Z","pushed_at":"2015-09-10T00:11:07Z","git_url":"git://github.com/Ruin0x11/beats.git","ssh_url":"git@github.com:Ruin0x11/beats.git","clone_url":"https://github.com/Ruin0x11/beats.git","svn_url":"https://github.com/Ruin0x11/beats","homepage":"","size":992,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"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":"acm-uiuc:master","ref":"master","sha":"6069835739e549ab2b64c2ea31c08490937c1c61","user":{"login":"acm-uiuc","id":425738,"avatar_url":"https://avatars.githubusercontent.com/u/425738?v=3","gravatar_id":"","url":"https://api.github.com/users/acm-uiuc","html_url":"https://github.com/acm-uiuc","followers_url":"https://api.github.com/users/acm-uiuc/followers","following_url":"https://api.github.com/users/acm-uiuc/following{/other_user}","gists_url":"https://api.github.com/users/acm-uiuc/gists{/gist_id}","starred_url":"https://api.github.com/users/acm-uiuc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acm-uiuc/subscriptions","organizations_url":"https://api.github.com/users/acm-uiuc/orgs","repos_url":"https://api.github.com/users/acm-uiuc/repos","events_url":"https://api.github.com/users/acm-uiuc/events{/privacy}","received_events_url":"https://api.github.com/users/acm-uiuc/received_events","type":"Organization","site_admin":false},"repo":{"id":17146594,"name":"beats","full_name":"acm-uiuc/beats","owner":{"login":"acm-uiuc","id":425738,"avatar_url":"https://avatars.githubusercontent.com/u/425738?v=3","gravatar_id":"","url":"https://api.github.com/users/acm-uiuc","html_url":"https://github.com/acm-uiuc","followers_url":"https://api.github.com/users/acm-uiuc/followers","following_url":"https://api.github.com/users/acm-uiuc/following{/other_user}","gists_url":"https://api.github.com/users/acm-uiuc/gists{/gist_id}","starred_url":"https://api.github.com/users/acm-uiuc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acm-uiuc/subscriptions","organizations_url":"https://api.github.com/users/acm-uiuc/orgs","repos_url":"https://api.github.com/users/acm-uiuc/repos","events_url":"https://api.github.com/users/acm-uiuc/events{/privacy}","received_events_url":"https://api.github.com/users/acm-uiuc/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/acm-uiuc/beats","description":"Beats by ACM","fork":false,"url":"https://api.github.com/repos/acm-uiuc/beats","forks_url":"https://api.github.com/repos/acm-uiuc/beats/forks","keys_url":"https://api.github.com/repos/acm-uiuc/beats/keys{/key_id}","collaborators_url":"https://api.github.com/repos/acm-uiuc/beats/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/acm-uiuc/beats/teams","hooks_url":"https://api.github.com/repos/acm-uiuc/beats/hooks","issue_events_url":"https://api.github.com/repos/acm-uiuc/beats/issues/events{/number}","events_url":"https://api.github.com/repos/acm-uiuc/beats/events","assignees_url":"https://api.github.com/repos/acm-uiuc/beats/assignees{/user}","branches_url":"https://api.github.com/repos/acm-uiuc/beats/branches{/branch}","tags_url":"https://api.github.com/repos/acm-uiuc/beats/tags","blobs_url":"https://api.github.com/repos/acm-uiuc/beats/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/acm-uiuc/beats/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/acm-uiuc/beats/git/refs{/sha}","trees_url":"https://api.github.com/repos/acm-uiuc/beats/git/trees{/sha}","statuses_url":"https://api.github.com/repos/acm-uiuc/beats/statuses/{sha}","languages_url":"https://api.github.com/repos/acm-uiuc/beats/languages","stargazers_url":"https://api.github.com/repos/acm-uiuc/beats/stargazers","contributors_url":"https://api.github.com/repos/acm-uiuc/beats/contributors","subscribers_url":"https://api.github.com/repos/acm-uiuc/beats/subscribers","subscription_url":"https://api.github.com/repos/acm-uiuc/beats/subscription","commits_url":"https://api.github.com/repos/acm-uiuc/beats/commits{/sha}","git_commits_url":"https://api.github.com/repos/acm-uiuc/beats/git/commits{/sha}","comments_url":"https://api.github.com/repos/acm-uiuc/beats/comments{/number}","issue_comment_url":"https://api.github.com/repos/acm-uiuc/beats/issues/comments{/number}","contents_url":"https://api.github.com/repos/acm-uiuc/beats/contents/{+path}","compare_url":"https://api.github.com/repos/acm-uiuc/beats/compare/{base}...{head}","merges_url":"https://api.github.com/repos/acm-uiuc/beats/merges","archive_url":"https://api.github.com/repos/acm-uiuc/beats/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/acm-uiuc/beats/downloads","issues_url":"https://api.github.com/repos/acm-uiuc/beats/issues{/number}","pulls_url":"https://api.github.com/repos/acm-uiuc/beats/pulls{/number}","milestones_url":"https://api.github.com/repos/acm-uiuc/beats/milestones{/number}","notifications_url":"https://api.github.com/repos/acm-uiuc/beats/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/acm-uiuc/beats/labels{/name}","releases_url":"https://api.github.com/repos/acm-uiuc/beats/releases{/id}","created_at":"2014-02-24T18:46:52Z","updated_at":"2015-04-23T23:10:06Z","pushed_at":"2015-09-10T00:11:31Z","git_url":"git://github.com/acm-uiuc/beats.git","ssh_url":"git@github.com:acm-uiuc/beats.git","clone_url":"https://github.com/acm-uiuc/beats.git","svn_url":"https://github.com/acm-uiuc/beats","homepage":"","size":1739,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":10,"mirror_url":null,"open_issues_count":28,"forks":10,"open_issues":28,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/acm-uiuc/beats/pulls/64"},"html":{"href":"https://github.com/acm-uiuc/beats/pull/64"},"issue":{"href":"https://api.github.com/repos/acm-uiuc/beats/issues/64"},"comments":{"href":"https://api.github.com/repos/acm-uiuc/beats/issues/64/comments"},"review_comments":{"href":"https://api.github.com/repos/acm-uiuc/beats/pulls/64/comments"},"review_comment":{"href":"https://api.github.com/repos/acm-uiuc/beats/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/acm-uiuc/beats/pulls/64/commits"},"statuses":{"href":"https://api.github.com/repos/acm-uiuc/beats/statuses/891f8fd8eb8831d7b6c7d7d1740316825439ed9c"}}}}