a little hacky but it works

This commit is contained in:
Will Freeman
2024-09-30 21:35:40 -05:00
parent acfff6bb40
commit 6d8b3ba42f
7 changed files with 372 additions and 11 deletions
@@ -1,6 +1,7 @@
package me.deflock.shotgun
import org.apache.pekko
import org.apache.pekko.http.scaladsl.model.headers.{HttpOrigin, HttpOriginRange, `Access-Control-Allow-Origin`}
import pekko.actor.typed.ActorSystem
import pekko.actor.typed.scaladsl.Behaviors
import pekko.http.scaladsl.Http
@@ -17,16 +18,32 @@ object ShotgunServer {
implicit val system: ActorSystem[Any] = ActorSystem(Behaviors.empty, "my-system")
implicit val executionContext: ExecutionContextExecutor = system.executionContext
val route =
path("oauth2" / "callback") {
get {
parameters(Symbol("code").?) { (code) =>
complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to Pekko HTTP</h1><p><b>Code: " + code.getOrElse("None") + "</b></p>"))
val routes = {
concat {
path("oauth2" / "callback") {
get {
parameters(Symbol("code").?) { (code) =>
complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to Pekko HTTP</h1><p><b>Code: " + code.getOrElse("None") + "</b></p>"))
}
}
}
path("alpr") {
get {
parameters("minLat".as[Double], "minLng".as[Double], "maxLat".as[Double], "maxLng".as[Double]) { (minLat, minLng, maxLat, maxLng) =>
val client = new services.OverpassClient() // TODO: make this global
val bBox = services.BoundingBox(minLat, minLng, maxLat, maxLng)
onSuccess(client.getALPRs(bBox)) { json =>
respondWithHeader(`Access-Control-Allow-Origin`.*) {
complete(HttpEntity(ContentTypes.`application/json`, json.toString()))
}
}
}
}
}
}
}
val bindingFuture = Http().newServerAt("localhost", 8080).bind(route)
val bindingFuture = Http().newServerAt("localhost", 8080).bind(routes)
println(s"Server now online. Please navigate to http://localhost:8080\nPress RETURN to stop...")
StdIn.readLine() // let it run until user presses return
@@ -0,0 +1,38 @@
package services
import org.apache.pekko
import pekko.actor.typed.ActorSystem
import pekko.actor.typed.scaladsl.Behaviors
import pekko.http.scaladsl.Http
import pekko.http.scaladsl.model._
import pekko.http.scaladsl.unmarshalling.Unmarshal
import io.circe._
import io.circe.parser._
import org.apache.pekko.http.scaladsl.client.RequestBuilding._
import scala.concurrent.duration.DurationInt
import scala.concurrent.{ExecutionContextExecutor, Future}
import scala.util.{Failure, Success}
case class BoundingBox(minLat: Double, minLng: Double, maxLat: Double, maxLng: Double)
class OverpassClient(implicit val system: ActorSystem[_], implicit val executionContext: ExecutionContextExecutor) {
val baseUrl = "https://overpass-api.de/api/interpreter"
def getALPRs(bBox: BoundingBox): Future[Json] = {
val query = s"""[out:json][bbox:${bBox.minLat},${bBox.minLng},${bBox.maxLat},${bBox.maxLng}];node["man_made"="surveillance"]["surveillance:type"="ALPR"];out body;>;out skel qt;"""
val formData = FormData("data" -> query).toEntity
val request = HttpRequest(
method = HttpMethods.POST,
uri = baseUrl,
entity = formData
)
Http().singleRequest(request).flatMap { response =>
response.entity.toStrict(5.seconds).flatMap { entity =>
Unmarshal(entity).to[String].map(parse(_).getOrElse(Json.Null))
}
}
}
}