🎨 Improve code readability by reformatting and updating function definitions and comments
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const readline = require('readline');
|
||||
|
||||
function logAction(action) {
|
||||
console.log(`[ACTION]: ${action}`);
|
||||
}
|
||||
|
||||
async function parseAndAddEmails(inputFilePath) {
|
||||
logAction('Starting to process the CSV file.');
|
||||
|
||||
const outputFilePath = inputFilePath.replace('.csv', '-with-emails.csv');
|
||||
const readStream = fs.createReadStream(inputFilePath);
|
||||
const writeStream = fs.createWriteStream(outputFilePath);
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: readStream,
|
||||
crlfDelay: Infinity
|
||||
});
|
||||
|
||||
let isHeader = true;
|
||||
|
||||
for await (const line of rl) {
|
||||
const columns = line.split(',');
|
||||
if (isHeader) {
|
||||
logAction('Processing header row.');
|
||||
writeStream.write(
|
||||
`${columns.slice(0, 6).join(',')},email,${columns[6]}\n`
|
||||
);
|
||||
isHeader = false;
|
||||
} else {
|
||||
logAction('Processing a data row.');
|
||||
const screenname = columns[5];
|
||||
const email = `${screenname}@example.com`;
|
||||
writeStream.write(
|
||||
`${columns.slice(0, 6).join(',')},${email},${columns[6]}\n`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
logAction('Finished processing the CSV file.');
|
||||
writeStream.end();
|
||||
logAction(`Output written to ${outputFilePath}`);
|
||||
}
|
||||
|
||||
// Example usage
|
||||
const inputFilePath =
|
||||
'/Users/fragginwagon/Developer/Source Code/discord/GODispute/docsNrefs/registrations/20250504-MK03mHVg2MthNoBwub5w-registrations.csv';
|
||||
parseAndAddEmails(inputFilePath).catch(err =>
|
||||
console.error(`[ERROR]: ${err.message}`)
|
||||
);
|
||||
@@ -0,0 +1,883 @@
|
||||
const axios = require('axios');
|
||||
const { CHALLONGE_API_BASE_URL } = require('../constants');
|
||||
const { challongeApiKey } = require('../../config');
|
||||
|
||||
let challongeApi = axios.create({
|
||||
baseURL: CHALLONGE_API_BASE_URL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json'
|
||||
},
|
||||
params: {
|
||||
api_key: challongeApiKey
|
||||
}
|
||||
});
|
||||
|
||||
const handleError = error => {
|
||||
return Promise.reject({ 'Challonge API Error': error });
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a list of tournaments created with your account.
|
||||
*
|
||||
* @param {Object} params - Query parameters for filtering tournaments.
|
||||
* @param {string} [params.state] - Filter by state (all, pending, in_progress, ended).
|
||||
* @param {string} [params.type] - Filter by type (single_elimination, double_elimination, round_robin, swiss).
|
||||
* @param {string} [params.created_after] - Filter by creation date after (YYYY-MM-DD).
|
||||
* @param {string} [params.created_before] - Filter by creation date before (YYYY-MM-DD).
|
||||
* @param {string} [params.subdomain] - Filter by subdomain (organization-hosted tournaments).
|
||||
* @returns {Promise<Object>} - A promise resolving to the list of tournaments.
|
||||
*/
|
||||
const listTournaments = async (params = {}) => {
|
||||
try {
|
||||
const url = '/tournaments';
|
||||
challongeApi.defaults.params = {
|
||||
...challongeApi.defaults.params,
|
||||
...params
|
||||
};
|
||||
const response = await challongeApi.get(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new tournament.
|
||||
*
|
||||
* @param {Object} data - The tournament data.
|
||||
* @param {string} data.name - Your event's name/title (Max: 60 characters) (required).
|
||||
* @param {string} [data.tournament_type] - Single elimination (default), double elimination, round robin, swiss.
|
||||
* @param {string} [data.url] - Custom URL (letters, numbers, and underscores only).
|
||||
* @param {string} [data.subdomain] - Subdomain for the tournament.
|
||||
* @param {string} [data.description] - Description/instructions to be displayed above the bracket.
|
||||
* @param {boolean} [data.open_signup] - True or false. Host a sign-up page.
|
||||
* @param {boolean} [data.hold_third_place_match] - True or false. Include a match between semifinal losers.
|
||||
* @param {number} [data.pts_for_match_win] - Points for match win (Swiss only).
|
||||
* @param {number} [data.pts_for_match_tie] - Points for match tie (Swiss only).
|
||||
* @param {number} [data.pts_for_game_win] - Points for game win (Swiss only).
|
||||
* @param {number} [data.pts_for_game_tie] - Points for game tie (Swiss only).
|
||||
* @param {number} [data.pts_for_bye] - Points for bye (Swiss only).
|
||||
* @param {number} [data.swiss_rounds] - Number of Swiss rounds.
|
||||
* @param {string} [data.ranked_by] - Ranking method ('match wins', 'game wins', 'points scored', etc.).
|
||||
* @param {number} [data.rr_pts_for_match_win] - Round Robin points for match win (custom only).
|
||||
* @param {number} [data.rr_pts_for_match_tie] - Round Robin points for match tie (custom only).
|
||||
* @param {number} [data.rr_pts_for_game_win] - Round Robin points for game win (custom only).
|
||||
* @param {number} [data.rr_pts_for_game_tie] - Round Robin points for game tie (custom only).
|
||||
* @param {boolean} [data.accept_attachments] - Allow match attachment uploads.
|
||||
* @param {boolean} [data.hide_forum] - Hide the forum tab on the Challonge page.
|
||||
* @param {boolean} [data.show_rounds] - Label each round above the bracket.
|
||||
* @param {boolean} [data.private] - Hide this tournament from the public index.
|
||||
* @param {boolean} [data.notify_users_when_matches_open] - Notify participants when matches open.
|
||||
* @param {boolean} [data.notify_users_when_the_tournament_ends] - Notify participants when the tournament ends.
|
||||
* @param {boolean} [data.sequential_pairings] - Use sequential pairings instead of traditional seeding rules.
|
||||
* @param {number} [data.signup_cap] - Maximum number of participants.
|
||||
* @param {string} [data.start_at] - Planned start time for the tournament (ISO 8601 format).
|
||||
* @param {number} [data.check_in_duration] - Length of the check-in window in minutes.
|
||||
* @param {string} [data.grand_finals_modifier] - Grand finals modifier ('single match', 'skip', or null).
|
||||
*
|
||||
* @returns {Promise<Object>} - A promise resolving to the created tournament data.
|
||||
*/
|
||||
const createTournament = async data => {
|
||||
try {
|
||||
const url = '/tournaments';
|
||||
const response = await challongeApi.post(url, { tournament: data });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a single tournament record created with your account.
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {string} [options.apiKey] - Your API key (required unless using HTTP basic authentication).
|
||||
* @param {boolean} [options.includeParticipants=false] - Whether to include an array of associated participant records.
|
||||
* @param {boolean} [options.includeMatches=false] - Whether to include an array of associated match records.
|
||||
* @returns {Promise<Object>} A promise that resolves to the tournament data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const getTournament = async (id, options = {}) => {
|
||||
// GET: Retrieve a single tournament record created with your account
|
||||
try {
|
||||
const url = `/tournaments/${id}`;
|
||||
const response = await challongeApi.get(url, {
|
||||
params: {
|
||||
include_participants: options?.includeParticipants || false,
|
||||
include_matches: options?.includeMatches || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates a tournament's attributes.
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} data - The tournament data to update.
|
||||
* @param {string} [data.name] - Your event's name/title (Max: 60 characters).
|
||||
* @param {string} [data.tournament_type] - Single elimination (default), double elimination, round robin, swiss.
|
||||
* @param {string} [data.url] - Custom URL (letters, numbers, and underscores only).
|
||||
* @param {string} [data.subdomain] - Subdomain for the tournament.
|
||||
* @param {string} [data.description] - Description/instructions to be displayed above the bracket.
|
||||
* @param {boolean} [data.open_signup] - True or false. Host a sign-up page.
|
||||
* @param {boolean} [data.hold_third_place_match] - True or false. Include a match between semifinal losers.
|
||||
* @param {number} [data.pts_for_match_win] - Points for match win (Swiss only).
|
||||
* @param {number} [data.pts_for_match_tie] - Points for match tie (Swiss only).
|
||||
* @param {number} [data.pts_for_game_win] - Points for game win (Swiss only).
|
||||
* @param {number} [data.pts_for_game_tie] - Points for game tie (Swiss only).
|
||||
* @param {number} [data.pts_for_bye] - Points for bye (Swiss only).
|
||||
* @param {number} [data.swiss_rounds] - Number of Swiss rounds.
|
||||
* @param {string} [data.ranked_by] - Ranking method ('match wins', 'game wins', 'points scored', etc.).
|
||||
* @param {number} [data.rr_pts_for_match_win] - Round Robin points for match win (custom only).
|
||||
* @param {number} [data.rr_pts_for_match_tie] - Round Robin points for match tie (custom only).
|
||||
* @param {number} [data.rr_pts_for_game_win] - Round Robin points for game win (custom only).
|
||||
* @param {number} [data.rr_pts_for_game_tie] - Round Robin points for game tie (custom only).
|
||||
* @param {boolean} [data.accept_attachments] - Allow match attachment uploads.
|
||||
* @param {boolean} [data.hide_forum] - Hide the forum tab on the Challonge page.
|
||||
* @param {boolean} [data.show_rounds] - Label each round above the bracket.
|
||||
* @param {boolean} [data.private] - Hide this tournament from the public index.
|
||||
* @param {boolean} [data.notify_users_when_matches_open] - Notify participants when matches open.
|
||||
* @param {boolean} [data.notify_users_when_the_tournament_ends] - Notify participants when the tournament ends.
|
||||
* @param {boolean} [data.sequential_pairings] - Use sequential pairings instead of traditional seeding rules.
|
||||
* @param {number} [data.signup_cap] - Maximum number of participants.
|
||||
* @param {string} [data.start_at] - Planned start time for the tournament (ISO 8601 format).
|
||||
* @param {number} [data.check_in_duration] - Length of the check-in window in minutes.
|
||||
* @param {string} [data.grand_finals_modifier] - Grand finals modifier ('single match', 'skip', or null).
|
||||
*
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated tournament data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const updateTournament = async (id, data) => {
|
||||
try {
|
||||
const url = `/tournaments/${id}`;
|
||||
const response = await challongeApi.put(url, { tournament: data });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a tournament along with all its associated records.
|
||||
* There is no undo, so use with care!
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @returns {Promise<Object>} - A promise resolving to the response data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const deleteTournament = async id => {
|
||||
try {
|
||||
const url = `/tournaments/${id}`;
|
||||
const response = await challongeApi.delete(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Processes check-in results for a tournament.
|
||||
* This should be invoked after a tournament's check-in window closes and before the tournament is started.
|
||||
*
|
||||
* Marks participants who have not checked in as inactive.
|
||||
* Moves inactive participants to bottom seeds (ordered by original seed).
|
||||
* Transitions the tournament state from 'checking_in' to 'checked_in'.
|
||||
* NOTE: Checked-in participants on the waiting list will be promoted if slots become available.
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {boolean} [options.includeParticipants=false] - Whether to include an array of associated participant records.
|
||||
* @param {boolean} [options.includeMatches=false] - Whether to include an array of associated match records.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated tournament data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const processCheckIns = async (id, options = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${id}/process_check_ins`;
|
||||
const response = await challongeApi.post(url, null, {
|
||||
params: {
|
||||
include_participants: options.includeParticipants || false,
|
||||
include_matches: options.includeMatches || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Aborts check-in for a tournament.
|
||||
* Makes all participants active and clears their checked_in_at times.
|
||||
* Transitions the tournament state from 'checking_in' or 'checked_in' to 'pending'.
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {boolean} [options.includeParticipants=false] - Whether to include an array of associated participant records.
|
||||
* @param {boolean} [options.includeMatches=false] - Whether to include an array of associated match records.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated tournament data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const abortCheckIn = async (id, options = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${id}/abort_check_in`;
|
||||
const response = await challongeApi.post(url, null, {
|
||||
params: {
|
||||
include_participants: options.includeParticipants || false,
|
||||
include_matches: options.includeMatches || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts a tournament, opening up first-round matches for score reporting.
|
||||
* The tournament must have at least 2 participants.
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {boolean} [options.includeParticipants=false] - Whether to include an array of associated participant records.
|
||||
* @param {boolean} [options.includeMatches=false] - Whether to include an array of associated match records.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated tournament data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const startTournament = async (id, options = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${id}/start`;
|
||||
const response = await challongeApi.post(url, null, {
|
||||
params: {
|
||||
include_participants: options.includeParticipants || false,
|
||||
include_matches: options.includeMatches || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalizes a tournament that has had all match scores submitted, rendering its results permanent.
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {boolean} [options.includeParticipants=false] - Whether to include an array of associated participant records.
|
||||
* @param {boolean} [options.includeMatches=false] - Whether to include an array of associated match records.
|
||||
* @returns {Promise<Object>} - A promise resolving to the finalized tournament data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const finalizeTournament = async (id, options = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${id}/finalize`;
|
||||
const response = await challongeApi.post(url, null, {
|
||||
params: {
|
||||
include_participants: options.includeParticipants || false,
|
||||
include_matches: options.includeMatches || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets a tournament, clearing all of its scores and attachments.
|
||||
* This allows you to add, remove, or edit participants before starting the tournament again.
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {boolean} [options.includeParticipants=false] - Whether to include an array of associated participant records.
|
||||
* @param {boolean} [options.includeMatches=false] - Whether to include an array of associated match records.
|
||||
* @returns {Promise<Object>} - A promise resolving to the reset tournament data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const resetTournament = async (id, options = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${id}/reset`;
|
||||
const response = await challongeApi.post(url, null, {
|
||||
params: {
|
||||
include_participants: options.includeParticipants || false,
|
||||
include_matches: options.includeMatches || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens a tournament for predictions.
|
||||
* Sets the state of the tournament to start accepting predictions.
|
||||
* Your tournament's 'prediction_method' attribute must be set to 1 (exponential scoring)
|
||||
* or 2 (linear scoring) to use this option.
|
||||
* Note: Once open for predictions, match records will be persisted, so participant additions
|
||||
* and removals will no longer be permitted.
|
||||
*
|
||||
* @param {string} id - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {boolean} [options.includeParticipants=false] - Whether to include an array of associated participant records.
|
||||
* @param {boolean} [options.includeMatches=false] - Whether to include an array of associated match records.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated tournament data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const openForPredictions = async (id, options = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${id}/open_for_predictions`;
|
||||
const response = await challongeApi.post(url, null, {
|
||||
params: {
|
||||
include_participants: options.includeParticipants || false,
|
||||
include_matches: options.includeMatches || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
// Participants API
|
||||
/**
|
||||
* Retrieves a tournament's participant list.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @returns {Promise<Object>} - A promise resolving to the list of participants.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const getParticipants = async tournamentId => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants`;
|
||||
const response = await challongeApi.get(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a participant to a tournament (up until it is started).
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} data - The participant data.
|
||||
* @param {string} [data.name] - The name displayed in the bracket/schedule. Must be unique per tournament.
|
||||
* @param {string} [data.challonge_username] - Challonge username of the participant (optional).
|
||||
* @param {string} [data.email] - Email of the participant (optional).
|
||||
* @param {number} [data.seed] - The participant's new seed (integer).
|
||||
* @param {string} [data.misc] - Multi-purpose field (max: 255 characters).
|
||||
* @returns {Promise<Object>} - A promise resolving to the added participant data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const addParticipant = async (tournamentId, data) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants`;
|
||||
const response = await challongeApi.post(url, { participant: data });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bulk adds participants to a tournament (up until it is started).
|
||||
* If an invalid participant is detected, bulk participant creation will halt,
|
||||
* and any previously added participants (from this API request) will be rolled back.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Array<Object>} data - An array of participant objects to add.
|
||||
* @param {string} [data[].name] - The name displayed in the bracket/schedule. Must be unique per tournament.
|
||||
* @param {string} [data[].invite_name_or_email] - Challonge username or email for inviting participants.
|
||||
* @param {number} [data[].seed] - The participant's new seed (integer).
|
||||
* @param {string} [data[].misc] - Multi-purpose field (max: 255 characters).
|
||||
* @returns {Promise<Object>} - A promise resolving to the response data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const bulkAddParticipants = async (tournamentId, data) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants/bulk_add`;
|
||||
const response = await challongeApi.post(url, { participants: data });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a single participant record for a tournament.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} participantId - The participant's unique ID.
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {boolean} [options.includeMatches=false] - Whether to include an array of associated match records.
|
||||
* @returns {Promise<Object>} - A promise resolving to the participant data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const getParticipant = async (tournamentId, participantId, options = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants/${participantId}`;
|
||||
const response = await challongeApi.get(url, {
|
||||
params: {
|
||||
include_matches: options.includeMatches || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the attributes of a tournament participant.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} participantId - The participant's unique ID.
|
||||
* @param {Object} data - The participant data to update.
|
||||
* @param {string} [data.name] - The name displayed in the bracket/schedule. Must be unique per tournament.
|
||||
* @param {string} [data.challonge_username] - Challonge username of the participant (optional).
|
||||
* @param {string} [data.email] - Email of the participant (optional).
|
||||
* @param {number} [data.seed] - The participant's new seed (integer).
|
||||
* @param {string} [data.misc] - Multi-purpose field (max: 255 characters).
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated participant data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const updateParticipant = async (tournamentId, participantId, data) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants/${participantId}`;
|
||||
const response = await challongeApi.put(url, { participant: data });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks a participant in, setting checked_in_at to the current time.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} participantId - The participant's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated participant data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const checkInParticipant = async (tournamentId, participantId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants/${participantId}/check_in`;
|
||||
const response = await challongeApi.post(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Undoes the check-in for a participant, setting checked_in_at to null.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} participantId - The participant's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated participant data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const undoCheckInParticipant = async (tournamentId, participantId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants/${participantId}/undo_check_in`;
|
||||
const response = await challongeApi.post(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes or deactivates a participant in a tournament.
|
||||
* If the tournament has not started, the participant is deleted, and the abandoned seed number is filled in.
|
||||
* If the tournament is underway, the participant is marked inactive, forfeiting their remaining matches.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} participantId - The participant's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the response data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const deleteParticipant = async (tournamentId, participantId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants/${participantId}`;
|
||||
const response = await challongeApi.delete(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes all participants in a tournament.
|
||||
* This action is only allowed if the tournament hasn't started yet.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @returns {Promise<Object>} - A promise resolving to the response data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const clearParticipants = async tournamentId => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants/clear`;
|
||||
const response = await challongeApi.delete(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Randomizes seeds among participants in a tournament.
|
||||
* This action is only applicable before the tournament has started.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @returns {Promise<Object>} - A promise resolving to the response data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const randomizeParticipants = async tournamentId => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/participants/randomize`;
|
||||
const response = await challongeApi.post(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
// Matches API
|
||||
/**
|
||||
* Retrieves a tournament's match list.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {Object} [params] - Optional query parameters for filtering matches.
|
||||
* @param {string} [params.state] - Filter by match state ('all', 'pending', 'open', 'complete').
|
||||
* @param {string} [params.participant_id] - Only retrieve matches that include the specified participant.
|
||||
* @returns {Promise<Object>} - A promise resolving to the list of matches.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const getMatches = async (tournamentId, params = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches`;
|
||||
const response = await challongeApi.get(url, { params });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a single match record for a tournament.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @param {Object} [options] - Optional parameters for the request.
|
||||
* @param {boolean} [options.includeAttachments=false] - Whether to include an array of associated attachment records.
|
||||
* @returns {Promise<Object>} - A promise resolving to the match data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const getMatch = async (tournamentId, matchId, options = {}) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}`;
|
||||
const response = await challongeApi.get(url, {
|
||||
params: {
|
||||
include_attachments: options.includeAttachments || false
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates or submits the score(s) for a match.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @param {Object} data - The match data to update.
|
||||
* @param {string} [data.scores_csv] - Comma-separated set/game scores with player 1 score first (e.g., "1-3,3-0,3-2").
|
||||
* @param {string} [data.winner_id] - The participant ID of the winner or "tie" if applicable (Round Robin and Swiss).
|
||||
* NOTE: If you change the outcome of a completed match, all matches in the bracket
|
||||
* that branch from the updated match will be reset.
|
||||
* @param {number} [data.player1_votes] - Overwrites the number of votes for player 1.
|
||||
* @param {number} [data.player2_votes] - Overwrites the number of votes for player 2.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated match data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const updateMatch = async (tournamentId, matchId, data) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}`;
|
||||
const response = await challongeApi.put(url, { match: data });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Reopens a match that was marked completed, automatically resetting matches that follow it.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated match data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const reopenMatch = async (tournamentId, matchId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}/reopen`;
|
||||
const response = await challongeApi.post(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks a match as underway.
|
||||
* Sets "underway_at" to the current time and highlights the match in the bracket.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated match data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const markMatchAsUnderway = async (tournamentId, matchId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}/mark_as_underway`;
|
||||
const response = await challongeApi.post(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Unmarks a match as underway.
|
||||
* Clears "underway_at" and unhighlights the match in the bracket.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated match data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const unmarkMatchAsUnderway = async (tournamentId, matchId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}/unmark_as_underway`;
|
||||
const response = await challongeApi.post(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
// Match Attachments API
|
||||
/**
|
||||
* Retrieves a match's attachments.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the list of match attachments.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const getMatchAttachments = async (tournamentId, matchId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}/attachments`;
|
||||
const response = await challongeApi.get(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a match attachment by adding a file, link, or text attachment to a match.
|
||||
* NOTE: The associated tournament's "accept_attachments" attribute must be true for this action to succeed.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @param {Object} data - The attachment data.
|
||||
* @param {File} [data.asset] - A file upload (250KB max, no more than 4 attachments per match). If provided, the url parameter will be ignored.
|
||||
* @param {string} [data.url] - A web URL.
|
||||
* @param {string} [data.description] - Text to describe the file or URL attachment, or this can simply be standalone text.
|
||||
* At least one of `asset`, `url`, or `description` must be provided.
|
||||
* @returns {Promise<Object>} - A promise resolving to the created match attachment data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const createMatchAttachment = async (tournamentId, matchId, data) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}/attachments`;
|
||||
const response = await challongeApi.post(url, { match_attachment: data });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a single match attachment record.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @param {string} attachmentId - The attachment's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the match attachment data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const getMatchAttachment = async (tournamentId, matchId, attachmentId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}/attachments/${attachmentId}`;
|
||||
const response = await challongeApi.get(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the attributes of a match attachment.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @param {string} attachmentId - The attachment's unique ID.
|
||||
* @param {Object} data - The attachment data to update.
|
||||
* @param {File} [data.asset] - A file upload (250KB max, no more than 4 attachments per match). If provided, the url parameter will be ignored.
|
||||
* @param {string} [data.url] - A web URL.
|
||||
* @param {string} [data.description] - Text to describe the file or URL attachment, or this can simply be standalone text.
|
||||
* At least one of `asset`, `url`, or `description` must be provided.
|
||||
* @returns {Promise<Object>} - A promise resolving to the updated match attachment data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const updateMatchAttachment = async (
|
||||
tournamentId,
|
||||
matchId,
|
||||
attachmentId,
|
||||
data
|
||||
) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}/attachments/${attachmentId}`;
|
||||
const response = await challongeApi.put(url, { match_attachment: data });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a match attachment.
|
||||
*
|
||||
* @param {string} tournamentId - The tournament ID (e.g., 10230) or URL (e.g., 'single_elim' for challonge.com/single_elim).
|
||||
* If assigned to a subdomain, the URL format must be :subdomain-:tournament_url
|
||||
* (e.g., 'test-mytourney' for test.challonge.com/mytourney).
|
||||
* @param {string} matchId - The match's unique ID.
|
||||
* @param {string} attachmentId - The attachment's unique ID.
|
||||
* @returns {Promise<Object>} - A promise resolving to the response data.
|
||||
* @throws {Error} If the request fails or the API returns an error.
|
||||
*/
|
||||
const deleteMatchAttachment = async (tournamentId, matchId, attachmentId) => {
|
||||
try {
|
||||
const url = `/tournaments/${tournamentId}/matches/${matchId}/attachments/${attachmentId}`;
|
||||
const response = await challongeApi.delete(url);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
listTournaments,
|
||||
createTournament,
|
||||
getTournament,
|
||||
updateTournament,
|
||||
deleteTournament,
|
||||
processCheckIns,
|
||||
abortCheckIn,
|
||||
startTournament,
|
||||
finalizeTournament,
|
||||
resetTournament,
|
||||
openForPredictions,
|
||||
getParticipants,
|
||||
addParticipant,
|
||||
bulkAddParticipants,
|
||||
getParticipant,
|
||||
updateParticipant,
|
||||
checkInParticipant,
|
||||
undoCheckInParticipant,
|
||||
deleteParticipant,
|
||||
clearParticipants,
|
||||
randomizeParticipants,
|
||||
getMatches,
|
||||
getMatch,
|
||||
updateMatch,
|
||||
reopenMatch,
|
||||
markMatchAsUnderway,
|
||||
unmarkMatchAsUnderway,
|
||||
getMatchAttachments,
|
||||
createMatchAttachment,
|
||||
getMatchAttachment,
|
||||
updateMatchAttachment,
|
||||
deleteMatchAttachment
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
const {
|
||||
listTournaments,
|
||||
createTournament,
|
||||
getTournament,
|
||||
updateTournament,
|
||||
deleteTournament,
|
||||
processCheckIns,
|
||||
abortCheckIn,
|
||||
startTournament,
|
||||
finalizeTournament,
|
||||
resetTournament,
|
||||
openForPredictions,
|
||||
getParticipants,
|
||||
addParticipant,
|
||||
bulkAddParticipants,
|
||||
getParticipant,
|
||||
updateParticipant,
|
||||
checkInParticipant,
|
||||
undoCheckInParticipant,
|
||||
deleteParticipant,
|
||||
clearParticipants,
|
||||
randomizeParticipants,
|
||||
getMatches,
|
||||
getMatch,
|
||||
updateMatch,
|
||||
reopenMatch,
|
||||
markMatchAsUnderway,
|
||||
unmarkMatchAsUnderway,
|
||||
getMatchAttachments,
|
||||
createMatchAttachment,
|
||||
getMatchAttachment,
|
||||
updateMatchAttachment,
|
||||
deleteMatchAttachment
|
||||
} = require('./challonge');
|
||||
const axios = require('axios');
|
||||
|
||||
jest.mock('axios');
|
||||
|
||||
describe('Challonge API', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('listTournaments', () => {
|
||||
it('should fetch a list of tournaments with default parameters', async () => {
|
||||
const mockResponse = {
|
||||
data: [
|
||||
{ id: 1, name: 'Tournament 1' },
|
||||
{ id: 2, name: 'Tournament 2' }
|
||||
]
|
||||
};
|
||||
axios.get.mockResolvedValueOnce(mockResponse);
|
||||
|
||||
const result = await listTournaments();
|
||||
|
||||
expect(axios.get).toHaveBeenCalledWith('/tournaments', {
|
||||
params: {}
|
||||
});
|
||||
expect(result).toEqual(mockResponse.data);
|
||||
});
|
||||
|
||||
it('should fetch a list of tournaments with provided parameters', async () => {
|
||||
const params = { state: 'in_progress', type: 'single_elimination' };
|
||||
const mockResponse = { data: [{ id: 3, name: 'Tournament 3' }] };
|
||||
axios.get.mockResolvedValueOnce(mockResponse);
|
||||
|
||||
const result = await listTournaments(params);
|
||||
|
||||
expect(axios.get).toHaveBeenCalledWith('/tournaments.json', { params });
|
||||
expect(result).toEqual(mockResponse.data);
|
||||
});
|
||||
|
||||
it('should handle errors when fetching tournaments', async () => {
|
||||
const mockError = new Error('Network Error');
|
||||
axios.get.mockRejectedValueOnce(mockError);
|
||||
|
||||
await expect(listTournaments()).rejects.toThrow('Network Error');
|
||||
expect(axios.get).toHaveBeenCalledWith('/tournaments.json', {
|
||||
params: {}
|
||||
});
|
||||
});
|
||||
});
|
||||
// createTournament;
|
||||
// getTournament;
|
||||
// updateTournament;
|
||||
// deleteTournament;
|
||||
// processCheckIns;
|
||||
// abortCheckIn;
|
||||
// startTournament;
|
||||
// finalizeTournament;
|
||||
// resetTournament;
|
||||
// openForPredictions;
|
||||
// getParticipants;
|
||||
// addParticipant;
|
||||
// bulkAddParticipants;
|
||||
// getParticipant;
|
||||
// updateParticipant;
|
||||
// checkInParticipant;
|
||||
// undoCheckInParticipant;
|
||||
// deleteParticipant;
|
||||
// clearParticipants;
|
||||
// randomizeParticipants;
|
||||
// getMatches;
|
||||
// getMatch;
|
||||
// updateMatch;
|
||||
// reopenMatch;
|
||||
// markMatchAsUnderway;
|
||||
// unmarkMatchAsUnderway;
|
||||
// getMatchAttachments;
|
||||
// createMatchAttachment;
|
||||
// getMatchAttachment;
|
||||
// updateMatchAttachment;
|
||||
// deleteMatchAttachment;
|
||||
});
|
||||
@@ -0,0 +1,995 @@
|
||||
Challonge API v1 Documentation
|
||||
The Challonge API expands tournament creation and control to the programmatic level. You can create tournaments on the fly and report scores directly from your application. This allows you to define score reporting permissions that fit your user model, and provide a more seamless tournament experience for your users.
|
||||
The API is accessible over a secure connection at https://api.challonge.com/v1/
|
||||
________________
|
||||
|
||||
|
||||
Authentication
|
||||
All interactions with the API require a Challonge account with a verified email address and API key. You can generate one from your developer settings page. We support HTTP basic authentication. Username = your Challonge username, Password = your API key. Many clients format these requests as: https://username:api-key@api.challonge.com/v1/... Or, if you prefer, you can just pass your API key as parameter api_key to all method calls.
|
||||
API methods with GET request types are permitted for any tournament, whether belonging to you or not. All other API methods are scoped to tournaments that you either own or have admin access to.
|
||||
________________
|
||||
|
||||
|
||||
Response Formats
|
||||
XML or JSON. The extension in your request indicates your desired response. e.g. https://api.challonge.com/v1/tournaments.xml or https://api.challonge.com/v1/tournaments.json - you may also set your request headers to accept application/json, text/xml or application/xml
|
||||
________________
|
||||
|
||||
|
||||
Response Codes
|
||||
The following HTTP response codes are issued by the API. All other codes are the result of a request not reaching the application.
|
||||
* 200- OK
|
||||
* 401- Unauthorized (Invalid API key or insufficient permissions)
|
||||
* 404- Object not found within your account scope
|
||||
* 406- Requested format is not supported - request JSON or XML only
|
||||
* 422- Validation error(s) for create or update method
|
||||
* 500- Something went wrong on our end. If you continually receive this, please contact us.
|
||||
________________
|
||||
|
||||
|
||||
Validation Errors
|
||||
Requests that complete but have validation errors or other issues will return an array of error messages and status code 422. e.g.:
|
||||
* XML
|
||||
* JSON
|
||||
{
|
||||
"errors": [
|
||||
"Name can't be blank",
|
||||
"URL can't be blank"
|
||||
]
|
||||
}
|
||||
________________
|
||||
|
||||
|
||||
REST API Methods
|
||||
Please note, two-stage tournaments are not yet supported by our public API. They'll be available in V2 along with 3+ participant per match support.
|
||||
Tournaments
|
||||
Index
|
||||
GET
|
||||
Retrieve a set of tournaments created with your account.
|
||||
Create
|
||||
POST
|
||||
Create a new tournament.
|
||||
Show
|
||||
GET
|
||||
Retrieve a single tournament record created with your account.
|
||||
Update
|
||||
PUT
|
||||
Update a tournament's attributes.
|
||||
Destroy
|
||||
DELETE
|
||||
Deletes a tournament along with all its associated records. There is no undo, so use with care!
|
||||
Process Check-ins
|
||||
POST
|
||||
This should be invoked after a tournament's check-in window closes before the tournament is started.
|
||||
1. Marks participants who have not checked in as inactive.
|
||||
2. Moves inactive participants to bottom seeds (ordered by original seed).
|
||||
3. Transitions the tournament state from 'checking_in' to 'checked_in'
|
||||
NOTE: Checked in participants on the waiting list will be promoted if slots become available.
|
||||
Abort Check-in
|
||||
POST
|
||||
When your tournament is in a 'checking_in' or 'checked_in' state, there's no way to edit the tournament's start time (start_at) or check-in duration (check_in_duration). You must first abort check-in, then you may edit those attributes.
|
||||
1. Makes all participants active and clears their checked_in_at times.
|
||||
2. Transitions the tournament state from 'checking_in' or 'checked_in' to 'pending'
|
||||
Start
|
||||
POST
|
||||
Start a tournament, opening up first round matches for score reporting. The tournament must have at least 2 participants.
|
||||
Finalize
|
||||
POST
|
||||
Finalize a tournament that has had all match scores submitted, rendering its results permanent.
|
||||
Reset
|
||||
POST
|
||||
Reset a tournament, clearing all of its scores and attachments. You can then add/remove/edit participants before starting the tournament again.
|
||||
Open for predictions
|
||||
POST
|
||||
Sets the state of the tournament to start accepting predictions. Your tournament's 'prediction_method' attribute must be set to 1 (exponential scoring) or 2 (linear scoring) to use this option. Note: Once open for predictions, match records will be persisted, so participant additions and removals will no longer be permitted.
|
||||
Participants
|
||||
Index
|
||||
GET
|
||||
Retrieve a tournament's participant list.
|
||||
Create
|
||||
POST
|
||||
Add a participant to a tournament (up until it is started).
|
||||
Bulk Add
|
||||
POST
|
||||
Bulk add participants to a tournament (up until it is started). If an invalid participant is detected, bulk participant creation will halt and any previously added participants (from this API request) will be rolled back.
|
||||
Show
|
||||
GET
|
||||
Retrieve a single participant record for a tournament.
|
||||
Update
|
||||
PUT
|
||||
Update the attributes of a tournament participant.
|
||||
Check in
|
||||
POST
|
||||
Checks a participant in, setting checked_in_at to the current time.
|
||||
Undo Check In
|
||||
POST
|
||||
Marks a participant as having not checked in, setting checked_in_at to nil.
|
||||
Destroy
|
||||
DELETE
|
||||
If the tournament has not started, delete a participant, automatically filling in the abandoned seed number. If tournament is underway, mark a participant inactive, automatically forfeiting his/her remaining matches.
|
||||
Clear
|
||||
DELETE
|
||||
Deletes all participants in a tournament. (Only allowed if tournament hasn't started yet)
|
||||
Randomize
|
||||
POST
|
||||
Randomize seeds among participants. Only applicable before a tournament has started.
|
||||
Matches
|
||||
Index
|
||||
GET
|
||||
Retrieve a tournament's match list.
|
||||
Show
|
||||
GET
|
||||
Retrieve a single match record for a tournament.
|
||||
Update
|
||||
PUT
|
||||
Update/submit the score(s) for a match.
|
||||
Reopen
|
||||
POST
|
||||
Reopens a match that was marked completed, automatically resetting matches that follow it
|
||||
Mark as underway
|
||||
POST
|
||||
Sets "underway_at" to the current time and highlights the match in the bracket
|
||||
Unmark as underway
|
||||
POST
|
||||
Clears "underway_at" and unhighlights the match in the bracket
|
||||
Match Attachments
|
||||
Index
|
||||
GET
|
||||
Retrieve a match's attachments.
|
||||
Create
|
||||
POST
|
||||
Add a file, link, or text attachment to a match. NOTE: The associated tournament's "accept_attachments" attribute must be true for this action to succeed.
|
||||
Show
|
||||
GET
|
||||
Retrieve a single match attachment record.
|
||||
Update
|
||||
PUT
|
||||
Update the attributes of a match attachment.
|
||||
Destroy
|
||||
DELETE
|
||||
Delete a match attachment.
|
||||
|
||||
|
||||
Tournaments API Calls
|
||||
List tournaments (index)
|
||||
Retrieve a set of tournaments created with your account.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
GET https://api.challonge.com/v1/tournaments.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
state
|
||||
all, pending, in_progress, ended
|
||||
type
|
||||
single_elimination, double_elimination, round_robin, swiss
|
||||
created_after
|
||||
YYYY-MM-DD
|
||||
created_before
|
||||
YYYY-MM-DD
|
||||
subdomain
|
||||
A Challonge subdomain you've published tournaments to. NOTE: Until v2 of our API, the subdomain parameter is required to retrieve a list of your organization-hosted tournaments.
|
||||
|
||||
|
||||
Create a tournament
|
||||
Create a new tournament.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
tournament[name]
|
||||
Your event's name/title (Max: 60 characters)
|
||||
tournament[tournament_type]
|
||||
Single elimination (default), double elimination, round robin, swiss
|
||||
tournament[url]
|
||||
challonge.com/url (letters, numbers, and underscores only); when blank on create, a random URL will be generated for you
|
||||
tournament[subdomain]
|
||||
subdomain.challonge.com/url (Requires write access to the specified subdomain)
|
||||
tournament[description]
|
||||
Description/instructions to be displayed above the bracket
|
||||
tournament[open_signup]
|
||||
True or false. Have Challonge host a sign-up page (otherwise, you manually add all participants)
|
||||
tournament[hold_third_place_match]
|
||||
True or false - Single Elimination only. Include a match between semifinal losers? (default: false)
|
||||
tournament[pts_for_match_win]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 1.0
|
||||
tournament[pts_for_match_tie]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 0.5
|
||||
tournament[pts_for_game_win]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 0.0
|
||||
tournament[pts_for_game_tie]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 0.0
|
||||
tournament[pts_for_bye]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 1.0
|
||||
tournament[swiss_rounds]
|
||||
Integer - Swiss only - We recommend limiting the number of rounds to less than two-thirds the number of players. Otherwise, an impossible pairing situation can be reached and your tournament may end before the desired number of rounds are played.
|
||||
tournament[ranked_by]
|
||||
One of the following: 'match wins', 'game wins', 'points scored', 'points difference', 'custom' Help
|
||||
tournament[rr_pts_for_match_win]
|
||||
Decimal (to the nearest tenth) - Round Robin "custom only" - default: 1.0
|
||||
tournament[rr_pts_for_match_tie]
|
||||
Decimal (to the nearest tenth) - Round Robin "custom" only - default: 0.5
|
||||
tournament[rr_pts_for_game_win]
|
||||
Decimal (to the nearest tenth) - Round Robin "custom" only - default: 0.0
|
||||
tournament[rr_pts_for_game_tie]
|
||||
Decimal (to the nearest tenth) - Round Robin "custom" only - default: 0.0
|
||||
tournament[accept_attachments]
|
||||
True or false - Allow match attachment uploads (default: false)
|
||||
tournament[hide_forum]
|
||||
True or false - Hide the forum tab on your Challonge page (default: false)
|
||||
tournament[show_rounds]
|
||||
True or false - Single & Double Elimination only - Label each round above the bracket (default: false)
|
||||
tournament[private]
|
||||
True or false - Hide this tournament from the public browsable index and your profile (default: false)
|
||||
tournament[notify_users_when_matches_open]
|
||||
True or false - Email registered Challonge participants when matches open up for them (default: false)
|
||||
tournament[notify_users_when_the_tournament_ends]
|
||||
True or false - Email registered Challonge participants the results when this tournament ends (default: false)
|
||||
tournament[sequential_pairings]
|
||||
True or false - Instead of traditional seeding rules, make pairings by going straight down the list of participants. First round matches are filled in top to bottom, then qualifying matches (if applicable). (default: false)
|
||||
tournament[signup_cap]
|
||||
Integer - Maximum number of participants in the bracket. A waiting list (attribute on Participant) will capture participants once the cap is reached.
|
||||
tournament[start_at]
|
||||
Datetime - the planned or anticipated start time for the tournament (Used with check_in_duration to determine participant check-in window). Timezone defaults to Eastern.
|
||||
tournament[check_in_duration]
|
||||
Integer - Length of the participant check-in window in minutes.
|
||||
tournament[grand_finals_modifier]
|
||||
String - This option only affects double elimination. null/blank (default) - give the winners bracket finalist two chances to beat the losers bracket finalist, 'single match' - create only one grand finals match, 'skip' - don't create a finals match between winners and losers bracket finalists
|
||||
|
||||
|
||||
|
||||
|
||||
Get a tournament (show)
|
||||
Retrieve a single tournament record created with your account.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
GET https://api.challonge.com/v1/tournaments/{tournament}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
include_participants
|
||||
0 or 1; includes an array of associated participant records
|
||||
include_matches
|
||||
0 or 1; includes an array of associated match records
|
||||
|
||||
|
||||
|
||||
|
||||
Update a tournament
|
||||
Update a tournament's attributes.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
PUT Help https://api.challonge.com/v1/tournaments/{tournament}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
tournament[name]
|
||||
Your event's name/title (Max: 60 characters)
|
||||
tournament[tournament_type]
|
||||
Single elimination (default), double elimination, round robin, swiss
|
||||
tournament[url]
|
||||
challonge.com/url (letters, numbers, and underscores only); when blank on create, a random URL will be generated for you
|
||||
tournament[subdomain]
|
||||
subdomain.challonge.com/url (Requires write access to the specified subdomain)
|
||||
tournament[description]
|
||||
Description/instructions to be displayed above the bracket
|
||||
tournament[open_signup]
|
||||
True or false. Have Challonge host a sign-up page (otherwise, you manually add all participants)
|
||||
tournament[hold_third_place_match]
|
||||
True or false - Single Elimination only. Include a match between semifinal losers? (default: false)
|
||||
tournament[pts_for_match_win]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 1.0
|
||||
tournament[pts_for_match_tie]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 0.5
|
||||
tournament[pts_for_game_win]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 0.0
|
||||
tournament[pts_for_game_tie]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 0.0
|
||||
tournament[pts_for_bye]
|
||||
Decimal (to the nearest tenth) - Swiss only - default: 1.0
|
||||
tournament[swiss_rounds]
|
||||
Integer - Swiss only - We recommend limiting the number of rounds to less than two-thirds the number of players. Otherwise, an impossible pairing situation can be reached and your tournament may end before the desired number of rounds are played.
|
||||
tournament[ranked_by]
|
||||
One of the following: 'match wins', 'game wins', 'points scored', 'points difference', 'custom' Help
|
||||
tournament[rr_pts_for_match_win]
|
||||
Decimal (to the nearest tenth) - Round Robin "custom only" - default: 1.0
|
||||
tournament[rr_pts_for_match_tie]
|
||||
Decimal (to the nearest tenth) - Round Robin "custom" only - default: 0.5
|
||||
tournament[rr_pts_for_game_win]
|
||||
Decimal (to the nearest tenth) - Round Robin "custom" only - default: 0.0
|
||||
tournament[rr_pts_for_game_tie]
|
||||
Decimal (to the nearest tenth) - Round Robin "custom" only - default: 0.0
|
||||
tournament[accept_attachments]
|
||||
True or false - Allow match attachment uploads (default: false)
|
||||
tournament[hide_forum]
|
||||
True or false - Hide the forum tab on your Challonge page (default: false)
|
||||
tournament[show_rounds]
|
||||
True or false - Single & Double Elimination only - Label each round above the bracket (default: false)
|
||||
tournament[private]
|
||||
True or false - Hide this tournament from the public browsable index and your profile (default: false)
|
||||
tournament[notify_users_when_matches_open]
|
||||
True or false - Email registered Challonge participants when matches open up for them (default: false)
|
||||
tournament[notify_users_when_the_tournament_ends]
|
||||
True or false - Email registered Challonge participants the results when this tournament ends (default: false)
|
||||
tournament[sequential_pairings]
|
||||
True or false - Instead of traditional seeding rules, make pairings by going straight down the list of participants. First round matches are filled in top to bottom, then qualifying matches (if applicable). (default: false)
|
||||
tournament[signup_cap]
|
||||
Integer - Maximum number of participants in the bracket. A waiting list (attribute on Participant) will capture participants once the cap is reached.
|
||||
tournament[start_at]
|
||||
Datetime - the planned or anticipated start time for the tournament (Used with check_in_duration to determine participant check-in window). Timezone defaults to Eastern.
|
||||
tournament[check_in_duration]
|
||||
Integer - Length of the participant check-in window in minutes.
|
||||
tournament[grand_finals_modifier]
|
||||
String - This option only affects double elimination. null/blank (default) - give the winners bracket finalist two chances to beat the losers bracket finalist, 'single match' - create only one grand finals match, 'skip' - don't create a finals match between winners and losers bracket finalists
|
||||
|
||||
|
||||
Delete a tournament
|
||||
Deletes a tournament along with all its associated records. There is no undo, so use with care!
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
DELETE Help https://api.challonge.com/v1/tournaments/{tournament}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Process check-in results for a tournament
|
||||
This should be invoked after a tournament's check-in window closes before the tournament is started.
|
||||
1. Marks participants who have not checked in as inactive.
|
||||
2. Moves inactive participants to bottom seeds (ordered by original seed).
|
||||
3. Transitions the tournament state from 'checking_in' to 'checked_in'
|
||||
NOTE: Checked in participants on the waiting list will be promoted if slots become available.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/process_check_ins.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
include_participants
|
||||
0 or 1; includes an array of associated participant records
|
||||
include_matches
|
||||
0 or 1; includes an array of associated match records
|
||||
Abort check-in for a tournament
|
||||
When your tournament is in a 'checking_in' or 'checked_in' state, there's no way to edit the tournament's start time (start_at) or check-in duration (check_in_duration). You must first abort check-in, then you may edit those attributes.
|
||||
1. Makes all participants active and clears their checked_in_at times.
|
||||
2. Transitions the tournament state from 'checking_in' or 'checked_in' to 'pending'
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/abort_check_in.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
include_participants
|
||||
0 or 1; includes an array of associated participant records
|
||||
include_matches
|
||||
0 or 1; includes an array of associated match records
|
||||
Start a tournament
|
||||
Start a tournament, opening up first round matches for score reporting. The tournament must have at least 2 participants.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/start.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
include_participants
|
||||
0 or 1; includes an array of associated participant records
|
||||
include_matches
|
||||
0 or 1; includes an array of associated match records
|
||||
Finalize a tournament
|
||||
Finalize a tournament that has had all match scores submitted, rendering its results permanent.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/finalize.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
include_participants
|
||||
0 or 1; includes an array of associated participant records
|
||||
include_matches
|
||||
0 or 1; includes an array of associated match records
|
||||
|
||||
|
||||
Reset a tournament
|
||||
Reset a tournament, clearing all of its scores and attachments. You can then add/remove/edit participants before starting the tournament again.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/reset.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
include_participants
|
||||
0 or 1; includes an array of associated participant records
|
||||
include_matches
|
||||
0 or 1; includes an array of associated match records
|
||||
Open the tournament for predictions
|
||||
Sets the state of the tournament to start accepting predictions. Your tournament's 'prediction_method' attribute must be set to 1 (exponential scoring) or 2 (linear scoring) to use this option. Note: Once open for predictions, match records will be persisted, so participant additions and removals will no longer be permitted.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/open_for_predictions.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
include_participants
|
||||
0 or 1; includes an array of associated participant records
|
||||
include_matches
|
||||
0 or 1; includes an array of associated match records
|
||||
PArticipant API Calls
|
||||
List a tournament's participants (index)
|
||||
Retrieve a tournament's participant list.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
GET https://api.challonge.com/v1/tournaments/{tournament}/participants.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
|
||||
|
||||
Create a participant
|
||||
Add a participant to a tournament (up until it is started).
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/participants.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
participant[name]
|
||||
The name displayed in the bracket/schedule - not required if email or challonge_username is provided. Must be unique per tournament.
|
||||
participant[challonge_username]
|
||||
Provide this if the participant has a Challonge account. He or she will be invited to the tournament.
|
||||
participant[email]
|
||||
Providing this will first search for a matching Challonge account. If one is found, this will have the same effect as the "challonge_username" attribute. If one is not found, the "new-user-email" attribute will be set, and the user will be invited via email to create an account.
|
||||
participant[seed]
|
||||
integer - The participant's new seed. Must be between 1 and the current number of participants (including the new record). Overwriting an existing seed will automatically bump other participants as you would expect.
|
||||
participant[misc]
|
||||
string - Max: 255 characters. Multi-purpose field that is only visible via the API and handy for site integration (e.g. key to your users table)
|
||||
Bulk create participants
|
||||
Bulk add participants to a tournament (up until it is started). If an invalid participant is detected, bulk participant creation will halt and any previously added participants (from this API request) will be rolled back.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/participants/bulk_add.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
participants[][name]
|
||||
The name displayed in the bracket/schedule - not required if email or challonge_username is provided. Must be unique per tournament.
|
||||
participants[][invite_name_or_email]
|
||||
Username can be provided if the participant has a Challonge account. Providing email will first search for a matching Challonge account. If one is found, the user will be invited. If not, the "new-user-email" attribute will be set, and the user will be invited via email to create an account.
|
||||
participants[][seed]
|
||||
integer - The participant's new seed. Must be between 1 and the current number of participants (including the new record). Overwriting an existing seed will automatically bump other participants as you would expect.
|
||||
participants[][misc]
|
||||
string - Max: 255 characters. Multi-purpose field that is only visible via the API and handy for site integration (e.g. key to your users table)
|
||||
Get a participant (show)
|
||||
Retrieve a single participant record for a tournament.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
GET https://api.challonge.com/v1/tournaments/{tournament}/participants/{participant_id}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{participant_id} (in URL string)
|
||||
The participant's unique ID
|
||||
include_matches
|
||||
0 or 1; includes an array of associated match records
|
||||
Update a participant
|
||||
Update the attributes of a tournament participant.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
PUT Help https://api.challonge.com/v1/tournaments/{tournament}/participants/{participant_id}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{participant_id} (in URL string)
|
||||
The participant's unique ID
|
||||
participant[name]
|
||||
The name displayed in the bracket/schedule - not required if email or challonge_username is provided. Must be unique per tournament.
|
||||
participant[challonge_username]
|
||||
Provide this if the participant has a Challonge account. He or she will be invited to the tournament.
|
||||
participant[email]
|
||||
Providing this will first search for a matching Challonge account. If one is found, this will have the same effect as the "challonge_username" attribute. If one is not found, the "new-user-email" attribute will be set, and the user will be invited via email to create an account.
|
||||
participant[seed]
|
||||
integer - The participant's new seed. Must be between 1 and the current number of participants (including the new record). Overwriting an existing seed will automatically bump other participants as you would expect.
|
||||
participant[misc]
|
||||
string - Max: 255 characters. Multi-purpose field that is only visible via the API and handy for site integration (e.g. key to your users table)
|
||||
Check in a participant
|
||||
Checks a participant in, setting checked_in_at to the current time.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/participants/{participant_id}/check_in.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{participant_id} (in URL string)
|
||||
The participant's unique ID
|
||||
Undo check-in for a participant
|
||||
Marks a participant as having not checked in, setting checked_in_at to nil.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/participants/{participant_id}/undo_check_in.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{participant_id} (in URL string)
|
||||
The participant's un
|
||||
Delete/deactivate a participant
|
||||
If the tournament has not started, delete a participant, automatically filling in the abandoned seed number. If tournament is underway, mark a participant inactive, automatically forfeiting his/her remaining matches.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
DELETE Help https://api.challonge.com/v1/tournaments/{tournament}/participants/{participant_id}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{participant_id} (in URL string)
|
||||
The participant'
|
||||
Clear/delete all participants
|
||||
Deletes all participants in a tournament. (Only allowed if tournament hasn't started yet)
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
DELETE Help https://api.challonge.com/v1/tournaments/{tournament}/participants/clear.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Randomize a tournament's participants
|
||||
Randomize seeds among participants. Only applicable before a tournament has started.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/participants/randomize.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
|
||||
|
||||
Match API Calls
|
||||
List a tournament's matches (index)
|
||||
Retrieve a tournament's match list.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
GET https://api.challonge.com/v1/tournaments/{tournament}/matches.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
state
|
||||
all (default), pending, open, complete
|
||||
participant_id
|
||||
Only retrieve matches that include the specified participant.
|
||||
|
||||
|
||||
Get a match (show)
|
||||
Retrieve a single match record for a tournament.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
GET https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
include_attachments
|
||||
0 or 1; include an array of associated attachment records
|
||||
Update a match
|
||||
Update/submit the score(s) for a match.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
PUT Help https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
match[scores_csv]
|
||||
Comma separated set/game scores with player 1 score first (e.g. "1-3,3-0,3-2")
|
||||
match[winner_id]
|
||||
The participant ID of the winner or "tie" if applicable (Round Robin and Swiss). NOTE: If you change the outcome of a completed match, all matches in the bracket that branch from the updated match will be reset.
|
||||
match[player1_votes]
|
||||
Overwrites the number of votes for player 1
|
||||
match[player2_votes]
|
||||
Overwrites the number of votes for player 2
|
||||
|
||||
|
||||
* If you're updating winner_id, scores_csv must also be provided. You may, however, update score_csv without providing winner_id for live score updates.
|
||||
Reopen a match
|
||||
Reopens a match that was marked completed, automatically resetting matches that follow it
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}/reopen.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
Mark a match as underway
|
||||
Sets "underway_at" to the current time and highlights the match in the bracket
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}/mark_as_underway.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
|
||||
|
||||
Unmark a match as underway
|
||||
Clears "underway_at" and unhighlights the match in the bracket
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}/unmark_as_underway.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
|
||||
|
||||
Attachment API Calls
|
||||
List a match's attachments (index)
|
||||
Retrieve a match's attachments.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
GET https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}/attachments.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's
|
||||
Create a match attachment
|
||||
Add a file, link, or text attachment to a match. NOTE: The associated tournament's "accept_attachments" attribute must be true for this action to succeed.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
POST https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}/attachments.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
match_attachment[asset]
|
||||
A file upload (250KB max, no more than 4 attachments per match). If provided, the url parameter will be ignored.
|
||||
match_attachment[url]
|
||||
A web URL
|
||||
match_attachment[description]
|
||||
Text to describe the file or URL attachment, or this can simply be standalone text.
|
||||
|
||||
|
||||
* At least 1 of the 3 optional parameters must be provided.
|
||||
* Files up to 25MB are allowed for tournaments hosted by Premier badge Challonge Premier subscribers.
|
||||
Get a match attachment (show)
|
||||
Retrieve a single match attachment record.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
GET https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}/attachments/{attachment_id}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
Required
|
||||
{attachment_id} (in URL string)
|
||||
The attachment's unique ID
|
||||
Update a match attachment
|
||||
Update the attributes of a match attachment.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
PUT Help https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}/attachments/{attachment_id}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
match_attachment[asset]
|
||||
A file upload (250KB max, no more than 4 attachments per match). If provided, the url parameter will be ignored.
|
||||
match_attachment[url]
|
||||
A web URL
|
||||
match_attachment[description]
|
||||
Text to describe the file or URL attachment, or this can simply be standalone text.
|
||||
|
||||
|
||||
* At least 1 of the 3 optional parameters must be provided.
|
||||
* Files up to 25MB are allowed for tournaments hosted by Premier badge Challonge Premier subscribers.
|
||||
Delete a match attachment
|
||||
Delete a match attachment.
|
||||
________________
|
||||
|
||||
|
||||
URL
|
||||
DELETE Help https://api.challonge.com/v1/tournaments/{tournament}/matches/{match_id}/attachments/{attachment_id}.{json|xml}
|
||||
________________
|
||||
Parameters
|
||||
Name
|
||||
Description
|
||||
Required
|
||||
api_key
|
||||
Your API key (required unless you're using HTTP basic authentication)
|
||||
Required
|
||||
{tournament} (in URL string)
|
||||
Tournament ID (e.g. 10230) or URL (e.g. 'single_elim' for challonge.com/single_elim). If assigned to a subdomain, URL format must be :subdomain-:tournament_url (e.g. 'test-mytourney' for test.challonge.com/mytourney)
|
||||
Required
|
||||
{match_id} (in URL string)
|
||||
The match's unique ID
|
||||
Required
|
||||
{attachment_id} (in URL string)
|
||||
The attachment's unique ID
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
const EPHEMERAL_MESSAGE_DURATION_MILLISECS = 5000;
|
||||
const CHALLONGE_API_BASE_URL = 'https://api.challonge.com/v1/';
|
||||
|
||||
module.exports = {
|
||||
EPHEMERAL_MESSAGE_DURATION_MILLISECS,
|
||||
CHALLONGE_API_BASE_URL
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
const EXPECTED_HEADERS = [
|
||||
'player_id',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'country_code',
|
||||
'division',
|
||||
'screenname',
|
||||
'email',
|
||||
'tournament_id'
|
||||
];
|
||||
|
||||
/**
|
||||
* Normalize a screenname for reliable matching.
|
||||
*/
|
||||
const normalizeScreenname = name =>
|
||||
name?.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
||||
|
||||
/**
|
||||
* Validate CSV headers.
|
||||
*/
|
||||
const validateCsvHeaders = headers => {
|
||||
if (!headers) throw new Error('CSV file is missing headers.');
|
||||
if (headers.length !== EXPECTED_HEADERS.length) {
|
||||
throw new Error(
|
||||
`Invalid CSV file headers: Expected ${EXPECTED_HEADERS.length} headers but found ${headers.length}.`
|
||||
);
|
||||
}
|
||||
const missingHeaders = EXPECTED_HEADERS.filter(h => !headers.includes(h));
|
||||
if (missingHeaders.length) {
|
||||
throw new Error(
|
||||
`Invalid CSV file headers: Missing the following headers: ${missingHeaders.join(', ')}.`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse CSV data into an object keyed by screenname.
|
||||
*/
|
||||
const parseCsv = csvData => {
|
||||
const rows = csvData
|
||||
.split('\n')
|
||||
.map(row => row.split(','))
|
||||
.filter(row => row.some(cell => cell.trim() !== ''));
|
||||
const headers = rows[0].map(header => header.trim());
|
||||
validateCsvHeaders(headers);
|
||||
|
||||
for (let i = 1; i < rows.length; i++) {
|
||||
if (rows[i].length !== EXPECTED_HEADERS.length) {
|
||||
throw new Error(`Invalid row format at line ${i + 1}.`);
|
||||
}
|
||||
}
|
||||
|
||||
return rows.slice(1).reduce((acc, row) => {
|
||||
const participant = {};
|
||||
EXPECTED_HEADERS.forEach((header, idx) => {
|
||||
participant[header] = row[idx];
|
||||
});
|
||||
acc[participant.screenname] = participant;
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
normalizeScreenname,
|
||||
validateCsvHeaders,
|
||||
parseCsv,
|
||||
EXPECTED_HEADERS
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const saveResponseToJson = require('../log-output-to-json.js');
|
||||
|
||||
const gamemasterFilePath = path.join(__dirname, `gamemaster/latest.json`);
|
||||
const gamemaster = JSON.parse(fs.readFileSync(gamemasterFilePath, 'utf8'));
|
||||
|
||||
const regionCheck = ['alola', 'galarian', 'hisuian', 'paldea'];
|
||||
const { pokemon, moves } = gamemaster.reduce(
|
||||
(acc, item) => {
|
||||
const templateId = item.templateId;
|
||||
// POKEMON FILTER
|
||||
// IF the templateId begins with 'V'
|
||||
// AND the templateId includes the word 'pokemon'
|
||||
if (
|
||||
templateId.startsWith('V') &&
|
||||
templateId.toLowerCase().includes('pokemon')
|
||||
) {
|
||||
const pokemonSettings = item.data?.pokemonSettings;
|
||||
const pokemonId = pokemonSettings?.pokemonId;
|
||||
if (
|
||||
// If the acc.seen has the pokemonId
|
||||
// OR if the acc.see has the pokemon id AND the pokemonSettings.form contains a keyword from the regionCheck array
|
||||
!acc.pokemonSeen.has(pokemonId) ||
|
||||
(acc.pokemonSeen.has(pokemonId) &&
|
||||
regionCheck.includes(
|
||||
pokemonSettings?.form?.split('_')[1].toLowerCase()
|
||||
))
|
||||
) {
|
||||
acc.pokemonSeen.add(pokemonId); // Mark pokemonId as seen
|
||||
acc.pokemon.push(item); // Add the item to the pokemon acc array
|
||||
}
|
||||
}
|
||||
|
||||
// POKEMON MOVE FILTER
|
||||
if (
|
||||
templateId.startsWith('V') &&
|
||||
templateId.toLowerCase().includes('move')
|
||||
) {
|
||||
const moveSettings = item.data?.moveSettings;
|
||||
const moveId = moveSettings?.movementId;
|
||||
if (!acc.pokemonSeen.has(moveId)) {
|
||||
acc.moveSeen.add(moveId); // Mark pokemonId as seen
|
||||
acc.moves.push(item); // Add the item to the pokemon acc array
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{ pokemon: [], pokemonSeen: new Set(), moves: [], moveSeen: new Set() }
|
||||
);
|
||||
|
||||
saveResponseToJson({
|
||||
response: pokemon,
|
||||
filename: 'pokemon.json',
|
||||
savePath: path.resolve(__dirname, 'gamemaster')
|
||||
});
|
||||
|
||||
saveResponseToJson({
|
||||
response: moves,
|
||||
filename: 'pokemon-moves.json',
|
||||
savePath: path.resolve(__dirname, 'gamemaster')
|
||||
});
|
||||
// console.log(AllPokemon);
|
||||
@@ -0,0 +1,40 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const simpleGit = require('simple-git');
|
||||
|
||||
const REPO_URL = 'https://github.com/PokeMiners/game_masters.git';
|
||||
const TEMP_DIR = path.join(__dirname, 'temp-repo');
|
||||
const TARGET_FILES = ['latest/latest.json'];
|
||||
const OUTPUT_FILE = path.join(`${__dirname}/gamemaster/`, 'latest.json'); // File to expose in the package
|
||||
|
||||
(async () => {
|
||||
const git = simpleGit();
|
||||
|
||||
try {
|
||||
// Clone the repository into a temporary directory
|
||||
console.log('Cloning repository...');
|
||||
await git.clone(REPO_URL, TEMP_DIR);
|
||||
console.log('Repository cloned successfully!');
|
||||
|
||||
// Copy the desired file to the package directory
|
||||
for (const targetFile of TARGET_FILES) {
|
||||
const sourceFile = path.join(TEMP_DIR, targetFile);
|
||||
const outputFile = path.join(
|
||||
`${__dirname}/gamemaster/`,
|
||||
path.basename(targetFile)
|
||||
);
|
||||
if (fs.existsSync(sourceFile)) {
|
||||
fs.copyFileSync(sourceFile, outputFile);
|
||||
console.log(`File copied to ${outputFile}`);
|
||||
} else {
|
||||
console.error(`File not found: ${sourceFile}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up the temporary directory
|
||||
fs.rmSync(TEMP_DIR, { recursive: true, force: true });
|
||||
console.log('Temporary files cleaned up.');
|
||||
} catch (error) {
|
||||
console.error('Error during postinstall:', error);
|
||||
}
|
||||
})();
|
||||
389906
code/junk-drawer/discordbot-godispute/src/utilities/gamemaster/latest.json
Normal file
389906
code/junk-drawer/discordbot-godispute/src/utilities/gamemaster/latest.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
101456
code/junk-drawer/discordbot-godispute/src/utilities/gamemaster/pokemon.json
Normal file
101456
code/junk-drawer/discordbot-godispute/src/utilities/gamemaster/pokemon.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* @license MIT
|
||||
*
|
||||
* © 2019-2020 xfanatical.com. All Rights Reserved.
|
||||
*
|
||||
* @since 1.1.2 interface fix
|
||||
* @since 1.1.1 Optimize performance (continued)
|
||||
* @since 1.1.0 Optimize performance
|
||||
* @since 1.0.0 Add all edit response urls and update new urls for new submissions
|
||||
*/
|
||||
function registerNewEditResponseURLTrigger() {
|
||||
// check if an existing trigger is set
|
||||
var existingTriggerId = PropertiesService.getUserProperties().getProperty(
|
||||
'onFormSubmitTriggerID'
|
||||
);
|
||||
if (existingTriggerId) {
|
||||
var foundExistingTrigger = false;
|
||||
ScriptApp.getProjectTriggers().forEach(function (trigger) {
|
||||
if (trigger.getUniqueId() === existingTriggerId) {
|
||||
foundExistingTrigger = true;
|
||||
}
|
||||
});
|
||||
if (foundExistingTrigger) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
var trigger = ScriptApp.newTrigger('onFormSubmitEvent')
|
||||
.forSpreadsheet(SpreadsheetApp.getActive())
|
||||
.onFormSubmit()
|
||||
.create();
|
||||
PropertiesService.getUserProperties().setProperty(
|
||||
'onFormSubmitTriggerID',
|
||||
trigger.getUniqueId()
|
||||
);
|
||||
}
|
||||
function getTimestampColumn(sheet) {
|
||||
for (var i = 1; i <= sheet.getLastColumn(); i += 1) {
|
||||
if (sheet.getRange(1, i).getValue() === 'Timestamp') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
function getFormResponseEditUrlColumn(sheet) {
|
||||
var form = FormApp.openByUrl(sheet.getFormUrl());
|
||||
for (var i = 1; i <= sheet.getLastColumn(); i += 1) {
|
||||
if (sheet.getRange(1, i).getValue() === 'Form Response Edit URL') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// get the last column at which the url can be placed.
|
||||
return Math.max(sheet.getLastColumn() + 1, form.getItems().length + 2);
|
||||
}
|
||||
/**
|
||||
* params: { sheet, form, formResponse, row }
|
||||
*/
|
||||
function addEditResponseURLToSheet(params) {
|
||||
if (!params.col) {
|
||||
params.col = getFormResponseEditUrlColumn(params.sheet);
|
||||
}
|
||||
var formResponseEditUrlRange = params.sheet.getRange(params.row, params.col);
|
||||
formResponseEditUrlRange.setValue(params.formResponse.getEditResponseUrl());
|
||||
}
|
||||
function onOpen() {
|
||||
var menu = [
|
||||
{
|
||||
name: 'Add Form Edit Response URLs',
|
||||
functionName: 'setupFormEditResponseURLs'
|
||||
}
|
||||
];
|
||||
SpreadsheetApp.getActive().addMenu('Forms', menu);
|
||||
}
|
||||
function setupFormEditResponseURLs() {
|
||||
var sheet = SpreadsheetApp.getActiveSheet();
|
||||
var spreadsheet = SpreadsheetApp.getActive();
|
||||
var formURL = sheet.getFormUrl();
|
||||
if (!formURL) {
|
||||
SpreadsheetApp.getUi().alert(
|
||||
'No Google Form associated with this sheet. Please connect it from your Form.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
var form = FormApp.openByUrl(formURL);
|
||||
// setup the header if not existed
|
||||
var headerFormEditResponse = sheet.getRange(
|
||||
1,
|
||||
getFormResponseEditUrlColumn(sheet)
|
||||
);
|
||||
var title = headerFormEditResponse.getValue();
|
||||
if (!title) {
|
||||
headerFormEditResponse.setValue('Form Response Edit URL');
|
||||
}
|
||||
var timestampColumn = getTimestampColumn(sheet);
|
||||
var editResponseUrlColumn = getFormResponseEditUrlColumn(sheet);
|
||||
|
||||
var timestampRange = sheet.getRange(
|
||||
2,
|
||||
timestampColumn,
|
||||
sheet.getLastRow() - 1,
|
||||
1
|
||||
);
|
||||
var editResponseUrlRange = sheet.getRange(
|
||||
2,
|
||||
editResponseUrlColumn,
|
||||
sheet.getLastRow() - 1,
|
||||
1
|
||||
);
|
||||
if (editResponseUrlRange) {
|
||||
var editResponseUrlValues = editResponseUrlRange.getValues();
|
||||
var timestampValues = timestampRange.getValues();
|
||||
for (var i = 0; i < editResponseUrlValues.length; i += 1) {
|
||||
var editResponseUrlValue = editResponseUrlValues[i][0];
|
||||
var timestampValue = timestampValues[i][0];
|
||||
if (editResponseUrlValue === '') {
|
||||
var timestamp = new Date(timestampValue);
|
||||
if (timestamp) {
|
||||
var formResponse = form.getResponses(timestamp)[0];
|
||||
editResponseUrlValues[i][0] = formResponse.getEditResponseUrl();
|
||||
var row = i + 2;
|
||||
if (row % 10 === 0) {
|
||||
spreadsheet.toast('processing rows ' + row + ' to ' + (row + 10));
|
||||
editResponseUrlRange.setValues(editResponseUrlValues);
|
||||
SpreadsheetApp.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editResponseUrlRange.setValues(editResponseUrlValues);
|
||||
SpreadsheetApp.flush();
|
||||
}
|
||||
registerNewEditResponseURLTrigger();
|
||||
SpreadsheetApp.getUi().alert(
|
||||
'You are all set! Please check the Form Response Edit URL column in this sheet. Future responses will automatically sync the form response edit url.'
|
||||
);
|
||||
}
|
||||
function onFormSubmitEvent(e) {
|
||||
var sheet = e.range.getSheet();
|
||||
var form = FormApp.openByUrl(sheet.getFormUrl());
|
||||
var formResponse = form.getResponses().pop();
|
||||
addEditResponseURLToSheet({
|
||||
sheet: sheet,
|
||||
form: form,
|
||||
formResponse: formResponse,
|
||||
row: e.range.getRow()
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
/**
|
||||
* Helper function to save a response as a JSON file.
|
||||
*
|
||||
* @param {string} filename - The name of the JSON file to create.
|
||||
* @param {object} response - The data to save in the JSON file.
|
||||
* @param {string} [savePath] - The path to save the JSON file. Defaults to the root of the project.
|
||||
*/
|
||||
function saveResponseToJson({
|
||||
filename,
|
||||
response,
|
||||
savePath = path.resolve(__dirname, '../../docsNrefs/loggedFiles')
|
||||
}) {
|
||||
try {
|
||||
// Ensure the file has a .json extension
|
||||
if (!filename.endsWith('.json')) {
|
||||
filename += '.json';
|
||||
}
|
||||
|
||||
// Resolve the full path
|
||||
const fullPath = path.resolve(savePath, filename);
|
||||
|
||||
// Ensure the directory exists
|
||||
fs.mkdirSync(savePath, { recursive: true });
|
||||
|
||||
// Write the JSON file
|
||||
fs.writeFileSync(fullPath, JSON.stringify(response, null, 2), 'utf8');
|
||||
console.log(`File saved successfully at: ${fullPath}`);
|
||||
} catch (error) {
|
||||
console.error('Error saving JSON file:', error);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = saveResponseToJson;
|
||||
@@ -0,0 +1,11 @@
|
||||
class PokemonModel {
|
||||
constructor({ templateId, data } = {}) {
|
||||
this.stats = {
|
||||
atk: data?.stats?.atk || 0,
|
||||
def: data?.stats?.def || 0,
|
||||
hp: data?.stats?.hp || 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default PokemonModel;
|
||||
@@ -0,0 +1,9 @@
|
||||
class ParticipantModel {
|
||||
constructor(participant = {}) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.phone = phone;
|
||||
}
|
||||
}
|
||||
|
||||
export default ParticipantModel;
|
||||
@@ -0,0 +1,104 @@
|
||||
class TournamentModel {
|
||||
constructor(tournament) {
|
||||
this.id = tournament.id;
|
||||
this.name = tournament.name;
|
||||
this.url = tournament.url || null;
|
||||
this.description = tournament.description || null;
|
||||
this.tournamentType = tournament.tournament_type || null;
|
||||
this.startDate = tournament.start_at || tournament.started_at || null;
|
||||
this.endDate = tournament.completed_at || null;
|
||||
this.requireScoreAgreement = tournament.require_score_agreement || false;
|
||||
this.notifyUsersWhenMatchesOpen =
|
||||
tournament.notify_users_when_matches_open || false;
|
||||
this.createdAt = tournament.created_at || null;
|
||||
this.updatedAt = tournament.updated_at || null;
|
||||
this.state = tournament.state || null;
|
||||
this.openSignup = tournament.open_signup || false;
|
||||
this.notifyUsersWhenTournamentEnds =
|
||||
tournament.notify_users_when_the_tournament_ends || false;
|
||||
this.progressMeter = tournament.progress_meter || 0;
|
||||
this.quickAdvance = tournament.quick_advance || false;
|
||||
this.holdThirdPlaceMatch = tournament.hold_third_place_match || false;
|
||||
this.pointsForGameWin = parseFloat(tournament.pts_for_game_win) || 0.0;
|
||||
this.pointsForGameTie = parseFloat(tournament.pts_for_game_tie) || 0.0;
|
||||
this.pointsForMatchWin = parseFloat(tournament.pts_for_match_win) || 0.0;
|
||||
this.pointsForMatchTie = parseFloat(tournament.pts_for_match_tie) || 0.0;
|
||||
this.pointsForBye = parseFloat(tournament.pts_for_bye) || 0.0;
|
||||
this.swissRounds = tournament.swiss_rounds || 0;
|
||||
this.private = tournament.private || false;
|
||||
this.rankedBy = tournament.ranked_by || null;
|
||||
this.showRounds = tournament.show_rounds || false;
|
||||
this.hideForum = tournament.hide_forum || false;
|
||||
this.sequentialPairings = tournament.sequential_pairings || false;
|
||||
this.acceptAttachments = tournament.accept_attachments || false;
|
||||
this.createdByApi = tournament.created_by_api || false;
|
||||
this.creditCapped = tournament.credit_capped || false;
|
||||
this.category = tournament.category || null;
|
||||
this.hideSeeds = tournament.hide_seeds || false;
|
||||
this.predictionMethod = tournament.prediction_method || 0;
|
||||
this.predictionsOpenedAt = tournament.predictions_opened_at || null;
|
||||
this.anonymousVoting = tournament.anonymous_voting || false;
|
||||
this.maxPredictionsPerUser = tournament.max_predictions_per_user || 0;
|
||||
this.signupCap = tournament.signup_cap || null;
|
||||
this.gameId = tournament.game_id || null;
|
||||
this.participantsCount = tournament.participants_count || 0;
|
||||
this.groupStagesEnabled = tournament.group_stages_enabled || false;
|
||||
this.allowParticipantMatchReporting =
|
||||
tournament.allow_participant_match_reporting || false;
|
||||
this.teams = tournament.teams || false;
|
||||
this.checkInDuration = tournament.check_in_duration || null;
|
||||
this.startedCheckingInAt = tournament.started_checking_in_at || null;
|
||||
this.tieBreaks = tournament.tie_breaks || [];
|
||||
this.lockedAt = tournament.locked_at || null;
|
||||
this.eventId = tournament.event_id || null;
|
||||
this.publicPredictionsBeforeStartTime =
|
||||
tournament.public_predictions_before_start_time || false;
|
||||
this.ranked = tournament.ranked || false;
|
||||
this.grandFinalsModifier = tournament.grand_finals_modifier || null;
|
||||
this.predictTheLosersBracket =
|
||||
tournament.predict_the_losers_bracket || false;
|
||||
this.nonEliminationTournamentData =
|
||||
tournament.non_elimination_tournament_data || {};
|
||||
this.autoAssignStations = tournament.auto_assign_stations || null;
|
||||
this.onlyStartMatchesWithStations =
|
||||
tournament.only_start_matches_with_stations || null;
|
||||
this.registrationFee = parseFloat(tournament.registration_fee) || 0.0;
|
||||
this.registrationType = tournament.registration_type || null;
|
||||
this.splitParticipants = tournament.split_participants || false;
|
||||
this.allowedRegions = tournament.allowed_regions || [];
|
||||
this.showParticipantCountry = tournament.show_participant_country || null;
|
||||
this.programId = tournament.program_id || null;
|
||||
this.programClassificationIdsAllowed =
|
||||
tournament.program_classification_ids_allowed || null;
|
||||
this.teamSizeRange = tournament.team_size_range || null;
|
||||
this.toxic = tournament.toxic || null;
|
||||
this.useNewStyle = tournament.use_new_style || false;
|
||||
this.optionalDisplayData = tournament.optional_display_data || {};
|
||||
this.processing = tournament.processing || false;
|
||||
this.oauthApplicationId = tournament.oauth_application_id || null;
|
||||
this.hideBracketPreview = tournament.hide_bracket_preview || false;
|
||||
this.consolationMatchesTargetRank =
|
||||
tournament.consolation_matches_target_rank || null;
|
||||
this.reviewSwissPairingsBeforeStartingRounds =
|
||||
tournament.review_swiss_pairings_before_starting_rounds || false;
|
||||
this.allowIncompleteRosters = tournament.allow_incomplete_rosters || false;
|
||||
this.checkInOnsite = tournament.check_in_onsite || false;
|
||||
this.descriptionSource = tournament.description_source || null;
|
||||
this.subdomain = tournament.subdomain || null;
|
||||
this.fullChallongeUrl = tournament.full_challonge_url || null;
|
||||
this.liveImageUrl = tournament.live_image_url || null;
|
||||
this.signUpUrl = tournament.sign_up_url || null;
|
||||
this.reviewBeforeFinalizing = tournament.review_before_finalizing || false;
|
||||
this.acceptingPredictions = tournament.accepting_predictions || false;
|
||||
this.participantsLocked = tournament.participants_locked || false;
|
||||
this.gameName = tournament.game_name || null;
|
||||
this.participantsSwappable = tournament.participants_swappable || false;
|
||||
this.teamConvertable = tournament.team_convertable || false;
|
||||
this.groupStagesWereStarted = tournament.group_stages_were_started || false;
|
||||
}
|
||||
isValid() {
|
||||
return this.name && this.startDate && this.endDate;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TournamentModel;
|
||||
@@ -0,0 +1,34 @@
|
||||
const { normalizeScreenname } = require('./csvUtils');
|
||||
|
||||
/**
|
||||
* Merge RK9 participants with Challonge participants using normalized screennames.
|
||||
*/
|
||||
const mergeRK9Participants = (rk9Participants, participantsById) => {
|
||||
const normalizedRK9 = Object.fromEntries(
|
||||
Object.entries(rk9Participants).map(([key, value]) => [
|
||||
normalizeScreenname(key),
|
||||
value
|
||||
])
|
||||
);
|
||||
|
||||
Object.values(participantsById).forEach(participant => {
|
||||
const normalized = normalizeScreenname(participant.name);
|
||||
const rk9Participant = normalizedRK9[normalized];
|
||||
if (rk9Participant) {
|
||||
participant.rk9Data = rk9Participant;
|
||||
participant.printIndex =
|
||||
Object.keys(normalizedRK9).indexOf(normalized) + 1;
|
||||
}
|
||||
});
|
||||
|
||||
// Collect participants without rk9Data for reporting issues
|
||||
const issues = Object.values(participantsById).reduce((acc, participant) => {
|
||||
if (!participant.rk9Data) acc.push(participant.name);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
// Return the original participantsById object and issues
|
||||
return { participantsById, issues };
|
||||
};
|
||||
|
||||
module.exports = { mergeRK9Participants };
|
||||
@@ -0,0 +1,19 @@
|
||||
require('module-alias/register'); // Ensure this is at the top
|
||||
|
||||
const { createClient } = require('redis');
|
||||
const { redisUrl } = require('@config'); // Using alias for config
|
||||
|
||||
const redisClient = createClient({
|
||||
url: process.env.REDIS_URL
|
||||
});
|
||||
|
||||
redisClient.on('error', err => {
|
||||
console.error('Redis Client Error', err);
|
||||
});
|
||||
|
||||
(async () => {
|
||||
await redisClient.connect();
|
||||
console.log(`Connected to Redis using ${redisUrl}`);
|
||||
})();
|
||||
|
||||
module.exports = redisClient;
|
||||
@@ -0,0 +1,18 @@
|
||||
require('module-alias/register');
|
||||
|
||||
const redisClient = require('@utilities/redis/redisClient.js');
|
||||
|
||||
async function getCachedApiData(key, fetchFunction, ttl = 3600) {
|
||||
const cachedData = await redisClient.get(key);
|
||||
if (cachedData) {
|
||||
return JSON.parse(cachedData);
|
||||
}
|
||||
|
||||
const data = await fetchFunction();
|
||||
await redisClient.set(key, JSON.stringify(data), { EX: ttl });
|
||||
return data;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getCachedApiData
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function sortParticipantsBySeed(filePath) {
|
||||
// Read the JSON file
|
||||
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
||||
|
||||
// Sort participants by seed
|
||||
const sortedParticipants = data.sort(
|
||||
(a, b) => a.participant.seed - b.participant.seed
|
||||
);
|
||||
|
||||
// Log the name of each participant
|
||||
sortedParticipants.forEach(participant => {
|
||||
console.log(participant.participant.name);
|
||||
});
|
||||
}
|
||||
|
||||
// Path to the JSON file
|
||||
const filePath = path.join(
|
||||
__dirname,
|
||||
'../../__mocks__/api/challonge/participants-atl.json'
|
||||
);
|
||||
|
||||
// Call the function
|
||||
sortParticipantsBySeed(filePath);
|
||||
Reference in New Issue
Block a user