mirror of
https://github.com/CompeyDev/fxtwitter-docker.git
synced 2025-04-10 21:10:54 +01:00
Changed poll handler to card handler
This commit is contained in:
parent
502fb7256a
commit
5c5fef873d
4 changed files with 117 additions and 92 deletions
97
src/card.ts
Normal file
97
src/card.ts
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
let barLength = 36;
|
||||||
|
|
||||||
|
export const calculateTimeLeft = (date: Date) => {
|
||||||
|
const now = new Date();
|
||||||
|
const diff = date.getTime() - now.getTime();
|
||||||
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||||||
|
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||||
|
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
||||||
|
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
|
||||||
|
return { days, hours, minutes, seconds };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const calculateTimeLeftString = (date: Date) => {
|
||||||
|
const { days, hours, minutes, seconds } = calculateTimeLeft(date);
|
||||||
|
const daysString = days > 0 ? `${days} ${days === 1 ? 'day left' : 'days left'}` : '';
|
||||||
|
const hoursString =
|
||||||
|
hours > 0 ? `${hours} ${hours === 1 ? 'hour left' : 'hours left'}` : '';
|
||||||
|
const minutesString =
|
||||||
|
minutes > 0 ? `${minutes} ${minutes === 1 ? 'minute left' : 'minutes left'}` : '';
|
||||||
|
const secondsString =
|
||||||
|
seconds > 0 ? `${seconds} ${seconds === 1 ? 'second left' : 'seconds left'}` : '';
|
||||||
|
return daysString || hoursString || minutesString || secondsString || 'Final results';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const renderCard = async (card: TweetCard, headers: string[], userAgent: string = ''): Promise<string> => {
|
||||||
|
let str = '\n\n';
|
||||||
|
const values = card.binding_values;
|
||||||
|
|
||||||
|
console.log('rendering card on ', card);
|
||||||
|
|
||||||
|
// Telegram's bars need to be a lot smaller to fit its bubbles
|
||||||
|
if (userAgent.indexOf('Telegram') > -1) {
|
||||||
|
barLength = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
let choices: { [label: string]: number } = {};
|
||||||
|
let totalVotes = 0;
|
||||||
|
let timeLeft = '';
|
||||||
|
|
||||||
|
/* TODO: make poll code cleaner */
|
||||||
|
if (typeof values !== 'undefined') {
|
||||||
|
if (typeof values.choice1_count !== 'undefined' &&
|
||||||
|
typeof values.choice2_count !== 'undefined') {
|
||||||
|
if (typeof values.end_datetime_utc !== 'undefined') {
|
||||||
|
const date = new Date(values.end_datetime_utc.string_value);
|
||||||
|
timeLeft = calculateTimeLeftString(date);
|
||||||
|
}
|
||||||
|
choices[values.choice1_label?.string_value || ''] = parseInt(
|
||||||
|
values.choice1_count.string_value
|
||||||
|
);
|
||||||
|
totalVotes += parseInt(values.choice1_count.string_value);
|
||||||
|
choices[values.choice2_label?.string_value || ''] = parseInt(
|
||||||
|
values.choice2_count.string_value
|
||||||
|
);
|
||||||
|
totalVotes += parseInt(values.choice2_count.string_value);
|
||||||
|
if (typeof values.choice3_count !== 'undefined') {
|
||||||
|
choices[values.choice3_label?.string_value || ''] = parseInt(
|
||||||
|
values.choice3_count.string_value
|
||||||
|
);
|
||||||
|
totalVotes += parseInt(values.choice3_count.string_value);
|
||||||
|
}
|
||||||
|
if (typeof values.choice4_count !== 'undefined') {
|
||||||
|
choices[values.choice4_label?.string_value || ''] = parseInt(
|
||||||
|
values.choice4_count.string_value
|
||||||
|
);
|
||||||
|
totalVotes += parseInt(values.choice4_count.string_value);
|
||||||
|
|
||||||
|
for (const [label, votes] of Object.entries(choices)) {
|
||||||
|
// render bar
|
||||||
|
const bar = '█'.repeat(Math.round((votes / totalVotes || 0) * barLength));
|
||||||
|
str += `${bar}
|
||||||
|
${label} (${Math.round((votes / totalVotes || 0) * 100)}%)
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
str += `\n${totalVotes} votes · ${timeLeft}`;
|
||||||
|
|
||||||
|
console.log(str);
|
||||||
|
}
|
||||||
|
} else if (typeof values.player_url !== "undefined") {
|
||||||
|
headers.push(
|
||||||
|
`<meta name="twitter:player" content="${values.player_url.string_value}">`,
|
||||||
|
`<meta name="twitter:player:width" content="${values.player_width?.string_value || "1280"}">`,
|
||||||
|
`<meta name="twitter:player:height" content="${values.player_height?.string_value || "720"}">`,
|
||||||
|
`<meta property="og:type" content="video.other">`,
|
||||||
|
`<meta property="og:video:url" content="${values.player_url.string_value}">`,
|
||||||
|
`<meta property="og:video:secure_url" content="${values.player_url.string_value}">`,
|
||||||
|
`<meta property="og:video:type" content="text/html">`,
|
||||||
|
`<meta property="og:video:width" content="${values.player_width?.string_value || "1280"}">`,
|
||||||
|
`<meta property="og:video:height" content="${values.player_height?.string_value || "720"}">`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return str;
|
||||||
|
};
|
89
src/poll.ts
89
src/poll.ts
|
@ -1,89 +0,0 @@
|
||||||
let barLength = 36;
|
|
||||||
|
|
||||||
export const calculateTimeLeft = (date: Date) => {
|
|
||||||
const now = new Date();
|
|
||||||
const diff = date.getTime() - now.getTime();
|
|
||||||
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
||||||
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
||||||
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
|
||||||
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
|
|
||||||
return { days, hours, minutes, seconds };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const calculateTimeLeftString = (date: Date) => {
|
|
||||||
const { days, hours, minutes, seconds } = calculateTimeLeft(date);
|
|
||||||
const daysString = days > 0 ? `${days} ${days === 1 ? 'day left' : 'days left'}` : '';
|
|
||||||
const hoursString =
|
|
||||||
hours > 0 ? `${hours} ${hours === 1 ? 'hour left' : 'hours left'}` : '';
|
|
||||||
const minutesString =
|
|
||||||
minutes > 0 ? `${minutes} ${minutes === 1 ? 'minute left' : 'minutes left'}` : '';
|
|
||||||
const secondsString =
|
|
||||||
seconds > 0 ? `${seconds} ${seconds === 1 ? 'second left' : 'seconds left'}` : '';
|
|
||||||
return daysString || hoursString || minutesString || secondsString || 'Final results';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const renderPoll = async (card: TweetCard, userAgent: string = ''): Promise<string> => {
|
|
||||||
let str = '\n\n';
|
|
||||||
const values = card.binding_values;
|
|
||||||
|
|
||||||
console.log('rendering poll on ', card);
|
|
||||||
|
|
||||||
// Telegram's bars need to be a lot smaller to fit its bubbles
|
|
||||||
if (userAgent.indexOf('Telegram') > -1) {
|
|
||||||
barLength = 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
let choices: { [label: string]: number } = {};
|
|
||||||
let totalVotes = 0;
|
|
||||||
let timeLeft = '';
|
|
||||||
|
|
||||||
if (typeof values !== 'undefined' && typeof values.end_datetime_utc !== 'undefined') {
|
|
||||||
const date = new Date(values.end_datetime_utc.string_value);
|
|
||||||
timeLeft = calculateTimeLeftString(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: make this cleaner */
|
|
||||||
if (
|
|
||||||
typeof values !== 'undefined' &&
|
|
||||||
typeof values.choice1_count !== 'undefined' &&
|
|
||||||
typeof values.choice2_count !== 'undefined'
|
|
||||||
) {
|
|
||||||
choices[values.choice1_label?.string_value || ''] = parseInt(
|
|
||||||
values.choice1_count.string_value
|
|
||||||
);
|
|
||||||
totalVotes += parseInt(values.choice1_count.string_value);
|
|
||||||
choices[values.choice2_label?.string_value || ''] = parseInt(
|
|
||||||
values.choice2_count.string_value
|
|
||||||
);
|
|
||||||
totalVotes += parseInt(values.choice2_count.string_value);
|
|
||||||
if (typeof values.choice3_count !== 'undefined') {
|
|
||||||
choices[values.choice3_label?.string_value || ''] = parseInt(
|
|
||||||
values.choice3_count.string_value
|
|
||||||
);
|
|
||||||
totalVotes += parseInt(values.choice3_count.string_value);
|
|
||||||
}
|
|
||||||
if (typeof values.choice4_count !== 'undefined') {
|
|
||||||
choices[values.choice4_label?.string_value || ''] = parseInt(
|
|
||||||
values.choice4_count.string_value
|
|
||||||
);
|
|
||||||
totalVotes += parseInt(values.choice4_count.string_value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('no choices found', values);
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
console.log(choices);
|
|
||||||
|
|
||||||
for (const [label, votes] of Object.entries(choices)) {
|
|
||||||
// render bar
|
|
||||||
const bar = '█'.repeat(Math.round((votes / totalVotes || 0) * barLength));
|
|
||||||
str += `${bar}
|
|
||||||
${label} (${Math.round((votes / totalVotes || 0) * 100)}%)
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
str += `\n${totalVotes} votes · ${timeLeft}`;
|
|
||||||
|
|
||||||
console.log(str);
|
|
||||||
return str;
|
|
||||||
};
|
|
|
@ -3,7 +3,7 @@ import { fetchUsingGuest } from './fetch';
|
||||||
import { Html } from './html';
|
import { Html } from './html';
|
||||||
import { linkFixer } from './linkFixer';
|
import { linkFixer } from './linkFixer';
|
||||||
import { colorFromPalette } from './palette';
|
import { colorFromPalette } from './palette';
|
||||||
import { renderPoll } from './poll';
|
import { renderCard } from './card';
|
||||||
import { handleQuote } from './quote';
|
import { handleQuote } from './quote';
|
||||||
import { sanitizeText } from './utils';
|
import { sanitizeText } from './utils';
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ export const handleStatus = async (
|
||||||
let authorText = 'Twitter';
|
let authorText = 'Twitter';
|
||||||
|
|
||||||
if (tweet.card) {
|
if (tweet.card) {
|
||||||
text += await renderPoll(tweet.card, userAgent);
|
text += await renderCard(tweet.card, headers, userAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
text = linkFixer(tweet, text);
|
text = linkFixer(tweet, text);
|
||||||
|
@ -129,7 +129,19 @@ export const handleStatus = async (
|
||||||
|
|
||||||
const processMedia = (media: TweetMedia) => {
|
const processMedia = (media: TweetMedia) => {
|
||||||
if (media.type === 'photo') {
|
if (media.type === 'photo') {
|
||||||
headers.push(`<meta name="twitter:image" content="${media.media_url_https}"/>`);
|
headers.push(
|
||||||
|
`<meta name="twitter:image" content="${media.media_url_https}"/>`,
|
||||||
|
`<meta property="og:image" content="${media.media_url_https}"/>`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (media.original_info?.width && media.original_info?.height) {
|
||||||
|
headers.push(
|
||||||
|
`<meta name="twitter:image:width" content="${media.original_info.width}"/>`,
|
||||||
|
`<meta name="twitter:image:height" content="${media.original_info.height}"/>`,
|
||||||
|
`<meta name="og:image:width" content="${media.original_info.width}"/>`,
|
||||||
|
`<meta name="og:image:height" content="${media.original_info.height}"/>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!pushedCardType) {
|
if (!pushedCardType) {
|
||||||
headers.push(`<meta name="twitter:card" content="summary_large_image"/>`);
|
headers.push(`<meta name="twitter:card" content="summary_large_image"/>`);
|
||||||
|
|
|
@ -76,6 +76,11 @@ type TweetCard = {
|
||||||
counts_are_final?: CardValue;
|
counts_are_final?: CardValue;
|
||||||
duration_minutes?: CardValue;
|
duration_minutes?: CardValue;
|
||||||
end_datetime_utc?: CardValue;
|
end_datetime_utc?: CardValue;
|
||||||
|
|
||||||
|
player_url?: CardValue;
|
||||||
|
player_width?: CardValue;
|
||||||
|
player_height?: CardValue;
|
||||||
|
title?: CardValue;
|
||||||
};
|
};
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue