Example #1
0
        public override SyncAttempt <IMedia> DeserializeSecondPass(IMedia item, XElement node, SyncSerializerOptions options)
        {
            var propertyAttempt = DeserializeProperties(item, node, options);

            if (!propertyAttempt.Success)
            {
                return(SyncAttempt <IMedia> .Fail(item.Name, ChangeType.Fail, "Failed to save properties", propertyAttempt.Exception));
            }

            var info = node.Element("Info");

            var sortOrder = info.Element("SortOrder").ValueOrDefault(-1);

            HandleSortOrder(item, sortOrder);

            var trashed = info.Element("Trashed").ValueOrDefault(false);

            HandleTrashedState(item, trashed);

            var attempt = mediaService.Save(item);

            if (!attempt.Success)
            {
                return(SyncAttempt <IMedia> .Fail(item.Name, ChangeType.Fail, ""));
            }

            // setting the saved flag on the attempt to true, stops base classes from saving the item.
            return(SyncAttempt <IMedia> .Succeed(item.Name, item, ChangeType.NoChange, propertyAttempt.Status, true,
                                                 propertyAttempt.Result));
        }
        /// <summary>
        ///  Get all the files in a folder and return them sorted by their level
        /// </summary>
        private IList <LeveledFile> GetLevelOrderedFiles(string folder, IList <uSyncAction> actions)
        {
            List <LeveledFile> nodes = new List <LeveledFile>();

            var files = syncFileService.GetFiles(folder, "*.config");

            foreach (var file in files)
            {
                try
                {
                    var node = LoadNode(file);
                    if (node != null)
                    {
                        nodes.Add(new LeveledFile
                        {
                            Level = node.GetLevel(),
                            File  = file
                        });
                    }
                }
                catch (XmlException ex)
                {
                    // one of the files is wrong. (do we stop or carry on)
                    logger.Warn(handlerType, $"Error loading file: {file} [{ex.Message}]");
                    actions.Add(uSyncActionHelper <TObject> .SetAction(
                                    SyncAttempt <TObject> .Fail(Path.GetFileName(file), ChangeType.Fail, $"Failed to Load: {ex.Message}"), file, Guid.Empty, this.Alias, false));
                }
            }

            return(nodes.OrderBy(x => x.Level).ToList());
        }
        public override SyncAttempt <IMedia> DeserializeSecondPass(IMedia item, XElement node, SerializerFlags flags)
        {
            var propertyAttempt = DeserializeProperties(item, node);

            if (!propertyAttempt.Success)
            {
                return(SyncAttempt <IMedia> .Fail(item.Name, ChangeType.Fail, "Failed to save properties", propertyAttempt.Exception));
            }

            var info = node.Element("Info");

            var sortOrder = info.Element("SortOrder").ValueOrDefault(-1);

            HandleSortOrder(item, sortOrder);

            var trashed = info.Element("Trashed").ValueOrDefault(false);

            HandleTrashedState(item, trashed);

            var attempt = mediaService.Save(item);

            if (!attempt.Success)
            {
                return(SyncAttempt <IMedia> .Fail(item.Name, ChangeType.Fail, ""));
            }

            // we return no-change so we don't trigger the second save
            return(SyncAttempt <IMedia> .Succeed(item.Name, item, ChangeType.NoChange, propertyAttempt.Status));
        }
Example #4
0
        public override SyncAttempt <IContent> DeserializeSecondPass(IContent item, XElement node, SerializerFlags flags)
        {
            var attempt = DeserializeProperties(item, node);

            if (!attempt.Success)
            {
                return(SyncAttempt <IContent> .Fail(item.Name, ChangeType.ImportFail, attempt.Exception));
            }

            // sort order
            var sortOrder = node.Element("Info").Element("SortOrder").ValueOrDefault(-1);

            HandleSortOrder(item, sortOrder);


            var trashed = node.Element("Info").Element("Trashed").ValueOrDefault(false);

            HandleTrashedState(item, trashed);

            // published status
            // this does the last save and publish
            var saveAttempt = DoSaveOrPublish(item, node);

            if (saveAttempt.Success)
            {
                // we say no change back, this stops the core second pass function from saving
                // this item (which we have just done with DoSaveOrPublish)
                return(SyncAttempt <IContent> .Succeed(item.Name, item, ChangeType.NoChange, attempt.Status));
            }

            return(SyncAttempt <IContent> .Fail(item.Name, item, ChangeType.ImportFail, $"{saveAttempt.Result} {attempt.Status}"));
        }
Example #5
0
        /// <summary>
        ///  Get all the files in a folder and return them sorted by their level
        /// </summary>
        private IList <LeveledFile> GetLevelOrderedFiles(string folder, IList <uSyncAction> actions)
        {
            List <LeveledFile> nodes = new List <LeveledFile>();

            var files = syncFileService.GetFiles(folder, $"*.{this.uSyncConfig.Settings.DefaultExtension}");

            foreach (var file in files)
            {
                try
                {
                    var node = LoadNode(file);
                    if (node != null)
                    {
                        nodes.Add(new LeveledFile
                        {
                            Level = (node.GetLevel() * 1000) + node.GetItemSortOrder(), // will hopefully let us put things in sort order in one go.
                            File  = file
                        });

                        // debug.
                        logger.LogDebug("{file} {level}", file, (node.GetLevel() * 1000) + node.GetItemSortOrder());
                    }
                }
                catch (XmlException ex)
                {
                    // one of the files is wrong. (do we stop or carry on)
                    logger.LogWarning($"Error loading file: {file} [{ex.Message}]");
                    actions.Add(uSyncActionHelper <TObject> .SetAction(
                                    SyncAttempt <TObject> .Fail(Path.GetFileName(file), ChangeType.Fail, $"Failed to Load: {ex.Message}"), file, Guid.Empty, this.Alias, false));
                }
            }

            return(nodes.OrderBy(x => x.Level).ToList());
        }
