{"action":"created","comment":{"url":"https://api.github.com/repos/mozilla/socorro/pulls/comments/32146245","id":32146245,"diff_hunk":"@@ -2,103 +2,329 @@\n # License, v. 2.0. If a copy of the MPL was not distributed with this\n # file, You can obtain one at http://mozilla.org/MPL/2.0/.\n \n-import contextlib\n-import csv\n+###!/usr/bin/python\n+\n+\n import datetime\n import gzip\n+import csv\n import os.path\n-import subprocess\n+import re\n+\n+import contextlib\n+\n \n from configman import Namespace\n-from crontabber.base import BaseCronApp\n+\n from crontabber.mixins import (\n-    as_backfill_cron_app,\n-    with_postgres_transactions,\n-    with_single_postgres_transaction\n+    using_postgres,\n+    with_subprocess,\n+    as_backfill_cron_app\n+)\n+from crontabber.base import BaseCronApp\n+\n+from socorro.external.postgresql.dbapi2_util import (\n+    execute_no_results\n )\n-from socorro.database.cachedIdAccess import IdCache\n from socorro.lib.util import DotDict\n \n-SQL = \"\"\"\n-select\n-  r.signature,  -- 0\n-  r.url,        -- 1\n-  'http://crash-stats.mozilla.com/report/index/' || r.uuid as uuid_url, -- 2\n-  to_char(r.client_crash_date,'YYYYMMDDHH24MI') as client_crash_date,   -- 3\n-  to_char(r.date_processed,'YYYYMMDDHH24MI') as date_processed,         -- 4\n-  r.last_crash, -- 5\n-  r.product,    -- 6\n-  r.version,    -- 7\n-  r.build,      -- 8\n-  '' as branch, -- 9\n-  r.os_name,    --10\n-  r.os_version, --11\n-  r.cpu_name || ' | ' || r.cpu_info as cpu_info,   --12\n-  r.address,    --13\n-  array(select ba.bug_id from bug_associations ba where ba.signature = r.signature) as bug_list, --14\n-  r.user_comments, --15\n-  r.uptime as uptime_seconds, --16\n-  case when (r.email is NULL OR r.email='') then '' else r.email end as email, --17\n-  (select sum(adi_count) from raw_adi adu\n-     where adu.date = '%(now_str)s'\n-       and r.product = adu.product_name and r.version = adu.product_version\n-       and substring(r.os_name from 1 for 3) = substring(adu.product_os_platform from 1 for 3)\n-       and r.os_version LIKE '%%'||adu.product_os_version||'%%') as adu_count, --18\n-  r.topmost_filenames, --19\n-  case when (r.addons_checked is NULL) then '[unknown]'when (r.addons_checked) then 'checked' else 'not' end as addons_checked, --20\n-  r.flash_version, --21\n-  r.hangid, --22\n-  r.reason, --23\n-  r.process_type, --24\n-  r.app_notes, --25\n-  r.install_age, --26\n-  rd.duplicate_of, --27\n-  r.release_channel, --28\n-  r.productid --29\n-from\n-  reports r left join reports_duplicates rd on r.uuid = rd.uuid\n-where\n-  '%(yesterday_str)s' <= r.date_processed and r.date_processed < '%(now_str)s'\n-  %(prod_phrase)s %(ver_phrase)s\n-order by 5 -- r.date_processed, munged\n-\"\"\"\n+\n+sql = \"\"\"\n+      select\n+        r.signature,  -- 0\n+        r.url,        -- 1\n+        'http://crash-stats.mozilla.com/report/index/' || r.uuid as uuid_url, -- 2\n+        to_char(r.client_crash_date,'YYYYMMDDHH24MI') as client_crash_date,   -- 3\n+        to_char(r.date_processed,'YYYYMMDDHH24MI') as date_processed,         -- 4\n+        r.last_crash, -- 5\n+        r.product,    -- 6\n+        r.version,    -- 7\n+        r.build,      -- 8\n+        '' as branch, -- 9\n+        r.os_name,    --10\n+        r.os_version, --11\n+        r.cpu_name || ' | ' || r.cpu_info as cpu_info,   --12\n+        r.address,    --13\n+        array(select ba.bug_id from bug_associations ba where ba.signature = r.signature) as bug_list, --14\n+        r.user_comments, --15\n+        r.uptime as uptime_seconds, --16\n+        case when (r.email is NULL OR r.email='') then '' else r.email end as email, --17\n+        (select sum(adi_count) from raw_adi adi\n+           where adi.date = '%(now_str)s'\n+             and r.product = adi.product_name and r.version = adi.product_version\n+             and substring(r.os_name from 1 for 3) = substring(adi.product_os_platform from 1 for 3)\n+             and r.os_version LIKE '%%'||adi.product_os_version||'%%') as adu_count, --18\n+        r.topmost_filenames, --19\n+        case when (r.addons_checked is NULL) then '[unknown]'when (r.addons_checked) then 'checked' else 'not' end as addons_checked, --20\n+        r.flash_version, --21\n+        r.hangid, --22\n+        r.reason, --23\n+        r.process_type, --24\n+        r.app_notes, --25\n+        r.install_age, --26\n+        rd.duplicate_of, --27\n+        r.release_channel, --28\n+        r.productid --29\n+      from\n+        reports r left join reports_duplicates rd on r.uuid = rd.uuid\n+      where\n+        '%(yesterday_str)s' <= r.date_processed and r.date_processed < '%(now_str)s'\n+        %(prod_phrase)s %(ver_phrase)s\n+      order by 5 -- r.date_processed, munged\n+      \"\"\"\n+\n+\n+#------------------------------------------------------------------------------\n+def setup_query_parameters(config, day):\n+    now = day + datetime.timedelta(1)\n+    now_str = now.strftime('%Y-%m-%d')\n+    yesterday = day\n+    yesterday_str = yesterday.strftime('%Y-%m-%d')\n+    config.logger.debug(\n+        \"day = %s; now = %s; yesterday = %s\",\n+        day,\n+        now,\n+        yesterday\n+    )\n+    prod_phrase = ''\n+    try:\n+        if config.product != '':\n+            if ',' in config.product:\n+                prod_list = [x.strip() for x in config.product.split(',')]\n+                prod_phrase = (\n+                    \"and r.product in ('%s')\" % \"','\".join(prod_list)\n+                )\n+            else:\n+                prod_phrase = \"and r.product = '%s'\" % config.product\n+    except Exception, x:\n+        config.logger.error(repr(x), exc_info=True)\n+    ver_phrase = ''\n+    try:\n+        if config.version != '':\n+            if ',' in config.product:\n+                ver_list = [v.strip() for v in config.version.split(',')]\n+                ver_phrase = (\"and r.version in ('%s')\" % \"','\".join(ver_list))\n+            else:\n+                ver_phrase = \"and r.version = '%s'\" % config.version\n+    except Exception, x:\n+        config.logger.error(repr(x), exc_info=True)\n+\n+    return DotDict({\n+        'now_str': now_str,\n+        'yesterday_str': yesterday_str,\n+        'prod_phrase': prod_phrase,\n+        'ver_phrase': ver_phrase\n+    })\n+\n+\n+#------------------------------------------------------------------------------\n+@contextlib.contextmanager\n+def gzipped_csv_files(config, day, gzip=gzip, csv=csv):\n+    private_out_filename = (\n+        \"%s-crashdata.csv.gz\" % day.strftime('%Y%m%d')\n+    )\n+    private_out_pathname = os.path.join(\n+        config.output_path,\n+        private_out_filename\n+    )\n+    config.private_out_pathname = private_out_pathname\n+    private_gzip_file_handle = gzip.open(private_out_pathname, \"w\")\n+    private_csv_file_handle = csv.writer(\n+        private_gzip_file_handle,\n+        delimiter='\\t',\n+        lineterminator='\\n'\n+    )\n+\n+    pubic_out_filename = (\"%s-pub-crashdata.csv.gz\"\n+                          % day.strftime('%Y%m%d'))\n+    public_out_pathname = None\n+    public_out_directory = config.get('public_output_path')\n+    public_gzip_file_handle = None\n+    public_csv_file_handle = None\n+    if public_out_directory:\n+        public_out_pathname = os.path.join(\n+            public_out_directory,\n+            pubic_out_filename\n+        )\n+        public_gzip_file_handle = gzip.open(public_out_pathname, \"w\")\n+        public_csv_file_handle = csv.writer(\n+            public_gzip_file_handle,\n+            delimiter='\\t',\n+            lineterminator='\\n'\n+        )\n+    else:\n+        config.logger.info(\"Will not create public (bowdlerized) gzip file\")\n+    config.public_out_pathname = public_out_pathname\n+    yield (private_csv_file_handle, public_csv_file_handle)\n+    private_gzip_file_handle.close()\n+    if public_gzip_file_handle:\n+        public_gzip_file_handle.close()\n+\n+\n+#------------------------------------------------------------------------------\n+linux_line_re = re.compile(\n+    r'0\\.0\\.0 [lL]inux.+[lL]inux$|[0-9.]+.+(i586|i686|sun4u|i86pc|x86_64)?'\n+)\n+linux_version_re = re.compile(\n+    r'(0\\.0\\.0 [lL]inux.)([0-9.]+[0-9]).*(i586|i686|sun4u|i86pc|x86_64).*'\n+)\n+linux_short_version_re = re.compile(r'(0\\.0\\.0 [lL]inux.)([0-9.]+[0-9]).*')\n \n \n+#------------------------------------------------------------------------------\n+def get_appropriat_os_version(name, original_version):\n+    \"\"\"\n+    If this is a linux os, chop out all the gubbish retaining only the actual\n+    version numbers and, if available, the architecture name.\n+    \"\"\"\n+    ret = original_version\n+    if 'Linux' != name:\n+        pass\n+    elif not linux_line_re.match(original_version):\n+        ret = ''\n+    else:\n+        m = linux_version_re.sub(r'\\2 \\3', original_version)\n+        ret = m\n+        if original_version == m:\n+            m = linux_short_version_re.sub(r'\\2', original_version)\n+            ret = \"%s ?arch?\" % (m)\n+            if original_version == m:\n+                ret = ''\n+    return ret\n+\n+\n+#------------------------------------------------------------------------------\n+def process_crash(a_crash_row):\n+    column_value_list = []\n+    os_name = None\n+    ooid = ''\n+    for i, x in enumerate(a_crash_row):\n+        if x is None:\n+            x = r'\\N'\n+        if i == 2:\n+            ooid = x.rsplit('/', 1)[-1]  # existing Bug - unused\n+        if i == 10:  # r.os_name\n+            x = os_name = x.strip()\n+        if i == 11:  # r.os_version\n+            # per bug 519703\n+            x = get_appropriat_os_version(os_name, x)\n+            os_name = None\n+        if i == 14:  # bug_associations.bug_id\n+            x = ','.join(str(bugid) for bugid in x)\n+        if i == 15:  # r.user_comments\n+            x = x.replace('\\t', ' ')  # per bug 519703\n+        if i == 17:  # r.email -- show 'email' if the email is likely useful\n+            # per bugs 529431/519703\n+            if '@' in x:\n+                x = 'yes'\n+            else:\n+                x = ''\n+        if type(x) == str:\n+            x = x.strip().replace('\\r', '').replace('\\n', ' | ')\n+        column_value_list.append(x)\n+    return column_value_list\n+\n+\n+#------------------------------------------------------------------------------\n+def write_row(file_handles_tuple,\n+              crash_list):\n+    \"\"\"\n+    Write a row to each file: Seen by internal users (full details), and\n+    external users (bowdlerized)\n+    \"\"\"\n+    private_file_handle, public_file_handle = file_handles_tuple\n+    # config.logger.debug(\"Writing crash %s (%s)\",crash_list,len(crash_list))\n+    private_file_handle.writerow(crash_list)\n+    crash_list[1] = 'URL (removed)'  # remove url\n+    crash_list[17] = ''  # remove email\n+    if public_file_handle:\n+        public_file_handle.writerow(crash_list)\n+\n+\n+#------------------------------------------------------------------------------\n+def dailyUrlDump(\n+    connection,\n+    config,\n+    day,\n+    get_output_context=gzipped_csv_files,\n+    write_row=write_row,\n+    process_crash=process_crash\n+):\n+\n+    try:\n+        with get_output_context(config, day) as output_context:\n+            execute_no_results(\n+                connection,\n+                \"\"\" SET TEMP_BUFFERS = %s \"\"\",\n+                (config.database_temp_buffer_size,)\n+            )\n+\n+            sql_parameters = setup_query_parameters(config, day)\n+            config.logger.debug(\n+                \"day = %s; now = %s; yesterday = %s\",\n+                day,\n+                sql_parameters.now_str,\n+                sql_parameters.yesterday_str\n+            )\n+\n+            with connection.cursor() as db_cursor:\n+                sql_query = sql % sql_parameters\n+                config.logger.debug(\"SQL is: %s\", sql_query)\n+                db_cursor.execute(sql_query)\n+                headers_not_yet_written = True\n+                while True:\n+                    crash_row = db_cursor.fetchone()\n+                    if crash_row is None:\n+                        break\n+                    if headers_not_yet_written:\n+                        write_row(\n+                            output_context,\n+                            [x[0] for x in db_cursor.description]\n+                        )\n+                        headers_not_yet_written = False\n+                    column_value_list = process_crash(crash_row)\n+                    write_row(output_context, column_value_list)\n+    except Exception, x:\n+        config.logger.error(repr(x), exc_info=True)","path":"socorro/cron/jobs/daily_url.py","position":338,"original_position":338,"commit_id":"9ca0b31d0b9f649add1e015390d919896722a160","original_commit_id":"9ca0b31d0b9f649add1e015390d919896722a160","user":{"login":"peterbe","id":26739,"avatar_url":"https://avatars.githubusercontent.com/u/26739?v=3","gravatar_id":"","url":"https://api.github.com/users/peterbe","html_url":"https://github.com/peterbe","followers_url":"https://api.github.com/users/peterbe/followers","following_url":"https://api.github.com/users/peterbe/following{/other_user}","gists_url":"https://api.github.com/users/peterbe/gists{/gist_id}","starred_url":"https://api.github.com/users/peterbe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peterbe/subscriptions","organizations_url":"https://api.github.com/users/peterbe/orgs","repos_url":"https://api.github.com/users/peterbe/repos","events_url":"https://api.github.com/users/peterbe/events{/privacy}","received_events_url":"https://api.github.com/users/peterbe/received_events","type":"User","site_admin":false},"body":"...and reporting. ","created_at":"2015-06-10T17:56:41Z","updated_at":"2015-06-10T17:56:41Z","html_url":"https://github.com/mozilla/socorro/pull/2844#discussion_r32146245","pull_request_url":"https://api.github.com/repos/mozilla/socorro/pulls/2844","_links":{"self":{"href":"https://api.github.com/repos/mozilla/socorro/pulls/comments/32146245"},"html":{"href":"https://github.com/mozilla/socorro/pull/2844#discussion_r32146245"},"pull_request":{"href":"https://api.github.com/repos/mozilla/socorro/pulls/2844"}}},"pull_request":{"url":"https://api.github.com/repos/mozilla/socorro/pulls/2844","id":37367409,"html_url":"https://github.com/mozilla/socorro/pull/2844","diff_url":"https://github.com/mozilla/socorro/pull/2844.diff","patch_url":"https://github.com/mozilla/socorro/pull/2844.patch","issue_url":"https://api.github.com/repos/mozilla/socorro/issues/2844","number":2844,"state":"open","locked":false,"title":"fixes Bug 1158877 - rework the daily_url cron job","user":{"login":"twobraids","id":581227,"avatar_url":"https://avatars.githubusercontent.com/u/581227?v=3","gravatar_id":"","url":"https://api.github.com/users/twobraids","html_url":"https://github.com/twobraids","followers_url":"https://api.github.com/users/twobraids/followers","following_url":"https://api.github.com/users/twobraids/following{/other_user}","gists_url":"https://api.github.com/users/twobraids/gists{/gist_id}","starred_url":"https://api.github.com/users/twobraids/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twobraids/subscriptions","organizations_url":"https://api.github.com/users/twobraids/orgs","repos_url":"https://api.github.com/users/twobraids/repos","events_url":"https://api.github.com/users/twobraids/events{/privacy}","received_events_url":"https://api.github.com/users/twobraids/received_events","type":"User","site_admin":false},"body":"making a version much closer to the original, make a version of the daily-url for crontabber\r\n* eliminate the dependency on the deprecated IdCache object\r\n* use the crontabber decorators for external process\r\n\r\n\r\n","created_at":"2015-06-10T14:54:10Z","updated_at":"2015-06-10T17:56:41Z","closed_at":null,"merged_at":null,"merge_commit_sha":"23f9c482c44878e0b17ccca17bb836961d334fa1","assignee":{"login":"peterbe","id":26739,"avatar_url":"https://avatars.githubusercontent.com/u/26739?v=3","gravatar_id":"","url":"https://api.github.com/users/peterbe","html_url":"https://github.com/peterbe","followers_url":"https://api.github.com/users/peterbe/followers","following_url":"https://api.github.com/users/peterbe/following{/other_user}","gists_url":"https://api.github.com/users/peterbe/gists{/gist_id}","starred_url":"https://api.github.com/users/peterbe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peterbe/subscriptions","organizations_url":"https://api.github.com/users/peterbe/orgs","repos_url":"https://api.github.com/users/peterbe/repos","events_url":"https://api.github.com/users/peterbe/events{/privacy}","received_events_url":"https://api.github.com/users/peterbe/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/mozilla/socorro/pulls/2844/commits","review_comments_url":"https://api.github.com/repos/mozilla/socorro/pulls/2844/comments","review_comment_url":"https://api.github.com/repos/mozilla/socorro/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mozilla/socorro/issues/2844/comments","statuses_url":"https://api.github.com/repos/mozilla/socorro/statuses/9ca0b31d0b9f649add1e015390d919896722a160","head":{"label":"twobraids:daily-url-reboot","ref":"daily-url-reboot","sha":"9ca0b31d0b9f649add1e015390d919896722a160","user":{"login":"twobraids","id":581227,"avatar_url":"https://avatars.githubusercontent.com/u/581227?v=3","gravatar_id":"","url":"https://api.github.com/users/twobraids","html_url":"https://github.com/twobraids","followers_url":"https://api.github.com/users/twobraids/followers","following_url":"https://api.github.com/users/twobraids/following{/other_user}","gists_url":"https://api.github.com/users/twobraids/gists{/gist_id}","starred_url":"https://api.github.com/users/twobraids/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twobraids/subscriptions","organizations_url":"https://api.github.com/users/twobraids/orgs","repos_url":"https://api.github.com/users/twobraids/repos","events_url":"https://api.github.com/users/twobraids/events{/privacy}","received_events_url":"https://api.github.com/users/twobraids/received_events","type":"User","site_admin":false},"repo":{"id":2617288,"name":"socorro","full_name":"twobraids/socorro","owner":{"login":"twobraids","id":581227,"avatar_url":"https://avatars.githubusercontent.com/u/581227?v=3","gravatar_id":"","url":"https://api.github.com/users/twobraids","html_url":"https://github.com/twobraids","followers_url":"https://api.github.com/users/twobraids/followers","following_url":"https://api.github.com/users/twobraids/following{/other_user}","gists_url":"https://api.github.com/users/twobraids/gists{/gist_id}","starred_url":"https://api.github.com/users/twobraids/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twobraids/subscriptions","organizations_url":"https://api.github.com/users/twobraids/orgs","repos_url":"https://api.github.com/users/twobraids/repos","events_url":"https://api.github.com/users/twobraids/events{/privacy}","received_events_url":"https://api.github.com/users/twobraids/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/twobraids/socorro","description":"Socorro is a server to accept and process Breakpad crash reports. ","fork":true,"url":"https://api.github.com/repos/twobraids/socorro","forks_url":"https://api.github.com/repos/twobraids/socorro/forks","keys_url":"https://api.github.com/repos/twobraids/socorro/keys{/key_id}","collaborators_url":"https://api.github.com/repos/twobraids/socorro/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/twobraids/socorro/teams","hooks_url":"https://api.github.com/repos/twobraids/socorro/hooks","issue_events_url":"https://api.github.com/repos/twobraids/socorro/issues/events{/number}","events_url":"https://api.github.com/repos/twobraids/socorro/events","assignees_url":"https://api.github.com/repos/twobraids/socorro/assignees{/user}","branches_url":"https://api.github.com/repos/twobraids/socorro/branches{/branch}","tags_url":"https://api.github.com/repos/twobraids/socorro/tags","blobs_url":"https://api.github.com/repos/twobraids/socorro/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/twobraids/socorro/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/twobraids/socorro/git/refs{/sha}","trees_url":"https://api.github.com/repos/twobraids/socorro/git/trees{/sha}","statuses_url":"https://api.github.com/repos/twobraids/socorro/statuses/{sha}","languages_url":"https://api.github.com/repos/twobraids/socorro/languages","stargazers_url":"https://api.github.com/repos/twobraids/socorro/stargazers","contributors_url":"https://api.github.com/repos/twobraids/socorro/contributors","subscribers_url":"https://api.github.com/repos/twobraids/socorro/subscribers","subscription_url":"https://api.github.com/repos/twobraids/socorro/subscription","commits_url":"https://api.github.com/repos/twobraids/socorro/commits{/sha}","git_commits_url":"https://api.github.com/repos/twobraids/socorro/git/commits{/sha}","comments_url":"https://api.github.com/repos/twobraids/socorro/comments{/number}","issue_comment_url":"https://api.github.com/repos/twobraids/socorro/issues/comments{/number}","contents_url":"https://api.github.com/repos/twobraids/socorro/contents/{+path}","compare_url":"https://api.github.com/repos/twobraids/socorro/compare/{base}...{head}","merges_url":"https://api.github.com/repos/twobraids/socorro/merges","archive_url":"https://api.github.com/repos/twobraids/socorro/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/twobraids/socorro/downloads","issues_url":"https://api.github.com/repos/twobraids/socorro/issues{/number}","pulls_url":"https://api.github.com/repos/twobraids/socorro/pulls{/number}","milestones_url":"https://api.github.com/repos/twobraids/socorro/milestones{/number}","notifications_url":"https://api.github.com/repos/twobraids/socorro/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/twobraids/socorro/labels{/name}","releases_url":"https://api.github.com/repos/twobraids/socorro/releases{/id}","created_at":"2011-10-21T00:42:48Z","updated_at":"2014-09-29T17:41:39Z","pushed_at":"2015-06-10T17:40:09Z","git_url":"git://github.com/twobraids/socorro.git","ssh_url":"git@github.com:twobraids/socorro.git","clone_url":"https://github.com/twobraids/socorro.git","svn_url":"https://github.com/twobraids/socorro","homepage":"https://wiki.mozilla.org/Socorro","size":164879,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":1,"default_branch":"master"}},"base":{"label":"mozilla:master","ref":"master","sha":"b5281505382d3995898ef0ec2ae33e5d41809cac","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":2263742,"name":"socorro","full_name":"mozilla/socorro","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/socorro","description":"Socorro is a server to accept and process Breakpad crash reports. ","fork":false,"url":"https://api.github.com/repos/mozilla/socorro","forks_url":"https://api.github.com/repos/mozilla/socorro/forks","keys_url":"https://api.github.com/repos/mozilla/socorro/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mozilla/socorro/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mozilla/socorro/teams","hooks_url":"https://api.github.com/repos/mozilla/socorro/hooks","issue_events_url":"https://api.github.com/repos/mozilla/socorro/issues/events{/number}","events_url":"https://api.github.com/repos/mozilla/socorro/events","assignees_url":"https://api.github.com/repos/mozilla/socorro/assignees{/user}","branches_url":"https://api.github.com/repos/mozilla/socorro/branches{/branch}","tags_url":"https://api.github.com/repos/mozilla/socorro/tags","blobs_url":"https://api.github.com/repos/mozilla/socorro/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mozilla/socorro/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mozilla/socorro/git/refs{/sha}","trees_url":"https://api.github.com/repos/mozilla/socorro/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mozilla/socorro/statuses/{sha}","languages_url":"https://api.github.com/repos/mozilla/socorro/languages","stargazers_url":"https://api.github.com/repos/mozilla/socorro/stargazers","contributors_url":"https://api.github.com/repos/mozilla/socorro/contributors","subscribers_url":"https://api.github.com/repos/mozilla/socorro/subscribers","subscription_url":"https://api.github.com/repos/mozilla/socorro/subscription","commits_url":"https://api.github.com/repos/mozilla/socorro/commits{/sha}","git_commits_url":"https://api.github.com/repos/mozilla/socorro/git/commits{/sha}","comments_url":"https://api.github.com/repos/mozilla/socorro/comments{/number}","issue_comment_url":"https://api.github.com/repos/mozilla/socorro/issues/comments{/number}","contents_url":"https://api.github.com/repos/mozilla/socorro/contents/{+path}","compare_url":"https://api.github.com/repos/mozilla/socorro/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mozilla/socorro/merges","archive_url":"https://api.github.com/repos/mozilla/socorro/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mozilla/socorro/downloads","issues_url":"https://api.github.com/repos/mozilla/socorro/issues{/number}","pulls_url":"https://api.github.com/repos/mozilla/socorro/pulls{/number}","milestones_url":"https://api.github.com/repos/mozilla/socorro/milestones{/number}","notifications_url":"https://api.github.com/repos/mozilla/socorro/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mozilla/socorro/labels{/name}","releases_url":"https://api.github.com/repos/mozilla/socorro/releases{/id}","created_at":"2011-08-24T19:21:49Z","updated_at":"2015-06-10T11:45:03Z","pushed_at":"2015-06-10T17:41:22Z","git_url":"git://github.com/mozilla/socorro.git","ssh_url":"git@github.com:mozilla/socorro.git","clone_url":"https://github.com/mozilla/socorro.git","svn_url":"https://github.com/mozilla/socorro","homepage":"https://wiki.mozilla.org/Socorro","size":191296,"stargazers_count":228,"watchers_count":228,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":122,"mirror_url":null,"open_issues_count":8,"forks":122,"open_issues":8,"watchers":228,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mozilla/socorro/pulls/2844"},"html":{"href":"https://github.com/mozilla/socorro/pull/2844"},"issue":{"href":"https://api.github.com/repos/mozilla/socorro/issues/2844"},"comments":{"href":"https://api.github.com/repos/mozilla/socorro/issues/2844/comments"},"review_comments":{"href":"https://api.github.com/repos/mozilla/socorro/pulls/2844/comments"},"review_comment":{"href":"https://api.github.com/repos/mozilla/socorro/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mozilla/socorro/pulls/2844/commits"},"statuses":{"href":"https://api.github.com/repos/mozilla/socorro/statuses/9ca0b31d0b9f649add1e015390d919896722a160"}}}}