mirror of
https://github.com/joaovitoriasilva/endurain.git
synced 2026-01-10 08:17:59 -05:00
Add Strava activity retrieval by date range
Updated backend and frontend to support retrieving Strava activities using a start and end date instead of days. Refactored API endpoints, utility functions, and UI components to handle date range selection and requests. Deprecated the previous days-based retrieval in favor of more flexible date range queries.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import logging
|
||||
from typing import Annotated
|
||||
from fastapi import APIRouter, Depends, BackgroundTasks
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -38,6 +38,7 @@ from core.database import SessionLocal
|
||||
async def fetch_and_process_activities(
|
||||
strava_client: Client,
|
||||
start_date: datetime,
|
||||
end_date: datetime,
|
||||
user_id: int,
|
||||
user_integrations: user_integrations_schema.UsersIntegrations,
|
||||
websocket_manager: websocket_schema.WebSocketManager,
|
||||
@@ -49,7 +50,9 @@ async def fetch_and_process_activities(
|
||||
|
||||
# Fetch Strava activities after the specified start date
|
||||
try:
|
||||
strava_activities = list(strava_client.get_activities(after=start_date))
|
||||
strava_activities = list(
|
||||
strava_client.get_activities(after=start_date, before=end_date)
|
||||
)
|
||||
except AccessUnauthorized as auth_err:
|
||||
# Log a more specific error message for authentication issues
|
||||
core_logger.print_to_log(
|
||||
@@ -699,14 +702,17 @@ async def retrieve_strava_users_activities_for_days(
|
||||
# Get all users
|
||||
users = users_crud.get_all_users(db)
|
||||
|
||||
# Calculate the start date and end date
|
||||
calculated_start_date = datetime.now(timezone.utc) - timedelta(days=days)
|
||||
calculated_end_date = datetime.now(timezone.utc)
|
||||
|
||||
# Process the activities for each user
|
||||
if users:
|
||||
for user in users:
|
||||
try:
|
||||
await get_user_strava_activities_by_days(
|
||||
(datetime.now(timezone.utc) - timedelta(days=days)).strftime(
|
||||
"%Y-%m-%dT%H:%M:%S"
|
||||
),
|
||||
await get_user_garminconnect_activities_by_dates(
|
||||
calculated_start_date,
|
||||
calculated_end_date,
|
||||
user.id,
|
||||
None,
|
||||
None,
|
||||
@@ -764,8 +770,9 @@ async def retrieve_strava_users_activities_for_days(
|
||||
db.close()
|
||||
|
||||
|
||||
async def get_user_strava_activities_by_days(
|
||||
async def get_user_garminconnect_activities_by_dates(
|
||||
start_date: datetime,
|
||||
end_date: datetime,
|
||||
user_id: int,
|
||||
websocket_manager: websocket_schema.WebSocketManager = None,
|
||||
db: Session = None,
|
||||
@@ -804,6 +811,7 @@ async def get_user_strava_activities_by_days(
|
||||
strava_activities_processed = await fetch_and_process_activities(
|
||||
strava_client,
|
||||
start_date,
|
||||
end_date,
|
||||
user_id,
|
||||
user_integrations,
|
||||
websocket_manager,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import os
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from datetime import datetime, timedelta, timezone, date
|
||||
from typing import Annotated, Callable
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks, Security
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -102,12 +102,13 @@ async def strava_link(
|
||||
|
||||
|
||||
@router.get(
|
||||
"/activities/days/{days}",
|
||||
"/activities",
|
||||
status_code=202,
|
||||
)
|
||||
async def strava_retrieve_activities_days(
|
||||
days: int,
|
||||
validate_access_token: Annotated[
|
||||
start_date: date,
|
||||
end_date: date,
|
||||
_validate_access_token: Annotated[
|
||||
Callable,
|
||||
Depends(auth_security.validate_access_token),
|
||||
],
|
||||
@@ -126,12 +127,16 @@ async def strava_retrieve_activities_days(
|
||||
# db: Annotated[Session, Depends(core_database.get_db)],
|
||||
background_tasks: BackgroundTasks,
|
||||
):
|
||||
start_datetime = datetime.combine(
|
||||
start_date, datetime.min.time(), tzinfo=timezone.utc
|
||||
)
|
||||
end_datetime = datetime.combine(end_date, datetime.max.time(), tzinfo=timezone.utc)
|
||||
|
||||
# Process strava activities in the background
|
||||
background_tasks.add_task(
|
||||
strava_activity_utils.get_user_strava_activities_by_days,
|
||||
(datetime.now(timezone.utc) - timedelta(days=days)).strftime(
|
||||
"%Y-%m-%dT%H:%M:%S"
|
||||
),
|
||||
strava_activity_utils.get_user_garminconnect_activities_by_dates,
|
||||
start_datetime,
|
||||
end_datetime,
|
||||
token_user_id,
|
||||
websocket_manager,
|
||||
)
|
||||
@@ -147,7 +152,7 @@ async def strava_retrieve_activities_days(
|
||||
|
||||
@router.get("/gear", status_code=201)
|
||||
async def strava_retrieve_gear(
|
||||
validate_access_token: Annotated[
|
||||
_validate_access_token: Annotated[
|
||||
Callable,
|
||||
Depends(auth_security.validate_access_token),
|
||||
],
|
||||
@@ -291,7 +296,7 @@ async def import_shoes_from_strava_export(
|
||||
@router.put("/client")
|
||||
async def strava_set_user_client(
|
||||
client: strava_schema.StravaClient,
|
||||
validate_access_token: Annotated[
|
||||
_validate_access_token: Annotated[
|
||||
Callable,
|
||||
Depends(auth_security.validate_access_token),
|
||||
],
|
||||
@@ -319,7 +324,7 @@ async def strava_set_user_client(
|
||||
)
|
||||
async def strava_set_user_unique_state(
|
||||
state: str | None,
|
||||
validate_access_token: Annotated[
|
||||
_validate_access_token: Annotated[
|
||||
Callable,
|
||||
Depends(auth_security.validate_access_token),
|
||||
],
|
||||
@@ -342,7 +347,7 @@ async def strava_set_user_unique_state(
|
||||
|
||||
@router.delete("/unlink")
|
||||
async def strava_unlink(
|
||||
validate_access_token: Annotated[
|
||||
_validate_access_token: Annotated[
|
||||
Callable,
|
||||
Depends(auth_security.validate_access_token),
|
||||
],
|
||||
|
||||
@@ -48,6 +48,17 @@
|
||||
>{{ $t('settingsIntegrationsZone.modalRetrieveActivitiesByDaysTitle') }}</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<!-- retrieve strava activities by date range -->
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="#"
|
||||
role="button"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#retrieveStravaActivitiesByDateRangeModal"
|
||||
>{{ $t('settingsIntegrationsZone.modalRetrieveActivitiesByDateRangeTitle') }}</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<!-- retrieve gear -->
|
||||
<a href="#" class="dropdown-item" @click="submitRetrieveStravaGear">{{
|
||||
@@ -219,7 +230,16 @@
|
||||
:numberFieldLabel="`${t('settingsIntegrationsZone.modalRetrieveActivitiesByDaysLabel')}`"
|
||||
:actionButtonType="`success`"
|
||||
:actionButtonText="t('settingsIntegrationsZone.modalRetrieveButton')"
|
||||
@numberToEmitAction="submitRetrieveStravaActivities"
|
||||
@numberToEmitAction="submitRetrieveStravaActivitiesDays"
|
||||
/>
|
||||
|
||||
<!-- modal retrieve Strava activities by date range -->
|
||||
<ModalComponentDateRangeInput
|
||||
modalId="retrieveStravaActivitiesByDateRangeModal"
|
||||
:title="t('settingsIntegrationsZone.modalRetrieveActivitiesByDateRangeTitle')"
|
||||
:actionButtonType="`success`"
|
||||
:actionButtonText="t('settingsIntegrationsZone.modalRetrieveButton')"
|
||||
@datesToEmitAction="submitRetrieveStravaActivitiesDataRange"
|
||||
/>
|
||||
|
||||
<!-- modal unlink Strava -->
|
||||
@@ -303,6 +323,15 @@ import { INTEGRATION_LOGOS } from '@/constants/integrationLogoConstants'
|
||||
const authStore = useAuthStore()
|
||||
const { locale, t } = useI18n()
|
||||
|
||||
function getStartAndEndDateFromDaysAgo(days) {
|
||||
const endDate = new Date()
|
||||
const startDate = new Date()
|
||||
startDate.setDate(endDate.getDate() - days)
|
||||
const formattedStartDate = startDate.toISOString().split('T')[0]
|
||||
const formattedEndDate = endDate.toISOString().split('T')[0]
|
||||
return { startDate: formattedStartDate, endDate: formattedEndDate }
|
||||
}
|
||||
|
||||
async function submitConnectStrava(stravaClient) {
|
||||
const array = new Uint8Array(16)
|
||||
window.crypto.getRandomValues(array)
|
||||
@@ -326,9 +355,21 @@ async function submitConnectStrava(stravaClient) {
|
||||
}
|
||||
}
|
||||
|
||||
async function submitRetrieveStravaActivities(daysToRetrieveStrava) {
|
||||
async function submitRetrieveStravaActivitiesDays(days) {
|
||||
try {
|
||||
await strava.getStravaActivitiesLastDays(daysToRetrieveStrava)
|
||||
const dates = getStartAndEndDateFromDaysAgo(days)
|
||||
await strava.getStravaActivitiesByDates(dates.startDate, dates.endDate)
|
||||
push.info(t('settingsIntegrationsZone.loadingMessageRetrievingStravaActivities'))
|
||||
} catch (error) {
|
||||
push.error(
|
||||
`${t('settingsIntegrationsZone.errorMessageUnableToGetStravaActivities')} - ${error}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function submitRetrieveStravaActivitiesDataRange(dateRange) {
|
||||
try {
|
||||
await strava.getStravaActivitiesByDates(dateRange.startDate, dateRange.endDate)
|
||||
push.info(t('settingsIntegrationsZone.loadingMessageRetrievingStravaActivities'))
|
||||
} catch (error) {
|
||||
push.error(
|
||||
@@ -363,12 +404,8 @@ async function buttonStravaUnlink() {
|
||||
|
||||
async function submitRetrieveGarminConnectActivitiesDays(days) {
|
||||
try {
|
||||
const endDate = new Date()
|
||||
const startDate = new Date()
|
||||
startDate.setDate(endDate.getDate() - days)
|
||||
const formattedStartDate = startDate.toISOString().split('T')[0]
|
||||
const formattedEndDate = endDate.toISOString().split('T')[0]
|
||||
await garminConnect.getGarminConnectActivitiesByDates(formattedStartDate, formattedEndDate)
|
||||
const dates = getStartAndEndDateFromDaysAgo(days)
|
||||
await garminConnect.getGarminConnectActivitiesByDates(dates.startDate, dates.endDate)
|
||||
push.info(t('settingsIntegrationsZone.loadingMessageRetrievingGarminConnectActivities'))
|
||||
} catch (error) {
|
||||
push.error(
|
||||
@@ -412,12 +449,8 @@ async function submitRetrieveGarminConnectHealthDataDataRange(dateRange) {
|
||||
|
||||
async function submitRetrieveGarminConnectHealthDataDays(days) {
|
||||
try {
|
||||
const endDate = new Date()
|
||||
const startDate = new Date()
|
||||
startDate.setDate(endDate.getDate() - days)
|
||||
const formattedStartDate = startDate.toISOString().split('T')[0]
|
||||
const formattedEndDate = endDate.toISOString().split('T')[0]
|
||||
await garminConnect.getGarminConnectHealthDataByDates(formattedStartDate, formattedEndDate)
|
||||
const dates = getStartAndEndDateFromDaysAgo(days)
|
||||
await garminConnect.getGarminConnectHealthDataByDates(dates.startDate, dates.endDate)
|
||||
push.info(t('settingsIntegrationsZone.loadingMessageRetrievingGarminConnectHealthData'))
|
||||
} catch (error) {
|
||||
push.error(
|
||||
|
||||
@@ -35,8 +35,8 @@ export const strava = {
|
||||
linkStravaCallback(state, code, scope) {
|
||||
return fetchPutRequest(`strava/link?state=${state}&code=${code}&scope=${scope}`)
|
||||
},
|
||||
getStravaActivitiesLastDays(days) {
|
||||
return fetchGetRequest(`strava/activities/days/${days}`)
|
||||
getStravaActivitiesByDates(startDate, endDate) {
|
||||
return fetchGetRequest(`strava/activities?start_date=${startDate}&end_date=${endDate}`)
|
||||
},
|
||||
getStravaGear() {
|
||||
return fetchGetRequest('strava/gear')
|
||||
|
||||
Reference in New Issue
Block a user