pixelfed/app/Http/Controllers/Admin/AdminInstanceController.php

302 lines
7.3 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use DB, Cache;
use App\{Instance, Profile};
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Services\InstanceService;
use App\Http\Resources\AdminInstance;
trait AdminInstanceController
{
public function instances(Request $request)
{
return view('admin.instances.home');
}
public function instanceScan(Request $request)
{
Profile::whereNotNull('domain')
->latest()
->groupBy(['domain', 'id'])
->where('created_at', '>', now()->subMonths(2))
->chunk(100, function($domains) {
foreach($domains as $domain) {
Instance::firstOrCreate([
'domain' => $domain->domain
]);
}
});
return redirect()->back();
}
public function instanceShow(Request $request, $id)
{
$instance = Instance::findOrFail($id);
return view('admin.instances.show', compact('instance'));
}
public function instanceEdit(Request $request, $id)
{
$this->validate($request, [
'action' => [
'required',
'string',
'min:1',
'max:20',
Rule::in(['autocw', 'unlist', 'ban'])
],
]);
$instance = Instance::findOrFail($id);
$unlisted = $instance->unlisted;
$autocw = $instance->auto_cw;
$banned = $instance->banned;
switch ($request->action) {
case 'autocw':
$instance->auto_cw = $autocw == true ? false : true;
$instance->save();
break;
case 'unlist':
$instance->unlisted = $unlisted == true ? false : true;
$instance->save();
break;
case 'ban':
$instance->banned = $banned == true ? false : true;
$instance->save();
break;
}
Cache::forget(InstanceService::CACHE_KEY_BANNED_DOMAINS);
Cache::forget(InstanceService::CACHE_KEY_UNLISTED_DOMAINS);
Cache::forget(InstanceService::CACHE_KEY_NSFW_DOMAINS);
return response()->json([]);
}
public function getInstancesStatsApi(Request $request)
{
return InstanceService::stats();
}
public function getInstancesQueryApi(Request $request)
{
$this->validate($request, [
'q' => 'required'
]);
$q = $request->input('q');
return AdminInstance::collection(
Instance::where('domain', 'like', '%' . $q . '%')
->orderByDesc('user_count')
->cursorPaginate(10)
->withQueryString()
);
}
public function getInstancesApi(Request $request)
{
$this->validate($request, [
'filter' => [
'nullable',
'string',
'min:1',
'max:20',
Rule::in([
'cw',
'unlisted',
'banned',
'popular_users',
'popular_statuses',
'new',
'all'
])
],
'sort' => [
'sometimes',
'string',
Rule::in([
'id',
'domain',
'software',
'user_count',
'status_count',
'banned',
'auto_cw',
'unlisted'
])
],
'dir' => 'sometimes|in:desc,asc'
]);
$filter = $request->input('filter');
$query = $request->input('q');
$sortCol = $request->input('sort');
$sortDir = $request->input('dir');
return AdminInstance::collection(Instance::when($query, function($q, $qq) use($query) {
return $q->where('domain', 'like', '%' . $query . '%');
})
->when($filter, function($q, $f) use($filter) {
if($filter == 'cw') { return $q->whereAutoCw(true); }
if($filter == 'unlisted') { return $q->whereUnlisted(true); }
if($filter == 'banned') { return $q->whereBanned(true); }
if($filter == 'new') { return $q->orderByDesc('id'); }
if($filter == 'popular_users') { return $q->orderByDesc('user_count'); }
if($filter == 'popular_statuses') { return $q->orderByDesc('status_count'); }
return $q->orderByDesc('id');
})
->when($sortCol, function($q, $s) use($sortCol, $sortDir, $filter) {
if(!in_array($filter, ['popular_users', 'popular_statuses'])) {
return $q->whereNotNull($sortCol)->orderBy($sortCol, $sortDir);
}
}, function($q) use($filter) {
if(!$filter || !in_array($filter, ['popular_users', 'popular_statuses'])) {
return $q->orderByDesc('id');
}
})
->cursorPaginate(10)
->withQueryString());
}
public function postInstanceUpdateApi(Request $request)
{
$this->validate($request, [
'id' => 'required',
'banned' => 'boolean',
'auto_cw' => 'boolean',
'unlisted' => 'boolean',
'notes' => 'nullable|string|max:500',
]);
$id = $request->input('id');
$instance = Instance::findOrFail($id);
$instance->update($request->only([
'banned',
'auto_cw',
'unlisted',
'notes'
]));
InstanceService::refresh();
return new AdminInstance($instance);
}
public function postInstanceCreateNewApi(Request $request)
{
$this->validate($request, [
'domain' => 'required|string',
'banned' => 'boolean',
'auto_cw' => 'boolean',
'unlisted' => 'boolean',
'notes' => 'nullable|string|max:500'
]);
$domain = $request->input('domain');
abort_if(!strpos($domain, '.'), 400, 'Invalid domain');
abort_if(!filter_var($domain, FILTER_VALIDATE_DOMAIN), 400, 'Invalid domain');
$instance = new Instance;
$instance->domain = $request->input('domain');
$instance->banned = $request->input('banned');
$instance->auto_cw = $request->input('auto_cw');
$instance->unlisted = $request->input('unlisted');
$instance->manually_added = true;
$instance->notes = $request->input('notes');
$instance->save();
InstanceService::refresh();
return new AdminInstance($instance);
}
public function postInstanceRefreshStatsApi(Request $request)
{
$this->validate($request, [
'id' => 'required'
]);
$instance = Instance::findOrFail($request->input('id'));
$instance->user_count = Profile::whereDomain($instance->domain)->count();
$instance->status_count = Profile::whereDomain($instance->domain)->leftJoin('statuses', 'profiles.id', '=', 'statuses.profile_id')->count();
$instance->save();
return new AdminInstance($instance);
}
public function postInstanceDeleteApi(Request $request)
{
$this->validate($request, [
'id' => 'required'
]);
$instance = Instance::findOrFail($request->input('id'));
$instance->delete();
InstanceService::refresh();
return 200;
}
public function downloadBackup(Request $request)
{
return response()->streamDownload(function () {
$json = [
'version' => 1,
'auto_cw' => Instance::whereAutoCw(true)->pluck('domain')->toArray(),
'unlisted' => Instance::whereUnlisted(true)->pluck('domain')->toArray(),
'banned' => Instance::whereBanned(true)->pluck('domain')->toArray(),
'created_at' => now()->format('c'),
];
$chk = hash('sha256', json_encode($json, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
$json['_sha256'] = $chk;
echo json_encode($json, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
}, 'pixelfed-instances-mod.json');
}
public function importBackup(Request $request)
{
$this->validate($request, [
'banned' => 'sometimes|array',
'auto_cw' => 'sometimes|array',
'unlisted' => 'sometimes|array',
]);
$banned = $request->input('banned');
$auto_cw = $request->input('auto_cw');
$unlisted = $request->input('unlisted');
foreach($banned as $i) {
Instance::updateOrCreate(
['domain' => $i],
['banned' => true]
);
}
foreach($auto_cw as $i) {
Instance::updateOrCreate(
['domain' => $i],
['auto_cw' => true]
);
}
foreach($unlisted as $i) {
Instance::updateOrCreate(
['domain' => $i],
['unlisted' => true]
);
}
InstanceService::refresh();
return [200];
}
}