playlists: Simplify detector/parser interface
This commit is contained in:
parent
bdcfab09f1
commit
2bcbbf03be
@ -14,18 +14,16 @@ except ImportError:
|
|||||||
import xml.etree.ElementTree as elementtree
|
import xml.etree.ElementTree as elementtree
|
||||||
|
|
||||||
|
|
||||||
# TODO: make detect_FOO_header reusable in general mopidy code.
|
def detect_m3u_header(data):
|
||||||
# i.e. give it just a "peek" like function.
|
return data[0:7].upper() == b'#EXTM3U'
|
||||||
def detect_m3u_header(typefind):
|
|
||||||
return typefind.peek(0, 7).upper() == b'#EXTM3U'
|
|
||||||
|
|
||||||
|
|
||||||
def detect_pls_header(typefind):
|
def detect_pls_header(data):
|
||||||
return typefind.peek(0, 10).lower() == b'[playlist]'
|
return data[0:10].lower() == b'[playlist]'
|
||||||
|
|
||||||
|
|
||||||
def detect_xspf_header(typefind):
|
def detect_xspf_header(data):
|
||||||
data = typefind.peek(0, 150)
|
data = data[0:150]
|
||||||
if b'xspf' not in data.lower():
|
if b'xspf' not in data.lower():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -38,8 +36,8 @@ def detect_xspf_header(typefind):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def detect_asx_header(typefind):
|
def detect_asx_header(data):
|
||||||
data = typefind.peek(0, 50)
|
data = data[0:50]
|
||||||
if b'asx' not in data.lower():
|
if b'asx' not in data.lower():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -55,7 +53,7 @@ def detect_asx_header(typefind):
|
|||||||
def parse_m3u(data):
|
def parse_m3u(data):
|
||||||
# TODO: convert non URIs to file URIs.
|
# TODO: convert non URIs to file URIs.
|
||||||
found_header = False
|
found_header = False
|
||||||
for line in data.readlines():
|
for line in data.splitlines():
|
||||||
if found_header or line.startswith(b'#EXTM3U'):
|
if found_header or line.startswith(b'#EXTM3U'):
|
||||||
found_header = True
|
found_header = True
|
||||||
else:
|
else:
|
||||||
@ -68,7 +66,7 @@ def parse_pls(data):
|
|||||||
# TODO: convert non URIs to file URIs.
|
# TODO: convert non URIs to file URIs.
|
||||||
try:
|
try:
|
||||||
cp = configparser.RawConfigParser()
|
cp = configparser.RawConfigParser()
|
||||||
cp.readfp(data)
|
cp.readfp(io.BytesIO(data))
|
||||||
except configparser.Error:
|
except configparser.Error:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -82,7 +80,7 @@ def parse_pls(data):
|
|||||||
def parse_xspf(data):
|
def parse_xspf(data):
|
||||||
try:
|
try:
|
||||||
# Last element will be root.
|
# Last element will be root.
|
||||||
for event, element in elementtree.iterparse(data):
|
for event, element in elementtree.iterparse(io.BytesIO(data)):
|
||||||
element.tag = element.tag.lower() # normalize
|
element.tag = element.tag.lower() # normalize
|
||||||
except elementtree.ParseError:
|
except elementtree.ParseError:
|
||||||
return
|
return
|
||||||
@ -95,7 +93,7 @@ def parse_xspf(data):
|
|||||||
def parse_asx(data):
|
def parse_asx(data):
|
||||||
try:
|
try:
|
||||||
# Last element will be root.
|
# Last element will be root.
|
||||||
for event, element in elementtree.iterparse(data):
|
for event, element in elementtree.iterparse(io.BytesIO(data)):
|
||||||
element.tag = element.tag.lower() # normalize
|
element.tag = element.tag.lower() # normalize
|
||||||
except elementtree.ParseError:
|
except elementtree.ParseError:
|
||||||
return
|
return
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
import io
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from mopidy.internal import playlists
|
from mopidy.internal import playlists
|
||||||
@ -77,15 +76,6 @@ XSPF = b"""<?xml version="1.0" encoding="UTF-8"?>
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TypeFind(object):
|
|
||||||
|
|
||||||
def __init__(self, data):
|
|
||||||
self.data = data
|
|
||||||
|
|
||||||
def peek(self, start, end):
|
|
||||||
return self.data[start:end]
|
|
||||||
|
|
||||||
|
|
||||||
class BasePlaylistTest(object):
|
class BasePlaylistTest(object):
|
||||||
valid = None
|
valid = None
|
||||||
invalid = None
|
invalid = None
|
||||||
@ -93,18 +83,18 @@ class BasePlaylistTest(object):
|
|||||||
parse = None
|
parse = None
|
||||||
|
|
||||||
def test_detect_valid_header(self):
|
def test_detect_valid_header(self):
|
||||||
self.assertTrue(self.detect(TypeFind(self.valid)))
|
self.assertTrue(self.detect(self.valid))
|
||||||
|
|
||||||
def test_detect_invalid_header(self):
|
def test_detect_invalid_header(self):
|
||||||
self.assertFalse(self.detect(TypeFind(self.invalid)))
|
self.assertFalse(self.detect(self.invalid))
|
||||||
|
|
||||||
def test_parse_valid_playlist(self):
|
def test_parse_valid_playlist(self):
|
||||||
uris = list(self.parse(io.BytesIO(self.valid)))
|
uris = list(self.parse(self.valid))
|
||||||
expected = [b'file:///tmp/foo', b'file:///tmp/bar', b'file:///tmp/baz']
|
expected = [b'file:///tmp/foo', b'file:///tmp/bar', b'file:///tmp/baz']
|
||||||
self.assertEqual(uris, expected)
|
self.assertEqual(uris, expected)
|
||||||
|
|
||||||
def test_parse_invalid_playlist(self):
|
def test_parse_invalid_playlist(self):
|
||||||
uris = list(self.parse(io.BytesIO(self.invalid)))
|
uris = list(self.parse(self.invalid))
|
||||||
self.assertEqual(uris, [])
|
self.assertEqual(uris, [])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user