How can I automate image upload to commercetools using JVM API - java

I'm a pretty new developer in CommerceTools and I've been working with this tool for just a few weeks.
At this moment I need to develop a process that should be able to upload all the images related to a product from a folder to commercetools using the JVM API.
I think the best way would be to recover the SKU (eg PROD001ABC) of each product from the CTP database and then use this string to locate in the given folder if there are images containing such SKU in the filename (PROD001ABC_front.jpg, PROD001ABC_side1.jpg, PROD001ABC_side2.jpg, etc.).
Once all the product images are located, I want to upload them to CommerceTools using the API.
As I've researched, I think I'd have to use the io.sphere.sdk.products.commands.ProductImageUploadCommand method, but I'm not sure how to get to that point.
I'm really lost.
Thanks so much for any help
Best regards.
Miguel

Basically what you need to do is to create an HttpClient and then use this client to execute the image upload command, to make things more concrete take a look at this test senario
here is the typical use of the commercetools JVM SDK for your purpose:
//create client
SphereClientConfig sphereClientConfig = SphereClientConfig.of( projectKey, clientId, clientSecret);
SphereClient client = SphereClient.of(sphereClientConfig, SphereClientFactory.of().createHttpClient(), SphereAccessTokenSupplier.ofConstantToken("accessToken"))
final ByIdVariantIdentifier identifier = product.getMasterData().getStaged().getMasterVariant().getIdentifier();
File imageFile = new File("Path to your image");
//create update commands
final ProductImageUploadCommand cmd1 = ProductImageUploadCommand
.ofVariantId(imageFile, identifier)
.withFilename("myProductImage1.gif")
.withStaged(true);
final ProductImageUploadCommand cmd2 = ProductImageUploadCommand
.ofVariantId(imageFile, identifier)
.withFilename("myProductImage2.gif")
.withStaged(true);
//update the product
final Product updatedProduct1 = client().executeBlocking(cmd1);
final Product updatedProduct = client().executeBlocking(cmd2);
//get the images
List<Image> images = updatedProduct.getMasterData().getStaged().getMasterVariant().getImages();
Hope this helps :)

Well, finally I have achieved it.
I used an attribute of my products (EAN) to locate the images in the path corresponding to "product type / EAN".
// Buscamos una carpeta con el nombre del EAN
final String pathCarpetaEan = rutaBaseLocal + "\\" + typeName + "\\" + vEan;
final File carpetaEAN = new File(pathCarpetaEan);
final File carpetaEanSubidas = new File(pathCarpetaEan + "\\subidas\\");
if (carpetaEAN.exists() && carpetaEAN.isDirectory()) {
// La carpeta existe. Buscamos imagenes dentro.
System.out.println("Encontrada la carpeta " + pathCarpetaEan);
File[] fileImages = carpetaEAN.listFiles();
for (File fileImagen : fileImages) {
if (fileImagen.isFile()) {
final String nomImagen = fileImagen.getName();
System.out.println("---\nNombre fichero: " + nomImagen);
if (nomImagen.startsWith(vEan)
&& (nomImagen.toLowerCase().endsWith(JPEG)
|| nomImagen.toLowerCase().endsWith(PNG)
|| nomImagen.toLowerCase().endsWith(GIF))) {
System.out.println("El nombre de archivo contiene el EAN: " + vEan);
System.out.println("Y se trata de una imagen");
// A partir de aqui realizamos la subida de las imagenes para la variante concreta.
final ProductImageUploadCommand cmd = ProductImageUploadCommand
.ofVariantId(fileImagen, identificador)
.withFilename(nomImagen)
.withStaged(true);
final Product updatedProduct = client.executeBlocking(cmd);
System.out.println("Uploaded your image (" + nomImagen + ") and added to the masterVariant");
System.out.println("Producto actualizado: " + updatedProduct.toString());
nUploadedImages++;
}
}
}
}
After uploading the images, I move them to another subfolder "uploaded".
Thank you very much for your help.

Related

Create and Save Outlook e-mail in Java Jacob library

