Compare commits

..

5 Commits

Author SHA1 Message Date
Shannon efd6bd82bd Revert "V8: Don't show multiple open menus (take two) (#5609)"
This reverts commit 9ce996cbba.

(cherry picked from commit 1d49c8626e)
2019-07-24 12:02:41 +02:00
Sebastiaan Janssen 17527c99eb Makes checks a little more robust
(cherry picked from commit ca75a25802)
2019-07-24 11:37:29 +02:00
Steve Megson 361557dc39 Handle CSV values in TagsPropertyEditor
(cherry picked from commit a97604d6c4)
2019-07-24 11:37:17 +02:00
Kenn Jacobsen 342b2087e9 Make sure save options are up to date with the content state
(cherry picked from commit 8a43e3a87e)
2019-07-24 10:59:01 +02:00
Steve Megson dc371c1979 Include CheckBoxList in ValueListPreValueMigrator 2019-07-23 12:48:48 +02:00
44 changed files with 2484 additions and 803 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ thoroughly. Then, proceed by filling out the rest of the details in the issue
template below. The more details you can give us, the easier it will be for us
to determine the cause of a problem.
See: https://github.com/umbraco/Umbraco-CMS/blob/v8/dev/.github/CONTRIBUTING.md
See: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md
-->
+2 -2
View File
@@ -18,5 +18,5 @@ using System.Resources;
[assembly: AssemblyVersion("8.0.0")]
// these are FYI and changed automatically
[assembly: AssemblyFileVersion("8.2.0")]
[assembly: AssemblyInformationalVersion("8.2.0")]
[assembly: AssemblyFileVersion("8.1.1")]
[assembly: AssemblyInformationalVersion("8.1.1")]
@@ -1,32 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
{
class DropDownFlexiblePreValueMigrator : IPreValueMigrator
{
public bool CanMigrate(string editorAlias)
=> editorAlias == "Umbraco.DropDown.Flexible";
public virtual string GetNewAlias(string editorAlias)
=> null;
public object GetConfiguration(int dataTypeId, string editorAlias, Dictionary<string, PreValueDto> preValues)
{
var config = new DropDownFlexibleConfiguration();
foreach (var preValue in preValues.Values)
{
if (preValue.Alias == "multiple")
{
config.Multiple = (preValue.Value == "1");
}
else
{
config.Items.Add(new ValueListConfiguration.ValueListItem { Id = preValue.Id, Value = preValue.Value });
}
}
return config;
}
}
}
@@ -19,7 +19,6 @@ public class PreValueMigratorComposer : ICoreComposer
.Append<NestedContentPreValueMigrator>()
.Append<DecimalPreValueMigrator>()
.Append<ListViewPreValueMigrator>()
.Append<DropDownFlexiblePreValueMigrator>()
.Append<ValueListPreValueMigrator>();
}
}
+1 -1
View File
@@ -114,7 +114,7 @@ namespace Umbraco.Core.Models
/// Gets of sets the alias of the property type.
/// </summary>
[DataMember]
public virtual string Alias
public string Alias
{
get => _alias;
set => SetPropertyValueAndDetectChanges(SanitizeAlias(value), ref _alias, nameof(Alias));
-1
View File
@@ -241,7 +241,6 @@
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\DefaultPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RenamingPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RichTextPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\DropDownFlexiblePreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\MergeDateAndDateTimePropertyEditor.cs" />
<Compile Include="Models\Entities\EntityExtensions.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\PreValueMigratorBase.cs" />
+1 -28
View File
@@ -48,31 +48,6 @@ namespace Umbraco.Examine
}
}
/// <summary>
/// Returns all index fields that are culture specific (suffixed) or invariant
/// </summary>
/// <param name="index"></param>
/// <param name="culture"></param>
/// <returns></returns>
public static IEnumerable<string> GetCultureAndInvariantFields(this IUmbracoIndex index, string culture)
{
var allFields = index.GetFields();
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var field in allFields)
{
var match = CultureIsoCodeFieldNameMatchExpression.Match(field);
if (match.Success && match.Groups.Count == 3 && culture.InvariantEquals(match.Groups[2].Value))
{
yield return field; //matches this culture field
}
else if (!match.Success)
{
yield return field; //matches no culture field (invariant)
}
}
}
internal static bool TryParseLuceneQuery(string query)
{
// TODO: I'd assume there would be a more strict way to parse the query but not that i can find yet, for now we'll
@@ -102,7 +77,7 @@ namespace Umbraco.Examine
/// <remarks>
/// This is not thread safe, use with care
/// </remarks>
internal static void ConfigureLuceneIndexes(this IExamineManager examineManager, ILogger logger, bool disableExamineIndexing)
internal static void UnlockLuceneIndexes(this IExamineManager examineManager, ILogger logger)
{
foreach (var luceneIndexer in examineManager.Indexes.OfType<LuceneIndex>())
{
@@ -111,8 +86,6 @@ namespace Umbraco.Examine
//that could end up halting shutdown for a very long time causing overlapping appdomains and many other problems.
luceneIndexer.WaitForIndexQueueOnShutdown = false;
if (disableExamineIndexing) continue; //exit if not enabled, we don't need to unlock them if we're not maindom
//we should check if the index is locked ... it shouldn't be! We are using simple fs lock now and we are also ensuring that
//the indexes are not operational unless MainDom is true
var dir = luceneIndexer.GetLuceneDirectory();
@@ -1,22 +0,0 @@
using Lucene.Net.Store;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Umbraco.Tests.TestHelpers
{
/// <summary>
/// Used for tests with Lucene so that each RAM directory is unique
/// </summary>
public class RandomIdRAMDirectory : RAMDirectory
{
private readonly string _lockId = Guid.NewGuid().ToString();
public override string GetLockId()
{
return _lockId;
}
}
}
-2
View File
@@ -157,7 +157,6 @@
<Compile Include="Services\MemberGroupServiceTests.cs" />
<Compile Include="Services\MediaTypeServiceTests.cs" />
<Compile Include="Services\PropertyValidationServiceTests.cs" />
<Compile Include="TestHelpers\RandomIdRamDirectory.cs" />
<Compile Include="Testing\Objects\TestDataSource.cs" />
<Compile Include="Published\PublishedSnapshotTestObjects.cs" />
<Compile Include="Published\ModelTypeTests.cs" />
@@ -269,7 +268,6 @@
<Compile Include="Strings\StylesheetHelperTests.cs" />
<Compile Include="Strings\StringValidationTests.cs" />
<Compile Include="Web\Mvc\ValidateUmbracoFormRouteStringAttributeTests.cs" />
<Compile Include="Web\PublishedContentQueryTests.cs" />
<Compile Include="Web\UmbracoHelperTests.cs" />
<Compile Include="Membership\MembershipProviderBaseTests.cs" />
<Compile Include="Membership\UmbracoServiceMembershipProviderTests.cs" />
@@ -1,99 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Examine;
using Examine.LuceneEngine.Providers;
using Lucene.Net.Store;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Examine;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.PublishedCache;
namespace Umbraco.Tests.Web
{
[TestFixture]
public class PublishedContentQueryTests
{
private class TestIndex : LuceneIndex, IUmbracoIndex
{
private readonly string[] _fieldNames;
public TestIndex(string name, Directory luceneDirectory, string[] fieldNames)
: base(name, luceneDirectory, null, null, null, null)
{
_fieldNames = fieldNames;
}
public bool EnableDefaultEventHandler => throw new NotImplementedException();
public bool PublishedValuesOnly => throw new NotImplementedException();
public IEnumerable<string> GetFields() => _fieldNames;
}
private TestIndex CreateTestIndex(Directory luceneDirectory, string[] fieldNames)
{
var indexer = new TestIndex("TestIndex", luceneDirectory, fieldNames);
using (indexer.ProcessNonAsync())
{
//populate with some test data
indexer.IndexItem(new ValueSet("1", "content", new Dictionary<string, object>
{
[fieldNames[0]] = "Hello world, there are products here",
[UmbracoContentIndex.VariesByCultureFieldName] = "n"
}));
indexer.IndexItem(new ValueSet("2", "content", new Dictionary<string, object>
{
[fieldNames[1]] = "Hello world, there are products here",
[UmbracoContentIndex.VariesByCultureFieldName] = "y"
}));
indexer.IndexItem(new ValueSet("3", "content", new Dictionary<string, object>
{
[fieldNames[2]] = "Hello world, there are products here",
[UmbracoContentIndex.VariesByCultureFieldName] = "y"
}));
}
return indexer;
}
private PublishedContentQuery CreatePublishedContentQuery(IIndex indexer)
{
var examineManager = new Mock<IExamineManager>();
IIndex outarg = indexer;
examineManager.Setup(x => x.TryGetIndex("TestIndex", out outarg)).Returns(true);
var contentCache = new Mock<IPublishedContentCache>();
contentCache.Setup(x => x.GetById(It.IsAny<int>())).Returns((int intId) => Mock.Of<IPublishedContent>(x => x.Id == intId));
var snapshot = Mock.Of<IPublishedSnapshot>(x => x.Content == contentCache.Object);
var variationContext = new VariationContext();
var variationContextAccessor = Mock.Of<IVariationContextAccessor>(x => x.VariationContext == variationContext);
return new PublishedContentQuery(snapshot, variationContextAccessor, examineManager.Object);
}
[TestCase("fr-fr", ExpectedResult = "1, 3", TestName = "Search Culture: fr-fr. Must return both fr-fr and invariant results")]
[TestCase("en-us", ExpectedResult = "1, 2", TestName = "Search Culture: en-us. Must return both en-us and invariant results")]
[TestCase("*", ExpectedResult = "1, 2, 3", TestName = "Search Culture: *. Must return all cultures and all invariant results")]
[TestCase(null, ExpectedResult = "1", TestName = "Search Culture: null. Must return only invariant results")]
public string Search(string culture)
{
using (var luceneDir = new RandomIdRAMDirectory())
{
var fieldNames = new[] { "title", "title_en-us", "title_fr-fr" };
using (var indexer = CreateTestIndex(luceneDir, fieldNames))
{
var pcq = CreatePublishedContentQuery(indexer);
var results = pcq.Search("Products", culture, "TestIndex");
var ids = results.Select(x => x.Content.Id).ToArray();
return string.Join(", ", ids);
}
}
}
}
}
+3 -7
View File
@@ -1,8 +1,5 @@
using System;
using System.Text;
using Examine.LuceneEngine;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
@@ -16,19 +13,18 @@ using Umbraco.Web;
namespace Umbraco.Tests.Web
{
[TestFixture]
public class UmbracoHelperTests
{
{
[TearDown]
public void TearDown()
{
Current.Reset();
}
// ------- Int32 conversion tests
[Test]
public static void Converting_Boxed_34_To_An_Int_Returns_34()
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -39,7 +39,7 @@
"npm": "^6.4.1",
"signalr": "2.4.0",
"spectrum-colorpicker": "1.8.0",
"tinymce": "^5.0.12",
"tinymce": "4.9.2",
"typeahead.js": "0.11.1",
"underscore": "1.9.1"
},
@@ -4,7 +4,7 @@
@restrict A
@description
Use this directive make an element sticky and follow the page when scrolling. `umb-sticky-bar--active` class is applied when the element is stuck
Use this directive make an element sticky and follow the page when scrolling.
<h3>Markup example</h3>
<pre>
@@ -12,102 +12,140 @@ Use this directive make an element sticky and follow the page when scrolling. `u
<div
class="my-sticky-bar"
umb-sticky-bar>
umb-sticky-bar
scrollable-container=".container">
</div>
</div>
</pre>
<h3>CSS example</h3>
<pre>
.my-sticky-bar {
padding: 15px 0;
background: #000000;
position: relative;
top: 0;
}
.my-sticky-bar.-umb-sticky-bar {
top: 100px;
}
</pre>
@param {string} scrollableContainer Set the class (".element") or the id ("#element") of the scrollable container element.
**/
(function () {
'use strict';
function StickyBarDirective() {
/**
On initial load, the intersector fires if the grid editor is in the viewport
This flag is used to suppress the setClass behaviour on the initial load
**/
var initial = true;
/**
Toggle `umb-sticky-bar--active` class on the sticky-bar element
**/
function setClass(addClass, current) {
if (!initial) {
current.classList.toggle('umb-sticky-bar--active', addClass);
} else {
initial = false;
}
}
/**
Inserts two elements in the umbStickyBar parent element
These are used by the IntersectionObserve to calculate scroll position
**/
function addSentinels(current) {
['-top', '-bottom'].forEach(s => {
const sentinel = document.createElement('div');
sentinel.classList.add('umb-sticky-sentinel', s);
current.parentElement.appendChild(sentinel);
});
}
/**
Calls into setClass when the footer sentinel enters/exits the bottom of the container
Container is the parent element of the umbStickyBar element
**/
function observeFooter(current, container) {
const observer = new IntersectionObserver((records, observer) => {
let [target, rootBounds, intersected] = [records[0].boundingClientRect, records[0].rootBounds, records[0].intersectionRatio === 1];
if (target.bottom > rootBounds.top && intersected) {
setClass(true, current);
}
if (target.top < rootBounds.top && target.bottom < rootBounds.bottom) {
setClass(false, current);
}
}, {
threshold: [1],
root: container
});
observer.observe(current.parentElement.querySelector('.umb-sticky-sentinel.-bottom'));
}
/**
Calls into setClass when the header sentinel enters/exits the top of the container
Container is the parent element of the umbStickyBar element
**/
function observeHeader(current, container) {
const observer = new IntersectionObserver((records, observer) => {
let [target, rootBounds] = [records[0].boundingClientRect, records[0].rootBounds];
if (target.bottom < rootBounds.top) {
setClass(true, current);
}
if (target.bottom >= rootBounds.top && target.bottom < rootBounds.bottom) {
setClass(false, current);
}
}, {
threshold: [0],
root: container
});
observer.observe(current.parentElement.querySelector('.umb-sticky-sentinel.-top'));
}
function StickyBarDirective($rootScope) {
function link(scope, el, attr, ctrl) {
let current = el[0];
let container = current.closest('[data-element="editor-container"]');
var bar = $(el);
var scrollableContainer = null;
var clonedBar = null;
var cloneIsMade = false;
addSentinels(current);
function activate() {
if (bar.parents(".umb-property").length > 1) {
bar.addClass("nested");
return;
}
if (attr.scrollableContainer) {
scrollableContainer = bar.closest(attr.scrollableContainer);
} else {
scrollableContainer = $(window);
}
scrollableContainer.on('scroll.umbStickyBar', determineVisibility).trigger("scroll");
$(window).on('resize.umbStickyBar', determineVisibility);
scope.$on('$destroy', function () {
scrollableContainer.off('.umbStickyBar');
$(window).off('.umbStickyBar');
});
}
function determineVisibility() {
var barTop = bar[0].offsetTop;
var scrollTop = scrollableContainer.scrollTop();
if (scrollTop > barTop) {
if (!cloneIsMade) {
createClone();
clonedBar.css({
'visibility': 'visible'
});
} else {
calculateSize();
}
} else {
if (cloneIsMade) {
//remove cloned element (switched places with original on creation)
bar.remove();
bar = clonedBar;
clonedBar = null;
bar.removeClass('-umb-sticky-bar');
bar.css({
position: 'relative',
'width': 'auto',
'height': 'auto',
'z-index': 'auto',
'visibility': 'visible'
});
cloneIsMade = false;
}
}
}
function calculateSize() {
var width = bar.innerWidth();
clonedBar.css({
width: width + 10 // + 10 (5*2) because we need to add border to avoid seeing the shadow beneath. Look at the CSS.
});
}
function createClone() {
//switch place with cloned element, to keep binding intact
clonedBar = bar;
bar = clonedBar.clone();
clonedBar.after(bar);
clonedBar.addClass('-umb-sticky-bar');
clonedBar.css({
'position': 'fixed',
// if you change this z-index value, make sure the sticky editor sub headers do not
// clash with umb-dropdown (e.g. the content actions dropdown in content list view)
'z-index': 99,
'visibility': 'hidden'
});
cloneIsMade = true;
calculateSize();
}
activate();
observeHeader(current, container);
observeFooter(current, container);
}
var directive = {
@@ -172,7 +172,7 @@ function entityResource($q, $http, umbRequestHelper) {
umbRequestHelper.getApiUrl(
"entityApiBaseUrl",
"GetUrlAndAnchors",
[{ id: id }])),
{ id: id })),
'Failed to retrieve url and anchors data for id ' + id);
},
@@ -195,8 +195,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
//distraction-free = Theme: inlite, inline: true
switch (args.mode) {
case "classic":
//modeTheme = "modern";
modeTheme = "silver";
modeTheme = "modern";
modeInline = false;
break;
@@ -207,8 +206,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
default:
//Will default to 'classic'
//modeTheme = "modern";
modeTheme = "silver";
modeTheme = "modern";
modeInline = false;
break;
}
@@ -338,10 +336,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
* @param {Object} editor the TinyMCE editor instance
*/
createInsertEmbeddedMedia: function (editor, callback) {
editor.ui.registry.addButton('umbembeddialog', {
editor.addButton('umbembeddialog', {
icon: 'custom icon-tv',
tooltip: 'Embed',
onAction: function (buttonApi) {
onclick: function () {
if (callback) {
angularHelper.safeApply($rootScope, function() {
callback();
@@ -358,10 +356,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
createAceCodeEditor: function(editor, callback){
editor.ui.registry.addButton("ace", {
editor.addButton("ace", {
icon: "code",
tooltip: "View Source Code",
onAction: function(buttonApi){
onclick: function(){
if (callback) {
angularHelper.safeApply($rootScope, function() {
callback();
@@ -383,11 +381,11 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
* @param {Object} editor the TinyMCE editor instance
*/
createMediaPicker: function (editor, callback) {
editor.ui.registry.addButton('umbmediapicker', {
editor.addButton('umbmediapicker', {
icon: 'custom icon-picture',
tooltip: 'Media Picker',
stateSelector: 'img',
onAction: function (buttonApi) {
onclick: function () {
var selectedElm = editor.selection.getNode(),
@@ -430,7 +428,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
id: '__mcenew',
'data-udi': img.udi
};
editor.selection.setContent(editor.dom.createHTML('img', data));
$timeout(function () {
@@ -449,9 +447,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
}
}
editor.dom.setAttrib(imgElm, 'id', null);
editor.fire('Change');
}, 500);
}
},
@@ -517,13 +515,13 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
}
/** Adds the button instance */
editor.ui.registry.addButton('umbmacro', {
editor.addButton('umbmacro', {
icon: 'custom icon-settings-alt',
tooltip: 'Insert macro',
onPostRender: function () {
let ctrl = this;
/**
* Check if the macro is currently selected and toggle the menu button
*/
@@ -545,7 +543,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
},
/** The insert macro button click event handler */
onAction: function (buttonApi) {
onclick: function () {
var dialogData = {
//flag for use in rte so we only show macros flagged for the editor
@@ -867,29 +865,29 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
});
}
editor.ui.registry.addButton('link', {
editor.addButton('link', {
icon: 'link',
tooltip: 'Insert/edit link',
shortcut: 'Ctrl+K',
onAction: createLinkList(showDialog),
onclick: createLinkList(showDialog),
stateSelector: 'a[href]'
});
// editor.ui.registry.addButton('unlink', {
// icon: 'unlink',
// tooltip: 'Remove link',
// cmd: 'unlink',
// stateSelector: 'a[href]'
// });
editor.addButton('unlink', {
icon: 'unlink',
tooltip: 'Remove link',
cmd: 'unlink',
stateSelector: 'a[href]'
});
editor.addShortcut('Ctrl+K', '', createLinkList(showDialog));
this.showDialog = showDialog;
editor.ui.registry.addMenuItem('link', {
editor.addMenuItem('link', {
icon: 'link',
text: 'Insert link',
shortcut: 'Ctrl+K',
onAction: createLinkList(showDialog),
onclick: createLinkList(showDialog),
stateSelector: 'a[href]',
context: 'insert',
prependToContext: true
@@ -1136,7 +1134,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
};
editorService.linkPicker(linkPicker);
});
});
//Create the insert media plugin
@@ -32,32 +32,15 @@
border-radius: 3px;
}
[umb-sticky-bar] {
.umb-editor-sub-header.-umb-sticky-bar {
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
transition: box-shadow 240ms;
margin-top: 0;
margin-top: 0;
margin-bottom: 0;
position:sticky;
z-index: 99;
top: calc(@appHeaderHeight + @editorHeaderHeight);
&.umb-sticky-bar--active {
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
}
}
.umb-sticky-sentinel {
position: absolute;
left: 0;
width: 100%;
pointer-events: none;
&.-top {
top:0px;
height:1px;
}
&.-bottom {
bottom:50px;
height:10px;
.umb-editor--infinityMode & {
top: calc(@editorHeaderHeight);
}
}
@@ -5,7 +5,6 @@
// --------------------------------------------------
.umb-property-editor {
width: 100%;
position:relative;
}
.umb-property-editor-tiny {
@@ -166,6 +165,8 @@
.sp-replacer {
display: inline-flex;
margin-right: 18px;
border: solid 1px @gray-8;
border-radius: 3px;
}
label {
@@ -59,10 +59,10 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController",
if (dialogOptions.currentTarget) {
// clone the current target so we don't accidentally update the caller's model while manipulating $scope.model.target
$scope.model.target = angular.copy(dialogOptions.currentTarget);
// if we have a node ID, we fetch the current node to build the form data
//if we have a node ID, we fetch the current node to build the form data
if ($scope.model.target.id || $scope.model.target.udi) {
// will be either a udi or an int
//will be either a udi or an int
var id = $scope.model.target.udi ? $scope.model.target.udi : $scope.model.target.id;
if ($scope.model.target.udi) {
@@ -1,5 +1,6 @@
<div
class="umb-editor-sub-header umb-editor-sub-header--{{appearance}}"
umb-sticky-bar
scrollable-container=".umb-editor-container"
ng-transclude>
</div>
@@ -10,12 +10,11 @@
vm.numberOfErrors = 0;
vm.commonLogMessages = [];
vm.commonLogMessagesCount = 10;
vm.dateRangeLabel = "";
// ChartJS Options - for count/overview of log distribution
vm.logTypeLabels = ["Debug", "Info", "Warning", "Error", "Fatal"];
vm.logTypeLabels = ["Info", "Debug", "Warning", "Error", "Critical"];
vm.logTypeData = [0, 0, 0, 0, 0];
vm.logTypeColors = ['#eaddd5', '#2bc37c', '#3544b1', '#ff9412', '#d42054'];
vm.logTypeColors = [ '#dcdcdc', '#97bbcd', '#46bfbd', '#fdb45c', '#f7464a'];
vm.chartOptions = {
legend: {
display: true,
@@ -24,42 +23,35 @@
};
let querystring = $location.search();
if (querystring.startDate) {
if(querystring.startDate){
vm.startDate = querystring.startDate;
vm.dateRangeLabel = getDateRangeLabel("Selected Time Period");
} else {
}else{
vm.startDate = new Date(Date.now());
vm.startDate.setDate(vm.startDate.getDate() - 1);
vm.startDate.setDate(vm.startDate.getDate()-1);
vm.startDate = vm.startDate.toIsoDateString();
vm.dateRangeLabel = getDateRangeLabel("Today");
}
if (querystring.endDate) {
if(querystring.endDate){
vm.endDate = querystring.endDate;
if (querystring.endDate === querystring.startDate) {
vm.dateRangeLabel = getDateRangeLabel("Selected Date");
}
} else {
}else{
vm.endDate = new Date(Date.now()).toIsoDateString();
}
vm.period = [vm.startDate, vm.endDate];
//functions
vm.searchLogQuery = searchLogQuery;
vm.findMessageTemplate = findMessageTemplate;
vm.searchErrors = searchErrors;
function preFlightCheck(){
vm.loading = true;
//Do our pre-flight check (to see if we can view logs)
//IE the log file is NOT too big such as 1GB & crash the site
logViewerResource.canViewLogs(vm.startDate, vm.endDate).then(function (result) {
logViewerResource.canViewLogs(vm.startDate, vm.endDate).then(function(result){
vm.loading = false;
vm.canLoadLogs = result;
if (result) {
if(result){
//Can view logs - so initalise
init();
}
@@ -70,39 +62,39 @@
function init() {
vm.loading = true;
var savedSearches = logViewerResource.getSavedSearches().then(function (data) {
vm.searches = data;
},
// fallback to some defaults if error from API response
function () {
vm.searches = [
{
"name": "Find all logs where the Level is NOT Verbose and NOT Debug",
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
vm.searches = data;
},
// fallback to some defaults if error from API response
function () {
vm.searches = [
{
"name": "Find all logs where the Level is NOT Verbose and NOT Debug",
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
},
{
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
"query": "Has(@Exception)"
{
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
"query": "Has(@Exception)"
},
{
"name": "Find all logs that have the property 'Duration'",
"query": "Has(Duration)"
{
"name": "Find all logs that have the property 'Duration'",
"query": "Has(Duration)"
},
{
"name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
"query": "Has(Duration) and Duration > 1000"
{
"name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
"query": "Has(Duration) and Duration > 1000"
},
{
"name": "Find all logs that are from the namespace 'Umbraco.Core'",
"query": "StartsWith(SourceContext, 'Umbraco.Core')"
{
"name": "Find all logs that are from the namespace 'Umbraco.Core'",
"query": "StartsWith(SourceContext, 'Umbraco.Core')"
},
{
"name": "Find all logs that use a specific log message template",
"query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'"
{
"name": "Find all logs that use a specific log message template",
"query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'"
}
]
});
});
var numOfErrors = logViewerResource.getNumberOfErrors(vm.startDate, vm.endDate).then(function (data) {
vm.numberOfErrors = data;
@@ -110,56 +102,41 @@
var logCounts = logViewerResource.getLogLevelCounts(vm.startDate, vm.endDate).then(function (data) {
vm.logTypeData = [];
for (let [key, value] of Object.entries(data)) {
const index = vm.logTypeLabels.findIndex(x => key.startsWith(x));
if (index > -1) {
vm.logTypeData[index] = value;
}
}
vm.logTypeData.push(data.Information);
vm.logTypeData.push(data.Debug);
vm.logTypeData.push(data.Warning);
vm.logTypeData.push(data.Error);
vm.logTypeData.push(data.Fatal);
});
var commonMsgs = logViewerResource.getMessageTemplates(vm.startDate, vm.endDate).then(function (data) {
var commonMsgs = logViewerResource.getMessageTemplates(vm.startDate, vm.endDate).then(function(data){
vm.commonLogMessages = data;
});
//Set loading indicator to false when these 3 queries complete
$q.all([savedSearches, numOfErrors, logCounts, commonMsgs]).then(function () {
//Set loading indicatior to false when these 3 queries complete
$q.all([savedSearches, numOfErrors, logCounts, commonMsgs]).then(function(data) {
vm.loading = false;
});
$timeout(function () {
navigationService.syncTree({
tree: "logViewer",
path: "-1"
});
navigationService.syncTree({ tree: "logViewer", path: "-1" });
});
}
function searchLogQuery(logQuery) {
$location.path("/settings/logViewer/search").search({
lq: logQuery,
startDate: vm.startDate,
endDate: vm.endDate
});
function searchLogQuery(logQuery){
$location.path("/settings/logViewer/search").search({lq: logQuery, startDate: vm.startDate, endDate: vm.endDate});
}
function findMessageTemplate(template) {
function findMessageTemplate(template){
var logQuery = "@MessageTemplate='" + template.MessageTemplate + "'";
searchLogQuery(logQuery);
}
function getDateRangeLabel(suffix) {
return "Log Overview for " + suffix;
}
function searchErrors(){
var logQuery = "@Level='Fatal' or @Level='Error' or Has(@Exception)";
searchLogQuery(logQuery);
}
preFlightCheck();
/////////////////////
vm.config = {
@@ -170,21 +147,20 @@
maxDate: "today",
conjunction: " to "
};
vm.dateRangeChange = function(selectedDates, dateStr, instance) {
if(selectedDates.length > 0){
vm.startDate = selectedDates[0].toIsoDateString();
vm.endDate = selectedDates[selectedDates.length-1].toIsoDateString(); // Take the last date as end
vm.dateRangeChange = function (selectedDates, dateStr, instance) {
if (selectedDates.length > 0) {
// Update view by re-requesting route with updated querystring.
// By doing this we make sure the URL matches the selected time period, aiding sharing the link.
// Also resolves a minor layout issue where the " to " conjunction between the selected dates
// is collapsed to a comma.
const startDate = selectedDates[0].toIsoDateString();
const endDate = selectedDates[selectedDates.length - 1].toIsoDateString(); // Take the last date as end
$location.path("/settings/logViewer/overview").search({
startDate: startDate,
endDate: endDate
});
if(vm.startDate === vm.endDate){
vm.period = [vm.startDate];
}else{
vm.period = [vm.startDate, vm.endDate];
}
preFlightCheck();
}
}
@@ -3,7 +3,7 @@
<umb-editor-view footer="false">
<umb-editor-header
name="vm.dateRangeLabel"
name="'Log Overview for Today'"
name-locked="true"
hide-icon="true"
hide-description="true"
@@ -74,16 +74,17 @@
<umb-box>
<umb-box-header title="Time Period"></umb-box-header>
<umb-flatpickr class="datepicker"
ng-model="vm.period"
options="vm.config"
on-close="vm.dateRangeChange(selectedDates, dateStr, instance)">
<umb-flatpickr
class="datepicker"
ng-model="vm.period"
options="vm.config"
on-close="vm.dateRangeChange(selectedDates, dateStr, instance)">
</umb-flatpickr>
</umb-box>
<div ng-show=" vm.canLoadLogs">
<!-- No of Errors -->
<umb-box ng-click="vm.searchErrors()" style="cursor:pointer;">
<umb-box ng-click="vm.searchLogQuery('Has(@Exception)')" style="cursor:pointer;">
<umb-box-header title="Number of Errors"></umb-box-header>
<umb-box-content class="block-form" style="font-size: 40px; font-weight:900; text-align:center; color:#fe6561;">
{{ vm.numberOfErrors }}
@@ -11,29 +11,27 @@
vm.showBackButton = true;
vm.page = {};
// this array is also used to map the logTypeColor param onto the log items
// in setLogTypeColors()
vm.logLevels = [
{
name: 'Verbose',
logTypeColor: ''
},
{
name: 'Debug',
logTypeColor: 'gray'
},
{
name: 'Information',
logTypeColor: 'success'
name: 'Debug',
logTypeColor: 'secondary'
},
{
name: 'Warning',
name: 'Information',
logTypeColor: 'primary'
},
{
name: 'Error',
name: 'Warning',
logTypeColor: 'warning'
},
{
name: 'Error',
logTypeColor: 'danger'
},
{
name: 'Fatal',
logTypeColor: 'danger'
@@ -120,7 +118,7 @@
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
},
{
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
"query": "Has(@Exception)"
},
{
@@ -175,8 +173,25 @@
}
function setLogTypeColor(logItems) {
logItems.forEach(logItem =>
logItem.logTypeColor = vm.logLevels.find(x => x.name === logItem.Level).logTypeColor);
angular.forEach(logItems, function (log) {
switch (log.Level) {
case "Information":
log.logTypeColor = "primary";
break;
case "Debug":
log.logTypeColor = "secondary";
break;
case "Warning":
log.logTypeColor = "warning";
break;
case "Fatal":
case "Error":
log.logTypeColor = "danger";
break;
default:
log.logTypeColor = "gray";
}
});
}
function getFilterName(array) {
@@ -48,19 +48,18 @@ angular.module("umbraco")
$q.all(promises).then(function (result) {
var standardConfig = result[promises.length - 1];
if (height !== null) {
standardConfig.plugins.splice(standardConfig.plugins.indexOf("autoresize"), 1);
}
//create a baseline Config to extend upon
var baseLineConfigObj = {
maxImageSize: editorConfig.maxImageSize
//width: width,
//height: height
maxImageSize: editorConfig.maxImageSize,
width: width,
height: height
};
angular.extend(baseLineConfigObj, standardConfig);
baseLineConfigObj.setup = function (editor) {
@@ -1,6 +1,6 @@
<div ng-controller="Umbraco.PropertyEditors.RTEController" class="umb-property-editor umb-rte">
<umb-load-indicator ng-if="isLoading"></umb-load-indicator>
<div ng-style="{ visibility : isLoading ? 'hidden' : 'visible', overflow: containerOverflow}"
<div ng-style="{ visibility : isLoading ? 'hidden' : 'visible', width :containerWidth, height: containerHeight, overflow: containerOverflow}"
id="{{textAreaHtmlId}}" class="umb-rte-editor"></div>
</div>
+2 -2
View File
@@ -345,9 +345,9 @@
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>8200</DevelopmentServerPort>
<DevelopmentServerPort>8110</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:8200</IISUrl>
<IISUrl>http://localhost:8110</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -4,7 +4,7 @@
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
},
{
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
"query": "Has(@Exception)"
},
{
@@ -26,13 +26,12 @@
<add key="serilog:write-to:File.restrictedToMinimumLevel" value="Debug" />
<add key="serilog:write-to:File.retainedFileCountLimit" value="32" />--> <!-- Number of log files to keep (or remove value to keep all files) -->
<!--<add key="serilog:write-to:File.rollingInterval" value="Day" />--> <!-- Create a new log file every Minute/Hour/Day/Month/Year/infinite -->
<!--<add key="serilog:write-to:File.outputTemplate" value="{Timestamp:yyyy-MM-dd HH:mm:ss,fff} [P{ProcessId}/D{AppDomainId}/T{ThreadId}] {Log4NetLevel} {SourceContext} - {Message:lj}{NewLine}{Exception}" /> -->
<!-- Filters all above sink's to use this expression -->
<!-- Common use case is to include SourceType starting with your own namespace -->
<!--
<add key="serilog:using:FilterExpressions" value="Serilog.Filters.Expressions" />
<add key="serilog:filter:ByIncludingOnly.expression" value="StartsWith(SourceContext, 'Umbraco.Core')" />
<add key="serilog:filter:ByIncluding.expression" value="StartsWith(SourceContext, 'Umbraco.Core')" />
-->
</appSettings>
+1 -11
View File
@@ -74,7 +74,6 @@ namespace Umbraco.Web.Editors
//id is passed in eventually we'll probably want to support GUID + Udi too
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetPagedChildren", "id", typeof(int), typeof(string)),
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetPath", "id", typeof(int), typeof(Guid), typeof(Udi)),
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetUrlAndAnchors", "id", typeof(int), typeof(Guid), typeof(Udi)),
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetById", "id", typeof(int), typeof(Guid), typeof(Udi)),
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetByIds", "ids", typeof(int[]), typeof(Guid[]), typeof(Udi[]))));
}
@@ -289,16 +288,7 @@ namespace Umbraco.Web.Editors
}
[HttpGet]
public UrlAndAnchors GetUrlAndAnchors(Udi id, string culture = "*")
{
var intId = Services.EntityService.GetId(id);
if (!intId.Success)
throw new HttpResponseException(HttpStatusCode.NotFound);
return GetUrlAndAnchors(intId.Result, culture);
}
[HttpGet]
public UrlAndAnchors GetUrlAndAnchors(int id, string culture = "*")
public UrlAndAnchors GetUrlAndAnchors([FromUri]int id, [FromUri]string culture = "*")
{
var url = UmbracoContext.UrlProvider.GetUrl(id);
var anchorValues = Services.ContentService.GetAnchorValuesFromRTEs(id, culture);
@@ -85,7 +85,7 @@ namespace Umbraco.Web.Editors
};
}
/// <summary>
/// Check if the index has been rebuilt
@@ -250,7 +250,7 @@ namespace Umbraco.Web.Editors
private void Indexer_IndexOperationComplete(object sender, EventArgs e)
{
var indexer = (IIndex)sender;
var indexer = (LuceneIndex)sender;
_logger.Debug<ExamineManagementController>("Logging operation completed for index {IndexName}", indexer.Name);
@@ -259,7 +259,7 @@ namespace Umbraco.Web.Editors
_logger
.Info<ExamineManagementController
>($"Rebuilding index '{indexer.Name}' done.");
>($"Rebuilding index '{indexer.Name}' done, {indexer.CommitCount} items committed (can differ from the number of items in the index)");
var cacheKey = "temp_indexing_op_" + indexer.Name;
_runtimeCache.Clear(cacheKey);
@@ -15,11 +15,11 @@ namespace Umbraco.Web.Editors
[PluginController("UmbracoApi")]
public class LogViewerController : UmbracoAuthorizedJsonController
{
private readonly ILogViewer _logViewer;
private ILogViewer _logViewer;
public LogViewerController(ILogViewer logViewer)
{
_logViewer = logViewer ?? throw new ArgumentNullException(nameof(logViewer));
_logViewer = logViewer;
}
private bool CanViewLogs(LogTimePeriod logTimePeriod)
@@ -91,6 +91,8 @@ namespace Umbraco.Web.Editors
var direction = orderDirection == "Descending" ? Direction.Descending : Direction.Ascending;
return _logViewer.GetLogs(logTimePeriod, filterExpression: filterExpression, pageNumber: pageNumber, orderDirection: direction, logLevels: logLevels);
}
@@ -223,6 +223,7 @@ namespace Umbraco.Web
_method = method;
_controllerName = controllerName;
_encryptedString = UrlHelperRenderExtensions.CreateEncryptedRouteString(controllerName, controllerAction, area, additionalRouteVals);
}
+4 -12
View File
@@ -39,14 +39,10 @@ namespace Umbraco.Web
/// <param name="culture">Optional culture.</param>
/// <param name="indexName">Optional index name.</param>
/// <remarks>
/// <para>
/// When the <paramref name="culture"/> is not specified or is *, all cultures are searched.
/// To search for only invariant documents and fields use null.
/// When searching on a specific culture, all culture specific fields are searched for the provided culture and all invariant fields for all documents.
/// </para>
/// <para>When the <paramref name="culture"/> is not specified, all cultures are searched.</para>
/// <para>While enumerating results, the ambient culture is changed to be the searched culture.</para>
/// </remarks>
IEnumerable<PublishedSearchResult> Search(string term, string culture = "*", string indexName = null);
IEnumerable<PublishedSearchResult> Search(string term, string culture = null, string indexName = null);
/// <summary>
/// Searches content.
@@ -58,14 +54,10 @@ namespace Umbraco.Web
/// <param name="culture">Optional culture.</param>
/// <param name="indexName">Optional index name.</param>
/// <remarks>
/// <para>
/// When the <paramref name="culture"/> is not specified or is *, all cultures are searched.
/// To search for only invariant documents and fields use null.
/// When searching on a specific culture, all culture specific fields are searched for the provided culture and all invariant fields for all documents.
/// </para>
/// <para>When the <paramref name="culture"/> is not specified, all cultures are searched.</para>
/// <para>While enumerating results, the ambient culture is changed to be the searched culture.</para>
/// </remarks>
IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = "*", string indexName = null);
IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = null, string indexName = null);
/// <summary>
/// Executes the query and converts the results to PublishedSearchResult.
+11 -1
View File
@@ -12,7 +12,7 @@ namespace Umbraco.Web.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.2.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -50,5 +50,15 @@ namespace Umbraco.Web.Properties {
return ((string)(this["test"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.WebServiceUrl)]
[global::System.Configuration.DefaultSettingValueAttribute("https://our.umbraco.com/umbraco/webservices/api/repository.asmx")]
public string umbraco_org_umbraco_our_Repository {
get {
return ((string)(this["umbraco_org_umbraco_our_Repository"]));
}
}
}
}
@@ -11,5 +11,8 @@
<Setting Name="test" Type="System.String" Scope="Application">
<Value Profile="(Default)">Something</Value>
</Setting>
<Setting Name="umbraco_org_umbraco_our_Repository" Type="(Web Service URL)" Scope="Application">
<Value Profile="(Default)">https://our.umbraco.com/umbraco/webservices/api/repository.asmx</Value>
</Setting>
</Settings>
</SettingsFile>
+12 -28
View File
@@ -20,22 +20,14 @@ namespace Umbraco.Web
{
private readonly IPublishedSnapshot _publishedSnapshot;
private readonly IVariationContextAccessor _variationContextAccessor;
private readonly IExamineManager _examineManager;
[Obsolete("Use the constructor with all parameters instead")]
public PublishedContentQuery(IPublishedSnapshot publishedSnapshot, IVariationContextAccessor variationContextAccessor)
: this (publishedSnapshot, variationContextAccessor, ExamineManager.Instance)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentQuery"/> class.
/// </summary>
public PublishedContentQuery(IPublishedSnapshot publishedSnapshot, IVariationContextAccessor variationContextAccessor, IExamineManager examineManager)
public PublishedContentQuery(IPublishedSnapshot publishedSnapshot, IVariationContextAccessor variationContextAccessor)
{
_publishedSnapshot = publishedSnapshot ?? throw new ArgumentNullException(nameof(publishedSnapshot));
_variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
_examineManager = examineManager ?? throw new ArgumentNullException(nameof(examineManager));
}
#region Content
@@ -183,19 +175,19 @@ namespace Umbraco.Web
#region Search
/// <inheritdoc />
public IEnumerable<PublishedSearchResult> Search(string term, string culture = "*", string indexName = null)
public IEnumerable<PublishedSearchResult> Search(string term, string culture = null, string indexName = null)
{
return Search(term, 0, 0, out _, culture, indexName);
}
/// <inheritdoc />
public IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = "*", string indexName = null)
public IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = null, string indexName = null)
{
indexName = string.IsNullOrEmpty(indexName)
? Constants.UmbracoIndexes.ExternalIndexName
: indexName;
if (!_examineManager.TryGetIndex(indexName, out var index) || !(index is IUmbracoIndex umbIndex))
if (!ExamineManager.Instance.TryGetIndex(indexName, out var index) || !(index is IUmbracoIndex umbIndex))
throw new InvalidOperationException($"No index found by name {indexName} or is not of type {typeof(IUmbracoIndex)}");
var searcher = umbIndex.GetSearcher();
@@ -203,28 +195,20 @@ namespace Umbraco.Web
// default to max 500 results
var count = skip == 0 && take == 0 ? 500 : skip + take;
//set this to the specific culture or to the culture in the request
culture = culture ?? _variationContextAccessor.VariationContext.Culture;
ISearchResults results;
if (culture == "*")
if (culture.IsNullOrWhiteSpace())
{
//search everything
results = searcher.Search(term, count);
}
else if (culture.IsNullOrWhiteSpace())
{
//only search invariant
var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, "n"); //must not vary by culture
qry = qry.And().ManagedQuery(term);
results = qry.Execute(count);
}
else
{
//search only the specified culture
//get all index fields suffixed with the culture name supplied
var cultureFields = umbIndex.GetCultureAndInvariantFields(culture).ToArray();
var qry = searcher.CreateQuery().ManagedQuery(term, cultureFields);
var cultureFields = umbIndex.GetCultureFields(culture);
var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, "y"); //must vary by culture
qry = qry.And().ManagedQuery(term, cultureFields.ToArray());
results = qry.Execute(count);
}
@@ -320,7 +304,7 @@ namespace Umbraco.Web
}
}
#endregion
+19 -19
View File
@@ -30,9 +30,8 @@ namespace Umbraco.Web.Search
private readonly IValueSetBuilder<IMedia> _mediaValueSetBuilder;
private readonly IValueSetBuilder<IMember> _memberValueSetBuilder;
private static bool _disableExamineIndexing = false;
private static bool _isConfigured = false;
private static object _configuredInit = null;
private static object _isConfiguredLocker = new object();
private static volatile bool _isConfigured = false;
private static readonly object IsConfiguredLocker = new object();
private readonly IScopeProvider _scopeProvider;
private readonly ServiceContext _services;
private static BackgroundTaskRunner<IBackgroundTask> _rebuildOnStartupRunner;
@@ -92,7 +91,7 @@ namespace Umbraco.Web.Search
if (!examineShutdownRegistered)
{
_logger.Info<ExamineComponent>("Examine shutdown not registered, this AppDomain is not the MainDom, Examine will be disabled");
_logger.Debug<ExamineComponent>("Examine shutdown not registered, this AppDomain is not the MainDom, Examine will be disabled");
//if we could not register the shutdown examine ourselves, it means we are not maindom! in this case all of examine should be disabled!
Suspendable.ExamineEvents.SuspendIndexers(_logger);
@@ -121,7 +120,7 @@ namespace Umbraco.Web.Search
MediaCacheRefresher.CacheUpdated += MediaCacheRefresherUpdated;
MemberCacheRefresher.CacheUpdated += MemberCacheRefresherUpdated;
ConfigureIndexes(_logger, _examineManager);
EnsureUnlocked(_logger, _examineManager);
// TODO: Instead of waiting 5000 ms, we could add an event handler on to fulfilling the first request, then start?
RebuildIndexes(_indexRebuilder, _logger, true, 5000);
@@ -162,24 +161,25 @@ namespace Umbraco.Web.Search
}
/// <summary>
/// Called on startup to configure each index.
/// Must be called to each index is unlocked before any indexing occurs
/// </summary>
/// <remarks>
/// Indexing rebuilding can occur on a normal boot if the indexes are empty or on a cold boot by the database server messenger. Before
/// either of these happens, we need to configure the indexes.
/// Configuring also ensure the indexes are not locked.
/// </remarks>
private static void ConfigureIndexes(ILogger logger, IExamineManager examineManager)
private static void EnsureUnlocked(ILogger logger, IExamineManager examineManager)
{
LazyInitializer.EnsureInitialized(
ref _configuredInit,
ref _isConfigured,
ref _isConfiguredLocker,
() =>
{
examineManager.ConfigureLuceneIndexes(logger, _disableExamineIndexing);
return null;
});
if (_disableExamineIndexing) return;
if (_isConfigured) return;
lock (IsConfiguredLocker)
{
//double check
if (_isConfigured) return;
_isConfigured = true;
examineManager.UnlockLuceneIndexes(logger);
}
}
#region Cache refresher updated event handlers
@@ -737,7 +737,7 @@ namespace Umbraco.Web.Search
{
var strId = id.ToString(CultureInfo.InvariantCulture);
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
.Where(x => x.PublishedValuesOnly || !keepIfUnpublished)
.Where(x => (keepIfUnpublished && !x.PublishedValuesOnly) || !keepIfUnpublished)
.Where(x => x.EnableDefaultEventHandler))
{
index.DeleteFromIndex(strId);
@@ -800,7 +800,7 @@ namespace Umbraco.Web.Search
if (_waitMilliseconds > 0)
Thread.Sleep(_waitMilliseconds);
ConfigureIndexes(_logger, _indexRebuilder.ExamineManager);
EnsureUnlocked(_logger, _indexRebuilder.ExamineManager);
_indexRebuilder.RebuildIndexes(_onlyEmptyIndexes);
}
}
+1 -1
View File
@@ -542,7 +542,7 @@ namespace Umbraco.Web.Security
}
/// <summary>
/// Returns the login status model of the currently logged in member.
/// Returns the login status model of the currently logged in member, if no member is logged in it returns null;
/// </summary>
/// <returns></returns>
public virtual LoginStatusModel GetCurrentLoginStatus()
+22
View File
@@ -906,6 +906,11 @@
<Compile Include="JavaScript\CssInitialization.cs" />
<Compile Include="JavaScript\DependencyPathRenderer.cs" />
<Compile Include="UmbracoComponentRenderer.cs" />
<Compile Include="Web References\org.umbraco.our\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Reference.map</DependentUpon>
</Compile>
<Compile Include="WebApi\AngularJsonMediaTypeFormatter.cs" />
<Compile Include="WebApi\AngularJsonOnlyConfigurationAttribute.cs" />
<Compile Include="Editors\Binders\MemberBinder.cs" />
@@ -1215,6 +1220,12 @@
<None Include="..\Umbraco.Web.UI\Views\web.config">
<Link>Mvc\web.config</Link>
</None>
<None Include="Web References\org.umbraco.our\Reference.map">
<Generator>MSDiscoCodeGenerator</Generator>
<LastGenOutput>Reference.cs</LastGenOutput>
</None>
<None Include="Web References\org.umbraco.our\repository.disco" />
<None Include="Web References\org.umbraco.our\repository.wsdl" />
<None Include="Web References\org.umbraco.update\UpgradeResult.datasource">
<DependentUpon>Reference.map</DependentUpon>
</None>
@@ -1227,6 +1238,17 @@
</None>
</ItemGroup>
<ItemGroup>
<WebReferenceUrl Include="http://our.umbraco.org/umbraco/webservices/api/repository.asmx">
<UrlBehavior>Dynamic</UrlBehavior>
<RelPath>Web References\org.umbraco.our\</RelPath>
<UpdateFromURL>http://our.umbraco.org/umbraco/webservices/api/repository.asmx</UpdateFromURL>
<ServiceLocationURL>
</ServiceLocationURL>
<CachedDynamicPropName>
</CachedDynamicPropName>
<CachedAppSettingsObjectName>Settings</CachedAppSettingsObjectName>
<CachedSettingsPropName>umbraco_org_umbraco_our_Repository</CachedSettingsPropName>
</WebReferenceUrl>
<WebReferenceUrl Include="http://update.umbraco.org/checkforupgrade.asmx">
<UrlBehavior>Dynamic</UrlBehavior>
<RelPath>Web References\org.umbraco.update\</RelPath>
-8
View File
@@ -53,15 +53,7 @@ namespace Umbraco.Web
{
// make sure we have a variation context
if (_variationContextAccessor.VariationContext == null)
{
// TODO: By using _defaultCultureAccessor.DefaultCulture this means that the VariationContext will always return a variant culture, it will never
// return an empty string signifying that the culture is invariant. But does this matter? Are we actually expecting this to return an empty string
// for invariant routes? From what i can tell throughout the codebase is that whenever we are checking against the VariationContext.Culture we are
// also checking if the content type varies by culture or not. This is fine, however the code in the ctor of VariationContext is then misleading
// since it's assuming that the Culture can be empty (invariant) when in reality of a website this will never be empty since a real culture is always set here.
_variationContextAccessor.VariationContext = new VariationContext(_defaultCultureAccessor.DefaultCulture);
}
var webSecurity = new WebSecurity(httpContext, _userService, _globalSettings);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<DiscoveryClientResultsFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Results>
<DiscoveryClientResult referenceType="System.Web.Services.Discovery.ContractReference" url="https://our.umbraco.com/umbraco/webservices/api/repository.asmx?wsdl" filename="repository.wsdl" />
<DiscoveryClientResult referenceType="System.Web.Services.Discovery.DiscoveryDocumentReference" url="https://our.umbraco.com/umbraco/webservices/api/repository.asmx?disco" filename="repository.disco" />
</Results>
</DiscoveryClientResultsFile>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
<contractRef ref="https://our.umbraco.com/umbraco/webservices/api/repository.asmx?wsdl" docRef="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<soap address="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" xmlns:q1="http://packages.umbraco.org/webservices/" binding="q1:RepositorySoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
<soap address="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" xmlns:q2="http://packages.umbraco.org/webservices/" binding="q2:RepositorySoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
</discovery>
@@ -0,0 +1,995 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://packages.umbraco.org/webservices/" xmlns:s1="http://microsoft.com/wsdl/types/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s2="http://packages.umbraco.org/webservices/AbstractTypes" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://packages.umbraco.org/webservices/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://packages.umbraco.org/webservices/">
<s:import namespace="http://microsoft.com/wsdl/types/" />
<s:element name="Categories">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="repositoryGuid" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CategoriesResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="CategoriesResult" type="tns:ArrayOfCategory" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="ArrayOfCategory">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="Category" nillable="true" type="tns:Category" />
</s:sequence>
</s:complexType>
<s:complexType name="Category">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Text" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Url" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Id" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="Packages" type="tns:ArrayOfPackage" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfPackage">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="Package" nillable="true" type="tns:Package" />
</s:sequence>
</s:complexType>
<s:complexType name="Package">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="RepoGuid" type="s1:guid" />
<s:element minOccurs="0" maxOccurs="1" name="Text" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Icon" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Thumbnail" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Documentation" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Demo" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Accepted" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="IsModule" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="EditorsPick" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="Protected" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="HasUpgrade" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="UpgradeVersion" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="UpgradeReadMe" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Url" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="Modules">
<s:complexType />
</s:element>
<s:element name="ModulesResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ModulesResult" type="tns:ArrayOfPackage" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ModulesCategorized">
<s:complexType />
</s:element>
<s:element name="ModulesCategorizedResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ModulesCategorizedResult" type="tns:ArrayOfCategory" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Nitros">
<s:complexType />
</s:element>
<s:element name="NitrosResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="NitrosResult" type="tns:ArrayOfPackage" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="NitrosCategorized">
<s:complexType />
</s:element>
<s:element name="NitrosCategorizedResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="NitrosCategorizedResult" type="tns:ArrayOfCategory" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="authenticate">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="email" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="md5Password" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="authenticateResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="authenticateResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="fetchPackage">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="fetchPackageResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="fetchPackageResult" type="s:base64Binary" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="fetchPackageByVersion">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="repoVersion" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="fetchPackageByVersionResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="fetchPackageByVersionResult" type="s:base64Binary" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="fetchProtectedPackage">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="memberKey" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="fetchProtectedPackageResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="fetchProtectedPackageResult" type="s:base64Binary" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="SubmitPackage">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="repositoryGuid" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="authorGuid" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="packageFile" type="s:base64Binary" />
<s:element minOccurs="0" maxOccurs="1" name="packageDoc" type="s:base64Binary" />
<s:element minOccurs="0" maxOccurs="1" name="packageThumbnail" type="s:base64Binary" />
<s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="author" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="authorUrl" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="description" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="SubmitPackageResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="SubmitPackageResult" type="tns:SubmitStatus" />
</s:sequence>
</s:complexType>
</s:element>
<s:simpleType name="SubmitStatus">
<s:restriction base="s:string">
<s:enumeration value="Complete" />
<s:enumeration value="Exists" />
<s:enumeration value="NoAccess" />
<s:enumeration value="Error" />
</s:restriction>
</s:simpleType>
<s:element name="PackageByGuid">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="PackageByGuidResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="PackageByGuidResult" type="tns:Package" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ArrayOfCategory" nillable="true" type="tns:ArrayOfCategory" />
<s:element name="ArrayOfPackage" nillable="true" type="tns:ArrayOfPackage" />
<s:element name="string" nillable="true" type="s:string" />
<s:element name="base64Binary" nillable="true" type="s:base64Binary" />
<s:element name="SubmitStatus" type="tns:SubmitStatus" />
<s:element name="Package" nillable="true" type="tns:Package" />
</s:schema>
<s:schema elementFormDefault="qualified" targetNamespace="http://microsoft.com/wsdl/types/">
<s:simpleType name="guid">
<s:restriction base="s:string">
<s:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
</s:restriction>
</s:simpleType>
</s:schema>
<s:schema targetNamespace="http://packages.umbraco.org/webservices/AbstractTypes">
<s:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<s:complexType name="StringArray">
<s:complexContent mixed="false">
<s:restriction base="soapenc:Array">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="String" type="s:string" />
</s:sequence>
</s:restriction>
</s:complexContent>
</s:complexType>
</s:schema>
</wsdl:types>
<wsdl:message name="CategoriesSoapIn">
<wsdl:part name="parameters" element="tns:Categories" />
</wsdl:message>
<wsdl:message name="CategoriesSoapOut">
<wsdl:part name="parameters" element="tns:CategoriesResponse" />
</wsdl:message>
<wsdl:message name="ModulesSoapIn">
<wsdl:part name="parameters" element="tns:Modules" />
</wsdl:message>
<wsdl:message name="ModulesSoapOut">
<wsdl:part name="parameters" element="tns:ModulesResponse" />
</wsdl:message>
<wsdl:message name="ModulesCategorizedSoapIn">
<wsdl:part name="parameters" element="tns:ModulesCategorized" />
</wsdl:message>
<wsdl:message name="ModulesCategorizedSoapOut">
<wsdl:part name="parameters" element="tns:ModulesCategorizedResponse" />
</wsdl:message>
<wsdl:message name="NitrosSoapIn">
<wsdl:part name="parameters" element="tns:Nitros" />
</wsdl:message>
<wsdl:message name="NitrosSoapOut">
<wsdl:part name="parameters" element="tns:NitrosResponse" />
</wsdl:message>
<wsdl:message name="NitrosCategorizedSoapIn">
<wsdl:part name="parameters" element="tns:NitrosCategorized" />
</wsdl:message>
<wsdl:message name="NitrosCategorizedSoapOut">
<wsdl:part name="parameters" element="tns:NitrosCategorizedResponse" />
</wsdl:message>
<wsdl:message name="authenticateSoapIn">
<wsdl:part name="parameters" element="tns:authenticate" />
</wsdl:message>
<wsdl:message name="authenticateSoapOut">
<wsdl:part name="parameters" element="tns:authenticateResponse" />
</wsdl:message>
<wsdl:message name="fetchPackageSoapIn">
<wsdl:part name="parameters" element="tns:fetchPackage" />
</wsdl:message>
<wsdl:message name="fetchPackageSoapOut">
<wsdl:part name="parameters" element="tns:fetchPackageResponse" />
</wsdl:message>
<wsdl:message name="fetchPackageByVersionSoapIn">
<wsdl:part name="parameters" element="tns:fetchPackageByVersion" />
</wsdl:message>
<wsdl:message name="fetchPackageByVersionSoapOut">
<wsdl:part name="parameters" element="tns:fetchPackageByVersionResponse" />
</wsdl:message>
<wsdl:message name="fetchProtectedPackageSoapIn">
<wsdl:part name="parameters" element="tns:fetchProtectedPackage" />
</wsdl:message>
<wsdl:message name="fetchProtectedPackageSoapOut">
<wsdl:part name="parameters" element="tns:fetchProtectedPackageResponse" />
</wsdl:message>
<wsdl:message name="SubmitPackageSoapIn">
<wsdl:part name="parameters" element="tns:SubmitPackage" />
</wsdl:message>
<wsdl:message name="SubmitPackageSoapOut">
<wsdl:part name="parameters" element="tns:SubmitPackageResponse" />
</wsdl:message>
<wsdl:message name="PackageByGuidSoapIn">
<wsdl:part name="parameters" element="tns:PackageByGuid" />
</wsdl:message>
<wsdl:message name="PackageByGuidSoapOut">
<wsdl:part name="parameters" element="tns:PackageByGuidResponse" />
</wsdl:message>
<wsdl:message name="CategoriesHttpGetIn">
<wsdl:part name="repositoryGuid" type="s:string" />
</wsdl:message>
<wsdl:message name="CategoriesHttpGetOut">
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
</wsdl:message>
<wsdl:message name="ModulesHttpGetIn" />
<wsdl:message name="ModulesHttpGetOut">
<wsdl:part name="Body" element="tns:ArrayOfPackage" />
</wsdl:message>
<wsdl:message name="ModulesCategorizedHttpGetIn" />
<wsdl:message name="ModulesCategorizedHttpGetOut">
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
</wsdl:message>
<wsdl:message name="NitrosHttpGetIn" />
<wsdl:message name="NitrosHttpGetOut">
<wsdl:part name="Body" element="tns:ArrayOfPackage" />
</wsdl:message>
<wsdl:message name="NitrosCategorizedHttpGetIn" />
<wsdl:message name="NitrosCategorizedHttpGetOut">
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
</wsdl:message>
<wsdl:message name="authenticateHttpGetIn">
<wsdl:part name="email" type="s:string" />
<wsdl:part name="md5Password" type="s:string" />
</wsdl:message>
<wsdl:message name="authenticateHttpGetOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="fetchPackageHttpGetIn">
<wsdl:part name="packageGuid" type="s:string" />
</wsdl:message>
<wsdl:message name="fetchPackageHttpGetOut">
<wsdl:part name="Body" element="tns:base64Binary" />
</wsdl:message>
<wsdl:message name="fetchPackageByVersionHttpGetIn">
<wsdl:part name="packageGuid" type="s:string" />
<wsdl:part name="repoVersion" type="s:string" />
</wsdl:message>
<wsdl:message name="fetchPackageByVersionHttpGetOut">
<wsdl:part name="Body" element="tns:base64Binary" />
</wsdl:message>
<wsdl:message name="fetchProtectedPackageHttpGetIn">
<wsdl:part name="packageGuid" type="s:string" />
<wsdl:part name="memberKey" type="s:string" />
</wsdl:message>
<wsdl:message name="fetchProtectedPackageHttpGetOut">
<wsdl:part name="Body" element="tns:base64Binary" />
</wsdl:message>
<wsdl:message name="SubmitPackageHttpGetIn">
<wsdl:part name="repositoryGuid" type="s:string" />
<wsdl:part name="authorGuid" type="s:string" />
<wsdl:part name="packageGuid" type="s:string" />
<wsdl:part name="packageFile" type="s2:StringArray" />
<wsdl:part name="packageDoc" type="s2:StringArray" />
<wsdl:part name="packageThumbnail" type="s2:StringArray" />
<wsdl:part name="name" type="s:string" />
<wsdl:part name="author" type="s:string" />
<wsdl:part name="authorUrl" type="s:string" />
<wsdl:part name="description" type="s:string" />
</wsdl:message>
<wsdl:message name="SubmitPackageHttpGetOut">
<wsdl:part name="Body" element="tns:SubmitStatus" />
</wsdl:message>
<wsdl:message name="PackageByGuidHttpGetIn">
<wsdl:part name="packageGuid" type="s:string" />
</wsdl:message>
<wsdl:message name="PackageByGuidHttpGetOut">
<wsdl:part name="Body" element="tns:Package" />
</wsdl:message>
<wsdl:message name="CategoriesHttpPostIn">
<wsdl:part name="repositoryGuid" type="s:string" />
</wsdl:message>
<wsdl:message name="CategoriesHttpPostOut">
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
</wsdl:message>
<wsdl:message name="ModulesHttpPostIn" />
<wsdl:message name="ModulesHttpPostOut">
<wsdl:part name="Body" element="tns:ArrayOfPackage" />
</wsdl:message>
<wsdl:message name="ModulesCategorizedHttpPostIn" />
<wsdl:message name="ModulesCategorizedHttpPostOut">
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
</wsdl:message>
<wsdl:message name="NitrosHttpPostIn" />
<wsdl:message name="NitrosHttpPostOut">
<wsdl:part name="Body" element="tns:ArrayOfPackage" />
</wsdl:message>
<wsdl:message name="NitrosCategorizedHttpPostIn" />
<wsdl:message name="NitrosCategorizedHttpPostOut">
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
</wsdl:message>
<wsdl:message name="authenticateHttpPostIn">
<wsdl:part name="email" type="s:string" />
<wsdl:part name="md5Password" type="s:string" />
</wsdl:message>
<wsdl:message name="authenticateHttpPostOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="fetchPackageHttpPostIn">
<wsdl:part name="packageGuid" type="s:string" />
</wsdl:message>
<wsdl:message name="fetchPackageHttpPostOut">
<wsdl:part name="Body" element="tns:base64Binary" />
</wsdl:message>
<wsdl:message name="fetchPackageByVersionHttpPostIn">
<wsdl:part name="packageGuid" type="s:string" />
<wsdl:part name="repoVersion" type="s:string" />
</wsdl:message>
<wsdl:message name="fetchPackageByVersionHttpPostOut">
<wsdl:part name="Body" element="tns:base64Binary" />
</wsdl:message>
<wsdl:message name="fetchProtectedPackageHttpPostIn">
<wsdl:part name="packageGuid" type="s:string" />
<wsdl:part name="memberKey" type="s:string" />
</wsdl:message>
<wsdl:message name="fetchProtectedPackageHttpPostOut">
<wsdl:part name="Body" element="tns:base64Binary" />
</wsdl:message>
<wsdl:message name="SubmitPackageHttpPostIn">
<wsdl:part name="repositoryGuid" type="s:string" />
<wsdl:part name="authorGuid" type="s:string" />
<wsdl:part name="packageGuid" type="s:string" />
<wsdl:part name="packageFile" type="s2:StringArray" />
<wsdl:part name="packageDoc" type="s2:StringArray" />
<wsdl:part name="packageThumbnail" type="s2:StringArray" />
<wsdl:part name="name" type="s:string" />
<wsdl:part name="author" type="s:string" />
<wsdl:part name="authorUrl" type="s:string" />
<wsdl:part name="description" type="s:string" />
</wsdl:message>
<wsdl:message name="SubmitPackageHttpPostOut">
<wsdl:part name="Body" element="tns:SubmitStatus" />
</wsdl:message>
<wsdl:message name="PackageByGuidHttpPostIn">
<wsdl:part name="packageGuid" type="s:string" />
</wsdl:message>
<wsdl:message name="PackageByGuidHttpPostOut">
<wsdl:part name="Body" element="tns:Package" />
</wsdl:message>
<wsdl:portType name="RepositorySoap">
<wsdl:operation name="Categories">
<wsdl:input message="tns:CategoriesSoapIn" />
<wsdl:output message="tns:CategoriesSoapOut" />
</wsdl:operation>
<wsdl:operation name="Modules">
<wsdl:input message="tns:ModulesSoapIn" />
<wsdl:output message="tns:ModulesSoapOut" />
</wsdl:operation>
<wsdl:operation name="ModulesCategorized">
<wsdl:input message="tns:ModulesCategorizedSoapIn" />
<wsdl:output message="tns:ModulesCategorizedSoapOut" />
</wsdl:operation>
<wsdl:operation name="Nitros">
<wsdl:input message="tns:NitrosSoapIn" />
<wsdl:output message="tns:NitrosSoapOut" />
</wsdl:operation>
<wsdl:operation name="NitrosCategorized">
<wsdl:input message="tns:NitrosCategorizedSoapIn" />
<wsdl:output message="tns:NitrosCategorizedSoapOut" />
</wsdl:operation>
<wsdl:operation name="authenticate">
<wsdl:input message="tns:authenticateSoapIn" />
<wsdl:output message="tns:authenticateSoapOut" />
</wsdl:operation>
<wsdl:operation name="fetchPackage">
<wsdl:input message="tns:fetchPackageSoapIn" />
<wsdl:output message="tns:fetchPackageSoapOut" />
</wsdl:operation>
<wsdl:operation name="fetchPackageByVersion">
<wsdl:input message="tns:fetchPackageByVersionSoapIn" />
<wsdl:output message="tns:fetchPackageByVersionSoapOut" />
</wsdl:operation>
<wsdl:operation name="fetchProtectedPackage">
<wsdl:input message="tns:fetchProtectedPackageSoapIn" />
<wsdl:output message="tns:fetchProtectedPackageSoapOut" />
</wsdl:operation>
<wsdl:operation name="SubmitPackage">
<wsdl:input message="tns:SubmitPackageSoapIn" />
<wsdl:output message="tns:SubmitPackageSoapOut" />
</wsdl:operation>
<wsdl:operation name="PackageByGuid">
<wsdl:input message="tns:PackageByGuidSoapIn" />
<wsdl:output message="tns:PackageByGuidSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="RepositoryHttpGet">
<wsdl:operation name="Categories">
<wsdl:input message="tns:CategoriesHttpGetIn" />
<wsdl:output message="tns:CategoriesHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="Modules">
<wsdl:input message="tns:ModulesHttpGetIn" />
<wsdl:output message="tns:ModulesHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="ModulesCategorized">
<wsdl:input message="tns:ModulesCategorizedHttpGetIn" />
<wsdl:output message="tns:ModulesCategorizedHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="Nitros">
<wsdl:input message="tns:NitrosHttpGetIn" />
<wsdl:output message="tns:NitrosHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="NitrosCategorized">
<wsdl:input message="tns:NitrosCategorizedHttpGetIn" />
<wsdl:output message="tns:NitrosCategorizedHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="authenticate">
<wsdl:input message="tns:authenticateHttpGetIn" />
<wsdl:output message="tns:authenticateHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="fetchPackage">
<wsdl:input message="tns:fetchPackageHttpGetIn" />
<wsdl:output message="tns:fetchPackageHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="fetchPackageByVersion">
<wsdl:input message="tns:fetchPackageByVersionHttpGetIn" />
<wsdl:output message="tns:fetchPackageByVersionHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="fetchProtectedPackage">
<wsdl:input message="tns:fetchProtectedPackageHttpGetIn" />
<wsdl:output message="tns:fetchProtectedPackageHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="SubmitPackage">
<wsdl:input message="tns:SubmitPackageHttpGetIn" />
<wsdl:output message="tns:SubmitPackageHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="PackageByGuid">
<wsdl:input message="tns:PackageByGuidHttpGetIn" />
<wsdl:output message="tns:PackageByGuidHttpGetOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="RepositoryHttpPost">
<wsdl:operation name="Categories">
<wsdl:input message="tns:CategoriesHttpPostIn" />
<wsdl:output message="tns:CategoriesHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="Modules">
<wsdl:input message="tns:ModulesHttpPostIn" />
<wsdl:output message="tns:ModulesHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="ModulesCategorized">
<wsdl:input message="tns:ModulesCategorizedHttpPostIn" />
<wsdl:output message="tns:ModulesCategorizedHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="Nitros">
<wsdl:input message="tns:NitrosHttpPostIn" />
<wsdl:output message="tns:NitrosHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="NitrosCategorized">
<wsdl:input message="tns:NitrosCategorizedHttpPostIn" />
<wsdl:output message="tns:NitrosCategorizedHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="authenticate">
<wsdl:input message="tns:authenticateHttpPostIn" />
<wsdl:output message="tns:authenticateHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="fetchPackage">
<wsdl:input message="tns:fetchPackageHttpPostIn" />
<wsdl:output message="tns:fetchPackageHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="fetchPackageByVersion">
<wsdl:input message="tns:fetchPackageByVersionHttpPostIn" />
<wsdl:output message="tns:fetchPackageByVersionHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="fetchProtectedPackage">
<wsdl:input message="tns:fetchProtectedPackageHttpPostIn" />
<wsdl:output message="tns:fetchProtectedPackageHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="SubmitPackage">
<wsdl:input message="tns:SubmitPackageHttpPostIn" />
<wsdl:output message="tns:SubmitPackageHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="PackageByGuid">
<wsdl:input message="tns:PackageByGuidHttpPostIn" />
<wsdl:output message="tns:PackageByGuidHttpPostOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="RepositorySoap" type="tns:RepositorySoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Categories">
<soap:operation soapAction="http://packages.umbraco.org/webservices/Categories" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Modules">
<soap:operation soapAction="http://packages.umbraco.org/webservices/Modules" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ModulesCategorized">
<soap:operation soapAction="http://packages.umbraco.org/webservices/ModulesCategorized" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Nitros">
<soap:operation soapAction="http://packages.umbraco.org/webservices/Nitros" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="NitrosCategorized">
<soap:operation soapAction="http://packages.umbraco.org/webservices/NitrosCategorized" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="authenticate">
<soap:operation soapAction="http://packages.umbraco.org/webservices/authenticate" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchPackage">
<soap:operation soapAction="http://packages.umbraco.org/webservices/fetchPackage" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchPackageByVersion">
<soap:operation soapAction="http://packages.umbraco.org/webservices/fetchPackageByVersion" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchProtectedPackage">
<soap:operation soapAction="http://packages.umbraco.org/webservices/fetchProtectedPackage" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SubmitPackage">
<soap:operation soapAction="http://packages.umbraco.org/webservices/SubmitPackage" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="PackageByGuid">
<soap:operation soapAction="http://packages.umbraco.org/webservices/PackageByGuid" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="RepositorySoap12" type="tns:RepositorySoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Categories">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/Categories" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Modules">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/Modules" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ModulesCategorized">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/ModulesCategorized" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Nitros">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/Nitros" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="NitrosCategorized">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/NitrosCategorized" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="authenticate">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/authenticate" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchPackage">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/fetchPackage" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchPackageByVersion">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/fetchPackageByVersion" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchProtectedPackage">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/fetchProtectedPackage" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SubmitPackage">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/SubmitPackage" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="PackageByGuid">
<soap12:operation soapAction="http://packages.umbraco.org/webservices/PackageByGuid" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="RepositoryHttpGet" type="tns:RepositoryHttpGet">
<http:binding verb="GET" />
<wsdl:operation name="Categories">
<http:operation location="/Categories" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Modules">
<http:operation location="/Modules" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ModulesCategorized">
<http:operation location="/ModulesCategorized" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Nitros">
<http:operation location="/Nitros" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="NitrosCategorized">
<http:operation location="/NitrosCategorized" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="authenticate">
<http:operation location="/authenticate" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchPackage">
<http:operation location="/fetchPackage" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchPackageByVersion">
<http:operation location="/fetchPackageByVersion" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchProtectedPackage">
<http:operation location="/fetchProtectedPackage" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SubmitPackage">
<http:operation location="/SubmitPackage" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="PackageByGuid">
<http:operation location="/PackageByGuid" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="RepositoryHttpPost" type="tns:RepositoryHttpPost">
<http:binding verb="POST" />
<wsdl:operation name="Categories">
<http:operation location="/Categories" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Modules">
<http:operation location="/Modules" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ModulesCategorized">
<http:operation location="/ModulesCategorized" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Nitros">
<http:operation location="/Nitros" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="NitrosCategorized">
<http:operation location="/NitrosCategorized" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="authenticate">
<http:operation location="/authenticate" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchPackage">
<http:operation location="/fetchPackage" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchPackageByVersion">
<http:operation location="/fetchPackageByVersion" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fetchProtectedPackage">
<http:operation location="/fetchProtectedPackage" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SubmitPackage">
<http:operation location="/SubmitPackage" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="PackageByGuid">
<http:operation location="/PackageByGuid" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Repository">
<wsdl:port name="RepositorySoap" binding="tns:RepositorySoap">
<soap:address location="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" />
</wsdl:port>
<wsdl:port name="RepositorySoap12" binding="tns:RepositorySoap12">
<soap12:address location="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" />
</wsdl:port>
<wsdl:port name="RepositoryHttpGet" binding="tns:RepositoryHttpGet">
<http:address location="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" />
</wsdl:port>
<wsdl:port name="RepositoryHttpPost" binding="tns:RepositoryHttpPost">
<http:address location="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>