From: James Procter Date: Thu, 29 Jun 2023 08:55:51 +0000 (+0100) Subject: Merge branch 'task/JAL-4001_Plausible_API' into develop X-Git-Tag: Release_2_11_3_0~13^2~5 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=939ec650efeb1e26a64f4ea8238a5f73ad7a1150;hp=3acfdb3ddd5e3b785fd0880bcebc9e267a717bbe;p=jalview.git Merge branch 'task/JAL-4001_Plausible_API' into develop --- diff --git a/help/help/html/privacy.html b/help/help/html/privacy.html index 9ad61b5..73138f6 100644 --- a/help/help/html/privacy.html +++ b/help/help/html/privacy.html @@ -34,35 +34,35 @@

Usage data is collected from the logs of various web services that the Jalview Desktop contacts through its normal operation. These are described below:

- -

+

Stopping Jalview from calling home
If you run Jalview in 'headless mode' via the command line, then the diff --git a/help/markdown/releases/release-2_11_2_7.md b/help/markdown/releases/release-2_11_2_7.md new file mode 100644 index 0000000..1ab0ebb --- /dev/null +++ b/help/markdown/releases/release-2_11_2_7.md @@ -0,0 +1,11 @@ +--- +version: 2.11.2.7 +date: 2023-06-29 +channel: "release" +--- + +## New Features +- Jalview now reports usage statistics via Plausible.io + +## Issues Resolved +- PDB structures slow to view when Jalview Java console is open diff --git a/help/markdown/whatsnew/whatsnew-2_11_2_7.md b/help/markdown/whatsnew/whatsnew-2_11_2_7.md new file mode 100644 index 0000000..a5e5a79 --- /dev/null +++ b/help/markdown/whatsnew/whatsnew-2_11_2_7.md @@ -0,0 +1,3 @@ +Jalview 2.11.2.7 is a rapid patch patch release. + + diff --git a/j11lib/JGoogleAnalytics_0.3.jar b/j11lib/JGoogleAnalytics_0.3.jar deleted file mode 100644 index 0dbc98c..0000000 Binary files a/j11lib/JGoogleAnalytics_0.3.jar and /dev/null differ diff --git a/j8lib/JGoogleAnalytics_0.3.jar b/j8lib/JGoogleAnalytics_0.3.jar deleted file mode 100644 index 0dbc98c..0000000 Binary files a/j8lib/JGoogleAnalytics_0.3.jar and /dev/null differ diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 7f5746e..924b9cb 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -1452,8 +1452,8 @@ label.choose_tempfac_type = Choose Temperature Factor type label.interpret_tempfac_as = Interpret Temperature Factor as label.add_pae_matrix_file = Add PAE matrix file label.nothing_selected = Nothing selected -prompt.google_analytics_title = Jalview Usage Statistics -prompt.google_analytics = Do you want to help make Jalview better by enabling the collection of usage statistics with Google Analytics?\nYou can enable or disable usage tracking in the preferences. +prompt.analytics_title = Jalview Usage Statistics +prompt.analytics = Do you want to help make Jalview better by enabling the collection of usage statistics with Plausible analytics?\nYou can enable or disable usage tracking in the preferences. label.working_ellipsis = Working ... action.show_groups_on_matrix = Show groups on matrix action.show_groups_on_matrix_tooltip = When enabled, clusters defined on the matrix's associated tree or below the assigned threshold are shown as different colours on the matrix annotation row diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index a4594dc..150a407 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -1434,5 +1434,5 @@ label.tftype_default = Default label.tftype_plddt = pLDDT label.add_pae_matrix_file = Añadir un fichero de matriz PAE label.nothing_selected = Nada seleccionado -prompt.google_analytics_title = Jalview Estadísticas de Uso -prompt.google_analytics = ¿Quiere ayudar a mejorar Jalview habilitando la recopilación de estadísticas de uso con Google Analytics?\nPuede habilitar o deshabilitar el seguimiento de uso en las preferencias. +prompt.analytics_title = Jalview Estadísticas de Uso +prompt.analytics = ¿Quiere ayudar a mejorar Jalview habilitando la recopilación de estadísticas de uso con análisis Plausible?\nPuede habilitar o deshabilitar el seguimiento de uso en las preferencias. diff --git a/src/jalview/analytics/GoogleAnalytics4.java b/src/jalview/analytics/Plausible.java similarity index 58% rename from src/jalview/analytics/GoogleAnalytics4.java rename to src/jalview/analytics/Plausible.java index ba8a920..74db1f7 100644 --- a/src/jalview/analytics/GoogleAnalytics4.java +++ b/src/jalview/analytics/Plausible.java @@ -1,8 +1,11 @@ package jalview.analytics; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.lang.invoke.MethodHandles; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; @@ -16,76 +19,86 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Random; -import java.util.UUID; import jalview.bin.Cache; import jalview.bin.Console; import jalview.util.ChannelProperties; +import jalview.util.HttpUtils; -public class GoogleAnalytics4 +public class Plausible { - private static final String JALVIEW_ID = "Jalview Desktop"; + private static final String USER_AGENT = HttpUtils.getUserAgent( + MethodHandles.lookup().lookupClass().getCanonicalName()); - private static final String SESSION_ID = new Random().toString(); + private static final String JALVIEW_ID = "Jalview Desktop"; - private static final String MEASUREMENT_ID = "G-6TMPHMXEQ0"; + private static final String DOMAIN = "jalview.org"; - private static final String API_SECRET = "Qb9NSbqkRDqizG6j2BBJ2g"; + private static final String CONFIG_API_BASE_URL = "https://www.jalview.org/services/config/analytics/url"; - // This will generate a different CLIENT_ID each time the application is - // launched. Do we want to store it in .jalview_properties? - private static final String CLIENT_ID = UUID.randomUUID().toString(); + private static final String DEFAULT_API_BASE_URL = "https://plausible.io/api/event"; - private static final String BASE_URL = "https://www.google-analytics.com/mp/collect"; + private static final String API_BASE_URL; - private static final String DESKTOP_EVENT = "desktop_event"; + public static final String APPLICATION_BASE_URL = "desktop://localhost"; private List> queryStringValues; private List> jsonObject; - private List events; - private List> cookieValues; private static boolean ENABLED = false; - private static GoogleAnalytics4 instance = null; + private static boolean DEBUG = true; + + private static Plausible instance = null; - private static final Map defaultParams; + private static final Map defaultProps; static { - defaultParams = new HashMap<>(); - defaultParams.put("app_name", + defaultProps = new HashMap<>(); + defaultProps.put("app_name", ChannelProperties.getProperty("app_name") + " Desktop"); - defaultParams.put("version", Cache.getProperty("VERSION")); - defaultParams.put("build_date", + defaultProps.put("version", Cache.getProperty("VERSION")); + defaultProps.put("build_date", Cache.getDefault("BUILD_DATE", "unknown")); - defaultParams.put("java_version", System.getProperty("java.version")); + defaultProps.put("java_version", System.getProperty("java.version")); String val = System.getProperty("sys.install4jVersion"); if (val != null) { - defaultParams.put("install4j_version", val); + defaultProps.put("install4j_version", val); } val = System.getProperty("installer_template_version"); if (val != null) { - defaultParams.put("install4j_template_version", val); + defaultProps.put("install4j_template_version", val); } val = System.getProperty("launcher_version"); if (val != null) { - defaultParams.put("launcher_version", val); + defaultProps.put("launcher_version", val); } - defaultParams.put("java_arch", + defaultProps.put("java_arch", System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version")); + defaultProps.put("os", System.getProperty("os.name")); + defaultProps.put("os_version", System.getProperty("os.version")); + defaultProps.put("os_arch", System.getProperty("os.arch")); + String installation = Cache.applicationProperties + .getProperty("INSTALLATION"); + if (installation != null) + { + defaultProps.put("installation", installation); + } + + // ascertain the API_BASE_URL + API_BASE_URL = getAPIBaseURL(); } - private GoogleAnalytics4() + private Plausible() { this.resetLists(); } @@ -95,72 +108,79 @@ public class GoogleAnalytics4 ENABLED = b; } - public void sendAnalytics(String eventName, String... paramsStrings) + public void sendEvent(String eventName, String urlString, + String... propsStrings) { - sendAnalytics(eventName, false, paramsStrings); + sendEvent(eventName, urlString, false, propsStrings); } /** * The simplest way to send an analytic event. * * @param eventName - * The event name. To emulate a webpage view use "page_view" and set - * a "page_location" parameter. See - * https://developers.google.com/analytics/devguides/collection/ga4/events?client_type=gtag - * @param sendDefaultParams - * Flag whether to add the default params about the application. - * @param paramsStrings + * The event name. To emulate a webpage view use "pageview" and set a + * "url" key/value. See https://plausible.io/docs/events-api + * @param sendDefaultProps + * Flag whether to add the default props about the application. + * @param propsStrings * Optional multiple Strings in key, value pairs (there should be an - * even number of paramsStrings) to be set as parameters of the - * event. To emulate a webpage view use "page_location" as the URL in - * a "page_view" event. + * even number of propsStrings) to be set as property of the event. + * To emulate a webpage view set "url" as the URL in a "pageview" + * event. */ - public void sendAnalytics(String eventName, boolean sendDefaultParams, - String... paramsStrings) + public void sendEvent(String eventName, String urlString, + boolean sendDefaultProps, String... propsStrings) { // clear out old lists this.resetLists(); if (!ENABLED) { - Console.debug("GoogleAnalytics4 not enabled."); + Console.debug("Plausible not enabled."); return; } - Map params = new HashMap<>(); - params.put("event_category", DESKTOP_EVENT); - params.put("event_label", eventName); + Map props = new HashMap<>(); // add these to all events from this application instance - if (sendDefaultParams) + if (sendDefaultProps) { - params.putAll(defaultParams); + props.putAll(defaultProps); } - // add (and overwrite with) the passed in params - if (paramsStrings != null && paramsStrings.length > 0) + // add (and overwrite with) the passed in props + if (propsStrings != null && propsStrings.length > 0) { - if (paramsStrings.length % 2 != 0) + if (propsStrings.length % 2 != 0) { Console.warn( - "Cannot addEvent with odd number of paramsStrings. Ignoring the last one."); + "Cannot addEvent with odd number of propsStrings. Ignoring the last one."); } - for (int i = 0; i < paramsStrings.length - 1; i += 2) + for (int i = 0; i < propsStrings.length - 1; i += 2) { - String key = paramsStrings[i]; - String value = paramsStrings[i + 1]; - params.put(key, value); + String key = propsStrings[i]; + String value = propsStrings[i + 1]; + props.put(key, value); } } - addEvent(eventName, params); - addQueryStringValue("measurement_id", MEASUREMENT_ID); - addQueryStringValue("api_secret", API_SECRET); - addJsonValue("client_id", CLIENT_ID); - addJsonValues("events", Event.toObjectList(events)); + addJsonValue("domain", DOMAIN); + addJsonValue("name", eventName); + StringBuilder eventUrlSb = new StringBuilder(APPLICATION_BASE_URL); + if (!APPLICATION_BASE_URL.endsWith("/") && !urlString.startsWith("/")) + { + eventUrlSb.append("/"); + } + eventUrlSb.append(urlString); + addJsonValue("url", eventUrlSb.toString()); + addJsonObject("props", props); StringBuilder urlSb = new StringBuilder(); - urlSb.append(BASE_URL); - urlSb.append('?'); - urlSb.append(buildQueryString()); + urlSb.append(API_BASE_URL); + String qs = buildQueryString(); + if (qs != null && qs.length() > 0) + { + urlSb.append('?'); + urlSb.append(qs); + } try { URL url = new URL(urlSb.toString()); @@ -171,15 +191,21 @@ public class GoogleAnalytics4 String jsonString = buildJson(); - Console.debug("GA4: HTTP Request is: '" + urlSb.toString() + "'"); - Console.debug("GA4: POSTed JSON is:\n" + jsonString); + Console.debug( + "Plausible: HTTP Request is: '" + urlSb.toString() + "'"); + if (DEBUG) + { + Console.debug("Plausible: User-Agent is: '" + USER_AGENT + "'"); + } + Console.debug("Plausible: POSTed JSON is:\n" + jsonString); byte[] jsonBytes = jsonString.getBytes(StandardCharsets.UTF_8); int jsonLength = jsonBytes.length; httpURLConnection.setFixedLengthStreamingMode(jsonLength); httpURLConnection.setRequestProperty("Content-Type", - "application/json; charset=UTF-8"); + "application/json"); + httpURLConnection.setRequestProperty("User-Agent", USER_AGENT); httpURLConnection.connect(); try (OutputStream os = httpURLConnection.getOutputStream()) { @@ -187,50 +213,63 @@ public class GoogleAnalytics4 } int responseCode = httpURLConnection.getResponseCode(); String responseMessage = httpURLConnection.getResponseMessage(); + if (responseCode < 200 || responseCode > 299) { - Console.warn("GoogleAnalytics4 connection failed: '" + responseCode - + " " + responseMessage + "'"); + Console.warn("Plausible connection failed: '" + responseCode + " " + + responseMessage + "'"); } else { - Console.debug("GoogleAnalytics4 connection succeeded: '" - + responseCode + " " + responseMessage + "'"); + Console.debug("Plausible connection succeeded: '" + responseCode + + " " + responseMessage + "'"); + } + + if (DEBUG) + { + BufferedReader br = new BufferedReader(new InputStreamReader( + (httpURLConnection.getInputStream()))); + StringBuilder sb = new StringBuilder(); + String response; + while ((response = br.readLine()) != null) + { + sb.append(response); + } + String body = sb.toString(); + Console.debug("Plausible response content:\n" + body); } } catch (MalformedURLException e) { Console.debug( - "Somehow the GoogleAnalytics4 BASE_URL and queryString is malformed.", + "Somehow the Plausible BASE_URL and queryString is malformed: '" + + urlSb.toString() + "'", e); return; } catch (IOException e) { - Console.debug("Connection to GoogleAnalytics4 BASE_URL '" + BASE_URL + Console.debug("Connection to Plausible BASE_URL '" + API_BASE_URL + "' failed.", e); } catch (ClassCastException e) { Console.debug( - "Couldn't cast URLConnection to HttpURLConnection in GoogleAnalytics4.", + "Couldn't cast URLConnection to HttpURLConnection in Plausible.", e); } } - public void addEvent(String name, Map params) + private void addJsonObject(String key, Map map) { - Event event = new Event(name); - if (params != null && params.size() > 0) + List> list = new ArrayList<>(); + for (String k : map.keySet()) { - for (String key : params.keySet()) - { - String value = params.get(key); - event.addParam(key, value); - } + list.add(stringEntry(k, map.get(k))); } - events.add(event); + addJsonObject(key, list); + } private void addJsonObject(String key, - List> object) + List> object) { jsonObject.add(objectEntry(key, object)); } @@ -268,16 +307,15 @@ public class GoogleAnalytics4 private void resetLists() { jsonObject = new ArrayList<>(); - events = new ArrayList(); queryStringValues = new ArrayList<>(); cookieValues = new ArrayList<>(); } - public static GoogleAnalytics4 getInstance() + public static Plausible getInstance() { if (instance == null) { - instance = new GoogleAnalytics4(); + instance = new Plausible(); } return instance; } @@ -480,52 +518,56 @@ public class GoogleAnalytics4 { return new AbstractMap.SimpleEntry(s, v); } -} - -class Event -{ - private String name; - - private List> params; - @SafeVarargs - public Event(String name, Map.Entry... paramEntries) + private static String getAPIBaseURL() { - this.name = name; - this.params = new ArrayList>(); - for (Map.Entry paramEntry : paramEntries) + try { - if (paramEntry == null) + URL url = new URL(CONFIG_API_BASE_URL); + URLConnection urlConnection = url.openConnection(); + HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection; + httpURLConnection.setRequestMethod("GET"); + httpURLConnection.setRequestProperty("User-Agent", USER_AGENT); + httpURLConnection.setConnectTimeout(5000); + httpURLConnection.setReadTimeout(3000); + httpURLConnection.connect(); + int responseCode = httpURLConnection.getResponseCode(); + String responseMessage = httpURLConnection.getResponseMessage(); + + if (responseCode < 200 || responseCode > 299) { - continue; + Console.warn("Config URL connection to '" + CONFIG_API_BASE_URL + + "' failed: '" + responseCode + " " + responseMessage + + "'"); } - params.add(paramEntry); - } - } - public void addParam(String param, String value) - { - params.add(GoogleAnalytics4.stringEntry(param, value)); - } + BufferedReader br = new BufferedReader( + new InputStreamReader((httpURLConnection.getInputStream()))); + StringBuilder sb = new StringBuilder(); + String response; + while ((response = br.readLine()) != null) + { + sb.append(response); + } + if (sb.length() > 7 && sb.substring(0, 5).equals("https")) + { + return sb.toString(); + } - protected List> toObject() - { - List> object = new ArrayList<>(); - object.add(GoogleAnalytics4.objectEntry("name", (Object) name)); - if (params.size() > 0) + } catch (MalformedURLException e) { - object.add(GoogleAnalytics4.objectEntry("params", (Object) params)); - } - return object; - } - - protected static List toObjectList(List events) - { - List eventObjectList = new ArrayList<>(); - for (Event event : events) + Console.debug("Somehow the config URL is malformed: '" + + CONFIG_API_BASE_URL + "'", e); + } catch (IOException e) { - eventObjectList.add((Object) event.toObject()); + Console.debug("Connection to Plausible BASE_URL '" + API_BASE_URL + + "' failed.", e); + } catch (ClassCastException e) + { + Console.debug( + "Couldn't cast URLConnection to HttpURLConnection in Plausible.", + e); } - return eventObjectList; + return DEFAULT_API_BASE_URL; } } diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index fc9ddda..5741908 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -43,6 +43,7 @@ import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; @@ -52,7 +53,7 @@ import java.util.TreeSet; import javax.swing.LookAndFeel; import javax.swing.UIManager; -import jalview.analytics.GoogleAnalytics4; +import jalview.analytics.Plausible; import jalview.datamodel.PDBEntry; import jalview.gui.Preferences; import jalview.gui.UserDefinedColours; @@ -128,7 +129,7 @@ import jalview.ws.sifts.SiftsSettings; * service *
  • QUESTIONNAIRE last questionnaire:responder id string from questionnaire * service
  • - *
  • USAGESTATS (false - user prompted) Enable google analytics tracker for + *
  • USAGESTATS (false - user prompted) Enable analytics tracker for * collecting usage statistics
  • *
  • SHOW_OVERVIEW boolean for overview window display
  • *
  • ANTI_ALIAS boolean for smooth fonts
  • @@ -954,146 +955,41 @@ public class Cache } /** - * GA tracker object - actually JGoogleAnalyticsTracker null if tracking not - * enabled. + * Initialise the tracker if it is not done already. */ - protected static Object tracker = null; - - protected static Class trackerfocus = null; - - protected static Class jgoogleanalyticstracker = null; - - private static boolean useGA4 = true; - - /** - * Initialise the google tracker if it is not done already. - */ - public static void initGoogleTracker() + public static void initAnalytics() { - if (useGA4) - { - GoogleAnalytics4.setEnabled(true); + Plausible.setEnabled(true); - String appName = ChannelProperties.getProperty("app_name") - + " Desktop"; - String version = Cache.getProperty("VERSION") + "_" - + Cache.getDefault("BUILD_DATE", "unknown"); - String path; - /* we don't want to encode ':' as "%3A" for backward compatibility with the UA setup - try - { - path = "/" + String.join("/", URLEncoder.encode(appName, "UTF-8"), - URLEncoder.encode(version, "UTF-8"), - URLEncoder.encode(APPLICATION_STARTED, "UTF-8")); - } catch (UnsupportedEncodingException e) - { - */ - path = ("/" + String.join("/", appName, version, APPLICATION_STARTED)) - .replace(' ', '+'); - /* - } - */ - GoogleAnalytics4 ga4 = GoogleAnalytics4.getInstance(); - - // This will add a page_view similar to the old UA analytics. - // We probably want to get rid of this once the application_launch event - // is being processed properly. - ga4.sendAnalytics("page_view", "page_location", path, "page_title", - APPLICATION_STARTED); - - // This will send a new "application_launch" event with parameters - // including the old-style "path", the channel name and version - ga4.sendAnalytics("application_launch", true, "page_location", path); - } - else + String appName = ChannelProperties.getProperty("app_name") + " Desktop"; + String version = Cache.getProperty("VERSION") + "_" + + Cache.getDefault("BUILD_DATE", "unknown"); + String path; + /* we don't want to encode ':' as "%3A" for backward compatibility with the UA setup + try { - if (tracker == null) - { - if (jgoogleanalyticstracker == null) - { - // try to get the tracker class - try - { - jgoogleanalyticstracker = Cache.class.getClassLoader() - .loadClass( - "com.boxysystems.jgoogleanalytics.JGoogleAnalyticsTracker"); - trackerfocus = Cache.class.getClassLoader().loadClass( - "com.boxysystems.jgoogleanalytics.FocusPoint"); - } catch (Exception e) - { - Console.debug( - "com.boxysystems.jgoogleanalytics package is not present - tracking not enabled."); - tracker = null; - jgoogleanalyticstracker = null; - trackerfocus = null; - return; - } - } - // now initialise tracker - Exception re = null, ex = null; - Error err = null; - String vrs = "No Version Accessible"; - try - { - // Google analytics tracking code for Library Finder - tracker = jgoogleanalyticstracker - .getConstructor(new Class[] - { String.class, String.class, String.class }) - .newInstance(new Object[] - { ChannelProperties.getProperty("app_name") + " Desktop", - (vrs = Cache.getProperty("VERSION") + "_" - + Cache.getDefault("BUILD_DATE", "unknown")), - "UA-9060947-1" }); - jgoogleanalyticstracker - .getMethod("trackAsynchronously", new Class[] - { trackerfocus }) - .invoke(tracker, new Object[] - { trackerfocus - .getConstructor(new Class[] - { String.class }) - .newInstance(new Object[] - { APPLICATION_STARTED }) }); - } catch (RuntimeException e) - { - re = e; - } catch (Exception e) - { - ex = e; - } catch (Error e) - { - err = e; - } - if (re != null || ex != null || err != null) - { - if (re != null) - { - Console.debug("Caught runtime exception in googletracker init:", - re); - } - if (ex != null) - { - Console.warn( - "Failed to initialise GoogleTracker for Jalview Desktop with version " - + vrs, - ex); - } - if (err != null) - { - Console.error( - "Whilst initing GoogleTracker for Jalview Desktop version " - + vrs, - err); - } - } - else - { - Console.debug("Successfully initialised tracker."); - } - } + path = "/" + String.join("/", URLEncoder.encode(appName, "UTF-8"), + URLEncoder.encode(version, "UTF-8"), + URLEncoder.encode(APPLICATION_STARTED, "UTF-8")); + } catch (UnsupportedEncodingException e) + { + */ + List pathParts = new ArrayList<>(); + pathParts.add(appName); + pathParts.add(version); + pathParts.add(APPLICATION_STARTED); + path = ("/" + String.join("/", pathParts)).replace(' ', '+'); + /* } + */ + Plausible plausible = Plausible.getInstance(); + + // This will send a new "application_launch" event with parameters + // including the old-style "path", the channel name and version + plausible.sendEvent("application_launch", path, true); } - private static final String APPLICATION_STARTED = "Application Started."; + private static final String APPLICATION_STARTED = "Application Started"; /** * get the user's default colour if available diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index 3a733f3..57f2575 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -633,8 +633,7 @@ public class Jalview { headless = true; } - System.setProperty("http.agent", - "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown")); + System.setProperty("http.agent", HttpUtils.getUserAgent()); try { @@ -810,6 +809,7 @@ public class Jalview // Run Commands from cli cmds = new Commands(argparser, headlessArg); boolean commandsSuccess = cmds.argsWereParsed(); + if (commandsSuccess) { if (headlessArg) @@ -1573,7 +1573,7 @@ public class Jalview + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n" + "-noquestionnaire\tTurn off questionnaire check.\n" + "-nonews\tTurn off check for Jalview news.\n" - + "-nousagestats\tTurn off google analytics tracking for this session.\n" + + "-nousagestats\tTurn off analytics tracking for this session.\n" + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n" // + // "-setprop PROPERTY=VALUE\tSet the given Jalview property, @@ -1596,16 +1596,15 @@ public class Jalview */ PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop, "USAGESTATS", - MessageManager.getString("prompt.google_analytics_title"), - MessageManager.getString("prompt.google_analytics"), + MessageManager.getString("prompt.plausible_analytics_title"), + MessageManager.getString("prompt.plausible_analytics"), new Runnable() { @Override public void run() { - Console.debug( - "Initialising googletracker for usage stats."); - Cache.initGoogleTracker(); + Console.debug("Initialising analytics for usage stats."); + Cache.initAnalytics(); Console.debug("Tracking enabled."); } }, new Runnable() @@ -1613,7 +1612,7 @@ public class Jalview @Override public void run() { - Console.debug("Not enabling Google Tracking."); + Console.debug("Not enabling analytics."); } }, null, true); desktop.addDialogThread(prompter); diff --git a/src/jalview/util/HttpUtils.java b/src/jalview/util/HttpUtils.java index 0454cab..8379777 100644 --- a/src/jalview/util/HttpUtils.java +++ b/src/jalview/util/HttpUtils.java @@ -25,10 +25,11 @@ import java.io.InputStream; import java.net.HttpURLConnection; import java.net.ProtocolException; import java.net.URL; -import java.util.List; import javax.ws.rs.HttpMethod; +import jalview.bin.Cache; + public class HttpUtils { @@ -101,4 +102,46 @@ public class HttpUtils return connection.getResponseCode() == 200; } + public static String getUserAgent() + { + return getUserAgent(null); + } + + public static String getUserAgent(String className) + { + StringBuilder sb = new StringBuilder(); + sb.append("Jalview"); + sb.append('/'); + sb.append(Cache.getDefault("VERSION", "Unknown")); + sb.append(" ("); + sb.append(System.getProperty("os.name")); + sb.append("; "); + sb.append(System.getProperty("os.arch")); + sb.append(' '); + sb.append(System.getProperty("os.name")); + sb.append(' '); + sb.append(System.getProperty("os.version")); + sb.append("; "); + sb.append("java/"); + sb.append(System.getProperty("java.version")); + sb.append("; "); + sb.append("jalview/"); + sb.append(ChannelProperties.getProperty("channel")); + if (className != null) + { + sb.append("; "); + sb.append(className); + } + String installation = Cache.applicationProperties + .getProperty("INSTALLATION"); + if (installation != null) + { + sb.append("; "); + sb.append(installation); + } + sb.append(')'); + sb.append(" help@jalview.org"); + return sb.toString(); + } + }