## Implementing Server Plugins: Full Example

In addition, the external rygel-gst-0-10-plugins project provides a Rygel Server plugin that uses an older GStreamer version and is an example of an external Rygel Server plugin implemented in C. Its media-export plugin exposes the contents of a directory via UPnP.

The `module_init` function first checks that the plugin has not been disabled and then creates an instance of its `RygelMediaExportPlugin`, which it adds to the provided `RygelPluginLoader` instance.

The `RygelMediaExportPlugin` class, derived from RygelMediaServerPlugin, simply instantiates its `RygelMediaExportRootContainer` class, derived from RygelMediaContainer, providing it to the base class as the root container.

The `RygelMediaExportRootContainer` creates an instance of a `RygelMediaExportMediaCache` class and a `RygelMediaExportHarvester` class. The harvester finds files on the filesystem, and stores them in the media cache, which uses SQLite to keep track of them.

`RygelMediaExportRootContainer` informs the media cache that it should have a child container for the media content as organised on the filesystem, and additionally some virtual folders for Music, Pictures, Video and Playlists, with further sub-divisions under these, for instance by publication year. These containers are added to the media cache via instances of the `RygelMediaExportNullContainer` class, but that is just to simplify the media cache API and these instances then serve no further purpose. The virtual folders are re-added whenever the filesystem's container is updated, so that they can show the updated content, though that is not particularly efficient.

`RygelMediaExportRootContainer` then delegates its `RygelMediaContainer` virtual function implementations to this media cache, which in turn uses the `RygelMediaExportObjectFactory` to instantiate new containers for each request based on their ID. For instance, it returns a `RygelMediaExportDBContainer` if the requested ID indicates a virtual container, using the definition in the rest of the ID to build a suitable SQL query.

The root container derives from `TrackableDbContainer`, which in turn implements the RygelTrackableContainer interface, to implement the change tracking profile of the UPnP ContentDirectory:3 specification. Therefore, whenever the root container, or its child items, have changed, we call the `rygel_trackable_container_updated()` function.

Any filesystem folders are implemented as UPnP containers via the `RygelMediaExportWritableDbContainer` class, which implements the RygelWritableContainer interface to allow new files to be uploaded to the filesystem via UPnP.