forked from grumpydevelop/federator
queue-redis connection + fqdn->CN follow-support
- the resque queue integration is now connected to our redis instance. - IMPORTANT NOTICE: In order for this to work, we needed to change the plugins file under vendor/resque/php-resque/lib/Resque/Redis.php #137 ($this->driver->auth($password, $user); (this change is neccessary for our implementation, as they normally don't support the $user attribute as it would be upstream breaking change). I might create a fork for this, to which we bind with composer - The inboxJob now inherits from api instead of creating its own api instance - inbox now actually works with follows and Undo-follows from mastodon->CN (adding the follower to our followers-db and removing it on undo). - fixed bug where paths for templates was incorrectly adjusted - better/proper support for comment-activity in getExternalPosts
This commit is contained in:
parent
6cf9a030a4
commit
767f51cc5b
8 changed files with 95 additions and 20 deletions
|
@ -47,7 +47,7 @@ class Api extends Main
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->contentType = "application/json";
|
$this->contentType = "application/json";
|
||||||
Main::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -127,7 +127,6 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
||||||
if (!isset($user)) {
|
if (!isset($user)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = \Resque::enqueue('inbox', 'Federator\\Jobs\\InboxJob', [
|
$token = \Resque::enqueue('inbox', 'Federator\\Jobs\\InboxJob', [
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
'activity' => $inboxActivity->toObject(),
|
'activity' => $inboxActivity->toObject(),
|
||||||
|
@ -160,6 +159,9 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
||||||
if ($user === null || $user->id === null) {
|
if ($user === null || $user->id === null) {
|
||||||
throw new \Federator\Exceptions\ServerError("Inbox::postForUser couldn't find user: $_user");
|
throw new \Federator\Exceptions\ServerError("Inbox::postForUser couldn't find user: $_user");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Not a local user, nothing to do
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootDir = PROJECT_ROOT . '/';
|
$rootDir = PROJECT_ROOT . '/';
|
||||||
|
@ -170,6 +172,44 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
||||||
FILE_APPEND
|
FILE_APPEND
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$type = $inboxActivity->getType();
|
||||||
|
|
||||||
|
if ($type === 'Follow') {
|
||||||
|
// Someone wants to follow our user
|
||||||
|
$actor = $inboxActivity->getAActor(); // The follower's actor URI
|
||||||
|
if ($actor !== '') {
|
||||||
|
// Extract follower username (you may need to adjust this logic)
|
||||||
|
$followerUsername = basename((string) (parse_url($actor, PHP_URL_PATH) ?? ''));
|
||||||
|
$followerDomain = parse_url($actor, PHP_URL_HOST);
|
||||||
|
if (is_string($followerDomain)) {
|
||||||
|
$followerId = "{$followerUsername}@{$followerDomain}";
|
||||||
|
|
||||||
|
// Save the follow relationship
|
||||||
|
\Federator\DIO\Followers::addFollow($dbh, $followerId, $user->id, $followerDomain);
|
||||||
|
error_log("Inbox::postForUser: Added follower $followerId for user $user->id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($type === 'Undo') {
|
||||||
|
// Check if this is an Undo of a Follow (i.e., Unfollow)
|
||||||
|
$object = $inboxActivity->getObject();
|
||||||
|
if (is_object($object) && method_exists($object, 'getType') && $object->getType() === 'Follow') {
|
||||||
|
if ($object instanceof \Federator\Data\ActivityPub\Common\Activity) {
|
||||||
|
$actor = $object->getAActor();
|
||||||
|
if ($actor !== '') {
|
||||||
|
$followerUsername = basename((string) (parse_url($actor, PHP_URL_PATH) ?? ''));
|
||||||
|
$followerDomain = parse_url($actor, PHP_URL_HOST);
|
||||||
|
if (is_string($followerDomain)) {
|
||||||
|
$followerId = "{$followerUsername}@{$followerDomain}";
|
||||||
|
|
||||||
|
// Remove the follow relationship
|
||||||
|
\Federator\DIO\Followers::removeFollow($dbh, $followerId, $user->id);
|
||||||
|
error_log("Inbox::postForUser: Removed follower $followerId for user $user->id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Federator\Jobs;
|
namespace Federator\Jobs;
|
||||||
|
|
||||||
class InboxJob
|
class InboxJob extends \Federator\Api
|
||||||
{
|
{
|
||||||
/** @var array<string, mixed> $args Arguments for the job */
|
/** @var array<string, mixed> $args Arguments for the job */
|
||||||
public $args = [];
|
public $args = [];
|
||||||
|
@ -28,19 +28,21 @@ class InboxJob
|
||||||
*/
|
*/
|
||||||
protected $dbh;
|
protected $dbh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up environment for this job
|
* Set up environment for this job
|
||||||
*/
|
*/
|
||||||
public function setUp(): void
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
$contentnation = new \Federator\Api();
|
$this->openDatabase();
|
||||||
$contentnation->openDatabase();
|
$this->loadPlugins();
|
||||||
$contentnation->loadPlugins();
|
|
||||||
|
|
||||||
// Recreate dependencies as needed
|
|
||||||
$this->dbh = $contentnation->getDatabase(); // get DB connection
|
|
||||||
$this->connector = $contentnation->getConnector(); // get connector
|
|
||||||
$this->cache = $contentnation->getCache(); // get cache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -232,9 +232,10 @@ class Main
|
||||||
*/
|
*/
|
||||||
public function renderTemplate($template, $data)
|
public function renderTemplate($template, $data)
|
||||||
{
|
{
|
||||||
|
$rootDir = PROJECT_ROOT . '/';
|
||||||
$smarty = new \Smarty\Smarty();
|
$smarty = new \Smarty\Smarty();
|
||||||
$smarty->setCompileDir(PROJECT_ROOT . $this->config['templates']['compiledir']);
|
$smarty->setCompileDir($rootDir . $this->config['templates']['compiledir']);
|
||||||
$smarty->setTemplateDir((string) realpath(PROJECT_ROOT . $this->config['templates']['path']));
|
$smarty->setTemplateDir((string) realpath($rootDir . $this->config['templates']['path']));
|
||||||
$smarty->assign('database', $this->dbh);
|
$smarty->assign('database', $this->dbh);
|
||||||
$smarty->assign('maininstance', $this);
|
$smarty->assign('maininstance', $this);
|
||||||
foreach ($data as $key => $value) {
|
foreach ($data as $key => $value) {
|
||||||
|
|
|
@ -4,6 +4,18 @@ define('PROJECT_ROOT', dirname(__DIR__, 3));
|
||||||
|
|
||||||
require_once PROJECT_ROOT . '/vendor/autoload.php';
|
require_once PROJECT_ROOT . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
$config = parse_ini_file(PROJECT_ROOT . '/rediscache.ini');
|
||||||
|
|
||||||
|
// Set the Redis backend for Resque
|
||||||
|
$redisUrl = sprintf(
|
||||||
|
'redis://%s:%s@%s:%d',
|
||||||
|
urlencode($config['username']),
|
||||||
|
urlencode($config['password']),
|
||||||
|
$config['host'],
|
||||||
|
intval($config['port'], 10)
|
||||||
|
);
|
||||||
|
\Resque::setBackend($redisUrl);
|
||||||
|
|
||||||
// Start the worker
|
// Start the worker
|
||||||
$worker = new \Resque_Worker(['inbox']);
|
$worker = new \Resque_Worker(['inbox']);
|
||||||
|
|
||||||
|
|
|
@ -170,8 +170,17 @@ class ContentNation implements Connector
|
||||||
$posts[] = $create;
|
$posts[] = $create;
|
||||||
break; // Article
|
break; // Article
|
||||||
case 'Comment':
|
case 'Comment':
|
||||||
|
$commentJson = $activity;
|
||||||
|
$commentJson['type'] = 'Note';
|
||||||
|
$commentJson['summary'] = $activity['subject'];
|
||||||
|
$note = \Federator\Data\ActivityPub\Factory::newFromJson($commentJson, "");
|
||||||
|
if ($note === null) {
|
||||||
|
error_log("ContentNation::getRemotePostsByUser couldn't create comment");
|
||||||
$comment = new \Federator\Data\ActivityPub\Common\Activity('Comment');
|
$comment = new \Federator\Data\ActivityPub\Common\Activity('Comment');
|
||||||
$create->setObject($comment);
|
$create->setObject($comment);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$create->setObject($note);
|
||||||
$posts[] = $create;
|
$posts[] = $create;
|
||||||
break; // Comment
|
break; // Comment
|
||||||
case 'Vote':
|
case 'Vote':
|
||||||
|
|
|
@ -71,6 +71,16 @@ class RedisCache implements Cache
|
||||||
$this->redis->pconnect($this->config['host'], intval($this->config['port'], 10));
|
$this->redis->pconnect($this->config['host'], intval($this->config['port'], 10));
|
||||||
// @phan-suppress-next-line PhanTypeMismatchArgumentInternalProbablyReal
|
// @phan-suppress-next-line PhanTypeMismatchArgumentInternalProbablyReal
|
||||||
$this->redis->auth([$this->config['username'], $this->config['password']]);
|
$this->redis->auth([$this->config['username'], $this->config['password']]);
|
||||||
|
|
||||||
|
// Set the Redis backend for Resque
|
||||||
|
$redisUrl = sprintf(
|
||||||
|
'redis://%s:%s@%s:%d',
|
||||||
|
urlencode($this->config['username']),
|
||||||
|
urlencode($this->config['password']),
|
||||||
|
$this->config['host'],
|
||||||
|
intval($this->config['port'], 10)
|
||||||
|
);
|
||||||
|
\Resque::setBackend($redisUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +114,8 @@ class RedisCache implements Cache
|
||||||
* @param array<string, mixed> $jsonData the json data from our platfrom @unused-param
|
* @param array<string, mixed> $jsonData the json data from our platfrom @unused-param
|
||||||
* @return \Federator\Data\ActivityPub\Common\Activity|false
|
* @return \Federator\Data\ActivityPub\Common\Activity|false
|
||||||
*/
|
*/
|
||||||
public function jsonToActivity(array $jsonData) {
|
public function jsonToActivity(array $jsonData)
|
||||||
|
{
|
||||||
error_log("rediscache::jsonToActivity not implemented");
|
error_log("rediscache::jsonToActivity not implemented");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +309,7 @@ class RedisCache implements Cache
|
||||||
{
|
{
|
||||||
$key = self::createKey('s', $_session . $_user);
|
$key = self::createKey('s', $_session . $_user);
|
||||||
$serialized = $user->toJson();
|
$serialized = $user->toJson();
|
||||||
$this->redis->setEx($key, $this->userTTL, $serialized,);
|
$this->redis->setEx($key, $this->userTTL, $serialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -314,7 +325,7 @@ class RedisCache implements Cache
|
||||||
$this->connect();
|
$this->connect();
|
||||||
}
|
}
|
||||||
$key = self::createKey('publickey', $keyId);
|
$key = self::createKey('publickey', $keyId);
|
||||||
$this->redis->setEx($key, $this->publicKeyPemTTL, $publicKeyPem); // TTL = 1 hour
|
$this->redis->setEx($key, $this->publicKeyPemTTL, $publicKeyPem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue