Bulk import product images - Commerce 7.5

Vote:
 

Hello guys

I am new to Commerce and any help would be appreciated.

I'm struggling to find a solution for a maybe simple task.

I have a list of product images with external urls that needs to be downloaded from its original source, uploaded as Commerce assets and attached to the matching products. This needs to be scheduled by a job that runs every night.

Thanks in advance

Miroslav

#80560
Jan 24, 2014 22:52
Vote:
 

Hello,

My suggested solution is (assuming you are using 7.5)

- Create a scheduled job, which inherits from JobBase and override the Execute method

- In the Execute method, you can write code to request to external urls and download images 

- Code to upload image to asset:

private IContentRepository _contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
private IContentTypeRepository _contenttypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
private BlobFactory _blobFactory = ServiceLocator.Current.GetInstance<BlobFactory>();

private ContentMediaResolver _contentMediaResolver = ServiceLocation.ServiceLocator.Current.GetInstance<ContentMediaResolver>();

private Guid SaveMediaContent(FileInfo fileInfo, Stream stream, ContentReference parentLink)
{

//Get the content type which is registered with this file extension
var contentType = _contenttypeRepository.Load(_contentMediaResolver.GetFirstMatching(fileInfo.Extension));

//Get the content of the destination folder
ContentFolder destinationFolder = _contentRepository.Get<ContentFolder>(parentLink);

//get the default content of the content type above
file = _contentRepository.GetDefault<MediaData>(parentLink, contentType.ID);

//assign content's name
file.Name = fileInfo.Name;

//Create a blob 
var blob = _blobFactory.CreateBlob(file.BinaryDataContainer, fileInfo.Extension);

//save blob data by the binary data of the file

blob.Write(stream);
file.BinaryData = blob;

//Save the content 
var content = _contentRepository.Save(file, DataAccess.SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);

//return the content's guid

return file.ContentGuid;

}

 

- Save the asset to the Catalog content (I don't know how you want to determine matching products?):

//Get the catalog entry dto  of the entry you just created, catalogEntryId is the id (integer) of the product

var catalogEntryDto = CatalogContext.Current.GetCatalogEntryDto(catalogEntryId);

//Create a new row for CatalogItemAsset

var row = catalogEntryDto.CatalogItemAsset.NewRow()

row.AssetKey = //Guid of the asset content
row.AssetType = "default"; //asset type, can be specified as you need
row.CatalogEntryId = //Catalog entry id

//Save the catalog entry dto 

CatalogContext.Current.Save(catalogEntryDto);

 

Regards.

/Q

 

#80561
Edited, Jan 25, 2014 3:19
Vote:
 

Hello Quan

 

I appreciate your help, I'll try this and get back to you.

Can you add some comments to the code, so I understand the flow in it.

As for the product determination, we are importing the products at the same time as the images.

I assume that a "row.CatalogEntryId =" in you code is used to assign reference for the product?

 

Best regards

Miroslav

#80568
Jan 25, 2014 21:47
Vote:
 

Hi

I added some comment to demo code above. The code to assign CatalogEntryId is used to set the CatalogEntryId. You can also follow the Developer guide to know how to create a catalog entry by code.

Hope this helps :).

/Q

#80570
Jan 26, 2014 6:52
Vote:
 

Hi Quan

 

Thanks a lot.

In your SaveMediaContent method, you are using _contentMediaResolver, where do you get the instance of that one.

I know that I'm pain in the behind, but I just want to be sure how to use this right. Can you please add some comments to the SaveMediaContent method. I just need to understand why to use the private IContentRepository, IContentTypeRepository and BlobFactory. What is the meaning behind all this? I tried to read the developer guide, but didn't get mutch out of it(maybe I'm just underdeveloped:).

So to sum this up:

1) Where do you get the _contentMediaResolver?

2) A description of the process when saving the image in asset system?

3) Is there a way to Unit test this?

 

Thanks in advance

Miroslav

#80572
Jan 26, 2014 20:18
Vote:
 

Hi,

I updated the code - _contentMediaResolver was missing - my mistake. I also added comments to the progress

I used private IContentRepository, IContentTypeRepository ... just as an example. Due to your specific needs, you can adjust them as well.

EPiServer Framework in general, is built on Structuremap for dependency injection. You can easily override those interfaces and unit test yourself  - just use Moq or some mocking frameworks you like

. Regards

/Q

#80578
Edited, Jan 27, 2014 9:08
Vote:
 

Thank you very much Quan.

This is a life saver, I'll try this and get back to you later today. ;)

 

UPDATE: Still haven't had time to investigate this, I'll get back as soon as I can. Thank you very much Quan!

 

Thanks a lot!

 

Best regards

Miroslav

#80579
Edited, Jan 27, 2014 9:18
Vote:
 

Hello Quan

 

This worked just as expected. Thank you very much.

There is one little thing on top of this:

I want to keep the versioning of the file, so I did some investigation and came up with the solution, but...

The solution is to keep the file(MediaData) and replace the binary data on it. My problem is that I don't know how to get the ContentReference when I only know the name of the file. Do you have a clue how to solve this?

 

Best regards

Miroslav

#80786
Feb 02, 2014 1:41
Vote:
 

Hi,

The idea is to use EPiServer Search API  to search for file name then filter to match the path/folder you are looking for. I would like to find you some example code, but I'm a bit busy at the moment :)

/Q

#81067
Feb 08, 2014 2:40
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.