HI I'm trying to create Outlook e-mail from Java
I'm working with Windows 10 and Outlook 365 desktop version
I'm able to do it with AposeEmail
https://docs.aspose.com/email/#asposeemail-for-java
and with
jotlmsg
https://github.com/ctabin/jotlmsg
But there are limitations.
Apose E-mial is not free. Only evaluation version is free.
Jotlmsg doesn't support html e-mails.
There’s also another possibility to use methods from dynamic libraries. There is library Jacob for this
Jacob Outlook example
However I don't know how to find way to do it in Jacob. Examples which I found on Stackoverflow or in other places doesn't work.
I have following VBA code which works.
Any idea how to do the same / similar thing in Jacob?
Alternative solution.
Do you know free JAVA library which supports .msg e-mail with HTML format?
Public Sub CreateEmail()
Dim objMsg As MailItem
Set objMsg = Application.CreateItem(olMailItem)
With objMsg
.To = Alias#domain.com
.CC = Alias2#domain.com
.BCC = Alias3#domain.com
.Subject = "This is the subject"
.Categories = "Test"
.VotingOptions = "Yes;No;Maybe;"
.BodyFormat = olFormatPlain ' send plain text message
.Importance = olImportanceHigh
.Sensitivity = olConfidential
.Attachments.Add ("path-to-file.docx")
' Calculate a date using DateAdd or enter an explicit date
.ExpiryTime = DateAdd("m", 6, Now) '6 months from now
.DeferredDeliveryTime = #8/1/2012 6:00:00 PM#
.Display
End With
Set objMsg = Nothing
End Sub
I tried AposeE-mail and Jotlmsg but they don't satisfy fully my needs.
I have found example
Jacob Outlook Sample
and modified:
/**
* JACOB Outlook sample contributed by
* Christopher Brind <christopher.brind#morse.com>
* Modified by PawDob https://stackoverflow.com/users/16168586/pawdob
*/
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
/**
* sample class to show simple outlook manipulation
*/
public class JacobOutlookEmail {
private ActiveXComponent ol;
private Dispatch oOutlook;
private Object email[] = new Object[1];
/**
* standard run loop
*
* #param asArgs command line arguments
* #throws Exception
*/
public static void main(String asArgs[]) throws Exception {
System.out.println("Outlook: IN");
JacobOutlookEmail jacobOutlook = new JacobOutlookEmail();
ActiveXComponent axOutlook = new ActiveXComponent("Outlook.Application");
try {
System.out.println("version=" + axOutlook.getProperty("Version"));
jacobOutlook.oOutlook = axOutlook.getObject();
System.out.println("version=" + Dispatch.get(jacobOutlook.oOutlook, "Version"));
Dispatch oNameSpace = axOutlook.getProperty("Session").toDispatch();
System.out.println("oNameSpace=" + oNameSpace);
String emailBody = "<HTML><BODY><p><b>Bold text</b></p>" +
"<p><i>Italic text</i></p>" +
"<p>Normal text</p>" +
"</BODY></HTML>";
String emailSubject = "Email demo using Jacob";
String recipientTo = "Alias#domain.com";
String recipientCC = "Alias2#domain.com";
String recipientBCC = "Alias3#domain.com";
String[] attachments = new String[]{"D:\\temp.txt"};
jacobOutlook.createEmail(emailSubject, recipientTo, recipientCC, recipientBCC, emailBody, attachments);
} finally {
// Uncomment if you want close outlook after job is done
// axOutlook.invoke("Quit", new Variant[]{});
}
}
public void createEmail(String subject, String recipientTo, String recipientCC, String recipientBCC, String body, String[] attachments) {
Dispatch mail = Dispatch.call(oOutlook, "CreateItem", email).toDispatch();
Dispatch.put(mail, "Subject", subject);
Dispatch.put(mail, "To", recipientTo);
Dispatch.put(mail, "CC", recipientCC);
Dispatch.put(mail, "BCC", recipientBCC);
// Use if sample text is used
// Dispatch.put(mail, "Body", body);
Dispatch.put(mail, "HTMLBody", body);
if (attachments.length > 0) {
Dispatch attachs = Dispatch.get(mail, "Attachments").toDispatch();
for (Object attachment : attachments) {
Dispatch.call(attachs, "Add", attachment);
}
}
// Save on D drive
Dispatch.call(mail, "SaveAs","D:\\JacobEmail.msg");
// Display in outlook
Dispatch.call(mail, "Display");
}
}
And finally it is working
Sometimes you have ask to find solution yourself :-)

