This commit is contained in:
Kevin Giszewski
2017-09-06 18:32:48 -04:00
parent b9179f4140
commit 1cb2139137
10 changed files with 231 additions and 57 deletions
@@ -1,9 +1,7 @@
using System.Collections.Generic;
using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Web.Http;
using AutoMapper;
using Umbraco.Core.Models;
@@ -11,29 +9,28 @@ using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
using Umbraco.Web.Editors;
using Archetype.Extensions;
using Archetype.Models;
namespace Archetype.Api
{/// <summary>
{
/// <summary>
/// Controller that handles datatype related interactions.
/// </summary>
/// <seealso cref="Umbraco.Web.Editors.UmbracoAuthorizedJsonController" />
[PluginController("ArchetypeApi")]
public class ArchetypeDataTypeController : UmbracoAuthorizedJsonController
{
private readonly ArchetypeHelper _archetypeHelper = new ArchetypeHelper();
{
public IEnumerable<object> GetAllPropertyEditors()
{
return
global::Umbraco.Core.PropertyEditors.PropertyEditorResolver.Current.PropertyEditors
.Select(x => new {defaultPreValues = x.DefaultPreValuesForArchetype(), alias = x.Alias, view = x.ValueEditor.View});
.Select(x => new { defaultPreValues = x.DefaultPreValuesForArchetype(), alias = x.Alias, view = x.ValueEditor.View });
}
/// <summary>
/// Gets all datatypes.
/// </summary>
/// <returns></returns>
public object GetAll()
public object GetAll()
{
var dataTypes = Services.DataTypeService.GetAllDataTypeDefinitions();
return dataTypes.Select(t => new { guid = t.Key, name = t.Name });
@@ -84,40 +81,56 @@ namespace Archetype.Api
/// <returns></returns>
public object GetDllVersion()
{
return new {dllVersion = _version()};
return new { dllVersion = ArchetypeHelper.Instance.DllVersion() };
}
/// <summary>
/// Globals the settings.
/// </summary>
/// <returns>System.Object.</returns>
[HttpGet]
public object GlobalSettings()
{
return new
{
isCheckingForUpdates = _archetypeHelper.GetGlobalSettings().IsCheckingForUpdates
isCheckingForUpdates = ArchetypeHelper.Instance.GetGlobalSettings().IsCheckingForUpdates
};
}
/// <summary>
/// Sets the check for updates.
/// </summary>
/// <param name="isChecking">if set to <c>true</c> [is checking].</param>
[HttpPost]
public void SetCheckForUpdates([FromBody] bool isChecking)
{
_archetypeHelper.SetCheckForUpdates(isChecking);
}
[HttpPost]
public void CheckForUpdates()
{
_archetypeHelper.CheckForUpdates();
ArchetypeHelper.Instance.SetCheckForUpdates(isChecking);
}
/// <summary>
/// Gets the DLL version from the file.
/// Checks for updates.
/// </summary>
/// <returns></returns>
private string _version()
/// <returns>System.Object.</returns>
[HttpPost]
public object CheckForUpdates()
{
var asm = Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(asm.Location);
if (!ArchetypeHelper.Instance.GetGlobalSettings().IsCheckingForUpdates)
{
return new
{
isUpdateAvailable = false
};
}
return fvi.FileVersion;
var updateNotificationModel = ArchetypeHelper.Instance.CheckForUpdates();
return new
{
isUpdateAvailable = updateNotificationModel.IsUpdateAvailable,
headline = updateNotificationModel.Headline,
type = updateNotificationModel.Type,
message = updateNotificationModel.Message
};
}
}
}
@@ -232,6 +232,7 @@
<Compile Include="Api\ArchetypeDataTypeController.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Events\ExpireCache.cs" />
<Compile Include="Events\StartUp.cs" />
<Compile Include="Extensions\ArchetypeFieldsetModelExtensions.cs" />
<Compile Include="Extensions\ArchetypeHelper.cs" />
<Compile Include="Extensions\ArchetypeModelExtensions.cs" />
@@ -250,6 +251,7 @@
<Compile Include="Models\ArchetypePublishedContent.cs" />
<Compile Include="Models\ArchetypePublishedContentSet.cs" />
<Compile Include="Models\ArchetypePublishedProperty.cs" />
<Compile Include="Models\ArchetypeUpdateNotification.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\VersionInfo.cs" />
<Compile Include="PropertyConverters\ArchetypeValueConverter.cs" />
@@ -14,5 +14,8 @@
public const string CacheKey_PreValueFromDataTypeId = "Archetype_GetArchetypePreValueFromDataTypeId_";
public const string CheckForUpdatesAlias = "Archetype:CheckForUpdates";
public const string IdAlias = "Archetype:Id";
public const string UmbracoVersionAlias = "umbracoConfigurationStatus";
public const string NotificationUrl = "https://api.gizmo42.com/v1/archetype/CheckForUpdates";
}
}
@@ -0,0 +1,38 @@
using System;
using System.Web.Configuration;
using Umbraco.Core;
namespace Archetype.Events
{
public class StartUp : ApplicationEventHandler
{
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
base.ApplicationStarting(umbracoApplication, applicationContext);
var config = WebConfigurationManager.OpenWebConfiguration("~");
//do we have an Archetype Id?
if (config.AppSettings.Settings[Constants.IdAlias] == null)
{
//guess we need one
config.AppSettings.Settings.Add(Constants.IdAlias, Guid.NewGuid().ToString());
config.Save();
}
else
{
//we have the setting, but is it a GUID?
Guid id;
if (!Guid.TryParse(config.AppSettings.Settings[Constants.IdAlias].Value, out id))
{
config.AppSettings.Settings.Remove(Constants.IdAlias);
config.AppSettings.Settings.Add(Constants.IdAlias, Guid.NewGuid().ToString());
config.Save();
}
//guess we're g2g
}
}
}
}
@@ -1,12 +1,17 @@
using System;
using System.Configuration;
using System.Linq;
using System.Web.Configuration;
using System.Net.Http;
using System.Text;
using Archetype.Models;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using System.Reflection;
using System.Diagnostics;
using System.Net;
/// <summary>
/// The Extensions namespace.
@@ -18,32 +23,69 @@ namespace Archetype.Extensions
/// </summary>
public class ArchetypeHelper
{
/// <summary>
/// The json settings
/// </summary>
protected JsonSerializerSettings _jsonSettings;
/// <summary>
/// The application
/// </summary>
protected ApplicationContext _app;
private ArchetypeGlobalSettings _globalSettings = new ArchetypeGlobalSettings();
private static readonly ArchetypeHelper _instance = new ArchetypeHelper();
internal static ArchetypeHelper Instance { get { return _instance; } }
/// <summary>
/// Initializes a new instance of the <see cref="ArchetypeHelper"/> class.
/// The global settings
/// </summary>
internal ArchetypeHelper()
private readonly ArchetypeGlobalSettings _globalSettings;
/// <summary>
/// The pad lock
/// </summary>
private static readonly object _padLock = new object();
/// <summary>
/// The instance
/// </summary>
private static ArchetypeHelper _instance = new ArchetypeHelper();
/// <summary>
/// Gets the instance.
/// </summary>
/// <value>The instance.</value>
internal static ArchetypeHelper Instance {
get
{
if (_instance == null)
{
lock (_padLock)
{
if (_instance == null)
{
_instance = new ArchetypeHelper();
}
}
}
return _instance;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="ArchetypeHelper" /> class.
/// </summary>
private ArchetypeHelper()
{
var dcr = new Newtonsoft.Json.Serialization.DefaultContractResolver();
dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic;
dcr.DefaultMembersSearchFlags |= BindingFlags.NonPublic;
_jsonSettings = new JsonSerializerSettings { ContractResolver = dcr };
_app = ApplicationContext.Current;
_globalSettings = new ArchetypeGlobalSettings();
}
/// <summary>
/// Gets the json serializer settings.
/// </summary>
/// <value>
/// The json serializer settings.
/// </value>
/// <value>The json serializer settings.</value>
internal JsonSerializerSettings JsonSerializerSettings { get { return _jsonSettings; } }
/// <summary>
@@ -51,7 +93,7 @@ namespace Archetype.Extensions
/// </summary>
/// <param name="sourceJson">The source JSON.</param>
/// <param name="dataTypePreValues">The data type pre values.</param>
/// <returns></returns>
/// <returns>ArchetypeModel.</returns>
internal ArchetypeModel DeserializeJsonToArchetype(string sourceJson, PreValueCollection dataTypePreValues)
{
try
@@ -83,7 +125,7 @@ namespace Archetype.Extensions
/// <param name="sourceJson">The source JSON.</param>
/// <param name="dataTypeId">The data type identifier.</param>
/// <param name="hostContentType">Type of the host content.</param>
/// <returns></returns>
/// <returns>ArchetypeModel.</returns>
internal ArchetypeModel DeserializeJsonToArchetype(string sourceJson, int dataTypeId, PublishedContentType hostContentType = null)
{
try
@@ -113,7 +155,7 @@ namespace Archetype.Extensions
/// Determines whether datatypeId has had it's PVC overridden.
/// </summary>
/// <param name="dataTypeId">The data type identifier.</param>
/// <returns></returns>
/// <returns><c>true</c> if [is property value converter overridden] [the specified data type identifier]; otherwise, <c>false</c>.</returns>
internal bool IsPropertyValueConverterOverridden(int dataTypeId)
{
var prevalues = GetArchetypePreValueFromDataTypeId(dataTypeId);
@@ -124,29 +166,79 @@ namespace Archetype.Extensions
return prevalues.OverrideDefaultPropertyValueConverter;
}
/// <summary>
/// Gets the global settings.
/// </summary>
/// <returns>ArchetypeGlobalSettings.</returns>
internal ArchetypeGlobalSettings GetGlobalSettings()
{
return _globalSettings;
}
/// <summary>
/// Sets the check for updates.
/// </summary>
/// <param name="isChecking">if set to <c>true</c> [is checking].</param>
internal void SetCheckForUpdates(bool isChecking)
{
_globalSettings.IsCheckingForUpdates = isChecking;
_globalSettings.Save();
}
internal void CheckForUpdates()
/// <summary>
/// Checks for updates.
/// </summary>
/// <returns>ArchetypeUpdateNotification.</returns>
internal ArchetypeUpdateNotification CheckForUpdates()
{
//http request
//send umb version
//send archetype version
try
{
using (var client = new HttpClient())
{
var id = ConfigurationManager.AppSettings[Constants.IdAlias];
if (id == null)
{
id = Guid.NewGuid().ToString();
}
var content = new StringContent(new
{
umbracoVersion = ConfigurationManager.AppSettings[Constants.UmbracoVersionAlias],
archetypeVersion = DllVersion(),
id = id
}.ToString(), Encoding.UTF8, "application/json");
var response = client.PostAsync(new Uri(Constants.NotificationUrl), content).Result;
if (response.StatusCode == HttpStatusCode.OK)
{
var responseString = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<ArchetypeUpdateNotification>(responseString);
}
return new ArchetypeUpdateNotification
{
IsUpdateAvailable = false
};
}
}
catch (Exception ex)
{
//if anything goes wrong let's make sure we don't break their site
return new ArchetypeUpdateNotification
{
IsUpdateAvailable = false
};
}
}
/// <summary>
/// Gets the archetype pre value from data type identifier.
/// </summary>
/// <param name="dataTypeId">The data type identifier.</param>
/// <returns></returns>
/// <returns>ArchetypePreValue.</returns>
private ArchetypePreValue GetArchetypePreValueFromDataTypeId(int dataTypeId)
{
return _app.ApplicationCache.RuntimeCache.GetCacheItem(
@@ -171,7 +263,7 @@ namespace Archetype.Extensions
/// Gets the archetype pre value from pre values collection.
/// </summary>
/// <param name="dataTypePreValues">The data type pre values.</param>
/// <returns></returns>
/// <returns>ArchetypePreValue.</returns>
private ArchetypePreValue GetArchetypePreValueFromPreValuesCollection(PreValueCollection dataTypePreValues)
{
var preValueAsString = dataTypePreValues.PreValuesAsDictionary.First().Value.Value;
@@ -183,7 +275,7 @@ namespace Archetype.Extensions
/// Gets the data type by unique identifier.
/// </summary>
/// <param name="guid">The unique identifier.</param>
/// <returns></returns>
/// <returns>IDataTypeDefinition.</returns>
internal IDataTypeDefinition GetDataTypeByGuid(Guid guid)
{
return (IDataTypeDefinition)ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem(
@@ -196,6 +288,7 @@ namespace Archetype.Extensions
/// </summary>
/// <param name="archetype">The Archetype to add the additional metadata to</param>
/// <param name="preValue">The configuration of the Archetype</param>
/// <param name="hostContentType">Type of the host content.</param>
private void RetrieveAdditionalProperties(ref ArchetypeModel archetype, ArchetypePreValue preValue, PublishedContentType hostContentType = null)
{
foreach (var fieldset in preValue.Fieldsets)
@@ -221,7 +314,6 @@ namespace Archetype.Extensions
/// <summary>
/// Retrieves additional metadata that isn't available on the stored model of an ArchetypePreValue
/// </summary>
/// <param name="archetype">The Archetype to add the additional metadata to</param>
/// <param name="preValue">The configuration of the Archetype</param>
private void RetrieveAdditionalProperties(ref ArchetypePreValue preValue)
{
@@ -233,5 +325,18 @@ namespace Archetype.Extensions
}
}
}
/// <summary>
/// Gets the DLL version from the file.
/// </summary>
/// <returns>System.String.</returns>
internal string DllVersion()
{
var asm = Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(asm.Location);
return fvi.FileVersion;
}
}
}
@@ -0,0 +1,10 @@
namespace Archetype.Models
{
public class ArchetypeUpdateNotification
{
public bool IsUpdateAvailable { get; set; }
public string Headline { get; set; }
public string Type { get; set; }
public string Message { get; set; }
}
}
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Archetype")]
[assembly: AssemblyDescription("Archetype's supporting code library for Umbraco")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Imulus")]
[assembly: AssemblyCompany("Kevin Giszewski LLC")]
[assembly: AssemblyProduct("Archetype")]
[assembly: AssemblyCopyright("MIT Licensed")]
[assembly: AssemblyTrademark("")]
+9 -7
View File
@@ -1,4 +1,4 @@
angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, dialogService, archetypePropertyEditorResource, archetypeGlobalConfigService, notificationService) {
angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, dialogService, archetypePropertyEditorResource, archetypeGlobalConfigService, notificationsService) {
//$scope.model.value = "";
//console.log($scope.model.value);
@@ -17,12 +17,14 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
$scope.dllVersion = data.dllVersion;
});
archetypeGlobalConfigService.checkForUpdates().then(function() {
console.log("checked...");
notificationService.showNotification({
type: 'info',
message: 'A new version of Archetype is available!'
});
archetypeGlobalConfigService.checkForUpdates().then(function(data) {
if(data.isUpdateAvailable) {
notificationsService.add({
headline: data.headline,
type: data.type,
message: data.message
});
}
});
//ini the render model
@@ -15,7 +15,7 @@
<label for="archetypeCheckForNewVersion"><input type="checkbox" id="archetypeCheckForNewVersion" ng-model="globalSettings.checkForNewVersion" ng-click="confirmCheckNewVersionChange();" /><archetype-localize key="checkForNewVersion">Automatically check for newer versions?</archetype-localize><small><archetype-localize key="checkForNewVersionDescription">Check this if you wish to be notified when a newer version of Archetype is available. This is a application level setting and changing this will cause the site to restart.</archetype-localize></small></label>
</div>
<div>
<label for="archetypeAdvancedOptionsConfigModel"><archetype-localize key="configModel">Config Model</archetype-localize><small><archetype-localize key="configModelDescription">Be careful editing the text below, it controls the schema for this archetype.</archetype-localize></small></label>
<label for="archetypeAdvancedOptionsConfigModel"><archetype-localize key="configModel">Config Model</archetype-localize><small><archetype-localize key="configModelDescription">Be careful editing the text below, it controls the schema for this Archetype.</archetype-localize></small></label>
<textarea class="archetypeDeveloperModel" id="archetypeAdvancedOptionsConfigModel" ng-model="dialogData.model" ng-change="dialogData.modelChanged = true"></textarea>
</div>
</div>
+2 -1
View File
@@ -2,7 +2,8 @@
<div class="archetypeConfig" ng-controller="Imulus.ArchetypeConfigController">
<h2 class="archetype-headline"><img src="../App_Plugins/Archetype/assets/logo_50.png"/>Archetype<small>{{dllVersion}}</small><a href="https://twitter.com/archetypekit" target="_blank"><img src="../App_Plugins/Archetype/assets/twitter.png"/></a></h2>
<p>At a minimum your Archetype needs at least one fieldset with at least one property. You can configure it to allow for multiple types of fieldsets within a single Archetype and you can even add another Archetype as a property. Please use the link below for the full manual:</p>
<p><a class="manual-link" href="https://github.com/kgiszewski/ArchetypeManual" target="_blank">Archetype Manual</a></p>
<p><a class="manual-link" href="https://github.com/kgiszewski/ArchetypeManual" target="_blank">Archetype Manual</a> | <a class="manual-link" href="https://github.com/kgiszewski/Archetype/blob/master/Terms%20of%20Service.md" target="_blank">Terms of Service</a></p>
<ul class="archetypeFieldsets" ui-sortable="sortableOptions" ng-model="archetypeConfigRenderModel.fieldsets">
<li ng-repeat="fieldset in archetypeConfigRenderModel.fieldsets" ng-hide="fieldset.remove">
<div class="archetypeFieldsetWrapper" >