Write an xkcd feed bot

1

The new xkcd feed bot room gave me an idea for a simple challenge.

Your code will have to monitor the xkcd website and output all the new comics to the user.

Specs

  • When first run it should just sit around waiting.
  • Then, when randall posts a new comic, within a minute, it should display the new comic in any of our usual standards for images (display, save, etc.)
  • If the comic is interactive and not a simple image, then print out the string "interactive comic".
  • This does not include the comics which are an image inside a link, those still have to be displayed normally.
  • After displaying the image, it should go back to waiting around for the next update.
  • Your program cannot access any sites except http://xkcd.com

This is , so shortest code in bytes wins!

Maltysen

Posted 2016-08-31T18:28:12.513

Reputation: 25 023

Link to the feed bot room: https://chat.stackexchange.com/rooms/44753/xkcd

– TuxCrafting – 2016-08-31T18:40:17.483

"If the comic is interactive and not a simple image" then how do we know? At present this seems underspecified. – Peter Taylor – 2016-08-31T18:46:20.650

A decent strategy would be to only check during the two to three hours around midnight eastern US time on M/W/F, but that would miss those comics he occasionally posts on other days (like April Fools and those week-long series he did in the past). – Mego – 2016-08-31T18:47:23.437

@PeterTaylor If it's a single image, there will be a permalink to the image on the page. If not, there won't be. You could also test to see if the main content pane contains an <img> tag. – Mego – 2016-08-31T18:48:51.110

@PeterTaylor there will be an image tag in the correct position, not an iframe or whatever else he uses – Maltysen – 2016-08-31T18:51:43.633

Are we allowed to use RSS feed libraries such as feedparser? – Beta Decay – 2016-08-31T20:43:20.297

Answers

4

PowerShell v2+ & Default Browser, 215 217 bytes

$l=date;for(){if(($x=([xml](iwr xkcd.com/rss.xml)).rss.channel.item[0]).pubdate-ge$l){if(($y=$x.description)-match'img src'){saps ($y-replace'<img src="'-replace'" .*')}else{echo "interactive comic"}}$l=date}

WARNING: Running this as-is will likely make Randall very mad at you, due to the high frequency of calls to the RSS feed ... so, y'know, don't do that. (See below for an alternate version that can be used in a one-off manner)

Sets the $last time we displayed a comic to the result of Get-Date. Then, enter an infinite for loop.

Each iteration, we iwr (alias for Invoke-WebRequest) the RSS feed for the site. That's parsed as [xml] (yes, PowerShell can cast as XML), and the .rss.channel.item[0] thereof (i.e., the newest) is stored in $x. If the .pubDate is -ge$l (i.e., newer than the last comic we showed), we have a new comic to display.

So, we first check the .description field (saved in $y), to see if it matches img src. If so, we parse out the img from $y, and feed that to saps (alias for Start-Process). Since it's a URI, this relies on Windows' default behavior for "executing" a URI, that is, it opens the default browser to that location. (If this is too cheaty, let me know and we can iwr down the actual image and save it.)

Otherwise, we echo out that we've got an interactive comic.

In either case, we update our $l date to "now" since we just displayed a comic.

Saved 7 bytes thanks to Matt for reminding me that http:// can be implied


"Safe" version that executes just once and displays the latest comic

$l=(date).AddDays(-3);if(($x=([xml](iwr http://xkcd.com/rss.xml)).rss.channel.item[0]).pubdate-ge$l){if(($y=$x.description)-match'img src'){saps ($y-replace'<img src="'-replace'" .*')}else{echo "interactive comic"}}

You can run this one safely to see how the logic works. It'll only execute once and only display the latest comic.

AdmBorkBork

Posted 2016-08-31T18:28:12.513

Reputation: 41 581

Why did you use echo here? echo "interactive comic"? Or am I not seeing the nested parentheses and you are capturing data somewhere else? Also iwr xkcd.com/rss.xml seems to work – Matt – 2016-08-31T23:40:33.350

@Matt When doing testing locally, I was getting inconsistent results without an explicit echo -- sometimes the output wouldn't update until the next time the XML updated, and then two "interactive comic"s would be output simultaneously. -- Thanks for the golf on http://, I keep forgetting that can be implied. – AdmBorkBork – 2016-09-01T12:25:20.450

I'd like to point out that you could probably DDoS xkcd with this. – Mathime – 2016-09-01T18:47:44.377

@Mathime I don't know if it'd reach DDoS levels, but it would definitely be a Bad Thing™, hence my disclaimer. – AdmBorkBork – 2016-09-01T18:50:09.923