JUnit test on recursive function (creating file and compare size)

I'm working on a project : copy a file and check if the size are equals. If not, delete file and redo it (number of retries is defined)
public boolean copieFichierAvecRetry(FileObject copieFichierFile, FileObject fichierACopier, int nbRetry, int currentNbRetry)
throws InterruptedException, IOException {
logger.logInfo("Deplacement du fichier " + fichierACopier.getName().getBaseName(),
"de " + fichierACopier.getParent().getName().getPath() + " vers "
+ copieFichierFile.getParent().getName().getPath());
copieFichierFile.copyFrom(fichierACopier, Selectors.SELECT_SELF);
boolean tailleOk = false;
// Si le flag de vérification est à true on vérifie que les fichiers
// copies ont la même taille
try {
tailleOk = verificationTailleCorrespondantes(copieFichierFile, fichierACopier);
if (!tailleOk && currentNbRetry <= nbRetry){
logger.logInfo("Erreur lors de la verification de la taille, essai n°" + currentNbRetry, null);
copieFichierFile.delete();
currentNbRetry++;
copieFichierAvecRetry(copieFichierFile, fichierACopier, nbRetry, currentNbRetry);
}
} catch (IOException e) {
logger.logWarn("Erreur lors de la verification de la taille : ", e.getMessage());
tailleOk = false;
}
return tailleOk;
}
Here is the unit test for the non-recursive function :
public void testCopieFichier()
throws IOException, InterruptedException, URISyntaxException, TransfertFichierException {
socleUtil.setNbTentativeMaxTransfert(1);
String nomFichierSource = "test123.txt";
String nomFichierDestination = "testDownloadSuccess.xml";
File fileOrigine = new File(getClass().getResource(SocleConstantes.SLASH).getFile());
String cheminFichierDistantOrigine = fileOrigine.getPath();
File fileDestination = new File(getClass().getResource(SocleConstantes.SLASH).toURI());
String cheminFichierDistantDestination = fileDestination.getPath() + FILE_SEPARATOR + "download";
assertTrue(socleUtil.copieFichier(
socleUtil.findFileLocal(cheminFichierDistantDestination + "/" + nomFichierDestination),
socleUtil.findFileLocal(cheminFichierDistantOrigine + "/" + nomFichierSource)));
assertTrue(fileDestination.exists());
}
As you can see in the code above, it will copy a file, check size and if it's OK then return true.
If it's false for 5 times (in the exemple) the function calls itself after deleting the file with wrong size.
verificationTailleCorrespondantes is the function to compare sizes.
tailleOk is true if both files are same size.
How should I test the recursivity of this function if it copies a file and never fail (which happens in production) ?
Thanks
In this case, I'd write the following scenarios:
the process success at its first iteration
the process fails at its (n-1)th iteration, success at its nth iteration with n < number of retries
the process fails at its nth iteration with n == number of retries
In order to do it, you'll need to mock your dependencies. Specially the one checking the file size. The mocking for the previous scenarios would be
file size check returns true. Assert that the check was run once and the result is valid
file size check returns false (n-1) times and true the nth time. Assert that the check was run n times and the result is valid
file size check returns false. Assert that the check was run number of retries times and the result is invalid

UIMA ruta - Using annotations from different views

