mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-10 00:34:50 +00:00
commit
0900045d8a
7 changed files with 280 additions and 148 deletions
|
@ -90,6 +90,14 @@
|
|||
- Updated Inbox, fixes #3314. ([dfcd2e6d](https://github.com/pixelfed/pixelfed/commit/dfcd2e6d))
|
||||
- Updated search service, fix banned instance edge case. ([74018e9c](https://github.com/pixelfed/pixelfed/commit/74018e9c))
|
||||
- Updated inbox, fixes #3315. ([c3c3ce18](https://github.com/pixelfed/pixelfed/commit/c3c3ce18))
|
||||
- Updated ApiV1Controller, fix instance endpoint. ([c383f100](https://github.com/pixelfed/pixelfed/commit/c383f100))
|
||||
- Updated ApiV1Controller, marshal json without escaped slashes. ([89303fa4](https://github.com/pixelfed/pixelfed/commit/89303fa4))
|
||||
- Updated ApiV1Controller, fix statusCreate validator. ([b6b15b0c](https://github.com/pixelfed/pixelfed/commit/b6b15b0c))
|
||||
- Updated ApiV1Controller, fix notification entities. ([afe903c3](https://github.com/pixelfed/pixelfed/commit/afe903c3))
|
||||
- Updated FederationController, fix webfinger endpoint. ([a0e15d89](https://github.com/pixelfed/pixelfed/commit/a0e15d89))
|
||||
- Updated ApiV1Controller, fix context entities. ([b1ab41e0](https://github.com/pixelfed/pixelfed/commit/b1ab41e0))
|
||||
- Updated ApiV1Controller, fix timeline default limit. ([a87f8301](https://github.com/pixelfed/pixelfed/commit/a87f8301))
|
||||
- Updated ApiV1Controller, fix search v2 entities. ([9dac861e](https://github.com/pixelfed/pixelfed/commit/9dac861e))
|
||||
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
||||
|
||||
## [v0.11.2 (2022-01-09)](https://github.com/pixelfed/pixelfed/compare/v0.11.1...v0.11.2)
|
||||
|
|
|
@ -91,6 +91,11 @@ class ApiV1Controller extends Controller
|
|||
$this->fractal->setSerializer(new ArraySerializer());
|
||||
}
|
||||
|
||||
public function json($res, $code = 200, $headers = [])
|
||||
{
|
||||
return response()->json($res, $code, $headers, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
public function apps(Request $request)
|
||||
{
|
||||
abort_if(!config_cache('pixelfed.oauth_enabled'), 404);
|
||||
|
@ -126,7 +131,7 @@ class ApiV1Controller extends Controller
|
|||
'vapid_key' => null
|
||||
];
|
||||
|
||||
return response()->json($res, 200, [
|
||||
return $this->json($res, 200, [
|
||||
'Access-Control-Allow-Origin' => '*'
|
||||
]);
|
||||
}
|
||||
|
@ -154,7 +159,7 @@ class ApiV1Controller extends Controller
|
|||
'fields' => []
|
||||
];
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,7 +175,7 @@ class ApiV1Controller extends Controller
|
|||
if(!$res) {
|
||||
return response()->json(['error' => 'Record not found'], 404);
|
||||
}
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -402,7 +407,7 @@ class ApiV1Controller extends Controller
|
|||
$res['bio'] = strip_tags($res['note']);
|
||||
$res = array_merge($res, $other);
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -449,7 +454,7 @@ class ApiV1Controller extends Controller
|
|||
->values()
|
||||
->toArray();
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -496,7 +501,7 @@ class ApiV1Controller extends Controller
|
|||
->values()
|
||||
->toArray();
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -582,7 +587,7 @@ class ApiV1Controller extends Controller
|
|||
})
|
||||
->values();
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -622,7 +627,7 @@ class ApiV1Controller extends Controller
|
|||
// Following already, return empty relationship
|
||||
if($isFollowing == true) {
|
||||
$res = RelationshipService::get($user->profile_id, $target->id) ?? [];
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
// Rate limits, max 7500 followers per account
|
||||
|
@ -672,7 +677,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$res = RelationshipService::get($user->profile_id, $target->id);
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -703,7 +708,7 @@ class ApiV1Controller extends Controller
|
|||
$resource = new Fractal\Resource\Item($target, new RelationshipTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
// Rate limits, follow 30 accounts per hour max
|
||||
|
@ -742,7 +747,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$res = RelationshipService::get($user->profile_id, $target->id);
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -768,7 +773,7 @@ class ApiV1Controller extends Controller
|
|||
->map(function($id) use($pid) {
|
||||
return RelationshipService::get($pid, $id);
|
||||
});
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -802,7 +807,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$resource = new Fractal\Resource\Collection($profiles, new AccountTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -834,7 +839,7 @@ class ApiV1Controller extends Controller
|
|||
$profiles = Profile::findOrFail($blocked);
|
||||
$resource = new Fractal\Resource\Collection($profiles, new AccountTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -878,7 +883,7 @@ class ApiV1Controller extends Controller
|
|||
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -913,13 +918,13 @@ class ApiV1Controller extends Controller
|
|||
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/custom_emojis
|
||||
*
|
||||
* Return empty array, we don't support custom emoji
|
||||
* Return custom emoji
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
@ -1003,13 +1008,9 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$baseUrl = config('app.url') . '/api/v1/favourites?limit=' . $limit . '&';
|
||||
$link = '<'.$baseUrl.'max_id='.$max.'>; rel="next",<'.$baseUrl.'min_id='.$min.'>; rel="prev"';
|
||||
return response()
|
||||
->json($res)
|
||||
->withHeaders([
|
||||
'Link' => $link,
|
||||
]);
|
||||
return $this->json($res, 200, ['Link' => $link]);
|
||||
} else {
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1064,7 +1065,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$status['favourited'] = true;
|
||||
$status['favourites_count'] = $status['favourites_count'] + 1;
|
||||
return response()->json($status);
|
||||
return $this->json($status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1104,7 +1105,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$res = StatusService::getMastodon($status->id, false);
|
||||
$res['favourited'] = false;
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1140,7 +1141,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$resource = new Fractal\Resource\Collection($profiles, new AccountTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1236,18 +1237,20 @@ class ApiV1Controller extends Controller
|
|||
'description' => 'Pixelfed is an image sharing platform, an ethical alternative to centralized platforms',
|
||||
'email' => config('instance.email'),
|
||||
'version' => '2.7.2 (compatible; Pixelfed ' . config('pixelfed.version') .')',
|
||||
'urls' => [],
|
||||
'urls' => [
|
||||
'streaming_api' => 'wss://' . config('pixelfed.domain.app')
|
||||
],
|
||||
'stats' => $stats,
|
||||
'thumbnail' => url('headers/default.jpg'),
|
||||
'thumbnail' => url('img/pixelfed-icon-color.png'),
|
||||
'languages' => ['en'],
|
||||
'registrations' => (bool) config('pixelfed.open_registration'),
|
||||
'registrations' => (bool) config_cache('pixelfed.open_registration'),
|
||||
'approval_required' => false,
|
||||
'contact_account' => $contact,
|
||||
'rules' => $rules
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1400,7 +1403,7 @@ class ApiV1Controller extends Controller
|
|||
$res = $this->fractal->createData($resource)->toArray();
|
||||
$res['preview_url'] = $media->url(). '?cb=1&_v=' . time();
|
||||
$res['url'] = $media->url(). '?cb=1&_v=' . time();
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1431,7 +1434,31 @@ class ApiV1Controller extends Controller
|
|||
$res = $this->fractal->createData($resource)->toArray();
|
||||
$res['preview_url'] = url('/storage/no-preview.png');
|
||||
$res['url'] = url('/storage/no-preview.png');
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/media/{id}
|
||||
*
|
||||
* @param integer $id
|
||||
*
|
||||
* @return MediaTransformer
|
||||
*/
|
||||
public function mediaGet(Request $request, $id)
|
||||
{
|
||||
abort_if(!$request->user(), 403);
|
||||
|
||||
$user = $request->user();
|
||||
|
||||
$media = Media::whereUserId($user->id)
|
||||
->whereNull('status_id')
|
||||
->findOrFail($id);
|
||||
|
||||
$resource = new Fractal\Resource\Item($media, new MediaTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
$res['preview_url'] = url('/storage/no-preview.png');
|
||||
$res['url'] = url('/storage/no-preview.png');
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1461,7 +1488,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$resource = new Fractal\Resource\Collection($accounts, new AccountTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1493,7 +1520,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$resource = new Fractal\Resource\Item($account, new RelationshipTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1527,7 +1554,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$resource = new Fractal\Resource\Item($account, new RelationshipTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1562,14 +1589,14 @@ class ApiV1Controller extends Controller
|
|||
$minId = null;
|
||||
|
||||
if($max) {
|
||||
$res = NotificationService::getMax($pid, $max, $limit);
|
||||
$res = NotificationService::getMaxMastodon($pid, $max, $limit);
|
||||
$ids = NotificationService::getRankedMaxId($pid, $max, $limit);
|
||||
if(!empty($ids)) {
|
||||
$maxId = max($ids);
|
||||
$minId = min($ids);
|
||||
}
|
||||
} else {
|
||||
$res = NotificationService::getMin($pid, $min ?? $since, $limit);
|
||||
$res = NotificationService::getMinMastodon($pid, $min ?? $since, $limit);
|
||||
$ids = NotificationService::getRankedMinId($pid, $min ?? $since, $limit);
|
||||
if(!empty($ids)) {
|
||||
$maxId = max($ids);
|
||||
|
@ -1600,15 +1627,8 @@ class ApiV1Controller extends Controller
|
|||
$link = '<'.$baseUrl.'max_id='.$maxId.'>; rel="next",<'.$baseUrl.'min_id='.$minId.'>; rel="prev"';
|
||||
}
|
||||
|
||||
$res = response()->json($res);
|
||||
|
||||
if(isset($link)) {
|
||||
$res->withHeaders([
|
||||
'Link' => $link,
|
||||
]);
|
||||
}
|
||||
|
||||
return $res;
|
||||
$headers = isset($link) ? ['Link' => $link] : [];
|
||||
return $this->json($res, 200, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1629,7 +1649,7 @@ class ApiV1Controller extends Controller
|
|||
$page = $request->input('page');
|
||||
$min = $request->input('min_id');
|
||||
$max = $request->input('max_id');
|
||||
$limit = $request->input('limit') ?? 3;
|
||||
$limit = $request->input('limit') ?? 20;
|
||||
$pid = $request->user()->profile_id;
|
||||
|
||||
$following = Cache::remember('profile:following:'.$pid, now()->addMinutes(1440), function() use($pid) {
|
||||
|
@ -1704,7 +1724,7 @@ class ApiV1Controller extends Controller
|
|||
->toArray();
|
||||
}
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1770,7 +1790,7 @@ class ApiV1Controller extends Controller
|
|||
})
|
||||
->values();
|
||||
|
||||
return response()->json($dms);
|
||||
return $this->json($dms);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1789,7 +1809,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$min = $request->input('min_id');
|
||||
$max = $request->input('max_id');
|
||||
$limit = $request->input('limit') ?? 3;
|
||||
$limit = $request->input('limit') ?? 20;
|
||||
$user = $request->user();
|
||||
$filtered = $user ? UserFilterService::filters($user->profile_id) : [];
|
||||
|
||||
|
@ -1825,7 +1845,8 @@ class ApiV1Controller extends Controller
|
|||
})
|
||||
->values()
|
||||
->toArray();
|
||||
return response()->json($res);
|
||||
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1859,7 +1880,8 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$res['favourited'] = LikeService::liked($user->profile_id, $res['id']);
|
||||
$res['reblogged'] = ReblogService::get($user->profile_id, $res['id']);
|
||||
return response()->json($res);
|
||||
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1874,42 +1896,51 @@ class ApiV1Controller extends Controller
|
|||
abort_if(!$request->user(), 403);
|
||||
|
||||
$user = $request->user();
|
||||
$status = StatusService::getMastodon($id, false);
|
||||
|
||||
$status = Status::findOrFail($id);
|
||||
if(!$status || !isset($status['account'])) {
|
||||
return response('', 404);
|
||||
}
|
||||
|
||||
if($status->profile_id !== $user->profile_id) {
|
||||
if($status->scope == 'private') {
|
||||
abort_if(!FollowerService::follows($user->profile_id, $status->profile_id), 403);
|
||||
if($status['account']['id'] != $user->profile_id) {
|
||||
if($status['visibility'] == 'private') {
|
||||
if(!FollowerService::follows($user->profile_id, $status['account']['id'])) {
|
||||
return response('', 404);
|
||||
}
|
||||
} else {
|
||||
abort_if(!in_array($status->scope, ['public','unlisted']), 403);
|
||||
if(!in_array($status['visibility'], ['public','unlisted'])) {
|
||||
return response('', 404);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($status->comments_disabled) {
|
||||
$res = [
|
||||
'ancestors' => [],
|
||||
'descendants' => []
|
||||
];
|
||||
} else {
|
||||
$ancestors = $status->parent();
|
||||
if($ancestors) {
|
||||
$ares = new Fractal\Resource\Item($ancestors, new StatusTransformer());
|
||||
$ancestors = [
|
||||
$this->fractal->createData($ares)->toArray()
|
||||
];
|
||||
} else {
|
||||
$ancestors = [];
|
||||
}
|
||||
$descendants = Status::whereInReplyToId($id)->latest()->limit(20)->get();
|
||||
$dres = new Fractal\Resource\Collection($descendants, new StatusTransformer());
|
||||
$descendants = $this->fractal->createData($dres)->toArray();
|
||||
$res = [
|
||||
'ancestors' => $ancestors,
|
||||
'descendants' => $descendants
|
||||
];
|
||||
$ancestors = [];
|
||||
$descendants = [];
|
||||
|
||||
if($status['in_reply_to_id']) {
|
||||
$ancestors[] = StatusService::getMastodon($status['in_reply_to_id'], false);
|
||||
}
|
||||
|
||||
return response()->json($res);
|
||||
if($status['replies_count']) {
|
||||
$descendants = DB::table('statuses')
|
||||
->where('in_reply_to_id', $id)
|
||||
->limit(20)
|
||||
->pluck('id')
|
||||
->map(function($sid) {
|
||||
return StatusService::getMastodon($sid, false);
|
||||
})
|
||||
->filter(function($post) {
|
||||
return $post && isset($post['account']);
|
||||
})
|
||||
->values();
|
||||
}
|
||||
|
||||
$res = [
|
||||
'ancestors' => $ancestors,
|
||||
'descendants' => $descendants
|
||||
];
|
||||
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1966,7 +1997,10 @@ class ApiV1Controller extends Controller
|
|||
$res = collect($ids)
|
||||
->map(function($id) {
|
||||
$status = StatusService::get($id);
|
||||
return AccountService::get($status['account']['id']);
|
||||
if($status) {
|
||||
return AccountService::get($status['account']['id']);
|
||||
}
|
||||
return;
|
||||
})
|
||||
->filter(function($account) {
|
||||
return $account && isset($account['id']);
|
||||
|
@ -1979,7 +2013,7 @@ class ApiV1Controller extends Controller
|
|||
$prev = $page > 1 ? $page - 1 : 1;
|
||||
$links = '<'.$url.'?page='.$next.'&limit='.$limit.'>; rel="next", <'.$url.'?page='.$prev.'&limit='.$limit.'>; rel="prev"';
|
||||
|
||||
return response()->json($res, 200, ['Link' => $links]);
|
||||
return $this->json($res, 200, ['Link' => $links]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2045,7 +2079,7 @@ class ApiV1Controller extends Controller
|
|||
$prev = $page > 1 ? $page - 1 : 1;
|
||||
$links = '<'.$url.'?page='.$next.'&limit='.$limit.'>; rel="next", <'.$url.'?page='.$prev.'&limit='.$limit.'>; rel="prev"';
|
||||
|
||||
return response()->json($res, 200, ['Link' => $links]);
|
||||
return $this->json($res, 200, ['Link' => $links]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2060,10 +2094,9 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$this->validate($request, [
|
||||
'status' => 'nullable|string',
|
||||
'in_reply_to_id' => 'nullable|integer',
|
||||
'media_ids' => 'array|max:' . config_cache('pixelfed.max_album_length'),
|
||||
'media_ids.*' => 'integer|min:1',
|
||||
'sensitive' => 'nullable|boolean',
|
||||
'in_reply_to_id' => 'nullable',
|
||||
'media_ids' => 'sometimes|array|max:' . config_cache('pixelfed.max_album_length'),
|
||||
'sensitive' => 'nullable',
|
||||
'visibility' => 'string|in:private,unlisted,public',
|
||||
]);
|
||||
|
||||
|
@ -2192,9 +2225,8 @@ class ApiV1Controller extends Controller
|
|||
Cache::forget('profile:embed:' . $status->profile_id);
|
||||
Cache::forget($limitKey);
|
||||
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
$res = StatusService::getMastodon($status->id, false);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2219,7 +2251,8 @@ class ApiV1Controller extends Controller
|
|||
$res = $this->fractal->createData($resource)->toArray();
|
||||
$res['text'] = $res['content'];
|
||||
unset($res['content']);
|
||||
return response()->json($res);
|
||||
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2262,7 +2295,7 @@ class ApiV1Controller extends Controller
|
|||
$res = StatusService::getMastodon($status->id);
|
||||
$res['reblogged'] = true;
|
||||
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2292,17 +2325,18 @@ class ApiV1Controller extends Controller
|
|||
->first();
|
||||
|
||||
if(!$reblog) {
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
$res = StatusService::getMastodon($status->id);
|
||||
$res['reblogged'] = false;
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
UndoSharePipeline::dispatch($reblog);
|
||||
ReblogService::del($user->profile_id, $status->id);
|
||||
|
||||
$res = StatusService::getMastodon($status->id);
|
||||
$res['reblogged'] = true;
|
||||
return response()->json($res);
|
||||
$res['reblogged'] = false;
|
||||
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2358,7 +2392,7 @@ class ApiV1Controller extends Controller
|
|||
->values()
|
||||
->toArray();
|
||||
|
||||
return response()->json($res, 200, [], JSON_PRETTY_PRINT);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2404,7 +2438,8 @@ class ApiV1Controller extends Controller
|
|||
foreach($bookmarks as $id) {
|
||||
$res[] = \App\Services\StatusService::getMastodon($id);
|
||||
}
|
||||
return $res;
|
||||
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2426,9 +2461,9 @@ class ApiV1Controller extends Controller
|
|||
'status_id' => $status->id,
|
||||
'profile_id' => $request->user()->profile_id
|
||||
]);
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
$res = StatusService::getMastodon($status->id);
|
||||
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2446,18 +2481,13 @@ class ApiV1Controller extends Controller
|
|||
->whereScope('public')
|
||||
->findOrFail($id);
|
||||
|
||||
Bookmark::firstOrCreate([
|
||||
'status_id' => $status->id,
|
||||
'profile_id' => $request->user()->profile_id
|
||||
]);
|
||||
$bookmark = Bookmark::whereStatusId($status->id)
|
||||
->whereProfileId($request->user()->profile_id)
|
||||
->firstOrFail();
|
||||
$bookmark->delete();
|
||||
$res = StatusService::getMastodon($status->id);
|
||||
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2483,7 +2513,7 @@ class ApiV1Controller extends Controller
|
|||
'following' => 'nullable'
|
||||
]);
|
||||
|
||||
return SearchApiV2Service::query($request);
|
||||
return $this->json(SearchApiV2Service::query($request, true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2515,7 +2545,7 @@ class ApiV1Controller extends Controller
|
|||
})
|
||||
->take(12)
|
||||
->values();
|
||||
return response()->json(compact('posts'));
|
||||
return $this->json(compact('posts'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2600,7 +2630,7 @@ class ApiV1Controller extends Controller
|
|||
'next' => $ids->nextPageUrl()
|
||||
];
|
||||
|
||||
return $res;
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2617,7 +2647,7 @@ class ApiV1Controller extends Controller
|
|||
$pid = $request->user()->profile_id;
|
||||
abort_if(!in_array($status->scope, ['public', 'unlisted', 'private']), 404);
|
||||
|
||||
return StatusService::getState($status->id, $pid);
|
||||
return $this->json(StatusService::getState($status->id, $pid));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2650,6 +2680,6 @@ class ApiV1Controller extends Controller
|
|||
->take(6)
|
||||
->values();
|
||||
|
||||
return response()->json($ids, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
return $this->json($ids);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,9 +48,12 @@ class FederationController extends Controller
|
|||
|
||||
public function webfinger(Request $request)
|
||||
{
|
||||
abort_if(!config('federation.webfinger.enabled'), 400);
|
||||
|
||||
abort_if(!$request->has('resource') || !$request->filled('resource'), 400);
|
||||
if (!config('federation.webfinger.enabled') ||
|
||||
!$request->has('resource') ||
|
||||
!$request->filled('resource')
|
||||
) {
|
||||
return response('', 400);
|
||||
}
|
||||
|
||||
$resource = $request->input('resource');
|
||||
$hash = hash('sha256', $resource);
|
||||
|
@ -59,14 +62,18 @@ class FederationController extends Controller
|
|||
return response()->json($cached, 200, [], JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
$domain = config('pixelfed.domain.app');
|
||||
abort_if(strpos($resource, $domain) == false, 400);
|
||||
if(strpos($resource, $domain) == false) {
|
||||
return response('', 400);
|
||||
}
|
||||
$parsed = Nickname::normalizeProfileUrl($resource);
|
||||
if(empty($parsed) || $parsed['domain'] !== $domain) {
|
||||
abort(400);
|
||||
return response('', 400);
|
||||
}
|
||||
$username = $parsed['username'];
|
||||
$profile = Profile::whereNull('domain')->whereUsername($username)->firstOrFail();
|
||||
abort_if($profile->status != null, 400);
|
||||
$profile = Profile::whereNull('domain')->whereUsername($username)->first();
|
||||
if(!$profile || $profile->status !== null) {
|
||||
return response('', 400);
|
||||
}
|
||||
$webfinger = (new Webfinger($profile))->generate();
|
||||
Cache::put($key, $webfinger, 1209600);
|
||||
|
||||
|
|
|
@ -16,6 +16,15 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
|||
class NotificationService {
|
||||
|
||||
const CACHE_KEY = 'pf:services:notifications:ids:';
|
||||
const MASTODON_TYPES = [
|
||||
'follow',
|
||||
'follow_request',
|
||||
'mention',
|
||||
'reblog',
|
||||
'favourite',
|
||||
'poll',
|
||||
'status'
|
||||
];
|
||||
|
||||
public static function get($id, $start = 0, $stop = 400)
|
||||
{
|
||||
|
@ -85,6 +94,63 @@ class NotificationService {
|
|||
return $res->toArray();
|
||||
}
|
||||
|
||||
|
||||
public static function getMaxMastodon($id = false, $start = 0, $limit = 10)
|
||||
{
|
||||
$ids = self::getRankedMaxId($id, $start, $limit);
|
||||
|
||||
if(empty($ids)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$res = collect([]);
|
||||
foreach($ids as $id) {
|
||||
$n = self::getNotification($id);
|
||||
if($n != null && in_array($n['type'], self::MASTODON_TYPES)) {
|
||||
$n['account'] = AccountService::getMastodon($n['account']['id']);
|
||||
|
||||
if(isset($n['relationship'])) {
|
||||
unset($n['relationship']);
|
||||
}
|
||||
|
||||
if(isset($n['status'])) {
|
||||
$n['status'] = StatusService::getMastodon($n['status']['id'], false);
|
||||
}
|
||||
|
||||
$res->push($n);
|
||||
}
|
||||
}
|
||||
return $res->toArray();
|
||||
}
|
||||
|
||||
public static function getMinMastodon($id = false, $start = 0, $limit = 10)
|
||||
{
|
||||
$ids = self::getRankedMinId($id, $start, $limit);
|
||||
|
||||
if(empty($ids)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$res = collect([]);
|
||||
foreach($ids as $id) {
|
||||
$n = self::getNotification($id);
|
||||
if($n != null && in_array($n['type'], self::MASTODON_TYPES)) {
|
||||
$n['account'] = AccountService::getMastodon($n['account']['id']);
|
||||
|
||||
if(isset($n['relationship'])) {
|
||||
unset($n['relationship']);
|
||||
}
|
||||
|
||||
if(isset($n['status'])) {
|
||||
$n['status'] = StatusService::getMastodon($n['status']['id'], false);
|
||||
}
|
||||
|
||||
$res->push($n);
|
||||
}
|
||||
}
|
||||
return $res->toArray();
|
||||
}
|
||||
|
||||
public static function getRankedMaxId($id = false, $start = null, $limit = 10)
|
||||
{
|
||||
if(!$start || !$id) {
|
||||
|
|
|
@ -19,9 +19,11 @@ use App\Services\StatusService;
|
|||
class SearchApiV2Service
|
||||
{
|
||||
private $query;
|
||||
static $mastodonMode = false;
|
||||
|
||||
public static function query($query)
|
||||
public static function query($query, $mastodonMode = false)
|
||||
{
|
||||
self::$mastodonMode = $mastodonMode;
|
||||
return (new self)->run($query);
|
||||
}
|
||||
|
||||
|
@ -81,6 +83,7 @@ class SearchApiV2Service
|
|||
|
||||
protected function accounts()
|
||||
{
|
||||
$mastodonMode = self::$mastodonMode;
|
||||
$user = request()->user();
|
||||
$limit = $this->query->input('limit') ?? 20;
|
||||
$offset = $this->query->input('offset') ?? 0;
|
||||
|
@ -93,6 +96,7 @@ class SearchApiV2Service
|
|||
->where('followers.profile_id', $user->profile_id);
|
||||
})
|
||||
->where('username', 'like', $query)
|
||||
->orderBy('domain')
|
||||
->orderByDesc('profiles.followers_count')
|
||||
->orderByDesc('followers.created_at')
|
||||
->offset($offset)
|
||||
|
@ -101,8 +105,10 @@ class SearchApiV2Service
|
|||
->filter(function($profile) use ($banned) {
|
||||
return in_array($profile->domain, $banned) == false;
|
||||
})
|
||||
->map(function($res) {
|
||||
return AccountService::get($res['id']);
|
||||
->map(function($res) use($mastodonMode) {
|
||||
return $mastodonMode ?
|
||||
AccountService::getMastodon($res['id']) :
|
||||
AccountService::get($res['id']);
|
||||
})
|
||||
->filter(function($account) {
|
||||
return $account && isset($account['id']);
|
||||
|
@ -114,6 +120,7 @@ class SearchApiV2Service
|
|||
|
||||
protected function hashtags()
|
||||
{
|
||||
$mastodonMode = self::$mastodonMode;
|
||||
$limit = $this->query->input('limit') ?? 20;
|
||||
$offset = $this->query->input('offset') ?? 0;
|
||||
$query = '%' . $this->query->input('q') . '%';
|
||||
|
@ -122,13 +129,18 @@ class SearchApiV2Service
|
|||
->offset($offset)
|
||||
->limit($limit)
|
||||
->get()
|
||||
->map(function($tag) {
|
||||
return [
|
||||
->map(function($tag) use($mastodonMode) {
|
||||
$res = [
|
||||
'name' => $tag->name,
|
||||
'url' => $tag->url(),
|
||||
'count' => HashtagService::count($tag->id),
|
||||
'history' => []
|
||||
'url' => $tag->url()
|
||||
];
|
||||
|
||||
if(!$mastodonMode) {
|
||||
$res['history'] = [];
|
||||
$res['count'] = HashtagService::count($tag->id);
|
||||
}
|
||||
|
||||
return $res;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -140,6 +152,7 @@ class SearchApiV2Service
|
|||
|
||||
protected function statusesById()
|
||||
{
|
||||
$mastodonMode = self::$mastodonMode;
|
||||
$accountId = $this->query->input('account_id');
|
||||
$limit = $this->query->input('limit', 20);
|
||||
$query = '%' . $this->query->input('q') . '%';
|
||||
|
@ -147,8 +160,10 @@ class SearchApiV2Service
|
|||
->whereProfileId($accountId)
|
||||
->limit($limit)
|
||||
->get()
|
||||
->map(function($status) {
|
||||
return StatusService::get($status->id);
|
||||
->map(function($status) use($mastodonMode) {
|
||||
return $mastodonMode ?
|
||||
StatusService::getMastodon($status->id) :
|
||||
StatusService::get($status->id);
|
||||
})
|
||||
->filter(function($status) {
|
||||
return $status && isset($status['account']);
|
||||
|
@ -158,6 +173,7 @@ class SearchApiV2Service
|
|||
|
||||
protected function resolveQuery()
|
||||
{
|
||||
$mastodonMode = self::$mastodonMode;
|
||||
$query = urldecode($this->query->input('q'));
|
||||
if(Helpers::validateLocalUrl($query)) {
|
||||
if(Str::contains($query, '/p/')) {
|
||||
|
@ -177,7 +193,7 @@ class SearchApiV2Service
|
|||
|
||||
if(Str::substrCount($query, '@') == 2) {
|
||||
try {
|
||||
$res = WebfingerService::lookup($query);
|
||||
$res = WebfingerService::lookup($query, $mastodonMode);
|
||||
} catch (\Exception $e) {
|
||||
return $default;
|
||||
}
|
||||
|
@ -209,7 +225,9 @@ class SearchApiV2Service
|
|||
if(!$obj || !isset($obj['id'])) {
|
||||
return $default;
|
||||
}
|
||||
$note = StatusService::get($obj['id']);
|
||||
$note = $mastodonMode ?
|
||||
StatusService::getMastodon($obj['id']) :
|
||||
StatusService::get($obj['id']);
|
||||
if(!$note) {
|
||||
return $default;
|
||||
}
|
||||
|
@ -225,7 +243,9 @@ class SearchApiV2Service
|
|||
if(in_array($obj['domain'], $banned)) {
|
||||
return $default;
|
||||
}
|
||||
$default['accounts'][] = AccountService::get($obj['id']);
|
||||
$default['accounts'][] = $mastodonMode ?
|
||||
AccountService::getMastodon($obj['id']) :
|
||||
AccountService::get($obj['id']);
|
||||
return $default;
|
||||
break;
|
||||
|
||||
|
@ -254,10 +274,7 @@ class SearchApiV2Service
|
|||
{
|
||||
$query = urldecode($this->query->input('q'));
|
||||
$query = last(explode('/', $query));
|
||||
$status = Status::whereNull('uri')
|
||||
->whereScope('public')
|
||||
->find($query);
|
||||
|
||||
$status = StatusService::getMastodon($query);
|
||||
if(!$status) {
|
||||
return [
|
||||
'accounts' => [],
|
||||
|
@ -266,14 +283,13 @@ class SearchApiV2Service
|
|||
];
|
||||
}
|
||||
|
||||
$fractal = new Fractal\Manager();
|
||||
$fractal->setSerializer(new ArraySerializer());
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
return [
|
||||
$res = [
|
||||
'accounts' => [],
|
||||
'hashtags' => [],
|
||||
'statuses' => $fractal->createData($resource)->toArray()
|
||||
'statuses' => [$status]
|
||||
];
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function resolveLocalProfile()
|
||||
|
|
|
@ -11,15 +11,17 @@ use App\Services\AccountService;
|
|||
|
||||
class WebfingerService
|
||||
{
|
||||
public static function lookup($query)
|
||||
public static function lookup($query, $mastodonMode = false)
|
||||
{
|
||||
return (new self)->run($query);
|
||||
return (new self)->run($query, $mastodonMode);
|
||||
}
|
||||
|
||||
protected function run($query)
|
||||
protected function run($query, $mastodonMode)
|
||||
{
|
||||
if($profile = Profile::whereUsername($query)->first()) {
|
||||
return AccountService::get($profile->id);
|
||||
return $mastodonMode ?
|
||||
AccountService::getMastodon($profile->id, true) :
|
||||
AccountService::get($profile->id);
|
||||
}
|
||||
$url = WebfingerUrl::generateWebfingerUrl($query);
|
||||
if(!Helpers::validateUrl($url)) {
|
||||
|
@ -54,6 +56,8 @@ class WebfingerService
|
|||
->first();
|
||||
|
||||
$profile = Helpers::profileFetch($link);
|
||||
return AccountService::get($profile->id);
|
||||
return $mastodonMode ?
|
||||
AccountService::getMastodon($profile->id, true) :
|
||||
AccountService::get($profile->id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ class AccountTransformer extends Fractal\TransformerAbstract
|
|||
'username' => $username,
|
||||
'acct' => $acct,
|
||||
'display_name' => $profile->name,
|
||||
'discoverable' => true,
|
||||
'locked' => (bool) $profile->is_private,
|
||||
'followers_count' => (int) $profile->followerCount(),
|
||||
'following_count' => (int) $profile->followingCount(),
|
||||
|
|
Loading…
Reference in a new issue