471 lines
19 KiB
C#
471 lines
19 KiB
C#
|
using Newtonsoft.Json;
|
|||
|
using Publisher.Models;
|
|||
|
using Publisher.Models.Confluence;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Net;
|
|||
|
using System.Net.Http;
|
|||
|
using System.Text;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace Publisher.Services
|
|||
|
{
|
|||
|
public class Confluence
|
|||
|
{
|
|||
|
private string Username;
|
|||
|
private string Password;
|
|||
|
private string Host;
|
|||
|
|
|||
|
public delegate void StatusUpdateHandler(object sender, StatusUpdateArgs e);
|
|||
|
public event StatusUpdateHandler OnUpdateStatus;
|
|||
|
|
|||
|
public Confluence(string host, string username, string password)
|
|||
|
{
|
|||
|
this.Host = host;
|
|||
|
this.Username = username;
|
|||
|
this.Password = password;
|
|||
|
}
|
|||
|
|
|||
|
public bool DeletePage(int pageId)
|
|||
|
{
|
|||
|
bool result = false;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
string auth = this.GetAuth();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(this.Host) && !string.IsNullOrEmpty(auth) && pageId > 0)
|
|||
|
{
|
|||
|
string url = this.Host + "/rest/api/content/" + pageId.ToString();
|
|||
|
|
|||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
|
|||
|
|
|||
|
webRequest.Method = "DELETE";
|
|||
|
webRequest.Headers.Add("Authorization", auth);
|
|||
|
webRequest.ContentType = "application/json; charset=utf-8";
|
|||
|
webRequest.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
|
|||
|
|
|||
|
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
|
|||
|
result = response.StatusCode == HttpStatusCode.NoContent;
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public ResponsePage UpdatePage(string title, string spaceKey, string pageId, string bodyHTML)
|
|||
|
{
|
|||
|
ResponsePage result = null;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
string auth = this.GetAuth();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(this.Host) && !string.IsNullOrEmpty(auth) && !string.IsNullOrEmpty(title) && !string.IsNullOrEmpty(pageId))
|
|||
|
{
|
|||
|
string url = this.Host + "/rest/api/content/" + pageId.ToString();
|
|||
|
|
|||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
|
|||
|
|
|||
|
webRequest.Method = "PUT";
|
|||
|
webRequest.Headers.Add("Authorization", auth);
|
|||
|
webRequest.ContentType = "application/json; charset=utf-8";
|
|||
|
webRequest.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
|
|||
|
|
|||
|
using (Stream stream = webRequest.GetRequestStream())
|
|||
|
{
|
|||
|
Content content = new Content();
|
|||
|
content.title = title;
|
|||
|
content.version = new ContentVersion();
|
|||
|
content.version.number = 2;
|
|||
|
content.id = pageId;
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(spaceKey))
|
|||
|
{
|
|||
|
content.space = new Space();
|
|||
|
content.space.key = spaceKey;
|
|||
|
}
|
|||
|
|
|||
|
content.body = new Body();
|
|||
|
content.body.storage = new Storage();
|
|||
|
content.body.storage.value = bodyHTML;
|
|||
|
|
|||
|
string dataJSON = JsonConvert.SerializeObject(content);
|
|||
|
byte[] data = Encoding.UTF8.GetBytes(dataJSON);
|
|||
|
stream.Write(data, 0, data.Length);
|
|||
|
}
|
|||
|
|
|||
|
WebResponse response = (HttpWebResponse)webRequest.GetResponse();
|
|||
|
|
|||
|
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(json))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
result = JsonConvert.DeserializeObject<ResponsePage>(json);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Response res = JsonConvert.DeserializeObject<Response>(json);
|
|||
|
|
|||
|
if (res != null)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", res.reason));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex1)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public void DeleteOldChildPages(int parentPageId, int limit = 5)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string auth = this.GetAuth();
|
|||
|
|
|||
|
Models.Confluence.Page[] childPages = this.GetChildPages(parentPageId);
|
|||
|
|
|||
|
if (childPages != null && childPages.Length > 0)
|
|||
|
{
|
|||
|
List<Models.Confluence.Page> sortChildPages = new List<Page>(childPages);
|
|||
|
sortChildPages = sortChildPages.OrderByDescending(m => m.id).ToList();
|
|||
|
|
|||
|
for(int i = 0; i < sortChildPages.Count; i++)
|
|||
|
{
|
|||
|
if(i >= limit)
|
|||
|
{
|
|||
|
this.DeletePage(sortChildPages[i].id);
|
|||
|
Thread.Sleep(1000);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public Models.Confluence.Page[] GetChildPages(int parentPageId)
|
|||
|
{
|
|||
|
Models.Confluence.Page[] result = null;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
string auth = this.GetAuth();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(this.Host) && !string.IsNullOrEmpty(auth))
|
|||
|
{
|
|||
|
string url = this.Host + "/rest/api/content/" + parentPageId.ToString() + "/child/page";
|
|||
|
|
|||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
|
|||
|
|
|||
|
webRequest.Method = "GET";
|
|||
|
webRequest.Headers.Add("Authorization", auth);
|
|||
|
webRequest.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
|
|||
|
WebResponse response = (HttpWebResponse)webRequest.GetResponse();
|
|||
|
|
|||
|
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(json))
|
|||
|
{
|
|||
|
SearchResults searchResults = JsonConvert.DeserializeObject<Models.Confluence.SearchResults>(json);
|
|||
|
|
|||
|
if (searchResults != null && searchResults.results != null && searchResults.results.Length > 0)
|
|||
|
{
|
|||
|
result = searchResults.results;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public ResponsePage CreatePage(string title, string spaceKey, string bodyHTML, int? parentPageId = null)
|
|||
|
{
|
|||
|
ResponsePage result = null;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
string auth = this.GetAuth();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(this.Host) && !string.IsNullOrEmpty(auth) && !string.IsNullOrEmpty(title))
|
|||
|
{
|
|||
|
string url = this.Host + "/rest/api/content/";
|
|||
|
|
|||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
|
|||
|
|
|||
|
webRequest.Method = "POST";
|
|||
|
webRequest.Headers.Add("Authorization", auth);
|
|||
|
webRequest.ContentType = "application/json; charset=utf-8";
|
|||
|
webRequest.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
|
|||
|
|
|||
|
using (Stream stream = webRequest.GetRequestStream())
|
|||
|
{
|
|||
|
Content content = new Content();
|
|||
|
content.title = title;
|
|||
|
|
|||
|
if(!string.IsNullOrEmpty(spaceKey))
|
|||
|
{
|
|||
|
content.space = new Space();
|
|||
|
content.space.key = spaceKey;
|
|||
|
}
|
|||
|
|
|||
|
if(parentPageId.HasValue)
|
|||
|
{
|
|||
|
content.ancestors = new Ancestors[] { new Ancestors() { id = parentPageId.Value } };
|
|||
|
}
|
|||
|
|
|||
|
content.body = new Body();
|
|||
|
content.body.storage = new Storage();
|
|||
|
content.body.storage.value = bodyHTML;
|
|||
|
|
|||
|
string dataJSON = JsonConvert.SerializeObject(content);
|
|||
|
byte[] data = Encoding.UTF8.GetBytes(dataJSON);
|
|||
|
stream.Write(data, 0, data.Length);
|
|||
|
}
|
|||
|
|
|||
|
WebResponse response = (HttpWebResponse)webRequest.GetResponse();
|
|||
|
|
|||
|
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(json))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
result = JsonConvert.DeserializeObject<ResponsePage>(json);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Response res = JsonConvert.DeserializeObject<Response>(json);
|
|||
|
|
|||
|
if(res != null)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", res.reason));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex1)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public ResponseAttachment AddAttachment(string pageId, string file, string content_type, string comment = null)
|
|||
|
{
|
|||
|
ResponseAttachment result = null;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
string auth = this.GetAuth();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(this.Host) && !string.IsNullOrEmpty(auth) && !string.IsNullOrEmpty(file) && File.Exists(file))
|
|||
|
{
|
|||
|
string url = this.Host + "/rest/api/content/" + pageId.ToString() + "/child/attachment";
|
|||
|
|
|||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
|
|||
|
webRequest.CookieContainer = new CookieContainer();
|
|||
|
webRequest.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
|
|||
|
|
|||
|
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
|
|||
|
webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
|
|||
|
webRequest.Method = "POST";
|
|||
|
webRequest.Headers.Add("Authorization", auth);
|
|||
|
webRequest.Headers.Add("X-Atlassian-Token", "no-check");
|
|||
|
boundary = "--" + boundary;
|
|||
|
|
|||
|
using (Stream stream = webRequest.GetRequestStream())
|
|||
|
{
|
|||
|
if(!string.IsNullOrEmpty(comment))
|
|||
|
{
|
|||
|
byte[] comment_bytes = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
|
|||
|
stream.Write(comment_bytes, 0, comment_bytes.Length);
|
|||
|
comment_bytes = Encoding.ASCII.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{1}", "comment", Environment.NewLine));
|
|||
|
stream.Write(comment_bytes, 0, comment_bytes.Length);
|
|||
|
comment_bytes = Encoding.UTF8.GetBytes(comment + Environment.NewLine);
|
|||
|
stream.Write(comment_bytes, 0, comment_bytes.Length);
|
|||
|
}
|
|||
|
|
|||
|
// Write the files
|
|||
|
var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
|
|||
|
stream.Write(buffer, 0, buffer.Length);
|
|||
|
buffer = Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"{2}", "file", Path.GetFileName(file), Environment.NewLine));
|
|||
|
stream.Write(buffer, 0, buffer.Length);
|
|||
|
buffer = Encoding.ASCII.GetBytes(string.Format("Content-Type: {0}{1}{1}", content_type, Environment.NewLine));
|
|||
|
stream.Write(buffer, 0, buffer.Length);
|
|||
|
byte[] file_bytes = File.ReadAllBytes(file);
|
|||
|
stream.Write(file_bytes, 0, file_bytes.Length);
|
|||
|
buffer = Encoding.ASCII.GetBytes(Environment.NewLine);
|
|||
|
stream.Write(buffer, 0, buffer.Length);
|
|||
|
|
|||
|
byte[] boundaryBuffer = Encoding.ASCII.GetBytes(boundary + "--");
|
|||
|
stream.Write(boundaryBuffer, 0, boundaryBuffer.Length);
|
|||
|
}
|
|||
|
|
|||
|
WebResponse response = (HttpWebResponse)webRequest.GetResponse();
|
|||
|
|
|||
|
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(json))
|
|||
|
{
|
|||
|
ResponseAttachments attachments = JsonConvert.DeserializeObject<Models.Confluence.ResponseAttachments>(json);
|
|||
|
|
|||
|
if(attachments != null && attachments.results != null && attachments.results.Length > 0)
|
|||
|
{
|
|||
|
result = attachments.results[0];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public Page[] SearchPages(string title = null, string spaceKey = null)
|
|||
|
{
|
|||
|
Models.Confluence.Page[] result = null;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
string auth = this.GetAuth();
|
|||
|
|
|||
|
if(!string.IsNullOrEmpty(this.Host) && !string.IsNullOrEmpty(auth))
|
|||
|
{
|
|||
|
string param = null;
|
|||
|
|
|||
|
if(!string.IsNullOrEmpty(title))
|
|||
|
{
|
|||
|
param = "title=" + title;
|
|||
|
}
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(spaceKey))
|
|||
|
{
|
|||
|
if(!string.IsNullOrEmpty(param))
|
|||
|
{
|
|||
|
param = param + "&spaceKey=" + spaceKey;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
param = "spaceKey=" + spaceKey;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
string url = this.Host + "/rest/api/content/" + (!string.IsNullOrEmpty(param) ? "?" + param : "");
|
|||
|
|
|||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
|
|||
|
|
|||
|
webRequest.Method = "GET";
|
|||
|
webRequest.Headers.Add("Authorization", auth);
|
|||
|
webRequest.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
|
|||
|
WebResponse response = (HttpWebResponse)webRequest.GetResponse();
|
|||
|
|
|||
|
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
|
|||
|
|
|||
|
if(!string.IsNullOrEmpty(json))
|
|||
|
{
|
|||
|
SearchResults searchResults = JsonConvert.DeserializeObject<Models.Confluence.SearchResults>(json);
|
|||
|
|
|||
|
if(searchResults != null && searchResults.results != null && searchResults.results.Length > 0)
|
|||
|
{
|
|||
|
result = searchResults.results;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
if (OnUpdateStatus != null)
|
|||
|
{
|
|||
|
OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private string GetAuth()
|
|||
|
{
|
|||
|
string result = null;
|
|||
|
|
|||
|
if(!string.IsNullOrEmpty(this.Username) && !string.IsNullOrEmpty(this.Password))
|
|||
|
{
|
|||
|
result = "Basic " + System.Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(this.Username + ":" + this.Password));
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|