/// <summary> /// Compares this instance to a specified Episode and returns an indication of their relative values. /// </summary> /// <param name="episode">Episode to compare</param> /// <returns>Comparison value used for sorting</returns> public int CompareTo(Episode episode) { // use episode number first, but if they're the same then use the date first aired. int num = Number.CompareTo(episode.Number); return num == 0 ? FirstAired.CompareTo(episode.FirstAired) : num; }
/// <summary> /// Check whether the specified episode is recorded. /// </summary> /// <param name="e">Episode to find</param> /// <returns>True if the specified Episode is recorded</returns> public bool Contains(Episode e) { return Shows.Contains(e.Season.Show) && e.Season.Show.Seasons.Contains(e.Season) && e.Season.Episodes.Contains(e); }
/// <summary> /// Get the list of recordings from the MythTV backend. /// </summary> public void Refresh() { XmlDocument xml = new XmlDocument(); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(string.Format(GET_LIST, _mythHost, _mythPort)); using(HttpWebResponse res = (HttpWebResponse)req.GetResponse()) using(Stream s = res.GetResponseStream()) { xml.Load(s); Shows.Clear(); XmlElement programList = xml["ProgramList"]; XmlElement programs = programList["Programs"]; foreach(XmlNode node in programs.ChildNodes) if(node.NodeType == XmlNodeType.Element && node.Name == "Program") { XmlElement program = (XmlElement)node; if(!program.ElementValue("Recording/RecGroup").Equals("Deleted", System.StringComparison.CurrentCultureIgnoreCase)) { Show show = GetShow(program.ElementValue("Title")); Season season = show.GetSeason(program.ElementValue("Season"), FindCoverArt(program)); Episode episode = new Episode(season, program.ElementValue("Recording/RecordedId"), program.ElementValue("FileName"), program.ElementValue("SubTitle"), program.ElementValue("Episode"), program.ElementValue("Airdate"), program.ElementValue("StartTime"), program.ElementValue("EndTime"), program.ElementValue("Recording/Status") ); season.Episodes.Add(episode); } } } Sort(); }
/// <summary> /// Play the specified Episode using a player selected from the Open With dialog. /// </summary> /// <param name="e">Episode to play</param> private void PlayEpisodeWith(Episode e) { Process.Start("rundll32.exe", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "shell32.dll") + ",OpenAs_RunDLL " + Path.Combine(_settings.RawFilesDirectory, e.Filename)); }
/// <summary> /// Show the info panel with information for the specified Episode. /// </summary> /// <param name="e">Episode to display</param> private void ShowEpisodeInfo(Episode e) { _pnlInfo.Controls.Clear(); _pnlInfo.Tag = e; string title = string.IsNullOrEmpty(e.Name) ? string.Format(Properties.Resources.InfoEpisodeTitleNameless, e.Season.Show.Title, e.FirstAired) : string.Format(Properties.Resources.InfoEpisodeTitle, e.Season.Show.Title, e.Name); _pnlInfo.Controls.Add(MakeInfoTitleLabel(title)); if(e.InProgress) { Label lbl = MakeInfoLabel(string.Format(Properties.Resources.InfoEpisodeStillRecording, (e.DoneRecording - DateTime.Now).ToStringUnit())); lbl.ForeColor = Color.Red; _pnlInfo.Controls.Add(lbl); } if(e.Season.Number > 0) _pnlInfo.Controls.Add(MakeInfoLabel(string.Format(Properties.Resources.InfoEpisodeSeasonEpisode, e.Season.Number, e.Number))); if(e.FirstAired != e.Recorded) _pnlInfo.Controls.Add(MakeInfoLabel(string.Format(Properties.Resources.InfoEpisodeFirstAired, e.FirstAired))); _pnlInfo.Controls.Add(MakeInfoLabel(string.Format(Properties.Resources.InfoEpisodeRecorded, e.Recorded))); _pnlInfo.Controls.Add(MakeInfoLabel(e.Duration.ToStringUnit())); _pnlInfo.Controls.Add(MakeInfoAction(Properties.Resources.Play18, Properties.Resources.ActionPlay, string.Format(Properties.Resources.TipPlay, title), btnEpisodePlay_Click)); _pnlInfo.Controls.Add(MakeInfoAction(Properties.Resources.PlayWith18, Properties.Resources.ActionPlayWith, string.Format(Properties.Resources.TipPlayWith, title), btnEpisodePlayWith_Click)); _pnlInfo.Controls.Add(MakeInfoAction(Properties.Resources.Export18, Properties.Resources.ActionExport, string.Format(Properties.Resources.TipExportEpisode, title), btnEpisodeExport_Click)); _pnlInfo.Controls.Add(MakeInfoAction(Properties.Resources.Delete18, Properties.Resources.ActionDelete, string.Format(Properties.Resources.TipDelete, title), btnEpisodeDelete_Click)); }
/// <summary> /// Export a single Episode to the specified path with the specified /// filename format. /// </summary> /// <param name="e">Episode to export</param> /// <param name="exportPath">Path to save Episode</param> /// <param name="nameFormat">Filename format to use</param> private void ExportEpisodeTo(Episode e, string exportPath, string nameFormat, FileOperation fo) { FileInfo fi = new FileInfo(Path.Combine(_settings.RawFilesDirectory, e.Filename)); fo.QueueFileCopy(fi, exportPath, SanitizeFilename(string.Format(nameFormat, e.Season.Show.Title, e.Name, e.FirstAired, e.Season.Number, e.Number)) + fi.Extension); }
/// <summary> /// Play the specified Episode using the default player. /// </summary> /// <param name="e">Episode to play</param> private void PlayEpisode(Episode e) { Process.Start(Path.Combine(_settings.RawFilesDirectory, e.Filename)); }
/// <summary> /// Export the specified Episode with a readable filename to the specified /// path with the specified filename format. /// </summary> /// <param name="e">Episode to export</param> /// <param name="exportPath">Path to save exported episode</param> /// <param name="nameFormat">Name format for exported episode</param> private void ExportEpisode(Episode e, string exportPath, string nameFormat) { using(FileOperation fo = new FileOperation()) ExportEpisodeTo(e, exportPath, nameFormat, fo); }
/// <summary> /// Export the specified Episode with a readable filename. /// </summary> /// <param name="e">Episode to export</param> private void ExportEpisode(Episode e) { string nameFormat, exportPath; if(AskExportDetails(e, false, out nameFormat, out exportPath)) { Thread exportThread = new Thread(() => ExportEpisode(e, exportPath, nameFormat)); exportThread.TrySetApartmentState(ApartmentState.MTA); exportThread.Name = "ExportEpisode"; exportThread.Start(); } }
/// <summary> /// Delete the specified Episode. /// </summary> /// <param name="e">Episode to delete</param> private void DeleteEpisode(Episode e) { TaskDialog td = new TaskDialog(); td.WindowTitle = Properties.Resources.TitleDelete; td.MainInstruction = Properties.Resources.InstrDelete; td.Content = Properties.Resources.NoteDelete; td.CommonButtons = TaskDialogCommonButtons.Cancel; td.Buttons = new TaskDialogButton[] { new TaskDialogButton(80, string.Format(Properties.Resources.DeleteOption, "\n")), new TaskDialogButton(81, string.Format(Properties.Resources.DeleteRerecordOption, "\n")) }; td.DefaultButton = 80; td.PositionRelativeToWindow = true; td.UseCommandLinks = true; int btnid = td.Show(this); if(btnid >= 80) if(e.Delete(btnid == 81)) if(_selected != null) if(_selected.Tag is Episode) if(_pnlMain.Controls.Count > 1) { int pos = _pnlMain.Controls.IndexOf(_selected); _pnlMain.Controls.Remove(_selected); if(pos < _pnlMain.Controls.Count) Select(_pnlMain.Controls[pos]); else Select(_pnlMain.Controls[pos - 1]); } else if(_recordings.Contains(e.Season.Show)) ListSeasons(e.Season.Show); else ListShows(); else ShowInfo(_selected.Tag); }
/// <summary> /// Show a dialog to choose a filename format with examples and available /// options based on the specified episode. /// </summary> /// <param name="e">Episode to determine available options and use for examples</param> /// <param name="plural">Whether more than one episode will be exported</param> /// <returns>Chosen filename format, or null if canceled</returns> private string AskExportFileFormat(Episode e, bool plural) { TaskDialog td = new TaskDialog(); td.WindowTitle = plural ? Properties.Resources.TitleExportPlural : Properties.Resources.TitleExportOne; td.MainInstruction = Properties.Resources.InstrExport; td.Content = Properties.Resources.NoteExport; td.CommonButtons = TaskDialogCommonButtons.Cancel; List<TaskDialogButton> buttons = new List<TaskDialogButton>(); if(string.IsNullOrEmpty(e.Name)) { buttons.Add(new TaskDialogButton(83, Properties.Resources.ExportOptionYear + "\n" + SanitizeFilename(string.Format(Properties.Resources.ExportYear, e.Season.Show.Title, e.Name, e.FirstAired, e.Season.Number, e.Number)))); buttons.Add(new TaskDialogButton(84, Properties.Resources.ExportOptionDate + "\n" + SanitizeFilename(string.Format(Properties.Resources.ExportDate, e.Season.Show.Title, e.Name, e.FirstAired, e.Season.Number, e.Number)))); buttons.Add(new TaskDialogButton(85, Properties.Resources.ExportOptionTitle + "\n" + SanitizeFilename(string.Format(Properties.Resources.ExportTitle, e.Season.Show.Title, e.Name, e.FirstAired, e.Season.Number, e.Number)))); } else { if(e.Season.Number > 0 && e.Number > 0) buttons.Add(new TaskDialogButton(80, Properties.Resources.ExportOptionSeasonEpisode + "\n" + SanitizeFilename(string.Format(Properties.Resources.ExportSeasonEpisode, e.Season.Show.Title, e.Name, e.FirstAired, e.Season.Number, e.Number)))); buttons.Add(new TaskDialogButton(81, Properties.Resources.ExportOptionDateEpisode + "\n" + SanitizeFilename(string.Format(Properties.Resources.ExportDateEpisode, e.Season.Show.Title, e.Name, e.FirstAired, e.Season.Number, e.Number)))); buttons.Add(new TaskDialogButton(82, Properties.Resources.ExportOptionEpisode + "\n" + SanitizeFilename(string.Format(Properties.Resources.ExportEpisode, e.Season.Show.Title, e.Name, e.FirstAired, e.Season.Number, e.Number)))); } td.Buttons = buttons.ToArray(); td.PositionRelativeToWindow = true; td.UseCommandLinks = true; switch(td.Show(this)) { case 80: return Properties.Resources.ExportSeasonEpisode; case 81: return Properties.Resources.ExportDateEpisode; case 82: return Properties.Resources.ExportEpisode; case 83: return Properties.Resources.ExportYear; case 84: return Properties.Resources.ExportDate; case 85: return Properties.Resources.ExportTitle; default: return null; } }
/// <summary> /// Prompt for choices needed to export episodes: filename format and /// export path. /// </summary> /// <param name="exampleEpisode">Episode to determine available options and use for examples</param> /// <param name="plural">Whether more than one episode will be exported</param> /// <param name="filenameFormat">Chosen filename format, or null if canceled</param> /// <param name="exportPath">Chosen export path, or null if canceled</param> /// <returns>True if all details have been chosen without cancelling</returns> private bool AskExportDetails(Episode exampleEpisode, bool plural, out string filenameFormat, out string exportPath) { exportPath = null; filenameFormat = AskExportFileFormat(exampleEpisode, plural); if(string.IsNullOrEmpty(filenameFormat)) return false; _dlgExportFolder.SelectedPath = _settings.LastExportDirectory; switch(_dlgExportFolder.ShowDialog(this)) { case DialogResult.OK: case DialogResult.Yes: exportPath = _settings.LastExportDirectory = _dlgExportFolder.SelectedPath; return true; default: return false; } }