Example #6
0
        private SyncAttempt <XElement> ExportMemberType(string key)
        {
            var _typeService = ApplicationContext.Current.Services.MemberTypeService;
            var item         = _typeService.Get(key);

            if (item != null)
            {
                return(uSyncCoreContext.Instance.MemberTypeSerializer.Serialize(item));
            }

            return(SyncAttempt <XElement> .Fail(key, ChangeType.Export, "item not found"));
        }
Example #7
0
 protected override SyncAttempt <TObject> CanDeserialize(XElement node, SerializerFlags flags)
 {
     if (flags.HasFlag(SerializerFlags.FailMissingParent))
     {
         // check the parent exists.
         if (!this.HasParentItem(node))
         {
             return(SyncAttempt <TObject> .Fail(node.GetAlias(), ChangeType.ParentMissing, $"The parent node for this item is missing, and config is set to not import when a parent is missing"));
         }
     }
     return(SyncAttempt <TObject> .Succeed("No check", ChangeType.NoChange));
 }
Example #8
0
        private SyncAttempt <XElement> ExportDictionaryItem(string key)
        {
            var _typeService = ApplicationContext.Current.Services.LocalizationService;
            var item         = _typeService.GetDictionaryItemByKey(key);

            if (item != null)
            {
                return(uSyncCoreContext.Instance.DictionarySerializer.Serialize(item));
            }

            return(SyncAttempt <XElement> .Fail(key, ChangeType.Export, "item not found"));
        }
Example #9
0
        protected override SyncAttempt <IDomain> DeserializeCore(XElement node, SyncSerializerOptions options)
        {
            var item = FindOrCreate(node);

            var info = node?.Element("Info");

            if (info == null)
            {
                return(SyncAttempt <IDomain> .Fail(node.GetAlias(), default(IDomain), ChangeType.Fail, "Missing info section in xml", new ArgumentNullException("Info", "Missing Info Section in XML")));
            }

            var isoCode = info.Element("Language").ValueOrDefault(string.Empty) ?? string.Empty;

            var changes = new List <uSyncChange>();

            if (!string.IsNullOrWhiteSpace(isoCode))
            {
                var language = localizationService.GetLanguageByIsoCode(isoCode);
                if (language != null && item.LanguageId != language.Id)
                {
                    changes.AddUpdate("Id", item.LanguageId, language.Id);
                    item.LanguageId = language.Id;
                }
            }

            var rootItem = default(IContent);

            var rootKey = info.Element("Root")?.Attribute("Key").ValueOrDefault(Guid.Empty) ?? Guid.Empty;

            if (rootKey != Guid.Empty)
            {
                rootItem = contentService.GetById(rootKey);
            }

            if (rootItem == default(IContent))
            {
                var rootName = info.Element("Root").ValueOrDefault(string.Empty);
                if (rootName != string.Empty)
                {
                    rootItem = FindByPath(rootName.ToDelimitedList("/"));
                }
            }

            if (rootItem != default(IContent) && item.RootContentId != rootItem.Id)
            {
                changes.AddUpdate("RootItem", item.RootContentId, rootItem.Id);
                item.RootContentId = rootItem.Id;
            }

            return(SyncAttempt <IDomain> .Succeed(item.DomainName, item, ChangeType.Import, changes));
        }
Example #10
0
        public override SyncAttempt <IContent> DeserializeSecondPass(IContent item, XElement node, SyncSerializerOptions options)
        {
            var attempt = DeserializeProperties(item, node, options);

            if (!attempt.Success)
            {
                return(SyncAttempt <IContent> .Fail(item.Name, ChangeType.ImportFail, attempt.Exception));
            }

            var changes = attempt.Result;

            // sort order
            var sortOrder = node.Element("Info").Element("SortOrder").ValueOrDefault(-1);

            changes.AddNotNull(HandleSortOrder(item, sortOrder));

            var trashed = node.Element("Info").Element("Trashed").ValueOrDefault(false);

            changes.AddNotNull(HandleTrashedState(item, trashed));


            var publishTimer = Stopwatch.StartNew();
            // published status
            // this does the last save and publish
            var saveAttempt = DoSaveOrPublish(item, node, options);

            if (saveAttempt.Success)
            {
                var message = attempt.Status;
                if (publishTimer.ElapsedMilliseconds > 10000)
                {
                    message += $" (Slow publish {publishTimer.ElapsedMilliseconds}ms)";
                }

                // we say no change back, this stops the core second pass function from saving
                // this item (which we have just done with DoSaveOrPublish)
                return(SyncAttempt <IContent> .Succeed(item.Name, item, ChangeType.NoChange, message, true, changes));
            }

            return(SyncAttempt <IContent> .Fail(item.Name, item, ChangeType.ImportFail, $"{saveAttempt.Result} {attempt.Status}"));
        }
Example #11
0
        internal override SyncAttempt <XElement> SerializeCore(IDataTypeDefinition item)
        {
            try
            {
                var node = new XElement(Constants.Packaging.DataTypeNodeName,
                                        new XAttribute("Name", item.Name),
                                        new XAttribute("Key", item.Key),
                                        new XAttribute("Id", item.PropertyEditorAlias),
                                        new XAttribute("DatabaseType", item.DatabaseType.ToString())
                                        );

                node.Add(SerializePreValues(item, node));

                return(SyncAttempt <XElement> .Succeed(item.Name, node, typeof(IDataTypeDefinition), ChangeType.Export));
            }
            catch (Exception ex)
            {
                LogHelper.Warn <DataTypeSerializer>("Error Serializing {0}", () => ex.ToString());
                return(SyncAttempt <XElement> .Fail(item.Name, typeof(IDataTypeDefinition), ChangeType.Export, "Failed to export", ex));
            }
        }
