From 9aa9de5a7a8bf82787888a29644690d9a6b52708 Mon Sep 17 00:00:00 2001 From: per ploug Date: Mon, 18 Aug 2014 20:42:56 +0200 Subject: [PATCH] WIP on background package installs --- src/Umbraco.Core/Constants-Applications.cs | 5 + .../src/common/resources/package.resource.js | 105 ++++++++++++++++++ .../dashboard/dashboard.tabs.controller.js | 38 +++++++ .../dashboard/forms/formsdashboardintro.html | 34 ++++++ .../config/Dashboard.Release.config | 11 ++ .../config/applications.Release.config | 3 +- .../Editors/BackOfficeController.cs | 5 + .../Editors/PackageInstallController.cs | 88 +++++++++++++++ src/Umbraco.Web/Models/PackageInstallModel.cs | 28 +++++ src/Umbraco.Web/Umbraco.Web.csproj | 3 + 10 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html create mode 100644 src/Umbraco.Web/Editors/PackageInstallController.cs create mode 100644 src/Umbraco.Web/Models/PackageInstallModel.cs diff --git a/src/Umbraco.Core/Constants-Applications.cs b/src/Umbraco.Core/Constants-Applications.cs index 2cb30630bc..5182259ddf 100644 --- a/src/Umbraco.Core/Constants-Applications.cs +++ b/src/Umbraco.Core/Constants-Applications.cs @@ -41,6 +41,11 @@ /// Application alias for the users section. /// public const string Users = "users"; + + /// + /// Application alias for the users section. + /// + public const string Forms = "forms"; } /// diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js new file mode 100644 index 0000000000..c1d95861eb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js @@ -0,0 +1,105 @@ +/** + * @ngdoc service + * @name umbraco.resources.packageInstallResource + * @description handles data for package installations + **/ +function packageResource($q, $http, umbDataFormatter, umbRequestHelper) { + + return { + + + /** + * @ngdoc method + * @name umbraco.resources.packageInstallResource#fetchPackage + * @methodOf umbraco.resources.packageInstallResource + * + * @description + * Downloads a package file from our.umbraco.org to the website server. + * + * ##usage + *
+         * packageResource.download("guid-guid-guid-guid")
+         *    .then(function(path) {
+         *        alert('downloaded');
+         *    });
+         * 
+ * + * @param {String} the unique package ID + * @returns {String} path to the downloaded zip file. + * + */ + fetch: function (id) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "packageInstallApiBaseUrl", + "Fetch", + [{ packageGuid: id }])), + 'Failed to download package with guid ' + id); + }, + + /** + * @ngdoc method + * @name umbraco.resources.packageInstallResource#createmanifest + * @methodOf umbraco.resources.packageInstallResource + * + * @description + * Creates a package manifest for a given folder of files. + * This manifest keeps track of all installed files and data items + * so a package can be uninstalled at a later time. + * After creating a manifest, you can use the ID to install files and data. + * + * ##usage + *
+         * packageResource.createManifest("packages/id-of-install-file")
+         *    .then(function(summary) {
+         *        alert('unzipped');
+         *    });
+         * 
+ * + * @param {String} folder the path to the temporary folder containing files + * @returns {Int} the ID assigned to the saved package manifest + * + */ + import: function (package) { + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "packageInstallApiBaseUrl", + "Import"), package), + 'Failed to create package manifest for zip file '); + }, + + installFiles: function (package) { + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "packageInstallApiBaseUrl", + "InstallFiles"), package), + 'Failed to create package manifest for zip file '); + }, + + installData: function (package) { + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "packageInstallApiBaseUrl", + "InstallData"), package), + 'Failed to create package manifest for zip file '); + }, + + cleanUp: function (package) { + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "packageInstallApiBaseUrl", + "CleanUp"), package), + 'Failed to create package manifest for zip file '); + } + }; +} + +angular.module('umbraco.resources').factory('packageResource', packageResource); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js index be10ebae9e..092f3cbf0f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js @@ -16,6 +16,44 @@ function startUpVideosDashboardController($scope, xmlhelper, $log, $http) { } angular.module("umbraco").controller("Umbraco.Dashboard.StartupVideosController", startUpVideosDashboardController); + + +function FormsController($scope, $route, packageResource) { + $scope.installForms = function(){ + $scope.state = "Installng package"; + packageResource + .fetch("6DA629D5-177A-4ACE-875B-A06B13CCEC48") + .then(function(pack){ + $scope.state = "importing"; + return packageResource.import(pack); + }, $scope.error) + .then(function(pack){ + $scope.state = "Installing"; + return packageResource.installFiles(pack); + }, $scope.error) + .then(function(pack){ + $scope.state = "Restarting, please hold..."; + return packageResource.installData(pack); + }, $scope.error) + .then(function(pack){ + $scope.state = "All done, your browser will now refresh"; + return packageResource.cleanUp(pack); + }, $scope.error) + .then($scope.complete, $scope.error); + }; + + $scope.complete = function(result){ + $route.reload(); + }; + + $scope.error = function(err){ + $scope.state = undefined; + $scope.error = err; + }; +} + +angular.module("umbraco").controller("Umbraco.Dashboard.FormsDashboardController", FormsController); + function startupLatestEditsController($scope) { } diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html new file mode 100644 index 0000000000..8ba5746a80 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html @@ -0,0 +1,34 @@ +
+

