diff --git a/app/Http/Controllers/Admin/AdminInstanceController.php b/app/Http/Controllers/Admin/AdminInstanceController.php
index b24592c31..6a17fdb2a 100644
--- a/app/Http/Controllers/Admin/AdminInstanceController.php
+++ b/app/Http/Controllers/Admin/AdminInstanceController.php
@@ -8,66 +8,13 @@ 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)
{
- $this->validate($request, [
-
- 'filter' => [
- 'nullable',
- 'string',
- 'min:1',
- 'max:20',
- Rule::in([
- 'cw',
- 'unlisted',
- 'banned',
- // 'popular',
- 'new',
- 'all'
- ])
- ],
- ]);
- if($request->has('q') && $request->filled('q')) {
- $instances = Instance::where('domain', 'like', '%' . $request->input('q') . '%')->simplePaginate(10);
- } else if($request->has('filter') && $request->filled('filter')) {
- switch ($request->filter) {
- case 'cw':
- $instances = Instance::select('id', 'domain', 'unlisted', 'auto_cw', 'banned')->whereAutoCw(true)->orderByDesc('id')->simplePaginate(10);
- break;
- case 'unlisted':
- $instances = Instance::select('id', 'domain', 'unlisted', 'auto_cw', 'banned')->whereUnlisted(true)->orderByDesc('id')->simplePaginate(10);
- break;
- case 'banned':
- $instances = Instance::select('id', 'domain', 'unlisted', 'auto_cw', 'banned')->whereBanned(true)->orderByDesc('id')->simplePaginate(10);
- break;
- case 'new':
- $instances = Instance::select('id', 'domain', 'unlisted', 'auto_cw', 'banned')->latest()->simplePaginate(10);
- break;
- // case 'popular':
- // $popular = Profile::selectRaw('*, count(domain) as count')
- // ->whereNotNull('domain')
- // ->groupBy('domain')
- // ->orderByDesc('count')
- // ->take(10)
- // ->get()
- // ->pluck('domain')
- // ->toArray();
- // $instances = Instance::whereIn('domain', $popular)->simplePaginate(10);
- // break;
-
- default:
- $instances = Instance::select('id', 'domain', 'unlisted', 'auto_cw', 'banned')->orderByDesc('id')->simplePaginate(10);
- break;
- }
- } else {
- $instances = Instance::select('id', 'domain', 'unlisted', 'auto_cw', 'banned')->orderByDesc('id')->simplePaginate(10);
- }
-
- return view('admin.instances.home', compact('instances'));
+ return view('admin.instances.home');
}
public function instanceScan(Request $request)
@@ -133,4 +80,146 @@ trait AdminInstanceController
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(20)
+ ->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'
+ ])
+ ],
+ ]);
+ $filter = $request->input('filter');
+ $query = $request->input('q');
+
+ 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)->orderByDesc('id'); }
+ if($filter == 'unlisted') { return $q->whereUnlisted(true)->orderByDesc('id'); }
+ if($filter == 'banned') { return $q->whereBanned(true)->orderByDesc('id'); }
+ 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');
+ }, function($q) {
+ 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;
+ }
}
diff --git a/app/Http/Resources/AdminInstance.php b/app/Http/Resources/AdminInstance.php
index 4a52e3481..d534f4681 100644
--- a/app/Http/Resources/AdminInstance.php
+++ b/app/Http/Resources/AdminInstance.php
@@ -24,6 +24,9 @@ class AdminInstance extends JsonResource
'user_count' => $this->user_count,
'status_count' => $this->status_count,
'last_crawled_at' => $this->last_crawled_at,
+ 'notes' => $this->notes,
+ 'base_domain' => $this->base_domain,
+ 'ban_subdomains' => $this->ban_subdomains,
'actors_last_synced_at' => $this->actors_last_synced_at,
'created_at' => $this->created_at,
];
diff --git a/app/Instance.php b/app/Instance.php
index 5541d86c9..6a7b8e6f2 100644
--- a/app/Instance.php
+++ b/app/Instance.php
@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
class Instance extends Model
{
- protected $fillable = ['domain'];
+ protected $fillable = ['domain', 'banned', 'auto_cw', 'unlisted', 'notes'];
public function profiles()
{
diff --git a/app/Services/InstanceService.php b/app/Services/InstanceService.php
index b53e8ac00..f044f1b27 100644
--- a/app/Services/InstanceService.php
+++ b/app/Services/InstanceService.php
@@ -11,6 +11,7 @@ class InstanceService
const CACHE_KEY_BANNED_DOMAINS = 'instances:banned:domains';
const CACHE_KEY_UNLISTED_DOMAINS = 'instances:unlisted:domains';
const CACHE_KEY_NSFW_DOMAINS = 'instances:auto_cw:domains';
+ const CACHE_KEY_STATS = 'pf:services:instances:stats';
public static function getByDomain($domain)
{
@@ -52,11 +53,24 @@ class InstanceService
});
}
+ public static function stats()
+ {
+ return Cache::remember(self::CACHE_KEY_STATS, 86400, function() {
+ return [
+ 'total_count' => Instance::count(),
+ 'new_count' => Instance::where('created_at', '>', now()->subDays(14))->count(),
+ 'banned_count' => Instance::whereBanned(true)->count(),
+ 'nsfw_count' => Instance::whereAutoCw(true)->count()
+ ];
+ });
+ }
+
public static function refresh()
{
Cache::forget(self::CACHE_KEY_BANNED_DOMAINS);
Cache::forget(self::CACHE_KEY_UNLISTED_DOMAINS);
Cache::forget(self::CACHE_KEY_NSFW_DOMAINS);
+ Cache::forget(self::CACHE_KEY_STATS);
self::getBannedDomains();
self::getUnlistedDomains();
diff --git a/database/migrations/2023_03_19_050342_add_notes_to_instances_table.php b/database/migrations/2023_03_19_050342_add_notes_to_instances_table.php
new file mode 100644
index 000000000..b259c2e5f
--- /dev/null
+++ b/database/migrations/2023_03_19_050342_add_notes_to_instances_table.php
@@ -0,0 +1,48 @@
+text('notes')->nullable();
+ $table->boolean('manually_added')->default(false);
+ $table->string('base_domain')->nullable();
+ $table->boolean('ban_subdomains')->nullable()->index();
+ $table->string('ip_address')->nullable();
+ $table->boolean('list_limitation')->default(false)->index();
+ $table->index('banned');
+ $table->index('auto_cw');
+ $table->index('unlisted');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('instances', function (Blueprint $table) {
+ $table->dropColumn('notes');
+ $table->dropColumn('manually_added');
+ $table->dropColumn('base_domain');
+ $table->dropColumn('ban_subdomains');
+ $table->dropColumn('ip_address');
+ $table->dropColumn('list_limitation');
+ $table->dropIndex('instances_banned_index');
+ $table->dropIndex('instances_auto_cw_index');
+ $table->dropIndex('instances_unlisted_index');
+ });
+ }
+};
diff --git a/resources/assets/components/admin/AdminInstances.vue b/resources/assets/components/admin/AdminInstances.vue
new file mode 100644
index 000000000..67bfe9fe6
--- /dev/null
+++ b/resources/assets/components/admin/AdminInstances.vue
@@ -0,0 +1,628 @@
+
+ Instances {{editingInstance.notes ? editingInstance.notes.length : 0}}/500 Enter a valid domain without https:// {{addNewInstance.notes ? addNewInstance.notes.length : 0}}/500Total Instances
+ {{ prettyCount(stats.total_count) }}
+ New (past 14 days)
+ {{ prettyCount(stats.new_count) }}
+ Banned Instances
+ {{ prettyCount(stats.banned_count) }}
+ NSFW Instances
+ {{ prettyCount(stats.nsfw_count) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Created
+
+
+
+
+
+ {{ instance.id }}
+
+
+ {{ instance.domain }}
+ {{ instance.software }}
+ {{ prettyCount(instance.user_count) }}
+ {{ prettyCount(instance.status_count) }}
+
+
+
+ {{ timeAgo(instance.created_at) }}
+
Warning
-No instances were found.
-Do you want to scan and populate instances from Profiles and Statuses?
--
- - @else -- {{$instance->domain}} -
-- @if($instance->unlisted) - - @endif - @if($instance->auto_cw) - - @endif - @if($instance->banned) - - @endif - Overview - -
-No results found
- - @endif - @if(request()->filled('filter') && $instances->count() == 0) -No results found
- - @endif -