For an upcoming project I thought of creating a GUI font installer app that would automatically install the latest version of a typeface that my client can start using at an early stage and then receive and immediately use updates as they become available.
Instead of making it available to use just for myself/my own fonts, I thought it could be an interesting piece of software to have publicly available.
I would program it in Python using a cross-platform GUI library such as pyGUI (recommendations welcome), and host it on Github. I would take responsibility for distributing a signed app for MacOS, and other people can make distros for Windows and Linux later. I really don't want to be bothered with the other platforms, except maybe quality control.
I'm looking for the simple-most design for both customers and distributors, and myself of course. I don't have much time
This is how I think it should work:
Each participating distributor sets up an API point on their website (https only).
After purchasing fonts, customers can then click on a link (can be nicely implemented using custom URL protocols) or copy/paste a URL into the app to show the available fonts.
The API point would accept a customer-specific API key parameter that would limit the available fonts to the purchases of that customer. The API point would then return a list of fonts and the customer can choose to install those fonts on his system with the option to keep them up-to-date automatically.
The distributor could choose to limit the number of installations of a font to the number of seats covered by the purchased license at his responsibility using the anonymous "uniqueAppID" parameter of the download URL (see below). He could then reject the inquiry with a predefined response such as "toomanyseats", together with a URL for the user to upgrade the license. Then, a font would first need to be removed from another installation.
The "seatsAllowed" and "upgradeSeatsURL" parameter in the JSON response below is merely for display in the app and would not be enforced in any way by the app. The rejection of the font download is in the distributor's responsibility.
(I'm not sure if this whole part is even necessary, because fonts would always be available to download from the distributor's web sites. Maybe just displaying the licensing information in the app is enough. The API point could return the "seatsInUse" attribute together with "seatsAllowed" to bully, sorry, convince the customer to upgrade their license. The GUI would display an information about that.
Anyway, rejecting a download and requiring a de-installation from another app instance opens up the gates for trouble and frustration and customer support, because how do you find which computers the fonts are installed on?)
Also, removal of fonts from a customer's system would be lazy, as customers can make copies of the fonts, and also re-download them from the distributor's web sites anyway.
and return such information (I wrote this JSON by hand, just for illustration purposes):
"supportEmail": "[email protected]",
"familyName": "Noname Sans",
"productName": "Desktop", # optional, thinking office fonts and such here, also see font's unique ID
"description": "Sans serif linear Antiqua with classicist character",
"license": "Yanone EULA",
"versionInformation": "Initial Release",
"versionInformation": "Updated spacing and kerning",
Individual fonts would then be pulled from a URL like this:
This would open one distributor to be able to distribute fonts of several foundries.
Which fonts the distributors include is in their responsibility. Could be free fonts, too.
A few questions:
Did I miss anything?
Should a font be removed from the app/system if it was included in the available fonts earlier but then removed by the foundry later?
Will the downloaded fonts need to be validated in a certain way to protect users? If yes, who knows how?
Which other security issues am I ignoring?
Do we have naming ideas for the app? It should be catchy, shouldn't it?
I have a generic logo idea, but I'm not showing it yet. Logo always needs to come first, right?