From 8ce6c1f2d2a7c31cc8cabcb3357542905996e1a9 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 20:35:07 -0600 Subject: [PATCH] Add /api/v1/accounts/{id}/statuses endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 80 ++++++++++++++++++++ routes/web.php | 2 +- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index a1a3fc60d..c33bacbfb 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -9,6 +9,7 @@ use App\Jobs\StatusPipeline\StatusDelete; use Laravel\Passport\Passport; use Auth, Cache, DB; use App\{ + Follower, Like, Media, Profile, @@ -189,6 +190,85 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/accounts/{id}/statuses + * + * @param integer $id + * + * @return \App\Transformer\Api\StatusTransformer + */ + public function accountStatusesById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'only_media' => 'nullable', + 'pinned' => 'nullable', + 'exclude_replies' => 'nullable', + 'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'since_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'limit' => 'nullable|integer|min:1|max:40' + ]); + + $profile = Profile::whereNull('status')->findOrFail($id); + + $limit = $request->limit ?? 20; + $max_id = $request->max_id; + $min_id = $request->min_id; + $pid = $request->user()->profile_id; + $scope = $request->only_media == true ? + ['photo', 'photo:album', 'video', 'video:album'] : + ['photo', 'photo:album', 'video', 'video:album', 'share', 'reply']; + + if($pid == $profile->id) { + $visibility = ['public', 'unlisted', 'private']; + } else if($profile->is_private) { + $following = Cache::remember('profile:following:'.$pid, now()->addMinutes(1440), function() use($pid) { + $following = Follower::whereProfileId($pid)->pluck('following_id'); + return $following->push($pid)->toArray(); + }); + $visibility = true == in_array($profile->id, $following) ? ['public', 'unlisted', 'private'] : []; + } else { + $following = Cache::remember('profile:following:'.$pid, now()->addMinutes(1440), function() use($pid) { + $following = Follower::whereProfileId($pid)->pluck('following_id'); + return $following->push($pid)->toArray(); + }); + $visibility = true == in_array($profile->id, $following) ? ['public', 'unlisted', 'private'] : ['public', 'unlisted']; + + } + + $dir = $min_id ? '>' : '<'; + $id = $min_id ?? $max_id; + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'scope', + 'local', + 'created_at', + 'updated_at' + )->whereProfileId($profile->id) + ->whereIn('type', $scope) + ->whereLocal(true) + ->whereNull('uri') + ->where('id', $dir, $id) + ->whereIn('visibility', $visibility) + ->latest() + ->limit($limit) + ->get(); + + $resource = new Fractal\Resource\Collection($timeline, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 1d461670a..1e5023d9d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -80,7 +80,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials')->middleware('auth:api'); Route::patch('accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware('auth:api'); Route::get('accounts/relationships', 'PublicApiController@relationships')->middleware('auth:api'); - Route::get('accounts/{id}/statuses', 'PublicApiController@accountStatuses')->middleware('auth:api'); + Route::get('accounts/{id}/statuses', 'Api\ApiV1Controller@accountStatusesById')->middleware('auth:api'); Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware('auth:api'); Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account');