//--- Methods --- public void SendNoticeToAdmin(string subject, string content, MimeType mime) { // TODO (arnec): should this be using the email service? UserBE adminUser = UserBL.GetAdmin(); if (adminUser == null) { throw new SiteNoAdminFatalException(); } string smtphost = string.Empty; int smtpport = 0; if (smtphost == string.Empty) { throw new SiteConflictException(DekiResources.SMTP_SERVER_NOT_CONFIGURED()); } if (string.IsNullOrEmpty(adminUser.Email)) { throw new SiteConflictException(DekiResources.ADMIN_EMAIL_NOT_SET()); } var smtpclient = new SmtpClient(); var msg = new MailMessage(); msg.To.Add(adminUser.Email); msg.From = new MailAddress(_user.Email, _user.Name); msg.Subject = _dekiInstance.SiteName + ": " + subject; msg.Body = content; smtpclient.Host = smtphost; if (smtpport != 0) { smtpclient.Port = smtpport; } smtpclient.Send(msg); }
public static XDoc GetCommentXmlAsAtom(IList <CommentBE> comments, XUri feedUri, PageBE page) { var resources = DekiContext.Current.Resources; string title = resources.Localize(DekiResources.COMMENT_FOR(page.Title.AsUserFriendlyName())); XAtomFeed feed = new XAtomFeed(title, feedUri, DateTime.UtcNow); feed.AddLink(PageBL.GetUriUi(page), XAtomBase.LinkRelation.Alternate, MimeType.XHTML, null, page.Title.AsUserFriendlyName()); feed.Id = feedUri; foreach (CommentBE c in comments) { UserBE posterUser = UserBL.GetUserById(c.PosterUserId); title = c.Title; if (string.IsNullOrEmpty(title)) { title = resources.Localize(DekiResources.COMMENT_BY_TO(posterUser.Name, page.Title.AsUserFriendlyName())); } XAtomEntry entry = feed.StartEntry(title, c.CreateDate, (c.LastEditDate == null || c.LastEditDate == DateTime.MinValue) ? c.CreateDate : c.LastEditDate.Value); entry.Id = GetUri(c); entry.AddAuthor(posterUser.Name, UserBL.GetUriUiHomePage(posterUser), posterUser.Email); MimeType commentMimetype; MimeType.TryParse(c.ContentMimeType, out commentMimetype); entry.AddContent(c.Content); XUri entryLink = PageBL.GetUriUi(page).WithFragment("comment" + c.Number); entry.AddLink(entryLink, XAtomBase.LinkRelation.Alternate, null, null, null); entry.AddLink(GetUri(c).At("content"), XAtomBase.LinkRelation.Enclosure, commentMimetype, c.Content.Length, "content"); feed.End(); } return(feed); }
//--- Constructors --- protected AttachmentBL() { _dekiContext = DekiContext.Current; _session = DbUtils.CurrentSession; _resources = _dekiContext.Resources; _resourceBL = ResourceBL.Instance; }
public void Localizing_non_existent_key_retuns_error_string() { _resourceManagerMock.Setup(x => x.GetString("System.API.Error.rating_invalid_score", CultureInfo.InvariantCulture, null)) .Returns((string)null).AtMostOnce().Verifiable(); var resource = DekiResources.RATING_INVALID_SCORE(); Assert.AreEqual("[MISSING: System.API.Error.rating_invalid_score]", _resources.Localize(resource)); _resourceManagerMock.VerifyAll(); }
public void Can_localize_resource_with_arguments() { _resourceManagerMock.Setup(x => x.GetString("System.API.Error.property_concurrency_error", CultureInfo.InvariantCulture, null)) .Returns("{0}").AtMostOnce().Verifiable(); var resource = DekiResources.PROPERTY_CONCURRENCY_ERROR(1234); Assert.AreEqual("1234", _resources.Localize(resource)); _resourceManagerMock.VerifyAll(); }
public void Can_localize_no_arg_resource() { _resourceManagerMock.Setup(x => x.GetString("System.API.Error.rating_invalid_score", CultureInfo.InvariantCulture, null)) .Returns("foo").AtMostOnce().Verifiable(); var resource = DekiResources.RATING_INVALID_SCORE(); Assert.AreEqual("foo", _resources.Localize(resource)); _resourceManagerMock.VerifyAll(); }
public void RestoreAttachment(ResourceBE attachmentToRestore, PageBE toPage, DateTime timestamp, uint transactionId) { if (toPage == null || toPage.ID == 0) { ArchiveBE archivesMatchingPageId = _session.Archive_GetPageHeadById(attachmentToRestore.ParentPageId.Value); if (archivesMatchingPageId == null) { throw new AttachmentRestoreFailedNoParentFatalException(); } else { toPage = PageBL.GetPageByTitle(archivesMatchingPageId.Title); if (0 == toPage.ID) { PageBL.Save(toPage, _resources.Localize(DekiResources.RESTORE_ATTACHMENT_NEW_PAGE_TEXT()), DekiMimeType.DEKI_TEXT, null); } } } string filename = attachmentToRestore.Name; //Check for name conflicts on target page ResourceBE conflictingFile = GetPageAttachment(toPage.ID, filename); if (conflictingFile != null) { //rename the restored file filename = string.Format("{0}(restored {1}){2}", attachmentToRestore.FilenameWithoutExtension, DateTime.Now.ToString("g"), string.IsNullOrEmpty(attachmentToRestore.FilenameExtension) ? string.Empty : "." + attachmentToRestore.FilenameExtension); conflictingFile = GetPageAttachment(toPage.ID, filename); if (conflictingFile != null) { throw new AttachmentRestoreNameConflictException(); } } //Build new revision for restored file attachmentToRestore = BuildRevForRestore(attachmentToRestore, toPage, filename, transactionId); //Insert new revision into DB attachmentToRestore = SaveResource(attachmentToRestore); //Recent Changes RecentChangeBL.AddFileRecentChange(_dekiContext.Now, toPage, _dekiContext.User, DekiResources.FILE_RESTORED(attachmentToRestore.Name), transactionId); _dekiContext.Instance.EventSink.AttachmentRestore(_dekiContext.Now, attachmentToRestore, _dekiContext.User); }
public string Localize(DekiResources resources) { var _builder = new StringBuilder(); foreach (var item in _resourceChain) { var resource = item as DekiResource; if (resource == null) { _builder.Append(item); } else { _builder.Append(resources.Localize(resource)); } } return(_builder.ToString()); }
public void Can_localize_string_resource_mixed_builder() { var resourceManagerMock = new Mock <IPlainTextResourceManager>(); var resources = new DekiResources(resourceManagerMock.Object, CultureInfo.InvariantCulture); resourceManagerMock.Setup(x => x.GetString("x", CultureInfo.InvariantCulture, null)) .Returns("abc").AtMostOnce().Verifiable(); resourceManagerMock.Setup(x => x.GetString("y", CultureInfo.InvariantCulture, null)) .Returns("xyz").AtMostOnce().Verifiable(); var b = new DekiResourceBuilder(); b.Append(new DekiResource("x")); b.Append("+"); b.Append(new DekiResource("y")); b.Append("-"); Assert.AreEqual("abc+xyz-", b.Localize(resources)); resourceManagerMock.VerifyAll(); }
internal static DekiResource GetPageDiffSummary(PageBE page, string before, string beforeMime, string after, string afterMime, int maxDelta) { ParserResult beforeDoc = DekiXmlParser.Parse(page, beforeMime, page.Language, before, ParserMode.EDIT, false, -1, null, null); ParserResult afterDoc = DekiXmlParser.Parse(page, afterMime, page.Language, after, ParserMode.EDIT, false, -1, null, null); Tuplet <ArrayDiffKind, XDocDiff.Token>[] diff = XDocDiff.Diff(beforeDoc.MainBody, afterDoc.MainBody, maxDelta); if (diff == null) { return(DekiResources.PAGE_DIFF_TOO_LARGE()); } // create change summary int added; int removed; int attributes; int structural; return(GetChangeSummary(diff, out added, out removed, out attributes, out structural)); }
//--- Class Methods --- // TODO: if we need more arguments, need to make the dispatcher smarter to pass in the desired arguments, so that the other handler // signatures don't have to change public static DreamMessage Map(Exception exception, DekiResources resources) { var exceptionType = exception.GetType(); MethodInfo handler; lock (_handlers) { if (!_handlers.TryGetValue(exceptionType, out handler)) { handler = (from method in typeof(DekiExceptionMapper).GetMethods(BindingFlags.NonPublic | BindingFlags.Static) let parameters = method.GetParameters() where parameters.Length == 2 && parameters[0].ParameterType.IsAssignableFrom(exceptionType) let depth = GetInheritanceChain(parameters[0].ParameterType, 0) orderby depth descending select method).FirstOrDefault(); if (handler == null) { return(null); } _handlers[exceptionType] = handler; } } return((DreamMessage)handler.Invoke(null, new object[] { exception, resources })); }
/// <summary> /// Move this attachment to the target page. /// </summary> /// <remarks> /// This will fail if destination page has a file with the same name. /// </remarks> /// <param name="sourcePage">Current file location</param> /// <param name="targetPage">Target file location. May be same as sourcepage for rename</param> /// <param name="name">New filename or null for no change</param> /// <returns></returns> public ResourceBE MoveAttachment(ResourceBE attachment, PageBE sourcePage, PageBE targetPage, string name, bool loggingEnabled) { //TODO MaxM: Connect with a changeset uint changeSetId = 0; attachment.AssertHeadRevision(); bool move = targetPage != null && targetPage.ID != sourcePage.ID; bool rename = name != null && !name.EqualsInvariant(attachment.Name); //Just return the current revision if no change is being made if (!move && !rename) { return(attachment); } //validate filename if (rename) { name = ValidateFileName(name); } //Check the resource exists on the target (may be same as source page) with new name (if given) or current name ResourceBE existingAttachment = GetPageAttachment((targetPage ?? sourcePage).ID, name ?? attachment.Name); if (existingAttachment != null) { throw new AttachmentExistsOnPageConflictException(name ?? attachment.Name, (targetPage ?? sourcePage).Title.AsUserFriendlyName()); } //Performing a move? if (move) { _dekiContext.Instance.Storage.MoveFile(attachment, targetPage); //Perform the IStorage move (should be a no-op) } //Build the new revision ResourceBE newRevision = BuildRevForMoveAndRename(attachment, targetPage, name, changeSetId); //Insert new revision into DB try { newRevision = SaveResource(newRevision); } catch { //failed to save the revision, undo the file move with the IStorage. (Should be a no-op) if (move) { _dekiContext.Instance.Storage.MoveFile(attachment, sourcePage); } throw; //NOTE MaxM: file rename does not even touch IStorage. No need to undo it } //Notification for file move if (loggingEnabled) { if (move) { RecentChangeBL.AddFileRecentChange(_dekiContext.Now, sourcePage, _dekiContext.User, DekiResources.FILE_MOVED_TO(attachment.Name, targetPage.Title.AsPrefixedUserFriendlyPath()), changeSetId); RecentChangeBL.AddFileRecentChange(_dekiContext.Now, targetPage, _dekiContext.User, DekiResources.FILE_MOVED_FROM(attachment.Name, sourcePage.Title.AsPrefixedUserFriendlyPath()), changeSetId); } if (rename) { RecentChangeBL.AddFileRecentChange(_dekiContext.Now, sourcePage, _dekiContext.User, DekiResources.FILE_RENAMED_TO(attachment.Name, name), changeSetId); } } //Notification for file rename and move use same event _dekiContext.Instance.EventSink.AttachmentMove(_dekiContext.Now, attachment, sourcePage, _dekiContext.User); return(newRevision); }
private static DreamMessage Map(TooManyResultsException e, DekiResources resources) { return(DreamMessage.Forbidden(resources.Localize(DekiResources.SITE_TOO_BIG_TO_GENERATE_SITEMAP()))); }
public ResourceBE AddAttachment(ResourceBE existingRevision, Stream filestream, long filesize, MimeType mimeType, PageBE targetPage, string userDescription, string fileName, bool isMsWebDav) { if (_dekiContext.Instance.MaxFileSize < filesize) { throw new AttachmentMaxFileSizeAllowedInvalidArgumentException(_dekiContext.Instance.MaxFileSize); } var saveFileName = ValidateFileName(fileName); if (existingRevision != null) { if (!saveFileName.EqualsInvariant(existingRevision.Name)) { // An existing file is getting renamed. Make sure no file exists with the new name var existingAttachment = GetPageAttachment(targetPage.ID, saveFileName); if (existingAttachment != null) { throw new AttachmentExistsOnPageConflictException(saveFileName, targetPage.Title.AsUserFriendlyName()); } } } // If file is found but has been deleted, create a new file. if (existingRevision != null && existingRevision.ResourceIsDeleted) { existingRevision = null; } if (isMsWebDav) { _log.DebugFormat("Upload client is MD WebDAV, provided mimetype is: {0}", mimeType); var extensionFileType = MimeType.FromFileExtension(Path.GetExtension(saveFileName)); if (!extensionFileType.Match(mimeType) || extensionFileType == MimeType.DefaultMimeType) { mimeType = existingRevision == null ? extensionFileType : existingRevision.MimeType; _log.DebugFormat("using mimetype '{0}' instead", mimeType); } } ResourceBE attachment; var resourceContents = new ResourceContentBE((uint)filesize, mimeType); var isUpdate = false; if (existingRevision == null) { attachment = _resourceBL.BuildRevForNewResource((uint)targetPage.ID, ResourceBE.ParentType.PAGE, saveFileName, mimeType, (uint)filesize, null, ResourceBE.Type.FILE, _dekiContext.User.ID, resourceContents); } else { isUpdate = true; attachment = BuildRevForContentUpdate(existingRevision, mimeType, (uint)filesize, null, saveFileName, resourceContents); } // rewrite mimetype to text/plain for certain extensions string extension = attachment.FilenameExtension; if (_dekiContext.Instance.FileExtensionForceAsTextList.Any(forcedExtensions => extension == forcedExtensions)) { attachment.MimeType = MimeType.TEXT; } // Insert the attachment into the DB attachment = SaveResource(attachment); try { // Save file to storage provider _dekiContext.Instance.Storage.PutFile(attachment, SizeType.ORIGINAL, new StreamInfo(filestream, filesize, mimeType)); } catch (Exception x) { _dekiContext.Instance.Log.WarnExceptionFormat(x, "Failed to save attachment to storage provider"); // Upon save failure, delete the record from the db. _session.Resources_DeleteRevision(attachment.ResourceId, attachment.Revision); throw; } // Set description property if (!string.IsNullOrEmpty(userDescription)) { attachment = SetDescription(attachment, userDescription); } // For images resolve width/height (if not in imagemagick's blacklist) attachment = IdentifyUnknownImage(attachment); // Pre render thumbnails of images AttachmentPreviewBL.PreSaveAllPreviews(attachment); PageBL.Touch(targetPage, DateTime.UtcNow); //TODO MaxM: Connect with transaction RecentChangeBL.AddFileRecentChange(targetPage.Touched, targetPage, _dekiContext.User, DekiResources.FILE_ADDED(attachment.Name), 0); if (isUpdate) { _dekiContext.Instance.EventSink.AttachmentUpdate(_dekiContext.Now, attachment, _dekiContext.User); } else { _dekiContext.Instance.EventSink.AttachmentCreate(_dekiContext.Now, attachment, _dekiContext.User); } return(attachment); }
private static DreamMessage Map(AttachmentPreviewBadImageFatalException e, DekiResources resources) { return(new DreamMessage(DreamStatus.InternalError, null, e.PreviewMimeType, e.PreviewImage)); }
public ConflictSubClass() : base(DekiResources.LANGUAGE_SET_TALK()) { }
public BadCallSubClass() : base(DekiResources.LANGUAGE_SET_TALK()) { }
public MissingSubClass() : base(DekiResources.LANGUAGE_SET_TALK()) { }
private static DreamMessage Map(MindTouchAccessDeniedException e, DekiResources resources) { return(DreamMessage.AccessDenied(e.AuthRealm, resources.Localize(e.Resource))); }
//--- Misc exception handlers --- private static DreamMessage Map(MindTouchInvalidOperationException e, DekiResources resources) { return(DreamMessage.BadRequest(e.Message)); }
private static DreamMessage Map(MindTouchNotFoundException e, DekiResources resources) { return(DreamMessage.NotFound(resources.Localize(e.Resource))); }
private static DreamMessage Map(MindTouchConflictException e, DekiResources resources) { return(DreamMessage.Conflict(resources.Localize(e.Resource))); }
private static DreamMessage Map(MindTouchFatalCallException e, DekiResources resources) { return(DreamMessage.InternalError(resources.Localize(e.Resource))); }
//--- generic ResourcedMindTouchException handlers --- private static DreamMessage Map(MindTouchInvalidCallException e, DekiResources resources) { return(DreamMessage.BadRequest(resources.Localize(e.Resource))); }
public void Setup() { _resourceManagerMock = new Mock<IPlainTextResourceManager>(); _resources = new DekiResources(_resourceManagerMock.Object, CultureInfo.InvariantCulture); }
private static void TruncateList(XDoc list, int selectedIndex, bool hidden) { var resources = DekiContext.Current.Resources; int count = list.ListLength; // check if the selected node is a phantom node (i.e. it's not in the list, but must be accounted for) bool phantom = false; if (selectedIndex < 0) { phantom = true; ++count; selectedIndex = ~selectedIndex; } int max_list_count = DekiContext.Current.Instance.NavMaxItems; int firstVisible; int lastVisible; if (max_list_count <= 0) { firstVisible = 0; lastVisible = count - 1; } else { firstVisible = Math.Max(0, selectedIndex - max_list_count / 2); lastVisible = Math.Min(count - 1, selectedIndex + max_list_count / 2); firstVisible = Math.Max(0, Math.Min(firstVisible, lastVisible - max_list_count + 1)); lastVisible = Math.Min(count - 1, firstVisible + max_list_count - 1); } if (firstVisible == 1) { firstVisible = 0; } if (lastVisible == (count - 2)) { lastVisible = count - 1; } // set nodes as hidden List <string> firstClosed = new List <string>(); List <string> lastClosed = new List <string>(); XDoc first = null; XDoc last = null; int counter = 0; foreach (XDoc current in list) { if (!phantom || (counter != selectedIndex)) { if (counter < firstVisible) { XDoc css = current["@class"]; if (first == null) { first = current; } else { css.ReplaceValue(css.Contents + (hidden ? " hiddenNode" : " closedNode hiddenNode")); firstClosed.Add(current["@id"].Contents); } } else if (counter > lastVisible) { XDoc css = current["@class"]; if (last == null) { last = current; } else { css.ReplaceValue(css.Contents + (hidden ? " hiddenNode" : " closedNode hiddenNode")); lastClosed.Add(current["@id"].Contents); } } } ++counter; } // convert first and last node into '...' nodes if (first != null) { first["@class"].ReplaceValue(first["@class"].Contents + " moreNodes"); XDoc address = first["a"]; first.Attr("content", address.AsXmlNode.InnerText); first.Attr("contentTitle", address["@title"].Contents); first.Attr("hiddenNodes", string.Join(",", firstClosed.ToArray())); address.ReplaceValue(string.Empty); address["span"].Remove(); address.Start("span").Attr("class", "more").Value("...").End(); address["@title"].ReplaceValue(resources.Localize(DekiResources.MORE_DOT_DOT_DOT())); } if (last != null) { last["@class"].ReplaceValue(last["@class"].Contents + " moreNodes"); XDoc address = last["a"]; last.Attr("content", address.AsXmlNode.InnerText); last.Attr("contentTitle", address["@title"].Contents); last.Attr("hiddenNodes", string.Join(",", lastClosed.ToArray())); address.ReplaceValue(string.Empty); address["span"].Remove(); address.Start("span").Attr("class", "more").Value("...").End(); address["@title"].ReplaceValue(resources.Localize(DekiResources.MORE_DOT_DOT_DOT())); } }
public void Setup() { _resourceManagerMock = new Mock <IPlainTextResourceManager>(); _resources = new DekiResources(_resourceManagerMock.Object, CultureInfo.InvariantCulture); }
public void Can_localize_string_resource_mixed_builder() { var resourceManagerMock = new Mock<IPlainTextResourceManager>(); var resources = new DekiResources(resourceManagerMock.Object, CultureInfo.InvariantCulture); resourceManagerMock.Setup(x => x.GetString("x", CultureInfo.InvariantCulture, null)) .Returns("abc").AtMostOnce().Verifiable(); resourceManagerMock.Setup(x => x.GetString("y", CultureInfo.InvariantCulture, null)) .Returns("xyz").AtMostOnce().Verifiable(); var b = new DekiResourceBuilder(); b.Append(new DekiResource("x")); b.Append("+"); b.Append(new DekiResource("y")); b.Append("-"); Assert.AreEqual("abc+xyz-",b.Localize(resources)); resourceManagerMock.VerifyAll(); }
public FatalSubClass() : base(DekiResources.LANGUAGE_SET_TALK()) { }
private DekiResourceBuilder CompareTagSets(List <TagBE> current, List <TagBE> proposed, out List <TagBE> added, out List <uint> removed) { // perform a subtraction of tags (in both directions) to determine which tags were added and removed from one set to another added = new List <TagBE>(); removed = new List <uint>(); TagComparer tagComparer = new TagComparer(); current.Sort(tagComparer); proposed.Sort(tagComparer); // determine which pages have been added StringBuilder addedSummary = new StringBuilder(); List <TagBE> addedList = new List <TagBE>(); foreach (TagBE proposedTag in proposed) { if ((current.BinarySearch(proposedTag, tagComparer) < 0)) { // only add the tag if is not already being added bool includeTag = (added.BinarySearch(proposedTag, tagComparer) < 0); if (includeTag && (TagType.TEXT == proposedTag.Type)) { TagBE proposedTagDefine = new TagBE(); proposedTagDefine.Type = TagType.DEFINE; proposedTagDefine.Name = proposedTag.Name; if (0 <= proposed.BinarySearch(proposedTagDefine, tagComparer)) { includeTag = false; } } if (includeTag) { added.Add(proposedTag); if (1 < added.Count) { addedSummary.Append(", "); } addedSummary.Append(proposedTag.PrefixedName); } } } // determine which pages have been removed StringBuilder removedSummary = new StringBuilder(); foreach (TagBE currentTag in current) { if (proposed.BinarySearch(currentTag, tagComparer) < 0) { removed.Add(currentTag.Id); if (1 < removed.Count) { removedSummary.Append(", "); } removedSummary.Append(currentTag.PrefixedName); } } // create a diff summary string var diffSummary = new DekiResourceBuilder(); if (0 < addedSummary.Length) { diffSummary.Append(DekiResources.TAG_ADDED(addedSummary.ToString())); } if (0 < removedSummary.Length) { if (!diffSummary.IsEmpty) { diffSummary.Append(" "); } diffSummary.Append(DekiResources.TAG_REMOVED(removedSummary.ToString())); } return(diffSummary); }
private static DreamMessage Map(MindTouchForbiddenException e, DekiResources resources) { return(DreamMessage.Forbidden(resources.Localize(e.Resource))); }
private static DreamMessage Map(DekiLicenseException e, DekiResources resources) { return(DreamMessage.BadRequest(e.Message)); }