package Assignment8 import net.liftweb.json import net.liftweb.json.DefaultFormats import java.net.URI import scala.concurrent.duration.Duration import scala.concurrent.{Await, Future} import scala.sys.process._ import scala.util.{Failure, Success} object Ex2 extends App { implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global implicit val formats: DefaultFormats.type = DefaultFormats case class Coin(id: String, icon: String, name: String, symbol: String, rank: Int, price: Double, priceBtc: Double, volume: Double, marketCap: Double, availableSupply: Double, totalSupply: Double, fullyDilutedValuation: Double, priceChange1h: Double, priceChange1d: Double, priceChange1w: Double, redditUrl: String, websiteUrl: String, twitterUrl: String, explorers: List[String]) case class Currency(name: String, rate: Double, symbol: String, imageUrl: String) val BITCOIN_TO_USD: String = "https://openapiv1.coinstats.app/coins/bitcoin" val USD_TO_CHF: String = "https://openapiv1.coinstats.app/fiats" private val API_KEY: String = sys.env.getOrElse("OPENAPI_KEY", "") def getUrl(url: String): Future[String] = { Future { val uri: URI = new URI(url) val cmd: String = "curl -s -H 'X-API-KEY: " + API_KEY + "' " + uri.toString cmd.!! } } def extractBitcoinToUSDRate(jsonStr: String): Double = { val data: Coin = json.parse(jsonStr).extract[Coin] return data.price } def extractUSDToCHFRate(jsonStr: String): Double = { val data: List[Currency] = json.parse(jsonStr).extract[List[Currency]] return data.find(currency => currency.name == "CHF") .map(currency => currency.rate) .get } def getBitcoinToUSD: Future[Double] = { getUrl(BITCOIN_TO_USD) map extractBitcoinToUSDRate } def getUSDToCHF: Future[Double] = { getUrl(USD_TO_CHF) map extractUSDToCHFRate } val f: Future[Double] = for { btc2usd <- getBitcoinToUSD usd2chf <- getUSDToCHF } yield btc2usd * usd2chf f onComplete { case Success(value) => println(s"1 BTC == $value CHF") case Failure(e) => println(s"An error occurred: $e") } Await.ready(f, Duration.Inf) }