Przeglądaj źródła

Update public timeline api, add experimental cache

Daniel Supernault 3 lat temu
rodzic
commit
192553ff77

+ 6 - 1
app/Http/Controllers/Api/ApiV1Controller.php

@@ -58,7 +58,8 @@ use App\Services\{
 	RelationshipService,
 	SearchApiV2Service,
 	StatusService,
-	MediaBlocklistService
+	MediaBlocklistService,
+	UserFilterService
 };
 use App\Util\Lexer\Autolink;
 
@@ -1487,6 +1488,7 @@ class ApiV1Controller extends Controller
 		$max = $request->input('max_id');
 		$limit = $request->input('limit') ?? 3;
 		$user = $request->user();
+        $filtered = $user ? UserFilterService::filters($user->profile_id) : [];
 
 		Cache::remember('api:v1:timelines:public:cache_check', 10368000, function() {
 			if(PublicTimelineService::count() == 0) {
@@ -1511,6 +1513,9 @@ class ApiV1Controller extends Controller
 			}
 			return $status;
 		})
+		->filter(function($s) use($filtered) {
+			return in_array($s['account']['id'], $filtered) == false;
+		})
 		->toArray();
 		return response()->json($res);
 	}

+ 1 - 1
app/Http/Controllers/LikeController.php

@@ -56,7 +56,7 @@ class LikeController extends Controller
 		}
 
 		Cache::forget('status:'.$status->id.':likedby:userid:'.$user->id);
-		StatusService::del($status->id);
+		StatusService::refresh($status->id);
 
 		if ($request->ajax()) {
 			$response = ['code' => 200, 'msg' => 'Like saved', 'count' => 0];

+ 95 - 24
app/Http/Controllers/PublicApiController.php

@@ -39,7 +39,6 @@ use App\Jobs\StatusPipeline\NewStatusPipeline;
 use League\Fractal\Serializer\ArraySerializer;
 use League\Fractal\Pagination\IlluminatePaginatorAdapter;
 
-
 class PublicApiController extends Controller
 {
     protected $fractal;
@@ -288,31 +287,103 @@ class PublicApiController extends Controller
         $max = $request->input('max_id');
         $limit = $request->input('limit') ?? 3;
         $user = $request->user();
+        $filtered = $user ? UserFilterService::filters($user->profile_id) : [];
 
-        Cache::remember('api:v1:timelines:public:cache_check', 10368000, function() {
-			if(PublicTimelineService::count() == 0) {
-				PublicTimelineService::warmCache(true, 400);
-			}
-		});
-
-		if ($max) {
-			$feed = PublicTimelineService::getRankedMaxId($max, $limit);
-		} else if ($min) {
-			$feed = PublicTimelineService::getRankedMinId($min, $limit);
-		} else {
-			$feed = PublicTimelineService::get(0, $limit);
-		}
-
-		$res = collect($feed)
-		->map(function($k) use($user) {
-			$status = StatusService::get($k);
-			if($user) {
-				$status['favourited'] = (bool) LikeService::liked($user->profile_id, $k);
-				$status['relationship'] = RelationshipService::get($user->profile_id, $status['account']['id']);
+        if(config('exp.cached_public_timeline') == false) {
+	        if($min || $max) {
+	            $dir = $min ? '>' : '<';
+	            $id = $min ?? $max;
+	            $timeline = Status::select(
+	                        'id',
+	                        'profile_id',
+	                        'type',
+	                        'scope',
+	                        'local'
+	                      )
+	                      ->where('id', $dir, $id)
+	                      ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])
+	                      ->whereLocal(true)
+	                      ->whereScope('public')
+	                      ->orderBy('id', 'desc')
+	                      ->limit($limit)
+	                      ->get()
+	                      ->map(function($s) use ($user) {
+	                           $status = StatusService::getFull($s->id, $user->profile_id);
+	                           $status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
+	                           return $status;
+	                      })
+	                      ->filter(function($s) use($filtered) {
+	                      		return in_array($s['account']['id'], $filtered) == false;
+	                      });
+	            $res = $timeline->toArray();
+	        } else {
+	            $timeline = Status::select(
+	                        'id',
+	                        'uri',
+	                        'caption',
+	                        'rendered',
+	                        'profile_id',
+	                        'type',
+	                        'in_reply_to_id',
+	                        'reblog_of_id',
+	                        'is_nsfw',
+	                        'scope',
+	                        'local',
+	                        'reply_count',
+	                        'comments_disabled',
+	                        'created_at',
+	                        'place_id',
+	                        'likes_count',
+	                        'reblogs_count',
+	                        'updated_at'
+	                      )
+	                      ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])
+	                      ->with('profile', 'hashtags', 'mentions')
+	                      ->whereLocal(true)
+	                      ->whereScope('public')
+	                      ->orderBy('id', 'desc')
+	                      ->limit($limit)
+	                      ->get()
+	                      ->map(function($s) use ($user) {
+	                           $status = StatusService::getFull($s->id, $user->profile_id);
+	                           $status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
+	                           return $status;
+	                      })
+	                      ->filter(function($s) use($filtered) {
+	                      		return in_array($s['account']['id'], $filtered) == false;
+	                      });
+
+	            $res = $timeline->toArray();
+	        }
+        } else {
+	  		Cache::remember('api:v1:timelines:public:cache_check', 10368000, function() {
+				if(PublicTimelineService::count() == 0) {
+					PublicTimelineService::warmCache(true, 400);
+				}
+			});
+
+			if ($max) {
+				$feed = PublicTimelineService::getRankedMaxId($max, $limit);
+			} else if ($min) {
+				$feed = PublicTimelineService::getRankedMinId($min, $limit);
+			} else {
+				$feed = PublicTimelineService::get(0, $limit);
 			}
-			return $status;
-		})
-		->toArray();
+
+			$res = collect($feed)
+			->map(function($k) use($user) {
+				$status = StatusService::get($k);
+				if($user) {
+					$status['favourited'] = (bool) LikeService::liked($user->profile_id, $k);
+					$status['relationship'] = RelationshipService::get($user->profile_id, $status['account']['id']);
+				}
+				return $status;
+			})
+			->filter(function($s) use($filtered) {
+				return in_array($s['account']['id'], $filtered) == false;
+			})
+			->toArray();
+        }
 
         return response()->json($res);
     }

