{"action":"created","comment":{"url":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/comments/39320572","id":39320572,"diff_hunk":"@@ -0,0 +1,131 @@\n+/*\n+  Add-on version validation and submission actions.\n+\n+  Adapted from actions/submit.js. It was difficult to completely reuse the\n+  add-on submission action code since we want to dispatch different action\n+  constants. Also, the route for versions is slightly different, we would\n+  have to pass down arguments down the chain all the way to the end to\n+  appropriately multiplex it.\n+\n+  TODO: refactor out the pieces we can from actions/submit.js for reuse.\n+*/\n+'use strict';\n+import {createAction} from 'redux-actions';\n+import req from 'request';\n+import Url from 'urlgray';\n+import urlJoin from 'url-join';\n+\n+\n+export const VALIDATION_BEGIN = 'ADDON_SUBMIT_VERSION__VALIDATION_BEGIN';\n+const validationBegin = createAction(VALIDATION_BEGIN);\n+\n+// For when the add-on upload has started processing.\n+export const VALIDATION_PENDING = 'ADDON_SUBMIT_VERSION__VALIDATION_PENDING';\n+const validationPending = createAction(VALIDATION_PENDING);\n+\n+// For when the add-on upload has finished validation.\n+export const VALIDATION_PASS = 'ADDON_SUBMIT_VERSION__VALIDATION_PASS';\n+const validationPassed = createAction(VALIDATION_PASS);\n+\n+export const VALIDATION_FAIL = 'ADDON_SUBMIT_VERSION__VALIDATION_FAIL';\n+const validationFail = createAction(VALIDATION_FAIL);\n+\n+export const SUBMIT_OK = 'ADDON_SUBMIT_VERSION__SUBMIT_OK';\n+const submitOk = createAction(SUBMIT_OK);\n+\n+export const SUBMIT_ERROR = 'ADDON_SUBMIT_VERSION__SUBMIT_ERROR';\n+const submitError = createAction(SUBMIT_ERROR);\n+\n+\n+export function submitVersion(fileData, addonSlug) {\n+  /*\n+    Upload add-on .zip file for validation.\n+\n+    addonSlug -- will be passed down all the way from validation, polling, to\n+                 actual version creation.\n+  */\n+  return (dispatch, getState) => {\n+    const apiArgs = getState().apiArgs || {};\n+    const validationUrl = Url(\n+      urlJoin(process.env.MKT_API_ROOT, 'extensions/validation/')\n+    ).q(apiArgs);\n+\n+    dispatch(validationBegin());\n+\n+    req\n+      .post(validationUrl)\n+      .set('Content-Type', 'application/zip')\n+      .set('Content-Disposition',\n+           'form-data; name=\"binary_data\"; filename=\"extension.zip\"')\n+      .send(fileData)\n+      .then(res => {\n+        // Notify the reducers.\n+        dispatch(validationPending(res.body.id));\n+\n+        // Take further action by polling.\n+        dispatch(pollValidator(res.body.id, addonSlug));\n+      }, err => {\n+        dispatch(validationFail(JSON.parse(err.response.text).detail));\n+      });\n+  };\n+}\n+\n+\n+export function pollValidator(validationId, addonSlug) {\n+  /*\n+    Poll add-on's validation detail endpoint to wait until validation has\n+    processed.\n+  */\n+  return (dispatch, getState) => {\n+    const apiArgs = getState().apiArgs || {};\n+    const pollUrl = Url(\n+      urlJoin(process.env.MKT_API_ROOT,\n+              `extensions/validation/${validationId}/`)\n+    ).q(apiArgs);\n+\n+    function poll(interval) {\n+      req\n+        .get(pollUrl)\n+        .then(res => {\n+          if (res.body.processed) {\n+            // If processed, then validation is complete. Resolve process.\n+            clearInterval(pollValidatorInterval);\n+\n+            if (res.body.valid) {\n+              dispatch(createVersion(addonSlug));\n+            } else {\n+              dispatch(validationFail(res.body.validation));\n+            }\n+          }\n+        });\n+    }\n+\n+    // Poll the validator, poll() will clear interval when complete + dispatch.\n+    const pollValidatorInterval = setInterval(() => {","path":"src/media/js/addon/actions/submitVersion.js","position":104,"original_position":104,"commit_id":"ee7d17121796485058c9e60d16ed159751da5e28","original_commit_id":"ee7d17121796485058c9e60d16ed159751da5e28","user":{"login":"chuckharmston","id":23885,"avatar_url":"https://avatars.githubusercontent.com/u/23885?v=3","gravatar_id":"","url":"https://api.github.com/users/chuckharmston","html_url":"https://github.com/chuckharmston","followers_url":"https://api.github.com/users/chuckharmston/followers","following_url":"https://api.github.com/users/chuckharmston/following{/other_user}","gists_url":"https://api.github.com/users/chuckharmston/gists{/gist_id}","starred_url":"https://api.github.com/users/chuckharmston/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chuckharmston/subscriptions","organizations_url":"https://api.github.com/users/chuckharmston/orgs","repos_url":"https://api.github.com/users/chuckharmston/repos","events_url":"https://api.github.com/users/chuckharmston/events{/privacy}","received_events_url":"https://api.github.com/users/chuckharmston/received_events","type":"User","site_admin":false},"body":"Does the validation clearer actually have access to the object? I thought with ES6 scoping it wouldn't. I'd double-check to make sure you're not no-opping.","created_at":"2015-09-11T21:37:54Z","updated_at":"2015-09-11T21:37:54Z","html_url":"https://github.com/mozilla/marketplace-content-tools/pull/23#discussion_r39320572","pull_request_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/23","_links":{"self":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/comments/39320572"},"html":{"href":"https://github.com/mozilla/marketplace-content-tools/pull/23#discussion_r39320572"},"pull_request":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/23"}}},"pull_request":{"url":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/23","id":44726464,"html_url":"https://github.com/mozilla/marketplace-content-tools/pull/23","diff_url":"https://github.com/mozilla/marketplace-content-tools/pull/23.diff","patch_url":"https://github.com/mozilla/marketplace-content-tools/pull/23.patch","issue_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues/23","number":23,"state":"open","locked":false,"title":"dashboard detail page + version uploads","user":{"login":"ngokevin","id":674727,"avatar_url":"https://avatars.githubusercontent.com/u/674727?v=3","gravatar_id":"","url":"https://api.github.com/users/ngokevin","html_url":"https://github.com/ngokevin","followers_url":"https://api.github.com/users/ngokevin/followers","following_url":"https://api.github.com/users/ngokevin/following{/other_user}","gists_url":"https://api.github.com/users/ngokevin/gists{/gist_id}","starred_url":"https://api.github.com/users/ngokevin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ngokevin/subscriptions","organizations_url":"https://api.github.com/users/ngokevin/orgs","repos_url":"https://api.github.com/users/ngokevin/repos","events_url":"https://api.github.com/users/ngokevin/events{/privacy}","received_events_url":"https://api.github.com/users/ngokevin/received_events","type":"User","site_admin":false},"body":"- Add-on version submission is done through Dashboard Detail pages (dashboard -> add-on detail)\r\n- Re-used what I could from add-on submission for add-on version submission without complicating things.\r\n    - I was able to refactor out AddonUpload to its own component, but I had to copy/paste/adapt the actions code.\r\n    - I was able to make the submit reducers generate a reducer so we could reuse the reducer for both add-on + add-on version.\r\n\r\n![Sherlocked Capture](http://sherlocked.dev.mozaws.net/api/captures/8e4c0f8a815d469ca1c26c401f995bdf)","created_at":"2015-09-10T22:17:32Z","updated_at":"2015-09-11T21:37:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d563e72dcf6479dfee80ff7f73314c48b3f186c3","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/23/commits","review_comments_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/23/comments","review_comment_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues/23/comments","statuses_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/statuses/ee7d17121796485058c9e60d16ed159751da5e28","head":{"label":"mozilla:dashboarddetail","ref":"dashboarddetail","sha":"ee7d17121796485058c9e60d16ed159751da5e28","user":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"repo":{"id":36391468,"name":"marketplace-content-tools","full_name":"mozilla/marketplace-content-tools","owner":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mozilla/marketplace-content-tools","description":"Tools for submitting content to the Firefox Marketplace.","fork":false,"url":"https://api.github.com/repos/mozilla/marketplace-content-tools","forks_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/forks","keys_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/teams","hooks_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/hooks","issue_events_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues/events{/number}","events_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/events","assignees_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/assignees{/user}","branches_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/branches{/branch}","tags_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/tags","blobs_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/languages","stargazers_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/stargazers","contributors_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/contributors","subscribers_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/subscribers","subscription_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/subscription","commits_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/contents/{+path}","compare_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/merges","archive_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/downloads","issues_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues{/number}","pulls_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/labels{/name}","releases_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/releases{/id}","created_at":"2015-05-27T19:45:33Z","updated_at":"2015-08-28T20:49:48Z","pushed_at":"2015-09-11T20:50:27Z","git_url":"git://github.com/mozilla/marketplace-content-tools.git","ssh_url":"git@github.com:mozilla/marketplace-content-tools.git","clone_url":"https://github.com/mozilla/marketplace-content-tools.git","svn_url":"https://github.com/mozilla/marketplace-content-tools","homepage":null,"size":1587,"stargazers_count":2,"watchers_count":2,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":2,"forks":4,"open_issues":2,"watchers":2,"default_branch":"master"}},"base":{"label":"mozilla:master","ref":"master","sha":"91a7915ea192aee52635bf7b154bbc3411cc65ad","user":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"repo":{"id":36391468,"name":"marketplace-content-tools","full_name":"mozilla/marketplace-content-tools","owner":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mozilla/marketplace-content-tools","description":"Tools for submitting content to the Firefox Marketplace.","fork":false,"url":"https://api.github.com/repos/mozilla/marketplace-content-tools","forks_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/forks","keys_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/teams","hooks_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/hooks","issue_events_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues/events{/number}","events_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/events","assignees_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/assignees{/user}","branches_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/branches{/branch}","tags_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/tags","blobs_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/languages","stargazers_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/stargazers","contributors_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/contributors","subscribers_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/subscribers","subscription_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/subscription","commits_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/contents/{+path}","compare_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/merges","archive_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/downloads","issues_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues{/number}","pulls_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/labels{/name}","releases_url":"https://api.github.com/repos/mozilla/marketplace-content-tools/releases{/id}","created_at":"2015-05-27T19:45:33Z","updated_at":"2015-08-28T20:49:48Z","pushed_at":"2015-09-11T20:50:27Z","git_url":"git://github.com/mozilla/marketplace-content-tools.git","ssh_url":"git@github.com:mozilla/marketplace-content-tools.git","clone_url":"https://github.com/mozilla/marketplace-content-tools.git","svn_url":"https://github.com/mozilla/marketplace-content-tools","homepage":null,"size":1587,"stargazers_count":2,"watchers_count":2,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":2,"forks":4,"open_issues":2,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/23"},"html":{"href":"https://github.com/mozilla/marketplace-content-tools/pull/23"},"issue":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues/23"},"comments":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/issues/23/comments"},"review_comments":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/23/comments"},"review_comment":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/pulls/23/commits"},"statuses":{"href":"https://api.github.com/repos/mozilla/marketplace-content-tools/statuses/ee7d17121796485058c9e60d16ed159751da5e28"}}}}