mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-25 15:55:22 +00:00
Update ApiV1Controller, add experimental home timeline support to v1/timelines/home
This commit is contained in:
parent
2a8a299058
commit
24c370ee22
1 changed files with 103 additions and 33 deletions
|
@ -71,6 +71,7 @@ use App\Services\{
|
||||||
CollectionService,
|
CollectionService,
|
||||||
FollowerService,
|
FollowerService,
|
||||||
HashtagService,
|
HashtagService,
|
||||||
|
HomeTimelineService,
|
||||||
InstanceService,
|
InstanceService,
|
||||||
LikeService,
|
LikeService,
|
||||||
NetworkTimelineService,
|
NetworkTimelineService,
|
||||||
|
@ -102,6 +103,7 @@ use Illuminate\Support\Facades\RateLimiter;
|
||||||
use Purify;
|
use Purify;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use App\Http\Resources\MastoApi\FollowedTagResource;
|
use App\Http\Resources\MastoApi\FollowedTagResource;
|
||||||
|
use App\Jobs\HomeFeedPipeline\FeedWarmCachePipeline;
|
||||||
|
|
||||||
class ApiV1Controller extends Controller
|
class ApiV1Controller extends Controller
|
||||||
{
|
{
|
||||||
|
@ -2129,11 +2131,11 @@ class ApiV1Controller extends Controller
|
||||||
public function timelineHome(Request $request)
|
public function timelineHome(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request,[
|
$this->validate($request,[
|
||||||
'page' => 'sometimes|integer|max:40',
|
'page' => 'sometimes|integer|max:40',
|
||||||
'min_id' => 'sometimes|integer|min:0|max:' . PHP_INT_MAX,
|
'min_id' => 'sometimes|integer|min:0|max:' . PHP_INT_MAX,
|
||||||
'max_id' => 'sometimes|integer|min:0|max:' . PHP_INT_MAX,
|
'max_id' => 'sometimes|integer|min:0|max:' . PHP_INT_MAX,
|
||||||
'limit' => 'sometimes|integer|min:1|max:100',
|
'limit' => 'sometimes|integer|min:1|max:40',
|
||||||
'include_reblogs' => 'sometimes',
|
'include_reblogs' => 'sometimes',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$napi = $request->has(self::PF_API_ENTITY_KEY);
|
$napi = $request->has(self::PF_API_ENTITY_KEY);
|
||||||
|
@ -2142,13 +2144,77 @@ class ApiV1Controller extends Controller
|
||||||
$max = $request->input('max_id');
|
$max = $request->input('max_id');
|
||||||
$limit = $request->input('limit') ?? 20;
|
$limit = $request->input('limit') ?? 20;
|
||||||
$pid = $request->user()->profile_id;
|
$pid = $request->user()->profile_id;
|
||||||
$includeReblogs = $request->filled('include_reblogs');
|
$includeReblogs = $request->filled('include_reblogs');
|
||||||
$nullFields = $includeReblogs ?
|
$nullFields = $includeReblogs ?
|
||||||
['in_reply_to_id'] :
|
['in_reply_to_id'] :
|
||||||
['in_reply_to_id', 'reblog_of_id'];
|
['in_reply_to_id', 'reblog_of_id'];
|
||||||
$inTypes = $includeReblogs ?
|
$inTypes = $includeReblogs ?
|
||||||
['photo', 'photo:album', 'video', 'video:album', 'photo:video:album', 'share'] :
|
['photo', 'photo:album', 'video', 'video:album', 'photo:video:album', 'share'] :
|
||||||
['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'];
|
['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'];
|
||||||
|
|
||||||
|
if(config('exp.cached_home_timeline')) {
|
||||||
|
if($min || $max) {
|
||||||
|
if($request->has('min_id')) {
|
||||||
|
$res = HomeTimelineService::getRankedMinId($pid, $min ?? 0, $limit + 10);
|
||||||
|
} else {
|
||||||
|
$res = HomeTimelineService::getRankedMaxId($pid, $max ?? 0, $limit + 10);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$res = HomeTimelineService::get($pid, 0, $limit + 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$res) {
|
||||||
|
$res = Cache::has('pf:services:apiv1:home:cached:coldbootcheck:' . $pid);
|
||||||
|
if(!$res) {
|
||||||
|
Cache::set('pf:services:apiv1:home:cached:coldbootcheck:' . $pid, 1, 86400);
|
||||||
|
FeedWarmCachePipeline::dispatchSync($pid);
|
||||||
|
return response()->json([], 206);
|
||||||
|
} else {
|
||||||
|
Cache::set('pf:services:apiv1:home:cached:coldbootcheck:' . $pid, 1, 86400);
|
||||||
|
return response()->json([], 206);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = collect($res)->take($limit)->map(function($id) use($napi) {
|
||||||
|
return $napi ? StatusService::get($id, false) : StatusService::getMastodon($id, false);
|
||||||
|
})->filter(function($res) {
|
||||||
|
return $res && isset($res['account']);
|
||||||
|
})->map(function($status) use($pid) {
|
||||||
|
if($pid) {
|
||||||
|
$status['favourited'] = (bool) LikeService::liked($pid, $status['id']);
|
||||||
|
$status['reblogged'] = (bool) ReblogService::get($pid, $status['id']);
|
||||||
|
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
||||||
|
}
|
||||||
|
return $status;
|
||||||
|
});
|
||||||
|
|
||||||
|
$baseUrl = config('app.url') . '/api/v1/timelines/home?limit=' . $limit . '&';
|
||||||
|
$minId = $res->map(function($s) {
|
||||||
|
return ['id' => $s['id']];
|
||||||
|
})->min('id');
|
||||||
|
$maxId = $res->map(function($s) {
|
||||||
|
return ['id' => $s['id']];
|
||||||
|
})->max('id');
|
||||||
|
|
||||||
|
if($minId == $maxId) {
|
||||||
|
$minId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($maxId) {
|
||||||
|
$link = '<'.$baseUrl.'max_id='.$minId.'>; rel="next"';
|
||||||
|
}
|
||||||
|
|
||||||
|
if($minId) {
|
||||||
|
$link = '<'.$baseUrl.'min_id='.$maxId.'>; rel="prev"';
|
||||||
|
}
|
||||||
|
|
||||||
|
if($maxId && $minId) {
|
||||||
|
$link = '<'.$baseUrl.'max_id='.$minId.'>; rel="next",<'.$baseUrl.'min_id='.$maxId.'>; rel="prev"';
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = isset($link) ? ['Link' => $link] : [];
|
||||||
|
return $this->json($res->toArray(), 200, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
$following = Cache::remember('profile:following:'.$pid, 1209600, function() use($pid) {
|
$following = Cache::remember('profile:following:'.$pid, 1209600, function() use($pid) {
|
||||||
$following = Follower::whereProfileId($pid)->pluck('following_id');
|
$following = Follower::whereProfileId($pid)->pluck('following_id');
|
||||||
|
@ -2161,6 +2227,7 @@ class ApiV1Controller extends Controller
|
||||||
$following = array_diff($following, $muted);
|
$following = array_diff($following, $muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if($min || $max) {
|
if($min || $max) {
|
||||||
$dir = $min ? '>' : '<';
|
$dir = $min ? '>' : '<';
|
||||||
$id = $min ?? $max;
|
$id = $min ?? $max;
|
||||||
|
@ -2199,22 +2266,22 @@ class ApiV1Controller extends Controller
|
||||||
if($pid) {
|
if($pid) {
|
||||||
$status['favourited'] = (bool) LikeService::liked($pid, $s['id']);
|
$status['favourited'] = (bool) LikeService::liked($pid, $s['id']);
|
||||||
$status['reblogged'] = (bool) ReblogService::get($pid, $status['id']);
|
$status['reblogged'] = (bool) ReblogService::get($pid, $status['id']);
|
||||||
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
||||||
}
|
}
|
||||||
return $status;
|
return $status;
|
||||||
})
|
})
|
||||||
->filter(function($status) {
|
->filter(function($status) {
|
||||||
return $status && isset($status['account']);
|
return $status && isset($status['account']);
|
||||||
})
|
})
|
||||||
->map(function($status) use($pid) {
|
->map(function($status) use($pid) {
|
||||||
if(!empty($status['reblog'])) {
|
if(!empty($status['reblog'])) {
|
||||||
$status['reblog']['favourited'] = (bool) LikeService::liked($pid, $status['reblog']['id']);
|
$status['reblog']['favourited'] = (bool) LikeService::liked($pid, $status['reblog']['id']);
|
||||||
$status['reblog']['reblogged'] = (bool) ReblogService::get($pid, $status['reblog']['id']);
|
$status['reblog']['reblogged'] = (bool) ReblogService::get($pid, $status['reblog']['id']);
|
||||||
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $status;
|
return $status;
|
||||||
})
|
})
|
||||||
->take($limit)
|
->take($limit)
|
||||||
->values();
|
->values();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2252,22 +2319,22 @@ class ApiV1Controller extends Controller
|
||||||
if($pid) {
|
if($pid) {
|
||||||
$status['favourited'] = (bool) LikeService::liked($pid, $s['id']);
|
$status['favourited'] = (bool) LikeService::liked($pid, $s['id']);
|
||||||
$status['reblogged'] = (bool) ReblogService::get($pid, $status['id']);
|
$status['reblogged'] = (bool) ReblogService::get($pid, $status['id']);
|
||||||
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
||||||
}
|
}
|
||||||
return $status;
|
return $status;
|
||||||
})
|
})
|
||||||
->filter(function($status) {
|
->filter(function($status) {
|
||||||
return $status && isset($status['account']);
|
return $status && isset($status['account']);
|
||||||
})
|
})
|
||||||
->map(function($status) use($pid) {
|
->map(function($status) use($pid) {
|
||||||
if(!empty($status['reblog'])) {
|
if(!empty($status['reblog'])) {
|
||||||
$status['reblog']['favourited'] = (bool) LikeService::liked($pid, $status['reblog']['id']);
|
$status['reblog']['favourited'] = (bool) LikeService::liked($pid, $status['reblog']['id']);
|
||||||
$status['reblog']['reblogged'] = (bool) ReblogService::get($pid, $status['reblog']['id']);
|
$status['reblog']['reblogged'] = (bool) ReblogService::get($pid, $status['reblog']['id']);
|
||||||
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
$status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $status;
|
return $status;
|
||||||
})
|
})
|
||||||
->take($limit)
|
->take($limit)
|
||||||
->values();
|
->values();
|
||||||
}
|
}
|
||||||
|
@ -2321,10 +2388,11 @@ class ApiV1Controller extends Controller
|
||||||
$max = $request->input('max_id');
|
$max = $request->input('max_id');
|
||||||
$limit = $request->input('limit') ?? 20;
|
$limit = $request->input('limit') ?? 20;
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
$remote = ($request->has('remote') && $request->input('remote') == true) || ($request->filled('local') && $request->input('local') != true);
|
$remote = $request->has('remote');
|
||||||
|
$local = $request->has('local');
|
||||||
$filtered = $user ? UserFilterService::filters($user->profile_id) : [];
|
$filtered = $user ? UserFilterService::filters($user->profile_id) : [];
|
||||||
|
|
||||||
if((!$request->has('local') || $remote) && config('instance.timeline.network.cached')) {
|
if($remote && config('instance.timeline.network.cached')) {
|
||||||
Cache::remember('api:v1:timelines:network:cache_check', 10368000, function() {
|
Cache::remember('api:v1:timelines:network:cache_check', 10368000, function() {
|
||||||
if(NetworkTimelineService::count() == 0) {
|
if(NetworkTimelineService::count() == 0) {
|
||||||
NetworkTimelineService::warmCache(true, config('instance.timeline.network.cache_dropoff'));
|
NetworkTimelineService::warmCache(true, config('instance.timeline.network.cache_dropoff'));
|
||||||
|
@ -2338,7 +2406,9 @@ class ApiV1Controller extends Controller
|
||||||
} else {
|
} else {
|
||||||
$feed = NetworkTimelineService::get(0, $limit + 5);
|
$feed = NetworkTimelineService::get(0, $limit + 5);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if($local || !$remote && !$local) {
|
||||||
Cache::remember('api:v1:timelines:public:cache_check', 10368000, function() {
|
Cache::remember('api:v1:timelines:public:cache_check', 10368000, function() {
|
||||||
if(PublicTimelineService::count() == 0) {
|
if(PublicTimelineService::count() == 0) {
|
||||||
PublicTimelineService::warmCache(true, 400);
|
PublicTimelineService::warmCache(true, 400);
|
||||||
|
|
Loading…
Reference in a new issue