public XDoc Calendar( [DekiExtParam("Google calendar feed uri ")] XUri uri, [DekiExtParam("starting date (default: today)", true)] string startDate, [DekiExtParam("ending date (default: 7 days from today)", true)] string endDate, [DekiExtParam("calendar width (default: 800)", true)] float? width, [DekiExtParam("calendar height (default: 800)", true)] float? height ) { XDoc result = new XDoc("html"); // try reading supplied dates DateTime start; DateTime end; if(!DateTime.TryParse(startDate, out start)) { start = DateTime.UtcNow; } if(!DateTime.TryParse(endDate, out end)) { end = DateTime.UtcNow.AddDays(7); } Plug calPlug = Plug.New(uri).With("start-min", start.ToString("s")).With("start-max", end.ToString("s")); DreamMessage response = calPlug.GetAsync().Wait(); if(response.IsSuccessful) { XDoc doc = response.ToDocument(); if(doc.HasName("feed")) { XAtomFeed calFeed = new XAtomFeed(doc); calFeed.UsePrefix("atom", "http://www.w3.org/2005/Atom"); XUri embedUri = calFeed["atom:link[@rel='alternate']/@href"].AsUri; result = NewIFrame(embedUri, width ?? 800, height ?? 800); } else { // BUGBUGBUG (steveb): user provided an embeddable representation; we won't be able to use the start and end date parameters then. result = NewIFrame(uri, width ?? 800, height ?? 800); } } return result; }
private XAtomFeed ConvertSearchResultsToOpenSearchAtom(XDoc luceneResults, string query, uint limit, uint offset, string format) { string luceneNamespace = "dekilucene"; int totalResults = 100000; bool firstPage = offset < limit; bool lastPage = luceneResults["document"].ToList().Count == 0 ? true : false; XUri searchUri = DekiContext.Current.ApiUri.At("site", "opensearch").With("q", query).With("format", format); XUri self = searchUri.With("offset", Convert.ToString(offset)).With("limit", Convert.ToString(limit)); XAtomFeed feed = new XAtomFeed("MindTouch Search", self, DateTime.Now); feed.UsePrefix("opensearch", "http://a9.com/-/spec/opensearch/1.1/"); feed.UsePrefix(luceneNamespace, "http://services.mindtouch.com/deki/draft/2007/06/luceneindex"); feed.UsePrefix("relevance", "http://a9.com/-/opensearch/extensions/relevance/1.0/"); feed.AddAuthor("MindTouch Core", null, string.Empty); feed.Id = self; feed.Elem("dekilucene:parsedQuery", luceneResults["parsedQuery"].AsText); // HACKHACKHACK show a fake <totalResults> until we run out if(!lastPage) { feed.Elem("opensearch:totalResults", totalResults); } if(offset >= limit) feed.Elem("opensearch:startIndex", offset); feed.Elem("opensearch:itemsPerPage", limit); feed.Start("opensearch:Query") .Attr("role", "request") .Attr("searchTerms", XUri.Encode(query)) .Attr("startPage", "1") .End(); feed.Start("link") .Attr("rel", "alternate") .Attr("type", MimeType.HTML.ToString()) .Attr("href", DekiContext.Current.UiUri.At("Special:Search").With("search", query).With("search", query).With("format", "html").With("limit", limit).With("offset", offset)) .End(); feed.Start("link") .Attr("rel", "search") .Attr("type", "application/opensearchdescription+xml") .Attr("href", DekiContext.Current.ApiUri.At("site", "opensearch", "description")) .End(); feed.Start("link") .Attr("rel", "first") .Attr("href", searchUri.With("offset", Convert.ToString(0)).With("limit", Convert.ToString(limit))) .Attr("type", MimeType.ATOM.ToString()) .End(); if(!firstPage) { feed.Start("link") .Attr("rel", "previous") .Attr("href", searchUri.With("offset", Convert.ToString(offset - limit)).With("limit", Convert.ToString(limit))) .Attr("type", MimeType.ATOM.ToString()) .End(); } if(!lastPage) { feed.Start("link") .Attr("rel", "next") .Attr("href", searchUri.With("offset", Convert.ToString(offset + limit)).With("limit", Convert.ToString(limit))) .Attr("type", MimeType.ATOM.ToString()) .End(); } if(!lastPage) { feed.Start("link") .Attr("rel", "last") .Attr("href", searchUri.With("offset", Convert.ToString(totalResults - limit)).With("limit", Convert.ToString(limit))) .Attr("type", MimeType.ATOM.ToString()) .End(); } var homepageId = DekiContext.Current.Instance.HomePageId; foreach(XDoc document in luceneResults["document"]) { var currentNode = feed.AsXmlNode; try { bool isPageChild = false; DateTime edited = DbUtils.ToDateTime(document["date.edited"].AsText); XAtomEntry entry = feed.StartEntry(document["title"].AsText, edited, edited); entry.Start("link") .Attr("href", document["uri"].AsUri) .End(); entry.Id = document["uri"].AsUri; entry.AddContent(StringUtil.EncodeHtmlEntities(document["preview"].AsText, Encoding.ASCII, false)); entry.Elem("relevance:score", document["score"].AsText); entry.Elem("dekilucene:size", document["size"].AsText); entry.Elem("dekilucene:wordcount", document["wordcount"].AsText); entry.Elem("dekilucene:path", document["path"].AsText); if(!document["id.file"].IsEmpty) { entry.Elem("dekilucene:id.file", document["id.file"].AsText); isPageChild = true; } else if(!document["id.comment"].IsEmpty) { entry.Elem("dekilucene:id.comment", document["id.comment"].AsText); isPageChild = true; } var pageId = document["id.page"].AsUInt ?? 0; if(!isPageChild) { entry.Elem("dekilucene:id.page", pageId); } if(pageId != homepageId) { uint parentPageId; string parentPath; string parentTitle; if(isPageChild) { parentPageId = pageId; parentPath = document["path"].AsText; parentTitle = document["title.page"].AsText; } else { parentPageId = document["id.parent"].AsUInt ?? 0; parentPath = document["path.parent"].AsText; parentTitle = document["title.parent"].AsText; } if(parentPath != null && parentTitle != null) { var title = Title.FromPrefixedDbPath(parentPath, parentTitle); entry.Start("dekilucene:page.parent") .Attr("id", parentPageId) .Attr("path", title.AsPrefixedDbPath()) .Attr("title", title.AsUserFriendlyName()) .Attr("href", DekiContext.Current.ApiUri.At("pages", parentPageId.ToString())) .End(); } } } catch(Exception e) { _log.Warn("found invalid data in search result. Likely a sign of a corrupted index. Skipping record", e); } finally { feed.End(currentNode); } } return feed; }