From bb2c149caa88564cd4554f4c90bf6dab83d0b7a0 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 13 Nov 2021 19:46:12 +0100 Subject: [PATCH] API - add preference for imperial units conversion --- docs/api/auth.html | 3 ++ docs/api/users.html | 3 ++ docs/searchindex.js | 2 +- fittrackee/application/models.py | 11 ++++++- ...8ca7620a_add_imperial_units_preferences.py | 31 +++++++++++++++++++ fittrackee/tests/users/test_auth_api.py | 7 +++++ fittrackee/tests/users/test_users_api.py | 8 +++++ fittrackee/tests/users/test_users_model.py | 1 + fittrackee/users/auth.py | 6 ++++ fittrackee/users/models.py | 2 ++ fittrackee/users/users.py | 3 ++ 11 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 fittrackee/migrations/versions/20_07188ca7620a_add_imperial_units_preferences.py diff --git a/docs/api/auth.html b/docs/api/auth.html index 0a505c5c..26de324d 100644 --- a/docs/api/auth.html +++ b/docs/api/auth.html @@ -319,6 +319,7 @@ "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "sam@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -419,6 +420,7 @@ "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "sam@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -537,6 +539,7 @@ "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "sam@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, diff --git a/docs/api/users.html b/docs/api/users.html index 87cd9be1..136bbdb8 100644 --- a/docs/api/users.html +++ b/docs/api/users.html @@ -160,6 +160,7 @@ "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "admin@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -297,6 +298,7 @@ "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "admin@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -442,6 +444,7 @@ "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "admin@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, diff --git a/docs/searchindex.js b/docs/searchindex.js index f547cb00..38af6d09 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["api/auth","api/configuration","api/index","api/records","api/sports","api/stats","api/users","api/workouts","changelog","features","index","installation","troubleshooting/administrator","troubleshooting/index","troubleshooting/user"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["api/auth.rst","api/configuration.rst","api/index.rst","api/records.rst","api/sports.rst","api/stats.rst","api/users.rst","api/workouts.rst","changelog.md","features.rst","index.rst","installation.rst","troubleshooting/administrator.rst","troubleshooting/index.rst","troubleshooting/user.rst"],objects:{"":{"/api/auth/login":[0,0,1,"post--api-auth-login"],"/api/auth/logout":[0,1,1,"get--api-auth-logout"],"/api/auth/password/reset-request":[0,0,1,"post--api-auth-password-reset-request"],"/api/auth/password/update":[0,0,1,"post--api-auth-password-update"],"/api/auth/picture":[0,0,1,"post--api-auth-picture"],"/api/auth/profile":[0,1,1,"get--api-auth-profile"],"/api/auth/profile/edit":[0,0,1,"post--api-auth-profile-edit"],"/api/auth/profile/edit/preferences":[0,0,1,"post--api-auth-profile-edit-preferences"],"/api/auth/profile/edit/sports":[0,0,1,"post--api-auth-profile-edit-sports"],"/api/auth/register":[0,0,1,"post--api-auth-register"],"/api/config":[1,3,1,"patch--api-config"],"/api/ping":[1,1,1,"get--api-ping"],"/api/records":[3,1,1,"get--api-records"],"/api/sports":[4,1,1,"get--api-sports"],"/api/sports/(int:sport_id)":[4,3,1,"patch--api-sports-(int-sport_id)"],"/api/stats/(user_name)/by_sport":[5,1,1,"get--api-stats-(user_name)-by_sport"],"/api/stats/(user_name)/by_time":[5,1,1,"get--api-stats-(user_name)-by_time"],"/api/stats/all":[5,1,1,"get--api-stats-all"],"/api/users":[6,1,1,"get--api-users"],"/api/users/(user_name)":[6,3,1,"patch--api-users-(user_name)"],"/api/users/(user_name)/picture":[6,1,1,"get--api-users-(user_name)-picture"],"/api/workouts":[7,0,1,"post--api-workouts"],"/api/workouts/(string:workout_short_id)":[7,3,1,"patch--api-workouts-(string-workout_short_id)"],"/api/workouts/(string:workout_short_id)/chart_data":[7,1,1,"get--api-workouts-(string-workout_short_id)-chart_data"],"/api/workouts/(string:workout_short_id)/chart_data/segment/(int:segment_id)":[7,1,1,"get--api-workouts-(string-workout_short_id)-chart_data-segment-(int-segment_id)"],"/api/workouts/(string:workout_short_id)/gpx":[7,1,1,"get--api-workouts-(string-workout_short_id)-gpx"],"/api/workouts/(string:workout_short_id)/gpx/segment/(int:segment_id)":[7,1,1,"get--api-workouts-(string-workout_short_id)-gpx-segment-(int-segment_id)"],"/api/workouts/map/(map_id)":[7,1,1,"get--api-workouts-map-(map_id)"],"/api/workouts/no_gpx":[7,0,1,"post--api-workouts-no_gpx"],"DEFAULT_STATICMAP \ud83c\udd95":[11,4,1,"envvar-DEFAULT_STATICMAP"],APP_LOG:[11,4,1,"-"],APP_SECRET_KEY:[11,4,1,"-"],APP_SETTINGS:[11,4,1,"-"],APP_WORKERS:[11,4,1,"-"],DATABASE_DISABLE_POOLING:[11,4,1,"-"],DATABASE_URL:[11,4,1,"-"],EMAIL_URL:[11,4,1,"-"],FLASK_APP:[11,4,1,"-"],HOST:[11,4,1,"-"],MAP_ATTRIBUTION:[11,4,1,"-"],PORT:[11,4,1,"-"],REDIS_URL:[11,4,1,"-"],SENDER_EMAIL:[11,4,1,"-"],TILE_SERVER_URL:[11,4,1,"-"],UI_URL:[11,4,1,"-"],UPLOAD_FOLDER:[11,4,1,"-"],VUE_APP_API_URL:[11,4,1,"-"],WEATHER_API_KEY:[11,4,1,"-"],WORKERS_PROCESSES:[11,4,1,"-"]},"/api/workouts/map_tile/(s)/(z)/(x)/(y)":{png:[7,1,1,"get--api-workouts-map_tile-(s)-(z)-(x)-(y).png"]}},objnames:{"0":["http","post","HTTP post"],"1":["http","get","HTTP get"],"2":["http","delete","HTTP delete"],"3":["http","patch","HTTP patch"],"4":["std","envvar","environment variable"]},objtypes:{"0":"http:post","1":"http:get","2":"http:delete","3":"http:patch","4":"std:envvar"},terms:{"0":[0,1,3,4,5,6,7,9,10,11],"00":[0,3,6,7],"000000":0,"01":[0,3,5,6,7,10],"02":[7,10],"03":[6,7,10],"04":[7,10],"06":5,"07":[0,3,6,7,10],"08":[0,3,6],"09":[0,6,10],"0mb":[0,7],"1":[0,1,3,4,5,6,7,9,10,11],"10":[0,1,3,6,7,10,11],"100":[7,9],"1000":5,"104":8,"1048576":1,"10485760":1,"109":8,"11":[0,3,6,8,9],"12":[0,3,6,7,10],"1232004":7,"12341":5,"1234538":7,"1267":5,"127":11,"13":[7,8],"14":[0,6,7,8],"15":[5,7,10],"150":5,"156":5,"1563529507772":7,"16":[7,10],"17":[7,10,11],"178":5,"18":[0,3,6,7,8],"19":10,"2":[0,1,3,4,5,6,7,10,11],"20":6,"200":[0,1,3,4,5,6,7],"201":[0,7],"2017":[5,7],"2018":[5,7,10],"2019":[0,3,5,6,7,10],"2020":10,"2021":10,"203":5,"204":[0,6,7],"21":10,"22":[7,8],"23":10,"24":8,"25":[8,11],"26":8,"27":[0,6],"279":7,"28":8,"280":7,"282":5,"29":10,"2930":7,"2e1ee2c":8,"3":[0,4,5,6,7,9,10,11],"30":[5,10],"3000":11,"301":11,"31":[7,10],"33":8,"34":8,"34614d5":8,"36":8,"37":8,"39":7,"4":[0,4,6,7,10,11],"40":8,"400":[0,1,4,7],"401":[0,1,3,4,5,6,7],"403":[0,1,4,5,6,7],"404":[0,4,5,6,7],"41":8,"4109":7,"413":[0,7],"43":8,"44":[7,8],"443":11,"45":7,"46":[5,8],"465":11,"47":[5,7,8],"4c3fc34":8,"5":[1,4,5,6,7,9,10,11],"50":[0,6,8],"500":[0,1,4,6,7],"5000":11,"5078118":7,"5079733":7,"51":7,"53":8,"54":8,"5432":11,"57":[7,8],"58":[0,6,8],"587":11,"59":8,"6":[0,4,6,7,10],"613":5,"62":8,"63":7,"64":8,"66":8,"67":[0,6],"7":[7,10,11],"70":8,"71":8,"72":8,"7380":7,"75":8,"78":5,"79":8,"8":[0,7,10],"80":[8,11],"8025":11,"81":8,"82":8,"83":8,"84":8,"895":[0,6],"9":[0,3,6,10,11],"90":8,"91":8,"93":8,"95":8,"98":8,"9960":5,"boolean":[0,1,6],"case":9,"default":[5,6,7,8,9,11],"do":[1,4,5,6,7],"export":10,"float":[0,7],"import":[8,11],"int":[4,7],"new":[0,9,11],"null":[0,4,6,7],"return":[3,7,11],"short":7,"static":[8,11],"switch":8,"true":[0,1,4,6,8,11],"try":[0,6,7],A:[6,8,9],AS:[0,3,6,7],For:[9,11],If:[9,11],In:[8,9],It:[8,9,10,12],NO:[0,6,7],NOT:[0,4,7],No:[0,6,7,8,10],Not:[4,5,6,7],OF:11,ON:11,On:11,One:11,TO:11,The:[8,9,11],There:11,To:11,WITH:11,With:11,_:8,__main__:11,_blank:11,access:11,account:[6,8],acit:7,activ:[4,8,9,10,11],ad:[0,8,9],adapt:11,add:[6,8,9,10],addit:11,address:11,admin:[0,1,3,4,5,6,7,8,9,11],administr:[0,6,7,10,13],after:[8,11],again:[0,1,3,4,5,6,7],agplv3:8,all:[3,4,5,6,11],allow:[0,1,7,8,10],along:7,alpin:9,alreadi:0,also:[8,10,11],altitud:8,alwai:11,an:[1,4,6,7,8,9,11],android:10,anoth:[6,11],anymor:8,apach:10,api:[0,1,3,4,5,6,7,8,9,10,11],apikei:11,app:10,app_log:11,app_secret_kei:11,app_set:11,app_work:11,appear:9,applic:[0,1,3,4,5,6,7,8,9,10,11],ar:[3,7,8,9,10,11,12],arch:11,archiv:[1,8,9,11],archlinux:11,asc:6,ascent:7,attribut:11,auth:[0,1,3,4,5,6,7],auth_token:0,auth_user_id:[1,3,4,5,6,7],authent:[1,2,3,4,5,6,7,10],author:[0,1,3,4,5,6,7],avail:[0,3,9,10,11],ave_spe:7,ave_speed_from:7,ave_speed_to:7,averag:[3,7,8,9],axi:7,b862a77:8,b:11,background:8,backup:11,bad:[0,1,4,7],bearer:[0,1,3,4,5,6,7],becom:8,been:8,befor:[8,11],begin:11,better:8,bike:[4,7,8,9],bin:11,bio:[0,6],biographi:0,birth:[0,8],birth_dat:[0,6],bound:7,build:11,by_sport:5,by_tim:5,c:7,calcul:8,calendar:[8,9],can:[6,8,9,10,11,12],cannot:8,cd:11,chang:[9,10,11],charact:[0,8],chart:[7,8,9,11],chart_data:7,check:[1,11,12],choos:8,client:[8,11],client_max_body_s:11,clone:11,code:[0,1,3,4,5,6,7],color:[0,4,8,9],com:[0,6,11],complet:8,config:[1,11],configur:[2,8,9,10,11],confirm:0,contact:[0,6,7],contain:[8,9,11],content:[0,1,3,4,5,6,7],contributor:[1,11],control:8,coordin:11,copi:[1,11],copyright:[1,11],correctli:8,countri:9,cp:11,creat:[0,7,8,9,11],create_app:11,created_at:[0,6],creation:[8,9],creation_d:7,credenti:[0,11],criteria:6,cross:9,current:8,custom:11,cycl:[4,8,9],d:[0,5,7],dai:[8,9],dark:11,darkski:[8,9],dashboard:[8,10],data:[0,1,3,4,5,6,7,8,10,11],databas:[8,11,12],database_disable_pool:11,database_url:[8,11],date:[0,5,7,8,9],db:11,debian:11,default_staticmap:[8,11],defin:9,definit:8,delet:[0,6,7,8,9],depend:[8,11],deploy:10,desc:7,descent:7,describ:11,descript:11,detail:[6,8,10],develop:10,dialect:12,differ:8,directli:11,directori:[8,11],disabl:[0,8,9,11],displai:[7,8,9,10,11,12],distanc:[3,7,8,9],distance_from:7,distance_to:7,distribut:11,docker:[8,10],document:[8,10,11],doe:[0,5,6,7,8],don:0,down:8,download:11,dramatiq:11,drop:8,dropdown:9,due:8,durat:[3,7,8,9],duration_from:7,duration_to:7,dure:[0,7],easi:8,edit:[0,8,9],electr:9,elev:[7,8,9,11],els:11,email:[0,6,8],email_url:11,empti:8,en:[0,6],enabl:[1,9],encount:11,end:[5,7],endpoint:[1,8],engin:[8,11,12],english:9,enter:[8,9],entiti:[0,7],entri:11,env:11,environ:[8,10,12],error:[0,1,4,6,7,8,9,11,12],europ:[0,6],evalu:[8,11],even:[8,9],exampl:[0,1,3,4,5,6,7,10,11],exc:12,exce:[0,7],exceed:8,except:6,execstart:11,exhaust:10,exist:[0,5,6,7,9,10,11],expir:[0,1,3,4,5,6,7],extens:[0,7],fa33f4d996844a5c73ecd1ae24456ab8:7,fail:[8,13],fals:[0,1,4,6,7,11],farest:[3,8,9],fd:[0,3,6,7],featur:[10,11],fetch:11,file:[0,1,7,8,9,10,11],filter:[8,9],first:[0,9,10],first_nam:[0,6],fitotrack:10,fittracke:[9,11,13],fittrackee_cli:11,fittrackee_init_data:11,fittrackee_upgrade_db:11,fittrackee_work:11,fix:10,flask:11,flask_app:11,flaticon:11,follow:[3,9,11,12],forbidden:[0,1,4,5,6,7],forecast:11,form:[0,7],format:[0,5,7],former:11,forrunn:10,forward:11,found:[0,4,5,6,7],fr:6,frame:5,freepik:11,french:[9,10],fri:7,from:[1,3,4,5,6,7,8,10],fullchain:11,gener:[8,11],get:[0,1,3,4,5,6,7],gif:0,git:11,github:11,given:11,gmt:[0,3,6,7],gpl:10,gpx:[7,8,9,10,11],gpx_limit_import:1,gpxpy:[0,9,11],grant:11,greater:8,gunicorn:[11,12],gz:11,h:[7,9],ha:[6,9],handl:[0,9,11],has_workout:4,have:[1,4,5,6,7,8],he:6,header:[0,1,3,4,5,6,7],health:1,heavi:[10,11],hexadecim:0,hi:[6,8,9],hike:[4,8,9],home:11,host:11,href:[1,11],http:[0,1,3,4,5,6,7,11],hvybqybra7wwxpastwr4v2:[0,3,6],i18n:8,icon:11,id:[0,1,3,4,5,6,7],imag:[0,6,7,8,9,11],improv:10,incorrect:8,index:7,info:0,inform:[8,10,11],init:11,initi:11,initialis:11,insid:11,instal:[8,10],instanc:[1,9,11],instead:9,integ:[1,3,4,5,6,7],interceptor:8,interfac:11,intern:[0,1,4,6,7],introduc:8,invalid:[0,1,3,4,5,6,7,8],io:11,ip:11,is_act:[0,4],is_active_for_us:4,is_registration_en:1,issu:[10,11],jan:7,javascript:8,john_do:6,jpeg:6,jpg:0,js:11,json:[0,1,3,4,5,6,7],jul:[0,3,6,7],keep:[8,10,11],kei:[8,9,11],kjxavsturjvoah2wvcegef:7,km:[7,9],label:4,languag:[0,6,9],larg:[0,7,9],larger:11,last:[0,11],last_nam:[0,6],latitud:7,layer:[8,11],ld:[0,3,6,7],leaflet:[7,11],least:7,less:8,librari:11,licens:[8,10],like:[9,11],limit:[8,9],link:11,linux:11,list:[8,10,11],listen:11,load:[8,12],local:[8,10,11],localhost:11,locat:[0,6,11],log:[0,1,3,4,5,6,7,10,11,12],logfil:11,login:0,logout:[0,8],longer:[8,12],longest:[3,8,9],longitud:7,m:[0,5,7],made:11,mai:[9,10,11],mailhog:11,major:8,make:[8,11],makefil:11,manag:8,mandatori:[7,8,11],map:[7,8,9,10],map_attribut:[1,11],map_id:7,map_til:7,match:0,max:[1,6,7,8],max_alt:7,max_single_file_s:1,max_spe:7,max_speed_from:7,max_speed_to:7,max_us:1,max_zip_file_s:1,maxim:7,maximum:[3,8,9],messag:[0,1,7,8],method:11,min:8,min_alt:7,minim:7,minor:10,miss:8,mobil:10,model:8,modifi:[6,8],modification_d:7,modul:11,mon:7,mondai:[0,5,9],montain:8,month:[5,8,9],more:[8,9,10,11],morn:7,mountain:[4,9],mous:8,move:[7,8],movement:8,mpwoadmin:11,ms:[0,3,6,7],multi:11,multipart:[0,7],must:[0,1,4,8,9,11,12],mv:11,n:0,name:[0,5,6,11],nano:11,nb_sport:[0,6],nb_workout:[0,5,6],necessari:[9,11],need:11,network:11,next:9,next_workout:7,nginx:[9,11],no_gpx:7,non:[4,10],noopen:11,noreferr:11,nosuchmoduleerror:12,note:[7,8,9,11],now:[8,9,11],number:[1,6,7,8,9,11],oauth:[0,1,3,4,5,6,7],object:[0,1,4,6,7],ok:[0,1,3,4,5,6,7],one:[6,7,9],onli:[6,7,8,9,11],open:[10,11],openstreetmap:[1,8,11],opentrack:10,option:11,order:[6,7,8],order_bi:6,org:[1,11],os:11,other:[6,11],out:0,outdoor:[8,10,11],over:8,overrid:9,overridden:9,overwrit:11,own:[6,10],owner:[8,9],packag:[8,11],page:[6,7],pagin:[6,7],par_pag:6,paramet:[0,1,3,4,5,6,7,8,9],pari:[0,6],pars:11,part:[0,7],pass:11,password:[0,8,9,11],password_conf:0,patch:[1,4,6,7],path:11,paus:[7,8],payload:[0,1,4,7],pem:11,per:[6,7,8],per_pag:[6,7],permiss:[1,4,5,6,7],pg_dump:11,pictur:[0,6,7],ping:1,pip:11,pipenv:8,pleas:[0,1,3,4,5,6,7,8],plugin:12,png:[0,7,11],poetri:[8,11],point:[8,11],pong:1,pool:11,port:11,possibl:[8,10],post:[0,7],postgr:[8,12],postgresql:[8,11,12],prefer:[0,8],prerequisit:10,previous_workout:7,privileg:11,privkei:11,process:[0,9,11],productionconfig:11,profil:0,project:11,provid:[0,1,3,4,5,6,7,8,9,11],proxi:11,proxy_add_x_forwarded_for:11,proxy_pass:11,proxy_redirect:11,proxy_set_head:11,pull:11,purpos:[8,11],pwd:11,py:11,pypi:10,python:[8,11],q:6,queri:[5,6,7],queue:11,r:11,rais:9,read:8,real:11,rebuild:8,rechart:7,recommend:11,record:[0,2,6,7,8,9,10],record_typ:[0,3,6,7],redi:[8,11],redis_url:11,refactor:8,regist:[0,1,11],registr:[0,1,8,9],rel:11,relat:11,releas:[10,11],remain:8,remote_addr:11,remov:9,renam:8,replac:[8,11],repo:11,repositori:11,request:[0,1,3,4,5,6,7],request_uri:11,requir:0,reset:[0,8,9],respons:[0,1,3,4,5,6,7],restart:11,restartsec:11,right:[6,8,9],rout:8,row:9,run:[4,8,9,11],runner:10,s:[6,7,8,9,11],sam:[0,6],same:8,samr1:11,sat:6,save:[8,9],schema:11,search:8,second:7,secret:11,see:[8,9,10,11],seem:8,segment:[7,8,9],segment_id:7,select:[0,7],send:[8,11],sender:11,sender_email:11,serv:11,server:[0,1,4,6,7,8,9,10],server_nam:11,servic:11,set:[8,9],sever:[10,11],shell:11,should:11,show:8,shown:8,side:8,signatur:[0,1,3,4,5,6,7],simpl:11,simplifi:8,sinc:11,singl:[1,6],size:[0,1,7,8,9],ski:9,sky:11,slow:8,smtp:11,some:[6,7,8,10,11],sorri:0,sort:[6,7],sourc:10,spawn:11,speed:[0,3,7,8,9,11],spinner:8,sport:[0,2,5,7,8,9,10,11],sport_id:[0,3,4,5,6,7],sports_list:[0,6],sql:11,sqlalchemi:[8,11,12],ssl:11,ssl_certif:11,ssl_certificate_kei:11,standard:[8,11],standarderror:11,standardoutput:11,start:[0,5,7,8,9,11,13],startlimitintervalsec:11,starttl:11,stat:[5,8],staticmap:11,statist:[2,10],statu:[0,1,3,4,5,6,7],step:11,still:[9,10],stop:[0,8,9,11],stopped_speed_threshold:[0,4],store:10,street:10,string:[0,4,5,6,7],subdomain:7,success:[0,1,3,4,5,6,7],successfulli:0,sun:[0,3,6,7],sundai:[5,7,9],support:[8,9,12],syslog:11,syslogidentifi:11,system:11,systemd:11,t:[0,12],tar:11,target:11,task:11,term:[8,11],test:11,textarea:8,than:8,thei:11,them:10,thi:[7,8,9,10,11],threshold:[0,8,9],thunderforest:[8,11],tile:[7,8],tile_server_url:11,time:[0,5,7,8,9],timezon:[0,6,8,9],titl:7,tl:11,todo:14,token:[0,1,3,4,5,6,7],too:[0,7],tool:11,tooltip:8,total:8,total_asc:5,total_dist:[0,5,6],total_dur:[0,5,6],track:10,trail:9,transport:[4,8,9],troubleshoot:10,type:[0,1,3,4,5,6,7,11],typescript:11,u:11,ui:8,ui_url:11,unauthor:[0,1,3,4,5,6,7],under:[10,11],unencrypt:11,unit:11,unreleas:10,unstabl:[10,11],up:[9,10],updat:[0,1,4,6,7,8,9,11],upload:[8,9,11],upload_fold:11,uploads_dir_s:5,url:[8,11,12],us:[0,6,7,8,9,10,11],user:[0,1,2,3,4,5,7,8,9,10,11,13],user_id:0,user_nam:[5,6],usernam:[0,6,11],uuid:[7,8],v0:11,v3:10,valid:[0,1,3,4,5,6,7,11],valu:[0,3,6,7],variabl:[8,10,12],venv:11,version:[1,10,11],view:8,virtualenv:11,vue3:11,vue:11,vue_app_api_url:11,vuex:11,wa:8,wai:11,walk:[4,8,9],wantedbi:11,warn:8,weather:[8,9,11],weather_api:11,weather_api_kei:11,weather_end:7,weather_start:7,web:[0,1,3,4,5,6,7,10,11],week:[0,5,8,9],weekend:8,weekm:[0,5],were:8,wget:11,when:[0,1,8,9,11],where:11,which:9,with_gpx:7,without:[5,6,7,8,9,10],worker:11,workers_process:11,workingdirectori:11,workout:[0,2,5,8,10],workout_d:[0,3,6,7],workout_id:[0,3,6,7],workout_short_id:7,workouts_count:6,written:11,www:[1,11],x:[7,11],xxxx:11,xzf:11,y:[0,5,7,11],yai:11,yarn:11,year:5,yet:10,you:[1,4,5,6,7,10],your:[6,10,11],z:[7,11],zip:[1,7,8,9],zone:0,zoom:7},titles:["Authentication","Configuration","API documentation","Records","Sports","Statistics","Users","Workouts","Change log","Features","FitTrackee","Installation","Administrator","Troubleshooting","User"],titleterms:{"0":8,"01":8,"02":8,"03":8,"04":8,"07":8,"09":8,"1":8,"10":8,"12":8,"15":8,"16":8,"17":8,"19":8,"2":8,"2018":8,"2019":8,"2020":8,"2021":8,"21":8,"23":8,"29":8,"3":8,"30":8,"31":8,"4":8,"5":8,"6":8,"7":8,"8":8,"9":8,"new":8,account:9,administr:[8,9,12],api:2,authent:0,avail:8,bug:8,chang:8,close:8,configur:1,content:10,dashboard:9,deploy:11,detail:9,dev:11,develop:11,docker:11,document:2,email:11,endpoint:[2,13],environ:11,fail:12,featur:[8,9],first:8,fittracke:[8,10,12],fix:8,french:8,from:11,improv:8,instal:11,issu:8,list:9,log:8,map:11,minor:8,misc:8,prefer:9,prerequisit:11,prod:11,product:11,pull:8,pypi:[8,11],record:3,releas:8,request:8,server:11,sourc:11,sport:4,start:12,statist:[5,8,9],tabl:10,tile:11,translat:9,troubleshoot:13,unreleas:8,upgrad:11,user:[6,14],variabl:11,version:8,workout:[7,9]}}) \ No newline at end of file +Search.setIndex({docnames:["api/auth","api/configuration","api/index","api/records","api/sports","api/stats","api/users","api/workouts","changelog","features","index","installation","troubleshooting/administrator","troubleshooting/index","troubleshooting/user"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["api/auth.rst","api/configuration.rst","api/index.rst","api/records.rst","api/sports.rst","api/stats.rst","api/users.rst","api/workouts.rst","changelog.md","features.rst","index.rst","installation.rst","troubleshooting/administrator.rst","troubleshooting/index.rst","troubleshooting/user.rst"],objects:{"":{"/api/auth/login":[0,0,1,"post--api-auth-login"],"/api/auth/logout":[0,1,1,"get--api-auth-logout"],"/api/auth/password/reset-request":[0,0,1,"post--api-auth-password-reset-request"],"/api/auth/password/update":[0,0,1,"post--api-auth-password-update"],"/api/auth/picture":[0,0,1,"post--api-auth-picture"],"/api/auth/profile":[0,1,1,"get--api-auth-profile"],"/api/auth/profile/edit":[0,0,1,"post--api-auth-profile-edit"],"/api/auth/profile/edit/preferences":[0,0,1,"post--api-auth-profile-edit-preferences"],"/api/auth/profile/edit/sports":[0,0,1,"post--api-auth-profile-edit-sports"],"/api/auth/register":[0,0,1,"post--api-auth-register"],"/api/config":[1,3,1,"patch--api-config"],"/api/ping":[1,1,1,"get--api-ping"],"/api/records":[3,1,1,"get--api-records"],"/api/sports":[4,1,1,"get--api-sports"],"/api/sports/(int:sport_id)":[4,3,1,"patch--api-sports-(int-sport_id)"],"/api/stats/(user_name)/by_sport":[5,1,1,"get--api-stats-(user_name)-by_sport"],"/api/stats/(user_name)/by_time":[5,1,1,"get--api-stats-(user_name)-by_time"],"/api/stats/all":[5,1,1,"get--api-stats-all"],"/api/users":[6,1,1,"get--api-users"],"/api/users/(user_name)":[6,3,1,"patch--api-users-(user_name)"],"/api/users/(user_name)/picture":[6,1,1,"get--api-users-(user_name)-picture"],"/api/workouts":[7,0,1,"post--api-workouts"],"/api/workouts/(string:workout_short_id)":[7,3,1,"patch--api-workouts-(string-workout_short_id)"],"/api/workouts/(string:workout_short_id)/chart_data":[7,1,1,"get--api-workouts-(string-workout_short_id)-chart_data"],"/api/workouts/(string:workout_short_id)/chart_data/segment/(int:segment_id)":[7,1,1,"get--api-workouts-(string-workout_short_id)-chart_data-segment-(int-segment_id)"],"/api/workouts/(string:workout_short_id)/gpx":[7,1,1,"get--api-workouts-(string-workout_short_id)-gpx"],"/api/workouts/(string:workout_short_id)/gpx/segment/(int:segment_id)":[7,1,1,"get--api-workouts-(string-workout_short_id)-gpx-segment-(int-segment_id)"],"/api/workouts/map/(map_id)":[7,1,1,"get--api-workouts-map-(map_id)"],"/api/workouts/no_gpx":[7,0,1,"post--api-workouts-no_gpx"],"DEFAULT_STATICMAP \ud83c\udd95":[11,4,1,"envvar-DEFAULT_STATICMAP"],APP_LOG:[11,4,1,"-"],APP_SECRET_KEY:[11,4,1,"-"],APP_SETTINGS:[11,4,1,"-"],APP_WORKERS:[11,4,1,"-"],DATABASE_DISABLE_POOLING:[11,4,1,"-"],DATABASE_URL:[11,4,1,"-"],EMAIL_URL:[11,4,1,"-"],FLASK_APP:[11,4,1,"-"],HOST:[11,4,1,"-"],MAP_ATTRIBUTION:[11,4,1,"-"],PORT:[11,4,1,"-"],REDIS_URL:[11,4,1,"-"],SENDER_EMAIL:[11,4,1,"-"],TILE_SERVER_URL:[11,4,1,"-"],UI_URL:[11,4,1,"-"],UPLOAD_FOLDER:[11,4,1,"-"],VUE_APP_API_URL:[11,4,1,"-"],WEATHER_API_KEY:[11,4,1,"-"],WORKERS_PROCESSES:[11,4,1,"-"]},"/api/workouts/map_tile/(s)/(z)/(x)/(y)":{png:[7,1,1,"get--api-workouts-map_tile-(s)-(z)-(x)-(y).png"]}},objnames:{"0":["http","post","HTTP post"],"1":["http","get","HTTP get"],"2":["http","delete","HTTP delete"],"3":["http","patch","HTTP patch"],"4":["std","envvar","environment variable"]},objtypes:{"0":"http:post","1":"http:get","2":"http:delete","3":"http:patch","4":"std:envvar"},terms:{"0":[0,1,3,4,5,6,7,9,10,11],"00":[0,3,6,7],"000000":0,"01":[0,3,5,6,7,10],"02":[7,10],"03":[6,7,10],"04":[7,10],"06":5,"07":[0,3,6,7,10],"08":[0,3,6],"09":[0,6,10],"0mb":[0,7],"1":[0,1,3,4,5,6,7,9,10,11],"10":[0,1,3,6,7,10,11],"100":[7,9],"1000":5,"104":8,"1048576":1,"10485760":1,"109":8,"11":[0,3,6,8,9],"12":[0,3,6,7,10],"1232004":7,"12341":5,"1234538":7,"1267":5,"127":11,"13":[7,8],"14":[0,6,7,8],"15":[5,7,10],"150":5,"156":5,"1563529507772":7,"16":[7,10],"17":[7,10,11],"178":5,"18":[0,3,6,7,8],"19":10,"2":[0,1,3,4,5,6,7,10,11],"20":6,"200":[0,1,3,4,5,6,7],"201":[0,7],"2017":[5,7],"2018":[5,7,10],"2019":[0,3,5,6,7,10],"2020":10,"2021":10,"203":5,"204":[0,6,7],"21":10,"22":[7,8],"23":10,"24":8,"25":[8,11],"26":8,"27":[0,6],"279":7,"28":8,"280":7,"282":5,"29":10,"2930":7,"2e1ee2c":8,"3":[0,4,5,6,7,9,10,11],"30":[5,10],"3000":11,"301":11,"31":[7,10],"33":8,"34":8,"34614d5":8,"36":8,"37":8,"39":7,"4":[0,4,6,7,10,11],"40":8,"400":[0,1,4,7],"401":[0,1,3,4,5,6,7],"403":[0,1,4,5,6,7],"404":[0,4,5,6,7],"41":8,"4109":7,"413":[0,7],"43":8,"44":[7,8],"443":11,"45":7,"46":[5,8],"465":11,"47":[5,7,8],"4c3fc34":8,"5":[1,4,5,6,7,9,10,11],"50":[0,6,8],"500":[0,1,4,6,7],"5000":11,"5078118":7,"5079733":7,"51":7,"53":8,"54":8,"5432":11,"57":[7,8],"58":[0,6,8],"587":11,"59":8,"6":[0,4,6,7,10],"613":5,"62":8,"63":7,"64":8,"66":8,"67":[0,6],"7":[7,10,11],"70":8,"71":8,"72":8,"7380":7,"75":8,"78":5,"79":8,"8":[0,7,10],"80":[8,11],"8025":11,"81":8,"82":8,"83":8,"84":8,"895":[0,6],"9":[0,3,6,10,11],"90":8,"91":8,"93":8,"95":8,"98":8,"9960":5,"boolean":[0,1,6],"case":9,"default":[5,6,7,8,9,11],"do":[1,4,5,6,7],"export":10,"float":[0,7],"import":[8,11],"int":[4,7],"new":[0,9,11],"null":[0,4,6,7],"return":[3,7,11],"short":7,"static":[8,11],"switch":8,"true":[0,1,4,6,8,11],"try":[0,6,7],A:[6,8,9],AS:[0,3,6,7],For:[9,11],If:[9,11],In:[8,9],It:[8,9,10,12],NO:[0,6,7],NOT:[0,4,7],No:[0,6,7,8,10],Not:[4,5,6,7],OF:11,ON:11,On:11,One:11,TO:11,The:[8,9,11],There:11,To:11,WITH:11,With:11,_:8,__main__:11,_blank:11,access:11,account:[6,8],acit:7,activ:[4,8,9,10,11],ad:[0,8,9],adapt:11,add:[6,8,9,10],addit:11,address:11,admin:[0,1,3,4,5,6,7,8,9,11],administr:[0,6,7,10,13],after:[8,11],again:[0,1,3,4,5,6,7],agplv3:8,all:[3,4,5,6,11],allow:[0,1,7,8,10],along:7,alpin:9,alreadi:0,also:[8,10,11],altitud:8,alwai:11,an:[1,4,6,7,8,9,11],android:10,anoth:[6,11],anymor:8,apach:10,api:[0,1,3,4,5,6,7,8,9,10,11],apikei:11,app:10,app_log:11,app_secret_kei:11,app_set:11,app_work:11,appear:9,applic:[0,1,3,4,5,6,7,8,9,10,11],ar:[3,7,8,9,10,11,12],arch:11,archiv:[1,8,9,11],archlinux:11,asc:6,ascent:7,attribut:11,auth:[0,1,3,4,5,6,7],auth_token:0,auth_user_id:[1,3,4,5,6,7],authent:[1,2,3,4,5,6,7,10],author:[0,1,3,4,5,6,7],avail:[0,3,9,10,11],ave_spe:7,ave_speed_from:7,ave_speed_to:7,averag:[3,7,8,9],axi:7,b862a77:8,b:11,background:8,backup:11,bad:[0,1,4,7],bearer:[0,1,3,4,5,6,7],becom:8,been:8,befor:[8,11],begin:11,better:8,bike:[4,7,8,9],bin:11,bio:[0,6],biographi:0,birth:[0,8],birth_dat:[0,6],bound:7,build:11,by_sport:5,by_tim:5,c:7,calcul:8,calendar:[8,9],can:[6,8,9,10,11,12],cannot:8,cd:11,chang:[9,10,11],charact:[0,8],chart:[7,8,9,11],chart_data:7,check:[1,11,12],choos:8,client:[8,11],client_max_body_s:11,clone:11,code:[0,1,3,4,5,6,7],color:[0,4,8,9],com:[0,6,11],complet:8,config:[1,11],configur:[2,8,9,10,11],confirm:0,contact:[0,6,7],contain:[8,9,11],content:[0,1,3,4,5,6,7],contributor:[1,11],control:8,coordin:11,copi:[1,11],copyright:[1,11],correctli:8,countri:9,cp:11,creat:[0,7,8,9,11],create_app:11,created_at:[0,6],creation:[8,9],creation_d:7,credenti:[0,11],criteria:6,cross:9,current:8,custom:11,cycl:[4,8,9],d:[0,5,7],dai:[8,9],dark:11,darkski:[8,9],dashboard:[8,10],data:[0,1,3,4,5,6,7,8,10,11],databas:[8,11,12],database_disable_pool:11,database_url:[8,11],date:[0,5,7,8,9],db:11,debian:11,default_staticmap:[8,11],defin:9,definit:8,delet:[0,6,7,8,9],depend:[8,11],deploy:10,desc:7,descent:7,describ:11,descript:11,detail:[6,8,10],develop:10,dialect:12,differ:8,directli:11,directori:[8,11],disabl:[0,8,9,11],displai:[7,8,9,10,11,12],distanc:[3,7,8,9],distance_from:7,distance_to:7,distribut:11,docker:[8,10],document:[8,10,11],doe:[0,5,6,7,8],don:0,down:8,download:11,dramatiq:11,drop:8,dropdown:9,due:8,durat:[3,7,8,9],duration_from:7,duration_to:7,dure:[0,7],easi:8,edit:[0,8,9],electr:9,elev:[7,8,9,11],els:11,email:[0,6,8],email_url:11,empti:8,en:[0,6],enabl:[1,9],encount:11,end:[5,7],endpoint:[1,8],engin:[8,11,12],english:9,enter:[8,9],entiti:[0,7],entri:11,env:11,environ:[8,10,12],error:[0,1,4,6,7,8,9,11,12],europ:[0,6],evalu:[8,11],even:[8,9],exampl:[0,1,3,4,5,6,7,10,11],exc:12,exce:[0,7],exceed:8,except:6,execstart:11,exhaust:10,exist:[0,5,6,7,9,10,11],expir:[0,1,3,4,5,6,7],extens:[0,7],fa33f4d996844a5c73ecd1ae24456ab8:7,fail:[8,13],fals:[0,1,4,6,7,11],farest:[3,8,9],fd:[0,3,6,7],featur:[10,11],fetch:11,file:[0,1,7,8,9,10,11],filter:[8,9],first:[0,9,10],first_nam:[0,6],fitotrack:10,fittracke:[9,11,13],fittrackee_cli:11,fittrackee_init_data:11,fittrackee_upgrade_db:11,fittrackee_work:11,fix:10,flask:11,flask_app:11,flaticon:11,follow:[3,9,11,12],forbidden:[0,1,4,5,6,7],forecast:11,form:[0,7],format:[0,5,7],former:11,forrunn:10,forward:11,found:[0,4,5,6,7],fr:6,frame:5,freepik:11,french:[9,10],fri:7,from:[1,3,4,5,6,7,8,10],fullchain:11,gener:[8,11],get:[0,1,3,4,5,6,7],gif:0,git:11,github:11,given:11,gmt:[0,3,6,7],gpl:10,gpx:[7,8,9,10,11],gpx_limit_import:1,gpxpy:[0,9,11],grant:11,greater:8,gunicorn:[11,12],gz:11,h:[7,9],ha:[6,9],handl:[0,9,11],has_workout:4,have:[1,4,5,6,7,8],he:6,header:[0,1,3,4,5,6,7],health:1,heavi:[10,11],hexadecim:0,hi:[6,8,9],hike:[4,8,9],home:11,host:11,href:[1,11],http:[0,1,3,4,5,6,7,11],hvybqybra7wwxpastwr4v2:[0,3,6],i18n:8,icon:11,id:[0,1,3,4,5,6,7],imag:[0,6,7,8,9,11],imperial_unit:[0,6],improv:10,incorrect:8,index:7,info:0,inform:[8,10,11],init:11,initi:11,initialis:11,insid:11,instal:[8,10],instanc:[1,9,11],instead:9,integ:[1,3,4,5,6,7],interceptor:8,interfac:11,intern:[0,1,4,6,7],introduc:8,invalid:[0,1,3,4,5,6,7,8],io:11,ip:11,is_act:[0,4],is_active_for_us:4,is_registration_en:1,issu:[10,11],jan:7,javascript:8,john_do:6,jpeg:6,jpg:0,js:11,json:[0,1,3,4,5,6,7],jul:[0,3,6,7],keep:[8,10,11],kei:[8,9,11],kjxavsturjvoah2wvcegef:7,km:[7,9],label:4,languag:[0,6,9],larg:[0,7,9],larger:11,last:[0,11],last_nam:[0,6],latitud:7,layer:[8,11],ld:[0,3,6,7],leaflet:[7,11],least:7,less:8,librari:11,licens:[8,10],like:[9,11],limit:[8,9],link:11,linux:11,list:[8,10,11],listen:11,load:[8,12],local:[8,10,11],localhost:11,locat:[0,6,11],log:[0,1,3,4,5,6,7,10,11,12],logfil:11,login:0,logout:[0,8],longer:[8,12],longest:[3,8,9],longitud:7,m:[0,5,7],made:11,mai:[9,10,11],mailhog:11,major:8,make:[8,11],makefil:11,manag:8,mandatori:[7,8,11],map:[7,8,9,10],map_attribut:[1,11],map_id:7,map_til:7,match:0,max:[1,6,7,8],max_alt:7,max_single_file_s:1,max_spe:7,max_speed_from:7,max_speed_to:7,max_us:1,max_zip_file_s:1,maxim:7,maximum:[3,8,9],messag:[0,1,7,8],method:11,min:8,min_alt:7,minim:7,minor:10,miss:8,mobil:10,model:8,modifi:[6,8],modification_d:7,modul:11,mon:7,mondai:[0,5,9],montain:8,month:[5,8,9],more:[8,9,10,11],morn:7,mountain:[4,9],mous:8,move:[7,8],movement:8,mpwoadmin:11,ms:[0,3,6,7],multi:11,multipart:[0,7],must:[0,1,4,8,9,11,12],mv:11,n:0,name:[0,5,6,11],nano:11,nb_sport:[0,6],nb_workout:[0,5,6],necessari:[9,11],need:11,network:11,next:9,next_workout:7,nginx:[9,11],no_gpx:7,non:[4,10],noopen:11,noreferr:11,nosuchmoduleerror:12,note:[7,8,9,11],now:[8,9,11],number:[1,6,7,8,9,11],oauth:[0,1,3,4,5,6,7],object:[0,1,4,6,7],ok:[0,1,3,4,5,6,7],one:[6,7,9],onli:[6,7,8,9,11],open:[10,11],openstreetmap:[1,8,11],opentrack:10,option:11,order:[6,7,8],order_bi:6,org:[1,11],os:11,other:[6,11],out:0,outdoor:[8,10,11],over:8,overrid:9,overridden:9,overwrit:11,own:[6,10],owner:[8,9],packag:[8,11],page:[6,7],pagin:[6,7],par_pag:6,paramet:[0,1,3,4,5,6,7,8,9],pari:[0,6],pars:11,part:[0,7],pass:11,password:[0,8,9,11],password_conf:0,patch:[1,4,6,7],path:11,paus:[7,8],payload:[0,1,4,7],pem:11,per:[6,7,8],per_pag:[6,7],permiss:[1,4,5,6,7],pg_dump:11,pictur:[0,6,7],ping:1,pip:11,pipenv:8,pleas:[0,1,3,4,5,6,7,8],plugin:12,png:[0,7,11],poetri:[8,11],point:[8,11],pong:1,pool:11,port:11,possibl:[8,10],post:[0,7],postgr:[8,12],postgresql:[8,11,12],prefer:[0,8],prerequisit:10,previous_workout:7,privileg:11,privkei:11,process:[0,9,11],productionconfig:11,profil:0,project:11,provid:[0,1,3,4,5,6,7,8,9,11],proxi:11,proxy_add_x_forwarded_for:11,proxy_pass:11,proxy_redirect:11,proxy_set_head:11,pull:11,purpos:[8,11],pwd:11,py:11,pypi:10,python:[8,11],q:6,queri:[5,6,7],queue:11,r:11,rais:9,read:8,real:11,rebuild:8,rechart:7,recommend:11,record:[0,2,6,7,8,9,10],record_typ:[0,3,6,7],redi:[8,11],redis_url:11,refactor:8,regist:[0,1,11],registr:[0,1,8,9],rel:11,relat:11,releas:[10,11],remain:8,remote_addr:11,remov:9,renam:8,replac:[8,11],repo:11,repositori:11,request:[0,1,3,4,5,6,7],request_uri:11,requir:0,reset:[0,8,9],respons:[0,1,3,4,5,6,7],restart:11,restartsec:11,right:[6,8,9],rout:8,row:9,run:[4,8,9,11],runner:10,s:[6,7,8,9,11],sam:[0,6],same:8,samr1:11,sat:6,save:[8,9],schema:11,search:8,second:7,secret:11,see:[8,9,10,11],seem:8,segment:[7,8,9],segment_id:7,select:[0,7],send:[8,11],sender:11,sender_email:11,serv:11,server:[0,1,4,6,7,8,9,10],server_nam:11,servic:11,set:[8,9],sever:[10,11],shell:11,should:11,show:8,shown:8,side:8,signatur:[0,1,3,4,5,6,7],simpl:11,simplifi:8,sinc:11,singl:[1,6],size:[0,1,7,8,9],ski:9,sky:11,slow:8,smtp:11,some:[6,7,8,10,11],sorri:0,sort:[6,7],sourc:10,spawn:11,speed:[0,3,7,8,9,11],spinner:8,sport:[0,2,5,7,8,9,10,11],sport_id:[0,3,4,5,6,7],sports_list:[0,6],sql:11,sqlalchemi:[8,11,12],ssl:11,ssl_certif:11,ssl_certificate_kei:11,standard:[8,11],standarderror:11,standardoutput:11,start:[0,5,7,8,9,11,13],startlimitintervalsec:11,starttl:11,stat:[5,8],staticmap:11,statist:[2,10],statu:[0,1,3,4,5,6,7],step:11,still:[9,10],stop:[0,8,9,11],stopped_speed_threshold:[0,4],store:10,street:10,string:[0,4,5,6,7],subdomain:7,success:[0,1,3,4,5,6,7],successfulli:0,sun:[0,3,6,7],sundai:[5,7,9],support:[8,9,12],syslog:11,syslogidentifi:11,system:11,systemd:11,t:[0,12],tar:11,target:11,task:11,term:[8,11],test:11,textarea:8,than:8,thei:11,them:10,thi:[7,8,9,10,11],threshold:[0,8,9],thunderforest:[8,11],tile:[7,8],tile_server_url:11,time:[0,5,7,8,9],timezon:[0,6,8,9],titl:7,tl:11,todo:14,token:[0,1,3,4,5,6,7],too:[0,7],tool:11,tooltip:8,total:8,total_asc:5,total_dist:[0,5,6],total_dur:[0,5,6],track:10,trail:9,transport:[4,8,9],troubleshoot:10,type:[0,1,3,4,5,6,7,11],typescript:11,u:11,ui:8,ui_url:11,unauthor:[0,1,3,4,5,6,7],under:[10,11],unencrypt:11,unit:11,unreleas:10,unstabl:[10,11],up:[9,10],updat:[0,1,4,6,7,8,9,11],upload:[8,9,11],upload_fold:11,uploads_dir_s:5,url:[8,11,12],us:[0,6,7,8,9,10,11],user:[0,1,2,3,4,5,7,8,9,10,11,13],user_id:0,user_nam:[5,6],usernam:[0,6,11],uuid:[7,8],v0:11,v3:10,valid:[0,1,3,4,5,6,7,11],valu:[0,3,6,7],variabl:[8,10,12],venv:11,version:[1,10,11],view:8,virtualenv:11,vue3:11,vue:11,vue_app_api_url:11,vuex:11,wa:8,wai:11,walk:[4,8,9],wantedbi:11,warn:8,weather:[8,9,11],weather_api:11,weather_api_kei:11,weather_end:7,weather_start:7,web:[0,1,3,4,5,6,7,10,11],week:[0,5,8,9],weekend:8,weekm:[0,5],were:8,wget:11,when:[0,1,8,9,11],where:11,which:9,with_gpx:7,without:[5,6,7,8,9,10],worker:11,workers_process:11,workingdirectori:11,workout:[0,2,5,8,10],workout_d:[0,3,6,7],workout_id:[0,3,6,7],workout_short_id:7,workouts_count:6,written:11,www:[1,11],x:[7,11],xxxx:11,xzf:11,y:[0,5,7,11],yai:11,yarn:11,year:5,yet:10,you:[1,4,5,6,7,10],your:[6,10,11],z:[7,11],zip:[1,7,8,9],zone:0,zoom:7},titles:["Authentication","Configuration","API documentation","Records","Sports","Statistics","Users","Workouts","Change log","Features","FitTrackee","Installation","Administrator","Troubleshooting","User"],titleterms:{"0":8,"01":8,"02":8,"03":8,"04":8,"07":8,"09":8,"1":8,"10":8,"12":8,"15":8,"16":8,"17":8,"19":8,"2":8,"2018":8,"2019":8,"2020":8,"2021":8,"21":8,"23":8,"29":8,"3":8,"30":8,"31":8,"4":8,"5":8,"6":8,"7":8,"8":8,"9":8,"new":8,account:9,administr:[8,9,12],api:2,authent:0,avail:8,bug:8,chang:8,close:8,configur:1,content:10,dashboard:9,deploy:11,detail:9,dev:11,develop:11,docker:11,document:2,email:11,endpoint:[2,13],environ:11,fail:12,featur:[8,9],first:8,fittracke:[8,10,12],fix:8,french:8,from:11,improv:8,instal:11,issu:8,list:9,log:8,map:11,minor:8,misc:8,prefer:9,prerequisit:11,prod:11,product:11,pull:8,pypi:[8,11],record:3,releas:8,request:8,server:11,sourc:11,sport:4,start:12,statist:[5,8,9],tabl:10,tile:11,translat:9,troubleshoot:13,unreleas:8,upgrad:11,user:[6,14],variabl:11,version:8,workout:[7,9]}}) \ No newline at end of file diff --git a/fittrackee/application/models.py b/fittrackee/application/models.py index ad3c6e95..c4d2cea8 100644 --- a/fittrackee/application/models.py +++ b/fittrackee/application/models.py @@ -1,6 +1,7 @@ from typing import Dict from flask import current_app +from sqlalchemy import exc from sqlalchemy.engine.base import Connection from sqlalchemy.event import listens_for from sqlalchemy.ext.declarative import DeclarativeMeta @@ -25,7 +26,15 @@ class AppConfig(BaseModel): @property def is_registration_enabled(self) -> bool: - nb_users = User.query.count() + try: + nb_users = User.query.count() + except exc.ProgrammingError as e: + # workaround for user model related migrations + if 'psycopg2.errors.UndefinedColumn' in str(e): + result = db.engine.execute("SELECT COUNT(*) FROM users;") + nb_users = result.fetchone()[0] + else: + raise e return self.max_users == 0 or nb_users < self.max_users @property diff --git a/fittrackee/migrations/versions/20_07188ca7620a_add_imperial_units_preferences.py b/fittrackee/migrations/versions/20_07188ca7620a_add_imperial_units_preferences.py new file mode 100644 index 00000000..f3f09963 --- /dev/null +++ b/fittrackee/migrations/versions/20_07188ca7620a_add_imperial_units_preferences.py @@ -0,0 +1,31 @@ +"""add imperial units preferences + +Revision ID: 07188ca7620a +Revises: 080acc8ee956 +Create Date: 2021-11-13 19:11:17.753567 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '07188ca7620a' +down_revision = '080acc8ee956' +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column( + 'users', + sa.Column('imperial_units', sa.Boolean(), nullable=True), + ) + op.execute("UPDATE users SET imperial_units = false") + op.alter_column('users', 'imperial_units', nullable=False) + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('users', 'imperial_units') + # ### end Alembic commands ### diff --git a/fittrackee/tests/users/test_auth_api.py b/fittrackee/tests/users/test_auth_api.py index 7fc87366..ca3e8437 100644 --- a/fittrackee/tests/users/test_auth_api.py +++ b/fittrackee/tests/users/test_auth_api.py @@ -487,6 +487,7 @@ class TestUserProfile(ApiTestCaseMixin): 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 @@ -517,6 +518,7 @@ class TestUserProfile(ApiTestCaseMixin): 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 @@ -553,6 +555,7 @@ class TestUserProfile(ApiTestCaseMixin): 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']) == 6 @@ -605,6 +608,7 @@ class TestUserProfileUpdate(ApiTestCaseMixin): assert data['data']['last_name'] == 'Doe' assert data['data']['birth_date'] assert data['data']['bio'] == 'Nothing to tell' + assert data['data']['imperial_units'] is False assert data['data']['location'] == 'Somewhere' assert data['data']['timezone'] is None assert data['data']['weekm'] is False @@ -648,6 +652,7 @@ class TestUserProfileUpdate(ApiTestCaseMixin): assert data['data']['last_name'] == 'Doe' assert data['data']['birth_date'] assert data['data']['bio'] == 'Nothing to tell' + assert data['data']['imperial_units'] is False assert data['data']['location'] == 'Somewhere' assert data['data']['timezone'] is None assert data['data']['weekm'] is False @@ -767,6 +772,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin): timezone='America/New_York', weekm=True, language='fr', + imperial_units=True, ) ), headers=dict(Authorization=f'Bearer {auth_token}'), @@ -784,6 +790,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin): 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 diff --git a/fittrackee/tests/users/test_users_api.py b/fittrackee/tests/users/test_users_api.py index 138a6705..371296de 100644 --- a/fittrackee/tests/users/test_users_api.py +++ b/fittrackee/tests/users/test_users_api.py @@ -36,6 +36,7 @@ class TestGetUser(ApiTestCaseMixin): assert user['last_name'] is None assert user['birth_date'] is None assert user['bio'] is None + assert user['imperial_units'] is False assert user['location'] is None assert user['timezone'] is None assert user['weekm'] is False @@ -77,6 +78,7 @@ class TestGetUser(ApiTestCaseMixin): assert user['last_name'] is None assert user['birth_date'] is None assert user['bio'] is None + assert user['imperial_units'] is False assert user['location'] is None assert user['timezone'] is None assert user['weekm'] is False @@ -129,6 +131,7 @@ class TestGetUsers(ApiTestCaseMixin): assert 'test@test.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]['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 @@ -138,6 +141,7 @@ class TestGetUsers(ApiTestCaseMixin): 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]['imperial_units'] is False assert data['data']['users'][1]['timezone'] is None assert data['data']['users'][1]['weekm'] is False assert data['data']['users'][1]['language'] is None @@ -147,6 +151,7 @@ class TestGetUsers(ApiTestCaseMixin): 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]['imperial_units'] is False assert data['data']['users'][2]['timezone'] is None assert data['data']['users'][2]['weekm'] is True assert data['data']['users'][2]['language'] is None @@ -196,6 +201,7 @@ class TestGetUsers(ApiTestCaseMixin): assert 'test@test.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]['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 @@ -204,6 +210,7 @@ class TestGetUsers(ApiTestCaseMixin): 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]['imperial_units'] is False assert data['data']['users'][1]['timezone'] is None assert data['data']['users'][1]['weekm'] is False assert data['data']['users'][1]['nb_sports'] == 1 @@ -212,6 +219,7 @@ class TestGetUsers(ApiTestCaseMixin): 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]['imperial_units'] is False assert data['data']['users'][2]['timezone'] is None assert data['data']['users'][2]['weekm'] is True assert data['data']['users'][2]['nb_sports'] == 0 diff --git a/fittrackee/tests/users/test_users_model.py b/fittrackee/tests/users/test_users_model.py index fdb01560..129c7866 100644 --- a/fittrackee/tests/users/test_users_model.py +++ b/fittrackee/tests/users/test_users_model.py @@ -14,6 +14,7 @@ class TestUserModel: assert serialized_user['admin'] is False assert serialized_user['first_name'] is None assert serialized_user['last_name'] is None + assert serialized_user['imperial_units'] is False assert serialized_user['bio'] is None assert serialized_user['location'] is None assert serialized_user['birth_date'] is None diff --git a/fittrackee/users/auth.py b/fittrackee/users/auth.py index 54dfafa8..e55b6871 100644 --- a/fittrackee/users/auth.py +++ b/fittrackee/users/auth.py @@ -313,6 +313,7 @@ def get_authenticated_user_profile( "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "sam@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -412,6 +413,7 @@ def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]: "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "sam@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -574,6 +576,7 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]: "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "sam@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -653,6 +656,7 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]: # get post data post_data = request.get_json() user_mandatory_data = { + 'imperial_units', 'language', 'timezone', 'weekm', @@ -660,12 +664,14 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]: if not post_data or not post_data.keys() >= user_mandatory_data: return InvalidPayloadErrorResponse() + imperial_units = post_data.get('imperial_units') language = post_data.get('language') timezone = post_data.get('timezone') weekm = post_data.get('weekm') try: user = User.query.filter_by(id=auth_user_id).first() + user.imperial_units = imperial_units user.language = language user.timezone = timezone user.weekm = weekm diff --git a/fittrackee/users/models.py b/fittrackee/users/models.py index 1f640344..9d07c5ff 100644 --- a/fittrackee/users/models.py +++ b/fittrackee/users/models.py @@ -40,6 +40,7 @@ class User(BaseModel): 'Record', lazy=True, backref=db.backref('user', lazy='joined') ) language = db.Column(db.String(50), nullable=True) + imperial_units = db.Column(db.Boolean, default=False, nullable=False) def __repr__(self) -> str: return f'' @@ -142,6 +143,7 @@ class User(BaseModel): ], 'total_distance': float(total[0]), 'total_duration': str(total[1]), + 'imperial_units': self.imperial_units, } diff --git a/fittrackee/users/users.py b/fittrackee/users/users.py index 390169d3..44faf458 100644 --- a/fittrackee/users/users.py +++ b/fittrackee/users/users.py @@ -64,6 +64,7 @@ def get_users(auth_user_id: int) -> Dict: "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "admin@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -246,6 +247,7 @@ def get_single_user( "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "admin@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null, @@ -400,6 +402,7 @@ def update_user( "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", "email": "admin@example.com", "first_name": null, + "imperial_units": false, "language": "en", "last_name": null, "location": null,