예제 #1
0
        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;
        }