Skip to content

Daemon Recommended Usage

Gustavo Sverzut Barbieri edited this page Dec 11, 2013 · 2 revisions

The daemon is recommended when multiple applications are interested in the same media data base. Since media tends to be an user-based information, the daemon will run in the D-Bus Session Bus and the applications should connect to it using the well-known name org.lightmediascanner and the path /org/lightmediascanner/Scanner1. If the service file is installed properly the dbus-daemon will auto-activate lightmediascannerd once any method is called, alternatively one can force its activation by calling org.freedesktop.DBus.StartServiceByName("org.lightmediascanner", 0) on the bus name org.freedesktop.DBus, path /org/freedesktop/DBus and interface org.freedesktop.DBus.

Properties

Once connected to the daemon, listen to its properties using org.freedesktop.DBus.Properties interface, it will provide, among others:

  • DataBasePath: string with the file system path to the SQLite3 database.
  • WriteLocked: someone holds the database and wants to write to it, for instance to update its own relation tables. Do not access the database while this property is true!
  • IsScanning: boolean that indicates whenever the daemon is working to scan new media and check if known media is up to date. This is a superset of WriteLocked=True, which is also set, but the scanning means the daemon itself is doing the work.
  • UpdateID: an incremental integer notifying the last update of the database. Whenever an operation results in a file being inserted, deleted or modified, this property will be incremented. Whenever you access the database store the UpdateID at that time. Whenever this property is updated and it becomes different from the value you had you must update your own data. See DataBase-Recommended Usage.
  • Categories: an array of pairs category and paths-to-scan-in-category (array of strings). This can be used as information of what will be scanned for debug purposes.

Methods

If the application wants to manage scan of new media, it should use the following methods of the org.lightmediascanner.Scanner1 interface of /org/lightmediascanner/Scanner1 object path:

  • Scan(a{sv}): start the scan. The argument specifies an array of pairs category and paths-to-scan-in-category (array of strings). If paths-to-scan-in-category is empty, then all paths of that category will be scanned. If no categories are given, all categories with all known paths will be scanned. The most common case is to give an empty list, which results in scan everything. If the application wants to know which categories exist and which directories they cover, see the property Categories. The argument is useful in the following cases:
    • Specific Media Players: an audio player may require only audio is scanned, video, pictures and other media will be left untouched. This is achieved using Array(["audio", Array([])]).
    • Removable Media Managers: an application that monitors the system for removable media being inserted or removed should scan with only that directory as input, leaving others untouched -- much faster. Suppose /media is in the category multimedia and /media/usbdrive1 is mounted. Then this application should use Array(["multimedia", Array(["/media/usbdrive1"])]). As soon as the drive is unmounted it should request scan again using the same arguments to mark all media from such directory as deleted! Remember LightMediaScanner is smart enough to not remove entries from database, just mark them as deleted (dtime), thus if the drive is inserted agai, mounted to the same directory and Scan() called with the same arguments the files will be marked alive without the need to parse them again.
  • Stop(): stop an existing scan. This is mostly useful for those that requested scan to abort it.
  • RequestWriteLock(): requests a lock for you (based on D-Bus unique name). If may fail since others may have hold the lock or the daemon is scanning. The lock will go away if the D-Bus unique name that holds it is gone (disconnects, process crashed, etc).
  • ReleaseWriteLock(): release a previously hold lock.

Signals

An user interface may listen to ScanProgress signal, it will be reported timely during scans to give an overview of the current category, path and number of items processed, deleted, up to date, etc.

Work Flow

Common work flow:

  1. Connect to D-Bus Session Bus
  2. org.freedesktop.DBus.StartServiceByName("org.lightmediascanner", 0)
  3. Watch name owner to see when org.lightmediascanner changes
    1. When name appears, get and monitor properties from /org/lightmediascanner/Scanner1
      1. If WriteLocked=False, open DataBasePath for read and remember UpdateID.
      2. If property changed reports WriteLocked=True, close DataBasePath and stop using it.
      3. If property changed reports UpdateID different from previous, then refresh your data.
    2. When name is gone, stop talking to /org/lightmediascanner/Scanner1, maybe show a warning to the user.

Scanner work flow, after name owner appears:

  1. Listen ScanProgress signal.
  2. Two new albums (Album1 and Album2) from Artist1 were imported to user's directory and should be scanned, then call Scan(Array(["audio", Array(["/home/user1/Music/Artist1/Album1", "/home/user1/Music/Artist1/Album2"])]))
    1. Handle errors, maybe database was locked or was already scanning.
    2. Show progress when ScanProgress signal is issued.
  3. When IsScanning=False the scan process is finished and should have WriteLocked=False. If some media was found, UpdateID was changed and you should refresh your views.

Writer work flow, after name owner appears:

  1. call RequestWriteLock()
  2. Handle errors, maybe database was locked or was already scanning.
  3. If no errors, do your own operations to database.
  4. If you want other applications to reload their views, then change update_id from files rows you changed and the table lms_internal, row matching tab = 'update_id' with a new version. This will be emitted as UpdateID by the daemon.
  5. call ReleaseWriteLock()
Clone this wiki locally