[ActivityPub] Add support fox search-box profile/notice grabbing
NoticeSearchAction: - Add new event before finding query matches ActivityPubPlugin: - Subscribe new searchNotice event - Bump minor version number Activitypub_explorer: - Update lookup to make remote-grabbing optional
This commit is contained in:
parent
3392939004
commit
fe2168c5ae
|
@ -1496,3 +1496,16 @@ StartDocNav: Before outputting the docs Nav
|
||||||
|
|
||||||
EndDocNav: After outputting the docs Nav
|
EndDocNav: After outputting the docs Nav
|
||||||
- $nav: The DoclNav widget
|
- $nav: The DoclNav widget
|
||||||
|
|
||||||
|
StartNoticeSearch: Before finding notices that match the given query
|
||||||
|
- string $query: The text query
|
||||||
|
|
||||||
|
StartNoticeSearchShowResults: Before displaying notices matching the query
|
||||||
|
- $out: HTMLOutputter used to output
|
||||||
|
- $query: The text query
|
||||||
|
- $notices: Array of DB notice objects
|
||||||
|
|
||||||
|
EndNoticeSearchShowResults: After displaying notices matching the query
|
||||||
|
- $out: HTMLOutputter used to output
|
||||||
|
- $query: The text query
|
||||||
|
- $notices: Array of DB notice objects
|
||||||
|
|
|
@ -65,6 +65,8 @@ class NoticesearchAction extends SearchAction
|
||||||
|
|
||||||
if (!empty($this->q)) {
|
if (!empty($this->q)) {
|
||||||
|
|
||||||
|
Event::handle('StartNoticeSearch', [$this->q]);
|
||||||
|
|
||||||
$stream = new SearchNoticeStream($this->q, $this->scoped);
|
$stream = new SearchNoticeStream($this->q, $this->scoped);
|
||||||
$page = $this->trimmed('page');
|
$page = $this->trimmed('page');
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ const ACTIVITYPUB_PUBLIC_TO = ['https://www.w3.org/ns/activitystreams#Public',
|
||||||
*/
|
*/
|
||||||
class ActivityPubPlugin extends Plugin
|
class ActivityPubPlugin extends Plugin
|
||||||
{
|
{
|
||||||
const PLUGIN_VERSION = '0.3.0alpha0';
|
const PLUGIN_VERSION = '0.4.0alpha0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Actor's URI from its local $profile
|
* Returns a Actor's URI from its local $profile
|
||||||
|
@ -119,7 +119,7 @@ class ActivityPubPlugin extends Plugin
|
||||||
$client = new HTTPClient();
|
$client = new HTTPClient();
|
||||||
$headers = [];
|
$headers = [];
|
||||||
$headers[] = 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"';
|
$headers[] = 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"';
|
||||||
$headers[] = 'User-Agent: GNUSocialBot v0.1 - https://gnu.io/social';
|
$headers[] = 'User-Agent: GNUSocialBot ' . GNUSOCIAL_VERSION . ' - https://gnu.io/social';
|
||||||
$response = $client->get($url, $headers);
|
$response = $client->get($url, $headers);
|
||||||
$object = json_decode($response->getBody(), true);
|
$object = json_decode($response->getBody(), true);
|
||||||
Activitypub_notice::validate_note($object);
|
Activitypub_notice::validate_note($object);
|
||||||
|
@ -398,6 +398,68 @@ class ActivityPubPlugin extends Plugin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack the notice search-box and try to grab remote profiles or notices.
|
||||||
|
*
|
||||||
|
* Note that, on successful grabbing, this function will redirect to the
|
||||||
|
* new profile/notice, so URL searching is directly affected. A good solution
|
||||||
|
* for this is to store the URLs in the notice text without the https/http
|
||||||
|
* prefixes. This would change the queries for URL searching and therefore we
|
||||||
|
* could do both search and grab.
|
||||||
|
*
|
||||||
|
* @param string $query search query
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function onStartNoticeSearch(string $query): void
|
||||||
|
{
|
||||||
|
if (!common_logged_in()) {
|
||||||
|
// early return, search-only for non-logged sessions
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filter_var($query, FILTER_VALIDATE_URL) &&
|
||||||
|
!preg_match('!^((?:\w+\.)*\w+@(?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+)$!', $query)) {
|
||||||
|
// early return, not an url or webfinger ID
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// someone we know about ?
|
||||||
|
try {
|
||||||
|
$explorer = new Activitypub_explorer();
|
||||||
|
$profile = $explorer->lookup($query, false)[0];
|
||||||
|
if ($profile instanceof Profile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// nope
|
||||||
|
}
|
||||||
|
|
||||||
|
// some notice we know about ?
|
||||||
|
try {
|
||||||
|
$notice = self::grab_notice_from_url($query, false);
|
||||||
|
if ($notice instanceof Notice) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// nope
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to grab profile
|
||||||
|
$aprofile = self::pull_remote_profile($query);
|
||||||
|
if ($aprofile instanceof Activitypub_profile) {
|
||||||
|
$url = common_local_url('userbyid', ['id' => $aprofile->getID()], null, null, false);
|
||||||
|
common_redirect($url, 303);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to grab notice
|
||||||
|
$notice = self::grab_notice_from_url($query);
|
||||||
|
if ($notice instanceof Notice) {
|
||||||
|
$url = common_local_url('shownotice', ['notice' => $notice->getID()]);
|
||||||
|
common_redirect($url, 303);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure necessary tables are filled out.
|
* Make sure necessary tables are filled out.
|
||||||
*
|
*
|
||||||
|
|
|
@ -65,13 +65,14 @@ class Activitypub_explorer
|
||||||
* so that there is no erroneous data
|
* so that there is no erroneous data
|
||||||
*
|
*
|
||||||
* @param string $url User's url
|
* @param string $url User's url
|
||||||
|
* @param bool $remote remote lookup?
|
||||||
* @return array of Profile objects
|
* @return array of Profile objects
|
||||||
* @throws HTTP_Request2_Exception
|
* @throws HTTP_Request2_Exception
|
||||||
* @throws NoProfileException
|
* @throws NoProfileException
|
||||||
* @throws ServerException
|
* @throws ServerException
|
||||||
* @author Diogo Cordeiro <diogo@fc.up.pt>
|
* @author Diogo Cordeiro <diogo@fc.up.pt>
|
||||||
*/
|
*/
|
||||||
public function lookup($url)
|
public function lookup(string $url, bool $remote = true)
|
||||||
{
|
{
|
||||||
if (in_array($url, ACTIVITYPUB_PUBLIC_TO)) {
|
if (in_array($url, ACTIVITYPUB_PUBLIC_TO)) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -80,7 +81,7 @@ class Activitypub_explorer
|
||||||
common_debug('ActivityPub Explorer: Started now looking for '.$url);
|
common_debug('ActivityPub Explorer: Started now looking for '.$url);
|
||||||
$this->discovered_actor_profiles = [];
|
$this->discovered_actor_profiles = [];
|
||||||
|
|
||||||
return $this->_lookup($url);
|
return $this->_lookup($url, $remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,6 +90,7 @@ class Activitypub_explorer
|
||||||
* $discovered_actor_profiles array
|
* $discovered_actor_profiles array
|
||||||
*
|
*
|
||||||
* @param string $url User's url
|
* @param string $url User's url
|
||||||
|
* @param bool $remote remote lookup?
|
||||||
* @return array of Profile objects
|
* @return array of Profile objects
|
||||||
* @throws HTTP_Request2_Exception
|
* @throws HTTP_Request2_Exception
|
||||||
* @throws NoProfileException
|
* @throws NoProfileException
|
||||||
|
@ -96,11 +98,13 @@ class Activitypub_explorer
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @author Diogo Cordeiro <diogo@fc.up.pt>
|
* @author Diogo Cordeiro <diogo@fc.up.pt>
|
||||||
*/
|
*/
|
||||||
private function _lookup($url)
|
private function _lookup(string $url, bool $remote)
|
||||||
{
|
{
|
||||||
// First check if we already have it locally and, if so, return it
|
$grab_local = $this->grab_local_user($url);
|
||||||
// If the local fetch fails: grab it remotely, store locally and return
|
|
||||||
if (! ($this->grab_local_user($url) || $this->grab_remote_user($url))) {
|
// First check if we already have it locally and, if so, return it.
|
||||||
|
// If the local fetch fails and remote grab is required: store locally and return.
|
||||||
|
if (!$grab_local && (!$remote || !$this->grab_remote_user($url))) {
|
||||||
throw new Exception('User not found.');
|
throw new Exception('User not found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +407,7 @@ class Activitypub_explorer
|
||||||
$client = new HTTPClient();
|
$client = new HTTPClient();
|
||||||
$headers = [];
|
$headers = [];
|
||||||
$headers[] = 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"';
|
$headers[] = 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"';
|
||||||
$headers[] = 'User-Agent: GNUSocialBot v0.1 - https://gnu.io/social';
|
$headers[] = 'User-Agent: GNUSocialBot ' . GNUSOCIAL_VERSION . ' - https://gnu.io/social';
|
||||||
$response = $client->get($url, $headers);
|
$response = $client->get($url, $headers);
|
||||||
if (!$response->isOk()) {
|
if (!$response->isOk()) {
|
||||||
throw new Exception('Invalid Actor URL.');
|
throw new Exception('Invalid Actor URL.');
|
||||||
|
|
Loading…
Reference in New Issue
Block a user