Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mastodon username search #1988

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions cypress/e2e/layout_dataset.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ describe('Layout Designer', function() {
cy.get('.select2-container--open').contains('test');
cy.get('.select2-container--open .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li:first').contains('test').click();

cy.get('[contenteditable="true" ]').should('exist');
cy.get('.cke_editable_inline').clear();
cy.get('.cke_editable_inline').type('No data to show').trigger('change');

cy.get('[name="lowerLimit"]').clear().type('1');
cy.get('[name="upperLimit"]').clear().type('10');
cy.get('.order-clause-row > :nth-child(2) > .form-control').select('Text', {force: true});
Expand Down
68 changes: 54 additions & 14 deletions lib/Widget/MastodonProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
namespace Xibo\Widget;

use Carbon\Carbon;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use Xibo\Widget\DataType\SocialMedia;
use Xibo\Widget\Provider\DataProviderInterface;
Expand All @@ -45,42 +47,55 @@ public function fetchData(DataProviderInterface $dataProvider): WidgetProviderIn
try {
$httpOptions = [
'timeout' => 20, // wait no more than 20 seconds
'query' => [
'limit' => $dataProvider->getProperty('numItems', 15)
]
];

$queryOptions = [
'limit' => $dataProvider->getProperty('numItems', 15)
];

if ($dataProvider->getProperty('searchOn', 'all') === 'local') {
$httpOptions['query']['local'] = true;
$queryOptions['local'] = true;
} elseif ($dataProvider->getProperty('searchOn', 'all') === 'remote') {
$httpOptions['query']['remote'] = true;
$queryOptions['remote'] = true;
}

// Media Only
if ($dataProvider->getProperty('onlyMedia', 0)) {
$httpOptions['query']['only_media'] = true;
$queryOptions['only_media'] = true;
}

if (!empty($dataProvider->getProperty('serverUrl', ''))) {
$uri = $dataProvider->getProperty('serverUrl', '');
$uri = $dataProvider->getProperty('serverUrl');
}

// Hashtag: When empty we should do a public search, when filled we should do a hashtag search
// Hashtag
$hashtag = trim($dataProvider->getProperty('hashtag', ''));
if (!empty($hashtag)) {
$uri = rtrim($uri, '/').'/api/v1/timelines/tag/'. trim($hashtag, '#');

// when username is provided do not search in public timeline
if (!empty($dataProvider->getProperty('userName', ''))) {
// username search: get account ID, always returns one record
$accountId = $this->getAccountId($uri, $dataProvider->getProperty('userName'), $dataProvider);
$queryOptions['tagged'] = trim($hashtag, '#');
$uri = rtrim($uri, '/') . '/api/v1/accounts/' . $accountId . '/statuses?';
} else {
$uri = rtrim($uri, '/').'/api/v1/timelines/public';
// Hashtag: When empty we should do a public search, when filled we should do a hashtag search
if (!empty($hashtag)) {
$uri = rtrim($uri, '/') . '/api/v1/timelines/tag/' . trim($hashtag, '#');
} else {
$uri = rtrim($uri, '/') . '/api/v1/timelines/public';
}
}

$this->getLog()->debug('Mastodon: uri: ' . $uri . ' httpOptions: '. json_encode($httpOptions));

$response = $dataProvider
->getGuzzleClient($httpOptions)
->get($uri);
->get($uri, [
'query' => $queryOptions
]);

$result = json_decode($response->getBody()->getContents(), true);

$this->getLog()->debug('Mastodon: uri: ' . $uri . ' httpOptions: ' . json_encode($httpOptions));

$this->getLog()->debug('Mastodon: count: ' . count($result));

// Expiry time for any media that is downloaded
Expand Down Expand Up @@ -157,4 +172,29 @@ public function getDataModifiedDt(DataProviderInterface $dataProvider): ?Carbon
{
return null;
}

/**
* Get Mastodon Account Id from username
* @throws GuzzleException
*/
private function getAccountId(string $uri, string $username, DataProviderInterface $dataProvider)
{
$uri = rtrim($uri, '/').'/api/v1/accounts/lookup?';

$httpOptions = [
'timeout' => 20, // wait no more than 20 seconds
'query' => [
'acct' => $username
],
];
$response = $dataProvider
->getGuzzleClient($httpOptions)
->get($uri);

$result = json_decode($response->getBody()->getContents(), true);

$this->getLog()->debug('Mastodon: getAccountId: ID ' . $result['id']);

return $result['id'];
}
}
7 changes: 6 additions & 1 deletion modules/mastodon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<class>\Xibo\Widget\MastodonProvider</class>
<type>mastodon</type>
<dataType>social-media</dataType>
<dataCacheKey>%hashtag%_%numItems%_%searchOn%_%onlyMedia%_%serverUrl%</dataCacheKey>
<dataCacheKey>%hashtag%_%numItems%_%searchOn%_%onlyMedia%_%serverUrl%_%userName%</dataCacheKey>
<schemaVersion>1</schemaVersion>
<assignable>1</assignable>
<regionSpecific>1</regionSpecific>
Expand Down Expand Up @@ -70,6 +70,11 @@
<helpText>Leave empty to use the one from settings.</helpText>
<default></default>
</property>
<property id="userName" type="text">
<title>Username</title>
<helpText>Provide Mastodon username to get public statuses from the account.</helpText>
<default></default>
</property>
<property id="numItems" type="number">
<title>Count</title>
<helpText>The number of posts to return (default = 15).</helpText>
Expand Down
Loading