mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-23 15:01:27 +00:00
commit
935fa47c59
4 changed files with 98 additions and 111 deletions
|
@ -45,6 +45,7 @@ use App\Jobs\AvatarPipeline\AvatarOptimize;
|
||||||
use App\Jobs\CommentPipeline\CommentPipeline;
|
use App\Jobs\CommentPipeline\CommentPipeline;
|
||||||
use App\Jobs\LikePipeline\LikePipeline;
|
use App\Jobs\LikePipeline\LikePipeline;
|
||||||
use App\Jobs\SharePipeline\SharePipeline;
|
use App\Jobs\SharePipeline\SharePipeline;
|
||||||
|
use App\Jobs\SharePipeline\UndoSharePipeline;
|
||||||
use App\Jobs\StatusPipeline\NewStatusPipeline;
|
use App\Jobs\StatusPipeline\NewStatusPipeline;
|
||||||
use App\Jobs\StatusPipeline\StatusDelete;
|
use App\Jobs\StatusPipeline\StatusDelete;
|
||||||
use App\Jobs\FollowPipeline\FollowPipeline;
|
use App\Jobs\FollowPipeline\FollowPipeline;
|
||||||
|
@ -57,8 +58,9 @@ use App\Jobs\VideoPipeline\{
|
||||||
|
|
||||||
use App\Services\{
|
use App\Services\{
|
||||||
AccountService,
|
AccountService,
|
||||||
LikeService,
|
FollowerService,
|
||||||
InstanceService,
|
InstanceService,
|
||||||
|
LikeService,
|
||||||
NotificationService,
|
NotificationService,
|
||||||
MediaPathService,
|
MediaPathService,
|
||||||
PublicTimelineService,
|
PublicTimelineService,
|
||||||
|
@ -74,6 +76,7 @@ use App\Util\Lexer\Autolink;
|
||||||
use App\Util\Localization\Localization;
|
use App\Util\Localization\Localization;
|
||||||
use App\Util\Media\License;
|
use App\Util\Media\License;
|
||||||
use App\Jobs\MediaPipeline\MediaSyncLicensePipeline;
|
use App\Jobs\MediaPipeline\MediaSyncLicensePipeline;
|
||||||
|
use App\Services\DiscoverService;
|
||||||
|
|
||||||
class ApiV1Controller extends Controller
|
class ApiV1Controller extends Controller
|
||||||
{
|
{
|
||||||
|
@ -1317,7 +1320,7 @@ class ApiV1Controller extends Controller
|
||||||
$settings = UserSetting::whereUserId($user->id)->first();
|
$settings = UserSetting::whereUserId($user->id)->first();
|
||||||
|
|
||||||
if($settings && !empty($settings->compose_settings)) {
|
if($settings && !empty($settings->compose_settings)) {
|
||||||
$compose = json_decode($settings->compose_settings, true);
|
$compose = $settings->compose_settings;
|
||||||
|
|
||||||
if(isset($compose['default_license']) && $compose['default_license'] != 1) {
|
if(isset($compose['default_license']) && $compose['default_license'] != 1) {
|
||||||
$license = $compose['default_license'];
|
$license = $compose['default_license'];
|
||||||
|
@ -1790,18 +1793,23 @@ class ApiV1Controller extends Controller
|
||||||
|
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
|
||||||
$status = Status::findOrFail($id);
|
$res = StatusService::get($id, false);
|
||||||
|
if(!$res || !isset($res['visibility'])) {
|
||||||
|
abort(404);
|
||||||
|
}
|
||||||
|
|
||||||
if($status->profile_id !== $user->profile_id) {
|
$scope = $res['visibility'];
|
||||||
if($status->scope == 'private') {
|
if(!in_array($scope, ['public', 'unlisted'])) {
|
||||||
abort_if(!$status->profile->followedBy($user->profile), 403);
|
if($scope === 'private') {
|
||||||
|
if($res['account']['id'] != $user->profile_id) {
|
||||||
|
abort_unless(FollowerService::follows($user->profile_id, $res['account']['id']), 403);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
abort_if(!in_array($status->scope, ['public','unlisted']), 403);
|
abort(400, 'Invalid request');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = StatusService::get($status->id);
|
$res['favourited'] = LikeService::liked($user->profile_id, $res['id']);
|
||||||
$res['favourited'] = LikeService::liked($user->profile_id, $status->id);
|
|
||||||
$res['reblogged'] = false;
|
$res['reblogged'] = false;
|
||||||
return response()->json($res);
|
return response()->json($res);
|
||||||
}
|
}
|
||||||
|
@ -2069,7 +2077,9 @@ class ApiV1Controller extends Controller
|
||||||
$status->in_reply_to_profile_id = $parent->profile_id;
|
$status->in_reply_to_profile_id = $parent->profile_id;
|
||||||
$status->save();
|
$status->save();
|
||||||
StatusService::del($parent->id);
|
StatusService::del($parent->id);
|
||||||
} else if($ids) {
|
}
|
||||||
|
|
||||||
|
if($ids) {
|
||||||
if(Media::whereUserId($user->id)
|
if(Media::whereUserId($user->id)
|
||||||
->whereNull('status_id')
|
->whereNull('status_id')
|
||||||
->find($ids)
|
->find($ids)
|
||||||
|
@ -2077,12 +2087,15 @@ class ApiV1Controller extends Controller
|
||||||
) {
|
) {
|
||||||
abort(400, 'Invalid media_ids');
|
abort(400, 'Invalid media_ids');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!$in_reply_to_id) {
|
||||||
$status = new Status;
|
$status = new Status;
|
||||||
$status->caption = strip_tags($request->input('status'));
|
$status->caption = strip_tags($request->input('status'));
|
||||||
$status->profile_id = $user->profile_id;
|
$status->profile_id = $user->profile_id;
|
||||||
$status->scope = 'draft';
|
$status->scope = 'draft';
|
||||||
$status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive', false);
|
$status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive', false);
|
||||||
$status->save();
|
$status->save();
|
||||||
|
}
|
||||||
|
|
||||||
$mimes = [];
|
$mimes = [];
|
||||||
|
|
||||||
|
@ -2230,6 +2243,7 @@ class ApiV1Controller extends Controller
|
||||||
UndoSharePipeline::dispatch($reblog);
|
UndoSharePipeline::dispatch($reblog);
|
||||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||||
$res = $this->fractal->createData($resource)->toArray();
|
$res = $this->fractal->createData($resource)->toArray();
|
||||||
|
$res['reblogged'] = false;
|
||||||
return response()->json($res);
|
return response()->json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2429,55 +2443,20 @@ class ApiV1Controller extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$limit = $request->input('limit', 40);
|
$limit = $request->input('limit', 40);
|
||||||
$profile = Auth::user()->profile;
|
$pid = $request->user()->profile_id;
|
||||||
$pid = $profile->id;
|
$filters = UserFilterService::filters($pid);
|
||||||
|
$forYou = DiscoverService::getForYou();
|
||||||
$following = Cache::remember('feature:discover:following:'.$pid, now()->addMinutes(15), function() use ($pid) {
|
$posts = $forYou->random(50)->map(function($post) {
|
||||||
return Follower::whereProfileId($pid)->pluck('following_id')->toArray();
|
|
||||||
});
|
|
||||||
|
|
||||||
$filters = Cache::remember("user:filter:list:$pid", now()->addMinutes(15), function() use($pid) {
|
|
||||||
$private = Profile::whereIsPrivate(true)
|
|
||||||
->orWhere('unlisted', true)
|
|
||||||
->orWhere('status', '!=', null)
|
|
||||||
->pluck('id')
|
|
||||||
->toArray();
|
|
||||||
$filters = UserFilter::whereUserId($pid)
|
|
||||||
->whereFilterableType('App\Profile')
|
|
||||||
->whereIn('filter_type', ['mute', 'block'])
|
|
||||||
->pluck('filterable_id')
|
|
||||||
->toArray();
|
|
||||||
return array_merge($private, $filters);
|
|
||||||
});
|
|
||||||
$following = array_merge($following, $filters);
|
|
||||||
|
|
||||||
$sql = config('database.default') !== 'pgsql';
|
|
||||||
$min_id = SnowflakeService::byDate(now()->subMonths(3));
|
|
||||||
$res = Status::select(
|
|
||||||
'id',
|
|
||||||
'is_nsfw',
|
|
||||||
'profile_id',
|
|
||||||
'type',
|
|
||||||
'uri',
|
|
||||||
)
|
|
||||||
->whereNull('uri')
|
|
||||||
->whereIn('type', ['photo','photo:album', 'video'])
|
|
||||||
->whereIsNsfw(false)
|
|
||||||
->whereVisibility('public')
|
|
||||||
->whereNotIn('profile_id', $following)
|
|
||||||
->where('id', '>', $min_id)
|
|
||||||
->inRandomOrder()
|
|
||||||
->take($limit)
|
|
||||||
->pluck('id')
|
|
||||||
->map(function($post) {
|
|
||||||
return StatusService::get($post);
|
return StatusService::get($post);
|
||||||
})
|
})
|
||||||
->filter(function($post) {
|
->filter(function($post) use($filters) {
|
||||||
return $post && isset($post['id']);
|
return $post &&
|
||||||
|
isset($post['account']) &&
|
||||||
|
isset($post['account']['id']) &&
|
||||||
|
!in_array($post['account']['id'], $filters);
|
||||||
})
|
})
|
||||||
->values()
|
->take(12)
|
||||||
->toArray();
|
->values();
|
||||||
|
return response()->json(compact('posts'));
|
||||||
return response()->json($res);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ use App\Services\ModLogService;
|
||||||
use App\Services\PublicTimelineService;
|
use App\Services\PublicTimelineService;
|
||||||
use App\Services\SnowflakeService;
|
use App\Services\SnowflakeService;
|
||||||
use App\Services\StatusService;
|
use App\Services\StatusService;
|
||||||
|
use App\Services\UserFilterService;
|
||||||
|
use App\Services\DiscoverService;
|
||||||
|
|
||||||
class InternalApiController extends Controller
|
class InternalApiController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -67,51 +69,21 @@ class InternalApiController extends Controller
|
||||||
|
|
||||||
public function discoverPosts(Request $request)
|
public function discoverPosts(Request $request)
|
||||||
{
|
{
|
||||||
$profile = Auth::user()->profile;
|
$pid = $request->user()->profile_id;
|
||||||
$pid = $profile->id;
|
$filters = UserFilterService::filters($pid);
|
||||||
$following = Cache::remember('feature:discover:following:'.$pid, now()->addMinutes(15), function() use ($pid) {
|
$forYou = DiscoverService::getForYou();
|
||||||
return Follower::whereProfileId($pid)->pluck('following_id')->toArray();
|
$posts = $forYou->random(50)->map(function($post) {
|
||||||
});
|
|
||||||
$filters = Cache::remember("user:filter:list:$pid", now()->addMinutes(15), function() use($pid) {
|
|
||||||
$private = Profile::whereIsPrivate(true)
|
|
||||||
->orWhere('unlisted', true)
|
|
||||||
->orWhere('status', '!=', null)
|
|
||||||
->pluck('id')
|
|
||||||
->toArray();
|
|
||||||
$filters = UserFilter::whereUserId($pid)
|
|
||||||
->whereFilterableType('App\Profile')
|
|
||||||
->whereIn('filter_type', ['mute', 'block'])
|
|
||||||
->pluck('filterable_id')
|
|
||||||
->toArray();
|
|
||||||
return array_merge($private, $filters);
|
|
||||||
});
|
|
||||||
$following = array_merge($following, $filters);
|
|
||||||
|
|
||||||
$sql = config('database.default') !== 'pgsql';
|
|
||||||
$min_id = SnowflakeService::byDate(now()->subMonths(3));
|
|
||||||
$posts = Status::select(
|
|
||||||
'id',
|
|
||||||
'is_nsfw',
|
|
||||||
'profile_id',
|
|
||||||
'type',
|
|
||||||
'uri',
|
|
||||||
)
|
|
||||||
->whereNull('uri')
|
|
||||||
->whereIn('type', ['photo','photo:album', 'video'])
|
|
||||||
->whereIsNsfw(false)
|
|
||||||
->whereVisibility('public')
|
|
||||||
->whereNotIn('profile_id', $following)
|
|
||||||
->where('id', '>', $min_id)
|
|
||||||
->inRandomOrder()
|
|
||||||
->take(39)
|
|
||||||
->pluck('id');
|
|
||||||
|
|
||||||
$res = [
|
|
||||||
'posts' => $posts->map(function($post) {
|
|
||||||
return StatusService::get($post);
|
return StatusService::get($post);
|
||||||
})
|
})
|
||||||
];
|
->filter(function($post) use($filters) {
|
||||||
return response()->json($res);
|
return $post &&
|
||||||
|
isset($post['account']) &&
|
||||||
|
isset($post['account']['id']) &&
|
||||||
|
!in_array($post['account']['id'], $filters);
|
||||||
|
})
|
||||||
|
->take(12)
|
||||||
|
->values();
|
||||||
|
return response()->json(compact('posts'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function directMessage(Request $request, $profileId, $threadId)
|
public function directMessage(Request $request, $profileId, $threadId)
|
||||||
|
|
36
app/Services/DiscoverService.php
Normal file
36
app/Services/DiscoverService.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use App\Status;
|
||||||
|
|
||||||
|
class DiscoverService
|
||||||
|
{
|
||||||
|
public static function getDailyIdPool()
|
||||||
|
{
|
||||||
|
$min_id = SnowflakeService::byDate(now()->subMonths(3));
|
||||||
|
return Status::select(
|
||||||
|
'id',
|
||||||
|
'is_nsfw',
|
||||||
|
'profile_id',
|
||||||
|
'type',
|
||||||
|
'uri',
|
||||||
|
)
|
||||||
|
->whereNull('uri')
|
||||||
|
->whereType('photo')
|
||||||
|
->whereIsNsfw(false)
|
||||||
|
->whereVisibility('public')
|
||||||
|
->where('id', '>', $min_id)
|
||||||
|
->inRandomOrder()
|
||||||
|
->take(300)
|
||||||
|
->pluck('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getForYou()
|
||||||
|
{
|
||||||
|
return Cache::remember('pf:services:discover:for-you', 21600, function() {
|
||||||
|
return self::getDailyIdPool();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -80,7 +80,7 @@ Route::group(['prefix' => 'api'], function() use($middleware) {
|
||||||
Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware($middleware);
|
Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware($middleware);
|
||||||
Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic')->middleware($middleware);
|
Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic')->middleware($middleware);
|
||||||
Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag');
|
Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag');
|
||||||
Route::get('discover/posts', 'Api\ApiV1Controlle@discoverPosts')->middleware($middleware);
|
Route::get('discover/posts', 'Api\ApiV1Controller@discoverPosts')->middleware($middleware);
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['prefix' => 'v2'], function() use($middleware) {
|
Route::group(['prefix' => 'v2'], function() use($middleware) {
|
||||||
|
|
Loading…
Reference in a new issue