This fixes a regression since e16b2533c where picard no saves vocal ARs
with no type set as generic "performer" ars; appearing in the UI like
Performer []: Some Vocalist
Performer [guest]: Some Guest Vocalist
Add special handling for the vocal relationship type to use a fallback
string if there is no vocal type set. The fallback string is "vocals"
(earlier versions of picard used "vocal"), for consistancy with the
current vocal type strings, which look like "lead vocals", "background
vocals", etc.
The previous use of "selection_mutex" didn't really prevent race conditions.
The only thing really stopping them was the hackish "throttling" implemented
using self.updating and self.update_pending. If self.update was called while
another update was already in-progress, it'd set self.update_pending to True
and return, thereby reducing the chance that two update threads would execute
simultaneously.
Another thing to note is that race conditions here are almost impossible to
reproduce in CPython by default, because the interpreter only checks for
possible thread switches every 100 virtual instructions or so (configurable
using sys.setcheckinterval). Still, relying on such behavior bothers me.
The new attempt here reduces the need for locking considerably, because
instead of having a constant, shared self.tag_diff object, each update
thread creates its own and passes it on as the result.
So, selection_mutex is now simply used to protect the cached selection vars
while they're being set in _update_selection and read in _update_tags. As
mentioned, CPython's default behavior makes selection_mutex pretty much
unnecessary, but I don't think it adds much overhead given its limited use.
Tested on Mac and Windows.
Introduce helpers to clarify and fix code:
- is_front_image()
- save_this_image_to_tags()
- image_type_from_id3_num()
- image_type_as_id3_num()
Fixes:
- honor "save_only_front_images_to_tags" option for apev2 format too
- save only caa front image to tags when "save_only_front_images_to_tags" is set
and image source is CAA, use 'front' flag from json.
Other sources should have only 1 front image anyways.
The _make_filename and _script_to_filename methods actually *do* need
to be passed a custom settings dict, so that the renaming examples
can update instantly.
If a release mbid is given (search type = Album) it will try to load it as
when using web browser tagger link.
If string looks like a known entity (artist, release-group, label, track)
it will open browser on corresponding url.
Examples:
Select box on Album + "abb7caf1-ac93-48e1-a066-60caad07e1a7" -> load release (http://musicbrainz.org/release/abb7caf1-ac93-48e1-a066-60caad07e1a7)
Select box on anything + "http://musicbrainz.org/artist/c19ff12b-058f-44a8-b245-b0efb4752925" -> open browser on Artist page
"ARTIST := c19ff12b-058f-44a8-b245-b0efb4752925 !!" -> open Artist page
Stop loop if first url is added because second one will be removed later anyway.
It happens with cdbaby urls (ie. http://musicbrainz.org/release/6e228dfa-b0c7-4987-a36d-7ac14541ae66)
Debug output without this patch:
D: 139947473626880 11:15:32 There are no suitable images in the cover art archive for 6e228dfa-b0c7-4987-a36d-7ac14541ae66
D: 139947473626880 11:15:32 Adding front image PyQt4.QtCore.QUrl(u'http://cdbaby.name/p/r/prozak.jpg')
D: 139947473626880 11:15:32 Adding front image PyQt4.QtCore.QUrl(u'http://www.cdbaby.com/cd/prozak')
D: 139947473626880 11:15:32 'Downloading http://cdbaby.name:80/p/r/prozak.jpg'
Debug output with this patch:
D: 140074644940544 11:16:55 There are no suitable images in the cover art archive for 6e228dfa-b0c7-4987-a36d-7ac14541ae66
D: 140074644940544 11:16:55 Adding front image PyQt4.QtCore.QUrl(u'http://cdbaby.name/p/r/prozak.jpg')
D: 140074644940544 11:16:55 'Downloading http://cdbaby.name:80/p/r/prozak.jpg'
If metadata.length is 0, it's Falsy and not added to the tagdiff stuff. This
stores it as a str because it's simpler than adding `or value != 0`
everywhere.
Binary and decimal modes are supported (MB and MiB ie.)
It supports i18n using gettext and locale.
Precision can be modified if needed, by default it is using 1 digit (if needed).
Extensive tests were written, the toughest was to make them work for
both default C locale and fr_FR.UTF-8 locale (ofc it is possible to test for more
locales...). If one locale isn't available on testing system, test is skipped.
fr locale was chosen because decimal point is replaced by a comma and byte units
becomes "octet" units (1.5 MB in english -> 1,5 Mo in french).
Unit tests will need to use gettext, so i modified a bit setup_gettext()
and it can now be easily imported.
I add to change the code a bit to make it work, i also fixed an issue with
locale under linux that was occuring when one imported this module.