kopia lustrzana https://github.com/pixelfed/pixelfed
commit
4fb007788e
|
@ -68,6 +68,8 @@
|
||||||
- Update StoryIndexService, fix markSeen method ([e09291775](https://github.com/pixelfed/pixelfed/commit/e09291775))
|
- Update StoryIndexService, fix markSeen method ([e09291775](https://github.com/pixelfed/pixelfed/commit/e09291775))
|
||||||
- Update StoryComposeController, add StoryIndexService support ([6c701b335](https://github.com/pixelfed/pixelfed/commit/6c701b335))
|
- Update StoryComposeController, add StoryIndexService support ([6c701b335](https://github.com/pixelfed/pixelfed/commit/6c701b335))
|
||||||
- Update StoryIndexService, improve predis + phpredis support ([564d8d109](https://github.com/pixelfed/pixelfed/commit/564d8d109))
|
- Update StoryIndexService, improve predis + phpredis support ([564d8d109](https://github.com/pixelfed/pixelfed/commit/564d8d109))
|
||||||
|
- Update StoryApiV1Controller, add missing validation rule ([76d9ded69](https://github.com/pixelfed/pixelfed/commit/76d9ded69))
|
||||||
|
- Update StoryIndexService, improve predis/phpredis support ([53b74bf16](https://github.com/pixelfed/pixelfed/commit/53b74bf16))
|
||||||
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
||||||
|
|
||||||
## [v0.12.5 (2025-03-23)](https://github.com/pixelfed/pixelfed/compare/v0.12.5...dev)
|
## [v0.12.5 (2025-03-23)](https://github.com/pixelfed/pixelfed/compare/v0.12.5...dev)
|
||||||
|
|
|
@ -399,8 +399,9 @@ class StoryApiV1Controller extends Controller
|
||||||
'overlays.*.absoluteY' => 'numeric',
|
'overlays.*.absoluteY' => 'numeric',
|
||||||
'overlays.*.color' => 'hex_color',
|
'overlays.*.color' => 'hex_color',
|
||||||
'overlays.*.backgroundColor' => 'string|in:transparent,#FFFFFF,#000000',
|
'overlays.*.backgroundColor' => 'string|in:transparent,#FFFFFF,#000000',
|
||||||
'overlays.*.content' => 'string|min:1|max:80',
|
'overlays.*.content' => 'string|min:1|max:250',
|
||||||
'overlays.*.fontSize' => 'numeric|min:10|max:80',
|
'overlays.*.fontSize' => 'numeric|min:10|max:180',
|
||||||
|
'overlays.*.fontFamily' => 'string|in:default,serif,mono,rounded,bold',
|
||||||
'overlays.*.rotation' => 'numeric|min:-360|max:360',
|
'overlays.*.rotation' => 'numeric|min:-360|max:360',
|
||||||
'overlays.*.scale' => 'numeric|min:0.1|max:5',
|
'overlays.*.scale' => 'numeric|min:0.1|max:5',
|
||||||
'overlays.*.x' => 'numeric',
|
'overlays.*.x' => 'numeric',
|
||||||
|
|
|
@ -99,6 +99,52 @@ class StoryIndexService
|
||||||
return $this->redisToBool($command());
|
return $this->redisToBool($command());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely convert Redis result to array, handling both predis and phpredis
|
||||||
|
*/
|
||||||
|
private function redisToArray($value): array
|
||||||
|
{
|
||||||
|
if (is_array($value)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($value)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle phpredis object returns that might be iterable
|
||||||
|
if (is_object($value)) {
|
||||||
|
if (method_exists($value, 'toArray')) {
|
||||||
|
return $value->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value instanceof \Iterator || $value instanceof \IteratorAggregate) {
|
||||||
|
return iterator_to_array($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method_exists($value, '__toString')) {
|
||||||
|
$str = $value->__toString();
|
||||||
|
|
||||||
|
return $str ? [$str] : [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle single values
|
||||||
|
if (is_string($value) || is_numeric($value)) {
|
||||||
|
return [$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely execute Redis commands that return arrays
|
||||||
|
*/
|
||||||
|
private function redisArray(callable $command): array
|
||||||
|
{
|
||||||
|
return $this->redisToArray($command());
|
||||||
|
}
|
||||||
|
|
||||||
public function indexStory($story): void
|
public function indexStory($story): void
|
||||||
{
|
{
|
||||||
if (! $story->active) {
|
if (! $story->active) {
|
||||||
|
@ -283,7 +329,7 @@ class StoryIndexService
|
||||||
|
|
||||||
private function clearStoryCache(): void
|
private function clearStoryCache(): void
|
||||||
{
|
{
|
||||||
$storyKeys = Redis::keys('story:*');
|
$storyKeys = $this->redisArray(fn () => Redis::keys('story:*'));
|
||||||
$storyKeys = array_filter($storyKeys, function ($key) {
|
$storyKeys = array_filter($storyKeys, function ($key) {
|
||||||
return ! str_contains($key, 'following:');
|
return ! str_contains($key, 'following:');
|
||||||
});
|
});
|
||||||
|
@ -348,7 +394,7 @@ class StoryIndexService
|
||||||
$authorIds = [];
|
$authorIds = [];
|
||||||
|
|
||||||
if ($followingCount > 1500) {
|
if ($followingCount > 1500) {
|
||||||
$active = Redis::smembers('story:active_authors');
|
$active = $this->redisArray(fn () => Redis::smembers('story:active_authors'));
|
||||||
if ($active) {
|
if ($active) {
|
||||||
$results = Redis::pipeline(function ($pipe) use ($active, $pid) {
|
$results = Redis::pipeline(function ($pipe) use ($active, $pid) {
|
||||||
foreach ($active as $aid) {
|
foreach ($active as $aid) {
|
||||||
|
@ -367,7 +413,7 @@ class StoryIndexService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$authorIds = Redis::sinter("following:{$pid}", 'story:active_authors');
|
$authorIds = $this->redisArray(fn () => Redis::sinter("following:{$pid}", 'story:active_authors'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->redisInt(fn () => Redis::zcard($this->authorKey($pid))) > 0) {
|
if ($this->redisInt(fn () => Redis::zcard($this->authorKey($pid))) > 0) {
|
||||||
|
@ -379,16 +425,18 @@ class StoryIndexService
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$responses = Redis::pipeline(function ($pipe) use ($authorIds, $opt) {
|
$responses = $this->redisArray(fn () => Redis::pipeline(function ($pipe) use ($authorIds, $opt) {
|
||||||
foreach ($authorIds as $aid) {
|
foreach ($authorIds as $aid) {
|
||||||
$pipe->zrevrange("story:by_author:{$aid}", 0, -1, $opt);
|
$pipe->zrevrange("story:by_author:{$aid}", 0, -1, $opt);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
$authorToStoryIds = [];
|
$authorToStoryIds = [];
|
||||||
$authorLatestTs = [];
|
$authorLatestTs = [];
|
||||||
foreach ($authorIds as $i => $aid) {
|
foreach ($authorIds as $i => $aid) {
|
||||||
$withScores = $responses[$i] ?? [];
|
$withScores = $responses[$i] ?? [];
|
||||||
|
// Ensure withScores is also an array
|
||||||
|
$withScores = $this->redisToArray($withScores);
|
||||||
$authorToStoryIds[$aid] = array_keys($withScores);
|
$authorToStoryIds[$aid] = array_keys($withScores);
|
||||||
$authorLatestTs[$aid] = $withScores ? (float) array_values($withScores)[0] : 0.0;
|
$authorLatestTs[$aid] = $withScores ? (float) array_values($withScores)[0] : 0.0;
|
||||||
}
|
}
|
||||||
|
@ -401,7 +449,7 @@ class StoryIndexService
|
||||||
|
|
||||||
$storyMap = [];
|
$storyMap = [];
|
||||||
foreach ($allStoryIds as $sid) {
|
foreach ($allStoryIds as $sid) {
|
||||||
$h = Redis::hgetall($this->storyKey($sid));
|
$h = $this->redisArray(fn () => Redis::hgetall($this->storyKey($sid)));
|
||||||
if (! empty($h)) {
|
if (! empty($h)) {
|
||||||
$storyMap[$sid] = $h;
|
$storyMap[$sid] = $h;
|
||||||
}
|
}
|
||||||
|
@ -409,10 +457,12 @@ class StoryIndexService
|
||||||
|
|
||||||
$seenCache = [];
|
$seenCache = [];
|
||||||
foreach ($authorIds as $aid) {
|
foreach ($authorIds as $aid) {
|
||||||
$seenCache[$aid] = Redis::smembers($this->seenKey($viewerId, (int) $aid)) ?: [];
|
$seenCache[$aid] = $this->redisArray(fn () => Redis::smembers($this->seenKey($viewerId, (int) $aid)));
|
||||||
$seenCache[$aid] = array_flip($seenCache[$aid]);
|
$seenCache[$aid] = array_flip($seenCache[$aid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure $authorIds is always an array before using array_map
|
||||||
|
$authorIds = $this->redisToArray($authorIds);
|
||||||
$profiles = $profileHydrator(array_map('intval', $authorIds));
|
$profiles = $profileHydrator(array_map('intval', $authorIds));
|
||||||
|
|
||||||
$nodes = [];
|
$nodes = [];
|
||||||
|
|
Ładowanie…
Reference in New Issue