NameError: name 'FileIngestModule' is not defined

When I try to load my Autopsy plugin I get this error:

SEVERE: Failed to load ExportImgVidAudFactory from C:\Users\user\AppData\Roaming\autopsy\python_modules\ExportImgVidAud\exportImgVidAud.py
Traceback (most recent call last):
File “”, line 1, in
File “C:\Users\user\AppData\Roaming\autopsy\python_modules\ExportImgVidAud\exportImgVidAud.py”, line 82, in
class ExportImgVidAud(FileIngestModule):
NameError: name ‘FileIngestModule’ is not defined

org.python.core.Py.NameError(Py.java:284)
org.python.core.PyFrame.getname(PyFrame.java:257)
exportImgVidAud$py.f$0(C:\Users\user\AppData\Roaming\autopsy\python_modules\ExportImgVidAud\exportImgVidAud.py:82)
exportImgVidAud$py.call_function(C:\Users\user\AppData\Roaming\autopsy\python_modules\ExportImgVidAud\exportImgVidAud.py)
org.python.core.PyTableCode.call(PyTableCode.java:167)
org.python.core.PyCode.call(PyCode.java:18)
org.python.core.imp.createFromCode(imp.java:436)
org.python.core.imp.createFromSource(imp.java:396)
org.python.core.imp.loadFromSource(imp.java:658)
org.python.core.imp.find_module(imp.java:543)
org.python.core.imp.import_next(imp.java:840)
org.python.core.imp.import_module_level(imp.java:959)
org.python.core.imp.importName(imp.java:1062)
org.python.core.ImportFunction.call(builtin.java:1280)
org.python.core.PyObject.call(PyObject.java:431)
org.python.core.builtin.import(builtin.java:1232)
org.python.core.imp.importOne(imp.java:1081)
org.python.pycode._pyx2.f$0(:1)
org.python.pycode._pyx2.call_function()
org.python.core.PyTableCode.call(PyTableCode.java:167)
org.python.core.PyCode.call(PyCode.java:18)
org.python.core.Py.runCode(Py.java:1386)
org.python.core.Py.exec(Py.java:1430)
org.python.util.PythonInterpreter.exec(PythonInterpreter.java:267)
org.sleuthkit.autopsy.python.JythonModuleLoader.createObjectFromScript(JythonModuleLoader.java:138)
org.sleuthkit.autopsy.python.JythonModuleLoader.getInterfaceImplementations(JythonModuleLoader.java:106)
org.sleuthkit.autopsy.python.JythonModuleLoader.getIngestModuleFactories(JythonModuleLoader.java:60)
org.sleuthkit.autopsy.ingest.IngestModuleFactoryLoader.getIngestModuleFactories(IngestModuleFactoryLoader.java:129)
org.sleuthkit.autopsy.ingest.IngestJobSettings.load(IngestJobSettings.java:316)
org.sleuthkit.autopsy.ingest.IngestJobSettings.(IngestJobSettings.java:119)
org.sleuthkit.autopsy.ingest.runIngestModuleWizard.IngestModulesConfigWizardPanel.getComponent(IngestModulesConfigWizardPanel.java:70)
org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesWizardIterator.(RunIngestModulesWizardIterator.java:58)
org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction.actionPerformed(RunIngestModulesAction.java:129)
javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
javax.swing.AbstractButton.doClick(AbstractButton.java:376)
javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:842)
javax.swing.plaf.basic.BasicMenuItemUI$Handler.menuDragMouseReleased(BasicMenuItemUI.java:952)
javax.swing.JMenuItem.fireMenuDragMouseReleased(JMenuItem.java:586)
javax.swing.JMenuItem.processMenuDragMouseEvent(JMenuItem.java:483)
javax.swing.JMenuItem.processMouseEvent(JMenuItem.java:429)
javax.swing.MenuSelectionManager.processMouseEvent(MenuSelectionManager.java:339)
javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.eventDispatched(BasicPopupMenuUI.java:870)
java.awt.Toolkit$SelectiveAWTEventListener.eventDispatched(Toolkit.java:2431)
java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Toolkit.java:2323)
java.awt.Toolkit.notifyAWTEventListeners(Toolkit.java:2281)
java.awt.Component.dispatchEventImpl(Component.java:4785)
java.awt.Container.dispatchEventImpl(Container.java:2297)
java.awt.Component.dispatchEvent(Component.java:4711)
java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904)
java.awt.LightweightDispatcher.processMouseEvent(Container.java:4535)
java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476)
java.awt.Container.dispatchEventImpl(Container.java:2283)
java.awt.Window.dispatchEventImpl(Window.java:2746)
java.awt.Component.dispatchEvent(Component.java:4711)
java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
java.awt.EventQueue.access$500(EventQueue.java:97)
java.awt.EventQueue$3.run(EventQueue.java:709)
java.awt.EventQueue$3.run(EventQueue.java:703)
java.security.AccessController.doPrivileged(Native Method)
java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
java.awt.EventQueue$4.run(EventQueue.java:733)
java.awt.EventQueue$4.run(EventQueue.java:731)
java.security.AccessController.doPrivileged(Native Method)
java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:159)
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

