mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 17:33:14 +01:00
Merge pull request #153 from ascribe/fix-digital-work-file-name
Fix digital work file name download
This commit is contained in:
commit
5b79648385
103
js/components/ascribe_buttons/s3_download_button.js
Normal file
103
js/components/ascribe_buttons/s3_download_button.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import S3Fetcher from '../../fetchers/s3_fetcher';
|
||||||
|
|
||||||
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
|
|
||||||
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
import { queryParamsToArgs } from '../../utils/url_utils';
|
||||||
|
|
||||||
|
|
||||||
|
const { string } = React.PropTypes;
|
||||||
|
|
||||||
|
const S3DownloadButton = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
url: string,
|
||||||
|
title: string,
|
||||||
|
artistName: string,
|
||||||
|
fileExtension: string
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState() {
|
||||||
|
return {
|
||||||
|
downloadUrl: null,
|
||||||
|
signatureExpiryTimerId: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
/**
|
||||||
|
* Initially, we request a signed url from
|
||||||
|
* the backend
|
||||||
|
*/
|
||||||
|
this.signUrl();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.clearInterval(this.state.signatureExpiryTimerId);
|
||||||
|
},
|
||||||
|
|
||||||
|
transformS3UrlToS3Key(url) {
|
||||||
|
return url.replace(`https://${AppConstants.cloudfrontDomain}/`, '');
|
||||||
|
},
|
||||||
|
|
||||||
|
signUrl() {
|
||||||
|
const { url, title, artistName } = this.props;
|
||||||
|
|
||||||
|
S3Fetcher
|
||||||
|
.signUrl(this.transformS3UrlToS3Key(url), title, artistName)
|
||||||
|
.then(({ signed_url: downloadUrl }) => {
|
||||||
|
const { signatureExpiryTimerId } = this.state;
|
||||||
|
let newState = { downloadUrl };
|
||||||
|
|
||||||
|
if(!signatureExpiryTimerId) {
|
||||||
|
/**
|
||||||
|
* The signed url, however can expire, which is why
|
||||||
|
* we need to renew it when it expires.
|
||||||
|
*/
|
||||||
|
const expires = parseInt(queryParamsToArgs(downloadUrl.split('?')[1]).expires, 10);
|
||||||
|
const now = new Date().getTime() / 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amazon uses seconds as their signature unix timestamp
|
||||||
|
* while `setInterval` uses milliseconds. Therefore we need to
|
||||||
|
* multiply with 1000.
|
||||||
|
*/
|
||||||
|
const interval = (expires - now) * 1000;
|
||||||
|
|
||||||
|
Object.assign(newState, {
|
||||||
|
// Substract 5s to make sure there is a big enough window to sign again before expiration
|
||||||
|
signatureExpiryTimerId: window.setInterval(this.signUrl, interval - 5000)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.setState(newState);
|
||||||
|
})
|
||||||
|
.catch(console.logGlobal);
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { fileExtension, url } = this.props;
|
||||||
|
const { downloadUrl } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
ref="downloadButton"
|
||||||
|
download
|
||||||
|
className="btn btn-xs btn-default ascribe-margin-1px"
|
||||||
|
target="_blank"
|
||||||
|
href={downloadUrl || url}>
|
||||||
|
{/*
|
||||||
|
If it turns out that `fileExtension` is an empty string, we're just
|
||||||
|
using the label 'file'.
|
||||||
|
*/}
|
||||||
|
{getLangText('Download')} .{fileExtension || 'file'} <Glyphicon glyph="cloud-download" />
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default S3DownloadButton;
|
@ -3,13 +3,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
|
||||||
|
|
||||||
import MediaPlayer from './../ascribe_media/media_player';
|
import MediaPlayer from './../ascribe_media/media_player';
|
||||||
|
|
||||||
import FacebookShareButton from '../ascribe_social_share/facebook_share_button';
|
import FacebookShareButton from '../ascribe_social_share/facebook_share_button';
|
||||||
import TwitterShareButton from '../ascribe_social_share/twitter_share_button';
|
import TwitterShareButton from '../ascribe_social_share/twitter_share_button';
|
||||||
|
|
||||||
|
import S3DownloadButton from '../ascribe_buttons/s3_download_button';
|
||||||
|
|
||||||
import CollapsibleButton from './../ascribe_collapsible/collapsible_button';
|
import CollapsibleButton from './../ascribe_collapsible/collapsible_button';
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import AclProxy from '../acl_proxy';
|
||||||
@ -131,17 +132,11 @@ let MediaContainer = React.createClass({
|
|||||||
show={['video', 'audio', 'image'].indexOf(mimetype) === -1 || content.acl.acl_download}
|
show={['video', 'audio', 'image'].indexOf(mimetype) === -1 || content.acl.acl_download}
|
||||||
aclObject={content.acl}
|
aclObject={content.acl}
|
||||||
aclName="acl_download">
|
aclName="acl_download">
|
||||||
<Button
|
<S3DownloadButton
|
||||||
bsSize="xsmall"
|
url={content.digital_work.url}
|
||||||
className="ascribe-margin-1px"
|
title={content.title}
|
||||||
href={content.digital_work.url}
|
artistName={content.artist_name}
|
||||||
target="_blank">
|
fileExtension={fileExtension} />
|
||||||
{/*
|
|
||||||
If it turns out that `fileExtension` is an empty string, we're just
|
|
||||||
using the label 'file'.
|
|
||||||
*/}
|
|
||||||
{getLangText('Download')} .{fileExtension || 'file'} <Glyphicon glyph="cloud-download" />
|
|
||||||
</Button>
|
|
||||||
</AclProxy>
|
</AclProxy>
|
||||||
{embed}
|
{embed}
|
||||||
</p>
|
</p>
|
||||||
|
@ -76,7 +76,8 @@ let ApiUrls = {
|
|||||||
'webhooks': AppConstants.apiEndpoint + 'webhooks/',
|
'webhooks': AppConstants.apiEndpoint + 'webhooks/',
|
||||||
'webhooks_events': AppConstants.apiEndpoint + 'webhooks/events/',
|
'webhooks_events': AppConstants.apiEndpoint + 'webhooks/events/',
|
||||||
'whitelabel_settings': AppConstants.apiEndpoint + 'whitelabel/settings/${subdomain}/',
|
'whitelabel_settings': AppConstants.apiEndpoint + 'whitelabel/settings/${subdomain}/',
|
||||||
'delete_s3_file': AppConstants.serverUrl + 's3/delete/'
|
'delete_s3_file': AppConstants.serverUrl + 's3/delete/',
|
||||||
|
'sign_url_s3': AppConstants.serverUrl + 's3/sign_url/'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ const constants = {
|
|||||||
'twitter': {
|
'twitter': {
|
||||||
'sdkUrl': 'https://platform.twitter.com/widgets.js'
|
'sdkUrl': 'https://platform.twitter.com/widgets.js'
|
||||||
},
|
},
|
||||||
|
'cloudfrontDomain': 'd1qjsxua1o9x03.cloudfront.net',
|
||||||
'errorMessagesToIgnore': [
|
'errorMessagesToIgnore': [
|
||||||
'Authentication credentials were not provided.',
|
'Authentication credentials were not provided.',
|
||||||
'Informations d\'authentification non fournies.'
|
'Informations d\'authentification non fournies.'
|
||||||
|
@ -11,6 +11,13 @@ let S3Fetcher = {
|
|||||||
key,
|
key,
|
||||||
bucket
|
bucket
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
signUrl(key, title, artistName) {
|
||||||
|
return requests.get('sign_url_s3', {
|
||||||
|
key,
|
||||||
|
title,
|
||||||
|
'artist_name': artistName
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,10 +34,6 @@ class NotificationStore {
|
|||||||
this.editionListNotifications = res.notifications;
|
this.editionListNotifications = res.notifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
onFlushPieceListNotifications() {
|
|
||||||
this.editionListNotifications = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
onUpdateEditionNotifications(res) {
|
onUpdateEditionNotifications(res) {
|
||||||
this.editionNotifications = res.notification;
|
this.editionNotifications = res.notification;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ class Requests {
|
|||||||
}
|
}
|
||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getUrl(url) {
|
getUrl(url) {
|
||||||
|
Loading…
Reference in New Issue
Block a user