# 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!()