import _ from 'lodash' ; import moment from 'moment' ; import log from '../util/Logger' ; import NI from '../util/NetworkInterface' ; import * as queries from '../scripts/tournamentQueries' ; import { ITournament , ITournamentData , ITournamentDataFull , ITournamentEventData , ITournamentPhaseData , ITournamentPhaseGroupData , ITournamentAttendeeData } from '../interfaces/ITournament' ; import { IVenue } from '../interfaces/IVenue' ; import { IOrganizer } from '../interfaces/IOrganizer' ; import { IEvent } from '../interfaces/IEvent' ; import { IPhase } from '../interfaces/IPhase' ; import { IPhaseGroup } from '../interfaces/IPhaseGroup' ; import { IGGSet , IGGSetOptions } from '../interfaces/IGGSet' ; import { IEntrant , IEntrantOptions } from '../interfaces/IEntrant' ; import { IAttendee , IAttendeeOptions , IAttendeeData , IAttendeePaginatedData } from '../interfaces/IAttendee' ; import { Venue } from './Venue' ; import { Organizer } from './Organizer' ; import { Event } from './Event' ; import { Phase } from './Phase' ; import { PhaseGroup } from './PhaseGroup' ; import { User } from './User' ; import { Entrant } from './Entrant' ; import { Attendee } from './Attendee' ; import { GGSet } from './GGSet' ; export class Tournament implements ITournament { public static parse ( data ) { const startTimeDate = data . startAt ? moment . unix ( data . startAt ! ) . toDate ( ) : null ; const endTimeDate = data . endAt ? moment . unix ( data . endAt ! ) . toDate ( ) : null ; const venue = new Venue ( data . venueName , data . venueAddress , data . city , data . addrState , data . countryCode , data . region , data . postalCode , data . lat , data . lng ) ; const organizer = new Organizer ( data . ownerId , data . contactEmail , data . contactPhone , data . contactTwitter , data . contactInfo ) ; return new Tournament ( data . id , data . name , data . slug , startTimeDate , endTimeDate , data . timezone , venue , organizer ) ; } public static parseFull ( data ) { return Tournament . parse ( data . tournament ) ; } public static async getById ( theId ) { log . info ( 'Getting Tournament with id %s' , theId ) ; const data = await NI . query ( queries . tournament , { id : theId } ) ; return Tournament . parseFull ( data ) ; } public static async get ( theSlug ) { log . info ( 'Getting Tournament with slug "%s"' , theSlug ) ; const data = await NI . query ( queries . tournamentBySlug , { slug : theSlug } ) ; return Tournament . parseFull ( data ) ; } private id : number ; private name : string ; private slug : string ; private startTime : Date | null ; private endTime : Date | null ; private timezone : string | null ; private venue : IVenue ; private organizer : IOrganizer ; constructor ( id , name , slug , startTime , endTime , timezone , venue , organizer ) { this . id = id ; this . name = name ; this . slug = slug ; this . startTime = startTime ; this . endTime = endTime ; this . timezone = timezone ; this . venue = venue ; this . organizer = organizer ; } public getId ( ) { return this . id ; } public getName ( ) { return this . name ; } public getSlug ( ) { return this . slug ; } public getTimezone ( ) { return this . timezone ; } public getStartTime ( ) { return this . startTime ; } public getStartTimeString ( ) { return String ( this . startTime ) ; } public getEndTime ( ) { return this . endTime ; } public getEndTimeString ( ) { return String ( this . endTime ) ; } public getVenue ( ) { return this . venue ; } public getVenueName ( ) { return this . venue . getName ( ) ; } public getCity ( ) { return this . venue . getCity ( ) ; } public getState ( ) { return this . venue . getState ( ) ; } public getAddress ( ) { return this . venue . getAddress ( ) ; } public getZipCode ( ) { return this . venue . getPostalCode ( ) ; } public getOrganizer ( ) { return this . organizer ; } public getContactInfo ( ) { return this . organizer . getInfo ( ) ; } public getContactEmail ( ) { return this . organizer . getEmail ( ) ; } public getContactTwitter ( ) { return this . organizer . getTwitter ( ) ; } public getOwnerId ( ) { return this . organizer . getId ( ) ; } public async getEvents ( ) { log . info ( 'Getting Events for Tournament [%s :: %s]' , this . id , this . name ) ; const data = await NI . query ( queries . tournamentEvents , { id : this . id } ) ; const events = data . tournament . events . map ( event => Event . parse ( event ) ) ; return events ; } public async getPhases ( ) { log . info ( 'Getting Phases for Tournament [%s :: %s]' , this . id , this . name ) ; const data = await NI . query ( queries . tournamentPhases , { id : this . id } ) ; const events = data . tournament . events ; const phases = _ . flatten ( events . map ( event => event . phases . map ( phase => Phase . parse ( phase , event . id ) ) ) ) ; return phases ; } public async getPhaseGroups ( ) { log . info ( 'Getting Phase Groups for Tournament [%s :: %s]' , this . id , this . name ) ; const data = await NI . query ( queries . tournamentPhaseGroups , { id : this . id } ) ; const events = data . tournament . events ; const phaseGroups = _ . flatten ( events . map ( event => event . phaseGroups . map ( group => PhaseGroup . parse ( group ) ) ) ) ; return phaseGroups ; } public async getSets ( options = GGSet . getDefaultSetOptions ( ) ) { log . info ( 'Getting Sets for Tournament [%s :: %s]' , this . id , this . name ) ; log . warn ( 'Puilling Sets for large or massive Tournaments may ' + 'lead to long execution times and lowered usability. It ' + 'is recommended to pull from Event if you are targetting ' + 'a single event\'s Sets' ) ; const pgs = await this . getPhaseGroups ( ) ; const sets = await NI . clusterQuery ( pgs , 'getSets' , options ) ; return _ . uniqBy ( _ . flatten ( sets ) , 'id' ) ; } public async getEntrants ( options = Entrant . getDefaultEntrantOptions ( ) ) { log . info ( 'Getting Entrants for Tournament [%s :: %s]' , this . id , this . name ) ; log . warn ( 'Puilling Entrants for large or massive Tournaments may ' + 'lead to long execution times and lowered usability. It is ' + 'recommended to pull from Event if you are targetting a ' + 'single event\'s Entrants' ) ; const pgs = await this . getPhaseGroups ( ) ; let entrants = await NI . clusterQuery ( pgs , 'getEntrants' , options ) ; entrants = _ . uniq ( entrants ) ; return _ . uniqBy ( _ . flatten ( entrants ) , 'id' ) ; } public async getAttendees2 ( options = Attendee . getDefaultAttendeeOptions ( ) ) { log . info ( 'Getting Attendees for Tournament [%s :: %s]' , this . id , this . name ) ; log . warn ( 'Puilling Attendees for large or massive Tournaments may ' + 'lead to long execution times and lowered usability. It is ' + 'recommended to pull from Event if you are targetting a ' + 'single event\'s Attendees' ) ; if ( options . page != null ) return await this . getAttendees ( options ) ; const pgs = await this . getPhaseGroups ( ) ; let attendees = await NI . clusterQuery ( pgs , 'getAttendees' , options ) ; attendees = _ . uniqWith ( attendees , ( a1 , a2 ) => Attendee . eq ( a1 , a2 ) ) ; return _ . uniqBy ( _ . flatten ( attendees ) , 'id' ) ; } public async searchAttendees ( theSmashtag ) { log . info ( 'Searching Tournament [%s :: %s] with smashtag: %s' , this . id , this . name , theSmashtag ) ; const results = await NI . query ( queries . tournamentAttendeeSearch , { id : this . id , smashtag : theSmashtag } ) ; try { const nodes = results . tournament . participants . nodes ; if ( nodes . length === 0 ) return null ; const matchingAttendees = nodes . map ( ( element ) => Attendee . parse ( element ) ) ; return _ . uniqBy ( matchingAttendees , 'id' ) ; } catch { return null ; } } public async searchAttendeesBySponsorTag ( sponsorTag ) { log . info ( 'Searching Tournament [%s :: %s] with smashtag: %s' , this . id , this . name , sponsorTag ) ; const results = await NI . query ( queries . tournamentAttendeeSearchByPrefix , { id : this . id , sponsor : sponsorTag . toLowerCase ( ) } ) ; try { const nodes = results . tournament . participants . nodes ; if ( nodes . length === 0 ) return null ; const matchingAttendees = nodes . map ( ( element ) => Attendee . parse ( element ) ) ; return _ . uniqBy ( matchingAttendees , 'id' ) ; } catch { return null ; } } public async getAttendees ( options = Attendee . getDefaultAttendeeOptions ( ) ) { const data = await NI . paginatedQuery ( `Tournament Attendee [${ this . id } :: ${ this . name }]` , queries . tournamentAttendees , { id : this . id } , options , { } , 3 ) ; const tournaments = _ . flatten ( data . map ( d => d . tournament ) ) ; const attendeeData = _ . flatten ( tournaments . map ( tournament => tournament . participants ) ) ; const attendees = _ . flatten ( attendeeData . map ( aData => aData . nodes . map ( attendee => Attendee . parse ( attendee ) ) ) ) ; return _ . uniqBy ( attendees , 'id' ) ; } }