Allow snaps to register new mime types?

snapd, when installing a snap, has some logic to parse desktop files and generate a mimeinfo.cache file that associates mime types to desktop files.

This allows e.g. a snapped app to advertise that it handles the application/x-foobarbaz mime type.

However there doesn’t seem to be a way for the snap to register application/x-foobarbaz as a new mime type (according to the shared-mime-info spec) so that it is recognized by the host system.

This would require invoking update-mime-database on a directory containing xml descriptions.

Are there any plans to add this functionality to snapd?

5 Likes

I recently wrote an app that requires this functionality. It needs to register a MIME type for a file type that is downloaded from a website. For this reason I was unable to distribute it as a Snap, and have to fall back to using a PPA. I’m sure there’s lots of other apps that would fall into this category that would benefit from being shipped as Snaps.

Has there been progress or updated plans in this area?

Flatpak has some logic that (presumably) allows for sane export of MIME types: https://github.com/flatpak/flatpak/issues/656

UX is not so great for apps that ship their own file format(s) at the moment.

Any news on this?

Do we have a bug open at least? I didn’t find one with a quick check

There wasn’t one, so I went ahead and filed bug #1849094.

1 Like

In looking at another issue, I came across this. In general, it seems reasonable as a feature. I do have some thoughts:

  • xml parsers have historically had many security vulnerabilities. Furthermore, we probably want to abstract the xml implementation details so in the future snapd can adjust as needed for different versions, implementations, or distro-differences. I suggest rather than parsing a snap-supplied xml file, we instead provide some declarative mechanism that is a sufficient subset for snapd to take and generate the xml file to give to update-mime-database (analogous to what we do for systemd service files). This need not be expressed in the snap.yaml (but could be). I defer that to a design discussion
  • I think, at least at first, it would be wise to guard against a mime handler from a snap becoming the default without user input. I’m not sure what the UX would be here, but it could be either a command for the user to run (see below) or userd prompting
  • We need to think through the interactions between this and xdg-open from snapd. userd has a hardcoded lists of handlers. It seems we need some careful thinking around if a snap is trying to register something that is already handled by xdg-open

One option is implementing mime registration as an interface (ie, we declare to snapd via interfaces). This allows for things like:

  • snap.yaml has:
    name: foo
    plugs:
      register-mime-foo:
        interface: register-mime
        ... whatever yaml we decide on
    
  • snap install foo
  • snap connect foo:register-mime-foo # generates xml/runs update-mime-info
  • have snap declaration that allows auto-connecting

There are a lot of details to be worked out, but implementing as an interface allows us to use all the same mechanisms we have today for connecting/disconnecting which map to registering/unregistering a mime type.

2 Likes

Two thoughts:

  • AppStream currently supports defining mime-types as application metadata. Snapcraft currently supports using metadata from an AppStream file for supported fields such as “description” and “version”. Ideally, once snapd supports mime-types, Snapcraft should be updated to automatically enable it for snaps already using the AppStream metadata functionality.
  • Searching the store for snaps supporting a certain mime-type would be very useful. Would this be possible using the plugs proposal?
1 Like

@pedronis - when you have a chance, can you weigh in on this?

1 Like

The idea of using an interface seems sound, it means both the user and snap-declaration can have voices controlling this. The details need to be designed.

I am working on a project now that could really use this functionality. I would love to contribute to the community by writing an interface that does such a thing in the way that @galgalesh suggested and @pedronis approved. However, there seems to be little documentation on how to write interfaces. Is there anything out there? If someone could point me in the right direction, I am happy to work on this! In the meantime, thanks for all the work that you all do on such a great tool! I hope that I am able to help somehow!
Will