From 0ea262b7554889b6b997e9f011ab60bdfe3ea814 Mon Sep 17 00:00:00 2001 From: Mark Summerville Date: Thu, 8 Feb 2018 20:58:15 +0800 Subject: [PATCH 1/5] Assembly Update --- TVRename#/Properties/AssemblyInfo.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TVRename#/Properties/AssemblyInfo.cs b/TVRename#/Properties/AssemblyInfo.cs index 5c1e03c17..5aa0f61f8 100644 --- a/TVRename#/Properties/AssemblyInfo.cs +++ b/TVRename#/Properties/AssemblyInfo.cs @@ -14,6 +14,6 @@ [assembly: Guid("3b5746c1-a5f7-48c2-a8de-95619489049b")] [assembly: NeutralResourcesLanguageAttribute("")] -[assembly: AssemblyVersion("2.3.2.0")] -[assembly: AssemblyFileVersion("2.3.2")] -[assembly: AssemblyInformationalVersion("2.3.2 rc2")] // Display version +[assembly: AssemblyVersion("2.3.3.0")] +[assembly: AssemblyFileVersion("2.3.3")] +[assembly: AssemblyInformationalVersion("2.3.3")] // Display version From b65f0d4ddcafbe27479487c5b94fd5a8c62135fd Mon Sep 17 00:00:00 2001 From: Mark Summerville Date: Thu, 8 Feb 2018 23:09:43 +0800 Subject: [PATCH 2/5] Fix for #325 --- .../DownloadMede8erMetaData.cs | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/TVRename#/DownloadIdentifers/DownloadMede8erMetaData.cs b/TVRename#/DownloadIdentifers/DownloadMede8erMetaData.cs index 56e956116..7df6aa729 100644 --- a/TVRename#/DownloadIdentifers/DownloadMede8erMetaData.cs +++ b/TVRename#/DownloadIdentifers/DownloadMede8erMetaData.cs @@ -10,8 +10,8 @@ namespace TVRename { class DownloadMede8erMetaData : DownloadIdentifier { - - public DownloadMede8erMetaData() + private List doneFiles; + public DownloadMede8erMetaData() { reset(); } @@ -21,7 +21,7 @@ public override DownloadType GetDownloadType() return DownloadType.downloadMetaData; } - public override ItemList ProcessShow(ShowItem si,bool forceRefresh) + public override ItemList ProcessShow(ShowItem si, bool forceRefresh) { if (TVSettings.Instance.Mede8erXML) { @@ -32,12 +32,20 @@ public override ItemList ProcessShow(ShowItem si,bool forceRefresh) bool needUpdate = !tvshowxml.Exists || (si.TheSeries().Srv_LastUpdated > TimeZone.Epoch(tvshowxml.LastWriteTime)); - if (forceRefresh || needUpdate) + if ((forceRefresh || needUpdate) && (!this.doneFiles.Contains(tvshowxml.FullName))) + { + this.doneFiles.Add(tvshowxml.FullName); TheActionList.Add(new ActionMede8erXML(tvshowxml, si)); + } + //Updates requested by zakwaan@gmail.com on 18/4/2013 FileInfo viewxml = FileHelper.FileInFolder(si.AutoAdd_FolderBase, "view.xml"); - if (!viewxml.Exists) TheActionList.Add(new ActionMede8erViewXML(viewxml,si)); + if ((!viewxml.Exists) && (!this.doneFiles.Contains(viewxml.FullName))) + { + this.doneFiles.Add(viewxml.FullName); + TheActionList.Add(new ActionMede8erViewXML(viewxml, si)); + } return TheActionList; @@ -54,7 +62,7 @@ public override ItemList ProcessSeason(ShowItem si, string folder, int snum, boo //Updates requested by zakwaan@gmail.com on 18/4/2013 FileInfo viewxml = FileHelper.FileInFolder(folder, "view.xml"); - if (!viewxml.Exists) TheActionList.Add(new ActionMede8erViewXML(viewxml,si,snum)); + if (!viewxml.Exists) TheActionList.Add(new ActionMede8erViewXML(viewxml, si, snum)); return TheActionList; @@ -84,7 +92,8 @@ public override ItemList ProcessEpisode(ProcessedEpisode dbep, FileInfo filo, bo public override void reset() { - base.reset(); + this.doneFiles = new List(); + base.reset(); } } From 10a0892557bd1ddf1cf2bb5202bd7955d8f94abb Mon Sep 17 00:00:00 2001 From: Mark Summerville Date: Sun, 11 Feb 2018 23:21:27 +0800 Subject: [PATCH 3/5] Fix for https://groups.google.com/forum/#!topic/tvrename/UGXqijwumEY --- TVRename#/ItemsAndActions/ActionDelete.cs | 107 +++++++++++----------- 1 file changed, 51 insertions(+), 56 deletions(-) diff --git a/TVRename#/ItemsAndActions/ActionDelete.cs b/TVRename#/ItemsAndActions/ActionDelete.cs index 072beb901..588bb8947 100644 --- a/TVRename#/ItemsAndActions/ActionDelete.cs +++ b/TVRename#/ItemsAndActions/ActionDelete.cs @@ -1,25 +1,11 @@ -using System; -using System.CodeDom; -using System.Diagnostics; using Alphaleonis.Win32.Filesystem; -using System.IO.MemoryMappedFiles; -using System.Linq; -using System.Security.AccessControl; -using System.Threading; -using System.Web.UI.WebControls; -using System.Windows.Forms; namespace TVRename { using System; - using Alphaleonis.Win32.Filesystem; using System.Windows.Forms; - using System.IO; - - using File = Alphaleonis.Win32.Filesystem.File; - using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo; - using FileSystemInfo = Alphaleonis.Win32.Filesystem.FileSystemInfo; - using DirectoryInfo = Alphaleonis.Win32.Filesystem.DirectoryInfo; + using FileInfo = FileInfo; + using DirectoryInfo = DirectoryInfo; public abstract class ActionDelete : ActionFileOperation { @@ -37,7 +23,7 @@ public override ListViewItem ScanListViewItem { ListViewItem lvi = new ListViewItem(); - if (Episode == null) + if (this.Episode == null) { lvi.Text = ""; lvi.SubItems.Add(""); @@ -47,10 +33,10 @@ public override ListViewItem ScanListViewItem } else { - lvi.Text = Episode.TheSeries.Name; - lvi.SubItems.Add(Episode.SeasonNumber.ToString()); - lvi.SubItems.Add(Episode.NumsAsString()); - DateTime? dt = Episode.GetAirDateDT(true); + lvi.Text = this.Episode.TheSeries.Name; + lvi.SubItems.Add(this.Episode.SeasonNumber.ToString()); + lvi.SubItems.Add(this.Episode.NumsAsString()); + DateTime? dt = this.Episode.GetAirDateDT(true); if ((dt != null) && (dt.Value.CompareTo(DateTime.MaxValue) != 0)) lvi.SubItems.Add(dt.Value.ToShortDateString()); else @@ -71,58 +57,58 @@ public override ListViewItem ScanListViewItem public class ActionDeleteFile : ActionDelete { - public FileInfo toRemove; + private readonly FileInfo toRemove; public ActionDeleteFile(FileInfo remove, ProcessedEpisode ep, TidySettings tidyup) { - _tidyup = tidyup; - PercentDone = 0; - Episode = ep; - toRemove = remove; + this._tidyup = tidyup; + this.PercentDone = 0; + this.Episode = ep; + this.toRemove = remove; } - public override string ProgressText => toRemove.Name; - public override string produces => toRemove.FullName; - public override IgnoreItem Ignore => toRemove == null ? null : new IgnoreItem(toRemove.FullName); - public override string TargetFolder => toRemove?.DirectoryName; + public override string ProgressText => this.toRemove.Name; + public override string produces => this.toRemove.FullName; + public override IgnoreItem Ignore => this.toRemove == null ? null : new IgnoreItem(this.toRemove.FullName); + public override string TargetFolder => this.toRemove?.DirectoryName; public override bool Go(ref bool pause, TVRenameStats stats) { try { - if (toRemove.Exists) + if (this.toRemove.Exists) { - DeleteOrRecycleFile(toRemove); - if (_tidyup != null && _tidyup.DeleteEmpty) + DeleteOrRecycleFile(this.toRemove); + if (this._tidyup != null && this._tidyup.DeleteEmpty) { - DoTidyup(toRemove.Directory); + DoTidyup(this.toRemove.Directory); } } } - catch (System.Exception e) + catch (Exception e) { this.Error = true; this.ErrorText = e.Message; } this.Done = true; - return !Error; + return !this.Error; } public override bool SameAs(Item o) { ActionDeleteFile cmr = o as ActionDeleteFile; - return (cmr != null) && FileHelper.Same(toRemove , cmr.toRemove); + return (cmr != null) && FileHelper.Same(this.toRemove , cmr.toRemove); } public override int Compare(Item o) { ActionDeleteFile cmr = o as ActionDeleteFile; - if (cmr == null || toRemove.Directory == null || cmr.toRemove.Directory == null ) + if (cmr == null || this.toRemove.Directory == null || cmr.toRemove.Directory == null ) return 0; return string.Compare(this.toRemove.FullName , cmr.toRemove.FullName , StringComparison.Ordinal); @@ -135,60 +121,69 @@ public override int Compare(Item o) public class ActionDeleteDirectory : ActionDelete { - public DirectoryInfo toRemove; + private readonly DirectoryInfo toRemove; public ActionDeleteDirectory(DirectoryInfo remove, ProcessedEpisode ep, TidySettings tidyup) { - _tidyup = tidyup; - PercentDone = 0; - Episode = ep; - toRemove = remove; + this._tidyup = tidyup; + this.PercentDone = 0; + this.Episode = ep; + this.toRemove = remove; } - public override string ProgressText => toRemove.Name; - public override string produces => toRemove.FullName; - public override IgnoreItem Ignore => toRemove == null ? null : new IgnoreItem(toRemove.FullName); - public override string TargetFolder => toRemove?.Parent.FullName; + public override string ProgressText => this.toRemove.Name; + public override string produces => this.toRemove.FullName; + public override IgnoreItem Ignore => this.toRemove == null ? null : new IgnoreItem(this.toRemove.FullName); + public override string TargetFolder => this.toRemove?.Parent.FullName; public override bool Go(ref bool pause, TVRenameStats stats) { + //if the directory is the root download folder do not delete + if (TVSettings.Instance.MonitorFolders && + TVSettings.Instance.SearchFoldersNames.Contains(this.toRemove.FullName)) + { + this.Error = true; + this.ErrorText = $@"Not removing {this.toRemove.FullName} as it is a Search Folder"; + return false; + } + try { - if (toRemove.Exists) + if ((this.toRemove.Exists) ) { - DeleteOrRecycleFolder(toRemove); - if (_tidyup != null && _tidyup.DeleteEmpty) + DeleteOrRecycleFolder(this.toRemove); + if (this._tidyup != null && this._tidyup.DeleteEmpty) { - DoTidyup(toRemove.Parent); + DoTidyup(this.toRemove.Parent); } } } - catch (System.Exception e) + catch (Exception e) { this.Error = true; this.ErrorText = e.Message; } this.Done = true; - return !Error; + return !this.Error; } public override bool SameAs(Item o) { ActionDeleteDirectory cmr = o as ActionDeleteDirectory; - return (cmr != null) && FileHelper.Same(toRemove, cmr.toRemove); + return (cmr != null) && FileHelper.Same(this.toRemove, cmr.toRemove); } public override int Compare(Item o) { ActionDeleteDirectory cmr = o as ActionDeleteDirectory; - if (cmr == null || toRemove.Parent.FullName == null || cmr.toRemove.Parent.FullName == null) + if (cmr == null || this.toRemove.Parent.FullName == null || cmr.toRemove.Parent.FullName == null) return 0; return string.Compare(this.toRemove.FullName, cmr.toRemove.FullName, StringComparison.Ordinal); @@ -198,4 +193,4 @@ public override int Compare(Item o) } -} \ No newline at end of file +} From b27e373a161b111e3009d9cba38ee6198946fa59 Mon Sep 17 00:00:00 2001 From: Mark Summerville Date: Wed, 14 Feb 2018 22:30:30 +0800 Subject: [PATCH 4/5] Finally got #44 sorted. Had to store the thumbnail for each individual episode and and link to them from the episodedetails in the NFO file --- .../DownloadIdentifers/DownloadXBMCImages.cs | 57 +++++++--- TVRename#/Exporter/UpcomingRSS.cs | 2 +- TVRename#/Exporter/UpcomingXML.cs | 3 +- TVRename#/Finders/FileFinder.cs | 2 +- TVRename#/Forms/CustomNameDesigner.cs | 4 +- TVRename#/Forms/EditRules.cs | 4 +- TVRename#/Forms/UpcomingPopup.cs | 4 +- TVRename#/ItemsAndActions/ActionDownload.cs | 39 ++----- TVRename#/ItemsAndActions/ActionNFO.cs | 100 ++++++++---------- TVRename#/Settings/CustomName.cs | 52 ++++++++- TVRename#/TheTVDB/TheTVDB.cs | 13 ++- TVRename#/Utility/Helpers.cs | 4 +- 12 files changed, 171 insertions(+), 113 deletions(-) diff --git a/TVRename#/DownloadIdentifers/DownloadXBMCImages.cs b/TVRename#/DownloadIdentifers/DownloadXBMCImages.cs index 67ea82c20..7c94d0679 100644 --- a/TVRename#/DownloadIdentifers/DownloadXBMCImages.cs +++ b/TVRename#/DownloadIdentifers/DownloadXBMCImages.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Text; using System.Globalization; @@ -160,24 +160,55 @@ public override ItemList ProcessEpisode(ProcessedEpisode dbep, FileInfo filo, bo { if (TVSettings.Instance.EpTBNs || TVSettings.Instance.KODIImages) { - ItemList TheActionList = new ItemList(); - string ban = dbep.GetFilename(); - if (!string.IsNullOrEmpty(ban)) + ItemList theActionList = new ItemList(); + + + if (dbep.type == ProcessedEpisode.ProcessedEpisodeType.merged) { - string basefn = filo.Name; - basefn = basefn.Substring(0, basefn.Length - filo.Extension.Length); //remove extension - FileInfo imgtbn = FileHelper.FileInFolder(filo.Directory, basefn + ".tbn"); - if (!imgtbn.Exists ||forceRefresh) - if (!(this.doneTBN.Contains(imgtbn.FullName))){ - TheActionList.Add(new ActionDownload(dbep.SI, dbep, imgtbn, ban)); - doneTBN.Add(filo.FullName); - } + //We have a merged episode, so we'll also download the images for the episodes had they been separate. + foreach (Episode sourceEp in dbep.sourceEpisodes) + { + string foldername = filo.DirectoryName; + string filename = + TVSettings.Instance.FilenameFriendly( + TVSettings.Instance.NamingStyle.GetTargetEpisodeName(sourceEp,dbep.SI.ShowName)); + ActionDownload b = DoEpisode(dbep.SI,sourceEp,new FileInfo(foldername+"/"+filename), ".jpg", forceRefresh); + if (b != null) theActionList.Add(b); + } } - return TheActionList; + else + { + ActionDownload a = DoEpisode(dbep.SI, dbep, filo, ".tbn", forceRefresh); + if (a != null) theActionList.Add(a); + } + + return theActionList; } return base.ProcessEpisode(dbep, filo, forceRefresh); } + private ActionDownload DoEpisode(ShowItem si, Episode ep, FileInfo filo,string extension, bool forceRefresh) + { + string ban = ep.GetFilename(); + if (!string.IsNullOrEmpty(ban)) + { + string basefn = filo.Name; + basefn = basefn.Substring(0, basefn.Length - filo.Extension.Length); //remove extension + FileInfo imgtbn = FileHelper.FileInFolder(filo.Directory, basefn + extension); + if (!imgtbn.Exists || forceRefresh) + if (!(this.doneTBN.Contains(imgtbn.FullName))) + { + this.doneTBN.Add(imgtbn.FullName); + + return new ActionDownload(si, (ep is ProcessedEpisode) ? (ProcessedEpisode)ep : new ProcessedEpisode(ep,si ), imgtbn, ban); + + } + } + + return null; + + } + public override void reset() { doneBannerJPG = new List(); diff --git a/TVRename#/Exporter/UpcomingRSS.cs b/TVRename#/Exporter/UpcomingRSS.cs index a6f53296e..286e74eda 100644 --- a/TVRename#/Exporter/UpcomingRSS.cs +++ b/TVRename#/Exporter/UpcomingRSS.cs @@ -37,7 +37,7 @@ protected override bool Generate(System.IO.Stream str, List el foreach (ProcessedEpisode ei in elist) { - string niceName = TVSettings.Instance.NamingStyle.NameForExt(ei, null, 0); + string niceName = TVSettings.Instance.NamingStyle.NameForExt(ei); writer.WriteStartElement("item"); diff --git a/TVRename#/Exporter/UpcomingXML.cs b/TVRename#/Exporter/UpcomingXML.cs index b30c60618..4cdcaa8b7 100644 --- a/TVRename#/Exporter/UpcomingXML.cs +++ b/TVRename#/Exporter/UpcomingXML.cs @@ -31,8 +31,7 @@ protected override bool Generate(System.IO.Stream str, List e foreach (ProcessedEpisode ei in elist) { - string niceName = TVSettings.Instance.NamingStyle.NameForExt(ei, null, 0); - + writer.WriteStartElement("item"); XMLHelper.WriteElementToXML(writer,"id",ei.TheSeries.TVDBCode); XMLHelper.WriteElementToXML(writer,"SeriesName",ei.TheSeries.Name); diff --git a/TVRename#/Finders/FileFinder.cs b/TVRename#/Finders/FileFinder.cs index c52494e6c..447f8bcdf 100644 --- a/TVRename#/Finders/FileFinder.cs +++ b/TVRename#/Finders/FileFinder.cs @@ -151,7 +151,7 @@ public void KeepTogether(ItemList Actionlist) // do case insensitive replace string n = fi.Name; - int p = n.ToUpper().IndexOf(basename.ToUpper()); + int p = n.IndexOf(basename, StringComparison.OrdinalIgnoreCase); string newName = n.Substring(0, p) + toname + n.Substring(p + basename.Length); if ((TVSettings.Instance.RenameTxtToSub) && (newName.EndsWith(".txt"))) newName = newName.Substring(0, newName.Length - 4) + ".sub"; diff --git a/TVRename#/Forms/CustomNameDesigner.cs b/TVRename#/Forms/CustomNameDesigner.cs index 3c1f5769d..1142fa7a4 100644 --- a/TVRename#/Forms/CustomNameDesigner.cs +++ b/TVRename#/Forms/CustomNameDesigner.cs @@ -81,7 +81,7 @@ private void FillExamples() foreach (ProcessedEpisode pe in this.Eps) { ListViewItem lvi = new ListViewItem(); - string fn = TVSettings.Instance.FilenameFriendly(this.CN.NameForExt(pe, null, 0)); + string fn = TVSettings.Instance.FilenameFriendly(this.CN.NameForExt(pe)); lvi.Text = fn; bool ok = false; @@ -141,4 +141,4 @@ private void lvTest_SelectedIndexChanged(object sender, System.EventArgs e) this.FillCombos(); } } -} \ No newline at end of file +} diff --git a/TVRename#/Forms/EditRules.cs b/TVRename#/Forms/EditRules.cs index f2ac6591e..047cb7671 100644 --- a/TVRename#/Forms/EditRules.cs +++ b/TVRename#/Forms/EditRules.cs @@ -177,8 +177,8 @@ private void FillPreview() this.lbEpsPreview.BeginUpdate(); this.lbEpsPreview.Items.Clear(); foreach (ProcessedEpisode pe in pel) - this.lbEpsPreview.Items.Add(this.NameStyle.NameForExt(pe, null, 0)); + this.lbEpsPreview.Items.Add(this.NameStyle.NameForExt(pe)); this.lbEpsPreview.EndUpdate(); } } -} \ No newline at end of file +} diff --git a/TVRename#/Forms/UpcomingPopup.cs b/TVRename#/Forms/UpcomingPopup.cs index 7560a1a9e..e1a023921 100644 --- a/TVRename#/Forms/UpcomingPopup.cs +++ b/TVRename#/Forms/UpcomingPopup.cs @@ -62,7 +62,7 @@ private void FillSelf() lvi.Text = ei.HowLong(); lvi.SubItems.Add(ei.DayOfWeek()); lvi.SubItems.Add(ei.TimeOfDay()); - lvi.SubItems.Add(TVSettings.Instance.NamingStyle.NameForExt(ei, null, 0)); + lvi.SubItems.Add(TVSettings.Instance.NamingStyle.NameForExt(ei)); this.lvUpcoming.Items.Add(lvi); } if (this.lvUpcoming.Items.Count > 0) @@ -97,4 +97,4 @@ private void lvUpcoming_Enter(object sender, System.EventArgs e) this.hiddenButton.Select(); } } -} \ No newline at end of file +} diff --git a/TVRename#/ItemsAndActions/ActionDownload.cs b/TVRename#/ItemsAndActions/ActionDownload.cs index dd491a1e5..fdc0def94 100644 --- a/TVRename#/ItemsAndActions/ActionDownload.cs +++ b/TVRename#/ItemsAndActions/ActionDownload.cs @@ -1,4 +1,4 @@ -// +// // Main website for TVRename is http://tvrename.com // // Source code available at http://code.google.com/p/tvrename/ @@ -43,31 +43,16 @@ public ActionDownload(ShowItem si, ProcessedEpisode pe, FileInfo dest, string pa public bool Error { get; set; } public string ErrorText { get; set; } - public string Name - { - get { return "Download"; } - } + public string Name => "Download"; - public string ProgressText - { - get { return this.Destination.Name; } - } + public string ProgressText => this.Destination.Name; - public double PercentDone - { - get { return this.Done ? 100 : 0; } - } + public double PercentDone => this.Done ? 100 : 0; - public string produces - { - get { return this.Destination.FullName; } - } + public string produces => this.Destination.FullName; // 0 to 100 - public long SizeOfWork - { - get { return 1000000; } - } + public long SizeOfWork => 1000000; // http://www.codeproject.com/Articles/2941/Resizing-a-Photographic-image-with-GDI-for-NET static Image MaxSize(Image imgPhoto, int Width, int Height) @@ -173,10 +158,7 @@ public int Compare(Item o) #region ScanListItem Members - public int IconNumber - { - get { return 5; } - } + public int IconNumber => 5; public ProcessedEpisode Episode { get; set; } @@ -226,10 +208,7 @@ public ListViewItem ScanListViewItem } } - public string ScanListViewGroup - { - get { return "lvgActionDownload"; } - } + public string ScanListViewGroup => "lvgActionDownload"; public string TargetFolder { @@ -243,4 +222,4 @@ public string TargetFolder #endregion } -} \ No newline at end of file +} diff --git a/TVRename#/ItemsAndActions/ActionNFO.cs b/TVRename#/ItemsAndActions/ActionNFO.cs index 8b8f5dfda..28cb608b4 100644 --- a/TVRename#/ItemsAndActions/ActionNFO.cs +++ b/TVRename#/ItemsAndActions/ActionNFO.cs @@ -1,4 +1,4 @@ -// +// // Main website for TVRename is http://tvrename.com // // Source code available at http://code.google.com/p/tvrename/ @@ -8,12 +8,8 @@ namespace TVRename { using System; - using Alphaleonis.Win32.Filesystem; using System.Windows.Forms; using System.Xml; - using FileSystemInfo = Alphaleonis.Win32.Filesystem.FileSystemInfo; - using Directory = Alphaleonis.Win32.Filesystem.Directory; - using DirectoryInfo = Alphaleonis.Win32.Filesystem.DirectoryInfo; using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo; public class ActionNFO : Item, Action, ScanListItem, ActionWriteMetadata @@ -37,41 +33,27 @@ public ActionNFO(FileInfo nfo, ShowItem si) #region Action Members - public string Name - { - get { return "Write KODI Metadata"; } - } + public string Name => "Write KODI Metadata"; public bool Done { get; private set; } public bool Error { get; private set; } public string ErrorText { get; set; } - public string ProgressText - { - get { return this.Where.Name; } - } + public string ProgressText => this.Where.Name; - public double PercentDone - { - get { return this.Done ? 100 : 0; } - } + public double PercentDone => this.Done ? 100 : 0; - public long SizeOfWork - { - get { return 10000; } - } + public long SizeOfWork => 10000; - public string produces - { - get { return this.Where.FullName; } - } + public string produces => this.Where.FullName; - private void writeEpisodeDetailsFor(Episode episode, XmlWriter writer) + private void writeEpisodeDetailsFor(Episode episode, XmlWriter writer,bool multi) { // See: http://xbmc.org/wiki/?title=Import_-_Export_Library#TV_Episodes writer.WriteStartElement("episodedetails"); XMLHelper.WriteElementToXML(writer, "title", episode.Name); + XMLHelper.WriteElementToXML(writer,"showtitle", this.Episode.SI.ShowName ); XMLHelper.WriteElementToXML(writer, "rating", episode.EpisodeRating); XMLHelper.WriteElementToXML(writer, "season", episode.SeasonNumber); XMLHelper.WriteElementToXML(writer, "episode", episode.EpNum); @@ -82,34 +64,25 @@ private void writeEpisodeDetailsFor(Episode episode, XmlWriter writer) writer.WriteValue(episode.FirstAired.Value.ToString("yyyy-MM-dd")); writer.WriteEndElement(); - if (this.Episode.SI != null) - { - XMLHelper.WriteElementToXML(writer, "mpaa", this.Episode.SI.TheSeries().GetRating()); - } + XMLHelper.WriteElementToXML(writer, "mpaa", this.Episode.SI?.TheSeries()?.GetRating(),true); //Director(s) - if (!String.IsNullOrEmpty(episode.EpisodeDirector)) + string epDirector = episode.EpisodeDirector; + if (!string.IsNullOrEmpty(epDirector)) { - string EpDirector = episode.EpisodeDirector; - if (!string.IsNullOrEmpty(EpDirector)) + foreach (string Daa in epDirector.Split('|')) { - foreach (string Daa in EpDirector.Split('|')) - { - if (string.IsNullOrEmpty(Daa)) - continue; - - XMLHelper.WriteElementToXML(writer, "director", Daa); - } + XMLHelper.WriteElementToXML(writer, "director", Daa,true); } } //Writers(s) - if (!String.IsNullOrEmpty(episode.Writer)) + string EpWriter = episode.Writer; + if (!string.IsNullOrEmpty(EpWriter)) { - string EpWriter = episode.Writer; - if (!string.IsNullOrEmpty(EpWriter)) + foreach (string txtWriter in EpWriter.Split('|')) { - XMLHelper.WriteElementToXML(writer, "credits", EpWriter); + XMLHelper.WriteElementToXML(writer, "credits", txtWriter, true); } } @@ -158,6 +131,29 @@ private void writeEpisodeDetailsFor(Episode episode, XmlWriter writer) } } + if (multi) + { + writer.WriteStartElement("resume"); + //we have to put 0 as we don't know where the multipart episode starts/ends + XMLHelper.WriteElementToXML(writer, "position", 0); + XMLHelper.WriteElementToXML(writer, "total", 0); + writer.WriteEndElement(); // resume + + //For now we only put art in for multipart episodes. Kodi finds the art appropriately + //without our help for the others + + ShowItem episodeSi = this.Episode.SI??this.SI; + string filename = + TVSettings.Instance.FilenameFriendly( + TVSettings.Instance.NamingStyle.GetTargetEpisodeName(episode, episodeSi.ShowName)); + + string thumbFilename = filename + ".jpg"; + XMLHelper.WriteElementToXML(writer, "thumb",thumbFilename); + //Should be able to do this using the local filename, but only seems to work if you provide a URL + //XMLHelper.WriteElementToXML(writer, "thumb", TheTVDB.Instance.GetTVDBDownloadURL(episode.GetFilename())); + + + } writer.WriteEndElement(); // episodedetails } @@ -191,9 +187,9 @@ public bool Go(ref bool pause, TVRenameStats stats) { if (this.Episode.type == ProcessedEpisode.ProcessedEpisodeType.merged) { - foreach (Episode ep in this.Episode.sourceEpisodes) writeEpisodeDetailsFor(ep, writer); + foreach (Episode ep in this.Episode.sourceEpisodes) writeEpisodeDetailsFor(ep, writer, true); } - else writeEpisodeDetailsFor(this.Episode, writer); + else writeEpisodeDetailsFor(this.Episode, writer, false); } else if (this.SI != null) // show overview (tvshow.nfo) { @@ -339,18 +335,12 @@ string ScanListItem.TargetFolder } } - public string ScanListViewGroup - { - get { return "lvgActionMeta"; } - } + public string ScanListViewGroup => "lvgActionMeta"; - public int IconNumber - { - get { return 7; } - } + public int IconNumber => 7; public ProcessedEpisode Episode { get; private set; } #endregion } -} \ No newline at end of file +} diff --git a/TVRename#/Settings/CustomName.cs b/TVRename#/Settings/CustomName.cs index df1ee9182..6efee2ed2 100644 --- a/TVRename#/Settings/CustomName.cs +++ b/TVRename#/Settings/CustomName.cs @@ -63,13 +63,13 @@ public static string OldNStyle(int n) "{ShowName} - S{Season:2}{AllEpisodes} - {EpisodeName}" }; - public string NameForExt(ProcessedEpisode pe, string extension, int folderNameLength) + public string NameForExt(ProcessedEpisode pe, string extension = "", int folderNameLength=0) { // set folderNameLength to have the filename truncated if the total path length is too long string r = NameForNoExt(pe, this.StyleString); - int maxLenOK = 200 - (folderNameLength + ((extension != null) ? extension.Length : 0)); + int maxLenOK = 200 - (folderNameLength + (extension?.Length ?? 0)); if (r.Length > maxLenOK) r = r.Substring(0, maxLenOK); @@ -82,6 +82,54 @@ public string NameForExt(ProcessedEpisode pe, string extension, int folderNameLe return r; } + public string GetTargetEpisodeName(Episode ep, string showname, bool urlEncode = false ) + { + //note this is for an Episode and not a ProcessedEpisode + String name = this.StyleString; + + string epname = ep.Name; + + name = name.ReplaceInsensitive("{ShowName}", showname); + name = name.ReplaceInsensitive("{Season}", ep.SeasonNumber.ToString()); + name = name.ReplaceInsensitive("{Season:2}", ep.SeasonNumber.ToString("00")); + name = name.ReplaceInsensitive("{Episode}", ep.EpNum.ToString("00")); + name = name.ReplaceInsensitive("{Episode2}", ep.EpNum.ToString("00")); + name = name.ReplaceInsensitive("{EpisodeName}", epname); + name = name.ReplaceInsensitive("{Number}", ""); + name = name.ReplaceInsensitive("{Number:2}", ""); + name = name.ReplaceInsensitive("{Number:3}", ""); + DateTime? airdt = ep.GetAirDateDT(false); + if (airdt != null) + { + DateTime dt = (DateTime)airdt; + name = name.ReplaceInsensitive("{ShortDate}", dt.ToString("d")); + name = name.ReplaceInsensitive("{LongDate}", dt.ToString("D")); + string ymd = dt.ToString("yyyy/MM/dd"); + if (urlEncode) + ymd = System.Web.HttpUtility.UrlEncode(ymd); + name = name.ReplaceInsensitive("{YMDDate}", ymd); + } + else + { + name = name.ReplaceInsensitive("{ShortDate}", "---"); + name = name.ReplaceInsensitive("{LongDate}", "------"); + string ymd = "----/--/--"; + if (urlEncode) + ymd = System.Web.HttpUtility.UrlEncode(ymd); + name = name.ReplaceInsensitive("{YMDDate}", ymd); + } + + name = Regex.Replace(name, "{AllEpisodes}", ep.EpNum.ToString("00")); + + name = Regex.Replace(name, "([^\\\\])\\[.*?[^\\\\]\\]", "$1"); // remove optional parts + + name = name.Replace("\\[", "["); + name = name.Replace("\\]", "]"); + + return name.Trim(); + } + + public static readonly List Tags = new List { "{ShowName}", diff --git a/TVRename#/TheTVDB/TheTVDB.cs b/TVRename#/TheTVDB/TheTVDB.cs index 2ebac23b9..bc952488e 100644 --- a/TVRename#/TheTVDB/TheTVDB.cs +++ b/TVRename#/TheTVDB/TheTVDB.cs @@ -435,8 +435,8 @@ private static string APIKey() return "5FEC454623154441"; // tvrename's API key on thetvdb.com } - - public byte[] GetTVDBDownload(string url, bool forceReload = false) { + public string GetTVDBDownloadURL(string url) + { string mirr = this.WebsiteRoot; if (url.StartsWith("/")) @@ -448,6 +448,15 @@ public byte[] GetTVDBDownload(string url, bool forceReload = false) { theURL += "banners/"; theURL += url; + return theURL; + } + + + + public byte[] GetTVDBDownload(string url, bool forceReload = false) + { + + string theURL = GetTVDBDownloadURL(url); System.Net.WebClient wc = new System.Net.WebClient(); diff --git a/TVRename#/Utility/Helpers.cs b/TVRename#/Utility/Helpers.cs index 5ad68d89c..d9f86aed2 100644 --- a/TVRename#/Utility/Helpers.cs +++ b/TVRename#/Utility/Helpers.cs @@ -80,8 +80,10 @@ public static string ReadStringFixQuotesAndSpaces(XmlReader r) return res; } - public static void WriteElementToXML(XmlWriter writer, string elementName, string value) + public static void WriteElementToXML(XmlWriter writer, string elementName, string value,bool ignoreifBlank = false) { + if (ignoreifBlank && string.IsNullOrEmpty(value)) return; + writer.WriteStartElement(elementName); writer.WriteValue(value??""); writer.WriteEndElement(); From 2309e63bfcb4ffa1a71edd168b765847c14bd688 Mon Sep 17 00:00:00 2001 From: Mark Summerville Date: Wed, 14 Feb 2018 22:48:21 +0800 Subject: [PATCH 5/5] Added tooltips #330 --- TVRename#/Forms/UI.Designer.cs | 119 +++++++++++++++++---------------- TVRename#/Forms/UI.cs | 10 +++ TVRename#/Forms/UI.resx | 13 ++-- 3 files changed, 79 insertions(+), 63 deletions(-) diff --git a/TVRename#/Forms/UI.Designer.cs b/TVRename#/Forms/UI.Designer.cs index 21c71e98a..afd9422b2 100644 --- a/TVRename#/Forms/UI.Designer.cs +++ b/TVRename#/Forms/UI.Designer.cs @@ -39,20 +39,20 @@ public void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UI)); - System.Windows.Forms.ListViewGroup listViewGroup1 = new System.Windows.Forms.ListViewGroup("Missing", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup2 = new System.Windows.Forms.ListViewGroup("Rename", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup3 = new System.Windows.Forms.ListViewGroup("Copy", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup4 = new System.Windows.Forms.ListViewGroup("Move", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup5 = new System.Windows.Forms.ListViewGroup("Remove", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup6 = new System.Windows.Forms.ListViewGroup("Download RSS", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup7 = new System.Windows.Forms.ListViewGroup("Download", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup8 = new System.Windows.Forms.ListViewGroup("Media Center Metadata", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup9 = new System.Windows.Forms.ListViewGroup("Update File Metadata", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup10 = new System.Windows.Forms.ListViewGroup("Downloading", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup11 = new System.Windows.Forms.ListViewGroup("Recently Aired", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup12 = new System.Windows.Forms.ListViewGroup("Next 7 Days", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup13 = new System.Windows.Forms.ListViewGroup("Future Episodes", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup14 = new System.Windows.Forms.ListViewGroup("Later", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup15 = new System.Windows.Forms.ListViewGroup("Missing", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup16 = new System.Windows.Forms.ListViewGroup("Rename", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup17 = new System.Windows.Forms.ListViewGroup("Copy", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup18 = new System.Windows.Forms.ListViewGroup("Move", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup19 = new System.Windows.Forms.ListViewGroup("Remove", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup20 = new System.Windows.Forms.ListViewGroup("Download RSS", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup21 = new System.Windows.Forms.ListViewGroup("Download", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup22 = new System.Windows.Forms.ListViewGroup("Media Center Metadata", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup23 = new System.Windows.Forms.ListViewGroup("Update File Metadata", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup24 = new System.Windows.Forms.ListViewGroup("Downloading", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup1 = new System.Windows.Forms.ListViewGroup("Recently Aired", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup2 = new System.Windows.Forms.ListViewGroup("Next 7 Days", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup3 = new System.Windows.Forms.ListViewGroup("Future Episodes", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup4 = new System.Windows.Forms.ListViewGroup("Later", System.Windows.Forms.HorizontalAlignment.Left); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -177,6 +177,7 @@ public void InitializeComponent() this.columnHeader33 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeader34 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeader35 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.menuStrip1.SuspendLayout(); this.tabControl1.SuspendLayout(); this.tbMyShows.SuspendLayout(); @@ -263,6 +264,7 @@ public void InitializeComponent() this.optionsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); this.optionsToolStripMenuItem.Text = "&Options"; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click); // // offlineOperationToolStripMenuItem // @@ -1292,37 +1294,37 @@ public void InitializeComponent() this.columnHeader56, this.columnHeader58}); this.lvAction.FullRowSelect = true; - listViewGroup1.Header = "Missing"; - listViewGroup1.Name = "lvgActionMissing"; - listViewGroup2.Header = "Rename"; - listViewGroup2.Name = "lvgActionRename"; - listViewGroup3.Header = "Copy"; - listViewGroup3.Name = "lvgActionCopy"; - listViewGroup4.Header = "Move"; - listViewGroup4.Name = "lvgActionMove"; - listViewGroup5.Header = "Remove"; - listViewGroup5.Name = "lvgActionDelete"; - listViewGroup6.Header = "Download RSS"; - listViewGroup6.Name = "lvgActionDownloadRSS"; - listViewGroup7.Header = "Download"; - listViewGroup7.Name = "lvgActionDownload"; - listViewGroup8.Header = "Media Center Metadata"; - listViewGroup8.Name = "lvgActionMeta"; - listViewGroup9.Header = "Update File Metadata"; - listViewGroup9.Name = "lvgUpdateFileDates"; - listViewGroup10.Header = "Downloading"; - listViewGroup10.Name = "lvgDownloading"; + listViewGroup15.Header = "Missing"; + listViewGroup15.Name = "lvgActionMissing"; + listViewGroup16.Header = "Rename"; + listViewGroup16.Name = "lvgActionRename"; + listViewGroup17.Header = "Copy"; + listViewGroup17.Name = "lvgActionCopy"; + listViewGroup18.Header = "Move"; + listViewGroup18.Name = "lvgActionMove"; + listViewGroup19.Header = "Remove"; + listViewGroup19.Name = "lvgActionDelete"; + listViewGroup20.Header = "Download RSS"; + listViewGroup20.Name = "lvgActionDownloadRSS"; + listViewGroup21.Header = "Download"; + listViewGroup21.Name = "lvgActionDownload"; + listViewGroup22.Header = "Media Center Metadata"; + listViewGroup22.Name = "lvgActionMeta"; + listViewGroup23.Header = "Update File Metadata"; + listViewGroup23.Name = "lvgUpdateFileDates"; + listViewGroup24.Header = "Downloading"; + listViewGroup24.Name = "lvgDownloading"; this.lvAction.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] { - listViewGroup1, - listViewGroup2, - listViewGroup3, - listViewGroup4, - listViewGroup5, - listViewGroup6, - listViewGroup7, - listViewGroup8, - listViewGroup9, - listViewGroup10}); + listViewGroup15, + listViewGroup16, + listViewGroup17, + listViewGroup18, + listViewGroup19, + listViewGroup20, + listViewGroup21, + listViewGroup22, + listViewGroup23, + listViewGroup24}); this.lvAction.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.lvAction.HideSelection = false; this.lvAction.Location = new System.Drawing.Point(0, 35); @@ -1404,21 +1406,21 @@ public void InitializeComponent() this.columnHeader34, this.columnHeader35}); this.lvWhenToWatch.FullRowSelect = true; - listViewGroup11.Header = "Recently Aired"; - listViewGroup11.Name = "justPassed"; - listViewGroup12.Header = "Next 7 Days"; - listViewGroup12.Name = "next7days"; - listViewGroup12.Tag = "1"; - listViewGroup13.Header = "Future Episodes"; - listViewGroup13.Name = "futureEps"; - listViewGroup14.Header = "Later"; - listViewGroup14.Name = "later"; - listViewGroup14.Tag = "2"; + listViewGroup1.Header = "Recently Aired"; + listViewGroup1.Name = "justPassed"; + listViewGroup2.Header = "Next 7 Days"; + listViewGroup2.Name = "next7days"; + listViewGroup2.Tag = "1"; + listViewGroup3.Header = "Future Episodes"; + listViewGroup3.Name = "futureEps"; + listViewGroup4.Header = "Later"; + listViewGroup4.Name = "later"; + listViewGroup4.Tag = "2"; this.lvWhenToWatch.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] { - listViewGroup11, - listViewGroup12, - listViewGroup13, - listViewGroup14}); + listViewGroup1, + listViewGroup2, + listViewGroup3, + listViewGroup4}); this.lvWhenToWatch.HideSelection = false; this.lvWhenToWatch.Location = new System.Drawing.Point(0, 35); this.lvWhenToWatch.Name = "lvWhenToWatch"; @@ -1644,5 +1646,6 @@ public void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem checkForNewVersionToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem duplicateFinderLOGToolStripMenuItem; private System.Windows.Forms.Timer tmrPeriodicScan; + private System.Windows.Forms.ToolTip toolTip1; } } diff --git a/TVRename#/Forms/UI.cs b/TVRename#/Forms/UI.cs index 5e8c09687..377a1b39c 100644 --- a/TVRename#/Forms/UI.cs +++ b/TVRename#/Forms/UI.cs @@ -317,6 +317,11 @@ private void UI_Load(object sender, System.EventArgs e) this.UI_LocationChanged(null, null); this.UI_SizeChanged(null, null); + System.Windows.Forms.ToolTip ToolTip1 = new System.Windows.Forms.ToolTip(); + ToolTip1.SetToolTip(this.btnActionQuickScan, "Scan shows with missing recent aired episodes and and shows that match files in the search folders"); + ToolTip1.SetToolTip(this.bnActionRecentCheck, "Scan shows with recent aired episodes"); + ToolTip1.SetToolTip(this.bnActionCheck , "Scan all shows"); + this.backgroundDownloadToolStripMenuItem.Checked = TVSettings.Instance.BGDownload; this.offlineOperationToolStripMenuItem.Checked = TVSettings.Instance.OfflineMode; this.BGDownloadTimer.Interval = 10000; // first time @@ -3740,5 +3745,10 @@ private void RunAutoScan(string scanType) logger.Info(scanType + " cancelled as the system is already busy"); } } + + private void optionsToolStripMenuItem_Click(object sender, EventArgs e) + { + + } } } diff --git a/TVRename#/Forms/UI.resx b/TVRename#/Forms/UI.resx index d5776bc3f..4c6b2b8e4 100644 --- a/TVRename#/Forms/UI.resx +++ b/TVRename#/Forms/UI.resx @@ -121,14 +121,14 @@ 17, 17 - 763, 54 + 876, 54 AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADk - HQAAAk1TRnQBSQFMAgEBEwEAAdgBAgHYAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + HQAAAk1TRnQBSQFMAgEBEwEAARABAwEQAQMBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAAVADAAEBAQABCAYAARQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA @@ -274,7 +274,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACa - GAAAAk1TRnQBSQFMAgEBCgEAAfQBAgH0AQIBEgEAAQ0BAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFI + GAAAAk1TRnQBSQFMAgEBCgEAASwBAwEsAQMBEgEAAQ0BAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFI AwABJwMAAQEBAAEYBQAB6AEgGAAD7wMSBjADCQYwAw8DKgMwAxsD0Q8AASEB1gEIASEB1gEIASEB1gEI ASEB1gEImQAD7wM8A58D5gMwA+ADzgNPA9gDtwOPA9EMAAEhAdYBCAEhAdYBCAEhAdYBCAEhAdYBCAEh AdYBCAEhAdYBCJYAA+8DNgOPA+IDMAPbA8YDTwPOA0ADjwPRDAABIQHWAQgBIQHWAQgBIQHWAQgBIQHW @@ -679,10 +679,13 @@ 475, 54 - 652, 54 + 765, 54 - 873, 54 + 986, 54 + + + 668, 54 95