From 53134208fef9a8bebc364e48de9b1a03e3addfbc Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 11 May 2021 18:17:03 -0600 Subject: [PATCH] Update config() to config_cache() --- app/Http/Controllers/FederationController.php | 16 +- app/Http/Controllers/ProfileController.php | 390 +++++------ app/Http/Controllers/SearchController.php | 626 +++++++++--------- app/Http/Controllers/StatusController.php | 9 +- app/Jobs/SharePipeline/SharePipeline.php | 216 +++--- app/Jobs/StatusPipeline/StatusDelete.php | 266 ++++---- app/Jobs/StatusPipeline/StatusEntityLexer.php | 244 +++---- app/Util/ActivityPub/Outbox.php | 4 +- app/Util/Site/Config.php | 2 +- 9 files changed, 889 insertions(+), 884 deletions(-) diff --git a/app/Http/Controllers/FederationController.php b/app/Http/Controllers/FederationController.php index 3c5b93950..c17019f1b 100644 --- a/app/Http/Controllers/FederationController.php +++ b/app/Http/Controllers/FederationController.php @@ -79,7 +79,7 @@ class FederationController extends Controller public function userOutbox(Request $request, $username) { - abort_if(!config('federation.activitypub.enabled'), 404); + abort_if(!config_cache('federation.activitypub.enabled'), 404); abort_if(!config('federation.activitypub.outbox'), 404); $profile = Profile::whereNull('domain') @@ -99,7 +99,7 @@ class FederationController extends Controller public function userInbox(Request $request, $username) { - abort_if(!config('federation.activitypub.enabled'), 404); + abort_if(!config_cache('federation.activitypub.enabled'), 404); abort_if(!config('federation.activitypub.inbox'), 404); $headers = $request->headers->all(); @@ -110,7 +110,7 @@ class FederationController extends Controller public function sharedInbox(Request $request) { - abort_if(!config('federation.activitypub.enabled'), 404); + abort_if(!config_cache('federation.activitypub.enabled'), 404); abort_if(!config('federation.activitypub.sharedInbox'), 404); $headers = $request->headers->all(); @@ -121,13 +121,13 @@ class FederationController extends Controller public function userFollowing(Request $request, $username) { - abort_if(!config('federation.activitypub.enabled'), 404); + abort_if(!config_cache('federation.activitypub.enabled'), 404); $profile = Profile::whereNull('remote_url') ->whereUsername($username) ->whereIsPrivate(false) ->firstOrFail(); - + if($profile->status != null) { abort(404); } @@ -139,12 +139,12 @@ class FederationController extends Controller 'totalItems' => 0, 'orderedItems' => [] ]; - return response()->json($obj); + return response()->json($obj); } public function userFollowers(Request $request, $username) { - abort_if(!config('federation.activitypub.enabled'), 404); + abort_if(!config_cache('federation.activitypub.enabled'), 404); $profile = Profile::whereNull('remote_url') ->whereUsername($username) @@ -163,6 +163,6 @@ class FederationController extends Controller 'orderedItems' => [] ]; - return response()->json($obj); + return response()->json($obj); } } diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 6bd42d177..a5909e4bc 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -20,229 +20,229 @@ use App\Transformer\ActivityPub\ProfileTransformer; class ProfileController extends Controller { - public function show(Request $request, $username) - { - $user = Profile::whereNull('domain') - ->whereNull('status') - ->whereUsername($username) - ->firstOrFail(); - - if($request->wantsJson() && config('federation.activitypub.enabled')) { - return $this->showActivityPub($request, $user); - } - return $this->buildProfile($request, $user); - } + public function show(Request $request, $username) + { + $user = Profile::whereNull('domain') + ->whereNull('status') + ->whereUsername($username) + ->firstOrFail(); - protected function buildProfile(Request $request, $user) - { - $username = $user->username; - $loggedIn = Auth::check(); - $isPrivate = false; - $isBlocked = false; - if(!$loggedIn) { - $key = 'profile:settings:' . $user->id; - $ttl = now()->addHours(6); - $settings = Cache::remember($key, $ttl, function() use($user) { - return $user->user->settings; - }); + if($request->wantsJson() && config_cache('federation.activitypub.enabled')) { + return $this->showActivityPub($request, $user); + } + return $this->buildProfile($request, $user); + } - if ($user->is_private == true) { - abort(404); - } + protected function buildProfile(Request $request, $user) + { + $username = $user->username; + $loggedIn = Auth::check(); + $isPrivate = false; + $isBlocked = false; + if(!$loggedIn) { + $key = 'profile:settings:' . $user->id; + $ttl = now()->addHours(6); + $settings = Cache::remember($key, $ttl, function() use($user) { + return $user->user->settings; + }); - $owner = false; - $is_following = false; + if ($user->is_private == true) { + abort(404); + } - $is_admin = $user->user->is_admin; - $profile = $user; - $settings = [ - 'crawlable' => $settings->crawlable, - 'following' => [ - 'count' => $settings->show_profile_following_count, - 'list' => $settings->show_profile_following - ], - 'followers' => [ - 'count' => $settings->show_profile_follower_count, - 'list' => $settings->show_profile_followers - ] - ]; - $ui = $request->has('ui') && $request->input('ui') == 'memory' ? 'profile.memory' : 'profile.show'; + $owner = false; + $is_following = false; - return view($ui, compact('profile', 'settings')); - } else { - $key = 'profile:settings:' . $user->id; - $ttl = now()->addHours(6); - $settings = Cache::remember($key, $ttl, function() use($user) { - return $user->user->settings; - }); + $is_admin = $user->user->is_admin; + $profile = $user; + $settings = [ + 'crawlable' => $settings->crawlable, + 'following' => [ + 'count' => $settings->show_profile_following_count, + 'list' => $settings->show_profile_following + ], + 'followers' => [ + 'count' => $settings->show_profile_follower_count, + 'list' => $settings->show_profile_followers + ] + ]; + $ui = $request->has('ui') && $request->input('ui') == 'memory' ? 'profile.memory' : 'profile.show'; - if ($user->is_private == true) { - $isPrivate = $this->privateProfileCheck($user, $loggedIn); - } + return view($ui, compact('profile', 'settings')); + } else { + $key = 'profile:settings:' . $user->id; + $ttl = now()->addHours(6); + $settings = Cache::remember($key, $ttl, function() use($user) { + return $user->user->settings; + }); - $isBlocked = $this->blockedProfileCheck($user); + if ($user->is_private == true) { + $isPrivate = $this->privateProfileCheck($user, $loggedIn); + } - $owner = $loggedIn && Auth::id() === $user->user_id; - $is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false; + $isBlocked = $this->blockedProfileCheck($user); - if ($isPrivate == true || $isBlocked == true) { - $requested = Auth::check() ? FollowRequest::whereFollowerId(Auth::user()->profile_id) - ->whereFollowingId($user->id) - ->exists() : false; - return view('profile.private', compact('user', 'is_following', 'requested')); - } + $owner = $loggedIn && Auth::id() === $user->user_id; + $is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false; - $is_admin = is_null($user->domain) ? $user->user->is_admin : false; - $profile = $user; - $settings = [ - 'crawlable' => $settings->crawlable, - 'following' => [ - 'count' => $settings->show_profile_following_count, - 'list' => $settings->show_profile_following - ], - 'followers' => [ - 'count' => $settings->show_profile_follower_count, - 'list' => $settings->show_profile_followers - ] - ]; - $ui = $request->has('ui') && $request->input('ui') == 'memory' ? 'profile.memory' : 'profile.show'; - return view($ui, compact('profile', 'settings')); - } - } + if ($isPrivate == true || $isBlocked == true) { + $requested = Auth::check() ? FollowRequest::whereFollowerId(Auth::user()->profile_id) + ->whereFollowingId($user->id) + ->exists() : false; + return view('profile.private', compact('user', 'is_following', 'requested')); + } - public function permalinkRedirect(Request $request, $username) - { - $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); + $is_admin = is_null($user->domain) ? $user->user->is_admin : false; + $profile = $user; + $settings = [ + 'crawlable' => $settings->crawlable, + 'following' => [ + 'count' => $settings->show_profile_following_count, + 'list' => $settings->show_profile_following + ], + 'followers' => [ + 'count' => $settings->show_profile_follower_count, + 'list' => $settings->show_profile_followers + ] + ]; + $ui = $request->has('ui') && $request->input('ui') == 'memory' ? 'profile.memory' : 'profile.show'; + return view($ui, compact('profile', 'settings')); + } + } - if ($request->wantsJson() && config('federation.activitypub.enabled')) { - return $this->showActivityPub($request, $user); - } + public function permalinkRedirect(Request $request, $username) + { + $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); - return redirect($user->url()); - } + if ($request->wantsJson() && config_cache('federation.activitypub.enabled')) { + return $this->showActivityPub($request, $user); + } - protected function privateProfileCheck(Profile $profile, $loggedIn) - { - if (!Auth::check()) { - return true; - } + return redirect($user->url()); + } - $user = Auth::user()->profile; - if($user->id == $profile->id || !$profile->is_private) { - return false; - } + protected function privateProfileCheck(Profile $profile, $loggedIn) + { + if (!Auth::check()) { + return true; + } - $follows = Follower::whereProfileId($user->id)->whereFollowingId($profile->id)->exists(); - if ($follows == false) { - return true; - } - - return false; - } + $user = Auth::user()->profile; + if($user->id == $profile->id || !$profile->is_private) { + return false; + } - public static function accountCheck(Profile $profile) - { - switch ($profile->status) { - case 'disabled': - case 'suspended': - case 'delete': - return view('profile.disabled'); - break; - - default: - break; - } - return abort(404); - } + $follows = Follower::whereProfileId($user->id)->whereFollowingId($profile->id)->exists(); + if ($follows == false) { + return true; + } - protected function blockedProfileCheck(Profile $profile) - { - $pid = Auth::user()->profile->id; - $blocks = UserFilter::whereUserId($profile->id) - ->whereFilterType('block') - ->whereFilterableType('App\Profile') - ->pluck('filterable_id') - ->toArray(); - if (in_array($pid, $blocks)) { - return true; - } + return false; + } - return false; - } + public static function accountCheck(Profile $profile) + { + switch ($profile->status) { + case 'disabled': + case 'suspended': + case 'delete': + return view('profile.disabled'); + break; - public function showActivityPub(Request $request, $user) - { - abort_if(!config('federation.activitypub.enabled'), 404); - abort_if($user->domain, 404); + default: + break; + } + return abort(404); + } - $fractal = new Fractal\Manager(); - $resource = new Fractal\Resource\Item($user, new ProfileTransformer); - $res = $fractal->createData($resource)->toArray(); - return response(json_encode($res['data']))->header('Content-Type', 'application/activity+json'); - } + protected function blockedProfileCheck(Profile $profile) + { + $pid = Auth::user()->profile->id; + $blocks = UserFilter::whereUserId($profile->id) + ->whereFilterType('block') + ->whereFilterableType('App\Profile') + ->pluck('filterable_id') + ->toArray(); + if (in_array($pid, $blocks)) { + return true; + } - public function showAtomFeed(Request $request, $user) - { - abort_if(!config('federation.atom.enabled'), 404); + return false; + } - $profile = $user = Profile::whereNull('status')->whereNull('domain')->whereUsername($user)->whereIsPrivate(false)->firstOrFail(); - if($profile->status != null) { - return $this->accountCheck($profile); - } - if($profile->is_private || Auth::check()) { - $blocked = $this->blockedProfileCheck($profile); - $check = $this->privateProfileCheck($profile, null); - if($check || $blocked) { - return redirect($profile->url()); - } - } - $items = $profile->statuses()->whereHas('media')->whereIn('visibility',['public', 'unlisted'])->orderBy('created_at', 'desc')->take(10)->get(); - return response()->view('atom.user', compact('profile', 'items')) - ->header('Content-Type', 'application/atom+xml'); - } + public function showActivityPub(Request $request, $user) + { + abort_if(!config_cache('federation.activitypub.enabled'), 404); + abort_if($user->domain, 404); - public function meRedirect() - { - abort_if(!Auth::check(), 404); - return redirect(Auth::user()->url()); - } + $fractal = new Fractal\Manager(); + $resource = new Fractal\Resource\Item($user, new ProfileTransformer); + $res = $fractal->createData($resource)->toArray(); + return response(json_encode($res['data']))->header('Content-Type', 'application/activity+json'); + } - public function embed(Request $request, $username) - { - $res = view('profile.embed-removed'); + public function showAtomFeed(Request $request, $user) + { + abort_if(!config('federation.atom.enabled'), 404); - if(strlen($username) > 15 || strlen($username) < 2) { - return response($res)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); - } + $profile = $user = Profile::whereNull('status')->whereNull('domain')->whereUsername($user)->whereIsPrivate(false)->firstOrFail(); + if($profile->status != null) { + return $this->accountCheck($profile); + } + if($profile->is_private || Auth::check()) { + $blocked = $this->blockedProfileCheck($profile); + $check = $this->privateProfileCheck($profile, null); + if($check || $blocked) { + return redirect($profile->url()); + } + } + $items = $profile->statuses()->whereHas('media')->whereIn('visibility',['public', 'unlisted'])->orderBy('created_at', 'desc')->take(10)->get(); + return response()->view('atom.user', compact('profile', 'items')) + ->header('Content-Type', 'application/atom+xml'); + } - $profile = Profile::whereUsername($username) - ->whereIsPrivate(false) - ->whereNull('status') - ->whereNull('domain') - ->first(); + public function meRedirect() + { + abort_if(!Auth::check(), 404); + return redirect(Auth::user()->url()); + } - if(!$profile) { - return response($res)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); - } + public function embed(Request $request, $username) + { + $res = view('profile.embed-removed'); - $content = Cache::remember('profile:embed:'.$profile->id, now()->addHours(12), function() use($profile) { - return View::make('profile.embed')->with(compact('profile'))->render(); - }); - - return response($content)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); - } + if(strlen($username) > 15 || strlen($username) < 2) { + return response($res)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); + } - public function stories(Request $request, $username) - { - abort_if(!config('instance.stories.enabled') || !$request->user(), 404); - $profile = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); - $pid = $profile->id; - $authed = Auth::user()->profile; - abort_if($pid != $authed->id && $profile->followedBy($authed) == false, 404); - $exists = Story::whereProfileId($pid) - ->where('expires_at', '>', now()) - ->count(); - abort_unless($exists > 0, 404); - return view('profile.story', compact('pid', 'profile')); - } + $profile = Profile::whereUsername($username) + ->whereIsPrivate(false) + ->whereNull('status') + ->whereNull('domain') + ->first(); + + if(!$profile) { + return response($res)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); + } + + $content = Cache::remember('profile:embed:'.$profile->id, now()->addHours(12), function() use($profile) { + return View::make('profile.embed')->with(compact('profile'))->render(); + }); + + return response($content)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); + } + + public function stories(Request $request, $username) + { + abort_if(!config('instance.stories.enabled') || !$request->user(), 404); + $profile = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); + $pid = $profile->id; + $authed = Auth::user()->profile; + abort_if($pid != $authed->id && $profile->followedBy($authed) == false, 404); + $exists = Story::whereProfileId($pid) + ->where('expires_at', '>', now()) + ->count(); + abort_unless($exists > 0, 404); + return view('profile.story', compact('pid', 'profile')); + } } diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 3f5accd35..c273e95d9 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -12,348 +12,348 @@ use App\Util\ActivityPub\Helpers; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Str; use App\Transformer\Api\{ - AccountTransformer, - HashtagTransformer, - StatusTransformer, + AccountTransformer, + HashtagTransformer, + StatusTransformer, }; use App\Services\WebfingerService; class SearchController extends Controller { - public $tokens = []; - public $term = ''; - public $hash = ''; - public $cacheKey = 'api:search:tag:'; + public $tokens = []; + public $term = ''; + public $hash = ''; + public $cacheKey = 'api:search:tag:'; - public function __construct() - { - $this->middleware('auth'); - } + public function __construct() + { + $this->middleware('auth'); + } - public function searchAPI(Request $request) - { - $this->validate($request, [ - 'q' => 'required|string|min:3|max:120', - 'src' => 'required|string|in:metro', - 'v' => 'required|integer|in:2', - 'scope' => 'required|in:all,hashtag,profile,remote,webfinger' - ]); + public function searchAPI(Request $request) + { + $this->validate($request, [ + 'q' => 'required|string|min:3|max:120', + 'src' => 'required|string|in:metro', + 'v' => 'required|integer|in:2', + 'scope' => 'required|in:all,hashtag,profile,remote,webfinger' + ]); - $scope = $request->input('scope') ?? 'all'; - $this->term = e(urldecode($request->input('q'))); - $this->hash = hash('sha256', $this->term); + $scope = $request->input('scope') ?? 'all'; + $this->term = e(urldecode($request->input('q'))); + $this->hash = hash('sha256', $this->term); - switch ($scope) { - case 'all': - $this->getHashtags(); - $this->getPosts(); - $this->getProfiles(); - // $this->getPlaces(); - break; + switch ($scope) { + case 'all': + $this->getHashtags(); + $this->getPosts(); + $this->getProfiles(); + // $this->getPlaces(); + break; - case 'hashtag': - $this->getHashtags(); - break; + case 'hashtag': + $this->getHashtags(); + break; - case 'profile': - $this->getProfiles(); - break; + case 'profile': + $this->getProfiles(); + break; - case 'webfinger': - $this->webfingerSearch(); - break; + case 'webfinger': + $this->webfingerSearch(); + break; - case 'remote': - $this->remoteLookupSearch(); - break; + case 'remote': + $this->remoteLookupSearch(); + break; - case 'place': - $this->getPlaces(); - break; + case 'place': + $this->getPlaces(); + break; - default: - break; - } + default: + break; + } - return response()->json($this->tokens, 200, [], JSON_PRETTY_PRINT); - } + return response()->json($this->tokens, 200, [], JSON_PRETTY_PRINT); + } - protected function getPosts() - { - $tag = $this->term; - $hash = hash('sha256', $tag); - if( Helpers::validateUrl($tag) != false && - Helpers::validateLocalUrl($tag) != true && - config('federation.activitypub.enabled') == true && - config('federation.activitypub.remoteFollow') == true - ) { - $remote = Helpers::fetchFromUrl($tag); - if( isset($remote['type']) && - $remote['type'] == 'Note') { - $item = Helpers::statusFetch($tag); - $this->tokens['posts'] = [[ - 'count' => 0, - 'url' => $item->url(), - 'type' => 'status', - 'value' => "by {$item->profile->username} {$item->created_at->diffForHumans(null, true, true)}", - 'tokens' => [$item->caption], - 'name' => $item->caption, - 'thumb' => $item->thumb(), - ]]; - } - } else { - $posts = Status::select('id', 'profile_id', 'caption', 'created_at') - ->whereHas('media') - ->whereNull('in_reply_to_id') - ->whereNull('reblog_of_id') - ->whereProfileId(Auth::user()->profile_id) - ->where('caption', 'like', '%'.$tag.'%') - ->latest() - ->limit(10) - ->get(); + protected function getPosts() + { + $tag = $this->term; + $hash = hash('sha256', $tag); + if( Helpers::validateUrl($tag) != false && + Helpers::validateLocalUrl($tag) != true && + config_cache('federation.activitypub.enabled') == true && + config('federation.activitypub.remoteFollow') == true + ) { + $remote = Helpers::fetchFromUrl($tag); + if( isset($remote['type']) && + $remote['type'] == 'Note') { + $item = Helpers::statusFetch($tag); + $this->tokens['posts'] = [[ + 'count' => 0, + 'url' => $item->url(), + 'type' => 'status', + 'value' => "by {$item->profile->username} {$item->created_at->diffForHumans(null, true, true)}", + 'tokens' => [$item->caption], + 'name' => $item->caption, + 'thumb' => $item->thumb(), + ]]; + } + } else { + $posts = Status::select('id', 'profile_id', 'caption', 'created_at') + ->whereHas('media') + ->whereNull('in_reply_to_id') + ->whereNull('reblog_of_id') + ->whereProfileId(Auth::user()->profile_id) + ->where('caption', 'like', '%'.$tag.'%') + ->latest() + ->limit(10) + ->get(); - if($posts->count() > 0) { - $posts = $posts->map(function($item, $key) { - return [ - 'count' => 0, - 'url' => $item->url(), - 'type' => 'status', - 'value' => "by {$item->profile->username} {$item->created_at->diffForHumans(null, true, true)}", - 'tokens' => [$item->caption], - 'name' => $item->caption, - 'thumb' => $item->thumb(), - 'filter' => $item->firstMedia()->filter_class - ]; - }); - $this->tokens['posts'] = $posts; - } - } - } + if($posts->count() > 0) { + $posts = $posts->map(function($item, $key) { + return [ + 'count' => 0, + 'url' => $item->url(), + 'type' => 'status', + 'value' => "by {$item->profile->username} {$item->created_at->diffForHumans(null, true, true)}", + 'tokens' => [$item->caption], + 'name' => $item->caption, + 'thumb' => $item->thumb(), + 'filter' => $item->firstMedia()->filter_class + ]; + }); + $this->tokens['posts'] = $posts; + } + } + } - protected function getHashtags() - { - $tag = $this->term; - $key = $this->cacheKey . 'hashtags:' . $this->hash; - $ttl = now()->addMinutes(1); - $tokens = Cache::remember($key, $ttl, function() use($tag) { - $htag = Str::startsWith($tag, '#') == true ? mb_substr($tag, 1) : $tag; - $hashtags = Hashtag::select('id', 'name', 'slug') - ->where('slug', 'like', '%'.$htag.'%') - ->whereHas('posts') - ->limit(20) - ->get(); - if($hashtags->count() > 0) { - $tags = $hashtags->map(function ($item, $key) { - return [ - 'count' => $item->posts()->count(), - 'url' => $item->url(), - 'type' => 'hashtag', - 'value' => $item->name, - 'tokens' => '', - 'name' => null, - ]; - }); - return $tags; - } - }); - $this->tokens['hashtags'] = $tokens; - } + protected function getHashtags() + { + $tag = $this->term; + $key = $this->cacheKey . 'hashtags:' . $this->hash; + $ttl = now()->addMinutes(1); + $tokens = Cache::remember($key, $ttl, function() use($tag) { + $htag = Str::startsWith($tag, '#') == true ? mb_substr($tag, 1) : $tag; + $hashtags = Hashtag::select('id', 'name', 'slug') + ->where('slug', 'like', '%'.$htag.'%') + ->whereHas('posts') + ->limit(20) + ->get(); + if($hashtags->count() > 0) { + $tags = $hashtags->map(function ($item, $key) { + return [ + 'count' => $item->posts()->count(), + 'url' => $item->url(), + 'type' => 'hashtag', + 'value' => $item->name, + 'tokens' => '', + 'name' => null, + ]; + }); + return $tags; + } + }); + $this->tokens['hashtags'] = $tokens; + } - protected function getPlaces() - { - $tag = $this->term; - // $key = $this->cacheKey . 'places:' . $this->hash; - // $ttl = now()->addHours(12); - // $tokens = Cache::remember($key, $ttl, function() use($tag) { - $htag = Str::contains($tag, ',') == true ? explode(',', $tag) : [$tag]; - $hashtags = Place::select('id', 'name', 'slug', 'country') - ->where('name', 'like', '%'.$htag[0].'%') - ->paginate(20); - $tags = []; - if($hashtags->count() > 0) { - $tags = $hashtags->map(function ($item, $key) { - return [ - 'count' => null, - 'url' => $item->url(), - 'type' => 'place', - 'value' => $item->name . ', ' . $item->country, - 'tokens' => '', - 'name' => null, - 'city' => $item->name, - 'country' => $item->country - ]; - }); - // return $tags; - } - // }); - $this->tokens['places'] = $tags; - $this->tokens['placesPagination'] = [ - 'total' => $hashtags->total(), - 'current_page' => $hashtags->currentPage(), - 'last_page' => $hashtags->lastPage() - ]; - } + protected function getPlaces() + { + $tag = $this->term; + // $key = $this->cacheKey . 'places:' . $this->hash; + // $ttl = now()->addHours(12); + // $tokens = Cache::remember($key, $ttl, function() use($tag) { + $htag = Str::contains($tag, ',') == true ? explode(',', $tag) : [$tag]; + $hashtags = Place::select('id', 'name', 'slug', 'country') + ->where('name', 'like', '%'.$htag[0].'%') + ->paginate(20); + $tags = []; + if($hashtags->count() > 0) { + $tags = $hashtags->map(function ($item, $key) { + return [ + 'count' => null, + 'url' => $item->url(), + 'type' => 'place', + 'value' => $item->name . ', ' . $item->country, + 'tokens' => '', + 'name' => null, + 'city' => $item->name, + 'country' => $item->country + ]; + }); + // return $tags; + } + // }); + $this->tokens['places'] = $tags; + $this->tokens['placesPagination'] = [ + 'total' => $hashtags->total(), + 'current_page' => $hashtags->currentPage(), + 'last_page' => $hashtags->lastPage() + ]; + } - protected function getProfiles() - { - $tag = $this->term; - $remoteKey = $this->cacheKey . 'profiles:remote:' . $this->hash; - $key = $this->cacheKey . 'profiles:' . $this->hash; - $remoteTtl = now()->addMinutes(15); - $ttl = now()->addHours(2); - if( Helpers::validateUrl($tag) != false && - Helpers::validateLocalUrl($tag) != true && - config('federation.activitypub.enabled') == true && - config('federation.activitypub.remoteFollow') == true - ) { - $remote = Helpers::fetchFromUrl($tag); - if( isset($remote['type']) && - $remote['type'] == 'Person' - ) { - $this->tokens['profiles'] = Cache::remember($remoteKey, $remoteTtl, function() use($tag) { - $item = Helpers::profileFirstOrNew($tag); - $tokens = [[ - 'count' => 1, - 'url' => $item->url(), - 'type' => 'profile', - 'value' => $item->username, - 'tokens' => [$item->username], - 'name' => $item->name, - 'entity' => [ - 'id' => (string) $item->id, - 'following' => $item->followedBy(Auth::user()->profile), - 'follow_request' => $item->hasFollowRequestById(Auth::user()->profile_id), - 'thumb' => $item->avatarUrl(), - 'local' => (bool) !$item->domain, - 'post_count' => $item->statuses()->count() - ] - ]]; - return $tokens; - }); - } - } + protected function getProfiles() + { + $tag = $this->term; + $remoteKey = $this->cacheKey . 'profiles:remote:' . $this->hash; + $key = $this->cacheKey . 'profiles:' . $this->hash; + $remoteTtl = now()->addMinutes(15); + $ttl = now()->addHours(2); + if( Helpers::validateUrl($tag) != false && + Helpers::validateLocalUrl($tag) != true && + config_cache('federation.activitypub.enabled') == true && + config('federation.activitypub.remoteFollow') == true + ) { + $remote = Helpers::fetchFromUrl($tag); + if( isset($remote['type']) && + $remote['type'] == 'Person' + ) { + $this->tokens['profiles'] = Cache::remember($remoteKey, $remoteTtl, function() use($tag) { + $item = Helpers::profileFirstOrNew($tag); + $tokens = [[ + 'count' => 1, + 'url' => $item->url(), + 'type' => 'profile', + 'value' => $item->username, + 'tokens' => [$item->username], + 'name' => $item->name, + 'entity' => [ + 'id' => (string) $item->id, + 'following' => $item->followedBy(Auth::user()->profile), + 'follow_request' => $item->hasFollowRequestById(Auth::user()->profile_id), + 'thumb' => $item->avatarUrl(), + 'local' => (bool) !$item->domain, + 'post_count' => $item->statuses()->count() + ] + ]]; + return $tokens; + }); + } + } - else { - $this->tokens['profiles'] = Cache::remember($key, $ttl, function() use($tag) { - if(Str::startsWith($tag, '@')) { - $tag = substr($tag, 1); - } - $users = Profile::select('status', 'domain', 'username', 'name', 'id') - ->whereNull('status') - ->where('username', 'like', '%'.$tag.'%') - ->limit(20) - ->orderBy('domain') - ->get(); + else { + $this->tokens['profiles'] = Cache::remember($key, $ttl, function() use($tag) { + if(Str::startsWith($tag, '@')) { + $tag = substr($tag, 1); + } + $users = Profile::select('status', 'domain', 'username', 'name', 'id') + ->whereNull('status') + ->where('username', 'like', '%'.$tag.'%') + ->limit(20) + ->orderBy('domain') + ->get(); - if($users->count() > 0) { - return $users->map(function ($item, $key) { - return [ - 'count' => 0, - 'url' => $item->url(), - 'type' => 'profile', - 'value' => $item->username, - 'tokens' => [$item->username], - 'name' => $item->name, - 'avatar' => $item->avatarUrl(), - 'id' => (string) $item->id, - 'entity' => [ - 'id' => (string) $item->id, - 'following' => $item->followedBy(Auth::user()->profile), - 'follow_request' => $item->hasFollowRequestById(Auth::user()->profile_id), - 'thumb' => $item->avatarUrl(), - 'local' => (bool) !$item->domain, - 'post_count' => $item->statuses()->count() - ] - ]; - }); - } - }); - } - } + if($users->count() > 0) { + return $users->map(function ($item, $key) { + return [ + 'count' => 0, + 'url' => $item->url(), + 'type' => 'profile', + 'value' => $item->username, + 'tokens' => [$item->username], + 'name' => $item->name, + 'avatar' => $item->avatarUrl(), + 'id' => (string) $item->id, + 'entity' => [ + 'id' => (string) $item->id, + 'following' => $item->followedBy(Auth::user()->profile), + 'follow_request' => $item->hasFollowRequestById(Auth::user()->profile_id), + 'thumb' => $item->avatarUrl(), + 'local' => (bool) !$item->domain, + 'post_count' => $item->statuses()->count() + ] + ]; + }); + } + }); + } + } - public function results(Request $request) - { - $this->validate($request, [ - 'q' => 'required|string|min:1', - ]); - - return view('search.results'); - } + public function results(Request $request) + { + $this->validate($request, [ + 'q' => 'required|string|min:1', + ]); - protected function webfingerSearch() - { - $wfs = WebfingerService::lookup($this->term); + return view('search.results'); + } - if(empty($wfs)) { - return; - } + protected function webfingerSearch() + { + $wfs = WebfingerService::lookup($this->term); - $this->tokens['profiles'] = [ - [ - 'count' => 1, - 'url' => $wfs['url'], - 'type' => 'profile', - 'value' => $wfs['username'], - 'tokens' => [$wfs['username']], - 'name' => $wfs['display_name'], - 'entity' => [ - 'id' => (string) $wfs['id'], - 'following' => null, - 'follow_request' => null, - 'thumb' => $wfs['avatar'], - 'local' => (bool) $wfs['local'] - ] - ] - ]; - return; - } + if(empty($wfs)) { + return; + } - protected function remotePostLookup() - { - $tag = $this->term; - $hash = hash('sha256', $tag); - $local = Helpers::validateLocalUrl($tag); - $valid = Helpers::validateUrl($tag); + $this->tokens['profiles'] = [ + [ + 'count' => 1, + 'url' => $wfs['url'], + 'type' => 'profile', + 'value' => $wfs['username'], + 'tokens' => [$wfs['username']], + 'name' => $wfs['display_name'], + 'entity' => [ + 'id' => (string) $wfs['id'], + 'following' => null, + 'follow_request' => null, + 'thumb' => $wfs['avatar'], + 'local' => (bool) $wfs['local'] + ] + ] + ]; + return; + } - if($valid == false || $local == true) { - return; - } - - if(Status::whereUri($tag)->whereLocal(false)->exists()) { - $item = Status::whereUri($tag)->first(); - $this->tokens['posts'] = [[ - 'count' => 0, - 'url' => "/i/web/post/_/$item->profile_id/$item->id", - 'type' => 'status', - 'username' => $item->profile->username, - 'caption' => $item->rendered ?? $item->caption, - 'thumb' => $item->firstMedia()->remote_url, - 'timestamp' => $item->created_at->diffForHumans() - ]]; - } + protected function remotePostLookup() + { + $tag = $this->term; + $hash = hash('sha256', $tag); + $local = Helpers::validateLocalUrl($tag); + $valid = Helpers::validateUrl($tag); - $remote = Helpers::fetchFromUrl($tag); + if($valid == false || $local == true) { + return; + } - if(isset($remote['type']) && $remote['type'] == 'Note') { - $item = Helpers::statusFetch($tag); - $this->tokens['posts'] = [[ - 'count' => 0, - 'url' => "/i/web/post/_/$item->profile_id/$item->id", - 'type' => 'status', - 'username' => $item->profile->username, - 'caption' => $item->rendered ?? $item->caption, - 'thumb' => $item->firstMedia()->remote_url, - 'timestamp' => $item->created_at->diffForHumans() - ]]; - } - } + if(Status::whereUri($tag)->whereLocal(false)->exists()) { + $item = Status::whereUri($tag)->first(); + $this->tokens['posts'] = [[ + 'count' => 0, + 'url' => "/i/web/post/_/$item->profile_id/$item->id", + 'type' => 'status', + 'username' => $item->profile->username, + 'caption' => $item->rendered ?? $item->caption, + 'thumb' => $item->firstMedia()->remote_url, + 'timestamp' => $item->created_at->diffForHumans() + ]]; + } - protected function remoteLookupSearch() - { - if(!Helpers::validateUrl($this->term)) { - return; - } - $this->getProfiles(); - $this->remotePostLookup(); - } -} \ No newline at end of file + $remote = Helpers::fetchFromUrl($tag); + + if(isset($remote['type']) && $remote['type'] == 'Note') { + $item = Helpers::statusFetch($tag); + $this->tokens['posts'] = [[ + 'count' => 0, + 'url' => "/i/web/post/_/$item->profile_id/$item->id", + 'type' => 'status', + 'username' => $item->profile->username, + 'caption' => $item->rendered ?? $item->caption, + 'thumb' => $item->firstMedia()->remote_url, + 'timestamp' => $item->created_at->diffForHumans() + ]]; + } + } + + protected function remoteLookupSearch() + { + if(!Helpers::validateUrl($this->term)) { + return; + } + $this->getProfiles(); + $this->remotePostLookup(); + } +} diff --git a/app/Http/Controllers/StatusController.php b/app/Http/Controllers/StatusController.php index 4e2d1a16a..985bcfe12 100644 --- a/app/Http/Controllers/StatusController.php +++ b/app/Http/Controllers/StatusController.php @@ -70,11 +70,16 @@ class StatusController extends Controller ]); } - if ($request->wantsJson() && config('federation.activitypub.enabled')) { + if ($request->wantsJson() && config_cache('federation.activitypub.enabled')) { return $this->showActivityPub($request, $status); } $template = $status->in_reply_to_id ? 'status.reply' : 'status.show'; + // $template = $status->type === 'video' && + // $request->has('video_beta') && + // $request->video_beta == 1 && + // $request->user() ? + // 'status.show_video' : 'status.show'; return view($template, compact('user', 'status')); } @@ -340,7 +345,7 @@ class StatusController extends Controller public static function mimeTypeCheck($mimes) { - $allowed = explode(',', config('pixelfed.media_types')); + $allowed = explode(',', config_cache('pixelfed.media_types')); $count = count($mimes); $photos = 0; $videos = 0; diff --git a/app/Jobs/SharePipeline/SharePipeline.php b/app/Jobs/SharePipeline/SharePipeline.php index a3cda16fe..46ed8bf25 100644 --- a/app/Jobs/SharePipeline/SharePipeline.php +++ b/app/Jobs/SharePipeline/SharePipeline.php @@ -18,132 +18,132 @@ use App\Util\ActivityPub\HttpSignature; class SharePipeline implements ShouldQueue { - use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - protected $status; + protected $status; - /** - * Delete the job if its models no longer exist. - * - * @var bool - */ - public $deleteWhenMissingModels = true; + /** + * Delete the job if its models no longer exist. + * + * @var bool + */ + public $deleteWhenMissingModels = true; - /** - * Create a new job instance. - * - * @return void - */ - public function __construct(Status $status) - { - $this->status = $status; - } + /** + * Create a new job instance. + * + * @return void + */ + public function __construct(Status $status) + { + $this->status = $status; + } - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - $status = $this->status; - $actor = $status->profile; - $target = $status->parent()->profile; + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $status = $this->status; + $actor = $status->profile; + $target = $status->parent()->profile; - if ($status->uri !== null) { - // Ignore notifications to remote statuses - return; - } + if ($status->uri !== null) { + // Ignore notifications to remote statuses + return; + } - $exists = Notification::whereProfileId($target->id) - ->whereActorId($status->profile_id) - ->whereAction('share') - ->whereItemId($status->reblog_of_id) - ->whereItemType('App\Status') - ->count(); + $exists = Notification::whereProfileId($target->id) + ->whereActorId($status->profile_id) + ->whereAction('share') + ->whereItemId($status->reblog_of_id) + ->whereItemType('App\Status') + ->count(); - if ($target->id === $status->profile_id) { - $this->remoteAnnounceDeliver(); - return true; - } + if ($target->id === $status->profile_id) { + $this->remoteAnnounceDeliver(); + return true; + } - if( $exists !== 0) { - return true; - } + if( $exists !== 0) { + return true; + } - $this->remoteAnnounceDeliver(); + $this->remoteAnnounceDeliver(); - try { - $notification = new Notification; - $notification->profile_id = $target->id; - $notification->actor_id = $actor->id; - $notification->action = 'share'; - $notification->message = $status->shareToText(); - $notification->rendered = $status->shareToHtml(); - $notification->item_id = $status->reblog_of_id ?? $status->id; - $notification->item_type = "App\Status"; - $notification->save(); + try { + $notification = new Notification; + $notification->profile_id = $target->id; + $notification->actor_id = $actor->id; + $notification->action = 'share'; + $notification->message = $status->shareToText(); + $notification->rendered = $status->shareToHtml(); + $notification->item_id = $status->reblog_of_id ?? $status->id; + $notification->item_type = "App\Status"; + $notification->save(); - $redis = Redis::connection(); - $key = config('cache.prefix').':user.'.$status->profile_id.'.notifications'; - $redis->lpush($key, $notification->id); - } catch (Exception $e) { - Log::error($e); - } - } + $redis = Redis::connection(); + $key = config('cache.prefix').':user.'.$status->profile_id.'.notifications'; + $redis->lpush($key, $notification->id); + } catch (Exception $e) { + Log::error($e); + } + } - public function remoteAnnounceDeliver() - { - if(config('federation.activitypub.enabled') == false) { - return true; - } - $status = $this->status; - $profile = $status->profile; + public function remoteAnnounceDeliver() + { + if(config_cache('federation.activitypub.enabled') == false) { + return true; + } + $status = $this->status; + $profile = $status->profile; - $fractal = new Fractal\Manager(); - $fractal->setSerializer(new ArraySerializer()); - $resource = new Fractal\Resource\Item($status, new Announce()); - $activity = $fractal->createData($resource)->toArray(); + $fractal = new Fractal\Manager(); + $fractal->setSerializer(new ArraySerializer()); + $resource = new Fractal\Resource\Item($status, new Announce()); + $activity = $fractal->createData($resource)->toArray(); - $audience = $status->profile->getAudienceInbox(); + $audience = $status->profile->getAudienceInbox(); - if(empty($audience) || $status->scope != 'public') { - // Return on profiles with no remote followers - return; - } + if(empty($audience) || $status->scope != 'public') { + // Return on profiles with no remote followers + return; + } - $payload = json_encode($activity); - - $client = new Client([ - 'timeout' => config('federation.activitypub.delivery.timeout') - ]); + $payload = json_encode($activity); - $requests = function($audience) use ($client, $activity, $profile, $payload) { - foreach($audience as $url) { - $headers = HttpSignature::sign($profile, $url, $activity); - yield function() use ($client, $url, $headers, $payload) { - return $client->postAsync($url, [ - 'curl' => [ - CURLOPT_HTTPHEADER => $headers, - CURLOPT_POSTFIELDS => $payload, - CURLOPT_HEADER => true - ] - ]); - }; - } - }; + $client = new Client([ + 'timeout' => config('federation.activitypub.delivery.timeout') + ]); - $pool = new Pool($client, $requests($audience), [ - 'concurrency' => config('federation.activitypub.delivery.concurrency'), - 'fulfilled' => function ($response, $index) { - }, - 'rejected' => function ($reason, $index) { - } - ]); - - $promise = $pool->promise(); + $requests = function($audience) use ($client, $activity, $profile, $payload) { + foreach($audience as $url) { + $headers = HttpSignature::sign($profile, $url, $activity); + yield function() use ($client, $url, $headers, $payload) { + return $client->postAsync($url, [ + 'curl' => [ + CURLOPT_HTTPHEADER => $headers, + CURLOPT_POSTFIELDS => $payload, + CURLOPT_HEADER => true + ] + ]); + }; + } + }; - $promise->wait(); + $pool = new Pool($client, $requests($audience), [ + 'concurrency' => config('federation.activitypub.delivery.concurrency'), + 'fulfilled' => function ($response, $index) { + }, + 'rejected' => function ($reason, $index) { + } + ]); - } + $promise = $pool->promise(); + + $promise->wait(); + + } } diff --git a/app/Jobs/StatusPipeline/StatusDelete.php b/app/Jobs/StatusPipeline/StatusDelete.php index 4f29d6b15..5202d79cf 100644 --- a/app/Jobs/StatusPipeline/StatusDelete.php +++ b/app/Jobs/StatusPipeline/StatusDelete.php @@ -4,13 +4,14 @@ namespace App\Jobs\StatusPipeline; use DB, Storage; use App\{ - AccountInterstitial, - MediaTag, - Notification, - Report, - Status, - StatusHashtag, + AccountInterstitial, + MediaTag, + Notification, + Report, + Status, + StatusHashtag, }; +use App\Models\StatusVideo; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -30,150 +31,149 @@ use App\Services\MediaStorageService; class StatusDelete implements ShouldQueue { - use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - protected $status; - - /** - * Delete the job if its models no longer exist. - * - * @var bool - */ - public $deleteWhenMissingModels = true; - - /** - * Create a new job instance. - * - * @return void - */ - public function __construct(Status $status) - { - $this->status = $status; - } + protected $status; - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - $status = $this->status; - $profile = $this->status->profile; + /** + * Delete the job if its models no longer exist. + * + * @var bool + */ + public $deleteWhenMissingModels = true; - StatusService::del($status->id); - $count = $profile->statuses() - ->getQuery() - ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album']) - ->whereNull('in_reply_to_id') - ->whereNull('reblog_of_id') - ->count(); + /** + * Create a new job instance. + * + * @return void + */ + public function __construct(Status $status) + { + $this->status = $status; + } - $profile->status_count = ($count - 1); - $profile->save(); + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $status = $this->status; + $profile = $this->status->profile; - if(config('federation.activitypub.enabled') == true) { - $this->fanoutDelete($status); - } else { - $this->unlinkRemoveMedia($status); - } + StatusService::del($status->id); + $count = $profile->statuses() + ->getQuery() + ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album']) + ->whereNull('in_reply_to_id') + ->whereNull('reblog_of_id') + ->count(); - } + $profile->status_count = ($count - 1); + $profile->save(); - public function unlinkRemoveMedia($status) - { - foreach ($status->media as $media) { - MediaStorageService::delete($media, true); - } + if(config_cache('federation.activitypub.enabled') == true) { + $this->fanoutDelete($status); + } else { + $this->unlinkRemoveMedia($status); + } - if($status->in_reply_to_id) { - DB::transaction(function() use($status) { - $parent = Status::findOrFail($status->in_reply_to_id); - --$parent->reply_count; - $parent->save(); - }); - } - DB::transaction(function() use($status) { - $comments = Status::where('in_reply_to_id', $status->id)->get(); - foreach ($comments as $comment) { - $comment->in_reply_to_id = null; - $comment->save(); - Notification::whereItemType('App\Status') - ->whereItemId($comment->id) - ->delete(); - } - $status->likes()->delete(); - Notification::whereItemType('App\Status') - ->whereItemId($status->id) - ->delete(); - StatusHashtag::whereStatusId($status->id)->delete(); - Report::whereObjectType('App\Status') - ->whereObjectId($status->id) - ->delete(); + } - MediaTag::where('status_id', $status->id) - ->cursor() - ->each(function($tag) { - Notification::where('item_type', 'App\MediaTag') - ->where('item_id', $tag->id) - ->forceDelete(); - $tag->delete(); - }); + public function unlinkRemoveMedia($status) + { + foreach ($status->media as $media) { + MediaStorageService::delete($media, true); + } - AccountInterstitial::where('item_type', 'App\Status') - ->where('item_id', $status->id) - ->delete(); + if($status->in_reply_to_id) { + DB::transaction(function() use($status) { + $parent = Status::findOrFail($status->in_reply_to_id); + --$parent->reply_count; + $parent->save(); + }); + } + DB::transaction(function() use($status) { + $comments = Status::where('in_reply_to_id', $status->id)->get(); + foreach ($comments as $comment) { + $comment->in_reply_to_id = null; + $comment->save(); + Notification::whereItemType('App\Status') + ->whereItemId($comment->id) + ->delete(); + } + $status->likes()->delete(); + Notification::whereItemType('App\Status') + ->whereItemId($status->id) + ->delete(); + StatusHashtag::whereStatusId($status->id)->delete(); + Report::whereObjectType('App\Status') + ->whereObjectId($status->id) + ->delete(); + MediaTag::where('status_id', $status->id) + ->cursor() + ->each(function($tag) { + Notification::where('item_type', 'App\MediaTag') + ->where('item_id', $tag->id) + ->forceDelete(); + $tag->delete(); + }); + StatusVideo::whereStatusId($status->id)->delete(); + AccountInterstitial::where('item_type', 'App\Status') + ->where('item_id', $status->id) + ->delete(); - $status->forceDelete(); - }); + $status->forceDelete(); + }); - return true; - } + return true; + } - protected function fanoutDelete($status) - { - $audience = $status->profile->getAudienceInbox(); - $profile = $status->profile; + protected function fanoutDelete($status) + { + $audience = $status->profile->getAudienceInbox(); + $profile = $status->profile; - $fractal = new Fractal\Manager(); - $fractal->setSerializer(new ArraySerializer()); - $resource = new Fractal\Resource\Item($status, new DeleteNote()); - $activity = $fractal->createData($resource)->toArray(); + $fractal = new Fractal\Manager(); + $fractal->setSerializer(new ArraySerializer()); + $resource = new Fractal\Resource\Item($status, new DeleteNote()); + $activity = $fractal->createData($resource)->toArray(); - $this->unlinkRemoveMedia($status); - - $payload = json_encode($activity); - - $client = new Client([ - 'timeout' => config('federation.activitypub.delivery.timeout') - ]); + $this->unlinkRemoveMedia($status); - $requests = function($audience) use ($client, $activity, $profile, $payload) { - foreach($audience as $url) { - $headers = HttpSignature::sign($profile, $url, $activity); - yield function() use ($client, $url, $headers, $payload) { - return $client->postAsync($url, [ - 'curl' => [ - CURLOPT_HTTPHEADER => $headers, - CURLOPT_POSTFIELDS => $payload, - CURLOPT_HEADER => true - ] - ]); - }; - } - }; + $payload = json_encode($activity); - $pool = new Pool($client, $requests($audience), [ - 'concurrency' => config('federation.activitypub.delivery.concurrency'), - 'fulfilled' => function ($response, $index) { - }, - 'rejected' => function ($reason, $index) { - } - ]); - - $promise = $pool->promise(); + $client = new Client([ + 'timeout' => config('federation.activitypub.delivery.timeout') + ]); - $promise->wait(); + $requests = function($audience) use ($client, $activity, $profile, $payload) { + foreach($audience as $url) { + $headers = HttpSignature::sign($profile, $url, $activity); + yield function() use ($client, $url, $headers, $payload) { + return $client->postAsync($url, [ + 'curl' => [ + CURLOPT_HTTPHEADER => $headers, + CURLOPT_POSTFIELDS => $payload, + CURLOPT_HEADER => true + ] + ]); + }; + } + }; - } + $pool = new Pool($client, $requests($audience), [ + 'concurrency' => config('federation.activitypub.delivery.concurrency'), + 'fulfilled' => function ($response, $index) { + }, + 'rejected' => function ($reason, $index) { + } + ]); + + $promise = $pool->promise(); + + $promise->wait(); + + } } diff --git a/app/Jobs/StatusPipeline/StatusEntityLexer.php b/app/Jobs/StatusPipeline/StatusEntityLexer.php index e173c6394..d7830c317 100644 --- a/app/Jobs/StatusPipeline/StatusEntityLexer.php +++ b/app/Jobs/StatusPipeline/StatusEntityLexer.php @@ -21,146 +21,146 @@ use Illuminate\Queue\SerializesModels; class StatusEntityLexer implements ShouldQueue { - use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - protected $status; - protected $entities; - protected $autolink; - - /** - * Delete the job if its models no longer exist. - * - * @var bool - */ - public $deleteWhenMissingModels = true; - - /** - * Create a new job instance. - * - * @return void - */ - public function __construct(Status $status) - { - $this->status = $status; - } + protected $status; + protected $entities; + protected $autolink; - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - $profile = $this->status->profile; + /** + * Delete the job if its models no longer exist. + * + * @var bool + */ + public $deleteWhenMissingModels = true; - $count = $profile->statuses() - ->getQuery() - ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album']) - ->whereNull('in_reply_to_id') - ->whereNull('reblog_of_id') - ->count(); + /** + * Create a new job instance. + * + * @return void + */ + public function __construct(Status $status) + { + $this->status = $status; + } - $profile->status_count = $count; - $profile->save(); + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $profile = $this->status->profile; - if($profile->no_autolink == false) { - $this->parseEntities(); - } - } + $count = $profile->statuses() + ->getQuery() + ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album']) + ->whereNull('in_reply_to_id') + ->whereNull('reblog_of_id') + ->count(); - public function parseEntities() - { - $this->extractEntities(); - } + $profile->status_count = $count; + $profile->save(); - public function extractEntities() - { - $this->entities = Extractor::create()->extract($this->status->caption); - $this->autolinkStatus(); - } + if($profile->no_autolink == false) { + $this->parseEntities(); + } + } - public function autolinkStatus() - { - $this->autolink = Autolink::create()->autolink($this->status->caption); - $this->storeEntities(); - } + public function parseEntities() + { + $this->extractEntities(); + } - public function storeEntities() - { - $this->storeHashtags(); - DB::transaction(function () { - $status = $this->status; - $status->rendered = nl2br($this->autolink); - $status->entities = json_encode($this->entities); - $status->save(); - }); - } + public function extractEntities() + { + $this->entities = Extractor::create()->extract($this->status->caption); + $this->autolinkStatus(); + } - public function storeHashtags() - { - $tags = array_unique($this->entities['hashtags']); - $status = $this->status; + public function autolinkStatus() + { + $this->autolink = Autolink::create()->autolink($this->status->caption); + $this->storeEntities(); + } - foreach ($tags as $tag) { - if(mb_strlen($tag) > 124) { - continue; - } - DB::transaction(function () use ($status, $tag) { - $slug = str_slug($tag, '-', false); - $hashtag = Hashtag::firstOrCreate( - ['name' => $tag, 'slug' => $slug] - ); - StatusHashtag::firstOrCreate( - [ - 'status_id' => $status->id, - 'hashtag_id' => $hashtag->id, - 'profile_id' => $status->profile_id, - 'status_visibility' => $status->visibility, - ] - ); - }); - } - $this->storeMentions(); - } + public function storeEntities() + { + $this->storeHashtags(); + DB::transaction(function () { + $status = $this->status; + $status->rendered = nl2br($this->autolink); + $status->entities = json_encode($this->entities); + $status->save(); + }); + } - public function storeMentions() - { - $mentions = array_unique($this->entities['mentions']); - $status = $this->status; + public function storeHashtags() + { + $tags = array_unique($this->entities['hashtags']); + $status = $this->status; - foreach ($mentions as $mention) { - $mentioned = Profile::whereUsername($mention)->first(); + foreach ($tags as $tag) { + if(mb_strlen($tag) > 124) { + continue; + } + DB::transaction(function () use ($status, $tag) { + $slug = str_slug($tag, '-', false); + $hashtag = Hashtag::firstOrCreate( + ['name' => $tag, 'slug' => $slug] + ); + StatusHashtag::firstOrCreate( + [ + 'status_id' => $status->id, + 'hashtag_id' => $hashtag->id, + 'profile_id' => $status->profile_id, + 'status_visibility' => $status->visibility, + ] + ); + }); + } + $this->storeMentions(); + } - if (empty($mentioned) || !isset($mentioned->id)) { - continue; - } + public function storeMentions() + { + $mentions = array_unique($this->entities['mentions']); + $status = $this->status; - DB::transaction(function () use ($status, $mentioned) { - $m = new Mention(); - $m->status_id = $status->id; - $m->profile_id = $mentioned->id; - $m->save(); + foreach ($mentions as $mention) { + $mentioned = Profile::whereUsername($mention)->first(); - MentionPipeline::dispatch($status, $m); - }); - } - $this->deliver(); - } + if (empty($mentioned) || !isset($mentioned->id)) { + continue; + } - public function deliver() - { - $status = $this->status; + DB::transaction(function () use ($status, $mentioned) { + $m = new Mention(); + $m->status_id = $status->id; + $m->profile_id = $mentioned->id; + $m->save(); - if(config('pixelfed.bouncer.enabled')) { - Bouncer::get($status); - } + MentionPipeline::dispatch($status, $m); + }); + } + $this->deliver(); + } - if($status->uri == null && $status->scope == 'public') { - PublicTimelineService::add($status->id); - } + public function deliver() + { + $status = $this->status; - if(config('federation.activitypub.enabled') == true && config('app.env') == 'production') { - StatusActivityPubDeliver::dispatch($this->status); - } - } + if(config('pixelfed.bouncer.enabled')) { + Bouncer::get($status); + } + + if($status->uri == null && $status->scope == 'public') { + PublicTimelineService::add($status->id); + } + + if(config_cache('federation.activitypub.enabled') == true && config('app.env') == 'production') { + StatusActivityPubDeliver::dispatch($this->status); + } + } } diff --git a/app/Util/ActivityPub/Outbox.php b/app/Util/ActivityPub/Outbox.php index 3e5f78a74..43adb36e3 100644 --- a/app/Util/ActivityPub/Outbox.php +++ b/app/Util/ActivityPub/Outbox.php @@ -13,7 +13,7 @@ class Outbox { public static function get($profile) { - abort_if(!config('federation.activitypub.enabled'), 404); + abort_if(!config_cache('federation.activitypub.enabled'), 404); abort_if(!config('federation.activitypub.outbox'), 404); if($profile->status != null) { @@ -48,4 +48,4 @@ class Outbox { return $outbox; } -} \ No newline at end of file +} diff --git a/app/Util/Site/Config.php b/app/Util/Site/Config.php index 2f89ca338..39f9d054c 100644 --- a/app/Util/Site/Config.php +++ b/app/Util/Site/Config.php @@ -27,7 +27,7 @@ class Config { ], 'activitypub' => [ - 'enabled' => config('federation.activitypub.enabled'), + 'enabled' => config_cache('federation.activitypub.enabled'), 'remote_follow' => config('federation.activitypub.remoteFollow') ],