xspf2m3u

simple XSPF to M3U conversion
git clone https://git.ce9e.org/xspf2m3u.git

commit
2e48e6277a6c2e3bcb050bc7ab2538edd513804e
parent
63a5c7f60d04ffb47822b3902d8b6b3303f6ddaf
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2020-10-04 17:34
add m3u2xspf

Diffstat

A m3u2xspf.py 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M setup.py 4 +++-

2 files changed, 79 insertions, 1 deletions


diff --git a/m3u2xspf.py b/m3u2xspf.py

@@ -0,0 +1,76 @@
   -1     1 #!/usr/bin/env python
   -1     2 
   -1     3 import os
   -1     4 import sys
   -1     5 import argparse
   -1     6 from xml.sax.saxutils import escape
   -1     7 
   -1     8 try:
   -1     9 	import mutagen
   -1    10 except ImportError:
   -1    11 	mutagen = None
   -1    12 
   -1    13 KEYS = {
   -1    14 	'location': 'location',
   -1    15 	'album': 'album',
   -1    16 	'artist': 'creator',
   -1    17 	'title': 'title',
   -1    18 }
   -1    19 
   -1    20 
   -1    21 def unlist(s):
   -1    22 	return s if isinstance(s, str) else '; '.join(s)
   -1    23 
   -1    24 
   -1    25 def get_tags(path):
   -1    26 	if not mutagen or not os.path.exists(path):
   -1    27 		return {'location': path}
   -1    28 	data = mutagen.File(path, easy=True)
   -1    29 	if data:
   -1    30 		return data
   -1    31 	else:
   -1    32 		return {'location': path}
   -1    33 
   -1    34 
   -1    35 def iter_lines(path):
   -1    36 	root = os.path.dirname(path)
   -1    37 	with open(sys.argv[1]) as fh:
   -1    38 		for line in fh:
   -1    39 			line = line.rstrip()
   -1    40 			if line.startswith('#'):
   -1    41 				pass
   -1    42 			elif line.startswith('http'):
   -1    43 				yield {'location': line}
   -1    44 			else:
   -1    45 				if not line.startswith('/'):
   -1    46 					line = os.path.join(root, line)
   -1    47 				yield get_tags(line)
   -1    48 
   -1    49 
   -1    50 def parse_args():
   -1    51 	parser = argparse.ArgumentParser()
   -1    52 	parser.add_argument('src')
   -1    53 	return parser.parse_args()
   -1    54 
   -1    55 
   -1    56 def main():
   -1    57 	args = parse_args()
   -1    58 
   -1    59 	print('<?xml version="1.0" ?>')
   -1    60 	print('<playlist version="1" xmlns="http://xspf.org/ns/0/">')
   -1    61 	print('  <trackList>')
   -1    62 	for entry in iter_lines(args.src):
   -1    63 		print('    <track>')
   -1    64 		for k, v in sorted(entry.items()):
   -1    65 			if k in KEYS:
   -1    66 				print('      <{key}>{value}</{key}>'.format(
   -1    67 					key=escape(KEYS[k]),
   -1    68 					value=escape(unlist(v)),
   -1    69 				))
   -1    70 		print('    </track>')
   -1    71 	print('  </trackList>')
   -1    72 	print('</playlist>')
   -1    73 
   -1    74 
   -1    75 if __name__ == '__main__':
   -1    76 	main()

diff --git a/setup.py b/setup.py

@@ -21,11 +21,13 @@ setup(
   21    21     url='https://github.com/xi/xspf2m3u',
   22    22     author='Tobias Bengfort',
   23    23     author_email='tobias.bengfort@posteo.de',
   24    -1     py_modules=['xspf2m3u'],
   -1    24     py_modules=['xspf2m3u', 'm3u2xspf'],
   25    25     extras_require={
   26    26         'youtube': ['youtube_dl'],
   -1    27         'mutagen': ['mutagen'],
   27    28     },
   28    29     entry_points={'console_scripts': [
   29    30         'xspf2m3u=xspf2m3u:main',
   -1    31         'm3u2xspf=m3u2xspf:main',
   30    32     ]},
   31    33     license='GPLv2+')