package com.github.andlyticsproject.model; import java.math.BigDecimal; import java.text.SimpleDateFormat; import android.annotation.SuppressLint; import android.util.SparseArray; import com.github.andlyticsproject.AppStatsDiff; public class AppStats extends Statistic { private int totalDownloads; private int activeInstalls; private int activeInstallsDiff; private int numberOfComments; private int numberOfCommentsDiff; private int dailyDownloads; private boolean smoothingApplied; private Integer versionCode; private Integer rating1 = 0; private Integer rating2 = 0; private Integer rating3 = 0; private Integer rating4 = 0; private Integer rating5 = 0; private Integer rating1Diff = 0; private Integer rating2Diff = 0; private Integer rating3Diff = 0; private Integer rating4Diff = 0; private Integer rating5Diff = 0; private float avgRating; private float avgRatingDiff; private int ratingCount; private int ratingCountDiff; private String avgRatingString; private String numberOfCommentsPercentString; private String ratingCountPercentString; private SparseArray<String> ratingPercentStringMap; private String activeInstallsPercentString; private String avgRatingDiffString; // XXX should put in wrapper class private String packageName; // TODO -- do we support diffs for this? private Integer numberOfErrors; private Revenue totalRevenue; public AppStats() { } /** * Copy Constructor * * @param appStats a <code>AppStats</code> object */ public AppStats(AppStats appStats) { this.totalDownloads = appStats.totalDownloads; this.activeInstalls = appStats.activeInstalls; this.numberOfComments = appStats.numberOfComments; this.date = appStats.date; this.dailyDownloads = appStats.dailyDownloads; this.smoothingApplied = appStats.smoothingApplied; this.rating1 = appStats.rating1; this.rating2 = appStats.rating2; this.rating3 = appStats.rating3; this.rating4 = appStats.rating4; this.rating5 = appStats.rating5; this.rating1Diff = appStats.rating1Diff; this.rating2Diff = appStats.rating2Diff; this.rating3Diff = appStats.rating3Diff; this.rating4Diff = appStats.rating4Diff; this.rating5Diff = appStats.rating5Diff; this.avgRating = appStats.avgRating; this.ratingCount = appStats.ratingCount; this.setAvgRatingString(appStats.getAvgRatingString()); this.numberOfCommentsPercentString = appStats.numberOfCommentsPercentString; this.ratingCountPercentString = appStats.ratingCountPercentString; this.ratingPercentStringMap = appStats.ratingPercentStringMap; this.setActiveInstallsPercentString(appStats.getActiveInstallsPercentString()); this.versionCode = appStats.versionCode; this.packageName = appStats.packageName; } public void init() { calcAvgRating(); calcAvgRatingString(); calcNumberOfCommentsPercentString(); calcRatingCount(); calcRatingCountPercentString(); calsRatingPercentStrings(); calcActiveInstallsPercentString(); calcAvgRatingDiffString(); } public int getTotalDownloads() { return totalDownloads; } public void setTotalDownloads(int totalDownloads) { this.totalDownloads = totalDownloads; } public int getActiveInstalls() { return activeInstalls; } public void setActiveInstalls(int activeInstalls) { this.activeInstalls = activeInstalls; } public int getNumberOfComments() { return numberOfComments; } public void setNumberOfComments(int numberOfComments) { this.numberOfComments = numberOfComments; } public int getDailyDownloads() { return dailyDownloads; } public void setDailyDownloads(int dailyDownloads) { this.dailyDownloads = dailyDownloads; } public boolean isSmoothingApplied() { return smoothingApplied; } public void setSmoothingApplied(boolean smoothingApplied) { this.smoothingApplied = smoothingApplied; } public void setRating(Integer rating1, Integer rating2, Integer rating3, Integer rating4, Integer rating5) { this.rating1 = rating1; this.rating2 = rating2; this.rating3 = rating3; this.rating4 = rating4; this.rating5 = rating5; } public void addRating(int i, int value) { switch (i) { case 1: this.rating1 = value; break; case 2: this.rating2 = value; break; case 3: this.rating3 = value; break; case 4: this.rating4 = value; break; case 5: this.rating5 = value; break; default: break; } } public float getAvgRating() { return avgRating; } public void calcAvgRating() { float ratings = 0; float count = 0; for (int i = 1; i < 6; i++) { int value = 0; switch (i) { case 1: value = rating1; break; case 2: value = rating2; break; case 3: value = rating3; break; case 4: value = rating4; break; case 5: value = rating5; break; default: break; } ratings += i * value; count += value; } if (count < 1) { this.avgRating = 0; } else { this.avgRating = ratings / count; } } public int getRatingCount() { return ratingCount; } public void calcRatingCount() { this.ratingCount = rating1 + rating2 + rating3 + rating4 + rating5; } public void calcAvgRatingString() { BigDecimal ratingBigDecimal = new BigDecimal(getAvgRating()); ratingBigDecimal = ratingBigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP); this.setAvgRatingString(ratingBigDecimal.toPlainString()); } public void calcAvgRatingDiffString() { BigDecimal ratingBigDecimal = new BigDecimal(getAvgRatingDiff()); ratingBigDecimal = ratingBigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP); this.setAvgRatingDiffString(ratingBigDecimal.toPlainString()); } public String getAvgRatingString() { return this.avgRatingString; } public String getRatingPercentString(int rating) { return ratingPercentStringMap.get(rating); } public void calsRatingPercentStrings() { this.ratingPercentStringMap = new SparseArray<String>(); int sum = getRatingCount(); for (int i = 1; i < 6; i++) { BigDecimal ratingBigDecimal = new BigDecimal(20); if (sum != 0) { Integer rate = null; switch (i) { case 1: rate = rating1; break; case 2: rate = rating2; break; case 3: rate = rating3; break; case 4: rate = rating4; break; case 5: rate = rating5; break; default: break; } if (rate == null || rate < 1) { rate = 0; } ratingBigDecimal = new BigDecimal(100.f / sum * rate); } ratingBigDecimal = ratingBigDecimal.setScale(2, BigDecimal.ROUND_HALF_EVEN); ratingPercentStringMap.put(i, ratingBigDecimal.toPlainString() + "%"); } } public String getActiveInstallsPercentString() { return activeInstallsPercentString; } public void calcActiveInstallsPercentString() { BigDecimal percentBigDecimal = new BigDecimal(getActiveInstallsPercent()); percentBigDecimal = percentBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP); this.setActiveInstallsPercentString(percentBigDecimal.toPlainString()); } @SuppressLint("SimpleDateFormat") public String getRequestDateString() { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return dateFormat.format(getDate()); } public double getActiveInstallsPercent() { if (totalDownloads < 1) { return 0; } return (activeInstalls * 100.0) / totalDownloads; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + activeInstalls; result = prime * result + dailyDownloads; result = prime * result + numberOfComments; result = prime * result + ((date == null) ? 0 : date.hashCode()); result = prime * result + (smoothingApplied ? 1231 : 1237); result = prime * result + totalDownloads; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; AppStats other = (AppStats) obj; if (activeInstalls != other.activeInstalls) return false; if (dailyDownloads != other.dailyDownloads) return false; if (numberOfComments != other.numberOfComments) return false; if (date == null) { if (other.date != null) return false; } else if (!date.equals(other.date)) return false; if (smoothingApplied != other.smoothingApplied) return false; if (totalDownloads != other.totalDownloads) return false; return true; } public String getNumberOfCommentsPercentString() { return numberOfCommentsPercentString; } public void calcNumberOfCommentsPercentString() { int numberOfComments = getNumberOfComments(); float percent = 0.0f; if (totalDownloads > 0) { percent = 100.0f / totalDownloads * numberOfComments; } BigDecimal percentBigDecimal = new BigDecimal(percent); percentBigDecimal = percentBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP); this.numberOfCommentsPercentString = percentBigDecimal.toPlainString(); } public String getRatingCountPercentString() { return ratingCountPercentString; } public void calcRatingCountPercentString() { int numberOfComments = getRatingCount(); float percent = 0.0f; if (totalDownloads > 0) { percent = 100.0f / totalDownloads * numberOfComments; } BigDecimal percentBigDecimal = new BigDecimal(percent); percentBigDecimal = percentBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP); this.ratingCountPercentString = percentBigDecimal.toPlainString(); } public Integer getRating1() { return rating1; } public void setRating1(Integer rating1) { this.rating1 = rating1; } public Integer getRating2() { return rating2; } public void setRating2(Integer rating2) { this.rating2 = rating2; } public Integer getRating3() { return rating3; } public void setRating3(Integer rating3) { this.rating3 = rating3; } public Integer getRating4() { return rating4; } public void setRating4(Integer rating4) { this.rating4 = rating4; } public Integer getRating5() { return rating5; } public Integer getRating1Diff() { return rating1Diff; } public void setRating1Diff(Integer rating1Diff) { this.rating1Diff = rating1Diff; } public Integer getRating2Diff() { return rating2Diff; } public void setRating2Diff(Integer rating2Diff) { this.rating2Diff = rating2Diff; } public Integer getRating3Diff() { return rating3Diff; } public void setRating3Diff(Integer rating3Diff) { this.rating3Diff = rating3Diff; } public Integer getRating4Diff() { return rating4Diff; } public void setRating4Diff(Integer rating4Diff) { this.rating4Diff = rating4Diff; } public Integer getRating5Diff() { return rating5Diff; } public void setRating5Diff(Integer rating5Diff) { this.rating5Diff = rating5Diff; } public void setRating5(Integer rating5) { this.rating5 = rating5; } public void setAvgRatingDiff(float avgRatingDiff) { this.avgRatingDiff = avgRatingDiff; } public float getAvgRatingDiff() { return avgRatingDiff; } public void setRatingCountDiff(int ratingCountDiff) { this.ratingCountDiff = ratingCountDiff; } public int getRatingCountDiff() { return ratingCountDiff; } public void setAvgRatingDiffString(String avgRatingDiffString) { this.avgRatingDiffString = avgRatingDiffString; } public String getAvgRatingDiffString() { return avgRatingDiffString; } public void setNumberOfCommentsDiff(int numberOfCommentsDiff) { this.numberOfCommentsDiff = numberOfCommentsDiff; } public int getNumberOfCommentsDiff() { return numberOfCommentsDiff; } public void setActiveInstallsDiff(int activeInstallsDiff) { this.activeInstallsDiff = activeInstallsDiff; } public int getActiveInstallsDiff() { return activeInstallsDiff; } public void setVersionCode(Integer versionCode) { this.versionCode = versionCode; } public Integer getVersionCode() { return versionCode; } public void setActiveInstallsPercentString(String activeInstallsPercentString) { this.activeInstallsPercentString = activeInstallsPercentString; } public void setAvgRatingString(String avgRatingString) { this.avgRatingString = avgRatingString; } public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public void setNumberOfErrors(Integer numberOfErrors) { this.numberOfErrors = numberOfErrors; } public Integer getNumberOfErrors() { return numberOfErrors; } public Revenue getTotalRevenue() { return totalRevenue; } public void setTotalRevenue(Revenue totalRevenue) { this.totalRevenue = totalRevenue; } public AppStatsDiff createDiff(AppStats previousStats, AppInfo appInfo) { AppStatsDiff diff = new AppStatsDiff(); diff.setAppName(appInfo.getName()); diff.setPackageName(appInfo.getPackageName()); diff.setIconName(appInfo.getIconName()); diff.setSkipNotification(appInfo.isSkipNotification()); diff.setVersionName(appInfo.getVersionName()); if (previousStats != null) { init(); previousStats.init(); diff.setActiveInstallsChange(getActiveInstalls() - previousStats.getActiveInstalls()); diff.setDownloadsChange(getTotalDownloads() - previousStats.getTotalDownloads()); diff.setCommentsChange(getNumberOfComments() - previousStats.getNumberOfComments()); diff.setAvgRatingChange(getAvgRating() - previousStats.getAvgRating()); diff.setRating1Change(getRating1() - previousStats.getRating1()); diff.setRating2Change(getRating2() - previousStats.getRating2()); diff.setRating3Change(getRating3() - previousStats.getRating3()); diff.setRating4Change(getRating4() - previousStats.getRating4()); diff.setRating5Change(getRating5() - previousStats.getRating5()); } return diff; } }