I have created a custom media type pdfDocument for handling PDF documents. Now I have to upload a large amount of documents and I'd want to use the Desktop Media Uploader to save time. The problem is that when I upload a PDF using the software it is uploaded as a File media type.
Is there a way to make a relationship with a file extension and a media type in DMU? Or any other way to archive what I've explained above?
You can do this, but you'll need to write a Media Factory to handle the .pdf file extension.
DMU uses Media Factories to decide what media type to use when creating a new media item, based on the files extension. To do you what you need, you'll just need to write a PDF media factory which implements the IMediaFactory interface and which handles the .pdf file extension, and creates the media item with your custom media type. Out of the box DMU just comes with 2 media factories. Image and File.
Hi! I have developed a Media Factory successfully taking a look at the source code, as you told me. Since DMU is now part of Umbraco, I have used the source code from the umbraco codeplex site (located here http://umbraco.codeplex.com/SourceControl/changeset/view/6e569de7740a). There is a minor change, since there is an Extensions property that has to be implemented also.
Well, here is the code for the Media Factory:
---
using System; using System.Collections.Generic; using System.Linq; using System.Web; using umbraco; using System.IO; using iTextSharp.text.pdf; using System.Text; using umbraco.cms.businesslogic.media;
namespace JSV.Umbraco.cms.businesslogic.media { public class UmbracoPdfDocumentMediaFactory : UmbracoMediaFactory { public override string MediaTypeAlias { get { return "PdfDocument"; } }
public override List<string> Extensions { get { return new List<string> { "pdf" }; } }
public override void DoHandleMedia(umbraco.cms.businesslogic.media.Media media, PostedMediaFile uploadedFile, umbraco.BusinessLogic.User user) { // Get umbracoFile property var propertyId = media.getProperty("umbracoFile").Id;
// Get paths var destFileName = ConstructDestFileName(propertyId, uploadedFile.FileName); var destPath = ConstructDestPath(propertyId); var destFilePath = VirtualPathUtility.Combine(destPath, destFileName); var ext = VirtualPathUtility.GetExtension(destFileName).Substring(1);
var absoluteDestPath = HttpContext.Current.Server.MapPath(destPath); var absoluteDestFilePath = HttpContext.Current.Server.MapPath(destFilePath);
// Set media properties media.getProperty("umbracoFile").Value = destFilePath; media.getProperty("umbracoBytes").Value = uploadedFile.ContentLength.ToString();
if (media.getProperty("umbracoExtension") != null) media.getProperty("umbracoExtension").Value = ext;
if (media.getProperty("umbracoExtensio") != null) media.getProperty("umbracoExtensio").Value = ext;
var reader = new PdfReader(uploadedFile.InputStream);
//Fill the additional properties if (media.getProperty("umbracoPdfTitle") != null) media.getProperty("umbracoPdfTitle").Value = reader.Info.Where(p => p.Key == "Title").FirstOrDefault().Value;
if (media.getProperty("umbracoPdfAuthor") != null) media.getProperty("umbracoPdfAuthor").Value = reader.Info.Where(p => p.Key == "Author").FirstOrDefault().Value;
if (media.getProperty("umbracoPdfVersion") != null) media.getProperty("umbracoPdfVersion").Value = reader.PdfVersion;
if (media.getProperty("umbracoPdfNumberOfPages") != null) media.getProperty("umbracoPdfNumberOfPages").Value = reader.NumberOfPages.ToString();
if (media.getProperty("umbracoPdfTableOfContent") != null) media.getProperty("umbracoPdfTableOfContent").Value = GenerateTextBookmark(reader);
// Create directory if (UmbracoSettings.UploadAllowDirectories) Directory.CreateDirectory(absoluteDestPath);
// Save file uploadedFile.SaveAs(absoluteDestFilePath);
// Close stream uploadedFile.InputStream.Close();
// Save media media.Save(); }
private static string GenerateTextBookmark(PdfReader reader) { IEnumerable<Dictionary<string, object>> bookmarks = SimpleBookmark.GetBookmark(reader); if (bookmarks == null) return String.Empty; var builder = new StringBuilder(); return GenerateBookmarkSection(bookmarks, builder); }
private static string GenerateBookmarkSection(IEnumerable<Dictionary<string, object>> section, StringBuilder builder) { if (section == null) return String.Empty; builder.Append("<ul>"); foreach (var bookmark in section) { object value; bookmark.TryGetValue("Title", out value); builder.Append("<li>"); builder.Append(value.ToString()); if (bookmark.Count == 5) { GenerateBookmarkSection((IEnumerable<Dictionary<string, object>>)bookmark.Values.Last(), builder); } builder.Append("</li>"); } builder.Append("</ul>"); return builder.ToString(); } } }
---
You will need to add a reference to iTextSharp library (I used version 5.1.1).
The only problem I could not manage to fix is when I try to set the property "umbracoBytes" to the value of uploadedFile.ContentLength. It throws me an exception that basically, can not convert int to Ntext. I imagined that the problem was on the Media Type definition, since that property uses the "Label" Data Type, which has its property "Database datatype" to "Ntext". But I've checked that Image and File Media types also have this setting, but it doesn't crashes like me. Anyway, simply casted ContentLength to String and the problem is workarounded.
Thank you once again for your help and I hope this can help anyone who faces a similar problem
Upload PDF as 'pdfDocument' custom media type
Hi!
I have created a custom media type pdfDocument for handling PDF documents. Now I have to upload a large amount of documents and I'd want to use the Desktop Media Uploader to save time. The problem is that when I upload a PDF using the software it is uploaded as a File media type.
Is there a way to make a relationship with a file extension and a media type in DMU? Or any other way to archive what I've explained above?
I'm currently using version 2.1.0 in Umbraco 4.7
Thank you in advance
Hey,
You can do this, but you'll need to write a Media Factory to handle the .pdf file extension.
DMU uses Media Factories to decide what media type to use when creating a new media item, based on the files extension. To do you what you need, you'll just need to write a PDF media factory which implements the IMediaFactory interface and which handles the .pdf file extension, and creates the media item with your custom media type. Out of the box DMU just comes with 2 media factories. Image and File.
You can take a look at how this work here:
http://dmu4umb.codeplex.com/SourceControl/changeset/view/0c5a4c0b9704#UmbracoMediaFactory.cs
I really need to get round to writing a blog post about Media Factories, but in the mean time, the source code above should give you a starting point.
Cheers
Matt
Thank you for you advice! I'll give it a try next week and I'll let you know about my progress...
Cheers
Hi! I have developed a Media Factory successfully taking a look at the source code, as you told me. Since DMU is now part of Umbraco, I have used the source code from the umbraco codeplex site (located here http://umbraco.codeplex.com/SourceControl/changeset/view/6e569de7740a). There is a minor change, since there is an Extensions property that has to be implemented also.
Well, here is the code for the Media Factory:
---
---
You will need to add a reference to iTextSharp library (I used version 5.1.1).
The only problem I could not manage to fix is when I try to set the property "umbracoBytes" to the value of uploadedFile.ContentLength. It throws me an exception that basically, can not convert int to Ntext. I imagined that the problem was on the Media Type definition, since that property uses the "Label" Data Type, which has its property "Database datatype" to "Ntext". But I've checked that Image and File Media types also have this setting, but it doesn't crashes like me. Anyway, simply casted ContentLength to String and the problem is workarounded.
Thank you once again for your help and I hope this can help anyone who faces a similar problem
That's brilliant! Nice work. Glad you got it working in the end.
Matt
is working on a reply...