public override DekiScriptLiteral ResolveMissingName(string name)
        {
            var result = base.ResolveMissingName(name);

            if (result != null)
            {
                return(result);
            }

            // check if name refers to a template name
            Title title = Title.FromUriPath(name);

            // If the page title is prefixed with :, do not assume the template namespace
            if (title.Path.StartsWith(":"))
            {
                title.Path = title.Path.Substring(1);
            }
            else if (title.IsMain)
            {
                title.Namespace = NS.TEMPLATE;
            }
            PageBE page = PageBL.GetPageByTitle(title);

            if ((page == null) || (page.ID == 0))
            {
                return(null);
            }
            return(DekiScriptExpression.Constant(DekiContext.Current.Deki.Self.At("template"), new DekiScriptList().Add(DekiScriptExpression.Constant(title.AsPrefixedDbPath()))));
        }
Example #2
0
        public Yield GetNavigationSiblings(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            CheckResponseCache(context, false);

            PageBE page = PageBL_GetPageFromUrl(context, false);

            if (page.Title.IsTalk)
            {
                page = PageBL.GetPageByTitle(page.Title.AsFront());
            }

            // build response
            IList <NavBE> list = NavBL.QueryNavSiblingsData(page, context.Culture);

            if (ShowDebug(context))
            {
                response.Return(DreamMessage.Ok(NavBL.ConvertNavPageListToDoc(list)));
            }
            else
            {
                XDoc doc = NavBL.ComputeNavigationDocument(list, page, (uint)page.ID, 0, true, context.GetParam("width", int.MaxValue));
                if (ShowXml(context))
                {
                    response.Return(DreamMessage.Ok(doc));
                }
                else
                {
                    XDoc result = new XDoc("tree");
                    result.Start("siblings");

                    // add name of sibling nodes
                    System.Text.StringBuilder nodes = new System.Text.StringBuilder();
                    ulong homepageId = DekiContext.Current.Instance.HomePageId;
                    foreach (NavBE sibling in list)
                    {
                        if ((sibling.ParentId == page.ParentID) && (sibling.Id != homepageId))
                        {
                            if (nodes.Length != 0)
                            {
                                nodes.Append(",");
                            }
                            nodes.AppendFormat("n{0}", sibling.Id);
                        }
                    }
                    result.Elem("nodes", nodes.ToString());

                    // add sibling nodes
                    result.Start("html");
                    result.Elem("pre", doc["siblings-pre"].Contents);
                    result.Elem("post", doc["siblings-post"].Contents);
                    result.End();
                    result.End();
                    response.Return(DreamMessage.Ok(result));
                }
            }
            yield break;
        }
Example #3
0
        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);
        }
Example #4
0
        private static UserBE RenameUser(UserBE user, string newUserName, string newFullName)
        {
            //Renaming requires admin rights.
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);

            if (!ServiceBL.IsLocalAuthService(user.ServiceId))
            {
                //TODO MaxM: allow renaming of external users
                throw new ExternalUserRenameNotImplementedExceptionException();
            }

            //Check for already existing user with same name
            UserBE existingUser = DbUtils.CurrentSession.Users_GetByName(newUserName);

            if (existingUser != null)
            {
                throw new UserWithIdExistsConflictException(existingUser.Name, existingUser.ID);
            }

            PageBE existingTargetUserHomePage = PageBL.GetPageByTitle(Title.FromUIUsername(newUserName));

            if (existingTargetUserHomePage != null && existingTargetUserHomePage.ID != 0 && !existingTargetUserHomePage.IsRedirect)
            {
                throw new UserHomepageRenameConflictException();
            }

            //Try to move the homepage.
            PageBE userHomePage = GetHomePage(user);

            if (userHomePage != null && userHomePage.ID != 0)
            {
                Title newTitle = Title.FromUIUsername(newUserName);

                // new user homepage displayname is the user's full name or rebuilt from the username
                newTitle.DisplayName = !string.IsNullOrEmpty(newFullName) ? newFullName : newTitle.AsUserFriendlyDisplayName();
                PageBL.MovePage(userHomePage, newTitle, true);
            }

            //Rename the user
            user.Name = newUserName;
            UserBL.UpdateUser(user);
            return(user);
        }
