Click or drag to resize

Sample Plugin

The TessPro plugin is a .Net framework class library which implements the IPlugin interface:

C#
namespace Opait.TessPro.Api
{
    /// <summary>
    /// The interface defines a plugin for the TessPro Service.
    /// </summary>
    public interface IPlugin
    {
        /// <summary>
        /// A processor has started.
        /// </summary>
        /// <param name="processor">The processor.</param>
        /// <returns>The instruction to the server on how to proceed.</returns>
        ActionCode ProcessorStarted(Processor processor);

        /// <summary>
        /// A job has been loaded and is about to be processed.
        /// </summary>
        /// <param name="job">The loaded job.</param>
        /// <returns>The instruction to the server on how to proceed.</returns>
        ActionCode JobStarted(Job job);

        /// <summary>
        /// A list of qualified source files were detected for the current job to process.
        /// </summary>
        /// <param name="job">The current active job.</param>
        /// <param name="documents">The list of qualified documents.</param>
        /// <param name="size">The total size of source files.</param>
        /// <returns>The instruction to the server on how to proceed.</returns>
        ActionCode DocumentsDetected(Job job, IList<Document> documents, long size);

        /// <summary>
        /// A specific document has been locked and is about to be processed.
        /// </summary>
        /// <param name="job">The current active job.</param>
        /// <param name="document">The locked document.</param>
        /// <returns>The instruction to the server on how to proceed.</returns>
        ActionCode DocumentStarted(Job job, Document document);

        /// <summary>
        /// A specific document has been successfully processed.
        /// </summary>
        /// <param name="job">The current active job.</param>
        /// <param name="document">The processed document.</param>
        /// <param name="error">The exception that caused a failure, or null if processing was successful.</param>
        /// <returns>The instruction to the server on how to proceed.</returns>
        ActionCode DocumentCompleted(Job job, Document document, Exception error = null);

        /// <summary>
        /// The processing of the specified job completed.
        /// </summary>
        /// <param name="job">The current active job.</param>
        /// <returns>The instruction to the server on how to proceed.</returns>
        ActionCode JobCompleted(Job job);

        /// <summary>
        /// The processor has completed.
        /// </summary>
        /// <param name="processor">The processor.</param>
        /// <param name="error">The exception that caused the termination, or null if no errors were encountered.</param>
        /// <param name="canceled">'True' if the user canceled, otherwise, 'false'.</param>
        /// <returns>The instruction to the server on how to proceed.</returns>
        ActionCode ProcessorCompleted(Processor processor, Exception error, bool canceled);
    }
}

The plugin is dynamically loaded by the processing engine during runtime. The methods defined in the IPlugin interface are called by the engine as it processes files. The Plugin code can act on these callbacks and modify the processing workflow by returning certain action codes.

The return codes from each plugin callback is one of the following values:

C#
namespace Opait.TessPro.Api
{
    /// <summary>
    /// Action codes that are returned from plugin callbacks.
    /// </summary>
    public enum ActionCode
    {
        /// <summary>
        /// Continue with the normal processing of the workflow.
        /// </summary>
        Continue,

        /// <summary>
        /// Continue processing after skipping the current operation. 
        /// </summary>
        Skip,

        /// <summary>
        /// Cancel the processing loop.
        /// </summary>
        Cancel,

        /// <summary>
        /// Fail the current job and move the file to the failed folder.
        /// </summary>
        Fail,

        /// <summary>
        /// Processing is complete. Move the file to the done folder.
        /// </summary>
        Done,

        /// <summary>
        /// Restart the processing of the file with new parameters.
        /// </summary>
        Restart
    }
}

The callback functions may also include various other interfaces and classes related to the processing phase of the workflow. These are documented in the reference portion of this guide.

If you are only interested in one or two of the callbacks, then you could derive you class from the base Plugin class and override one or two virtual methods. This will save you from having to implement all functions of the interface. The following code illustrates this point by only overriding some callback functions.

C#
using System;
using System.Diagnostics;
using Opait.TessPro.Api;

namespace TessConsole
{
    /// <summary>
    /// A simple plugin implementation for post processing documents after
    /// they have been processed by the OCR engine. The plugin is derived
    /// from the PluginBase class which provides a default, do nothing, 
    /// implementation of the IPlugin interface. All methods of the PluginBase
    /// class are virtual and can be overridden in a concrete implementation.
    /// </summary>
    public class MyPlugin : PluginBase
    {
        /// <summary>
        /// Using a stopwatch to time the processing.
        /// </summary>
        private Stopwatch stopwatch = new Stopwatch();

        public override ActionCode ProcessorStarted(Processor processor)
        {
            stopwatch.Start();
            Console.WriteLine($"Processing started: {processor.Project.FileName}");
            return base.ProcessorStarted(processor);
        }

        /// <summary>
        /// This plugin method is called by the processing engine after a 
        /// document has been processed and converted to a searchable PDF.
        /// The callback identifies attributes of the source file, as well as, 
        /// where the destination, searchable PDF, was created.
        /// </summary>
        /// <param name="job">Access to the job that processed the document.</param>
        /// <param name="document">The document that was processed.</param>
        /// <param name="error">The error that was received if the processing failed.</param>
        /// <returns>Instruction to the processing engine on how to proceed.</returns>
        public override ActionCode DocumentCompleted(Job job, Document document, Exception error = null)
        {
            // Here, we are simply logging some info to the console. In an actual 
            // implementation, the document could be routed to another area, 
            // passed to a third-party application an so on.
            Console.WriteLine();
            Console.WriteLine($"Job:       {job.JobName}");
            Console.WriteLine($"FileName:  {document.FileName}");
            Console.WriteLine($"DestName:  {document.DestName}");
            Console.WriteLine($"PageCount: {document.PageCount}");
            if (error != null)
                Console.WriteLine($"Error:     {error}");
            return base.DocumentCompleted(job, document, error);
        }

        public override ActionCode ProcessorCompleted(Processor processor, Exception error, bool Canceled)
        {
            stopwatch.Stop();
            Console.WriteLine();

            if (canceled)
                Console.WriteLine("Processing canceled.");
            else if (error != null)
                Console.WriteLine($"Processing failed: {error}");
            else
                Console.WriteLine($"Processing completed in {stopwatch.ElapsedMilliseconds / 1000} seconds.");

            return ActionCode.Continue;
        }
    }
}