diff --git a/README.md b/README.md
index ee1c6b12e..a25f058f8 100644
--- a/README.md
+++ b/README.md
@@ -37,10 +37,6 @@ Prototype of a decentralized video streaming platform using P2P (BitTorrent) dir
-
-
-
-
diff --git a/client/src/app/admin/admin-routing.module.ts b/client/src/app/admin/admin-routing.module.ts
index 6bff25033..cabc6df15 100644
--- a/client/src/app/admin/admin-routing.module.ts
+++ b/client/src/app/admin/admin-routing.module.ts
@@ -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
]
}
];
diff --git a/client/src/app/admin/admin.module.ts b/client/src/app/admin/admin.module.ts
index 63d99a3db..d3ada8ce8 100644
--- a/client/src/app/admin/admin.module.ts
+++ b/client/src/app/admin/admin.module.ts
@@ -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
],
diff --git a/client/src/app/admin/menu-admin.component.html b/client/src/app/admin/menu-admin.component.html
index e250615aa..ad7a7a1b4 100644
--- a/client/src/app/admin/menu-admin.component.html
+++ b/client/src/app/admin/menu-admin.component.html
@@ -15,6 +15,11 @@
Request stats
+
+
diff --git a/client/src/app/admin/video-abuses/index.ts b/client/src/app/admin/video-abuses/index.ts
new file mode 100644
index 000000000..7f5e65f91
--- /dev/null
+++ b/client/src/app/admin/video-abuses/index.ts
@@ -0,0 +1,3 @@
+export * from './video-abuse-list';
+export * from './video-abuses.component';
+export * from './video-abuses.routes';
diff --git a/client/src/app/admin/video-abuses/video-abuse-list/index.ts b/client/src/app/admin/video-abuses/video-abuse-list/index.ts
new file mode 100644
index 000000000..3f2ed1714
--- /dev/null
+++ b/client/src/app/admin/video-abuses/video-abuse-list/index.ts
@@ -0,0 +1 @@
+export * from './video-abuse-list.component';
diff --git a/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.html b/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.html
new file mode 100644
index 000000000..46043577c
--- /dev/null
+++ b/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.html
@@ -0,0 +1,27 @@
+
Video abuses list
+
+
+
+
+ ID |
+ Reason |
+ Reporter pod host |
+ Reporter username |
+ Video |
+ Created at |
+
+
+
+
+
+ {{ videoAbuse.id }} |
+ {{ videoAbuse.reason }} |
+ {{ videoAbuse.reporterPodHost }} |
+ {{ videoAbuse.reporterUsername }} |
+
+ {{ videoAbuse.videoId }}
+ |
+ {{ videoAbuse.createdAt | date: 'medium' }} |
+
+
+
diff --git a/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.scss b/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.scss
new file mode 100644
index 000000000..a094f74b8
--- /dev/null
+++ b/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.scss
@@ -0,0 +1,7 @@
+.cell-id {
+ width: 40px;
+}
+
+.cell-reason {
+ width: 200px;
+}
diff --git a/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.ts b/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.ts
new file mode 100644
index 000000000..de58bba3d
--- /dev/null
+++ b/client/src/app/admin/video-abuses/video-abuse-list/video-abuse-list.component.ts
@@ -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)
+ );
+ }
+}
diff --git a/client/src/app/admin/video-abuses/video-abuses.component.ts b/client/src/app/admin/video-abuses/video-abuses.component.ts
new file mode 100644
index 000000000..001f27e87
--- /dev/null
+++ b/client/src/app/admin/video-abuses/video-abuses.component.ts
@@ -0,0 +1,8 @@
+import { Component } from '@angular/core';
+
+@Component({
+ template: '
'
+})
+
+export class VideoAbusesComponent {
+}
diff --git a/client/src/app/admin/video-abuses/video-abuses.routes.ts b/client/src/app/admin/video-abuses/video-abuses.routes.ts
new file mode 100644
index 000000000..26a761887
--- /dev/null
+++ b/client/src/app/admin/video-abuses/video-abuses.routes.ts
@@ -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'
+ }
+ }
+ }
+ ]
+ }
+];
diff --git a/client/src/app/shared/forms/form-validators/index.ts b/client/src/app/shared/forms/form-validators/index.ts
index 119b5d9bf..ab7c2df31 100644
--- a/client/src/app/shared/forms/form-validators/index.ts
+++ b/client/src/app/shared/forms/form-validators/index.ts
@@ -1,4 +1,4 @@
export * from './host.validator';
export * from './user';
-export * from './video-report';
+export * from './video-abuse';
export * from './video';
diff --git a/client/src/app/shared/forms/form-validators/video-report.ts b/client/src/app/shared/forms/form-validators/video-abuse.ts
similarity index 90%
rename from client/src/app/shared/forms/form-validators/video-report.ts
rename to client/src/app/shared/forms/form-validators/video-abuse.ts
index 036ee1721..94a29a3b7 100644
--- a/client/src/app/shared/forms/form-validators/video-report.ts
+++ b/client/src/app/shared/forms/form-validators/video-abuse.ts
@@ -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.',
diff --git a/client/src/app/shared/index.ts b/client/src/app/shared/index.ts
index 52a647b83..7876e6f14 100644
--- a/client/src/app/shared/index.ts
+++ b/client/src/app/shared/index.ts
@@ -3,4 +3,5 @@ export * from './forms';
export * from './rest';
export * from './search';
export * from './users';
+export * from './video-abuse';
export * from './shared.module';
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index 748c5d520..7b2386d6c 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -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 { }
diff --git a/client/src/app/shared/video-abuse/index.ts b/client/src/app/shared/video-abuse/index.ts
new file mode 100644
index 000000000..563533ba5
--- /dev/null
+++ b/client/src/app/shared/video-abuse/index.ts
@@ -0,0 +1,2 @@
+export * from './video-abuse.service';
+export * from './video-abuse.model';
diff --git a/client/src/app/shared/video-abuse/video-abuse.model.ts b/client/src/app/shared/video-abuse/video-abuse.model.ts
new file mode 100644
index 000000000..bb0373027
--- /dev/null
+++ b/client/src/app/shared/video-abuse/video-abuse.model.ts
@@ -0,0 +1,8 @@
+export interface VideoAbuse {
+ id: string;
+ reason: string;
+ reporterPodHost: string;
+ reporterUsername: string;
+ videoId: string;
+ createdAt: Date;
+}
diff --git a/client/src/app/shared/video-abuse/video-abuse.service.ts b/client/src/app/shared/video-abuse/video-abuse.service.ts
new file mode 100644
index 000000000..2750a41c7
--- /dev/null
+++ b/client/src/app/shared/video-abuse/video-abuse.service.ts
@@ -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 };
+ }
+}
diff --git a/client/src/app/videos/video-watch/video-report.component.ts b/client/src/app/videos/video-watch/video-report.component.ts
index 7bc1677ab..7a125f53e 100644
--- a/client/src/app/videos/video-watch/video-report.component.ts
+++ b/client/src/app/videos/video-watch/video-report.component.ts
@@ -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 => {
diff --git a/server/initializers/database.js b/server/initializers/database.js
index f8f68adeb..043152a0e 100644
--- a/server/initializers/database.js
+++ b/server/initializers/database.js
@@ -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)
})
diff --git a/server/models/video-abuse.js b/server/models/video-abuse.js
index 766a7568d..67cead3af 100644
--- a/server/models/video-abuse.js
+++ b/server/models/video-abuse.js
@@ -106,7 +106,8 @@ function toFormatedJSON () {
reporterPodHost,
reason: this.reason,
reporterUsername: this.reporterUsername,
- videoId: this.videoId
+ videoId: this.videoId,
+ createdAt: this.createdAt
}
return json