Example #12
0
        public override SyncAttempt <IMedia> DeserializeSecondPass(IMedia item, XElement node, SerializerFlags flags)
        {
            DeserializeProperties(item, node);

            var info = node.Element("Info");

            var sortOrder = info.Element("SortOrder").ValueOrDefault(-1);

            if (sortOrder != -1)
            {
                item.SortOrder = sortOrder;
            }


            var trashed = info.Element("Trashed").ValueOrDefault(false);

            if (trashed)
            {
                if (!item.Trashed)
                {
                    mediaService.MoveToRecycleBin(item);
                }
                return(SyncAttempt <IMedia> .Succeed(item.Name, ChangeType.Import));
            }

            if (item.Trashed)
            {
                // remove from bin.
                // ?
            }

            var attempt = mediaService.Save(item);

            if (attempt.Success)
            {
                return(SyncAttempt <IMedia> .Succeed(item.Name, ChangeType.Import));
            }

            return(SyncAttempt <IMedia> .Fail(item.Name, ChangeType.Fail, ""));
        }
Example #13
0
        virtual public SyncAttempt <TObject> Import(string filePath, HandlerSettings config, SerializerFlags flags)
        {
            try
            {
                syncFileService.EnsureFileExists(filePath);

                using (var stream = syncFileService.OpenRead(filePath))
                {
                    var node    = XElement.Load(stream);
                    var attempt = serializer.Deserialize(node, flags);
                    return(attempt);
                }
            }
            catch (FileNotFoundException notFoundException)
            {
                return(SyncAttempt <TObject> .Fail(Path.GetFileName(filePath), ChangeType.Fail, $"File not found {notFoundException.Message}"));
            }
            catch (Exception ex)
            {
                return(SyncAttempt <TObject> .Fail(Path.GetFileName(filePath), ChangeType.Fail, $"Import Fail: {ex.Message}"));
            }
        }
Example #14
0
        internal override SyncAttempt <ILanguage> DeserializeCore(XElement node)
        {
            var culture = node.Attribute("CultureAlias");
            var fName   = node.Attribute("FriendlyName");

            if (culture == null || fName == null)
            {
                return(SyncAttempt <ILanguage> .Fail(node.NameFromNode(), ChangeType.Import, "missing Alias or Name"));
            }

            // by name
            ILanguage item = _localizationService.GetLanguageByCultureCode(fName.Value);

            // by iso code
            if (item == null)
            {
                item = _localizationService.GetLanguageByIsoCode(culture.Value);
            }

            // create a new one
            if (item == null)
            {
                item = new Language(culture.Value);
            }

            // all that failed
            if (item == null)
            {
                return(SyncAttempt <ILanguage> .Fail(node.NameFromNode(), ChangeType.Import, "Unable to import language"));
            }

            // it worked update stuff..
            item.IsoCode     = culture.Value;
            item.CultureName = fName.Value;
            _localizationService.Save(item);

            return(SyncAttempt <ILanguage> .Succeed(item.CultureName, item, ChangeType.Import));
        }
Example #15
0
        public override SyncAttempt <IContent> DeserializeSecondPass(IContent item, XElement node, SerializerFlags flags)
        {
            DeserializeProperties(item, node);

            // sort order
            var sortOrder = node.Element("Info").Element("SortOrder").ValueOrDefault(-1);

            if (sortOrder != -1)
            {
                item.SortOrder = sortOrder;
            }

            // published status
            // this does the last save and publish
            if (DoSaveOrPublish(item, node))
            {
                return(SyncAttempt <IContent> .Succeed(item.Name, ChangeType.Import));
            }

            return(SyncAttempt <IContent> .Fail(item.Name, ChangeType.ImportFail, ""));

            // second pass, is when we do the publish and stuff.
        }
Example #16
0
        protected override SyncAttempt <FieldPreValueSource> DeserializeCore(XElement node, SyncSerializerOptions options)
        {
            var item = FindItem(node);

            if (item == null)
            {
                item    = new FieldPreValueSource();
                item.Id = node.GetKey();
            }

            var info = node.Element("Info");

            if (info != null)
            {
                // validate that the prevalue source type exists (can be added in custom code)
                var fieldTypeId = info.Element("FieldPreValueSourceTypeId").ValueOrDefault(Guid.Empty);
                if (!fieldPreValueSourceTypes.Any(x => x.Id == fieldTypeId))
                {
                    return(SyncAttempt <FieldPreValueSource> .Fail(node.GetAlias(), ChangeType.Fail,
                                                                   new Exception("FieldType cannot be found (missing a PreValueProvider?)")));
                }

                item.Name = info.Element("Name").ValueOrDefault(node.GetAlias());
                item.FieldPreValueSourceTypeId = fieldTypeId;
            }



            var settings = node.Element("Settings").ValueOrDefault(string.Empty);

            if (!string.IsNullOrWhiteSpace(settings))
            {
                item.Settings = JsonConvert.DeserializeObject <Dictionary <string, string> >(settings);
            }

            return(SyncAttempt <FieldPreValueSource> .Succeed(item.Name, item, ChangeType.Import));
        }
Example #17
0
        protected override SyncAttempt <ITemplate> DeserializeCore(XElement node, SyncSerializerOptions options)
        {
            var key   = node.GetKey();
            var alias = node.GetAlias();

            var name = node.Element("Name").ValueOrDefault(string.Empty);
            var item = default(ITemplate);

            var details = new List <uSyncChange>();

            if (key != Guid.Empty)
            {
                item = fileService.GetTemplate(key);
            }

            if (item == null)
            {
                item = fileService.GetTemplate(alias);
            }

            if (item == null)
            {
                // create
                var templatePath = IOHelper.MapPath(SystemDirectories.MvcViews + "/" + alias.ToSafeFileName() + ".cshtml");
                if (System.IO.File.Exists(templatePath))
                {
                    logger.Debug <TemplateSerializer>("Reading {0} contents", templatePath);
                    var content = System.IO.File.ReadAllText(templatePath);
                    item         = new Template(name, alias);
                    item.Path    = templatePath;
                    item.Content = content;

                    details.AddNew(alias, alias, "Template");
                }
                else
                {
                    // template is missing
                    // we can't create
                    return(SyncAttempt <ITemplate> .Fail(name, ChangeType.Import, "The template '.cshtml' file is missing."));
                }
            }

            if (item == null)
            {
                // creating went wrong
                return(SyncAttempt <ITemplate> .Fail(name, ChangeType.Import, "Failed to create template"));
            }

            if (item.Key != key)
            {
                details.AddUpdate("Key", item.Key, key);
                item.Key = key;
            }

            if (item.Name != name)
            {
                details.AddUpdate("Name", item.Name, name);
                item.Name = name;
            }

            if (item.Alias != alias)
            {
                details.AddUpdate("Alias", item.Alias, alias);
                item.Alias = alias;
            }

            //var master = node.Element("Parent").ValueOrDefault(string.Empty);
            //if (master != string.Empty)
            //{
            //    var masterItem = fileService.GetTemplate(master);
            //    if (masterItem != null)
            //        item.SetMasterTemplate(masterItem);
            //}

            // Deserialize now takes care of the save.
            // fileService.SaveTemplate(item);

            return(SyncAttempt <ITemplate> .Succeed(item.Name, item, ChangeType.Import, details));
        }
