Rename pageviews to events

This commit is contained in:
Uku Taht 2019-10-24 14:58:17 +08:00
parent 74ee0a163c
commit 0c453be08c
15 changed files with 165 additions and 86 deletions

View File

@ -15,9 +15,9 @@ defmodule Plausible.Auth do
def user_completed_setup?(user) do
query =
from(
p in Plausible.Pageview,
e in Plausible.Event,
join: s in Plausible.Site,
on: s.domain == p.hostname,
on: s.domain == e.hostname,
join: sm in Plausible.Site.Membership,
on: sm.site_id == s.id,
join: u in Plausible.Auth.User,

View File

@ -118,11 +118,10 @@ defmodule Plausible.Billing do
defp site_usage(site) do
Repo.aggregate(from(
p in Plausible.Pageview,
where: p.hostname == ^site.domain,
where: p.timestamp >= fragment("now() - '30 days'::interval")
), :count, :id
)
e in Plausible.Event,
where: e.hostname == ^site.domain,
where: e.timestamp >= fragment("now() - '30 days'::interval")
), :count, :id)
end
defp format_subscription(params) do

View File

@ -1,19 +1,19 @@
defmodule Plausible.Pageview do
defmodule Plausible.Event do
use Ecto.Schema
import Ecto.Changeset
schema "pageviews" do
schema "events" do
field :hostname, :string
field :pathname, :string
field :new_visitor, :boolean
field :user_id, :binary_id
field :referrer, :string
field :screen_size, :string
field :referrer_source, :string
field :country_code, :string
field :screen_size, :string
field :operating_system, :string
field :browser, :string
field :referrer_source, :string
timestamps(inserted_at: :timestamp, updated_at: false)
end

View File

@ -13,8 +13,8 @@ defmodule Plausible.Sites do
def has_pageviews?(site) do
Repo.exists?(
from p in Plausible.Pageview,
where: p.hostname == ^site.domain
from e in Plausible.Event,
where: e.hostname == ^site.domain
)
end

View File

