Введение

Я люблю кататься на велосипедах. Я также довольно часто путешествую пешком и, как специалист по информатике, люблю данные.

Так что я с детства собираю статистику о своих поездках.
Расстояние, средняя скорость, сама трасса (в виде файла GPX)… В туре может быть интересно все.

Сбор всех этих данных вручную — трудоемкая задача, поэтому мне пришлось потратить гораздо больше времени на поиск способа автоматизации всех этих операций.

Чего я хотел добиться

Перед тем, как приступить к этому проекту, моя типичная рутина будет такой:

  • Запишите поездку/поход с помощью приложения Strava.
  • Перейти на сайт Стравы
  • Экспорт тура в формате GPX
  • Скопируйте его статистику в электронную таблицу
  • Импорт файла GPX в Google Планета Земля Про

За исключением первого шага, все в этом списке можно автоматизировать. Моим идеальным результатом было бы иметь скрипт, который работает каждый день в фоновом режиме.

API-интерфейс Стравы

К счастью, Strava предлагает публичный API. Доступ к API непрост: разработчики должны следовать устрашающему процессу, основанному на OAuth2.

Если вы никогда не слышали об OAuth2, ничего страшного, я тоже никогда о нем не слышал. Вам просто нужно помнить следующее:
- Существует токен для доступа к API
- Срок действия токена истекает
- Существует второй токен для обновления первого после истечения срока его действия

Если вам интересна эта тема и вы хотите узнать больше, ознакомьтесь с Библией OAuth.

Я уже использовал другие API. Но у всех у них был простой ключ API, который я мог использовать неоднократно. Тот факт, что токен меняется, является проблемой. Мне нужно сохранить его между прогонами.

Я решил использовать файл settings.json со следующей структурой:

Чтение, синтаксический анализ и запись файла JSON всегда просты, поэтому я подумал, что это правильный путь.

Перед каждым запросом мне нужно проверить, не истек ли срок действия токена, и если да, то обновить его. В конце скрипта я могу сохранить этот файл настроек с обновленной информацией:

Если вам интересно, какой язык программирования я использую… это Swift! Я уже использовал его для других проектов, так что я могу работать быстро и сосредоточиться на важных вещах!

Как уже было сказано, скрипт должен запускаться ежедневно и делать все автоматически. Поэтому сначала ему нужно выяснить, есть ли действия, с которыми он еще не имел дело.

Оказывается, Strava хранит каждое действие с помощью удобного id, который является просто растущим long.

Мы можем сохранить идентификатор последней загруженной активности в нашем файле settings.json.

Затем мы можем получить все действия пользователя, обратившись к /athlete/activities:

На этом этапе мы фильтруем действия по их id. Если новых действий нет, мы выходим с кодом состояния 2. Это пригодится позже.

создание GPX

Теперь мы можем написать еще одну функцию для экспорта файла gpx. К сожалению, Strava не предоставляет для этого конечную точку API. Однако он предлагает stream:

Мы можем создать файл GPX из этого потока, используя CoreGPX:

CoreGPX также предлагает удобный метод gpx(), который создает соответствующую String только что созданному объекту. Затем мы можем сохранить файл, используя простой .write(to: url, atomically: false, encoding: .utf8.

Заполнение электронной таблицы

Теперь мне нужно заполнить электронную таблицу, которая находится в Excel. К сожалению, это Excel с поддержкой макросов, то есть это .xlsm. И оказалось, что существует не так много библиотек Swift для записи файлов такого типа.
На самом деле, все, что я пробовал, в конечном итоге приводило к повреждению или изменению файла непреднамеренным образом.

Я наткнулся на Apache POI-OpenXML4J, который предлагает именно то, что мне было нужно, но для Java.

Вот как половина этого проекта была разработана в совершенно другой среде.

OpenXML4J можно быстро установить с помощью Maven, и он чрезвычайно прост в использовании:

Теперь повторите это для 25 столбцов и всех новых действий, и все готово!

Импорт в Google Планета Земля

Осталось одно: импортировать сохраненный файл gpx в Google Earth. Это самая сложная часть, поскольку у приложения нет API или библиотеки для взаимодействия с ним.

И я хочу, чтобы все происходило в фоновом режиме, поэтому приложение даже не должно быть активировано!

Просматривая сообщения StackOverflow, я обнаружил, что Google Планета Земля сохраняет все в ~/Library/Application Support/Google Earth/myplaces.kml.

Это хорошо, поскольку KML — это не какой-то загадочный файл, который может быть открыт только создавшим его приложением (что часто бывает в macOS). На самом деле это XML, и вы можете написать корректный KML-файл вручную:

На этот раз найти библиотеку было довольно легко. Я выбрал Jsoup, так как его можно установить с помощью Maven (который мы уже использовали для части Excel).

Создать новый элемент легко…

Создание элемента координат:

Наконец, мы извлекаем папку, в которую помещаем новый элемент. Я сортирую свои действия по годам в Google Планета Земля, так что я хочу, чтобы я сделал это и в этом скрипте:

Собираем все вместе

Теперь у нас есть быстрый скрипт и проект Java Maven, которые нужно запускать последовательно.

Благодаря exec-maven-plugin мы можем запускать проект из Терминала. Его просто нужно настроить с помощью основного класса и имени цели:

Теперь мы можем использовать mvn exec:stravaToGoogleEarth для запуска приложения из командной строки.

Наконец, я создал файл main.sh:

Я создал файл .plist в ~/Library/LaunchAgents для запуска этого скрипта в фоновом режиме. Lingon X — отличное приложение, которое поможет вам в этом!

Этот проект улучшил мою способность взаимодействовать с API и использовать разные библиотеки и среды вместе.

Было весело, а главное приятно! Вы хоть представляете, как здорово видеть уведомление, которое информирует вас о том, что:

  • файл excel был обновлен
  • файл gpx загружен и находится в нужной папке
  • Когда вы откроете Google Планета Земля, появится новое действие!

Вот что такое часть таблицы Excel (обратите внимание, что я не вставлял ни одну из этих строк):

А это действия в Google Планета Земля, которые уже присутствовали, когда я запустил приложение:

Я надеюсь, что это вдохновит некоторых из вас на создание собственных проектов и автоматизацию скучных вещей, которые вы предпочли бы не делать!