(front) Fix ELS services for multiple indexes

Remove or comment unused methods
Better handle of errors
This commit is contained in:
2020-04-12 01:45:25 +02:00
parent 0c8a17febe
commit fac3629d14
2 changed files with 87 additions and 85 deletions

View File

@@ -39,12 +39,13 @@ export class DashboardComponent implements OnInit {
this.elsService.getSize().then(result => this.totalSize = result); this.elsService.getSize().then(result => this.totalSize = result);
this.elsService.getCountSong('song') this.elsService.getCountSong(ElsService.SONG_INDEX_NAME)
.then(result => this.trackCountSong = result); .then(result => this.trackCountSong = result);
this.elsService.getCountSong('artist') // TODO: Unused information
.then(result => this.trackCountArtist = result); // this.elsService.getCountSong(ElsService.ARTIST_INDEX_NAME)
this.elsService.getCountSong('album') // .then(result => this.trackCountArtist = result);
.then(result => this.trackCountAlbum = result); // this.elsService.getCountSong(ElsService.ALBUM_INDEX_NAME)
// .then(result => this.trackCountAlbum = result);
this.elsService.getCountNeverListenSong() this.elsService.getCountNeverListenSong()
.then(result => this.neverListenSong = result); .then(result => this.neverListenSong = result);

View File

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