From e620c153d7b58e9c07e9fbd8e81292792f337f36 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Sun, 12 Jun 2016 14:58:28 +0100 Subject: [PATCH 1/3] Extracts package's required Umbraco version metadata When a package is uploaded to the Our Umbraco repository, we extract the "package.xml" manifest to detect the required (minimum) Umbraco version number. This task is part of U4-8156, at CGRT16 --- .../MarketPlace/Providers/MediaProvider.cs | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/OurUmbraco/MarketPlace/Providers/MediaProvider.cs b/OurUmbraco/MarketPlace/Providers/MediaProvider.cs index 140f073c..b03fbd90 100644 --- a/OurUmbraco/MarketPlace/Providers/MediaProvider.cs +++ b/OurUmbraco/MarketPlace/Providers/MediaProvider.cs @@ -1,9 +1,16 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Web; +using System.Xml.Linq; +using System.Xml.XPath; +using ICSharpCode.SharpZipLib.Zip; using OurUmbraco.MarketPlace.Interfaces; using OurUmbraco.MarketPlace.Models; using OurUmbraco.Wiki.BusinessLogic; +using Umbraco.Core; +using Umbraco.Core.IO; namespace OurUmbraco.MarketPlace.Providers { @@ -120,11 +127,53 @@ namespace OurUmbraco.MarketPlace.Providers //Convert to Deli Media file var MediaFile = GetFileById(uWikiFile.Id); + + // If upload is package, extract the package XML manifest and check the version number + type [LK:2016-06-12@CGRT16] + if (fileType == FileType.package) + { + var minimumUmbracoVersion = GetMinimumUmbracoVersion(MediaFile); + if (!string.IsNullOrWhiteSpace(minimumUmbracoVersion)) + { + MediaFile.Versions = new List() { new UmbracoVersion { Version = minimumUmbracoVersion } }; + } + } + MediaFile.DotNetVersion = dotNetVersion; SaveOrUpdate(MediaFile); return MediaFile; } + private string GetMinimumUmbracoVersion(WikiFile mediaFile) + { + var extractor = new PackageExtraction(); + var filePath = IOHelper.MapPath(mediaFile.Path); + var packageXml = extractor.ReadTextFileFromArchive(filePath, Constants.Packaging.PackageXmlFileName); + if (string.IsNullOrWhiteSpace(packageXml)) + { + return null; + } + + var packageXmlDoc = XDocument.Parse(packageXml); + if (packageXmlDoc == null) + { + return null; + } + + // The XPath query will detect if the 'requirements' element has the attribute that we're looking for, + // and if the child elements also exist. [LK:2016-06-12@CGRT16] + var requirements = packageXmlDoc.XPathSelectElement("/umbPackage/info/package/requirements[@type='strict' and major and minor and patch]"); + if (requirements == null) + { + return null; + } + + var major = requirements.Element("major").Value; + var minor = requirements.Element("minor").Value; + var patch = requirements.Element("patch").Value; + + return string.Join(".", new[] { major, minor, patch }); + } + public static string ToVersionString(List Versions) { var stringVers = string.Empty; @@ -152,4 +201,88 @@ namespace OurUmbraco.MarketPlace.Providers } + + // [LK:2016-06-12] This code has been copied over from Umbraco v7.5.0, (coded during CGRT16) + // Once Our has upgraded to v7.5+, then this code can be replaced with references to the core code. + class PackageExtraction + { + public string ReadTextFileFromArchive(string packageFilePath, string fileToRead) + { + string retVal = null; + bool fileFound = false; + string foundDir = null; + + ReadZipfileEntries(packageFilePath, (entry, stream) => + { + string fileName = Path.GetFileName(entry.Name); + + if (string.IsNullOrEmpty(fileName) == false && + fileName.Equals(fileToRead, StringComparison.CurrentCultureIgnoreCase)) + { + + foundDir = entry.Name.Substring(0, entry.Name.Length - fileName.Length); + fileFound = true; + using (var reader = new StreamReader(stream)) + { + retVal = reader.ReadToEnd(); + return false; + } + } + return true; + }); + + if (fileFound == false) + { + throw new FileNotFoundException(string.Format("Could not find file in package {0}", packageFilePath), fileToRead); + } + + return retVal; + } + + private static void CheckPackageExists(string packageFilePath) + { + if (string.IsNullOrEmpty(packageFilePath)) + { + throw new ArgumentNullException("packageFilePath"); + } + + if (File.Exists(packageFilePath) == false) + { + if (File.Exists(packageFilePath) == false) + throw new ArgumentException(string.Format("Package file: {0} could not be found", packageFilePath)); + } + + string extension = Path.GetExtension(packageFilePath).ToLower(); + + var alowedExtension = new[] { ".umb", ".zip" }; + + // Check if the file is a valid package + if (alowedExtension.All(ae => ae.Equals(extension) == false)) + { + throw new ArgumentException( + string.Format("Error - file isn't a package. only extentions: \"{0}\" is allowed", string.Join(", ", alowedExtension))); + } + } + + private void ReadZipfileEntries(string packageFilePath, Func entryFunc, bool skipsDirectories = true) + { + CheckPackageExists(packageFilePath); + + using (var fs = File.OpenRead(packageFilePath)) + { + using (var zipInputStream = new ZipInputStream(fs)) + { + ZipEntry zipEntry; + while ((zipEntry = zipInputStream.GetNextEntry()) != null) + { + if (zipEntry.IsDirectory && skipsDirectories) continue; + if (entryFunc(zipEntry, zipInputStream) == false) break; + } + + zipInputStream.Close(); + } + fs.Close(); + } + } + } } From 5675a68b8c6c592230b24c3987c9c4d898508c74 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Sun, 12 Jun 2016 15:08:06 +0100 Subject: [PATCH 2/3] Package upload: amends styling of Umbraco versions Quick and dirty fix to correct the styling of the Umbraco version selection on the package uploader options. --- OurUmbraco.Site/usercontrols/Deli/Package/Steps/Files.ascx | 3 ++- OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/OurUmbraco.Site/usercontrols/Deli/Package/Steps/Files.ascx b/OurUmbraco.Site/usercontrols/Deli/Package/Steps/Files.ascx index 18d4ec96..d5170509 100644 --- a/OurUmbraco.Site/usercontrols/Deli/Package/Steps/Files.ascx +++ b/OurUmbraco.Site/usercontrols/Deli/Package/Steps/Files.ascx @@ -192,9 +192,10 @@

