add more election types; add image overlay to simulator (wip)
This commit is contained in:
parent
1c82c1d5ca
commit
4d5dc235d1
|
@ -84,6 +84,16 @@ const commands = [
|
|||
description: 'The odds of the candidate to win in any state',
|
||||
type: ApplicationCommandOptionType.Number
|
||||
},
|
||||
{
|
||||
name: 'image_overlay',
|
||||
description: 'Overlay an image',
|
||||
type: ApplicationCommandOptionType.Attachment
|
||||
},
|
||||
{
|
||||
name: 'image_opacity',
|
||||
description: 'Image overlay opacity',
|
||||
type: ApplicationCommandOptionType.Number
|
||||
},
|
||||
...Elections[e].candidates.flatMap(c => [
|
||||
{
|
||||
name: c.party.toLowerCase().replace(/ /g, "_") + "_candidate",
|
||||
|
|
17
src/index.ts
17
src/index.ts
|
@ -72,7 +72,7 @@ if (!config.token) {
|
|||
.setDescription("API test")
|
||||
.addFields(Object.values(results[year][0].candidates).map((candidate: any) => ({
|
||||
name: `${candidate.winner ? ":white_check_mark:" : ""} ${CandidateEmojis[candidate.party] ?? ""} ${candidate.name} ${candidate.incumbent ? "(I)" : ""} (${candidate.party})`,
|
||||
value: `${results[year][0].election_type === "electoral" ? `${candidate.electoral_votes} electoral votes\n` : ""} ${candidate.votes.toLocaleString()} votes (${candidate.percent}%)`,
|
||||
value: `${results[year][0].election_type === "electoral" ? `${candidate.electoral_votes} electoral votes\n` : ""}${results[year][0].election_type === "parliament" ? `${candidate.seats_won} seats\n` : ""}${candidate.states_carried !== null && candidate.states_carried !== undefined ? `${candidate.states_carried} states carried\n` : ""}${candidate.delegates !== null && candidate.delegates !== undefined ? `${candidate.delegates} delegates\n` : ""}${candidate.votes !== null && candidate.votes !== undefined ? `${candidate.votes.toLocaleString()} votes (${candidate.percent}%)` : ""}`,
|
||||
inline: true
|
||||
})))
|
||||
.setTimestamp();
|
||||
|
@ -105,6 +105,7 @@ if (!config.token) {
|
|||
|
||||
case "simulate":
|
||||
var electionname = (i.options as CommandInteractionOptionResolver).getSubcommand();
|
||||
var overlayimage = (i.options as CommandInteractionOptionResolver).getAttachment('image_overlay');
|
||||
|
||||
var election = structuredClone(Elections[electionname]);
|
||||
for (const candidate of election.candidates) {
|
||||
|
@ -141,14 +142,24 @@ if (!config.token) {
|
|||
for (const state of Object.keys(election.states))
|
||||
election.states[state].odds[party] = odds;
|
||||
}
|
||||
var result = await MakePrediction(election);
|
||||
if (overlayimage !== null) {
|
||||
if (overlayimage.size > 5000000) {
|
||||
await i.editReply("Keep images under 5 MB please!");
|
||||
return;
|
||||
}
|
||||
if (overlayimage.contentType?.substring(0, 5) != "image") {
|
||||
await i.editReply("Invalid image!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
var result = await MakePrediction(election, overlayimage?.url);
|
||||
var embed = new EmbedBuilder()
|
||||
.setTitle(election.title)
|
||||
.setDescription(election.description.replace("$WINNER", result.winner))
|
||||
.addFields(result.candidates.map(c => {
|
||||
return {
|
||||
name: `${(result.winner === c.name ? ":white_check_mark:" : "")} ${c.name} (${c.party})`,
|
||||
value: `${election.voteType === VoteType.Electoral ? `${c.electoralVotes} electoral votes\n` : ""}${c.votes} votes (${((c.votes / result.totalVotes) * 100).toFixed(2)}%)`,
|
||||
value: `${election.voteType === VoteType.Electoral ? `${c.electoralVotes} electoral votes\n` : ""}${c.votes.toLocaleString()} votes (${((c.votes / result.totalVotes) * 100).toFixed(2)}%)`,
|
||||
inline: true
|
||||
}
|
||||
}))
|
||||
|
|
|
@ -5,7 +5,7 @@ import crypto from "crypto";
|
|||
import Election from "./election.js";
|
||||
import VoteType from './VoteType.js';
|
||||
|
||||
export function MakePrediction(election : Election) : Promise<Prediction> {
|
||||
export function MakePrediction(election : Election, overlay_image?: string) : Promise<Prediction> {
|
||||
return new Promise(async res => {
|
||||
const window = createSVGWindow();
|
||||
registerWindow(window, window.document);
|
||||
|
@ -41,6 +41,33 @@ export function MakePrediction(election : Election) : Promise<Prediction> {
|
|||
|
||||
var s = sharp(Buffer.from(draw.svg()));
|
||||
var png = await s.png().toBuffer();
|
||||
|
||||
//overlay image
|
||||
if (overlay_image !== undefined) {
|
||||
const url = await fetch(overlay_image);
|
||||
const arrayBuffer = await url.arrayBuffer();
|
||||
const overlayBuffer = Buffer.from(arrayBuffer);
|
||||
|
||||
const overlay = await sharp(overlayBuffer)
|
||||
.composite([{
|
||||
input: Buffer.from([0, 0, 0, 255]),
|
||||
raw: {
|
||||
width: 1,
|
||||
height: 1,
|
||||
channels: 4,
|
||||
},
|
||||
tile: true,
|
||||
blend: 'dest-in',
|
||||
}])
|
||||
.png()
|
||||
.toBuffer();
|
||||
|
||||
png = await sharp(png)
|
||||
.composite([{ input: overlay, blend: 'over' }])
|
||||
.png()
|
||||
.toBuffer();
|
||||
}
|
||||
|
||||
if (election.voteType === VoteType.Electoral)
|
||||
pred.winner = pred.candidates.sort((a : any, b : any) => b.electoralVotes - a.electoralVotes)[0].name;
|
||||
else if (election.voteType === VoteType.Popular)
|
||||
|
|
Loading…
Reference in a new issue