/// <summary> /// High level method that posts a Post to Medium including uploading of /// images. /// </summary> /// <param name="post">An instance of the post to post to the server</param> /// <param name="publicationId">Publication/Blog id</param> /// <param name="documentBasePath">Base path for images to find relatively pathed images</param> /// <returns></returns> public MediumPost PublishCompletePost(Post post, string documentBasePath = null, bool sendasDraft = false) { var mediumPost = new MediumPost { title = post.Title, content = post.Body, contentFormat = "html", publishStatus = sendasDraft ? "draft" : "public", tags = post.Tags }; if (!GetUser()) { return(null); } if (!PublishPostImages(mediumPost, documentBasePath)) { return(null); } return(PublishPost(mediumPost, WeblogInfo.BlogId.ToString())); }
/// <summary> /// Returns the Image Url from the Post operation /// </summary> /// <param name="post"></param> /// <param name="userId"></param> /// <returns></returns> public MediumPost PublishPost(MediumPost post, string publicationId = null) { if (string.IsNullOrEmpty(UserId)) { ErrorMessage = "UserId has not been set yet. Make sure to call GetUser first."; return(null); } var settings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented }; var json = JsonConvert.SerializeObject(post, settings); string url = MediumApiUrl + "users/" + UserId + "/posts"; if (!string.IsNullOrEmpty(publicationId)) { url = MediumApiUrl + "publications/" + publicationId + "/posts"; } var http = CreateHttpClient(url, json); var httpResult = http.DownloadString(url); if (http.Error) { ErrorMessage = http.ErrorMessage; return(null); } if (httpResult.Contains("\"errors\":")) { //{ "errors":[{"message":"Publication does not exist or user not allowed to publish in it","code":2006}]} var errorResult = JsonConvert.DeserializeObject <ErrorResult>(httpResult); StringBuilder sb = new StringBuilder(); foreach (var err in errorResult.errors) { sb.AppendLine(err.message); } ErrorMessage = sb.ToString(); return(null); } var postResult = JsonConvert.DeserializeObject <MediumPostResult>(httpResult); if (postResult.data == null) { ErrorMessage = "Unable to parse publishing API response."; return(null); } this.PostUrl = postResult.data.url; return(postResult.data); }
/// <summary> /// Scans the HTML document and uploads any local files to the Medium /// API and returns URL that are embedded as http links into the document /// </summary> /// <param name="post"></param> /// <param name="basePath"></param> /// <returns></returns> bool PublishPostImages(MediumPost post, string basePath) { // base folder name for uploads - just the folder name of the image var baseName = Path.GetFileName(basePath); baseName = FileUtils.SafeFilename(baseName).Replace(" ", "-"); var doc = new HtmlDocument(); doc.LoadHtml(post.content); try { // send up normalized path images as separate media items var images = doc.DocumentNode.SelectNodes("//img"); if (images != null) { foreach (HtmlNode img in images) { string imgFile = img.Attributes["src"]?.Value as string; if (imgFile == null) { continue; } if (!imgFile.StartsWith("http://") && !imgFile.StartsWith("https://")) { if (!imgFile.Contains(":\\")) { imgFile = Path.Combine(basePath, imgFile.Replace("/", "\\")); } if (File.Exists(imgFile)) { var imgUrl = PublishImage(imgFile); img.Attributes["src"].Value = imgUrl; } } } post.content = doc.DocumentNode.OuterHtml; } } catch (Exception ex) { ErrorMessage = "Error posting images to Medium: " + ex.Message; return(false); } return(true); }