Files
animexe/routes/api.php
T
2026-07-14 00:01:48 +03:00

224 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\ImportApiController;
use App\Http\Controllers\Api\AuthApiController;
use App\Http\Controllers\Api\AnimeApiController;
use App\Http\Controllers\Api\UserApiController;
use App\Http\Controllers\Api\CommentApiController;
use App\Http\Controllers\Api\AiApiController;
use App\Http\Controllers\Api\SocialApiController;
use App\Http\Controllers\Api\TribunalApiController;
use App\Http\Controllers\Api\MessageApiController;
use App\Http\Controllers\Api\PlanApiController;
// ── Import API (internal Python scraper) ─────────────────────────────────────
Route::middleware('import.api')->prefix('import')->group(function () {
Route::get('test', [ImportApiController::class, 'test']);
Route::get('stats', [ImportApiController::class, 'stats']);
Route::get('settings', [ImportApiController::class, 'settings']);
Route::get('next-job', [ImportApiController::class, 'nextJob']);
Route::post('jobs', [ImportApiController::class, 'createJob']); // AUTO-IMPORT
Route::get('imported-ids', [ImportApiController::class, 'importedIds']);
Route::get('imported-titles', [ImportApiController::class, 'importedTitles']);
Route::get('ongoing', [ImportApiController::class, 'ongoingAnimes']);
Route::get('all-animes', [ImportApiController::class, 'allAniziumAnimes']);
Route::get('jobs/{job}', [ImportApiController::class, 'getJob']);
Route::post('jobs/{job}/status', [ImportApiController::class, 'updateStatus']);
Route::post('jobs/{job}/episode', [ImportApiController::class, 'saveEpisode']);
Route::post('jobs/{job}/subtitle', [ImportApiController::class, 'saveSubtitle']);
Route::get('jobs/{job}/done-episodes', [ImportApiController::class, 'doneEpisodes']);
// Altyazı yenileme
Route::get('anizium-episodes', [ImportApiController::class, 'aniziumEpisodes']);
Route::post('subtitle-direct', [ImportApiController::class, 'saveSubtitleDirect']);
// Sağlık kontrolü + deaktivasyon
Route::get('anizium-health', [ImportApiController::class, 'aniziumHealthData']);
Route::post('deactivate-anime', [ImportApiController::class, 'deactivateAnime']);
// Animecix-specific
Route::get('animecix/pending', [ImportApiController::class, 'animecixPendingJobs']);
Route::post('episodes/{episode}/video-sources', [ImportApiController::class, 'saveVideoSources']);
// Çapraz kaynak desteği
Route::get('anime/lookup', [ImportApiController::class, 'animeLookup']);
Route::get('published-animes-with-jobs', [ImportApiController::class, 'publishedAnimesWithJobs']);
});
// ── Mobile App API ────────────────────────────────────────────────────────────
// App status (public — called on startup to check maintenance/force-update)
Route::get('app-status', function () {
$minVersion = \App\Models\Setting::get('mobile_min_version', '1.0.0');
$currentVersion = \App\Models\Setting::get('mobile_current_version', '1.0.0');
$maintenance = \App\Models\Setting::get('mobile_maintenance_mode', '0') === '1';
$maintMsg = \App\Models\Setting::get('mobile_maintenance_message', 'Uygulama şu anda bakımda.');
$apkUrl = \App\Models\Setting::get('mobile_apk_url', '');
$forceMsg = \App\Models\Setting::get('mobile_force_update_msg', 'Lütfen uygulamayı güncelleyin.');
// Determine force_update by comparing appVersion (sent as ?v=x.y.z) with minVersion
$appVersion = request('v', '0.0.0');
$forceUpdate = version_compare($appVersion, $minVersion, '<');
return response()->json([
'maintenance' => $maintenance,
'maintenance_message' => $maintMsg,
'min_version' => $minVersion,
'current_version' => $currentVersion,
'apk_url' => $apkUrl ?: null,
'force_update' => $forceUpdate,
'force_update_message'=> $forceMsg,
]);
});
// Auth (public)
Route::prefix('auth')->group(function () {
Route::post('register', [AuthApiController::class, 'register']);
Route::post('login', [AuthApiController::class, 'login']);
});
// Public content
Route::get('home', [AnimeApiController::class, 'home']);
Route::get('animes', [AnimeApiController::class, 'index']);
Route::get('animes/{slug}', [AnimeApiController::class, 'show']);
Route::get('genres', [AnimeApiController::class, 'genres']);
Route::get('genres/{slug}', [AnimeApiController::class, 'genre']);
Route::get('watch/{slug}/{season}/{episode}', [AnimeApiController::class, 'watch']);
// AniSkip (public — no auth needed, does Jikan+AniSkip lookup with caching)
Route::get('aniskip/{slug}/{season}/{episode}', [AnimeApiController::class, 'aniSkip']);
// Skip segments (public — no auth needed)
Route::get('episodes/{episode}/skip-segments', [AnimeApiController::class, 'skipSegments']);
Route::post('episodes/{episode}/skip-event', [AnimeApiController::class, 'recordSkipEvent'])
->middleware('throttle:60,1'); // max 60 events per minute per IP
// HEVC flag — player tarafından HEVC hatası alınan kaynakları işaretler
Route::post('sources/flag-hevc', [AnimeApiController::class, 'flagHevc'])
->middleware('throttle:30,1');
// Reklam istatistikleri — path bilerek nötr ('ads' değil), adblocker /api/ads/ engelliyor
Route::post('slot/{ad}/view', [\App\Http\Controllers\Api\AdApiController::class, 'impression'])
->middleware('throttle:30,1');
Route::post('slot/{ad}/hit', [\App\Http\Controllers\Api\AdApiController::class, 'click'])
->middleware('throttle:30,1');
// Comments (public read, auth write)
Route::get('comments', [CommentApiController::class, 'index']);
// NicoNico timestamp comments (public read)
Route::get('episodes/{episode}/nico-comments', [SocialApiController::class, 'timestampComments']);
// Predictions (public read)
Route::get('episodes/{episode}/predictions', [SocialApiController::class, 'predictions']);
// Spoiler boxes (public read)
Route::get('episodes/{episode}/spoiler-boxes', [SocialApiController::class, 'spoilerBoxes']);
// Tribunal (public read)
Route::get('tribunals', [TribunalApiController::class, 'index']);
Route::get('tribunals/{tribunal}', [TribunalApiController::class, 'show']);
// Watch party info (public)
Route::get('party/{roomCode}', [SocialApiController::class, 'partyInfo']);
// Mood engine (public)
Route::post('mood/recommend', [SocialApiController::class, 'moodRecommend']);
// Anime requests (public list)
Route::get('anime-request', [UserApiController::class, 'requestIndex']);
// Notifications count (optional auth)
Route::get('notifications/count', [UserApiController::class, 'notificationsCount'])
->middleware('auth:sanctum');
// ── Auth required ─────────────────────────────────────────────────────────────
Route::middleware('auth:sanctum')->group(function () {
// Auth
Route::post('auth/logout', [AuthApiController::class, 'logout']);
Route::get('auth/me', [AuthApiController::class, 'me']);
Route::post('auth/profile', [AuthApiController::class, 'updateProfile']);
Route::post('auth/fcm-token', [AuthApiController::class, 'saveFcmToken']);
// Profile stats
Route::get('profile/stats', [UserApiController::class, 'profileStats']);
// Watchlist
Route::get('watchlist', [UserApiController::class, 'watchlist']);
Route::post('watchlist/{anime}/toggle', [UserApiController::class, 'watchlistToggle']);
// Continue watching
Route::post('continue-watching', [UserApiController::class, 'continueWatchingUpdate']);
// Rate & Follow
Route::post('anime/{anime}/rate', [UserApiController::class, 'animeRate']);
Route::post('anime/{anime:slug}/follow', [UserApiController::class, 'followToggle']);
// Notifications
Route::get('notifications', [UserApiController::class, 'notifications']);
// Achievements
Route::get('achievements', [UserApiController::class, 'achievements']);
// Episode notes
Route::post('episode/{episode}/note', [UserApiController::class, 'noteStore']);
Route::delete('notes/{note}', [UserApiController::class, 'noteDelete']);
Route::get('episode/{episode}/notes', [UserApiController::class, 'episodeNotesList']);
// Comments
Route::post('comments', [CommentApiController::class, 'store']);
Route::post('comments/{comment}/like', [CommentApiController::class, 'like']);
// Anime requests
Route::post('anime-request', [UserApiController::class, 'requestStore']);
Route::post('anime-request/{animeRequest}/vote', [UserApiController::class, 'requestVote']);
// AI
Route::post('ai/chat', [AiApiController::class, 'chat']);
Route::post('ai/recommend', [AiApiController::class, 'recommend']);
Route::post('ai/similar', [AiApiController::class, 'similar']);
Route::post('ai/search', [AiApiController::class, 'search']);
// NicoNico (auth write)
Route::post('episodes/{episode}/nico-comments', [SocialApiController::class, 'timestampCommentStore']);
// Predictions (auth write)
Route::post('episodes/{episode}/predictions', [SocialApiController::class, 'predictionStore']);
Route::post('predictions/{prediction}/vote', [SocialApiController::class, 'predictionVote']);
// Spoiler boxes (auth write)
Route::post('episodes/{episode}/spoiler-boxes', [SocialApiController::class, 'spoilerBoxStore']);
Route::post('spoiler-boxes/{box}/like', [SocialApiController::class, 'spoilerBoxLike']);
// Time capsule
Route::get('capsules', [SocialApiController::class, 'capsuleIndex']);
Route::post('capsules', [SocialApiController::class, 'capsuleStore']);
Route::post('capsules/{capsule}/open', [SocialApiController::class, 'capsuleOpen']);
// Tribunal (auth write)
Route::post('tribunals', [TribunalApiController::class, 'store']);
Route::post('tribunals/{tribunal}/vote', [TribunalApiController::class, 'vote']);
Route::post('tribunals/{tribunal}/argue', [TribunalApiController::class, 'argue']);
Route::post('tribunal-arguments/{argument}/vote', [TribunalApiController::class, 'argVote']);
// Watch party
Route::post('party/create', [SocialApiController::class, 'partyCreate']);
Route::post('party/{roomCode}/join', [SocialApiController::class, 'partyJoin']);
Route::post('party/{roomCode}/sync', [SocialApiController::class, 'partySync']);
Route::post('party/{roomCode}/leave', [SocialApiController::class, 'partyLeave']);
// User follow
Route::post('users/{user}/follow', [SocialApiController::class, 'followToggle']);
// Plans
Route::get('plans', [PlanApiController::class, 'index']);
// ── Mesajlar (Mobile Chat) — sabit rotalar önce gelmeli
Route::get('messages', [MessageApiController::class, 'conversations']);
Route::post('messages/start/{user}', [MessageApiController::class, 'startConversation']);
Route::get('messages/{conversation}', [MessageApiController::class, 'show']);
Route::post('messages/{conversation}', [MessageApiController::class, 'send']);
Route::get('messages/{conversation}/poll', [MessageApiController::class, 'poll']);
});