{"action":"created","comment":{"url":"https://api.github.com/repos/dimagi/commcare-odk/pulls/comments/41736957","id":41736957,"diff_hunk":"@@ -0,0 +1,256 @@\n+package org.commcare.dalvik.activities;\n+\n+import android.os.AsyncTask;\n+import android.os.Bundle;\n+import android.util.Log;\n+\n+import org.commcare.android.framework.CommCareActivity;\n+import org.commcare.android.resource.AppInstallStatus;\n+import org.commcare.android.resource.ResourceInstallUtils;\n+import org.commcare.android.tasks.InstallStagedUpdateTask;\n+import org.commcare.android.tasks.TaskListener;\n+import org.commcare.android.tasks.TaskListenerRegistrationException;\n+import org.commcare.android.tasks.UpdateTask;\n+import org.commcare.dalvik.dialogs.CustomProgressDialog;\n+import org.commcare.dalvik.utils.ConnectivityStatus;\n+import org.javarosa.core.services.locale.Localization;\n+\n+/**\n+ * Allow user to manage app updating:\n+ * - Check and download the latest update\n+ * - Stop a downloading update\n+ * - Apply a downloaded update\n+ *\n+ * @author Phillip Mates (pmates@dimagi.com)\n+ */\n+public class UpdateActivity extends CommCareActivity<UpdateActivity>\n+        implements TaskListener<Integer, AppInstallStatus> {\n+\n+    private static final String TAG = UpdateActivity.class.getSimpleName();\n+    private static final String TASK_CANCELLING_KEY = \"update_task_cancelling\";\n+    private static final int DIALOG_UPGRADE_INSTALL = 6;\n+\n+    private boolean taskIsCancelling;\n+    private UpdateTask updateTask;\n+    private UpdateUIState uiState;\n+\n+    @Override\n+    protected void onCreate(Bundle savedInstanceState) {\n+        super.onCreate(savedInstanceState);\n+\n+        uiState = new UpdateUIState(this);\n+\n+        loadSaveInstanceState(savedInstanceState);\n+\n+        setupUpdateTask();\n+    }\n+\n+    private void loadSaveInstanceState(Bundle savedInstanceState) {\n+        if (savedInstanceState != null) {\n+            taskIsCancelling =\n+                    savedInstanceState.getBoolean(TASK_CANCELLING_KEY, false);\n+        }\n+    }\n+\n+    private void setupUpdateTask() {\n+        updateTask = UpdateTask.getRunningInstance();\n+\n+        try {\n+            if (updateTask != null) {\n+                updateTask.registerTaskListener(this);\n+            }\n+        } catch (TaskListenerRegistrationException e) {\n+            Log.e(TAG, \"Attempting to register a TaskListener to an already \" +\n+                    \"registered task.\");\n+            uiState.errorUiState();\n+        }\n+    }\n+\n+    @Override\n+    protected void onResume() {\n+        super.onResume();\n+\n+        if (!ConnectivityStatus.isNetworkAvailable(this) &&\n+                ConnectivityStatus.isAirplaneModeOn(this)) {\n+            uiState.noConnectivityUiState();\n+            return;\n+        }\n+\n+        int currentProgress = 0;\n+        int maxProgress = 0;\n+        if (updateTask != null) {\n+            currentProgress = updateTask.getProgress();\n+            maxProgress = updateTask.getMaxProgress();\n+            if (taskIsCancelling) {\n+                uiState.cancellingUiState();\n+            } else {\n+                setUiStateFromRunningTask(updateTask.getStatus());\n+            }\n+        } else {\n+            pendingUpdateOrIdle();\n+        }\n+        uiState.updateProgressBar(currentProgress, maxProgress);\n+        uiState.refreshStatusText();\n+    }\n+\n+    private void setUiStateFromRunningTask(AsyncTask.Status taskStatus) {\n+        switch (taskStatus) {\n+            case RUNNING:\n+                uiState.downloadingUiState();\n+                break;\n+            case PENDING:\n+                pendingUpdateOrIdle();\n+                break;\n+            case FINISHED:\n+                uiState.errorUiState();\n+                break;\n+            default:\n+                uiState.errorUiState();\n+        }\n+    }\n+\n+    private void pendingUpdateOrIdle() {\n+        if (ResourceInstallUtils.isUpdateReadyToInstall()) {\n+            uiState.unappliedUpdateAvailableUiState();\n+        } else {\n+            uiState.idleUiState();\n+        }\n+    }\n+\n+    @Override\n+    protected void onDestroy() {\n+        super.onDestroy();\n+\n+        unregisterTask();\n+    }\n+\n+    private void unregisterTask() {\n+        if (updateTask != null) {\n+            try {\n+                updateTask.unregisterTaskListener(this);\n+            } catch (TaskListenerRegistrationException e) {\n+                Log.e(TAG, \"Attempting to unregister a not previously \" +\n+                        \"registered TaskListener.\");\n+            }\n+            updateTask = null;\n+        }\n+    }\n+\n+    @Override\n+    protected void onSaveInstanceState(Bundle outState) {\n+        super.onSaveInstanceState(outState);\n+\n+        outState.putBoolean(TASK_CANCELLING_KEY, taskIsCancelling);\n+    }\n+\n+    @Override\n+    public void handleTaskUpdate(Integer... vals) {\n+        int progress = vals[0];\n+        int max = vals[1];\n+        uiState.updateProgressBar(progress, max);\n+        String msg = Localization.get(\"updates.found\",\n+                new String[]{\"\" + progress, \"\" + max});\n+        uiState.updateProgressText(msg);\n+    }\n+\n+    @Override\n+    public void handleTaskCompletion(AppInstallStatus result) {\n+        if (result == AppInstallStatus.UpdateStaged) {\n+            uiState.unappliedUpdateAvailableUiState();\n+        } else {\n+            uiState.upToDateUiState();\n+        }\n+\n+        unregisterTask();\n+\n+        uiState.refreshStatusText();\n+    }\n+\n+    @Override\n+    public void handleTaskCancellation(AppInstallStatus result) {\n+        unregisterTask();\n+\n+        uiState.idleUiState();\n+    }\n+\n+    protected void startUpdateCheck() {\n+        try {\n+            updateTask = UpdateTask.getNewInstance();\n+            updateTask.startPinnedNotification(this);\n+            updateTask.registerTaskListener(this);\n+        } catch (IllegalStateException e) {\n+            enterErrorState(\"There is already an existing update task instance.\");\n+            return;\n+        } catch (TaskListenerRegistrationException e) {\n+            enterErrorState(\"Attempting to register a TaskListener to an \" +\n+                    \"already registered task.\");\n+            return;\n+        }\n+\n+        String ref = ResourceInstallUtils.getDefaultProfileRef();\n+        updateTask.execute(ref);\n+        uiState.downloadingUiState();\n+    }\n+\n+    private void enterErrorState(String errorMsg) {\n+        Log.e(TAG, errorMsg);\n+        uiState.errorUiState();\n+    }\n+\n+    public void stopUpdateCheck() {\n+        if (updateTask != null) {\n+            updateTask.cancel(true);\n+            taskIsCancelling = true;\n+            uiState.cancellingUiState();\n+        } else {\n+            uiState.idleUiState();\n+        }\n+    }\n+\n+    /**\n+     * Block the user with a dialog while the update is finalized.\n+     */\n+    protected void lauchUpdateInstallTask() {\n+        InstallStagedUpdateTask<UpdateActivity> task =\n+                new InstallStagedUpdateTask<UpdateActivity>(DIALOG_UPGRADE_INSTALL) {\n+\n+                    @Override\n+                    protected void deliverResult(UpdateActivity receiver,\n+                                                 AppInstallStatus result) {\n+                        if (result == AppInstallStatus.Installed) {\n+                            uiState.updateInstalledUiState();","path":"app/src/org/commcare/dalvik/activities/UpdateActivity.java","position":221,"original_position":221,"commit_id":"3763f7a16a9ad0110eae786a57257f53d170629c","original_commit_id":"3763f7a16a9ad0110eae786a57257f53d170629c","user":{"login":"ctsims","id":155066,"avatar_url":"https://avatars.githubusercontent.com/u/155066?v=3","gravatar_id":"","url":"https://api.github.com/users/ctsims","html_url":"https://github.com/ctsims","followers_url":"https://api.github.com/users/ctsims/followers","following_url":"https://api.github.com/users/ctsims/following{/other_user}","gists_url":"https://api.github.com/users/ctsims/gists{/gist_id}","starred_url":"https://api.github.com/users/ctsims/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ctsims/subscriptions","organizations_url":"https://api.github.com/users/ctsims/orgs","repos_url":"https://api.github.com/users/ctsims/repos","events_url":"https://api.github.com/users/ctsims/events{/privacy}","received_events_url":"https://api.github.com/users/ctsims/received_events","type":"User","site_admin":false},"body":"receiver.uiState","created_at":"2015-10-12T09:14:37Z","updated_at":"2015-10-12T09:14:37Z","html_url":"https://github.com/dimagi/commcare-odk/pull/507#discussion_r41736957","pull_request_url":"https://api.github.com/repos/dimagi/commcare-odk/pulls/507","_links":{"self":{"href":"https://api.github.com/repos/dimagi/commcare-odk/pulls/comments/41736957"},"html":{"href":"https://github.com/dimagi/commcare-odk/pull/507#discussion_r41736957"},"pull_request":{"href":"https://api.github.com/repos/dimagi/commcare-odk/pulls/507"}}},"pull_request":{"url":"https://api.github.com/repos/dimagi/commcare-odk/pulls/507","id":42025114,"html_url":"https://github.com/dimagi/commcare-odk/pull/507","diff_url":"https://github.com/dimagi/commcare-odk/pull/507.diff","patch_url":"https://github.com/dimagi/commcare-odk/pull/507.patch","issue_url":"https://api.github.com/repos/dimagi/commcare-odk/issues/507","number":507,"state":"open","locked":false,"title":"Auto-update checks in background","user":{"login":"phillipm","id":94817,"avatar_url":"https://avatars.githubusercontent.com/u/94817?v=3","gravatar_id":"","url":"https://api.github.com/users/phillipm","html_url":"https://github.com/phillipm","followers_url":"https://api.github.com/users/phillipm/followers","following_url":"https://api.github.com/users/phillipm/following{/other_user}","gists_url":"https://api.github.com/users/phillipm/gists{/gist_id}","starred_url":"https://api.github.com/users/phillipm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/phillipm/subscriptions","organizations_url":"https://api.github.com/users/phillipm/orgs","repos_url":"https://api.github.com/users/phillipm/repos","events_url":"https://api.github.com/users/phillipm/events{/privacy}","received_events_url":"https://api.github.com/users/phillipm/received_events","type":"User","site_admin":false},"body":"Enable auto-update checks and downloads to occur in the background.\r\nAdd a new update manager activity that allows users to check the status of updates, cancel downloading updates, and apply downloaded updates.\r\n\r\nCross-requested with https://github.com/dimagi/commcare/pull/117\r\n\r\n[Spec found here](https://docs.google.com/document/d/1oSd6EF0pDgNui8tDbCY1eETx4KlHGDPt9m1L-jya9WI/edit?usp=sharing)\r\n\r\nList of TODOs:\r\n - Test all failure modes!\r\n - Fix rectangle button text/image layout\r\n - Log update failure stats to HQ\r\n - Check for UpdateTask cancellation in the middle of large file downloads\r\n - Make progress bar in UpdateActivity fit the color theme\r\n\r\n__Release Notes__:\r\nPerform auto-update checks for new app versions in the background.","created_at":"2015-08-10T14:22:51Z","updated_at":"2015-10-12T09:14:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1c58d12b993b8a5ec3be6f4cbdcc24af0e119e96","assignee":null,"milestone":{"url":"https://api.github.com/repos/dimagi/commcare-odk/milestones/4","html_url":"https://github.com/dimagi/commcare-odk/milestones/commcare_2.24","labels_url":"https://api.github.com/repos/dimagi/commcare-odk/milestones/4/labels","id":1276470,"number":4,"title":"commcare_2.24","description":null,"creator":{"login":"phillipm","id":94817,"avatar_url":"https://avatars.githubusercontent.com/u/94817?v=3","gravatar_id":"","url":"https://api.github.com/users/phillipm","html_url":"https://github.com/phillipm","followers_url":"https://api.github.com/users/phillipm/followers","following_url":"https://api.github.com/users/phillipm/following{/other_user}","gists_url":"https://api.github.com/users/phillipm/gists{/gist_id}","starred_url":"https://api.github.com/users/phillipm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/phillipm/subscriptions","organizations_url":"https://api.github.com/users/phillipm/orgs","repos_url":"https://api.github.com/users/phillipm/repos","events_url":"https://api.github.com/users/phillipm/events{/privacy}","received_events_url":"https://api.github.com/users/phillipm/received_events","type":"User","site_admin":false},"open_issues":5,"closed_issues":41,"state":"open","created_at":"2015-08-27T20:11:24Z","updated_at":"2015-10-09T13:19:35Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/dimagi/commcare-odk/pulls/507/commits","review_comments_url":"https://api.github.com/repos/dimagi/commcare-odk/pulls/507/comments","review_comment_url":"https://api.github.com/repos/dimagi/commcare-odk/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dimagi/commcare-odk/issues/507/comments","statuses_url":"https://api.github.com/repos/dimagi/commcare-odk/statuses/3763f7a16a9ad0110eae786a57257f53d170629c","head":{"label":"dimagi:feature/background-auto-update","ref":"feature/background-auto-update","sha":"3763f7a16a9ad0110eae786a57257f53d170629c","user":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"repo":{"id":20939877,"name":"commcare-odk","full_name":"dimagi/commcare-odk","owner":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dimagi/commcare-odk","description":"","fork":false,"url":"https://api.github.com/repos/dimagi/commcare-odk","forks_url":"https://api.github.com/repos/dimagi/commcare-odk/forks","keys_url":"https://api.github.com/repos/dimagi/commcare-odk/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dimagi/commcare-odk/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dimagi/commcare-odk/teams","hooks_url":"https://api.github.com/repos/dimagi/commcare-odk/hooks","issue_events_url":"https://api.github.com/repos/dimagi/commcare-odk/issues/events{/number}","events_url":"https://api.github.com/repos/dimagi/commcare-odk/events","assignees_url":"https://api.github.com/repos/dimagi/commcare-odk/assignees{/user}","branches_url":"https://api.github.com/repos/dimagi/commcare-odk/branches{/branch}","tags_url":"https://api.github.com/repos/dimagi/commcare-odk/tags","blobs_url":"https://api.github.com/repos/dimagi/commcare-odk/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dimagi/commcare-odk/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dimagi/commcare-odk/git/refs{/sha}","trees_url":"https://api.github.com/repos/dimagi/commcare-odk/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dimagi/commcare-odk/statuses/{sha}","languages_url":"https://api.github.com/repos/dimagi/commcare-odk/languages","stargazers_url":"https://api.github.com/repos/dimagi/commcare-odk/stargazers","contributors_url":"https://api.github.com/repos/dimagi/commcare-odk/contributors","subscribers_url":"https://api.github.com/repos/dimagi/commcare-odk/subscribers","subscription_url":"https://api.github.com/repos/dimagi/commcare-odk/subscription","commits_url":"https://api.github.com/repos/dimagi/commcare-odk/commits{/sha}","git_commits_url":"https://api.github.com/repos/dimagi/commcare-odk/git/commits{/sha}","comments_url":"https://api.github.com/repos/dimagi/commcare-odk/comments{/number}","issue_comment_url":"https://api.github.com/repos/dimagi/commcare-odk/issues/comments{/number}","contents_url":"https://api.github.com/repos/dimagi/commcare-odk/contents/{+path}","compare_url":"https://api.github.com/repos/dimagi/commcare-odk/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dimagi/commcare-odk/merges","archive_url":"https://api.github.com/repos/dimagi/commcare-odk/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dimagi/commcare-odk/downloads","issues_url":"https://api.github.com/repos/dimagi/commcare-odk/issues{/number}","pulls_url":"https://api.github.com/repos/dimagi/commcare-odk/pulls{/number}","milestones_url":"https://api.github.com/repos/dimagi/commcare-odk/milestones{/number}","notifications_url":"https://api.github.com/repos/dimagi/commcare-odk/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dimagi/commcare-odk/labels{/name}","releases_url":"https://api.github.com/repos/dimagi/commcare-odk/releases{/id}","created_at":"2014-06-17T21:17:26Z","updated_at":"2015-05-06T16:04:54Z","pushed_at":"2015-10-12T08:27:28Z","git_url":"git://github.com/dimagi/commcare-odk.git","ssh_url":"git@github.com:dimagi/commcare-odk.git","clone_url":"https://github.com/dimagi/commcare-odk.git","svn_url":"https://github.com/dimagi/commcare-odk","homepage":null,"size":66605,"stargazers_count":3,"watchers_count":3,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":7,"forks":8,"open_issues":7,"watchers":3,"default_branch":"master"}},"base":{"label":"dimagi:master","ref":"master","sha":"e6c6003fa0389ec377b5c5d82840f9faeb1e9773","user":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"repo":{"id":20939877,"name":"commcare-odk","full_name":"dimagi/commcare-odk","owner":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dimagi/commcare-odk","description":"","fork":false,"url":"https://api.github.com/repos/dimagi/commcare-odk","forks_url":"https://api.github.com/repos/dimagi/commcare-odk/forks","keys_url":"https://api.github.com/repos/dimagi/commcare-odk/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dimagi/commcare-odk/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dimagi/commcare-odk/teams","hooks_url":"https://api.github.com/repos/dimagi/commcare-odk/hooks","issue_events_url":"https://api.github.com/repos/dimagi/commcare-odk/issues/events{/number}","events_url":"https://api.github.com/repos/dimagi/commcare-odk/events","assignees_url":"https://api.github.com/repos/dimagi/commcare-odk/assignees{/user}","branches_url":"https://api.github.com/repos/dimagi/commcare-odk/branches{/branch}","tags_url":"https://api.github.com/repos/dimagi/commcare-odk/tags","blobs_url":"https://api.github.com/repos/dimagi/commcare-odk/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dimagi/commcare-odk/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dimagi/commcare-odk/git/refs{/sha}","trees_url":"https://api.github.com/repos/dimagi/commcare-odk/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dimagi/commcare-odk/statuses/{sha}","languages_url":"https://api.github.com/repos/dimagi/commcare-odk/languages","stargazers_url":"https://api.github.com/repos/dimagi/commcare-odk/stargazers","contributors_url":"https://api.github.com/repos/dimagi/commcare-odk/contributors","subscribers_url":"https://api.github.com/repos/dimagi/commcare-odk/subscribers","subscription_url":"https://api.github.com/repos/dimagi/commcare-odk/subscription","commits_url":"https://api.github.com/repos/dimagi/commcare-odk/commits{/sha}","git_commits_url":"https://api.github.com/repos/dimagi/commcare-odk/git/commits{/sha}","comments_url":"https://api.github.com/repos/dimagi/commcare-odk/comments{/number}","issue_comment_url":"https://api.github.com/repos/dimagi/commcare-odk/issues/comments{/number}","contents_url":"https://api.github.com/repos/dimagi/commcare-odk/contents/{+path}","compare_url":"https://api.github.com/repos/dimagi/commcare-odk/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dimagi/commcare-odk/merges","archive_url":"https://api.github.com/repos/dimagi/commcare-odk/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dimagi/commcare-odk/downloads","issues_url":"https://api.github.com/repos/dimagi/commcare-odk/issues{/number}","pulls_url":"https://api.github.com/repos/dimagi/commcare-odk/pulls{/number}","milestones_url":"https://api.github.com/repos/dimagi/commcare-odk/milestones{/number}","notifications_url":"https://api.github.com/repos/dimagi/commcare-odk/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dimagi/commcare-odk/labels{/name}","releases_url":"https://api.github.com/repos/dimagi/commcare-odk/releases{/id}","created_at":"2014-06-17T21:17:26Z","updated_at":"2015-05-06T16:04:54Z","pushed_at":"2015-10-12T08:27:28Z","git_url":"git://github.com/dimagi/commcare-odk.git","ssh_url":"git@github.com:dimagi/commcare-odk.git","clone_url":"https://github.com/dimagi/commcare-odk.git","svn_url":"https://github.com/dimagi/commcare-odk","homepage":null,"size":66605,"stargazers_count":3,"watchers_count":3,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":7,"forks":8,"open_issues":7,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dimagi/commcare-odk/pulls/507"},"html":{"href":"https://github.com/dimagi/commcare-odk/pull/507"},"issue":{"href":"https://api.github.com/repos/dimagi/commcare-odk/issues/507"},"comments":{"href":"https://api.github.com/repos/dimagi/commcare-odk/issues/507/comments"},"review_comments":{"href":"https://api.github.com/repos/dimagi/commcare-odk/pulls/507/comments"},"review_comment":{"href":"https://api.github.com/repos/dimagi/commcare-odk/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dimagi/commcare-odk/pulls/507/commits"},"statuses":{"href":"https://api.github.com/repos/dimagi/commcare-odk/statuses/3763f7a16a9ad0110eae786a57257f53d170629c"}}}}