Example #18
0
        internal override SyncAttempt <IMedia> DeserializeCore(XElement node, int parentId, bool forceUpdate)
        {
            var nodeGuid = node.Attribute("guid");

            if (nodeGuid == null)
            {
                return(SyncAttempt <IMedia> .Fail(node.NameFromNode(), ChangeType.Import, "No guid, in xml"));
            }

            Guid guid = new Guid(nodeGuid.Value);

            var    name           = node.Attribute("nodeName").Value;
            string mediaTypeAlias = node.Attribute("nodeTypeAlias").Value;

            var update = node.Attribute("updated").ValueOrDefault(DateTime.Now);

            var item = _mediaService.GetById(guid);

            if (item == null || item.Trashed)
            {
                item = _mediaService.CreateMedia(name, parentId, mediaTypeAlias);
            }
            else
            {
                if (!forceUpdate)
                {
                    if (DateTime.Compare(update, item.UpdateDate.ToLocalTime()) < 0)
                    {
                        return(SyncAttempt <IMedia> .Succeed(item.Name, item, ChangeType.NoChange));
                    }
                }
            }

            if (item != null)
            {
                if (item.Key != guid)
                {
                    item.Key = guid;
                }

                if (item.Name != name)
                {
                    item.Name = name;
                }

                if (item.ParentId != parentId)
                {
                    item.ParentId = parentId;
                }

                /*
                 * properties are set in second pass, for speed we don't do it here.
                 */
                /*
                 * var properties = node.Elements().Where(x => x.Attribute("isDoc") == null);
                 * foreach (var property in properties)
                 * {
                 *  var propertyTypeAlias = property.Name.LocalName;
                 *  if (item.HasProperty(propertyTypeAlias))
                 *  {
                 *      var propType = item.Properties[propertyTypeAlias].PropertyType;
                 *      var newValue = GetImportIds(propType, GetImportXml(property));
                 *
                 *      LogHelper.Debug<Events>("#### Setting property: [{0}] to {1}", () => propertyTypeAlias, () => newValue);
                 *      item.SetValue(propertyTypeAlias, newValue);
                 *  }
                 * }
                 */

                _mediaService.Save(item);
            }

            return(SyncAttempt <IMedia> .Succeed(item.Name, item, ChangeType.Import));
        }
Example #19
0
        /// <summary>
        ///  this is the simple interface, based purely on level,
        ///  we could get clever (like dependency trees for content types)
        ///
        ///  but that would have to be implimented lower down (and it doesn't
        ///  really matter for things in containers only things that parent others).
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="force"></param>
        /// <param name="updates"></param>
        /// <returns></returns>
        protected override IEnumerable <uSyncAction> ImportFolder(string folder, HandlerSettings config, Dictionary <string, TObject> updates, bool force, SyncUpdateCallback callback)
        {
            // if not using flat, then directory structure is doing
            // this for us.
            if (config.UseFlatStructure == false)
            {
                return(base.ImportFolder(folder, config, updates, force, callback));
            }

            List <uSyncAction> actions = new List <uSyncAction>();

            var files = syncFileService.GetFiles(folder, "*.config");

            List <LeveledFile> nodes = new List <LeveledFile>();

            callback?.Invoke("Calculating import order", 0, 1);
            logger.Verbose(handlerType, "Calculating import order");

            foreach (var file in files)
            {
                try
                {
                    var node = LoadNode(file);
                    if (node != null)
                    {
                        nodes.Add(new LeveledFile
                        {
                            Level = node.GetLevel(),
                            File  = file
                        });
                    }
                }
                catch (XmlException ex)
                {
                    // one of the files is wrong. (do we stop or carry on)
                    logger.Warn(handlerType, $"Error loading file: {file} [{ex.Message}]");
                    actions.Add(uSyncActionHelper <TObject> .SetAction(
                                    SyncAttempt <TObject> .Fail(Path.GetFileName(file), ChangeType.Fail, $"Failed to Load: {ex.Message}"), file, false));
                }
            }

            // loaded - now process.
            var flags = SerializerFlags.None;

            if (force)
            {
                flags |= SerializerFlags.Force;
            }
            if (config.BatchSave)
            {
                flags |= SerializerFlags.DoNotSave;
            }

            var cleanMarkers = new List <string>();

            foreach (var item in nodes.OrderBy(x => x.Level).Select((Node, Index) => new { Node, Index }))
            {
                var filename = Path.GetFileNameWithoutExtension(item.Node.File);
                callback?.Invoke($"{filename}", item.Index, nodes.Count);

                logger.Verbose(handlerType, "{Index} Importing: {File}, [Level {Level}]", item.Index, filename, item.Node.Level);

                var attempt = Import(item.Node.File, config, flags);
                if (attempt.Success)
                {
                    if (attempt.Change == ChangeType.Clean)
                    {
                        cleanMarkers.Add(item.Node.File);
                    }
                    else if (attempt.Item != null)
                    {
                        updates.Add(item.Node.File, attempt.Item);
                    }
                }

                actions.Add(uSyncActionHelper <TObject> .SetAction(attempt, item.Node.File, IsTwoPass));
            }

            if (flags.HasFlag(SerializerFlags.DoNotSave) && updates.Any())
            {
                // bulk save - should be the fastest way to do this
                callback?.Invoke($"Saving {updates.Count()} changes", 1, 1);
                serializer.Save(updates.Select(x => x.Value));
            }

            var folders = syncFileService.GetDirectories(folder);

            foreach (var children in folders)
            {
                actions.AddRange(ImportFolder(children, config, updates, force, callback));
            }

            if (actions.All(x => x.Success))
            {
                // LINQ
                // actions.AddRange(cleanMarkers.Select(x => CleanFolder(x)).SelectMany(a => a));

                // only if there are no fails.
                // then we consider the folder safe to clean
                foreach (var cleanfile in cleanMarkers)
                {
                    actions.AddRange(CleanFolder(cleanfile, false, config.UseFlatStructure));
                }
                // remove the actual cleans (they will have been replaced by the deletes
                actions.RemoveAll(x => x.Change == ChangeType.Clean);
            }

            callback?.Invoke("", 1, 1);

            return(actions);
        }
