Quantcast
Channel: Experiencing Adobe Experience Manager (AEM, CQ)
Viewing all articles
Browse latest Browse all 525

AEM - Generate Smart Crop Rect Log of Images in a DM Classic (Scene7 Account)

$
0
0

Goal

This is Part-1 of Migrating the Smart Crop Settings of images in a DM Classic (Scene7) account to a different Scene7 account. Executing the standalone class apps.GenerateSmartCropsLog, smart crop settings of all assets in the account (or a folder) are written to a log all-smart-crops.csv..

Part 2 is for updating the smart crop settings in destination Scene7 account

Package | Source Code




Running the tool

1) Install Java JRE 8

2) Extract migrate-smart-crops.zip into a folder migrate-smart-crops

3) Set the following properties in migrate-smart-crops\apps\config.properties

                         a. when path is empty the entire account is traversed or set path to a Scene7 folder eg. EAEM/experience-aem

                         b. Set the src scene7 account credentials in companyHandle/user/pass format (the company handle is available in AEM at location /conf/global/settings/cloudconfigs/dmscene7/jcr:content@companyHandle)

                                                  eg. src=c|1111111/user@company.com/NeverSharePassword

4) Running migrate-smart-crops/fetch.bat reads the smart crops from source S7 account and adds in csv migrate-smart-crops/apps/all-smart-crops.csv

5) Or for manually running the fetch "C:\Program Files\Java\jdk1.8.0_221\bin\java" -classpath ".;./libs/*" apps.GenerateSmartCropsLog


Code

The following java class apps.GenerateSmartCropsLog contains logic to connect to DM Classic (Scene7) and fetch the smart crop settings of each asset in the account...

package apps;

import com.scene7.ipsapi.*;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.io.IOUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.*;
import java.net.URL;
import java.util.*;

