wanjingy.github.io / hw8 / backend / server.js
server.js
Raw
const { default: axios } = require('axios');
const { response } = require('express');
const express = require('express');
const geohash = require('ngeohash');
var SpotifyWebApi = require('spotify-web-api-node');
const port = process.env.PORT || 8080;
const ticketmasterKey = 'qkbDvyaw0KZXm7BZ6hEHAFS6rXVlAlaI';
const categoryMap = {
    music: 'KZFzniwnSyZfZ7v7nJ',
    sports: 'KZFzniwnSyZfZ7v7nE',
    arts_theatre: 'KZFzniwnSyZfZ7v7na',
    film: 'KZFzniwnSyZfZ7v7nn',
    miscellaneous: 'KZFzniwnSyZfZ7v7n1'
}

var spotifyApi = new SpotifyWebApi(
    {
        clientId: '25bfc767fb414d5ab4bb496e0b3c2fad',
        clientSecret: '589108ca59d14670bfcf2acee2d59168',
        redirectUri: 'https://event-search-ywj.wl.r.appspot.com/'
    }
);


var app = express();
app.use(express.static("./dist/event-search"));

app.listen(port, function () {
    console.log("Backend Application listening on port: " + port);
})

app.get('/', function (req, res) {
    res.send('Event Search Node.js Backend');
})

app.get('/autofill/:keyword', function (req, res) {
    const autoFillUrl = 'https://app.ticketmaster.com/discovery/v2/suggest';
    axios.get(autoFillUrl, {
        params: {
            apikey: ticketmasterKey,
            keyword: req.params.keyword
        }
    }).then(response => {
        var result = [];
        if (response.data._embedded != null && response.data._embedded.attractions != null) {
            for (var attraction of response.data._embedded.attractions) {
                result.push(attraction.name);
            }
        }
        res.json(result);
    }).catch(error => {
        console.log(error);
    })
})

app.get('/events', function (req, res) {
    console.log(req.query);
    const eventsUrl = 'https://app.ticketmaster.com/discovery/v2/events.json';
    var par = {
        apikey: ticketmasterKey,
        keyword: req.query.keyword,
        radius: req.query.distance,
        unit: 'miles'
    }
    if (req.query.category != 'default') {
        par.segmentId = categoryMap[req.query.category];
    }
    par.geoPoint = geohash.encode(req.query.lat, req.query.lng, 5);
    console.log(par);
    axios.get(eventsUrl, {
        params: par
    }).then(response => {
        var result = [];
        if (response.data._embedded != undefined) {
            const events = response.data._embedded.events;
            for (var event of events) {
                var processedEvent = {};
                processedEvent.name = event.name;
                processedEvent.id = event.id;
                processedEvent.iconUrl = '';
                if (typeof event.images !== 'undefined') {
                    for (var img of event.images) {
                        if (img.ratio == '4_3') {
                            processedEvent.iconUrl = img.url;
                            break;
                        }
                    }
                    if (processedEvent.iconUrl == '') {
                        processedEvent.iconUrl = event.images[0].url;
                    }
                }
                processedEvent.date = '';
                processedEvent.time = '';
                if (typeof event.dates !== 'undefined' && typeof event.dates.start !== 'undefined') {
                    const eventDate = event.dates.start;
                    if (eventDate.dateTBA) {
                        processedEvent.date = 'TBA';
                    } else if (eventDate.dateTBD) {
                        processedEvent.date = 'TBD';
                    } else if (typeof eventDate.localDate !== 'undefined') {
                        processedEvent.date = eventDate.localDate;
                    }
                    if (eventDate.timeTBA) {
                        processedEvent.time = 'TBA';
                    } else if (eventDate.noSpecificTime) {
                        processedEvent.time = 'No Specific Time'
                    } else if (typeof eventDate.localTime !== 'undefined') {
                        processedEvent.time = eventDate.localTime;
                    }
                }
                processedEvent.genre = '';
                if (typeof event.classifications !== 'undefined' && event.classifications.length >= 1) {
                    const segmentName = event.classifications[0].segment.name
                    processedEvent.genre = segmentName != 'Undefined' ? segmentName : '';
                }
                processedEvent.venue = '';
                if (typeof event._embedded !== 'undefined' && typeof event._embedded.venues !== 'undefined' && event._embedded.venues.length >= 1) {
                    processedEvent.venue = event._embedded.venues[0].name;
                }
                result.push(processedEvent);
            }
        }
        res.json(result);

    }).catch(error => {
        console.log(error);
    })
})