Example #5
0
 private void PageChanged(DateTime eventTime, PageBE page, UserBE user, XDoc extra, params string[] path)
 {
     try {
         XUri     channel  = _channel.At(PAGES).At(path);
         XUri     resource = PageBL.GetUriCanonical(page).WithHost(_wikiid);
         string[] origin   = new string[] { PageBL.GetUriCanonical(page).AsServerUri().ToString(), XUri.Localhost + "/" + page.Title.AsUiUriPath() };
         XDoc     doc      = new XDoc("deki-event")
                             .Elem("channel", channel)
                             // BUGBUGBUG: This will generally generate a Uri based on the request that caused the event,
                             //            which may not really be canonical
                             .Elem("uri", PageBL.GetUriCanonical(page).AsPublicUri().ToString())
                             .Elem("pageid", page.ID)
                             .Start("user")
                             .Attr("id", user.ID)
                             .Attr("anonymous", UserBL.IsAnonymous(user))
                             .Elem("uri", UserBL.GetUri(user))
                             .End()
                             .Start("content.uri")
                             .Attr("type", "application/xml")
                             .Value(PageBL.GetUriContentsCanonical(page).With("format", "xhtml").AsServerUri().ToString())
                             .End()
                             .Elem("revision.uri", PageBL.GetUriRevisionCanonical(page).AsServerUri().ToString())
                             .Elem("tags.uri", PageBL.GetUriCanonical(page).At("tags").AsServerUri().ToString())
                             .Elem("comments.uri", PageBL.GetUriCanonical(page).At("comments").AsServerUri().ToString())
                             .Elem("path", page.Title.AsUiUriPath());
         if (extra != null)
         {
             doc.Add(extra);
         }
         Queue(eventTime, channel, resource, origin, doc);
         if (page.Title.IsTalk)
         {
             PageBE front = PageBL.GetPageByTitle(page.Title.AsFront());
             if ((front != null) && (front.ID > 0))
             {
                 PageChanged(eventTime, front, user, extra, ArrayUtil.Concat(new string[] { DEPENDENTS_CHANGED, TALK }, path));
             }
         }
     } catch (Exception e) {
         _log.WarnExceptionMethodCall(e, "PageChanged", "event couldn't be created");
     }
 }
