-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit caca406
Showing
7 changed files
with
406 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
name: CGL | ||
on: push | ||
jobs: | ||
cgl: | ||
runs-on: [ubuntu-latest] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- uses: shivammathur/setup-php@v2 | ||
with: | ||
php-version: '8.2' | ||
|
||
- name: Composer install | ||
run: composer install | ||
|
||
- name: CGL | ||
run: composer cgl-ci |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/.ddev/ | ||
/.idea/ | ||
|
||
/vendor/ | ||
/composer.lock | ||
/test.php | ||
/.php-cs-fixer.cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
<?php | ||
|
||
use PhpCsFixer\Config; | ||
use PhpCsFixer\Finder; | ||
|
||
$rules = [ | ||
'array_syntax' => ['syntax' => 'short'], | ||
'binary_operator_spaces' => [ | ||
'default' => 'single_space', | ||
'operators' => ['=>' => null] | ||
], | ||
'blank_line_after_namespace' => true, | ||
'blank_line_after_opening_tag' => true, | ||
'blank_line_before_statement' => [ | ||
'statements' => ['return'] | ||
], | ||
'single_space_around_construct' => true, | ||
'control_structure_braces' => true, | ||
'control_structure_continuation_position' => true, | ||
'declare_parentheses' => true, | ||
'no_multiple_statements_per_line' => true, | ||
'braces_position' => true, | ||
'statement_indentation' => true, | ||
'cast_spaces' => true, | ||
'class_definition' => true, | ||
'concat_space' => [ | ||
'spacing' => 'none' | ||
], | ||
'declare_equal_normalize' => true, | ||
'declare_strict_types' => true, | ||
'elseif' => true, | ||
'encoding' => true, | ||
'full_opening_tag' => true, | ||
'fully_qualified_strict_types' => true, // added by Shift | ||
'function_declaration' => true, | ||
'type_declaration_spaces' => true, | ||
'heredoc_to_nowdoc' => true, | ||
'include' => true, | ||
'increment_style' => ['style' => 'post'], | ||
'indentation_type' => true, | ||
'linebreak_after_opening_tag' => true, | ||
'line_ending' => true, | ||
'lowercase_cast' => true, | ||
'lowercase_keywords' => true, | ||
'lowercase_static_reference' => true, // added from Symfony | ||
'magic_method_casing' => true, // added from Symfony | ||
'magic_constant_casing' => true, | ||
'method_argument_space' => true, | ||
'native_function_casing' => true, | ||
'no_alias_functions' => true, | ||
'no_extra_blank_lines' => [ | ||
'tokens' => [ | ||
'extra', | ||
'throw', | ||
'use', | ||
] | ||
], | ||
'class_attributes_separation' => [ | ||
'elements' => ['trait_import' => 'none'] | ||
], | ||
'no_blank_lines_after_class_opening' => true, | ||
'no_blank_lines_after_phpdoc' => true, | ||
'no_closing_tag' => true, | ||
'no_empty_phpdoc' => true, | ||
'no_empty_statement' => true, | ||
'no_leading_import_slash' => true, | ||
'no_leading_namespace_whitespace' => true, | ||
'no_mixed_echo_print' => [ | ||
'use' => 'echo' | ||
], | ||
'no_multiline_whitespace_around_double_arrow' => true, | ||
'multiline_whitespace_before_semicolons' => [ | ||
'strategy' => 'no_multi_line' | ||
], | ||
'no_short_bool_cast' => true, | ||
'no_singleline_whitespace_before_semicolons' => true, | ||
'no_spaces_after_function_name' => true, | ||
'no_spaces_around_offset' => true, | ||
'spaces_inside_parentheses' => true, | ||
'no_trailing_comma_in_singleline' => true, | ||
'no_trailing_whitespace' => true, | ||
'no_trailing_whitespace_in_comment' => true, | ||
'no_unneeded_control_parentheses' => true, | ||
'no_unreachable_default_argument_value' => true, | ||
'no_unused_imports' => true, | ||
'no_useless_return' => true, | ||
'no_whitespace_before_comma_in_array' => true, | ||
'no_whitespace_in_blank_line' => true, | ||
'normalize_index_brace' => true, | ||
'not_operator_with_successor_space' => true, | ||
'object_operator_without_whitespace' => true, | ||
'ordered_imports' => ['sort_algorithm' => 'alpha'], | ||
'phpdoc_indent' => true, | ||
'phpdoc_no_access' => true, | ||
'phpdoc_no_package' => true, | ||
'phpdoc_no_useless_inheritdoc' => true, | ||
'phpdoc_scalar' => true, | ||
'phpdoc_single_line_var_spacing' => true, | ||
'phpdoc_summary' => true, | ||
'phpdoc_to_comment' => true, | ||
'phpdoc_trim' => true, | ||
'phpdoc_types' => true, | ||
'phpdoc_var_without_name' => true, | ||
'self_accessor' => true, | ||
'short_scalar_cast' => true, | ||
'simplified_null_return' => true, | ||
'single_blank_line_at_eof' => true, | ||
'blank_lines_before_namespace' => true, | ||
'single_class_element_per_statement' => true, | ||
'single_import_per_statement' => true, | ||
'single_line_after_imports' => true, | ||
'single_line_comment_style' => [ | ||
'comment_types' => ['hash'] | ||
], | ||
'single_quote' => true, | ||
'space_after_semicolon' => true, | ||
'standardize_not_equals' => true, | ||
'switch_case_semicolon_to_colon' => true, | ||
'switch_case_space' => true, | ||
'ternary_operator_spaces' => true, | ||
'trailing_comma_in_multiline' => true, | ||
'trim_array_spaces' => true, | ||
'unary_operator_spaces' => true, | ||
'visibility_required' => [ | ||
'elements' => ['method', 'property'] | ||
], | ||
'whitespace_after_comma_in_array' => true, | ||
]; | ||
|
||
$finder = Finder::create() | ||
->in('src') | ||
->name('*.php') | ||
->ignoreDotFiles(true) | ||
->ignoreVCS(true); | ||
|
||
return (new Config()) | ||
->setFinder($finder) | ||
->setRules($rules) | ||
->setRiskyAllowed(true) | ||
->setUsingCache(true); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "woeler/komoot-php", | ||
"description": "A PHP library to interact with Komoot", | ||
"type": "library", | ||
"require-dev": { | ||
"friendsofphp/php-cs-fixer": "^3.54", | ||
"symfony/var-dumper": "^7.0" | ||
}, | ||
"license": "GPL-3.0-or-later", | ||
"autoload": { | ||
"psr-4": { | ||
"Woeler\\KomootPhp\\": "src/" | ||
} | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Woeler", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"require": { | ||
"guzzlehttp/guzzle": "^7.8" | ||
}, | ||
"scripts": { | ||
"cgl": [ | ||
"vendor/bin/php-cs-fixer fix --config .php-cs-fixer.php" | ||
], | ||
"cgl-ci": [ | ||
"vendor/bin/php-cs-fixer fix --config .php-cs-fixer.php -v --dry-run --diff" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Woeler\KomootPhp\Api; | ||
|
||
use GuzzleHttp\Client; | ||
use GuzzleHttp\Cookie\CookieJar; | ||
use GuzzleHttp\Cookie\SetCookie; | ||
use Woeler\KomootPhp\Enums\PrivacySetting; | ||
use Woeler\KomootPhp\Enums\Sport; | ||
|
||
class Komoot | ||
{ | ||
private Client $client; | ||
private CookieJar $cookies; | ||
private ?int $userid = null; | ||
|
||
public function __construct(private readonly string $email, private readonly string $password, ?Client $client = null) | ||
{ | ||
$this->client = $client ?? new Client(); | ||
$this->cookies = new CookieJar(); | ||
} | ||
|
||
public function login(): void | ||
{ | ||
$response = $this->client->post('https://account.komoot.com/v1/signin', [ | ||
'json' => ['email' => $this->email, 'password' => $this->password, 'reason' => 'header'], | ||
]); | ||
|
||
$headerSetCookies = $response->getHeader('Set-Cookie'); | ||
|
||
foreach ($headerSetCookies as $header) { | ||
$this->cookies->setCookie(SetCookie::fromString($header)); | ||
} | ||
|
||
$this->setAccountId(); | ||
|
||
$response = $this->client->get('https://account.komoot.com/actions/transfer?type=signin&reason=header', [ | ||
'cookies' => $this->cookies, | ||
]); | ||
|
||
$headerSetCookies = $response->getHeader('Set-Cookie'); | ||
|
||
foreach ($headerSetCookies as $header) { | ||
$this->cookies->setCookie(SetCookie::fromString($header)); | ||
} | ||
} | ||
|
||
private function setAccountId(): void | ||
{ | ||
$response = json_decode($this->client->get('https://account.komoot.com/api/account/v1/session?hl=en', [ | ||
'cookies' => $this->cookies, | ||
])->getBody()->getContents(), true); | ||
|
||
$this->userid = (int) $response['_embedded']['profile']['username']; | ||
} | ||
|
||
public function getTours(int $page = 0, int $limit = 50): array | ||
{ | ||
return json_decode($this->client->get('https://www.komoot.com/api/v007/users/'.$this->userid.'/activities/?page='.$page.'&limit='.$limit, [ | ||
'cookies' => $this->cookies, | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function getAllTours(): array | ||
{ | ||
$page = 0; | ||
$all = []; | ||
while (true) { | ||
$tours = $this->getTours($page, 50); | ||
$all = array_merge($all, $tours['_embedded']['items']); | ||
|
||
if ($page + 1 === $tours['page']['totalPages']) { | ||
break; | ||
} | ||
$page++; | ||
} | ||
|
||
return $all; | ||
} | ||
|
||
public function getTour(int $tourId): array | ||
{ | ||
return json_decode($this->client->get('https://www.komoot.com/api/v007/tours/'.$tourId, [ | ||
'cookies' => $this->cookies, | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function getTourGpx(int $tourId): string | ||
{ | ||
return $this->client->get('https://www.komoot.com/api/v007/tours/'.$tourId.'.gpx', [ | ||
'cookies' => $this->cookies, | ||
])->getBody()->getContents(); | ||
} | ||
|
||
public function renameTour(int $tourId, string $name): array | ||
{ | ||
return json_decode($this->client->patch('https://www.komoot.com/api/v007/tours/'.$tourId, [ | ||
'cookies' => $this->cookies, | ||
'json' => ['name' => $name], | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function changeTourPrivacy(int $tourId, PrivacySetting $privacy): array | ||
{ | ||
return json_decode($this->client->patch('https://www.komoot.com/api/v007/tours/'.$tourId, [ | ||
'cookies' => $this->cookies, | ||
'json' => ['status' => $privacy->value], | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function changeSport(int $tourId, Sport $sport): array | ||
{ | ||
return json_decode($this->client->patch('https://www.komoot.com/api/v007/tours/'.$tourId, [ | ||
'cookies' => $this->cookies, | ||
'json' => ['sport' => $sport->value], | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function getUser(int $userId): array | ||
{ | ||
return json_decode($this->client->get('https://www.komoot.com/api/v007/users/'.$userId, [ | ||
'cookies' => $this->cookies, | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function getSelfUser(): array | ||
{ | ||
return $this->getUser($this->userid); | ||
} | ||
|
||
public function getCollections(int $page = 0, int $limit = 50): array | ||
{ | ||
return json_decode($this->client->get('https://www.komoot.com/api/v007/users/'.$this->userid.'/collections/?page='.$page.'&limit='.$limit, [ | ||
'cookies' => $this->cookies, | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function getCollection(int $collectionId): array | ||
{ | ||
return json_decode($this->client->get('https://www.komoot.com/api/v007/collections/'.$collectionId, [ | ||
'cookies' => $this->cookies, | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function getCollectionTours(int $collectionId): array | ||
{ | ||
return json_decode($this->client->get('https://www.komoot.com/api/v007/collections/'.$collectionId.'/compilation/', [ | ||
'cookies' => $this->cookies, | ||
])->getBody()->getContents(), true); | ||
} | ||
|
||
public function customRequest(string $endpoint, array $guzzleConfig = [], string $method = 'GET'): array | ||
{ | ||
if (! in_array(strtolower($method), ['get', 'delete', 'head', 'options', 'patch', 'post', 'put'])) { | ||
throw new \InvalidArgumentException('Invalid HTTP method given', 1714987334); | ||
} | ||
|
||
return json_decode($this->client->{strtolower($method)}($endpoint, [ | ||
'cookies' => $this->cookies, | ||
] + $guzzleConfig)->getBody()->getContents(), true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Woeler\KomootPhp\Enums; | ||
|
||
enum PrivacySetting: string | ||
{ | ||
case PUBLIC = 'public'; | ||
case PRIVATE = 'private'; | ||
case FRIENDS = 'friends'; | ||
} |
Oops, something went wrong.