<chapter id="writing-an-indexer-module">
  <chapterinfo>
    <author>
      <firstname>Carlos</firstname>
      <surname>Garnacho</surname>
      <affiliation>
	<address>
	  <email>carlos@@imendio.com</email>
	</address>
      </affiliation>
    </author>
  </chapterinfo>

  <title>Writing An Indexer Module</title>

  <para>
    Tracker's indexer has a modular design, so applications can
    specify where to locate the data to extract metadata from,
    plus how it should be extracted. To achieve this,
    tracker-indexer needs two files, one to define module behavior
    (.module files) plus a .so file that will be called on each
    of the files the module is interested in.
  </para>

  <section id="creating-module-definition-file">
    <title>Creating a module definition file</title>

    <para>
      .module files are a key file with the following format:

      <programlisting>
[General]
Description=My extractor
Enabled=true

[Monitors]
Directories=
RecurseDirectories=$HOME/Documents;$HOME/Music

[Ignored]
Directories=
Files=

[Index]
Service=EvolutionEmails
MimeTypes=
Files=
      </programlisting>

      This file will be installed in $prefix/share/tracker/modules/ and
      it must share the same name with the corresponding .so file, prefixed with
      "libtracker-module-" (that is, for my-extractor.module, there must be
      a libtracker-module-my-extractor.so)
    </para>

    <table pgwide="1">
      <title>Module file description</title>

      <tgroup cols="2">
        <colspec colname="field" />
        <colspec colname="def" />
        <spanspec spanname="title-span" namest="field" nameend="def" align="center" />
        <thead>
          <row colspan="2">
            <entry spanname="title-span">General</entry>
          </row>
        </thead>
        <tbody>
          <row>
            <entry>Description</entry>
            <entry>A short description for the module</entry>
          </row>
          <row>
            <entry>Enabled</entry>
            <entry>Whether the module is enabled or not. This is useful at a sysadmin level.</entry>
          </row>
        </tbody>
      </tgroup>

      <tgroup cols="2">
        <colspec colname="field" />
        <colspec colname="def" />
        <spanspec spanname="title-span" namest="field" nameend="def" align="center" />
        <thead>
          <row colspan="2">
            <entry spanname="title-span">Monitors</entry>
          </row>
        </thead>
        <tbody>
          <row>
            <entry>Directories</entry>
            <entry>
              Semicolon separated list of directories that
              the module will handle, the indexer will not
              recurse into their contents.
            </entry>
          </row>
          <row>
            <entry>RecurseDirectories</entry>
            <entry>
              Semicolon separated list of directories
              that the module will handle, the indexer
              will recurse inside these directories' contents.
            </entry>
          </row>
        </tbody>
      </tgroup>

      <tgroup cols="2">
        <colspec colname="field" />
        <colspec colname="def" />
        <spanspec spanname="title-span" namest="field" nameend="def" align="center" />
        <thead>
          <row colspan="2">
            <entry spanname="title-span">Ignored</entry>
          </row>
        </thead>
        <tbody>
          <row>
            <entry>Directories</entry>
            <entry>Directories that the indexer will skip.</entry>
          </row>
          <row>
            <entry>Files</entry>
            <entry>Files that the indexer will skip.</entry>
          </row>
        </tbody>
      </tgroup>

      <!-- FIXME: Missing Index section -->
    </table>
  </section>

  <section id="creating-extractor-module-binary">
    <title>Creating an extractor module binary</title>

    <para>
      Modules are implemented as standalone .so files with a defined API,
      the indexer's task is to crawl through all the defined directories in
      the .module file and ask the module for information about that file.
    </para>

    <para>
      The API to implement is the following:

      <programlisting>
void     indexer_module_initialize (void); /* GTypes and other static data initialization */
void     indexer_module_shutdown   (void); /* Free all static resources here */
#TrackerModuleFile *
         indexer_module_create_file (GFile *file);
      </programlisting>
    </para>

    <para>
      Modules can implement one or many #TrackerModuleFile objects, which will
      be used by the indexer to extract information. Optionally, #TrackerModuleFile
      objects can also implement the #TrackerModuleIteratable interface, so the
      indexer can iterate through the contents of the file and index them as
      separate entities.
    </para>
  </section>
</chapter>
