com.baulsupp.oksocial.output.ConsoleHandler.kt Maven / Gradle / Ivy
package com.baulsupp.oksocial.output
import com.baulsupp.oksocial.output.iterm.ItermOutputHandler
import com.baulsupp.oksocial.output.iterm.itermIsAvailable
import com.baulsupp.oksocial.output.process.exec
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.cbor.CBORFactory
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule
import kotlinx.coroutines.experimental.runBlocking
import okio.BufferedSource
import okio.Okio
import java.awt.Desktop
import java.io.BufferedInputStream
import java.io.ByteArrayInputStream
import java.io.File
import java.io.IOException
import java.net.URI
import java.net.UnknownHostException
import java.util.Arrays.asList
import java.util.concurrent.TimeUnit
import java.util.logging.Level
import java.util.logging.Logger
import javax.sound.sampled.AudioSystem
import javax.sound.sampled.LineEvent
open class ConsoleHandler(protected var responseExtractor: ResponseExtractor) : OutputHandler {
val jqInstalled by lazy {
runBlocking {
isInstalled("jq")
}
}
override suspend fun showError(message: String?, e: Throwable?) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.WARNING, message, e)
}
if (e is UsageException) {
System.err.println(e.message)
} else if (e is UnknownHostException && e.cause == null) {
if (message != null) {
System.err.print("$message: ")
}
System.err.println(e.toString())
} else {
if (message != null) {
System.err.println(message)
}
e?.printStackTrace()
}
}
override suspend fun showOutput(response: R) {
var mimeType = responseExtractor.mimeType(response)
var source = responseExtractor.source(response)
if (mimeType != null) {
if (isCbor(mimeType)) {
source = convertCborToJson(source)
mimeType = "application/json"
}
if (isMedia(mimeType)) {
openPreview(response)
return
} else if (isAudio(mimeType)) {
playAudio(response)
return
} else if (jqInstalled && isJson(mimeType)) {
prettyPrintJson(source)
return
}
}
// TODO support a nice hex mode for binary files
source.writeToSink(systemOut)
println("")
}
private fun cborMapper(): ObjectMapper {
return ObjectMapper(CBORFactory()).registerModule(ParameterNamesModule())
.registerModule(Jdk8Module())
.registerModule(JavaTimeModule())
}
private fun jsonMapper(): ObjectMapper {
return ObjectMapper().registerModule(ParameterNamesModule())
.registerModule(Jdk8Module())
.registerModule(JavaTimeModule())
}
private fun convertCborToJson(source: BufferedSource): BufferedSource {
// TODO consider adding streaming
val cborMapper = cborMapper()
val map = cborMapper.readValue(source.inputStream(),
object : TypeReference