Warning: session_start(): open(/var/lib/php/sessions/sess_mp8f6j6efjdqjuvi4093aac1hq, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
concept CLotteryResult {
S date;
L numbers;
S jackpot;
[stdToString]
}
standardBot1 LotteryBot {
long resultsChannelID;
init {
dbIndexing(CLotteryResult, 'date);
onDiscordStarted(r { doEveryHourAndNow(r grabResults) });
}
allServers {
S lotteryURL = "https://www.lotteryusa.com/missouri/show-me-cash/";
void grabResults enter {
LotteryResult r = scrapeLotteryResults(loadPage(lotteryURL));
if (r == null) ret with print("No lottery results!?");
CLotteryResult lr, bool isNew = unpair uniq2(CLotteryResult, date := r.date);
copyFields(r, lr);
change();
print("Grabbed: " + lr + ", new: " + isNew);
if (isNew) postLastResult_allServers();
}
void postLastResult_allServers {
L guilds = discord.getGuilds();
for (Guild guild : guilds) pcall {
ByServer bs = getByServer(guild);
if (bs != null)
bs.postLastResult();
}
}
S renderResult(CLotteryResult r) {
ret formatCSVLine(flattenList2(r.date, r.numbers, r.jackpot));
}
CLotteryResult latestResult() {
ret first(conceptsSortedByFieldDesc CLotteryResult('date));
}
}
processSimplified {
optPar Message msg;
Message.Attachment attachment = msg == null ? null : first(msg.getAttachments());
if (attachment != null && authed(_)) {
File file = prepareCacheProgramFile(guildID + "/" + attachment.getFileName());
print("Downloading attachment: " + file);
deleteFile(file);
if (!attachment.download(file)) ret "Couldn't download attachment";
S contents = loadTextFile(file);
contents = replaceAll(contents, "^,+\r?\n", "");
if (!startsWith(contents, "\"") && !startsWithDigit(contents)) null; //ret "Attachment is not a CSV text file";
LLS l = parseCSV_unquote_noHeader(contents);
l = map(l, row -> l(row) != 7 ? row
: spliceList(row, 1, 6, ll(joinWithComma(subList(row, 1, 6)))));
Set lengths = mapToSet(lambda1 l, l);
if (neq(lengths, litset(3))) ret "CSV does not have 3 columns throughout";
for (LS line : l) {
S date = first(line);
if (!regexpMatches(regexpYMDminus(), date)) ret "Bad date: " + backtickQuote(date);
CLotteryResult lr = uniq(CLotteryResult, +date);
cset(lr, numbers := map parseInt(tok_splitAtComma(second(line))), jackpot := third(line));
}
ret "OK, " + nResults(l) + " imported";
}
S s0 = s;
s = dropMyPrefixOpt(s);
if "clear lottery results" {
try answer checkAuth(_);
ret "OK, " + nResults(deleteConcepts(CLotteryResult)) + " deleted";
}
if "lottery|lottery results|show me cash" {
optPar long channelID;
L l = sortedByFieldDesc date(list(CLotteryResult));
if (empty(l)) ret "No lottery results gathered yet";
S date1 = first(l).date;
S text = windowsLineBreaks(mapToLines_rtrim(l, lambda1 renderResult));
uploadFileInChannel(channelID,
toUtf8(text),
"lottery-" + date1 + ".csv", null, null);
null;
}
if "Post lottery here" {
long channelID = longPar channelID(_);
if (channelID == 0) ret "Please do this in a channel";
if (resultsChannelID != channelID) {
resultsChannelID = channelID;
change();
}
doAfter(2.0, r postLastResult);
ret "OK, I will post new lottery results in this channel. Type `stop posting lottery` to stop.";
}
if "stop posting lottery" {
resultsChannelID = 0;
change();
ret "OK";
}
if null (s = dropMyPrefixOrNull(s0)) null;
if "help" {
ret [[
@me `lottery` - download latest lottery results as CSV
@me `clear lottery results` - delete all lottery results
To add lottery results, just upload a CSV file.
]].replace("@me", atSelf());
}
}
void postLastResult {
if (resultsChannelID != 0 && latestResult() != null)
postInChannel(resultsChannelID, "Here are the latest lottery results: " + renderResult(latestResult()));
}
}