Provide GPX download from track page

This commit is contained in:
Paul Bienkowski 2022-02-25 11:53:28 +01:00
parent a71dadfc7f
commit 70fa1a41c4
3 changed files with 25 additions and 6 deletions

View file

@ -214,6 +214,24 @@ async def download_original_file(req, slug: str):
) )
@api.get("/tracks/<slug:str>/download/track.gpx")
async def download_track_gpx(req, slug: str):
track = await _load_track(req, slug)
if not track.is_visible_to(req.ctx.user):
raise Forbidden()
file_path = join(req.app.config.PROCESSING_OUTPUT_DIR, track.file_path, "track.gpx")
if not exists(file_path) or not isfile(file_path):
raise NotFound()
return await file_stream(
file_path,
mime_type="application/gpx+xml",
filename=f"{slug}.gpx",
)
@api.put("/tracks/<slug:str>") @api.put("/tracks/<slug:str>")
@require_auth @require_auth
async def put_track(req, slug: str): async def put_track(req, slug: str):

View file

@ -2,11 +2,11 @@ import React from 'react'
import {Link} from 'react-router-dom' import {Link} from 'react-router-dom'
import {Icon, Popup, Button, Dropdown} from 'semantic-ui-react' import {Icon, Popup, Button, Dropdown} from 'semantic-ui-react'
export default function TrackActions({slug, isAuthor, onDownloadOriginal}) { export default function TrackActions({slug, isAuthor, onDownload}) {
return ( return (
<> <>
{isAuthor ? ( {isAuthor ? (
<Dropdown text="Download" button> <Dropdown text="Download" button upward>
<Dropdown.Menu> <Dropdown.Menu>
<Popup <Popup
content={ content={
@ -18,8 +18,9 @@ export default function TrackActions({slug, isAuthor, onDownloadOriginal}) {
</p> </p>
</> </>
} }
trigger={<Dropdown.Item text="Original" onClick={onDownloadOriginal} />} trigger={<Dropdown.Item text="Original" onClick={() => onDownload('original.csv')} />}
/> />
<Dropdown.Item text="Track (GPX)" onClick={() => onDownload('track.gpx')} />
</Dropdown.Menu> </Dropdown.Menu>
</Dropdown> </Dropdown>
) : ( ) : (

View file

@ -145,8 +145,8 @@ const TrackPage = connect((state) => ({login: state.login}))(function TrackPage(
[slug, reloadComments] [slug, reloadComments]
) )
const onDownloadOriginal = React.useCallback(() => { const onDownload= React.useCallback((filename) => {
api.downloadFile(`/tracks/${slug}/download/original.csv`) api.downloadFile(`/tracks/${slug}/download/${filename}`)
}, [slug]) }, [slug])
const isAuthor = login?.username === data?.track?.author?.username const isAuthor = login?.username === data?.track?.author?.username
@ -191,7 +191,7 @@ const TrackPage = connect((state) => ({login: state.login}))(function TrackPage(
<> <>
<Header as="h1">{track.title || 'Unnamed track'}</Header> <Header as="h1">{track.title || 'Unnamed track'}</Header>
<TrackDetails {...{track, isAuthor}} /> <TrackDetails {...{track, isAuthor}} />
<TrackActions {...{isAuthor, onDownloadOriginal, slug}} /> <TrackActions {...{isAuthor, onDownload, slug}} />
</> </>
)} )}
</Segment> </Segment>