Example #20
0
        internal override SyncAttempt <IContent> DeserializeCore(XElement node, int parentId, bool forceUpdate = false)
        {
            var nodeGuid = node.Attribute("guid");

            if (nodeGuid == null)
            {
                return(SyncAttempt <IContent> .Fail(node.NameFromNode(), ChangeType.Import, "No Guid in XML"));
            }

            Guid guid = new Guid(nodeGuid.Value);

            var name          = node.Attribute("nodeName").Value;
            var type          = node.Attribute("nodeTypeAlias").Value;
            var templateAlias = node.Attribute("templateAlias").Value;

            var sortOrder = int.Parse(node.Attribute("sortOrder").Value);
            var published = bool.Parse(node.Attribute("published").Value);

            // because later set the guid, we are going for a match at this point
            var item = _contentService.GetById(guid);

            if (item == null)
            {
                item = _contentService.CreateContent(name, parentId, type);
            }
            else
            {
                // update is different for content, we go on publish times..
                if (!forceUpdate)
                {
                    DateTime updateTime = node.Attribute("updated").ValueOrDefault(DateTime.Now);

                    if (DateTime.Compare(updateTime, item.UpdateDate.ToLocalTime()) <= 0)
                    {
                        // the import is older than the content on this site;
                        return(SyncAttempt <IContent> .Succeed(item.Name, item, ChangeType.NoChange));
                    }
                }
            }

            if (item == null)
            {
                return(SyncAttempt <IContent> .Fail(node.NameFromNode(), ChangeType.ImportFail, "Cannot find or create content item"));
            }

            // if it's in the trash remove it.
            if (item.Trashed)
            {
                item.ChangeTrashedState(false);
            }

            var template = ApplicationContext.Current.Services.FileService.GetTemplate(templateAlias);

            if (template != null)
            {
                item.Template = template;
            }

            item.Key = guid;

            item.SortOrder = sortOrder;
            item.Name      = name;

            if (item.ParentId != parentId)
            {
                item.ParentId = parentId;
            }

            var properties = node.Elements().Where(x => x.Attribute("isDoc") == null);

            foreach (var property in properties)
            {
                var propertyTypeAlias = property.Name.LocalName;
                if (item.HasProperty(propertyTypeAlias))
                {
                    var propType = item.Properties[propertyTypeAlias].PropertyType;
                    var newValue = GetImportIds(propType, GetImportXml(property));

                    LogHelper.Debug <Events>("#### Setting property: [{0}] to {1}", () => propertyTypeAlias, () => newValue);
                    item.SetValue(propertyTypeAlias, newValue);
                }
            }

            PublishOrSave(item, published);

            return(SyncAttempt <IContent> .Succeed(item.Name, item, ChangeType.Import));
        }
Example #21
0
        protected override SyncAttempt <IMedia> DeserializeCore(XElement node, SyncSerializerOptions options)
        {
            var attempt = FindOrCreate(node);

            if (!attempt.Success)
            {
                throw attempt.Exception;
            }

            var item = attempt.Result;

            var details = new List <uSyncChange>();

            details.AddRange(DeserializeBase(item, node, options));

            if (node.Element("Info") != null)
            {
                var trashed = node.Element("Info").Element("Trashed").ValueOrDefault(false);
                details.AddNotNull(HandleTrashedState(item, trashed));
            }

            var propertyAttempt = DeserializeProperties(item, node, options);

            if (!propertyAttempt.Success)
            {
                return(SyncAttempt <IMedia> .Fail(item.Name, item, ChangeType.Fail, "Failed to save properties", propertyAttempt.Exception));
            }

            var info = node.Element("Info");

            var sortOrder = info.Element("SortOrder").ValueOrDefault(-1);

            HandleSortOrder(item, sortOrder);


            if (details.HasWarning() && options.FailOnWarnings())
            {
                // Fail on warning. means we don't save or publish because something is wrong ?
                return(SyncAttempt <IMedia> .Fail(item.Name, item, ChangeType.ImportFail, "Failed with warnings", details,
                                                  new Exception("Import failed because of warnings, and fail on warnings is true")));
            }

            var saveAttempt = mediaService.Save(item);

            if (!saveAttempt.Success)
            {
                var errors = saveAttempt.Result?.EventMessages?.FormatMessages() ?? "";
                return(SyncAttempt <IMedia> .Fail(item.Name, item, ChangeType.Fail, errors, saveAttempt.Exception));
            }

            // add warning messages if things are missing
            var message = "";

            if (details.Any(x => x.Change == ChangeDetailType.Warning))
            {
                message += $" with warning(s)";
            }

            // setting the saved flag on the attempt to true, stops base classes from saving the item.
            return(SyncAttempt <IMedia> .Succeed(item.Name, item, ChangeType.Import, "", true, propertyAttempt.Result));
        }
