Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/assets/stylesheets/app/metrics-card.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
.metrics-card-body {
height: 450px;
height: 275px;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

choosing an arbitrary number for development. this is used for the height of the chart card div wrapper, and needed a stable height consistent between the loading card and metrics card.


.metrics-chart {
height: 100%;
}

.metrics-table {
height: 100%;
}
// .metrics-table {
// height: 100%;
// }
}
56 changes: 56 additions & 0 deletions app/controllers/concerns/metrics_queries.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require "active_support/concern"

module MetricsQueries
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this concern never made it to main because it was part of the now-closed PR for the agents cards. so bringing it back again to save some lines and reuse common queries between Podcast and Episode. (and potentially Feed, for the next PR)

extend ActiveSupport::Concern

def alltime_downloads(model)
model_id, column = model_attrs(model)

Rollups::HourlyDownload
.where("#{column}": model_id)
.select(column, "SUM(count) AS count")
.group(column)
.final
.load_async
end

def daterange_downloads(model, date_start = Date.utc_today - 28.days, date_end = Time.now, interval = "DAY")
model_id, column = model_attrs(model)

Rollups::HourlyDownload
.where("#{column}": model_id, hour: (date_start..date_end))
.select(column, "DATE_TRUNC('#{interval}', hour) AS hour", "SUM(count) AS count")
.group(column, "DATE_TRUNC('#{interval}', hour) AS hour")
.order(Arel.sql("DATE_TRUNC('#{interval}', hour) ASC"))
.final
.load_async
end

def alltime_downloads_by_month(model)
model_id, column = model_attrs(model)

Rollups::HourlyDownload
.where("#{column}": model_id)
.select(column, "DATE_TRUNC('MONTH', hour) AS hour", "SUM(count) AS count")
.group(column, "DATE_TRUNC('MONTH', hour) AS hour")
.order(Arel.sql("DATE_TRUNC('MONTH', hour) AS hour"))
end

def model_attrs(model)
model_id = if model.is_a?(Enumerable)
model.pluck(:guid)
elsif model.is_a?(Podcast)
model[:id]
elsif model.is_a?(Episode)
model[:guid]
end

column = if model.is_a?(Enumerable)
"#{model.first.class.to_s.downcase}_id"
else
"#{model.class.to_s.downcase}_id"
end

[model_id, column]
end
end
28 changes: 21 additions & 7 deletions app/controllers/concerns/metrics_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,39 @@ def primary_blue
"#0072a3"
end

def light_pink
"#e7d4ff"
end

def light_blue
"#aafff5"
end

def orange
"#ff9601"
end

def single_rollups(downloads, label = I18n.t(".helpers.label.metrics.chart.all_episodes"))
{
rollups: downloads,
color: primary_blue,
color: light_blue,
label: label
}
end

def multiple_episode_rollups(episodes, rollups, totals)
episodes.to_enum(:each_with_index).map do |episode, i|
def multiple_episode_rollups(episodes, rollups)
episodes.map.with_index do |episode, i|
color = if i == 0
orange
else
light_blue
end
{
episode: episode,
rollups: rollups.select do |r|
r["episode_id"] == episode.guid
end,
totals: totals.select do |r|
r["episode_id"] == episode.guid
end,
color: colors[i]
color: color
}
end
end
Expand Down
58 changes: 15 additions & 43 deletions app/controllers/podcast_metrics_controller.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class PodcastMetricsController < ApplicationController
include MetricsUtils
include MetricsQueries

before_action :set_podcast
before_action :check_clickhouse, except: %i[show]
# before_action :check_clickhouse, except: %i[show]

def show
end
Expand All @@ -28,60 +29,31 @@ def episode_sparkline
}
end

def downloads
@downloads_within_date_range =
Rollups::HourlyDownload
.where(podcast_id: @podcast.id, hour: (@date_start..@date_end))
.select("DATE_TRUNC('#{@interval}', hour) AS hour", "SUM(count) AS count")
.group("DATE_TRUNC('#{@interval}', hour) AS hour")
.order(Arel.sql("DATE_TRUNC('#{@interval}', hour) ASC"))
.load_async
def monthly_downloads
@date_start = (Date.utc_today - 11.months).beginning_of_month
@date_end = Date.utc_today
@date_range = generate_date_range(@date_start, @date_end.beginning_of_month, "MONTH")
@downloads_within_date_range = daterange_downloads(@podcast, @date_start, @date_end, "MONTH")

@downloads = single_rollups(@downloads_within_date_range)
@downloads = single_rollups(@downloads_within_date_range, "Downloads")

