R/mod_client_stats.R

Defines functions mod_client_stats_server mod_client_stats_ui

#' client_stats UI Function
#'
#' @description A shiny Module.
#'
#' @param id,input,output,session Internal parameters for {shiny}.
#'
#' @noRd
#'
#' @importFrom shiny NS tagList
mod_client_stats_ui <- function(id) {
  ns <- NS(id)
  tagList(fluidRow(
    column(
      theme = bs_theme(version = 4, bootswatch = "minty"),
      width = 12,
      HTML("<h4>Market share of Clients by users Device Display Names (excluding Element)</h4>"),
      shinycssloaders::withSpinner(plotOutput(ns(
        "clientMarketShare_no_element"
      ), height = "900px"))
    )
  ),fluidRow(
    column(
      theme = bs_theme(version = 4, bootswatch = "minty"),
      width = 12,
      HTML("<h4>Market share of Clients by users Device Display Names</h4>"),
      shinycssloaders::withSpinner(plotOutput(ns(
        "clientMarketShare"
      ), height = "900px"))
    )
  ),
  HTML("<br/>"))
}

#' client_stats Server Functions
#'
#' @import ggplot2
#' @import plotly
#' @import stringr
#' @import readr
#' @import treemapify
#'
#' @noRd
mod_client_stats_server <- function(id) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns
    
    output$clientMarketShare_no_element <- renderPlot({
      df = read.csv("/opt/devices_snapshots/datadump.csv", header = FALSE)
      p <- df |>
        mutate(
          Client = case_when(
            str_detect(V1, '^.*.element.io') ~ 'Element Web',
            str_detect(V1, '^chat.mozilla.org') ~ 'Element Web',
            str_detect(V1, '^element.') ~ 'Element Web',
            str_detect(V1, '^Riot Desktop') ~ 'Riot Desktop',
            str_detect(V1, '^Element Desktop') ~ 'Element Desktop',
            str_detect(V1, '^Fluffychat') ~ 'Fluffychat',
            str_detect(V1, '^FluffyChat') ~ 'Fluffychat',
            str_detect(V1, '^Fluffy') ~ 'Fluffychat',
            str_detect(V1, '^RiotX Android') ~ 'RiotX Android',
            str_detect(V1, '^Element Android') ~ 'Element Android',
            str_detect(V1, '^Element .*Android') ~ 'Element Android',
            str_detect(V1, '^Element') ~ 'Element',
            str_detect(V1, '^SchildiChat Android') ~ 'SchildiChat Android',
            str_detect(V1, '^SchildiChat Desktop') ~ 'SchildiChat Desktop',
            str_detect(V1, '^gomuks') ~ 'gomuks',
            str_detect(V1, '^Syphon') ~ 'Syphon',
            str_detect(V1, '^Hydrogen') ~ 'Hydrogen',
            str_detect(V1, '^Mirage') ~ 'Mirage',
            str_detect(V1, '^riot.im/') ~ 'Riot.im Web',
            str_detect(V1, '^https://riot.im/') ~ 'Riot.im Web',
            str_detect(V1, '^Weechat') ~ 'Weechat',
            str_detect(V1, '^wechat') ~ 'wechat',
            str_detect(V1, '^Nheko') ~ 'Nheko',
            str_detect(V1, '^nheko') ~ 'Nheko',
            str_detect(V1, '^Beeper login check') ~ 'Beeper login check',
            str_detect(V1, '^Beeper Android') ~ 'Beeper Android',
            str_detect(V1, '^Beeper Desktop') ~ 'Beeper Desktop',
            str_detect(V1, '^talk.chatcloud.net') ~ 'Element Web',
            str_detect(V1, '^Cinny Web') ~ 'Cinny Web',
            str_detect(V1, '^chat.minds.com') ~ 'Minds.com',
            str_detect(V1, '^webchat.kde.org') ~ 'Element Web',
            str_detect(V1, '^chat.fosdem.org') ~ 'Element Web',
            str_detect(V1, '^purple-matrix') ~ 'purple-matrix',
            str_detect(V1, '^pantalaimon') ~ 'pantalaimon',
            str_detect(V1, '^chat.tchncs.de') ~ 'Element Web',
            str_detect(V1, '^https://chat.mozilla.org/') ~ 'Element Web',
            str_detect(V1, '^riot.grin.hu') ~ 'Element Web',
            str_detect(V1, '^Sailtrix') ~ 'Sailtrix',
            str_detect(V1, '^Fractal Next') ~ 'Fractal Next',
            str_detect(V1, '^Fractal$') ~ 'Fractal',
            str_detect(V1, '^Pattle Android') ~ 'Pattle Android',
            str_detect(V1, '^www.riot.im/') ~ 'Riot.im Web',
            str_detect(V1, '^WhatsApp Bridge') ~ 'WhatsApp Bridge',
            str_detect(V1, '^Telegram Bridge') ~ 'Telegram Bridge',
            str_detect(V1, '^Chatty') ~ 'Chatty',
            str_detect(V1, '^app.schildi.chat') ~ 'SchildiChat Web',
            str_detect(V1, '^chat.') ~ 'Element Web',
            str_detect(V1, '^nerdsin.space') ~ 'Element Web',
            str_detect(V1, '^matrix.radicle.community') ~ 'Element Web',
            str_detect(V1, '^matrix.radicle.community') ~ 'Element Web',
            str_detect(V1, '^matrix-commander') ~ 'matrix-commander',
            str_detect(V1, '^Riot Web') ~ 'Riot Web',
            str_detect(V1, '^riot.ruhr-uni-bochum.de') ~ 'Element Web',
            str_detect(V1, '^https://webchat.kde.org/') ~ 'Element Web',
            str_detect(V1, '^https://riot.ruhr-uni-bochum.de/') ~ 'Element Web',
            str_detect(V1, '^Facebook Messenger Bridge') ~ 'Facebook Messenger Bridge',
            str_detect(V1, '^Famedly Web') ~ 'Famedly Web',
            str_detect(V1, '^Discord Puppet Bridge') ~ 'Discord Puppet Bridge',
            str_detect(V1, '^iMessage Bridge') ~ 'iMessage Bridge',
            str_detect(V1, '^Thunderbird') ~ 'Thunderbird',
            str_detect(V1, '^Signal Bridge') ~ 'Signal Bridge',
            str_detect(V1, '^SchildiChat .*Android') ~ 'SchildiChat Android',
            str_detect(V1, '^Instagram Bridge') ~ 'Instagram Bridge',
            str_detect(V1, '^Slack Puppet Bridge') ~ 'Slack Puppet Bridge',
            str_detect(V1, '^Famedly android') ~ 'Famedly Android',
            str_detect(V1, '^Matrix Recorder') ~ 'Matrix Recorder',
            str_detect(V1, '^Hangouts Bridge') ~ 'Hangouts Bridge',
            str_detect(V1, '^LinkedIn Messages Bridge') ~ 'LinkedIn Messages Bridge',
            str_detect(V1, '^SchildiChat .*(Linux)') ~ 'SchildiChat Desktop',
            str_detect(V1, '^Pattle iOS') ~ 'Pattle iOS',
            str_detect(V1, '^RiotX') ~ 'RiotX',
            str_detect(V1, '^Android Messages Bridge') ~ 'Android Messages Bridge',
            str_detect(V1, '^Famedly ios') ~ 'Famedly iOS',
            str_detect(V1, '^Synapse Admin') ~ 'Synapse Admin',
            str_detect(V1, '^WeeMatrix') ~ 'WeeMatrix',
            str_detect(V1, '^Daydream') ~ 'Daydream',
            str_detect(V1, '^SchildiChat') ~ 'SchildiChat',
            str_detect(V1, '^EachChat Android') ~ 'EachChat Android',
            str_detect(V1, '^ponies.im/_matrix/client') ~ 'ponies.im',
            str_detect(V1, '^riot.') ~ 'Element Web',
            str_detect(V1, '^https://riot.') ~ 'Element Web',
            str_detect(V1, 'Element Web') ~ 'Element Web',
            str_detect(V1, '^Mobile$') ~ 'Element iOS (presumably)',
            str_detect(V1, '^Radical') ~ 'Radical',
            str_detect(V1, '^Quaternion') ~ 'Quaternion',
            str_detect(V1, '^Blast Android') ~ 'Blast Android',
            str_detect(V1, '^matrix-sdk') ~ 'matrix-sdk',
            str_detect(V1, '^Maunium') ~ 'Maunium',
            str_detect(V1, '^Nextcloud') ~ 'Nextcloud',
            str_detect(V1, '^Spectral') ~ 'Spectral',
            str_detect(V1, '^NeoChat') ~ 'NeoChat',
            str_detect(V1, '^SimpleMatrix') ~ 'SimpleMatrix',
            str_detect(V1, '^matrix-tag-manager') ~ 'matrix-tag-manager',
            str_detect(V1, '^Blast Desktop') ~ 'Blast Desktop',
            str_detect(V1, '^IndieChat android') ~ 'IndieChat android',
            str_detect(V1, '^Revolution Desktop') ~ 'Revolution Desktop',
            str_detect(V1, '^Riot.im') ~ 'Element Web',
            str_detect(V1, '^Beeper') ~ 'Beeper',
            str_detect(V1, '^Famedly windows') ~ 'Famedly Windows',
            str_detect(V1, '^Riot on Android') ~ 'Riot Android',
            str_detect(V1, '^Prometheus') ~ 'Prometheus',
            str_detect(V1, '^prometheus') ~ 'Prometheus',
            str_detect(V1, '^mautrix-manager') ~ 'mautrix-manager',
            str_detect(V1, '^mauPhone') ~ 'mauPhone',
            str_detect(V1, '^_nheko_') ~ 'Nheko',
            str_detect(V1, '^mirage') ~ 'Mirage',
            str_detect(V1, '^Schildi Android') ~ 'SchildiChat Android',
            str_detect(V1, '^Schildi') ~ 'SchildiChat',
            str_detect(V1, '^Blast Desktop') ~ 'Blast Desktop',
            TRUE ~ 'Other'
          )
        ) |>
        filter(Client != 'Other') |>
        group_by(Client) |>
        summarize(total = sum(V2)) |>
        filter(Client != 'Element') |>
        filter(Client != 'Element Android') |>
        filter(Client != 'Element Web') |>
        filter(Client != 'Element Desktop') |>
        filter(Client != 'Element iOS (presumably)') |>
        filter(Client != 'Riot Desktop') |>
        filter(Client != 'Riot.im Web') |>
        ggplot2::ggplot(ggplot2::aes(
          area = total,
          fill = Client,
          label = Client
        )) +
        geom_treemap() +
        geom_treemap_text(
          fontface = "italic",
          colour = "white",
          place = "centre",
          grow = TRUE
        )
      p
    })
    
    output$clientMarketShare <- renderPlot({
      df = read.csv("/opt/devices_snapshots/datadump.csv", header = FALSE)
      p <- df |>
        mutate(
          Client = case_when(
            str_detect(V1, '^.*.element.io') ~ 'Element Web',
            str_detect(V1, '^chat.mozilla.org') ~ 'Element Web',
            str_detect(V1, '^element.') ~ 'Element Web',
            str_detect(V1, '^Riot Desktop') ~ 'Riot Desktop',
            str_detect(V1, '^Element Desktop') ~ 'Element Desktop',
            str_detect(V1, '^Fluffychat') ~ 'Fluffychat',
            str_detect(V1, '^FluffyChat') ~ 'Fluffychat',
            str_detect(V1, '^Fluffy') ~ 'Fluffychat',
            str_detect(V1, '^RiotX Android') ~ 'RiotX Android',
            str_detect(V1, '^Element Android') ~ 'Element Android',
            str_detect(V1, '^Element .*Android') ~ 'Element Android',
            str_detect(V1, '^Element') ~ 'Element',
            str_detect(V1, '^SchildiChat Android') ~ 'SchildiChat Android',
            str_detect(V1, '^SchildiChat Desktop') ~ 'SchildiChat Desktop',
            str_detect(V1, '^gomuks') ~ 'gomuks',
            str_detect(V1, '^Syphon') ~ 'Syphon',
            str_detect(V1, '^Hydrogen') ~ 'Hydrogen',
            str_detect(V1, '^Mirage') ~ 'Mirage',
            str_detect(V1, '^riot.im/') ~ 'Riot.im Web',
            str_detect(V1, '^https://riot.im/') ~ 'Riot.im Web',
            str_detect(V1, '^Weechat') ~ 'Weechat',
            str_detect(V1, '^wechat') ~ 'wechat',
            str_detect(V1, '^Nheko') ~ 'Nheko',
            str_detect(V1, '^nheko') ~ 'Nheko',
            str_detect(V1, '^Beeper login check') ~ 'Beeper login check',
            str_detect(V1, '^Beeper Android') ~ 'Beeper Android',
            str_detect(V1, '^Beeper Desktop') ~ 'Beeper Desktop',
            str_detect(V1, '^talk.chatcloud.net') ~ 'Element Web',
            str_detect(V1, '^Cinny Web') ~ 'Cinny Web',
            str_detect(V1, '^chat.minds.com') ~ 'Minds.com',
            str_detect(V1, '^webchat.kde.org') ~ 'Element Web',
            str_detect(V1, '^chat.fosdem.org') ~ 'Element Web',
            str_detect(V1, '^purple-matrix') ~ 'purple-matrix',
            str_detect(V1, '^pantalaimon') ~ 'pantalaimon',
            str_detect(V1, '^chat.tchncs.de') ~ 'Element Web',
            str_detect(V1, '^https://chat.mozilla.org/') ~ 'Element Web',
            str_detect(V1, '^riot.grin.hu') ~ 'Element Web',
            str_detect(V1, '^Sailtrix') ~ 'Sailtrix',
            str_detect(V1, '^Fractal Next') ~ 'Fractal Next',
            str_detect(V1, '^Fractal$') ~ 'Fractal',
            str_detect(V1, '^Pattle Android') ~ 'Pattle Android',
            str_detect(V1, '^www.riot.im/') ~ 'Riot.im Web',
            str_detect(V1, '^WhatsApp Bridge') ~ 'WhatsApp Bridge',
            str_detect(V1, '^Telegram Bridge') ~ 'Telegram Bridge',
            str_detect(V1, '^Chatty') ~ 'Chatty',
            str_detect(V1, '^app.schildi.chat') ~ 'SchildiChat Web',
            str_detect(V1, '^chat.') ~ 'Element Web',
            str_detect(V1, '^nerdsin.space') ~ 'Element Web',
            str_detect(V1, '^matrix.radicle.community') ~ 'Element Web',
            str_detect(V1, '^matrix.radicle.community') ~ 'Element Web',
            str_detect(V1, '^matrix-commander') ~ 'matrix-commander',
            str_detect(V1, '^Riot Web') ~ 'Riot Web',
            str_detect(V1, '^riot.ruhr-uni-bochum.de') ~ 'Element Web',
            str_detect(V1, '^https://webchat.kde.org/') ~ 'Element Web',
            str_detect(V1, '^https://riot.ruhr-uni-bochum.de/') ~ 'Element Web',
            str_detect(V1, '^Facebook Messenger Bridge') ~ 'Facebook Messenger Bridge',
            str_detect(V1, '^Famedly Web') ~ 'Famedly Web',
            str_detect(V1, '^Discord Puppet Bridge') ~ 'Discord Puppet Bridge',
            str_detect(V1, '^iMessage Bridge') ~ 'iMessage Bridge',
            str_detect(V1, '^Thunderbird') ~ 'Thunderbird',
            str_detect(V1, '^Signal Bridge') ~ 'Signal Bridge',
            str_detect(V1, '^SchildiChat .*Android') ~ 'SchildiChat Android',
            str_detect(V1, '^Instagram Bridge') ~ 'Instagram Bridge',
            str_detect(V1, '^Slack Puppet Bridge') ~ 'Slack Puppet Bridge',
            str_detect(V1, '^Famedly android') ~ 'Famedly Android',
            str_detect(V1, '^Matrix Recorder') ~ 'Matrix Recorder',
            str_detect(V1, '^Hangouts Bridge') ~ 'Hangouts Bridge',
            str_detect(V1, '^LinkedIn Messages Bridge') ~ 'LinkedIn Messages Bridge',
            str_detect(V1, '^SchildiChat .*(Linux)') ~ 'SchildiChat Desktop',
            str_detect(V1, '^Pattle iOS') ~ 'Pattle iOS',
            str_detect(V1, '^RiotX') ~ 'RiotX',
            str_detect(V1, '^Android Messages Bridge') ~ 'Android Messages Bridge',
            str_detect(V1, '^Famedly ios') ~ 'Famedly iOS',
            str_detect(V1, '^Synapse Admin') ~ 'Synapse Admin',
            str_detect(V1, '^WeeMatrix') ~ 'WeeMatrix',
            str_detect(V1, '^Daydream') ~ 'Daydream',
            str_detect(V1, '^SchildiChat') ~ 'SchildiChat',
            str_detect(V1, '^EachChat Android') ~ 'EachChat Android',
            str_detect(V1, '^ponies.im/_matrix/client') ~ 'ponies.im',
            str_detect(V1, '^riot.') ~ 'Element Web',
            str_detect(V1, '^https://riot.') ~ 'Element Web',
            str_detect(V1, 'Element Web') ~ 'Element Web',
            str_detect(V1, '^Mobile$') ~ 'Element iOS (presumably)',
            str_detect(V1, '^Radical') ~ 'Radical',
            str_detect(V1, '^Quaternion') ~ 'Quaternion',
            str_detect(V1, '^Blast Android') ~ 'Blast Android',
            str_detect(V1, '^matrix-sdk') ~ 'matrix-sdk',
            str_detect(V1, '^Maunium') ~ 'Maunium',
            str_detect(V1, '^Nextcloud') ~ 'Nextcloud',
            str_detect(V1, '^Spectral') ~ 'Spectral',
            str_detect(V1, '^NeoChat') ~ 'NeoChat',
            str_detect(V1, '^SimpleMatrix') ~ 'SimpleMatrix',
            str_detect(V1, '^matrix-tag-manager') ~ 'matrix-tag-manager',
            str_detect(V1, '^Blast Desktop') ~ 'Blast Desktop',
            str_detect(V1, '^IndieChat android') ~ 'IndieChat android',
            str_detect(V1, '^Revolution Desktop') ~ 'Revolution Desktop',
            str_detect(V1, '^Riot.im') ~ 'Element Web',
            str_detect(V1, '^Beeper') ~ 'Beeper',
            str_detect(V1, '^Famedly windows') ~ 'Famedly Windows',
            str_detect(V1, '^Riot on Android') ~ 'Riot Android',
            str_detect(V1, '^Prometheus') ~ 'Prometheus',
            str_detect(V1, '^prometheus') ~ 'Prometheus',
            str_detect(V1, '^mautrix-manager') ~ 'mautrix-manager',
            str_detect(V1, '^mauPhone') ~ 'mauPhone',
            str_detect(V1, '^_nheko_') ~ 'Nheko',
            str_detect(V1, '^mirage') ~ 'Mirage',
            str_detect(V1, '^Schildi Android') ~ 'SchildiChat Android',
            str_detect(V1, '^Schildi') ~ 'SchildiChat',
            str_detect(V1, '^Blast Desktop') ~ 'Blast Desktop',
            TRUE ~ 'Other'
          )
        ) |>
        filter(Client != 'Other') |>
        group_by(Client) |>
        summarize(total = sum(V2)) |>
        ggplot2::ggplot(ggplot2::aes(
          area = total,
          fill = Client,
          label = Client
        )) +
        geom_treemap() +
        geom_treemap_text(
          fontface = "italic",
          colour = "white",
          place = "centre",
          grow = TRUE
        )
      p
    })
  })
}

## To be copied in the UI
# mod_client_stats_ui("client_stats_ui_1")

## To be copied in the server
# mod_client_stats_server("client_stats_ui_1")
mx-serverstats/server_stats_web_statistics documentation built on Dec. 21, 2021, 11:06 p.m.