-
-
Save SethTisue/3a5a04e5054fc5b75011 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env sbt -Dsbt.version=0.13.9 -Dsbt.main.class=sbt.ScriptMain --error | |
// This script uses the Stack Exchange API to retrieve the most recent | |
// Stack Overflow questions tagged with "netlogo" and print their | |
// titles and URLs. The output is suitable for posting to the | |
// netlogo-users group on Yahoo, in messages such as | |
// http://netlogo-users.18673.x6.nabble.com/NetLogo-Q-A-on-Stack-Overflow-Mar-14-19-tp5004602.html | |
/*** | |
scalaVersion := "2.11.7" | |
onLoadMessage := "" | |
scalacOptions ++= Seq( | |
"-deprecation", "-unchecked", "-feature", "-Xfatal-warnings") | |
libraryDependencies ++= Seq( | |
"net.databinder.dispatch" %% "dispatch-core" % "0.11.2", | |
"org.json4s" %% "json4s-native" % "3.2.11", | |
"org.slf4j" % "slf4j-nop" % "1.7.10", | |
"org.apache.commons" % "commons-lang3" % "3.3.2" | |
) | |
*/ | |
import dispatch._, Defaults._ | |
import org.json4s.JsonAST._ | |
import org.json4s.native.JsonParser | |
import java.util.zip.GZIPInputStream | |
import org.apache.commons.lang3.StringEscapeUtils.{ unescapeHtml4 => unescape } | |
case class Question(name: String, url: String) | |
object Question { | |
def fromJson(j: JValue): Question = { | |
val JString(title) = j \ "title" | |
val JString(link) = j \ "share_link" | |
Question(unescape(title), link) | |
} | |
} | |
// | |
// Notes on our use of Dispatch: | |
// | |
// - By policy, Stack Exchange always responds with compressed data, | |
// so it isn't strictly necessary for us to set Accept-Encoding in our | |
// request, but at http://api.stackexchange.com/docs/compression | |
// they recommend doing it anyway. | |
// | |
// - The support for gzip-encoded responses that existed in Dispatch | |
// 0.8 seems not to exist in 0.9 and subsequent versions, so we | |
// bypass Dispatch's json4s integration, and bypass Dispatch's | |
// Future-based APIs, too and, drop down to dealing with InputStream | |
// directly. At least, that's the only way forward I was able to | |
// find. See https://github.com/dispatch/reboot/issues/52 | |
// | |
// Notes on our use of the Stack Exchange API: | |
// | |
// - We want the "share" URL not the regular URL of the questions | |
// (it's no big deal, but IMO the regular ones are too long), | |
// but the share_link field isn't included in the default filter. | |
// So I made a new filter with the [edit] link near the bottom of | |
// http://api.stackexchange.com/docs/questions, checking the | |
// share_link box. When you make an edit like this the page shows | |
// a string you can use to refer to the filter you just made; so | |
// that's where "!9WgJf_3fM" came from. | |
// | |
val host = :/("api.stackexchange.com").secure <:< | |
Map("Accept-Encoding" -> "gzip") | |
val base = host / "2.2" / "questions" | |
def getQuestions(): List[Question] = { | |
val req = base <<? Map("site" -> "stackoverflow", | |
"tagged" -> "netlogo", | |
"sort" -> "creation", | |
"order" -> "desc", | |
"filter" -> "!9WgJf_3fM") | |
// println(req.toRequest.getRawUrl) // useful for debugging | |
val stream = Http(req OK as.Response(_.getResponseBodyAsStream)).apply | |
val result = | |
JsonParser.parse( | |
new java.io.InputStreamReader( | |
new GZIPInputStream(stream))) | |
val JArray(items) = result \ "items" | |
for (item <- items) | |
yield Question.fromJson(item) | |
} | |
println( | |
"""|Stack Overflow is a popular Q&A site for getting help with coding | |
|in all languages, including NetLogo. NetLogo questions are at: | |
|http://stackoverflow.com/questions/tagged/netlogo | |
| | |
|Here are some recent questions and answers. | |
| | |
|""".stripMargin) | |
for(Question(title, link) <- getQuestions()) { | |
println(title) | |
println(link) | |
println() | |
} | |
Http.shutdown() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment