From 3dac3cb4e2cbbfc9473d2ca73349d516a63d883a Mon Sep 17 00:00:00 2001
From: "Fabien \"egg\" O'Carroll"
Date: Fri, 7 Apr 2023 12:52:37 +0700
Subject: [PATCH 1/5] Added fetchAndDownloadFile method to utils service
The existing approach didn't expose when the download was complete.
By fetching the file upfront and downloading from a blob we can better
estimate when the download is complete because we load the file in
memory, and then download from there.
The promise resolves after the file is in memory, so the delay between
the promise resolving and the file actually being downloaded is a lot
shorter, and based on the size of the file.
---
ghost/admin/app/services/utils.js | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/ghost/admin/app/services/utils.js b/ghost/admin/app/services/utils.js
index a173c38002..4a02af6ab8 100644
--- a/ghost/admin/app/services/utils.js
+++ b/ghost/admin/app/services/utils.js
@@ -1,4 +1,5 @@
import Service from '@ember/service';
+import fetch from 'fetch';
export default class UtilsService extends Service {
downloadFile(url) {
@@ -14,6 +15,29 @@ export default class UtilsService extends Service {
iframe.setAttribute('src', url);
}
+ /**
+ * This method will fetch a file from the server and then download it, resolving
+ * once the initial fetch is complete, allowing it to be used with loading spinners.
+ *
+ * @param {string} url - The URL of the file to download
+ * @returns {Promise}
+ */
+ async fetchAndDownloadFile(url) {
+ const response = await fetch(url);
+ const blob = await response.blob();
+
+ const anchor = document.createElement('a');
+
+ anchor.href = window.URL.createObjectURL(blob);
+ anchor.download = /filename="(.*)"/.exec(response.headers.get('Content-Disposition'))[1];
+
+ document.body.append(anchor);
+
+ anchor.click();
+
+ document.body.removeChild(anchor);
+ }
+
/**
* Remove tracking parameters from a URL
* @param {string} url
From a890f0b707c39c35c895db926dd4a9cdf97a341f Mon Sep 17 00:00:00 2001
From: "Fabien \"egg\" O'Carroll"
Date: Fri, 7 Apr 2023 12:54:31 +0700
Subject: [PATCH 2/5] Updated the posts export button to be a GhTaskButton
refs https://github.com/TryGhost/Team/issues/2935
This allows us to track the state with a loading spinner and a
success/error message on completion. This is expecially important for
larger sites where the download can take a long time, and users are
unsure if something is happening.
---
ghost/admin/app/components/settings/analytics.hbs | 4 +---
ghost/admin/app/components/settings/analytics.js | 9 ++++++---
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/ghost/admin/app/components/settings/analytics.hbs b/ghost/admin/app/components/settings/analytics.hbs
index 4c808e648f..b82481018e 100644
--- a/ghost/admin/app/components/settings/analytics.hbs
+++ b/ghost/admin/app/components/settings/analytics.hbs
@@ -110,9 +110,7 @@
Download a CSV file of all your post data for easy analysis in one place
-
+
diff --git a/ghost/admin/app/components/settings/analytics.js b/ghost/admin/app/components/settings/analytics.js
index c7f40b0625..34d4ca4fc4 100644
--- a/ghost/admin/app/components/settings/analytics.js
+++ b/ghost/admin/app/components/settings/analytics.js
@@ -2,6 +2,7 @@ import Component from '@glimmer/component';
import ghostPaths from 'ghost-admin/utils/ghost-paths';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';
+import {task} from 'ember-concurrency';
export default class Analytics extends Component {
@service settings;
@@ -16,13 +17,15 @@ export default class Analytics extends Component {
this.settings.emailTrackOpens = !this.settings.emailTrackOpens;
}
- @action
- exportData() {
+ @task
+ *exportPostsTask() {
let exportUrl = ghostPaths().url.api('posts/export');
let downloadParams = new URLSearchParams();
downloadParams.set('limit', 'all');
- this.utils.downloadFile(`${exportUrl}?${downloadParams.toString()}`);
+ yield this.utils.fetchAndDownloadFile(`${exportUrl}?${downloadParams.toString()}`);
+
+ return true;
}
@action
From c99016fd2fca58eaacbebb9dca6c974aabaa67f6 Mon Sep 17 00:00:00 2001
From: "Fabien \"egg\" O'Carroll"
Date: Fri, 7 Apr 2023 13:24:59 +0700
Subject: [PATCH 3/5] Limited post export size to 1000 posts
refs https://github.com/TryGhost/Team/issues/2936
We want to make sure that downloads complete in a reasonable number of
time, and the simplest way to do that is to cap the size of the file.
---
ghost/admin/app/components/settings/analytics.hbs | 2 +-
ghost/admin/app/components/settings/analytics.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ghost/admin/app/components/settings/analytics.hbs b/ghost/admin/app/components/settings/analytics.hbs
index b82481018e..8fb4a1db77 100644
--- a/ghost/admin/app/components/settings/analytics.hbs
+++ b/ghost/admin/app/components/settings/analytics.hbs
@@ -107,7 +107,7 @@
Export post analytics
- Download a CSV file of all your post data for easy analysis in one place
+ Download a CSV file of your last 1000 posts data for easy analysis in one place