private void FormatTeamCreationPost(UserContentViewModel item) { string[] teamData = item.Content.Split('|'); string id = teamData[0]; string name = teamData[1]; string motto = teamData[2]; string memberCount = teamData[3]; bool recruiting = false; if (teamData.Length > 4) { recruiting = bool.Parse(teamData[4] ?? "False"); } string postTemplate = ContentFormatter.FormatUrlContentToShow(item.UserContentType); string translatedText = SharedLocalizer["A new team has been created with {0} members.", memberCount].ToString(); if (recruiting) { translatedText = SharedLocalizer["A team is recruiting!", memberCount].ToString(); } item.Content = String.Format(postTemplate, translatedText, name, motto); item.Url = Url.Action("Details", "Team", new { teamId = id }); item.Language = SupportedLanguage.English; }
public void ContentFormat_WidthSingleMultiLine_ReturnValidFormatting() { bool hasTestFailed = false; List <String> rawContent = new List <String>(); rawContent.Add("Lorem ipsum\n"); rawContent.Add("consetetur"); List <String> definedContent = new List <String>(); definedContent.Add("Lorem ipsum"); definedContent.Add("consetetur"); ContentFormatter contentFormatter = new ContentFormatter(rawContent, 11); List <String> result = contentFormatter._formatted; for (int i = 0; i < definedContent.Count; i++) { if (definedContent[i] != result[i]) { hasTestFailed = true; } } Assert.AreEqual(hasTestFailed, false); }
//HW public string GetContentFormatted(long id) { var content = GetContent(id); var formattedContent = ContentFormatter.Format(content); return(formattedContent); }
protected virtual async Task <T> PostAsync <T>(string method, FormUrlEncodedContent content, CancellationToken cancellationToken) { var response = await httpClient.PostAsync(rootEndPoint + method, content, cancellationToken).ConfigureAwait(false); using (var stream = await response.EnsureSuccessStatusCode().Content.ReadAsStreamAsync().ConfigureAwait(false)) { return((T)ContentFormatter.Deserialize(typeof(T), stream)); } }
private static IContentFormatter GetFormatter(string bizFlag) { var simpleFormatter = new ContentFormatter( (r, b, c, e) => $"{r}您好,您的忘记密码验证码为{c},有效期为{(int)e.TotalSeconds}秒."); //如果就一个业务场景,也可以直接返回simpleFormatter var formatter = new ComplexContentFormatter(); formatter.SetFormatter(bizFlag, simpleFormatter); return(formatter); }
public void Given_Url_Text_Does_Not_Exceed_Max_Allowed_Length_Title_Attribute_Is_Added_And_Http_Scheme_Removed() { var contentBeforeFormatting = "<a href=\"http://t.co/lzi51BTM\">http://sergejus.blogas.lt/itishnikai-7-jau-online-1586.html</a>"; var contentAfterFormatting = "<a href=\"http://t.co/lzi51BTM\" title=\"http://sergejus.blogas.lt/itishnikai-7-jau-online-1586.html\">sergejus.blogas.lt/itishnikai-7-jau-online-1586.html</a>"; var contentFormatter = new ContentFormatter(maxUrlTextLength: 100); var formattedContent = contentFormatter.Format(contentBeforeFormatting); Assert.That(formattedContent, Is.EqualTo(contentAfterFormatting)); }
public void Given_Url_Text_Exeeds_Max_Allowed_Length_It_Is_Shortened() { var contentBeforeFormatting = "<a href=\"http://t.co/lzi51BTM\">http://sergejus.blogas.lt/itishnikai-7-jau-online-1586.html</a>"; var contentAfterFormatting = "<a href=\"http://t.co/lzi51BTM\" title=\"http://sergejus.blogas.lt/itishnikai-7-jau-online-1586.html\">sergejus.blogas.lt/../itishnikai-7-jau-online-1586.html</a>"; var contentFormatter = new ContentFormatter(maxUrlTextLength: 30); var formattedContent = contentFormatter.Format(contentBeforeFormatting); Assert.That(formattedContent, Is.EqualTo(contentAfterFormatting)); }
protected virtual IEnumerator _PostAsync <T>(string method, WWWForm content, Action <T> onCompleted, Action <Exception> onError, Action <float> reportProgress) { using (var www = new WWW(rootEndPoint + method, content.data, MergeHeaders(content.headers))) { while (!www.isDone) { if (reportProgress != null) { try { reportProgress(www.progress); } catch (Exception ex) { if (onError != null) { onError(ex); } yield break; } } yield return(null); } if (www.error != null) { var ex = new Exception(www.error ?? ""); if (onError != null) { onError(ex); } } else { try { using (var ms = new MemoryStream(www.bytes)) { var value = (T)ContentFormatter.Deserialize(typeof(T), ms); onCompleted(value); } } catch (Exception ex) { if (onError != null) { onError(ex); } } } } }
protected virtual async Task <T> PostAsync <T>(string method, FormUrlEncodedContent content, CancellationToken cancellationToken) { if (ContentFormatter.MediaType != null) { content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentFormatter.MediaType); } var response = await httpClient.PostAsync(rootEndPoint + method, content, cancellationToken).ConfigureAwait(false); using (var stream = await response.EnsureSuccessStatusCode().Content.ReadAsStreamAsync().ConfigureAwait(false)) { return((T)ContentFormatter.Deserialize(typeof(T), stream)); } }
public async Task <IActionResult> Details(Guid id) { OperationResultVo <UserContentViewModel> serviceResult = userContentAppService.GetById(CurrentUserId, id); if (!serviceResult.Success) { TempData["Message"] = SharedLocalizer["Content not found!"].Value; return(RedirectToAction("Index", "Home")); } UserContentViewModel vm = serviceResult.Value; vm.Content = ContentFormatter.FormatContentToShow(vm.Content); SetAuthorDetails(vm); if (vm.GameId.HasValue && vm.GameId.Value != Guid.Empty) { OperationResultVo <GameViewModel> gameServiceResult = gameAppService.GetById(CurrentUserId, vm.GameId.Value); GameViewModel game = gameServiceResult.Value; vm.GameTitle = game.Title; vm.GameThumbnail = UrlFormatter.Image(game.UserId, ImageType.GameThumbnail, game.ThumbnailUrl); } vm.Content = vm.Content.Replace("image-style-align-right", "image-style-align-right float-right p-10"); vm.Content = vm.Content.Replace("image-style-align-left", "image-style-align-left float-left p-10"); vm.Content = vm.Content.Replace("<img src=", @"<img class=""img-fluid"" src="); if (string.IsNullOrEmpty(vm.Title)) { vm.Title = SharedLocalizer["Content posted on"] + " " + vm.CreateDate.ToString(); } if (string.IsNullOrWhiteSpace(vm.Introduction)) { vm.Introduction = SharedLocalizer["Content posted on"] + " " + vm.CreateDate.ToShortDateString(); } ApplicationUser user = await UserManager.FindByIdAsync(CurrentUserId.ToString()); bool userIsAdmin = user != null && await UserManager.IsInRoleAsync(user, Roles.Administrator.ToString()); vm.Permissions.CanEdit = vm.UserId == CurrentUserId || userIsAdmin; vm.Permissions.CanDelete = vm.UserId == CurrentUserId || userIsAdmin; ViewData["IsDetails"] = true; return(View(vm)); }
public IActionResult Details(Guid id, int?pointsEarned) { OperationResultVo <JobPositionViewModel> op = jobPositionAppService.GetById(CurrentUserId, id); JobPositionViewModel vm = op.Value; SetLocalization(vm); SetAuthorDetails(vm); vm.Description = ContentFormatter.FormatContentToShow(vm.Description); SetGamificationMessage(pointsEarned); return(View("_Details", vm)); }
public virtual void SendMessageToAll <T>(string messageKey, T?messageArgs) where T : class { if (messageKey == null) { throw new ArgumentNullException(nameof(messageKey)); } IHubContext hubContext = _connectionManager.GetHubContext <MessagesHub>(); string objectArgsAsString = messageArgs == null ? string.Empty : ContentFormatter.Serialize(messageArgs); hubContext.Clients.All.OnMessageReceived(messageKey, objectArgsAsString); }
public async Task <IActionResult> Edit(Guid id) { CourseViewModel model; OperationResultVo serviceResult = await studyAppService.GetCourseById(CurrentUserId, id); OperationResultVo <CourseViewModel> castResult = serviceResult as OperationResultVo <CourseViewModel>; model = castResult.Value; model.Description = ContentFormatter.FormatCFormatTextAreaBreaks(model.Description); return(View("CourseCreateEditWrapper", model)); }
public ViewResult Edit(Guid id) { GiveawayViewModel model; OperationResultVo serviceResult = giveawayAppService.GetForEdit(CurrentUserId, id); OperationResultVo <GiveawayViewModel> castResult = serviceResult as OperationResultVo <GiveawayViewModel>; model = castResult.Value; model.Description = ContentFormatter.FormatCFormatTextAreaBreaks(model.Description); SetTimeZoneDropdown(model); return(View("CreateEditWrapper", model)); }
public virtual void SaveLog(LogEntry logEntry) { if (logEntry == null) { throw new ArgumentNullException(nameof(logEntry)); } EventLog appLog = new EventLog("Application") { Source = _activeAppEnvironment.AppInfo.Name }; EventLogEntryType eventLogsSeverity; if (logEntry.Severity == "Warning") { eventLogsSeverity = EventLogEntryType.Warning; } else if (logEntry.Severity == "Information") { eventLogsSeverity = EventLogEntryType.Information; } else { eventLogsSeverity = EventLogEntryType.Error; } string logContents = ContentFormatter.Serialize(logEntry); if (logContents.Length >= 30000) { logContents = logContents.Substring(0, 29999); } if (_activeAppEnvironment.TryGetConfig("EventLogId", out long eventLogId)) { appLog.WriteEntry(logContents, eventLogsSeverity, Convert.ToInt32(eventLogId)); } else { appLog.WriteEntry(logContents, eventLogsSeverity); } }
public virtual async Task <SSOPageModel> GetSSOPageModelAsync(CancellationToken cancellationToken) { return(new SSOPageModel { AppTitle = _activeAppEnvironment .Cultures .ExtendedSingle($"Finding cultures of {_activeAppEnvironment.AppInfo.DefaultCulture} in {_activeAppEnvironment.Name} environment", c => c.Name == _activeAppEnvironment.AppInfo.DefaultCulture) .Values .ExtendedSingle($"Finding AppTitle in {_activeAppEnvironment.AppInfo.DefaultCulture} cultures of {_activeAppEnvironment.Name} environment", v => v.Name == "AppTitle").Title, AppName = _activeAppEnvironment.AppInfo.Name, AppVersion = _activeAppEnvironment.AppInfo.Version, Culture = _activeAppEnvironment.AppInfo.DefaultCulture, DebugMode = _activeAppEnvironment.DebugMode, DesiredTimeZoneValue = _activeAppEnvironment.AppInfo.DefaultTimeZone, Theme = _activeAppEnvironment.AppInfo.DefaultTheme, EnvironmentConfigsJson = ContentFormatter.Serialize(_activeAppEnvironment .Configs.Where(c => c.AccessibleInClientSide == true) .Select(c => new { value = c.Value, key = c.Key })), BaseHref = _activeAppEnvironment.GetHostVirtualPath() }); }
protected virtual IObservable <T> _PostAsync <T>(string contract, string operation, WWWForm content, List <KeyValuePair <string, string[]> > contentList, IProgress <float> reportProgress) { var deferredOperation = Observable.Defer(() => { var headers = CopyHeaders(); if (contentList.Count == 0) { content.AddField("_", "_"); // add dummy } OnBeforeRequest(contract, operation, contentList, ref headers); var postObservable = (headers == null) ? ObservableWWW.PostWWW(rootEndPoint + "/" + contract + "/" + operation, content, reportProgress) : ObservableWWW.PostWWW(rootEndPoint + "/" + contract + "/" + operation, content, headers, reportProgress); var weboperation = postObservable .Select(x => { string header; if (x.responseHeaders.TryGetValue("Content-Encoding", out header) && header == "gzip") { using (var ms = new MemoryStream(x.bytes)) { var value = (T)ContentFormatter.Deserialize(typeof(T), ms); return(value); } } else { using (var ms = new MemoryStream(x.bytes)) { var value = (T)plainJsonContentFormatter.Deserialize(typeof(T), ms); return(value); } } }); return(weboperation); }); return(deferredOperation); }
public virtual void SendMessageToUsers <T>(string messageKey, T?messageArgs, string[] userIds) where T : class { if (userIds == null) { throw new ArgumentNullException(nameof(userIds)); } if (messageKey == null) { throw new ArgumentNullException(nameof(messageKey)); } IHubContext hubContext = _connectionManager.GetHubContext <MessagesHub>(); string objectArgsAsString = messageArgs == null ? string.Empty : ContentFormatter.Serialize(messageArgs); foreach (string u in userIds) { hubContext.Clients.Group(u).OnMessageReceived(messageKey, objectArgsAsString); } }
protected virtual IObservable <T> _PostAsync <T>(string contract, string operation, WWWForm content, IProgress <float> reportProgress) { var deferredOperation = Observable.Defer(() => { var postObservable = (defaultHeaders == null) ? ObservableWWW.PostAndGetBytes(rootEndPoint + "/" + contract + "/" + operation, content, reportProgress) : ObservableWWW.PostAndGetBytes(rootEndPoint + "/" + contract + "/" + operation, content, defaultHeaders, reportProgress); var weboperation = postObservable .Select(x => { using (var ms = new MemoryStream(x)) { var value = (T)ContentFormatter.Deserialize(typeof(T), ms); return(value); } }); return(weboperation); }); AddAdditionalFlow(contract, operation, ref deferredOperation); return(deferredOperation); }
private void FormatJobPositionPostForTheFeed(UserContentViewModel item) { JobPositionViewModel obj = JsonConvert.DeserializeObject <JobPositionViewModel>(item.Content); SupportedLanguage language = SupportedLanguage.English; if (obj.Remote) { obj.Location = SharedLocalizer["remote"]; } if (obj.Language != 0) { language = obj.Language; } string postTemplate = ContentFormatter.FormatUrlContentToShow(item.UserContentType); string translatedText = SharedLocalizer["A new job position for {0}({1}) is open for applications.", SharedLocalizer[obj.WorkType.ToDisplayName()], obj.Location].ToString(); item.Content = String.Format(postTemplate, translatedText, SharedLocalizer[obj.WorkType.ToDisplayName()], obj.Location); item.Url = Url.Action("Details", "JobPosition", new { area = "Work", id = obj.Id.ToString() }); item.Language = language; }
/// <summary> /// Fetches the resource at the given index from OneDrive, formats it into the /// requested type using the given ContentFormatter and returns it to the callback function. /// </summary> /// <typeparam name="T">Type of the resource to create with the fetched data.</typeparam> /// <param name="formatter">Function to use to convert the raw data into a resource of type T.</param> /// <param name="callback">Function to which the created resource should be sent.</param> protected override async Task GetResourceAt <T>(int resourceIndex, ContentFormatter <T> formatter, Action <T> callback) { // We fetch the children for the first time // here since we can't do it in the constructor. if (ResourceIds == null) { await FetchResourceIds(); } string resourceId = GetResourceIdAt(resourceIndex); if (string.IsNullOrWhiteSpace(resourceId)) { Debug.LogError("The requested resource has a null ID."); return; } byte[] resourceData = await oneDriveController.GetItemContentAsync(resourceId); // Decompress bytes on a background thread. ImageUtils.ImageInfo imageInfo = await ImageUtils.DecompressImageBytes(resourceData); if (imageInfo.DecompressedBytes == null) { Debug.LogError("Failed to fetch the requested resource from OneDrive."); return; } // EventQueueManager executes the given Action on the main thread. // This is required for resource formatting (i.e. Texture2D.LoadImage()). EventQueueManager.Instance?.Execute(() => { T resource = formatter(imageInfo); callback(resource); }); }
public async Task GetNextResource <T>(ContentFormatter <T> formatter, Action <T> callback, int offset = 1) { MoveForward(offset); await GetCurrentResource <T>(formatter, callback); }
private RssRoot GetRssCore(string category, int maxDayCount, int maxEntryCount) { if (RedirectToFeedBurnerIfNeeded(category) == true) { return(null); } EntryCollection entries = null; //We only build the entries if blogcore doesn't exist and we'll need them later... if (dataService.GetLastEntryUpdate() == DateTime.MinValue) { entries = BuildEntries(category, maxDayCount, maxEntryCount); } //Try to get out as soon as possible with as little CPU as possible if (inASMX) { DateTime lastModified = SiteUtilities.GetLatestModifedEntryDateTime(dataService, entries); if (SiteUtilities.GetStatusNotModified(lastModified)) { return(null); } } if (inASMX) { string referrer = Context.Request.UrlReferrer != null?Context.Request.UrlReferrer.AbsoluteUri:""; if (ReferralBlackList.IsBlockedReferrer(referrer)) { if (siteConfig.EnableReferralUrlBlackList404s) { return(null); } } else { loggingService.AddReferral( new LogDataItem( Context.Request.RawUrl, referrer, Context.Request.UserAgent, Context.Request.UserHostName)); } } //not-modified didn't work, do we have this in cache? string CacheKey = "Rss:" + category + ":" + maxDayCount.ToString() + ":" + maxEntryCount.ToString(); RssRoot documentRoot = cache[CacheKey] as RssRoot; if (documentRoot == null) //we'll have to build it... { //However, if we made it this far, the not-modified check didn't work, and we may not have entries... if (entries == null) { entries = BuildEntries(category, maxDayCount, maxEntryCount); } documentRoot = new RssRoot(); documentRoot.Namespaces.Add("dc", "http://purl.org/dc/elements/1.1/"); documentRoot.Namespaces.Add("trackback", "http://madskills.com/public/xml/rss/module/trackback/"); documentRoot.Namespaces.Add("pingback", "http://madskills.com/public/xml/rss/module/pingback/"); if (siteConfig.EnableComments) { documentRoot.Namespaces.Add("wfw", "http://wellformedweb.org/CommentAPI/"); documentRoot.Namespaces.Add("slash", "http://purl.org/rss/1.0/modules/slash/"); } if (siteConfig.EnableGeoRss) { documentRoot.Namespaces.Add("georss", "http://www.georss.org/georss"); } RssChannel ch = new RssChannel(); if (category == null) { ch.Title = siteConfig.Title; } else { ch.Title = siteConfig.Title + " - " + category; } if (siteConfig.Description == null || siteConfig.Description.Trim().Length == 0) { ch.Description = siteConfig.Subtitle; } else { ch.Description = siteConfig.Description; } ch.Link = SiteUtilities.GetBaseUrl(siteConfig); ch.Copyright = siteConfig.Copyright; if (siteConfig.RssLanguage != null && siteConfig.RssLanguage.Length > 0) { ch.Language = siteConfig.RssLanguage; } ch.ManagingEditor = siteConfig.Contact; ch.WebMaster = siteConfig.Contact; ch.Image = null; if (siteConfig.ChannelImageUrl != null && siteConfig.ChannelImageUrl.Trim().Length > 0) { ChannelImage channelImage = new ChannelImage(); channelImage.Title = ch.Title; channelImage.Link = ch.Link; if (siteConfig.ChannelImageUrl.StartsWith("http")) { channelImage.Url = siteConfig.ChannelImageUrl; } else { channelImage.Url = SiteUtilities.RelativeToRoot(siteConfig, siteConfig.ChannelImageUrl); } ch.Image = channelImage; } documentRoot.Channels.Add(ch); foreach (Entry entry in entries) { if (entry.IsPublic == false || entry.Syndicated == false) { continue; } XmlDocument doc2 = new XmlDocument(); List <XmlElement> anyElements = new List <XmlElement>(); RssItem item = new RssItem(); item.Title = entry.Title; item.Guid = new Rss20.Guid(); item.Guid.IsPermaLink = false; item.Guid.Text = SiteUtilities.GetPermaLinkUrl(siteConfig, entry.EntryId); item.Link = SiteUtilities.GetPermaLinkUrl(siteConfig, (ITitledEntry)entry); User user = SiteSecurity.GetUser(entry.Author); //Scott Hanselman: According to the RSS 2.0 spec and FeedValidator.org, // we can have EITHER an Author tag OR the preferred dc:creator tag, but NOT BOTH. // if (user != null && user.EmailAddress != null && user.EmailAddress.Length > 0) // { // if (user.DisplayName != null && user.DisplayName.Length > 0) // { // item.Author = String.Format("{0} ({1})", user.EmailAddress, user.DisplayName); // } // else // { // item.Author = user.EmailAddress; // } // } XmlElement trackbackPing = doc2.CreateElement("trackback", "ping", "http://madskills.com/public/xml/rss/module/trackback/"); trackbackPing.InnerText = SiteUtilities.GetTrackbackUrl(siteConfig, entry.EntryId); anyElements.Add(trackbackPing); XmlElement pingbackServer = doc2.CreateElement("pingback", "server", "http://madskills.com/public/xml/rss/module/pingback/"); pingbackServer.InnerText = new Uri(new Uri(SiteUtilities.GetBaseUrl(siteConfig)), "pingback.aspx").ToString(); anyElements.Add(pingbackServer); XmlElement pingbackTarget = doc2.CreateElement("pingback", "target", "http://madskills.com/public/xml/rss/module/pingback/"); pingbackTarget.InnerText = SiteUtilities.GetPermaLinkUrl(siteConfig, entry.EntryId); anyElements.Add(pingbackTarget); XmlElement dcCreator = doc2.CreateElement("dc", "creator", "http://purl.org/dc/elements/1.1/"); if (user != null) { // HACK AG No author e-mail address in feed items. // if (user.DisplayName != null && user.DisplayName.Length > 0) // { // if(user.EmailAddress != null && user.EmailAddress.Length > 0) // { // dcCreator.InnerText = String.Format("{0} ({1})", user.EmailAddress, user.DisplayName); // } // else // { dcCreator.InnerText = user.DisplayName; // } // } // else // { // dcCreator.InnerText = user.EmailAddress; // } } anyElements.Add(dcCreator); // Add GeoRSS if it exists. if (siteConfig.EnableGeoRss) { Nullable <double> latitude = new Nullable <double>(); Nullable <double> longitude = new Nullable <double>(); if (entry.Latitude.HasValue) { latitude = entry.Latitude; } else { if (siteConfig.EnableDefaultLatLongForNonGeoCodedPosts) { latitude = siteConfig.DefaultLatitude; } } if (entry.Longitude.HasValue) { longitude = entry.Longitude; } else { if (siteConfig.EnableDefaultLatLongForNonGeoCodedPosts) { longitude = siteConfig.DefaultLongitude; } } if (latitude.HasValue && longitude.HasValue) { XmlElement geoLoc = doc2.CreateElement("georss", "point", "http://www.georss.org/georss"); geoLoc.InnerText = String.Format(CultureInfo.InvariantCulture, "{0:R} {1:R}", latitude, longitude); anyElements.Add(geoLoc); } } if (siteConfig.EnableComments) { if (entry.AllowComments) { XmlElement commentApi = doc2.CreateElement("wfw", "comment", "http://wellformedweb.org/CommentAPI/"); commentApi.InnerText = SiteUtilities.GetCommentViewUrl(siteConfig, entry.EntryId); anyElements.Add(commentApi); } XmlElement commentRss = doc2.CreateElement("wfw", "commentRss", "http://wellformedweb.org/CommentAPI/"); commentRss.InnerText = SiteUtilities.GetEntryCommentsRssUrl(siteConfig, entry.EntryId); anyElements.Add(commentRss); //for RSS conformance per FeedValidator.org int commentsCount = dataService.GetPublicCommentsFor(entry.EntryId).Count; if (commentsCount > 0) { XmlElement slashComments = doc2.CreateElement("slash", "comments", "http://purl.org/rss/1.0/modules/slash/"); slashComments.InnerText = commentsCount.ToString(); anyElements.Add(slashComments); } item.Comments = SiteUtilities.GetCommentViewUrl(siteConfig, entry.EntryId); } item.Language = entry.Language; if (entry.Categories != null && entry.Categories.Length > 0) { if (item.Categories == null) { item.Categories = new RssCategoryCollection(); } string[] cats = entry.Categories.Split(';'); foreach (string c in cats) { RssCategory cat = new RssCategory(); string cleanCat = c.Replace('|', '/'); cat.Text = cleanCat; item.Categories.Add(cat); } } if (entry.Attachments.Count > 0) { // RSS currently supports only a single enclsoure so we return the first one item.Enclosure = new Enclosure(); item.Enclosure.Url = SiteUtilities.GetEnclosureLinkUrl(entry.EntryId, entry.Attachments[0]); item.Enclosure.Type = entry.Attachments[0].Type; item.Enclosure.Length = entry.Attachments[0].Length.ToString(); } item.PubDate = entry.CreatedUtc.ToString("R"); if (ch.LastBuildDate == null || ch.LastBuildDate.Length == 0) { ch.LastBuildDate = item.PubDate; } if (!siteConfig.AlwaysIncludeContentInRSS && entry.Description != null && entry.Description.Trim().Length > 0) { item.Description = PreprocessItemContent(entry.EntryId, entry.Description); } else { if (siteConfig.HtmlTidyContent == false) { item.Description = "<div>" + PreprocessItemContent(entry.EntryId, entry.Content) + "</div>"; } else { item.Description = ContentFormatter.FormatContentAsHTML(PreprocessItemContent(entry.EntryId, entry.Content)); try { string xhtml = ContentFormatter.FormatContentAsXHTML(PreprocessItemContent(entry.EntryId, entry.Content)); doc2.LoadXml(xhtml); anyElements.Add((XmlElement)doc2.SelectSingleNode("//*[local-name() = 'body'][namespace-uri()='http://www.w3.org/1999/xhtml']")); } catch //(Exception ex) { //Debug.Write(ex.ToString()); // absorb } } } item.anyElements = anyElements.ToArray(); ch.Items.Add(item); } cache.Insert(CacheKey, documentRoot, DateTime.Now.AddMinutes(5)); } return(documentRoot); }
private AtomRoot GetAtomCore(string category, int maxDayCount, int maxEntryCount) { if (RedirectToFeedBurnerIfNeeded(category) == true) { return(null); } EntryCollection entries = null; //We only build the entries if blogcore doesn't exist and we'll need them later... if (dataService.GetLastEntryUpdate() == DateTime.MinValue) { entries = BuildEntries(category, maxDayCount, maxEntryCount); } //Try to get out as soon as possible with as little CPU as possible if (inASMX) { if (SiteUtilities.GetStatusNotModified(SiteUtilities.GetLatestModifedEntryDateTime(dataService, entries))) { return(null); } } if (inASMX) { string referrer = Context.Request.UrlReferrer != null?Context.Request.UrlReferrer.AbsoluteUri:""; if (ReferralBlackList.IsBlockedReferrer(referrer)) { if (siteConfig.EnableReferralUrlBlackList404s) { return(null); } } else { loggingService.AddReferral( new LogDataItem( Context.Request.RawUrl, referrer, Context.Request.UserAgent, Context.Request.UserHostName)); } } //not-modified didn't work, do we have this in cache? string CacheKey = "Atom:" + category + ":" + maxDayCount.ToString() + ":" + maxEntryCount.ToString(); AtomRoot atomFeed = cache[CacheKey] as AtomRoot; if (atomFeed == null) //we'll have to build it... { atomFeed = new AtomRoot(); //However, if we made it this far, the not-modified check didn't work, and we may not have entries... if (entries == null) { entries = BuildEntries(category, maxDayCount, maxEntryCount); } if (siteConfig.RssLanguage != null && siteConfig.RssLanguage.Length > 0) { atomFeed.Lang = siteConfig.RssLanguage; } else //original default behavior of dasBlog { atomFeed.Lang = "en-us"; } if (category == null) { atomFeed.Title = siteConfig.Title; } else { atomFeed.Title = siteConfig.Title + " - " + category; } atomFeed.Tagline = siteConfig.Subtitle; atomFeed.Links.Add(new AtomLink(SiteUtilities.GetBaseUrl(siteConfig))); atomFeed.Links.Add(new AtomLink(SiteUtilities.GetAtomUrl(siteConfig), "self", null)); atomFeed.Author = new AtomParticipant(); // shouldn't we use the display name of an owner?? atomFeed.Author.Name = siteConfig.Copyright; atomFeed.Generator = new AtomGenerator(); atomFeed.Generator.Version = GetType().Assembly.GetName().Version.ToString(); atomFeed.Icon = "favicon.ico"; atomFeed.Id = SiteUtilities.GetBaseUrl(siteConfig); atomFeed.Logo = null; if (siteConfig.ChannelImageUrl != null && siteConfig.ChannelImageUrl.Trim().Length > 0) { if (siteConfig.ChannelImageUrl.StartsWith("http")) { atomFeed.Logo = siteConfig.ChannelImageUrl; } else { atomFeed.Logo = SiteUtilities.RelativeToRoot(siteConfig, siteConfig.ChannelImageUrl); } } DateTime feedModified = DateTime.MinValue; foreach (Entry entry in entries) { if (entry.IsPublic == false || entry.Syndicated == false) { continue; } string entryLink = SiteUtilities.GetPermaLinkUrl(siteConfig, (ITitledEntry)entry); string entryGuid = SiteUtilities.GetPermaLinkUrl(siteConfig, entry.EntryId); AtomEntry atomEntry = new AtomEntry(entry.Title, new AtomLink(entryLink), entryGuid, entry.CreatedUtc, entry.ModifiedUtc); //atomEntry.Created = entry.CreatedUtc; //not needed in 1.0 atomEntry.Summary = PreprocessItemContent(entry.EntryId, entry.Description); // for multiuser blogs we want to be able to // show the author per entry User user = SiteSecurity.GetUser(entry.Author); if (user != null) { // only the displayname atomEntry.Author = new AtomParticipant() { Name = user.DisplayName }; } if (entry.Categories != null && entry.Categories.Length > 0) { if (atomEntry.Categories == null) { atomEntry.Categories = new AtomCategoryCollection(); } string[] cats = entry.Categories.Split(';'); foreach (string c in cats) { AtomCategory cat = new AtomCategory(); //paulb: scheme should be a valid IRI, acsording to the spec // (http://www.atomenabled.org/developers/syndication/atom-format-spec.php#element.category) // so I changed this to the Category view for specified category. Now the feed validator likes us again ;-) cat.Scheme = SiteUtilities.GetCategoryViewUrl(siteConfig, c); // "hierarchical"; // sub categories should be delimited using the path delimiter string cleanCat = c.Replace('|', '/'); //Grab the first category, atom doesn't let us do otherwise! cat.Term = HttpUtility.HtmlEncode(cleanCat); cat.Label = HttpUtility.HtmlEncode(cleanCat); atomEntry.Categories.Add(cat); } } // only if we don't have a summary we emit the content if (siteConfig.AlwaysIncludeContentInRSS || entry.Description == null || entry.Description.Length == 0) { atomEntry.Summary = null; // remove empty summary tag try { AtomContent atomContent = new AtomContent(); atomContent.Type = "xhtml"; XmlDocument xmlDoc2 = new XmlDocument(); xmlDoc2.LoadXml(ContentFormatter.FormatContentAsXHTML(PreprocessItemContent(entry.EntryId, entry.Content), "div")); atomContent.anyElements = new XmlElement[] { xmlDoc2.DocumentElement }; // set the langauge for the content item atomContent.Lang = entry.Language; atomEntry.Content = atomContent; } catch (Exception) //XHTML isn't happening today { //Try again as HTML AtomContent atomContent = new AtomContent(); atomContent.Type = "html"; atomContent.TextContent = ContentFormatter.FormatContentAsHTML(PreprocessItemContent(entry.EntryId, entry.Content)); // set the langauge for the content item atomContent.Lang = entry.Language; atomEntry.Content = atomContent; } } if (atomEntry.ModifiedUtc > feedModified) { feedModified = atomEntry.ModifiedUtc; } atomFeed.Entries.Add(atomEntry); } // set feed modified date to the most recent entry date atomFeed.ModifiedUtc = feedModified; cache.Insert(CacheKey, atomFeed, DateTime.Now.AddMinutes(5)); } return(atomFeed); }
private RssRoot GetRssCore(string category, int maxDayCount, int maxEntryCount) { EntryCollection entries = null; //We only build the entries if blogcore doesn't exist and we'll need them later... if (_dataService.GetLastEntryUpdate() == DateTime.MinValue) { entries = BuildEntries(category, maxDayCount, maxEntryCount); } // TODO: Detecting modified data? //DateTime lastModified = this.GetLatestModifedEntryDateTime(entries); //if (SiteUtilities.GetStatusNotModified(lastModified)) // return null; RssRoot documentRoot = new RssRoot();; //However, if we made it this far, the not-modified check didn't work, and we may not have entries... if (entries == null) { entries = BuildEntries(category, maxDayCount, maxEntryCount); } documentRoot.Namespaces.Add("dc", "http://purl.org/dc/elements/1.1/"); documentRoot.Namespaces.Add("trackback", "http://madskills.com/public/xml/rss/module/trackback/"); documentRoot.Namespaces.Add("pingback", "http://madskills.com/public/xml/rss/module/pingback/"); if (_dasBlogSettings.SiteConfiguration.EnableComments) { documentRoot.Namespaces.Add("wfw", "http://wellformedweb.org/CommentAPI/"); documentRoot.Namespaces.Add("slash", "http://purl.org/rss/1.0/modules/slash/"); } if (_dasBlogSettings.SiteConfiguration.EnableGeoRss) { documentRoot.Namespaces.Add("georss", "http://www.georss.org/georss"); } RssChannel ch = new RssChannel(); if (category == null) { ch.Title = _dasBlogSettings.SiteConfiguration.Title; } else { ch.Title = _dasBlogSettings.SiteConfiguration.Title + " - " + category; } if (_dasBlogSettings.SiteConfiguration.Description == null || _dasBlogSettings.SiteConfiguration.Description.Trim().Length == 0) { ch.Description = _dasBlogSettings.SiteConfiguration.Subtitle; } else { ch.Description = _dasBlogSettings.SiteConfiguration.Description; } ch.Link = _dasBlogSettings.GetBaseUrl(); ch.Copyright = _dasBlogSettings.SiteConfiguration.Copyright; if (_dasBlogSettings.SiteConfiguration.RssLanguage != null && _dasBlogSettings.SiteConfiguration.RssLanguage.Length > 0) { ch.Language = _dasBlogSettings.SiteConfiguration.RssLanguage; } ch.ManagingEditor = _dasBlogSettings.SiteConfiguration.Contact; ch.WebMaster = _dasBlogSettings.SiteConfiguration.Contact; ch.Image = null; if (_dasBlogSettings.SiteConfiguration.ChannelImageUrl != null && _dasBlogSettings.SiteConfiguration.ChannelImageUrl.Trim().Length > 0) { newtelligence.DasBlog.Web.Services.Rss20.ChannelImage channelImage = new newtelligence.DasBlog.Web.Services.Rss20.ChannelImage(); channelImage.Title = ch.Title; channelImage.Link = ch.Link; if (_dasBlogSettings.SiteConfiguration.ChannelImageUrl.StartsWith("http")) { channelImage.Url = _dasBlogSettings.SiteConfiguration.ChannelImageUrl; } else { channelImage.Url = _dasBlogSettings.RelativeToRoot(_dasBlogSettings.SiteConfiguration.ChannelImageUrl); } ch.Image = channelImage; } documentRoot.Channels.Add(ch); foreach (Entry entry in entries) { if (entry.IsPublic == false || entry.Syndicated == false) { continue; } XmlDocument doc2 = new XmlDocument(); List <XmlElement> anyElements = new List <XmlElement>(); RssItem item = new RssItem(); item.Title = entry.Title; item.Guid = new newtelligence.DasBlog.Web.Services.Rss20.Guid(); item.Guid.IsPermaLink = false; item.Guid.Text = _dasBlogSettings.GetPermaLinkUrl(entry.EntryId); item.Link = _dasBlogSettings.GetPermaLinkUrl(entry.EntryId); User user = _dasBlogSettings.GetUser(entry.Author); XmlElement trackbackPing = doc2.CreateElement("trackback", "ping", "http://madskills.com/public/xml/rss/module/trackback/"); trackbackPing.InnerText = _dasBlogSettings.GetTrackbackUrl(entry.EntryId); anyElements.Add(trackbackPing); XmlElement pingbackServer = doc2.CreateElement("pingback", "server", "http://madskills.com/public/xml/rss/module/pingback/"); pingbackServer.InnerText = _dasBlogSettings.RelativeToRoot("pingback"); anyElements.Add(pingbackServer); XmlElement pingbackTarget = doc2.CreateElement("pingback", "target", "http://madskills.com/public/xml/rss/module/pingback/"); pingbackTarget.InnerText = _dasBlogSettings.GetPermaLinkUrl(entry.EntryId); anyElements.Add(pingbackTarget); XmlElement dcCreator = doc2.CreateElement("dc", "creator", "http://purl.org/dc/elements/1.1/"); if (user != null) { dcCreator.InnerText = user.DisplayName; } anyElements.Add(dcCreator); // Add GeoRSS if it exists. if (_dasBlogSettings.SiteConfiguration.EnableGeoRss) { Nullable <double> latitude = new Nullable <double>(); Nullable <double> longitude = new Nullable <double>(); if (entry.Latitude.HasValue) { latitude = entry.Latitude; } else { if (_dasBlogSettings.SiteConfiguration.EnableDefaultLatLongForNonGeoCodedPosts) { latitude = _dasBlogSettings.SiteConfiguration.DefaultLatitude; } } if (entry.Longitude.HasValue) { longitude = entry.Longitude; } else { if (_dasBlogSettings.SiteConfiguration.EnableDefaultLatLongForNonGeoCodedPosts) { longitude = _dasBlogSettings.SiteConfiguration.DefaultLongitude; } } if (latitude.HasValue && longitude.HasValue) { XmlElement geoLoc = doc2.CreateElement("georss", "point", "http://www.georss.org/georss"); geoLoc.InnerText = String.Format(CultureInfo.InvariantCulture, "{0:R} {1:R}", latitude, longitude); anyElements.Add(geoLoc); } } if (_dasBlogSettings.SiteConfiguration.EnableComments) { if (entry.AllowComments) { XmlElement commentApi = doc2.CreateElement("wfw", "comment", "http://wellformedweb.org/CommentAPI/"); commentApi.InnerText = _dasBlogSettings.GetCommentViewUrl(entry.EntryId); anyElements.Add(commentApi); } XmlElement commentRss = doc2.CreateElement("wfw", "commentRss", "http://wellformedweb.org/CommentAPI/"); commentRss.InnerText = _dasBlogSettings.GetEntryCommentsRssUrl(entry.EntryId); anyElements.Add(commentRss); //for RSS conformance per FeedValidator.org int commentsCount = _dataService.GetPublicCommentsFor(entry.EntryId).Count; if (commentsCount > 0) { XmlElement slashComments = doc2.CreateElement("slash", "comments", "http://purl.org/rss/1.0/modules/slash/"); slashComments.InnerText = commentsCount.ToString(); anyElements.Add(slashComments); } item.Comments = _dasBlogSettings.GetCommentViewUrl(entry.EntryId); } item.Language = entry.Language; if (entry.Categories != null && entry.Categories.Length > 0) { if (item.Categories == null) { item.Categories = new RssCategoryCollection(); } string[] cats = entry.Categories.Split(';'); foreach (string c in cats) { RssCategory cat = new RssCategory(); string cleanCat = c.Replace('|', '/'); cat.Text = cleanCat; item.Categories.Add(cat); } } if (entry.Attachments.Count > 0) { // RSS currently supports only a single enclsoure so we return the first one item.Enclosure = new Enclosure(); item.Enclosure.Url = entry.Attachments[0].Name; item.Enclosure.Type = entry.Attachments[0].Type; item.Enclosure.Length = entry.Attachments[0].Length.ToString(); } item.PubDate = entry.CreatedUtc.ToString("R"); if (ch.LastBuildDate == null || ch.LastBuildDate.Length == 0) { ch.LastBuildDate = item.PubDate; } if (!_dasBlogSettings.SiteConfiguration.AlwaysIncludeContentInRSS && entry.Description != null && entry.Description.Trim().Length > 0) { item.Description = PreprocessItemContent(entry.EntryId, entry.Description); } else { if (_dasBlogSettings.SiteConfiguration.HtmlTidyContent == false) { item.Description = "<div>" + PreprocessItemContent(entry.EntryId, entry.Content) + "</div>"; } else { item.Description = ContentFormatter.FormatContentAsHTML(PreprocessItemContent(entry.EntryId, entry.Content)); try { string xhtml = ContentFormatter.FormatContentAsXHTML(PreprocessItemContent(entry.EntryId, entry.Content)); doc2.LoadXml(xhtml); anyElements.Add((XmlElement)doc2.SelectSingleNode("//*[local-name() = 'body'][namespace-uri()='http://www.w3.org/1999/xhtml']")); } catch //(Exception ex) { //Debug.Write(ex.ToString()); // absorb } } } item.anyElements = anyElements.ToArray(); ch.Items.Add(item); } return(documentRoot); }
private IARoot GetInstantArticleCount(int maxDays, int maxEntries) { EntryCollection entries = null; //We only build the entries if blogcore doesn't exist and we'll need them later... if (dataService.GetLastEntryUpdate() == DateTime.MinValue) { entries = BuildEntries(null, maxDays, maxEntries); } //Try to get out as soon as possible with as little CPU as possible if (inASMX) { DateTime lastModified = SiteUtilities.GetLatestModifedEntryDateTime(dataService, entries); if (SiteUtilities.GetStatusNotModified(lastModified)) { return(null); } } if (inASMX) { string referrer = Context.Request.UrlReferrer != null ? Context.Request.UrlReferrer.AbsoluteUri : ""; if (ReferralBlackList.IsBlockedReferrer(referrer)) { if (siteConfig.EnableReferralUrlBlackList404s) { return(null); } } else { loggingService.AddReferral( new LogDataItem( Context.Request.RawUrl, referrer, Context.Request.UserAgent, Context.Request.UserHostName)); } } //not-modified didn't work, do we have this in cache? string CacheKey = string.Format("InstantArticle:{0}:{1}", maxDays, maxEntries); IARoot documentRoot = cache[CacheKey] as IARoot; if (documentRoot == null) //we'll have to build it... { //However, if we made it this far, the not-modified check didn't work, and we may not have entries... if (entries == null) { entries = BuildEntries(null, maxDays, maxEntries); } documentRoot = new IARoot(); documentRoot.Namespaces.Add("content", "http://purl.org/rss/1.0/modules/content/"); IAChannel ch = new IAChannel(); ch.Title = siteConfig.Title; ch.Link = SiteUtilities.GetBaseUrl(siteConfig); if (siteConfig.Description == null || siteConfig.Description.Trim().Length == 0) { ch.Description = siteConfig.Subtitle; } else { ch.Description = siteConfig.Description; } ch.PubDate = DateTime.UtcNow.ToString(); ch.LastBuildDate = DateTime.UtcNow.ToString(); if (siteConfig.RssLanguage != null && siteConfig.RssLanguage.Length > 0) { ch.Language = siteConfig.RssLanguage; } //generator ch.Docs = string.Empty; documentRoot.Channels.Add(ch); foreach (Entry entry in entries) { if (entry.IsPublic == false || entry.Syndicated == false) { continue; } IAItem item = new IAItem(); List <XmlElement> anyElements = new List <XmlElement>(); XmlDocument xmlDoc = new XmlDocument(); item.Title = entry.Title; item.PubDate = entry.CreatedUtc.ToString("R"); if (ch.LastBuildDate == null || ch.LastBuildDate.Length == 0) { ch.LastBuildDate = item.PubDate; } item.Link = SiteUtilities.GetPermaLinkUrl(siteConfig, (ITitledEntry)entry); item.Guid = entry.EntryId; if (!siteConfig.AlwaysIncludeContentInRSS && entry.Description != null && entry.Description.Trim().Length > 0) { item.Description = PreprocessItemContent(entry.EntryId, entry.Description); } else { item.Description = ContentFormatter.FormatContentAsHTML(PreprocessItemContent(entry.EntryId, entry.Content)); } XmlElement contentEncoded = xmlDoc.CreateElement("content", "encoded", "http://purl.org/rss/1.0/modules/content/"); string encData = string.Format("<!doctype html>" + "<html lang=\"en\" prefix=\"op: http://media.facebook.com/op#\">" + "<head>" + "<meta charset=\"utf-8\">" + "<link rel=\"canonical\" href=\"{3}\">" + "<meta property=\"op:markup_version\" content=\"v1.0\">" + "</head>" + "<body><article>" + "<header>{0}</header>" + "{1}" + "<footer>{2}</footer>" + "</article></body></html>", entry.Title, ContentFormatter.FormatContentAsHTML(PreprocessItemContent(entry.EntryId, entry.Content)), string.Empty, item.Link); XmlCDataSection cdata = xmlDoc.CreateCDataSection(encData); contentEncoded.AppendChild(cdata); anyElements.Add(contentEncoded); item.anyElements = anyElements.ToArray(); ch.Items.Add(item); } cache.Insert(CacheKey, documentRoot, DateTime.Now.AddMinutes(5)); } return(documentRoot); }
public async Task <IViewComponentResult> InvokeAsync(int count, Guid?gameId, Guid?userId, Guid?oldestId, DateTime?oldestDate, bool?articlesOnly) { UserPreferencesViewModel preferences = _userPreferencesAppService.GetByUserId(CurrentUserId); ActivityFeedRequestViewModel vm = new ActivityFeedRequestViewModel { CurrentUserId = CurrentUserId, Count = count, GameId = gameId, UserId = userId, Languages = preferences.Languages, OldestId = oldestId, OldestDate = oldestDate, ArticlesOnly = articlesOnly }; List <UserContentViewModel> model = _userContentAppService.GetActivityFeed(vm).ToList(); bool userIsAdmin = User.Identity.IsAuthenticated && User.IsInRole(Roles.Administrator.ToString()); foreach (UserContentViewModel item in model) { if (item.UserContentType == UserContentType.TeamCreation) { FormatTeamCreationPost(item); } if (item.UserContentType == UserContentType.JobPosition) { FormatJobPositionPostForTheFeed(item); } else { item.Content = ContentFormatter.FormatContentToShow(item.Content); if (item.FeaturedMediaType == MediaType.Youtube) { item.FeaturedImageResponsive = ContentFormatter.GetYoutubeVideoId(item.FeaturedImage); item.FeaturedImageLquip = ContentHelper.SetFeaturedImage(Guid.Empty, Constants.DefaultFeaturedImageLquip, ImageRenderType.LowQuality); } } foreach (CommentViewModel comment in item.Comments) { comment.Text = ContentFormatter.FormatHashTagsToShow(comment.Text); } item.Permissions.CanEdit = !item.HasPoll && (item.UserId == CurrentUserId || userIsAdmin); item.Permissions.CanDelete = item.UserId == CurrentUserId || userIsAdmin; } if (model.Any()) { UserContentViewModel oldest = model.OrderByDescending(x => x.CreateDate).Last(); ViewData["OldestPostGuid"] = oldest.Id; ViewData["OldestPostDate"] = oldest.CreateDate.ToString("yyyy-MM-ddTHH:mm:ss.fffffff"); } ViewData["IsMorePosts"] = oldestId.HasValue; ViewData["UserId"] = userId; return(await Task.Run(() => View(model))); }
List <AppInsightsLogKeyVal> PopulateLogKeyValues(LogEntry logEntry) { List <AppInsightsLogKeyVal?> keyValues = logEntry.LogData.Select(ld => { string k = ld.Key; if (k == nameof(IRequestInformationProvider.HttpMethod) || k == nameof(IRequestInformationProvider.DisplayUrl) || k == "ResponseStatusCode" || k == nameof(IRequestInformationProvider.ClientIp) || ld.Value == null) { return(null); // Already being logged by app insights! } string?v = null; if (ld.Value is string valueAsStr) { v = valueAsStr; } if (k == "ClientLogs" || k == "OperationArgs") { v = ContentFormatter.Serialize(ld.Value); } else { v = ld.Value.ToString(); } return(new AppInsightsLogKeyVal { Key = k, Value = v }); }) .Where(d => d != null) .ToList(); keyValues.Add(new AppInsightsLogKeyVal { Key = nameof(LogEntry.MemoryUsage), Value = logEntry.MemoryUsage.ToString(CultureInfo.InvariantCulture) }); if (logEntry.AppServerDateTime != null) { keyValues.Add(new AppInsightsLogKeyVal { Key = nameof(LogEntry.AppServerDateTime), Value = logEntry.AppServerDateTime.ToString() }); } keyValues.Add(new AppInsightsLogKeyVal { Key = nameof(LogEntry.Severity), Value = logEntry.Severity }); keyValues.Add(new AppInsightsLogKeyVal { Key = nameof(LogEntry.Message), Value = logEntry.Message }); if (logEntry.Id != null) { keyValues.Add(new AppInsightsLogKeyVal { Key = nameof(LogEntry.Id), Value = logEntry.Id.ToString() }); } if (logEntry.AppServerThreadId != null) { keyValues.Add(new AppInsightsLogKeyVal { Key = nameof(LogEntry.AppServerThreadId), Value = logEntry.AppServerThreadId.ToString() }); } return(keyValues !); }
public async Task GetCurrentResource <T>(ContentFormatter <T> formatter, Action <T> callback) { await contentProvider.GetResourceAt <T>(currentResourceIndex, formatter, callback); }
public async Task GetPreviousResource <T>(ContentFormatter <T> formatter, Action <T> callback, int offset = 1) { MoveBack(offset); await GetCurrentResource <T>(formatter, callback); }