However there is no real error in my plugin.
What causes this error?

C:\Users\user\AppData\Roaming\autopsy\python_modules\ExportImgVidAud\exportImgVidAud.py

# File: ExportImgVidAudFactory
# Version 0.0.1
# Date 12:36 23.02.2020
# Copyright (c) 2020 S. A. Ditlefsen
# License: http://opensource.org/licenses/gpl-license.php GNU Public License
#

import jarray
import inspect
import os
from subprocess import Popen, PIPE
import json

from javax.swing import JCheckBox
from javax.swing import JButton
from javax.swing import ButtonGroup
from javax.swing import JTextField
from javax.swing import JLabel
from java.awt import GridLayout
from java.awt import GridBagLayout
from java.awt import GridBagConstraints
from javax.swing import JPanel
from javax.swing import JList
from javax.swing import JScrollPane
from javax.swing import JFileChooser
from javax.swing import JComboBox
from javax.swing import JPasswordField
from javax.swing.filechooser import FileNameExtensionFilter

from java.lang import Class
from java.lang import System
from java.sql  import DriverManager, SQLException
from java.util.logging import Level
from java.io import File
from org.sleuthkit.datamodel import SleuthkitCase
from org.sleuthkit.datamodel import AbstractFile
from org.sleuthkit.datamodel import ReadContentInputStream
from org.sleuthkit.datamodel import BlackboardArtifact
from org.sleuthkit.datamodel import BlackboardAttribute
from org.sleuthkit.datamodel import TskData
from org.sleuthkit.autopsy.ingest import IngestModule
from org.sleuthkit.autopsy.ingest.IngestModule import IngestModuleException
from org.sleuthkit.autopsy.ingest import DataSourceIngestModule
from org.sleuthkit.autopsy.ingest import IngestModuleFactoryAdapter
from org.sleuthkit.autopsy.ingest import GenericIngestModuleJobSettings
from org.sleuthkit.autopsy.ingest import IngestModuleIngestJobSettingsPanel
from org.sleuthkit.autopsy.ingest import IngestMessage
from org.sleuthkit.autopsy.ingest import IngestServices
from org.sleuthkit.autopsy.ingest import ModuleDataEvent
from org.sleuthkit.autopsy.coreutils import Logger
from org.sleuthkit.autopsy.coreutils import PlatformUtil
from org.sleuthkit.autopsy.casemodule import Case
from org.sleuthkit.autopsy.casemodule.services import Services
from org.sleuthkit.autopsy.casemodule.services import FileManager
from org.sleuthkit.autopsy.datamodel import ContentUtils

# Copy Multimedia Factory ---------------------------------------------------------------------------------------------------
class ExportImgVidAudFactory(IngestModuleFactoryAdapter):

    # TODO: give it a unique name.  Will be shown in module list, logs, etc.
    moduleName = "Export images videos and audio module"

    def getModuleDisplayName(self):
        return self.moduleName

    # TODO: Give it a description
    def getModuleDescription(self):
        return "Module that find all images, videoes and audio. It copies everything to a new folder. "

    def getModuleVersionNumber(self):
        return "1.0"

    # Return true if module wants to get called for each file
    def isFileIngestModuleFactory(self):
        return True

    # can return null if isFileIngestModuleFactory returns false
    def createFileIngestModule(self, ingestOptions):
        return ExportImgVidAud()