public class GenerateSmartCropsLog {
private static String S7_NA_IPS_URL = "https://s7sps1apissl.scene7.com/scene7/api/IpsApiService";
private static String SRC_S7_COMPANY_HANDLE = "";
private static String SRC_S7_USER = "";
private static String SRC_S7_PASS = "";
private static String STAND_ALONE_APP_NAME = "Experiencing AEM";
private static String logName = "all-smart-crops.csv";
private static BufferedWriter LOG_WRITER = null;
private static int assetCount = 0;

public static void main(String[] args) throws Exception {
String path = setProperties();

if((path == null) || path.trim().isEmpty()){
System.out.println("INFO : Reading smart crops of all assets in account : " + SRC_S7_COMPANY_HANDLE);

browseFolder(null);
}else{
System.out.println("INFO : Reading smart crops of all assets in folder and sub folders : " + path);

S7Folder rootFolder = new S7Folder();

rootFolder.setFolderPath(path);

browseFolder(rootFolder);
}

System.out.println("TOTAL ASSETS READ : " + assetCount);

LOG_WRITER.flush();
LOG_WRITER.close();
}

private static String setProperties(){
String path = "";

try{
URL propFile = GenerateSmartCropsLog.class.getResource("config.properties");

System.out.println("INFO : Reading configuration from : " + propFile.getPath());

InputStream input = new FileInputStream(propFile.getPath());

Properties prop = new Properties();
prop.load(input);

String srcAccount = prop.getProperty("src");

if((srcAccount == null) || srcAccount.trim().equals("")){
System.out.println("ERROR: 'src' property not found in config.properties");
System.exit(-1);
}

String[] words = srcAccount.split("/");

if(words.length != 3){
System.out.println("ERROR: 'src' property format is 's7CompanyHandle/user/pass' eg.'c|230095/user@company.com/password'");
System.exit(-1);
}

SRC_S7_COMPANY_HANDLE = words[0];
SRC_S7_USER = words[1];
SRC_S7_PASS = words[2];

path = prop.getProperty("path");

LOG_WRITER = new BufferedWriter(new FileWriter((new File(propFile.getPath())).getParentFile().getPath() + "/" + logName));
}catch(Exception e){
System.out.println("ERROR: Reading config.properties, is it in the current folder? - " + e.getMessage());
e.printStackTrace();
System.exit(-1);
}

return path;
}

private static void browseFolder(S7Folder s7Folder) throws Exception {
AuthHeader authHeader = getS7AuthHeader();

Marshaller marshaller = getMarshaller(AuthHeader.class);
StringWriter sw = new StringWriter();
marshaller.marshal(authHeader, sw);

String authHeaderStr = sw.toString();

GetFolderTreeParam getFolderTreeParam = getGetFolderTreeParam(s7Folder);

marshaller = getMarshaller(getFolderTreeParam.getClass());
sw = new StringWriter();
marshaller.marshal(getFolderTreeParam, sw);

String apiMethod = sw.toString();

byte[] responseBody = getResponse(authHeaderStr, apiMethod);

List<S7Folder> folders = parseResponse(responseBody, s7Folder);

folders.forEach(folder -> {
if(folder.isHasSubFolders()){
try{
browseFolder(folder);
}catch (Exception e){
e.printStackTrace();
}
}
});

printFolders(s7Folder, folders);
}

private static void printFolders(S7Folder parentFolder, List<S7Folder> folders){
if( ( parentFolder == null ) && folders.isEmpty()){
System.out.println("No folders or assets in account - " + SRC_S7_COMPANY_HANDLE);
return;
}

if(folders.isEmpty()){
System.out.println("No folders or assets under - " + parentFolder.getFolderPath());
return;
}

if(parentFolder == null){
System.out.println(SRC_S7_COMPANY_HANDLE);
}else{
System.out.println(parentFolder.getFolderPath());
}

folders.forEach(folder -> {
List<S7Asset> assets = folder.getAssets();

assetCount = assetCount + assets.size();

System.out.println("\t" + folder.getFolderPath() + " - " + assets.size());

assets.forEach(asset -> {
try {
LOG_WRITER.write(asset.getAssetPath() + "," + asset.getCropRectsStr());
LOG_WRITER.write("\r\n");
LOG_WRITER.flush();
}catch (Exception lw){
System.out.println("ERROR: writing to log : " + lw.getMessage());
}
});
});
}

private static List<S7Folder> parseResponse(byte[] responseBody, S7Folder parentFolder) throws Exception{
List<S7Folder> folders = new ArrayList<S7Folder>();

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

ByteArrayInputStream input = new ByteArrayInputStream(responseBody);

Document doc = builder.parse(input);

XPath xPath = XPathFactory.newInstance().newXPath();

String expression = "/getFolderTreeReturn/folders";

if( (parentFolder != null) && (parentFolder.getFolderHandle() != null)){
expression = "/getFolderTreeReturn/folders/subfolderArray";
}

NodeList itemList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);

for (int i = 0; i < itemList.getLength(); i++) {
Node item = itemList.item(i);

if( (parentFolder != null) && (parentFolder.getFolderHandle() != null)){
NodeList childList = item.getChildNodes();

for (int j = 0; j < childList.getLength(); j++) {
folders.add(fillFolderDetail(childList.item(j)));
}
}else{
folders.add(fillFolderDetail(item));
}
}

return folders;
}

private static S7Folder fillFolderDetail(Node item) throws Exception{
S7Folder s7Folder = new S7Folder();

if(item.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) item;

s7Folder.setFolderHandle(eElement.getElementsByTagName("folderHandle").item(0).getTextContent());
s7Folder.setFolderPath(eElement.getElementsByTagName("path").item(0).getTextContent());
s7Folder.setHasSubFolders(new Boolean(eElement.getElementsByTagName("hasSubfolders").item(0).getTextContent()));

fillAssetDetails(s7Folder);
}

return s7Folder;
}

private static void fillAssetDetails(S7Folder s7Folder) throws Exception{
AuthHeader authHeader = getS7AuthHeader();

Marshaller marshaller = getMarshaller(AuthHeader.class);
StringWriter sw = new StringWriter();
marshaller.marshal(authHeader, sw);

String authHeaderStr = sw.toString();

SearchAssetsParam searchAssetsParam = getSearchAssetsParam(s7Folder);

marshaller = getMarshaller(searchAssetsParam .getClass());
sw = new StringWriter();
marshaller.marshal(searchAssetsParam , sw);

String apiMethod = sw.toString();

byte[] responseBody = getResponse(authHeaderStr, apiMethod);

parseSearchResponse(responseBody, s7Folder);
}

private static void parseSearchResponse(byte[] responseBody, S7Folder parentFolder) throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

ByteArrayInputStream input = new ByteArrayInputStream(responseBody);

Document doc = builder.parse(input);

XPath xPath = XPathFactory.newInstance().newXPath();

String expression = "/searchAssetsReturn/assetArray/items";

NodeList itemList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);