Example #22
0
        internal override SyncAttempt <ITemplate> DeserializeCore(XElement node)
        {
            if (node == null || node.Element("Alias") == null || node.Element("Name") == null)
            {
                throw new ArgumentException("Bad xml import");
            }

            var alias = node.Element("Alias").ValueOrDefault(string.Empty);

            if (string.IsNullOrEmpty(alias))
            {
                SyncAttempt <ITemplate> .Fail(node.NameFromNode(), ChangeType.Import, "No Alias node in xml");
            }

            LogHelper.Debug <Events>("# Importing Template : {0}", () => alias);

            var name = node.Element("Name").ValueOrDefault(string.Empty);
            var item = _fileService.GetTemplate(alias);

            if (item == null)
            {
                var templatePath = IOHelper.MapPath(SystemDirectories.MvcViews + "/" + alias.ToSafeFileName() + ".cshtml");
                if (!System.IO.File.Exists(templatePath))
                {
                    templatePath = IOHelper.MapPath(SystemDirectories.Masterpages + "/" + alias.ToSafeFileName() + ".master");
                    if (!System.IO.File.Exists(templatePath))
                    {
                        // cannot find the master for this..
                        templatePath = string.Empty;
                        LogHelper.Warn <TemplateSerializer>("Cannot find underling template file, so we cannot create the template");
                    }
                }

                if (!string.IsNullOrEmpty(templatePath))
                {
                    var content = System.IO.File.ReadAllText(templatePath);

                    item         = new Template(name, alias);
                    item.Path    = templatePath;
                    item.Content = content;
                }
                else
                {
                    LogHelper.Warn <TemplateSerializer>("Can't get a template path?");
                    return(SyncAttempt <ITemplate> .Fail(name, ChangeType.Import, "Failed to generate template path"));
                }
            }

            if (item == null)
            {
                LogHelper.Warn <TemplateSerializer>("Cannot create the template, something missing?");
                return(SyncAttempt <ITemplate> .Fail(name, ChangeType.Import, "Item create fail"));
            }

            if (node.Element("Name").Value != item.Name)
            {
                item.Name = node.Element("Name").Value;
            }

            if (node.Element("Master") != null)
            {
                var masterName = node.Element("Master").Value;
                if (!string.IsNullOrEmpty(masterName))
                {
                    var master = _fileService.GetTemplate(masterName);
                    if (master != null)
                    {
                        item.SetMasterTemplate(master);
                    }
                }
            }

            var key = node.Element("Key").ValueOrDefault(Guid.Empty);

            if (key != Guid.Empty)
            {
                item.Key = key;
            }

            _fileService.SaveTemplate(item);

            return(SyncAttempt <ITemplate> .Succeed(item.Name, item, ChangeType.Import));
        }
Example #23
0
        protected override SyncAttempt <ITemplate> DeserializeCore(XElement node, SyncSerializerOptions options)
        {
            var key   = node.GetKey();
            var alias = node.GetAlias();

            var name = node.Element("Name").ValueOrDefault(string.Empty);
            var item = default(ITemplate);

            var details = new List <uSyncChange>();

            if (key != Guid.Empty)
            {
                item = fileService.GetTemplate(key);
            }

            if (item == null)
            {
                item = fileService.GetTemplate(alias);
            }

            if (item == null)
            {
                item = new Template(shortStringHelper, name, alias);
                details.AddNew(alias, alias, "Template");

                if (ShouldGetContentFromNode(node, options))
                {
                    logger.LogDebug("Getting content for Template from XML");
                    item.Content = GetContentFromConfig(node);
                }
                else
                {
                    logger.LogDebug("Loading template content from disk");

                    var templatePath = ViewPath(alias);
                    if (_viewFileSystem.FileExists(templatePath))
                    {
                        logger.LogDebug("Reading {0} contents", templatePath);
                        item.Content = GetContentFromFile(templatePath);
                        item.Path    = templatePath;
                    }
                    else
                    {
                        if (!options.GetSetting <bool>("UsingRazorViews", false))
                        {
                            // template is missing
                            // we can't create
                            logger.LogWarning("Failed to create template {path} the local file is missing", templatePath);
                            return(SyncAttempt <ITemplate> .Fail(name, ChangeType.Import, $"The template {templatePath} file is missing."));
                        }
                        else
                        {
                            // template is not on disk, we could use the viewEngine to find the view
                            // if this finds the view it tells us that the view is somewhere else ?

                            logger.LogDebug("Failed to find content, but UsingRazorViews so will create anyway, then delete the file");
                            item.Content = $"<!-- [uSyncMarker:{this.Id}]  template content - will be removed -->";
                        }
                    }
                }
            }

            if (item == null)
            {
                // creating went wrong
                logger.LogWarning("Failed to create template");
                return(SyncAttempt <ITemplate> .Fail(name, ChangeType.Import, "Failed to create template"));
            }

            if (item.Key != key)
            {
                details.AddUpdate("Key", item.Key, key);
                item.Key = key;
            }

            if (item.Name != name)
            {
                details.AddUpdate("Name", item.Name, name);
                item.Name = name;
            }

            if (item.Alias != alias)
            {
                details.AddUpdate("Alias", item.Alias, alias);
                item.Alias = alias;
            }

            if (ShouldGetContentFromNode(node, options))
            {
                var content = GetContentFromConfig(node);
                if (content != item.Content)
                {
                    details.AddUpdate("Content", item.Content, content);
                    item.Content = content;
                }
            }

            //var master = node.Element("Parent").ValueOrDefault(string.Empty);
            //if (master != string.Empty)
            //{
            //    var masterItem = fileService.GetTemplate(master);
            //    if (masterItem != null)
            //        item.SetMasterTemplate(masterItem);
            //}

            // Deserialize now takes care of the save.
            // fileService.SaveTemplate(item);

            return(SyncAttempt <ITemplate> .Succeed(item.Name, item, ChangeType.Import, details));
        }