-
+
+

If your package manifest references a specific version of Umbraco, then that will be used instead.

diff --git a/OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx b/OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx index 18d4ec96..d5170509 100644 --- a/OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx +++ b/OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx @@ -192,9 +192,10 @@

-
+
+

If your package manifest references a specific version of Umbraco, then that will be used instead.

From 7b720101f531bb570c307cd0ef4e44b1a77d954a Mon Sep 17 00:00:00 2001 From: leekelleher Date: Sun, 12 Jun 2016 16:17:22 +0100 Subject: [PATCH 3/3] Package upload: Updated ASP.NET version numbers Added the most recent ASP.NET versions for the dropdown list --- .../Project/usercontrols/Deli/Package/Steps/Files.ascx.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx.cs b/OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx.cs index cd2c0c92..35b6632f 100644 --- a/OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx.cs +++ b/OurUmbraco/Project/usercontrols/Deli/Package/Steps/Files.ascx.cs @@ -232,7 +232,7 @@ namespace OurUmbraco.Project.usercontrols.Deli.Package.Steps lt_versions.Text = umboptions; - string[] dotnetversions = { "", "2.0", "3.5", "4.0", "4.5" }; + string[] dotnetversions = { "", "2.0", "3.5", "4.0", "4.5", "4.5.1", "4.5.2", "4.6.0", "4.6.1" }; string dotnetoptions = string.Empty; foreach (var opt in dotnetversions)