package com.drawbridge.utils; import java.awt.Component; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import javax.swing.JFrame; import javax.swing.JOptionPane; import org.joda.time.DateTime; import com.drawbridge.Activity; import com.drawbridge.dm.animation.AnimationManager.AnimationState; import com.github.segmentio.Analytics; import com.github.segmentio.models.EventProperties; public class AnalyticUtils { public static String username = ""; public static boolean initialised = false; public final static boolean ANALYTICS_ENABLED = (Utils.loadDrawBridgeProperty("analytics").equals("true")); public static boolean mCanReachAnalytics = true; public static void init(final Component parent, final String mVersionName) { long time = System.currentTimeMillis(); if (ANALYTICS_ENABLED) { if(isSegmentIOReachable()){ Analytics.initialize("zep9v99pnixt69gruba7"); initialised = true; int count = 0; while((username == null || username.length() <= 0) && count < 5){ username = (String) JOptionPane.showInputDialog( parent, "Please enter your name:", "Username", JOptionPane.PLAIN_MESSAGE, null, null, ""); count++; } if(count == 5){ JOptionPane.showMessageDialog(null, "I hope you have a good reason for bypassing the username!"); username = "" + time; } else username += time; EventProperties ep = new EventProperties(); ep.put("startType", mVersionName); Analytics.track(AnalyticUtils.username, "Started DrawBridge", ep, new DateTime(time)); } else{ mCanReachAnalytics = false; JOptionPane.showMessageDialog(parent, "Cannot reach internet for analytics. Please alert the researcher!"); } appendToLoggerFile("" + AnalyticUtils.username + ", " + "Started DrawBridge" + ", " + mVersionName + ", " + time); } else{ JOptionPane.showMessageDialog(parent, "Warning, Analytics are turned off!"); } } /** * Records how long the user has been looking at a given pair of representations * * @param positionIndex * - the index of the selector */ public static void recordTimeOnRepresentation(int oldPositionIndex, long timeOnIndex) { if (ANALYTICS_ENABLED) { String repsInView = ""; switch (Activity.getInstance().mVersion) { case VERSION_NOCONCRETE_TEXTFIRST: if (oldPositionIndex == 0) { repsInView = "CODE_VL"; } else if (oldPositionIndex == 1) { repsInView = "VL_WEB"; } break; case VERSION_NOCONCRETE_VISUALFIRST: if (oldPositionIndex == 0) { repsInView = "VL_CODE"; } else if (oldPositionIndex == 1) { repsInView = "CODE_WEB"; } break; case VERSION_CONCRETE_TEXTFIRST: if (oldPositionIndex == 0) { repsInView = "PAPER_DM"; } else if (oldPositionIndex == 1) { repsInView = "DM_DMS"; } else if (oldPositionIndex == 2) { repsInView = "DMS_CODE"; } else if (oldPositionIndex == 3) { repsInView = "CODE_VL"; } else if (oldPositionIndex == 4) { repsInView = "VL_WEB"; } break; case VERSION_CONCRETE_VISUALFIRST: if (oldPositionIndex == 0) { repsInView = "PAPER_DM"; } else if (oldPositionIndex == 1) { repsInView = "DM_DMS"; } else if (oldPositionIndex == 2) { repsInView = "DMS_VL"; } else if (oldPositionIndex == 3) { repsInView = "VL_CODE"; } else if (oldPositionIndex == 4) { repsInView = "CODE_WEB"; } break; case VERSION_CONCRETE_JUSTVISUAL: if (oldPositionIndex == 0) { repsInView = "PAPER_DM"; } else if (oldPositionIndex == 1) { repsInView = "DM_DMS"; } else if (oldPositionIndex == 2) { repsInView = "DMS_VL"; } else if (oldPositionIndex == 3) { repsInView = "VL_WEB"; } break; case VERSION_CONCRETE_JUSTTEXTUAL: if (oldPositionIndex == 0) { repsInView = "PAPER_DM"; } else if (oldPositionIndex == 1) { repsInView = "DM_DMS"; } else if (oldPositionIndex == 2) { repsInView = "DMS_CODE"; } else if (oldPositionIndex == 3) { repsInView = "CODE_WEB"; } break; } long time = System.currentTimeMillis(); EventProperties ep = new EventProperties(); ep.put("repsInView", repsInView); ep.put("timeSpentInRep", timeOnIndex); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "PositionTimed", ep, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", " + repsInView + ", " + timeOnIndex + ", " + time); Utils.out.println("Analytics Track:" + repsInView); } } public static void close() { Utils.out.println("CLOSED"); long time = System.currentTimeMillis(); long timeDifference = time - Activity.getInstance().getToolbar().getSelector().getTimestamp(); AnalyticUtils.recordTimeOnRepresentation(Activity.getInstance().getToolbar().getSelector().getSelected(), timeDifference); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "DrawBridge Closed", null, new DateTime(time+1)); appendToLoggerFile("" + AnalyticUtils.username + ", DrawBridge Closed, " + ", " + time+1); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Analytics.close(); System.exit(0); } public static void recordSyntaxError(String message, int lineNumber){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); EventProperties ep = new EventProperties(); ep.put("Type", "Syntax"); ep.put("Message", message); ep.put("LineNo", lineNumber); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "Error", ep, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", ErrorType: Syntax , Message:" + message + ", LineNumber:" + lineNumber + ", " + time); } } public static void recordLintError(String message, int lineNumber){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); EventProperties ep = new EventProperties(); ep.put("Type", "Lint"); ep.put("Message", message); ep.put("LineNo", lineNumber); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "Error", ep, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", ErrorType: Lint , Message:" + message + ", LineNumber:" + lineNumber + ", " + time); } } public static void appendToLoggerFile(String str) { try { File logFile = new File(Utils.getTemporaryFolder() + "/log-" + AnalyticUtils.username + ".txt"); Utils.out.println(logFile.getAbsolutePath()); if (!logFile.exists()) { logFile.createNewFile(); } PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(logFile.getAbsolutePath(), true))); out.println(str); out.close(); } catch (IOException e) { Utils.err.println("Could not write to local log file!"); } } public static void recordDialling(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "Dialled", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", Dialled, " + ", " + time); } } public static WindowListener getWindowListener() { if(ANALYTICS_ENABLED){ WindowListener wl = new WindowAdapter(){ @Override public void windowClosing(WindowEvent e) { Utils.out.println("windowClosing"); AnalyticUtils.close(); } @Override public void windowClosed(WindowEvent e) { Utils.out.println("windowClosed"); AnalyticUtils.close(); } @Override public void windowIconified(WindowEvent e) { long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "windowIconified", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", windowIconified, " + ", " + time); //reset the time Activity.getInstance().getToolbar().getSelector().resetTimestamp(); } @Override public void windowDeiconified(WindowEvent e) { long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "windowDeiconified", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", windowDeiconified, " + ", " + time); int selected = Activity.getInstance().getToolbar().getSelector().getSelected(); long timeDifference = System.currentTimeMillis() - Activity.getInstance().getToolbar().getSelector().getTimestamp(); AnalyticUtils.recordTimeOnRepresentation(selected, timeDifference); } @Override public void windowActivated(WindowEvent e) { long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "windowActivated", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", windowActivated, " + ", " + time); Activity.getInstance().getToolbar().getSelector().resetTimestamp(); } @Override public void windowDeactivated(WindowEvent e) { long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "windowDeactivated", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", windowDeactivated, " + ", " + time); int selected = Activity.getInstance().getToolbar().getSelector().getSelected(); long timeDifference = System.currentTimeMillis() - Activity.getInstance().getToolbar().getSelector().getTimestamp(); AnalyticUtils.recordTimeOnRepresentation(selected, timeDifference); } }; return wl; } else return null; } /** * Records any changes in Animation State * @param mState */ public static void recordAnimationStateChange(AnimationState mState){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); EventProperties ep = new EventProperties(); ep.put("AnimationStateChange", mState.name()); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "AnimationStateChange", ep, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", RecordState:, " + mState.name() + ", " + time); } } /** * Records a DM Click */ public static void recordDMClick(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "DMClick", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", DMClick, " + time); } } /** * Records a DM Simple Click */ public static void recordDMSimpleClick(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "DMSimpleClick", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", DMSimpleClick, " + time); } } /** * Records user moving a VL Block */ public static void recordVLBlockClick(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "VLBlockClick", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", VLBlockClick, " + time); } } /** * Records user getting new block from palette */ public static void recordNewVLBlock(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "NewVLBlock", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", NewVLBlock, " + time); } } /** * Records user clicking "test" in the web view. */ public static void recordTestClick(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "TestClick", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", TestClick, " + time); } } /** * Records user showing their animation in the browser */ public static void recordShowInBrowserClick(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "ShowInBrowserClick", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", ShowInBrowserClick, " + time); } } /** * Records user resetting their animation */ public static void recordResetClick(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "ResetAnimationClick", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", ResetAnimationClick, " + time); } } /** * Records users loading images */ public static void recordLoadImageClick(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "LoadImageClick", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", ResetAnimationClick, " + time); } } /** * Records users loading the webcam */ public static void recordWebcamClick(){ if(ANALYTICS_ENABLED){ long time = System.currentTimeMillis(); if(mCanReachAnalytics) Analytics.track(AnalyticUtils.username, "WebcamClick", null, new DateTime(time)); appendToLoggerFile("" + AnalyticUtils.username + ", WebcamClick, " + time); } } public static int getCloseOperation() { if(ANALYTICS_ENABLED){ return JFrame.DO_NOTHING_ON_CLOSE; } else return JFrame.EXIT_ON_CLOSE; } public static boolean isSegmentIOReachable(){ try{ String HOST = "http://www.segment.io"; URL url = new URL(HOST); URLConnection conn = url.openConnection(); conn.setConnectTimeout(3000); conn.setReadTimeout(3000); InputStream in = conn.getInputStream(); in.close(); } catch(Exception e){ e.printStackTrace(); return false; } return true; } }