Bläddra i källkod

Add mark as spammer mod tool, unlists and applies content warning to existing and future posts

Daniel Supernault 4 år sedan
förälder
incheckning
6d956a86f4

+ 20 - 1
app/Http/Controllers/InternalApiController.php

@@ -28,6 +28,7 @@ use App\Transformer\Api\{
 };
 use App\Util\Media\Filter;
 use App\Jobs\StatusPipeline\NewStatusPipeline;
+use App\Jobs\ModPipeline\HandleSpammerPipeline;
 use League\Fractal\Serializer\ArraySerializer;
 use League\Fractal\Pagination\IlluminatePaginatorAdapter;
 use Illuminate\Validation\Rule;
@@ -175,7 +176,8 @@ class InternalApiController extends Controller
 				Rule::in([
 					'addcw',
 					'remcw',
-					'unlist'
+					'unlist',
+					'spammer'
 				])
 			],
 			'item_id' => 'required|integer|min:1',
@@ -310,6 +312,23 @@ class InternalApiController extends Controller
 					$u->save();
 				}
 			break;
+
+			case 'spammer':
+				$status = Status::findOrFail($item_id);
+				HandleSpammerPipeline::dispatch($status->profile);
+				ModLogService::boot()
+					->user(Auth::user())
+					->objectUid($status->profile->user_id)
+					->objectId($status->id)
+					->objectType('App\User::class')
+					->action('admin.status.moderate')
+					->metadata([
+						'action' => 'spammer',
+						'message' => 'Success!'
+					])
+					->accessLevel('admin')
+					->save();
+			break;
 		}
 
 		Cache::forget('_api:statuses:recent_9:' . $status->profile_id);

+ 52 - 0
app/Jobs/ModPipeline/HandleSpammerPipeline.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Jobs\ModPipeline;
+
+use Cache;
+use App\Profile;
+use App\Status;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+use App\Services\StatusService;
+
+class HandleSpammerPipeline implements ShouldQueue
+{
+	use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+	protected $profile;
+
+	public $deleteWhenMissingModels = true;
+
+	public function __construct(Profile $profile)
+	{
+		$this->profile = $profile;
+	}
+
+	public function handle()
+	{
+		$profile = $this->profile;
+
+		$profile->unlisted = true;
+		$profile->cw = true;
+		$profile->no_autolink = true;
+		$profile->save();
+
+		Status::whereProfileId($profile->id)
+			->chunk(50, function($statuses) {
+				foreach($statuses as $status) {
+					$status->is_nsfw = true;
+					$status->scope = $status->scope === 'public' ? 'unlisted' : $status->scope;
+					$status->visibility = $status->scope;
+					$status->save();
+					StatusService::del($status->id);
+				}
+		});
+
+		Cache::forget('_api:statuses:recent_9:'.$profile->id);
+
+		return 1;
+	}
+}

+ 116 - 82
resources/assets/js/components/partials/ContextMenu.vue

@@ -37,6 +37,10 @@
 				<div class="list-group-item rounded cursor-pointer" @click="moderatePost(status, 'unlist')">Unlist from Timelines</div>
 				<div v-if="status.sensitive" class="list-group-item rounded cursor-pointer" @click="moderatePost(status, 'remcw')">Remove Content Warning</div>
 				<div v-else class="list-group-item rounded cursor-pointer" @click="moderatePost(status, 'addcw')">Add Content Warning</div>
+				<div class="list-group-item rounded cursor-pointer" @click="moderatePost(status, 'spammer')">
+					Mark as Spammer<br />
+					<span class="small">Unlist + CW existing and future posts</span>
+				</div>
 				<!-- <div class="list-group-item rounded cursor-pointer" @click="ctxModOtherMenuShow()">Other</div> -->
 				<div class="list-group-item rounded cursor-pointer text-lighter" @click="ctxModMenuClose()">Cancel</div>
 			</div>
