mirror of
https://github.com/plausible/analytics.git
synced 2024-11-23 03:04:43 +03:00
Allow user to cancel ongoing import
This commit is contained in:
parent
0f58d56c11
commit
51cd24bcaf
@ -307,8 +307,6 @@ defmodule Plausible.Google.Api do
|
||||
{:ok, nil}
|
||||
|
||||
{:error, error} ->
|
||||
Plausible.ClickhouseRepo.clear_imported_stats_for(site.domain)
|
||||
|
||||
Sentry.capture_message("Error saving Google analytics data", extra: error)
|
||||
{:error, error["error"]["message"]}
|
||||
end
|
||||
|
@ -23,6 +23,14 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
end
|
||||
end
|
||||
|
||||
def imported_pageview_count(site) do
|
||||
Plausible.ClickhouseRepo.one(
|
||||
from i in "imported_visitors",
|
||||
where: i.site_id == ^site.id,
|
||||
select: sum(i.pageviews)
|
||||
)
|
||||
end
|
||||
|
||||
def usage_breakdown(domains) do
|
||||
range =
|
||||
Date.range(
|
||||
|
@ -170,12 +170,20 @@ defmodule PlausibleWeb.SiteController do
|
||||
def settings_general(conn, _params) do
|
||||
site =
|
||||
conn.assigns[:site]
|
||||
|> Repo.preload([:custom_domain, :google_auth])
|
||||
|> Repo.preload([:custom_domain])
|
||||
|
||||
imported_pageviews =
|
||||
if site.imported_data do
|
||||
Plausible.Stats.Clickhouse.imported_pageview_count(site)
|
||||
else
|
||||
0
|
||||
end
|
||||
|
||||
conn
|
||||
|> assign(:skip_plausible_tracking, true)
|
||||
|> render("settings_general.html",
|
||||
site: site,
|
||||
imported_pageviews: imported_pageviews,
|
||||
changeset: Plausible.Site.changeset(site, %{}),
|
||||
layout: {PlausibleWeb.LayoutView, "site_settings.html"}
|
||||
)
|
||||
@ -712,6 +720,14 @@ defmodule PlausibleWeb.SiteController do
|
||||
|
||||
cond do
|
||||
site.imported_data ->
|
||||
Oban.cancel_all_jobs(
|
||||
from(j in Oban.Job,
|
||||
where:
|
||||
j.queue == "google_analytics_imports" and
|
||||
fragment("(? ->> 'site_id')::int", j.args) == ^site.id
|
||||
)
|
||||
)
|
||||
|
||||
Plausible.Imported.forget(site)
|
||||
|
||||
site
|
||||
@ -719,7 +735,7 @@ defmodule PlausibleWeb.SiteController do
|
||||
|> Repo.update!()
|
||||
|
||||
conn
|
||||
|> put_flash(:success, "Imported data has been forgotten")
|
||||
|> put_flash(:success, "Imported data has been cleared")
|
||||
|> redirect(to: Routes.site_path(conn, :settings_general, site.domain))
|
||||
|
||||
true ->
|
||||
|
@ -59,23 +59,36 @@
|
||||
<%= if Keyword.get(Application.get_env(:plausible, :google), :client_id) do %>
|
||||
<%= cond do %>
|
||||
<% @site.imported_data && @site.imported_data.status == "importing" -> %>
|
||||
<div class="py-2"></div>
|
||||
<div class="text-sm">We are importing data from <%= @site.imported_data.source %> in the background... You will receive an email when it's completed</div>
|
||||
<li class="py-4 flex items-center justify-between space-x-4">
|
||||
<div class="flex flex-col">
|
||||
<p class="text-sm leading-5 font-medium text-gray-900 dark:text-gray-100">
|
||||
Import from <%= @site.imported_data.source %>
|
||||
<svg class="animate-spin -mr-1 ml-1 h-4 w-4 inline text-indigo-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</p>
|
||||
<p class="text-sm leading-5 text-gray-500 dark:text-gray-200">
|
||||
From <%= PlausibleWeb.EmailView.date_format(@site.imported_data.start_date) %> to <%= PlausibleWeb.EmailView.date_format(@site.imported_data.end_date) %>
|
||||
</p>
|
||||
</div>
|
||||
<%= link("Cancel import", to: "/#{URI.encode_www_form(@site.domain)}/settings/forget-imported", method: :delete, class: "inline-block mt-4 px-4 py-2 border border-gray-300 dark:border-gray-500 text-sm leading-5 font-medium rounded-md text-red-700 bg-white dark:bg-gray-800 hover:text-red-500 dark:hover:text-red-400 focus:outline-none focus:border-blue-300 focus:ring active:text-red-800 active:bg-gray-50 transition ease-in-out duration-150") %>
|
||||
</li>
|
||||
|
||||
<% @site.imported_data && @site.imported_data.status == "ok" -> %>
|
||||
<li class="py-4 flex items-center justify-between space-x-4">
|
||||
<div class="flex flex-col">
|
||||
<p class="text-sm leading-5 font-medium text-gray-900 dark:text-gray-100">
|
||||
Import from <%= @site.imported_data.source %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 inline -mt-1 text-green-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<svg class="h-4 w-4 inline ml-1 -mt-1 text-green-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</p>
|
||||
<p class="text-sm leading-5 text-gray-500 dark:text-gray-200">
|
||||
<%= PlausibleWeb.EmailView.date_format(@site.imported_data.start_date) %> - <%= PlausibleWeb.EmailView.date_format(@site.imported_data.end_date) %>
|
||||
From <%= PlausibleWeb.EmailView.date_format(@site.imported_data.start_date) %> to <%= PlausibleWeb.EmailView.date_format(@site.imported_data.end_date) %>
|
||||
</p>
|
||||
</div>
|
||||
<%= link("Clear imported stats", to: "/#{URI.encode_www_form(@site.domain)}/settings/forget-imported", method: :delete, class: "inline-block mt-4 px-4 py-2 border border-gray-300 dark:border-gray-500 text-sm leading-5 font-medium rounded-md text-red-700 bg-white dark:bg-gray-800 hover:text-red-500 dark:hover:text-red-400 focus:outline-none focus:border-blue-300 focus:ring active:text-red-800 active:bg-gray-50 transition ease-in-out duration-150") %>
|
||||
<%= link("Clear " <> PlausibleWeb.StatsView.large_number_format(@imported_pageviews) <> " imported pageviews", to: "/#{URI.encode_www_form(@site.domain)}/settings/forget-imported", method: :delete, class: "inline-block mt-4 px-4 py-2 border border-gray-300 dark:border-gray-500 text-sm leading-5 font-medium rounded-md text-red-700 bg-white dark:bg-gray-800 hover:text-red-500 dark:hover:text-red-400 focus:outline-none focus:border-blue-300 focus:ring active:text-red-800 active:bg-gray-50 transition ease-in-out duration-150") %>
|
||||
</li>
|
||||
|
||||
<% @site.imported_data && @site.imported_data.status == "error" -> %>
|
||||
|
@ -46,6 +46,7 @@ defmodule Plausible.Workers.ImportGoogleAnalytics do
|
||||
site = Repo.preload(site, memberships: :user)
|
||||
|
||||
Plausible.Site.import_failure(site) |> Repo.update!()
|
||||
Plausible.ClickhouseRepo.clear_imported_stats_for(site.id)
|
||||
|
||||
Enum.each(site.memberships, fn membership ->
|
||||
if membership.role in [:owner, :admin] do
|
||||
|
@ -769,5 +769,41 @@ defmodule PlausibleWeb.SiteControllerTest do
|
||||
|
||||
assert Repo.reload(site).imported_data == nil
|
||||
end
|
||||
|
||||
test "removes actual imported data from Clickhouse", %{conn: conn, site: site} do
|
||||
Plausible.Site.start_import(site, ~D[2022-01-01], Timex.today(), "Google Analytics")
|
||||
|> Repo.update!()
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_visitors, pageviews: 10)
|
||||
])
|
||||
|
||||
delete(conn, "/#{site.domain}/settings/forget-imported")
|
||||
|
||||
assert Plausible.Stats.Clickhouse.imported_pageview_count(site) == 0
|
||||
end
|
||||
|
||||
test "cancels Oban job if it exists", %{conn: conn, site: site} do
|
||||
{:ok, job} =
|
||||
Plausible.Workers.ImportGoogleAnalytics.new(%{
|
||||
"site_id" => site.id,
|
||||
"view_id" => "123",
|
||||
"start_date" => "2022-01-01",
|
||||
"end_date" => "2023-01-01",
|
||||
"access_token" => "token"
|
||||
})
|
||||
|> Oban.insert()
|
||||
|
||||
Plausible.Site.start_import(site, ~D[2022-01-01], Timex.today(), "Google Analytics")
|
||||
|> Repo.update!()
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_visitors, pageviews: 10)
|
||||
])
|
||||
|
||||
delete(conn, "/#{site.domain}/settings/forget-imported")
|
||||
|
||||
assert Repo.reload(job).state == "cancelled"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,7 @@ defmodule Plausible.Workers.ImportGoogleAnalyticsTest do
|
||||
use Plausible.DataCase
|
||||
use Bamboo.Test
|
||||
import Double
|
||||
import Plausible.TestUtils
|
||||
alias Plausible.Workers.ImportGoogleAnalytics
|
||||
|
||||
@imported_data %Plausible.Site.ImportedData{
|
||||
@ -100,6 +101,39 @@ defmodule Plausible.Workers.ImportGoogleAnalyticsTest do
|
||||
assert Repo.reload!(site).imported_data.status == "error"
|
||||
end
|
||||
|
||||
test "clears any orphaned data during impot" do
|
||||
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
||||
site = insert(:site, members: [user], imported_data: @imported_data)
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_visitors, pageviews: 10)
|
||||
])
|
||||
|
||||
api_stub =
|
||||
stub(Plausible.Google.Api, :import_analytics, fn _site,
|
||||
_view_id,
|
||||
_start_date,
|
||||
_end_date,
|
||||
_access_token ->
|
||||
{:error, "Something went wrong"}
|
||||
end)
|
||||
|
||||
ImportGoogleAnalytics.perform(
|
||||
%Oban.Job{
|
||||
args: %{
|
||||
"site_id" => site.id,
|
||||
"view_id" => "view_id",
|
||||
"start_date" => "2020-01-01",
|
||||
"end_date" => "2022-01-01",
|
||||
"access_token" => "token"
|
||||
}
|
||||
},
|
||||
api_stub
|
||||
)
|
||||
|
||||
assert Plausible.Stats.Clickhouse.imported_pageview_count(site) == 0
|
||||
end
|
||||
|
||||
test "sends email to owner after failed import" do
|
||||
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
||||
site = insert(:site, members: [user], imported_data: @imported_data)
|
||||
|
Loading…
Reference in New Issue
Block a user