List<S7Asset> assets = new ArrayList<S7Asset>();

for (int i = 0; i < itemList.getLength(); i++) {
Node item = itemList.item(i);

if(item.getNodeType() != Node.ELEMENT_NODE) {
continue;
}

S7Asset s7asset = new S7Asset();

Element eElement = (Element) item;

s7asset.setType(getTextContent(eElement, "type"));
s7asset.setAssetHandle(getTextContent(eElement, "assetHandle"));
s7asset.setAssetPath(getTextContent(eElement, "folder") + getTextContent(eElement, "fileName"));

NodeList imageInfoList = eElement.getElementsByTagName("imageInfo");

for (int j = 0; j < imageInfoList.getLength(); j++) {
Node imageInfo = imageInfoList.item(j);

if(imageInfo.getNodeType() != Node.ELEMENT_NODE) {
continue;
}

s7asset.setAssetSize(new Long(getTextContent((Element)imageInfo, "fileSize")));

}

if("Image".equals(s7asset.getType())){
Map<String, String> cropRects = getSmartCropsCropRects(s7asset.getAssetHandle());

s7asset.setCropRects(cropRects);
}

assets.add(s7asset);
}

parentFolder.setAssets(assets);
}

public static Map<String, String> getSmartCropsCropRects(String assetHandle) throws Exception{
AuthHeader authHeader = getS7AuthHeader();

Marshaller marshaller = getMarshaller(AuthHeader.class);
StringWriter sw = new StringWriter();
marshaller.marshal(authHeader, sw);

String authHeaderStr = sw.toString();

GetAssociatedAssetsParam getAssociatedAssetsParam = new GetAssociatedAssetsParam();
getAssociatedAssetsParam.setCompanyHandle(SRC_S7_COMPANY_HANDLE);
getAssociatedAssetsParam.setAssetHandle(assetHandle);

marshaller = getMarshaller(AuthHeader.class);
sw = new StringWriter();
marshaller.marshal(authHeader, sw);

marshaller = getMarshaller(getAssociatedAssetsParam.getClass());
sw = new StringWriter();
marshaller.marshal(getAssociatedAssetsParam, sw);

String apiMethod = sw.toString();

byte[] responseBody = getResponse(authHeaderStr, apiMethod);

return parseResponseForCropRects(responseBody);
}

private static Map<String, String> parseResponseForCropRects(byte[] responseBody) throws Exception{
Map<String, String> cropRects = new HashMap<String, String>();

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

ByteArrayInputStream input = new ByteArrayInputStream(responseBody);

Document doc = builder.parse(input);

XPath xPath = XPathFactory.newInstance().newXPath();

String expression = "/getAssociatedAssetsReturn/subAssetArray/items";

NodeList itemList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);
String subAssetHandle = null, name, cropRectStr;

for (int i = 0; i < itemList.getLength(); i++) {
Node item = itemList.item(i);

if(item.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) item;

subAssetHandle = eElement.getElementsByTagName("subAssetHandle").item(0).getTextContent();
name = eElement.getElementsByTagName("name").item(0).getTextContent();

try{
Element cropRectEle = (Element)((Element)eElement.getElementsByTagName("smartCrop").item(0))
.getElementsByTagName("cropRect").item(0);

cropRectStr = getCropRectStr(cropRectEle);
}catch(Exception ce){
//ignore no smart crop images
cropRectStr = "";
}

cropRects.put(name, cropRectStr);
}
}

return cropRects;
}

private static String getCropRectStr(Element cropRectEle){
StringWriter sw = new StringWriter();

sw.append("leftN=").append(cropRectEle.getElementsByTagName("leftN").item(0).getTextContent()).append("|");
sw.append("topN=").append(cropRectEle.getElementsByTagName("topN").item(0).getTextContent()).append("|");
sw.append("widthN=").append(cropRectEle.getElementsByTagName("widthN").item(0).getTextContent()).append("|");
sw.append("heightN=").append(cropRectEle.getElementsByTagName("heightN").item(0).getTextContent()).append("|");

return sw.toString();
}

private static String getTextContent(Element eElement, String tagName){
return eElement.getElementsByTagName(tagName).item(0).getTextContent();
}

