public void OnExecutionFinished(IT4File file) { lock (ExecutionLocker) { var location = file.PhysicalPsiSourceFile.GetLocation(); var definition = RunningFiles[location]; definition.Terminate(); RunningFiles.Remove(location); } }
public AppModel() { this.listener = new Lazy <AppModelTraceListener>(() => Trace.Listeners.OfType <AppModelTraceListener>().FirstOrDefault()); this.uMonitor = new UTorrentMonitor(Application.Current.Dispatcher); this.uMonitor.ReadyTorrents += OnTorrentReady; this.WorkQueue = new BlockingCollection <EpisodeFile>(); this.RunningFiles = new ObservableCollection <EpisodeFile>(); this.Files = new ObservableCollection <EpisodeFile>(); this.CompletedFiles = new ObservableCollection <EpisodeFile>(); this.Files.CollectionChanged += (s, e) => { switch (e.Action) { case NotifyCollectionChangedAction.Remove: foreach (var item in e.OldItems.Cast <EpisodeFile>()) { item.Cancel(); } break; case NotifyCollectionChangedAction.Reset: foreach (var item in this.Files) { item.Cancel(); } break; } OnPropertyChanged("IsFileSetEmpty", "Status"); }; this.RunningFiles.CollectionChanged += (s, e) => { if (e.Action == NotifyCollectionChangedAction.Add) { foreach (var item in e.NewItems.Cast <EpisodeFile>()) { item.Status = "Waiting ..."; this.WorkQueue.Add(item); } } }; Task.Factory.StartNew(() => { foreach (var item in WorkQueue.GetConsumingEnumerable()) { var file = item; // do the processing file.Status = "Processing ..."; var errors = new List <string>(); // first do copy foreach ( var action in file.Actions.Where(a => a.Command == EpisodeFileActionCommand.Copy && a.IsEnabled)) { try { item.Status = action.TargetCommand; var dir = Path.GetDirectoryName(action.TargetPath); if ((dir != null) && (!Directory.Exists(dir))) { Directory.CreateDirectory(dir); } var fo = new InteropSHFileOperation() { pFrom = item.FilePath, pTo = action.TargetPath, wFunc = InteropSHFileOperation.FO_Func.FO_COPY, fFlags = new InteropSHFileOperation.FILEOP_FLAGS() { FOF_RENAMEONCOLLISION = true } }; fo.Execute(); //File.Copy(item.FilePath, action.TargetPath, false); action.IsEnabled = false; } catch (Exception ex) { errors.Add(ex.Message); } } var renameAction = file.Actions.FirstOrDefault(a => a.Command == EpisodeFileActionCommand.Move && a.IsEnabled); if (errors.Count == 0 && renameAction != null) { try { file.Status = renameAction.TargetCommand; var dir = Path.GetDirectoryName(renameAction.TargetPath); if ((dir != null) && (!Directory.Exists(dir))) { Directory.CreateDirectory(dir); } var fo = new InteropSHFileOperation() { pFrom = item.FilePath, pTo = renameAction.TargetPath, wFunc = InteropSHFileOperation.FO_Func.FO_MOVE, fFlags = new InteropSHFileOperation.FILEOP_FLAGS() { FOF_RENAMEONCOLLISION = true } }; fo.Execute(); renameAction.IsEnabled = false; } catch (Exception ex) { errors.Add(ex.Message); } } if (errors.Count == 0) { file.Status = "Done"; try { //detect if this directory contains any more video files or files bigger then 1MB // if not, delete it var dir = Path.GetDirectoryName(file.FilePath); if (!Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories).Select(fl => new FileInfo(fl)).Any(fl => ((fl.Length > 1024 * 1024) || Settings.GetVideoExtensions().Any(ex => string.Equals(fl.Extension, ex, StringComparison.CurrentCultureIgnoreCase))) )) { // delete directory Directory.Delete(dir, true); } } catch { } Application.Current.Dispatcher.BeginInvoke(new Action(() => { file.Errors.Clear(); RunningFiles.Remove(file); CompletedFiles.Add(file); })); } else { file.Status = "Waiting for retry"; Application.Current.Dispatcher.BeginInvoke(new Action(() => { file.Errors.Clear(); foreach (var err in errors) { file.Errors.Add(err); } })); file.RetryTimer = new DispatcherTimer(TimeSpan.FromMinutes(5), DispatcherPriority.Normal, (s, e) => { file.Errors.Clear(); file.RetryTimer.Stop(); file.Status = "Pending ..."; this.WorkQueue.Add(file); }, Application.Current.Dispatcher); } } }); this.RunWatcher(); //this.Watcher.EnableRaisingEvents = this.Settings.RunMonitor; this.Settings.SettingsSaving += Settings_SettingsSaving; }