@@ -465,99 +469,129 @@
 
 			moderatePost(status, action, $event) {
 				let username = status.account.username;
+				let pid = status.id;
 				let msg = '';
 				let self = this;
 				switch(action) {
 					case 'addcw':
-					msg = 'Are you sure you want to add a content warning to this post?';
-					swal({
-						title: 'Confirm',
-						text: msg,
-						icon: 'warning',
-						buttons: true,
-						dangerMode: true
-					}).then(res =>  {
-						if(res) {
-							axios.post('/api/v2/moderator/action', {
-								action: action,
-								item_id: status.id,
-								item_type: 'status'
-							}).then(res => {
-								swal('Success', 'Successfully added content warning', 'success');
-								status.sensitive = true;
-								self.ctxModMenuClose();
-							}).catch(err => {
-								swal(
-									'Error',
-									'Something went wrong, please try again later.',
-									'error'
-									);
-								self.ctxModMenuClose();
-							});
-						}
-					});
+						msg = 'Are you sure you want to add a content warning to this post?';
+						swal({
+							title: 'Confirm',
+							text: msg,
+							icon: 'warning',
+							buttons: true,
+							dangerMode: true
+						}).then(res =>  {
+							if(res) {
+								axios.post('/api/v2/moderator/action', {
+									action: action,
+									item_id: status.id,
+									item_type: 'status'
+								}).then(res => {
+									swal('Success', 'Successfully added content warning', 'success');
+									status.sensitive = true;
+									self.ctxModMenuClose();
+								}).catch(err => {
+									swal(
+										'Error',
+										'Something went wrong, please try again later.',
+										'error'
+										);
+									self.ctxModMenuClose();
+								});
+							}
+						});
 					break;
 
 					case 'remcw':
-					msg = 'Are you sure you want to remove the content warning on this post?';
-					swal({
-						title: 'Confirm',
-						text: msg,
-						icon: 'warning',
-						buttons: true,
-						dangerMode: true
-					}).then(res =>  {
-						if(res) {
-							axios.post('/api/v2/moderator/action', {
-								action: action,
-								item_id: status.id,
-								item_type: 'status'
-							}).then(res => {
-								swal('Success', 'Successfully added content warning', 'success');
-								status.sensitive = false;
-								self.ctxModMenuClose();
-							}).catch(err => {
-								swal(
-									'Error',
-									'Something went wrong, please try again later.',
-									'error'
-									);
-								self.ctxModMenuClose();
-							});
-						}
-					});
+						msg = 'Are you sure you want to remove the content warning on this post?';
+						swal({
+							title: 'Confirm',
+							text: msg,
+							icon: 'warning',
+							buttons: true,
+							dangerMode: true
+						}).then(res =>  {
+							if(res) {
+								axios.post('/api/v2/moderator/action', {
+									action: action,
+									item_id: status.id,
+									item_type: 'status'
+								}).then(res => {
+									swal('Success', 'Successfully added content warning', 'success');
+									status.sensitive = false;
+									self.ctxModMenuClose();
+								}).catch(err => {
+									swal(
+										'Error',
+										'Something went wrong, please try again later.',
+										'error'
+										);
+									self.ctxModMenuClose();
+								});
+							}
+						});
 					break;
 
 					case 'unlist':
-					msg = 'Are you sure you want to unlist this post?';
-					swal({
-						title: 'Confirm',
-						text: msg,
-						icon: 'warning',
-						buttons: true,
-						dangerMode: true
-					}).then(res =>  {
-						if(res) {
-							axios.post('/api/v2/moderator/action', {
-								action: action,
-								item_id: status.id,
-								item_type: 'status'
-							}).then(res => {
-								this.feed = this.feed.filter(f => {
-									return f.id != status.id;
+						msg = 'Are you sure you want to unlist this post?';
+						swal({
+							title: 'Confirm',
+							text: msg,
+							icon: 'warning',
+							buttons: true,
+							dangerMode: true
+						}).then(res =>  {
+							if(res) {
+								axios.post('/api/v2/moderator/action', {
+									action: action,
+									item_id: status.id,
+									item_type: 'status'
+								}).then(res => {
+									this.feed = this.feed.filter(f => {
+										return f.id != status.id;
+									});
+									swal('Success', 'Successfully unlisted post', 'success');
+									self.ctxModMenuClose();
+								}).catch(err => {
+									self.ctxModMenuClose();
+									swal(
+										'Error',
+										'Something went wrong, please try again later.',
+										'error'
+										);
 								});
-								swal('Success', 'Successfully unlisted post', 'success');
-								self.ctxModMenuClose();
-							}).catch(err => {
-								self.ctxModMenuClose();
-								swal(
-									'Error',
-									'Something went wrong, please try again later.',
-									'error'
-									);
-							});
-						}
-					});
+							}
+						});
+					break;
+
+					case 'spammer':
+						msg = 'Are you sure you want to mark this user as a spammer? All existing and future posts will be unlisted on timelines and a content warning will be applied.';
+						swal({
+							title: 'Confirm',
+							text: msg,
+							icon: 'warning',
+							buttons: true,
+							dangerMode: true
+						}).then(res =>  {
+							if(res) {
+								axios.post('/api/v2/moderator/action', {
+									action: action,
+									item_id: status.id,
+									item_type: 'status'
+								}).then(res => {
+									swal('Success', 'Successfully marked account as spammer', 'success');
+									self.ctxModMenuClose();
+								}).catch(err => {
+									self.ctxModMenuClose();
+									swal(
+										'Error',
+										'Something went wrong, please try again later.',
+										'error'
+										);
+								});
+							}
+						});
 					break;
 				}
 			},