private static byte[] getResponse(String authHeaderStr, String apiMethod) throws Exception{
StringBuilder requestBody = new StringBuilder("<Request xmlns=\"http://www.scene7.com/IpsApi/xsd/2017-10-29-beta\">");
requestBody.append(authHeaderStr).append(apiMethod).append("</Request>");

byte[] responseBody = null;
PostMethod postMethod = null;

try {
HttpClient httpclient = new HttpClient();

postMethod = new PostMethod(S7_NA_IPS_URL);

postMethod.setRequestHeader("Content-Type", "text/xml");
postMethod.setRequestEntity(new ByteArrayRequestEntity(requestBody.toString().getBytes()));

int responseCode = httpclient.executeMethod(postMethod);

if(responseCode != 200){
System.out.println("Response code - " + responseCode + ", returning here...");
}

InputStream is = postMethod.getResponseBodyAsStream();

responseBody = IOUtils.toByteArray(is);
}finally{
if(postMethod != null){
postMethod.releaseConnection();
}
}

return responseBody;
}

private static AuthHeader getS7AuthHeader(){
AuthHeader authHeader = new AuthHeader();

authHeader.setUser(SRC_S7_USER);
authHeader.setPassword(SRC_S7_PASS);
authHeader.setAppName(STAND_ALONE_APP_NAME);
authHeader.setAppVersion("1.0");
authHeader.setFaultHttpStatusCode(new Integer(200));

return authHeader;
}

private static GetFolderTreeParam getGetFolderTreeParam(S7Folder s7Folder){
GetFolderTreeParam getFolderTreeParam = new GetFolderTreeParam();

getFolderTreeParam.setCompanyHandle(SRC_S7_COMPANY_HANDLE);

getFolderTreeParam.setDepth(1);

if(s7Folder != null){
getFolderTreeParam.setFolderPath(s7Folder.getFolderPath());
}

return getFolderTreeParam;
}

private static SearchAssetsParam getSearchAssetsParam(S7Folder s7Folder){
SearchAssetsParam searchAssetsParam = new SearchAssetsParam();
StringArray assetTypes = new StringArray();
assetTypes.getItems().add("Image");

searchAssetsParam.setCompanyHandle(SRC_S7_COMPANY_HANDLE);
searchAssetsParam.setFolder(s7Folder.getFolderPath());
searchAssetsParam.setIncludeSubfolders(false);
searchAssetsParam.setAssetTypeArray(assetTypes);

return searchAssetsParam;
}

private static Marshaller getMarshaller(Class apiMethodClass) throws JAXBException {
Marshaller marshaller = JAXBContext.newInstance(new Class[]{apiMethodClass}).createMarshaller();
marshaller.setProperty("jaxb.formatted.output", Boolean.valueOf(true));
marshaller.setProperty("jaxb.fragment", Boolean.valueOf(true));
return marshaller;
}

private static class S7Folder{
private String folderHandle;
private String folderPath;
private boolean hasSubFolders;
private List<S7Asset> assets;

public String getFolderHandle() {
return folderHandle;
}

public void setFolderHandle(String folderHandle) {
this.folderHandle = folderHandle;
}

public String getFolderPath() {
return folderPath;
}

public void setFolderPath(String folderPath) {
this.folderPath = folderPath;
}

public boolean isHasSubFolders() {
return hasSubFolders;
}

public void setHasSubFolders(boolean hasSubFolders) {
this.hasSubFolders = hasSubFolders;
}

public List<S7Asset> getAssets() {
return assets;
}

public void setAssets(List<S7Asset> assets) {
this.assets = assets;
}

public String toString(){
return "[" + folderHandle + "," + folderPath + "," + hasSubFolders + "]";
}
}

private static class S7Asset{
private String type;
private String assetHandle;
private String assetPath;
private long assetSize;
private Map<String, String> cropRects;

public String getAssetHandle() {
return assetHandle;
}

public void setAssetHandle(String assetHandle) {
this.assetHandle = assetHandle;
}

public String getAssetPath() {
return assetPath;
}

public void setAssetPath(String assetPath) {
this.assetPath = assetPath;
}

public long getAssetSize() {
return assetSize;
}

public void setAssetSize(long assetSize) {
this.assetSize = assetSize;
}

public Map<String, String> getCropRects() {
return cropRects;
}

public String getCropRectsStr() {
if(cropRects == null){
return "";
}

StringWriter sw = new StringWriter();

cropRects.forEach((k, v) -> sw.append(k).append(":").append(v).append(","));

return sw.toString();
}

public void setCropRects(Map<String, String> cropRects) {
this.cropRects = cropRects;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}
}
}




Viewing all articles
Browse latest Browse all 525

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>