app.get('/eventDetail/:id', function (req, res) {
    const eventDetailurl = 'https://app.ticketmaster.com/discovery/v2/events/' + req.params.id;
    axios.get(eventDetailurl, {
        params: {
            apikey: ticketmasterKey
        }
    }).then(response => {
        var result = {};
        result.id = response.data.id;
        result.name = response.data.name;
        result.url = '';
        if (typeof response.data.url !== 'undefined') {
            result.url = response.data.url;
        }
        result.date = '';
        result.time = '';
        if (typeof response.data.dates !== 'undefined' && typeof response.data.dates.start !== 'undefined') {
            const eventDate = response.data.dates.start;
            if (eventDate.dateTBA) {
                result.date = 'TBA';
            } else if (eventDate.dateTBD) {
                result.date = 'TBD';
            } else if (typeof eventDate.localDate !== 'undefined') {
                result.date = eventDate.localDate;
            }
            if (eventDate.timeTBA) {
                result.time = 'TBA';
            } else if (eventDate.noSpecificTime) {
                result.time = 'No Specific Time'
            } else if (typeof eventDate.localTime !== 'undefined') {
                result.time = eventDate.localTime;
            }
        }
        result.artistTeams = [];
        result.musicArtists = [];
        if (typeof response.data._embedded !== 'undefined' && typeof response.data._embedded.attractions !== 'undefined' && response.data._embedded.attractions.length >= 1) {
            const attractions = response.data._embedded.attractions;
            for (var attraction of attractions) {
                result.artistTeams.push(attraction.name);
                if (typeof attraction.classifications !== 'undefined' && attraction.classifications.length >= 1 && typeof attraction.classifications[0].segment !== 'undefined' && typeof attraction.classifications[0].segment.name !== 'undefined') {
                    if (attraction.classifications[0].segment.name == 'Music') {
                        result.musicArtists.push(attraction.name);
                    }
                }
            }
        }
        result.venue = '';
        if (typeof response.data._embedded !== 'undefined' && typeof response.data._embedded.venues !== 'undefined' && response.data._embedded.venues.length >= 1) {
            result.venue = response.data._embedded.venues[0].name;
        }
        result.genres = [];
        if (typeof response.data.classifications !== 'undefined' && response.data.classifications.length >= 1) {
            const classification = response.data.classifications[0];
            if (typeof classification.segment !== 'undefined' && classification.segment.name != 'Undefined') {
                result.genres.push(classification.segment.name);
            }
            if (typeof classification.genre !== 'undefined' && classification.genre.name != 'Undefined') {
                result.genres.push(classification.genre.name);
            }
            if (typeof classification.subGenre !== 'undefined' && classification.subGenre.name != 'Undefined') {
                result.genres.push(classification.subGenre.name);
            }
            if (typeof classification.type !== 'undefined' && classification.type.name != 'Undefined') {
                result.genres.push(classification.type.name);
            }
            if (typeof classification.subType !== 'undefined' && classification.subType.name != 'Undefined') {
                result.genres.push(classification.subType.name);
            }
        }
        result.priceRanges = '';
        if (typeof response.data.priceRanges !== 'undefined' && response.data.priceRanges.length >= 1) {
            const price = response.data.priceRanges[0];
            if (typeof price.min !== 'undefined') {
                result.priceRanges += price.min;
            }
            if (typeof price.max !== 'undefined') {
                if (result.priceRanges.length > 0) {
                    result.priceRanges += '-';
                }
                result.priceRanges += price.max;
            }
        }
        result.ticketStatus = '';
        if (typeof response.data.dates !== 'undefined' && typeof response.data.dates.status !== 'undefined') {
            result.ticketStatus = response.data.dates.status.code;
        }
        result.seatMapUrl = '';
        if (typeof response.data.seatmap !== 'undefined' && typeof response.data.seatmap.staticUrl !== 'undefined') {
            result.seatMapUrl = response.data.seatmap.staticUrl;
        }
        res.json(result);
    })
})

