First I added a method to the Nop.Plugin.Misc.WebServices plug in that allowed for image uploads with a product id. This uses code copied over from the admin image upload to add the product image.
public bool UploadImage(byte[] imageFile, string fileName, int productId)
{
try
{
string contentType = string.Empty;
switch (Path.GetExtension(fileName))
{
case ".bmp":
contentType = "image/bmp";
break;
case ".gif":
contentType = "image/gif";
break;
case ".jpeg":
case ".jpg":
case ".jpe":
case ".jfif":
case ".pjpeg":
case ".pjp":
contentType = "image/jpeg";
break;
case ".png":
contentType = "image/png";
break;
case ".tiff":
case ".tif":
contentType = "image/tiff";
break;
default:
break;
}
var picture = _pictureService.InsertPicture(imageFile, contentType, null, true);
var product = _productService.GetProductById(productId);
if (product == null)
throw new ArgumentException("No product found with the specified id");
//Add new one
_productService.InsertProductPicture(new ProductPicture()
{
PictureId = picture.Id,
ProductId = productId,
DisplayOrder = 0
});
_pictureService.SetSeoFilename(picture.Id, _pictureService.GetPictureSeName(product.Name));
return true;
}
catch
{
return false;
}
return false;
}
All of our images from ASPDotNetStorefront are saved by the SKU as the filename so searching them and matching to products in Nop Commerce DB was easy. You can change the query to search for any field (MPN for example) as well. For this I just wrote a small console application that connected to the Nop Commerce web service when a filename/sku match was found and uploaded the image. I ran it on 31,000 images for about 9,000 products and it seems to work well.
Console.WriteLine("---------------------\r\nNop Bulk Image Importer by Tom Bishop\r\n---------------------");
Console.WriteLine("Where are your images stored? (enter full path)");
imageDirectory = Console.ReadLine();
string productSqlQuery = string.Format("select * from productvariant");
int importedImageCount = 0;
int failedImageCount = 0;
if (!string.IsNullOrEmpty(imageDirectory))
{
Console.WriteLine("Connecting to database...");
SqlConnection sqlConnection = new SqlConnection(Properties.Settings.Default.NopDatabase);
sqlConnection.Open();
using (IDataReader reader = GetReader(productSqlQuery, sqlConnection))
{
string[] files = Directory.GetFiles(imageDirectory);
string previousSku = string.Empty;
Console.WriteLine("Connected! " + files.Count() + " images found...");
while (reader.Read())
{
string sku = reader["Sku"].ToString();
if (!string.IsNullOrEmpty(sku))
{
if (sku.Contains(" "))
sku = sku.Split((" ").ToCharArray())[0];
if (sku != previousSku)
{
Console.WriteLine("Searching images for sku: " + sku);
long previousImageFileSize = 0;
foreach (string file in files)
{
if (file.Contains(sku))
{
string filePath = Path.Combine(imageDirectory, file);
FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fStream);
FileInfo fileInfo = new FileInfo(filePath);
//Make sure this image isn't a duplicate of one that just went up
if (fileInfo.Length != previousImageFileSize)
{
byte[] data = br.ReadBytes((int)fileInfo.Length);
br.Close();
NopServiceClient client = new NopServiceClient();
bool result = client.UploadImage(data, file, Convert.ToInt32(reader["ProductId"]));
if (result)
{
previousImageFileSize = fileInfo.Length;
importedImageCount++;
Console.WriteLine("Image found & uploaded for sku: " + sku + " (" + file + ")");
}
else
{
failedImageCount++;
}
}
}
}
}
}
previousSku = sku;
}
}
sqlConnection.Close();
}
Console.WriteLine("Search complete. Imported " + importedImageCount + " images! " + failedImageCount + " failed.");
Console.WriteLine("Press any key to continue...");
Console.ReadLine();
PLEASE NOTE: I did not authenticate, you may want to add that or remove this method from the service once you are done using it.
You could even move the DB searched to the web service and just pass the filename. I wrote this fairly quickly but it works! Hope this helps someone as it has helped me!