analytics/priv/repo/seeds.exs

385 lines
10 KiB
Elixir

# Script for populating the database. You can run it as:
#
# mix run priv/repo/seeds.exs
#
# Inside the script, you can read and write to any of your
# repositories directly:
#
# Plausible.Repo.insert!(%Plausible.SomeSchema{})
#
# We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong.
use Plausible
import Plausible.Teams.Test
words =
for i <- 0..(:erlang.system_info(:atom_count) - 1),
do: :erlang.binary_to_term(<<131, 75, i::24>>)
user = new_user(email: "user@plausible.test", password: "plausible")
native_stats_range =
Date.range(
Date.add(Date.utc_today(), -720),
Date.utc_today()
)
native_stats_range2 =
Date.range(
Date.add(Date.utc_today(), -320),
Date.utc_today()
)
imported_stats_range =
Date.range(
Date.add(native_stats_range.first, -180),
Date.add(native_stats_range.first, -1)
)
long_random_paths =
for _ <- 1..100 do
path =
words
|> Enum.shuffle()
|> Enum.take(Enum.random(1..20))
|> Enum.join("/")
"/#{path}.html"
end
long_random_paths = ["/", "/register", "/login", "/about"] ++ long_random_paths
long_random_urls =
for path <- long_random_paths do
"https://dummy.site#{path}"
end
FunWithFlags.enable(:live_dashboard)
site =
new_site(
domain: "dummy.site",
team: [
native_stats_start_at: NaiveDateTime.new!(native_stats_range.first, ~T[00:00:00]),
stats_start_date: NaiveDateTime.new!(imported_stats_range.first, ~T[00:00:00])
],
owner: user
)
add_guest(site, user: new_user(name: "Arnold Wallaby", password: "plausible"), role: :viewer)
add_guest(site, user: new_user(name: "Lois Lane", password: "plausible"), role: :editor)
another_site =
new_site(
domain: "another.site",
team: [
native_stats_start_at: NaiveDateTime.new!(native_stats_range2.first, ~T[00:00:00]),
stats_start_date: NaiveDateTime.new!(native_stats_range2.first, ~T[00:00:00])
],
owner: user
)
user2 = new_user(name: "Mary Jane", email: "user2@plausible.test", password: "plausible")
site2 = new_site(domain: "computer.example.com", owner: user2)
invite_guest(site2, user, inviter: user2, role: :viewer)
on_ee do
solo_user = new_user(name: "Solo User", email: "solo@plausible.test", password: "plausible")
new_site(domain: "mysolosite.com", owner: solo_user)
{:ok, solo_team} = Plausible.Teams.get_or_create(solo_user)
Plausible.Billing.DevSubscriptions.create(solo_team.id, "910413")
end
Plausible.Factory.insert_list(29, :ip_rule, site: site)
Plausible.Factory.insert(:country_rule, site: site, country_code: "PL")
Plausible.Factory.insert(:country_rule, site: site, country_code: "EE")
Plausible.Factory.insert(:google_auth,
user: user,
site: site,
property: "sc-domain:dummy.test",
expires: NaiveDateTime.add(NaiveDateTime.utc_now(), 3600)
)
# Plugins API: on dev environment, use "plausible-plugin-dev-seed-token" for "dummy.site" to authenticate
seeded_token = Plausible.Plugins.API.Token.generate("seed-token")
{:ok, _, _} =
Plausible.Plugins.API.Tokens.create(site, "plausible-plugin-dev-seed-token", seeded_token)
{:ok, site} = Plausible.Props.allow(site, ["logged_in"])
{:ok, goal1} = Plausible.Goals.create(site, %{"page_path" => "/"})
{:ok, goal2} = Plausible.Goals.create(site, %{"page_path" => "/register"})
{:ok, goal3} =
Plausible.Goals.create(site, %{"page_path" => "/login", "display_name" => "User logs in"})
{:ok, revenue_goal} =
Plausible.Goals.create(site, %{
"event_name" => "Purchase",
"currency" => "USD",
"display_name" => "North America Purchases"
})
{:ok, _goal5} = Plausible.Goals.create(site, %{"page_path" => Enum.random(long_random_paths)})
{:ok, outbound} = Plausible.Goals.create(site, %{"event_name" => "Outbound Link: Click"})
if ee?() do
{:ok, _funnel} =
Plausible.Funnels.create(site, "From homepage to login", [
%{"goal_id" => goal1.id},
%{"goal_id" => goal2.id},
%{"goal_id" => goal3.id}
])
end
geolocations = [
[
country_code: "IT",
subdivision1_code: "IT-62",
subdivision2_code: "IT-RM",
city_geoname_id: 3_169_070
],
[
country_code: "EE",
subdivision1_code: "EE-37",
subdivision2_code: "EE-784",
city_geoname_id: 588_409
],
[
country_code: "BR",
subdivision1_code: "BR-SP",
subdivision2_code: "",
city_geoname_id: 3_448_439
],
[
country_code: "PL",
subdivision1_code: "PL-14",
subdivision2_code: "",
city_geoname_id: 756_135
],
[
country_code: "DE",
subdivision1_code: "DE-BE",
subdivision2_code: "",
city_geoname_id: 2_950_159
],
[
country_code: "US",
subdivision1_code: "US-CA",
subdivision2_code: "",
city_geoname_id: 5_391_959
],
[]
]
sources = [
"",
"Facebook",
"Twitter",
"DuckDuckGo",
"Google",
"opensource.com",
"indiehackers.com"
]
utm_medium = %{
"" => ["email", ""],
"Google" => ["cpc", ""],
"Facebook" => ["social", "cpc"],
"Twitter" => ["social"]
}
random_event_data = fn site ->
domain = site.domain
referrer_source = Enum.random(sources)
[
site_id: site.id,
hostname: Enum.random(["en.#{domain}", "es.#{domain}", domain]),
referrer_source: referrer_source,
browser: Enum.random(["Microsoft Edge", "Chrome", "curl", "Safari", "Firefox", "Vivaldi"]),
browser_version: to_string(Enum.random(0..50)),
screen_size: Enum.random(["Mobile", "Tablet", "Desktop", "Laptop"]),
operating_system: Enum.random(["Windows", "Mac", "GNU/Linux"]),
operating_system_version: to_string(Enum.random(0..15)),
utm_medium: Enum.random(Map.get(utm_medium, referrer_source, [""])),
utm_source: String.downcase(referrer_source),
utm_campaign: Enum.random(["", "Referral", "Advertisement", "Email"]),
pathname: Enum.random(long_random_paths),
"meta.key": ["url", "logged_in"],
"meta.value": [
Enum.random(long_random_urls),
Enum.random(["true", "false"])
]
]
|> Keyword.merge(Enum.random(geolocations))
end
clickhouse_max_uint64 = 18_446_744_073_709_551_615
with_random_time = fn date ->
random_time = Time.new!(:rand.uniform(23), :rand.uniform(59), 0)
date
|> NaiveDateTime.new!(random_time)
|> NaiveDateTime.truncate(:second)
end
next_event_timestamp = fn timestamp ->
seconds_to_next_event = :rand.uniform(300)
NaiveDateTime.add(timestamp, seconds_to_next_event)
end
native_stats_range
|> Enum.flat_map(fn date ->
n_visitors = 50 + :rand.uniform(150)
Enum.flat_map(0..n_visitors, fn _ ->
visit_start_timestamp = with_random_time.(date)
user_id = :rand.uniform(clickhouse_max_uint64)
event =
random_event_data.(site)
|> Keyword.merge(user_id: user_id)
Enum.reduce(0..Enum.random(0..5), [], fn event_index, events ->
timestamp =
case events do
[] -> visit_start_timestamp
[event | _] -> next_event_timestamp.(event.timestamp)
end
event = Keyword.merge(event, timestamp: timestamp)
to_insert =
cond do
event_index > 0 && :rand.uniform() < 0.1 ->
event
|> Keyword.merge(name: outbound.event_name)
|> then(&[Plausible.Factory.build(:event, &1)])
event_index > 0 && :rand.uniform() < 0.05 ->
amount = Decimal.new(:rand.uniform(100))
event
|> Keyword.merge(name: revenue_goal.event_name)
|> Keyword.merge(revenue_source_currency: "USD")
|> Keyword.merge(revenue_source_amount: amount)
|> Keyword.merge(revenue_reporting_currency: "USD")
|> Keyword.merge(revenue_reporting_amount: amount)
|> then(&[Plausible.Factory.build(:event, &1)])
true ->
pageview = Plausible.Factory.build(:pageview, event)
engagement =
Map.merge(pageview, %{
name: "engagement",
engagement_time: Enum.random(300..10000),
scroll_depth: Enum.random(1..100)
})
[engagement, pageview]
end
to_insert ++ events
end)
|> Enum.reverse()
end)
end)
|> Plausible.TestUtils.populate_stats()
native_stats_range2
|> Enum.flat_map(fn date ->
n_visitors = 10 + :rand.uniform(70)
Enum.flat_map(0..n_visitors, fn _ ->
visit_start_timestamp = with_random_time.(date)
user_id = :rand.uniform(clickhouse_max_uint64)
event =
random_event_data.(another_site)
|> Keyword.merge(user_id: user_id)
Enum.reduce(0..Enum.random(0..5), [], fn _event_index, events ->
timestamp =
case events do
[] -> visit_start_timestamp
[event | _] -> next_event_timestamp.(event.timestamp)
end
event = Keyword.merge(event, timestamp: timestamp)
pageview = Plausible.Factory.build(:pageview, event)
engagement =
Map.merge(pageview, %{
name: "engagement",
engagement_time: Enum.random(300..10000),
scroll_depth: Enum.random(1..100)
})
[engagement, pageview] ++ events
end)
|> Enum.reverse()
end)
end)
|> Plausible.TestUtils.populate_stats()
site_import =
site
|> Plausible.Imported.SiteImport.create_changeset(user, %{
source: :universal_analytics,
start_date: imported_stats_range.first,
end_date: imported_stats_range.last,
legacy: false
})
|> Plausible.Imported.SiteImport.start_changeset()
|> Plausible.Repo.insert!()
imported_stats_range
|> Enum.flat_map(fn date ->
Enum.flat_map(0..Enum.random(1..50), fn _ ->
pages_visits = Enum.random(1..15)
[
Plausible.Factory.build(:imported_visitors,
date: date,
pageviews: Enum.random(1..50),
visitors: Enum.random(1..10),
bounces: Enum.random(1..6),
visits: Enum.random(1..15),
visit_duration: Enum.random(1000..10000)
),
Plausible.Factory.build(:imported_sources,
date: date,
source: Enum.random(sources),
pageviews: Enum.random(1..50),
visitors: Enum.random(1..10),
bounces: Enum.random(1..6),
visits: Enum.random(1..15),
visit_duration: Enum.random(1000..10000)
),
Plausible.Factory.build(:imported_pages,
date: date,
page: Enum.random(long_random_paths),
visitors: Enum.random(1..10),
visits: pages_visits,
pageviews: Enum.random(1..50),
exits: Enum.random(1..10),
total_time_on_page: Enum.random(1000..10000),
total_time_on_page_visits: pages_visits
)
]
end)
end)
|> then(&Plausible.TestUtils.populate_stats(site, site_import.id, &1))
site_import
|> Plausible.Imported.SiteImport.complete_changeset()
|> Plausible.Repo.update!()