Example #6
0
        public Yield GetNavigationFull(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            CheckResponseCache(context, false);

            PageBE page = PageBL_GetPageFromUrl(context, false);

            if (page.Title.IsTalk)
            {
                page = PageBL.GetPageByTitle(page.Title.AsFront());
            }

            // check if requestest page exists, otherwise find nearest parent
            uint         new_page_id = NavBL.NEW_PAGE_ID;
            ulong        homepageId  = DekiContext.Current.Instance.HomePageId;
            List <NavBE> list;
            bool         expandableNav = context.GetParam("type", "compact").EqualsInvariantIgnoreCase("expandable");

            // check if a page was found
            if (page.ID == 0)
            {
                // find nearest ancestor and authorize access
                PageBE ancestor = page;
                while (!ancestor.Title.IsHomepage)
                {
                    // fetch ancestor page based on title
                    ulong id = DbUtils.CurrentSession.Nav_GetNearestParent(ancestor.Title);
                    ancestor = PageBL.GetPageById(id);
                    if (PermissionsBL.IsUserAllowed(DekiContext.Current.User, ancestor, Permissions.BROWSE))
                    {
                        break;
                    }

                    // determine parent page title
                    Title title = ancestor.Title.GetParent();
                    if (title == null)
                    {
                        // current ancestor was the homepage
                        break;
                    }
                    ancestor = new PageBE {
                        Title = title
                    };
                }
                if (ancestor.ID == 0)
                {
                    ancestor = PageBL.GetHomePage();
                }
                list = NavBL.QueryNavTreeData(ancestor, context.Culture, expandableNav).ToList();

                // find the nearest parent node and increase its child count
                foreach (NavBE nearestAncestors in list)
                {
                    if (nearestAncestors.Id == ancestor.ID)
                    {
                        nearestAncestors.ChildCount = nearestAncestors.ChildCount + 1;
                        break;
                    }
                }

                // for each missing node, generate a dummy page and insert it into result set
                ulong        ancestor_id       = ancestor.ID;
                string[]     ancestor_segments = ancestor.Title.AsUnprefixedDbSegments();
                string[]     new_page_segments = page.Title.AsUnprefixedDbSegments();
                List <NavBE> newNodes          = new List <NavBE>(32);
                for (int i = ancestor_segments.Length; i < new_page_segments.Length; ++i)
                {
                    string title = string.Join("/", new_page_segments, 0, i + 1);

                    // create dummy node with <page><page_id /><page_namespace /><page_title ><page_parent /><page_children /></page>
                    NavBE newPage = new NavBE {
                        Id         = new_page_id,
                        NameSpace  = (ushort)page.Title.Namespace,
                        Title      = title,
                        ParentId   = (ancestor_id == homepageId) ? 0 : ancestor_id,
                        ChildCount = (i == new_page_segments.Length - 1) ? 0 : 1
                    };
                    newNodes.Add(newPage);

                    // update page information
                    page.ID       = new_page_id;
                    page.ParentID = ancestor_id;
                    ancestor_id   = new_page_id++;
                }

                // check if we need to remove the children nodes of the ancestor
                ancestor_id = (ancestor.ID == homepageId) ? 0 : (uint)ancestor.ID;
                if (!expandableNav && (new_page_segments.Length - ancestor_segments.Length) > 1)
                {
                    // remove ancestor children and add new dummy nodes
                    for (int start = 0; start < list.Count; ++start)
                    {
                        // check if we found a matching child
                        if ((list[start].ParentId == ancestor_id) && (list[start].Id != homepageId))
                        {
                            // look for last child to remove so we can remove an entire range at once
                            int end = start + 1;
                            for (; (end < list.Count) && (list[end].ParentId == ancestor_id) && (list[end].Id != homepageId); ++end)
                            {
                            }
                            list.RemoveRange(start, end - start);
                            --start;
                        }
                    }
                }
                else
                {
                    // find where among the ancestor children we need to insert the dummy node
                    for (int index = 0; index < list.Count; ++index)
                    {
                        NavBE current = list[index];
                        if ((current.ParentId == ancestor_id) && (current.Id != homepageId))
                        {
                            string[] parts = Title.FromDbPath(NS.UNKNOWN, current.Title, current.DisplayName).AsUnprefixedDbSegments();
                            if ((parts.Length > 0) && (new_page_segments.Length > 0) && (string.Compare(parts[parts.Length - 1], new_page_segments[parts.Length - 1], true, context.Culture) > 0))
                            {
                                // found the spot
                                list.InsertRange(index, newNodes);
                                newNodes = null;
                                break;
                            }
                        }
                    }
                }

                // check if we didn't find the spot
                if (newNodes != null)
                {
                    // add new nodes to the end
                    list.AddRange(newNodes);
                }
            }
            else
            {
                list = NavBL.QueryNavTreeData(page, context.Culture, expandableNav).ToList();
            }

            // find first parent
            ulong parent_id    = homepageId;
            int   parent_index = -1;

            for (int i = 0; i < list.Count; ++i)
            {
                if (list[i].Id == parent_id)
                {
                    parent_index = i;
                    break;
                }
            }
            if (parent_index == -1)
            {
                throw new Exception("unexpected [homepage not found]");
            }

            // add any missing ancestor nodes (might have been removed by permission check or might simply not exist)
            string[] page_segments = page.Title.AsUnprefixedDbSegments();
            ushort   ns            = (ushort)page.Title.Namespace;

            for (int i = 0; i <= page_segments.Length; ++i)
            {
                string title = string.Join("/", page_segments, 0, i);

                // loop over all nodes
                bool found = false;
                for (int j = 0; j < list.Count; ++j)
                {
                    NavBE node = list[j];

                    // NOTE (steveb): we walk the path one parent at a time; however, there are a few special cases, because of namespaces
                    //      for instance, the parent page of User:Bob is the homepage (ditto for Template:Page), but the parent page of Admin:Config is Admin:

                    // check if we found a node matching the current title
                    if ((string.Compare(node.Title, title, true, context.Culture) == 0) && (((i == 0) && (ns != (ushort)NS.ADMIN)) ? (node.NameSpace == (ushort)NS.MAIN) : (node.NameSpace == ns)))
                    {
                        found = true;

                        // let's make sure node is pointing to right parent
                        node.ParentId = (parent_id == homepageId) ? 0 : parent_id;
                        parent_id     = node.Id;
                        parent_index  = j;
                        break;
                    }
                }
                if (!found)
                {
                    // node is missing, let's create a new one
                    NavBE newPage = new NavBE {
                        Id        = new_page_id,
                        NameSpace = (ushort)page.Title.Namespace,
                        Title     = title,
                        ParentId  = (parent_id == homepageId) ? 0 : parent_id, ChildCount = 1
                    };

                    // add new page after parent
                    list.Insert(parent_index + 1, newPage);
                    parent_id    = new_page_id++;
                    parent_index = parent_index + 1;
                }
            }

            // build response
            if (ShowDebug(context))
            {
                response.Return(DreamMessage.Ok(NavBL.ConvertNavPageListToDoc(list)));
            }
            else
            {
                XDoc result = expandableNav ? NavBL.ComputeExpandableNavigationDocument(list, page, 0, 0, false) : NavBL.ComputeNavigationDocument(list, page, 0, 0, false, context.GetParam("width", int.MaxValue));
                if (ShowXml(context))
                {
                    response.Return(DreamMessage.Ok(result));
                }
                else
                {
                    response.Return(DreamMessage.Ok(new XDoc("tree").Value(result.Contents)));
                }
            }
            yield break;
        }
