<commit_before>package io.mediachain.api.operations

import java.util.UUID

import cats.data.Xor
import gremlin.scala._
import io.mediachain.Traversals
import io.mediachain.Query
import io.mediachain.Types._
import io.mediachain.core.GraphError.SubtreeError
import org.json4s._
import org.json4s.jackson.Serialization.{read, write}
import shapeless.HNil

object CanonicalQueries {
  import Traversals.GremlinScalaImplicits
  import org.json4s.JsonDSL._
  implicit val formats = DefaultFormats

  val PAGE_SIZE = 20

  def listCanonicals(page: Int)(graph: Graph): List[Canonical] = {
    val first = page * PAGE_SIZE
    val last = first + PAGE_SIZE

    graph.V.hasLabel[Canonical].toCC[Canonical]
      .range(first, last).toList
  }


  def canonicalWithID(canonicalID: UUID)(graph: Graph): Option[Canonical] =
    Traversals.canonicalsWithUUID(graph.V, canonicalID)
      .toCC[Canonical]
      .headOption

  def historyForCanonical(canonicalID: UUID)(graph: Graph): Option[JObject] = {
    val treeXor = Traversals.canonicalsWithUUID(graph.V, canonicalID).findSubtreeXor

    for {
      tree <- treeXor.toOption
      canonicalGS = Traversals.canonicalsWithUUID(tree.V, canonicalID)
      canonical <- canonicalGS.toCC[Canonical].headOption
      revisions = Traversals.describingOrModifyingBlobs(tree.V, canonical)
    } yield {
      //val revisionsJ = somehowSerialize(revisions)
      ("canonicalID" -> canonical.canonicalID) ~
        ("revisions" -> List())
    }<commit_msg>Extraction.decompose was the answer 😎<commit_after>package io.mediachain.api.operations

import java.util.UUID

import cats.data.Xor
import gremlin.scala._
import io.mediachain.Traversals
import io.mediachain.Types._
import io.mediachain.core.GraphError.SubtreeError
import org.json4s._
import org.json4s.jackson.Serialization.{read, write}
import org.json4s.Extraction

object CanonicalQueries {
  import Traversals.GremlinScalaImplicits
  import org.json4s.JsonDSL._
  implicit val formats = DefaultFormats

  val PAGE_SIZE = 20

  def listCanonicals(page: Int)(graph: Graph): List[Canonical] = {
    val first = page * PAGE_SIZE
    val last = first + PAGE_SIZE

    graph.V.hasLabel[Canonical].toCC[Canonical]
      .range(first, last).toList
  }


  def canonicalWithID(canonicalID: UUID)(graph: Graph): Option[Canonical] =
    Traversals.canonicalsWithUUID(graph.V, canonicalID)
      .toCC[Canonical]
      .headOption

  def historyForCanonical(canonicalID: UUID)(graph: Graph): Option[JObject] = {
    val treeXor = Traversals.canonicalsWithUUID(graph.V, canonicalID).findSubtreeXor

    for {
      tree <- treeXor.toOption
      canonicalGS = Traversals.canonicalsWithUUID(tree.V, canonicalID)
      canonical <- canonicalGS.toCC[Canonical].headOption
      revisions = Traversals.describingOrModifyingBlobs(tree.V, canonical).toCC[ImageBlob].toList
    } yield {
      val revisionsJ = revisions.map(Extraction.decompose)
      ("canonicalID" -> canonical.canonicalID) ~
        ("revisions" -> revisionsJ)
    }
{'fraction_non_alphanumeric': 0.10129525074726005, 'fraction_numerical': 0.0036532713384257723, 'mean_word_length': 4.131175468483816, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3959253', 'n_tokens_mistral': 1017, 'n_tokens_neox': 972, 'n_words': 180}