Введение
Я люблю кататься на велосипедах. Я также довольно часто путешествую пешком и, как специалист по информатике, люблю данные.
Так что я с детства собираю статистику о своих поездках.
Расстояние, средняя скорость, сама трасса (в виде файла 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 Планета Земля, которые уже присутствовали, когда я запустил приложение:
Я надеюсь, что это вдохновит некоторых из вас на создание собственных проектов и автоматизацию скучных вещей, которые вы предпочли бы не делать!