@ -24,10 +24,10 @@ defmodule Plausible.Stats do
end)
groups = Repo.all(
from p in base_query(site, query),
from e in base_query(site, query),
group_by: 1,
order_by: 1,
select: {fragment("date_trunc('month', ? at time zone 'utc' at time zone ?)", p.timestamp, ^site.timezone), count(p.user_id, :distinct)}
select: {fragment("date_trunc('month', ? at time zone 'utc' at time zone ?)", e.timestamp, ^site.timezone), count(e.user_id, :distinct)}
) |> Enum.into(%{})
|> transform_keys(fn dt -> NaiveDateTime.to_date(dt) end)
@ -42,10 +42,10 @@ defmodule Plausible.Stats do
steps = Enum.into(query.date_range, [])
groups = Repo.all(
from p in base_query(site, query),
from e in base_query(site, query),
group_by: 1,
order_by: 1,
select: {fragment("date_trunc('day', ? at time zone 'utc' at time zone ?)", p.timestamp, ^site.timezone), count(p.user_id, :distinct)}
select: {fragment("date_trunc('day', ? at time zone 'utc' at time zone ?)", e.timestamp, ^site.timezone), count(e.user_id, :distinct)}
) |> Enum.into(%{})
|> transform_keys(fn dt -> NaiveDateTime.to_date(dt) end)
@ -68,10 +68,10 @@ defmodule Plausible.Stats do
end)
groups = Repo.all(
from p in base_query(site, query),
from e in base_query(site, query),
group_by: 1,
order_by: 1,
select: {fragment("date_trunc('hour', ? at time zone 'utc' at time zone ?)", p.timestamp, ^site.timezone), count(p.user_id, :distinct)}
select: {fragment("date_trunc('hour', ? at time zone 'utc' at time zone ?)", e.timestamp, ^site.timezone), count(e.user_id, :distinct)}
)
|> Enum.into(%{})
|> transform_keys(fn dt -> NaiveDateTime.truncate(dt, :second) end)
@ -85,8 +85,8 @@ defmodule Plausible.Stats do
def pageviews_and_visitors(site, query) do
Repo.one(from(
p in base_query(site, query),
select: {count(p.id), count(p.user_id, :distinct)}
e in base_query(site, query),
select: {count(e.id), count(e.user_id, :distinct)}
))
end
@ -96,43 +96,43 @@ defmodule Plausible.Stats do
def unique_visitors(site, query) do
Repo.one(from(
p in base_query(site, query),
select: count(p.user_id, :distinct)
e in base_query(site, query),
select: count(e.user_id, :distinct)
))
end
def top_referrers(site, query, limit \\ 5) do
Repo.all(from p in base_query(site, query),
select: {p.referrer_source, count(p.referrer_source)},
group_by: p.referrer_source,
where: p.new_visitor == true and not is_nil(p.referrer_source),
Repo.all(from e in base_query(site, query),
select: {e.referrer_source, count(e.referrer_source)},
group_by: e.referrer_source,
where: e.new_visitor == true and not is_nil(e.referrer_source),
order_by: [desc: 2],
limit: ^limit
)
end
def visitors_from_referrer(site, query, referrer) do
Repo.one(from p in base_query(site, query),
select: count(p),
where: p.new_visitor == true and p.referrer_source == ^referrer
Repo.one(from e in base_query(site, query),
select: count(e),
where: e.new_visitor == true and e.referrer_source == ^referrer
)
end
def referrer_drilldown(site, query, referrer) do
Repo.all(from p in base_query(site, query),
select: {p.referrer, count(p)},
group_by: p.referrer,
where: p.new_visitor == true and p.referrer_source == ^referrer,
Repo.all(from e in base_query(site, query),
select: {e.referrer, count(e)},
group_by: e.referrer,
where: e.new_visitor == true and e.referrer_source == ^referrer,
order_by: [desc: 2],
limit: 100
)
end
def top_pages(site, query, limit \\ 5) do
Repo.all(from p in base_query(site, query),
select: {p.pathname, count(p.pathname)},
group_by: p.pathname,
order_by: [desc: count(p.pathname)],
Repo.all(from e in base_query(site, query),
select: {e.pathname, count(e.pathname)},
group_by: e.pathname,
order_by: [desc: count(e.pathname)],
limit: ^limit
)
end
@ -140,10 +140,10 @@ defmodule Plausible.Stats do
@available_screen_sizes ["Desktop", "Laptop", "Tablet", "Mobile"]
def top_screen_sizes(site, query) do
Repo.all(from p in base_query(site, query),
select: {p.screen_size, count(p.screen_size)},
group_by: p.screen_size,
where: p.new_visitor == true and not is_nil(p.screen_size)
Repo.all(from e in base_query(site, query),
select: {e.screen_size, count(e.screen_size)},
group_by: e.screen_size,
where: e.new_visitor == true and not is_nil(e.screen_size)
) |> Enum.sort(fn {screen_size1, _}, {screen_size2, _} ->
index1 = Enum.find_index(@available_screen_sizes, fn s -> s == screen_size1 end)
index2 = Enum.find_index(@available_screen_sizes, fn s -> s == screen_size2 end)
@ -152,11 +152,11 @@ defmodule Plausible.Stats do
end
def countries(site, query, limit \\ 5) do
Repo.all(from p in base_query(site, query),
select: {p.country_code, count(p.country_code)},
group_by: p.country_code,
where: p.new_visitor == true and not is_nil(p.country_code),
order_by: [desc: count(p.country_code)],
Repo.all(from e in base_query(site, query),
select: {e.country_code, count(e.country_code)},
group_by: e.country_code,
where: e.new_visitor == true and not is_nil(e.country_code),
order_by: [desc: count(e.country_code)],
limit: ^limit
) |> Enum.map(fn {country_code, count} ->
{Plausible.Stats.CountryName.from_iso3166(country_code), count}
@ -164,31 +164,31 @@ defmodule Plausible.Stats do
end
def browsers(site, query, limit \\ 5) do
Repo.all(from p in base_query(site, query),
select: {p.browser, count(p.browser)},
group_by: p.browser,
where: p.new_visitor == true and not is_nil(p.browser),
order_by: [desc: count(p.browser)],
Repo.all(from e in base_query(site, query),
select: {e.browser, count(e.browser)},
group_by: e.browser,
where: e.new_visitor == true and not is_nil(e.browser),
order_by: [desc: count(e.browser)],
limit: ^limit
)
end
def operating_systems(site, query, limit \\ 5) do
Repo.all(from p in base_query(site, query),
select: {p.operating_system, count(p.operating_system)},
group_by: p.operating_system,
where: p.new_visitor == true and not is_nil(p.operating_system),
order_by: [desc: count(p.operating_system)],
Repo.all(from e in base_query(site, query),
select: {e.operating_system, count(e.operating_system)},
group_by: e.operating_system,
where: e.new_visitor == true and not is_nil(e.operating_system),
order_by: [desc: count(e.operating_system)],
limit: ^limit
)
end
def current_visitors(site) do
Repo.one(
from p in Plausible.Pageview,
where: p.timestamp >= fragment("(now() at time zone 'utc') - '5 minutes'::interval"),
where: p.hostname == ^site.domain,
select: count(p.user_id, :distinct)
from e in Plausible.Event,
where: e.timestamp >= fragment("(now() at time zone 'utc') - '5 minutes'::interval"),
where: e.hostname == ^site.domain,
select: count(e.user_id, :distinct)
)
end
@ -199,9 +199,9 @@ defmodule Plausible.Stats do
{:ok, last} = NaiveDateTime.new(query.date_range.last |> Timex.shift(days: 1), ~T[00:00:00])
last_datetime = Timex.to_datetime(last, site.timezone)
from(p in Plausible.Pageview,
where: p.hostname == ^site.domain,
where: p.timestamp >= ^first_datetime and p.timestamp < ^last_datetime
from(e in Plausible.Event,
where: e.hostname == ^site.domain,
where: e.timestamp >= ^first_datetime and e.timestamp < ^last_datetime
)
end

View File

@ -55,7 +55,7 @@ defmodule PlausibleWeb.Api.ExternalController do
screen_size: calculate_screen_size(params["screen_width"])
}
Plausible.Pageview.changeset(%Plausible.Pageview{}, pageview_attrs)
Plausible.Event.changeset(%Plausible.Event{}, pageview_attrs)
|> Plausible.Repo.insert
end
end

View File

@ -4,8 +4,8 @@ defmodule PlausibleWeb.Api.InternalController do
def domain_status(conn, %{"domain" => domain}) do
has_pageviews = Repo.exists?(
from p in Plausible.Pageview,
where: p.hostname == ^domain
from e in Plausible.Event,
where: e.hostname == ^domain
)
if has_pageviews do

View File

@ -90,7 +90,7 @@ defmodule PlausibleWeb.SiteController do
|> Repo.preload(:google_auth)
Repo.delete_all(from sm in "site_memberships", where: sm.site_id == ^site.id)
Repo.delete_all(from p in "pageviews", where: p.hostname == ^site.domain)
Repo.delete_all(from e in "events", where: e.hostname == ^site.domain)
if site.google_auth do
Repo.delete!(site.google_auth)

View File

@ -0,0 +1,7 @@
defmodule Plausible.Repo.Migrations.RenamePageviewsToEvents do
use Ecto.Migration
def change do
rename table("pageviews"), to: table("events")
end
end

View File

@ -0,0 +1,21 @@
defmodule Plausible.AuthTest do
use Plausible.DataCase
alias Plausible.Auth
describe "user_completed_setup?" do
test "is false if user does not have any events" do
user = insert(:user)
insert(:site, members: [user])
refute Auth.user_completed_setup?(user)
end
test "is true if user does have events" do
user = insert(:user)
site = insert(:site, members: [user])
insert(:pageview, hostname: site.domain)
assert Auth.user_completed_setup?(user)
end
end
end

View File

@ -2,6 +2,23 @@ defmodule Plausible.BillingTest do
use Plausible.DataCase
alias Plausible.Billing
describe "usage" do
test "is 0 with no events" do
user = insert(:user)
assert Billing.usage(user) == 0
end
test "counts the total number of events" do
user = insert(:user)
site = insert(:site, members: [user])
insert(:pageview, hostname: site.domain)
insert(:pageview, hostname: site.domain)
assert Billing.usage(user) == 2
end
end
describe "trial_days_left" do
test "is 30 days for new signup" do
user = insert(:user)

View File

@ -0,0 +1,35 @@
defmodule Plausible.SitesTest do
use Plausible.DataCase
alias Plausible.Sites
describe "has_pageviews?" do
test "is true if site has pageviews" do
site = insert(:site)
insert(:pageview, hostname: site.domain)
assert Sites.has_pageviews?(site)
end
test "is false if site does not have pageviews" do
site = insert(:site)
refute Sites.has_pageviews?(site)
end
end
describe "is_owner?" do
test "is true if user is the owner of the site" do
user = insert(:user)
site = insert(:site, members: [user])
assert Sites.is_owner?(user.id, site)
end
test "is false if user is not the owner" do
user = insert(:user)
site = insert(:site)
refute Sites.is_owner?(user.id, site)
end
end
end

View File

@ -21,7 +21,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("cf-ipcountry", @country_code)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.hostname == "gigride.live"
@ -41,7 +41,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("content-type", "text/plain")
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert pageview.hostname == "example.com"
end
@ -57,7 +57,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", "generic crawler")
|> post("/api/page", Jason.encode!(params))
pageviews = Repo.all(Plausible.Pageview)
pageviews = Repo.all(Plausible.Event)
assert Enum.count(pageviews) == 0
end
@ -74,7 +74,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.operating_system == "Mac"
@ -94,7 +94,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.referrer_source == "Facebook"
@ -113,7 +113,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.referrer_source == nil
@ -132,7 +132,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.referrer_source == nil
@ -151,7 +151,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.referrer_source == "blog.gigride.live"
@ -169,7 +169,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("content-type", "text/plain")
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert pageview.referrer == "indiehackers.com/page"
end
@ -186,7 +186,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("content-type", "text/plain")
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert pageview.referrer_source == "traffic-source"
end
@ -203,7 +203,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("content-type", "text/plain")
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert pageview.referrer_source == "traffic-source"
end
@ -221,7 +221,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
assert Repo.aggregate(Plausible.Pageview, :count, :id) == 0
assert Repo.aggregate(Plausible.Event, :count, :id) == 0
end
test "if it's an :unknown referrer, just the domain is used", %{conn: conn} do
@ -237,7 +237,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.referrer_source == "indiehackers.com"
@ -256,7 +256,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert is_nil(pageview.referrer_source)
@ -277,7 +277,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.screen_size == "Mobile"
@ -295,7 +295,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
|> put_req_header("user-agent", @user_agent)
|> post("/api/page", Jason.encode!(params))
pageview = Repo.one(Plausible.Pageview)
pageview = Repo.one(Plausible.Event)
assert response(conn, 202) == ""
assert pageview.screen_size == nil

View File

@ -120,7 +120,7 @@ defmodule PlausibleWeb.SiteControllerTest do
delete(conn, "/#{site.domain}")
refute Repo.exists?(from s in Plausible.Site, where: s.id == ^site.id)
refute Repo.exists?(from p in Plausible.Pageview, where: p.id == ^pageview.id)
refute Repo.exists?(from e in Plausible.Event, where: e.id == ^pageview.id)
end
end
end

View File

@ -25,7 +25,7 @@ defmodule Plausible.Factory do
def pageview_factory do
hostname = sequence(:domain, &"example-#{&1}.com")
%Plausible.Pageview{
%Plausible.Event{
hostname: hostname,
pathname: "/",
new_visitor: true,