1
0

AdminInstanceController.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use DB, Cache;
  4. use App\{Instance, Profile};
  5. use Carbon\Carbon;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Validation\Rule;
  8. use App\Services\InstanceService;
  9. use App\Http\Resources\AdminInstance;
  10. trait AdminInstanceController
  11. {
  12. public function instances(Request $request)
  13. {
  14. return view('admin.instances.home');
  15. }
  16. public function instanceScan(Request $request)
  17. {
  18. Profile::whereNotNull('domain')
  19. ->latest()
  20. ->groupBy(['domain', 'id'])
  21. ->where('created_at', '>', now()->subMonths(2))
  22. ->chunk(100, function($domains) {
  23. foreach($domains as $domain) {
  24. Instance::firstOrCreate([
  25. 'domain' => $domain->domain
  26. ]);
  27. }
  28. });
  29. return redirect()->back();
  30. }
  31. public function instanceShow(Request $request, $id)
  32. {
  33. $instance = Instance::findOrFail($id);
  34. return view('admin.instances.show', compact('instance'));
  35. }
  36. public function instanceEdit(Request $request, $id)
  37. {
  38. $this->validate($request, [
  39. 'action' => [
  40. 'required',
  41. 'string',
  42. 'min:1',
  43. 'max:20',
  44. Rule::in(['autocw', 'unlist', 'ban'])
  45. ],
  46. ]);
  47. $instance = Instance::findOrFail($id);
  48. $unlisted = $instance->unlisted;
  49. $autocw = $instance->auto_cw;
  50. $banned = $instance->banned;
  51. switch ($request->action) {
  52. case 'autocw':
  53. $instance->auto_cw = $autocw == true ? false : true;
  54. $instance->save();
  55. break;
  56. case 'unlist':
  57. $instance->unlisted = $unlisted == true ? false : true;
  58. $instance->save();
  59. break;
  60. case 'ban':
  61. $instance->banned = $banned == true ? false : true;
  62. $instance->save();
  63. break;
  64. }
  65. Cache::forget(InstanceService::CACHE_KEY_BANNED_DOMAINS);
  66. Cache::forget(InstanceService::CACHE_KEY_UNLISTED_DOMAINS);
  67. Cache::forget(InstanceService::CACHE_KEY_NSFW_DOMAINS);
  68. return response()->json([]);
  69. }
  70. public function getInstancesStatsApi(Request $request)
  71. {
  72. return InstanceService::stats();
  73. }
  74. public function getInstancesQueryApi(Request $request)
  75. {
  76. $this->validate($request, [
  77. 'q' => 'required'
  78. ]);
  79. $q = $request->input('q');
  80. return AdminInstance::collection(
  81. Instance::where('domain', 'like', '%' . $q . '%')
  82. ->orderByDesc('user_count')
  83. ->cursorPaginate(10)
  84. ->withQueryString()
  85. );
  86. }
  87. public function getInstancesApi(Request $request)
  88. {
  89. $this->validate($request, [
  90. 'filter' => [
  91. 'nullable',
  92. 'string',
  93. 'min:1',
  94. 'max:20',
  95. Rule::in([
  96. 'cw',
  97. 'unlisted',
  98. 'banned',
  99. 'popular_users',
  100. 'popular_statuses',
  101. 'new',
  102. 'all'
  103. ])
  104. ],
  105. 'sort' => [
  106. 'sometimes',
  107. 'string',
  108. Rule::in([
  109. 'id',
  110. 'domain',
  111. 'software',
  112. 'user_count',
  113. 'status_count',
  114. 'banned',
  115. 'auto_cw',
  116. 'unlisted'
  117. ])
  118. ],
  119. 'dir' => 'sometimes|in:desc,asc'
  120. ]);
  121. $filter = $request->input('filter');
  122. $query = $request->input('q');
  123. $sortCol = $request->input('sort');
  124. $sortDir = $request->input('dir');
  125. return AdminInstance::collection(Instance::when($query, function($q, $qq) use($query) {
  126. return $q->where('domain', 'like', '%' . $query . '%');
  127. })
  128. ->when($filter, function($q, $f) use($filter) {
  129. if($filter == 'cw') { return $q->whereAutoCw(true); }
  130. if($filter == 'unlisted') { return $q->whereUnlisted(true); }
  131. if($filter == 'banned') { return $q->whereBanned(true); }
  132. if($filter == 'new') { return $q->orderByDesc('id'); }
  133. if($filter == 'popular_users') { return $q->orderByDesc('user_count'); }
  134. if($filter == 'popular_statuses') { return $q->orderByDesc('status_count'); }
  135. return $q->orderByDesc('id');
  136. })
  137. ->when($sortCol, function($q, $s) use($sortCol, $sortDir, $filter) {
  138. if(!in_array($filter, ['popular_users', 'popular_statuses'])) {
  139. return $q->whereNotNull($sortCol)->orderBy($sortCol, $sortDir);
  140. }
  141. }, function($q) use($filter) {
  142. if(!$filter || !in_array($filter, ['popular_users', 'popular_statuses'])) {
  143. return $q->orderByDesc('id');
  144. }
  145. })
  146. ->cursorPaginate(10)
  147. ->withQueryString());
  148. }
  149. public function postInstanceUpdateApi(Request $request)
  150. {
  151. $this->validate($request, [
  152. 'id' => 'required',
  153. 'banned' => 'boolean',
  154. 'auto_cw' => 'boolean',
  155. 'unlisted' => 'boolean',
  156. 'notes' => 'nullable|string|max:500',
  157. ]);
  158. $id = $request->input('id');
  159. $instance = Instance::findOrFail($id);
  160. $instance->update($request->only([
  161. 'banned',
  162. 'auto_cw',
  163. 'unlisted',
  164. 'notes'
  165. ]));
  166. InstanceService::refresh();
  167. return new AdminInstance($instance);
  168. }
  169. public function postInstanceCreateNewApi(Request $request)
  170. {
  171. $this->validate($request, [
  172. 'domain' => 'required|string',
  173. 'banned' => 'boolean',
  174. 'auto_cw' => 'boolean',
  175. 'unlisted' => 'boolean',
  176. 'notes' => 'nullable|string|max:500'
  177. ]);
  178. $domain = $request->input('domain');
  179. abort_if(!strpos($domain, '.'), 400, 'Invalid domain');
  180. abort_if(!filter_var($domain, FILTER_VALIDATE_DOMAIN), 400, 'Invalid domain');
  181. $instance = new Instance;
  182. $instance->domain = $request->input('domain');
  183. $instance->banned = $request->input('banned');
  184. $instance->auto_cw = $request->input('auto_cw');
  185. $instance->unlisted = $request->input('unlisted');
  186. $instance->manually_added = true;
  187. $instance->notes = $request->input('notes');
  188. $instance->save();
  189. InstanceService::refresh();
  190. return new AdminInstance($instance);
  191. }
  192. public function postInstanceRefreshStatsApi(Request $request)
  193. {
  194. $this->validate($request, [
  195. 'id' => 'required'
  196. ]);
  197. $instance = Instance::findOrFail($request->input('id'));
  198. $instance->user_count = Profile::whereDomain($instance->domain)->count();
  199. $instance->status_count = Profile::whereDomain($instance->domain)->leftJoin('statuses', 'profiles.id', '=', 'statuses.profile_id')->count();
  200. $instance->save();
  201. return new AdminInstance($instance);
  202. }
  203. public function postInstanceDeleteApi(Request $request)
  204. {
  205. $this->validate($request, [
  206. 'id' => 'required'
  207. ]);
  208. $instance = Instance::findOrFail($request->input('id'));
  209. $instance->delete();
  210. InstanceService::refresh();
  211. return 200;
  212. }
  213. public function downloadBackup(Request $request)
  214. {
  215. return response()->streamDownload(function () {
  216. $json = [
  217. 'version' => 1,
  218. 'auto_cw' => Instance::whereAutoCw(true)->pluck('domain')->toArray(),
  219. 'unlisted' => Instance::whereUnlisted(true)->pluck('domain')->toArray(),
  220. 'banned' => Instance::whereBanned(true)->pluck('domain')->toArray(),
  221. 'created_at' => now()->format('c'),
  222. ];
  223. $chk = hash('sha256', json_encode($json, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
  224. $json['_sha256'] = $chk;
  225. echo json_encode($json, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
  226. }, 'pixelfed-instances-mod.json');
  227. }
  228. public function importBackup(Request $request)
  229. {
  230. $this->validate($request, [
  231. 'banned' => 'sometimes|array',
  232. 'auto_cw' => 'sometimes|array',
  233. 'unlisted' => 'sometimes|array',
  234. ]);
  235. $banned = $request->input('banned');
  236. $auto_cw = $request->input('auto_cw');
  237. $unlisted = $request->input('unlisted');
  238. foreach($banned as $i) {
  239. Instance::updateOrCreate(
  240. ['domain' => $i],
  241. ['banned' => true]
  242. );
  243. }
  244. foreach($auto_cw as $i) {
  245. Instance::updateOrCreate(
  246. ['domain' => $i],
  247. ['auto_cw' => true]
  248. );
  249. }
  250. foreach($unlisted as $i) {
  251. Instance::updateOrCreate(
  252. ['domain' => $i],
  253. ['unlisted' => true]
  254. );
  255. }
  256. InstanceService::refresh();
  257. return [200];
  258. }
  259. }