Example #7
0
        public Yield GetNavigationChildren(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            CheckResponseCache(context, false);

            PageBE page = PageBL_GetPageFromUrl(context, false);

            if (page.Title.IsTalk)
            {
                page = PageBL.GetPageByTitle(page.Title.AsFront());
            }

            // build response
            uint          exclude = context.GetParam <uint>("exclude", 0);
            IList <NavBE> list    = NavBL.QueryNavChildrenData(page, context.Culture);

            if (ShowDebug(context))
            {
                response.Return(DreamMessage.Ok(NavBL.ConvertNavPageListToDoc(list)));
            }
            else
            {
                bool expandableNav = context.GetParam("type", "compact").EqualsInvariantIgnoreCase("expandable");
                XDoc doc           = expandableNav ? NavBL.ComputeExpandableNavigationDocument(list, page, 0, exclude, true) : NavBL.ComputeNavigationDocument(list, page, 0, exclude, true, context.GetParam("width", int.MaxValue));
                if (ShowXml(context))
                {
                    response.Return(DreamMessage.Ok(doc));
                }
                else
                {
                    XDoc result = new XDoc("tree");
                    result.Start("children");

                    // add name of children nodes
                    System.Text.StringBuilder nodes = new System.Text.StringBuilder();
                    ulong homepageId = DekiContext.Current.Instance.HomePageId;
                    ulong parentId   = (page.ID == homepageId) ? 0 : page.ID;
                    foreach (NavBE child in list)
                    {
                        if ((child.ParentId == parentId) && (child.Id != homepageId))
                        {
                            if (nodes.Length != 0)
                            {
                                nodes.Append(",");
                            }
                            nodes.AppendFormat("n{0}", child.Id);
                        }
                    }
                    result.Elem("nodes", nodes.ToString());

                    // add <div> list
                    result.Start("html");
                    if (exclude != 0)
                    {
                        result.Start("pre").Value(doc["children-pre"].Contents).End();
                        result.Start("post").Value(doc["children-post"].Contents).End();
                    }
                    else
                    {
                        result.Value(doc.Contents);
                    }
                    result.End();
                    result.End();
                    response.Return(DreamMessage.Ok(result));
                }
            }
            yield break;
        }
        //--- Methods ---
        public void Append(XDoc manifestDoc)
        {
            XUri apiUri = DekiContext.Current.ApiUri;

            _log.DebugFormat("building import plan against api uri: {0}", apiUri.AsPublicUri());
            bool preserveExistingLocalChanges = manifestDoc["@preserve-local"].AsBool ?? false;
            var  security = manifestDoc["security"];

            foreach (XDoc importXml in manifestDoc.Elements)
            {
                try {
                    if (importXml.HasName("page"))
                    {
                        if (importXml["path"].IsEmpty)
                        {
                            throw new PageIdInvalidArgumentException();
                        }

                        // Generate the request needed to import the page
                        Title title = Title.FromRelativePath(_relToTitle, importXml["path"].Contents);
                        XUri  uri   = apiUri.At("pages", title.AsApiParam(), "contents").With("reltopath", _relToTitle.AsPrefixedDbPath());
                        _uris[uri] = null;
                        uri        = uri.With("language", importXml["language"].AsText)
                                     .With("title", importXml["title"].AsText)
                                     .With("edittime", DateTime.MaxValue.ToString("yyyyMMddHHmmss"))
                                     .With("redirects", "0");
                        var importEtag         = importXml["etag"].AsText;
                        var importDateModified = (importXml["date.modified"].AsDate ?? DateTime.MinValue).ToSafeUniversalTime();
                        if (importDateModified != DateTime.MinValue)
                        {
                            uri = uri.With("importtime", importDateModified.ToString("yyyyMMddHHmmss"));
                        }

                        // unless we're forcing overwrite...
                        if (!_forceoverwrite)
                        {
                            // ...check for existing page
                            var page = PageBL.GetPageByTitle(title);
                            if (page != null && page.ID != 0 && !page.IsRedirect)
                            {
                                // check for previous import
                                var lastImport = PropertyBL.Instance.GetPageProperty((uint)page.ID, LAST_IMPORT);
                                if (lastImport != null)
                                {
                                    try {
                                        var content                    = lastImport.Content;
                                        var previousImportXml          = XDocFactory.From(content.ToStream(), content.MimeType);
                                        var previousImportEtag         = previousImportXml["etag"].AsText;
                                        var previousImportDateModified = (previousImportXml["date.modified"].AsDate ?? DateTime.MinValue).ToSafeUniversalTime();
                                        if (preserveExistingLocalChanges)           // if we are supposed to preserve local changes
                                        {
                                            if (importEtag == previousImportEtag || // and page either hasn't changed
                                                previousImportEtag != page.Etag     // or is locally modified
                                                )                                   // then skip importing the page
                                            {
                                                _log.DebugFormat("skipping previously imported page '{0}', because page either hasn't changed or is locally modified", title);
                                                continue;
                                            }
                                        }
                                        else if (previousImportDateModified > importDateModified)
                                        {
                                            // if the previous import is newer, skip import
                                            _log.DebugFormat("skipping previously imported page '{0}', because previous import is newer", title);
                                            continue;
                                        }
                                    } catch (Exception e) {
                                        // if there was a parsing problem, skip import as a precaution
                                        _log.Warn(string.Format("a parsing problem occured with the import info property and import of page {0} is being skipped", page.ID), e);
                                        continue;
                                    }
                                }
                                else if (preserveExistingLocalChanges)
                                {
                                    // there was no previous import property, so the local content is by definition locally changed, ignore import
                                    _log.DebugFormat("skipping page '{0}', because of local content and preserve-local package preference", title);
                                    continue;
                                }
                            }
                        }
                        AddRequest("POST", uri, importXml["@dataid"].AsText, MimeType.XML.ToString());

                        // if we have security xml for the import, create a request command for it
                        if (!security.IsEmpty)
                        {
                            AddBodyRequest("POST", apiUri.At("pages", title.AsApiParam(), "security"), security, MimeType.XML.ToString());
                        }
                    }
                    else if (importXml.HasName("tags"))
                    {
                        // Ensure that the tags have a corresponding import page
                        Title title   = Title.FromRelativePath(_relToTitle, importXml["path"].Contents);
                        XUri  pageUri = apiUri.At("pages", title.AsApiParam(), "contents").With("reltopath", _relToTitle.AsPrefixedDbPath());
                        if (!_uris.ContainsKey(pageUri))
                        {
                            PageBE page = PageBL.GetPageByTitle(title);
                            if ((null == page) && (0 >= page.ID))
                            {
                                throw new PageIdInvalidArgumentException();
                            }
                            else
                            {
                                _uris[pageUri] = null;
                            }
                        }

                        // Generate the request to import the tags
                        XUri tagsUri = apiUri.At("pages", title.AsApiParam(), "tags");
                        _uris[tagsUri] = null;
                        tagsUri        = tagsUri.With("redirects", "0");
                        AddRequest("PUT", tagsUri, importXml["@dataid"].AsText, MimeType.XML.ToString());
                    }
                    else if (importXml.HasName("file"))
                    {
                        if (importXml["filename"].IsEmpty)
                        {
                            throw new AttachmentMissingFilenameInvalidArgumentException();
                        }

                        // Ensure that the file has a corresponding import page or that the page already exists in the wiki
                        Title title   = Title.FromRelativePath(_relToTitle, importXml["path"].Contents);
                        XUri  pageUri = apiUri.At("pages", title.AsApiParam(), "contents").With("reltopath", _relToTitle.AsPrefixedDbPath());
                        if (!_uris.ContainsKey(pageUri))
                        {
                            PageBE page = PageBL.GetPageByTitle(title);
                            if ((null == page) && (0 >= page.ID))
                            {
                                throw new PageIdInvalidArgumentException();
                            }
                            _uris[pageUri] = null;
                        }

                        // Generate the request to import the file
                        XUri fileUri = apiUri.At("pages", title.AsApiParam(), "files", Title.AsApiParam(importXml["filename"].Contents));
                        _uris[fileUri] = null;
                        fileUri        = fileUri.With("redirects", "0");
                        AddRequest("PUT", fileUri, importXml["@dataid"].AsText, importXml["contents/@type"].AsText);
                    }
                    else if (importXml.HasName("property"))
                    {
                        if (importXml["name"].IsEmpty)
                        {
                            throw new SiteImportUndefinedNameInvalidArgumentException("name");
                        }

                        // Ensure that that the property has a corresponding import page/file
                        Title title = Title.FromRelativePath(_relToTitle, importXml["path"].Contents);
                        XUri  uri   = apiUri.At("pages", title.AsApiParam());
                        if (importXml["filename"].IsEmpty)
                        {
                            if (!_uris.ContainsKey(uri.At("contents").With("reltopath", _relToTitle.AsPrefixedDbPath())))
                            {
                                throw new PageIdInvalidArgumentException();
                            }
                        }
                        else
                        {
                            uri = uri.At("files", Title.AsApiParam(importXml["filename"].AsText));
                            if (!_uris.ContainsKey(uri))
                            {
                                throw new AttachmentFilenameInvalidArgumentException();
                            }
                        }

                        // Generate the request to import the property
                        uri        = uri.At("properties", Title.AsApiParam(importXml["name"].Contents).Substring(1));
                        _uris[uri] = null;
                        uri        = uri.With("abort", "never")
                                     .With("redirects", "0");
                        AddRequest("PUT", uri, importXml["@dataid"].AsText, importXml["contents/@type"].AsText);
                    }
                    else
                    {
                        throw new DreamResponseException(DreamMessage.NotImplemented(importXml.Name));
                    }
                } catch (ResourcedMindTouchException e) {
                    ErrorImport(e.Message, (int)e.Status, importXml);
                } catch (DreamAbortException e) {
                    ErrorImport(e.Message, (int)e.Response.Status, importXml);
                } catch (Exception e) {
                    ErrorImport(e.Message, (int)DreamStatus.InternalError, importXml);
                }
            }
        }
        //--- Methods ---
        public void Append(XDoc exportDoc)
        {
            _manifestDoc.Attr("date.created", DateTime.UtcNow).Attr("preserve-local", false);
            foreach (XDoc exportXml in exportDoc.Elements)
            {
                // Retrieve the current page
                try {
                    if (exportXml.HasName("page"))
                    {
                        // Generate the manifest and request needed to export the page
                        PageBE page = null;
                        if (!exportXml["@id"].IsEmpty)
                        {
                            uint pageId = DbUtils.Convert.To <uint>(exportXml["@id"].Contents, 0);
                            if (0 < pageId)
                            {
                                page = PageBL.GetPageById(pageId);
                            }
                        }
                        else if (!exportXml["@path"].IsEmpty)
                        {
                            page = PageBL.GetPageByTitle(Title.FromPrefixedDbPath(exportXml["@path"].Contents, null));
                        }
                        if ((null == page) || (0 == page.ID))
                        {
                            throw new PageNotFoundException();
                        }

                        // Check whether to exclude subpages, files, and/or properties
                        bool recursive            = exportXml["@recursive"].AsBool ?? false;
                        ExportExcludeType exclude = ExportExcludeType.NONE;
                        if (!exportXml["@exclude"].IsEmpty)
                        {
                            exclude = SysUtil.ChangeType <ExportExcludeType>(exportXml["@exclude"].Contents);
                        }

                        // Export the page
                        PageExport(recursive, exclude, page);
                    }
                    else if (exportXml.HasName("file"))
                    {
                        // Generate the manifest and request needed to export the file
                        ResourceBE file = null;
                        if (!exportXml["@id"].IsEmpty)
                        {
                            uint fileId = DbUtils.Convert.To <uint>(exportXml["@id"].Contents, 0);
                            if (0 < fileId)
                            {
                                uint resourceId = ResourceMapBL.GetResourceIdByFileId(fileId) ?? 0;
                                if (resourceId > 0)
                                {
                                    file = ResourceBL.Instance.GetResource(resourceId);
                                }
                            }
                        }
                        if (null == file)
                        {
                            throw new AttachmentNotFoundException();
                        }

                        // Check whether to exclude properties
                        ExportExcludeType exclude = ExportExcludeType.NONE;
                        if (!exportXml["@exclude"].IsEmpty)
                        {
                            exclude = SysUtil.ChangeType <ExportExcludeType>(exportXml["@exclude"].Contents);
                        }

                        // Perform the file export
                        PageBE page = PageBL.GetPageById(file.ParentPageId.Value);
                        page = PageBL.AuthorizePage(DekiContext.Current.User, Permissions.READ, page, false);
                        AttachmentExport(exclude, page, file);
                    }
                    else
                    {
                        throw new DreamResponseException(DreamMessage.NotImplemented(exportXml.Name));
                    }
                } catch (ResourcedMindTouchException e) {
                    AddError(e.Message, (int)e.Status, exportXml);
                } catch (DreamAbortException e) {
                    AddError(e.Message, (int)e.Response.Status, exportXml);
                } catch (Exception e) {
                    AddError(e.Message, (int)DreamStatus.InternalError, exportXml);
                }
            }
        }
        private void PageExport(bool recursive, ExportExcludeType exclude, PageBE page)
        {
            // Validate the page export
            page = PageBL.AuthorizePage(DekiContext.Current.User, Permissions.READ, page, false);
            if (page.IsRedirect)
            {
                throw new SiteExportRedirectInvalidOperationException();
            }

            // Export the page
            XUri uri = PageBL.GetUriCanonical(page).At("contents")
                       .With("mode", "edit")
                       .With("reltopath", _relToTitle.AsPrefixedDbPath())
                       .With("format", "xhtml");

            if (!_uris.ContainsKey(uri))
            {
                _uris.Add(uri, null);
                var dateModified = page.TimeStamp;
                var lastImport   = PropertyBL.Instance.GetPageProperty((uint)page.ID, SiteImportBuilder.LAST_IMPORT);
                if (lastImport != null)
                {
                    var content   = lastImport.Content;
                    var importDoc = XDocFactory.From(content.ToStream(), content.MimeType);
                    if (importDoc["etag"].AsText.EqualsInvariant(page.Etag))
                    {
                        dateModified = importDoc["date.modified"].AsDate ?? DateTime.MinValue;
                    }
                }
                var manifestDoc = new XDoc("page").Elem("title", page.Title.DisplayName)
                                  .Elem("path", page.Title.AsRelativePath(_relToTitle))
                                  .Elem("language", page.Language)
                                  .Elem("etag", page.Etag)
                                  .Elem("date.modified", dateModified.ToSafeUniversalTime())
                                  .Start("contents").Attr("type", page.ContentType).End();
                Add(uri, manifestDoc);
            }

            // Export page tags (if not excluded)
            if (ExportExcludeType.NONE == (ExportExcludeType.TAGS & exclude))
            {
                XUri tagUri = PageBL.GetUriCanonical(page).At("tags");
                if (!_uris.ContainsKey(tagUri))
                {
                    _uris.Add(tagUri, null);
                    XDoc manifestDoc = new XDoc("tags").Elem("path", page.Title.AsRelativePath(_relToTitle));
                    Add(tagUri, manifestDoc);
                }
            }

            // Export page properties (if not excluded)
            if (ExportExcludeType.NONE == (ExportExcludeType.PROPS & exclude))
            {
                IList <ResourceBE> properties = PropertyBL.Instance.GetPageProperties(page.ID);
                foreach (ResourceBE property in properties)
                {
                    if (property.Name.EqualsInvariant(SiteImportBuilder.LAST_IMPORT))
                    {
                        continue;
                    }
                    PropertyExport(page, null, property);
                }
            }

            // Export page files (if not excluded)
            if (ExportExcludeType.NONE == (ExportExcludeType.FILES & exclude))
            {
                IList <ResourceBE> files = AttachmentBL.Instance.GetPageAttachments(page.ID);
                foreach (ResourceBE file in files)
                {
                    AttachmentExport(exclude, page, file);
                }
            }

            // Export talk page (if not excluded)
            if ((ExportExcludeType.NONE == (ExportExcludeType.TALK & exclude)) && (!page.Title.IsTalk))
            {
                PageBE talkPage = PageBL.GetPageByTitle(page.Title.AsTalk());
                if ((null != talkPage) && (0 < talkPage.ID))
                {
                    PageExport(false, exclude, talkPage);
                }
            }

            // Export subpages (if not excluded)
            if (recursive)
            {
                ICollection <PageBE> children = PageBL.GetChildren(page, true);
                children = PermissionsBL.FilterDisallowed(DekiContext.Current.User, PageBL.GetChildren(page, true), false, Permissions.READ);
                if (children != null)
                {
                    foreach (PageBE child in children)
                    {
                        PageExport(recursive, exclude, child);
                    }
                }
            }
        }
Example #11
0
 public static PageBE GetHomePage(UserBE user)
 {
     return(PageBL.GetPageByTitle(Title.FromUIUsername(user.Name)));
 }