[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
c06182c38f
commit
19409cb999
@ -1496,3 +1496,16 @@ StartDocNav: Before outputting the docs Nav
|
||||
|
||||
EndDocNav: After outputting the docs Nav
|
||||
- $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)) {
|
||||
|
||||
Event::handle('StartNoticeSearch', [$this->q]);
|
||||
|
||||
$stream = new SearchNoticeStream($this->q, $this->scoped);
|
||||
$page = $this->trimmed('page');
|
||||
|
||||
|
@ -50,7 +50,7 @@ const ACTIVITYPUB_PUBLIC_TO = ['https://www.w3.org/ns/activitystreams#Public',
|
||||
*/
|
||||
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
|
||||
@ -119,7 +119,7 @@ class ActivityPubPlugin extends Plugin
|
||||
$client = new HTTPClient();
|
||||
$headers = [];
|
||||
$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);
|
||||
$object = json_decode($response->getBody(), true);
|
||||
Activitypub_notice::validate_note($object);
|
||||
@ -398,6 +398,68 @@ class ActivityPubPlugin extends Plugin
|
||||
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.
|
||||
*
|
||||
|
@ -65,13 +65,14 @@ class Activitypub_explorer
|
||||
* so that there is no erroneous data
|
||||
*
|
||||
* @param string $url User's url
|
||||
* @param bool $remote remote lookup?
|
||||
* @return array of Profile objects
|
||||
* @throws HTTP_Request2_Exception
|
||||
* @throws NoProfileException
|
||||
* @throws ServerException
|
||||
* @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)) {
|
||||
return [];
|
||||
@ -80,7 +81,7 @@ class Activitypub_explorer
|
||||
common_debug('ActivityPub Explorer: Started now looking for '.$url);
|
||||
$this->discovered_actor_profiles = [];
|
||||
|
||||
return $this->_lookup($url);
|
||||
return $this->_lookup($url, $remote);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,6 +90,7 @@ class Activitypub_explorer
|
||||
* $discovered_actor_profiles array
|
||||
*
|
||||
* @param string $url User's url
|
||||
* @param bool $remote remote lookup?
|
||||
* @return array of Profile objects
|
||||
* @throws HTTP_Request2_Exception
|
||||
* @throws NoProfileException
|
||||
@ -96,11 +98,13 @@ class Activitypub_explorer
|
||||
* @throws Exception
|
||||
* @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
|
||||
// If the local fetch fails: grab it remotely, store locally and return
|
||||
if (! ($this->grab_local_user($url) || $this->grab_remote_user($url))) {
|
||||
$grab_local = $this->grab_local_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.');
|
||||
}
|
||||
|
||||
@ -403,7 +407,7 @@ class Activitypub_explorer
|
||||
$client = new HTTPClient();
|
||||
$headers = [];
|
||||
$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);
|
||||
if (!$response->isOk()) {
|
||||
throw new Exception('Invalid Actor URL.');
|
||||
|
Loading…
Reference in New Issue
Block a user