mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-12-23 13:33:18 +00:00
Merge pull request #3333 from pixelfed/staging
MastoAPI Compatibility fixes
This commit is contained in:
commit
160097c287
9 changed files with 793 additions and 595 deletions
|
@ -100,6 +100,15 @@
|
|||
- Updated ApiV1Controller, fix search v2 entities. ([9dac861e](https://github.com/pixelfed/pixelfed/commit/9dac861e))
|
||||
- Updated ApiV1Controller, fix apps endpoint. ([50baae52](https://github.com/pixelfed/pixelfed/commit/50baae52))
|
||||
- Updated ApiV1Controller, add apps/verify_credentials endpoint. ([c4d38c20](https://github.com/pixelfed/pixelfed/commit/c4d38c20))
|
||||
- Updated ApiV1Controller, increase max limion timelines. ([df22f2e4](https://github.com/pixelfed/pixelfed/commit/df22f2e4))
|
||||
- Updated ApiV1Controller, add preferences endpoint. ([c3e56b87](https://github.com/pixelfed/pixelfed/commit/c3e56b87))
|
||||
- Updated ApiV1Controller, fix tag timeline limits and remove has(media) constraint. ([8c65d60b](https://github.com/pixelfed/pixelfed/commit/8c65d60b))
|
||||
- Updated ApiV1Controller, add trends endpoint. ([d40a8453](https://github.com/pixelfed/pixelfed/commit/d40a8453))
|
||||
- Updated ApiV1Controller, add announcements endpoint. ([fbe07c51](https://github.com/pixelfed/pixelfed/commit/fbe07c51))
|
||||
- Updated ApiV1Controller, add markers endpoint. ([93a9769e](https://github.com/pixelfed/pixelfed/commit/93a9769e))
|
||||
- Updated ApiV1Controller, increase limits from 80 to 100. ([15eccd44](https://github.com/pixelfed/pixelfed/commit/15eccd44))
|
||||
- Updated ApiV1Controller, fix accountStatusesById endpoint. ([db7b1af3](https://github.com/pixelfed/pixelfed/commit/db7b1af3))
|
||||
- Updated ApiV1Controller, update statusCreate entity. ([a84ab6ea](https://github.com/pixelfed/pixelfed/commit/a84ab6ea))
|
||||
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
||||
|
||||
## [v0.11.2 (2022-01-09)](https://github.com/pixelfed/pixelfed/compare/v0.11.1...v0.11.2)
|
||||
|
|
25
app/Auth/BearerTokenResponse.php
Normal file
25
app/Auth/BearerTokenResponse.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Auth;
|
||||
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
|
||||
class BearerTokenResponse extends \League\OAuth2\Server\ResponseTypes\BearerTokenResponse
|
||||
{
|
||||
/**
|
||||
* Add custom fields to your Bearer Token response here, then override
|
||||
* AuthorizationServer::getResponseType() to pull in your version of
|
||||
* this class rather than the default.
|
||||
*
|
||||
* @param AccessTokenEntityInterface $accessToken
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getExtraParams(AccessTokenEntityInterface $accessToken)
|
||||
{
|
||||
return [
|
||||
'created_at' => time(),
|
||||
'scope' => 'read write follow push'
|
||||
];
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@ use App\Util\Media\License;
|
|||
use App\Jobs\MediaPipeline\MediaSyncLicensePipeline;
|
||||
use App\Services\DiscoverService;
|
||||
use App\Services\CustomEmojiService;
|
||||
use App\Services\MarkerService;
|
||||
|
||||
class ApiV1Controller extends Controller
|
||||
{
|
||||
|
@ -536,11 +537,14 @@ class ApiV1Controller extends Controller
|
|||
'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'since_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'limit' => 'nullable|integer|min:1|max:80'
|
||||
'limit' => 'nullable|integer|min:1|max:100'
|
||||
]);
|
||||
|
||||
$profile = AccountService::getMastodon($id);
|
||||
abort_if(!$profile, 404);
|
||||
$profile = AccountService::getMastodon($id, true);
|
||||
|
||||
if(!$profile || !isset($profile['id']) || !$user) {
|
||||
return response('', 404);
|
||||
}
|
||||
|
||||
$limit = $request->limit ?? 20;
|
||||
$max_id = $request->max_id;
|
||||
|
@ -566,7 +570,9 @@ class ApiV1Controller extends Controller
|
|||
$visibility = ['public', 'unlisted', 'private'];
|
||||
} else if($profile['locked']) {
|
||||
$following = FollowerService::follows($pid, $profile['id']);
|
||||
abort_unless($following, 403);
|
||||
if(!$following) {
|
||||
return response('', 403);
|
||||
}
|
||||
$visibility = ['public', 'unlisted', 'private'];
|
||||
} else {
|
||||
$following = FollowerService::follows($pid, $profile['id']);
|
||||
|
@ -585,11 +591,8 @@ class ApiV1Controller extends Controller
|
|||
->orderByDesc('id')
|
||||
->get()
|
||||
->map(function($s) use($user) {
|
||||
try {
|
||||
$status = StatusService::getMastodon($s->id, false);
|
||||
} catch (\Exception $e) {
|
||||
$status = false;
|
||||
}
|
||||
|
||||
if($user && $status) {
|
||||
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
|
||||
}
|
||||
|
@ -1581,7 +1584,7 @@ class ApiV1Controller extends Controller
|
|||
abort_if(!$request->user(), 403);
|
||||
|
||||
$this->validate($request, [
|
||||
'limit' => 'nullable|integer|min:1|max:80',
|
||||
'limit' => 'nullable|integer|min:1|max:100',
|
||||
'min_id' => 'nullable|integer|min:1|max:'.PHP_INT_MAX,
|
||||
'max_id' => 'nullable|integer|min:1|max:'.PHP_INT_MAX,
|
||||
'since_id' => 'nullable|integer|min:1|max:'.PHP_INT_MAX,
|
||||
|
@ -1656,7 +1659,7 @@ class ApiV1Controller extends Controller
|
|||
'page' => 'nullable|integer|max:40',
|
||||
'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'limit' => 'nullable|integer|max:80'
|
||||
'limit' => 'nullable|integer|max:100'
|
||||
]);
|
||||
|
||||
$page = $request->input('page');
|
||||
|
@ -1817,7 +1820,7 @@ class ApiV1Controller extends Controller
|
|||
$this->validate($request,[
|
||||
'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'limit' => 'nullable|integer|max:80'
|
||||
'limit' => 'nullable|integer|max:100'
|
||||
]);
|
||||
|
||||
$min = $request->input('min_id');
|
||||
|
@ -1983,7 +1986,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$this->validate($request, [
|
||||
'page' => 'nullable|integer|min:1|max:40',
|
||||
'limit' => 'nullable|integer|min:1|max:80'
|
||||
'limit' => 'nullable|integer|min:1|max:100'
|
||||
]);
|
||||
|
||||
$limit = $request->input('limit') ?? 40;
|
||||
|
@ -2042,7 +2045,7 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$this->validate($request, [
|
||||
'page' => 'nullable|integer|min:1|max:40',
|
||||
'limit' => 'nullable|integer|min:1|max:80'
|
||||
'limit' => 'nullable|integer|min:1|max:100'
|
||||
]);
|
||||
|
||||
$page = $request->input('page', 1);
|
||||
|
@ -2239,6 +2242,11 @@ class ApiV1Controller extends Controller
|
|||
Cache::forget($limitKey);
|
||||
|
||||
$res = StatusService::getMastodon($status->id, false);
|
||||
$res['favourited'] = false;
|
||||
$res['language'] = 'en';
|
||||
$res['bookmarked'] = false;
|
||||
$res['pinned'] = false;
|
||||
$res['card'] = null;
|
||||
return $this->json($res);
|
||||
}
|
||||
|
||||
|
@ -2365,7 +2373,7 @@ class ApiV1Controller extends Controller
|
|||
'page' => 'nullable|integer|max:40',
|
||||
'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX,
|
||||
'limit' => 'nullable|integer|max:40'
|
||||
'limit' => 'nullable|integer|max:100'
|
||||
]);
|
||||
|
||||
$tag = Hashtag::whereName($hashtag)
|
||||
|
@ -2390,18 +2398,18 @@ class ApiV1Controller extends Controller
|
|||
|
||||
$res = StatusHashtag::whereHashtagId($tag->id)
|
||||
->whereStatusVisibility('public')
|
||||
->whereHas('media')
|
||||
->where('status_id', $dir, $id)
|
||||
->latest()
|
||||
->limit($limit)
|
||||
->pluck('status_id')
|
||||
->filter(function($i) {
|
||||
return StatusService::getMastodon($i);
|
||||
})
|
||||
->map(function ($i) {
|
||||
if($i) {
|
||||
return StatusService::getMastodon($i);
|
||||
}
|
||||
})
|
||||
->filter(function($i) {
|
||||
return $i && isset($i['account']);
|
||||
})
|
||||
->filter()
|
||||
->values()
|
||||
->toArray();
|
||||
|
||||
|
@ -2514,7 +2522,7 @@ class ApiV1Controller extends Controller
|
|||
abort_if(!$request->user(), 403);
|
||||
|
||||
$this->validate($request, [
|
||||
'q' => 'required|string|min:1|max:80',
|
||||
'q' => 'required|string|min:1|max:100',
|
||||
'account_id' => 'nullable|string',
|
||||
'max_id' => 'nullable|string',
|
||||
'min_id' => 'nullable|string',
|
||||
|
@ -2695,4 +2703,95 @@ class ApiV1Controller extends Controller
|
|||
|
||||
return $this->json($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/preferences
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPreferences(Request $request)
|
||||
{
|
||||
abort_if(!$request->user(), 403);
|
||||
$pid = $request->user()->profile_id;
|
||||
$account = AccountService::get($pid);
|
||||
|
||||
return $this->json([
|
||||
'posting:default:visibility' => $account['locked'] ? 'private' : 'public',
|
||||
'posting:default:sensitive' => false,
|
||||
'posting:default:language' => null,
|
||||
'reading:expand:media' => 'default',
|
||||
'reading:expand:spoilers' => false
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/trends
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTrends(Request $request)
|
||||
{
|
||||
abort_if(!$request->user(), 403);
|
||||
|
||||
return $this->json([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/announcements
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAnnouncements(Request $request)
|
||||
{
|
||||
abort_if(!$request->user(), 403);
|
||||
|
||||
return $this->json([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/markers
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMarkers(Request $request)
|
||||
{
|
||||
abort_if(!$request->user(), 403);
|
||||
$type = $request->input('timeline');
|
||||
if(is_array($type)) {
|
||||
$type = $type[0];
|
||||
}
|
||||
if(!$type || !in_array($type, ['home', 'notifications'])) {
|
||||
return $this->json([]);
|
||||
}
|
||||
$pid = $request->user()->profile_id;
|
||||
return $this->json(MarkerService::get($pid, $type));
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/v1/markers
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function setMarkers(Request $request)
|
||||
{
|
||||
abort_if(!$request->user(), 403);
|
||||
$pid = $request->user()->profile_id;
|
||||
$home = $request->input('home.last_read_id');
|
||||
$notifications = $request->input('notifications.last_read_id');
|
||||
|
||||
if($home) {
|
||||
return $this->json(MarkerService::set($pid, 'home', $home));
|
||||
}
|
||||
|
||||
if($notifications) {
|
||||
return $this->json(MarkerService::set($pid, 'notifications', $notifications));
|
||||
}
|
||||
|
||||
return $this->json([]);
|
||||
}
|
||||
}
|
||||
|
|
27
app/Providers/PassportServiceProvider.php
Normal file
27
app/Providers/PassportServiceProvider.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Auth\BearerTokenResponse;
|
||||
use Laravel\Passport\Bridge;
|
||||
use League\OAuth2\Server\AuthorizationServer;
|
||||
|
||||
class PassportServiceProvider extends \Laravel\Passport\PassportServiceProvider
|
||||
{
|
||||
/**
|
||||
* Make the authorization service instance.
|
||||
*
|
||||
* @return \League\OAuth2\Server\AuthorizationServer
|
||||
*/
|
||||
public function makeAuthorizationServer()
|
||||
{
|
||||
return new AuthorizationServer(
|
||||
$this->app->make(Bridge\ClientRepository::class),
|
||||
$this->app->make(Bridge\AccessTokenRepository::class),
|
||||
$this->app->make(Bridge\ScopeRepository::class),
|
||||
$this->makeCryptKey('private'),
|
||||
app('encrypter')->getKey(),
|
||||
new BearerTokenResponse()
|
||||
);
|
||||
}
|
||||
}
|
28
app/Services/MarkerService.php
Normal file
28
app/Services/MarkerService.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Cache;
|
||||
|
||||
class MarkerService
|
||||
{
|
||||
const CACHE_KEY = 'pf:services:markers:timeline:';
|
||||
|
||||
public static function get($profileId, $timeline = 'home')
|
||||
{
|
||||
return Cache::get(self::CACHE_KEY . $timeline . ':' . $profileId);
|
||||
}
|
||||
|
||||
public static function set($profileId, $timeline = 'home', $entityId)
|
||||
{
|
||||
$existing = self::get($profileId, $timeline);
|
||||
$key = self::CACHE_KEY . $timeline . ':' . $profileId;
|
||||
$val = [
|
||||
'last_read_id' => (string) $entityId,
|
||||
'version' => $existing ? ($existing['version'] + 1) : 1,
|
||||
'updated_at' => now()->format('c')
|
||||
];
|
||||
Cache::put($key, $val, 2592000);
|
||||
return $val;
|
||||
}
|
||||
}
|
|
@ -73,6 +73,7 @@
|
|||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": [
|
||||
"laravel/passport"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
1146
composer.lock
generated
1146
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -165,6 +165,7 @@ return [
|
|||
App\Providers\HorizonServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
App\Providers\PassportServiceProvider::class,
|
||||
|
||||
],
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ Route::group(['prefix' => 'api'], function() use($middleware) {
|
|||
Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware($middleware);
|
||||
Route::get('accounts/{id}/lists', 'Api\ApiV1Controller@accountListsById')->middleware($middleware);
|
||||
Route::get('lists/{id}/accounts', 'Api\ApiV1Controller@accountListsById')->middleware($middleware);
|
||||
Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById');
|
||||
Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById')->middleware($middleware);
|
||||
|
||||
Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware($middleware);
|
||||
Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware($middleware);
|
||||
|
@ -83,6 +83,12 @@ Route::group(['prefix' => 'api'], function() use($middleware) {
|
|||
Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic')->middleware($middleware);
|
||||
Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag');
|
||||
Route::get('discover/posts', 'Api\ApiV1Controller@discoverPosts')->middleware($middleware);
|
||||
|
||||
Route::get('preferences', 'Api\ApiV1Controller@getPreferences')->middleware($middleware);
|
||||
Route::get('trends', 'Api\ApiV1Controller@getTrends')->middleware($middleware);
|
||||
Route::get('announcements', 'Api\ApiV1Controller@getAnnouncements')->middleware($middleware);
|
||||
Route::get('markers', 'Api\ApiV1Controller@getMarkers')->middleware($middleware);
|
||||
Route::post('markers', 'Api\ApiV1Controller@setMarkers')->middleware($middleware);
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'v2'], function() use($middleware) {
|
||||
|
|
Loading…
Reference in a new issue