From c63228206df57bc0bba648ca33ac1204f4392682 Mon Sep 17 00:00:00 2001 From: Rick Carragher and Dave Cameron Date: Mon, 25 Nov 2013 23:35:35 -0500 Subject: [PATCH 1/4] Bugs are keyed by a hash on the server This simplifies code dealing with previously compound keys. It easily allows single bugs to be retrieved directly. It makes the 'resolved' documents smaller. In the storage database view indexing is faster and smaller. --- _attachments/partials/bug-details.html | 6 +- _attachments/partials/bugs-table.html | 12 +- _attachments/partials/reports-table.html | 2 +- _attachments/script/DashboardControllers.js | 3 +- .../script/ReportsBrowserControllers.js | 25 ++- _attachments/script/config.js | 2 +- _attachments/script/service.reportsstore.js | 184 ++++++++---------- 7 files changed, 121 insertions(+), 113 deletions(-) diff --git a/_attachments/partials/bug-details.html b/_attachments/partials/bug-details.html index c42a5d3..a94db5c 100644 --- a/_attachments/partials/bug-details.html +++ b/_attachments/partials/bug-details.html @@ -5,15 +5,15 @@

Bug Summary

- + - + - + diff --git a/_attachments/partials/bugs-table.html b/_attachments/partials/bugs-table.html index b97b69b..0341040 100644 --- a/_attachments/partials/bugs-table.html +++ b/_attachments/partials/bugs-table.html @@ -16,10 +16,10 @@
- + - - + +
@@ -40,10 +40,10 @@
{{bug.value.count}}
{{bug.latest}}
-
{{bug.key[0]}}
+
{{bug.value.appVersion}}
- {{bug.key[1]}}
- Caused by: {{bug.key[2]}} + {{bug.value.exception}}
+ Caused by: {{bug.value.rootCause}}
diff --git a/_attachments/partials/reports-table.html b/_attachments/partials/reports-table.html index 81c7f51..b1aec9f 100644 --- a/_attachments/partials/reports-table.html +++ b/_attachments/partials/reports-table.html @@ -24,7 +24,7 @@ {{report.value.android_version}}{{report.value.device}}
- {{report.value.signature.digest}} + {{report.value.signature.full}} Caused by: {{report.value.signature.rootCause}}
diff --git a/_attachments/script/DashboardControllers.js b/_attachments/script/DashboardControllers.js index 497f57e..42e514b 100644 --- a/_attachments/script/DashboardControllers.js +++ b/_attachments/script/DashboardControllers.js @@ -121,7 +121,8 @@ }; $scope.getData = function() { - ReportsStore.bugsList(function(data) { + ReportsStore.recentBugsList( + function(data) { console.log("Refresh data for latest bugs"); mergeBugsLists($scope.bugs, data.rows); $scope.totalBugs = data.total_rows; diff --git a/_attachments/script/ReportsBrowserControllers.js b/_attachments/script/ReportsBrowserControllers.js index 3cb2c23..ccd9631 100644 --- a/_attachments/script/ReportsBrowserControllers.js +++ b/_attachments/script/ReportsBrowserControllers.js @@ -96,6 +96,29 @@ } }); + $scope.getDevice = function(doc) { + if(doc.BUILD) { + if(doc.BUILD.MANUFACTURER) { + return doc.BUILD.MANUFACTURER + " " + doc.BUILD.BRAND + " " + doc.BUILD.MODEL; + } else { + return doc.BUILD.BRAND + " " + doc.BUILD.MODEL; + } + } else { + var value = ""; + if(doc.BRAND) { + value = doc.BRAND; + } + if(doc.PRODUCT) { + value += " " + doc.PRODUCT; + } + if(doc.PHONE_MODEL) { + value += " " + doc.MODEL; + } + + return value; + } + }; + $scope.getData = function() { $scope.loading = true; var successHandler = function(data) { @@ -124,7 +147,7 @@ } else if($scope.bug) { if($scope.selectedUser) { // Filter by bug AND user - var filterKey = $scope.bug.key.slice(0); + var filterKey = [$scope.bug.key]; filterKey.push($scope.selectedUser.installationId); ReportsStore.filteredReportsList("bug-by-installation-id", filterKey, $scope.startKey, $scope.paginator.pageSize, $scope.fullSearch, successHandler, errorHandler); } else { diff --git a/_attachments/script/config.js b/_attachments/script/config.js index c6692d0..f8abb77 100644 --- a/_attachments/script/config.js +++ b/_attachments/script/config.js @@ -1,7 +1,7 @@ (function(acralyzerConfig, undefined ) { "use strict"; // Update this variable with the name of your app: - acralyzerConfig.defaultApp = ""; + acralyzerConfig.defaultApp = "test"; acralyzerConfig.backgroundPollingOnStartup = true; acralyzerConfig.appDBPrefix = "acra-"; diff --git a/_attachments/script/service.reportsstore.js b/_attachments/script/service.reportsstore.js index fa172d5..03e8294 100644 --- a/_attachments/script/service.reportsstore.js +++ b/_attachments/script/service.reportsstore.js @@ -125,16 +125,8 @@ reduce: false }; - if(filterName.indexOf("bug") === 0) { - // Bugs have composite keys, already an array. - viewParams.endkey = JSON.stringify(filterValue); - var startKeyValue = filterValue.slice(0); - startKeyValue.push({}); - viewParams.startkey = JSON.stringify(startKeyValue); - } else { - viewParams.endkey = JSON.stringify([filterValue]); - viewParams.startkey = JSON.stringify([filterValue,{}]); - } + viewParams.endkey = JSON.stringify([].concat(filterValue)); + viewParams.startkey = JSON.stringify([].concat(filterValue,{})); if(pageStartKey !== null) { viewParams.startkey = JSON.stringify(pageStartKey); @@ -182,97 +174,95 @@ return ReportsStore.views.get({view: 'recent-items-by-androidver', group_level: 1}, cb); }; - // BUGS MANAGEMENT - var computeBugId = function(bug) { - if (bug.id) { - return bug.id; - } else { - return hex_md5(bug.key[0] + "|" + bug.key[1] + "|" + bug.key[2]); - } - }; - - ReportsStore.bugsList = function(cb, errorHandler) { - var viewParams = { - view: 'bugs', - descending: true, - group: true - }; + ReportsStore.bugListWithLimit = function(limit, bugId) { + + return function(cb, errorHandler){ + var viewParams = { + view: 'bugs', + descending: true, + group: true + }; + + if (limit > 0) { viewParams.limit = limit; } + if (bugId) { viewParams.key = bugId; } + + var bugEqualityTest = function(bug2) { + if( + this.value.key !== bug2.value.key || + this.value.latest !== bug2.value.latest || + this.value.count !== bug2.value.count || + this.value.solved !== bug2.value.solved || + this.value.description !== bug2.value.description) { + return false; + } + return true; + }; - var bugEqualityTest = function(bug2) { - if(this.value.latest !== bug2.value.latest || - this.value.count !== bug2.value.count || - this.value.solved !== bug2.value.solved || - this.value.description !== bug2.value.description) { - return false; - } - return true; - }; + var bugUpdate = function(bug2) { + if(this.value.latest !== bug2.value.latest) { + this.value.latest = bug2.value.latest; + } + if(this.value.count !== bug2.value.count) { + this.value.count = bug2.value.count; + } + if(this.value.solved !== bug2.value.solved) { + this.value.solved = bug2.value.solved; + } + if(this.value.description !== bug2.value.description) { + this.value.description = bug2.value.description; + } + }; - var bugUpdate = function(bug2) { - if(this.value.latest !== bug2.value.latest) { - this.value.latest = bug2.value.latest; - } - if(this.value.count !== bug2.value.count) { - this.value.count = bug2.value.count; - } - if(this.value.solved !== bug2.value.solved) { - this.value.solved = bug2.value.solved; - } - if(this.value.description !== bug2.value.description) { - this.value.description = bug2.value.description; - } - }; + var toggleSolved = function() { + var bug = this; + this.solvedPending = true; + ReportsStore.toggleSolvedBug(bug, function(data){ + bug.solvedPending = false; + }); + }; + + var additionalCallback = function(data) { + // The bug view does not return individual documents. Unless data has been specifically updated about + // one bug, there is no bug document in a database. We add here the computed id of each 'virtual' bug. + for (var i = 0; i < data.rows.length; i++) { + data.rows[i].id = ""+data.rows[i].key; + data.rows[i].equals = bugEqualityTest; + data.rows[i].updateWithBug = bugUpdate; + data.rows[i].toggleSolved = toggleSolved; + data.rows[i].descriptionHtml = converter.makeHtml(data.rows[i].value.description); + } + cb(data); + }; - var toggleSolved = function() { - var bug = this; - this.solvedPending = true; - ReportsStore.toggleSolvedBug(bug, function(data){ - bug.solvedPending = false; - }); + return ReportsStore.views.get(viewParams, additionalCallback, errorHandler); }; + }; - var additionalCallback = function(data) { - // The bug view does not return individual documents. Unless data has been specifically updated about - // one bug, there is no bug document in a database. We add here the computed id of each 'virtual' bug. - for (var i = 0; i < data.rows.length; i++) { - data.rows[i].id = computeBugId(data.rows[i]); - data.rows[i].equals = bugEqualityTest; - data.rows[i].updateWithBug = bugUpdate; - data.rows[i].toggleSolved = toggleSolved; - data.rows[i].descriptionHtml = converter.makeHtml(data.rows[i].value.description); - } - cb(data); - }; + ReportsStore.recentBugsList = ReportsStore.bugListWithLimit(0); - return ReportsStore.views.get(viewParams, additionalCallback, errorHandler); - }; + ReportsStore.bugsList = ReportsStore.bugListWithLimit(0); ReportsStore.toggleSolvedBug = function(bug, callback) { + var updateBrowserBug = function(data) { + bug.value.solved = curBug.solved; + callback(data); + }; var curBug = ReportsStore.bug.get({ bugid: bug.id}, function() { // Success callback curBug.solved = ! curBug.solved; - var state = curBug.solved; - curBug.$save(function(data) { - bug.value.solved = state; - console.log("bug is now:"); - console.log(bug); - callback(data); - }); + ReportsStore.bug.save(curBug, updateBrowserBug); }, function() { // Fail callback curBug = new ReportsStore.bug( { _id: bug.id, - APP_VERSION_CODE: bug.key[0], - digest: bug.key[1], - rootCause: bug.key[2], + SIGNATURE: { + hash: bug.key + }, solved: true, type: "solved_signature" }); - curBug.$save(function(data) { - bug.value.solved = curBug.solved; - callback(data); - }); + ReportsStore.bug.save(curBug, updateBrowserBug); }); }; @@ -285,9 +275,9 @@ curBug = new ReportsStore.bug( { _id: bug.id, - APP_VERSION_CODE: bug.key[0], - digest: bug.key[1], - rootCause: bug.key[2], + signature: { + hash: bug.value.hash + }, solved: bug.value.solved, type: "solved_signature", description: bug.value.description @@ -308,17 +298,11 @@ * @param cb */ ReportsStore.getBugForId = function(bugId, cb) { - var bug = {}; - ReportsStore.bugsList(function(data) { - console.log("looking for bug with id " + bugId); - for (var i = 0; i < data.rows.length; i++) { - if (data.rows[i].id === bugId) { - bug = data.rows[i]; - console.log("Bug found:"); - console.log(bug); - break; - } - } + var bug = null; + console.log("looking for bug with id " + bugId); + ReportsStore.bugListWithLimit(1, bugId)(function(data) { + bug = data.rows[0]; + if (bug === null) { console.log("Error, unable to find bug with id " + bugId); } cb(bug); }); return bug; @@ -483,16 +467,16 @@ var viewParams = { view: 'users-per-bug', reduce: true, - group_level: 4 + group_level: 2 }; - viewParams.startkey = JSON.stringify([bug.key[0], bug.key[1], bug.key[2]]); - viewParams.endkey = JSON.stringify([bug.key[0], bug.key[1], bug.key[2], {}]); + viewParams.startkey = JSON.stringify([bug.key]); + viewParams.endkey = JSON.stringify([bug.key, {}]); var result = []; ReportsStore.views.get(viewParams,function(data) { for(var row = 0; row < data.rows.length; row++) { var user = { - installationId: data.rows[row].key[3], + installationId: data.rows[row].key[1], reportsCount: data.rows[row].value }; result.push(user); From e2c3cd376eeae19a0dab9389eb8c34a4bd931fc2 Mon Sep 17 00:00:00 2001 From: Rick Carragher and Dave Cameron Date: Sun, 17 Nov 2013 21:06:07 -0500 Subject: [PATCH 2/4] Reduce number of couch views needed by re-using views Couch's include_docs and group_level parameters enable several places that previously used reports-per-x to instead re-use the recent-items-by views, but with a reduction done to get the count. This reduces the time it takes to index, and reduces the size of the indexes on disk. --- _attachments/partials/reports-table.html | 12 +++---- _attachments/script/DashboardControllers.js | 33 ++++++++++++++++--- .../script/ReportsBrowserControllers.js | 10 +++--- _attachments/script/service.reportsstore.js | 16 ++++----- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/_attachments/partials/reports-table.html b/_attachments/partials/reports-table.html index b1aec9f..e3b4cf7 100644 --- a/_attachments/partials/reports-table.html +++ b/_attachments/partials/reports-table.html @@ -18,14 +18,14 @@ - + {{report.displayDate}} - {{report.value.application_version_name}} - {{report.value.android_version}} - {{report.value.device}} + {{report.doc.APP_VERSION_NAME}} + {{report.doc.ANDROID_VERSION}} + {{getDevice(report.doc)}}
- {{report.value.signature.full}} - Caused by: {{report.value.signature.rootCause}} + {{report.doc.SIGNATURE.full}} + Caused by: {{report.doc.SIGNATURE.rootCause}}
\ No newline at end of file diff --git a/_attachments/script/DashboardControllers.js b/_attachments/script/DashboardControllers.js index 42e514b..c10fa94 100644 --- a/_attachments/script/DashboardControllers.js +++ b/_attachments/script/DashboardControllers.js @@ -58,6 +58,29 @@ }); }; + $scope.getDevice = function(doc) { + if(doc.BUILD) { + if(doc.BUILD.MANUFACTURER) { + return doc.BUILD.MANUFACTURER + " " + doc.BUILD.BRAND + " " + doc.BUILD.MODEL; + } else { + return doc.BUILD.BRAND + " " + doc.BUILD.MODEL; + } + } else { + var value = ""; + if(doc.BRAND) { + value = doc.BRAND; + } + if(doc.PRODUCT) { + value += " " + doc.PRODUCT; + } + if(doc.PHONE_MODEL) { + value += " " + doc.MODEL; + } + + return value; + } + }; + $scope.loadReport = function(report) { $scope.selectedReport = ReportsStore.reportDetails(report.id, function(data) { data.readableUptime = moment.duration(data.uptime, 'seconds').humanize(); @@ -374,11 +397,11 @@ /* Pie charts */ function PieChartsCtrl($scope, ReportsStore, $user) { $scope.fieldNames = [ - {name: "android-version", label: "Android version"}, - {name: "android-sdk-version", label: "Android SDK version"}, - {name: "app-version-name", label: "Application version name"}, - {name: "app-version-code", label: "Application version code"}, - {name: "device", label: "Device"} + {name: "recent-items-by-androidver", label: "Android version"}, + {name: "reports-per-android-sdk-version", label: "Android SDK version"}, + {name: "recent-items-by-appver", label: "Application version name"}, + {name: "recent-items-by-appvercode", label: "Application version code"}, + {name: "reports-per-device", label: "Device"} ]; $scope.fieldName = $scope.fieldNames[0]; diff --git a/_attachments/script/ReportsBrowserControllers.js b/_attachments/script/ReportsBrowserControllers.js index ccd9631..b818eb9 100644 --- a/_attachments/script/ReportsBrowserControllers.js +++ b/_attachments/script/ReportsBrowserControllers.js @@ -141,22 +141,22 @@ }; if(($scope.filterName === $scope.noFilter || $scope.filterValue === $scope.noFilterValue) && !$scope.bug && !$scope.selectedUser) { - ReportsStore.reportsList($scope.startKey, $scope.paginator.pageSize, $scope.fullSearch, successHandler, errorHandler); + ReportsStore.reportsList($scope.startKey, $scope.paginator.pageSize, true, successHandler, errorHandler); } else if($scope.filterName !== $scope.noFilter && $scope.filterValue !== $scope.noFilterValue){ - ReportsStore.filteredReportsList($scope.filterName.value, $scope.filterValue.value,$scope.startKey, $scope.paginator.pageSize, $scope.fullSearch, successHandler, errorHandler); + ReportsStore.filteredReportsList($scope.filterName.value, $scope.filterValue.value,$scope.startKey, $scope.paginator.pageSize, true, successHandler, errorHandler); } else if($scope.bug) { if($scope.selectedUser) { // Filter by bug AND user var filterKey = [$scope.bug.key]; filterKey.push($scope.selectedUser.installationId); - ReportsStore.filteredReportsList("bug-by-installation-id", filterKey, $scope.startKey, $scope.paginator.pageSize, $scope.fullSearch, successHandler, errorHandler); + ReportsStore.filteredReportsList("bug-by-installation-id", filterKey, $scope.startKey, $scope.paginator.pageSize, true, successHandler, errorHandler); } else { // Filter by bug only - ReportsStore.filteredReportsList("bug", $scope.bug.key, $scope.startKey, $scope.paginator.pageSize, $scope.fullSearch, successHandler, errorHandler); + ReportsStore.filteredReportsList("bug-by-installation-id", $scope.bug.key, $scope.startKey, $scope.paginator.pageSize, true, successHandler, errorHandler, 1); } } else if($scope.selectedUser) { // Filter by user only - ReportsStore.filteredReportsList("installation-id", $scope.selectedUser.installationId, $scope.startKey, $scope.paginator.pageSize, $scope.fullSearch, successHandler, errorHandler); + ReportsStore.filteredReportsList("installation-id", $scope.selectedUser.installationId, $scope.startKey, $scope.paginator.pageSize, true, successHandler, errorHandler); } }; diff --git a/_attachments/script/service.reportsstore.js b/_attachments/script/service.reportsstore.js index 03e8294..ddc619a 100644 --- a/_attachments/script/service.reportsstore.js +++ b/_attachments/script/service.reportsstore.js @@ -88,7 +88,7 @@ // 10 latest reports - Key: date/time Value: report digest ReportsStore.recentReports = function(cb, errorHandler) { - return ReportsStore.views.get({view: 'recent-items', limit: 10, descending: true}, cb, errorHandler); + return ReportsStore.views.get({view: 'recent-items', limit: 10, descending: true, include_docs: true}, cb, errorHandler); }; // Key: report ID Value: report digest @@ -138,10 +138,8 @@ } for(var row = 0; row < data.rows.length; row++) { - if(filterName === "bug") { - data.rows[row].displayDate = moment(data.rows[row].key[3]).fromNow(); - } else if(filterName === "bug-by-installation-id") { - data.rows[row].displayDate = moment(data.rows[row].key[4]).fromNow(); + if(filterName === "bug-by-installation-id") { + data.rows[row].displayDate = moment(data.rows[row].key[2]).fromNow(); } else { data.rows[row].displayDate = moment(data.rows[row].key[1]).fromNow(); } @@ -159,19 +157,19 @@ }; ReportsStore.reportsPerFieldName = function(fieldName, cb, errorHandler) { - return ReportsStore.views.get({view: 'reports-per-' + fieldName, group_level: 1}, cb, errorHandler); + return ReportsStore.views.get({view: fieldName, group_level: 1}, cb, errorHandler); }; ReportsStore.appVersionsList = function(cb) { - return ReportsStore.views.get({view: 'recent-items-by-appver', group_level: 1}, cb); + return ReportsStore.views.get({view: 'recent-items-by-appver', reduce: true, group_level: 1, include_docs: false}, cb); }; ReportsStore.appVersionCodesList = function(cb) { - return ReportsStore.views.get({view: 'recent-items-by-appvercode', group_level: 1}, cb); + return ReportsStore.views.get({view: 'recent-items-by-appvercode', reduce: true, group_level: 1, include_docs: false}, cb); }; ReportsStore.androidVersionsList = function(cb) { - return ReportsStore.views.get({view: 'recent-items-by-androidver', group_level: 1}, cb); + return ReportsStore.views.get({view: 'recent-items-by-androidver', reduce: true, group_level: 1, include_docs: false}, cb); }; ReportsStore.bugListWithLimit = function(limit, bugId) { From a075b200d66eb8477b1dec5b2b629436b8c56dcf Mon Sep 17 00:00:00 2001 From: Rick Carragher and Dave Cameron Date: Sat, 11 Jan 2014 23:00:08 -0500 Subject: [PATCH 3/4] Accept stale data throughout the dashboard --- _attachments/script/DashboardControllers.js | 2 +- _attachments/script/service.reportsstore.js | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/_attachments/script/DashboardControllers.js b/_attachments/script/DashboardControllers.js index c10fa94..4e8a850 100644 --- a/_attachments/script/DashboardControllers.js +++ b/_attachments/script/DashboardControllers.js @@ -80,7 +80,7 @@ return value; } }; - + $scope.loadReport = function(report) { $scope.selectedReport = ReportsStore.reportDetails(report.id, function(data) { data.readableUptime = moment.duration(data.uptime, 'seconds').humanize(); diff --git a/_attachments/script/service.reportsstore.js b/_attachments/script/service.reportsstore.js index ddc619a..d62ce4a 100644 --- a/_attachments/script/service.reportsstore.js +++ b/_attachments/script/service.reportsstore.js @@ -82,13 +82,13 @@ * @return Key: date/time, Value: quantity */ ReportsStore.reportsPerDay = function(grouplvl, cb, errorHandler) { - return ReportsStore.views.get({view: 'reports-per-day', group_level: grouplvl}, cb, errorHandler); + return ReportsStore.views.get({view: 'reports-per-day', group_level: grouplvl, stale: 'update_after'}, cb, errorHandler); }; // 10 latest reports - Key: date/time Value: report digest ReportsStore.recentReports = function(cb, errorHandler) { - return ReportsStore.views.get({view: 'recent-items', limit: 10, descending: true, include_docs: true}, cb, errorHandler); + return ReportsStore.views.get({view: 'recent-items', limit: 10, descending: true, stale: 'update_after', include_docs: true}, cb, errorHandler); }; // Key: report ID Value: report digest @@ -97,6 +97,7 @@ view: 'recent-items', descending: true, limit: reportsCount + 1, + stale: 'update_after', include_docs: includeDocs }; if(startKey !== null) { @@ -121,6 +122,7 @@ view: 'recent-items-by-' + filterName, descending: true, limit: reportsCount + 1, + stale: 'update_after', include_docs: includeDocs, reduce: false }; @@ -157,19 +159,19 @@ }; ReportsStore.reportsPerFieldName = function(fieldName, cb, errorHandler) { - return ReportsStore.views.get({view: fieldName, group_level: 1}, cb, errorHandler); + return ReportsStore.views.get({view: fieldName, group_level: 1, stale: 'update_after'}, cb, errorHandler); }; ReportsStore.appVersionsList = function(cb) { - return ReportsStore.views.get({view: 'recent-items-by-appver', reduce: true, group_level: 1, include_docs: false}, cb); + return ReportsStore.views.get({view: 'recent-items-by-appver', reduce: true, group_level: 1, include_docs: false, stale: 'update_after'}, cb); }; ReportsStore.appVersionCodesList = function(cb) { - return ReportsStore.views.get({view: 'recent-items-by-appvercode', reduce: true, group_level: 1, include_docs: false}, cb); + return ReportsStore.views.get({view: 'recent-items-by-appvercode', reduce: true, group_level: 1, include_docs: false, stale: 'update_after'}, cb); }; ReportsStore.androidVersionsList = function(cb) { - return ReportsStore.views.get({view: 'recent-items-by-androidver', reduce: true, group_level: 1, include_docs: false}, cb); + return ReportsStore.views.get({view: 'recent-items-by-androidver', reduce: true, group_level: 1, include_docs: false, stale: 'update_after'}, cb); }; ReportsStore.bugListWithLimit = function(limit, bugId) { @@ -178,7 +180,8 @@ var viewParams = { view: 'bugs', descending: true, - group: true + group: true, + stale: 'update_after' }; if (limit > 0) { viewParams.limit = limit; } @@ -465,7 +468,8 @@ var viewParams = { view: 'users-per-bug', reduce: true, - group_level: 2 + group_level: 2, + stale: 'update_after' }; viewParams.startkey = JSON.stringify([bug.key]); From a49b7ff3be42b9ce06b996f1ca80dfd38de3226d Mon Sep 17 00:00:00 2001 From: Dave Cameron Date: Sun, 24 Nov 2013 22:01:55 -0500 Subject: [PATCH 4/4] add logcat link, but it is only text, not clickable --- _attachments/script/service.reportsstore.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/_attachments/script/service.reportsstore.js b/_attachments/script/service.reportsstore.js index d62ce4a..5a95fcf 100644 --- a/_attachments/script/service.reportsstore.js +++ b/_attachments/script/service.reportsstore.js @@ -26,7 +26,7 @@ * @singleton * @static */ - acralyzer.factory('ReportsStore', ['$rootScope', '$http', '$resource', function($rootScope, $http, $resource) { + acralyzer.factory('ReportsStore', ['$rootScope', '$http', '$resource', '$location', function($rootScope, $http, $resource, $location) { // ReportsStore service instance var ReportsStore = { lastseq : -1, @@ -45,9 +45,17 @@ * @param {function} cb Callback to be executed after database changed. */ ReportsStore.setApp = function (newAppName, cb) { + var addLogcatLink = function(data, headersGetter) { + var report = JSON.parse(data); + if (report._attachments['logcat.txt'].stub) { + var link = $location.protocol() + '://' + $location.host() + ':' + $location.port() + '/' + ReportsStore.dbName + '/' + report._id + '/logcat.txt'; + report._attachments['logcat.txt'].link = link; + } + return report; + }; ReportsStore.dbName = acralyzerConfig.appDBPrefix + newAppName; ReportsStore.views = $resource('/' + ReportsStore.dbName + '/_design/acra-storage/_view/:view'); - ReportsStore.details = $resource('/' + ReportsStore.dbName + '/:reportid'); + ReportsStore.details = $resource('/' + ReportsStore.dbName + '/:reportid', null, {'get': {method:'GET', transformResponse: addLogcatLink}}); ReportsStore.bug = $resource('/' + ReportsStore.dbName + '/:bugid', { bugid: '@_id' }, { save: {method: 'PUT'}}); ReportsStore.dbstate = $resource('/' + ReportsStore.dbName + '/'); ReportsStore.changes = $resource('/' + ReportsStore.dbName + '/_changes');
Application version code:{{bug.key[0]}}{{bug.value.appVersion}}
Exception:{{bug.key[1]}}{{bug.value.exception}}
Root Exception:{{bug.key[2]}}{{bug.value.rootCause}}
Solved: