I don't know how my cache got into this state, but I had an empty size
file:
$ cat ~/.cache/mcg/127.0.0.1/size
$ stat ~/.cache/mcg/127.0.0.1/size
File: /home/jeremy/.cache/mcg/127.0.0.1/size
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 254,0 Inode: 18493061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ jeremy) Gid: ( 100/ users)
Access: 2022-09-14 00:18:32.942885525 -0700
Modify: 2022-09-07 12:32:44.151734944 -0700
Change: 2022-09-07 12:32:44.151734944 -0700
Birth: 2022-08-25 10:01:01.729717504 -0700
This was causing mcg's Library view to crash like this:
(.mcg-wrapped:879276): Gtk-CRITICAL **: 00:19:15.727: gtk_window_add_accel_group: assertion 'GTK_IS_WINDOW (window)' failed
Exception in thread Thread-1 (_set_playlist):
Traceback (most recent call last):
File "/nix/store/c1vb2z3c64i0sd92iz7fv0lb720qcvhb-python3-3.10.6/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
self.run()
File "/nix/store/c1vb2z3c64i0sd92iz7fv0lb720qcvhb-python3-3.10.6/lib/python3.10/threading.py", line 953, in run
self._target(*self._args, **self._kwargs)
File "/nix/store/l935dwmk93sq2chr4xxiipv9amyfcg43-CoverGrid-3.1/share/mcg/mcg/playlistpanel.py", line 256, in _set_playlist
cache = client.MCGCache(host, size)
File "/nix/store/l935dwmk93sq2chr4xxiipv9amyfcg43-CoverGrid-3.1/share/mcg/mcg/client.py", line 1279, in __init__
self._read_size()
File "/nix/store/l935dwmk93sq2chr4xxiipv9amyfcg43-CoverGrid-3.1/share/mcg/mcg/client.py", line 1293, in _read_size
size = int(f.readline())
ValueError: invalid literal for int() with base 10: ''
Maybe mcg crashed while writing the `size` file at some point? I see
that it writes directly to the size file, which seems potentially risky:
it would probably be safer to write to a temp file and then (atomically)
move it. Still, it seems like a good practice to be resilient here.
After this change, here's what I see get printed by mcg:
(.mcg-wrapped:889856): Gtk-CRITICAL **: 00:37:00.045: gtk_window_add_accel_group: assertion 'GTK_IS_WINDOW (window)' failed
2022-09-14 00:37:00,076 WARNING: invalid cache file: /home/jeremy/.cache/mcg/127.0.0.1/size, deleting file
Traceback (most recent call last):
File "/nix/store/vzgcfs00nq543hjk8hrk81k1rs8aqpqw-CoverGrid-3.1/share/mcg/mcg/client.py", line 1295, in _read_size
size = int(f.readline())
ValueError: invalid literal for int() with base 10: ''
And then the problem goes away =)
When doing a `python setup.py build` on my machine, I found that
`build/lib` would not end up with a compiled gresource file until the
second invocation of `python setup.py build`.
Before:
$ python setup.py build
running build
running build_py
creating build
creating build/lib
creating build/lib/mcg
copying mcg/connectionpanel.py -> build/lib/mcg
copying mcg/shortcutsdialog.py -> build/lib/mcg
copying mcg/serverpanel.py -> build/lib/mcg
copying mcg/application.py -> build/lib/mcg
copying mcg/window.py -> build/lib/mcg
copying mcg/playlistpanel.py -> build/lib/mcg
copying mcg/utils.py -> build/lib/mcg
copying mcg/coverpanel.py -> build/lib/mcg
copying mcg/infodialog.py -> build/lib/mcg
copying mcg/librarypanel.py -> build/lib/mcg
copying mcg/client.py -> build/lib/mcg
copying mcg/zeroconf.py -> build/lib/mcg
copying mcg/mcg.py -> build/lib/mcg
copying mcg/__init__.py -> build/lib/mcg
copying mcg/albumheaderbar.py -> build/lib/mcg
package init file 'data/__init__.py' not found (or not a regular file)
compiling gresources
compiling gschemas
$ ls build/lib/mcg/data/
ls: cannot access 'build/lib/mcg/data/': No such file or directory
Note how there is no data directory at all. Now check out what happens
on the second build:
$ git status
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
data/gschemas.compiled
data/xyz.suruatoel.mcg.gresource
nothing added to commit but untracked files present (use "git add" to track)
$ python setup.py build
running build
running build_py
package init file 'data/__init__.py' not found (or not a regular file)
creating build/lib/mcg/data
copying data/xyz.suruatoel.mcg.gresource -> build/lib/mcg/data
compiling gresources
compiling gschemas
$ ls build/lib/mcg/data/
xyz.suruatoel.mcg.gresource
That's because the first build generated the compiled schemas and
resources (you can see evidence of that in `git status`), and then the
second build was able to copy the gresource file over according to the
`package_data` rules. The fix I've introduced here is to just do the
compilations *before* we call `super(...).run(...)`. There might be
better ways of doing this, I'm not very familiar with packaging gtk
python applications.
Things were even worse for the gschemas.compiled file: in addition to
the ordering issue it's not even mentioned in `data_files`, so even if
it does exist, it doesn't have a chance to get copied over when
installed. So I've added it to the `data_files` section. I don't know if
that'll play nicely or not with the existing `--no-compile-schemas`
flag.
Use GTK Composite Templates for GUI elements to clean up and simplify
the code for widgets and all UI elements. This includes splitting the
large “gtk.glade” file into smaller .ui files and the large “widgets.py”
file into smaller .py files.
Load the playlist before loading the status for the idle event “changed”
to make sure the playlist information is attached to the current album
correctly.
Load the album covers using MPD’s new “albumart” command instead of
reading the covers from the harddrive. Remove the corresponding UI
elements and configuration option.
Use the recv() method to read data from the socket instead of makefile()
to allow reading of binary data that is not text. This requires using a
custom buffer.
Introduce two new callbacks for this: one when initializing the loading
of albums and another one on handling the loading of each album. Use the
first one to initialize and the second one to pulse the progress bar on
the Library panel.
Additionally use the text of the progress as status label instead of a
separate label widget.
Fix setting the default image (if the selected/current album does not
has a cover) for the Cover panel, the Playlist panel and the Library
panel by using the default image instead of clearing the image widget.
Additionally fix the check for the empty URL String.
As the documentation on the “locale” module states, the “gettext” module
should be used instead. Therefore adjust the localization calls to use
gettext instead.
Additionally fix one button label which did not use localization at all
and update the message catalogues.
Drawing the cover image on the Cover panel triggers the re-allocation of
the widget which in turn triggers the re-drawing of the cover image.
This led to an infinite loop of drawing the cover image causing high CPU
usage. To prevent this, the widget size is now stored and the the
resizing of the cover image is only done if the size has really changed.