Merge branch 'release-v0.6.2'
12
CHANGELOG.md
@ -1,5 +1,17 @@
|
||||
# Change log
|
||||
|
||||
## Version 0.6.2 (2022/04/03)
|
||||
|
||||
### Issues Closed
|
||||
|
||||
#### Bugs Fixed
|
||||
|
||||
* [#175](https://github.com/SamR1/FitTrackee/issues/175) - Distance card on dashboard is not refreshed
|
||||
* [#173](https://github.com/SamR1/FitTrackee/issues/173) - link to user profile in workout card is incorrect
|
||||
|
||||
In this release 2 issues were closed.
|
||||
|
||||
|
||||
## Version 0.6.1 (2022/03/27)
|
||||
|
||||
### Issues Closed
|
||||
|
@ -3,14 +3,14 @@
|
||||
|
||||
[![PyPI version](https://img.shields.io/pypi/v/fittrackee.svg)](https://pypi.org/project/fittrackee/)
|
||||
[![Python Version](https://img.shields.io/badge/python-3.7+-brightgreen.svg)](https://python.org)
|
||||
[![Flask Version](https://img.shields.io/badge/flask-2.0-brightgreen.svg)](http://flask.pocoo.org/)
|
||||
[![Flask Version](https://img.shields.io/badge/flask-2.1-brightgreen.svg)](http://flask.pocoo.org/)
|
||||
[![code style: black](https://img.shields.io/badge/code%20style-black-black)](https://github.com/psf/black)
|
||||
[![type check: mypy](https://img.shields.io/badge/type%20check-mypy-blue)](http://mypy-lang.org/)
|
||||
[![Vue Version](https://img.shields.io/badge/vue-3.2-brightgreen.svg)](https://v3.vuejs.org/)
|
||||
[![Typescript Version](https://img.shields.io/npm/types/typescript)](https://www.typescriptlang.org/)
|
||||
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
|
||||
![pipeline status](https://github.com/SamR1/FitTrackee/actions/workflows/.tests-python.yml/badge.svg?branch=master)
|
||||
![pipeline status](https://github.com/SamR1/FitTrackee/actions/workflows/.tests-javascript.yml/badge.svg?branch=master)
|
||||
[![pipeline status](https://github.com/SamR1/FitTrackee/actions/workflows/.tests-python.yml/badge.svg?branch=master)](https://github.com/SamR1/FitTrackee/actions/workflows/.tests-python.yml)
|
||||
[![pipeline status](https://github.com/SamR1/FitTrackee/actions/workflows/.tests-javascript.yml/badge.svg?branch=master)](https://github.com/SamR1/FitTrackee/actions/workflows/.tests-javascript.yml)
|
||||
|
||||
|
||||
---
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Sphinx build info version 1
|
||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||
config: 61330c9d18ff48d9802f7a0c5ced8d16
|
||||
config: 2ca26683378198d52362ecd6dd5b71fe
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||
|
Before Width: | Height: | Size: 538 KiB After Width: | Height: | Size: 539 KiB |
Before Width: | Height: | Size: 368 KiB After Width: | Height: | Size: 368 KiB |
Before Width: | Height: | Size: 201 KiB After Width: | Height: | Size: 202 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 103 KiB |
@ -1,5 +1,17 @@
|
||||
# Change log
|
||||
|
||||
## Version 0.6.2 (2022/04/03)
|
||||
|
||||
### Issues Closed
|
||||
|
||||
#### Bugs Fixed
|
||||
|
||||
* [#175](https://github.com/SamR1/FitTrackee/issues/175) - Distance card on dashboard is not refreshed
|
||||
* [#173](https://github.com/SamR1/FitTrackee/issues/173) - link to user profile in workout card is incorrect
|
||||
|
||||
In this release 2 issues were closed.
|
||||
|
||||
|
||||
## Version 0.6.1 (2022/03/27)
|
||||
|
||||
### Issues Closed
|
||||
|
@ -369,13 +369,13 @@ Production environment
|
||||
.. warning::
|
||||
| Note that FitTrackee is under heavy development, some features may be unstable.
|
||||
|
||||
- Download the last release (for now, it is the release v0.6.1):
|
||||
- Download the last release (for now, it is the release v0.6.2):
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.1.tar.gz
|
||||
$ tar -xzf v0.6.1.tar.gz
|
||||
$ mv FitTrackee-0.6.1 FitTrackee
|
||||
$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.2.tar.gz
|
||||
$ tar -xzf v0.6.2.tar.gz
|
||||
$ mv FitTrackee-0.6.2 FitTrackee
|
||||
$ cd FitTrackee
|
||||
|
||||
- Create **.env** from example and update it
|
||||
@ -493,13 +493,13 @@ Prod environment
|
||||
|
||||
- Change to the directory where FitTrackee directory is located
|
||||
|
||||
- Download the last release (for now, it is the release v0.6.1) and overwrite existing files:
|
||||
- Download the last release (for now, it is the release v0.6.2) and overwrite existing files:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.1.tar.gz
|
||||
$ tar -xzf v0.6.1.tar.gz
|
||||
$ cp -R FitTrackee-0.6.1/* FitTrackee/
|
||||
$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.2.tar.gz
|
||||
$ tar -xzf v0.6.2.tar.gz
|
||||
$ cp -R FitTrackee-0.6.2/* FitTrackee/
|
||||
$ cd FitTrackee
|
||||
|
||||
- Update **.env** if needed (see `Environment variables <installation.html#environment-variables>`__).
|
||||
|
72
docs/_static/doctools.js
vendored
@ -154,9 +154,7 @@ var Documentation = {
|
||||
this.fixFirefoxAnchorBug();
|
||||
this.highlightSearchWords();
|
||||
this.initIndexTable();
|
||||
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
|
||||
this.initOnKeyListeners();
|
||||
}
|
||||
this.initOnKeyListeners();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -269,6 +267,13 @@ var Documentation = {
|
||||
window.history.replaceState({}, '', url);
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to focus on search bar
|
||||
*/
|
||||
focusSearchBar : function() {
|
||||
$('input[name=q]').first().focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* make the url absolute
|
||||
*/
|
||||
@ -291,27 +296,54 @@ var Documentation = {
|
||||
},
|
||||
|
||||
initOnKeyListeners: function() {
|
||||
// only install a listener if it is really needed
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
|
||||
!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
|
||||
return;
|
||||
|
||||
$(document).keydown(function(event) {
|
||||
var activeElementType = document.activeElement.tagName;
|
||||
// don't navigate when in search box, textarea, dropdown or button
|
||||
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
|
||||
&& activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey
|
||||
&& !event.shiftKey) {
|
||||
switch (event.keyCode) {
|
||||
case 37: // left
|
||||
var prevHref = $('link[rel="prev"]').prop('href');
|
||||
if (prevHref) {
|
||||
window.location.href = prevHref;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 39: // right
|
||||
var nextHref = $('link[rel="next"]').prop('href');
|
||||
if (nextHref) {
|
||||
window.location.href = nextHref;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
&& activeElementType !== 'BUTTON') {
|
||||
if (event.altKey || event.ctrlKey || event.metaKey)
|
||||
return;
|
||||
|
||||
if (!event.shiftKey) {
|
||||
switch (event.key) {
|
||||
case 'ArrowLeft':
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS)
|
||||
break;
|
||||
var prevHref = $('link[rel="prev"]').prop('href');
|
||||
if (prevHref) {
|
||||
window.location.href = prevHref;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS)
|
||||
break;
|
||||
var nextHref = $('link[rel="next"]').prop('href');
|
||||
if (nextHref) {
|
||||
window.location.href = nextHref;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'Escape':
|
||||
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
|
||||
break;
|
||||
Documentation.hideSearchWords();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// some keyboard layouts may need Shift to get /
|
||||
switch (event.key) {
|
||||
case '/':
|
||||
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
|
||||
break;
|
||||
Documentation.focusSearchBar();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
6
docs/_static/documentation_options.js
vendored
@ -1,6 +1,6 @@
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '0.6.1',
|
||||
VERSION: '0.6.2',
|
||||
LANGUAGE: 'None',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
@ -8,5 +8,7 @@ var DOCUMENTATION_OPTIONS = {
|
||||
LINK_SUFFIX: '.html',
|
||||
HAS_SOURCE: true,
|
||||
SOURCELINK_SUFFIX: '.txt',
|
||||
NAVIGATION_WITH_KEYS: false
|
||||
NAVIGATION_WITH_KEYS: false,
|
||||
SHOW_SEARCH_SUMMARY: true,
|
||||
ENABLE_SEARCH_SHORTCUTS: true,
|
||||
};
|
8
docs/_static/searchtools.js
vendored
@ -172,10 +172,6 @@ var Search = {
|
||||
}
|
||||
// stem the word
|
||||
var word = stemmer.stemWord(tmp[i].toLowerCase());
|
||||
// prevent stemmer from cutting word smaller than two chars
|
||||
if(word.length < 3 && tmp[i].length >= 3) {
|
||||
word = tmp[i];
|
||||
}
|
||||
var toAppend;
|
||||
// select the correct list
|
||||
if (word[0] == '-') {
|
||||
@ -276,7 +272,7 @@ var Search = {
|
||||
setTimeout(function() {
|
||||
displayNextItem();
|
||||
}, 5);
|
||||
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
|
||||
} else if (DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY) {
|
||||
$.ajax({url: requestUrl,
|
||||
dataType: "text",
|
||||
complete: function(jqxhr, textstatus) {
|
||||
@ -293,7 +289,7 @@ var Search = {
|
||||
}, 5);
|
||||
}});
|
||||
} else {
|
||||
// no source available, just display title
|
||||
// just display title
|
||||
Search.output.append(listItem);
|
||||
setTimeout(function() {
|
||||
displayNextItem();
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Authentication — FitTrackee 0.6.1
|
||||
<title>Authentication — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -628,8 +628,9 @@ character “_” allowed</p></li>
|
||||
<dt class="field-odd">Request JSON Object</dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>timezone</strong> (<em>string</em>) – user time zone</p></li>
|
||||
<li><p><strong>weekm</strong> (<em>string</em>) – does week start on Monday?</p></li>
|
||||
<li><p><strong>weekm</strong> (<em>boolean</em>) – does week start on Monday?</p></li>
|
||||
<li><p><strong>language</strong> (<em>string</em>) – language preferences</p></li>
|
||||
<li><p><strong>imperial_units</strong> (<em>boolean</em>) – display distance in imperial units</p></li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="field-even">Request Headers</dt>
|
||||
@ -1103,7 +1104,7 @@ character “_” allowed</p></li>
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Configuration — FitTrackee 0.6.1
|
||||
<title>Configuration — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -142,13 +142,14 @@
|
||||
|
||||
<span class="p">{</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"admin_contact"</span><span class="p">:</span><span class="w"> </span><span class="s2">"admin@example.com"</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"gpx_limit_import"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"is_registration_enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"max_single_file_size"</span><span class="p">:</span><span class="w"> </span><span class="mi">1048576</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"max_zip_file_size"</span><span class="p">:</span><span class="w"> </span><span class="mi">10485760</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"max_users"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"max_zip_file_size"</span><span class="p">:</span><span class="w"> </span><span class="mi">10485760</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"map_attribution"</span><span class="p">:</span><span class="w"> </span><span class="nt">"&copy; <a href=http://www.openstreetmap.org/copyright>OpenStreetMap</a> contributors"</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.6.1"</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.6.2"</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="p">},</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"success"</span><span class="w"></span>
|
||||
<span class="p">}</span><span class="w"></span>
|
||||
@ -182,10 +183,12 @@
|
||||
<span class="w"> </span><span class="nt">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"admin_contact"</span><span class="p">:</span><span class="w"> </span><span class="s2">"admin@example.com"</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"gpx_limit_import"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"is_registration_enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"is_registration_enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"max_single_file_size"</span><span class="p">:</span><span class="w"> </span><span class="mi">1048576</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"max_users"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"max_zip_file_size"</span><span class="p">:</span><span class="w"> </span><span class="mi">10485760</span><span class="p">,</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"max_users"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"map_attribution"</span><span class="p">:</span><span class="w"> </span><span class="nt">"&copy; <a href=http://www.openstreetmap.org/copyright>OpenStreetMap</a> contributors"</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.6.2"</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="p">},</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"success"</span><span class="w"></span>
|
||||
<span class="p">}</span><span class="w"></span>
|
||||
@ -198,8 +201,8 @@
|
||||
<li><p><strong>gpx_limit_import</strong> (<em>integer</em>) – max number of files in zip archive</p></li>
|
||||
<li><p><strong>is_registration_enabled</strong> (<em>boolean</em>) – is registration enabled ?</p></li>
|
||||
<li><p><strong>max_single_file_size</strong> (<em>integer</em>) – max size of a single file</p></li>
|
||||
<li><p><strong>max_zip_file_size</strong> (<em>integer</em>) – max size of a zip archive</p></li>
|
||||
<li><p><strong>max_users</strong> (<em>integer</em>) – max users allowed to register on instance</p></li>
|
||||
<li><p><strong>max_zip_file_size</strong> (<em>integer</em>) – max size of a zip archive</p></li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="field-even">Request Headers</dt>
|
||||
@ -268,7 +271,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>API documentation — FitTrackee 0.6.1
|
||||
<title>API documentation — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -154,7 +154,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Records — FitTrackee 0.6.1
|
||||
<title>Records — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -246,7 +246,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Sports — FitTrackee 0.6.1
|
||||
<title>Sports — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -484,7 +484,7 @@ Authenticated user must be an admin</p>
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Statistics — FitTrackee 0.6.1
|
||||
<title>Statistics — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -411,7 +411,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Users — FitTrackee 0.6.1
|
||||
<title>Users — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -279,7 +279,8 @@ has admin rights</p>
|
||||
<dl class="http get">
|
||||
<dt class="sig sig-object http" id="get--api-users-(user_name)">
|
||||
<span class="sig-name descname"><span class="pre">GET</span> </span><span class="sig-name descname"><span class="pre">/api/users/</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="pre">user_name</span></em><span class="sig-paren">)</span><a class="headerlink" href="#get--api-users-(user_name)" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Get single user details. Only user with admin rights can get user details.</p>
|
||||
<dd><p>Get single user details. Only user with admin rights can get other users
|
||||
details.</p>
|
||||
<p>It returns user preferences only for authenticated user.</p>
|
||||
<p><strong>Example request</strong>:</p>
|
||||
<div class="highlight-http notranslate"><div class="highlight"><pre><span></span><span class="nf">GET</span> <span class="nn">/api/users/admin</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
|
||||
@ -624,7 +625,7 @@ one admin</p>
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Workouts — FitTrackee 0.6.1
|
||||
<title>Workouts — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -1148,7 +1148,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Change log — FitTrackee 0.6.1
|
||||
<title>Change log — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
|
||||
@ -39,7 +39,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -77,223 +77,230 @@
|
||||
role="menu"
|
||||
aria-labelledby="dLabelLocalToc"><ul>
|
||||
<li><a class="reference internal" href="#">Change log</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-6-1-2022-03-27">Version 0.6.1 (2022/03/27)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-6-2-2022-04-03">Version 0.6.2 (2022/04/03)</a><ul>
|
||||
<li><a class="reference internal" href="#issues-closed">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#bugs-fixed">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-6-0-2022-03-27">Version 0.6.0 (2022/03/27)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-6-1-2022-03-27">Version 0.6.1 (2022/03/27)</a><ul>
|
||||
<li><a class="reference internal" href="#id1">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#features">Features</a></li>
|
||||
<li><a class="reference internal" href="#id2">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-6-0-2022-03-27">Version 0.6.0 (2022/03/27)</a><ul>
|
||||
<li><a class="reference internal" href="#id3">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#features">Features</a></li>
|
||||
<li><a class="reference internal" href="#id4">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#pull-requests">Pull Requests</a><ul>
|
||||
<li><a class="reference internal" href="#id3">Bugs Fixed</a></li>
|
||||
<li><a class="reference internal" href="#id5">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-7-2022-02-13">Version 0.5.7 (2022/02/13)</a><ul>
|
||||
<li><a class="reference internal" href="#id4">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id6">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#misc">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id5">Pull Requests</a><ul>
|
||||
<li><a class="reference internal" href="#id7">Pull Requests</a><ul>
|
||||
<li><a class="reference internal" href="#security">Security</a></li>
|
||||
<li><a class="reference internal" href="#id6">Misc</a></li>
|
||||
<li><a class="reference internal" href="#id8">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-6-2022-02-05">Version 0.5.6 (2022/02/05)</a><ul>
|
||||
<li><a class="reference internal" href="#id7">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id8">Bugs Fixed</a></li>
|
||||
<li><a class="reference internal" href="#id9">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id10">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id9">Pull Requests</a></li>
|
||||
<li><a class="reference internal" href="#id11">Pull Requests</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-5-2022-01-19">Version 0.5.5 (2022/01/19)</a><ul>
|
||||
<li><a class="reference internal" href="#id10">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#new-features">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id11">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-4-2022-01-01">Version 0.5.4 (2022/01/01)</a><ul>
|
||||
<li><a class="reference internal" href="#id12">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#new-features">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id13">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-3-2022-01-01">Version 0.5.3 (2022/01/01)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-5-4-2022-01-01">Version 0.5.4 (2022/01/01)</a><ul>
|
||||
<li><a class="reference internal" href="#id14">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id15">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-2-2021-12-19">Version 0.5.2 (2021/12/19)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-5-3-2022-01-01">Version 0.5.3 (2022/01/01)</a><ul>
|
||||
<li><a class="reference internal" href="#id16">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id17">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id17">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-1-2021-11-30">Version 0.5.1 (2021/11/30)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-5-2-2021-12-19">Version 0.5.2 (2021/12/19)</a><ul>
|
||||
<li><a class="reference internal" href="#id18">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id19">New Features</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-0-2021-11-14">Version 0.5.0 (2021/11/14)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-5-1-2021-11-30">Version 0.5.1 (2021/11/30)</a><ul>
|
||||
<li><a class="reference internal" href="#id20">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id21">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id22">Bugs Fixed</a></li>
|
||||
<li><a class="reference internal" href="#id23">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id24">Pull Requests</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-5-0-2021-11-14">Version 0.5.0 (2021/11/14)</a><ul>
|
||||
<li><a class="reference internal" href="#id22">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id23">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id24">Bugs Fixed</a></li>
|
||||
<li><a class="reference internal" href="#id25">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id26">Pull Requests</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-9-2021-07-16">Version 0.4.9 (2021/07/16)</a><ul>
|
||||
<li><a class="reference internal" href="#id25">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id26">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id27">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-8-2021-07-03">Version 0.4.8 (2021/07/03)</a><ul>
|
||||
<li><a class="reference internal" href="#id28">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id27">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id28">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id29">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-7-2021-04-07">Version 0.4.7 (2021/04/07)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-4-8-2021-07-03">Version 0.4.8 (2021/07/03)</a><ul>
|
||||
<li><a class="reference internal" href="#id30">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id31">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id32">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-7-2021-04-07">Version 0.4.7 (2021/04/07)</a><ul>
|
||||
<li><a class="reference internal" href="#id32">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id33">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id34">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-6-2021-02-21">Version 0.4.6 (2021/02/21)</a><ul>
|
||||
<li><a class="reference internal" href="#id33">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id34">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-5-2021-02-17">Version 0.4.5 (2021/02/17)</a><ul>
|
||||
<li><a class="reference internal" href="#id35">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id36">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-4-2021-01-31">Version 0.4.4 (2021/01/31)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-4-5-2021-02-17">Version 0.4.5 (2021/02/17)</a><ul>
|
||||
<li><a class="reference internal" href="#id37">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id38">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id39">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-4-2021-01-31">Version 0.4.4 (2021/01/31)</a><ul>
|
||||
<li><a class="reference internal" href="#id39">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id40">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id41">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-3-2021-01-10">Version 0.4.3 (2021/01/10)</a><ul>
|
||||
<li><a class="reference internal" href="#id40">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id41">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id42">Bugs Fixed</a></li>
|
||||
<li><a class="reference internal" href="#id42">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id43">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id44">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-2-2021-01-03">Version 0.4.2 (2021/01/03)</a><ul>
|
||||
<li><a class="reference internal" href="#id43">Misc</a></li>
|
||||
<li><a class="reference internal" href="#id45">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-1-2020-12-31">Version 0.4.1 (2020/12/31)</a><ul>
|
||||
<li><a class="reference internal" href="#id44">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id45">New Features</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-4-0-fittrackee-on-pypi-2020-09-19">Version 0.4.0 - FitTrackee on PyPI (2020/09/19)</a><ul>
|
||||
<li><a class="reference internal" href="#id46">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id47">New Features</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-3-0-administration-2020-07-15">Version 0.3.0 - Administration (2020/07/15)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-4-0-fittrackee-on-pypi-2020-09-19">Version 0.4.0 - FitTrackee on PyPI (2020/09/19)</a><ul>
|
||||
<li><a class="reference internal" href="#id48">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id49">New Features</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-3-0-administration-2020-07-15">Version 0.3.0 - Administration (2020/07/15)</a><ul>
|
||||
<li><a class="reference internal" href="#id50">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id51">New Features</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-2-5-fix-and-improvements-2020-01-31">Version 0.2.5 - Fix and improvements (2020/01/31)</a><ul>
|
||||
<li><a class="reference internal" href="#id50">Misc</a></li>
|
||||
<li><a class="reference internal" href="#id52">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-2-4-minor-fix-2020-01-30">Version 0.2.4 - Minor fix (2020/01/30)</a><ul>
|
||||
<li><a class="reference internal" href="#id51">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id52">Bugs Fixed</a></li>
|
||||
<li><a class="reference internal" href="#id53">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id54">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-2-3-fittrackee-available-in-french-2019-12-29">Version 0.2.3 - FitTrackee available in French (2019/12/29)</a><ul>
|
||||
<li><a class="reference internal" href="#id53">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id54">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id55">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-2-2-statistics-fix-2019-09-23">Version 0.2.2 - Statistics fix (2019/09/23)</a><ul>
|
||||
<li><a class="reference internal" href="#id56">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id55">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id56">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id57">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-2-1-fix-and-improvements-2019-09-01">Version 0.2.1 - Fix and improvements (2019/09/01)</a><ul>
|
||||
<li><a class="reference internal" href="#version-0-2-2-statistics-fix-2019-09-23">Version 0.2.2 - Statistics fix (2019/09/23)</a><ul>
|
||||
<li><a class="reference internal" href="#id58">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id59">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id60">Bugs Fixed</a></li>
|
||||
<li><a class="reference internal" href="#id59">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id61">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-2-1-fix-and-improvements-2019-09-01">Version 0.2.1 - Fix and improvements (2019/09/01)</a><ul>
|
||||
<li><a class="reference internal" href="#id60">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id61">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id62">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id63">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-2-0-statistics-2019-07-07">Version 0.2.0 - Statistics (2019/07/07)</a><ul>
|
||||
<li><a class="reference internal" href="#id62">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id63">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id64">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id65">New Features</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#id64">Misc</a></li>
|
||||
<li><a class="reference internal" href="#id66">Misc</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-1-1-fix-and-improvements-2019-02-07">Version 0.1.1 - Fix and improvements (2019/02/07)</a><ul>
|
||||
<li><a class="reference internal" href="#id65">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id66">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id67">Bugs Fixed</a></li>
|
||||
<li><a class="reference internal" href="#id67">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id68">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id69">Bugs Fixed</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#version-0-1-0-first-release-2018-07-04">Version 0.1.0 - First release 🎉 (2018-07-04)</a><ul>
|
||||
<li><a class="reference internal" href="#id68">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id69">New Features</a></li>
|
||||
<li><a class="reference internal" href="#id70">Issues Closed</a><ul>
|
||||
<li><a class="reference internal" href="#id71">New Features</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@ -345,13 +352,27 @@
|
||||
|
||||
<section id="change-log">
|
||||
<h1>Change log<a class="headerlink" href="#change-log" title="Permalink to this headline">¶</a></h1>
|
||||
<section id="version-0-6-1-2022-03-27">
|
||||
<h2>Version 0.6.1 (2022/03/27)<a class="headerlink" href="#version-0-6-1-2022-03-27" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="version-0-6-2-2022-04-03">
|
||||
<h2>Version 0.6.2 (2022/04/03)<a class="headerlink" href="#version-0-6-2-2022-04-03" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="issues-closed">
|
||||
<h3>Issues Closed<a class="headerlink" href="#issues-closed" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="bugs-fixed">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#bugs-fixed" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/175">#175</a> - Distance card on dashboard is not refreshed</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/173">#173</a> - link to user profile in workout card is incorrect</p></li>
|
||||
</ul>
|
||||
<p>In this release 2 issues were closed.</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section id="version-0-6-1-2022-03-27">
|
||||
<h2>Version 0.6.1 (2022/03/27)<a class="headerlink" href="#version-0-6-1-2022-03-27" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id1">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id2">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/171">#171</a> - Stats chart is not updated correctly</p></li>
|
||||
</ul>
|
||||
<p>In this release 1 issue was closed.</p>
|
||||
@ -361,8 +382,8 @@
|
||||
<section id="version-0-6-0-2022-03-27">
|
||||
<h2>Version 0.6.0 (2022/03/27)<a class="headerlink" href="#version-0-6-0-2022-03-27" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This version introduces some changes on <a class="reference external" href="https://samr1.github.io/FitTrackee/features.html#account-preferences">user registration</a>.<br />From now on, a user needs to confirm his account after registration (an email with confirmation instructions is sent after registration).</p>
|
||||
<section id="id1">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id3">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="features">
|
||||
<h4>Features<a class="headerlink" href="#features" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
@ -370,8 +391,8 @@
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/106">#106</a> - Allow user to update email</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id2">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id4">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/169">#169</a> - user picture is not refreshed after update</p></li>
|
||||
</ul>
|
||||
@ -379,8 +400,8 @@
|
||||
</section>
|
||||
<section id="pull-requests">
|
||||
<h3>Pull Requests<a class="headerlink" href="#pull-requests" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id3">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id5">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/pull/161">#161</a> - Minor translation issue on ‘Farthest’</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/pull/160">#160</a> - Minor translation issue on APP_ERROR</p></li>
|
||||
@ -395,8 +416,8 @@
|
||||
<p>This release contains several fixes including security fixes.<br />Thanks to @DanielSiersleben for the report.</p>
|
||||
<p>And from now on, admin account is not created on application initialization.<br />A new command is added to set administration rights on the account created after registration
|
||||
(see <a class="reference external" href="https://samr1.github.io/FitTrackee/installation.html#upgrade">documentation</a>)</p>
|
||||
<section id="id4">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id6">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="misc">
|
||||
<h4>Misc<a class="headerlink" href="#misc" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
@ -404,8 +425,8 @@
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="id5">
|
||||
<h3>Pull Requests<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id7">
|
||||
<h3>Pull Requests<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="security">
|
||||
<h4>Security<a class="headerlink" href="#security" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
@ -423,8 +444,8 @@
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id6">
|
||||
<h4>Misc<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id8">
|
||||
<h4>Misc<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/pull/152">#152</a> - Fixes and improvements:</p>
|
||||
<ul>
|
||||
@ -440,17 +461,17 @@
|
||||
</section>
|
||||
<section id="version-0-5-6-2022-02-05">
|
||||
<h2>Version 0.5.6 (2022/02/05)<a class="headerlink" href="#version-0-5-6-2022-02-05" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id7">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id8">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id9">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id10">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/146">#146</a> - incorrect label on workouts filters</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="id9">
|
||||
<h3>Pull Requests<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id11">
|
||||
<h3>Pull Requests<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/pull/145">#145</a> - fix on database models</p></li>
|
||||
</ul>
|
||||
@ -459,8 +480,8 @@
|
||||
</section>
|
||||
<section id="version-0-5-5-2022-01-19">
|
||||
<h2>Version 0.5.5 (2022/01/19)<a class="headerlink" href="#version-0-5-5-2022-01-19" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id10">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id12">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="new-features">
|
||||
<h4>New Features<a class="headerlink" href="#new-features" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
@ -470,8 +491,8 @@
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/134">#134</a> - Wind direction</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id11">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id13">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/commit/877fa0faaabc0130402638905fe04f84563eb278">877fa0f</a> - fix sport icon color (when changed) on calendar on small resolutions</p></li>
|
||||
</ul>
|
||||
@ -481,10 +502,10 @@
|
||||
</section>
|
||||
<section id="version-0-5-4-2022-01-01">
|
||||
<h2>Version 0.5.4 (2022/01/01)<a class="headerlink" href="#version-0-5-4-2022-01-01" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id12">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id13">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id14">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id15">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/131">#131</a> - No workouts displayed on calendar</p></li>
|
||||
</ul>
|
||||
@ -494,10 +515,10 @@
|
||||
</section>
|
||||
<section id="version-0-5-3-2022-01-01">
|
||||
<h2>Version 0.5.3 (2022/01/01)<a class="headerlink" href="#version-0-5-3-2022-01-01" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id14">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id15">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id16">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id16" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id17">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id17" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/129">#129</a> - Display only active sports when editing a workout</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/127">#127</a> - parse_email_url() can’t validate a legitimate EMAIL_URI such as “smtp://localhost:25”</p></li>
|
||||
@ -508,10 +529,10 @@
|
||||
</section>
|
||||
<section id="version-0-5-2-2021-12-19">
|
||||
<h2>Version 0.5.2 (2021/12/19)<a class="headerlink" href="#version-0-5-2-2021-12-19" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id16">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id16" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id17">
|
||||
<h4>New Features<a class="headerlink" href="#id17" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id18">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id18" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id19">
|
||||
<h4>New Features<a class="headerlink" href="#id19" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/123">#123</a> - Allow user to reset preferences for a sport</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/121">#121</a> - Add activity : snowshoes</p></li>
|
||||
@ -522,10 +543,10 @@
|
||||
</section>
|
||||
<section id="version-0-5-1-2021-11-30">
|
||||
<h2>Version 0.5.1 (2021/11/30)<a class="headerlink" href="#version-0-5-1-2021-11-30" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id18">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id18" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id19">
|
||||
<h4>New Features<a class="headerlink" href="#id19" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id20">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id20" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id21">
|
||||
<h4>New Features<a class="headerlink" href="#id21" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/116">#116</a> - Better UI for Speed and Elevation buttons in the graph of the Workout screen</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/115">#115</a> - Add option to download the GPX file of a Workout</p></li>
|
||||
@ -537,10 +558,10 @@
|
||||
</section>
|
||||
<section id="version-0-5-0-2021-11-14">
|
||||
<h2>Version 0.5.0 (2021/11/14)<a class="headerlink" href="#version-0-5-0-2021-11-14" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id20">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id20" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id21">
|
||||
<h4>New Features<a class="headerlink" href="#id21" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id22">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id22" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id23">
|
||||
<h4>New Features<a class="headerlink" href="#id23" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/99">#99</a> - Display workout with imperial units</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/91">#91</a> - Display elevation chart with min and max altitude of workout</p></li>
|
||||
@ -548,21 +569,21 @@
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/18">#18</a> - Better UI</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id22">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id22" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id24">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id24" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/95">#95</a> - Some workouts seem to be missing on statistics chart</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id23">
|
||||
<h4>Misc<a class="headerlink" href="#id23" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id25">
|
||||
<h4>Misc<a class="headerlink" href="#id25" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/104">#104</a> - Switch to AGPLv3 license</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="id24">
|
||||
<h3>Pull Requests<a class="headerlink" href="#id24" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id26">
|
||||
<h3>Pull Requests<a class="headerlink" href="#id26" title="Permalink to this headline">¶</a></h3>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/pull/101">#101</a> - Docker updates for full files</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/pull/100">#100</a> - Add client application in docker for development</p></li>
|
||||
@ -579,17 +600,17 @@
|
||||
</section>
|
||||
<section id="version-0-4-9-2021-07-16">
|
||||
<h2>Version 0.4.9 (2021/07/16)<a class="headerlink" href="#version-0-4-9-2021-07-16" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id25">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id25" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id26">
|
||||
<h4>New Features<a class="headerlink" href="#id26" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id27">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id27" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id28">
|
||||
<h4>New Features<a class="headerlink" href="#id28" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/83">#83</a> - allow using configured tile server to generate static maps<br /><strong>Note</strong>: to keep using the default tile server, set environment variable <code class="docutils literal notranslate"><span class="pre">DEFAULT_STATICMAP</span></code> to <code class="docutils literal notranslate"><span class="pre">True</span></code></p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/81">#81</a> - display remaining characters in textarea</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id27">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id27" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id29">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id29" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/82">#82</a> - a user can not modify his birth day</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/80">#80</a> - can not save notes with control characters</p></li>
|
||||
@ -600,10 +621,10 @@
|
||||
</section>
|
||||
<section id="version-0-4-8-2021-07-03">
|
||||
<h2>Version 0.4.8 (2021/07/03)<a class="headerlink" href="#version-0-4-8-2021-07-03" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id28">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id28" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id29">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id29" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id30">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id30" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id31">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id31" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/79">#79</a> - Fails to start after make rebuild</p></li>
|
||||
</ul>
|
||||
@ -613,17 +634,17 @@
|
||||
</section>
|
||||
<section id="version-0-4-7-2021-04-07">
|
||||
<h2>Version 0.4.7 (2021/04/07)<a class="headerlink" href="#version-0-4-7-2021-04-07" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id30">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id30" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id31">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id31" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id32">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id32" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id33">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id33" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/75">#75</a> - Workouts on the same day are not displayed in right order</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="id32">
|
||||
<h3>Misc<a class="headerlink" href="#id32" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id34">
|
||||
<h3>Misc<a class="headerlink" href="#id34" title="Permalink to this headline">¶</a></h3>
|
||||
<ul class="simple">
|
||||
<li><p>Update Python and Javascript dependencies<br /><strong>IMPORTANT</strong>: Due to <a class="reference external" href="https://docs.sqlalchemy.org/en/14/changelog/changelog_14.html#change-3687655465c25a39b968b4f5f6e9170b">SQLAlchemy update (1.4+)</a>, engine URLs starting with <code class="docutils literal notranslate"><span class="pre">postgres://</span></code> are no longer supported. Please update <code class="docutils literal notranslate"><span class="pre">DATABASE_URL</span></code> with <code class="docutils literal notranslate"><span class="pre">postgresql://</span></code>.</p></li>
|
||||
</ul>
|
||||
@ -632,10 +653,10 @@
|
||||
</section>
|
||||
<section id="version-0-4-6-2021-02-21">
|
||||
<h2>Version 0.4.6 (2021/02/21)<a class="headerlink" href="#version-0-4-6-2021-02-21" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id33">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id33" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id34">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id34" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id35">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id35" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id36">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id36" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/72">#72</a> - Error message when file exceeding size is incorrect</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/71">#71</a> - max size or max number of files must be greater than 0</p></li>
|
||||
@ -647,10 +668,10 @@
|
||||
</section>
|
||||
<section id="version-0-4-5-2021-02-17">
|
||||
<h2>Version 0.4.5 (2021/02/17)<a class="headerlink" href="#version-0-4-5-2021-02-17" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id35">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id35" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id36">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id36" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id37">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id37" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id38">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id38" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/66">#66</a> - invalid gpx limit used when importing zip archive</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/64">#64</a> - Only 50 workouts per month shown in calendar</p></li>
|
||||
@ -661,17 +682,17 @@
|
||||
</section>
|
||||
<section id="version-0-4-4-2021-01-31">
|
||||
<h2>Version 0.4.4 (2021/01/31)<a class="headerlink" href="#version-0-4-4-2021-01-31" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id37">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id37" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id38">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id38" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id39">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id39" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id40">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id40" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/62">#62</a> - Error when sending reset password email</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="id39">
|
||||
<h3>Misc<a class="headerlink" href="#id39" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id41">
|
||||
<h3>Misc<a class="headerlink" href="#id41" title="Permalink to this headline">¶</a></h3>
|
||||
<ul class="simple">
|
||||
<li><p>Refactoring before introducing new features.</p></li>
|
||||
<li><p>Add docker files for evaluation purposes.</p></li>
|
||||
@ -681,16 +702,16 @@
|
||||
</section>
|
||||
<section id="version-0-4-3-2021-01-10">
|
||||
<h2>Version 0.4.3 (2021/01/10)<a class="headerlink" href="#version-0-4-3-2021-01-10" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id40">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id40" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id41">
|
||||
<h4>New Features<a class="headerlink" href="#id41" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id42">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id42" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id43">
|
||||
<h4>New Features<a class="headerlink" href="#id43" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/58">#58</a> - Standardize terms used for workouts<br /><strong>Note:</strong> Database model, upload directory for workouts and API endpoints are also updated.</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id42">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id42" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id44">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id44" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/59">#59</a> - No message displayed on uploading image error</p></li>
|
||||
</ul>
|
||||
@ -700,18 +721,18 @@
|
||||
</section>
|
||||
<section id="version-0-4-2-2021-01-03">
|
||||
<h2>Version 0.4.2 (2021/01/03)<a class="headerlink" href="#version-0-4-2-2021-01-03" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id43">
|
||||
<h3>Misc<a class="headerlink" href="#id43" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id45">
|
||||
<h3>Misc<a class="headerlink" href="#id45" title="Permalink to this headline">¶</a></h3>
|
||||
<p>No new features in this release, only some refactorings before introducing
|
||||
new features.</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="version-0-4-1-2020-12-31">
|
||||
<h2>Version 0.4.1 (2020/12/31)<a class="headerlink" href="#version-0-4-1-2020-12-31" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id44">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id44" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id45">
|
||||
<h4>New Features<a class="headerlink" href="#id45" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id46">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id46" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id47">
|
||||
<h4>New Features<a class="headerlink" href="#id47" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/57">#57</a> - Use uuid for activities</p></li>
|
||||
</ul>
|
||||
@ -727,10 +748,10 @@ new features.</p>
|
||||
<li><p>It’s now possible to change the tile provider for maps. The default tile server is now <strong>OpenStreetMap</strong>’s standard tile layer (replacing <strong>ThunderForest Outdoors</strong>),
|
||||
see <a class="reference external" href="https://samr1.github.io/FitTrackee/installation.html#map-tile-server">Map tile server in documentation</a>.</p></li>
|
||||
</ul>
|
||||
<section id="id46">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id46" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id47">
|
||||
<h4>New Features<a class="headerlink" href="#id47" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id48">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id48" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id49">
|
||||
<h4>New Features<a class="headerlink" href="#id49" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/54">#54</a> - Tile server can be changed</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/53">#53</a> - Simplify FitTrackee installation</p></li>
|
||||
@ -746,10 +767,10 @@ see <a class="reference external" href="https://samr1.github.io/FitTrackee/insta
|
||||
<li><p>FitTrackee administration is now available (see <a class="reference external" href="https://samr1.github.io/FitTrackee/features.html#administration">documentation</a>)<br />⚠️ Warning: some application parameters move from environment variables to database (see <a class="reference external" href="https://samr1.github.io/FitTrackee/installation.html#environment-variables">installation</a>).</p></li>
|
||||
<li><p>in order to send emails, Redis is now a mandatory dependency</p></li>
|
||||
</ul>
|
||||
<section id="id48">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id48" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id49">
|
||||
<h4>New Features<a class="headerlink" href="#id49" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id50">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id50" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id51">
|
||||
<h4>New Features<a class="headerlink" href="#id51" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/50">#50</a> - A user can reset his password</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/17">#17</a> - A user can delete his account</p></li>
|
||||
@ -761,8 +782,8 @@ see <a class="reference external" href="https://samr1.github.io/FitTrackee/insta
|
||||
</section>
|
||||
<section id="version-0-2-5-fix-and-improvements-2020-01-31">
|
||||
<h2>Version 0.2.5 - Fix and improvements (2020/01/31)<a class="headerlink" href="#version-0-2-5-fix-and-improvements-2020-01-31" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id50">
|
||||
<h3>Misc<a class="headerlink" href="#id50" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id52">
|
||||
<h3>Misc<a class="headerlink" href="#id52" title="Permalink to this headline">¶</a></h3>
|
||||
<p>This version contains minor fix and improvements on client side:</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/commit/4c3fc343d51b9c27d3ebab71df648bcf7d7bae59">4c3fc34</a> - empty user data on logout</p></li>
|
||||
@ -775,10 +796,10 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
</section>
|
||||
<section id="version-0-2-4-minor-fix-2020-01-30">
|
||||
<h2>Version 0.2.4 - Minor fix (2020/01/30)<a class="headerlink" href="#version-0-2-4-minor-fix-2020-01-30" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id51">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id51" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id52">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id52" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id53">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id53" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id54">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id54" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/47">#47</a> - timezone drop-down is not displayed correctly</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/46">#46</a> - calendar cannot display more than 5 or 6 activities on the same day</p></li>
|
||||
@ -789,17 +810,17 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
</section>
|
||||
<section id="version-0-2-3-fittrackee-available-in-french-2019-12-29">
|
||||
<h2>Version 0.2.3 - FitTrackee available in French (2019/12/29)<a class="headerlink" href="#version-0-2-3-fittrackee-available-in-french-2019-12-29" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id53">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id53" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id54">
|
||||
<h4>New Features<a class="headerlink" href="#id54" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id55">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id55" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id56">
|
||||
<h4>New Features<a class="headerlink" href="#id56" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/43">#43</a> - Display weekend days with a different background color on calendar</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/40">#40</a> - Localize FitTrackee (i18n)</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id55">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id55" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id57">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id57" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/44">#44</a> - Cannot edit an activity that does not have a gpx file</p></li>
|
||||
</ul>
|
||||
@ -809,10 +830,10 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
</section>
|
||||
<section id="version-0-2-2-statistics-fix-2019-09-23">
|
||||
<h2>Version 0.2.2 - Statistics fix (2019/09/23)<a class="headerlink" href="#version-0-2-2-statistics-fix-2019-09-23" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id56">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id56" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id57">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id57" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id58">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id58" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id59">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id59" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/41">#41</a> - User statistics are incorrect</p></li>
|
||||
</ul>
|
||||
@ -822,10 +843,10 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
</section>
|
||||
<section id="version-0-2-1-fix-and-improvements-2019-09-01">
|
||||
<h2>Version 0.2.1 - Fix and improvements (2019/09/01)<a class="headerlink" href="#version-0-2-1-fix-and-improvements-2019-09-01" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id58">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id58" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id59">
|
||||
<h4>New Features<a class="headerlink" href="#id59" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id60">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id60" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id61">
|
||||
<h4>New Features<a class="headerlink" href="#id61" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/4">#4</a> - Show points on the map when mouse over the chart</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/14">#14</a> - Display segments informations</p></li>
|
||||
@ -836,15 +857,15 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/37">#37</a> - Display map on activities list</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id60">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id60" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id62">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id62" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/34">#34</a> - Weather is not displayed anymore</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="id61">
|
||||
<h3>Misc<a class="headerlink" href="#id61" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id63">
|
||||
<h3>Misc<a class="headerlink" href="#id63" title="Permalink to this headline">¶</a></h3>
|
||||
<ul class="simple">
|
||||
<li><p><strong><a class="reference external" href="https://poetry.eustace.io/">Poetry</a></strong> replaces <strong><a class="reference external" href="https://docs.pipenv.org">pipenv</a></strong> for Python packages management</p></li>
|
||||
</ul>
|
||||
@ -853,17 +874,17 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
</section>
|
||||
<section id="version-0-2-0-statistics-2019-07-07">
|
||||
<h2>Version 0.2.0 - Statistics (2019/07/07)<a class="headerlink" href="#version-0-2-0-statistics-2019-07-07" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id62">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id62" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id63">
|
||||
<h4>New Features<a class="headerlink" href="#id63" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id64">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id64" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id65">
|
||||
<h4>New Features<a class="headerlink" href="#id65" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/Fittrackee/issues/13">#13</a> - Detailed statistics</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="id64">
|
||||
<h3>Misc<a class="headerlink" href="#id64" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id66">
|
||||
<h3>Misc<a class="headerlink" href="#id66" title="Permalink to this headline">¶</a></h3>
|
||||
<ul class="simple">
|
||||
<li><p>Update dependencies</p></li>
|
||||
</ul>
|
||||
@ -872,17 +893,17 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
</section>
|
||||
<section id="version-0-1-1-fix-and-improvements-2019-02-07">
|
||||
<h2>Version 0.1.1 - Fix and improvements (2019/02/07)<a class="headerlink" href="#version-0-1-1-fix-and-improvements-2019-02-07" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="id65">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id65" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id66">
|
||||
<h4>New Features<a class="headerlink" href="#id66" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id67">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id67" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id68">
|
||||
<h4>New Features<a class="headerlink" href="#id68" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/25">#25</a> - Display records on calendar</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/22">#22</a> - Add a total on current month statistics</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="id67">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id67" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id69">
|
||||
<h4>Bugs Fixed<a class="headerlink" href="#id69" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/31">#31</a> - Use moving duration for stats</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/29">#29</a> - Pause duration calculation with segments</p></li>
|
||||
@ -931,10 +952,10 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
<li><p>no administration for now</p></li>
|
||||
</ul>
|
||||
<p>➡️ more informations: see <a class="reference external" href="https://samr1.github.io/FitTrackee/">documentation</a> and <a class="reference external" href="https://github.com/SamR1/FitTrackee/issues">current issues</a></p>
|
||||
<section id="id68">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id68" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id69">
|
||||
<h4>New Features<a class="headerlink" href="#id69" title="Permalink to this headline">¶</a></h4>
|
||||
<section id="id70">
|
||||
<h3>Issues Closed<a class="headerlink" href="#id70" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="id71">
|
||||
<h4>New Features<a class="headerlink" href="#id71" title="Permalink to this headline">¶</a></h4>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/11">#11</a> - Timezone support</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/SamR1/FitTrackee/issues/10">#10</a> - Add a note to an activity</p></li>
|
||||
@ -962,7 +983,7 @@ add URL interceptors to simplify routes definition</p></li>
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Features — FitTrackee 0.6.1
|
||||
<title>Features — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -359,7 +359,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Index — FitTrackee 0.6.1
|
||||
<title>Index — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
|
||||
@ -37,7 +37,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -179,7 +179,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>HTTP Routing Table — FitTrackee 0.6.1
|
||||
<title>HTTP Routing Table — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
|
||||
@ -44,7 +44,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -355,7 +355,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>FitTrackee — FitTrackee 0.6.1
|
||||
<title>FitTrackee — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
|
||||
@ -39,7 +39,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -173,7 +173,7 @@ Map</a>.</div>
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Installation — FitTrackee 0.6.1
|
||||
<title>Installation — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -632,11 +632,11 @@ $ make install-db
|
||||
</div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>Download the last release (for now, it is the release v0.6.1):</p></li>
|
||||
<li><p>Download the last release (for now, it is the release v0.6.2):</p></li>
|
||||
</ul>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.1.tar.gz
|
||||
$ tar -xzf v0.6.1.tar.gz
|
||||
$ mv FitTrackee-0.6.1 FitTrackee
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.2.tar.gz
|
||||
$ tar -xzf v0.6.2.tar.gz
|
||||
$ mv FitTrackee-0.6.2 FitTrackee
|
||||
$ <span class="nb">cd</span> FitTrackee
|
||||
</pre></div>
|
||||
</div>
|
||||
@ -752,11 +752,11 @@ $ <span class="nb">source</span> .env
|
||||
<ul class="simple">
|
||||
<li><p>Stop the application</p></li>
|
||||
<li><p>Change to the directory where FitTrackee directory is located</p></li>
|
||||
<li><p>Download the last release (for now, it is the release v0.6.1) and overwrite existing files:</p></li>
|
||||
<li><p>Download the last release (for now, it is the release v0.6.2) and overwrite existing files:</p></li>
|
||||
</ul>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.1.tar.gz
|
||||
$ tar -xzf v0.6.1.tar.gz
|
||||
$ cp -R FitTrackee-0.6.1/* FitTrackee/
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.2.tar.gz
|
||||
$ tar -xzf v0.6.2.tar.gz
|
||||
$ cp -R FitTrackee-0.6.2/* FitTrackee/
|
||||
$ <span class="nb">cd</span> FitTrackee
|
||||
</pre></div>
|
||||
</div>
|
||||
@ -984,7 +984,7 @@ $ make docker-build docker-run docker-init
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
BIN
docs/objects.inv
@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Search — FitTrackee 0.6.1
|
||||
<title>Search — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
|
||||
@ -44,7 +44,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -149,7 +149,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Administrator — FitTrackee 0.6.1
|
||||
<title>Administrator — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -155,7 +155,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Troubleshooting — FitTrackee 0.6.1
|
||||
<title>Troubleshooting — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -152,7 +152,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>User — FitTrackee 0.6.1
|
||||
<title>User — FitTrackee 0.6.2
|
||||
documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css" />
|
||||
@ -40,7 +40,7 @@
|
||||
</button>
|
||||
<a class="navbar-brand" href="../index.html">
|
||||
FitTrackee</a>
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.1
|
||||
<span class="navbar-text navbar-version pull-left"><b>0.6.2
|
||||
</b></span>
|
||||
</div>
|
||||
|
||||
@ -143,7 +143,7 @@
|
||||
</p>
|
||||
<p>
|
||||
© Copyright 2018 - 2022, SamR1.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.4.0.<br/>
|
||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.5.0.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
Before Width: | Height: | Size: 538 KiB After Width: | Height: | Size: 539 KiB |
Before Width: | Height: | Size: 368 KiB After Width: | Height: | Size: 368 KiB |
Before Width: | Height: | Size: 201 KiB After Width: | Height: | Size: 202 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 103 KiB |
@ -369,13 +369,13 @@ Production environment
|
||||
.. warning::
|
||||
| Note that FitTrackee is under heavy development, some features may be unstable.
|
||||
|
||||
- Download the last release (for now, it is the release v0.6.1):
|
||||
- Download the last release (for now, it is the release v0.6.2):
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.1.tar.gz
|
||||
$ tar -xzf v0.6.1.tar.gz
|
||||
$ mv FitTrackee-0.6.1 FitTrackee
|
||||
$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.2.tar.gz
|
||||
$ tar -xzf v0.6.2.tar.gz
|
||||
$ mv FitTrackee-0.6.2 FitTrackee
|
||||
$ cd FitTrackee
|
||||
|
||||
- Create **.env** from example and update it
|
||||
@ -493,13 +493,13 @@ Prod environment
|
||||
|
||||
- Change to the directory where FitTrackee directory is located
|
||||
|
||||
- Download the last release (for now, it is the release v0.6.1) and overwrite existing files:
|
||||
- Download the last release (for now, it is the release v0.6.2) and overwrite existing files:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.1.tar.gz
|
||||
$ tar -xzf v0.6.1.tar.gz
|
||||
$ cp -R FitTrackee-0.6.1/* FitTrackee/
|
||||
$ wget https://github.com/SamR1/FitTrackee/archive/v0.6.2.tar.gz
|
||||
$ tar -xzf v0.6.2.tar.gz
|
||||
$ cp -R FitTrackee-0.6.2/* FitTrackee/
|
||||
$ cd FitTrackee
|
||||
|
||||
- Update **.env** if needed (see `Environment variables <installation.html#environment-variables>`__).
|
||||
|
@ -19,8 +19,9 @@ from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy.exc import ProgrammingError
|
||||
|
||||
from fittrackee.emails.email import EmailService
|
||||
from fittrackee.request import CustomRequest
|
||||
|
||||
VERSION = __version__ = '0.6.1'
|
||||
VERSION = __version__ = '0.6.2'
|
||||
db = SQLAlchemy()
|
||||
bcrypt = Bcrypt()
|
||||
migrate = Migrate()
|
||||
@ -35,9 +36,17 @@ logging.basicConfig(
|
||||
appLog = logging.getLogger('fittrackee')
|
||||
|
||||
|
||||
class CustomFlask(Flask):
|
||||
# add custom Request to handle user-agent parsing
|
||||
# (removed in Werkzeug 2.1)
|
||||
request_class = CustomRequest
|
||||
|
||||
|
||||
def create_app() -> Flask:
|
||||
# instantiate the app
|
||||
app = Flask(__name__, static_folder='dist/static', template_folder='dist')
|
||||
app = CustomFlask(
|
||||
__name__, static_folder='dist/static', template_folder='dist'
|
||||
)
|
||||
|
||||
# set config
|
||||
with app.app_context():
|
||||
@ -105,7 +114,7 @@ def create_app() -> Flask:
|
||||
appLog.setLevel(logging.DEBUG)
|
||||
|
||||
# Enable CORS
|
||||
@app.after_request
|
||||
@app.after_request # type: ignore
|
||||
def after_request(response: Response) -> Response:
|
||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||
response.headers.add(
|
||||
|
@ -40,13 +40,14 @@ def get_application_config() -> Union[Dict, HttpResponse]:
|
||||
|
||||
{
|
||||
"data": {
|
||||
"admin_contact": "admin@example.com",
|
||||
"gpx_limit_import": 10,
|
||||
"is_registration_enabled": false,
|
||||
"max_single_file_size": 1048576,
|
||||
"max_zip_file_size": 10485760,
|
||||
"max_users": 0,
|
||||
"max_zip_file_size": 10485760,
|
||||
"map_attribution": "© <a href=http://www.openstreetmap.org/copyright>OpenStreetMap</a> contributors"
|
||||
"version": "0.6.1"
|
||||
"version": "0.6.2"
|
||||
},
|
||||
"status": "success"
|
||||
}
|
||||
@ -90,10 +91,12 @@ def update_application_config(auth_user: User) -> Union[Dict, HttpResponse]:
|
||||
"data": {
|
||||
"admin_contact": "admin@example.com",
|
||||
"gpx_limit_import": 10,
|
||||
"is_registration_enabled": true,
|
||||
"is_registration_enabled": false,
|
||||
"max_single_file_size": 1048576,
|
||||
"max_users": 10,
|
||||
"max_zip_file_size": 10485760,
|
||||
"max_users": 10
|
||||
"map_attribution": "© <a href=http://www.openstreetmap.org/copyright>OpenStreetMap</a> contributors"
|
||||
"version": "0.6.2"
|
||||
},
|
||||
"status": "success"
|
||||
}
|
||||
@ -102,8 +105,8 @@ def update_application_config(auth_user: User) -> Union[Dict, HttpResponse]:
|
||||
:<json integer gpx_limit_import: max number of files in zip archive
|
||||
:<json boolean is_registration_enabled: is registration enabled ?
|
||||
:<json integer max_single_file_size: max size of a single file
|
||||
:<json integer max_zip_file_size: max size of a zip archive
|
||||
:<json integer max_users: max users allowed to register on instance
|
||||
:<json integer max_zip_file_size: max size of a zip archive
|
||||
|
||||
:reqheader Authorization: OAuth 2.0 Bearer Token
|
||||
|
||||
|
2
fittrackee/dist/index.html
vendored
@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><link rel="stylesheet" href="/static/css/fork-awesome.min.css"/><link rel="stylesheet" href="/static/css/leaflet.css"/><title>FitTrackee</title><script defer="defer" src="/static/js/chunk-vendors.c045258f.js"></script><script defer="defer" src="/static/js/app.5c12d3f9.js"></script><link href="/static/css/app.3729aa92.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="fittrackee_client"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but FitTrackee doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><link rel="stylesheet" href="/static/css/fork-awesome.min.css"/><link rel="stylesheet" href="/static/css/leaflet.css"/><title>FitTrackee</title><script defer="defer" src="/static/js/chunk-vendors.63e25135.js"></script><script defer="defer" src="/static/js/app.9fb29e8d.js"></script><link href="/static/css/app.3729aa92.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="fittrackee_client"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but FitTrackee doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
2
fittrackee/dist/service-worker.js
vendored
2
fittrackee/dist/service-worker.js.map
vendored
1
fittrackee/dist/static/js/app.9fb29e8d.js.map
vendored
Normal file
2
fittrackee/dist/static/js/app.ea909ac0.js
vendored
1
fittrackee/dist/static/js/chunk-vendors.63e25135.js.map
vendored
Normal file
2
fittrackee/dist/static/js/reset.30b1815a.js
vendored
24
fittrackee/request.py
Normal file
@ -0,0 +1,24 @@
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from flask import Request
|
||||
from ua_parser import user_agent_parser
|
||||
from werkzeug.user_agent import UserAgent as IUserAgent
|
||||
|
||||
|
||||
class UserAgent(IUserAgent):
|
||||
def __init__(self, string: str):
|
||||
super().__init__(string)
|
||||
self.platform, self.browser = self._parse_user_agent(self.string)
|
||||
|
||||
@staticmethod
|
||||
def _parse_user_agent(
|
||||
user_agent: str,
|
||||
) -> Tuple[Optional[str], Optional[str]]:
|
||||
parsed_string = user_agent_parser.Parse(user_agent)
|
||||
platform = parsed_string.get('os', {}).get('family')
|
||||
browser = parsed_string.get('user_agent', {}).get('family')
|
||||
return platform, browser
|
||||
|
||||
|
||||
class CustomRequest(Request):
|
||||
user_agent_class = UserAgent
|
@ -4,17 +4,18 @@ from typing import Optional
|
||||
import pytest
|
||||
from flask import Flask
|
||||
|
||||
import fittrackee
|
||||
from fittrackee.application.models import AppConfig
|
||||
from fittrackee.users.models import User
|
||||
|
||||
from ..mixins import ApiTestCaseMixin
|
||||
from ..utils import jsonify_dict
|
||||
|
||||
|
||||
class TestGetConfig(ApiTestCaseMixin):
|
||||
def test_it_gets_application_config_for_unauthenticated_user(
|
||||
self, app: Flask
|
||||
) -> None:
|
||||
app_config = AppConfig.query.first()
|
||||
client = app.test_client()
|
||||
|
||||
response = client.get('/api/config')
|
||||
@ -22,18 +23,7 @@ class TestGetConfig(ApiTestCaseMixin):
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert data['data']['admin_contact'] is None
|
||||
assert data['data']['gpx_limit_import'] == 10
|
||||
assert data['data']['is_registration_enabled'] is True
|
||||
assert data['data']['max_single_file_size'] == 1048576
|
||||
assert data['data']['max_zip_file_size'] == 10485760
|
||||
assert data['data']['max_users'] == 100
|
||||
assert data['data']['map_attribution'] == (
|
||||
'© <a href="http://www.openstreetmap.org/copyright" '
|
||||
'target="_blank" rel="noopener noreferrer">OpenStreetMap</a> '
|
||||
'contributors'
|
||||
)
|
||||
assert data['data']['version'] == fittrackee.__version__
|
||||
assert data['data'] == jsonify_dict(app_config.serialize())
|
||||
|
||||
def test_it_gets_application_config(
|
||||
self, app: Flask, user_1: User
|
||||
|
@ -1,22 +1,51 @@
|
||||
from flask import Flask
|
||||
|
||||
from fittrackee import VERSION
|
||||
from fittrackee.application.models import AppConfig
|
||||
from fittrackee.users.models import User
|
||||
|
||||
|
||||
class TestConfigModel:
|
||||
def test_application_config(self, app: Flask) -> None:
|
||||
app_config = AppConfig.query.first()
|
||||
assert 1 == app_config.id
|
||||
app_config.admin_contact = 'admin@example.com'
|
||||
|
||||
assert app_config.is_registration_enabled is True
|
||||
assert (
|
||||
app_config.map_attribution
|
||||
== app.config['TILE_SERVER']['ATTRIBUTION']
|
||||
)
|
||||
|
||||
serialized_app_config = app_config.serialize()
|
||||
assert serialized_app_config['gpx_limit_import'] == 10
|
||||
assert serialized_app_config['is_registration_enabled'] is True
|
||||
assert serialized_app_config['max_single_file_size'] == 1048576
|
||||
assert serialized_app_config['max_zip_file_size'] == 10485760
|
||||
assert serialized_app_config['max_users'] == 100
|
||||
assert serialized_app_config['map_attribution'] == (
|
||||
'© <a href="http://www.openstreetmap.org/copyright" '
|
||||
'target="_blank" rel="noopener noreferrer">OpenStreetMap</a> '
|
||||
'contributors'
|
||||
assert (
|
||||
serialized_app_config['admin_contact'] == app_config.admin_contact
|
||||
)
|
||||
assert 'admin_contact' in serialized_app_config
|
||||
assert (
|
||||
serialized_app_config['gpx_limit_import']
|
||||
== app_config.gpx_limit_import
|
||||
)
|
||||
assert serialized_app_config['is_registration_enabled'] is True
|
||||
assert (
|
||||
serialized_app_config['max_single_file_size']
|
||||
== app_config.max_single_file_size
|
||||
)
|
||||
assert (
|
||||
serialized_app_config['max_zip_file_size']
|
||||
== app_config.max_zip_file_size
|
||||
)
|
||||
assert serialized_app_config['max_users'] == app_config.max_users
|
||||
assert (
|
||||
serialized_app_config['map_attribution']
|
||||
== app_config.map_attribution
|
||||
)
|
||||
assert serialized_app_config['version'] == VERSION
|
||||
|
||||
def test_it_returns_registration_disabled_when_users_count_exceeds_limit(
|
||||
self, app: Flask, user_1: User, user_2: User
|
||||
) -> None:
|
||||
app_config = AppConfig.query.first()
|
||||
app_config.max_users = 2
|
||||
serialized_app_config = app_config.serialize()
|
||||
|
||||
assert app_config.is_registration_enabled is False
|
||||
assert serialized_app_config['is_registration_enabled'] is False
|
||||
|
81
fittrackee/tests/fixtures/fixtures_workouts.py
vendored
@ -1,6 +1,6 @@
|
||||
import datetime
|
||||
from io import BytesIO
|
||||
from typing import Generator
|
||||
from typing import Generator, List
|
||||
from unittest.mock import Mock, patch
|
||||
from uuid import uuid4
|
||||
|
||||
@ -107,96 +107,105 @@ def workout_running_user_1() -> Workout:
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def seven_workouts_user_1() -> Workout:
|
||||
workout = Workout(
|
||||
def seven_workouts_user_1() -> List[Workout]:
|
||||
workouts = []
|
||||
workout_1 = Workout(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
workout_date=datetime.datetime.strptime('20/03/2017', '%d/%m/%Y'),
|
||||
distance=5,
|
||||
duration=datetime.timedelta(seconds=1024),
|
||||
)
|
||||
update_workout(workout)
|
||||
workout.ascent = 120
|
||||
workout.descent = 200
|
||||
db.session.add(workout)
|
||||
update_workout(workout_1)
|
||||
workout_1.ascent = 120
|
||||
workout_1.descent = 200
|
||||
db.session.add(workout_1)
|
||||
db.session.flush()
|
||||
workouts.append(workout_1)
|
||||
|
||||
workout = Workout(
|
||||
workout_2 = Workout(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
workout_date=datetime.datetime.strptime('01/06/2017', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=3456),
|
||||
)
|
||||
update_workout(workout)
|
||||
workout.ascent = 100
|
||||
workout.descent = 80
|
||||
db.session.add(workout)
|
||||
update_workout(workout_2)
|
||||
workout_2.ascent = 100
|
||||
workout_2.descent = 80
|
||||
db.session.add(workout_2)
|
||||
db.session.flush()
|
||||
workouts.append(workout_2)
|
||||
|
||||
workout = Workout(
|
||||
workout_3 = Workout(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
workout_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=1024),
|
||||
)
|
||||
update_workout(workout)
|
||||
workout.ascent = 80
|
||||
workout.descent = 100
|
||||
db.session.add(workout)
|
||||
update_workout(workout_3)
|
||||
workout_3.ascent = 80
|
||||
workout_3.descent = 100
|
||||
db.session.add(workout_3)
|
||||
db.session.flush()
|
||||
workouts.append(workout_3)
|
||||
|
||||
workout = Workout(
|
||||
workout_4 = Workout(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
workout_date=datetime.datetime.strptime('23/02/2018', '%d/%m/%Y'),
|
||||
distance=1,
|
||||
duration=datetime.timedelta(seconds=600),
|
||||
)
|
||||
update_workout(workout)
|
||||
workout.ascent = 120
|
||||
workout.descent = 180
|
||||
db.session.add(workout)
|
||||
update_workout(workout_4)
|
||||
workout_4.ascent = 120
|
||||
workout_4.descent = 180
|
||||
db.session.add(workout_4)
|
||||
db.session.flush()
|
||||
workouts.append(workout_4)
|
||||
|
||||
workout = Workout(
|
||||
workout_5 = Workout(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
workout_date=datetime.datetime.strptime('23/02/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=1000),
|
||||
)
|
||||
update_workout(workout)
|
||||
workout.ascent = 100
|
||||
workout.descent = 200
|
||||
db.session.add(workout)
|
||||
update_workout(workout_5)
|
||||
workout_5.ascent = 100
|
||||
workout_5.descent = 200
|
||||
db.session.add(workout_5)
|
||||
db.session.flush()
|
||||
workouts.append(workout_5)
|
||||
|
||||
workout = Workout(
|
||||
workout_6 = Workout(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
workout_date=datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'),
|
||||
distance=8,
|
||||
duration=datetime.timedelta(seconds=6000),
|
||||
)
|
||||
update_workout(workout)
|
||||
workout.ascent = 40
|
||||
workout.descent = 20
|
||||
db.session.add(workout)
|
||||
update_workout(workout_6)
|
||||
workout_6.ascent = 40
|
||||
workout_6.descent = 20
|
||||
db.session.add(workout_6)
|
||||
db.session.flush()
|
||||
workouts.append(workout_6)
|
||||
|
||||
workout = Workout(
|
||||
workout_7 = Workout(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
workout_date=datetime.datetime.strptime('09/05/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=3000),
|
||||
)
|
||||
update_workout(workout)
|
||||
db.session.add(workout)
|
||||
update_workout(workout_7)
|
||||
db.session.add(workout_7)
|
||||
db.session.commit()
|
||||
return workout
|
||||
workouts.append(workout_7)
|
||||
|
||||
return workouts
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
@ -4,6 +4,7 @@ from uuid import uuid4
|
||||
import pytest
|
||||
|
||||
from fittrackee.files import display_readable_file_size
|
||||
from fittrackee.request import UserAgent
|
||||
from fittrackee.utils import get_readable_duration
|
||||
|
||||
|
||||
@ -42,3 +43,28 @@ class TestReadableDuration:
|
||||
readable_duration = get_readable_duration(30, locale)
|
||||
|
||||
assert readable_duration == expected_duration
|
||||
|
||||
|
||||
class TestParseUserAgent:
|
||||
string = (
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:98.0) '
|
||||
'Gecko/20100101 Firefox/98.0'
|
||||
)
|
||||
|
||||
def test_it_returns_browser_name(self) -> None:
|
||||
user_agent = UserAgent(self.string)
|
||||
assert user_agent.browser == 'Firefox'
|
||||
|
||||
def test_it_returns_other_as_brother_name_when_empty_string_provided(
|
||||
self,
|
||||
) -> None:
|
||||
user_agent = UserAgent('')
|
||||
assert user_agent.browser == 'Other'
|
||||
|
||||
def test_it_returns_operating_system(self) -> None:
|
||||
user_agent = UserAgent(self.string)
|
||||
assert user_agent.platform == 'Linux'
|
||||
|
||||
def test_it_returns_other_as_os_when_empty_string_provided(self) -> None:
|
||||
user_agent = UserAgent('')
|
||||
assert user_agent.platform == 'Other'
|
||||
|
@ -9,9 +9,10 @@ from freezegun import freeze_time
|
||||
|
||||
from fittrackee.users.models import User, UserSportPreference
|
||||
from fittrackee.users.utils.token import get_user_token
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
from fittrackee.workouts.models import Sport
|
||||
|
||||
from ..mixins import ApiTestCaseMixin
|
||||
from ..utils import jsonify_dict
|
||||
|
||||
USER_AGENT = (
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0'
|
||||
@ -284,8 +285,8 @@ class TestUserRegistration(ApiTestCaseMixin):
|
||||
{
|
||||
'username': username,
|
||||
'fittrackee_url': 'http://0.0.0.0:5000',
|
||||
'operating_system': 'linux',
|
||||
'browser_name': 'firefox',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
'account_confirmation_url': (
|
||||
'http://0.0.0.0:5000/account-confirmation'
|
||||
f'?token={expected_token}'
|
||||
@ -453,9 +454,7 @@ class TestUserProfile(ApiTestCaseMixin):
|
||||
|
||||
self.assert_401(response, 'invalid token, please log in again')
|
||||
|
||||
def test_it_returns_user_minimal_profile(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
def test_it_returns_user(self, app: Flask, user_1: User) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
)
|
||||
@ -468,92 +467,7 @@ class TestUserProfile(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['data'] is not None
|
||||
assert data['data']['username'] == 'test'
|
||||
assert data['data']['email'] == 'test@test.com'
|
||||
assert data['data']['created_at']
|
||||
assert not data['data']['admin']
|
||||
assert data['data']['timezone'] is None
|
||||
assert data['data']['weekm'] is False
|
||||
assert data['data']['imperial_units'] is False
|
||||
assert data['data']['language'] is None
|
||||
assert data['data']['nb_sports'] == 0
|
||||
assert data['data']['nb_workouts'] == 0
|
||||
assert data['data']['records'] == []
|
||||
assert data['data']['sports_list'] == []
|
||||
assert data['data']['total_distance'] == 0
|
||||
assert data['data']['total_duration'] == '0:00:00'
|
||||
|
||||
def test_it_returns_user_full_profile(
|
||||
self, app: Flask, user_1_full: User
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1_full.email
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/auth/profile',
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['data'] is not None
|
||||
assert data['data']['username'] == 'test'
|
||||
assert data['data']['email'] == 'test@test.com'
|
||||
assert data['data']['created_at']
|
||||
assert not data['data']['admin']
|
||||
assert data['data']['first_name'] == 'John'
|
||||
assert data['data']['last_name'] == 'Doe'
|
||||
assert data['data']['birth_date']
|
||||
assert data['data']['bio'] == 'just a random guy'
|
||||
assert data['data']['imperial_units'] is False
|
||||
assert data['data']['location'] == 'somewhere'
|
||||
assert data['data']['timezone'] == 'America/New_York'
|
||||
assert data['data']['weekm'] is False
|
||||
assert data['data']['language'] == 'en'
|
||||
assert data['data']['nb_sports'] == 0
|
||||
assert data['data']['nb_workouts'] == 0
|
||||
assert data['data']['records'] == []
|
||||
assert data['data']['sports_list'] == []
|
||||
assert data['data']['total_distance'] == 0
|
||||
assert data['data']['total_duration'] == '0:00:00'
|
||||
|
||||
def test_it_returns_user_profile_with_workouts(
|
||||
self,
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
sport_2_running: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/auth/profile',
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['data'] is not None
|
||||
assert data['data']['username'] == 'test'
|
||||
assert data['data']['email'] == 'test@test.com'
|
||||
assert data['data']['created_at']
|
||||
assert not data['data']['admin']
|
||||
assert data['data']['timezone'] is None
|
||||
assert data['data']['imperial_units'] is False
|
||||
assert data['data']['nb_sports'] == 2
|
||||
assert data['data']['nb_workouts'] == 2
|
||||
assert len(data['data']['records']) == 8
|
||||
assert data['data']['sports_list'] == [1, 2]
|
||||
assert data['data']['total_distance'] == 22
|
||||
assert data['data']['total_duration'] == '2:40:00'
|
||||
assert data['data'] == jsonify_dict(user_1.serialize(user_1))
|
||||
|
||||
|
||||
class TestUserProfileUpdate(ApiTestCaseMixin):
|
||||
@ -618,25 +532,7 @@ class TestUserProfileUpdate(ApiTestCaseMixin):
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['message'] == 'user profile updated'
|
||||
assert data['data']['username'] == user_1.username
|
||||
assert data['data']['email'] == user_1.email
|
||||
assert not data['data']['admin']
|
||||
assert data['data']['created_at']
|
||||
assert data['data']['first_name'] == first_name
|
||||
assert data['data']['last_name'] == last_name
|
||||
assert data['data']['birth_date'] == 'Tue, 01 Jan 1980 00:00:00 GMT'
|
||||
assert data['data']['bio'] == bio
|
||||
assert data['data']['imperial_units'] is False
|
||||
assert data['data']['location'] == location
|
||||
assert data['data']['timezone'] is None
|
||||
assert data['data']['weekm'] is False
|
||||
assert data['data']['language'] is None
|
||||
assert data['data']['nb_sports'] == 0
|
||||
assert data['data']['nb_workouts'] == 0
|
||||
assert data['data']['records'] == []
|
||||
assert data['data']['sports_list'] == []
|
||||
assert data['data']['total_distance'] == 0
|
||||
assert data['data']['total_duration'] == '0:00:00'
|
||||
assert data['data'] == jsonify_dict(user_1.serialize(user_1))
|
||||
|
||||
|
||||
class TestUserAccountUpdate(ApiTestCaseMixin):
|
||||
@ -911,8 +807,8 @@ class TestUserAccountUpdate(ApiTestCaseMixin):
|
||||
{
|
||||
'username': user_1.username,
|
||||
'fittrackee_url': 'http://0.0.0.0:5000',
|
||||
'operating_system': 'linux',
|
||||
'browser_name': 'firefox',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
'new_email_address': new_email,
|
||||
},
|
||||
)
|
||||
@ -953,8 +849,8 @@ class TestUserAccountUpdate(ApiTestCaseMixin):
|
||||
{
|
||||
'username': user_1.username,
|
||||
'fittrackee_url': 'http://0.0.0.0:5000',
|
||||
'operating_system': 'linux',
|
||||
'browser_name': 'firefox',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
'email_confirmation_url': (
|
||||
f'http://0.0.0.0:5000/email-update?token={expected_token}'
|
||||
),
|
||||
@ -1113,8 +1009,8 @@ class TestUserAccountUpdate(ApiTestCaseMixin):
|
||||
{
|
||||
'username': user_1.username,
|
||||
'fittrackee_url': 'http://0.0.0.0:5000',
|
||||
'operating_system': 'linux',
|
||||
'browser_name': 'firefox',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
},
|
||||
)
|
||||
|
||||
@ -1270,25 +1166,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin):
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['message'] == 'user preferences updated'
|
||||
assert data['data']['username'] == user_1.username
|
||||
assert data['data']['email'] == user_1.email
|
||||
assert not data['data']['admin']
|
||||
assert data['data']['created_at']
|
||||
assert data['data']['first_name'] is None
|
||||
assert data['data']['last_name'] is None
|
||||
assert data['data']['birth_date'] is None
|
||||
assert data['data']['bio'] is None
|
||||
assert data['data']['imperial_units']
|
||||
assert data['data']['location'] is None
|
||||
assert data['data']['timezone'] == 'America/New_York'
|
||||
assert data['data']['weekm'] is True
|
||||
assert data['data']['language'] == 'fr'
|
||||
assert data['data']['nb_sports'] == 0
|
||||
assert data['data']['nb_workouts'] == 0
|
||||
assert data['data']['records'] == []
|
||||
assert data['data']['sports_list'] == []
|
||||
assert data['data']['total_distance'] == 0
|
||||
assert data['data']['total_duration'] == '0:00:00'
|
||||
assert data['data'] == jsonify_dict(user_1.serialize(user_1))
|
||||
|
||||
|
||||
class TestUserSportPreferencesUpdate(ApiTestCaseMixin):
|
||||
@ -1812,8 +1690,8 @@ class TestPasswordResetRequest(ApiTestCaseMixin):
|
||||
f'http://0.0.0.0:5000/password-reset?token={token}'
|
||||
),
|
||||
'fittrackee_url': 'http://0.0.0.0:5000',
|
||||
'operating_system': 'linux',
|
||||
'browser_name': 'firefox',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
},
|
||||
)
|
||||
|
||||
@ -2025,8 +1903,8 @@ class TestPasswordUpdate(ApiTestCaseMixin):
|
||||
{
|
||||
'username': user_1.username,
|
||||
'fittrackee_url': 'http://0.0.0.0:5000',
|
||||
'operating_system': 'linux',
|
||||
'browser_name': 'firefox',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
},
|
||||
)
|
||||
|
||||
@ -2252,8 +2130,8 @@ class TestResendAccountConfirmationEmail(ApiTestCaseMixin):
|
||||
{
|
||||
'username': inactive_user.username,
|
||||
'fittrackee_url': 'http://0.0.0.0:5000',
|
||||
'operating_system': 'linux',
|
||||
'browser_name': 'firefox',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
'account_confirmation_url': (
|
||||
'http://0.0.0.0:5000/account-confirmation'
|
||||
f'?token={expected_token}'
|
||||
|
@ -10,6 +10,7 @@ from fittrackee.utils import get_readable_duration
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..mixins import ApiTestCaseMixin
|
||||
from ..utils import jsonify_dict
|
||||
|
||||
|
||||
class TestGetUser(ApiTestCaseMixin):
|
||||
@ -28,6 +29,26 @@ class TestGetUser(ApiTestCaseMixin):
|
||||
|
||||
self.assert_403(response)
|
||||
|
||||
def test_user_can_access_his_profile(
|
||||
self, app: Flask, user_1: User, user_2: User
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
f'/api/users/{user_1.username}',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert data['status'] == 'success'
|
||||
assert len(data['data']['users']) == 1
|
||||
user = data['data']['users'][0]
|
||||
assert user['username'] == user_1.username
|
||||
|
||||
def test_it_gets_inactive_user(
|
||||
self, app: Flask, user_1_admin: User, inactive_user: User
|
||||
) -> None:
|
||||
@ -46,22 +67,7 @@ class TestGetUser(ApiTestCaseMixin):
|
||||
assert data['status'] == 'success'
|
||||
assert len(data['data']['users']) == 1
|
||||
user = data['data']['users'][0]
|
||||
assert user['username'] == inactive_user.username
|
||||
assert user['email'] == inactive_user.email
|
||||
assert user['created_at']
|
||||
assert not user['admin']
|
||||
assert not user['is_active']
|
||||
assert user['first_name'] is None
|
||||
assert user['last_name'] is None
|
||||
assert user['birth_date'] is None
|
||||
assert user['bio'] is None
|
||||
assert user['location'] is None
|
||||
assert user['nb_sports'] == 0
|
||||
assert user['nb_workouts'] == 0
|
||||
assert user['records'] == []
|
||||
assert user['sports_list'] == []
|
||||
assert user['total_distance'] == 0
|
||||
assert user['total_duration'] == '0:00:00'
|
||||
assert user == jsonify_dict(inactive_user.serialize(user_1_admin))
|
||||
|
||||
def test_it_gets_single_user_without_workouts(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
@ -81,22 +87,7 @@ class TestGetUser(ApiTestCaseMixin):
|
||||
assert data['status'] == 'success'
|
||||
assert len(data['data']['users']) == 1
|
||||
user = data['data']['users'][0]
|
||||
assert user['username'] == user_2.username
|
||||
assert user['email'] == user_2.email
|
||||
assert user['created_at']
|
||||
assert not user['admin']
|
||||
assert user['is_active']
|
||||
assert user['first_name'] is None
|
||||
assert user['last_name'] is None
|
||||
assert user['birth_date'] is None
|
||||
assert user['bio'] is None
|
||||
assert user['location'] is None
|
||||
assert user['nb_sports'] == 0
|
||||
assert user['nb_workouts'] == 0
|
||||
assert user['records'] == []
|
||||
assert user['sports_list'] == []
|
||||
assert user['total_distance'] == 0
|
||||
assert user['total_duration'] == '0:00:00'
|
||||
assert user == jsonify_dict(user_2.serialize(user_1_admin))
|
||||
|
||||
def test_it_gets_single_user_with_workouts(
|
||||
self,
|
||||
@ -123,22 +114,7 @@ class TestGetUser(ApiTestCaseMixin):
|
||||
assert data['status'] == 'success'
|
||||
assert len(data['data']['users']) == 1
|
||||
user = data['data']['users'][0]
|
||||
assert user['username'] == user_1.username
|
||||
assert user['email'] == user_1.email
|
||||
assert user['created_at']
|
||||
assert not user['admin']
|
||||
assert user['is_active']
|
||||
assert user['first_name'] is None
|
||||
assert user['last_name'] is None
|
||||
assert user['birth_date'] is None
|
||||
assert user['bio'] is None
|
||||
assert user['location'] is None
|
||||
assert len(user['records']) == 8
|
||||
assert user['nb_sports'] == 2
|
||||
assert user['nb_workouts'] == 2
|
||||
assert user['sports_list'] == [1, 2]
|
||||
assert user['total_distance'] == 22
|
||||
assert user['total_duration'] == '2:40:00'
|
||||
assert user == jsonify_dict(user_1.serialize(user_2_admin))
|
||||
|
||||
def test_it_returns_error_if_user_does_not_exist(
|
||||
self, app: Flask, user_1_admin: User
|
||||
@ -187,106 +163,15 @@ class TestGetUsers(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['users']) == 3
|
||||
assert 'created_at' in data['data']['users'][0]
|
||||
assert 'created_at' in data['data']['users'][1]
|
||||
assert 'created_at' in data['data']['users'][2]
|
||||
assert 'admin' in data['data']['users'][0]['username']
|
||||
assert 'inactive' in data['data']['users'][1]['username']
|
||||
assert 'sam' in data['data']['users'][2]['username']
|
||||
assert 'admin@example.com' in data['data']['users'][0]['email']
|
||||
assert 'inactive@example.com' in data['data']['users'][1]['email']
|
||||
assert 'sam@test.com' in data['data']['users'][2]['email']
|
||||
assert data['data']['users'][0]['is_active']
|
||||
assert not data['data']['users'][1]['is_active']
|
||||
assert data['data']['users'][2]['is_active']
|
||||
assert data['data']['users'][0]['imperial_units'] is False
|
||||
assert data['data']['users'][0]['timezone'] is None
|
||||
assert data['data']['users'][0]['weekm'] is False
|
||||
assert data['data']['users'][0]['language'] is None
|
||||
assert data['data']['users'][0]['nb_sports'] == 0
|
||||
assert data['data']['users'][0]['nb_workouts'] == 0
|
||||
assert data['data']['users'][0]['records'] == []
|
||||
assert data['data']['users'][0]['sports_list'] == []
|
||||
assert data['data']['users'][0]['total_distance'] == 0
|
||||
assert data['data']['users'][0]['total_duration'] == '0:00:00'
|
||||
assert data['data']['users'][1]['nb_sports'] == 0
|
||||
assert data['data']['users'][1]['nb_workouts'] == 0
|
||||
assert data['data']['users'][1]['records'] == []
|
||||
assert data['data']['users'][1]['sports_list'] == []
|
||||
assert data['data']['users'][1]['total_distance'] == 0
|
||||
assert data['data']['users'][1]['total_duration'] == '0:00:00'
|
||||
assert data['data']['users'][2]['records'] == []
|
||||
assert data['data']['users'][2]['nb_sports'] == 0
|
||||
assert data['data']['users'][2]['nb_workouts'] == 0
|
||||
assert data['data']['users'][2]['sports_list'] == []
|
||||
assert data['data']['users'][2]['total_distance'] == 0
|
||||
assert data['data']['users'][2]['total_duration'] == '0:00:00'
|
||||
assert data['pagination'] == {
|
||||
'has_next': False,
|
||||
'has_prev': False,
|
||||
'page': 1,
|
||||
'pages': 1,
|
||||
'total': 3,
|
||||
}
|
||||
|
||||
def test_it_gets_users_list_with_workouts(
|
||||
self,
|
||||
app: Flask,
|
||||
user_1_admin: User,
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
sport_2_running: Sport,
|
||||
workout_running_user_1: Workout,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1_admin.email
|
||||
assert data['data']['users'][0] == jsonify_dict(
|
||||
user_1_admin.serialize(user_1_admin)
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/users',
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
assert data['data']['users'][1] == jsonify_dict(
|
||||
inactive_user.serialize(user_1_admin)
|
||||
)
|
||||
assert data['data']['users'][2] == jsonify_dict(
|
||||
user_3.serialize(user_1_admin)
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['users']) == 3
|
||||
assert 'created_at' in data['data']['users'][0]
|
||||
assert 'created_at' in data['data']['users'][1]
|
||||
assert 'created_at' in data['data']['users'][2]
|
||||
assert 'admin' in data['data']['users'][0]['username']
|
||||
assert 'toto' in data['data']['users'][1]['username']
|
||||
assert 'sam' in data['data']['users'][2]['username']
|
||||
assert 'admin@example.com' in data['data']['users'][0]['email']
|
||||
assert 'toto@toto.com' in data['data']['users'][1]['email']
|
||||
assert 'sam@test.com' in data['data']['users'][2]['email']
|
||||
assert data['data']['users'][0]['is_active']
|
||||
assert data['data']['users'][1]['is_active']
|
||||
assert data['data']['users'][2]['is_active']
|
||||
assert data['data']['users'][0]['imperial_units'] is False
|
||||
assert data['data']['users'][0]['timezone'] is None
|
||||
assert data['data']['users'][0]['weekm'] is False
|
||||
assert data['data']['users'][0]['nb_sports'] == 2
|
||||
assert data['data']['users'][0]['nb_workouts'] == 2
|
||||
assert len(data['data']['users'][0]['records']) == 8
|
||||
assert data['data']['users'][0]['sports_list'] == [1, 2]
|
||||
assert data['data']['users'][0]['total_distance'] == 22.0
|
||||
assert data['data']['users'][0]['total_duration'] == '2:40:00'
|
||||
assert data['data']['users'][1]['nb_sports'] == 1
|
||||
assert data['data']['users'][1]['nb_workouts'] == 1
|
||||
assert len(data['data']['users'][1]['records']) == 4
|
||||
assert data['data']['users'][1]['sports_list'] == [1]
|
||||
assert data['data']['users'][1]['total_distance'] == 15
|
||||
assert data['data']['users'][1]['total_duration'] == '1:00:00'
|
||||
assert data['data']['users'][2]['nb_sports'] == 0
|
||||
assert data['data']['users'][2]['nb_workouts'] == 0
|
||||
assert len(data['data']['users'][2]['records']) == 0
|
||||
assert data['data']['users'][2]['sports_list'] == []
|
||||
assert data['data']['users'][2]['total_distance'] == 0
|
||||
assert data['data']['users'][2]['total_duration'] == '0:00:00'
|
||||
assert data['pagination'] == {
|
||||
'has_next': False,
|
||||
'has_prev': False,
|
||||
|
@ -9,77 +9,145 @@ from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
|
||||
class TestUserModel:
|
||||
@staticmethod
|
||||
def assert_serialized_used(serialized_user: Dict) -> None:
|
||||
assert 'created_at' in serialized_user
|
||||
assert serialized_user['admin'] is False
|
||||
assert serialized_user['first_name'] is None
|
||||
assert serialized_user['is_active']
|
||||
assert serialized_user['last_name'] is None
|
||||
assert serialized_user['bio'] is None
|
||||
assert serialized_user['location'] is None
|
||||
assert serialized_user['birth_date'] is None
|
||||
assert serialized_user['picture'] is False
|
||||
assert serialized_user['nb_workouts'] == 0
|
||||
|
||||
def test_user_model_as_auth_user(self, app: Flask, user_1: User) -> None:
|
||||
def test_it_returns_username_in_string_value(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
assert '<User \'test\'>' == str(user_1)
|
||||
|
||||
|
||||
class UserModelAssertMixin:
|
||||
@staticmethod
|
||||
def assert_user_account(serialized_user: Dict, user: User) -> None:
|
||||
assert serialized_user['admin'] == user.admin
|
||||
assert serialized_user['email_to_confirm'] == user.email_to_confirm
|
||||
assert serialized_user['is_active'] == user.is_active
|
||||
assert serialized_user['username'] == user.username
|
||||
|
||||
@staticmethod
|
||||
def assert_user_profile(serialized_user: Dict, user: User) -> None:
|
||||
assert serialized_user['bio'] == user.bio
|
||||
assert serialized_user['birth_date'] == user.birth_date
|
||||
assert serialized_user['first_name'] == user.first_name
|
||||
assert serialized_user['last_name'] == user.last_name
|
||||
assert serialized_user['location'] == user.location
|
||||
assert serialized_user['picture'] is False
|
||||
|
||||
@staticmethod
|
||||
def assert_workouts_keys_are_present(serialized_user: Dict) -> None:
|
||||
assert 'nb_sports' in serialized_user
|
||||
assert 'nb_workouts' in serialized_user
|
||||
assert 'records' in serialized_user
|
||||
assert 'sports_list' in serialized_user
|
||||
assert 'total_distance' in serialized_user
|
||||
assert 'total_duration' in serialized_user
|
||||
|
||||
|
||||
class TestUserSerializeAsAuthUser(UserModelAssertMixin):
|
||||
def test_it_returns_user_account_infos(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
serialized_user = user_1.serialize(user_1)
|
||||
|
||||
self.assert_serialized_used(serialized_user)
|
||||
assert 'test' == serialized_user['username']
|
||||
assert 'test@test.com' == serialized_user['email']
|
||||
assert serialized_user['nb_sports'] == 0
|
||||
assert serialized_user['records'] == []
|
||||
assert serialized_user['sports_list'] == []
|
||||
assert serialized_user['total_distance'] == 0
|
||||
assert serialized_user['total_duration'] == '0:00:00'
|
||||
assert serialized_user['imperial_units'] is False
|
||||
assert serialized_user['language'] is None
|
||||
assert serialized_user['timezone'] is None
|
||||
assert serialized_user['weekm'] is False
|
||||
assert serialized_user['email_to_confirm'] is None
|
||||
assert 'confirmation_token' not in serialized_user
|
||||
self.assert_user_account(serialized_user, user_1)
|
||||
|
||||
def test_user_model_as_admin(
|
||||
def test_it_returns_user_profile_infos(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
serialized_user = user_1.serialize(user_1)
|
||||
|
||||
self.assert_user_profile(serialized_user, user_1)
|
||||
|
||||
def test_it_returns_user_preferences(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
serialized_user = user_1.serialize(user_1)
|
||||
|
||||
assert serialized_user['imperial_units'] == user_1.imperial_units
|
||||
assert serialized_user['language'] == user_1.language
|
||||
assert serialized_user['timezone'] == user_1.timezone
|
||||
assert serialized_user['weekm'] == user_1.weekm
|
||||
|
||||
def test_it_returns_workouts_infos(self, app: Flask, user_1: User) -> None:
|
||||
serialized_user = user_1.serialize(user_1)
|
||||
|
||||
self.assert_workouts_keys_are_present(serialized_user)
|
||||
|
||||
def test_it_does_not_return_confirmation_token(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
serialized_user = user_2.serialize(user_1_admin)
|
||||
|
||||
assert 'confirmation_token' not in serialized_user
|
||||
|
||||
|
||||
class TestUserSerializeAsAdmin(UserModelAssertMixin):
|
||||
def test_it_returns_user_account_infos(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
serialized_user = user_2.serialize(user_1_admin)
|
||||
|
||||
self.assert_user_account(serialized_user, user_2)
|
||||
|
||||
def test_it_returns_user_profile_infos(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
serialized_user = user_2.serialize(user_1_admin)
|
||||
|
||||
self.assert_user_profile(serialized_user, user_1_admin)
|
||||
|
||||
def test_it_does_return_user_preferences(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
serialized_user = user_2.serialize(user_1_admin)
|
||||
|
||||
self.assert_serialized_used(serialized_user)
|
||||
assert 'toto' == serialized_user['username']
|
||||
assert 'toto@toto.com' == serialized_user['email']
|
||||
assert serialized_user['nb_sports'] == 0
|
||||
assert serialized_user['records'] == []
|
||||
assert serialized_user['sports_list'] == []
|
||||
assert serialized_user['total_distance'] == 0
|
||||
assert serialized_user['total_duration'] == '0:00:00'
|
||||
assert serialized_user['email_to_confirm'] is None
|
||||
assert 'imperial_units' not in serialized_user
|
||||
assert 'language' not in serialized_user
|
||||
assert 'timezone' not in serialized_user
|
||||
assert 'weekm' not in serialized_user
|
||||
|
||||
def test_it_returns_workouts_infos(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
serialized_user = user_2.serialize(user_1_admin)
|
||||
|
||||
self.assert_workouts_keys_are_present(serialized_user)
|
||||
|
||||
def test_it_does_not_return_confirmation_token(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
serialized_user = user_2.serialize(user_1_admin)
|
||||
|
||||
assert 'confirmation_token' not in serialized_user
|
||||
|
||||
|
||||
class TestInactiveUserSerialize(UserModelAssertMixin):
|
||||
def test_it_returns_is_active_to_false_for_inactive_user(
|
||||
self,
|
||||
app: Flask,
|
||||
inactive_user: User,
|
||||
) -> None:
|
||||
serialized_user = inactive_user.serialize(inactive_user)
|
||||
|
||||
assert serialized_user['is_active'] is False
|
||||
|
||||
|
||||
class TestUserSerializeAsRegularUser(UserModelAssertMixin):
|
||||
def test_user_model_as_regular_user(
|
||||
self, app: Flask, user_1: User, user_2: User
|
||||
) -> None:
|
||||
with pytest.raises(UserNotFoundException):
|
||||
user_2.serialize(user_1)
|
||||
|
||||
def test_encode_auth_token(self, app: Flask, user_1: User) -> None:
|
||||
auth_token = user_1.encode_auth_token(user_1.id)
|
||||
assert isinstance(auth_token, str)
|
||||
|
||||
def test_encode_password_token(self, app: Flask, user_1: User) -> None:
|
||||
password_token = user_1.encode_password_reset_token(user_1.id)
|
||||
assert isinstance(password_token, str)
|
||||
class TestUserRecords(UserModelAssertMixin):
|
||||
def test_it_returns_empty_list_when_no_workouts(
|
||||
self,
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
) -> None:
|
||||
serialized_user = user_1.serialize(user_1)
|
||||
|
||||
def test_decode_auth_token(self, app: Flask, user_1: User) -> None:
|
||||
auth_token = user_1.encode_auth_token(user_1.id)
|
||||
assert isinstance(auth_token, str)
|
||||
assert User.decode_auth_token(auth_token) == user_1.id
|
||||
assert serialized_user['records'] == []
|
||||
|
||||
def test_it_returns_user_records(
|
||||
self,
|
||||
@ -100,14 +168,79 @@ class TestUserModel:
|
||||
)
|
||||
assert serialized_user['records'][0]['workout_date']
|
||||
|
||||
def test_it_returns_is_active_to_false_fot_inactive_user(
|
||||
|
||||
class TestUserWorkouts(UserModelAssertMixin):
|
||||
def test_it_returns_infos_when_no_workouts(
|
||||
self,
|
||||
app: Flask,
|
||||
inactive_user: User,
|
||||
user_1: User,
|
||||
) -> None:
|
||||
serialized_user = inactive_user.serialize(inactive_user)
|
||||
serialized_user = user_1.serialize(user_1)
|
||||
|
||||
assert serialized_user['is_active'] is False
|
||||
assert serialized_user['nb_sports'] == 0
|
||||
assert serialized_user['nb_workouts'] == 0
|
||||
assert serialized_user['sports_list'] == []
|
||||
assert serialized_user['total_distance'] == 0
|
||||
assert serialized_user['total_duration'] == '0:00:00'
|
||||
|
||||
def test_it_returns_infos_when_only_one_workout_exists(
|
||||
self,
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
serialized_user = user_1.serialize(user_1)
|
||||
|
||||
assert serialized_user['nb_sports'] == 1
|
||||
assert serialized_user['nb_workouts'] == 1
|
||||
assert serialized_user['sports_list'] == [sport_1_cycling.id]
|
||||
assert (
|
||||
serialized_user['total_distance']
|
||||
== workout_cycling_user_1.distance
|
||||
)
|
||||
assert serialized_user['total_duration'] == str(
|
||||
workout_cycling_user_1.duration
|
||||
)
|
||||
|
||||
def test_it_returns_infos_when_several_sports(
|
||||
self,
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
sport_2_running: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
serialized_user = user_1.serialize(user_1)
|
||||
|
||||
assert serialized_user['nb_sports'] == 2
|
||||
assert serialized_user['nb_workouts'] == 2
|
||||
assert serialized_user['sports_list'] == [
|
||||
sport_1_cycling.id,
|
||||
sport_2_running.id,
|
||||
]
|
||||
assert serialized_user['total_distance'] == (
|
||||
workout_cycling_user_1.distance + workout_running_user_1.distance
|
||||
)
|
||||
assert serialized_user['total_duration'] == str(
|
||||
workout_cycling_user_1.duration + workout_running_user_1.duration
|
||||
)
|
||||
|
||||
|
||||
class TestUserModelToken:
|
||||
def test_encode_auth_token(self, app: Flask, user_1: User) -> None:
|
||||
auth_token = user_1.encode_auth_token(user_1.id)
|
||||
assert isinstance(auth_token, str)
|
||||
|
||||
def test_encode_password_token(self, app: Flask, user_1: User) -> None:
|
||||
password_token = user_1.encode_password_reset_token(user_1.id)
|
||||
assert isinstance(password_token, str)
|
||||
|
||||
def test_decode_auth_token(self, app: Flask, user_1: User) -> None:
|
||||
auth_token = user_1.encode_auth_token(user_1.id)
|
||||
assert isinstance(auth_token, str)
|
||||
assert User.decode_auth_token(auth_token) == user_1.id
|
||||
|
||||
|
||||
class TestUserSportModel:
|
||||
|
@ -1,6 +1,9 @@
|
||||
import random
|
||||
import string
|
||||
from typing import Optional
|
||||
from json import loads
|
||||
from typing import Dict, Optional
|
||||
|
||||
from flask import json as flask_json
|
||||
|
||||
|
||||
def random_string(
|
||||
@ -23,3 +26,7 @@ def random_string(
|
||||
|
||||
def random_email() -> str:
|
||||
return random_string(suffix='@example.com')
|
||||
|
||||
|
||||
def jsonify_dict(data: Dict) -> Dict:
|
||||
return loads(flask_json.dumps(data))
|
||||
|
@ -14,26 +14,34 @@ class TestRecordModel:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
record_type = 'LD'
|
||||
|
||||
record_ld = Record.query.filter_by(
|
||||
user_id=workout_cycling_user_1.user_id,
|
||||
sport_id=workout_cycling_user_1.sport_id,
|
||||
record_type='LD',
|
||||
record_type=record_type,
|
||||
).first()
|
||||
assert 'test' == record_ld.user.username
|
||||
assert 1 == record_ld.sport_id
|
||||
assert 1 == record_ld.workout_id
|
||||
assert 'LD' == record_ld.record_type
|
||||
assert '2018-01-01 00:00:00' == str(record_ld.workout_date)
|
||||
|
||||
assert record_ld.user.username == user_1.username
|
||||
assert record_ld.sport_id == sport_1_cycling.id
|
||||
assert record_ld.workout_id == workout_cycling_user_1.sport_id
|
||||
assert record_ld.record_type == record_type
|
||||
assert str(record_ld.workout_date) == str(
|
||||
workout_cycling_user_1.workout_date
|
||||
)
|
||||
assert record_ld.value == workout_cycling_user_1.duration
|
||||
|
||||
assert '<Record Cycling - LD - 2018-01-01>' == str(record_ld)
|
||||
|
||||
record_serialize = record_ld.serialize()
|
||||
assert 'id' in record_serialize
|
||||
assert 'user' in record_serialize
|
||||
assert 'sport_id' in record_serialize
|
||||
assert 'workout_id' in record_serialize
|
||||
assert 'record_type' in record_serialize
|
||||
assert 'workout_date' in record_serialize
|
||||
assert 'value' in record_serialize
|
||||
|
||||
record_serialize['id'] = record_ld.id
|
||||
record_serialize['record_type'] = record_ld.record_type
|
||||
record_serialize['sport_id'] = record_ld.sport_id
|
||||
record_serialize['user'] = record_ld.user.username
|
||||
record_serialize['value'] = record_ld.value
|
||||
record_serialize['workout_id'] = record_ld.workout_id
|
||||
record_serialize['workout_date'] = record_ld.workout_date
|
||||
|
||||
def test_record_model_with_none_value(
|
||||
self,
|
||||
@ -48,12 +56,7 @@ class TestRecordModel:
|
||||
record_type='LD',
|
||||
).first()
|
||||
record_ld.value = None
|
||||
assert 'test' == record_ld.user.username
|
||||
assert 1 == record_ld.sport_id
|
||||
assert 1 == record_ld.workout_id
|
||||
assert 'LD' == record_ld.record_type
|
||||
assert '2018-01-01 00:00:00' == str(record_ld.workout_date)
|
||||
assert '<Record Cycling - LD - 2018-01-01>' == str(record_ld)
|
||||
|
||||
assert record_ld.value is None
|
||||
|
||||
record_serialize = record_ld.serialize()
|
||||
@ -80,7 +83,7 @@ class TestRecordModel:
|
||||
assert record_serialize.get('value') == 10.0
|
||||
assert isinstance(record_serialize.get('value'), float)
|
||||
|
||||
def test_add_farest_distance_records(
|
||||
def test_add_farthest_distance_records(
|
||||
self,
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
|
@ -7,41 +7,7 @@ from fittrackee.users.models import User, UserSportPreference
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..mixins import ApiTestCaseMixin
|
||||
|
||||
expected_sport_1_cycling_result = {
|
||||
'id': 1,
|
||||
'label': 'Cycling',
|
||||
'is_active': True,
|
||||
'is_active_for_user': True,
|
||||
'color': None,
|
||||
'stopped_speed_threshold': 1,
|
||||
}
|
||||
expected_sport_1_cycling_admin_result = expected_sport_1_cycling_result.copy()
|
||||
expected_sport_1_cycling_admin_result['has_workouts'] = False
|
||||
|
||||
expected_sport_2_running_result = {
|
||||
'id': 2,
|
||||
'label': 'Running',
|
||||
'is_active': True,
|
||||
'is_active_for_user': True,
|
||||
'color': None,
|
||||
'stopped_speed_threshold': 0.1,
|
||||
}
|
||||
expected_sport_2_running_admin_result = expected_sport_2_running_result.copy()
|
||||
expected_sport_2_running_admin_result['has_workouts'] = False
|
||||
|
||||
expected_sport_1_cycling_inactive_result = {
|
||||
'id': 1,
|
||||
'label': 'Cycling',
|
||||
'is_active': False,
|
||||
'is_active_for_user': False,
|
||||
'color': None,
|
||||
'stopped_speed_threshold': 1,
|
||||
}
|
||||
expected_sport_1_cycling_inactive_admin_result = (
|
||||
expected_sport_1_cycling_inactive_result.copy()
|
||||
)
|
||||
expected_sport_1_cycling_inactive_admin_result['has_workouts'] = False
|
||||
from ..utils import jsonify_dict
|
||||
|
||||
|
||||
class TestGetSports(ApiTestCaseMixin):
|
||||
@ -75,8 +41,12 @@ class TestGetSports(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['sports']) == 2
|
||||
assert data['data']['sports'][0] == expected_sport_1_cycling_result
|
||||
assert data['data']['sports'][1] == expected_sport_2_running_result
|
||||
assert data['data']['sports'][0] == jsonify_dict(
|
||||
sport_1_cycling.serialize()
|
||||
)
|
||||
assert data['data']['sports'][1] == jsonify_dict(
|
||||
sport_2_running.serialize()
|
||||
)
|
||||
|
||||
def test_it_gets_all_sports_with_inactive_one(
|
||||
self,
|
||||
@ -98,11 +68,12 @@ class TestGetSports(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['sports']) == 2
|
||||
assert (
|
||||
data['data']['sports'][0]
|
||||
== expected_sport_1_cycling_inactive_result
|
||||
assert data['data']['sports'][0] == jsonify_dict(
|
||||
sport_1_cycling_inactive.serialize()
|
||||
)
|
||||
assert data['data']['sports'][1] == jsonify_dict(
|
||||
sport_2_running.serialize()
|
||||
)
|
||||
assert data['data']['sports'][1] == expected_sport_2_running_result
|
||||
|
||||
def test_it_gets_all_sports_with_admin_rights(
|
||||
self,
|
||||
@ -124,12 +95,11 @@ class TestGetSports(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['sports']) == 2
|
||||
assert (
|
||||
data['data']['sports'][0]
|
||||
== expected_sport_1_cycling_inactive_admin_result
|
||||
assert data['data']['sports'][0] == jsonify_dict(
|
||||
sport_1_cycling_inactive.serialize(is_admin=True)
|
||||
)
|
||||
assert (
|
||||
data['data']['sports'][1] == expected_sport_2_running_admin_result
|
||||
assert data['data']['sports'][1] == jsonify_dict(
|
||||
sport_2_running.serialize(is_admin=True)
|
||||
)
|
||||
|
||||
def test_it_gets_sports_with_auth_user_preferences(
|
||||
@ -158,11 +128,14 @@ class TestGetSports(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['sports']) == 2
|
||||
assert data['data']['sports'][0]['color'] == '#000000'
|
||||
assert data['data']['sports'][0]['stopped_speed_threshold'] == 0.5
|
||||
assert data['data']['sports'][0]['is_active_for_user'] is False
|
||||
assert (
|
||||
data['data']['sports'][1] == expected_sport_2_running_admin_result
|
||||
assert data['data']['sports'][0] == jsonify_dict(
|
||||
sport_1_cycling.serialize(
|
||||
is_admin=True,
|
||||
sport_preferences=user_admin_sport_1_preference.serialize(),
|
||||
)
|
||||
)
|
||||
assert data['data']['sports'][1] == jsonify_dict(
|
||||
sport_2_running.serialize(is_admin=True)
|
||||
)
|
||||
|
||||
|
||||
@ -183,7 +156,9 @@ class TestGetSport(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert data['data']['sports'][0] == expected_sport_1_cycling_result
|
||||
assert data['data']['sports'][0] == jsonify_dict(
|
||||
sport_1_cycling.serialize()
|
||||
)
|
||||
|
||||
def test_it_gets_a_sport_with_preferences(
|
||||
self,
|
||||
@ -205,7 +180,11 @@ class TestGetSport(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert data['data']['sports'][0] == expected_sport_1_cycling_result
|
||||
assert data['data']['sports'][0] == jsonify_dict(
|
||||
sport_1_cycling.serialize(
|
||||
sport_preferences=user_sport_1_preference.serialize()
|
||||
)
|
||||
)
|
||||
|
||||
def test_it_returns_404_if_sport_does_not_exist(
|
||||
self, app: Flask, user_1: User
|
||||
@ -238,9 +217,8 @@ class TestGetSport(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert (
|
||||
data['data']['sports'][0]
|
||||
== expected_sport_1_cycling_inactive_result
|
||||
assert data['data']['sports'][0] == jsonify_dict(
|
||||
sport_1_cycling_inactive.serialize()
|
||||
)
|
||||
|
||||
def test_it_get_an_inactive_sport_with_admin_rights(
|
||||
@ -259,9 +237,8 @@ class TestGetSport(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert (
|
||||
data['data']['sports'][0]
|
||||
== expected_sport_1_cycling_inactive_admin_result
|
||||
assert data['data']['sports'][0] == jsonify_dict(
|
||||
sport_1_cycling_inactive.serialize(is_admin=True)
|
||||
)
|
||||
|
||||
|
||||
@ -388,7 +365,6 @@ class TestUpdateSport(ApiTestCaseMixin):
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert data['data']['sports'][0]['is_active'] is False
|
||||
assert data['data']['sports'][0]['is_active_for_user'] is False
|
||||
assert data['data']['sports'][0]['is_active_for_user'] is False
|
||||
assert data['data']['sports'][0]['has_workouts'] is False
|
||||
|
||||
def test_it_enables_a_sport_with_preferences(
|
||||
|
@ -17,15 +17,17 @@ class TestSportModel:
|
||||
assert '<Sport \'Cycling\'>' == str(sport)
|
||||
|
||||
serialized_sport = sport.serialize(is_admin=is_admin)
|
||||
assert 1 == serialized_sport['id']
|
||||
assert 'Cycling' == serialized_sport['label']
|
||||
assert serialized_sport['label'] == sport.label
|
||||
assert serialized_sport['id'] == sport.id
|
||||
assert serialized_sport['is_active'] is True
|
||||
assert serialized_sport['is_active_for_user'] is True
|
||||
assert serialized_sport['color'] is None
|
||||
assert serialized_sport['stopped_speed_threshold'] == 1
|
||||
return serialized_sport
|
||||
|
||||
def test_sport_model(self, app: Flask, sport_1_cycling: Sport) -> None:
|
||||
def test_sport_model_without_workout(
|
||||
self, app: Flask, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
serialized_sport = self.assert_sport_model(sport_1_cycling)
|
||||
assert 'has_workouts' not in serialized_sport
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import json
|
||||
from typing import List
|
||||
from unittest.mock import patch
|
||||
from uuid import uuid4
|
||||
|
||||
@ -8,6 +9,7 @@ from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..mixins import ApiTestCaseMixin
|
||||
from ..utils import jsonify_dict
|
||||
from .utils import get_random_short_id
|
||||
|
||||
|
||||
@ -45,25 +47,12 @@ class TestGetWorkouts(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['workouts']) == 2
|
||||
assert 'creation_date' in data['data']['workouts'][0]
|
||||
assert (
|
||||
'Sun, 01 Apr 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][0]['workout_date']
|
||||
assert data['data']['workouts'][0] == jsonify_dict(
|
||||
workout_running_user_1.serialize()
|
||||
)
|
||||
assert 'test' == data['data']['workouts'][0]['user']
|
||||
assert 2 == data['data']['workouts'][0]['sport_id']
|
||||
assert 12.0 == data['data']['workouts'][0]['distance']
|
||||
assert '1:40:00' == data['data']['workouts'][0]['duration']
|
||||
|
||||
assert 'creation_date' in data['data']['workouts'][1]
|
||||
assert (
|
||||
'Mon, 01 Jan 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][1]['workout_date']
|
||||
assert data['data']['workouts'][1] == jsonify_dict(
|
||||
workout_cycling_user_1.serialize()
|
||||
)
|
||||
assert 'test' == data['data']['workouts'][1]['user']
|
||||
assert 1 == data['data']['workouts'][1]['sport_id']
|
||||
assert 10.0 == data['data']['workouts'][1]['distance']
|
||||
assert '1:00:00' == data['data']['workouts'][1]['duration']
|
||||
assert data['pagination'] == {
|
||||
'has_next': False,
|
||||
'has_prev': False,
|
||||
@ -119,7 +108,7 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -134,18 +123,22 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['workouts']) == 5
|
||||
assert 'creation_date' in data['data']['workouts'][0]
|
||||
assert (
|
||||
'Wed, 09 May 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][0]['workout_date']
|
||||
assert data['data']['workouts'][0] == jsonify_dict(
|
||||
seven_workouts_user_1[6].serialize()
|
||||
)
|
||||
assert '0:50:00' == data['data']['workouts'][0]['duration']
|
||||
assert 'creation_date' in data['data']['workouts'][4]
|
||||
assert (
|
||||
'Mon, 01 Jan 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][4]['workout_date']
|
||||
assert data['data']['workouts'][1] == jsonify_dict(
|
||||
seven_workouts_user_1[5].serialize()
|
||||
)
|
||||
assert '0:17:04' == data['data']['workouts'][4]['duration']
|
||||
assert data['data']['workouts'][2] == jsonify_dict(
|
||||
seven_workouts_user_1[3].serialize()
|
||||
)
|
||||
assert data['data']['workouts'][3] == jsonify_dict(
|
||||
seven_workouts_user_1[4].serialize()
|
||||
)
|
||||
assert data['data']['workouts'][4] == jsonify_dict(
|
||||
seven_workouts_user_1[2].serialize()
|
||||
)
|
||||
|
||||
assert data['pagination'] == {
|
||||
'has_next': True,
|
||||
'has_prev': False,
|
||||
@ -159,7 +152,7 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -174,18 +167,21 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['workouts']) == 5
|
||||
assert 'creation_date' in data['data']['workouts'][0]
|
||||
assert (
|
||||
'Wed, 09 May 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][0]['workout_date']
|
||||
assert data['data']['workouts'][0] == jsonify_dict(
|
||||
seven_workouts_user_1[6].serialize()
|
||||
)
|
||||
assert '0:50:00' == data['data']['workouts'][0]['duration']
|
||||
assert 'creation_date' in data['data']['workouts'][4]
|
||||
assert (
|
||||
'Mon, 01 Jan 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][4]['workout_date']
|
||||
assert data['data']['workouts'][1] == jsonify_dict(
|
||||
seven_workouts_user_1[5].serialize()
|
||||
)
|
||||
assert data['data']['workouts'][2] == jsonify_dict(
|
||||
seven_workouts_user_1[3].serialize()
|
||||
)
|
||||
assert data['data']['workouts'][3] == jsonify_dict(
|
||||
seven_workouts_user_1[4].serialize()
|
||||
)
|
||||
assert data['data']['workouts'][4] == jsonify_dict(
|
||||
seven_workouts_user_1[2].serialize()
|
||||
)
|
||||
assert '0:17:04' == data['data']['workouts'][4]['duration']
|
||||
assert data['pagination'] == {
|
||||
'has_next': True,
|
||||
'has_prev': False,
|
||||
@ -199,7 +195,7 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -214,18 +210,12 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['workouts']) == 2
|
||||
assert 'creation_date' in data['data']['workouts'][0]
|
||||
assert (
|
||||
'Thu, 01 Jun 2017 00:00:00 GMT'
|
||||
== data['data']['workouts'][0]['workout_date']
|
||||
assert data['data']['workouts'][0] == jsonify_dict(
|
||||
seven_workouts_user_1[1].serialize()
|
||||
)
|
||||
assert '0:57:36' == data['data']['workouts'][0]['duration']
|
||||
assert 'creation_date' in data['data']['workouts'][1]
|
||||
assert (
|
||||
'Mon, 20 Mar 2017 00:00:00 GMT'
|
||||
== data['data']['workouts'][1]['workout_date']
|
||||
assert data['data']['workouts'][1] == jsonify_dict(
|
||||
seven_workouts_user_1[0].serialize()
|
||||
)
|
||||
assert '0:17:04' == data['data']['workouts'][1]['duration']
|
||||
assert data['pagination'] == {
|
||||
'has_next': False,
|
||||
'has_prev': True,
|
||||
@ -239,7 +229,7 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -267,7 +257,7 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -286,7 +276,7 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -301,13 +291,11 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['workouts']) == 6
|
||||
assert (
|
||||
'Wed, 09 May 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][0]['workout_date']
|
||||
assert data['data']['workouts'][0] == jsonify_dict(
|
||||
seven_workouts_user_1[6].serialize()
|
||||
)
|
||||
assert (
|
||||
'Thu, 01 Jun 2017 00:00:00 GMT'
|
||||
== data['data']['workouts'][5]['workout_date']
|
||||
assert data['data']['workouts'][5] == jsonify_dict(
|
||||
seven_workouts_user_1[1].serialize()
|
||||
)
|
||||
assert data['pagination'] == {
|
||||
'has_next': True,
|
||||
@ -323,7 +311,7 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -338,13 +326,14 @@ class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['workouts']) == 3
|
||||
assert (
|
||||
'Wed, 09 May 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][0]['workout_date']
|
||||
assert data['data']['workouts'][0] == jsonify_dict(
|
||||
seven_workouts_user_1[6].serialize()
|
||||
)
|
||||
assert (
|
||||
'Fri, 23 Feb 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][2]['workout_date']
|
||||
assert data['data']['workouts'][1] == jsonify_dict(
|
||||
seven_workouts_user_1[5].serialize()
|
||||
)
|
||||
assert data['data']['workouts'][2] == jsonify_dict(
|
||||
seven_workouts_user_1[4].serialize()
|
||||
)
|
||||
assert data['pagination'] == {
|
||||
'has_next': True,
|
||||
@ -361,7 +350,7 @@ class TestGetWorkoutsWithOrder(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -397,7 +386,7 @@ class TestGetWorkoutsWithOrder(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -433,7 +422,7 @@ class TestGetWorkoutsWithOrder(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -471,7 +460,7 @@ class TestGetWorkoutsWithOrderBy(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -507,7 +496,7 @@ class TestGetWorkoutsWithOrderBy(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -537,7 +526,7 @@ class TestGetWorkoutsWithOrderBy(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -567,7 +556,7 @@ class TestGetWorkoutsWithOrderBy(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -599,7 +588,7 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -625,7 +614,6 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
'Fri, 23 Feb 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][1]['workout_date']
|
||||
)
|
||||
assert '0:10:00' == data['data']['workouts'][1]['duration']
|
||||
assert data['pagination'] == {
|
||||
'has_next': False,
|
||||
'has_prev': False,
|
||||
@ -639,7 +627,7 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -667,7 +655,7 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -704,7 +692,7 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -740,7 +728,7 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -776,7 +764,7 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -808,7 +796,7 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -876,7 +864,7 @@ class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
sport_2_running: Sport,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
@ -912,7 +900,7 @@ class TestGetWorkoutsWithFiltersAndPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -948,7 +936,7 @@ class TestGetWorkoutsWithFiltersAndPagination(ApiTestCaseMixin):
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
seven_workouts_user_1: List[Workout],
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
@ -1001,15 +989,9 @@ class TestGetWorkout(ApiTestCaseMixin):
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['workouts']) == 1
|
||||
assert 'creation_date' in data['data']['workouts'][0]
|
||||
assert (
|
||||
'Mon, 01 Jan 2018 00:00:00 GMT'
|
||||
== data['data']['workouts'][0]['workout_date']
|
||||
assert data['data']['workouts'][0] == jsonify_dict(
|
||||
workout_cycling_user_1.serialize()
|
||||
)
|
||||
assert 'test' == data['data']['workouts'][0]['user']
|
||||
assert 1 == data['data']['workouts'][0]['sport_id']
|
||||
assert 10.0 == data['data']['workouts'][0]['distance']
|
||||
assert '1:00:00' == data['data']['workouts'][0]['duration']
|
||||
|
||||
def test_it_returns_403_if_workout_belongs_to_a_different_user(
|
||||
self,
|
||||
|
@ -1,15 +1,17 @@
|
||||
from uuid import UUID
|
||||
from datetime import timedelta
|
||||
|
||||
from flask import Flask
|
||||
|
||||
from fittrackee import db
|
||||
from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
from fittrackee.workouts.utils.short_id import decode_short_id
|
||||
from fittrackee.workouts.utils.short_id import encode_uuid
|
||||
|
||||
from ..utils import random_string
|
||||
|
||||
|
||||
class TestWorkoutModel:
|
||||
def test_workout_model(
|
||||
def test_sport_label_and_date_are_in_string_value(
|
||||
self,
|
||||
app: Flask,
|
||||
sport_1_cycling: Sport,
|
||||
@ -18,48 +20,109 @@ class TestWorkoutModel:
|
||||
) -> None:
|
||||
workout_cycling_user_1.title = 'Test'
|
||||
db.session.commit()
|
||||
|
||||
assert 1 == workout_cycling_user_1.id
|
||||
assert workout_cycling_user_1.uuid is not None
|
||||
assert 1 == workout_cycling_user_1.user_id
|
||||
assert 1 == workout_cycling_user_1.sport_id
|
||||
assert '2018-01-01 00:00:00' == str(
|
||||
workout_cycling_user_1.workout_date
|
||||
)
|
||||
assert 10.0 == float(workout_cycling_user_1.distance)
|
||||
assert '1:00:00' == str(workout_cycling_user_1.duration)
|
||||
assert 'Test' == workout_cycling_user_1.title
|
||||
assert '<Workout \'Cycling\' - 2018-01-01 00:00:00>' == str(
|
||||
workout_cycling_user_1
|
||||
)
|
||||
|
||||
serialized_workout = workout_cycling_user_1.serialize()
|
||||
assert isinstance(decode_short_id(serialized_workout['id']), UUID)
|
||||
assert 'test' == serialized_workout['user']
|
||||
assert 1 == serialized_workout['sport_id']
|
||||
assert serialized_workout['title'] == 'Test'
|
||||
assert 'creation_date' in serialized_workout
|
||||
assert serialized_workout['modification_date'] is not None
|
||||
assert str(serialized_workout['workout_date']) == '2018-01-01 00:00:00'
|
||||
assert serialized_workout['duration'] == '1:00:00'
|
||||
assert serialized_workout['pauses'] is None
|
||||
assert serialized_workout['moving'] == '1:00:00'
|
||||
assert serialized_workout['distance'] == 10.0
|
||||
assert serialized_workout['max_alt'] is None
|
||||
assert serialized_workout['descent'] is None
|
||||
def test_short_id_returns_encoded_workout_uuid(
|
||||
self,
|
||||
app: Flask,
|
||||
sport_1_cycling: Sport,
|
||||
user_1: User,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
assert workout_cycling_user_1.short_id == encode_uuid(
|
||||
workout_cycling_user_1.uuid
|
||||
)
|
||||
|
||||
def test_serialize_for_workout_without_gpx(
|
||||
self,
|
||||
app: Flask,
|
||||
sport_1_cycling: Sport,
|
||||
user_1: User,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout = workout_cycling_user_1
|
||||
|
||||
serialized_workout = workout.serialize()
|
||||
assert serialized_workout['ascent'] is None
|
||||
assert serialized_workout['max_speed'] == 10.0
|
||||
assert serialized_workout['ave_speed'] == 10.0
|
||||
assert serialized_workout['with_gpx'] is False
|
||||
assert serialized_workout['ave_speed'] == float(workout.ave_speed)
|
||||
assert serialized_workout['bounds'] == []
|
||||
assert serialized_workout['previous_workout'] is None
|
||||
assert serialized_workout['next_workout'] is None
|
||||
assert serialized_workout['segments'] == []
|
||||
assert serialized_workout['records'] != []
|
||||
assert 'creation_date' in serialized_workout
|
||||
assert serialized_workout['descent'] is None
|
||||
assert serialized_workout['distance'] == float(workout.distance)
|
||||
assert serialized_workout['duration'] == str(workout.duration)
|
||||
assert serialized_workout['id'] == workout.short_id
|
||||
assert serialized_workout['map'] is None
|
||||
assert serialized_workout['weather_start'] is None
|
||||
assert serialized_workout['weather_end'] is None
|
||||
assert serialized_workout['max_alt'] is None
|
||||
assert serialized_workout['max_speed'] == float(workout.max_speed)
|
||||
assert serialized_workout['min_alt'] is None
|
||||
assert serialized_workout['modification_date'] is None
|
||||
assert serialized_workout['moving'] == str(workout.moving)
|
||||
assert serialized_workout['next_workout'] is None
|
||||
assert serialized_workout['notes'] is None
|
||||
assert serialized_workout['pauses'] is None
|
||||
assert serialized_workout['previous_workout'] is None
|
||||
assert serialized_workout['records'] == [
|
||||
record.serialize() for record in workout.records
|
||||
]
|
||||
assert serialized_workout['segments'] == []
|
||||
assert serialized_workout['sport_id'] == workout.sport_id
|
||||
assert serialized_workout['title'] == workout.title
|
||||
assert serialized_workout['user'] == workout.user.username
|
||||
assert serialized_workout['weather_end'] is None
|
||||
assert serialized_workout['weather_start'] is None
|
||||
assert serialized_workout['with_gpx'] is False
|
||||
assert str(serialized_workout['workout_date']) == '2018-01-01 00:00:00'
|
||||
|
||||
def test_serialize_for_workout_with_gpx(
|
||||
self,
|
||||
app: Flask,
|
||||
sport_1_cycling: Sport,
|
||||
user_1: User,
|
||||
workout_cycling_user_1: Workout,
|
||||
workout_cycling_user_1_segment: Workout,
|
||||
) -> None:
|
||||
workout = workout_cycling_user_1
|
||||
workout.bounds = [1, 2, 3, 4]
|
||||
workout.gpx = random_string()
|
||||
workout.map = random_string()
|
||||
workout.pauses = timedelta(minutes=15)
|
||||
|
||||
serialized_workout = workout.serialize()
|
||||
assert serialized_workout['ascent'] is None
|
||||
assert serialized_workout['ave_speed'] == float(workout.ave_speed)
|
||||
assert serialized_workout['bounds'] == [
|
||||
float(bound) for bound in workout.bounds
|
||||
]
|
||||
assert 'creation_date' in serialized_workout
|
||||
assert serialized_workout['descent'] is None
|
||||
assert serialized_workout['distance'] == float(workout.distance)
|
||||
assert serialized_workout['duration'] == str(workout.duration)
|
||||
assert serialized_workout['id'] == workout.short_id
|
||||
assert serialized_workout['map'] is None
|
||||
assert serialized_workout['max_alt'] is None
|
||||
assert serialized_workout['max_speed'] == float(workout.max_speed)
|
||||
assert serialized_workout['min_alt'] is None
|
||||
assert serialized_workout['modification_date'] is not None
|
||||
assert serialized_workout['moving'] == str(workout.moving)
|
||||
assert serialized_workout['next_workout'] is None
|
||||
assert serialized_workout['notes'] is None
|
||||
assert serialized_workout['pauses'] == str(workout.pauses)
|
||||
assert serialized_workout['previous_workout'] is None
|
||||
assert serialized_workout['records'] == [
|
||||
record.serialize() for record in workout.records
|
||||
]
|
||||
assert serialized_workout['segments'] == [
|
||||
segment.serialize() for segment in workout.segments
|
||||
]
|
||||
assert serialized_workout['sport_id'] == workout.sport_id
|
||||
assert serialized_workout['title'] == workout.title
|
||||
assert serialized_workout['user'] == workout.user.username
|
||||
assert serialized_workout['weather_end'] is None
|
||||
assert serialized_workout['weather_start'] is None
|
||||
assert serialized_workout['with_gpx'] is True
|
||||
assert str(serialized_workout['workout_date']) == '2018-01-01 00:00:00'
|
||||
|
||||
def test_workout_segment_model(
|
||||
self,
|
||||
@ -74,3 +137,35 @@ class TestWorkoutModel:
|
||||
f'for workout \'{workout_cycling_user_1.short_id}\'>'
|
||||
== str(workout_cycling_user_1_segment)
|
||||
)
|
||||
|
||||
def test_it_returns_previous_workout(
|
||||
self,
|
||||
app: Flask,
|
||||
sport_1_cycling: Sport,
|
||||
sport_2_running: Sport,
|
||||
user_1: User,
|
||||
workout_cycling_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
serialized_workout = workout_running_user_1.serialize()
|
||||
|
||||
assert (
|
||||
serialized_workout['previous_workout']
|
||||
== workout_cycling_user_1.short_id
|
||||
)
|
||||
|
||||
def test_it_returns_next_workout(
|
||||
self,
|
||||
app: Flask,
|
||||
sport_1_cycling: Sport,
|
||||
sport_2_running: Sport,
|
||||
user_1: User,
|
||||
workout_cycling_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
serialized_workout = workout_cycling_user_1.serialize()
|
||||
|
||||
assert (
|
||||
serialized_workout['next_workout']
|
||||
== workout_running_user_1.short_id
|
||||
)
|
||||
|
@ -791,8 +791,9 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
|
||||
}
|
||||
|
||||
:<json string timezone: user time zone
|
||||
:<json string weekm: does week start on Monday?
|
||||
:<json boolean weekm: does week start on Monday?
|
||||
:<json string language: language preferences
|
||||
:<json boolean imperial_units: display distance in imperial units
|
||||
|
||||
:reqheader Authorization: OAuth 2.0 Bearer Token
|
||||
|
||||
|
@ -249,12 +249,13 @@ def get_users(auth_user: User) -> Dict:
|
||||
|
||||
|
||||
@users_blueprint.route('/users/<user_name>', methods=['GET'])
|
||||
@authenticate_as_admin
|
||||
@authenticate
|
||||
def get_single_user(
|
||||
auth_user: User, user_name: str
|
||||
) -> Union[Dict, HttpResponse]:
|
||||
"""
|
||||
Get single user details. Only user with admin rights can get user details.
|
||||
Get single user details. Only user with admin rights can get other users
|
||||
details.
|
||||
|
||||
It returns user preferences only for authenticated user.
|
||||
|
||||
@ -353,6 +354,9 @@ def get_single_user(
|
||||
:statuscode 404:
|
||||
- user does not exist
|
||||
"""
|
||||
if user_name != auth_user.username and not auth_user.admin:
|
||||
return ForbiddenErrorResponse()
|
||||
|
||||
try:
|
||||
user = User.query.filter_by(username=user_name).first()
|
||||
if user:
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fittrackee_client",
|
||||
"version": "0.6.1",
|
||||
"version": "0.6.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
@ -22,7 +22,7 @@
|
||||
"chartjs-plugin-datalabels": "^2.0.0",
|
||||
"core-js": "^3.21.1",
|
||||
"date-fns": "^2.28.0",
|
||||
"date-fns-tz": "^1.3.1",
|
||||
"date-fns-tz": "^1.3.3",
|
||||
"leaflet": "^1.7.1",
|
||||
"register-service-worker": "^1.7.1",
|
||||
"vue": "^3.0.0",
|
||||
@ -36,8 +36,8 @@
|
||||
"@intlify/vue-i18n-loader": "^4.0.1",
|
||||
"@types/chai": "^4.2.11",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.17.0",
|
||||
"@typescript-eslint/parser": "^5.17.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.1",
|
||||
"@vue/cli-plugin-eslint": "~5.0.1",
|
||||
"@vue/cli-plugin-pwa": "~5.0.1",
|
||||
@ -51,14 +51,14 @@
|
||||
"chai": "^4.3.6",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-import-resolver-typescript": "^2.7.0",
|
||||
"eslint-import-resolver-typescript": "^2.7.1",
|
||||
"eslint-plugin-import": "^2.24.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^8.5.0",
|
||||
"prettier": "^2.6.1",
|
||||
"sass": "^1.49.9",
|
||||
"prettier": "^2.6.2",
|
||||
"sass": "^1.49.11",
|
||||
"sass-loader": "^12.6.0",
|
||||
"typescript": "~4.5.5",
|
||||
"typescript": "^4.6.3",
|
||||
"vue-cli-plugin-i18n": "~2.3.1"
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
@ -29,10 +29,10 @@
|
||||
|
||||
import StatCard from '@/components/Common/StatCard.vue'
|
||||
import { TUnit } from '@/types/units'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import { convertDistance, units } from '@/utils/units'
|
||||
interface Props {
|
||||
user: IUserProfile
|
||||
user: IAuthUserProfile
|
||||
}
|
||||
const props = defineProps<Props>()
|
||||
|
||||
@ -47,9 +47,11 @@
|
||||
const unitTo: TUnit = user.value.imperial_units
|
||||
? units[defaultUnitFrom].defaultTarget
|
||||
: defaultUnitFrom
|
||||
const totalDistance = user.value.imperial_units
|
||||
? convertDistance(user.value.total_distance, defaultUnitFrom, unitTo, 2)
|
||||
: parseFloat(user.value.total_distance.toFixed(2))
|
||||
const totalDistance: ComputedRef<number> = computed(() =>
|
||||
user.value.imperial_units
|
||||
? convertDistance(user.value.total_distance, defaultUnitFrom, unitTo, 2)
|
||||
: parseFloat(user.value.total_distance.toFixed(2))
|
||||
)
|
||||
|
||||
function get_duration(total_duration: ComputedRef<string>) {
|
||||
const duration = total_duration.value.match(/day/g)
|
||||
|
@ -263,7 +263,7 @@ const routes: Array<RouteRecordRaw> = [
|
||||
},
|
||||
{
|
||||
path: 'users/:username',
|
||||
name: 'User',
|
||||
name: 'UserFromAdmin',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: 'profile' */ '@/views/user/UserView.vue'),
|
||||
props: { fromAdmin: true },
|
||||
|
@ -1456,7 +1456,7 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^5.0.0", "@typescript-eslint/eslint-plugin@^5.4.0":
|
||||
"@typescript-eslint/eslint-plugin@^5.0.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz#78f246dd8d1b528fc5bfca99a8a64d4023a3d86d"
|
||||
integrity sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==
|
||||
@ -1471,7 +1471,22 @@
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.4.0":
|
||||
"@typescript-eslint/eslint-plugin@^5.17.0":
|
||||
version "5.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz#704eb4e75039000531255672bf1c85ee85cf1d67"
|
||||
integrity sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.17.0"
|
||||
"@typescript-eslint/type-utils" "5.17.0"
|
||||
"@typescript-eslint/utils" "5.17.0"
|
||||
debug "^4.3.2"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
ignore "^5.1.8"
|
||||
regexpp "^3.2.0"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/parser@^5.0.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.16.0.tgz#e4de1bde4b4dad5b6124d3da227347616ed55508"
|
||||
integrity sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==
|
||||
@ -1481,6 +1496,16 @@
|
||||
"@typescript-eslint/typescript-estree" "5.16.0"
|
||||
debug "^4.3.2"
|
||||
|
||||
"@typescript-eslint/parser@^5.17.0":
|
||||
version "5.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.17.0.tgz#7def77d5bcd8458d12d52909118cf3f0a45f89d5"
|
||||
integrity sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.17.0"
|
||||
"@typescript-eslint/types" "5.17.0"
|
||||
"@typescript-eslint/typescript-estree" "5.17.0"
|
||||
debug "^4.3.2"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz#7e7909d64bd0c4d8aef629cdc764b9d3e1d3a69a"
|
||||
@ -1489,6 +1514,14 @@
|
||||
"@typescript-eslint/types" "5.16.0"
|
||||
"@typescript-eslint/visitor-keys" "5.16.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.17.0":
|
||||
version "5.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz#4cea7d0e0bc0e79eb60cad431c89120987c3f952"
|
||||
integrity sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.17.0"
|
||||
"@typescript-eslint/visitor-keys" "5.17.0"
|
||||
|
||||
"@typescript-eslint/type-utils@5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz#b482bdde1d7d7c0c7080f7f2f67ea9580b9e0692"
|
||||
@ -1498,11 +1531,25 @@
|
||||
debug "^4.3.2"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/type-utils@5.17.0":
|
||||
version "5.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz#1c4549d68c89877662224aabb29fbbebf5fc9672"
|
||||
integrity sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==
|
||||
dependencies:
|
||||
"@typescript-eslint/utils" "5.17.0"
|
||||
debug "^4.3.2"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/types@5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.16.0.tgz#5827b011982950ed350f075eaecb7f47d3c643ee"
|
||||
integrity sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==
|
||||
|
||||
"@typescript-eslint/types@5.17.0":
|
||||
version "5.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.17.0.tgz#861ec9e669ffa2aa9b873dd4d28d9b1ce26d216f"
|
||||
integrity sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz#32259459ec62f5feddca66adc695342f30101f61"
|
||||
@ -1516,6 +1563,19 @@
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.17.0":
|
||||
version "5.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz#a7cba7dfc8f9cc2ac78c18584e684507df4f2488"
|
||||
integrity sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.17.0"
|
||||
"@typescript-eslint/visitor-keys" "5.17.0"
|
||||
debug "^4.3.2"
|
||||
globby "^11.0.4"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/utils@5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.16.0.tgz#42218b459d6d66418a4eb199a382bdc261650679"
|
||||
@ -1528,6 +1588,18 @@
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/utils@5.17.0":
|
||||
version "5.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.17.0.tgz#549a9e1d491c6ccd3624bc3c1b098f5cfb45f306"
|
||||
integrity sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.17.0"
|
||||
"@typescript-eslint/types" "5.17.0"
|
||||
"@typescript-eslint/typescript-estree" "5.17.0"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz#f27dc3b943e6317264c7492e390c6844cd4efbbb"
|
||||
@ -1536,6 +1608,14 @@
|
||||
"@typescript-eslint/types" "5.16.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.17.0":
|
||||
version "5.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz#52daae45c61b0211b4c81b53a71841911e479128"
|
||||
integrity sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.17.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@ungap/promise-all-settled@1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
|
||||
@ -3198,10 +3278,10 @@ data-urls@^3.0.1:
|
||||
whatwg-mimetype "^3.0.0"
|
||||
whatwg-url "^10.0.0"
|
||||
|
||||
date-fns-tz@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/date-fns-tz/-/date-fns-tz-1.3.1.tgz#88b6374e5a74cfb11ec2d2b120cfe0bc02eeb862"
|
||||
integrity sha512-Uy+wph6HcQ0IG8TWbVyXicgDmB1zdvb0CoIknZQaxiTun4uSfxLR+8gSTC2C3KCLq+0fEIuEtJ/ORDRIn6doQw==
|
||||
date-fns-tz@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/date-fns-tz/-/date-fns-tz-1.3.3.tgz#7884a4b3ed6cd95bfd81831d608e5ef8be500c86"
|
||||
integrity sha512-Gks46gwbSauBQnV3Oofluj1wTm8J0tM7sbSJ9P+cJq/ZnTCpMohTKmmO5Tn+jQ7dyn0+b8G7cY4O2DZ5P/LXcA==
|
||||
|
||||
date-fns@^2.28.0:
|
||||
version "2.28.0"
|
||||
@ -3646,10 +3726,10 @@ eslint-import-resolver-node@^0.3.6:
|
||||
debug "^3.2.7"
|
||||
resolve "^1.20.0"
|
||||
|
||||
eslint-import-resolver-typescript@^2.7.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.0.tgz#1f9d391b636dccdbaa4a3b1a87eb9a8237e23963"
|
||||
integrity sha512-MNHS3u5pebvROX4MjGP9coda589ZGfL1SqdxUV4kSrcclfDRWvNE2D+eljbnWVMvWDVRgT89nhscMHPKYGcObQ==
|
||||
eslint-import-resolver-typescript@^2.7.1:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz#a90a4a1c80da8d632df25994c4c5fdcdd02b8751"
|
||||
integrity sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
glob "^7.2.0"
|
||||
@ -6317,11 +6397,16 @@ prettier-linter-helpers@^1.0.0:
|
||||
dependencies:
|
||||
fast-diff "^1.1.2"
|
||||
|
||||
"prettier@^1.18.2 || ^2.0.0", prettier@^2.6.1:
|
||||
"prettier@^1.18.2 || ^2.0.0":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.1.tgz#d472797e0d7461605c1609808e27b80c0f9cfe17"
|
||||
integrity sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==
|
||||
|
||||
prettier@^2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032"
|
||||
integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==
|
||||
|
||||
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
||||
@ -6673,10 +6758,10 @@ sass-loader@^12.6.0:
|
||||
klona "^2.0.4"
|
||||
neo-async "^2.6.2"
|
||||
|
||||
sass@^1.49.9:
|
||||
version "1.49.9"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.9.tgz#b15a189ecb0ca9e24634bae5d1ebc191809712f9"
|
||||
integrity sha512-YlYWkkHP9fbwaFRZQRXgDi3mXZShslVmmo+FVK3kHLUELHHEYrCmL1x6IUjC7wLS6VuJSAFXRQS/DxdsC4xL1A==
|
||||
sass@^1.49.11:
|
||||
version "1.49.11"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.11.tgz#1ffeb77faeed8b806a2a1e021d7c9fd3fc322cb7"
|
||||
integrity sha512-wvS/geXgHUGs6A/4ud5BFIWKO1nKd7wYIGimDk4q4GFkJicILActpv9ueMT4eRGSsp1BdKHuw1WwAHXbhsJELQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
@ -7471,10 +7556,10 @@ type-is@~1.6.18:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
typescript@~4.5.5:
|
||||
version "4.5.5"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3"
|
||||
integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==
|
||||
typescript@^4.6.3:
|
||||
version "4.6.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c"
|
||||
integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==
|
||||
|
||||
unbox-primitive@^1.0.1:
|
||||
version "1.0.1"
|
||||
|
223
poetry.lock
generated
@ -93,7 +93,7 @@ typecheck = ["mypy"]
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "22.1.0"
|
||||
version = "22.3.0"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -104,7 +104,7 @@ click = ">=8.0.0"
|
||||
mypy-extensions = ">=0.4.3"
|
||||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
tomli = ">=1.1.0"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""}
|
||||
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
|
||||
|
||||
@ -146,11 +146,11 @@ unicode_backport = ["unicodedata2"]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.0.4"
|
||||
version = "8.1.2"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
@ -232,7 +232,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "dramatiq"
|
||||
version = "1.12.3"
|
||||
version = "1.13.0"
|
||||
description = "Background Processing for Python 3."
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -243,8 +243,8 @@ prometheus-client = ">=0.2"
|
||||
redis = {version = ">=2.0,<5.0", optional = true, markers = "extra == \"redis\""}
|
||||
|
||||
[package.extras]
|
||||
all = ["gevent (>=1.1)", "redis (>=2.0,<5.0)", "watchdog", "pika (>=1.0,<2.0)", "watchdog-gevent", "pylibmc (>=1.5,<2.0)"]
|
||||
dev = ["gevent (>=1.1)", "redis (>=2.0,<5.0)", "watchdog", "pika (>=1.0,<2.0)", "watchdog-gevent", "pylibmc (>=1.5,<2.0)", "alabaster", "sphinx (<1.8)", "sphinxcontrib-napoleon", "flake8", "flake8-bugbear", "flake8-quotes", "isort", "bumpversion", "hiredis", "twine", "wheel", "pytest", "pytest-benchmark", "pytest-cov", "tox"]
|
||||
all = ["redis (>=2.0,<5.0)", "pylibmc (>=1.5,<2.0)", "watchdog", "watchdog-gevent", "pika (>=1.0,<2.0)", "gevent (>=1.1)"]
|
||||
dev = ["redis (>=2.0,<5.0)", "pylibmc (>=1.5,<2.0)", "watchdog", "watchdog-gevent", "pika (>=1.0,<2.0)", "gevent (>=1.1)", "alabaster", "sphinx (<1.8)", "sphinxcontrib-napoleon", "flake8", "flake8-bugbear", "flake8-quotes", "isort", "bumpversion", "hiredis", "twine", "wheel", "pytest", "pytest-benchmark", "pytest-cov", "tox"]
|
||||
gevent = ["gevent (>=1.1)"]
|
||||
memcached = ["pylibmc (>=1.5,<2.0)"]
|
||||
rabbitmq = ["pika (>=1.0,<2.0)"]
|
||||
@ -267,14 +267,15 @@ pyflakes = ">=2.3.0,<2.4.0"
|
||||
|
||||
[[package]]
|
||||
name = "flask"
|
||||
version = "2.0.3"
|
||||
version = "2.1.1"
|
||||
description = "A simple framework for building complex web applications."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=7.1.2"
|
||||
click = ">=8.0"
|
||||
importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""}
|
||||
itsdangerous = ">=2.0"
|
||||
Jinja2 = ">=3.0"
|
||||
Werkzeug = ">=2.0"
|
||||
@ -285,14 +286,14 @@ dotenv = ["python-dotenv"]
|
||||
|
||||
[[package]]
|
||||
name = "flask-bcrypt"
|
||||
version = "0.7.1"
|
||||
version = "1.0.0"
|
||||
description = "Brcrypt hashing for Flask."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
bcrypt = "*"
|
||||
bcrypt = ">=3.1.1"
|
||||
Flask = "*"
|
||||
|
||||
[[package]]
|
||||
@ -584,12 +585,16 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "9.0.1"
|
||||
version = "9.1.0"
|
||||
description = "Python Imaging Library (Fork)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinx-rtd-theme (>=1.0)", "sphinxext-opengraph"]
|
||||
tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "2.5.1"
|
||||
@ -748,14 +753,14 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.
|
||||
|
||||
[[package]]
|
||||
name = "pytest-base-url"
|
||||
version = "1.4.2"
|
||||
version = "2.0.0"
|
||||
description = "pytest plugin for URL based testing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.7,<4.0"
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=2.7.3"
|
||||
pytest = ">=3.0.0,<8.0.0"
|
||||
requests = ">=2.9"
|
||||
|
||||
[[package]]
|
||||
@ -928,7 +933,7 @@ sphinx = ">=1.3.1"
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "4.2.0"
|
||||
version = "4.2.1"
|
||||
description = "Python client for Redis database and key-value store"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -939,7 +944,7 @@ async-timeout = ">=4.0.2"
|
||||
deprecated = ">=1.2.3"
|
||||
importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""}
|
||||
packaging = ">=20.4"
|
||||
typing-extensions = "*"
|
||||
typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
|
||||
|
||||
[package.extras]
|
||||
hiredis = ["hiredis (>=1.0.0)"]
|
||||
@ -1033,7 +1038,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "sphinx"
|
||||
version = "4.4.0"
|
||||
version = "4.5.0"
|
||||
description = "Python documentation generator"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -1269,7 +1274,7 @@ python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "types-freezegun"
|
||||
version = "1.1.7"
|
||||
version = "1.1.8"
|
||||
description = "Typing stubs for freezegun"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -1285,7 +1290,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "types-requests"
|
||||
version = "2.27.15"
|
||||
version = "2.27.16"
|
||||
description = "Typing stubs for requests"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -1310,6 +1315,14 @@ category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "ua-parser"
|
||||
version = "0.10.0"
|
||||
description = "Python port of Browserscope's user agent parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.26.9"
|
||||
@ -1332,11 +1345,11 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "werkzeug"
|
||||
version = "2.0.3"
|
||||
version = "2.1.1"
|
||||
description = "The comprehensive WSGI web application library."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
watchdog = ["watchdog"]
|
||||
@ -1375,7 +1388,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.7"
|
||||
content-hash = "545f5ef79ba67d5a2d2df007fb5ac67ca37630efd4ff04c3a15e181c73b4f466"
|
||||
content-hash = "e130b306957d6577ecd21cc1a19daa81073d5bbe77ba9f6a60ff83d8af0a2f05"
|
||||
|
||||
[metadata.files]
|
||||
alabaster = [
|
||||
@ -1416,29 +1429,29 @@ bcrypt = [
|
||||
{file = "bcrypt-3.2.0.tar.gz", hash = "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29"},
|
||||
]
|
||||
black = [
|
||||
{file = "black-22.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6"},
|
||||
{file = "black-22.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866"},
|
||||
{file = "black-22.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71"},
|
||||
{file = "black-22.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab"},
|
||||
{file = "black-22.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5"},
|
||||
{file = "black-22.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a"},
|
||||
{file = "black-22.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0"},
|
||||
{file = "black-22.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba"},
|
||||
{file = "black-22.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1"},
|
||||
{file = "black-22.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8"},
|
||||
{file = "black-22.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28"},
|
||||
{file = "black-22.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912"},
|
||||
{file = "black-22.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3"},
|
||||
{file = "black-22.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3"},
|
||||
{file = "black-22.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61"},
|
||||
{file = "black-22.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd"},
|
||||
{file = "black-22.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f"},
|
||||
{file = "black-22.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0"},
|
||||
{file = "black-22.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c"},
|
||||
{file = "black-22.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2"},
|
||||
{file = "black-22.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321"},
|
||||
{file = "black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d"},
|
||||
{file = "black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5"},
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
|
||||
{file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
|
||||
{file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
|
||||
{file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
|
||||
{file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
|
||||
{file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
|
||||
{file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
|
||||
{file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
|
||||
{file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
|
||||
{file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
|
||||
{file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
|
||||
{file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
|
||||
{file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
|
||||
{file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
|
||||
{file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
|
||||
]
|
||||
certifi = [
|
||||
{file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
|
||||
@ -1501,8 +1514,8 @@ charset-normalizer = [
|
||||
{file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"},
|
||||
]
|
||||
click = [
|
||||
{file = "click-8.0.4-py3-none-any.whl", hash = "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1"},
|
||||
{file = "click-8.0.4.tar.gz", hash = "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"},
|
||||
{file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"},
|
||||
{file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||
@ -1586,19 +1599,20 @@ docutils = [
|
||||
{file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"},
|
||||
]
|
||||
dramatiq = [
|
||||
{file = "dramatiq-1.12.3-py3-none-any.whl", hash = "sha256:eccb0f54d44ebd9e2c79e00d67b808397589a1a621ba7c5fd58df5fb6204a0a8"},
|
||||
{file = "dramatiq-1.12.3.tar.gz", hash = "sha256:380bd77b6b19d642f417b642935049ff71ddf4b4e57d821e4f55b92541430f21"},
|
||||
{file = "dramatiq-1.13.0-py3-none-any.whl", hash = "sha256:8ef7509ca62bc45c3f1e3b1a0248e9f774337100e32ba1502cfcca15df79ad61"},
|
||||
{file = "dramatiq-1.13.0.tar.gz", hash = "sha256:b4fe0ca6b55b06bebf82cd14c88044fb267505a57d4aa47378194efa0cef5f47"},
|
||||
]
|
||||
flake8 = [
|
||||
{file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
|
||||
{file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"},
|
||||
]
|
||||
flask = [
|
||||
{file = "Flask-2.0.3-py3-none-any.whl", hash = "sha256:59da8a3170004800a2837844bfa84d49b022550616070f7cb1a659682b2e7c9f"},
|
||||
{file = "Flask-2.0.3.tar.gz", hash = "sha256:e1120c228ca2f553b470df4a5fa927ab66258467526069981b3eb0a91902687d"},
|
||||
{file = "Flask-2.1.1-py3-none-any.whl", hash = "sha256:8a4cf32d904cf5621db9f0c9fbcd7efabf3003f22a04e4d0ce790c7137ec5264"},
|
||||
{file = "Flask-2.1.1.tar.gz", hash = "sha256:a8c9bd3e558ec99646d177a9739c41df1ded0629480b4c8d2975412f3c9519c8"},
|
||||
]
|
||||
flask-bcrypt = [
|
||||
{file = "Flask-Bcrypt-0.7.1.tar.gz", hash = "sha256:d71c8585b2ee1c62024392ebdbc447438564e2c8c02b4e57b56a4cafd8d13c5f"},
|
||||
{file = "Flask-Bcrypt-1.0.0.tar.gz", hash = "sha256:e622fbd3b0bf63d516b8844fe3431fc30213592412b430036c3928a0c52dfb27"},
|
||||
{file = "Flask_Bcrypt-1.0.0-py3-none-any.whl", hash = "sha256:64a947e15ff06823c3843f4826d4548dfae038c7df8f98ea82755db62092ec4c"},
|
||||
]
|
||||
flask-dramatiq = [
|
||||
{file = "flask-dramatiq-0.6.0.tar.gz", hash = "sha256:63709e73d7c8d2e5d9bc554d1e859d91c5c5c9a4ebc9461752655bf1e0b87420"},
|
||||
@ -1806,41 +1820,44 @@ pathspec = [
|
||||
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
|
||||
]
|
||||
pillow = [
|
||||
{file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"},
|
||||
{file = "Pillow-9.0.1-1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976"},
|
||||
{file = "Pillow-9.0.1-1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc"},
|
||||
{file = "Pillow-9.0.1-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd"},
|
||||
{file = "Pillow-9.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f"},
|
||||
{file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a"},
|
||||
{file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049"},
|
||||
{file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a"},
|
||||
{file = "Pillow-9.0.1-cp310-cp310-win32.whl", hash = "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e"},
|
||||
{file = "Pillow-9.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b"},
|
||||
{file = "Pillow-9.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e"},
|
||||
{file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360"},
|
||||
{file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b"},
|
||||
{file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030"},
|
||||
{file = "Pillow-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669"},
|
||||
{file = "Pillow-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092"},
|
||||
{file = "Pillow-9.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204"},
|
||||
{file = "Pillow-9.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e"},
|
||||
{file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c"},
|
||||
{file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5"},
|
||||
{file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae"},
|
||||
{file = "Pillow-9.0.1-cp38-cp38-win32.whl", hash = "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c"},
|
||||
{file = "Pillow-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00"},
|
||||
{file = "Pillow-9.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838"},
|
||||
{file = "Pillow-9.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28"},
|
||||
{file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c"},
|
||||
{file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b"},
|
||||
{file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7"},
|
||||
{file = "Pillow-9.0.1-cp39-cp39-win32.whl", hash = "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7"},
|
||||
{file = "Pillow-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac"},
|
||||
{file = "Pillow-9.0.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97"},
|
||||
{file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56"},
|
||||
{file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e"},
|
||||
{file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"},
|
||||
{file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"},
|
||||
{file = "Pillow-9.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea"},
|
||||
{file = "Pillow-9.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652"},
|
||||
{file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a"},
|
||||
{file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7"},
|
||||
{file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e"},
|
||||
{file = "Pillow-9.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3"},
|
||||
{file = "Pillow-9.1.0-cp310-cp310-win32.whl", hash = "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160"},
|
||||
{file = "Pillow-9.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033"},
|
||||
{file = "Pillow-9.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c"},
|
||||
{file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165"},
|
||||
{file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a"},
|
||||
{file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2"},
|
||||
{file = "Pillow-9.1.0-cp37-cp37m-win32.whl", hash = "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244"},
|
||||
{file = "Pillow-9.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef"},
|
||||
{file = "Pillow-9.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512"},
|
||||
{file = "Pillow-9.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477"},
|
||||
{file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b"},
|
||||
{file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378"},
|
||||
{file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e"},
|
||||
{file = "Pillow-9.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5"},
|
||||
{file = "Pillow-9.1.0-cp38-cp38-win32.whl", hash = "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a"},
|
||||
{file = "Pillow-9.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34"},
|
||||
{file = "Pillow-9.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717"},
|
||||
{file = "Pillow-9.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581"},
|
||||
{file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6"},
|
||||
{file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4"},
|
||||
{file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331"},
|
||||
{file = "Pillow-9.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8"},
|
||||
{file = "Pillow-9.1.0-cp39-cp39-win32.whl", hash = "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58"},
|
||||
{file = "Pillow-9.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595"},
|
||||
{file = "Pillow-9.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481"},
|
||||
{file = "Pillow-9.1.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0"},
|
||||
{file = "Pillow-9.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a"},
|
||||
{file = "Pillow-9.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7"},
|
||||
{file = "Pillow-9.1.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3"},
|
||||
{file = "Pillow-9.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8"},
|
||||
{file = "Pillow-9.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458"},
|
||||
{file = "Pillow-9.1.0.tar.gz", hash = "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97"},
|
||||
]
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"},
|
||||
@ -1954,8 +1971,8 @@ pytest = [
|
||||
{file = "pytest-7.1.1.tar.gz", hash = "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63"},
|
||||
]
|
||||
pytest-base-url = [
|
||||
{file = "pytest-base-url-1.4.2.tar.gz", hash = "sha256:7f1f32e08c2ee751e59e7f5880235b46e83496adc5cba5a01ca218c6fe81333d"},
|
||||
{file = "pytest_base_url-1.4.2-py2.py3-none-any.whl", hash = "sha256:8b6523a1a3af73c317bdae97b722dfb55a7336733d1ad411eb4a4931347ba77a"},
|
||||
{file = "pytest-base-url-2.0.0.tar.gz", hash = "sha256:e1e88a4fd221941572ccdcf3bf6c051392d2f8b6cef3e0bc7da95abec4b5346e"},
|
||||
{file = "pytest_base_url-2.0.0-py3-none-any.whl", hash = "sha256:ed36fd632c32af9f1c08f2c2835dcf42ca8fcd097d6ed44a09f253d365ad8297"},
|
||||
]
|
||||
pytest-black = [
|
||||
{file = "pytest-black-0.3.12.tar.gz", hash = "sha256:1d339b004f764d6cd0f06e690f6dd748df3d62e6fe1a692d6a5500ac2c5b75a5"},
|
||||
@ -2008,8 +2025,8 @@ recommonmark = [
|
||||
{file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"},
|
||||
]
|
||||
redis = [
|
||||
{file = "redis-4.2.0-py3-none-any.whl", hash = "sha256:3cbe235cea80b9c9991b397567aa2d65eb4e6fb09787f61d227ae82eb4eb50b4"},
|
||||
{file = "redis-4.2.0.tar.gz", hash = "sha256:6758d01dec81af191b98a35cce3402675d115456584c39b500ab485a5e386bbb"},
|
||||
{file = "redis-4.2.1-py3-none-any.whl", hash = "sha256:69d05fac17bf3f43937afbb775c536eb516bd21355a4f17d59a966f4a531ce71"},
|
||||
{file = "redis-4.2.1.tar.gz", hash = "sha256:fe45513881229dbee610620b9e0817b1f48c47ba635870320fd44a712204bbdd"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
|
||||
@ -2043,8 +2060,8 @@ sortedcontainers = [
|
||||
{file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"},
|
||||
]
|
||||
sphinx = [
|
||||
{file = "Sphinx-4.4.0-py3-none-any.whl", hash = "sha256:5da895959511473857b6d0200f56865ed62c31e8f82dd338063b84ec022701fe"},
|
||||
{file = "Sphinx-4.4.0.tar.gz", hash = "sha256:6caad9786055cb1fa22b4a365c1775816b876f91966481765d7d50e9f0dd35cc"},
|
||||
{file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"},
|
||||
{file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"},
|
||||
]
|
||||
sphinx-bootstrap-theme = [
|
||||
{file = "sphinx-bootstrap-theme-0.8.1.tar.gz", hash = "sha256:683e3b735448dadd0149f76edecf95ff4bd9157787e9e77e0d048ca6f1d680df"},
|
||||
@ -2165,16 +2182,16 @@ typed-ast = [
|
||||
{file = "typed_ast-1.5.2.tar.gz", hash = "sha256:525a2d4088e70a9f75b08b3f87a51acc9cde640e19cc523c7e41aa355564ae27"},
|
||||
]
|
||||
types-freezegun = [
|
||||
{file = "types-freezegun-1.1.7.tar.gz", hash = "sha256:e9d1327e98c6caa8f65de0018ded274347e8e34198d59aa9a5c24ad9265d5e5e"},
|
||||
{file = "types_freezegun-1.1.7-py3-none-any.whl", hash = "sha256:efa02341ad35e4f24b3346d09b60332e967586a5bc495a56b1c9c927b4c788b6"},
|
||||
{file = "types-freezegun-1.1.8.tar.gz", hash = "sha256:f4bb08c54aa46816c77a1b5c7a2a54f5393c3ce58e7d4002e67f9081b411e921"},
|
||||
{file = "types_freezegun-1.1.8-py3-none-any.whl", hash = "sha256:59dd99a6d168bdb5bf884fda6daebd68c35bc86383df183cf182abc6dfcbb7b7"},
|
||||
]
|
||||
types-pytz = [
|
||||
{file = "types-pytz-2021.3.6.tar.gz", hash = "sha256:74547fd90d8d8ab4f1eedf3a344a7d186d97486973895f81221a712e1e2cd993"},
|
||||
{file = "types_pytz-2021.3.6-py3-none-any.whl", hash = "sha256:6805c72d51118923c5bf98633c39593d5b464d2ab49a803440e2d7ab6b8920df"},
|
||||
]
|
||||
types-requests = [
|
||||
{file = "types-requests-2.27.15.tar.gz", hash = "sha256:2d371183c535208d2cc8fe7473d9b49c344c7077eb70302eb708638fb86086a8"},
|
||||
{file = "types_requests-2.27.15-py3-none-any.whl", hash = "sha256:77d09182a68e447e9e8b0ffc21abf54618b96f07689dffbb6a41cf0356542969"},
|
||||
{file = "types-requests-2.27.16.tar.gz", hash = "sha256:c8010c18b291a7efb60b1452dbe12530bc25693dd657e70c62803fcdc4bffe9b"},
|
||||
{file = "types_requests-2.27.16-py3-none-any.whl", hash = "sha256:2437a5f4d16c0c8bd7539a8126d492b7aeb41e6cda670d76b286c7f83a658d42"},
|
||||
]
|
||||
types-urllib3 = [
|
||||
{file = "types-urllib3-1.26.11.tar.gz", hash = "sha256:24d64e441168851eb05f1d022de18ae31558f5649c8f1117e384c2e85e31315b"},
|
||||
@ -2184,13 +2201,17 @@ typing-extensions = [
|
||||
{file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"},
|
||||
{file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"},
|
||||
]
|
||||
ua-parser = [
|
||||
{file = "ua-parser-0.10.0.tar.gz", hash = "sha256:47b1782ed130d890018d983fac37c2a80799d9e0b9c532e734c67cf70f185033"},
|
||||
{file = "ua_parser-0.10.0-py2.py3-none-any.whl", hash = "sha256:46ab2e383c01dbd2ab284991b87d624a26a08f72da4d7d413f5bfab8b9036f8a"},
|
||||
]
|
||||
urllib3 = [
|
||||
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
|
||||
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
|
||||
]
|
||||
werkzeug = [
|
||||
{file = "Werkzeug-2.0.3-py3-none-any.whl", hash = "sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8"},
|
||||
{file = "Werkzeug-2.0.3.tar.gz", hash = "sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c"},
|
||||
{file = "Werkzeug-2.1.1-py3-none-any.whl", hash = "sha256:3c5493ece8268fecdcdc9c0b112211acd006354723b280d643ec732b6d4063d6"},
|
||||
{file = "Werkzeug-2.1.1.tar.gz", hash = "sha256:f8e89a20aeabbe8a893c24a461d3ee5dad2123b05cc6abd73ceed01d39c3ae74"},
|
||||
]
|
||||
wrapt = [
|
||||
{file = "wrapt-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:5a9a1889cc01ed2ed5f34574c90745fab1dd06ec2eee663e8ebeefe363e8efd7"},
|
||||
|
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "fittrackee"
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
description = "Self-hosted outdoor workout/activity tracker"
|
||||
authors = ["SamR1"]
|
||||
license = "AGPL-3.0"
|
||||
@ -24,9 +24,9 @@ exclude = ["fittrackee/tests"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
dramatiq = {version = "^1.12.3", extras = ["redis"]}
|
||||
flask = "^2.0"
|
||||
flask-bcrypt = "^0.7.1"
|
||||
dramatiq = {version = "^1.13", extras = ["redis"]}
|
||||
flask = "^2.1"
|
||||
flask-bcrypt = "^1.0"
|
||||
flask-dramatiq = "^0.6.0"
|
||||
flask-migrate = "^3.1"
|
||||
gpxpy = "=1.3.4"
|
||||
@ -40,9 +40,10 @@ shortuuid = "^1.0.8"
|
||||
staticmap = "^0.5.4"
|
||||
SQLAlchemy = "1.4.32"
|
||||
pyOpenSSL = "^22.0"
|
||||
ua-parser = "^0.10.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
black = "^22.1"
|
||||
black = "^22.3"
|
||||
freezegun = "^1.2"
|
||||
mypy = "^0.942"
|
||||
pytest = "^7.1"
|
||||
@ -58,7 +59,7 @@ sphinxcontrib-httpdomain = "^1.7"
|
||||
types-pytz = "^2021.3"
|
||||
types-requests = "^2.27"
|
||||
types-freezegun = "^1.1"
|
||||
Sphinx = "^4.4.0"
|
||||
Sphinx = "^4.5"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
fittrackee = 'fittrackee.__main__:main'
|
||||
|