{"id":17184812,"url":"https://github.com/liskin/strava-gear","last_synced_at":"2025-09-11T17:10:17.999Z","repository":{"id":57471696,"uuid":"49095751","full_name":"liskin/strava-gear","owner":"liskin","description":"Rule based tracker of gear and component wear primarily for Strava","archived":false,"fork":false,"pushed_at":"2024-06-16T15:46:03.000Z","size":216,"stargazers_count":33,"open_issues_count":4,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-07-08T09:52:57.403Z","etag":null,"topics":["command-line","hacktoberfest","liskin-cookiecutter-python-cli","python","python3","strava","strava-activities","strava-bulk-export","strava-data"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/liskin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-01-05T22:09:04.000Z","updated_at":"2025-04-22T06:17:44.000Z","dependencies_parsed_at":"2023-11-18T12:32:22.169Z","dependency_job_id":"d213f0f6-6a6a-4041-ad5e-901fe8581c31","html_url":"https://github.com/liskin/strava-gear","commit_stats":{"total_commits":183,"total_committers":3,"mean_commits":61.0,"dds":0.02732240437158473,"last_synced_commit":"31b2b9eda5026126fcc56b531cade2957113d6b7"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/liskin/strava-gear","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liskin%2Fstrava-gear","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liskin%2Fstrava-gear/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liskin%2Fstrava-gear/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liskin%2Fstrava-gear/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/liskin","download_url":"https://codeload.github.com/liskin/strava-gear/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liskin%2Fstrava-gear/sbom","scorecard":{"id":592472,"data":{"date":"2025-08-11","repo":{"name":"github.com/liskin/strava-gear","commit":"cff6ece0f2538080c98e1780d64119d00dcbb508"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check.yaml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check.yaml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check.yaml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check.yaml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check.yaml:105: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:141: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:146: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:151: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:156: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/check.yaml:171: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/check.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yaml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/pypi.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yaml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/pypi.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yaml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/pypi.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yaml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/pypi.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pypi.yaml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/liskin/strava-gear/pypi.yaml/main?enable=pin","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of  10 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'actions' permission set to 'write': .github/workflows/check.yaml:169","Warn: no topLevel permission defined: .github/workflows/check.yaml:1","Warn: no topLevel permission defined: .github/workflows/pypi.yaml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T22:19:08.853Z","repository_id":57471696,"created_at":"2025-08-20T22:19:08.853Z","updated_at":"2025-08-20T22:19:08.853Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274674774,"owners_count":25328910,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line","hacktoberfest","liskin-cookiecutter-python-cli","python","python3","strava","strava-activities","strava-bulk-export","strava-data"],"created_at":"2024-10-15T00:44:28.894Z","updated_at":"2025-09-11T17:10:17.965Z","avatar_url":"https://github.com/liskin.png","language":"Python","funding_links":["https://www.paypal.me/lisknisi/10EUR","https://github.com/sponsors/liskin"],"categories":[],"sub_categories":[],"readme":"# strava-gear\n\n**Rule based tracker of gear and component wear primarily for [Strava][]**\n\n[![PyPI Python Version badge](https://img.shields.io/pypi/pyversions/strava-gear)](https://pypi.org/project/strava-gear/)\n[![PyPI Version badge](https://img.shields.io/pypi/v/strava-gear)](https://pypi.org/project/strava-gear/)\n![License badge](https://img.shields.io/github/license/liskin/strava-gear)\n[![Chat at Gitter](https://badges.gitter.im/liskin/strava-gear.svg)](https://gitter.im/liskin/strava-gear)\n\nSimple, yet powerful, local and open-source gear tracker for Strava. Uses\n[strava-offline][] to keep a local database of activities and then reads\nrules such as when a chain was replaced or that a certain hashtag means a\ndifferent set of wheels was used, and computes the wear (distance ridden and\ntime used) of all components.\n\nCompared to [Strava My Gear][]:\n\n* unlimited number of components\n* tracks wear of components swapped from one bike to another, or taken off\n  temporarily\n* hashtags for temporary component changes (race wheels, bikepacking bags, …)\n* easy and reversible editing of maintenance history (it's just YAML, and you\n  can put it under [version control][git])\n\nPlanned, not yet implemented features:\n\n* [configurable alerts that a component might be worn out and needs servicing\n  or replacing](https://github.com/liskin/strava-gear/issues/3)\n\n![Example screenshot](https://user-images.githubusercontent.com/300342/133298545-0573cef3-593d-427a-89b1-5c049374d394.png)\n\n[strava-offline]: https://github.com/liskin/strava-offline#readme\n[Strava]: https://strava.com/\n[Strava My Gear]: https://support.strava.com/hc/en-us/articles/216918727-Adding-Gear-to-your-activities-on-Strava\n[git]: https://git-scm.com/\n[pipx]: https://github.com/pypa/pipx\n\n## Installation\n\nUsing [pipx][]:\n\n```\npipx ensurepath\npipx install \"strava-gear[strava]\"\n```\n\nAlternatively, if you don't need the isolated virtualenv that [pipx][]\nprovides, feel free to just:\n\n```\npip install \"strava-gear[strava]\"\n```\n\nIf you've already installed [strava-offline][] and use it separately, you can\nomit the `[strava]` bit to avoid installing strava-offline twice.\n\n## Setup and usage\n\n* Run `strava-gear-sync` (or `strava-offline sqlite` if you chose to install\n  [strava-offline][] separately) to synchronize activities metadata to a local\n  sqlite database. This takes a while: first time a couple dozen seconds, then\n  it syncs incrementally which only takes a few seconds each time. Add `-v` to\n  see progress.\n\n  The first time you do this, it will open Strava in a browser and ask for\n  permissions. Should you run into any trouble at this point, consult\n  [strava-offline][] readme or open an issue.\n\n  If you make changes to older activities (to assign a different bike to a\n  ride, for example), you may need a `--full` re-sync rathen than the default\n  incremental one. See the [note about incremental synchronization](https://github.com/liskin/strava-offline#note-about-incremental-synchronization)\n  for a detailed explanation.\n\n* Create `~/.config/strava_gear/rules.yaml` (the location will be different on\n  Windows/MacOS, please consult `--help` or just use `--rules` explicitly) and\n  define components and rules. The complete format of the `rules.yaml` file is\n  documented in [Rules syntax](#rules-syntax), but a good start might be\n  something like this:\n\n  ```yaml\n  rules:\n  - gravel:\n      casette: grx-hg800\n      chain: grx-chain-1\n  - since: 2021-01-01\n    gravel:\n      chain: grx-chain-2\n  ```\n\n  This defines two rules:\n\n  1. The first one has no `since:`, and defines the initial configuration: a\n     bike named \"gravel\" in Strava starts with two components in two roles,\n     respectively. The first component, \"gravel-hg800\", is assigned the\n     \"casette\" role and \"gravel-chain-1\" is assigned to \"chain\".\n\n  2. Then, on 2021-01-01, we replaced the chain. This is expressed as a rule\n     with `since: 2021-01-01` that assigns component \"gravel-chain-2\" to the\n     \"chain\" role of our \"gravel\" bicycle.\n\n* Run `strava-gear`:\n\n  ```\n  $ strava-gear\n  bike    role     id           name              km    hour  first … last\n  ------  -------  -----------  -----------  -------  ------  -----------------------\n  gravel  casette  grx-hg800    grx-hg800    19462.0   913.9  2016-01-12 … 2021-09-11\n  gravel  chain    grx-chain-2  grx-chain-2   2236.6   113.5  2021-01-18 … 2021-09-11\n  ```\n\n  As you see, strava-gear displays the components currently assigned to your\n  gravel bike and their computed usage: distance, hours, first and last use.\n\n  You'll also notice that the component ids are shown twice. This is because\n  if you [declare your components explicitly](#rules-syntax), you can assign\n  long names to them, such as \"Shimano CN-HG701-11 with Quick-Link\". This\n  column can be hidden using the `--hide-name` [command-line\n  option](#command-line-options).\n\n  If you want to see all components regardless of their current assignment,\n  ordered by last usage, just ask for the `components` report:\n\n  ```\n  $ strava-gear --report=components\n  id           name              km    hour  first … last\n  -----------  -----------  -------  ------  -----------------------\n  grx-chain-1  grx-chain-1  17225.5   800.4  2016-01-12 … 2020-12-12\n  grx-hg800    grx-hg800    19462.0   913.9  2016-01-12 … 2021-09-11\n  grx-chain-2  grx-chain-2   2236.6   113.5  2021-01-18 … 2021-09-11\n  ```\n\n  There are more ways to customize the output (and input), use `--help` or see\n  [Command line options](#command-line-options).\n\n## Rules syntax\n\nThe rules for strava-gear are by default loaded from\n`~/.config/strava_gear/rules.yaml` (the location will be different on\nWindows/MacOS, please consult `--help` or just use `--rules` explicitly).\nHere's an informal description of what goes inside:\n\n```yaml\n# The rules section is mandatory, and there must be at least one rule.\nrules:\n\n  # The general format of a rule is:\n  - since: date  # ISO-8601 format, defaults to unix epoch if omitted\n    # Bicycle id, name or alias (see further)\n    bicycle:\n      # Role can be anything like \"chain\", \"rear-tyre\", …\n      role: component1_id\n      role2: component2_id\n      # …\n    # Multiple bicycles and hashtags can be specified in one rule:\n    bicycle2:\n      role: component3_id\n      # …\n    \"#hashtag1\":\n      role: component4_id\n      # …\n    # …\n\n  # Typically, the first rule will specify initial component assigment,\n  # for example:\n  - gravel:\n      frame: specialized-diverge-frame\n      tyre-front: specialized-roubaix-pro-1\n      tyre-rear: specialized-roubaix-pro-2\n      chain: chain11-1\n    road:\n      frame: isaac-element-frame\n      tyre-front: schwalbe-one-1\n      tyre-rear: schwalbe-one-2\n      chain: chain11-2\n  # Note that this doesn't need to be at the top of the file. The rules are\n  # sorted by their \"since\" fields anyway. It's totally okay to first specify\n  # all rules for the gravel bike, then rules for the road bike, and so on.\n\n  # Most rules will then specify a \"since\" field and some component changes:\n  - since: 2020-02-01\n    gravel:\n      chain: chain11-3\n  - since: 2020-08-01\n    gravel:\n      chain: chain11-4\n    road:\n      chain: chain11-5\n  # and so on and so forth…\n\n  # When null (a YAML keyword) is specified in place of a component,\n  # it means the component was taken off the bike:\n  - since: 2019-11-01\n    road:\n      mudguards: crud-roadracer-mk3  # mudguards for the winter\n  - since: 2020-03-01\n    road:\n      mudguards: null                # but take them off as soon as possible!\n\n  # Components can be moved from one bike to another without explicitly\n  # unassigning them from the first bike:\n  - since: 2021-01-01\n    gravel:\n      # These are automatically unassigned from road bike:\n      tyre-front: schwalbe-one-1\n      tyre-rear: schwalbe-one-2\n\n  # For temporary component assignments, we can define hashtag rules:\n  - \"#cx-tyres\":\n      tyre-front: schwalbe-x-one-1\n      tyre-rear: schwalbe-x-one-2\n  - since: 2020-06-01\n    \"#cx-tyres\":\n      tyre-front: schwalbe-x-one-3\n      tyre-rear: schwalbe-x-one-4\n\n  # These temporarily change component assignments whenever the given hashtag\n  # appears in the name (not description!) of an activity.\n  #\n  # Note that null component in a hashtag rule only means that the hashtag no\n  # longer assigns that component, it doesn't result in temporary unassignment\n  # whenever that hashtag is used in an activity name. If you need that, use a\n  # dummy component id.\n\n  # Special virtual hashtags `#column=value` are available for all columns in\n  # the input database/csv. These can for example be used to define component\n  # assignments for indoor trainer rides from Zwift, Rouvy, etc.:\n  - \"#type=VirtualRide\":\n      tyre-front: wahoo-kickr-climb\n      tyre-rear: wahoo-kickr\n  - \"#commute=1\":\n      shoes: chrome-industries-kursk\n\n  # Dates are interpreted as midnight in your current time zone.\n  # Time can be specified too, if you swapped components in between rides in\n  # one day:\n  - since: 2020-05-01T14:00\n  # If you travel between timezones and need strava-gear to give consistent\n  # results, it's a good idea to specify the timezone as well:\n  - since: 2020-05-01T14:00+02:00  # Central European Summer Time\n\n# The components section is optional, but it's useful to declare component\n# names or initial usage (second hand components, usage not tracked in Strava,\n# etc.).\ncomponents:\n  # The key is component id, the value is component name:\n  chain11-1: \"Shimano CN-HG701-11 (Quick-Link)\"\n\n  # To specify initial usage, the value must be an object instead:\n  chain11-2:\n    name: \"Shimano CN-HG701-11 (connecting pin)\"\n    kms: 1000\n    hours: 50\n\n  # A component with same id and name can also be declared explicitly,\n  # although it doesn't need to be.\n  chain11-3:\n\n# The aliases section can be omitted if you just want to use bike names as\n# defined in Strava. If you, however, want to use shorter bike ids, or if\n# you often rename your bikes in Strava and want to keep the names stable\n# here, you can define aliases explicitly.\naliases:\n  city: b123456    # To get these ids, visit https://www.strava.com/settings/gear\n  gravel: b234567  # and prepend \"b\" to the number in the URL of the bike link.\n  road: b345678    # Or just look into the strava-offline database. :-)\n```\n\nFor a real life example, take a look at [my own rules.yaml](https://github.com/liskin/dotfiles/blob/home/.config/strava_gear/rules.yaml).\n\n## Command line options\n\n\u003c!-- include tests/readme/help.md --\u003e\n\u003c!--\n    $ export COLUMNS=120\n--\u003e\n\n    $ strava-gear --help\n    Usage: strava-gear [OPTIONS]\n    \n    Options:\n      --rules FILENAME                Rules configuration (bikes, components, ...)  [default:\n                                      /home/user/.config/strava_gear/rules.yaml]\n      --csv FILENAME                  Load activities from CSV instead of the strava-offline database (columns: distance,\n                                      gear_id, moving_time, name, start_date, total_elevation_gain)\n      --strava-database PATH          Location of the strava-offline database  [default:\n                                      /home/user/.local/share/strava_offline/strava.sqlite]\n      -o, --output FILENAME           Output file  [default: -]\n      -r, --report [components|bikes]\n                                      Type of report  [default: bikes]\n      -f, --tablefmt TEXT             Table format, see \u003chttps://github.com/astanin/python-tabulate#table-format\u003e.\n                                      Additionally, \"csv\" is supported for CSV output.  [default: simple]\n      --show-name / --hide-name       Show long component names  [default: show-name]\n      --show-first-last / --hide-first-last\n                                      Show first/last usage of components  [default: show-first-last]\n      --show-vert / --hide-vert       Show vertical (elevation gain)  [default: hide-vert]\n      --show-retired / --hide-retired\n                                      Show retired bikes (on Strava)  [default: hide-retired]\n      --units [metric|imperial]       Show data in metric or imperial  [default: metric]\n      --date-start ISO8601            Filter activities: start at or after the specified date(time)\n      --date-end ISO8601              Filter activities: start before the specified date(time)\n      --help                          Show this message and exit.\n\u003c!-- end include tests/readme/help.md --\u003e\n\n## Contributing\n\n### Code\n\nWe welcome bug fixes, (reasonable) new features, documentation improvements,\nand more. Submit these as GitHub pull requests. Use GitHub issues to report\nbugs and discuss non-trivial code improvements; alternatively, get in touch\nvia [IRC/Matrix/Fediverse](https://work.lisk.in/contact/).\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for more details about the code base\n(including running tests locally).\n\nNote that this project was born out of a desire to solve a problem I was\nfacing. While I'm excited to share it with the world, keep in mind that I'll\nbe prioritizing features and bug fixes that align with my personal use cases.\nThere may be times when I'm busy with other commitments and replies to\ncontributions might be delayed, or even occasionally missed. Progress may come\nin bursts. Adjust your expectations accordingly.\n\n### Donations (♥ = €)\n\nIf you like this tool and wish to support its development and maintenance,\nplease consider [a small donation](https://www.paypal.me/lisknisi/10EUR) or\n[recurrent support through GitHub Sponsors](https://github.com/sponsors/liskin).\n\nBy donating, you'll also support the development of my other projects. You\nmight like these:\n\n* [strava-offline](https://github.com/liskin/strava-offline) – Keep a local mirror of Strava activities for further analysis/processing\n* [strava-map-switcher](https://github.com/liskin/strava-map-switcher) – Map switcher for Strava website\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliskin%2Fstrava-gear","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliskin%2Fstrava-gear","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliskin%2Fstrava-gear/lists"}