spradio-server-django/savepointradio/radio/management/commands/importoldradio.py

193 lines
6.7 KiB
Python

'''
Django management command to import old playlist data. This should only be used
for seeding a newly created database.
'''
import decimal
import json
import os
import re
from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone
from core.utils import path_to_iri
from radio.models import Album, Artist, Game, Store, Song
decimal.getcontext().prec = 8
PROGRESS = '\rAdding {}: [{:>{width}} / {}]'
COMPLETED = 'Imported {} {}'
class Command(BaseCommand):
'''Main "importoldreadio" command class'''
help = 'Imports the old radio data from an exported playlist'
def add_arguments(self, parser):
parser.add_argument('playlist_file', nargs=1)
def handle(self, *args, **options):
playlist_file = options['playlist_file'][0]
if not os.path.isfile(playlist_file):
raise CommandError('File does not exist')
with open(playlist_file, 'r', encoding='utf8') as pfile:
playlist = json.load(pfile, parse_float=decimal.Decimal)
totals = {
'albums': 0,
'artists': 0,
'games': 0,
'songs': 0,
'jingles': 0
}
# Fetching albums first
number = len(playlist['albums']) if 'albums' in playlist else 0
self.stdout.write('\n')
for album in playlist['albums']:
Album.objects.create(title=album['title'],
disabled=album['disabled'])
totals['albums'] += 1
self.stdout.write(PROGRESS.format(
'albums',
totals['albums'],
number,
width=len(str(number))
), ending='')
self.stdout.flush()
self.stdout.write('\n')
self.stdout.write(COMPLETED.format(str(totals['albums']), 'albums'))
# Next up, artists
number = len(playlist['artists']) if 'artists' in playlist else 0
self.stdout.write('\n')
for artist in playlist['artists']:
Artist.objects.create(alias=artist['alias'] or '',
first_name=artist['first_name'] or '',
last_name=artist['last_name'] or '',
disabled=artist['disabled'])
totals['artists'] += 1
self.stdout.write(PROGRESS.format(
'artists',
totals['artists'],
number,
width=len(str(number))
), ending='')
self.stdout.flush()
self.stdout.write('\n')
self.stdout.write(COMPLETED.format(str(totals['artists']), 'artists'))
# On to games
number = len(playlist['games']) if 'games' in playlist else 0
self.stdout.write('\n')
for game in playlist['games']:
Game.objects.create(title=game['title'],
disabled=game['disabled'])
totals['games'] += 1
self.stdout.write(PROGRESS.format(
'games',
totals['games'],
number,
width=len(str(number))
), ending='')
self.stdout.flush()
self.stdout.write('\n')
self.stdout.write(COMPLETED.format(str(totals['games']), 'games'))
# Followed by the songs
number = len(playlist['songs']) if 'songs' in playlist else 0
progress = '\rAdding requestables: [{:>{width}} / {}]'
self.stdout.write('\n')
for song in playlist['songs']:
try:
album = Album.objects.get(title__exact=song['album'])
except Album.DoesNotExist:
album = None
try:
game = Game.objects.get(title__exact=song['game'])
except Game.DoesNotExist:
game = None
new_song = Song.objects.create(album=album,
game=game,
disabled=song['disabled'],
song_type=song['type'],
title=song['title'])
for artist in song['artists']:
new_artist = Artist.objects.get(
alias__exact=artist['alias'] or '',
first_name__exact=artist['first_name'] or '',
last_name__exact=artist['last_name'] or ''
)
new_song.artists.add(new_artist)
localfile = re.match(
r'^(?:(?:[A-Za-z]:|\\)\\|\/)',
song['store']['path']
)
if localfile:
iri = path_to_iri(song['store']['path'])
else:
iri = song['store']['path']
if song['store']['track_gain']:
gain_str = re.sub(r'[dB\+ ]', '', song['store']['track_gain'])
gain = decimal.Decimal(gain_str)
else:
gain = None
if song['store']['track_peak']:
peak = decimal.Decimal(song['store']['track_peak'])
else:
peak = None
new_store = Store.objects.create(
iri=iri,
mime_type=song['store']['mime'],
file_size=song['store']['filesize'],
length=song['store']['length'],
track_gain=gain,
track_peak=peak
)
new_song.stores.add(new_store)
new_song.active_store = new_store
new_song.save()
if song['type'] == 'S':
totals['songs'] += 1
else:
totals['jingles'] += 1
self.stdout.write(PROGRESS.format(
'requestables',
totals['songs'] + totals['jingles'],
number,
width=len(str(number))
), ending='')
self.stdout.flush()
self.stdout.write('\n')
self.stdout.write(COMPLETED.format(
str(totals['songs'] + totals['jingles']),
'requestables ({} songs, {} jingles)'.format(
str(totals['songs']),
str(totals['jingles'])
)
))
pub = input('Do you want to publish all imported objects as well? '
'[Y/N] ')
if pub in ('Y', 'y'):
date = timezone.now()
Album.objects.all().update(published_date=date)
Artist.objects.all().update(published_date=date)
Game.objects.all().update(published_date=date)
Song.objects.all().update(published_date=date)
self.stdout.write('Published imported objects successfully')
else:
self.stdout.write('Skipped publishing songs')