private async Task BuildToc()
        {
            string tocJson = null;

            switch (RepositoryType)
            {
            case RepositoryTypes.GitHubRaw:
                tocJson = await TableOfContentsHelper.GetTocJsonFromGitHubRaw(GitHubMasterUrlRaw);

                break;

            case RepositoryTypes.VstsGit:
                tocJson = await VstsHelper.GetTocJson(VstsInstance, VstsProjectName, VstsDocsFolder, VstsPat, VstsApiVersion);

                break;
            }
            if (string.IsNullOrEmpty(tocJson))
            {
                return;
            }

            var dynamicToc = TableOfContentsHelper.GetDynamicTocFromJson(tocJson);

            Topics = TableOfContentsHelper.BuildTocFromDynamicToc(dynamicToc, null, string.Empty, out List <TableOfContentsItem> flatTopicsList);
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            // Setup parser and extract command line arguments
            var parser      = new CommandLineParser.CommandLineParser();
            var cmdLineArgs = new CommandLineArgs();

            try
            {
                // Add the verbose switch programmatically because I am having issues with the attributes
                var verbose = new SwitchArgument('v', "verbose", "Turns on verbose output.", false);
                parser.Arguments.Add(verbose);

                parser.ShowUsageHeader = "Downloads a file or folder from VSTS to the specified location.\r\n\r\n" +
                                         "VSTS-GET -a <Account> [-u <User ID>] -p <Password> -t <Project> -r <Repo> [-f|-o] <File/Folder> " +
                                         "-d <Destination>";
                parser.ShowUsageOnEmptyCommandline = true;

                parser.ExtractArgumentAttributes(cmdLineArgs);
                parser.ParseCommandLine(args);

                if (parser.ParsingSucceeded)
                {
                    var authentication = new BasicAuthentication(cmdLineArgs.Account, cmdLineArgs.UserId, cmdLineArgs.Password);

                    if (!string.IsNullOrEmpty(cmdLineArgs.FilePath))
                    {
                        // If the --file argument was specified, then assume we're downloading a single file
                        var helper = new VstsHelper();

                        Console.WriteLine(helper.DownloadFile(authentication, cmdLineArgs.Project, cmdLineArgs.Repo,
                                                              cmdLineArgs.FilePath, cmdLineArgs.Destination,
                                                              verbose.Value)
                            ? "    File download successful."
                            : "    File download failed.");
                    }
                    else if (!string.IsNullOrEmpty(cmdLineArgs.FolderPath))
                    {
                        var helper = new VstsHelper();

                        Console.WriteLine(helper.DownloadFolder(authentication, cmdLineArgs.Project, cmdLineArgs.Repo,
                                                                cmdLineArgs.FolderPath, cmdLineArgs.Destination,
                                                                verbose.Value)
                            ? "    Folder download successful."
                            : "    Folder download failed.");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                parser.ShowUsage();
            }

            if (Debugger.IsAttached)
            {
                // Keep the console window from closing when running from IDE
                Console.WriteLine("\r\nPress any key to close command window.");
                Console.ReadKey();
            }
        }
Beispiel #3
0
        static void Main(string[] args)
        {
            // Setup parser and extract command line arguments
            var parser      = new CommandLineParser.CommandLineParser();
            var cmdLineArgs = new CommandLineArgs();

            try
            {
                parser.ShowUsageHeader = "Retrieves a list of user e-mail addresses, last access date/time and license type " +
                                         "from VSTS in comma-delimited format.\r\n\r\n" +
                                         "VSTS-Users -a <Account> [-u <User ID>] -p <Password> ";
                parser.ShowUsageOnEmptyCommandline = true;

                parser.ExtractArgumentAttributes(cmdLineArgs);
                parser.ParseCommandLine(args);

                if (parser.ParsingSucceeded)
                {
                    var authentication = new BasicAuthentication(cmdLineArgs.Account, cmdLineArgs.UserId, cmdLineArgs.Password);
                    var helper         = new VstsHelper();

                    var results = helper.GetVstsUsers(authentication);

                    if (results != null)
                    {
                        if (cmdLineArgs.IncludeHeader)
                        {
                            Console.WriteLine($"{QuoteIfHasSpaces("User", cmdLineArgs.IncludeQuotes)}," +
                                              $"{QuoteIfHasSpaces("Last Accessed Date/Time", cmdLineArgs.IncludeQuotes)}," +
                                              QuoteIfHasSpaces("User License", cmdLineArgs.IncludeQuotes));
                        }

                        foreach (var user in results.Value.OrderBy(x => x.User.MailAddress))
                        {
                            var email       = QuoteIfHasSpaces(user.User.MailAddress, cmdLineArgs.IncludeQuotes);
                            var lastAccess  = QuoteIfHasSpaces(user.LastAccessedDate.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), cmdLineArgs.IncludeQuotes);
                            var userLicense = QuoteIfHasSpaces(user.AccessLevel.LicenseDisplayName, cmdLineArgs.IncludeQuotes);

                            Console.WriteLine($"{email},{lastAccess},{userLicense}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                parser.ShowUsage();
            }

            if (Debugger.IsAttached)
            {
                // Keep the console window from closing when running from IDE
                Console.WriteLine("\r\nPress any key to close command window.");
                Console.ReadKey();
            }
        }
Beispiel #4
0
        static void Main(string[] args)
        {
            // Setup parser and extract command line arguments
            var parser      = new CommandLineParser.CommandLineParser();
            var cmdLineArgs = new CommandLineArgs();

            try
            {
                // Add the verbose switch programmatically because I am having issues with the attributes
                var verbose     = new SwitchArgument('v', "verbose", "Turns on verbose output.", false);
                var keepForever = new SwitchArgument('k', "keep", "If specified, sets to \"Keep Forever\"; Otherwise, removes the flag.", false);

                parser.Arguments.Add(verbose);
                parser.Arguments.Add(keepForever);

                parser.ShowUsageHeader = "Sets or removes \"keep forever\" retention for the specified build number in VSTS.\r\n\r\n" +
                                         "VSTS-KEEP -a <Account> [-u <User ID>] -p <Password> -t <Project> -b <BuildNumber> [-k]";
                parser.ShowUsageOnEmptyCommandline = true;

                parser.ExtractArgumentAttributes(cmdLineArgs);
                parser.ParseCommandLine(args);

                if (parser.ParsingSucceeded)
                {
                    var authentication = new BasicAuthentication(cmdLineArgs.Account, cmdLineArgs.UserId, cmdLineArgs.Password);
                    var helper         = new VstsHelper();

                    Console.WriteLine(helper.KeepForever(authentication, cmdLineArgs.Project, cmdLineArgs.BuildNumber,
                                                         keepForever.Value, verbose.Value)
                        ? "    Retention set successfully."
                        : "    Failed to set retention.");
                }
            }
            catch (System.Net.WebException ex)
            {
                Console.WriteLine(ex.Message);
                if (ex.Message.Contains("(401) Unauthorized."))
                {
                    Console.WriteLine("VSTS-Keep requires access to the account's OAuth token in order to correctly set the keep forever config.");
                    Console.WriteLine("Please go to this build definition's options tab and enable build scripts to access the OAuth token.");
                }
                parser.ShowUsage();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                parser.ShowUsage();
            }

            if (Debugger.IsAttached)
            {
                // Keep the console window from closing when running from IDE
                Console.WriteLine("\r\nPress any key to close command window.");
                Console.ReadKey();
            }
        }
Beispiel #5
0
        public Md2WpClient(string baseUrl, string userName, string password, string accountUrl,
                           string project, string repoName, string branch, string accessToken, string metadataFilename,
                           bool embedExternalImages, bool publishAsCommitter, bool processSubfolders, bool useFolderNameAsCategory,
                           bool useFolderNameAsTag, bool publishNewPostsAsDraft, bool trackPostIdInFilename,
                           bool addEditLink, string editLinkText, string editLinkStyle)
        {
            Logger.LogMessage("MDWWPClient::ctor");
            Logger.LogMessage($"  BaseUrl = {baseUrl}");
            Logger.LogMessage($"  UserName = {userName}");
            Logger.LogMessage("  Password = ********");
            Logger.LogMessage($"  Account URL = {accountUrl}");
            Logger.LogMessage($"  Project = {project}");
            Logger.LogMessage($"  RepoName = {repoName}");
            Logger.LogMessage($"  Branch = {branch}");
            Logger.LogMessage("  AccessToken = ********");
            Logger.LogMessage($"  MetadataFilename = {metadataFilename}");
            Logger.LogMessage($"  EmbedExternalImages = {embedExternalImages}");
            Logger.LogMessage($"  PublishAsCommitter = {publishAsCommitter}");
            Logger.LogMessage($"  ProcessSubfolders = {processSubfolders}");
            Logger.LogMessage($"  UseFolderNameAsCategory = {useFolderNameAsCategory}");
            Logger.LogMessage($"  UseFolderNameAsTag = {useFolderNameAsTag}");
            Logger.LogMessage($"  PublishNewPostsAsDraft = {publishNewPostsAsDraft}");
            Logger.LogMessage($"  TrackPostIdInFilename = {trackPostIdInFilename}");
            Logger.LogMessage($"  AddEditLink = {addEditLink}");
            Logger.LogMessage($"  EditLinkText = {editLinkText}");
            Logger.LogMessage($"  editLinkStyle = {editLinkStyle}");

            vstsAuthentication = new BasicAuthentication(accountUrl, string.Empty, accessToken);
            vstsHelper         = new VstsHelper();
            wpHelper           = new WordPressHelper(baseUrl, userName, password);

            //siteConfig = new WordPressSiteConfig()
            //{
            //    BaseUrl = baseUrl,
            //    Username = userName,
            //    Password = password
            //};

            //this.accountUrl = accountUrl;
            this.project  = project;
            this.repoName = repoName;
            this.branch   = branch;
            //this.accessToken = accessToken;
            this.metadataFilename        = metadataFilename.TrimStart('\\');
            this.embedExternalImages     = embedExternalImages;
            this.publishAsCommitter      = publishAsCommitter;
            this.processSubfolders       = processSubfolders;
            this.useFolderNameAsCategory = useFolderNameAsCategory;
            this.useFolderNameAsTag      = useFolderNameAsTag;
            this.publishNewPostsAsDraft  = publishNewPostsAsDraft;
            this.trackPostIdInFilename   = trackPostIdInFilename;
            this.addEditLink             = addEditLink;
            this.editLinkText            = editLinkText;
            this.editLinkStyle           = editLinkStyle;
        }
Beispiel #6
0
        public VstsHelperTests()
        {
            var settings = IntegrationTestSettings.GetIntegrationTestSettings();

            _accountUrl  = settings.AzureDevOps.AccountUrl;
            _accessToken = settings.AzureDevOps.PersonalAccessToken;
            _repoName    = settings.AzureDevOps.RepoName;
            _projectName = settings.AzureDevOps.ProjectName;
            _branchName  = settings.AzureDevOps.BranchName;

            _authentication = new BasicAuthentication(_accountUrl, string.Empty, _accessToken);
            _vstsHelper     = new VstsHelper();
        }
Beispiel #7
0
        public string GetStateHtmlTag(string state)
        {
            lock (_workItemStatesLockDummy)
                if (!_workItemStatesIsPopulated)
                {
                    var instance            = _parent.GetSetting <string>(SettingsEnum.VstsInstance);
                    var projectName         = _parent.GetSetting <string>(SettingsEnum.VstsProjectName);
                    var personalAccessToken = _parent.GetSetting <string>(SettingsEnum.VstsPat);
                    var apiVersion          = _parent.GetSetting <string>(SettingsEnum.VstsApiVersion);
                    var workItemTypesJson   = VstsHelper.GetWorkItemTypes(instance, projectName, personalAccessToken, apiVersion).Result;
                    if (!string.IsNullOrEmpty(workItemTypesJson))
                    {
                        dynamic workItemTypes = JObject.Parse(workItemTypesJson);
                        foreach (var workItemType in workItemTypes.value)
                        {
                            var workItemTypeName  = (string)workItemType.name;
                            var workItemStateJson = VstsHelper.GetWorkItemTypeStates(workItemTypeName, instance, projectName, personalAccessToken, apiVersion).Result;
                            if (!string.IsNullOrEmpty(workItemStateJson))
                            {
                                dynamic workItemStates = JObject.Parse(workItemStateJson);
                                foreach (dynamic workItemState in workItemStates.value)
                                {
                                    var name = (string)workItemState.name;
                                    name = name.ToLowerInvariant();
                                    var color = (string)workItemState.color;
                                    if (!_workItemStates.ContainsKey(name))
                                    {
                                        _workItemStates.Add(name, color);
                                    }
                                }
                            }
                        }
                    }
                    _workItemStatesIsPopulated = true;
                }

            //var stateClass = state.ToLowerInvariant().Replace(" ", "-").Replace("--","-").Replace("--","-");
            //stateClass = "vsts-state vsts-state-" + stateClass;

            var style    = string.Empty;
            var stateKey = state.ToLowerInvariant();

            if (_workItemStates.ContainsKey(stateKey))
            {
                var color = _workItemStates[stateKey];
                style = "border-color: #" + color + "; background-color: #" + color + ";";
            }

            return("<div class=\"vsts-state\" style=\"" + style + "\"> </div>");
        }
        public async Task Reindex()
        {
            if (Topics == null || Topics.Count < 1)
            {
                return;
            }

            var nextTopic = Topics.FirstOrDefault();

            while (nextTopic != null)
            {
                var normalizedLink = nextTopic.LinkPure.ToLowerInvariant();
                var content        = string.Empty;
                if (normalizedLink.StartsWith("https://") || normalizedLink.StartsWith("http://"))
                {
                    // This is an absolute link, so we can just try to load it
                    content = await WebClientEx.GetStringAsync(nextTopic.Link);
                }
                else
                {
                    switch (RepositoryType)
                    {
                    case RepositoryTypes.GitHubRaw:
                        content = await WebClientEx.GetStringAsync(GetFullExternalLink(nextTopic.Title));

                        break;

                    case RepositoryTypes.VstsGit:
                        if (!string.IsNullOrEmpty(nextTopic.LinkPure))
                        {
                            content = await VstsHelper.GetFileContents(nextTopic.LinkPure, VstsInstance, VstsProjectName, VstsDocsFolder, VstsPat, VstsApiVersion);
                        }
                        break;
                    }
                }

                if (!string.IsNullOrEmpty(content))
                {
                    await AddToIndex(nextTopic, content, nextTopic.LinkPure.ToLowerInvariant());
                }
            }
            nextTopic = nextTopic.NextTopic;
        }
        private async Task BuildToc()
        {
            string tocJson = null;

            var repositoryType = RepositoryTypeHelper.GetTypeFromTypeName(GetSetting <string>(SettingsEnum.RepositoryType));

            var logoUrl           = GetSetting <string>(SettingsEnum.LogoPath);
            var logoUrlLower      = logoUrl.ToLowerInvariant();
            var logoUrlIsAbsolute = true;

            if (!logoUrl.StartsWith("http://") && !logoUrl.StartsWith("https://"))
            {
                logoUrlIsAbsolute = false;
            }
            LogoUrl = logoUrl;

            if (UseSqlServer) // SQL server *may* provide a local tabe of contents that would override all others
            {
                tocJson = await SqlDataAccess.GetRepositoryLocalTableOfContents(CurrentPrefix);
            }

            if (string.IsNullOrEmpty(tocJson))
            {
                switch (repositoryType)
                {
                case RepositoryTypes.GitHubRaw:
                    tocJson = await TableOfContentsHelper.GetTocJsonFromGitHubRaw(GitHubMasterUrlRaw);

                    if (!logoUrlIsAbsolute)
                    {
                        LogoUrl = GitHubMasterUrlRaw + logoUrl;
                    }
                    break;

                case RepositoryTypes.GitHubApi:
                    tocJson = await TableOfContentsHelper.GetTocJsonFromGitHubApi(GitHubOwner, GitHubRepository, GitHubPat);

                    // TODO: if (!logoUrlIsAbsolute)
                    //    LogoUrl = GitHubMasterUrlRaw + logoUrl;
                    break;

                case RepositoryTypes.VstsGit:
                    tocJson = await VstsHelper.GetTocJson(GetSetting <string>(SettingsEnum.VstsInstance), GetSetting <string>(SettingsEnum.VstsProjectName), GetSetting <string>(SettingsEnum.VstsDocsFolder), GetSetting <string>(SettingsEnum.VstsPat), GetSetting <string>(SettingsEnum.VstsApiVersion));

                    if (!logoUrlIsAbsolute)
                    {
                        LogoUrl = $"/___FileProxy___?mode=vstsgit&path={logoUrl}";
                    }
                    break;
                }
            }
            if (string.IsNullOrEmpty(tocJson))
            {
                return;
            }

            var dynamicToc = TableOfContentsHelper.GetDynamicTocFromJson(tocJson);

            if (dynamicToc.title != null)
            {
                RepositoryTitle = dynamicToc.title;
            }
            if (dynamicToc.owner != null)
            {
                Owner = dynamicToc.owner;
            }

            Topics     = TableOfContentsHelper.BuildTocFromDynamicToc(dynamicToc, this, CurrentSlug, out List <TableOfContentsItem> flatTopicList);
            FlatTopics = flatTopicList;
            MainMenu   = TableOfContentsHelper.BuildMainMenuStructureFromDynamicToc(dynamicToc);

            var matchingTopic = FlatTopics.FirstOrDefault(t => TopicHelper.SlugMatchesTopic(CurrentSlug, t));

            if (matchingTopic == null)
            {
                matchingTopic = FlatTopics.FirstOrDefault(t => TopicHelper.SlugMatchesTopic(CurrentSlug, t, true));
            }
            if (matchingTopic == null)
            {
                matchingTopic = FlatTopics.FirstOrDefault(t => TopicHelper.LinkMatchesTopic(CurrentSlug, t));
            }
            if (matchingTopic == null)
            {
                matchingTopic = Topics.FirstOrDefault();
            }

            SelectedTopic = matchingTopic;
            TableOfContentsHelper.EnsureExpanded(SelectedTopic);

            TocSettings          = dynamicToc.settings;
            CurrentTopicSettings = SelectedTopic?.SettingsDynamic;
        }
        private async Task GetHtmlContent()
        {
            var rawTopic = new TopicInformation {
                OriginalName = SelectedTopic.Title, Type = SelectedTopic.Type
            };

            ImageRootUrl = string.Empty;

            var normalizedLink = SelectedTopic.LinkPure.ToLowerInvariant();

            if (normalizedLink.StartsWith("https://") || normalizedLink.StartsWith("http://"))
            {
                // This is an absolute link, so we can just try to load it
                rawTopic.OriginalContent = await WebClientEx.GetStringAsync(SelectedTopic.Link);

                ImageRootUrl = StringHelper.JustPath(SelectedTopic.Link) + "/";
            }
            else if (!string.IsNullOrEmpty(normalizedLink))
            {
                var repositoryType = RepositoryTypeHelper.GetTypeFromTypeName(GetSetting <string>(SettingsEnum.RepositoryType));

                // Even if the overall repository type is something else, we will switch to different repository access for specific node types,
                // as they may point to other repositories or require different APIs even within the same repository
                if (TopicTypeHelper.IsVstsWorkItemType(rawTopic?.Type))
                {
                    repositoryType = RepositoryTypes.VstsWorkItemTracking;
                }

                switch (repositoryType)
                {
                case RepositoryTypes.GitHubRaw:
                    var fullGitHubRawUrl = GitHubMasterUrlRaw + SelectedTopic.Link;
                    if (string.IsNullOrEmpty(rawTopic.Type))
                    {
                        rawTopic.Type = TopicTypeHelper.GetTopicTypeFromLink(fullGitHubRawUrl);
                    }
                    if (TopicTypeHelper.IsMatch(rawTopic.Type, TopicBodyFormats.Markdown) || TopicTypeHelper.IsMatch(rawTopic.Type, TopicBodyFormats.Html))
                    {
                        rawTopic.OriginalContent = await WebClientEx.GetStringAsync(fullGitHubRawUrl);
                    }
                    else if (TopicTypeHelper.IsMatch(rawTopic.Type, TopicBodyFormats.ImageUrl))
                    {
                        rawTopic.OriginalContent = fullGitHubRawUrl;
                    }
                    ImageRootUrl = StringHelper.JustPath(fullGitHubRawUrl);
                    if (!string.IsNullOrEmpty(ImageRootUrl) && !ImageRootUrl.EndsWith("/"))
                    {
                        ImageRootUrl += "/";
                    }
                    break;

                case RepositoryTypes.GitHubApi:
                    if (TopicTypeHelper.IsMatch(rawTopic.Type, TopicBodyFormats.Markdown) || TopicTypeHelper.IsMatch(rawTopic.Type, TopicBodyFormats.Html))
                    {
                        var gitHubClient  = new GithubRepositoryParser(GitHubOwner, GitHubRepository, GitHubPat);
                        var gitHubContent = await gitHubClient.GetItemContent(SelectedTopic.Link);

                        rawTopic.OriginalContent = gitHubContent.Text;
                    }
                    // TODO: else if (TopicTypeHelper.IsMatch(rawTopic.Type, TopicBodyFormats.ImageUrl))
                    //    rawTopic.OriginalContent = fullGitHubRawUrl;
                    //ImageRootUrl = StringHelper.JustPath(fullGitHubRawUrl);
                    //if (!string.IsNullOrEmpty(ImageRootUrl) && !ImageRootUrl.EndsWith("/")) ImageRootUrl += "/";
                    break;

                case RepositoryTypes.VstsGit:
                    if (!string.IsNullOrEmpty(SelectedTopic.LinkPure))
                    {
                        rawTopic.OriginalContent = await VstsHelper.GetFileContents(SelectedTopic.LinkPure, GetSetting <string>(SettingsEnum.VstsInstance), GetSetting <string>(SettingsEnum.VstsProjectName), GetSetting <string>(SettingsEnum.VstsDocsFolder), GetSetting <string>(SettingsEnum.VstsPat), GetSetting <string>(SettingsEnum.VstsApiVersion));
                    }
                    ImageRootUrl = "/___FileProxy___?mode=" + RepositoryTypeNames.VstsGit + "&path=";
                    if (SelectedTopic.LinkPure.Contains("/"))
                    {
                        ImageRootUrl += StringHelper.JustPath(SelectedTopic.LinkPure) + "/";
                    }
                    break;

                case RepositoryTypes.VstsWorkItemTracking:
                    if ((TopicTypeHelper.IsMatch(rawTopic?.Type, TopicBodyFormats.VstsWorkItemQuery) || TopicTypeHelper.IsMatch(rawTopic?.Type, TopicBodyFormats.VstsWorkItemQueries)) && HttpContext.Request.Query.ContainsKey("workitemnumber"))
                    {
                        // The current node is a work item query, but we use it as a context to get the actual work item
                        var itemNumber = int.Parse(HttpContext.Request.Query["workitemnumber"]);
                        rawTopic.OriginalContent = await VstsHelper.GetWorkItemJson(itemNumber, GetSetting <string>(SettingsEnum.VstsInstance), GetSetting <string>(SettingsEnum.VstsPat), GetSetting <string>(SettingsEnum.VstsApiVersion));

                        rawTopic.Type = TopicBodyFormats.VstsWorkItem;
                    }
                    else if (TopicTypeHelper.IsMatch(rawTopic?.Type, TopicBodyFormats.VstsWorkItemQueries) && HttpContext.Request.Query.ContainsKey("queryid"))
                    {
                        // The current node is a list of work item queries, but we use it as a context to run the actual query
                        var queryId       = HttpContext.Request.Query["queryid"];
                        var queryInfoJson = await VstsHelper.GetWorkItemQueriesJson(queryId, GetSetting <string>(SettingsEnum.VstsInstance), GetSetting <string>(SettingsEnum.VstsProjectName), GetSetting <string>(SettingsEnum.VstsPat), GetSetting <string>(SettingsEnum.VstsApiVersion));

                        dynamic queryInfo = JObject.Parse(queryInfoJson);
                        if (queryInfo != null)
                        {
                            Title = "Query: " + queryInfo.name;
                        }
                        rawTopic.OriginalContent = await VstsHelper.RunWorkItemQueryJson(queryId, GetSetting <string>(SettingsEnum.VstsInstance), GetSetting <string>(SettingsEnum.VstsProjectName), GetSetting <string>(SettingsEnum.VstsPat), GetSetting <string>(SettingsEnum.VstsApiVersion));

                        if (rawTopic.OriginalContent.StartsWith("{"))
                        {
                            rawTopic.Type = TopicBodyFormats.VstsWorkItemQuery;
                        }
                        else
                        {
                            rawTopic.Type = TopicBodyFormats.Markdown;     // Something went wrong, but one way or another, we didn't end up with JSON
                        }
                    }
                    else if (TopicTypeHelper.IsMatch(rawTopic?.Type, TopicBodyFormats.VstsWorkItem))
                    {
                        // Plain work item node
                        var itemNumber = int.Parse(SelectedTopic.Link);
                        rawTopic.OriginalContent = await VstsHelper.GetWorkItemJson(itemNumber, GetSetting <string>(SettingsEnum.VstsInstance), GetSetting <string>(SettingsEnum.VstsPat), GetSetting <string>(SettingsEnum.VstsApiVersion));
                    }
                    else if (TopicTypeHelper.IsMatch(rawTopic?.Type, TopicBodyFormats.VstsWorkItemQueries))
                    {
                        // Plain work item queries
                        rawTopic.OriginalContent = await VstsHelper.GetWorkItemQueriesJson(SelectedTopic.Link, GetSetting <string>(SettingsEnum.VstsInstance), GetSetting <string>(SettingsEnum.VstsProjectName), GetSetting <string>(SettingsEnum.VstsPat), GetSetting <string>(SettingsEnum.VstsApiVersion));

                        Title = SelectedTopic.Title;
                    }
                    else if (TopicTypeHelper.IsMatch(rawTopic?.Type, TopicBodyFormats.VstsWorkItemQuery))
                    {
                        // Plain work item query
                        rawTopic.OriginalContent = await VstsHelper.RunWorkItemQueryJson(SelectedTopic.Link, GetSetting <string>(SettingsEnum.VstsInstance), GetSetting <string>(SettingsEnum.VstsProjectName), GetSetting <string>(SettingsEnum.VstsPat), GetSetting <string>(SettingsEnum.VstsApiVersion));

                        Title = SelectedTopic.Title;
                    }

                    Vsts.ImageLink = "/___FileProxy___?mode=" + RepositoryTypeNames.VstsWorkItemTracking + "&topic=" + CurrentSlug + "&path=";
                    break;
                }
            }

            var renderer = TopicRendererFactory.GetTopicRenderer(rawTopic);

            var intermediateHtml = renderer.RenderToHtml(rawTopic, ImageRootUrl, this);

            if (!string.IsNullOrEmpty(intermediateHtml))
            {
                intermediateHtml = await ProcessKavaTopic(intermediateHtml);

                intermediateHtml = AutoGenerateTitle(intermediateHtml);
                intermediateHtml = ProcessBrokenImageLinks(intermediateHtml, ImageRootUrl);
            }

            Html = intermediateHtml;

            Json         = renderer.RenderToJson(rawTopic, ImageRootUrl, this);
            TemplateName = renderer.GetTemplateName(rawTopic, TemplateName, this);

            if (string.IsNullOrEmpty(Html) && SelectedTopic != null)
            {
                var sb = new StringBuilder();
                sb.Append("<h1>" + SelectedTopic.Title + "</h1>");

                if (SelectedTopic.Topics.Count > 0)
                {
                    sb.Append("<ul>");
                    foreach (var topic in SelectedTopic.Topics)
                    {
                        sb.Append("<li class=\"kava-auto-link\">");
                        sb.Append("<a href=\"" + TopicHelper.GetNormalizedName(topic.Title) + "\">");
                        sb.Append(topic.Title);
                        sb.Append("</a>");
                        sb.Append("</li>");
                    }
                    sb.Append("</ul>");
                }

                Html = sb.ToString();
            }
        }
Beispiel #11
0
        public async Task <IActionResult> FileProxy(string mode, string path, string topic = "", string fileName = "")
        {
            // Special processing for file retrieval of attachments to TFS work items. This is mainly used to return images in item descriptions.
            if (RepositoryTypeHelper.IsMatch(mode, RepositoryTypeNames.VstsWorkItemTracking))
            {
                var model = new TopicViewModel(topic, HttpContext);
                if (SqlDataAccess.CanUseSql)
                {
                    var prefix   = ControllerHelper.GetCurrentDomainPrefix(HttpContext.Request);
                    var settings = await SqlDataAccess.GetSqlRepositorySettingsDynamic(prefix);

                    if (settings == null)
                    {
                        return(NotFound($"Document repository {prefix} does not exist."));
                    }
                    model.SetRootSettingsForRequest(settings);
                }
                await model.LoadData(buildHtml : false, buildToc : true);

                var instance = model.GetSetting <string>(SettingsEnum.VstsInstance);
                var pat      = model.GetSetting <string>(SettingsEnum.VstsPat);
                var stream   = await VstsHelper.GetWorkItemAttachmentStream(path, instance, pat);

                return(File(stream, GetContentTypeFromUrl(fileName), fileName));
            }

            // If we got this far, and the path is a fully qualified URL, then we just retrieve it
            if (path.ToLowerInvariant().StartsWith("http://") || path.ToLowerInvariant().StartsWith("https://"))
            {
                using (var client = new WebClientEx())
                {
                    var data = await client.DownloadDataTaskAsync(new Uri(path));

                    return(File(data, GetContentTypeFromUrl(path), StringHelper.JustFileName(path)));
                }
            }

            // If it is in a VSTS Git repository, we use the API to retrieve it
            if (RepositoryTypeHelper.IsMatch(mode, RepositoryTypeNames.VstsGit))
            {
                if (SqlDataAccess.CanUseSql)
                {
                    var prefix   = ControllerHelper.GetCurrentDomainPrefix(HttpContext.Request);
                    var settings = await SqlDataAccess.GetSqlRepositorySettingsDynamic(prefix);

                    if (settings == null)
                    {
                        return(NotFound($"Document repository {prefix} does not exist."));
                    }
                    var stream = await VstsHelper.GetFileStream(path,
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsInstance, requestRootSettings: settings),
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsProjectName, requestRootSettings: settings),
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsDocsFolder, requestRootSettings: settings),
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsPat, requestRootSettings: settings),
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsApiVersion, requestRootSettings: settings));

                    return(File(stream, GetContentTypeFromUrl(path), StringHelper.JustFileName(path)));
                }
                else
                {
                    var stream = await VstsHelper.GetFileStream(path,
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsInstance),
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsProjectName),
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsDocsFolder),
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsPat),
                                                                SettingsHelper.GetSetting <string>(SettingsEnum.VstsApiVersion));

                    return(File(stream, GetContentTypeFromUrl(path), StringHelper.JustFileName(path)));
                }
            }

            // Otherwise, we got nothing :-)
            return(null);
        }