# Copy Multimedia ----------------------------------------------------------------------------------------------------------
class ExportImgVidAud(FileIngestModule):

    _logger = Logger.getLogger(ExportImgVidAudFactory.moduleName)

    def log(self, level, msg):
        self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)

    # Startup
    def startUp(self, context):
        self.filesFound = 0

        pass

    # Process
    def process(self, file):
        # Skip non-files
        if ((file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) or
            (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) or
            (file.isFile() == False)):
            return IngestModule.ProcessResult.OK

        # Blackboard
        blackboard = Case.getCurrentCase().getServices().getBlackboard()
	
	# Filetype utils, to get a list of images and videoes file types
	#FileTypeUtils.IMAGE_MIME_TYPES

	# List of images and videoes
	listOfMimeToCopy = ['image/bmp','image/gif', 'image/jpeg', 'image/png', 'image/tiff',
                        'image/vnd.adobe.photoshop', 'image/x-raw-nikon', 'image/x-ms-bmp', 'image/x-icon', 'image/webp',
                        'image/vnd.microsoft.icon', 'image/x-rgb', 'image/x-ms-bmp','image/x-xbitmap','image/x-portable-graymap',
                        'image/x-portable-bitmap',
			'video/webm', 'video/3gpp', 'video/3gpp2', 'video/ogg','video/mpeg', 
                         'video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/x-flv', 'video/x-m4v', 
                         'video/x-ms-wmv',
			'audio/midi', 'audio/mpeg', 'audio/webm', 'audio/ogg', 'audio/wav', 
                        'audio/vnd.wave', 'audio/x-ms-wma']

	# Export directory (C:\Users\user\Documents\cases\1568795\Autopsy\1568795_2020_5060_90_1_sofias_pc\Export)
        exportDirectory = Case.getCurrentCase().getExportDirectory()
	caseName = Case.getCurrentCase().getName()
	number = Case.getCurrentCase().getNumber()
	exportDirectory = exportDirectory.replace("\\Autopsy", "");
	exportDirectory = exportDirectory.replace("\\" + str(number), "");
	exportDirectory = exportDirectory.replace("\\Export", "");
	ImgVideoAudioDirectory = os.path.join(exportDirectory, "Img_video_audio")
	self.log(Level.INFO, "==>exportDirectory=" + str(exportDirectory) + " number=" + str(number))
	try: 
		os.mkdir(ImgVideoAudioDirectory)
	except:
		self.log(Level.INFO, "")

        # For an example, we will flag files with .txt in the name and make a blackboard artifact.
	if(file.getMIMEType() in listOfMimeToCopy):

		# Recreate path
		uniquePathFullLinux = file.getUniquePath();
		
		# Recreate path Windows
		uniquePathFullWindows = uniquePathFullLinux.replace("/", "\\")
		uniquePathFullWindows = uniquePathFullWindows[1:]
		
		fileName = os.path.basename(uniquePathFullWindows)
		uniquePathWindows = uniquePathFullWindows.replace(fileName, "");
		
		# Create directory
		splitDir = uniquePathWindows.split("\\")
		pathToCreate = os.path.join(exportDirectory, "Img_video_audio")
		for directory in splitDir:
			directory = directory.replace(":", "")
			pathToCreate = os.path.join(pathToCreate, directory)
			# self.log(Level.INFO, "==> directory=" + str(directory) + " pathToCreate=" + str(pathToCreate))

			try: 
				os.mkdir(pathToCreate)
			except:
				self.log(Level.INFO, "")
		
		# Write file
                try:
			extractedFile = os.path.join(pathToCreate, file.getName())
			ContentUtils.writeToFile(file, File(extractedFile))

                except:
			self.log(Level.SEVERE, "Error writing File " + file.getName() + " to " + extractedFile)


		# Make artifact on blackboard
		art = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT)
		att = BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, ExportImgVidAudFactory.moduleName, "Images, videoes and audio")
		art.addAttribute(att)

		# Index artifact
		try:
			# index the artifact for keyword search
			blackboard.indexArtifact(art)
		except Blackboard.BlackboardException as e:
			self.log(Level.SEVERE, "Error indexing artifact " + art.getDisplayName())

		# UI
		IngestServices.getInstance().fireModuleDataEvent(ModuleDataEvent(ExportImgVidAudFactory.moduleName, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, None))



        return IngestModule.ProcessResult.OK
    # Shutdown
    def shutDown(self):
        # As a final part of this example, we'll send a message to the ingest inbox with the number of files found (in this thread)
        message = IngestMessage.createMessage(
            IngestMessage.MessageType.DATA, ExportImgVidAudFactory.moduleName,
                str(self.filesFound) + " files found")
        ingestServices = IngestServices.getInstance().postMessage(message)

Looks like you have not imported FileIngestModule, you have imported DataSourceIngestModule though which you can probably remove.

1 Like

Thanks, that did the trick.