Skip to content
6 changes: 2 additions & 4 deletions src/client/app/redux/thunks/exportThunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { createAppThunk } from './appThunk';
import { selectAnythingFetching } from '../../redux/selectors/apiSelectors';
import { RootState } from '../../store';
import { find, sortBy } from 'lodash';
import { estimateRawExportSizeMB } from '../../../../common/RawExportFileSize';

const selectCanExport = (state: RootState) => {
const fetchInProgress = selectAnythingFetching(state);
Expand Down Expand Up @@ -134,10 +135,7 @@ export const exportRawReadings = createAppThunk(
// the wrong value. The time to do this is small compared to most raw exports (if file is large
// when it matters).
const count = await dispatch(metersApi.endpoints.lineReadingsCount.initiate({ meterIDs, timeInterval })).unwrap();
// Estimated file size in MB. Note that changing the language effects the size about +/- 8%.
// This is just a decent estimate for larger files.
// This estimate is also present in src/server/routes/readings.js and must be kept consistent between files.
const fileSize = (count * 0.082 / 1000);
const fileSize = estimateRawExportSizeMB(count);
// Decides if the readings should be exported, true if should.
let shouldDownload = false;
if (fileSize <= adminState.defaultWarningFileSize) {
Expand Down
14 changes: 14 additions & 0 deletions src/common/RawExportFileSize.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

/**
* Estimates the size of a raw export in MB based on the number of readings.
* Note that changing the language effects the size about +/- 8%.
* This is just a decent estimate for larger files.
* @param readingCount - The number of readings to estimate.
* @returns The estimated size in MB.
*/
export function estimateRawExportSizeMB(readingCount: number): number;
22 changes: 22 additions & 0 deletions src/common/RawExportFileSize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

const ESTIMATED_MB_PER_RAW_READING = 8.2e-5;

/**

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a blank line before the JSDco.

* Estimates the size of a raw export in MB based on the number of readings.
* Note that changing the language effects the size about +/- 8%.
* This is just a decent estimate for larger files.
* @param readingCount - The number of readings to estimate.
* @returns The estimated size in MB.
*/
function estimateRawExportSizeMB(readingCount) {
return readingCount * ESTIMATED_MB_PER_RAW_READING;
}

module.exports = {
estimateRawExportSizeMB
};
5 changes: 2 additions & 3 deletions src/server/routes/readings.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const { isTokenAuthorized } = require('../util/userRoles');
const Preferences = require('../models/Preferences');
const User = require('../models/User');
const { success, failure } = require('./response');
const { estimateRawExportSizeMB } = require('../../common/RawExportFileSize');

const router = express.Router();

Expand Down Expand Up @@ -111,11 +112,9 @@ router.get('/line/raw/meter/:meter_id', optionalAuthMiddleware, async (req, res)
timeInterval = TimeInterval.fromString(req.query.timeInterval);
// Check if user is allowed to export.
let shouldDownload = false;
// Estimated file size. The full explanation of the estimate used can be found in the client.
// This estimate is also present in src/client/app/redux/thunks/exportThunk.ts and must be kept consistent between files.
// This count only checks a single meterID, while client testing checks multiple meterIDs, so the estimate is slightly different.
const count = await Reading.getCountByMeterIDAndDateRange(meterID, timeInterval.startTimestamp, timeInterval.endTimestamp, conn);
const fileSize = (count * 0.082 / 1000);
const fileSize = estimateRawExportSizeMB(count);
const preferences = await Preferences.get(conn);
if (fileSize <= preferences.defaultFileSizeLimit) {
// File size within limit, anyone can download.
Expand Down
27 changes: 27 additions & 0 deletions src/server/test/util/rawExportFileSizeTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

const { expect, mocha } = require('../common');
const { estimateRawExportSizeMB } = require('../../../common/RawExportFileSize');
const DELTA = 1e-15;

mocha.describe('Raw Export File Size Estimator', () => {
mocha.it('returns zero for zero readings', () => {
expect(estimateRawExportSizeMB(0)).to.be.closeTo(0, DELTA);
});

mocha.it('returns 0.082 MB for 1000 readings', () => {
expect(estimateRawExportSizeMB(1000)).to.be.closeTo(0.082, DELTA);
});

mocha.it('returns 0.11808 MB for 1440 readings', () => {
expect(estimateRawExportSizeMB(1440)).to.be.closeTo(0.11808, DELTA);
});

mocha.it('returns 0.71832 MB for 8760 readings', () => {
expect(estimateRawExportSizeMB(8760)).to.be.closeTo(0.71832, DELTA);
});
});
Loading