mirror of
https://github.com/jikan-me/jikan-rest.git
synced 2025-02-20 11:23:35 +08:00
add v4 User endpoint
This commit is contained in:
parent
3a2a9b06ce
commit
359070af5e
15
.env.dist
15
.env.dist
@ -53,13 +53,14 @@ CACHE_DRIVER=array
|
||||
CACHE_METHOD=queue
|
||||
|
||||
# Caching TTL (in seconds) on specific endpoints
|
||||
CACHE_DEFAULT_EXPIRE=86400
|
||||
CACHE_META_EXPIRE=300
|
||||
CACHE_USER_EXPIRE=300
|
||||
CACHE_404_EXPIRE=604800
|
||||
CACHE_SEARCH_EXPIRE=432000
|
||||
CACHE_PRODUCERS_EXPIRE=432000
|
||||
CACHE_MAGAZINES_EXPIRE=432000
|
||||
CACHE_DEFAULT_EXPIRE=86400 # 1 day
|
||||
CACHE_META_EXPIRE=300 # 5 minutes
|
||||
CACHE_USER_EXPIRE=300 # 5 minutes
|
||||
CACHE_USERLIST_EXPIRE=3600 # 1 hour
|
||||
CACHE_404_EXPIRE=604800 # 7 days
|
||||
CACHE_SEARCH_EXPIRE=432000 # 5 days
|
||||
CACHE_PRODUCERS_EXPIRE=432000 # 5 days
|
||||
CACHE_MAGAZINES_EXPIRE=432000 # 5 days
|
||||
|
||||
# You can even add your own by
|
||||
# including the endpoint's name
|
||||
|
@ -42,7 +42,6 @@ class Club extends Model
|
||||
'_id', 'request_hash', 'expiresAt', 'image_url'
|
||||
];
|
||||
|
||||
|
||||
public function getImageAttribute()
|
||||
{
|
||||
$imageUrl = $this->attributes['image_url'];
|
||||
|
@ -2,6 +2,12 @@
|
||||
|
||||
namespace App\Http\Controllers\V4DB;
|
||||
|
||||
use App\Anime;
|
||||
use App\Http\HttpHelper;
|
||||
use App\Http\HttpResponse;
|
||||
use App\Profile;
|
||||
use App\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Jikan\Request\User\RecentlyOnlineUsersRequest;
|
||||
use Jikan\Request\User\UserAnimeListRequest;
|
||||
use Jikan\Request\User\UserClubsRequest;
|
||||
@ -11,13 +17,67 @@ use Jikan\Request\User\UserFriendsRequest;
|
||||
use Jikan\Request\User\UserHistoryRequest;
|
||||
use Jikan\Request\User\UserRecommendationsRequest;
|
||||
use Jikan\Request\User\UserReviewsRequest;
|
||||
use MongoDB\BSON\UTCDateTime;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function profile(string $username)
|
||||
public function profile(Request $request, string $username)
|
||||
{
|
||||
$user = $this->jikan->getUserProfile(new UserProfileRequest($username));
|
||||
return response($this->serializer->serialize($user, 'json'));
|
||||
$results = Profile::query()
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Profile::scrape($username);
|
||||
|
||||
if (HttpHelper::hasError($response)) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Profile::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Profile::query()
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Profile::query()
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
}
|
||||
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProfileResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
}
|
||||
|
||||
public function history(string $username, ?string $type = null)
|
||||
|
33
app/Http/Resources/V4/ProfileResource.php
Normal file
33
app/Http/Resources/V4/ProfileResource.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V4;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ProfileResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'mal_id' => $this->mal_id,
|
||||
'username' => $this->username,
|
||||
'url' => $this->url,
|
||||
'images' => $this->images,
|
||||
'last_online' => $this->last_online,
|
||||
'gender' => $this->gender,
|
||||
'birthday' => $this->birthday,
|
||||
'location' => $this->location,
|
||||
'joined' => $this->joined,
|
||||
'anime_stats' => $this->anime_stats,
|
||||
'manga_stats' => $this->manga_stats,
|
||||
'favorites' => $this->favorites,
|
||||
'about' => $this->about,
|
||||
];
|
||||
}
|
||||
}
|
78
app/Profile.php
Normal file
78
app/Profile.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use App\Http\HttpHelper;
|
||||
use Jenssegers\Mongodb\Eloquent\Model;
|
||||
use Jikan\Helper\Media;
|
||||
use Jikan\Helper\Parser;
|
||||
use Jikan\Jikan;
|
||||
use Jikan\Model\Common\YoutubeMeta;
|
||||
use Jikan\Request\Anime\AnimeRequest;
|
||||
use Jikan\Request\User\UserProfileRequest;
|
||||
|
||||
class Profile extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'mal_id', 'username', 'url', 'image_url', 'last_online', 'gender', 'birthday', 'location', 'joined', 'anime_stats', 'manga_stats', 'favorites', 'about'
|
||||
];
|
||||
|
||||
/**
|
||||
* The accessors to append to the model's array form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = ['images'];
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'users';
|
||||
|
||||
/**
|
||||
* The attributes excluded from the model's JSON form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'_id', 'image_url'
|
||||
];
|
||||
|
||||
public function setImagesAttribute($value)
|
||||
{
|
||||
$this->attributes['images'] = $this->getImagesAttribute();
|
||||
}
|
||||
|
||||
public function getImagesAttribute()
|
||||
{
|
||||
$imageUrl = $this->attributes['image_url'];
|
||||
|
||||
return [
|
||||
'jpg' => [
|
||||
'image_url' => $imageUrl,
|
||||
],
|
||||
'webp' => [
|
||||
'image_url' => str_replace('.jpg', '.webp', $imageUrl),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function scrape(string $username)
|
||||
{
|
||||
$data = app('JikanParser')->getUserProfile(new UserProfileRequest($username));
|
||||
|
||||
return json_decode(
|
||||
app('SerializerV4')
|
||||
->serialize($data, 'json'),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
"flipbox/lumen-generator": "^6",
|
||||
"illuminate/redis": "^7",
|
||||
"jenssegers/mongodb": "^4.0",
|
||||
"jikan-me/jikan": "v3.0.0-alpha.9",
|
||||
"jikan-me/jikan": "v3.0.0-alpha.10",
|
||||
"jms/serializer": "^1.13",
|
||||
"laravel/lumen-framework": "^7.0",
|
||||
"league/flysystem": "^1.0",
|
||||
|
23
composer.lock
generated
23
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "9d6fb513e40aa21d6baf7214d9ed9b79",
|
||||
"content-hash": "1ed69715f37c5e76091e7f4b6d4edb89",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@ -2210,16 +2210,16 @@
|
||||
},
|
||||
{
|
||||
"name": "jikan-me/jikan",
|
||||
"version": "v3.0.0-alpha.9",
|
||||
"version": "v3.0.0-alpha.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jikan-me/jikan.git",
|
||||
"reference": "d9aba6d2d16c0ab387c08740d64db2ffef3fcb11"
|
||||
"reference": "0d1a587ab092e729f277860347b9fd371177fd0d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jikan-me/jikan/zipball/d9aba6d2d16c0ab387c08740d64db2ffef3fcb11",
|
||||
"reference": "d9aba6d2d16c0ab387c08740d64db2ffef3fcb11",
|
||||
"url": "https://api.github.com/repos/jikan-me/jikan/zipball/0d1a587ab092e729f277860347b9fd371177fd0d",
|
||||
"reference": "0d1a587ab092e729f277860347b9fd371177fd0d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2227,14 +2227,15 @@
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"brianium/paratest": "1.*",
|
||||
"brianium/paratest": "~4.0",
|
||||
"doctrine/collections": "^1.5",
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"jakub-onderka/php-parallel-lint": "^1.0",
|
||||
"jikan-me/jikan-fixtures": "dev-master",
|
||||
"php-vcr/php-vcr": "~1.3.2",
|
||||
"php-vcr/phpunit-testlistener-vcr": "^3.0",
|
||||
"phpro/grumphp": "^0.15.2",
|
||||
"phpunit/phpunit": "^6.3",
|
||||
"php-vcr/php-vcr": "~1.4",
|
||||
"php-vcr/phpunit-testlistener-vcr": "~3.2",
|
||||
"phpro/grumphp": "^0.19",
|
||||
"phpunit/phpunit": "~9.0",
|
||||
"squizlabs/php_codesniffer": "^3.3"
|
||||
},
|
||||
"type": "library",
|
||||
@ -2256,7 +2257,7 @@
|
||||
}
|
||||
],
|
||||
"description": "Jikan is an unofficial MyAnimeList API",
|
||||
"time": "2020-07-10T15:19:00+00:00"
|
||||
"time": "2020-07-11T07:32:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jms/metadata",
|
||||
|
@ -138,14 +138,32 @@ return [
|
||||
'MagazineController@resource' => 'magazines_manga',
|
||||
|
||||
'UserController@recentlyOnline' => 'users_recently_online',
|
||||
'UserController@profile' => 'users',
|
||||
'UserController@history' => 'users_history',
|
||||
'UserController@friends' => 'users_friends',
|
||||
'UserController@profile' => [
|
||||
'table_name' => 'users',
|
||||
'ttl' => env('CACHE_DEFAULT_EXPIRE')
|
||||
],
|
||||
'UserController@history' => [
|
||||
'table_name' => 'users_history',
|
||||
'ttl' => env('CACHE_USER_EXPIRE')
|
||||
],
|
||||
'UserController@friends' => [
|
||||
'table_name' => 'users_friends',
|
||||
'ttl' => env('CACHE_USER_EXPIRE')
|
||||
],
|
||||
'UserController@recommendations' => [
|
||||
'table_name' => 'users_recommendations',
|
||||
'ttl' => env('CACHE_USER_EXPIRE')
|
||||
],
|
||||
'UserController@reviews' => [
|
||||
'table_name' => 'users_reviews',
|
||||
'ttl' => env('CACHE_USER_EXPIRE')
|
||||
],
|
||||
'UserController@clubs' => [
|
||||
'table_name' => 'users_clubs',
|
||||
'ttl' => env('CACHE_USER_EXPIRE')
|
||||
],
|
||||
'UserController@animelist' => 'users_animelist',
|
||||
'UserController@mangalist' => 'users_mangalist',
|
||||
'UserController@recommendations' => 'users_recommendations',
|
||||
'UserController@reviews' => 'users_reviews',
|
||||
'UserController@clubs' => 'users_clubs',
|
||||
|
||||
'GenreController@mainAnime' => [
|
||||
'table_name' => 'common',
|
||||
|
@ -8,7 +8,7 @@ class CreateIndex extends Migration
|
||||
{
|
||||
|
||||
const IGNORE = [
|
||||
'anime', 'manga', 'people', 'characters', 'magazines', 'producers', 'clubs'
|
||||
'anime', 'manga', 'people', 'characters', 'magazines', 'producers', 'clubs', 'users'
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProfilesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->unique(['request_hash' => 1], 'request_hash');
|
||||
$table->unique(['mal_id' => 1], 'mal_id');
|
||||
$table->unique(['username' => 1], 'username');
|
||||
$table->date('last_online')->index();
|
||||
$table->index('gender');
|
||||
$table->date('birthday')->index();
|
||||
$table->index('location');
|
||||
$table->date('joined')->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user