Merge branch 'dev' into oauth2
This commit is contained in:
@ -21,7 +21,7 @@ from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
from fittrackee.emails.email import EmailService
|
||||
from fittrackee.request import CustomRequest
|
||||
|
||||
VERSION = __version__ = '0.6.9'
|
||||
VERSION = __version__ = '0.6.10'
|
||||
db = SQLAlchemy()
|
||||
bcrypt = Bcrypt()
|
||||
migrate = Migrate()
|
||||
|
@ -48,7 +48,7 @@ def get_application_config() -> Union[Dict, HttpResponse]:
|
||||
"max_users": 0,
|
||||
"max_zip_file_size": 10485760,
|
||||
"map_attribution": "© <a href=http://www.openstreetmap.org/copyright>OpenStreetMap</a> contributors"
|
||||
"version": "0.6.9"
|
||||
"version": "0.6.10"
|
||||
},
|
||||
"status": "success"
|
||||
}
|
||||
@ -98,7 +98,7 @@ def update_application_config(auth_user: User) -> Union[Dict, HttpResponse]:
|
||||
"max_users": 10,
|
||||
"max_zip_file_size": 10485760,
|
||||
"map_attribution": "© <a href=http://www.openstreetmap.org/copyright>OpenStreetMap</a> contributors"
|
||||
"version": "0.6.9"
|
||||
"version": "0.6.10"
|
||||
},
|
||||
"status": "success"
|
||||
}
|
||||
|
@ -43,8 +43,9 @@ class BaseConfig:
|
||||
' contributors',
|
||||
),
|
||||
'DEFAULT_STATICMAP': (
|
||||
os.environ.get('DEFAULT_STATICMAP', 'False') == 'True'
|
||||
os.environ.get('DEFAULT_STATICMAP', 'false').lower() == 'true'
|
||||
),
|
||||
'STATICMAP_SUBDOMAINS': os.environ.get('STATICMAP_SUBDOMAINS', ''),
|
||||
}
|
||||
TRANSLATIONS_FOLDER = os.path.join(
|
||||
current_app.root_path, 'emails/translations'
|
||||
|
2
fittrackee/dist/index.html
vendored
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.7123d468.js"></script><script defer="defer" src="/static/js/app.51b2bdb0.js"></script><link href="/static/css/app.32d0ced1.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.7132edc6.js"></script><script defer="defer" src="/static/js/app.bf1d4e1c.js"></script><link href="/static/css/app.32d0ced1.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
vendored
File diff suppressed because one or more lines are too long
2
fittrackee/dist/service-worker.js.map
vendored
2
fittrackee/dist/service-worker.js.map
vendored
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
"use strict";(self["webpackChunkfittrackee_client"]=self["webpackChunkfittrackee_client"]||[]).push([[328],{6e3:function(t,e,i){i.r(e),i.d(e,{default:function(){return _}});var a=i(6252),n=i(2262),s=i(8273),c=i(8602),r=i(9917);const S=t=>((0,a.dD)("data-v-64629971"),t=t(),(0,a.Cn)(),t),l={id:"admin",class:"view"},p={key:0,class:"container"},u=S((()=>(0,a._)("div",{id:"bottom"},null,-1)));var T=(0,a.aZ)({__name:"AdminView",setup(t){const e=(0,r.o)(),i=(0,a.Fl)((()=>e.getters[c.SY.GETTERS.APP_CONFIG])),S=(0,a.Fl)((()=>e.getters[c.SY.GETTERS.APP_STATS])),T=(0,a.Fl)((()=>e.getters[c.YN.GETTERS.IS_ADMIN])),d=(0,a.Fl)((()=>e.getters[c.YN.GETTERS.USER_LOADING]));return(0,a.wF)((()=>e.dispatch(c.SY.ACTIONS.GET_APPLICATION_STATS))),(t,e)=>{const c=(0,a.up)("router-view");return(0,a.wg)(),(0,a.iD)("div",l,[(0,n.SU)(d)?(0,a.kq)("",!0):((0,a.wg)(),(0,a.iD)("div",p,[(0,n.SU)(T)?((0,a.wg)(),(0,a.j4)(c,{key:0,appConfig:(0,n.SU)(i),appStatistics:(0,n.SU)(S)},null,8,["appConfig","appStatistics"])):((0,a.wg)(),(0,a.j4)(s.Z,{key:1})),u]))])}}}),d=i(3744);const o=(0,d.Z)(T,[["__scopeId","data-v-64629971"]]);var _=o}}]);
|
||||
//# sourceMappingURL=admin.d8f63f79.js.map
|
||||
//# sourceMappingURL=admin.b19d15cc.js.map
|
1
fittrackee/dist/static/js/admin.b19d15cc.js.map
vendored
Normal file
1
fittrackee/dist/static/js/admin.b19d15cc.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/js/admin.b19d15cc.js","mappings":"mOAGA,MAAMA,EAAeC,KAAMC,EAAAA,EAAAA,IAAa,mBAAmBD,EAAEA,KAAIE,EAAAA,EAAAA,MAAcF,GACzEG,EAAa,CACjBC,GAAI,QACJC,MAAO,QAEHC,EAAa,CACjBC,IAAK,EACLF,MAAO,aAEHG,EAA2BT,GAAa,KAAmBU,EAAAA,EAAAA,GAAoB,MAAO,CAAEL,GAAI,UAAY,MAAO,KAUrH,OAA4BM,EAAAA,EAAAA,IAAiB,CAC3CC,OAAQ,YACRC,MAAMC,GAEN,MAAMC,GAAQC,EAAAA,EAAAA,KAERC,GAAqCC,EAAAA,EAAAA,KACzC,IAAMH,EAAMI,QAAQC,EAAAA,GAAAA,QAAAA,cAEhBC,GAA6CH,EAAAA,EAAAA,KACjD,IAAMH,EAAMI,QAAQC,EAAAA,GAAAA,QAAAA,aAEhBE,GAAuCJ,EAAAA,EAAAA,KAC3C,IAAMH,EAAMI,QAAQI,EAAAA,GAAAA,QAAAA,YAEhBC,GAAoCN,EAAAA,EAAAA,KACxC,IAAMH,EAAMI,QAAQI,EAAAA,GAAAA,QAAAA,gBAKxB,OAFEE,EAAAA,EAAAA,KAAc,IAAMV,EAAMW,SAASN,EAAAA,GAAAA,QAAAA,yBAE9B,CAACO,EAAUC,KAChB,MAAMC,GAAyBC,EAAAA,EAAAA,IAAkB,eAEjD,OAAQC,EAAAA,EAAAA,OAAcC,EAAAA,EAAAA,IAAoB,MAAO5B,EAAY,EACzD6B,EAAAA,EAAAA,IAAOT,IAWLU,EAAAA,EAAAA,IAAoB,IAAI,KAVvBH,EAAAA,EAAAA,OAAcC,EAAAA,EAAAA,IAAoB,MAAOzB,EAAY,EACnD0B,EAAAA,EAAAA,IAAOX,KACHS,EAAAA,EAAAA,OAAcI,EAAAA,EAAAA,IAAaN,EAAwB,CAClDrB,IAAK,EACLS,WAAWgB,EAAAA,EAAAA,IAAOhB,GAClBI,eAAeY,EAAAA,EAAAA,IAAOZ,IACrB,KAAM,EAAG,CAAC,YAAa,qBACzBU,EAAAA,EAAAA,OAAcI,EAAAA,EAAAA,IAAaC,EAAAA,EAAU,CAAE5B,IAAK,KACjDC,W,UClDV,MAAM4B,GAA2B,OAAgB,EAAQ,CAAC,CAAC,YAAY,qBAEvE","sources":["webpack://fittrackee_client/./src/views/AdminView.vue?67de","webpack://fittrackee_client/./src/views/AdminView.vue"],"sourcesContent":["import { defineComponent as _defineComponent } from 'vue'\nimport { unref as _unref, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createElementVNode as _createElementVNode, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-64629971\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = {\n id: \"admin\",\n class: \"view\"\n}\nconst _hoisted_2 = {\n key: 0,\n class: \"container\"\n}\nconst _hoisted_3 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode(\"div\", { id: \"bottom\" }, null, -1))\n\nimport { computed, ComputedRef, onBeforeMount } from 'vue'\n\n import NotFound from '@/components/Common/NotFound.vue'\n import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'\n import { TAppConfig, IAppStatistics } from '@/types/application'\n import { useStore } from '@/use/useStore'\n\n \nexport default /*#__PURE__*/_defineComponent({\n __name: 'AdminView',\n setup(__props) {\n\n const store = useStore()\n\n const appConfig: ComputedRef<TAppConfig> = computed(\n () => store.getters[ROOT_STORE.GETTERS.APP_CONFIG]\n )\n const appStatistics: ComputedRef<IAppStatistics> = computed(\n () => store.getters[ROOT_STORE.GETTERS.APP_STATS]\n )\n const isAuthUserAmin: ComputedRef<boolean> = computed(\n () => store.getters[AUTH_USER_STORE.GETTERS.IS_ADMIN]\n )\n const userLoading: ComputedRef<boolean> = computed(\n () => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]\n )\n\n onBeforeMount(() => store.dispatch(ROOT_STORE.ACTIONS.GET_APPLICATION_STATS))\n\nreturn (_ctx: any,_cache: any) => {\n const _component_router_view = _resolveComponent(\"router-view\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (!_unref(userLoading))\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_2, [\n (_unref(isAuthUserAmin))\n ? (_openBlock(), _createBlock(_component_router_view, {\n key: 0,\n appConfig: _unref(appConfig),\n appStatistics: _unref(appStatistics)\n }, null, 8, [\"appConfig\", \"appStatistics\"]))\n : (_openBlock(), _createBlock(NotFound, { key: 1 })),\n _hoisted_3\n ]))\n : _createCommentVNode(\"\", true)\n ]))\n}\n}\n\n})","import script from \"./AdminView.vue?vue&type=script&setup=true&lang=ts\"\nexport * from \"./AdminView.vue?vue&type=script&setup=true&lang=ts\"\n\nimport \"./AdminView.vue?vue&type=style&index=0&id=64629971&lang=scss&scoped=true\"\n\nimport exportComponent from \"/mnt/data-lnx/Devs/00_Perso/FitTrackee/fittrackee_client/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['__scopeId',\"data-v-64629971\"]])\n\nexport default __exports__"],"names":["_withScopeId","n","_pushScopeId","_popScopeId","_hoisted_1","id","class","_hoisted_2","key","_hoisted_3","_createElementVNode","_defineComponent","__name","setup","__props","store","useStore","appConfig","computed","getters","ROOT_STORE","appStatistics","isAuthUserAmin","AUTH_USER_STORE","userLoading","onBeforeMount","dispatch","_ctx","_cache","_component_router_view","_resolveComponent","_openBlock","_createElementBlock","_unref","_createCommentVNode","_createBlock","NotFound","__exports__"],"sourceRoot":""}
|
@ -1 +0,0 @@
|
||||
{"version":3,"file":"static/js/admin.d8f63f79.js","mappings":"mOAGA,MAAMA,EAAeC,KAAMC,EAAAA,EAAAA,IAAa,mBAAmBD,EAAEA,KAAIE,EAAAA,EAAAA,MAAcF,GACzEG,EAAa,CACjBC,GAAI,QACJC,MAAO,QAEHC,EAAa,CACjBC,IAAK,EACLF,MAAO,aAEHG,EAA2BT,GAAa,KAAmBU,EAAAA,EAAAA,GAAoB,MAAO,CAAEL,GAAI,UAAY,MAAO,KAUrH,OAA4BM,EAAAA,EAAAA,IAAiB,CAC3CC,OAAQ,YACRC,MAAMC,GAEN,MAAMC,GAAQC,EAAAA,EAAAA,KAERC,GAAqCC,EAAAA,EAAAA,KACzC,IAAMH,EAAMI,QAAQC,EAAAA,GAAAA,QAAAA,cAEhBC,GAA6CH,EAAAA,EAAAA,KACjD,IAAMH,EAAMI,QAAQC,EAAAA,GAAAA,QAAAA,aAEhBE,GAAuCJ,EAAAA,EAAAA,KAC3C,IAAMH,EAAMI,QAAQI,EAAAA,GAAAA,QAAAA,YAEhBC,GAAoCN,EAAAA,EAAAA,KACxC,IAAMH,EAAMI,QAAQI,EAAAA,GAAAA,QAAAA,gBAKxB,OAFEE,EAAAA,EAAAA,KAAc,IAAMV,EAAMW,SAASN,EAAAA,GAAAA,QAAAA,yBAE9B,CAACO,EAAUC,KAChB,MAAMC,GAAyBC,EAAAA,EAAAA,IAAkB,eAEjD,OAAQC,EAAAA,EAAAA,OAAcC,EAAAA,EAAAA,IAAoB,MAAO5B,EAAY,EACzD6B,EAAAA,EAAAA,IAAOT,IAWLU,EAAAA,EAAAA,IAAoB,IAAI,KAVvBH,EAAAA,EAAAA,OAAcC,EAAAA,EAAAA,IAAoB,MAAOzB,EAAY,EACnD0B,EAAAA,EAAAA,IAAOX,KACHS,EAAAA,EAAAA,OAAcI,EAAAA,EAAAA,IAAaN,EAAwB,CAClDrB,IAAK,EACLS,WAAWgB,EAAAA,EAAAA,IAAOhB,GAClBI,eAAeY,EAAAA,EAAAA,IAAOZ,IACrB,KAAM,EAAG,CAAC,YAAa,qBACzBU,EAAAA,EAAAA,OAAcI,EAAAA,EAAAA,IAAaC,EAAAA,EAAU,CAAE5B,IAAK,KACjDC,W,UClDV,MAAM4B,GAA2B,OAAgB,EAAQ,CAAC,CAAC,YAAY,qBAEvE","sources":["webpack://fittrackee_client/./node_modules/vue-loader/dist/index.js","webpack://fittrackee_client/./src/views/AdminView.vue"],"sourcesContent":["import { defineComponent as _defineComponent } from 'vue'\nimport { unref as _unref, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createElementVNode as _createElementVNode, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-64629971\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = {\n id: \"admin\",\n class: \"view\"\n}\nconst _hoisted_2 = {\n key: 0,\n class: \"container\"\n}\nconst _hoisted_3 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode(\"div\", { id: \"bottom\" }, null, -1))\n\nimport { computed, ComputedRef, onBeforeMount } from 'vue'\n\n import NotFound from '@/components/Common/NotFound.vue'\n import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'\n import { TAppConfig, IAppStatistics } from '@/types/application'\n import { useStore } from '@/use/useStore'\n\n \nexport default /*#__PURE__*/_defineComponent({\n __name: 'AdminView',\n setup(__props) {\n\n const store = useStore()\n\n const appConfig: ComputedRef<TAppConfig> = computed(\n () => store.getters[ROOT_STORE.GETTERS.APP_CONFIG]\n )\n const appStatistics: ComputedRef<IAppStatistics> = computed(\n () => store.getters[ROOT_STORE.GETTERS.APP_STATS]\n )\n const isAuthUserAmin: ComputedRef<boolean> = computed(\n () => store.getters[AUTH_USER_STORE.GETTERS.IS_ADMIN]\n )\n const userLoading: ComputedRef<boolean> = computed(\n () => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]\n )\n\n onBeforeMount(() => store.dispatch(ROOT_STORE.ACTIONS.GET_APPLICATION_STATS))\n\nreturn (_ctx: any,_cache: any) => {\n const _component_router_view = _resolveComponent(\"router-view\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (!_unref(userLoading))\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_2, [\n (_unref(isAuthUserAmin))\n ? (_openBlock(), _createBlock(_component_router_view, {\n key: 0,\n appConfig: _unref(appConfig),\n appStatistics: _unref(appStatistics)\n }, null, 8, [\"appConfig\", \"appStatistics\"]))\n : (_openBlock(), _createBlock(NotFound, { key: 1 })),\n _hoisted_3\n ]))\n : _createCommentVNode(\"\", true)\n ]))\n}\n}\n\n})","import script from \"./AdminView.vue?vue&type=script&setup=true&lang=ts\"\nexport * from \"./AdminView.vue?vue&type=script&setup=true&lang=ts\"\n\nimport \"./AdminView.vue?vue&type=style&index=0&id=64629971&lang=scss&scoped=true\"\n\nimport exportComponent from \"/mnt/data-lnx/Devs/00_Perso/FitTrackee/fittrackee_client/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['__scopeId',\"data-v-64629971\"]])\n\nexport default __exports__"],"names":["_withScopeId","n","_pushScopeId","_popScopeId","_hoisted_1","id","class","_hoisted_2","key","_hoisted_3","_createElementVNode","_defineComponent","__name","setup","__props","store","useStore","appConfig","computed","getters","ROOT_STORE","appStatistics","isAuthUserAmin","AUTH_USER_STORE","userLoading","onBeforeMount","dispatch","_ctx","_cache","_component_router_view","_resolveComponent","_openBlock","_createElementBlock","_unref","_createCommentVNode","_createBlock","NotFound","__exports__"],"sourceRoot":""}
|
2
fittrackee/dist/static/js/app.51b2bdb0.js
vendored
2
fittrackee/dist/static/js/app.51b2bdb0.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
fittrackee/dist/static/js/app.bf1d4e1c.js
vendored
Normal file
2
fittrackee/dist/static/js/app.bf1d4e1c.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
fittrackee/dist/static/js/app.bf1d4e1c.js.map
vendored
Normal file
1
fittrackee/dist/static/js/app.bf1d4e1c.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
fittrackee/dist/static/js/chunk-vendors.7132edc6.js.map
vendored
Normal file
1
fittrackee/dist/static/js/chunk-vendors.7132edc6.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
"use strict";(self["webpackChunkfittrackee_client"]=self["webpackChunkfittrackee_client"]||[]).push([[845],{4264:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});var n=r(6252),a=r(2262),s=r(3577),u=r(2119),o=r(7167),i=r(8602),c=r(9917);const l={key:0,id:"account-confirmation",class:"center-card with-margin"},E={class:"error-message"};var _=(0,n.aZ)({__name:"AccountConfirmationView",setup(e){const t=(0,u.yj)(),r=(0,u.tv)(),_=(0,c.o)(),d=(0,n.Fl)((()=>_.getters[i.SY.GETTERS.ERROR_MESSAGES])),S=(0,n.Fl)((()=>t.query.token));function m(){S.value?_.dispatch(i.YN.ACTIONS.CONFIRM_ACCOUNT,{token:S.value}):r.push("/")}return(0,n.wF)((()=>m())),(0,n.Ah)((()=>_.commit(i.SY.MUTATIONS.EMPTY_ERROR_MESSAGES))),(e,t)=>{const r=(0,n.up)("router-link");return(0,a.SU)(d)?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(o.Z),(0,n._)("p",E,[(0,n._)("span",null,(0,s.zw)(e.$t("error.SOMETHING_WRONG"))+".",1),(0,n.Wm)(r,{class:"links",to:"/account-confirmation/resend"},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.$t("buttons.ACCOUNT-CONFIRMATION-RESEND"))+"? ",1)])),_:1})])])):(0,n.kq)("",!0)}}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-785df978"]]);var m=S},8160:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});var n=r(6252),a=r(2262),s=r(3577),u=r(2119),o=r(7167),i=r(8602),c=r(9917);const l={key:0,id:"email-update",class:"center-card with-margin"},E={class:"error-message"};var _=(0,n.aZ)({__name:"EmailUpdateView",setup(e){const t=(0,u.yj)(),r=(0,u.tv)(),_=(0,c.o)(),d=(0,n.Fl)((()=>_.getters[i.YN.GETTERS.AUTH_USER_PROFILE])),S=(0,n.Fl)((()=>_.getters[i.YN.GETTERS.IS_AUTHENTICATED])),m=(0,n.Fl)((()=>_.getters[i.SY.GETTERS.ERROR_MESSAGES])),p=(0,n.Fl)((()=>t.query.token));function R(){p.value?_.dispatch(i.YN.ACTIONS.CONFIRM_EMAIL,{token:p.value,refreshUser:S.value}):r.push("/")}return(0,n.wF)((()=>R())),(0,n.Ah)((()=>_.commit(i.SY.MUTATIONS.EMPTY_ERROR_MESSAGES))),(0,n.YP)((()=>m.value),(e=>{d.value.username&&e&&r.push("/")})),(e,t)=>{const r=(0,n.up)("router-link"),u=(0,n.up)("i18n-t");return(0,a.SU)(m)&&!(0,a.SU)(d).username?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(o.Z),(0,n._)("p",E,[(0,n._)("span",null,(0,s.zw)(e.$t("error.SOMETHING_WRONG"))+".",1),(0,n._)("span",null,[(0,n.Wm)(u,{keypath:"user.PROFILE.ERRORED_EMAIL_UPDATE"},{default:(0,n.w5)((()=>[(0,n.Wm)(r,{to:"/login"},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.$t("user.LOG_IN")),1)])),_:1})])),_:1})])])])):(0,n.kq)("",!0)}}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-8c2ec9ce"]]);var m=S},6266:function(e,t,r){r.r(t),r.d(t,{default:function(){return d}});var n=r(6252),a=r(2262),s=r(8602),u=r(9917);const o=e=>((0,n.dD)("data-v-05463732"),e=e(),(0,n.Cn)(),e),i={key:0,id:"profile",class:"container view"},c=o((()=>(0,n._)("div",{id:"bottom"},null,-1)));var l=(0,n.aZ)({__name:"ProfileView",setup(e){const t=(0,u.o)(),r=(0,n.Fl)((()=>t.getters[s.YN.GETTERS.AUTH_USER_PROFILE]));return(e,t)=>{const s=(0,n.up)("router-view");return(0,a.SU)(r).username?((0,n.wg)(),(0,n.iD)("div",i,[(0,n.Wm)(s,{user:(0,a.SU)(r)},null,8,["user"]),c])):(0,n.kq)("",!0)}}}),E=r(3744);const _=(0,E.Z)(l,[["__scopeId","data-v-05463732"]]);var d=_},9453:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});var n=r(6252),a=r(2262),s=r(2119),u=r(2179),o=r(7408),i=r(8602),c=r(9917);const l={key:0,id:"user",class:"view"},E={class:"box"};var _=(0,n.aZ)({__name:"UserView",props:{fromAdmin:{type:Boolean}},setup(e){const t=e,{fromAdmin:r}=(0,a.BK)(t),_=(0,s.yj)(),d=(0,c.o)(),S=(0,n.Fl)((()=>d.getters[i.RT.GETTERS.USER]));return(0,n.wF)((()=>{_.params.username&&"string"===typeof _.params.username&&d.dispatch(i.RT.ACTIONS.GET_USER,_.params.username)})),(0,n.Jd)((()=>{d.dispatch(i.RT.ACTIONS.EMPTY_USER)})),(e,t)=>(0,a.SU)(S).username?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(u.Z,{user:(0,a.SU)(S)},null,8,["user"]),(0,n._)("div",E,[(0,n.Wm)(o.Z,{user:(0,a.SU)(S),"from-admin":(0,a.SU)(r)},null,8,["user","from-admin"])])])):(0,n.kq)("",!0)}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-af7007f4"]]);var m=S}}]);
|
||||
//# sourceMappingURL=profile.cc6add96.js.map
|
||||
"use strict";(self["webpackChunkfittrackee_client"]=self["webpackChunkfittrackee_client"]||[]).push([[845],{4264:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});var n=r(6252),a=r(2262),s=r(3577),u=r(2201),o=r(7167),i=r(8602),c=r(9917);const l={key:0,id:"account-confirmation",class:"center-card with-margin"},E={class:"error-message"};var _=(0,n.aZ)({__name:"AccountConfirmationView",setup(e){const t=(0,u.yj)(),r=(0,u.tv)(),_=(0,c.o)(),d=(0,n.Fl)((()=>_.getters[i.SY.GETTERS.ERROR_MESSAGES])),S=(0,n.Fl)((()=>t.query.token));function m(){S.value?_.dispatch(i.YN.ACTIONS.CONFIRM_ACCOUNT,{token:S.value}):r.push("/")}return(0,n.wF)((()=>m())),(0,n.Ah)((()=>_.commit(i.SY.MUTATIONS.EMPTY_ERROR_MESSAGES))),(e,t)=>{const r=(0,n.up)("router-link");return(0,a.SU)(d)?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(o.Z),(0,n._)("p",E,[(0,n._)("span",null,(0,s.zw)(e.$t("error.SOMETHING_WRONG"))+".",1),(0,n.Wm)(r,{class:"links",to:"/account-confirmation/resend"},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.$t("buttons.ACCOUNT-CONFIRMATION-RESEND"))+"? ",1)])),_:1})])])):(0,n.kq)("",!0)}}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-785df978"]]);var m=S},8160:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});var n=r(6252),a=r(2262),s=r(3577),u=r(2201),o=r(7167),i=r(8602),c=r(9917);const l={key:0,id:"email-update",class:"center-card with-margin"},E={class:"error-message"};var _=(0,n.aZ)({__name:"EmailUpdateView",setup(e){const t=(0,u.yj)(),r=(0,u.tv)(),_=(0,c.o)(),d=(0,n.Fl)((()=>_.getters[i.YN.GETTERS.AUTH_USER_PROFILE])),S=(0,n.Fl)((()=>_.getters[i.YN.GETTERS.IS_AUTHENTICATED])),m=(0,n.Fl)((()=>_.getters[i.SY.GETTERS.ERROR_MESSAGES])),p=(0,n.Fl)((()=>t.query.token));function R(){p.value?_.dispatch(i.YN.ACTIONS.CONFIRM_EMAIL,{token:p.value,refreshUser:S.value}):r.push("/")}return(0,n.wF)((()=>R())),(0,n.Ah)((()=>_.commit(i.SY.MUTATIONS.EMPTY_ERROR_MESSAGES))),(0,n.YP)((()=>m.value),(e=>{d.value.username&&e&&r.push("/")})),(e,t)=>{const r=(0,n.up)("router-link"),u=(0,n.up)("i18n-t");return(0,a.SU)(m)&&!(0,a.SU)(d).username?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(o.Z),(0,n._)("p",E,[(0,n._)("span",null,(0,s.zw)(e.$t("error.SOMETHING_WRONG"))+".",1),(0,n._)("span",null,[(0,n.Wm)(u,{keypath:"user.PROFILE.ERRORED_EMAIL_UPDATE"},{default:(0,n.w5)((()=>[(0,n.Wm)(r,{to:"/login"},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.$t("user.LOG_IN")),1)])),_:1})])),_:1})])])])):(0,n.kq)("",!0)}}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-8c2ec9ce"]]);var m=S},6266:function(e,t,r){r.r(t),r.d(t,{default:function(){return d}});var n=r(6252),a=r(2262),s=r(8602),u=r(9917);const o=e=>((0,n.dD)("data-v-05463732"),e=e(),(0,n.Cn)(),e),i={key:0,id:"profile",class:"container view"},c=o((()=>(0,n._)("div",{id:"bottom"},null,-1)));var l=(0,n.aZ)({__name:"ProfileView",setup(e){const t=(0,u.o)(),r=(0,n.Fl)((()=>t.getters[s.YN.GETTERS.AUTH_USER_PROFILE]));return(e,t)=>{const s=(0,n.up)("router-view");return(0,a.SU)(r).username?((0,n.wg)(),(0,n.iD)("div",i,[(0,n.Wm)(s,{user:(0,a.SU)(r)},null,8,["user"]),c])):(0,n.kq)("",!0)}}}),E=r(3744);const _=(0,E.Z)(l,[["__scopeId","data-v-05463732"]]);var d=_},9453:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});var n=r(6252),a=r(2262),s=r(2201),u=r(2179),o=r(7408),i=r(8602),c=r(9917);const l={key:0,id:"user",class:"view"},E={class:"box"};var _=(0,n.aZ)({__name:"UserView",props:{fromAdmin:{type:Boolean}},setup(e){const t=e,{fromAdmin:r}=(0,a.BK)(t),_=(0,s.yj)(),d=(0,c.o)(),S=(0,n.Fl)((()=>d.getters[i.RT.GETTERS.USER]));return(0,n.wF)((()=>{_.params.username&&"string"===typeof _.params.username&&d.dispatch(i.RT.ACTIONS.GET_USER,_.params.username)})),(0,n.Jd)((()=>{d.dispatch(i.RT.ACTIONS.EMPTY_USER)})),(e,t)=>(0,a.SU)(S).username?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(u.Z,{user:(0,a.SU)(S)},null,8,["user"]),(0,n._)("div",E,[(0,n.Wm)(o.Z,{user:(0,a.SU)(S),"from-admin":(0,a.SU)(r)},null,8,["user","from-admin"])])])):(0,n.kq)("",!0)}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-af7007f4"]]);var m=S}}]);
|
||||
//# sourceMappingURL=profile.12bdb140.js.map
|
1
fittrackee/dist/static/js/profile.12bdb140.js.map
vendored
Normal file
1
fittrackee/dist/static/js/profile.12bdb140.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
fittrackee/dist/static/js/reset.90b2d965.js.map
vendored
Normal file
1
fittrackee/dist/static/js/reset.90b2d965.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
"use strict";(self["webpackChunkfittrackee_client"]=self["webpackChunkfittrackee_client"]||[]).push([[193],{9161:function(e,s,t){t.r(s),t.d(s,{default:function(){return A}});t(6699);var a=t(6252),r=t(2262),l=t(3577),o=t(3324),n=t(9996);const c={class:"chart-menu"},i={class:"chart-arrow"},u={class:"time-frames custom-checkboxes-group"},d={class:"time-frames-checkboxes custom-checkboxes"},p=["id","name","checked","onInput"],m={class:"chart-arrow"};var v=(0,a.aZ)({__name:"StatsMenu",emits:["arrowClick","timeFrameUpdate"],setup(e,{emit:s}){const t=(0,r.iH)("month"),o=["week","month","year"];function n(e){t.value=e,s("timeFrameUpdate",e)}return(e,r)=>((0,a.wg)(),(0,a.iD)("div",c,[(0,a._)("div",i,[(0,a._)("i",{class:"fa fa-chevron-left","aria-hidden":"true",onClick:r[0]||(r[0]=e=>s("arrowClick",!0))})]),(0,a._)("div",u,[(0,a._)("div",d,[((0,a.wg)(),(0,a.iD)(a.HY,null,(0,a.Ko)(o,(s=>(0,a._)("div",{class:"time-frame custom-checkbox",key:s},[(0,a._)("label",null,[(0,a._)("input",{type:"radio",id:s,name:s,checked:t.value===s,onInput:e=>n(s)},null,40,p),(0,a._)("span",null,(0,l.zw)(e.$t(`statistics.TIME_FRAMES.${s}`)),1)])]))),64))])]),(0,a._)("div",m,[(0,a._)("i",{class:"fa fa-chevron-right","aria-hidden":"true",onClick:r[1]||(r[1]=e=>s("arrowClick",!1))})])]))}}),k=t(3744);const _=(0,k.Z)(v,[["__scopeId","data-v-22d55de2"]]);var S=_,w=t(631);const f={class:"sports-menu"},h=["id","name","checked","onInput"],U={class:"sport-label"};var b=(0,a.aZ)({__name:"StatsSportsMenu",props:{userSports:null,selectedSportIds:{default:()=>[]}},emits:["selectedSportIdsUpdate"],setup(e,{emit:s}){const t=e,{t:n}=(0,o.QT)(),c=(0,a.f3)("sportColors"),{selectedSportIds:i}=(0,r.BK)(t),u=(0,a.Fl)((()=>(0,w.xH)(t.userSports,n)));function d(e){s("selectedSportIdsUpdate",e)}return(e,s)=>{const t=(0,a.up)("SportImage");return(0,a.wg)(),(0,a.iD)("div",f,[((0,a.wg)(!0),(0,a.iD)(a.HY,null,(0,a.Ko)((0,r.SU)(u),(e=>((0,a.wg)(),(0,a.iD)("label",{type:"checkbox",key:e.id,style:(0,l.j5)({color:e.color?e.color:(0,r.SU)(c)[e.label]})},[(0,a._)("input",{type:"checkbox",id:e.id,name:e.label,checked:(0,r.SU)(i).includes(e.id),onInput:s=>d(e.id)},null,40,h),(0,a.Wm)(t,{"sport-label":e.label,color:e.color},null,8,["sport-label","color"]),(0,a._)("span",U,(0,l.zw)(e.translatedLabel),1)],4)))),128))])}}});const I=b;var g=I,T=t(9318);const y={key:0,id:"user-statistics"};var C=(0,a.aZ)({__name:"index",props:{sports:null,user:null},setup(e){const s=e,{t:t}=(0,o.QT)(),{sports:l,user:c}=(0,r.BK)(s),i=(0,r.iH)("month"),u=(0,r.iH)(v(i.value)),d=(0,a.Fl)((()=>(0,w.xH)(s.sports,t))),p=(0,r.iH)(_(s.sports));function m(e){i.value=e,u.value=v(i.value)}function v(e){return(0,T.aZ)(new Date,e,s.user.weekm)}function k(e){u.value=(0,T.FN)(u.value,e,s.user.weekm)}function _(e){return e.map((e=>e.id))}function f(e){p.value.includes(e)?p.value=p.value.filter((s=>s!==e)):p.value.push(e)}return(0,a.YP)((()=>s.sports),(e=>{p.value=_(e)})),(e,s)=>(0,r.SU)(d)?((0,a.wg)(),(0,a.iD)("div",y,[(0,a.Wm)(S,{onTimeFrameUpdate:m,onArrowClick:k}),(0,a.Wm)(n.Z,{sports:(0,r.SU)(l),user:(0,r.SU)(c),chartParams:u.value,"displayed-sport-ids":p.value,fullStats:!0},null,8,["sports","user","chartParams","displayed-sport-ids"]),(0,a.Wm)(g,{"selected-sport-ids":p.value,"user-sports":(0,r.SU)(l),onSelectedSportIdsUpdate:f},null,8,["selected-sport-ids","user-sports"])])):(0,a.kq)("",!0)}});const F=(0,k.Z)(C,[["__scopeId","data-v-d693c7da"]]);var Z=F,x=t(5630),D=t(8602),H=t(9917);const E={id:"statistics",class:"view"},R={key:0,class:"container"};var W=(0,a.aZ)({__name:"StatisticsView",setup(e){const s=(0,H.o)(),t=(0,a.Fl)((()=>s.getters[D.YN.GETTERS.AUTH_USER_PROFILE])),o=(0,a.Fl)((()=>s.getters[D.O8.GETTERS.SPORTS].filter((e=>t.value.sports_list.includes(e.id)))));return(e,s)=>{const n=(0,a.up)("Card");return(0,a.wg)(),(0,a.iD)("div",E,[(0,r.SU)(t).username?((0,a.wg)(),(0,a.iD)("div",R,[(0,a.Wm)(n,null,{title:(0,a.w5)((()=>[(0,a.Uk)((0,l.zw)(e.$t("statistics.STATISTICS")),1)])),content:(0,a.w5)((()=>[(0,a.Wm)(Z,{class:(0,l.C_)({"stats-disabled":0===(0,r.SU)(t).nb_workouts}),user:(0,r.SU)(t),sports:(0,r.SU)(o)},null,8,["class","user","sports"])])),_:1}),0===(0,r.SU)(t).nb_workouts?((0,a.wg)(),(0,a.j4)(x.Z,{key:0})):(0,a.kq)("",!0)])):(0,a.kq)("",!0)])}}});const P=(0,k.Z)(W,[["__scopeId","data-v-2e341d4e"]]);var A=P}}]);
|
||||
//# sourceMappingURL=statistics.145d19e3.js.map
|
||||
//# sourceMappingURL=statistics.1ad194e3.js.map
|
1
fittrackee/dist/static/js/statistics.1ad194e3.js.map
vendored
Normal file
1
fittrackee/dist/static/js/statistics.1ad194e3.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
fittrackee/dist/static/js/workouts.22600b70.js.map
vendored
Normal file
1
fittrackee/dist/static/js/workouts.22600b70.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
fittrackee/tests/fixtures/fixtures_app.py
vendored
2
fittrackee/tests/fixtures/fixtures_app.py
vendored
@ -81,6 +81,8 @@ def app(monkeypatch: pytest.MonkeyPatch) -> Generator:
|
||||
monkeypatch.setenv('WEATHER_API_KEY', '')
|
||||
if os.getenv('TILE_SERVER_URL'):
|
||||
monkeypatch.delenv('TILE_SERVER_URL')
|
||||
if os.getenv('STATICMAP_SUBDOMAINS'):
|
||||
monkeypatch.delenv('STATICMAP_SUBDOMAINS')
|
||||
if os.getenv('MAP_ATTRIBUTION'):
|
||||
monkeypatch.delenv('MAP_ATTRIBUTION')
|
||||
if os.getenv('DEFAULT_STATICMAP'):
|
||||
|
56
fittrackee/tests/fixtures/fixtures_workouts.py
vendored
56
fittrackee/tests/fixtures/fixtures_workouts.py
vendored
@ -702,6 +702,62 @@ def gpx_file_with_segments() -> str:
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def gpx_file_with_3_segments() -> str:
|
||||
"""60 seconds between each segment"""
|
||||
return (
|
||||
'<?xml version=\'1.0\' encoding=\'UTF-8\'?>'
|
||||
'<gpx xmlns:gpxdata="http://www.cluetrust.com/XML/GPXDATA/1/0" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpxext="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns="http://www.topografix.com/GPX/1/1">' # noqa
|
||||
' <metadata/>'
|
||||
' <trk>'
|
||||
' <name>just a workout</name>'
|
||||
' <trkseg>'
|
||||
' <trkpt lat="44.68095" lon="6.07367">'
|
||||
' <ele>998</ele>'
|
||||
' <time>2018-03-13T12:44:50Z</time>'
|
||||
' </trkpt>'
|
||||
' <trkpt lat="44.68091" lon="6.07367">'
|
||||
' <ele>998</ele>'
|
||||
' <time>2018-03-13T12:44:55Z</time>'
|
||||
' </trkpt>'
|
||||
' <trkpt lat="44.6808" lon="6.07364">'
|
||||
' <ele>994</ele>'
|
||||
' <time>2018-03-13T12:45:00Z</time>'
|
||||
' </trkpt>'
|
||||
' </trkseg>'
|
||||
' <trkseg>'
|
||||
' <trkpt lat="44.67972" lon="6.07367">'
|
||||
' <ele>987</ele>'
|
||||
' <time>2018-03-13T12:46:00Z</time>'
|
||||
' </trkpt>'
|
||||
' <trkpt lat="44.67966" lon="6.07368">'
|
||||
' <ele>987</ele>'
|
||||
' <time>2018-03-13T12:46:05Z</time>'
|
||||
' </trkpt>'
|
||||
' <trkpt lat="44.67961" lon="6.0737">'
|
||||
' <ele>986</ele>'
|
||||
' <time>2018-03-13T12:46:10Z</time>'
|
||||
' </trkpt>'
|
||||
' </trkseg>'
|
||||
' <trkseg>'
|
||||
' <trkpt lat="44.67858" lon="6.07425">'
|
||||
' <ele>980</ele>'
|
||||
' <time>2018-03-13T12:47:10Z</time>'
|
||||
' </trkpt>'
|
||||
' <trkpt lat="44.67842" lon="6.07434">'
|
||||
' <ele>979</ele>'
|
||||
' <time>2018-03-13T12:47:15Z</time>'
|
||||
' </trkpt>'
|
||||
' <trkpt lat="44.67837" lon="6.07435">'
|
||||
' <ele>979</ele>'
|
||||
' <time>2018-03-13T12:47:20Z</time>'
|
||||
' </trkpt>'
|
||||
' </trkseg>'
|
||||
' </trk>'
|
||||
'</gpx>'
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def gpx_file_storage(gpx_file: str) -> FileStorage:
|
||||
return FileStorage(
|
||||
|
@ -1,7 +1,7 @@
|
||||
import json
|
||||
import time
|
||||
from random import randint
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
from urllib.parse import parse_qs
|
||||
|
||||
from flask import Flask
|
||||
@ -286,10 +286,20 @@ class ApiTestCaseMixin(OAuth2Mixin, RandomMixin):
|
||||
|
||||
|
||||
class CallArgsMixin:
|
||||
"""call args are returned differently between Python 3.7 and 3.7+"""
|
||||
|
||||
@staticmethod
|
||||
def get_args(call_args: Any) -> Any:
|
||||
def get_args(call_args: Tuple) -> Tuple:
|
||||
if len(call_args) == 2:
|
||||
args, _ = call_args
|
||||
else:
|
||||
_, args, _ = call_args
|
||||
return args
|
||||
|
||||
@staticmethod
|
||||
def get_kwargs(call_args: Tuple) -> Dict:
|
||||
if len(call_args) == 2:
|
||||
_, kwargs = call_args
|
||||
else:
|
||||
_, _, kwargs = call_args
|
||||
return kwargs
|
||||
|
@ -1,3 +1,4 @@
|
||||
from datetime import timedelta
|
||||
from unittest.mock import call, patch
|
||||
|
||||
import pytest
|
||||
@ -5,9 +6,10 @@ from flask import Flask
|
||||
from gpxpy.gpx import IGNORE_TOP_SPEED_PERCENTILES, MovingData
|
||||
from werkzeug.datastructures import FileStorage
|
||||
|
||||
from fittrackee.tests.utils import random_string
|
||||
from fittrackee.users.models import User, UserSportPreference
|
||||
from fittrackee.workouts.models import Sport
|
||||
from fittrackee.workouts.utils.workouts import process_files
|
||||
from fittrackee.workouts.utils.workouts import get_gpx_info, process_files
|
||||
|
||||
folders = {
|
||||
'extract_dir': '/tmp/fitTrackee/uploads',
|
||||
@ -96,3 +98,35 @@ class TestStoppedSpeedThreshold:
|
||||
IGNORE_TOP_SPEED_PERCENTILES, # speed_extreemes_percentiles
|
||||
True, # ignore_nonstandard_distances
|
||||
)
|
||||
|
||||
|
||||
class TestGetGpxInfoStopTime:
|
||||
def test_stop_time_equals_to_0_when_gpx_file_contains_one_segment(
|
||||
self, gpx_file: str
|
||||
) -> None:
|
||||
"""
|
||||
stopped_speed_threshold to 0 to avoid calculated stopped time
|
||||
in segments
|
||||
"""
|
||||
with patch('builtins.open', return_value=gpx_file):
|
||||
|
||||
gpx_data, _, _ = get_gpx_info(
|
||||
gpx_file=random_string(), stopped_speed_threshold=0.0
|
||||
)
|
||||
|
||||
assert gpx_data['stop_time'] == timedelta(seconds=0)
|
||||
|
||||
def test_stop_time_equals_to_stopped_time_sum_between_all_segments(
|
||||
self, gpx_file_with_3_segments: str
|
||||
) -> None:
|
||||
"""
|
||||
stopped_speed_threshold to 0 to avoid calculated stopped time
|
||||
in segments
|
||||
"""
|
||||
with patch('builtins.open', return_value=gpx_file_with_3_segments):
|
||||
|
||||
gpx_data, _, _ = get_gpx_info(
|
||||
gpx_file=random_string(), stopped_speed_threshold=0.0
|
||||
)
|
||||
|
||||
assert gpx_data['stop_time'] == timedelta(seconds=120)
|
||||
|
63
fittrackee/tests/workouts/test_utils/test_maps.py
Normal file
63
fittrackee/tests/workouts/test_utils/test_maps.py
Normal file
@ -0,0 +1,63 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from fittrackee.workouts.utils.maps import get_static_map_tile_server_url
|
||||
|
||||
|
||||
class TestGetStaticMapTileServerUrl:
|
||||
@pytest.mark.parametrize(
|
||||
'input_tile_server_url,'
|
||||
'input_tile_server_subdomains,'
|
||||
'expected_tile_server_url',
|
||||
[
|
||||
(
|
||||
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
'',
|
||||
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
),
|
||||
(
|
||||
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
'a',
|
||||
'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
),
|
||||
(
|
||||
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
'',
|
||||
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
),
|
||||
(
|
||||
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
'a',
|
||||
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_it_returns_tile_server_url(
|
||||
self,
|
||||
input_tile_server_url: str,
|
||||
input_tile_server_subdomains: str,
|
||||
expected_tile_server_url: str,
|
||||
) -> None:
|
||||
tile_config = {
|
||||
'URL': input_tile_server_url,
|
||||
'STATICMAP_SUBDOMAINS': input_tile_server_subdomains,
|
||||
}
|
||||
|
||||
assert (
|
||||
get_static_map_tile_server_url(tile_config)
|
||||
== expected_tile_server_url
|
||||
)
|
||||
|
||||
def test_it_returns_tile_server_url_with_random_subdomain(self) -> None:
|
||||
"""in case multiple subdomains are provided"""
|
||||
tile_config = {
|
||||
'URL': 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
'STATICMAP_SUBDOMAINS': 'a,b,c',
|
||||
}
|
||||
|
||||
with patch('random.choice', return_value='b'):
|
||||
assert (
|
||||
get_static_map_tile_server_url(tile_config)
|
||||
== 'https://b.tile.openstreetmap.org/{z}/{x}/{y}.png'
|
||||
)
|
@ -9,6 +9,7 @@ from unittest.mock import Mock
|
||||
import pytest
|
||||
from flask import Flask
|
||||
|
||||
from fittrackee import VERSION
|
||||
from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
@ -442,7 +443,7 @@ class TestPostWorkoutWithGpx(ApiTestCaseMixin, CallArgsMixin):
|
||||
assert len(data['data']['workouts']) == 1
|
||||
assert data['data']['workouts'][0]['notes'] == input_notes
|
||||
|
||||
def test_it_calls_configured_tile_server_for_static_map(
|
||||
def test_it_calls_configured_tile_server_for_static_map_when_default_static_map_to_false( # noqa
|
||||
self,
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
@ -473,7 +474,36 @@ class TestPostWorkoutWithGpx(ApiTestCaseMixin, CallArgsMixin):
|
||||
in call_args[0]
|
||||
)
|
||||
|
||||
def test_it_calls_default_tile_server_for_static_map(
|
||||
def test_it_calls_static_map_with_fittrackee_user_agent_when_default_static_map_to_false( # noqa
|
||||
self,
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file: str,
|
||||
static_map_get_mock: Mock,
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, user_1.email
|
||||
)
|
||||
client.post(
|
||||
'/api/workouts',
|
||||
data=dict(
|
||||
file=(BytesIO(str.encode(gpx_file)), 'example.gpx'),
|
||||
data='{"sport_id": 1}',
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
call_kwargs = self.get_kwargs(static_map_get_mock.call_args)
|
||||
|
||||
assert call_kwargs['headers'] == {
|
||||
'User-Agent': f'FitTrackee v{VERSION}'
|
||||
}
|
||||
|
||||
def test_it_calls_default_tile_server_for_static_map_when_default_static_map_to_true( # noqa
|
||||
self,
|
||||
app_default_static_map: Flask,
|
||||
user_1: User,
|
||||
@ -504,6 +534,35 @@ class TestPostWorkoutWithGpx(ApiTestCaseMixin, CallArgsMixin):
|
||||
not in call_args[0]
|
||||
)
|
||||
|
||||
def test_it_calls_static_map_with_fittrackee_user_agent_when_default_static_map_to_true( # noqa
|
||||
self,
|
||||
app_default_static_map: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file: str,
|
||||
static_map_get_mock: Mock,
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_default_static_map, user_1.email
|
||||
)
|
||||
client.post(
|
||||
'/api/workouts',
|
||||
data=dict(
|
||||
file=(BytesIO(str.encode(gpx_file)), 'example.gpx'),
|
||||
data='{"sport_id": 1}',
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
call_kwargs = self.get_kwargs(static_map_get_mock.call_args)
|
||||
|
||||
assert call_kwargs['headers'] == {
|
||||
'User-Agent': f'FitTrackee v{VERSION}'
|
||||
}
|
||||
|
||||
def test_it_returns_500_if_gpx_file_has_not_tracks(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -527,7 +586,7 @@ class TestPostWorkoutWithGpx(ApiTestCaseMixin, CallArgsMixin):
|
||||
),
|
||||
)
|
||||
|
||||
data = self.assert_500(response, 'Error during gpx processing.')
|
||||
data = self.assert_500(response, 'error during gpx processing')
|
||||
assert 'data' not in data
|
||||
|
||||
def test_it_returns_500_if_gpx_has_invalid_xml(
|
||||
@ -556,7 +615,7 @@ class TestPostWorkoutWithGpx(ApiTestCaseMixin, CallArgsMixin):
|
||||
),
|
||||
)
|
||||
|
||||
data = self.assert_500(response, 'Error during gpx file parsing.')
|
||||
data = self.assert_500(response, 'error during gpx file parsing')
|
||||
assert 'data' not in data
|
||||
|
||||
def test_it_returns_400_if_workout_gpx_has_invalid_extension(
|
||||
@ -973,7 +1032,7 @@ class TestPostWorkoutWithZipArchive(ApiTestCaseMixin):
|
||||
),
|
||||
)
|
||||
|
||||
data = self.assert_500(response, 'Error during gpx processing.')
|
||||
data = self.assert_500(response, 'error during gpx processing')
|
||||
assert 'data' not in data
|
||||
|
||||
def test_it_imports_only_max_number_of_files(
|
||||
|
@ -104,7 +104,9 @@ def get_gpx_info(
|
||||
# if a previous segment exists, calculate stopped time between
|
||||
# the two segments
|
||||
if prev_seg_last_point:
|
||||
stopped_time_between_seg = point.time - prev_seg_last_point
|
||||
stopped_time_between_seg += (
|
||||
point.time - prev_seg_last_point
|
||||
)
|
||||
|
||||
# last segment point
|
||||
if point_idx == (segment_points_nb - 1):
|
||||
|
@ -1,20 +1,32 @@
|
||||
import hashlib
|
||||
from typing import List
|
||||
import random
|
||||
from typing import Dict, List
|
||||
|
||||
from flask import current_app
|
||||
from staticmap import Line, StaticMap
|
||||
|
||||
from fittrackee import VERSION
|
||||
from fittrackee.files import get_absolute_file_path
|
||||
|
||||
|
||||
def get_static_map_tile_server_url(tile_server_config: Dict) -> str:
|
||||
if tile_server_config['STATICMAP_SUBDOMAINS']:
|
||||
subdomains = tile_server_config['STATICMAP_SUBDOMAINS'].split(',')
|
||||
subdomain = f'{random.choice(subdomains)}.' # nosec
|
||||
else:
|
||||
subdomain = ''
|
||||
return tile_server_config['URL'].replace('{s}.', subdomain)
|
||||
|
||||
|
||||
def generate_map(map_filepath: str, map_data: List) -> None:
|
||||
"""
|
||||
Generate and save map image from map data
|
||||
"""
|
||||
m = StaticMap(400, 225, 10)
|
||||
m.headers = {'User-Agent': f'FitTrackee v{VERSION}'}
|
||||
if not current_app.config['TILE_SERVER']['DEFAULT_STATICMAP']:
|
||||
m.url_template = current_app.config['TILE_SERVER']['URL'].replace(
|
||||
'{s}.', ''
|
||||
m.url_template = get_static_map_tile_server_url(
|
||||
current_app.config['TILE_SERVER']
|
||||
)
|
||||
line = Line(map_data, '#3388FF', 4)
|
||||
m.add_line(line)
|
||||
|
@ -307,9 +307,9 @@ def process_one_gpx_file(
|
||||
absolute_map_filepath = get_absolute_file_path(map_filepath)
|
||||
generate_map(absolute_map_filepath, map_data)
|
||||
except (gpxpy.gpx.GPXXMLSyntaxException, TypeError) as e:
|
||||
raise WorkoutException('error', 'Error during gpx file parsing.', e)
|
||||
raise WorkoutException('error', 'error during gpx file parsing', e)
|
||||
except Exception as e:
|
||||
raise WorkoutException('error', 'Error during gpx processing.', e)
|
||||
raise WorkoutException('error', 'error during gpx processing', e)
|
||||
|
||||
try:
|
||||
new_workout = create_workout(
|
||||
|
Reference in New Issue
Block a user