I've extended my 'onsave' button to, depending on the document type and if a property it's filed, grab some online data from a JSON API (getting among other stuff, a URL to a live image).
How can I create one media image on the fly, when saving the document (from an IUserComposer extension) ?
(I just need help for the Umbraco Media parts, using what I guess it is the Media Service in V8)
Here's a bit of code for when I imported my old blog content into v8, should help, mainly the last part I guess - make sure to get a stream from the file and then you can indeed use the MediaService to save it:
public GuidUdi CreateMediaImageFromMediaId(int mediaId, IEnumerable<MediaItem> mediaItems, string nodeName)
{
var mediaFile = mediaItems.FirstOrDefault(x => x.Id == mediaId);
if (mediaFile == null)
return null;
var url = $"https://cultiv.nl/{mediaFile.UmbracoFile}";
return CreateMediaImageFromUrl(url, nodeName);
}
private GuidUdi CreateMediaImageFromUrl(string url, string nodeName)
{
var downloadPath = IOHelper.MapPath("~/App_Data/TEMP/DownloadedFiles");
if (Directory.Exists(downloadPath) == false)
Directory.CreateDirectory(downloadPath);
var fileName = url.Substring(url.LastIndexOf('/') + 1);
if (fileName.Contains("?"))
fileName = fileName.Substring(0, fileName.IndexOf("?"));
var filePath = $"{downloadPath}/{fileName}";
if (File.Exists(filePath) == false)
using (var client = new WebClient())
try
{
client.DownloadFile(url, filePath);
}
catch (Exception e)
{
}
if (File.Exists(filePath) == false)
return null;
var blogPostsRoot = _helper.MediaAtRoot().FirstOrDefault(x => x.Name == "Blog Posts");
Guid blogPostsRootFolderId;
if (blogPostsRoot == null)
{
var blogPostsRootFolder = _mediaService.CreateMedia("Blog Posts", -1, "Folder");
_mediaService.Save(blogPostsRootFolder, userId: -1);
blogPostsRootFolderId = blogPostsRootFolder.Key;
}
else
{
blogPostsRootFolderId = blogPostsRoot.Key;
}
var thisBlogPostRoot = _helper.Media(blogPostsRootFolderId).Children.FirstOrDefault(x => x.Name == nodeName);
Guid thisBlogPostsRootFolderId;
if (thisBlogPostRoot == null)
{
var thisBlogPostsRootFolder = _mediaService.CreateMedia(nodeName, blogPostsRootFolderId, "Folder");
_mediaService.Save(thisBlogPostsRootFolder, userId: -1);
thisBlogPostsRootFolderId = thisBlogPostsRootFolder.Key;
}
else
{
thisBlogPostsRootFolderId = thisBlogPostRoot.Key;
}
using (var imageStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
// Stream the file into a new umbraco media item
var imageMedia = _mediaService.CreateMedia(fileName, thisBlogPostsRootFolderId, "Image");
imageMedia.SetValue(_contentTypeBaseServiceProvider, "umbracoFile", fileName, imageStream);
_mediaService.Save(imageMedia, -1);
return new GuidUdi("media", imageMedia.Key);
}
}
Creating media on the fly
Hey,
I've extended my 'onsave' button to, depending on the document type and if a property it's filed, grab some online data from a JSON API (getting among other stuff, a URL to a live image).
How can I create one media image on the fly, when saving the document (from an IUserComposer extension) ?
(I just need help for the Umbraco Media parts, using what I guess it is the Media Service in V8)
TIA /LPP
Here's a bit of code for when I imported my old blog content into v8, should help, mainly the last part I guess - make sure to get a stream from the file and then you can indeed use the MediaService to save it:
Thanks Sebastiaan
Having a difficulty crossing this 'lines'.
_mediaService and _contentTypeBaseServiceProvider declaration from y ContentService.IUserComposer extension
Use dependency injection. :-)
So if your class is named
Importer
, create a new constructorpublic Importer() { .. }
and ask for the things you need:I have more of a detailed explanation here: https://our.umbraco.com/forum/umbraco-8/96125-custom-application-started-events#comment-304012
Awesome.
Sebastiaan, you're the man.
Thanks a lot :)
is working on a reply...