Skip to content

Commit

Permalink
Merge pull request #10 from Lucs1590/path-improvement
Browse files Browse the repository at this point in the history
Path improvement
  • Loading branch information
Lucs1590 authored Sep 27, 2024
2 parents f8d3216 + 568bcca commit 51b0743
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/greatings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/first-interaction@v1
- uses: actions/first-interaction@v1.3.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: "Thanks for contributing this issue! We will be replying soon."
Expand Down
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Current File",
"type": "debugpy",
"request": "launch",
"program": "src/main.py",
"console": "integratedTerminal"
}
]
}
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ The idea for this script came from the need to synchronize my triathlon training
### Workflow

1. Choose the sport you want to export;
2. Do you want to download the `.tcx` file or select from the local directory?
2. Do you want to download the `.tcx` file or select from the local directory;
1. User chooses the ID of the activity on Strava;
2. The download is performed by accessing the activity route with `/export_original` or `/export_tcx` endpoints;
3. Indicate the path of the local directory file;
4. If it is swimming or something else, the `.tcx` file is formatted; if it is running or biking, the `.tcx` file is validated;
5. Indent the `.tcx` file.
3. If it is swimming or something else, the `.tcx` file is formatted; if it is running or biking, the `.tcx` file is validated;
4. Indent the `.tcx` file.

## Installation

Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
defusedxml>=0.7.1
questionary>=2.0.1
tcxreader>=0.4.10
defusedxml==0.7.1
questionary==2.0.1
tcxreader==0.4.10
32 changes: 27 additions & 5 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os
import logging
import webbrowser

import time
from defusedxml.minidom import parseString

import questionary
Expand Down Expand Up @@ -31,7 +31,13 @@ def main():
logger.info("Downloading the TCX file from Strava")
download_tcx_file(activity_id, sport)

file_path = ask_file_path(file_location)
time.sleep(3)
file_path = get_latest_download()
logger.info(
f"Automatically detected downloaded file path: {file_path}"
)
else:
file_path = ask_file_path(file_location)

if sport in ["Swim", "Other"]:
logger.info("Formatting the TCX file to be imported to TrainingPeaks")
Expand Down Expand Up @@ -76,12 +82,28 @@ def download_tcx_file(activity_id: str, sport: str) -> None:
try:
webbrowser.open(url)
except Exception as err:
logger.error(
"Failed to download the TCX file from Strava."
)
logger.error("Failed to download the TCX file from Strava.")
raise ValueError("Error opening the browser") from err


def get_latest_download() -> str:
download_folder = os.path.expanduser("~/Downloads")
try:
files = os.listdir(download_folder)
except FileNotFoundError:
files = []
paths = [os.path.join(download_folder, f)
for f in files if f.endswith('.tcx')]

if paths:
latest_file = max(paths, key=os.path.getmtime)
else:
logger.error("No TCX file found in the Downloads folder.")
latest_file = ask_file_path("Download")

return latest_file


def ask_file_path(file_location) -> str:
question = "Enter the path to the TCX file:" if file_location == "Provide path" else "Check if the TCX file was downloaded and then enter the path to the file:"
return questionary.path(
Expand Down
37 changes: 27 additions & 10 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
ask_sport,
ask_file_location,
ask_activity_id,
ask_file_path
ask_file_path,
get_latest_download
)


Expand Down Expand Up @@ -131,27 +132,27 @@ def test_indent_xml_file_error(self):

self.assertTrue(mock_parse_string.called)

@patch('src.main.get_latest_download')
@patch('src.main.ask_sport')
@patch('src.main.ask_file_location')
@patch('src.main.ask_activity_id')
@patch('src.main.download_tcx_file')
@patch('src.main.ask_file_path')
@patch('src.main.format_to_swim')
@patch('src.main.validate_tcx_file')
@patch('src.main.indent_xml_file')
def test_main(self, mock_indent, mock_validate, mock_format, mock_ask_path, mock_download, mock_ask_id,
mock_ask_location, mock_ask_sport):
def test_main(self, mock_indent, mock_validate, mock_format, mock_download, mock_ask_id,
mock_ask_location, mock_ask_sport, mock_latest_download):
mock_ask_sport.return_value = "Swim"
mock_ask_location.return_value = "Download"
mock_ask_id.return_value = "12345"
mock_ask_path.return_value = "assets/swim.tcx"
mock_latest_download.return_value = "assets/swim.tcx"

main()

mock_ask_sport.assert_called_once()
mock_ask_location.assert_called_once()
mock_ask_id.assert_called_once()
mock_ask_path.assert_called_once()
mock_latest_download.assert_called_once()
mock_download.assert_called_once_with("12345", "Swim")
mock_format.assert_called_once_with("assets/swim.tcx")
mock_validate.assert_not_called()
Expand All @@ -161,24 +162,24 @@ def test_main(self, mock_indent, mock_validate, mock_format, mock_ask_path, mock
@patch('src.main.ask_file_location')
@patch('src.main.ask_activity_id')
@patch('src.main.download_tcx_file')
@patch('src.main.ask_file_path')
@patch('src.main.get_latest_download')
@patch('src.main.format_to_swim')
@patch('src.main.validate_tcx_file')
@patch('src.main.indent_xml_file')
def test_main_invalid_sport(self, mock_indent, mock_validate, mock_format, mock_ask_path, mock_download,
def test_main_invalid_sport(self, mock_indent, mock_validate, mock_format, mock_latest_download, mock_download,
mock_ask_id, mock_ask_location, mock_ask_sport):
mock_ask_sport.return_value = "InvalidSport"
mock_ask_location.return_value = "Download"
mock_ask_id.return_value = "12345"
mock_ask_path.return_value = "assets/swim.tcx"
mock_latest_download.return_value = "assets/swim.tcx"

with self.assertRaises(ValueError):
main()

mock_ask_sport.assert_called_once()
mock_ask_location.assert_called_once()
mock_ask_id.assert_called_once()
mock_ask_path.assert_called_once()
mock_latest_download.assert_called_once()
mock_download.assert_called_once()
mock_format.assert_not_called()
mock_validate.assert_not_called()
Expand Down Expand Up @@ -258,6 +259,22 @@ def test_ask_file_path(self):
)
self.assertEqual(result, "assets/downloaded.tcx")

@patch('os.path.expanduser')
@patch('os.listdir')
def test_get_latest_downloads_without_ask(self, mock_listdir, mock_expanduser):
mock_listdir.return_value = ["bike.tcx", "run.tcx", "swim.tcx"]
mock_expanduser.return_value = "assets/"
result = get_latest_download()

self.assertEqual(result, "assets/swim.tcx")

@patch('src.main.ask_file_path')
def test_get_latest_downloads_with_ask(self, mock_ask_path):
mock_ask_path.return_value = "assets/bike.tcx"
result = get_latest_download()

self.assertEqual(result, "assets/bike.tcx")


if __name__ == '__main__':
unittest.main()

0 comments on commit 51b0743

Please sign in to comment.