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()
|
||||
{
|
||||
$this->contentType = "application/json";
|
||||
Main::__construct();
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -107,7 +107,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
|
||||
// Extract username from the actor URL
|
||||
$username = basename((string)(parse_url($actor, PHP_URL_PATH) ?? ''));
|
||||
$username = basename((string) (parse_url($actor, PHP_URL_PATH) ?? ''));
|
||||
$domain = parse_url($actor, PHP_URL_HOST);
|
||||
if ($username === null || $domain === null) {
|
||||
error_log("Inbox::post no username or domain found");
|
||||
|
@ -127,7 +127,6 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
if (!isset($user)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$token = \Resque::enqueue('inbox', 'Federator\\Jobs\\InboxJob', [
|
||||
'user' => $user,
|
||||
'activity' => $inboxActivity->toObject(),
|
||||
|
@ -160,6 +159,9 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
if ($user === null || $user->id === null) {
|
||||
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 . '/';
|
||||
|
@ -170,6 +172,44 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class Activity extends APObject
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getAActor() : string
|
||||
public function getAActor(): string
|
||||
{
|
||||
return $this->aactor;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Federator\Jobs;
|
||||
|
||||
class InboxJob
|
||||
class InboxJob extends \Federator\Api
|
||||
{
|
||||
/** @var array<string, mixed> $args Arguments for the job */
|
||||
public $args = [];
|
||||
|
@ -28,19 +28,21 @@ class InboxJob
|
|||
*/
|
||||
protected $dbh;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up environment for this job
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
$contentnation = new \Federator\Api();
|
||||
$contentnation->openDatabase();
|
||||
$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
|
||||
$this->openDatabase();
|
||||
$this->loadPlugins();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -232,9 +232,10 @@ class Main
|
|||
*/
|
||||
public function renderTemplate($template, $data)
|
||||
{
|
||||
$rootDir = PROJECT_ROOT . '/';
|
||||
$smarty = new \Smarty\Smarty();
|
||||
$smarty->setCompileDir(PROJECT_ROOT . $this->config['templates']['compiledir']);
|
||||
$smarty->setTemplateDir((string) realpath(PROJECT_ROOT . $this->config['templates']['path']));
|
||||
$smarty->setCompileDir($rootDir . $this->config['templates']['compiledir']);
|
||||
$smarty->setTemplateDir((string) realpath($rootDir . $this->config['templates']['path']));
|
||||
$smarty->assign('database', $this->dbh);
|
||||
$smarty->assign('maininstance', $this);
|
||||
foreach ($data as $key => $value) {
|
||||
|
|
|
@ -4,6 +4,18 @@ define('PROJECT_ROOT', dirname(__DIR__, 3));
|
|||
|
||||
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
|
||||
$worker = new \Resque_Worker(['inbox']);
|
||||
|
||||
|
|
|
@ -170,8 +170,17 @@ class ContentNation implements Connector
|
|||
$posts[] = $create;
|
||||
break; // Article
|
||||
case 'Comment':
|
||||
$comment = new \Federator\Data\ActivityPub\Common\Activity('Comment');
|
||||
$create->setObject($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');
|
||||
$create->setObject($comment);
|
||||
break;
|
||||
}
|
||||
$create->setObject($note);
|
||||
$posts[] = $create;
|
||||
break; // Comment
|
||||
case 'Vote':
|
||||
|
|
|
@ -71,6 +71,16 @@ class RedisCache implements Cache
|
|||
$this->redis->pconnect($this->config['host'], intval($this->config['port'], 10));
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentInternalProbablyReal
|
||||
$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
|
||||
* @return \Federator\Data\ActivityPub\Common\Activity|false
|
||||
*/
|
||||
public function jsonToActivity(array $jsonData) {
|
||||
public function jsonToActivity(array $jsonData)
|
||||
{
|
||||
error_log("rediscache::jsonToActivity not implemented");
|
||||
return false;
|
||||
}
|
||||
|
@ -298,7 +309,7 @@ class RedisCache implements Cache
|
|||
{
|
||||
$key = self::createKey('s', $_session . $_user);
|
||||
$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();
|
||||
}
|
||||
$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