private WordPressResult UploadAudioFile(PodcastPost podcastPost) { Console.Write("Uploading the audio file... "); _logger.Info("Beginning upload of audio file"); WordPressResult result = _podcastService.UploadAudioFile(podcastPost.AudioFilePath); if (result.IsSuccess) { Console.WriteLine($"Success! (Id = {result.Id})"); _logger.Info($"Upload was successful - id = {result.Id}"); _logger.Info($"Audio file URL = {result.Url}"); } else { Console.WriteLine("Oh dear, it didn't work - here is the error: "); Console.WriteLine(result.ErrorMessage); Console.WriteLine("See the log file for more details..."); _logger.Error($"Upload failed with error: {result.ErrorMessage}"); //TODO need to capture the detailed error somehow } return(result); }
private string GetTitlePrefixedWithDate(PodcastPost podcastPost) { //e.g. 5th March 2017 – Hosting the Presence of God DateTime date = podcastPost.Date; return($"{date.Day}{GetDaySuffix(date.Day)} {GetMonthName(date.Month)} {date.Year} - {podcastPost.Title}"); }
public void UpdateRssFeed(PodcastPost podcastPost) { //1. search for the existing feed media item WordPressMedia media = _wordPressService.FindMediaByTitle("scfFeed"); //2. download the existing feed - get the URL from the item XDocument doc = GetRssFeedAsXml(media.source_url); //3. update it with the details of the new podcast AddPodcastItemToDocument(doc, podcastPost); //3.5 save a copy of the file locally SaveRssFeedLocally(doc); //4. delete the existing feed //http://windows7vm/wordpress/wp-json/wp/v2/media/2663?force=true WordPressResult deleteMediaResult = _wordPressService.DeleteMedia(media.id); if (!deleteMediaResult.IsSuccess) { throw new InvalidOperationException("Error deleting the existing RSS feed"); } //5. create the new one WordPressResult addMediaResult = _wordPressService.AddMedia("scfFeed.xml", "text/xml"); //http://windows7vm/wordpress/wp-json/wp/v2/media //6. download the media to make sure it is there //- validate it against a schema?? }
public WordPressResult CreatePodcastPost(PodcastPost podcastPost) { //1. read in template string templateText = ReadTemplate(); //2. make substitutions to template List <string> substitutions = new List <string> { podcastPost.Speaker, //{0} podcastPost.BibleText, //{1} podcastPost.GetFormattedDuration(), //{2} podcastPost.GetFormattedSize(), //{3} podcastPost.PodcastMediaUrl, //{4} podcastPost.Title //{5} }; string content = string.Format(templateText, substitutions.ToArray()); //3. call WordPress to add the post WordPressPost wordPressPost = new WordPressPost() { status = "publish", title = GetTitlePrefixedWithDate(podcastPost), content = content, date = podcastPost.Date.ToString("yyyy-MM-dd hh:mm:ss"), categories = new [] { _configurationService.Configuration.WordPressPodcastCategoryId }, author = _configurationService.Configuration.WordPressAuthorId, featured_media = podcastPost.FeaturedMediaId }; WordPressResult result = _wordPressService.AddPost(wordPressPost); //4. return result return(result); }
private void UpdateRssFeed(PodcastPost podcastPost) { Console.Write("Updating RSS feed... "); _logger.Info("Updating RSS feed"); _podcastService.UpdateRssFeed(podcastPost); Console.WriteLine("Success!"); _logger.Info("RSS feed updated"); }
static void Main(string[] args) { using (var context = new BlogContext()) { var videoPost = new VideoPost { Blog = new Blog { Name = "Blog1", Author = new Author { Name = "Jan Kowalski" } }, Title = "test", VideoUrl = "http://fake/adres" }; context.Add(videoPost); var podcastPost = new PodcastPost { Blog = new Blog { Name = "Blog2", Author = new Author { Name = "Jan Kowalski" } }, Title = "test", PodcastUrl = "http://fake/adres" }; context.Add(podcastPost); var textPost = new TextPost { Blog = new Blog { Name = "Blog3", Author = new Author { Name = "Jan Kowalski" } }, Title = "test", PostContent = "test" }; context.Add(textPost); context.SaveChanges(); } }
private XElement CreateRssFeedItemXElement(PodcastPost podcastPost) { string itemTemplate = ReadRssFeedItemTemplate(); string substitutedTemplate = string.Format(itemTemplate, GetTitlePrefixedWithDate(podcastPost), //0 podcastPost.Speaker, //1 podcastPost.PodcastPostUrl, //2 podcastPost.PodcastMediaUrl, //3 podcastPost.GetMediaSizeInBytes(), //4 podcastPost.GetDateInRssFormat() //5 ); return(XElement.Parse(substitutedTemplate)); }
private void AddPodcastItemToDocument(XDocument doc, PodcastPost podcastPost) { XElement newItemElem = CreateRssFeedItemXElement(podcastPost); XElement firstItem = doc.Descendants().FirstOrDefault(e => e.Name.LocalName == "item"); if (firstItem != null) { firstItem.AddBeforeSelf(newItemElem); } else { //no items... throw new InvalidOperationException("RSS feed does not contain any items - please upload a proper file"); } }
private PodcastPost LoadDetailsFromFile() { IConfigurationBuilder builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddIniFile("PodcastDetails.ini"); IConfigurationRoot config = builder.Build(); string title = config["PodcastDetails:Title"]; string speaker = config["PodcastDetails:Speaker"]; string bibleText = config["PodcastDetails:BibleText"]; string dateString = config["PodcastDetails:Date"]; string audioFilePath = config["PodcastDetails:AudioFilePath"]; string featuredMedia = config["PodcastDetails:FeaturedMedia"]; DateTime date; if (!DateTime.TryParseExact(dateString, new[] { "dd/MM/yyyy", "d/MM/yyyy", "dd/M/yyyy" }, null, DateTimeStyles.None, out date)) { throw new ArgumentException("The date in the PodcastDetails.ini file must be in the format dd/mm/yyyy e.g. 31/01/2017"); } PodcastPost podcastPost = new PodcastPost(_configurationService.Configuration) { Title = title, Speaker = speaker, BibleText = bibleText, Date = date.AddHours(11), //set the date to 11am AudioFilePath = audioFilePath }; int featuredMediaId; if (int.TryParse(featuredMedia, out featuredMediaId)) { podcastPost.FeaturedMediaId = featuredMediaId; } return(podcastPost); }
private PodcastPost PromptUserForPodcastDetails() { PodcastPost podcastPost = new PodcastPost(_configurationService.Configuration); Console.Write("Title: "); podcastPost.Title = Console.ReadLine(); _logger.Info("Title entered: " + podcastPost.Title); Console.Write("Speaker: "); podcastPost.Speaker = Console.ReadLine(); _logger.Info("Speaker entered: " + podcastPost.Speaker); Console.Write("Bible text(s): "); podcastPost.BibleText = Console.ReadLine(); _logger.Info("Bible text(s) entered: " + podcastPost.BibleText); podcastPost.Date = PromptForDate(); podcastPost.AudioFilePath = PromptForAudioFilePath(); return(podcastPost); }
private WordPressResult CreatePost(PodcastPost podcastPost) { Console.Write("Creating WordPress post... "); _logger.Info("Beginning creation of post"); WordPressResult result = _podcastService.CreatePodcastPost(podcastPost); if (result.IsSuccess) { Console.WriteLine($"Success! (Id = {result.Id})"); Console.WriteLine($"The URL of the new post is:\n{result.Url}"); _logger.Info($"Post creation succeeded - id = {result.Id}"); _logger.Info($"Post URL = {result.Url}"); } else { Console.WriteLine("Oh dear, it didn't work - here is the error: "); Console.WriteLine(result.ErrorMessage); Console.WriteLine("See the log file for more details..."); } return(result); }
private string CreateMp3File(string filepath, PodcastPost podcastPost) { if (filepath.EndsWith(".mp3")) { Console.WriteLine("Supplied audio file is MP3 file so skipping MP3 generation"); return(filepath); } //must be a WAV file, so create the MP3 Console.Write("Generating MP3 file - please be patient... "); try { string mp3Filepath = _podcastService.GenerateMp3File(filepath, podcastPost); Console.WriteLine("Success!"); return(mp3Filepath); } catch (System.Exception ex) { Console.WriteLine("Failed with error:"); Console.WriteLine(ex.Message); throw; } }
public string GenerateMp3File(string wavFilePath, PodcastPost podcastPost) { //1. create input file for ffmpeg string[] files = new [] { $"file '{_configurationService.Configuration.IntroWavFilePath}'", $"file '{wavFilePath}'" }; DirectoryInfo tempFolder = Directory.CreateDirectory("temp"); string filelistPath = Path.Combine(tempFolder.FullName, "filelist.txt"); _logger.Info($"Generating filelist.txt at: {filelistPath}"); File.WriteAllLines(filelistPath, files); //2. call ffmpeg to create the wav file string podcastWavFilepath = Path.Combine(tempFolder.FullName, "podcast.wav"); Process ffmpeg = new Process(); ffmpeg.StartInfo.FileName = _configurationService.Configuration.FfmpegPath; ffmpeg.StartInfo.Arguments = $"-y -f concat -safe 0 -i \"{filelistPath}\" -c copy \"{podcastWavFilepath}\""; ffmpeg.StartInfo.UseShellExecute = false; ffmpeg.StartInfo.RedirectStandardOutput = true; ffmpeg.StartInfo.RedirectStandardError = true; _logger.Info($"Calling ffmpeg to create WAV file with arguments: {ffmpeg.StartInfo.Arguments}"); ffmpeg.Start(); // string output = ffmpeg.StandardOutput.ReadToEnd(); string output = ffmpeg.StandardError.ReadToEnd(); _logger.InfoFormat($"Output from ffmpeg:\n{output}"); ffmpeg.WaitForExit(); _logger.Info("WAV file generation finished"); if (!File.Exists(podcastWavFilepath)) { throw new InvalidOperationException("Intermediate WAV file was not generated"); } //3. call ffmpeg to encode the generated file as an MP3 int bitrate = _configurationService.Configuration.VbrBitrate; string podcastFilename = $"SCF_{podcastPost.Date.ToString("yyyy-MM-dd")}.mp3"; string podcastFilePath = Path.Combine(_configurationService.Configuration.PodcastAudioFolder, podcastFilename); _logger.Info($"Ensuring output path exists: {_configurationService.Configuration.PodcastAudioFolder}"); Directory.CreateDirectory(_configurationService.Configuration.PodcastAudioFolder); _logger.Info($"MP3 file will be saved as: {podcastFilePath}"); //create the metadata file for the ID3 tags string metadataTemplate = File.ReadAllText(_configurationService.Configuration.FfmpegMetadataTemplatePath); string metadata = string.Format(metadataTemplate, podcastPost.Title, podcastPost.Speaker); string metadataFilepath = Path.Combine(tempFolder.FullName, "metadata.txt"); _logger.Info("Writing metadata file"); File.WriteAllText(metadataFilepath, metadata); ffmpeg = new Process(); ffmpeg.StartInfo.FileName = _configurationService.Configuration.FfmpegPath; ffmpeg.StartInfo.Arguments = $"-y -i \"{podcastWavFilepath}\" -i \"{metadataFilepath}\" -map_metadata 1 -c:a copy -id3v2_version 3 -write_id3v1 1 -codec:a libmp3lame -qscale:a {bitrate} \"{podcastFilePath}\""; ffmpeg.StartInfo.UseShellExecute = false; ffmpeg.StartInfo.RedirectStandardOutput = true; ffmpeg.StartInfo.RedirectStandardError = true; _logger.Info($"Calling ffmpeg to create MP3 file with arguments: {ffmpeg.StartInfo.Arguments}"); ffmpeg.Start(); // string output = ffmpeg.StandardOutput.ReadToEnd(); output = ffmpeg.StandardError.ReadToEnd(); _logger.InfoFormat($"Output from ffmpeg:\n{output}"); ffmpeg.WaitForExit(); _logger.Info("MP3 file generation finished"); if (!File.Exists(podcastFilePath)) { throw new InvalidOperationException("MP3 file was not generated"); } //5. if all went well, tidy up try { tempFolder.Delete(true); } catch (Exception ex) { _logger.Warn("Could not delete temp folder", ex); } return(podcastFilePath); }