I have a document, after few annotations, i am writing it into a new view using HTMLConverter
Sample Input:
<p class="MsoNormal"><span data-bkmark="para10121"></span><span style="font-family:Arial; font-size:10pt; color:#color: #000000">[1] SJ. Goetsch,BD. Murphy,R. Schmidt,et al. "Physics of rotating gamma systems for stereotactic radiosurgery. "</span> <span style="font-family:Arial; font-size:10pt; color:#color: #000000">International Journal of Radiation Oncologybiologyphysics,</span> vol.<span style="font-family:Arial; font-size:10pt; color:#color: #000000">43, no.3, pp.689-696, 1999.</span><span data-bkmark="para10121"></span></p>
I am using htmlconvertor to create a new view "plaintextview"
CONFIGURE(HtmlAnnotator, "onlyContent" = false);
Document{-> EXEC(HtmlAnnotator)};
Document { -> CONFIGURE(HtmlConverter, "inputView" = "_InitialView","outputView" = "plaintextview"),
EXEC(HtmlConverter,{TAG})};
After which i would run my own engine and perform few manual annotations
try {
for (AnnotationFS afs : CasUtil.select(cas.getView("plaintextview"), type))
{
Feature bookmarkFtr = type.getFeatureByBaseName("RefBookmark");
System.out.println("\n Ref is " + afs.getCoveredText());
System.out.println("STart is " + afs.getBegin());
System.out.println("End is " + afs.getEnd());
String test = " vol.43, no.3, pp.689-696, 1999.";
if (afs.getCoveredText().contains(test)) {
int start = afs.getCoveredText().indexOf(test) + afs.getBegin();
int end = start + test.length();
testanno annotation = new testanno(cas.getView("plaintextview").getJCas());
annotation.setBegin(start);
annotation.setEnd(end);
annotation.addToIndexes();
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
This code will annotate the particular text in the plaintextview (Why? - because the _initialview document will have html spans in between the text ex: vol.43, no.3, < some html tags > pp. 689-696, 1999.)
So how do i get my annotaions from plaintextview to initial view or use these annotaions inside my ruta script using my annotations from different views(i.e, _initialview and plaintextview) ?
In Ruta you cannot directly write rules for specific CAS views. (You could use EXEC to apply an analysis engine on the different view from within a Ruta script.)
The normal way to approach this is on framework level by either apply sofa mapping in an aggregated analysis engine or copying the view to the _initialView of a new CAS.
DISCLAIMER: I am a developer of UIMA Ruta

Problems fetching URL in java with Jsoup

Edit: I have apparently solve the problem forcing the code getting the HTML. The problem I have is that randomly the HTML is not taken. To force that I have added:
int intento = 0;
while (document == null) {
intento++;
System.out.println("Intento número: " + intento);
document = getHtmlDocument(urlPage);
}
I am experiencing this random issue. Sometimes it gives me problems when fetching an URL an as it reaches to the timeout the program execution stops. The code:
public static int getStatusConnectionCode(String url) {
Response response = null;
try {
response = Jsoup.connect(url).userAgent("Mozilla/5.0").timeout(100000).ignoreHttpErrors(true).execute();
} catch (IOException ex) {
System.out.println("Excepción al obtener el Status Code: " + ex.getMessage());
}
return response.statusCode();
}
/**
* Con este método devuelvo un objeto de la clase Document con el contenido del
* HTML de la web que me permitirá parsearlo con los métodos de la librelia JSoup
* #param url
* #return Documento con el HTML
*/
public static Document getHtmlDocument(String url) {
Document doc = null;
try {
doc = Jsoup.connect(url).userAgent("Mozilla/5.0").timeout(100000).get();
} catch (IOException ex) {
System.out.println("Excepción al obtener el HTML de la página" + ex.getMessage());
}
return doc;
}
Should I use another method or increase the time out limit? The problem is that the program execution spends more or less 10 hours, and sometimes the problem happens in the URL number 500 another time in the 250...this is nonsense for me...if there is a problem in the link number 250, why if I run another time the program the problem happens in the link number 450 (for example)? I have been thinking that it could be internet problems but it's not.
The solution for another case is not solving my problem: Java JSoup error fetching URL
Thanks in advice.

How to get a retweet text message using Twitter4j library

I am new to Twitter4j library. I need to get all the retweets of a tweet. To do this I have written this java code:
try {
Twitter twitter = tf.getInstance();
List<Status> statuses = twitter.getRetweets(Long.parseLong(id));
System.out.println(statuses.size());
for (Status status : statuses) {
System.out.println("#" + status.getUser().getScreenName() + " - " + status.get);
}
} catch{
some code...
}
tf is a variable I declared as
tf = new TwitterFactory(configuration);
and includes the information about the configuration. When I run the code the output I get is
#rssmiranda - RT #repubblicait: Tokyo, una corona per Edymar: è la miss delle miss
As you can see we have on the left the info about the user but on the right we have the message of the general tweet, not the message included in the retweet written by the user.
How can I display the retweet written by (for example) #rssmiranda? Thanks!!!!!
For showing number of retweet:
https://api.twitter.com/1/statuses/show.json?id=<id>
It will give you the answer like -
"retweet_count": 1 etc.
For all the details of retweet read this :GET statuses/retweets/:id

Categories