public static async Task <IEnumerable <JenkinsView> > GetViews(JenkinsServer server) { Uri serverUri = new Uri(server.Url); Uri viewInfoUri = new Uri(serverUri, VIEW_QUERY); JenkinsOverview overview = await GetFromJSONData <JenkinsOverview>(server, viewInfoUri); if (overview == null) { overview = new JenkinsOverview(); } foreach (var view in overview.Views) { view.Url = FixPrimaryViewUrl(view); } return(overview.Views); }
private async Task LoadJenkinsJobs() { if (SelectedJenkinsServer == null) { return; } lock (_loadingJobsBusyLock) { if (_loadingJobsBusy) { return; } _loadingJobsBusy = true; } try { JenkinsOverview newOverview = await JenkinsManager.APIHandler.Managers.JenkinsManager.GetJenkinsOverview(SelectedJenkinsServer.Url); if (newOverview == null) { StatusMessage = "Could not fetch jobs overview"; LoadingFailed = true; return; } if (JOverview == null) { JOverview = newOverview; SelectedView = JOverview.Views.FirstOrDefault(); } else { foreach (var newView in newOverview.Views) { var existingView = JOverview.Views.FirstOrDefault((v) => string.Equals(v.Url, newView.Url)); if (existingView != null) { var existingJobs = existingView.Jobs; var newJobs = newView.Jobs; IEnumerable <Job> jobsToDelete = existingJobs.Except(newJobs, Job.JobComparer).ToArray(); IEnumerable <Job> jobsToAdd = newJobs.Except(existingJobs, Job.JobComparer).ToArray(); IEnumerable <Job> jobsToUpdate = newJobs.Intersect(existingJobs, Job.JobComparer).ToArray(); UIHelper.InvokeUI(() => { foreach (var job in jobsToDelete) { existingJobs.Remove(job); } foreach (var job in jobsToAdd) { existingJobs.Add(job); } foreach (var job in jobsToUpdate) { var existingJob = existingJobs.Intersect(new[] { job }, Job.JobComparer).Single(); existingJob.Building = job.Building; existingJob.Color = job.Color; existingJob.Name = job.Name; existingJob.Queued = job.Queued; } }); } } } LoadingFailed = false; StatusMessage = null; UpdateJobLinkedStatus(); } catch (Exception ex) { StatusMessage = ex.Message; LoadingFailed = true; } finally { lock (_loadingJobsBusyLock) { _loadingJobsBusy = false; } } }
/// <summary> /// Loads all job information /// </summary> /// <param name="jenkinsServerUrl">The url of the server, without any api paths (eg http://jenkins.cyanogenmod.com/)</param> /// <returns>The list of Jobs</returns> public async static Task <JenkinsOverview> GetJenkinsOverview(string jenkinsServerUrl) { JenkinsOverview overview = null; JenkinsQueue queue = null; JenkinsServer server = SettingManager.GetJenkinsServer(jenkinsServerUrl); if (server == null) { return(null); } using (WebClient wc = new WebClient()) { if (!string.IsNullOrWhiteSpace(server.UserName)) { // WebClient.Credentials can not be used, because those credentials will only be send to the server // when the server responds with a challenge from the server. Jenkins won't send this challenge as documented // on the wiki: https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients // We should use the "old fashion" way of setting the header manually string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", server.UserName, server.ApiToken))); wc.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials; } Uri baseUri = new Uri(jenkinsServerUrl); Task <string> jsonRawDataTask = wc.DownloadStringTaskAsync(new Uri(baseUri, "api/json?pretty=true&tree=views[name,url]")); if (await Task.WhenAny(jsonRawDataTask, Task.Delay(3000)) == jsonRawDataTask) { overview = JsonConvert.DeserializeObject <JenkinsOverview>(jsonRawDataTask.Result) ?? new JenkinsOverview(); string jsonQueueData = await wc.DownloadStringTaskAsync(new Uri(baseUri, "queue/api/json?pretty=true&tree=items[why,task[name,url,color]]")); queue = JsonConvert.DeserializeObject <JenkinsQueue>(jsonQueueData) ?? new JenkinsQueue(); queue.Items = queue.Items ?? new List <ScheduledJob>(); object allJobLock = new object(); var allJobs = new List <Job>(); foreach (var view in overview.Views.AsParallel()) { // Fix JSON problem which contains wrong url for primary view (is always the base url which contains // all builds, not just the ones for that view). if (!view.Url.Contains("/view/")) { view.Url = string.Format("{0}/view/{1}/", view.Url, view.Name); } JenkinsView viewData = await GetJenkinsView(jenkinsServerUrl, view.Url); if (viewData == null) { continue; } foreach (var job in viewData.Jobs) { lock (allJobLock) { var allJobsJob = allJobs.FirstOrDefault((j) => string.Equals(j.Url, job.Url)); if (allJobsJob != null) { view.Jobs.Add(allJobsJob); } else { view.Jobs.Add(job); allJobs.Add(job); } } } } overview.Jobs = ParseJobs(allJobs, queue); return(overview); } } return(new JenkinsOverview()); }