Example #24
0
        /// <summary>
        ///  this is the simple interface, based purely on level,
        ///  we could get clever (like dependency trees for content types)
        ///
        ///  but that would have to be implimented lower down (and it doesn't
        ///  really matter for things in containers only things that parent others).
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="force"></param>
        /// <param name="updates"></param>
        /// <returns></returns>
        protected override IEnumerable <uSyncAction> ImportFolder(string folder, HandlerSettings config, Dictionary <string, TObject> updates, bool force, SyncUpdateCallback callback)
        {
            // if not using flat, then directory structure is doing
            // this for us.
            if (config.UseFlatStructure == false)
            {
                return(base.ImportFolder(folder, config, updates, force, callback));
            }

            List <uSyncAction> actions = new List <uSyncAction>();

            var files = syncFileService.GetFiles(folder, "*.config");

            List <LeveledFile> nodes = new List <LeveledFile>();

            callback?.Invoke("Calculating import order", 0, 1);

            foreach (var file in files)
            {
                try
                {
                    var node = LoadNode(file);
                    if (node != null)
                    {
                        nodes.Add(new LeveledFile
                        {
                            Level = node.GetLevel(),
                            File  = file
                        });
                    }
                }
                catch (XmlException ex)
                {
                    // one of the files is wrong. (do we stop or carry on)
                    logger.Warn <TObject>($"Error loading file: {file} [{ex.Message}]");
                    actions.Add(uSyncActionHelper <TObject> .SetAction(
                                    SyncAttempt <TObject> .Fail(Path.GetFileName(file), ChangeType.Fail, $"Failed to Load: {ex.Message}"), file, false));
                }
            }

            // loaded - now process.
            var flags = SerializerFlags.None;

            if (force)
            {
                flags |= SerializerFlags.Force;
            }
            if (config.BatchSave)
            {
                flags |= SerializerFlags.DoNotSave;
            }

            var count = 0;

            foreach (var node in nodes.OrderBy(x => x.Level))
            {
                count++;
                callback?.Invoke($"{Path.GetFileName(node.File)}", count, nodes.Count);

                var attempt = Import(node.File, config, flags);
                if (attempt.Success && attempt.Item != null)
                {
                    updates.Add(node.File, attempt.Item);
                }

                actions.Add(uSyncActionHelper <TObject> .SetAction(attempt, node.File, IsTwoPass));
            }

            if (flags.HasFlag(SerializerFlags.DoNotSave) && updates.Any())
            {
                // bulk save - should be the fastest way to do this
                callback?.Invoke($"Saving {updates.Count()} changes", 1, 1);
                serializer.Save(updates.Select(x => x.Value));
            }

            var folders = syncFileService.GetDirectories(folder);

            foreach (var children in folders)
            {
                actions.AddRange(ImportFolder(children, config, updates, force, callback));
            }

            callback?.Invoke("", 1, 1);

            return(actions);
        }
Example #25
0
        internal override SyncAttempt <IMacro> DeserializeCore(XElement node)
        {
            LogHelper.Debug <MacroSerializer>("<< DeserailizeCore Macro");
            var item = _packaingService.ImportMacros(node).FirstOrDefault();

            // other bits.
            if (item == null)
            {
                return(SyncAttempt <IMacro> .Fail(node.NameFromNode(), ChangeType.Import, "Package Service import failed"));
            }

            LogHelper.Debug <MacroSerializer>("<<< DeserailizeCore - General properties");

            if (node.Element("name") != null)
            {
                item.Name = node.Element("name").Value;
            }

            if (node.Element("scriptType") != null)
            {
                item.ControlType = node.Element("scriptType").Value;
            }

            if (node.Element("scriptAssembly") != null)
            {
                item.ControlAssembly = node.Element("scriptAssembly").Value;
            }

            if (node.Element("xslt") != null)
            {
                item.XsltPath = node.Element("xslt").Value;
            }

            if (node.Element("scriptingFile") != null)
            {
                item.ScriptPath = node.Element("scriptingFile").Value;
            }

            LogHelper.Debug <MacroSerializer>("<<< DeserailizeCore - Defaults");

            item.UseInEditor   = node.Element("useInEditor").ValueOrDefault(false);
            item.CacheDuration = node.Element("refreshRate").ValueOrDefault(0);
            item.CacheByMember = node.Element("cacheByMember").ValueOrDefault(false);
            item.CacheByPage   = node.Element("cacheByPage").ValueOrDefault(false);
            item.DontRender    = node.Element("dontRender").ValueOrDefault(true);


            LogHelper.Debug <MacroSerializer>("<<< DeserailizeCore - Properties");
            List <string> propertiesToRemove = new List <string>();

            var properties = node.Element("properties");

            if (properties != null && properties.HasElements)
            {
                foreach (var property in properties.Elements("property"))
                {
                    var alias        = property.Attribute("alias").Value;
                    var itemProperty = item.Properties.FirstOrDefault(x => string.Equals(x.Alias, alias, StringComparison.OrdinalIgnoreCase) == true);
                    if (itemProperty != null)
                    {
                        LogHelper.Debug <MacroSerializer>("<<< Updating Property: {0}", () => alias);
                        itemProperty.Alias       = alias;
                        itemProperty.Name        = property.Attribute("name").Value;
                        itemProperty.EditorAlias = property.Attribute("propertyType").Value;
                    }
                }
            }

            foreach (var property in item.Properties)
            {
                var nodeProp = properties.Elements("property").FirstOrDefault(x => x.Attribute("alias").Value == property.Alias);

                if (nodeProp == null)
                {
                    propertiesToRemove.Add(property.Alias);
                }
            }

            if (propertiesToRemove.Any())
            {
                foreach (var alias in propertiesToRemove)
                {
                    LogHelper.Debug <MacroSerializer>("<<< Removing Property : {0}", () => alias);
                    item.Properties.Remove(alias);
                }
            }

            LogHelper.Debug <MacroSerializer>("<<< DeserailizeCore - Saving");
            ApplicationContext.Current.Services.MacroService.Save(item);

            LogHelper.Debug <MacroSerializer>("<<< DeserailizeCore - Return");
            return(SyncAttempt <IMacro> .Succeed(item.Name, item, ChangeType.Import));
        }
