mirror of https://github.com/Chocobozzz/PeerTube
Client: add basic support to report video abuses
parent
4f8c0eb0e9
commit
11ac88de40
|
@ -37,10 +37,6 @@ Prototype of a decentralized video streaming platform using P2P (BitTorrent) dir
|
|||
<img src="https://david-dm.org/Chocobozzz/PeerTube/dev-status.svg" alt="devDependency Status" />
|
||||
</a>
|
||||
|
||||
<a href="https://codeclimate.com/github/Chocobozzz/PeerTube">
|
||||
<img src="https://codeclimate.com/github/Chocobozzz/PeerTube/badges/gpa.svg" alt="Code climate" />
|
||||
</a>
|
||||
|
||||
<a href="http://standardjs.com/">
|
||||
<img src="https://img.shields.io/badge/code%20style-standard-brightgreen.svg" alt="JavaScript Style Guide" />
|
||||
</a>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { AdminComponent } from './admin.component';
|
|||
import { FriendsRoutes } from './friends';
|
||||
import { RequestsRoutes } from './requests';
|
||||
import { UsersRoutes } from './users';
|
||||
import { VideoAbusesRoutes } from './video-abuses';
|
||||
|
||||
const adminRoutes: Routes = [
|
||||
{
|
||||
|
@ -18,7 +19,8 @@ const adminRoutes: Routes = [
|
|||
},
|
||||
...FriendsRoutes,
|
||||
...RequestsRoutes,
|
||||
...UsersRoutes
|
||||
...UsersRoutes,
|
||||
...VideoAbusesRoutes
|
||||
]
|
||||
}
|
||||
];
|
||||
|
|
|
@ -5,6 +5,7 @@ import { AdminRoutingModule } from './admin-routing.module';
|
|||
import { FriendsComponent, FriendAddComponent, FriendListComponent, FriendService } from './friends';
|
||||
import { RequestsComponent, RequestStatsComponent, RequestService } from './requests';
|
||||
import { UsersComponent, UserAddComponent, UserListComponent, UserService } from './users';
|
||||
import { VideoAbusesComponent, VideoAbuseListComponent } from './video-abuses';
|
||||
import { MenuAdminComponent } from './menu-admin.component';
|
||||
import { SharedModule } from '../shared';
|
||||
|
||||
|
@ -28,6 +29,9 @@ import { SharedModule } from '../shared';
|
|||
UserAddComponent,
|
||||
UserListComponent,
|
||||
|
||||
VideoAbusesComponent,
|
||||
VideoAbuseListComponent,
|
||||
|
||||
MenuAdminComponent
|
||||
],
|
||||
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
<span class="hidden-xs glyphicon glyphicon-stats"></span>
|
||||
<a [routerLink]="['/admin/requests/stats']">Request stats</a>
|
||||
</div>
|
||||
|
||||
<div id="panel-video-abuses" class="panel-button">
|
||||
<span class="hidden-xs glyphicon glyphicon-alert"></span>
|
||||
<a [routerLink]="['/admin/video-abuses/list']">Video abuses</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-block">
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export * from './video-abuse-list';
|
||||
export * from './video-abuses.component';
|
||||
export * from './video-abuses.routes';
|
|
@ -0,0 +1 @@
|
|||
export * from './video-abuse-list.component';
|
|
@ -0,0 +1,27 @@
|
|||
<h3>Video abuses list</h3>
|
||||
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="cell-id">ID</th>
|
||||
<th class="cell-reason">Reason</th>
|
||||
<th>Reporter pod host</th>
|
||||
<th>Reporter username</th>
|
||||
<th>Video</th>
|
||||
<th>Created at</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr *ngFor="let videoAbuse of videoAbuses">
|
||||
<td>{{ videoAbuse.id }}</td>
|
||||
<td>{{ videoAbuse.reason }}</td>
|
||||
<td>{{ videoAbuse.reporterPodHost }}</td>
|
||||
<td>{{ videoAbuse.reporterUsername }}</td>
|
||||
<td>
|
||||
<a [routerLink]="buildVideoLink(videoAbuse)" title="Go to video">{{ videoAbuse.videoId }}</a>
|
||||
</td>
|
||||
<td>{{ videoAbuse.createdAt | date: 'medium' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
|
@ -0,0 +1,7 @@
|
|||
.cell-id {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.cell-reason {
|
||||
width: 200px;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
import { setInterval } from 'timers'
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { VideoAbuseService, VideoAbuse} from '../../../shared';
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-abuse-list',
|
||||
templateUrl: './video-abuse-list.component.html',
|
||||
styleUrls: [ './video-abuse-list.component.scss' ]
|
||||
})
|
||||
export class VideoAbuseListComponent implements OnInit {
|
||||
videoAbuses: VideoAbuse[];
|
||||
|
||||
constructor(private videoAbuseService: VideoAbuseService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.getVideoAbuses();
|
||||
}
|
||||
|
||||
buildVideoLink(videoAbuse: VideoAbuse) {
|
||||
return `/videos/${videoAbuse.videoId}`;
|
||||
}
|
||||
|
||||
private getVideoAbuses() {
|
||||
this.videoAbuseService.getVideoAbuses().subscribe(
|
||||
res => this.videoAbuses = res.videoAbuses,
|
||||
|
||||
err => alert(err.text)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: '<router-outlet></router-outlet>'
|
||||
})
|
||||
|
||||
export class VideoAbusesComponent {
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import { Routes } from '@angular/router';
|
||||
|
||||
import { VideoAbusesComponent } from './video-abuses.component';
|
||||
import { VideoAbuseListComponent } from './video-abuse-list';
|
||||
|
||||
export const VideoAbusesRoutes: Routes = [
|
||||
{
|
||||
path: 'video-abuses',
|
||||
component: VideoAbusesComponent
|
||||
,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'list',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
{
|
||||
path: 'list',
|
||||
component: VideoAbuseListComponent,
|
||||
data: {
|
||||
meta: {
|
||||
titleSuffix: ' - Video abuses list'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
|
@ -1,4 +1,4 @@
|
|||
export * from './host.validator';
|
||||
export * from './user';
|
||||
export * from './video-report';
|
||||
export * from './video-abuse';
|
||||
export * from './video';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Validators } from '@angular/forms';
|
||||
|
||||
export const VIDEO_REPORT_REASON = {
|
||||
export const VIDEO_ABUSE_REASON = {
|
||||
VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ],
|
||||
MESSAGES: {
|
||||
'required': 'Report reason name is required.',
|
|
@ -3,4 +3,5 @@ export * from './forms';
|
|||
export * from './rest';
|
||||
export * from './search';
|
||||
export * from './users';
|
||||
export * from './video-abuse';
|
||||
export * from './shared.module';
|
||||
|
|
|
@ -14,6 +14,7 @@ import { FileUploadModule } from 'ng2-file-upload/ng2-file-upload';
|
|||
import { AUTH_HTTP_PROVIDERS } from './auth';
|
||||
import { RestExtractor, RestService } from './rest';
|
||||
import { SearchComponent, SearchService } from './search';
|
||||
import { VideoAbuseService } from './video-abuse';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -57,7 +58,8 @@ import { SearchComponent, SearchService } from './search';
|
|||
AUTH_HTTP_PROVIDERS,
|
||||
RestExtractor,
|
||||
RestService,
|
||||
SearchService
|
||||
SearchService,
|
||||
VideoAbuseService
|
||||
]
|
||||
})
|
||||
export class SharedModule { }
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export * from './video-abuse.service';
|
||||
export * from './video-abuse.model';
|
|
@ -0,0 +1,8 @@
|
|||
export interface VideoAbuse {
|
||||
id: string;
|
||||
reason: string;
|
||||
reporterPodHost: string;
|
||||
reporterUsername: string;
|
||||
videoId: string;
|
||||
createdAt: Date;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import 'rxjs/add/operator/catch';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
import { AuthService } from '../core';
|
||||
import { AuthHttp } from '../auth';
|
||||
import { RestExtractor, ResultList } from '../rest';
|
||||
import { VideoAbuse } from './video-abuse.model';
|
||||
|
||||
@Injectable()
|
||||
export class VideoAbuseService {
|
||||
private static BASE_VIDEO_ABUSE_URL = '/api/v1/videos/';
|
||||
|
||||
constructor(
|
||||
private authHttp: AuthHttp,
|
||||
private restExtractor: RestExtractor
|
||||
) {}
|
||||
|
||||
getVideoAbuses() {
|
||||
return this.authHttp.get(VideoAbuseService.BASE_VIDEO_ABUSE_URL + 'abuse')
|
||||
.map(this.restExtractor.extractDataList)
|
||||
.map(this.extractVideoAbuses)
|
||||
}
|
||||
|
||||
reportVideo(id: string, reason: string) {
|
||||
const body = {
|
||||
reason
|
||||
};
|
||||
const url = VideoAbuseService.BASE_VIDEO_ABUSE_URL + id + '/abuse';
|
||||
|
||||
return this.authHttp.post(url, body)
|
||||
.map(this.restExtractor.extractDataBool)
|
||||
.catch((res) => this.restExtractor.handleError(res));
|
||||
}
|
||||
|
||||
private extractVideoAbuses(result: ResultList) {
|
||||
const videoAbuses: VideoAbuse[] = result.data;
|
||||
const totalVideoAbuses = result.total;
|
||||
|
||||
return { videoAbuses, totalVideoAbuses };
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
|||
|
||||
import { ModalDirective } from 'ng2-bootstrap/modal';
|
||||
|
||||
import { FormReactive, VIDEO_REPORT_REASON } from '../../shared';
|
||||
import { FormReactive, VideoAbuseService, VIDEO_ABUSE_REASON } from '../../shared';
|
||||
import { Video, VideoService } from '../shared';
|
||||
|
||||
@Component({
|
||||
|
@ -21,12 +21,12 @@ export class VideoReportComponent extends FormReactive implements OnInit {
|
|||
reason: ''
|
||||
};
|
||||
validationMessages = {
|
||||
reason: VIDEO_REPORT_REASON.MESSAGES
|
||||
reason: VIDEO_ABUSE_REASON.MESSAGES
|
||||
};
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private videoService: VideoService
|
||||
private videoAbuseService: VideoAbuseService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export class VideoReportComponent extends FormReactive implements OnInit {
|
|||
|
||||
buildForm() {
|
||||
this.form = this.formBuilder.group({
|
||||
reason: [ '', VIDEO_REPORT_REASON.VALIDATORS ]
|
||||
reason: [ '', VIDEO_ABUSE_REASON.VALIDATORS ]
|
||||
});
|
||||
|
||||
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
|
||||
|
@ -54,7 +54,7 @@ export class VideoReportComponent extends FormReactive implements OnInit {
|
|||
report() {
|
||||
const reason = this.form.value['reason']
|
||||
|
||||
this.videoService.reportVideo(this.video.id, reason)
|
||||
this.videoAbuseService.reportVideo(this.video.id, reason)
|
||||
.subscribe(
|
||||
// TODO: move alert to beautiful notifications
|
||||
ok => {
|
||||
|
|
|
@ -70,7 +70,7 @@ function init (silent, callback) {
|
|||
}
|
||||
})
|
||||
|
||||
if (!silent) logger.info('Database is ready.')
|
||||
if (!silent) logger.info('Database %s is ready.', dbname)
|
||||
|
||||
return callback(null)
|
||||
})
|
||||
|
|
|
@ -106,7 +106,8 @@ function toFormatedJSON () {
|
|||
reporterPodHost,
|
||||
reason: this.reason,
|
||||
reporterUsername: this.reporterUsername,
|
||||
videoId: this.videoId
|
||||
videoId: this.videoId,
|
||||
createdAt: this.createdAt
|
||||
}
|
||||
|
||||
return json
|
||||
|
|
Loading…
Reference in New Issue