How to do it...

Follow these steps to create a Song model and a management command, which imports the top tracks from Last.fm to the database in JSON format:

  1. If you haven't done so, in the music app, create a management directory, and then a commands subdirectory beneath it. Add empty __init__.py files in both of the new directories to make them Python packages.
  2. Add an import_music_from_lastfm_json.py file with the following content:
# myproject/apps/music/management/commands
# /import_music_from_lastfm_json.py

from
django.core.management.base import BaseCommand

class Command(BaseCommand):
help = "Imports top songs from last.fm as JSON."
SILENT, NORMAL, VERBOSE, VERY_VERBOSE = 0, 1, 2, 3
API_URL = "https://ws.audioscrobbler.com/2.0/"

def add_arguments(self, parser):
# Named (optional) arguments
parser.add_argument("--max_pages", type=int, default=0)

def handle(self, *args, **options):
self.verbosity = options.get("verbosity", self.NORMAL)
self.max_pages = options["max_pages"]
self.prepare()
self.main()
self.finalize()
  1. Then, in the same file for the Command class, create a prepare() method:
    def prepare(self):
from django.conf import settings

self.imported_counter = 0
self.skipped_counter = 0
self.params = {
"method": "tag.gettoptracks",
"tag": "indie",
"api_key": settings.LAST_FM_API_KEY,
"format": "json",
"page": 1,
}
  1. Then, create the main() method there:
    def main(self):
import requests

response = requests.get(self.API_URL, params=self.params)
if response.status_code != requests.codes.ok:
self.stderr.write(f"Error connecting to
{response.url}")
return
response_dict = response.json()
pages = int(
response_dict.get("tracks", {})
.get("@attr", {}).get("totalPages", 1)
)

if self.max_pages > 0:
pages = min(pages, self.max_pages)

if self.verbosity >= self.NORMAL:
self.stdout.write(f"=== Importing {pages} page(s)
of tracks ==="
)

self.save_page(response_dict)

for page_number in range(2, pages + 1):
self.params["page"] = page_number
response = requests.get(self.API_URL,
params=self.params)

if response.status_code != requests.codes.ok:
self.stderr.write(f"Error connecting to
{response.url}")
return
response_dict = response.json()
self.save_page(response_dict)
  1. Each page from the paginated feed will be saved by the save_page() method that we should create, as follows:
    def save_page(self, data):
import os
import requests
from io import BytesIO
from django.core.files import File
from ...forms import SongForm

for track_dict in data.get("tracks", {}).get("track"):
if not track_dict:
continue

song_dict = {
"artist": track_dict.get("artist", {}).get("name", ""),
"title": track_dict.get("name", ""),
"url": track_dict.get("url", ""),
}
form = SongForm(data=song_dict)
if form.is_valid():
song = form.save()

image_dict = track_dict.get("image", None)
if image_dict:
image_url = image_dict[1]["#text"]
image_response = requests.get(image_url)
song.image.save(
os.path.basename(image_url),
File(BytesIO(image_response.content)),
)

if self.verbosity >= self.NORMAL:
self.stdout.write(f" - {song} ")
self.imported_counter += 1
else:
if self.verbosity >= self.NORMAL:
self.stderr.write(
f"Errors importing song "
f"{song_dict['artist']} -
{song_dict['title']}: "
)
self.stderr.write(f"{form.errors.as_json()} ")
self.skipped_counter += 1
  1. And we'll finish the class with the finalize() method:
    def finalize(self):
if self.verbosity >= self.NORMAL:
self.stdout.write(f"------------------------- ")
self.stdout.write(f"Songs imported:
{self.imported_counter} ")
self.stdout.write(f"Songs skipped:
{self.skipped_counter} ")
  1. To run the import, call the following in the command line:
(env)$ python manage.py import_music_from_lastfm_json --max_pages=3
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.151.141