Build flawless forms without a single line of code

+
Contour makes creating contact forms, entry forms and questionnaires just as easy as using Word. You won't need to write a single line of code.
+
Instead, you can create, edit and administer your forms via a user interface that is a fully integrated part of Umbraco.
+ + + + +
+

{{state}}...

+
+
+ + {{error}} + +
+ +

Some of the great features

+ +
+
+

Feature

+
+
+

Feature

+
+
+

Feature

+
+
+

Feature

+
+
+
\ No newline at end of file diff --git a/src/Umbraco.Web.UI/config/Dashboard.Release.config b/src/Umbraco.Web.UI/config/Dashboard.Release.config index c0a2080d49..9ab9b8b313 100644 --- a/src/Umbraco.Web.UI/config/Dashboard.Release.config +++ b/src/Umbraco.Web.UI/config/Dashboard.Release.config @@ -12,6 +12,17 @@ +
+ + forms + + + + views/dashboard/forms/formsdashboardintro.html + + +
+
developer diff --git a/src/Umbraco.Web.UI/config/applications.Release.config b/src/Umbraco.Web.UI/config/applications.Release.config index 062500e1fc..c35a68e941 100644 --- a/src/Umbraco.Web.UI/config/applications.Release.config +++ b/src/Umbraco.Web.UI/config/applications.Release.config @@ -6,5 +6,6 @@ - + + \ No newline at end of file diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 3a9886be1e..cc0c01f48f 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -178,6 +178,10 @@ namespace Umbraco.Web.Editors "memberApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetByKey(Guid.Empty)) }, + { + "packageInstallApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( + controller => controller.Fetch(string.Empty)) + }, { "rteApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetConfiguration()) @@ -186,6 +190,7 @@ namespace Umbraco.Web.Editors "stylesheetApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetAll()) }, + { "templateApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetById(0)) diff --git a/src/Umbraco.Web/Editors/PackageInstallController.cs b/src/Umbraco.Web/Editors/PackageInstallController.cs new file mode 100644 index 0000000000..346a5153d1 --- /dev/null +++ b/src/Umbraco.Web/Editors/PackageInstallController.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Web.Http; +using System.Xml; +using System.Xml.Linq; +using umbraco.cms.businesslogic.packager.repositories; +using Umbraco.Core.IO; +using Umbraco.Core.Packaging.Models; +using Umbraco.Core.Services; +using Umbraco.Web.Models; +using Umbraco.Web.Mvc; +using Umbraco.Web.WebApi.Filters; + +namespace Umbraco.Web.Editors +{ + [PluginController("UmbracoApi")] + [UmbracoApplicationAuthorize(Core.Constants.Applications.Developer)] + public class PackageInstallController : UmbracoAuthorizedJsonController + { + + [HttpGet] + public PackageInstallModel Fetch(string packageGuid) + { + //Default path + string path = Path.Combine("packages", packageGuid + ".umb"); + if (!File.Exists(IOHelper.MapPath(Path.Combine(SystemDirectories.Data, path)))) + { + //our repo guid + var our = Repository.getByGuid("65194810-1f85-11dd-bd0b-0800200c9a66"); + path = our.fetch(packageGuid); + } + + PackageInstallModel p = new PackageInstallModel(); + p.PackageGuid = Guid.Parse(packageGuid); + p.RepositoryGuid = Guid.Parse("65194810-1f85-11dd-bd0b-0800200c9a66"); + //p.ZipFilePath = path; + p.ZipFilePath = Path.Combine("temp", "package.umb"); + return p; + } + + [HttpPost] + public PackageInstallModel Import(PackageInstallModel model) + { + global::umbraco.cms.businesslogic.packager.Installer ins = new global::umbraco.cms.businesslogic.packager.Installer(); + model.TemporaryDirectoryPath = Path.Combine(SystemDirectories.Data, ins.Import(model.ZipFilePath)); + model.Id = ins.CreateManifest( IOHelper.MapPath(model.TemporaryDirectoryPath), model.PackageGuid.ToString(), model.RepositoryGuid.ToString()); + return model; + } + + [HttpPost] + public PackageInstallModel InstallFiles(PackageInstallModel model) + { + global::umbraco.cms.businesslogic.packager.Installer ins = new global::umbraco.cms.businesslogic.packager.Installer(); + ins.LoadConfig(IOHelper.MapPath(model.TemporaryDirectoryPath)); + ins.InstallFiles(model.Id, IOHelper.MapPath(model.TemporaryDirectoryPath)); + return model; + } + + + [HttpPost] + public PackageInstallModel InstallData(PackageInstallModel model) + { + global::umbraco.cms.businesslogic.packager.Installer ins = new global::umbraco.cms.businesslogic.packager.Installer(); + ins.LoadConfig(IOHelper.MapPath(model.TemporaryDirectoryPath)); + ins.InstallBusinessLogic(model.Id, IOHelper.MapPath(model.TemporaryDirectoryPath)); + return model; + } + + + [HttpPost] + public PackageInstallModel CleanUp(PackageInstallModel model) + { + global::umbraco.cms.businesslogic.packager.Installer ins = new global::umbraco.cms.businesslogic.packager.Installer(); + ins.LoadConfig(IOHelper.MapPath(model.TemporaryDirectoryPath)); + ins.InstallCleanUp(model.Id, IOHelper.MapPath(model.TemporaryDirectoryPath)); + return model; + } + + + } +} diff --git a/src/Umbraco.Web/Models/PackageInstallModel.cs b/src/Umbraco.Web/Models/PackageInstallModel.cs new file mode 100644 index 0000000000..34b28843b6 --- /dev/null +++ b/src/Umbraco.Web/Models/PackageInstallModel.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace Umbraco.Web.Models +{ + [DataContract(Name = "packageInstallModel")] + public class PackageInstallModel + { + [DataMember(Name="id")] + public int Id { get; set; } + + [DataMember(Name = "packageGuid")] + public Guid PackageGuid { get; set; } + + [DataMember(Name = "repositoryGuid")] + public Guid RepositoryGuid { get; set; } + + [DataMember(Name = "temporaryDirectoryPath")] + public string TemporaryDirectoryPath { get; set; } + + [DataMember(Name = "zipFilePath")] + public string ZipFilePath { get; set; } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 78b68a2f1c..f9940e551d 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -160,6 +160,7 @@ System.Drawing + False False @@ -302,9 +303,11 @@ + +