+ 1 - 1
app/Jobs/LikePipeline/LikePipeline.php

@@ -59,7 +59,7 @@ class LikePipeline implements ShouldQueue
             return;
         }
 
-        StatusService::del($status->id);
+        StatusService::refresh($status->id);
 
         if($status->url && $actor->domain == null) {
             return $this->remoteLikeDeliver();

+ 1 - 1
app/Jobs/LikePipeline/UnlikePipeline.php

@@ -63,7 +63,7 @@ class UnlikePipeline implements ShouldQueue
 		$status->likes_count = $count - 1;
 		$status->save();
 
-		StatusService::del($status->id);
+		StatusService::refresh($status->id);
 
 		if($actor->id !== $status->profile_id && $status->url && $actor->domain == null) {
 			$this->remoteLikeDeliver();

+ 8 - 0
app/Services/StatusService.php

@@ -62,4 +62,12 @@ class StatusService {
 		Cache::forget(self::key($id, false));
 		return Cache::forget(self::key($id));
 	}
+
+	public static function refresh($id)
+	{
+		Cache::forget(self::key($id, false));
+		Cache::forget(self::key($id, true));
+		self::get($id, false);
+		self::get($id, true);
+	}
 }

+ 2 - 1
config/exp.php

@@ -6,5 +6,6 @@ return [
 	'rec' => false,
 	'loops' => false,
 	'top' => env('EXP_TOP', false),
-	'polls' => env('EXP_POLLS', false)
+	'polls' => env('EXP_POLLS', false),
+	'cached_public_timeline' => env('EXP_CPT', false),
 ];