private static int TypeNumber(Item a) { return(a switch { ShowItemMissing _ => 1, MovieItemMissing _ => 2, ActionCopyMoveRename _ => 3, ActionMoveRenameDirectory _ => 4, ActionTDownload _ => 5, ActionDownloadImage _ => 6, ActionMede8erViewXML _ => 7, ActionMede8erXML _ => 8, ActionNfo _ => 9, ActionPyTivoMeta _ => 10, ActionWdtvMeta _ => 11, ItemDownloading _ => 12, ActionDeleteFile _ => 13, ActionDeleteDirectory _ => 14, ActionDateTouchEpisode _ => 15, ActionDateTouchSeason _ => 16, ActionDateTouchMedia _ => 17, ActionDateTouchMovie _ => 18, ActionTRemove _ => 19, _ => throw new NotSupportedException() });
public override bool SameAs(Item o) { ActionCopyMoveRename cmr = o as ActionCopyMoveRename; return((cmr != null) && (Operation == cmr.Operation) && FileHelper.Same(From, cmr.From) && FileHelper.Same(To, cmr.To)); }
private bool UpdateCopyProgress() // return true if all tasks are done { // update each listview item, for non-empty queues bool allDone = true; lvProgress.BeginUpdate(); int top = lvProgress.TopItem?.Index ?? 0; ActionCopyMoveRename activeCmAction = GetActiveCmAction(); long workDone = 0; long totalWork = 0; lvProgress.Items.Clear(); foreach (Action action in mToDo.Where(aq => aq.Actions.Count != 0).SelectMany(aq => aq.Actions)) { if (!action.Outcome.Done) { allDone = false; } long size = action.SizeOfWork; workDone += (long)(size * action.PercentDone / 100); totalWork += action.SizeOfWork; if (!action.Outcome.Done) { ListViewItem lvi = new ListViewItem(action.Name); lvi.SubItems.Add(action.ProgressText); lvProgress.Items.Add(lvi); } } if (top >= lvProgress.Items.Count) { top = lvProgress.Items.Count - 1; } if (top >= 0) { try { lvProgress.TopItem = lvProgress.Items[top]; } catch (NullReferenceException) { //Ignore this as we're done } } lvProgress.EndUpdate(); if (activeCmAction != null) { txtFilename.Text = activeCmAction.ProgressText; SetPercentages(activeCmAction.PercentDone, totalWork == 0 ? 0.0 : workDone * 100.0 / totalWork); } return(allDone); }
private void UpdateDiskSpace() { int diskValue = 0; string diskText = "--- GB free"; ActionCopyMoveRename activeCmAction = GetActiveCmAction(); if (activeCmAction is null) { return; } string folder = activeCmAction.TargetFolder; DirectoryInfo toRoot = !string.IsNullOrEmpty(folder) && !folder.StartsWith("\\\\", StringComparison.Ordinal) ? new DirectoryInfo(folder).Root : null; if (toRoot != null) { System.IO.DriveInfo di; try { // try to get root of drive di = new System.IO.DriveInfo(toRoot.ToString()); } catch (ArgumentException) { di = null; } try { if (di != null) { (diskValue, diskText) = DiskValue(di.TotalFreeSpace, di.TotalSize); } } catch (UnauthorizedAccessException) { } catch (IOException) { } } DirectoryInfo toUncRoot = !string.IsNullOrEmpty(folder) && folder.StartsWith("\\\\", StringComparison.Ordinal) ? new DirectoryInfo(folder).Root : null; if (toUncRoot != null) { FileSystemProperties driveStats = FileHelper.GetProperties(toUncRoot.ToString()); long?availableBytes = driveStats.AvailableBytes; long?totalBytes = driveStats.TotalBytes; if (availableBytes.HasValue && totalBytes.HasValue) { (diskValue, diskText) = DiskValue(availableBytes.Value, totalBytes.Value); } } pbDiskSpace.Value = diskValue; txtDiskSpace.Text = diskText; }
private void UpdateDiskSpace() { int diskValue = 0; string diskText = "--- GB free"; ActionCopyMoveRename activeCMAction = null; activeCMAction = GetActiveCmAction(); if (activeCMAction is null) { return; } string folder = activeCMAction.TargetFolder; DirectoryInfo toRoot = (!string.IsNullOrEmpty(folder) && !folder.StartsWith("\\\\")) ? new DirectoryInfo(folder).Root : null; if (toRoot != null) { System.IO.DriveInfo di; try { // try to get root of drive di = new System.IO.DriveInfo(toRoot.ToString()); } catch (System.ArgumentException) { di = null; } if (di != null) { int pct = (int)((1000 * di.TotalFreeSpace) / di.TotalSize); diskValue = 1000 - pct; diskText = di.TotalFreeSpace.GBMB(1) + " free"; } } DirectoryInfo toUNCRoot = (!string.IsNullOrEmpty(folder) && folder.StartsWith("\\\\")) ? new DirectoryInfo(folder).Root : null; if (toUNCRoot != null) { FileSystemProperties driveStats = FileHelper.GetProperties(toUNCRoot.ToString()); if (driveStats != null) { int pct = (int)((1000 * driveStats.AvailableBytes) / driveStats.TotalBytes); diskValue = 1000 - pct; diskText = (driveStats.AvailableBytes ?? 0).GBMB(1) + " free"; } } this.pbDiskSpace.Value = diskValue; this.txtDiskSpace.Text = diskText; }
public override void Run() { if (!Active()) { return; } try { XmlWriterSettings settings = new XmlWriterSettings { Indent = true, NewLineOnAttributes = true }; using (XmlWriter writer = XmlWriter.Create(Location(), settings)) { writer.WriteStartDocument(); writer.WriteStartElement("TVRename"); XmlHelper.WriteAttributeToXml(writer, "Version", "2.1"); writer.WriteStartElement(MainXmlElementName()); foreach (Item action in TheActionList) { if (!IsOutput(action)) { continue; } ActionCopyMoveRename acmr = (ActionCopyMoveRename)action; writer.WriteStartElement("Item"); XmlHelper.WriteAttributeToXml(writer, "Operation", acmr.Name); XmlHelper.WriteAttributeToXml(writer, "FromFolder", acmr.From.DirectoryName); XmlHelper.WriteAttributeToXml(writer, "FromName", acmr.From.Name); XmlHelper.WriteAttributeToXml(writer, "ToFolder", acmr.To.DirectoryName); XmlHelper.WriteAttributeToXml(writer, "ToName", acmr.To.Name); XmlHelper.WriteAttributeToXml(writer, "ShowName", acmr.Episode.TheSeries.Name); XmlHelper.WriteAttributeToXml(writer, "Season", acmr.Episode.AppropriateSeasonNumber); XmlHelper.WriteAttributeToXml(writer, "Episode", acmr.Episode.NumsAsString()); writer.WriteEndElement(); //Item } writer.WriteEndElement(); // Name writer.WriteEndElement(); // tvrename writer.WriteEndDocument(); } } catch (Exception e) { LOGGER.Error(e); } }
public int Compare(Item o) { ActionCopyMoveRename cmr = o as ActionCopyMoveRename; if (cmr == null || this.From.Directory == null || this.To.Directory == null || cmr.From.Directory == null || cmr.To.Directory == null) { return(0); } string s1 = this.From.FullName + (this.From.Directory.Root.FullName != this.To.Directory.Root.FullName ? "0" : "1"); string s2 = cmr.From.FullName + (cmr.From.Directory.Root.FullName != cmr.To.Directory.Root.FullName ? "0" : "1"); return(s1.CompareTo(s2)); }
public override int Compare(Item o) { ActionCopyMoveRename cmr = o as ActionCopyMoveRename; if (cmr == null || From.Directory == null || To.Directory == null || cmr.From.Directory == null || cmr.To.Directory == null) { return(0); } string s1 = From.FullName + (From.Directory.Root.FullName != To.Directory.Root.FullName ? "0" : "1"); string s2 = cmr.From.FullName + (cmr.From.Directory.Root.FullName != cmr.To.Directory.Root.FullName ? "0" : "1"); return(string.Compare(s1, s2, StringComparison.Ordinal)); }
protected override void Do() { XmlWriterSettings settings = new XmlWriterSettings { Indent = true, NewLineOnAttributes = true }; using (XmlWriter writer = XmlWriter.Create(Location(), settings)) { writer.WriteStartDocument(); writer.WriteStartElement("TVRename"); writer.WriteAttributeToXml("Version", "2.1"); writer.WriteStartElement(MainXmlElementName()); foreach (Item action in TheActionList) { if (!IsOutput(action)) { continue; } ActionCopyMoveRename acmr = (ActionCopyMoveRename)action; writer.WriteStartElement("Item"); writer.WriteAttributeToXml("Operation", acmr.Name); writer.WriteAttributeToXml("FromFolder", acmr.From.DirectoryName); writer.WriteAttributeToXml("FromName", acmr.From.Name); writer.WriteAttributeToXml("ToFolder", acmr.To.DirectoryName); writer.WriteAttributeToXml("ToName", acmr.To.Name); writer.WriteAttributeToXml("ShowName", acmr.SeriesName); writer.WriteAttributeToXml("Season", acmr.SourceEpisode.AppropriateSeasonNumber); writer.WriteAttributeToXml("Episode", acmr.SourceEpisode.EpNumsAsString()); writer.WriteEndElement(); //Item } writer.WriteEndElement(); // Name writer.WriteEndElement(); // tvrename writer.WriteEndDocument(); } }
protected static void ReorganiseToLeaveOriginals([NotNull] ItemList newList) { // go through and change last of each operation on a given source file to a 'Move' // ideally do that move within same filesystem // sort based on source file, and destination drive, putting last if destdrive == sourcedrive newList.Sort(new ActionItemSorter()); // sort puts all the CopyMoveRenames together // then set the last of each source file to be a move for (int i = 0; i < newList.Count; i++) { ActionCopyMoveRename cmr1 = newList[i] as ActionCopyMoveRename; bool ok1 = cmr1 != null; if (!ok1) { continue; } bool last = i == newList.Count - 1; ActionCopyMoveRename cmr2 = !last ? newList[i + 1] as ActionCopyMoveRename : null; bool ok2 = cmr2 != null; if (ok2) { ActionCopyMoveRename a1 = cmr1; ActionCopyMoveRename a2 = cmr2; if (!FileHelper.Same(a1.From, a2.From)) { a1.Operation = ActionCopyMoveRename.Op.move; } } else { // last item, or last copymoverename item in the list ActionCopyMoveRename a1 = cmr1; a1.Operation = ActionCopyMoveRename.Op.move; } } }
private static void KeepTogetherForItem(ItemList actionlist, bool fromLibrary, [NotNull] ActionCopyMoveRename action, ItemList extras, bool showErrors, TVDoc d) { try { DirectoryInfo sfdi = action.From.Directory; string basename = action.From.Name; int l = basename.Length; basename = basename.Substring(0, l - action.From.Extension.Length); string toname = action.To.Name; int l2 = toname.Length; toname = toname.Substring(0, l2 - action.To.Extension.Length); try { FileInfo[] flist = sfdi.GetFiles(basename + ".*"); foreach (FileInfo fi in flist) { //check to see whether the file is one of the types we do/don't want to include //If we are copying from outside the library we use the 'Keep Together' Logic if (!fromLibrary && !TVSettings.Instance.KeepTogetherFilesWithType(fi.Extension)) { continue; } //If we are with in the library we use the 'Other Extensions' if (fromLibrary && !TVSettings.Instance.FileHasUsefulExtension(fi, true)) { continue; } string newName = GetFilename(fi.Name, basename, toname); ActionCopyMoveRename newitem = new ActionCopyMoveRename(action.Operation, fi, FileHelper.FileInFolder(action.To.Directory, newName), action.Episode, false, null, d); // tidy up on main action, not this // check this item isn't already in our to-do list if (ActionListContains(actionlist, newitem)) { continue; } if (!newitem.SameAs(action)) // don't re-add ourself { extras.Add(newitem); } } } catch (UnauthorizedAccessException) { LOGGER.Warn("Could not access: " + action.From.FullName); } catch (DirectoryNotFoundException) { LOGGER.Warn("Could not find: " + action.From.FullName); } } catch (PathTooLongException e) { string t = "Path or filename too long. " + action.From.FullName + ", " + e.Message; LOGGER.Warn(e, "Path or filename too long. " + action.From.FullName); if (showErrors && Environment.UserInteractive) { MessageBox.Show(t, "Path or filename too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } }
public bool SameSource(ActionCopyMoveRename o) { return (Helpers.Same(this.From, o.From)); }
public bool SameSource([NotNull] ActionCopyMoveRename o) => FileHelper.Same(From, o.From);
public bool SameSource(ActionCopyMoveRename o) { return(Helpers.Same(this.From, o.From)); }
private static bool ActionListContains([NotNull] ItemList actionlist, ActionCopyMoveRename newItem) { return(actionlist.CopyMoveRename.Any(cmAction => cmAction.SameSource(newItem))); }
private void KeepTogether(ItemList actionlist) { // for each of the items in rcl, do the same copy/move if for other items with the same // base name, but different extensions ItemList extras = new ItemList(); foreach (Item action1 in actionlist) { if (!(action1 is ActionCopyMoveRename)) { continue; } ActionCopyMoveRename action = (ActionCopyMoveRename)(action1); try { DirectoryInfo sfdi = action.From.Directory; string basename = action.From.Name; int l = basename.Length; basename = basename.Substring(0, l - action.From.Extension.Length); string toname = action.To.Name; int l2 = toname.Length; toname = toname.Substring(0, l2 - action.To.Extension.Length); FileInfo[] flist = sfdi.GetFiles(basename + ".*"); foreach (FileInfo fi in flist) { //check to see whether the file is one of the types we do/don't want to include if (!TVSettings.Instance.KeepTogetherFilesWithType(fi.Extension)) { continue; } // do case insensitive replace string n = fi.Name; 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"; } ActionCopyMoveRename newitem = new ActionCopyMoveRename(action.Operation, fi, FileHelper.FileInFolder(action.To.Directory, newName), action.Episode, null, null); // tidyup on main action, not this // check this item isn't already in our to-do list if (ActionListContains(actionlist, newitem)) { continue; } if (!newitem.SameAs(action)) // don't re-add ourself { extras.Add(newitem); } } } catch (System.IO.PathTooLongException e) { string t = "Path or filename too long. " + action.From.FullName + ", " + e.Message; LOGGER.Warn(e, "Path or filename too long. " + action.From.FullName); if ((!Doc.Args.Unattended) && (!Doc.Args.Hide)) { MessageBox.Show(t, "Path or filename too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } foreach (Item action in extras) { // check we don't already have this in our list and, if we don't add it! bool have = AlreadyHaveAction(actionlist, action); if (!have) { actionlist.Insert(0, action); // put before other actions, so tidyup is run last } } }
private static bool ActionListContains(ItemList actionlist, ActionCopyMoveRename newitem) { return(actionlist.CopyMoveItems().Any(cmAction => cmAction.SameSource(newitem))); }
public override void Check(SetProgressDelegate prog, int startpct, int totPct) { prog.Invoke(0); ItemList newList = new ItemList(); ItemList toRemove = new ItemList(); int fileCount = 0; foreach (string s in this.mDoc.SearchFolders) { fileCount += DirCache.CountFiles(s, true); } int c = 0; DirCache dirCache = new DirCache(); foreach (String s in this.mDoc.SearchFolders) { if (this.ActionCancel) { return; } c = dirCache.AddFolder(prog, c, fileCount, s, true); } c = 0; int totalN = this.TheActionList.Count; foreach (Item action1 in this.TheActionList) { if (this.ActionCancel) { return; } prog.Invoke(50 + 50 * (++c) / (totalN + 1)); // second 50% of progress bar if (action1 is ItemMissing) { if (this.FindMissingEp(dirCache, (ItemMissing)(action1), newList, ActionCopyMoveRename.Op.Copy)) { toRemove.Add(action1); } } } if (TVSettings.Instance.KeepTogether) { this.KeepTogether(newList); } prog.Invoke(100); if (!TVSettings.Instance.LeaveOriginals) { // go through and change last of each operation on a given source file to a 'Move' // ideally do that move within same filesystem // sort based on source file, and destination drive, putting last if destdrive == sourcedrive newList.Sort(new ActionItemSorter()); // sort puts all the CopyMoveRenames together // then set the last of each source file to be a move for (int i = 0; i < newList.Count; i++) { ActionCopyMoveRename cmr1 = newList[i] as ActionCopyMoveRename; bool ok1 = cmr1 != null; if (!ok1) { continue; } bool last = i == (newList.Count - 1); ActionCopyMoveRename cmr2 = !last ? newList[i + 1] as ActionCopyMoveRename : null; bool ok2 = cmr2 != null; if (ok2) { ActionCopyMoveRename a1 = cmr1; ActionCopyMoveRename a2 = cmr2; if (!FileHelper.Same(a1.From, a2.From)) { a1.Operation = ActionCopyMoveRename.Op.Move; } } else { // last item, or last copymoverename item in the list ActionCopyMoveRename a1 = cmr1; a1.Operation = ActionCopyMoveRename.Op.Move; } } } foreach (Item i in toRemove) { this.TheActionList.Remove(i); } foreach (Item i in newList) { this.TheActionList.Add(i); } // if (Settings->ExportFOXML) // ExportFOXML(Settings->ExportFOXMLTo); }
public void KeepTogether(ItemList Actionlist) { // for each of the items in rcl, do the same copy/move if for other items with the same // base name, but different extensions ItemList extras = new ItemList(); foreach (Item Action1 in Actionlist) { if (!(Action1 is ActionCopyMoveRename)) { continue; } ActionCopyMoveRename Action = (ActionCopyMoveRename)(Action1); try { DirectoryInfo sfdi = Action.From.Directory; string basename = Action.From.Name; int l = basename.Length; basename = basename.Substring(0, l - Action.From.Extension.Length); string toname = Action.To.Name; int l2 = toname.Length; toname = toname.Substring(0, l2 - Action.To.Extension.Length); FileInfo[] flist = sfdi.GetFiles(basename + ".*"); foreach (FileInfo fi in flist) { // do case insensitive replace string n = fi.Name; int p = n.ToUpper().IndexOf(basename.ToUpper()); 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"; } ActionCopyMoveRename newitem = new ActionCopyMoveRename(Action.Operation, fi, FileHelper.FileInFolder(Action.To.Directory, newName), Action.Episode, null); // tidyup on main action, not this // check this item isn't already in our to-do list bool doNotAdd = false; foreach (Item ai2 in Actionlist) { if (!(ai2 is ActionCopyMoveRename)) { continue; } if (((ActionCopyMoveRename)(ai2)).SameSource(newitem)) { doNotAdd = true; break; } } if (!doNotAdd) { if (!newitem.SameAs(Action)) // don't re-add ourself { extras.Add(newitem); } } } } catch (System.IO.PathTooLongException e) { string t = "Path or filename too long. " + Action.From.FullName + ", " + e.Message; logger.Warn(e, "Path or filename too long. " + Action.From.FullName); if ((!this.mDoc.Args.Unattended) && (!this.mDoc.Args.Hide)) { MessageBox.Show(t, "Path or filename too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } foreach (Item action in extras) { // check we don't already have this in our list and, if we don't add it! bool have = false; foreach (Item action2 in Actionlist) { if (action2.SameAs(action)) { have = true; break; } if ((action is Action) && (action2 is Action)) { Action a1 = (Action)action; Action a2 = (Action)action2; if (a2.produces == a1.produces) { have = true; break; } } } if (!have) { Actionlist.Insert(0, action); // put before other actions, so tidyup is run last } } }
public void Go(ListView lv, WhichResults which) { //this.uTorrenting = new System.Collections.Generic.List<ItemuTorrenting>(); this.Missing = new System.Collections.Generic.List <ItemMissing>(); this.RSS = new System.Collections.Generic.List <ActionRSS>(); this.CopyMove = new System.Collections.Generic.List <ActionCopyMoveRename>(); this.Rename = new System.Collections.Generic.List <ActionCopyMoveRename>(); this.Download = new System.Collections.Generic.List <ActionDownloadImage>(); this.NFO = new System.Collections.Generic.List <ActionNFO>(); this.PyTivoMeta = new System.Collections.Generic.List <ActionPyTivoMeta>(); this.FlatList = new ItemList(); System.Collections.Generic.List <ListViewItem> sel = new System.Collections.Generic.List <ListViewItem>(); if (which == WhichResults.Checked) { ListView.CheckedListViewItemCollection ss = lv.CheckedItems; foreach (ListViewItem lvi in ss) { sel.Add(lvi); } } else if (which == WhichResults.Selected) { ListView.SelectedListViewItemCollection ss = lv.SelectedItems; foreach (ListViewItem lvi in ss) { sel.Add(lvi); } } else // all { foreach (ListViewItem lvi in lv.Items) { sel.Add(lvi); } } this.Count = sel.Count; if (sel.Count == 0) { return; } System.Type firstType = ((Item)(sel[0].Tag)).GetType(); this.AllSameType = true; foreach (ListViewItem lvi in sel) { if (lvi == null) { continue; } Item action = (Item)(lvi.Tag); if (action is Item) { this.FlatList.Add(action as Item); } if (action.GetType() != firstType) { this.AllSameType = false; } if (action is ActionCopyMoveRename) { ActionCopyMoveRename cmr = action as ActionCopyMoveRename; if (cmr.Operation == ActionCopyMoveRename.Op.Rename) { this.Rename.Add(cmr); } else // copy/move { this.CopyMove.Add(cmr); } } else if (action is ActionDownloadImage) { this.Download.Add((ActionDownloadImage)(action)); } else if (action is ActionRSS) { this.RSS.Add((ActionRSS)(action)); } else if (action is ItemMissing) { this.Missing.Add((ItemMissing)(action)); } else if (action is ActionNFO) { this.NFO.Add((ActionNFO)(action)); } else if (action is ActionPyTivoMeta) { this.PyTivoMeta.Add((ActionPyTivoMeta)(action)); } //else if (action is ItemuTorrenting) // this.uTorrenting.Add((ItemuTorrenting) (action)); } }
// consider each of the files, see if it is suitable for series "ser" and episode "epi" // if so, add a rcitem for copy to "fi" public bool FindMissingEp(DirCache dirCache, ItemMissing me, ItemList addTo, ActionCopyMoveRename.Op whichOp) { string showname = me.Episode.SI.ShowName; int season = me.Episode.SeasonNumber; //String ^toName = FilenameFriendly(Settings->NamingStyle->NameFor(me->PE)); int epnum = me.Episode.EpNum; // TODO: find a 'best match', or use first ? showname = Helpers.SimplifyName(showname); foreach (DirCacheEntry dce in dirCache) { if (this.ActionCancel) return true; bool matched = false; try { if (!dce.HasUsefulExtension_NotOthersToo) // not a usefile file extension continue; if (TVSettings.Instance.IgnoreSamples && dce.LowerName.Contains("sample") && ((dce.Length / (1024 * 1024)) < TVSettings.Instance.SampleFileMaxSizeMB)) continue; matched = Regex.Match(dce.SimplifiedFullName, "\\b" + showname + "\\b", RegexOptions.IgnoreCase).Success; // if we don't match the main name, then test the aliases if (!matched) { foreach (string alias in me.Episode.SI.AliasNames) { string aliasName = Helpers.SimplifyName(alias); matched = Regex.Match(dce.SimplifiedFullName, "\\b" + aliasName + "\\b", RegexOptions.IgnoreCase).Success; if (matched) break; } } if (matched) { int seasF; int epF; if ((TVDoc.FindSeasEp(dce.TheFile, out seasF, out epF, me.Episode.SI) && (seasF == season) && (epF == epnum)) || (me.Episode.SI.UseSequentialMatch && TVDoc.MatchesSequentialNumber(dce.TheFile.Name, ref seasF, ref epF, me.Episode) && (seasF == season) && (epF == epnum))) { FileInfo fi = new FileInfo(me.TheFileNoExt + dce.TheFile.Extension); // don't remove the base search folders bool doTidyup = true; foreach (String folder in this.mDoc.SearchFolders) { // http://stackoverflow.com/questions/1794025/how-to-check-whether-2-directoryinfo-objects-are-pointing-to-the-same-directory if (String.Compare(folder.ToLower().TrimEnd('\\'), fi.Directory.FullName.ToLower().TrimEnd('\\'), StringComparison.InvariantCultureIgnoreCase) == 0) { doTidyup = false; break; } } addTo.Add(new ActionCopyMoveRename(whichOp, dce.TheFile, fi, me.Episode, doTidyup ? TVSettings.Instance.Tidyup : null)); DownloadIdentifiersController di = new DownloadIdentifiersController(); // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it addTo.Add(di.ProcessEpisode(me.Episode, fi)); return true; } } } catch (System.IO.PathTooLongException e) { string t = "Path too long. " + dce.TheFile.FullName + ", " + e.Message; t += ". Try to display more info?"; DialogResult dr = MessageBox.Show(t, "Path too long", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (dr == DialogResult.Yes) { t = "DirectoryName " + dce.TheFile.DirectoryName + ", File name: " + dce.TheFile.Name; t += matched ? ", matched. " : ", no match. "; if (matched) { t += "Show: " + me.Episode.TheSeries.Name + ", Season " + season + ", Ep " + epnum + ". "; t += "To: " + me.TheFileNoExt; } MessageBox.Show(t, "Path too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } return false; }
// consider each of the files, see if it is suitable for series "ser" and episode "epi" // if so, add a rcitem for copy to "fi" public bool FindMissingEp(DirCache dirCache, ItemMissing me, ItemList addTo, ActionCopyMoveRename.Op whichOp) { string showname = me.Episode.SI.ShowName; int season = me.Episode.SeasonNumber; //String ^toName = FilenameFriendly(Settings->NamingStyle->NameFor(me->PE)); int epnum = me.Episode.EpNum; // TODO: find a 'best match', or use first ? showname = Helpers.SimplifyName(showname); foreach (DirCacheEntry dce in dirCache) { if (this.ActionCancel) return true; bool matched = false; try { if (!dce.HasUsefulExtension_NotOthersToo) // not a usefile file extension continue; if (this.Settings.IgnoreSamples && dce.LowerName.Contains("sample") && ((dce.Length / (1024 * 1024)) < this.Settings.SampleFileMaxSizeMB)) continue; matched = Regex.Match(dce.SimplifiedFullName, "\\b" + showname + "\\b", RegexOptions.IgnoreCase).Success; // if we don't match the main name, then test the aliases if (!matched) { foreach (string alias in me.Episode.SI.AliasNames) { string aliasName = Helpers.SimplifyName(alias); matched = Regex.Match(dce.SimplifiedFullName, "\\b" + aliasName + "\\b", RegexOptions.IgnoreCase).Success; if (matched) break; } } if (matched) { int seasF; int epF; // String ^fn = file->Name; if ((this.FindSeasEp(dce.TheFile, out seasF, out epF, me.Episode.SI) && (seasF == season) && (epF == epnum)) || (me.Episode.SI.UseSequentialMatch && this.MatchesSequentialNumber(dce.TheFile.Name, ref seasF, ref epF, me.Episode) && (seasF == season) && (epF == epnum))) { FileInfo fi = new FileInfo(me.TheFileNoExt + dce.TheFile.Extension); addTo.Add(new ActionCopyMoveRename(whichOp, dce.TheFile, fi, me.Episode)); // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it this.ThumbnailAndNFOCheck(me.Episode, fi, addTo); return true; } } } catch (System.IO.PathTooLongException e) { string t = "Path too long. " + dce.TheFile.FullName + ", " + e.Message; t += ". Try to display more info?"; DialogResult dr = MessageBox.Show(t, "Path too long", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (dr == DialogResult.Yes) { t = "DirectoryName " + dce.TheFile.DirectoryName + ", File name: " + dce.TheFile.Name; t += matched ? ", matched. " : ", no match. "; if (matched) { t += "Show: " + me.Episode.TheSeries.Name + ", Season " + season + ", Ep " + epnum + ". "; t += "To: " + me.TheFileNoExt; } MessageBox.Show(t, "Path too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } return false; }
public void KeepTogether(ItemList Actionlist) { // for each of the items in rcl, do the same copy/move if for other items with the same // base name, but different extensions ItemList extras = new ItemList(); foreach (Item Action1 in Actionlist) { if (!(Action1 is ActionCopyMoveRename)) continue; ActionCopyMoveRename Action = (ActionCopyMoveRename) (Action1); try { DirectoryInfo sfdi = Action.From.Directory; string basename = Action.From.Name; int l = basename.Length; basename = basename.Substring(0, l - Action.From.Extension.Length); string toname = Action.To.Name; int l2 = toname.Length; toname = toname.Substring(0, l2 - Action.To.Extension.Length); FileInfo[] flist = sfdi.GetFiles(basename + ".*"); foreach (FileInfo fi in flist) { // do case insensitive replace string n = fi.Name; int p = n.ToUpper().IndexOf(basename.ToUpper()); string newName = n.Substring(0, p) + toname + n.Substring(p + basename.Length); if ((this.Settings.RenameTxtToSub) && (newName.EndsWith(".txt"))) newName = newName.Substring(0, newName.Length - 4) + ".sub"; ActionCopyMoveRename newitem = new ActionCopyMoveRename(Action.Operation, fi, Helpers.FileInFolder(Action.To.Directory, newName), Action.Episode); // check this item isn't already in our to-do list bool doNotAdd = false; foreach (Item ai2 in Actionlist) { if (!(ai2 is ActionCopyMoveRename)) continue; if (((ActionCopyMoveRename) (ai2)).SameSource(newitem)) { doNotAdd = true; break; } } if (!doNotAdd) { if (!newitem.SameAs(Action)) // don't re-add ourself extras.Add(newitem); } } } catch (System.IO.PathTooLongException e) { string t = "Path or filename too long. " + Action.From.FullName + ", " + e.Message; MessageBox.Show(t, "Path or filename too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } foreach (Item action in extras) { // check we don't already have this in our list and, if we don't add it! bool have = false; foreach (Item action2 in Actionlist) { if (action2.SameAs(action)) { have = true; break; } } if (!have) Actionlist.Add(action); } }
public bool SameAs(Item o) { ActionCopyMoveRename cmr = o as ActionCopyMoveRename; return((cmr != null) && (this.Operation == cmr.Operation) && Helpers.Same(this.From, cmr.From) && Helpers.Same(this.To, cmr.To)); }
public override void Check(SetProgressDelegate prog, int startpct, int totPct) { prog.Invoke(startpct); ItemList newList = new ItemList(); ItemList toRemove = new ItemList(); int fileCount = 0; foreach (string s in TVSettings.Instance.DownloadFolders) { fileCount += DirCache.CountFiles(s, true); } DirCache dirCache = new DirCache(); foreach (string s in TVSettings.Instance.DownloadFolders) { if (ActionCancel) { return; } dirCache.AddFolder(prog, 0, fileCount, s, true); } int currentItem = 0; int totalN = ActionList.Count; foreach (ItemMissing me in ActionList.MissingItems()) { if (ActionCancel) { return; } prog.Invoke(startpct + ((totPct - startpct) * (++currentItem) / (totalN + 1))); ItemList thisRound = new ItemList(); List <DirCacheEntry> matchedFiles = new List <DirCacheEntry>(); foreach (DirCacheEntry dce in dirCache) { if (!ReviewFile(me, thisRound, dce)) { continue; } matchedFiles.Add(dce); } if (matchedFiles.Count == 1) { if (!OtherActionsMatch(matchedFiles[0], me)) { toRemove.Add(me); newList.AddRange(thisRound); } else { LOGGER.Warn($"Ignoring potential match for {me.Episode.Show.ShowName} S{me.Episode.AppropriateSeasonNumber} E{me.Episode.AppropriateEpNum}: with file {matchedFiles[0]?.TheFile.FullName} as there are multiple actions for that file"); me.AddComment( $"Ignoring potential match with file {matchedFiles[0]?.TheFile.FullName} as there are multiple actions for that file"); } } else if (matchedFiles.Count > 1) { List <DirCacheEntry> bestMatchedFiles = IdentifyBestMatches(matchedFiles); if (bestMatchedFiles.Count == 1) { //We have one file that is better, lets use it toRemove.Add(me); newList.AddRange(thisRound); } else { foreach (DirCacheEntry matchedFile in matchedFiles) { LOGGER.Warn( $"Ignoring potential match for {me.Episode.Show.ShowName} S{me.Episode.AppropriateSeasonNumber} E{me.Episode.AppropriateEpNum}: with file {matchedFile?.TheFile.FullName} as there are multiple files for that action"); me.AddComment( $"Ignoring potential match with file {matchedFile?.TheFile.FullName} as there are multiple files for that action"); } } } } if (TVSettings.Instance.KeepTogether) { KeepTogether(newList); } prog.Invoke(totPct); if (!TVSettings.Instance.LeaveOriginals) { // go through and change last of each operation on a given source file to a 'Move' // ideally do that move within same filesystem // sort based on source file, and destination drive, putting last if destdrive == sourcedrive newList.Sort(new ActionItemSorter()); // sort puts all the CopyMoveRenames together // then set the last of each source file to be a move for (int i = 0; i < newList.Count; i++) { ActionCopyMoveRename cmr1 = newList[i] as ActionCopyMoveRename; bool ok1 = cmr1 != null; if (!ok1) { continue; } bool last = i == (newList.Count - 1); ActionCopyMoveRename cmr2 = !last ? newList[i + 1] as ActionCopyMoveRename : null; bool ok2 = cmr2 != null; if (ok2) { ActionCopyMoveRename a1 = cmr1; ActionCopyMoveRename a2 = cmr2; if (!FileHelper.Same(a1.From, a2.From)) { a1.Operation = ActionCopyMoveRename.Op.move; } } else { // last item, or last copymoverename item in the list ActionCopyMoveRename a1 = cmr1; a1.Operation = ActionCopyMoveRename.Op.move; } } } foreach (Item i in toRemove) { ActionList.Remove(i); } foreach (Item i in newList) { ActionList.Add(i); } }
private bool UpdateNewStyle() // return true if all tasks are done { // update each listview item, for non-empty queues bool allDone = true; this.lvProgress.BeginUpdate(); int top = this.lvProgress.TopItem != null ? this.lvProgress.TopItem.Index : 0; ActionCopyMoveRename activeCMAction = null; long workDone = 0; long totalWork = 0; this.lvProgress.Items.Clear(); foreach (ActionQueue aq in this.mToDo) { if (aq.Actions.Count == 0) { continue; } foreach (Action action in aq.Actions) { if (!action.Done) { allDone = false; } long size = action.SizeOfWork; workDone += (long)(size * action.PercentDone / 100); totalWork += action.SizeOfWork; if (!action.Done) { if ((action is ActionCopyMoveRename) && (action.PercentDone > 0)) { activeCMAction = action as ActionCopyMoveRename; } ListViewItem lvi = new ListViewItem(action.Name); lvi.SubItems.Add(action.ProgressText); this.lvProgress.Items.Add(lvi); } } } if (top >= this.lvProgress.Items.Count) { top = this.lvProgress.Items.Count - 1; } if (top >= 0) { this.lvProgress.TopItem = this.lvProgress.Items[top]; } this.lvProgress.EndUpdate(); int diskValue = 0; string diskText = "--- GB free"; string fileText = ""; if (activeCMAction != null) { string folder = activeCMAction.TargetFolder; DirectoryInfo toRoot = (!string.IsNullOrEmpty(folder) && !folder.StartsWith("\\\\")) ? new DirectoryInfo(folder).Root : null; if (toRoot != null) { System.IO.DriveInfo di; try { // try to get root of drive di = new System.IO.DriveInfo(toRoot.ToString()); } catch (System.ArgumentException) { di = null; } if (di != null) { int pct = (int)((1000 * di.TotalFreeSpace) / di.TotalSize); diskValue = 1000 - pct; diskText = ((int)(di.TotalFreeSpace / 1024.0 / 1024.0 / 1024.0 + 0.5)) + " GB free"; } fileText = activeCMAction.ProgressText; } this.txtFilename.Text = fileText; this.pbDiskSpace.Value = diskValue; this.txtDiskSpace.Text = diskText; this.SetPercentages(activeCMAction.PercentDone, totalWork == 0 ? 0.0 : (workDone * 100.0 / totalWork)); } return(allDone); }
public bool SameSource(ActionCopyMoveRename o) => FileHelper.Same(this.From, o.From);
private bool UpdateCopyProgress() // return true if all tasks are done { // update each listview item, for non-empty queues bool allDone = true; this.lvProgress.BeginUpdate(); int top = lvProgress.TopItem?.Index ?? 0; ActionCopyMoveRename activeCMAction = null; long workDone = 0; long totalWork = 0; this.lvProgress.Items.Clear(); foreach (ActionQueue aq in this.mToDo) { if (aq.Actions.Count == 0) { continue; } foreach (Action action in aq.Actions) { if (!action.Done) { allDone = false; } long size = action.SizeOfWork; workDone += (long)(size * action.PercentDone / 100); totalWork += action.SizeOfWork; if (!action.Done) { if ((action is ActionCopyMoveRename) && (action.PercentDone > 0)) { activeCMAction = action as ActionCopyMoveRename; } ListViewItem lvi = new ListViewItem(action.Name); lvi.SubItems.Add(action.ProgressText); this.lvProgress.Items.Add(lvi); } } } if (top >= this.lvProgress.Items.Count) { top = this.lvProgress.Items.Count - 1; } if (top >= 0) { this.lvProgress.TopItem = this.lvProgress.Items[top]; } this.lvProgress.EndUpdate(); if (activeCMAction != null) { this.txtFilename.Text = activeCMAction.ProgressText; this.SetPercentages(activeCMAction.PercentDone, totalWork == 0 ? 0.0 : (workDone * 100.0 / totalWork)); } return(allDone); }