diff --git a/dashboard/src/app/dashboard/dashboard.component.ts b/dashboard/src/app/dashboard/dashboard.component.ts index 69d1c39..8a4f328 100644 --- a/dashboard/src/app/dashboard/dashboard.component.ts +++ b/dashboard/src/app/dashboard/dashboard.component.ts @@ -39,12 +39,13 @@ export class DashboardComponent implements OnInit { this.elsService.getSize().then(result => this.totalSize = result); - this.elsService.getCountSong('song') + this.elsService.getCountSong(ElsService.SONG_INDEX_NAME) .then(result => this.trackCountSong = result); - this.elsService.getCountSong('artist') - .then(result => this.trackCountArtist = result); - this.elsService.getCountSong('album') - .then(result => this.trackCountAlbum = result); + // TODO: Unused information + // this.elsService.getCountSong(ElsService.ARTIST_INDEX_NAME) + // .then(result => this.trackCountArtist = result); + // this.elsService.getCountSong(ElsService.ALBUM_INDEX_NAME) + // .then(result => this.trackCountAlbum = result); this.elsService.getCountNeverListenSong() .then(result => this.neverListenSong = result); diff --git a/dashboard/src/app/els.service.ts b/dashboard/src/app/els.service.ts index b633f04..a19286f 100644 --- a/dashboard/src/app/els.service.ts +++ b/dashboard/src/app/els.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http' import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { map, catchError } from 'rxjs/operators'; import { Song } from './model/song'; import { Album } from './model/album'; @@ -12,19 +12,21 @@ import { Bucket } from './model/bucket'; @Injectable() export class ElsService { public static readonly DEFAULT_SIZE: number = 50; - private static readonly INDEX_NAME = 'itunessongs'; + public static readonly SONG_INDEX_NAME = '/itunes-songs'; + public static readonly ARTIST_INDEX_NAME = '/itunes-artists'; + public static readonly ALBUM_INDEX_NAME = '/itunes-albums'; private static readonly ACTION_SEARCH = '/_search'; private static readonly ACTION_COUNT = '/_count'; - private elsUrl = 'http://localhost:9200/' + ElsService.INDEX_NAME + '/'; + private elsUrl = 'http://localhost:9200'; private headers = new HttpHeaders({'Content-Type': 'application/json'}); constructor(private http: HttpClient) { } getTime(): Promise { return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ aggs: { sum_time: { @@ -35,18 +37,12 @@ export class ElsService { }), {headers: this.headers}) .toPromise() .then(res => res.aggregations.sum_time.value as number) - .catch(this.handleError); - } - - getTimeSlowly(): Promise { - return new Promise(resolve => { - setTimeout(() => resolve(this.getTime()), 2000); - }); + .catch(error => this.handleError(error, 'getTime()')); } getSize(): Promise { return this.http - .post(this.elsUrl + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ aggs: { sum_time: { @@ -57,26 +53,20 @@ export class ElsService { }), {headers: this.headers}) .toPromise() .then(res => res.aggregations.sum_time.value as number) - .catch(this.handleError); + .catch(error => this.handleError(error, 'getSize()')); } - getSizeSlowly(): Promise { - return new Promise(resolve => { - setTimeout(() => resolve(this.getSize()), 2000); - }); - } - - getCountSong(type: string): Promise { + getCountSong(index: string): Promise { return this.http - .get(this.elsUrl + type + ElsService.ACTION_COUNT) + .get(this.elsUrl + index + ElsService.ACTION_COUNT) .toPromise() .then(res => res.count as number) - .catch(this.handleError); + .catch(error => this.handleError(error, 'getCountSong(' + index + ')')); } getCountNeverListenSong(): Promise { return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_COUNT, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_COUNT, JSON.stringify({ 'query': { 'bool': { @@ -88,20 +78,14 @@ export class ElsService { }), {headers: this.headers}) .toPromise() .then(res => res.count as number) - .catch(this.handleError); - } - - getTrackCountSlowly(type: string): Promise { - return new Promise(resolve => { - setTimeout(() => resolve(this.getCountSong(type)), 2000); - }); + .catch(error => this.handleError(error, 'getCountNeverListenSong()')); } getMostPlayedTrack(): Observable { // Thank to http://chariotsolutions.com/blog/post/angular2-observables-http-separating-services-components/ // for the map part return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'sort': [ { 'Play Count': { @@ -111,7 +95,8 @@ export class ElsService { 'size': 5 }), {headers: this.headers}) .pipe( - map(res => this.responseToSongs(res)) + map(res => this.responseToSongs(res)), + catchError(error => this.handleError(error, 'getMostPlayedTrack()')) ); } @@ -120,10 +105,10 @@ export class ElsService { */ getMostPlayedAlbumNaive(): Promise { return this.http - .get(this.elsUrl + 'album' + ElsService.ACTION_SEARCH + '?sort=Play Count:desc&size=20') + .get(this.elsUrl + ElsService.ALBUM_INDEX_NAME + ElsService.ACTION_SEARCH + '?sort=Play Count:desc&size=20') .toPromise() .then(res => this.responseToAlbums(res)) - .catch(this.handleError); + .catch(error => this.handleError(error, 'getMostPlayedAlbumNaive')); // TODO Excluse 'Divers' + compilation } @@ -133,7 +118,7 @@ export class ElsService { */ getMostPlayedAlbum(): Observable { return this.http - .post(this.elsUrl + 'album' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.ALBUM_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'sort': [ { @@ -148,22 +133,23 @@ export class ElsService { ] }), {headers: this.headers}) .pipe( - map(res => this.responseToAlbums(res)) + map(res => this.responseToAlbums(res)), + catchError(error => this.handleError(error, 'getMostPlayedAlbum()')) ); } getMostPlayedArtistNaive(): Promise { return this.http - .get(this.elsUrl + 'artist' + ElsService.ACTION_SEARCH + '?sort=Play Count:desc&size=20') + .get(this.elsUrl + ElsService.ARTIST_INDEX_NAME + ElsService.ACTION_SEARCH + '?sort=Play Count:desc&size=20') .toPromise() .then(res => this.responseToAlbums(res)) - .catch(this.handleError); + .catch(error => this.handleError(error, 'getMostPlayedArtistNaive')); // TODO Excluse 'Divers' + compilation } getMostPlayedArtist(): Observable { return this.http - .post(this.elsUrl + 'artist' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.ARTIST_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'sort': [ { @@ -179,14 +165,15 @@ export class ElsService { 'size': 100 }), {headers: this.headers}) .pipe( - map(res => this.responseToArtists(res)) + map(res => this.responseToArtists(res)), + catchError(error => this.handleError(error, 'getMostPlayedArtist()')) ); } getAlbumSongs(albumName: string, from: number = 0): Observable { console.info('getAlbumSongs- Album name: ' + albumName + ' - from: ' + from); return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'query': { 'match_phrase': { 'Album': albumName } @@ -195,7 +182,8 @@ export class ElsService { 'from': from }), {headers: this.headers}) .pipe( - map(res => this.responseToSongs(res)) + map(res => this.responseToSongs(res)), + catchError(error => this.handleError(error, 'getAlbumSongs(' + albumName + ',' + from + ')')) ); } @@ -203,7 +191,7 @@ export class ElsService { console.info('getGenreSongs- Genre name: ' + genreName + ' - from: ' + from); // TODO Code repetition => to refactor return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'query': { 'match_phrase': { 'Genre': genreName } @@ -212,14 +200,15 @@ export class ElsService { 'from': from }), {headers: this.headers}) .pipe( - map(res => this.responseToSongs(res)) + map(res => this.responseToSongs(res)), + catchError(error => this.handleError(error, 'getAlbumSongs(' + genreName + ',' + from + ')')) ); } getArtistSongs(artistName: string, from: number = 0): Observable { console.info('getArtistSongs- Artist name: ' + artistName + ' - from: ' + from); return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'query': { 'bool': { @@ -233,13 +222,16 @@ export class ElsService { 'from': from }), {headers: this.headers}) .pipe( - map(res => this.responseToSongs(res)) + map(res => this.responseToSongs(res)), + catchError(error => this.handleError(error, 'getArtistSongs(' + artistName + ',' + from + ')')) ); } getAlbum(albumName: string): Observable { + // TODO Why this is used on album pages? + // When it's commented, the album information goes up correctly */ return this.http - .post(this.elsUrl + 'album' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.ALBUM_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'query': { 'match_phrase': { 'Album': albumName } @@ -247,13 +239,14 @@ export class ElsService { 'size': ElsService.DEFAULT_SIZE }), {headers: this.headers}) .pipe( - map(res => this.responseToOneTypedResult(res, albumName)) + map(res => this.responseToOneTypedResult(res, albumName)), + catchError(error => this.handleError(error, 'getAlbum(' + albumName + ')')) ); } getArtist(artistName: string): Observable { return this.http - .post(this.elsUrl + 'artist' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.ARTIST_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'query': { 'match_phrase': { 'Artist': artistName } @@ -261,18 +254,19 @@ export class ElsService { 'size': ElsService.DEFAULT_SIZE }), {headers: this.headers}) .pipe( - map(res => this.responseToOneTypedResult(res, artistName)) + map(res => this.responseToOneTypedResult(res, artistName)), + catchError(error => this.handleError(error, 'getArtist(' + artistName + ')')) ); } getGenres(ordering: string = 'desc'): Observable { return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'aggs' : { 'genres' : { 'terms' : { - 'field' : 'Genre.original', + 'field' : 'Genre', 'size' : 10, 'missing': 'N/A', 'order': { '_count' : ordering } @@ -282,32 +276,33 @@ export class ElsService { 'size': 0 }), {headers: this.headers}) .pipe( - map(res => this.responseAggregationToBucket(res, 'genres')) + map(res => this.responseAggregationToBucket(res, 'genres')), + catchError(error => this.handleError(error, 'getGenres(' + ordering + ')')) ); } - getGenreCount(): Observable { - return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, - JSON.stringify({ - 'aggs' : { - 'genres' : { - 'cardinality' : { - 'field' : 'Genre.original', - 'missing': 'N/A', - } - } - }, - 'size': 0 - }), {headers: this.headers}) - .pipe( - map(res => res.aggregations.genres.value) - ); - } +// getGenreCount(): Observable { +// return this.http +// .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, +// JSON.stringify({ +// 'aggs' : { +// 'genres' : { +// 'cardinality' : { +// 'field' : 'Genre.original', +// 'missing': 'N/A', +// } +// } +// }, +// 'size': 0 +// }), {headers: this.headers}) +// .pipe( +// map(res => res.aggregations.genres.value) +// ); +// } getLastAddedAlbums(month: number): Observable { return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'query': { 'range' : { @@ -328,7 +323,7 @@ export class ElsService { 'aggs': { 'album': { 'terms': { - 'field': 'Album.original' + 'field': 'Album.raw' } } } @@ -336,14 +331,15 @@ export class ElsService { } }), {headers: this.headers}) .pipe( - map(res => this.responseSubAggregationToBucket(res, 'date')) + map(res => this.responseSubAggregationToBucket(res, 'date')), + catchError(error => this.handleError(error, 'getLastAddedAlbums(' + month + ')' )) ); // TODO Take in consideration "sum_other_doc_count" } getArtistFromAlbumName(albumname: string): Observable { return this.http - .post(this.elsUrl + 'album' + ElsService.ACTION_SEARCH, + .post(this.elsUrl + ElsService.ALBUM_INDEX_NAME + ElsService.ACTION_SEARCH, JSON.stringify({ 'query': { 'match_phrase' : { @@ -360,14 +356,15 @@ export class ElsService { result.push(hit._source); }); return result; - }) + }), + catchError(error => this.handleError(error, 'getArtistFromAlbumName' + albumname + ')')) ); } getCountArtistSong(artistName: string): Observable { console.log('artistname: ' + artistName); return this.http - .post(this.elsUrl + 'song' + ElsService.ACTION_COUNT, + .post(this.elsUrl + ElsService.SONG_INDEX_NAME + ElsService.ACTION_COUNT, JSON.stringify({ 'query': { 'bool': { @@ -379,7 +376,8 @@ export class ElsService { } }), {headers: this.headers}) .pipe( - map(res => res.count as number) + map(res => res.count as number), + catchError(error => this.handleError(error, 'getCountArtistSong' + artistName + ')')) ); } @@ -464,8 +462,11 @@ export class ElsService { return result; } - private handleError(error: any): Promise { - console.error('An error occurred', error); // for demo purposes only + private handleError(error: any, origin: string): Promise { + console.error('An error occurred!'); + console.error('Origin function: ', origin); + console.error('An error occurred!', error); // for demo purposes only + console.error(error); // for demo purposes only return Promise.reject(error.message || error); } }