Commit Graph

411 Commits

Author SHA1 Message Date
Philipp Wolfer
601df7b158 Simpified initializing Metadata() in formats tests 2019-03-26 07:32:59 +00:00
Laurent Monin
c80ae1344b Name countries-related tests, classes and variables consistently 2019-03-25 14:40:52 +01:00
Laurent Monin
a458bbe2ff country_list_from_node() -> countries_from_node() 2019-03-25 14:38:51 +01:00
Laurent Monin
5ae92454f4 Add a test for release without events vs countries 2019-03-25 14:36:56 +01:00
Laurent Monin
4983631f70 Merge pull request #1142 from zas/coverimage_metadata_cleanup
CoverArtImage/ImageList/Metadata cleanup
2019-03-24 14:33:50 +01:00
Laurent Monin
b33e59428f Clean up various matching iterations, unify a bit
- use generators for candidates
- introduce picard.util.find_best_match() and sort_by_similarity() with tests
- partially revert change that removed sorted(), it was actually faster and cleaner
- use namedtuples to get rid of numeric indexes
- when no match, output max similarity, threshold and number of candidates to debug log
- make code easier to understand, using long names and namedtuple attributes, and simpler workflow
- use repr(best_match) for debug, as it provides all the needed info
- set values explicitly using namedtuple kw parameters
- use same prefix for namedtuples names, it eases searching through code

Typical debug output looks like:
```
D: 13:16:41,806 cluster._lookup_finished:223: BestMatch(similarity=0.79, result=SimMatchRelease(similarity=0.79, release={'id': '36b8f767-c4c0-4ba1-becd-f40a452303d5', 'score': 79, 'count': 1, 'title': 'Purple', 'status': 'Official', 'packaging': 'Jewel Case', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'artist': {'id': '8c32bb01-58a3-453b-8050-8c0620edb0e5', 'name': 'Stone Temple Pilots', 'sort-name': 'Stone Temple Pilots'}}], 'release-group': {'id': '01d45519-54a6-3427-b0dc-222203fa5d57', 'type-id': 'f529b476-6e62-324f-b0aa-1f3e33d313fc', 'title': 'Purple', 'primary-type': 'Album'}, 'date': '1995-08-25', 'country': 'US', 'release-events': [{'date': '1995-08-25', 'area': {'id': '489ce91b-6658-3307-9877-795b68554c98', 'name': 'United States', 'sort-name': 'United States', 'iso-3166-1-codes': ['US']}}], 'track-count': 11, 'media': [{'format': 'CD', 'disc-count': 10, 'track-count': 11}]}), num_results=25) < threshold=0.800000
```
2019-03-23 16:29:44 +01:00
Laurent Monin
7e3c9673c8 Add test for Metadata.apply_func() with preserved tags 2019-03-22 11:04:44 +01:00
Laurent Monin
b81947e22d Add test for Metadata.strip_whitespace() 2019-03-22 10:54:31 +01:00
Laurent Monin
99896bff8b Add tests for ImageList copy()/clear()/del
Note: clear() is apparently inherited, i read docs saying otherwise, so i add a test for it to be sure
2019-03-22 10:32:32 +01:00
Laurent Monin
3a44ec41e2 Disable pylint warning about ImageList.insert() 2019-03-22 10:32:32 +01:00
Laurent Monin
9340c6c2ec Drop Metadata.set_front_image(), replace with ImageList.strip_front_images()
- only used in ui/coverartbox.py and not directly linked to metadata
- add tests
-
2019-03-22 10:32:31 +01:00
Laurent Monin
78c9890e21 Drop Metadata.append_image(), use Metadata.images.append() instead 2019-03-22 10:32:31 +01:00
Laurent Monin
6bf103bf34 Drop useless Metadata.remove_image() 2019-03-22 10:32:31 +01:00
Laurent Monin
0b837ebe8d Move Metadata.images_to_be_saved_to_tags() to ImageList.to_be_saved_to_tags()
- make it a generator
- drop @property, it's a function, no point in hiding it
- add tests
2019-03-22 10:32:31 +01:00
Laurent Monin
eb73ea6bc4 Replace Metadata.get_single_front_image() with ImageList.get_front_image()
- it makes much more sense, Metadata.images is an ImageList
- minimal changes required
- add tests for it
2019-03-22 10:32:31 +01:00
Laurent Monin
d60afe35d7 ImageList(): fix untestable class, since it requires gettext...
- image.types_as_string() was called from get_image_type() without translate=False
- dependency wasn't satisfied, so impossible to test as is
- make tests depending on languages isn't a good idea anyway
- use new CoverArtImage.normalized_types() instead
- simplify code
- add tests for ImageList.append() and ImageList.__eq__()
2019-03-22 10:32:31 +01:00
Laurent Monin
9d7b8dc995 CoverArtImage.__init__(): add parameters to override supported types
It's convenient for testing
2019-03-22 10:32:31 +01:00
Laurent Monin
bc11a330ab Introduce SettingsOverride class to fix this more elegantly
- basically it returns config.setting[key] when key isn't in the internal dict
- it protects config.setting from any write, since __setitem__ only write to self._dict
- del settings['xxx'] will remove 'xxx' from internal dict, but still allow access to config.setting
- it can be used for tests
- minimal implementation based on MutableMapping
- add tests for it
2019-03-22 10:29:57 +01:00
Laurent Monin
b58c353259 Metadata.__setitem__(): accept any iterable as values
https://github.com/metabrainz/picard/pull/1137#discussion_r266974994
2019-03-21 11:53:39 +01:00
Laurent Monin
b5cc54e255 Make Metadata.__setitem__() consistent with Metadata.add() regarding 0 values
m['tag'] = 0 wasn't doing the same thing as m.add('tag', 0), because the test in __setitem__()
was different: if value vs if value or value == 0
So modify it to make behavior much more consistent.

m['tag'] = 0 or m.add('tag', 0) actually set tag to ['0']
m.add('tag', '') does nothing
m['tag'] = '' explicitly delete the tag (removing it from store, adding it to deleted tags)
m = Metadata(tag='') doesn't create an entry 'tag' (at all)
m = Metadata(tag=0) creates a tag, with internal value ['0']

This way, one can rewrite:

self.metadata = Metadata()
self.metadata['album'] = name
self.metadata['albumartist'] = artist
self.metadata['totaltracks'] = 0

to:
self.metadata = Metadata(album=name, albumartist=artist, totaltracks=0)

Without this patch, totaltracks wasn't set at all.
2019-03-21 11:38:58 +01:00
Laurent Monin
99604ac01f Test and annotate the case of del with unknown keys 2019-03-20 21:17:06 +01:00
Laurent Monin
f6e3aedf7a Raises TypeError if Metadata.update() is called without argument
This is more consistent with dict.update() behavior (and shouldn't happen anyway).
2019-03-20 11:03:56 +01:00
Laurent Monin
39b069adae Test Metadata.len() with images 2019-03-20 10:42:50 +01:00
Laurent Monin
1a1e250489 Add tests for Metadata with images 2019-03-20 10:42:50 +01:00
Laurent Monin
2aec4a4185 Metadata.update(): fix a corner case leading to inconsistent data
```python
m = Metadata(tag1='a', tag2='b')
del m['tag1']
```

```
m store: {'tag2': ['b']}
m deleted: {'tag1'}
```

```python
m2 = Metadata(tag1='c', tag2='d')
del m2['tag2']
```

```
m2 store: {'tag2': ['b']}
m2 deleted: {'tag1'}
```

```python
m.update(m2)
```

```
m store: {'tag1': ['c']}
m deleted: {'tag1', 'tag2'} <---- this was incorrect, and untested case
```

This patch fixes it, and results to:

```
m store: {'tag1': ['c']}
m deleted: {'tag2'}
```
2019-03-20 10:42:50 +01:00
Laurent Monin
090c1e4eaf Reduce code redundancy in tests 2019-03-20 10:42:50 +01:00
Laurent Monin
4e977cfb2c Improve dict compatibility of Metadata.update() + minor fixes 2019-03-20 10:42:50 +01:00
Laurent Monin
503b5203f1 Metadata class: inherit from MutableMapping instead of dict 2019-03-20 10:42:49 +01:00
Laurent Monin
a9cf9d55c8 File._preserve_times(): fix broken logic
- access times are likely to differ, a race condition is possible
- stat() has be done after the change to be able to compare
- comments added
- force sync after modifying test file
- make code easier to understand

See https://github.com/metabrainz/picard/pull/1132#issuecomment-474113665
2019-03-19 23:21:59 +01:00
Laurent Monin
6a63c3e5be Improve file times preservation using os.utime() ns parameter (py >= 3.3)
https://docs.python.org/3/library/os.html#os.utime
Since Python 3.3, ns parameter is available
"The best way to preserve exact times is to use the st_atime_ns and st_mtime_ns
fields from the os.stat() result object with the ns parameter to utime."

Make time preservation testable.
2019-03-14 10:57:55 +01:00
Philipp Wolfer
bba5cef5fe PICARD-1490: Run Windows path test on Windows only 2019-03-12 16:18:45 +01:00
Philipp Wolfer
e573dccc09 PICARD-1490: Fix local cover art loading on Windows 2019-03-12 09:19:16 +01:00
Philipp Wolfer
f0619614a3 PICARD-1485: Format track durations with hours
Durations of an hour or more will show the hours as HH:MM:SS
2019-03-08 10:24:12 +01:00
Laurent Monin
6388ef20f5 Use IS_WIN, IS_MACOS, IS_LINUX 2019-03-05 21:53:32 +01:00
Laurent Monin
9df54c1610 Introduce _assertFile()/_assertNoFile() and reduce redundancy a bit more 2019-03-05 11:03:23 +01:00
Laurent Monin
549800aa0a Simplify even more 2019-03-05 10:54:42 +01:00
Laurent Monin
48206692de Reduce code redundancy, introducing _move_additional_files(files) 2019-03-05 10:23:51 +01:00
Laurent Monin
5fa087dde3 Use a dict to store filepaths 2019-03-05 10:17:58 +01:00
Laurent Monin
bd7b471416 Test File.move_additional_files() for hidden files cases
In case patterns start with a dot we don't ignore hidden files
It was implemented in https://github.com/metabrainz/picard/pull/519
2019-03-04 21:48:07 +01:00
Laurent Monin
1ca043dd90 Add tests for mbid_validate() 2019-03-04 19:35:05 +01:00
Philipp Wolfer
a9709f97ea PICARD-455: Set dimensions for images saved to FLAC 2019-02-27 08:29:23 +01:00
Philipp Wolfer
ccebf9c8b9 Refactored local cover art class
Generalized the handling of cover art URLs to also handle file:// scheme.
2019-02-22 14:14:00 +01:00
Philipp Wolfer
ecf8ad565a PICARD-1178: Support comparing cover images with only one type
All our current tags support either no or only one type.
Fixes issues where files where shown as modified when loading again and comparing against cover art with more than one type.
2019-02-22 11:05:08 +01:00
Philipp Wolfer
14277c18b5 PICARD-1288: Added unit tests 2019-02-20 12:55:33 +01:00
Michael Wiencek
f908e66a1e PICARD-1471: Artist searches do not show begin and end area
The search server outputs these property names with hyphens, not
underscores.

MBS does output them using underscores for artist lookups, but (1)
Picard doesn't appear to perform any artist lookups, and (2) MBS will be
fixing that to use hyphens as well.
2019-02-13 02:50:59 -06:00
Wieland Hoffmann
5391db12e7 Remove unused imports 2019-01-13 10:22:25 +01:00
Laurent Monin
b19d1039ad Fix fake tuple issue again: sys.platform in ("win32") doesn't do what it is meant for 2018-12-16 17:17:47 +01:00
Laurent Monin
b7203e4280 Docstrings should use triple double quotes (PEP257)
https://www.python.org/dev/peps/pep-0257/#id15

For consistency, always use """triple double quotes""" around docstrings.
2018-12-16 16:54:37 +01:00
Philipp Wolfer
4c01a084ff PICARD-490: Support tagging AAC files with APEv2 2018-12-12 10:40:15 +01:00
Philipp Wolfer
6038409d44 PICARD-490: Support load and rename for AAC (ADTS/ADIF) files 2018-12-12 10:40:15 +01:00