Include domain and dates in zip archive filename (#3921)

* include domain and dates in zip archive filename

* adapt to comments
This commit is contained in:
ruslandoga 2024-03-21 18:35:42 +08:00 committed by GitHub
parent 32ab138301
commit 5f9465614b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 4 deletions

View File

@ -6,6 +6,22 @@ defmodule Plausible.Exports do
require Plausible
import Ecto.Query
@doc """
Renders filename for the Zip archive containing the exported CSV files.
Examples:
iex> archive_filename("plausible.io", ~D[2021-01-01], ~D[2024-12-31])
"plausible.io_20210101_20241231.zip"
iex> archive_filename("Bücher.example", ~D[2021-01-01], ~D[2024-12-31])
"Bücher.example_20210101_20241231.zip"
"""
def archive_filename(domain, min_date, max_date) do
"#{domain}_#{Calendar.strftime(min_date, "%Y%m%d")}_#{Calendar.strftime(max_date, "%Y%m%d")}.zip"
end
@doc """
Builds Ecto queries to export data from `events_v2` and `sessions_v2`
tables into the format of `imported_*` tables for a website.

View File

@ -84,15 +84,25 @@ defmodule Plausible.S3 do
In the current implementation the bucket always goes into the path component.
"""
@spec export_upload_multipart(Enumerable.t(), String.t(), Path.t(), keyword) ::
@spec export_upload_multipart(Enumerable.t(), String.t(), Path.t(), String.t(), keyword) ::
:uri_string.uri_string()
def export_upload_multipart(stream, s3_bucket, s3_path, config_overrides \\ []) do
def export_upload_multipart(stream, s3_bucket, s3_path, filename, config_overrides \\ []) do
config = ExAws.Config.new(:s3)
encoded_filename = URI.encode(filename)
disposition = ~s[attachment; filename="#{encoded_filename}"]
disposition =
if encoded_filename != filename do
disposition <> "; filename*=utf-8''#{encoded_filename}"
else
disposition
end
# 5 MiB is the smallest chunk size AWS S3 supports
chunk_into_parts(stream, 5 * 1024 * 1024)
|> ExAws.S3.upload(s3_bucket, s3_path,
content_disposition: ~s|attachment; filename="Plausible.zip"|,
content_disposition: disposition,
content_type: "application/zip"
)
|> ExAws.request!(config_overrides)

View File

@ -23,6 +23,14 @@ defmodule Plausible.Sites do
Repo.get_by!(Site, domain: domain)
end
def get_domain!(site_id) do
Plausible.Repo.one!(
from s in Plausible.Site,
where: [id: ^site_id],
select: s.domain
)
end
@spec toggle_pin(Auth.User.t(), Site.t()) ::
{:ok, Site.UserPreference.t()} | {:error, :too_many_pins}
def toggle_pin(user, site) do

View File

@ -43,6 +43,10 @@ defmodule Plausible.Workers.ExportCSV do
)
)
else
domain = Plausible.Sites.get_domain!(site_id)
export_archive_filename = Plausible.Exports.archive_filename(domain, min_date, max_date)
s3_config_overrides = s3_config_overrides(args)
download_url =
DBConnection.run(
ch,
@ -55,7 +59,12 @@ defmodule Plausible.Workers.ExportCSV do
),
format: "CSVWithNames"
)
|> Plausible.S3.export_upload_multipart(s3_bucket, s3_path, s3_config_overrides(args))
|> Plausible.S3.export_upload_multipart(
s3_bucket,
s3_path,
export_archive_filename,
s3_config_overrides
)
end,
timeout: :infinity
)

View File

@ -1,6 +1,8 @@
defmodule Plausible.ExportsTest do
use Plausible.DataCase, async: true
doctest Plausible.Exports, import: true
# for e2e export->import tests please see Plausible.Imported.CSVImporterTest
describe "export_queries/2" do