Add ImportReleasesCommand and a generation script
To import your local albums!
This commit is contained in:
parent
0c17bbbc4c
commit
2b1da5098b
39
scripts/gen-releases-csv.py
Executable file
39
scripts/gen-releases-csv.py
Executable file
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate a CSV usable with the import:releases command from a directory.
|
||||||
|
|
||||||
|
This script assumes your have the same format for your release directories as
|
||||||
|
me, which is "Artist/Year - Release".
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
release_re = re.compile(r"(?P<year>\d{4})[\d\.]*(?: -)? (?P<title>.+)")
|
||||||
|
|
||||||
|
argparser = argparse.ArgumentParser()
|
||||||
|
argparser.add_argument('directory', help='directory to explore')
|
||||||
|
args = argparser.parse_args()
|
||||||
|
root = args.directory
|
||||||
|
|
||||||
|
with open('releases.csv', 'w', newline='') as output_file:
|
||||||
|
csv_writer = csv.writer(output_file)
|
||||||
|
|
||||||
|
for artist in os.listdir(root):
|
||||||
|
artist_dir = os.path.join(root, artist)
|
||||||
|
if not os.path.isdir(artist_dir):
|
||||||
|
continue
|
||||||
|
for release in os.listdir(os.path.join(root, artist)):
|
||||||
|
release_dir = os.path.join(artist_dir, release)
|
||||||
|
if not os.path.isdir(release_dir):
|
||||||
|
continue
|
||||||
|
match = release_re.match(release)
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
match_dict = match.groupdict()
|
||||||
|
csv_writer.writerow([
|
||||||
|
artist,
|
||||||
|
match_dict["title"],
|
||||||
|
match_dict["year"],
|
||||||
|
])
|
104
src/Command/ImportReleasesCommand.php
Normal file
104
src/Command/ImportReleasesCommand.php
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Command;
|
||||||
|
|
||||||
|
use App\Entity\Artist;
|
||||||
|
use App\Entity\Release;
|
||||||
|
use App\Repository\ArtistRepository;
|
||||||
|
use App\Repository\ReleaseRepository;
|
||||||
|
use App\Repository\UserRepository;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
|
#[AsCommand(
|
||||||
|
name: 'import:releases',
|
||||||
|
description: 'Import releases from a CSV file.',
|
||||||
|
)]
|
||||||
|
class ImportReleasesCommand extends Command
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected EntityManagerInterface $entityManager,
|
||||||
|
protected ArtistRepository $artistRepository,
|
||||||
|
protected ReleaseRepository $releaseRepository,
|
||||||
|
protected UserRepository $userRepository,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configure(): void
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->addArgument('username', InputArgument::REQUIRED, 'Owner username')
|
||||||
|
->addArgument('csv', InputArgument::REQUIRED, 'CSV file')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
$csvFilename = $input->getArgument('csv');
|
||||||
|
$ownerName = $input->getArgument('username');
|
||||||
|
|
||||||
|
$owner = $this->userRepository->findOneBy(['username' => $ownerName]);
|
||||||
|
if (!$owner) {
|
||||||
|
$io->error("No user with the username $ownerName.");
|
||||||
|
return Command::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$numNewArtists = 0;
|
||||||
|
$numNewReleases = 0;
|
||||||
|
$numSkippedReleases = 0;
|
||||||
|
$csvFile = fopen($csvFilename, 'r');
|
||||||
|
while (($row = fgetcsv($csvFile)) !== false) {
|
||||||
|
$numCols = count($row);
|
||||||
|
if ($numCols < 2) {
|
||||||
|
$io->error('Skipping row with less than two columns: ' . json_encode($row));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$artistName = $row[0];
|
||||||
|
$title = $row[1];
|
||||||
|
|
||||||
|
$artist = $this->artistRepository->findOneBy(['name' => $artistName]);
|
||||||
|
if (!$artist) {
|
||||||
|
$artist = new Artist();
|
||||||
|
$artist->setName($artistName);
|
||||||
|
$this->entityManager->persist($artist);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
$numNewArtists++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$releaseExists = false;
|
||||||
|
foreach ($artist->getReleases() as $artistRelease) {
|
||||||
|
if ($artistRelease->getTitle() === $title) {
|
||||||
|
$releaseExists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$releaseExists) {
|
||||||
|
$release = new Release();
|
||||||
|
$release->setTitle($title);
|
||||||
|
$release->setOwner($owner);
|
||||||
|
$release->addArtist($artist);
|
||||||
|
$this->entityManager->persist($release);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
$numNewReleases++;
|
||||||
|
} else {
|
||||||
|
$numSkippedReleases++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose($csvFile);
|
||||||
|
|
||||||
|
$io->success(
|
||||||
|
'Import successful:'
|
||||||
|
. " $numNewArtists new artists,"
|
||||||
|
. " $numNewReleases new releases ($numSkippedReleases skipped)."
|
||||||
|
);
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue