Check-in [2ee52fe7e8]
Overview
| Comment: | Switch to XDG_CACHE_HOME/.cache (because that's what the cache files are, not really user data). More consistently use new storage path throughout core and plugins (favicon+cachereset). |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
2ee52fe7e8f181b1cb38048d52eeadf0 |
| User & Date: | mario on 2019-02-06 21:16:44 |
| Other Links: | manifest | tags |
Context
|
2019-03-24
| ||
| 10:25 | Crude fix for new station lookup. Regex still has horrible backtracking. (Should use resolve_urn rather than rnjs playlist workaround.) check-in: 6bfe67e367 user: mario tags: trunk | |
|
2019-02-06
| ||
| 21:16 | Switch to XDG_CACHE_HOME/.cache (because that's what the cache files are, not really user data). More consistently use new storage path throughout core and plugins (favicon+cachereset). check-in: 2ee52fe7e8 user: mario tags: trunk | |
|
2019-02-04
| ||
| 09:30 | Transitional .cache/XDG_DATA_HOME support (by symlinking from .config dir) check-in: 77d42c82df user: mario tags: trunk | |
Changes
Modified channels/favicon.py from [edc53741f5] to [81d5a0ff38].
| ︙ | ︙ | |||
78 79 80 81 82 83 84 |
meta = plugin_meta()
# Register with main
def __init__(self, parent):
# Prepare favicon cache directory
| | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
meta = plugin_meta()
# Register with main
def __init__(self, parent):
# Prepare favicon cache directory
conf.icon_dir = conf.datadir + "/icons"
if not os.path.exists(conf.icon_dir):
os.mkdir(conf.icon_dir)
open(conf.icon_dir+"/.nobackup", "a").close()
# Reference main, and register station .play() hook
self.parent, self.main = parent, parent
parent.hooks["play"].append(self.update_playing)
|
| ︙ | ︙ |
Modified config.py from [08e51d1986] to [833278b4e6].
| ︙ | ︙ | |||
9 10 11 12 13 14 15 |
# { arg: --gtk3, type: boolean, name: gtk3, description: Start with Gtk3 interface. }
# { arg: --nt, type: boolean, name: nothreads, description: Disable threading/gtk_idle UI. }
# { arg: -D, type: boolean, name: debug, description: Enable debug messages on console }
# { arg: action, type: str *, name: action[], description: CLI interface commands. }
# { arg: -x, type: boolean, name: exit, hidden: 1 }
# { arg: -V, type: boolean, name: version, description: Print version. }
# { arg: -w, type: boolean, name: pydoc, hiden: 1 }
| | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# { arg: --gtk3, type: boolean, name: gtk3, description: Start with Gtk3 interface. }
# { arg: --nt, type: boolean, name: nothreads, description: Disable threading/gtk_idle UI. }
# { arg: -D, type: boolean, name: debug, description: Enable debug messages on console }
# { arg: action, type: str *, name: action[], description: CLI interface commands. }
# { arg: -x, type: boolean, name: exit, hidden: 1 }
# { arg: -V, type: boolean, name: version, description: Print version. }
# { arg: -w, type: boolean, name: pydoc, hiden: 1 }
# version: 2.8
# priority: core
# depends: pluginconf >= 0.1, os, json, re, zlib, pkgutil
#
# Ties together the global conf.* object. It's typically used
# in the main application and modules with:
#
# from config import *
|
| ︙ | ︙ | |||
202 203 204 205 206 207 208 |
return players[typ][-1]
# http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
def xdg(self, path="/streamtuner2"):
home = os.environ.get("HOME", self.tmp)
config = os.environ.get("XDG_CONFIG_HOME", os.environ.get("APPDATA", home+"/.config"))
| | | | > > > | > | > | > | > > > | | > > | < | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
return players[typ][-1]
# http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
def xdg(self, path="/streamtuner2"):
home = os.environ.get("HOME", self.tmp)
config = os.environ.get("XDG_CONFIG_HOME", os.environ.get("APPDATA", home+"/.config"))
datadir = os.environ.get("XDG_CACHE_HOME", os.environ.get("APPDATA", home+"/.cache"))
# storage dir
self.dir = config + path
self.datadir = datadir + path
# create if necessary
if (not os.path.exists(self.dir)):
os.makedirs(self.dir)
if (not os.path.exists(self.datadir)):
os.makedirs(self.datadir)
# symlink subdirs from .config to .cache
self.xdg_move(self.dir, self.datadir, ["cache", "icons", "themes"])
# move/symlink cache files/dirs into datadir
def xdg_move(self, config_dir, cache_dir, folders):
if self.windows:
return
for sub in folders:
source, target = (dir+"/"+sub for dir in [config_dir, cache_dir])
if not os.path.exists(target):
if os.path.exists(source): # move .config/* to .cache/*
os.rename(source, target)
else:
os.makedirs(target) # create .cache/*
if os.path.exists(target) and not os.path.exists(source):
os.symlink(target, source) # symlink .config → .cache
# store some configuration list/dict into a file
def save(self, name="settings", data=None, gz=0, nice=0):
name = name + ".json"
if (data is None):
data = vars(self)
if "args" in data:
data.pop("args")
nice = 1
# target filename
file = self.dir + "/" + name
# check for subdir
if (name.find("/") > 0):
subdir = name[0:name.find("/")]
subdir = self.datadir + "/" + subdir
if (not os.path.exists(subdir)):
os.mkdir(subdir)
open(subdir+"/.nobackup", "w").close()
file = self.datadir + "/" + name
# encode as JSON
try:
data = json.dumps(data, indent=(4 if nice else None), sort_keys=True)
except Exception as e:
log.ERR("JSON encoding failed", e)
return
# .gz or normal file
|
| ︙ | ︙ | |||
263 264 265 266 267 268 269 |
except TypeError as e:
f.write(data) # Python3 sometimes wants to write strings rather than bytes
f.close()
# retrieve data from config file
def load(self, name):
name = name + ".json"
| > > > | | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
except TypeError as e:
f.write(data) # Python3 sometimes wants to write strings rather than bytes
f.close()
# retrieve data from config file
def load(self, name):
name = name + ".json"
if (name.find("/") > 0):
file = self.datadir + "/" + name
else:
file = self.dir + "/" + name
try:
# .gz or normal file
if os.path.exists(file + ".gz"):
f = gzip.open(file + ".gz", self.open_mode)
elif os.path.exists(file):
f = open(file, self.open_mode)
else:
|
| ︙ | ︙ |
Modified contrib/cachereset.py from [3bc4b461a7] to [33337efeee].
1 2 3 4 | # encoding: UTF-8 # api: streamtuner2 # title: Cache Reset # description: Allows to empty cached stations and favicons | | | 1 2 3 4 5 6 7 8 9 10 11 12 | # encoding: UTF-8 # api: streamtuner2 # title: Cache Reset # description: Allows to empty cached stations and favicons # version: 0.3 # type: feature # category: config # priority: optional # hooks: config_load # # Inserts a [Cache Reset] button into the Options tab. Allows # to either clear channel caches and/or stored favicons. |
| ︙ | ︙ | |||
49 50 51 52 53 54 55 |
self.l1 = self.t1.get_children()[0]
self.l2 = self.t2.get_children()[0]
self.l3 = self.t3.get_children()[0]
# Update size labels
def dialog_update(self, *w):
| | | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
self.l1 = self.t1.get_children()[0]
self.l2 = self.t2.get_children()[0]
self.l3 = self.t3.get_children()[0]
# Update size labels
def dialog_update(self, *w):
s1 = self.foldersize(conf.datadir + "/cache") / 1024
s2 = self.foldersize(conf.datadir + "/icons") / 1024
s3 = self.foldersize(conf.tmp) / 1024
self.l1.set_text("Channels (%s KB)" % s1)
self.l2.set_text("Icons (%s KB)" % s2)
self.l3.set_text("Temp (%s KB)" % s3)
# Calculate folder size (flat dir)
def foldersize(self, p):
if os.path.exists(p):
try:
return sum([os.path.getsize(p+"/"+fn) for fn in os.listdir(p)])
except:
pass
return 0
# Actually delete stuff
def execute(self, *w):
for dir, btn in [(conf.datadir+"/cache/", self.t1), (conf.datadir+"/icons/", self.t2), (conf.tmp+"/", self.t3)]:
# check if checked
if not btn.get_state():
continue
# list dir + delete files
for fn in os.listdir(dir):
os.unlink(dir + fn)
open(dir + ".nobackup", "a").close()
self.dialog_update()
|
Modified help/favicon.page from [5b234a7e90] to [ecdea1f5bb].
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | <p>Some channels (Jamendo or Radionomy) provide small album previews or banners even. Whereas normal favicons are just 16x16 pixel images.</p> <note><p>Downloaded image files are meanwhile all sanitized (internally converted to ensure they're really image files). Albeit that's not strictly necessary for modern Gtk versions. (But better safe than sorry). | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <p>Some channels (Jamendo or Radionomy) provide small album previews or banners even. Whereas normal favicons are just 16x16 pixel images.</p> <note><p>Downloaded image files are meanwhile all sanitized (internally converted to ensure they're really image files). Albeit that's not strictly necessary for modern Gtk versions. (But better safe than sorry). Images are kept in the <file>~/.cache/streamtuner2/icons</file> directory (or below <file>%APPDATA%\</file> on Windows). </p></note> <section id="configuration"> <title>Configuration options</title> |
| ︙ | ︙ |
Modified help/pluginmanager2.page from [09f72a2f34] to [00cea8f39d].
| ︙ | ︙ | |||
50 51 52 53 54 55 56 |
</list>
</item>
</list>
</section>
<section id="userplugins">
<title>User plugins</title>
| | > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
</list>
</item>
</list>
</section>
<section id="userplugins">
<title>User plugins</title>
<p>Downloaded plugins are stored in <file>~/.config/streamtuner2/plugins/</file>
(not in <file>~/.cache</file>, because they're sort of configuration
and should be backed up in case of local modifications).
To remove them, delete the individual *.py files there manually. But
keep the <file>__init__.py</file> stub.</p>
<p>On Windows they're stored in <file>%APPDATA%\streamtuner2\plugins\</file>.</p>
<note style="bug"><p>Core plugins (those which are installed
system-wide) can often also be updated. The user-saved plugin will
take precedence after a restart. However the version number in
PluginManager2 still shows the system-installed/older version
|
| ︙ | ︙ |
Modified help/technical.page from [40cbc0e2c0] to [a446a003df].
| ︙ | ︙ | |||
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<title>Configuration files</title>
<terms>
<item>
<title><file>/home/$USER/.config/streamtuner2/</file></title>
<p>Corresponds to the XDG_CONFIG_HOME setting. All ST2 configuration settings
are contained within here and are in JSON format.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/settings.json</file></title>
<p>General runtime options, plugin settings, and configured audio players.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/window.json</file></title>
<p>Saved window sizes, list widths.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/state.json</file></title>
<p>Last category in each channel tab.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/bookmarks.json</file></title>
<p>Is a separate cache file for your bookmarked/favourite radio stations.</p>
</item>
<item>
| > > > > > > | | | | > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
<title>Configuration files</title>
<terms>
<item>
<title><file>/home/$USER/.config/streamtuner2/</file></title>
<p>Corresponds to the XDG_CONFIG_HOME setting. All ST2 configuration settings
are contained within here and are in JSON format.</p>
</item>
<item>
<title><file>/home/$USER/.cache/streamtuner2/</file></title>
<p>Set from XDG_CACHE_HOME environment variable. Contains the
channel cache/ and icons/. Symlinks in <file>.config</file>
remain for convenience.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/settings.json</file></title>
<p>General runtime options, plugin settings, and configured audio players.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/window.json</file></title>
<p>Saved window sizes, list widths.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/state.json</file></title>
<p>Last category in each channel tab.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/bookmarks.json</file></title>
<p>Is a separate cache file for your bookmarked/favourite radio stations.</p>
</item>
<item>
<title><file>~/.cache/streamtuner2/cache/***.json</file></title>
<p>Channel cache, with station/stream lists in JSON files.</p>
</item>
<item>
<title><file>~/.cache/streamtuner2/icons/*.png</file></title>
<p>Holds downloaded favicons for station homepages.</p>
</item>
<item>
<title><file>~/.config/streamtuner2/plugins/*.py</file></title>
<p>Contain downloaded contrib/ plugins.</p>
</item>
</terms>
<p>On Windows the <file>~/.config/</file> directory is called
<file>%APPDATA%</file> instead. The paths in there are equally
structured. On Linux <file>~/.cache/</file> is used to separate
temporary from configuration data.</p>
</section>
<section id="install_dirs">
<title>Installation spread</title>
<terms>
<item>
|
| ︙ | ︙ |