render partial: "metrics/downloads_card", locals: {
url: request.fullpath,
form_id: "podcast_downloads_metrics",
date_start: @date_start,
date_end: @date_end,
interval: @interval,
render partial: "metrics/monthly_card", locals: {
date_range: @date_range,
downloads: @downloads
}
end

def episodes
@episodes =
@podcast.episodes
.published
.order(first_rss_published_at: :desc)
.paginate(params[:episodes], params[:per])
@episodes = @podcast.episodes.published.dropdate_desc.limit(10)
@date_range = generate_date_range(Date.utc_today - 28.days, Date.utc_today, "DAY")

@episodes_recent =
Rollups::HourlyDownload
.where(podcast_id: @podcast.id, episode_id: @episodes.pluck(:guid), hour: (@date_start..@date_end))
.select(:episode_id, "DATE_TRUNC('#{@interval}', hour) AS hour", "SUM(count) AS count")
.group(:episode_id, "DATE_TRUNC('#{@interval}', hour) AS hour")
.order(Arel.sql("DATE_TRUNC('#{@interval}', hour) ASC"))
.load_async
@episodes_alltime =
Rollups::HourlyDownload
.where(podcast_id: @podcast.id, episode_id: @episodes.pluck(:guid))
.select(:episode_id, "SUM(count) AS count")
.group(:episode_id)
.load_async
@episodes_downloads = daterange_downloads(@episodes)

@episode_rollups = multiple_episode_rollups(@episodes, @episodes_recent, @episodes_alltime)
@episode_rollups = multiple_episode_rollups(@episodes, @episodes_downloads)

render partial: "metrics/episodes_card", locals: {
url: request.fullpath,
form_id: "podcast_episodes_metrics",
date_start: @date_start,
date_end: @date_end,
interval: @interval,
date_range: @date_range,
episodes: @episodes,
episode_rollups: @episode_rollups
episode_rollups: @episode_rollups,
date_range: @date_range
}
end

Expand Down
4 changes: 4 additions & 0 deletions app/controllers/podcasts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class PodcastsController < ApplicationController
include Prx::Api
include SlackHelper
include MetricsQueries

before_action :set_podcast, only: %i[show edit update destroy]

Expand All @@ -20,6 +21,9 @@ def show
@recently_published_episodes = @podcast.episodes.published.dropdate_desc.limit(4)
@trend_episodes = @podcast.default_feed.episodes.published.dropdate_desc.where.not(first_rss_published_at: nil).offset(1).limit(4)
@episode_trend_pairs = episode_trend_pairs(@recently_published_episodes, @trend_episodes)
@alltime_downloads = alltime_downloads(@podcast).sum(&:count)
@daterange_downloads = daterange_downloads(@podcast).sum(&:count)
@episode_count = @podcast.episodes.published.length

# @recently_published is used for the prod branch
@recently_published = @recently_published_episodes[0..2]
Expand Down
15 changes: 9 additions & 6 deletions app/javascript/controllers/apex_episodes_controller.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import { Controller } from "@hotwired/stimulus"
import { buildDateTimeChart, buildDownloadsSeries, LINE_TYPE } from "util/apex"
import { buildDateTimeChart, buildDownloadsSeries, LINE_TYPE, destroyChart } from "util/apex"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reusing this controller for the Episode Downloads card since it's the same purpose.


export default class extends Controller {
static values = {
id: String,
selectedEpisodes: Array,
rollups: Array,
dateRange: Array,
interval: String,
options: String,
}

static targets = ["chart"]

connect() {
const series = buildDownloadsSeries(this.selectedEpisodesValue, this.dateRangeValue)
const title = `Downloads by ${this.intervalValue.toLowerCase()}`
const chart = buildDateTimeChart(this.idValue, series, this.chartTarget, LINE_TYPE, title)
const series = buildDownloadsSeries(this.rollupsValue, this.dateRangeValue)

const chart = buildDateTimeChart(this.idValue, series, this.chartTarget, LINE_TYPE, this.dateRangeValue)

chart.render()
}

disconnect() {
destroyChart(this.idValue)
}
}
24 changes: 24 additions & 0 deletions app/javascript/controllers/apex_monthly_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Controller } from "@hotwired/stimulus"
import { buildDateTimeChart, buildDownloadsSeries, BAR_TYPE, destroyChart } from "util/apex"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new controller for the Monthly Downloads chart.


export default class extends Controller {
static values = {
id: String,
downloads: Object,
dateRange: Array,
}

static targets = ["chart"]

connect() {
const series = buildDownloadsSeries(this.downloadsValue, this.dateRangeValue)

const chart = buildDateTimeChart(this.idValue, series, this.chartTarget, BAR_TYPE)

chart.render()
}

disconnect() {
destroyChart(this.idValue)
}
}
Loading