Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add netlify function for download statistics #383

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,13 @@ All the developers, contributors and community members of the BioImage.IO are re

## User Agreement
By using the BioImage.IO website and/or viewing material on the website, you agree to become bound by the terms of this [User Agreement](./docs/terms_of_service.md). If you do not agree to the Disclaimer, Terms of Use, and Privacy Statements of this User Agreement, do not use this website or any portion thereof in any form or manner.

## Development

Start a development server:

```bash
ntl dev
# or run without netlify functions:
npm run serve
```
8 changes: 8 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[dev]
command = "npm run serve"
autoLaunch = false
targetPort = 8080
port = 8083
[build]
publish = "dist"
functions = "netlify/functions"
48 changes: 48 additions & 0 deletions netlify/functions/download.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const axios = require('axios');

// example url: https://bioimage.netlify.app/.netlify/functions/download/10.5281/zenodo.5764892/files/weights.onnx?debug=1
exports.handler = async function(event, context) {
const queryParams = event.queryStringParameters;
const uadata = queryParams.uadata || '{"brands":[{"brand":"unknown","version":"unknown"}]}';

// Extracting the initial DOI from the path, assuming path format and initial parsing logic
const pathSegments = event.path.split('/').filter(segment => segment);
if (pathSegments.length < 7) {
return { statusCode: 400, body: JSON.stringify({ message: "Invalid path format." }) };
}
const doi = `${pathSegments[3]}/${pathSegments[4]}`; // Combines "10.5281" and "zenodo.XXXXX"
const initialDoiUrl = `https://doi.org/${doi}`;

try {
// Attempt to resolve the DOI URL without following redirects
const response = await axios.get(initialDoiUrl, { maxRedirects: 0, validateStatus: status => status >= 300 && status < 400 });
const finalZenodoUrl = response.headers.location;

// Extract Zenodo version ID from the redirect URL
const zenodoVersionIdMatch = finalZenodoUrl.match(/record\/(\d+)/);

if (!zenodoVersionIdMatch || !zenodoVersionIdMatch[1]) {
return { statusCode: 500, body: JSON.stringify({ message: "Failed to extract Zenodo version ID.", pathSegments, finalZenodoUrl, zenodoVersionIdMatch}) };
}
const zenodoVersionId = zenodoVersionIdMatch[1];

// Update the DOI and construct URLs with the specific version ID
const updatedDoi = `10.5281/zenodo.${zenodoVersionId}`;
const filePath = pathSegments.slice(6).join('/');
const actualFileUrl = `https://zenodo.org/api/records/${zenodoVersionId}/files/${filePath}/content`;
const matomoReportUrl = `https://bioimage.matomo.cloud/matomo.php?download=https://doi.org/${updatedDoi}&idsite=1&rec=1&r=646242&h=13&m=35&s=20&url=http://bioimage.io/#/?id=${updatedDoi}&uadata=${encodeURIComponent(uadata)}`;

if (queryParams.debug) {
return { statusCode: 200, body: JSON.stringify({ actualFileUrl, matomoReportUrl }) };
}

// Log the download event to Matomo
await axios.get(matomoReportUrl);

// Redirect to the actual file URL
return { statusCode: 302, headers: { 'Location': actualFileUrl } };
} catch (error) {
// Handle errors during the DOI resolution process or HTTP requests
return { statusCode: 500, body: JSON.stringify({ message: "Error during processing.", error: error.message }) };
}
};
Loading