/// <summary> /// Adds a conversion job to the queue /// This function does NOT take a lock on the queue before modifying it. This function is not thread safe /// </summary> /// <param name="filePath">File to add</param> /// <param name="monitorTask">Monitor task name which found the file</param> /// <param name="manual">True if this is a manuall added entry, false if it's added by a monitor task</param> private void AddJobs(string filePath, MonitorJobOptions monitorTask, bool manual) { bool filterMatchSuccessful = false; // Check if the file has already been processed in the past if so skip if (_conversionTaskFilterMismatchFiles.Contains(filePath)) return; // foreach (ConversionJobOptions conversionTask in MCEBuddyConf.GlobalMCEConfig.AllConversionTasks) { // Check if the task is disabled, which case skip if (!conversionTask.enabled) { Log.AppLog.WriteEntry(this, Localise.GetPhrase("Conversion Task") + " " + conversionTask.taskName + " " + Localise.GetPhrase("disabled, skipping file") + " " + filePath, Log.LogEntryType.Debug, true); continue; } conversionTask.sourceVideo = filePath; // Monitor Task name matching if not empty if ((monitorTask != null) && !String.IsNullOrWhiteSpace(monitorTask.taskName) && (conversionTask.monitorTaskNames != null)) { bool foundMatch = false; foreach (string matchMonitorTaskName in conversionTask.monitorTaskNames) { if (monitorTask.taskName.ToLower().Trim() != matchMonitorTaskName.ToLower().Trim()) // match the list of a name continue; // move onto next monitor task name else { foundMatch = true; break; } } if (!foundMatch) { Log.AppLog.WriteEntry(this, "Skipping Conversion task " + conversionTask.taskName + " for file " + filePath + " since Monitor task " + monitorTask.taskName + " does not match the list of monitor tasks in the conversion task.", Log.LogEntryType.Debug, true); continue; // move into next conversion task } } // Metadata extract and pattern match from conversion task VideoMetaData metaData = MetadataMatchFilters(conversionTask); if (metaData != null) // We got a match - process the file { // Calculate where to add the job in the queue int idx; if (manual || conversionTask.insertQueueTop) // Manual jobs to the head of the queue, just after the current active job, or check if the conversion task is asking to add the job at the head of the queue { for (idx = 0; idx < _jobQueue.Count; idx++) { if (!_jobQueue[idx].Active) break; } } else idx = _jobQueue.Count; // Add the job to the end of the active queue // If it's a manual entry then we need to convert, reset the skip reconverting flag if it's set if (manual && conversionTask.skipReprocessing) { conversionTask.skipReprocessing = conversionTask.checkReprocessingHistory = false; // We can make a direct change since this is a copy object Log.AppLog.WriteEntry(this, "Manually added file, resetting the skip reprocessing option, the file will converted even if it has been processed before", Log.LogEntryType.Debug, true); } Log.AppLog.WriteEntry(this, Localise.GetPhrase("Added new job to queue for") + " " + filePath, Log.LogEntryType.Information, true); ConversionJob job = new ConversionJob(conversionTask, metaData); _jobQueue.Insert(idx, job); filterMatchSuccessful = true; // we cleared filters and processed the file // Send an eMail if required GeneralOptions go = MCEBuddyConf.GlobalMCEConfig.GeneralOptions; bool sendEMail = go.sendEmail; // do we need to send an eMail after adding a job to the queue bool sendQueue = go.eMailSettings.queueEvent; string sendQueueSubject = go.eMailSettings.queueSubject; bool skipBody = go.eMailSettings.skipBody; if (sendEMail && sendQueue) { string subject = Localise.GetPhrase("MCEBuddy added a video conversion to the queue"); string message = Localise.GetPhrase("Source Video") + " -> " + job.OriginalFileName + "\r\n"; message += Localise.GetPhrase("Profile") + " -> " + job.Profile + "\r\n"; message += Localise.GetPhrase("Conversion Task") + " -> " + job.TaskName + "\r\n"; // Check for custom subject and process if (!String.IsNullOrWhiteSpace(sendQueueSubject)) subject = UserCustomParams.CustomParamsReplace(sendQueueSubject, job.WorkingPath, "", "", job.OriginalFileName, "", "", "", job.Profile, job.TaskName, metaData.MetaData, Log.AppLog); eMailSendEngine.AddEmailToSendQueue(subject, (skipBody ? "" : message)); // Send the eMail through the eMail engine } } else if (manual) // Delete manual file entry if we didn't create a conversion job, otherwise the engine will clear it on completion { // Manual files may be added multiple times and the filter may already have it from the last time, so be safe and delete it Ini iniManualQueue = new Ini(GlobalDefs.ManualQueueFile); // Delete the entry from the manual queue iniManualQueue.DeleteKey("ManualQueue", filePath); } } // If we have been through all the conversion tasks and not a single task has processed this file, hence we add it to the filter mismatch list so it won't be processed in future (MetadataExtract is very intensive and also prevent overburdening the log file) if (!filterMatchSuccessful) _conversionTaskFilterMismatchFiles.Add(filePath); }
private void WriteHistory(ConversionJob job) { Ini historyIni = new Ini(GlobalDefs.HistoryFile); GeneralOptions go = MCEBuddyConf.GlobalMCEConfig.GeneralOptions; bool sendEMail = go.sendEmail; // do we need to send an eMail after each job bool sendSuccess = go.eMailSettings.successEvent; bool sendFailed = go.eMailSettings.failedEvent; bool sendCancelled = go.eMailSettings.cancelledEvent; bool skipBody = go.eMailSettings.skipBody; string sendSuccessSubject = go.eMailSettings.successSubject; string sendFailedSubject = go.eMailSettings.failedSubject; string sendCancelledSubject = go.eMailSettings.cancelledSubject; string result = "Converted"; if (job.Status.Error) result = "Error"; if (job.Status.Cancelled) result = "Cancelled"; // Cancelled should be the last status to set because an error can be set if is cancelled int convCount = 0; while (historyIni.ReadString(job.OriginalFileName, result + "At" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), "") != "") convCount++; historyIni.Write(job.OriginalFileName, result + "At" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), DateTime.Now.ToString("s", System.Globalization.CultureInfo.InvariantCulture)); switch (result) { case "Converted": { if (job.Status.SuccessfulSkipConversion) Log.AppLog.WriteEntry(this, "Job for " + job.OriginalFileName + " Skipped ReConverting successfully using Conversion Task " + job.TaskName + " and Profile " + job.Profile, Log.LogEntryType.Information, true); else Log.AppLog.WriteEntry(this, "Job for " + job.OriginalFileName + " Converted successfully using Conversion Task " + job.TaskName + " and Profile " + job.Profile, Log.LogEntryType.Information, true); historyIni.Write(job.OriginalFileName, "ConvertedTo" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.ConvertedFile); historyIni.Write(job.OriginalFileName, "ConvertedUsingProfile" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.Profile); historyIni.Write(job.OriginalFileName, "ConvertedUsingTask" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.TaskName); historyIni.Write(job.OriginalFileName, "ConvertedStart" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.ConversionStartTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture)); //Ensure converted files are not then re-converted during a scan historyIni.Write(job.ConvertedFile, "Status", "OutputFromConversion"); // Status indicates destination file is output of an conversion, if the same file is added back for reconversion then it would log as converted if (job.Status.SuccessfulSkipConversion) historyIni.Write(job.ConvertedFile, "SkipConvertedToOutputAt" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.ConversionEndTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture)); else historyIni.Write(job.ConvertedFile, "ConvertedToOutputAt" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.ConversionEndTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture)); // Send an eMail if required if (sendEMail && sendSuccess) { string subject = Localise.GetPhrase("MCEBuddy successfully converted a video"); string message = Localise.GetPhrase("Source Video") + " -> " + job.OriginalFileName + "\r\n"; message += Localise.GetPhrase("Converted Video") + " -> " + job.ConvertedFile + "\r\n"; message += Localise.GetPhrase("Profile") + " -> " + job.Profile + "\r\n"; message += Localise.GetPhrase("Conversion Task") + " -> " + job.TaskName + "\r\n"; message += Localise.GetPhrase("Converted At") + " -> " + job.ConversionEndTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture) + "\r\n"; message += Localise.GetPhrase("Time taken to convert") + " (hh:mm) -> " + (job.ConversionEndTime - job.ConversionStartTime).Hours.ToString("00") + ":" + (job.ConversionEndTime - job.ConversionStartTime).Minutes.ToString("00") + "\r\n"; // Check for custom subject and process if (!String.IsNullOrWhiteSpace(sendSuccessSubject)) subject = UserCustomParams.CustomParamsReplace(sendSuccessSubject, job.WorkingPath, Path.GetDirectoryName(job.ConvertedFile), job.ConvertedFile, job.OriginalFileName, "", "", "", job.Profile, job.TaskName, job.MetaData, Log.AppLog); eMailSendEngine.AddEmailToSendQueue(subject, (skipBody ? "" : message)); // Send the eMail through the email engine } } break; case "Error": { Log.AppLog.WriteEntry(this, "Job for " + job.OriginalFileName + " has Error " + job.Status.ErrorMsg + " using Conversion Task " + job.TaskName + " and Profile " + job.Profile, Log.LogEntryType.Information, true); historyIni.Write(job.OriginalFileName, "ErrorMessage" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.Status.ErrorMsg); historyIni.Write(job.OriginalFileName, "ErrorUsingProfile" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.Profile); historyIni.Write(job.OriginalFileName, "ErrorUsingTask" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.TaskName); // Send an eMail if required if (sendEMail && sendFailed) { string subject = Localise.GetPhrase("MCEBuddy failed to converted a video"); string message = Localise.GetPhrase("Source Video") + " -> " + job.OriginalFileName + "\r\n"; message += Localise.GetPhrase("Profile") + " -> " + job.Profile + "\r\n"; message += Localise.GetPhrase("Conversion Task") + " -> " + job.TaskName + "\r\n"; message += Localise.GetPhrase("Error") + " -> " + job.Status.ErrorMsg + "\r\n"; message += Localise.GetPhrase("Failed At") + " -> " + job.ConversionEndTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture) + "\r\n"; // Check for custom subject and process if (!String.IsNullOrWhiteSpace(sendFailedSubject)) subject = UserCustomParams.CustomParamsReplace(sendFailedSubject, job.WorkingPath, "", job.ConvertedFile, job.OriginalFileName, "", "", "", job.Profile, job.TaskName, job.MetaData, Log.AppLog); eMailSendEngine.AddEmailToSendQueue(subject, (skipBody ? "" : message)); // Send the eMail through the eMail engine } } break; case "Cancelled": { Log.AppLog.WriteEntry(this, "Job for " + job.OriginalFileName + " Cancelled using Conversion Task " + job.TaskName + " and Profile " + job.Profile, Log.LogEntryType.Information, true); historyIni.Write(job.OriginalFileName, "CancelledUsingProfile" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.Profile); historyIni.Write(job.OriginalFileName, "CancelledUsingTask" + convCount.ToString(System.Globalization.CultureInfo.InvariantCulture), job.TaskName); // Send an eMail if required if (sendEMail && sendCancelled) { string subject = Localise.GetPhrase("MCEBuddy cancelled a video conversion"); string message = Localise.GetPhrase("Source Video") + " -> " + job.OriginalFileName + "\r\n"; message += Localise.GetPhrase("Profile") + " -> " + job.Profile + "\r\n"; message += Localise.GetPhrase("Conversion Task") + " -> " + job.TaskName + "\r\n"; message += Localise.GetPhrase("Cancelled At") + " -> " + DateTime.Now.ToString("s", System.Globalization.CultureInfo.InvariantCulture) + "\r\n"; // It can be cancelled before it starts so end time is not a good indicator // Check for custom subject and process if (!String.IsNullOrWhiteSpace(sendCancelledSubject)) subject = UserCustomParams.CustomParamsReplace(sendCancelledSubject, job.WorkingPath, "", job.ConvertedFile, job.OriginalFileName, "", "", "", job.Profile, job.TaskName, job.MetaData, Log.AppLog); eMailSendEngine.AddEmailToSendQueue(subject, (skipBody ? "" : message)); // Send the eMail through the eMail engine } } break; default: Log.AppLog.WriteEntry(this, "INVALID STATE (" + result + ") -> Job for " + job.OriginalFileName + " Converted using Conversion Task " + job.TaskName + " and Profile " + job.Profile, Log.LogEntryType.Error, true); break; } if ( _queueManager.JobCount(job.OriginalFileName) <= 1) { // This is the last job processing this file, so write the status to the history file STATUS historyIni.Write(job.OriginalFileName, "Status", result); // Source file status } }