summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Steinmetz <richard@steinmetz.cloud>2023-01-09 10:01:16 +0100
committerGitHub <noreply@github.com>2023-01-09 10:01:16 +0100
commite9253b41c5c3b09eeea4da0139cd085d7b300b12 (patch)
tree7306e7eba72683489214af4cbba6343915770bd6
parent219b8442b0cb07c10381bc5878a37de054833d97 (diff)
parent706e9d5bd29f245ba0ff014d54efd21a39d65bb7 (diff)
Merge pull request #3170 from nextcloud/backport/3152/stable5.0
[stable5.0] use Mastodon API instead of scraping
-rw-r--r--lib/Service/Social/MastodonProvider.php50
-rw-r--r--tests/unit/Service/Social/MastodonProviderTest.php39
2 files changed, 56 insertions, 33 deletions
diff --git a/lib/Service/Social/MastodonProvider.php b/lib/Service/Social/MastodonProvider.php
index 99eb5a58..a5db02a3 100644
--- a/lib/Service/Social/MastodonProvider.php
+++ b/lib/Service/Social/MastodonProvider.php
@@ -62,7 +62,6 @@ class MastodonProvider implements ISocialProvider {
public function getImageUrls(array $contact):array {
$profileIds = $this->getProfileIds($contact);
$urls = [];
-
foreach ($profileIds as $profileId) {
$url = $this->getImageUrl($profileId);
if (isset($url)) {
@@ -82,21 +81,15 @@ class MastodonProvider implements ISocialProvider {
public function getImageUrl(string $profileUrl):?string {
try {
$result = $this->httpClient->get($profileUrl);
-
- $htmlResult = new \DOMDocument();
- $htmlResult->loadHTML($result->getBody());
- $img = $htmlResult->getElementById('profile_page_avatar');
- if (!is_null($img)) {
- return $img->getAttribute('data-original');
- }
- return null;
+ $jsonResult = json_decode($result->getBody());
+ return $jsonResult->avatar;
} catch (\Exception $e) {
return null;
}
}
/**
- * Returns all possible profile ids for contact
+ * Returns all possible profile URI for contact by searching the mastodon instance
*
* @param {array} contact information
*
@@ -108,9 +101,21 @@ class MastodonProvider implements ISocialProvider {
if (isset($socialprofiles)) {
foreach ($socialprofiles as $profile) {
if (strtolower($profile['type']) == $this->name) {
- $profileId = $this->cleanupId($profile['value']);
- if (isset($profileId)) {
- $profileIds[] = $profileId;
+ $masto_user_server = $this->cleanupId($profile['value']);
+ if (isset($masto_user_server)) {
+ try {
+ [$masto_user, $masto_server] = $masto_user_server;
+ # search for user on Mastodon
+ $search = $masto_server . '/api/v2/search?q=' . $masto_user;
+ $result = $this->httpClient->get($search);
+ $jsonResult = json_decode($result->getBody());
+ # take first search result
+ $masto_id = $jsonResult->accounts[0]->id;
+ $profileId = $masto_server . "/api/v1/accounts/" . $masto_id;
+ $profileIds[] = $profileId;
+ } catch (\Exception $e) {
+ continue;
+ }
}
}
}
@@ -123,18 +128,25 @@ class MastodonProvider implements ISocialProvider {
*
* @param {string} the value from the contact's x-socialprofile
*
- * @return string
+ * @return array username and server instance
*/
- protected function cleanupId(string $candidate):?string {
+ protected function cleanupId(string $candidate):?array {
$candidate = preg_replace('/^' . preg_quote('x-apple:', '/') . '/', '', $candidate);
try {
+ $user_server = explode('@', $candidate);
if (strpos($candidate, 'http') !== 0) {
- $user_server = explode('@', $candidate);
- $candidate = 'https://' . array_pop($user_server) . '/@' . array_pop($user_server);
+ $masto_server = "https://" . array_pop($user_server);
+ $masto_user = array_pop($user_server);
+ } else {
+ $masto_user = array_pop($user_server);
+ $masto_server = array_pop($user_server);
+ }
+ if ((empty($masto_server)) || (empty($masto_user))) {
+ return null;
}
+ return array($masto_user, $masto_server);
} catch (\Exception $e) {
- $candidate = null;
+ return null;
}
- return $candidate;
}
}
diff --git a/tests/unit/Service/Social/MastodonProviderTest.php b/tests/unit/Service/Social/MastodonProviderTest.php
index 9611bf6b..db1d6fc3 100644
--- a/tests/unit/Service/Social/MastodonProviderTest.php
+++ b/tests/unit/Service/Social/MastodonProviderTest.php
@@ -90,20 +90,33 @@ class MastodonProviderTest extends TestCase {
$contactWithSocial = [
'X-SOCIALPROFILE' => [
["value" => "user1@cloud1", "type" => "mastodon"],
- ["value" => "user2@cloud2", "type" => "mastodon"]
+ ["value" => "@user2@cloud2", "type" => "mastodon"],
+ ["value" => "https://cloud3/@user3", "type" => "mastodon"],
+ ["value" => "https://cloud/wrongSyntax", "type" => "mastodon"],
+ ["value" => "@wrongSyntax", "type" => "mastodon"],
+ ["value" => "wrongSyntax", "type" => "mastodon"]
]
];
$contactWithSocialUrls = [
- "https://cloud1/@user1",
- "https://cloud2/@user2",
+ "https://cloud1/api/v2/search?q=user1",
+ "https://cloud2/api/v2/search?q=user2",
+ "https://cloud3//api/v2/search?q=user3",
+ "https://cloud1/api/v1/accounts/1",
+ "https://cloud2/api/v1/accounts/2",
+ "https://cloud3//api/v1/accounts/3"
];
- $contactWithSocialHtml = [
- '<html><profile id="profile_page_avatar" data-original="user1.jpg" /></html>',
- '<html><profile id="profile_page_avatar" data-original="user2.jpg" /></html>'
+ $contactWithSocialApi = [
+ '{"accounts":[{"id":"1","username":"user1"}]}',
+ '{"accounts":[{"id":"2","username":"user2"}]}',
+ '{"accounts":[{"id":"3","username":"user3"}]}',
+ '{"id":"1","avatar":"user1.jpg"}',
+ '{"id":"2","avatar":"user2.jpg"}',
+ '{"id":"3","avatar":"user3.jpg"}'
];
$contactWithSocialImgs = [
"user1.jpg",
- "user2.jpg"
+ "user2.jpg",
+ "user3.jpg"
];
$contactWithoutSocial = [
@@ -113,19 +126,19 @@ class MastodonProviderTest extends TestCase {
]
];
$contactWithoutSocialUrls = [];
- $contactWithoutSocialHtml = [];
+ $contactWithoutSocialApi = [];
$contactWithoutSocialImgs = [];
return [
'contact with mastodon fields' => [
$contactWithSocial,
- $contactWithSocialHtml,
+ $contactWithSocialApi,
$contactWithSocialUrls,
$contactWithSocialImgs
],
'contact without mastodon fields' => [
$contactWithoutSocial,
- $contactWithoutSocialHtml,
+ $contactWithoutSocialApi,
$contactWithoutSocialUrls,
$contactWithoutSocialImgs
]
@@ -135,9 +148,9 @@ class MastodonProviderTest extends TestCase {
/**
* @dataProvider dataProviderGetImageUrls
*/
- public function testGetImageUrls($contact, $htmls, $urls, $imgs) {
+ public function testGetImageUrls($contact, $api, $urls, $imgs) {
if (count($urls)) {
- $this->response->method("getBody")->willReturnOnConsecutiveCalls(...$htmls);
+ $this->response->method("getBody")->willReturnOnConsecutiveCalls(...$api);
$this->client
->expects($this->exactly(count($urls)))
->method("get")
@@ -146,8 +159,6 @@ class MastodonProviderTest extends TestCase {
}, $urls))
->willReturn($this->response);
}
-
-
$result = $this->provider->getImageUrls($contact);
$this->assertEquals($imgs, $result);
}