simonw / datasette

An open source multi-tool for exploring and publishing data
https://datasette.io
Apache License 2.0
9.21k stars 657 forks source link

Ability to set a custom favicon #1767

Open simonw opened 2 years ago

simonw commented 2 years ago

If you're running a website on Datasette, like https://www.niche-museums.com/ or https://til.simonwillison.net/ - you should have the ability to easily specify a custom favicon.

Currently the /favicon.ico view is hard-coded to do this: https://github.com/simonw/datasette/blob/9f1eb0d4eac483b953392157bd9fd6cc4df37de7/datasette/app.py#L179-L188

simonw commented 2 years ago

Some options:

Note that I need a way to set the content_type correctly too.

simonw commented 2 years ago

I think I want this to be a default feature, not a plugin.

simonw commented 2 years ago

Loading it using the existing templating system would be better I think, since that way both custom installations AND plugins could influence the favicon in the same way that they influence the templates.

simonw commented 2 years ago

The content type thing is a bit weird because usually I'd base that on the file extension, but here the favicon.ico file extension doesn't necessarily reflect if the image itself is a PNG or some other thing.

simonw commented 2 years ago

Annoyingly it looks like the standard library mimetypes module only uses filenames as the clue, it doesn't look at the bytes themselves.

I'm using that here: https://github.com/simonw/datasette/blob/9f1eb0d4eac483b953392157bd9fd6cc4df37de7/datasette/utils/asgi.py#L261-L277

https://pypi.org/project/python-magic/ can inspect files, but I don't want to add a whole new dependency just for this one feature.

simonw commented 2 years ago

I could use the imghdr standard library module, but frustratingly it's marked as deprecated in Python 3.11! https://docs.python.org/3/library/imghdr.html

simonw commented 2 years ago

I could vendor the necessary parts of imghdr - it's pretty tiny: https://github.com/python/cpython/blob/3.11/Lib/imghdr.py

simonw commented 2 years ago

https://www.w3.org/2005/10/howto-favicon suggests that it only needs to be able to identify PNG, GIF or ICO.

simonw commented 2 years ago

Based on https://github.com/python/cpython/blob/3.11/Lib/imghdr.py I'm tempted to say that if the file starts with b'\211PNG\r\n\032\n' then it's a PNG, if it starts with b'GIF8 then it's a GIF, anything else I assume an ICO.

simonw commented 7 months ago

Came up in office hours again today.

mroswell commented 7 months ago

It might be helpful to have a little library of Datasette favicons. One for documentation, one for cloud, one for default Datasette, one for the Substack, and maybe some others colors to make it easier to keep track of which ports and datasettes are which.. Maybe even a set with the datasette logo, with superimposed labels 1, 2, and 3, in case we have three different ports running at a time. (Hmm... I see the Substack already does have a slightly different favicon color and maybe different size as well. Different enough to be able to distinguish the tabs. That's helpful.)

mroswell commented 7 months ago

Maybe a little favicon designer hackathon, too! (The current default icon is VERRRY nerdy--maybe appropriate, but a slightly less nerdy favicon might be a draw?) The current icon also defaults (on my screen, anyhow) to a light color icon on a light color tab background. Doesn't stand out much. (Personally I couldn't create anything better, though). But now that Datasette can do so much ("multitool"), maybe the favicon should reflect that.