Example #26
0
        /// <summary>
        ///  handles export (needs type folded by filename)
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public async Task <bool> Export(string[] args)
        {
            if (args == null || args.Length < 3)
            {
                return(false);
            }

            var type = args[0].ToLower().Replace("-", "");
            var name = args[1].ToLower();
            var file = args[2].ToLower();

            await Out.WriteLineAsync(
                string.Format("Exporting: {0} {1} {2}", type, name, file));

            var attempt = SyncAttempt <XElement> .Fail("unknown", ChangeType.Export, "Unknown type");

            switch (type)
            {
            case "contenttype":
                attempt = ExportContentType(name);
                break;

            case "mediatype":
                attempt = ExportMediaType(name);
                break;

            case "datatype":
                attempt = ExportDataType(name);
                break;

            case "dictionaryitem":
            case "dictionary":
                attempt = ExportDictionaryItem(name);
                break;

            case "language":
                attempt = ExportLanguage(name);
                break;

            case "macro":
                attempt = ExportMacro(name);
                break;

            case "template":
                attempt = ExportTemplate(name);
                break;

            case "membertype":
                attempt = ExportMemberType(name);
                break;
            }

            if (attempt.Success)
            {
                var saveRoot = Path.Combine(
                    new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "..\\uSync\\Export\\");

                var savePath = Path.Combine(saveRoot, file);
                if (!Directory.Exists(Path.GetDirectoryName(savePath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(savePath));
                }


                if (File.Exists(savePath))
                {
                    File.Delete(savePath);
                }

                attempt.Item.Save(savePath);

                await Out.WriteLineAsync(
                    string.Format("{0} exported to {1}", name, savePath));
            }
            else
            {
                await Out.WriteLineAsync("Failed to export " + name + " " + attempt.Message);
            }

            return(true);
        }
Example #27
0
        protected override SyncAttempt <IContent> DeserializeCore(XElement node, SyncSerializerOptions options)
        {
            var attempt = FindOrCreate(node);

            if (!attempt.Success)
            {
                throw attempt.Exception;
            }

            var item = attempt.Result;

            var details = new List <uSyncChange>();

            details.AddRange(DeserializeBase(item, node, options));

            if (node.Element("Info") != null)
            {
                var trashed = node.Element("Info").Element("Trashed").ValueOrDefault(false);
                details.AddNotNull(HandleTrashedState(item, trashed));
            }

            details.AddNotNull(DeserializeTemplate(item, node));

            var propertiesAttempt = DeserializeProperties(item, node, options);

            if (!propertiesAttempt.Success)
            {
                return(SyncAttempt <IContent> .Fail(item.Name, item, ChangeType.ImportFail, "Failed to deserialize properties", attempt.Exception));
            }

            details.AddRange(propertiesAttempt.Result);

            // sort order
            var sortOrder = node.Element("Info").Element("SortOrder").ValueOrDefault(-1);

            details.AddNotNull(HandleSortOrder(item, sortOrder));

            var publishTimer = Stopwatch.StartNew();


            if (details.HasWarning() && options.FailOnWarnings())
            {
                // Fail on warning. means we don't save or publish because something is wrong ?
                return(SyncAttempt <IContent> .Fail(item.Name, item, ChangeType.ImportFail, "Failed with warnings", details,
                                                    new Exception("Import failed because of warnings, and fail on warnings is true")));
            }

            // published status
            // this does the last save and publish
            var saveAttempt = DoSaveOrPublish(item, node, options);

            if (saveAttempt.Success)
            {
                var message = saveAttempt.Result;

                if (details.Any(x => x.Change == ChangeDetailType.Warning))
                {
                    message += $" with warning(s)";
                }

                if (publishTimer.ElapsedMilliseconds > 10000)
                {
                    message += $" (Slow publish {publishTimer.ElapsedMilliseconds}ms)";
                }

                var changeType = options.GetSetting(uSyncConstants.DefaultSettings.OnlyPublishDirty, uSyncConstants.DefaultSettings.OnlyPublishDirty_Default) && !item.IsDirty()
                    ? ChangeType.NoChange : ChangeType.Import;

                // we say no change back, this stops the core second pass function from saving
                // this item (which we have just done with DoSaveOrPublish)
                return(SyncAttempt <IContent> .Succeed(item.Name, item, changeType, message, true, details));
            }
            else
            {
                return(SyncAttempt <IContent> .Fail(item.Name, item, ChangeType.ImportFail, saveAttempt.Result, saveAttempt.Exception));
            }
        }
Example #28
0
        protected override SyncAttempt <ITemplate> DeserializeCore(XElement node)
        {
            var key   = node.GetKey();
            var alias = node.GetAlias();

            var name = node.Element("Name").ValueOrDefault(string.Empty);
            var item = default(ITemplate);

            if (key != Guid.Empty)
            {
                item = fileService.GetTemplate(key);
            }

            if (item == null)
            {
                item = fileService.GetTemplate(alias);
            }

            if (item == null)
            {
                // create
                var templatePath = IOHelper.MapPath(SystemDirectories.MvcViews + "/" + alias.ToSafeFileName() + ".cshtml");
                if (System.IO.File.Exists(templatePath))
                {
                    var content = System.IO.File.ReadAllText(templatePath);

                    item         = new Template(name, alias);
                    item.Path    = templatePath;
                    item.Content = content;
                }
                else
                {
                    // template is missing
                    // we can't create
                }
            }

            if (item == null)
            {
                // creating went wrong
                return(SyncAttempt <ITemplate> .Fail(name, ChangeType.Import, "Failed to create template"));
            }

            if (item.Key != key)
            {
                item.Key = key;
            }

            if (item.Name != name)
            {
                item.Name = name;
            }

            if (item.Alias != alias)
            {
                item.Alias = alias;
            }

            var master = node.Element("Parent").ValueOrDefault(string.Empty);

            if (master != string.Empty)
            {
                var masterItem = fileService.GetTemplate(master);
                if (masterItem != null)
                {
                    item.SetMasterTemplate(masterItem);
                }
            }

            // Deserialize now takes care of the save.
            // fileService.SaveTemplate(item);

            return(SyncAttempt <ITemplate> .Succeed(item.Name, item, ChangeType.Import));
        }