[core/theme] Add FontAwesome name resolution

Theme writers are now able to use FontAwesome names and IDs instead of
the symbols itself!

The implementation itself is *slightly* hacky and might get improved in
the future: Upon the first start, a YAML file containing the FontAwesome
symbols is fetched from
https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/src/icons.yml

Note: This is only done once - to retrigger this (i.e. for an update),
please just delete the file and restart bumblebee-status.

Then, in the *icon* theme itself, you can use ${<name or id>} instead of
the actual symbol.

Names and IDs can be found here:
http://fontawesome.io/cheatsheet/

(simply remove the "fa-" prefix)

An example is provided in themes/icons/awesome-fonts.json.

(finally) fixes #20

sorry for taking so long :)
This commit is contained in:
Tobias Witek 2017-12-29 14:49:13 +01:00
parent 2a95e9fcc2
commit bac3d6bc57
2 changed files with 48 additions and 3 deletions

View file

@ -6,7 +6,16 @@ import os
import glob
import copy
import json
import yaml
import io
import re
import logging
try:
import requests
from requests.exceptions import RequestException
except ImportError:
pass
import bumblebee.error
@ -36,11 +45,39 @@ class Theme(object):
self._cycle = {}
self._prevbg = None
self._colorset = {}
self.load_symbols()
data = self.load(name)
if not data:
raise bumblebee.error.ThemeLoadError("no such theme")
self._init(data)
def load_symbols(self):
self._symbols = {}
path = os.path.expanduser("~/.config/bumblebee-status/")
try:
os.makedirs(path)
except Exception:
pass
try:
if not os.path.exists("{}/symbols.json".format(path)):
data = yaml.load(requests.get("https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/src/icons.yml").text)
with io.open("{}/symbols.json".format(path), "w") as f:
json.dump(data, f)
data = json.load(io.open("{}/symbols.json".format(path)))
self._symbols = {}
for icon in data["icons"]:
code = int(icon["unicode"], 16)
try:
code = unichr(code)
except Exception:
code = chr(code)
self._symbols["${{{}}}".format(icon["id"])] = code
self._symbols["${{{}}}".format(icon["name"])] = code
except Exception as e:
logging.error("failed to load symbols: {}".format(str(e)))
def _init(self, data):
"""Initialize theme from data structure"""
self._theme = data
@ -131,7 +168,15 @@ class Theme(object):
result = {}
for path in theme_path():
self._merge(result, self.load(name, path="{}/icons/".format(path)))
return result
return self._replace_symbols(result)
def _replace_symbols(self, data):
rep = json.dumps(data)
tokens = re.findall(r"\${[^}]+}", rep)
for token in tokens:
rep = rep.replace(token, self._symbols[token])
return json.loads(rep)
def load(self, name, path=theme_path()):
"""Load and parse a theme file"""

View file

@ -3,8 +3,8 @@
"separator": "", "padding": " ",
"unknown": { "prefix": "" }
},
"date": { "prefix": "" },
"time": { "prefix": "" },
"date": { "prefix": "${calendar}" },
"time": { "prefix": "${clock-o}" },
"datetime": { "prefix": "" },
"memory": { "prefix": "" },
"cpu": { "prefix": "" },