app.get('/venue/:venue', function (req, res) {
    const venueUrl = 'https://app.ticketmaster.com/discovery/v2/venues.json';
    axios.get(venueUrl, {
        params: {
            keyword: req.params.venue.replace('.', ' '),
            apikey: ticketmasterKey
        }
    }).then(response => {
        var result = {};
        if (typeof response.data._embedded !== 'undefined' && typeof response.data._embedded.venues !== 'undefined' && response.data._embedded.venues.length >= 1) {
            const venue = response.data._embedded.venues[0];
            result.name = venue.name;
            result.address = '';
            if (typeof venue.address !== 'undefined' && typeof venue.address.line1 !== 'undefined') {
                result.address += (venue.address.line1 + ', ');
            }
            if (typeof venue.city !== 'undefined' && typeof venue.city.name !== 'undefined') {
                result.address += (venue.city.name + ', ');
            }
            if (typeof venue.state !== 'undefined' && typeof venue.state.name !== 'undefined') {
                result.address += (venue.state.name);
            }
            if (result.address.endsWith(', ')) {
                result.address = result.address.substring(0, result.address.length - 2);
            }
            result.phoneNumber = '';
            result.openHours = '';
            if (typeof venue.boxOfficeInfo !== 'undefined') {
                if (typeof venue.boxOfficeInfo.phoneNumberDetail !== 'undefined') {
                    result.phoneNumber = venue.boxOfficeInfo.phoneNumberDetail;
                }
                if (typeof venue.boxOfficeInfo.openHoursDetail !== 'undefined') {
                    result.openHours = venue.boxOfficeInfo.openHoursDetail;
                }
            }
            result.generalRule = '';
            result.childRule = '';
            if (typeof venue.generalInfo !== 'undefined') {
                if (typeof venue.generalInfo.generalRule !== 'undefined') {
                    result.generalRule = venue.generalInfo.generalRule;
                }
                if (typeof venue.generalInfo.childRule !== 'undefined') {
                    result.childRule = venue.generalInfo.childRule;
                }
            }
        }
        res.json(result);
    })
})

app.get('/artist/:artist', function (req, res) {
    const artistName = req.params.artist;
    spotifyApi.searchArtists(artistName, {limit: 1})
        .then(
            function (data) {
                console.log('Successfully search artist '+artistName);
                getArtistDetail(data.body, res);
            },
            function (err) {
                console.log('Fail to search artist '+artistName, err.body);
                if (err.body.error.status == '401') {
                    spotifyApi.clientCredentialsGrant().then(
                        function (data) {
                            console.log(data.body);
                            spotifyApi.setAccessToken(data.body.access_token);
                            spotifyApi.searchArtists(artistName, {limit: 1}).then(
                                function(data) {
                                    console.log('Successfully search artist '+artistName);
                                    getArtistDetail(data.body, res);
                                },
                                function(err){
                                    console.log('Fail to search artist '+artistName, err.body);
                                    res.json({});
                                }
                            )
                        },
                        function(err){
                            console.log('Something went wrong when retrieving an access token', err.body);
                            res.json({});
                        }
                    )
                }
            });
})

function getArtistDetail(data, res){
    var detail = {};
    if(typeof data.artists !== 'undefined' && typeof data.artists.items !== 'undefined' && data.artists.items.length >= 1){
        const artist = data.artists.items[0];
        detail.name = artist.name;
        detail.popularity = -1;
        if(typeof artist.popularity !== 'undefined'){
            detail.popularity = artist.popularity;
        }
        detail.followers = -1;
        if(typeof artist.followers !== 'undefined' && typeof artist.followers.total !== 'undefined'){
            detail.followers = artist.followers.total;
        }
        detail.link = '';
        if(typeof artist.external_urls !== 'undefined' && typeof artist.external_urls.spotify !== 'undefined'){
            detail.link = artist.external_urls.spotify;
        }
        detail.artistImgUrl = '';
        if(typeof artist.images !== 'undefined' && artist.images.length >= 1){
            detail.artistImgUrl = artist.images[0].url;
        }
        detail.albumsImgsUrls = [];
        spotifyApi.getArtistAlbums(artist.id, {limit: 3}).then(
            function(data){
                console.log('Successfully get albums of ' + artist.name);
                detail.albumsImgsUrls = getAlbums(data.body)
                res.json(detail);
            },
            function(err){
                console.log('Fail to get albums of ' + artist.name, err);
                if(err.body.error.status == '401'){
                    spotifyApi.clientCredentialsGrant().then(
                        function (data) {
                            console.log(data.body);
                            spotifyApi.setAccessToken(data.body.access_token);
                            spotifyApi.getArtistAlbums(artist.id, {limit: 3}).then(
                                function(data) {
                                    console.log('Successfully get albums of ' + artist.name);
                                    detail.albumsImgsUrls = getAlbums(data.body)
                                    res.json(detail);
                                },
                                function(err){
                                    console.log('Fail to get albums of ' + artist.name, err.body);
                                    res.json(detail);
                                }
                            )
                        },
                        function(err){
                            console.log('Something went wrong when retrieving an access token', err.body);
                            res.json(detail);
                        }
                    )
                }
            }
        )
    }
}

function getAlbums(data){
    var albums = [];
    if(typeof data.items !== 'undefined' && data.items.length >= 1){
        for(var album of data.items){
            if(typeof album.images !== 'undefined' && album.images.length >= 1){
                albums.push(album.images[0].url);
            }
        }
    }
    return albums;
}