package org.netevolved.tincan; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; import org.elasticsearch.search.aggregations.bucket.terms.StringTerms.Bucket; import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.entermediadb.asset.MediaArchive; import org.entermediadb.elasticsearch.ElasticHitTracker; import org.entermediadb.elasticsearch.ElasticSearchQuery; import org.ijsolutions.testbench.TestBench; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.openedit.CatalogEnabled; import org.openedit.Data; import org.openedit.ModuleManager; import org.openedit.data.Searcher; import org.openedit.hittracker.HitTracker; import org.openedit.hittracker.SearchQuery; import org.openedit.users.User; public class BenchAnalytics implements CatalogEnabled { private static final Log log = LogFactory.getLog(TinCan.class); protected String fieldCatalogId; protected ModuleManager fieldModuleManager; public String getCatalogId() { return fieldCatalogId; } public void setCatalogId(String inCatalogId) { fieldCatalogId = inCatalogId; } public ModuleManager getModuleManager() { return fieldModuleManager; } public void setModuleManager(ModuleManager inModuleManager) { fieldModuleManager = inModuleManager; } protected MediaArchive getMediaArchive() { MediaArchive archive = (MediaArchive) getModuleManager().getBean(getCatalogId(), "mediaArchive"); return archive; } protected TestBench getTestBench() { TestBench archive = (TestBench) getModuleManager().getBean(getCatalogId(), "testBench"); return archive; } public HitTracker loadAllStatements() { return getTestBench().getSearcher("lrsactivities").getAllHits(); } public HitTracker getStatementsForUser(String inUserId, String inLearningGroup) { return getTestBench().getSearcher("lrsactivities").query().ignoreEmpty().exact("userid", inUserId).exact("learningGroup", inLearningGroup).sort("dateDown").search(); } public HitTracker getStatementsForUser(String inUserId) { return getStatementsForUser(inUserId, null); } public JSONObject getActivityProgress(String inLearningGroup, String inTestPlan, String inReportID) { HashMap jsonreport = new HashMap(); ArrayList data = new ArrayList(); jsonreport.put("data", data); ArrayList labels = new ArrayList(); jsonreport.put("labels", labels); ArrayList colours = new ArrayList(); jsonreport.put("colours", colours); //ArrayList timereport = new ArrayList(); //jsonreport.put("timereport", timereport); doesn't work as dataset info for activityprogress.html Searcher searcher = getTestBench().getSearcher("lrsactivities"); ElasticSearchQuery query = (ElasticSearchQuery) searcher.createSearchQuery(); //query.addMatches("learningGroup", inLearningGroup); query.addContains("activity", inTestPlan); Data report = getMediaArchive().getData("reports", inReportID); if (report != null && report.get("aggs") != null) { query.setAggregationJson(report.get("aggs")); } ElasticHitTracker results = (ElasticHitTracker) searcher.search(query); String json = results.getSearchResponse(0).toString(); //JsonParser parser = new JsonParser(); log.info(json); StringTerms userbuckets = (StringTerms) results.getAggregations().get("by_user"); DecimalFormat df = new DecimalFormat("0.00"); double bucketcounter = 0; double averageduration = 0; for (Iterator iterator = userbuckets.getBuckets().iterator(); iterator.hasNext();) { Bucket userbucket = (StringTerms.Bucket) iterator.next(); String username = userbucket.getKeyAsString(); Sum sum = userbucket.getAggregations().get("user_stats"); //Data passed = searcher.query().contains("userid", username).contains("activity", inTestPlan).contains("verb", "passed").searchOne(); Data passed = searcher.query().contains("userid", username).contains("activity", inTestPlan).contains("verbid", "passed").searchOne(); String seconds = null; if (sum.getValue() / 3600 > 24) { seconds = "25.00"; //time cap } else { seconds = df.format(sum.getValue() / 3600); //display in hours } data.add(seconds); if (passed != null) { colours.add("green"); } else { colours.add("orange"); } User user = getTestBench().getUserManager().getUser(username); labels.add(user.toString()); //String studenttime = PeriodFormat.getDefault().print(new Period(0, 0, (int)sum.getValue(), 0).normalizedStandard()); displays time as a string in hrs, mins, secs format, but chart builder can't use this as data. //timereport.add(studenttime); bucketcounter++; averageduration = averageduration + sum.getValue() / 3600; } averageduration = averageduration / bucketcounter; String classaverage = df.format(averageduration); data.add(classaverage); labels.add("Average Class Duration"); colours.add("blue"); JSONObject object = new JSONObject(jsonreport); return object; } public JSONObject getChartData(ElasticHitTracker inResponse, Data inReport) throws Exception { HashMap jsonreport = new HashMap(); ArrayList data = new ArrayList(); jsonreport.put("data", data); ArrayList labels = new ArrayList(); jsonreport.put("labels", labels); ArrayList colours = new ArrayList(); jsonreport.put("colours", colours); String json = inResponse.getSearchResponse(0).toString(); String reporttype = (String) inReport.getValue("reporttype"); Searcher searcher = getTestBench().getSearcher("lrsactivities"); SearchQuery query = inResponse.getSearchQuery().copy(); JSONParser parser = new JSONParser(); JSONObject results = (JSONObject) parser.parse(json); JSONObject aggs = (JSONObject) results.get("aggregations"); if (aggs != null) { for (Iterator iterator = aggs.keySet().iterator(); iterator.hasNext();) { String key = (String) iterator.next(); //key is "user_userid" in our example String[] temp = key.split("_"); //splits "user_userid" into two parts String tableid = temp[0]; //in our example, "user" JSONObject value = (JSONObject) aggs.get(key); //the "user_userid" object JSONArray buckets = (JSONArray) value.get("buckets"); //array of buckets inside the object for (Iterator iterator2 = buckets.iterator(); iterator2.hasNext();) { JSONObject bucket = (JSONObject) iterator2.next(); //the individual buckets inside the bucket array, one bucket per user in our example if ("termbucket".equals(reporttype)) { JSONObject result = (JSONObject) bucket.get(key + "_response"); Object aggregatevalue = result.get("value"); if (inReport.get("scalefactor") != null) { Double scalefactor = Double.valueOf(inReport.get("scalefactor")); if (scalefactor > 0) { Double elasticvalue = Double.valueOf(aggregatevalue.toString()); aggregatevalue = scalefactor * elasticvalue; } } data.add(aggregatevalue); // in our example, the sum of all of the period durations of the activity statements String bucketvalue = (String) bucket.get("key"); //the unique key value for the bucket, so the username in our example, eg "1234" Data target = getMediaArchive().getData(tableid, bucketvalue); //in our example, the user table and the userid to give the username, eg "1234" labels.add(target.getName()); // converts "1234" into actual name of user, eg John Doe colours.add("blue"); //Data passed = searcher.query().contains("userid", bucketvalue).contains("activity", inTestPlan).contains("verbid", "passed").searchOne(); // query.addContains("userid", bucketvalue); // query.addContains("verbid", "passed"); // HitTracker specificresults = searcher.search(query); // if (specificresults.size()>0) { // colours.add("green"); // } else { // colours.add("orange"); // } // query.removeTerm("userid"); } else if ("datehistogram".equals(reporttype)) { Object count = bucket.get("doc_count"); Object label = bucket.get("key_as_string"); data.add(count); labels.add(label); colours.add("blue"); } } } } JSONObject object = new JSONObject(jsonreport); return object; } }