Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events
SOLVED

Unused Assets Clean Up

Avatar

Level 4

I want to clean up unused assets from dam for my project and with the help of managed controlled processes -> /apps/acs-commons/content/manage-controlled-processes.html I can get the list of assets which are not being referenced in the pages. However if an asset is updated in the author and the page is not published then the old asset which is still referenced in the live page doesn't show up in the results under published reference of MCP. 
Is there a better way to achieve this goal?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @SHIBANI06,

So, in general you will need to exclude from the list of assets that are not referenced those that are published. Here is a complete code of ProcessDefinition that will create process that can be run from MCP.

Alternatively you check below groovy scripts.

First script will search for all assets under given DAM path, next it will check each asset, one by one if it is used on any page. Finally it will check it asset is published. As a result you will get list of all assets with clear indication for each asset if it is used on any page and if it is published. This will give you complete set of information you need to do the clean up.

import javax.jcr.query.Query
import com.day.cq.replication.ReplicationStatus

DAM_PATH = "/content/dam/we-retail"
CONTENT_PATH = "/content/we-retail"

// searching for all assetes under given dam path
def assets = resourceResolver.findResources("SELECT * FROM [dam:Asset] AS s WHERE ISDESCENDANTNODE([${DAM_PATH}])", Query.JCR_SQL2)
assets?.each { asset ->
    boolean hasReferences = false
    boolean isPublished = false

    def assetPath = asset?.path
    // searching for all pages where given asset could be used
    def references = resourceResolver
        .findResources("SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE([${CONTENT_PATH}]) and CONTAINS(s.*, '${assetPath}')",
            Query.JCR_SQL2)

    hasReferences = references?.hasNext()
    isPublished = asset.adaptTo(ReplicationStatus.class)?.isDelivered()
    
    println "Asset path: ${assetPath}, has references: ${hasReferences ? 'Yes' : 'No'}, is published: ${isPublished ? 'Yes' : 'No'}"
}

Second script is variation of the first one. It will search for all assets under given DAM path, next it will check each asset if it is published, and if not it will simply check if asset is used. As a result you will get list of assets that are not used and have not been published - so this will address you case.

import javax.jcr.query.Query
import com.day.cq.replication.ReplicationStatus

DAM_PATH = "/content/dam/we-retail"
CONTENT_PATH = "/content/we-retail"

// searching for all assetes under given dam path
def assets = resourceResolver.findResources("SELECT * FROM [dam:Asset] AS s WHERE ISDESCENDANTNODE([${DAM_PATH}])", Query.JCR_SQL2)
assets?.each { asset ->
    def assetPath = asset?.path
    // searching for all pages where given asset could be used
    if (!asset.adaptTo(ReplicationStatus.class)?.isDelivered()) {
        def references = resourceResolver
            .findResources("SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE([${CONTENT_PATH}]) and CONTAINS(s.*, '${assetPath}')",
                Query.JCR_SQL2)
   
        if (!references?.hasNext()) {
            println "Asset path: ${assetPath}"
        }
    }
}

View solution in original post

2 Replies

Avatar

Correct answer by
Community Advisor

Hi @SHIBANI06,

So, in general you will need to exclude from the list of assets that are not referenced those that are published. Here is a complete code of ProcessDefinition that will create process that can be run from MCP.

Alternatively you check below groovy scripts.

First script will search for all assets under given DAM path, next it will check each asset, one by one if it is used on any page. Finally it will check it asset is published. As a result you will get list of all assets with clear indication for each asset if it is used on any page and if it is published. This will give you complete set of information you need to do the clean up.

import javax.jcr.query.Query
import com.day.cq.replication.ReplicationStatus

DAM_PATH = "/content/dam/we-retail"
CONTENT_PATH = "/content/we-retail"

// searching for all assetes under given dam path
def assets = resourceResolver.findResources("SELECT * FROM [dam:Asset] AS s WHERE ISDESCENDANTNODE([${DAM_PATH}])", Query.JCR_SQL2)
assets?.each { asset ->
    boolean hasReferences = false
    boolean isPublished = false

    def assetPath = asset?.path
    // searching for all pages where given asset could be used
    def references = resourceResolver
        .findResources("SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE([${CONTENT_PATH}]) and CONTAINS(s.*, '${assetPath}')",
            Query.JCR_SQL2)

    hasReferences = references?.hasNext()
    isPublished = asset.adaptTo(ReplicationStatus.class)?.isDelivered()
    
    println "Asset path: ${assetPath}, has references: ${hasReferences ? 'Yes' : 'No'}, is published: ${isPublished ? 'Yes' : 'No'}"
}

Second script is variation of the first one. It will search for all assets under given DAM path, next it will check each asset if it is published, and if not it will simply check if asset is used. As a result you will get list of assets that are not used and have not been published - so this will address you case.

import javax.jcr.query.Query
import com.day.cq.replication.ReplicationStatus

DAM_PATH = "/content/dam/we-retail"
CONTENT_PATH = "/content/we-retail"

// searching for all assetes under given dam path
def assets = resourceResolver.findResources("SELECT * FROM [dam:Asset] AS s WHERE ISDESCENDANTNODE([${DAM_PATH}])", Query.JCR_SQL2)
assets?.each { asset ->
    def assetPath = asset?.path
    // searching for all pages where given asset could be used
    if (!asset.adaptTo(ReplicationStatus.class)?.isDelivered()) {
        def references = resourceResolver
            .findResources("SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE([${CONTENT_PATH}]) and CONTAINS(s.*, '${assetPath}')",
                Query.JCR_SQL2)
   
        if (!references?.hasNext()) {
            println "Asset path: ${assetPath}"
        }
    }
}