<?xml version="1.0" encoding="UTF-8"?>
<documents xmlns="http://www.sophoracms.com/import/4.2">
  <document nodeType="sophora-nt:clientScriptDocument" externalID="8d8ab868-68ac-4ed8-8a38-d82e839e9bfb" exportedUuid="8d8ab868-68ac-4ed8-8a38-d82e839e9bfb">
    <properties>
      <property name="sophora:activeOnReadonly">
        <value>false</value>
      </property>
      <property name="sophora:activeTriggers">
        <value>DOCUMENT_ACTION_SAVE</value>
      </property>
      <property name="sophora:documentSources">
        <value>editor</value>
      </property>
      <property name="sophora:firstPublicationDate">
        <value>2023-03-31T17:34:57.216+02:00</value>
      </property>
      <property name="sophora:menuText">
        <value>Generate AI Variants</value>
      </property>
      <property name="sophora:name">
        <value>GenerateAIImageVariants</value>
      </property>
      <property name="sophora:neverSetOffline">
        <value>false</value>
      </property>
      <property name="sophora:nodeTypes">
        <value>subshell-content-nt:imageObject</value>
      </property>
      <property name="sophora:script">
        <value>def IMAGE_AI_URI = 'https://imageai.example.com:8080'
def IGNORE_USERNAMES = ['importer']


class Response {
    CropHint[] cropHints
    String cropHintsComment
}

class CropHint {
    Rectangle rectangle
}

class Rectangle {
    int x
    int y
    int width
    int height
}


if (IGNORE_USERNAMES.contains(sophoraClient.username)) {
    return
}

def doc = context.document

if (!context.isUpdatable(doc)) {
    return
}

if (context.trigger != ClientScriptTrigger.DIRECT &amp;&amp; doc.UUID != null) {
    return
}

def variantNodes = doc.getNodesByName('sophora-extension:imagedata')

def originalVariantNode = variantNodes.find { it.getString('sophora-extension:imagetype') == 'original' }
if (!originalVariantNode) {
    return
}

def originalBinary = originalVariantNode.getBinaryData('sophora-extension:binarydata')
if (!originalBinary) {
    return
}

def originalWidth = originalVariantNode.getLong('sophora-extension:width')
def originalHeight = originalVariantNode.getLong('sophora-extension:height')
def originalAspectRatio = (double) originalWidth / (double) originalHeight

def siteUUID = doc.structureInfo.siteUUID

def siteVariants = sophoraClient.getImageVariantsForSite(siteUUID)
    .findAll { it.name != 'original' }
    .findAll { it.getStateForSite(siteUUID) == com.subshell.sophora.api.structure.ImageVariant.State.ACTIVE }

def aspectRatios = siteVariants.collect {
    it.width != null &amp;&amp; it.height != null ?
        (double) it.width / (double) it.height :
        originalAspectRatio
}

def clientBuilder = context.getHttpClientBuilder()
    .userAgent('Image AI Generate AI Variants')
    .timeout(java.time.Duration.ofSeconds(30))

def response
def error = false

context.showBusyWhile('Calculate image variants', {
    try (def client = clientBuilder.build()) {
        def restClient = new HttpClientRestWrapper(client)
    
        def request = [
            image: java.util.Base64.encoder.encodeToString(originalBinary.bytes),
            cropHints: [
                aspectRatios: aspectRatios
            ]
        ]

        response = restClient.post(IMAGE_AI_URI + '/rest/v1/image-ai', request, Response.class)
    } catch (Exception e) {
        error = true
    }
})

if (error) {
    context.dialog().showMessage('An error has occurred. Please try again later.')
    return
}

response.cropHints.eachWithIndex { cropHint, cropHintIdx -&gt;
    def variantName = siteVariants[cropHintIdx].name
    def variantNode = variantNodes.find { it.getString('sophora-extension:imagetype') == variantName }
    
    variantNode.setLong('sophora-extension:clipX', cropHint.rectangle.x)
    variantNode.setLong('sophora-extension:clipY', cropHint.rectangle.y)
    variantNode.setLong('sophora-extension:width', cropHint.rectangle.width)
    variantNode.setLong('sophora-extension:height', cropHint.rectangle.height)
    variantNode.setBoolean('sophora-extension:disabled', false)
}

def historyItem = doc.addNode('sophora-extension:imageAIHistory', 'sophora-extension-nt:imageAIHistoryItem')
historyItem.setDate('sophora-extension:eventDate', java.util.GregorianCalendar.instance)
historyItem.setString('sophora-extension:description', response.cropHintsComment)

context.updateDocument(doc)
</value>
      </property>
      <property name="sophora:scriptType">
        <value>default</value>
      </property>
      <property name="sophora:tooltip">
        <value>Image AI: Generate AI Variants</value>
      </property>
    </properties>
    <childNodes>
      <childNode nodeType="sophora-nt:yellowData" name="sophora:yellowData">
        <properties />
        <childNodes />
        <resourceList />
      </childNode>
    </childNodes>
    <resourceList />
    <fields>
      <site>system</site>
      <structureNode>/</structureNode>
      <categories />
      <idstem>clientscriptdocument</idstem>
      <forceLock>true</forceLock>
      <forceCreate>false</forceCreate>
      <channels>
        <enabledChannels />
        <disabledChannels />
      </channels>
    </fields>
    <instructions>
      <lifecycleActivities>
        <lifecycleActivity type="publish" />
      </lifecycleActivities>
      <proposals />
      <stickyNotes />
    </instructions>
  </document>
</documents>
