Last active
March 12, 2018 10:50
-
-
Save halcat0x15a/60fc5981b37f5d08e372016e356fb725 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
package starlight | |
import akka.actor.Actor | |
import akka.actor.ActorSystem | |
import akka.actor.Props | |
import akka.stream.ActorMaterializer | |
import akka.stream.scaladsl.FileIO | |
import akka.stream.scaladsl.Source | |
import java.awt.RenderingHints | |
import java.awt.image.BufferedImage | |
import java.net.URL | |
import java.nio.file.Files | |
import java.nio.file.Path | |
import java.nio.file.Paths | |
import java.nio.file.StandardOpenOption | |
import javax.imageio.ImageIO | |
import play.api.libs.json.JsValue | |
import play.api.libs.ws.ahc.AhcWSClient | |
import play.api.mvc.MultipartFormData | |
import scala.collection.JavaConverters._ | |
import scala.concurrent.ExecutionContext | |
import scala.concurrent.Future | |
import scala.util.Failure | |
object Main { | |
def main(args: Array[String]): Unit = { | |
val accessToken = args(0) | |
val channel = args(1) | |
implicit val system = ActorSystem() | |
system.registerOnTermination { | |
System.exit(0) | |
} | |
implicit val materializer = ActorMaterializer() | |
val wsClient = AhcWSClient() | |
ImageIO.setUseCache(false) | |
val urls = Paths.get("urls.txt") | |
val files = if (Files.exists(urls)) { | |
Files.lines(urls).iterator.asScala.map { url => | |
Paths.get(url).getFileName.toString | |
}.toSet | |
} else { | |
Set.empty[String] | |
} | |
val writer = system.actorOf(Props(classOf[FileWriter], urls)) | |
import system.dispatcher | |
call(wsClient, files) { result => | |
val title = s"[${result.title}]${result.name}" | |
upload(wsClient, accessToken, channel, result.id, title, result.image).map { url => | |
writer ! url | |
} | |
}.andThen { | |
case Failure(e) => e.printStackTrace() | |
}.andThen { | |
case _ => wsClient.close() | |
}.andThen { | |
case _ => system.terminate() | |
} | |
} | |
def call(wsClient: AhcWSClient, files: Set[String])(f: KiraraResult => Future[Unit])(implicit ec: ExecutionContext) = { | |
wsClient.url("https://starlight.kirara.ca/api/v1/list/card_t").get().flatMap { response ⇒ | |
Future.traverse((response.json \ "result").as[Seq[JsValue]]) { data => | |
val id = (data \ "id").as[Int] | |
val rarity = (data \ "rarity_dep" \ "rarity").as[Int] | |
if (rarity == 7 && !files.contains(s"${id}.png")) { | |
val title = (data \ "title").as[String] | |
val name = (data \ "name_only").as[String] | |
f(KiraraResult(id, title, name, draw(id, true))) | |
} else { | |
Future.successful(()) | |
} | |
} | |
} | |
} | |
def draw(id: Long, withSign: Boolean): BufferedImage = { | |
val char = ImageIO.read(new URL(s"https://truecolor.kirara.ca/spread/${id}.png")) | |
assert(char.getWidth == 1280) | |
val image = new BufferedImage(1280, 720, BufferedImage.TYPE_INT_ARGB) | |
val g = image.createGraphics | |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR) | |
g.drawImage(char, 0, 0, 1280, 720, 0, char.getHeight - 720, 1280, char.getHeight, null) | |
if (withSign) { | |
val sign = ImageIO.read(new URL(s"https://truecolor.kirara.ca/sign/${id}.png")) | |
val w = (sign.getWidth * 0.75).toInt | |
val h = (sign.getHeight * 0.75).toInt | |
g.drawImage(sign, 0, 720 - h, w, 720, 0, 0, sign.getWidth, sign.getHeight, null) | |
} | |
g.dispose() | |
image | |
} | |
def upload(wsClient: AhcWSClient, accessToken: String, channel: String, id: Long, title: String, image: BufferedImage)(implicit ec: ExecutionContext) = { | |
val temp = Files.createTempFile("starlight", "kirara") | |
ImageIO.write(image, "PNG", temp.toFile) | |
val form = List( | |
MultipartFormData.FilePart("file", s"${id}.png", Some("image/png"), FileIO.fromPath(temp)), | |
MultipartFormData.DataPart("token", accessToken), | |
MultipartFormData.DataPart("channels", channel), | |
MultipartFormData.DataPart("title", title) | |
) | |
wsClient.url("https://slack.com/api/files.upload").post(Source(form)).map { res => | |
(res.json \ "file" \ "url_private").as[String] | |
}.andThen { | |
case _ => Files.delete(temp) | |
} | |
} | |
} | |
case class KiraraResult(id: Long, title: String, name: String, image: BufferedImage) | |
class FileWriter(out: Path) extends Actor { | |
def receive = { | |
case url: String => Files.write(out, (url + '\n').getBytes, StandardOpenOption.CREATE, StandardOpenOption.APPEND) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment