/test/test_mbxml.py

https://github.com/lalinsky/picard · Python · 429 lines · 382 code · 42 blank · 5 comment · 4 complexity · 15358ecdc95997631c6e3c870f8584e4 MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. import unittest
  3. import picard
  4. from picard import config
  5. from picard.metadata import Metadata
  6. from picard.mbxml import (
  7. track_to_metadata,
  8. release_to_metadata,
  9. artist_credit_from_node,
  10. _translate_artist_node
  11. )
  12. settings = {
  13. "standardize_tracks": False,
  14. "standardize_artists": False,
  15. "standardize_releases": False,
  16. "translate_artist_names": False
  17. }
  18. class XmlNode(object):
  19. def __init__(self, text=u'', children={}, attribs={}):
  20. self.text = text
  21. self.children = children
  22. self.attribs = attribs
  23. def __repr__(self):
  24. return repr(self.__dict__)
  25. def __getattr__(self, name):
  26. try:
  27. return self.children[name]
  28. except KeyError:
  29. try:
  30. return self.attribs[name]
  31. except KeyError:
  32. raise
  33. #raise AttributeError, name
  34. class TrackTest(unittest.TestCase):
  35. def test_1(self):
  36. config.setting = settings
  37. class Track:
  38. pass
  39. node = XmlNode(attribs={'id': u'321'}, children={
  40. 'title': [XmlNode(text=u'Foo')],
  41. 'length': [XmlNode(text=u'180000')],
  42. 'position': [XmlNode(text=u'1')],
  43. 'recording': [XmlNode(attribs={'id': u'123'}, children={
  44. 'relation_list': [XmlNode(attribs={'target_type': u'work'}, children={
  45. 'relation': [XmlNode(attribs={'type': u'performance'}, children={
  46. 'work': [XmlNode(attribs={'id': u'workid123'}, children={
  47. 'title': [XmlNode(text=u'Bar')],
  48. 'language': [XmlNode(text=u'eng')]
  49. })]
  50. })]
  51. })]
  52. })],
  53. 'artist_credit': [XmlNode(children={
  54. 'name_credit': [XmlNode(attribs={'joinphrase': u' & '}, children={
  55. 'artist': [XmlNode(attribs={'id': u'456'}, children={
  56. 'name': [XmlNode(text=u'Foo Bar')],
  57. 'sort_name': [XmlNode(text=u'Bar, Foo')]
  58. })]
  59. }), XmlNode(children={
  60. 'artist': [XmlNode(attribs={'id': u'789'}, children={
  61. 'name': [XmlNode(text=u'Baz')],
  62. 'sort_name': [XmlNode(text=u'Baz')]
  63. })]
  64. })]
  65. })]
  66. })
  67. track = Track()
  68. m = track.metadata = Metadata()
  69. track_to_metadata(node, track)
  70. self.assertEqual(u'123', m['musicbrainz_recordingid'])
  71. self.assertEqual(u'321', m['musicbrainz_trackid'])
  72. self.assertEqual(u'456; 789', m['musicbrainz_artistid'])
  73. self.assertEqual(u'Foo', m['title'])
  74. self.assertEqual(u'Foo Bar & Baz', m['artist'])
  75. self.assertEqual(u'Bar, Foo & Baz', m['artistsort'])
  76. self.assertEqual(u'workid123', m['musicbrainz_workid'])
  77. self.assertEqual(u'Bar', m['work'])
  78. self.assertEqual(u'eng', m['language'])
  79. class ReleaseTest(unittest.TestCase):
  80. def test_1(self):
  81. config.setting = settings
  82. release = XmlNode(attribs={'id': u'123'}, children={
  83. 'title': [XmlNode(text=u'Foo')],
  84. 'status': [XmlNode(text=u'Official')],
  85. 'text_representation': [XmlNode(children={
  86. 'language': [XmlNode(text=u'eng')],
  87. 'script': [XmlNode(text=u'Latn')]
  88. })],
  89. 'artist_credit': [XmlNode(children={
  90. 'name_credit': [XmlNode(attribs={'joinphrase': u' & '}, children={
  91. 'artist': [XmlNode(attribs={'id': u'456'}, children={
  92. 'name': [XmlNode(text=u'Foo Bar')],
  93. 'sort_name': [XmlNode(text=u'Bar, Foo')]
  94. })]
  95. }), XmlNode(children={
  96. 'artist': [XmlNode(attribs={'id': u'789'}, children={
  97. 'name': [XmlNode(text=u'Baz')],
  98. 'sort_name': [XmlNode(text=u'Baz')]
  99. })]
  100. })]
  101. })],
  102. 'date': [XmlNode(text=u'2009-08-07')],
  103. 'country': [XmlNode(text=u'GB')],
  104. 'barcode': [XmlNode(text=u'012345678929')],
  105. 'asin': [XmlNode(text=u'B123456789')],
  106. 'label_info_list': [XmlNode(attribs={'count': u'1'}, children={
  107. 'label_info': [XmlNode(children={
  108. 'catalog_number': [XmlNode(text=u'ABC 123')],
  109. 'label': [XmlNode(children={
  110. 'name': [XmlNode(text=u'ABC')]
  111. })]
  112. })]
  113. })]
  114. })
  115. m = Metadata()
  116. release_to_metadata(release, m)
  117. self.assertEqual(u'123', m['musicbrainz_albumid'])
  118. self.assertEqual(u'456; 789', m['musicbrainz_albumartistid'])
  119. self.assertEqual(u'Foo', m['album'])
  120. self.assertEqual(u'official', m['releasestatus'])
  121. self.assertEqual(u'eng', m['~releaselanguage'])
  122. self.assertEqual(u'Latn', m['script'])
  123. self.assertEqual(u'Foo Bar & Baz', m['albumartist'])
  124. self.assertEqual(u'Bar, Foo & Baz', m['albumartistsort'])
  125. self.assertEqual(u'2009-08-07', m['date'])
  126. self.assertEqual(u'GB', m['releasecountry'])
  127. self.assertEqual(u'012345678929', m['barcode'])
  128. self.assertEqual(u'B123456789', m['asin'])
  129. self.assertEqual(u'ABC', m['label'])
  130. self.assertEqual(u'ABC 123', m['catalognumber'])
  131. class ArtistTest(unittest.TestCase):
  132. def test_1(self):
  133. config.setting = settings
  134. node = XmlNode(children={
  135. 'name_credit': [XmlNode(attribs={'joinphrase': u' & '}, children={
  136. 'artist': [XmlNode(attribs={'id': u'456'}, children={
  137. 'name': [XmlNode(text=u'Foo Bar')],
  138. 'sort_name': [XmlNode(text=u'Bar, Foo')]
  139. })]
  140. }), XmlNode(children={
  141. 'artist': [XmlNode(attribs={'id': u'789'}, children={
  142. 'name': [XmlNode(text=u'Baz')],
  143. 'sort_name': [XmlNode(text=u'Baz')]
  144. })]
  145. })]
  146. })
  147. artist, artist_sort, artists, artists_sort = artist_credit_from_node(node)
  148. self.assertEqual(u'Foo Bar & Baz', artist)
  149. self.assertEqual([u'Foo Bar', u'Baz'], artists)
  150. self.assertEqual(u'Bar, Foo & Baz', artist_sort)
  151. self.assertEqual([u'Bar, Foo', u'Baz'], artists_sort)
  152. def test_trans1(self):
  153. config.setting = settings
  154. node = XmlNode(
  155. attribs={u'id': u'666'},
  156. children={
  157. u'name': [XmlNode(text=u'Pink Floyd')],
  158. u'alias_list': [
  159. XmlNode(
  160. attribs={u'count': u'5'},
  161. children={u'alias': [
  162. XmlNode(
  163. text=u'Pink Floid',
  164. attribs={
  165. u'type': u'Search hint',
  166. u'sort_name': u'Pink Floid Sort'
  167. }
  168. ),
  169. XmlNode(
  170. text=u'Pink Floyd Artist',
  171. attribs={
  172. u'locale': u'en',
  173. u'type': u'Artist name',
  174. u'primary': u'primary',
  175. u'sort_name': u'Pink Floyd Artist Sort'
  176. }
  177. ),
  178. XmlNode(
  179. text=u'The Pink Floyd',
  180. attribs={
  181. u'locale': u'en',
  182. u'type': u'Artist name',
  183. u'sort_name': u'The Pink Floyd Sort'
  184. }
  185. ),
  186. XmlNode(
  187. text=u'ピンク・フロイド',
  188. attribs={
  189. u'locale': u'ja',
  190. u'type': u'Artist name',
  191. u'primary': u'primary',
  192. u'sort_name': u'ピンク・フロイド Sort'
  193. }
  194. ),
  195. XmlNode(
  196. text=u'핑크 플로이드',
  197. attribs={
  198. u'locale': u'ko',
  199. u'type': u'Artist name',
  200. u'primary': u'primary',
  201. u'sort_name': u'핑크 플로이드 Sort'
  202. }
  203. )
  204. ]}
  205. )
  206. ],
  207. u'sort_name': [XmlNode(text=u'Pink Floyd Sort')]
  208. }
  209. )
  210. config.setting["translate_artist_names"] = False
  211. config.setting["artist_locale"] = "en"
  212. transl, translsort = _translate_artist_node(node)
  213. self.assertEqual(u"Pink Floyd", transl)
  214. self.assertEqual(u"Pink Floyd Sort", translsort)
  215. config.setting["translate_artist_names"] = True
  216. config.setting["artist_locale"] = "ja"
  217. transl, translsort = _translate_artist_node(node)
  218. self.assertEqual(u'ピンク・フロイド', transl)
  219. self.assertEqual(u'ピンク・フロイド Sort', translsort)
  220. config.setting["artist_locale"] = "ko"
  221. transl, translsort = _translate_artist_node(node)
  222. self.assertEqual(u'핑크 플로이드', transl)
  223. self.assertEqual(u'핑크 플로이드 Sort', translsort)
  224. config.setting["artist_locale"] = "en"
  225. transl, translsort = _translate_artist_node(node)
  226. self.assertEqual(u"Pink Floyd Artist", transl)
  227. self.assertEqual(u"Pink Floyd Artist Sort", translsort)
  228. def test_trans3(self):
  229. "Legal name vs Artist name, same locales"
  230. config.setting = settings
  231. node = XmlNode(
  232. attribs={u'id': u'666'},
  233. children={
  234. u'name': [XmlNode(text=u'Pink Floyd')],
  235. u'alias_list': [
  236. XmlNode(
  237. attribs={u'count': u'3'},
  238. children={u'alias': [
  239. XmlNode(
  240. text=u'Pink Floyd Legal en',
  241. attribs={
  242. u'locale': u'en',
  243. u'primary': u'primary',
  244. u'type': u'Legal Name',
  245. u'sort_name': u'Pink Floyd Legal en Sort'
  246. }
  247. ),
  248. XmlNode(
  249. text=u'Pink Floyd Artist en',
  250. attribs={
  251. u'locale': u'en',
  252. u'primary': u'primary',
  253. u'type': u'Artist name',
  254. u'sort_name': u'Pink Floyd Artist en Sort'
  255. }
  256. ),
  257. XmlNode(
  258. text=u'Pink Floyd Legal en_US',
  259. attribs={
  260. u'locale': u'en_US',
  261. u'primary': u'primary',
  262. u'type': u'Legal Name',
  263. u'sort_name': u'Pink Floyd Legal en_US Sort'
  264. }
  265. ),
  266. ]}
  267. )
  268. ],
  269. u'sort_name': [XmlNode(text=u'Pink Floyd Sort')]
  270. }
  271. )
  272. config.setting["translate_artist_names"] = True
  273. config.setting["artist_locale"] = "en"
  274. transl, translsort = _translate_artist_node(node)
  275. self.assertEqual(u"Pink Floyd Artist en", transl)
  276. self.assertEqual(u"Pink Floyd Artist en Sort", translsort)
  277. # should pickup Artist name/en over Legal name/en_US ?
  278. config.setting["artist_locale"] = "en_US"
  279. transl, translsort = _translate_artist_node(node)
  280. self.assertEqual(u"Pink Floyd Artist en", transl)
  281. self.assertEqual(u"Pink Floyd Artist en Sort", translsort)
  282. def test_trans4(self):
  283. "exact locale match, new type/primary set"
  284. config.setting = settings
  285. node = XmlNode(
  286. attribs={u'id': u'666'},
  287. children={
  288. u'name': [XmlNode(text=u'Pink Floyd')],
  289. u'alias_list': [
  290. XmlNode(
  291. attribs={u'count': u'2'},
  292. children={u'alias': [
  293. XmlNode(
  294. text=u'Pink Floyd en',
  295. attribs={
  296. u'locale': u'en_US',
  297. u'primary': u'primary',
  298. u'type': u'New type',
  299. u'sort_name': u'Pink Floyd en Sort'
  300. }
  301. ),
  302. ]}
  303. )
  304. ],
  305. u'sort_name': [XmlNode(text=u'Pink Floyd Sort')]
  306. }
  307. )
  308. config.setting["translate_artist_names"] = True
  309. config.setting["artist_locale"] = "en_US"
  310. transl, translsort = _translate_artist_node(node)
  311. self.assertEqual(u"Pink Floyd en", transl)
  312. self.assertEqual(u"Pink Floyd en Sort", translsort)
  313. def test_trans5(self):
  314. "Lang vs locale, all artist name/primary"
  315. config.setting = settings
  316. node = XmlNode(
  317. attribs={u'id': u'666'},
  318. children={
  319. u'name': [XmlNode(text=u'Pink Floyd')],
  320. u'alias_list': [
  321. XmlNode(
  322. attribs={u'count': u'2'},
  323. children={u'alias': [
  324. XmlNode(
  325. text=u'Pink Floyd en_US',
  326. attribs={
  327. u'locale': u'en_US',
  328. u'primary': u'primary',
  329. u'type': u'Artist name',
  330. u'sort_name': u'Pink Floyd en_US Sort'
  331. }
  332. ),
  333. XmlNode(
  334. text=u'Pink Floyd en_UK',
  335. attribs={
  336. u'locale': u'en_UK',
  337. u'primary': u'primary',
  338. u'type': u'Artist name',
  339. u'sort_name': u'Pink Floyd en_UK Sort'
  340. }
  341. ),
  342. XmlNode(
  343. text=u'Pink Floyd en',
  344. attribs={
  345. u'locale': u'en',
  346. u'primary': u'primary',
  347. u'type': u'Artist name',
  348. u'sort_name': u'Pink Floyd en Sort'
  349. }
  350. ),
  351. XmlNode(
  352. text=u'Pink Floyd en_AU',
  353. attribs={
  354. u'locale': u'en_AU',
  355. u'primary': u'primary',
  356. u'type': u'Artist name',
  357. u'sort_name': u'Pink Floyd en_AU Sort'
  358. }
  359. ),
  360. ]}
  361. )
  362. ],
  363. u'sort_name': [XmlNode(text=u'Pink Floyd Sort')]
  364. }
  365. )
  366. config.setting["translate_artist_names"] = True
  367. config.setting["artist_locale"] = "en"
  368. transl, translsort = _translate_artist_node(node)
  369. self.assertEqual(u"Pink Floyd en", transl)
  370. self.assertEqual(u"Pink Floyd en Sort", translsort)
  371. def test_trans6(self):
  372. "No alias, name without latin chars, it will use translate_from_sortname()"
  373. config.setting = settings
  374. node = XmlNode(
  375. attribs={u'id': u'666'},
  376. children={
  377. u'name': [XmlNode(text=u'ピンク・フロイド')],
  378. u'sort_name': [XmlNode(text=u'Pink Floyd')]
  379. }
  380. )
  381. config.setting["translate_artist_names"] = True
  382. # hacky en translation is chosen over native artist's name, because
  383. # artist's name has no locale definition, this case is a bit weird
  384. config.setting["artist_locale"] = "ja"
  385. transl, translsort = _translate_artist_node(node)
  386. self.assertEqual(u"Pink Floyd", transl)
  387. self.assertEqual(u"Pink Floyd", translsort)