Skip to content

Instantly share code, notes, and snippets.

@pomadchin
Last active July 27, 2021 22:37
Show Gist options
  • Save pomadchin/86e61dc151fbf2be9fa9f824473071b7 to your computer and use it in GitHub Desktop.
Save pomadchin/86e61dc151fbf2be9fa9f824473071b7 to your computer and use it in GitHub Desktop.
Code to update STAC Catalog via STAC4s Client
import com.azavea.stac4s.StacItem
import com.azavea.stac4s.api.client.{ETag, SttpStacClient}
import cats.effect.{ExitCode, IO, IOApp}
import cats.syntax.option._
import eu.timepit.refined.types.string.NonEmptyString
import sttp.client3.asynchttpclient.cats.AsyncHttpClientCatsBackend
import sttp.client3.UriContext
import java.net.URI
object STACCatalogUpdate extends IOApp {
implicit class ETagOps[T](val self: T) extends AnyVal {
def etag: ETag[T] = ETag(self, NonEmptyString.unsafeFrom(self.##.toString).some)
}
implicit class StacItemOps(val self: StacItem) extends AnyVal {
def getId: NonEmptyString = NonEmptyString.unsafeFrom(self.id)
/** Convert AVIRIS FTP links into HTTPS */
def ftpToHttps(str: String): String =
if (!str.startsWith("ftp")) str
else {
val uri = new URI(str)
s"https://${uri.getHost}/avcl${uri.getPath}"
}
def ftpToFtps(str: String): String =
if (str.startsWith("ftp://")) str.replace("ftp://", "ftps://")
else str
def assetFtpToHttps: StacItem = {
val assets = self.assets
val https = assets
.get("ftp")
.map { asset =>
"https" -> asset.copy(
href = ftpToHttps(asset.href),
title = "https".some
)
}
.toMap
val nassets = (assets - "ftp") ++ https
self.copy(assets = nassets)
}
def assetFtpReflToHttps: StacItem = {
val assets = self.assets
val https = assets
.get("ftp_refl")
.map { asset =>
"https" -> asset.copy(
href = ftpToHttps(asset.href),
title = "https_refl".some
)
}
.toMap
val nassets = (assets - "ftp_refl") ++ https
self.copy(assets = nassets)
}
def assetFtpToFtps: StacItem = {
val assets = self.assets
val ftps = assets
.get("ftp")
.map { asset =>
"ftps" -> asset.copy(
href = ftpToFtps(asset.href),
title = "ftps".some
)
}
.toMap
val nassets = (assets - "ftp") ++ ftps
self.copy(assets = nassets)
}
}
def run(args: List[String]): IO[ExitCode] = {
// aviris-classic or aviris-ng
val collectionId = NonEmptyString.unsafeFrom(args.head)
AsyncHttpClientCatsBackend
.resource[IO]()
.use { backend =>
val client = SttpStacClient(backend, uri"http://localhost:9090/")
client
.items(collectionId)
.map(_.getId)
.parEvalMap(300) { itemId =>
client.item(collectionId, itemId).flatMap { eitem =>
// aviris-classic case
client.itemUpdate(collectionId, eitem.copy(eitem.entity.assetFtpToHttps))
// client.itemUpdate(collectionId, eitem.copy(eitem.entity.assetFtpReflToHttps))
// aviris-ng case
// client.itemUpdate(collectionId, eitem.copy(eitem.entity.assetFtpToFtps))
}
}
.compile
.drain
}
.as(ExitCode.Success)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment