mirror of
https://github.com/ToxicCrack/PrintABrick.git
synced 2025-05-19 13:40:08 -07:00
Merged feat/LDraw-data into dev
This commit is contained in:
commit
ee78bdc07e
@ -8,6 +8,8 @@ A Symfony project
|
|||||||
* PDO
|
* PDO
|
||||||
* SOAP
|
* SOAP
|
||||||
* *date.timezone* setting set in *php.ini*
|
* *date.timezone* setting set in *php.ini*
|
||||||
|
* PHP Zip Extension enabled
|
||||||
|
* LDView OSMesa >= 4.2.1 [source](https://tcobbs.github.io/ldview/).
|
||||||
|
|
||||||
You can check if your system meets requirements by running `$ bin/symfony_requirements`
|
You can check if your system meets requirements by running `$ bin/symfony_requirements`
|
||||||
|
|
||||||
@ -26,4 +28,5 @@ For full requirements see Symfony 3.2 [docs](http://symfony.com/doc/3.2/referenc
|
|||||||
####Database
|
####Database
|
||||||
1. Set application parameters in *app/config/parameters.yml*
|
1. Set application parameters in *app/config/parameters.yml*
|
||||||
2. Generate empty database by running command `$ php bin/console doctrine:database:create`
|
2. Generate empty database by running command `$ php bin/console doctrine:database:create`
|
||||||
|
3. To load LDraw models into database run commad `$ php bin/console app:load:ldraw`
|
||||||
|
If you prefer local ldraw library you can specify source by running `$ php bin/console app:load:ldraw [ldraw_dir_path]` instead
|
@ -22,4 +22,7 @@ parameters:
|
|||||||
brickset_apikey: ~
|
brickset_apikey: ~
|
||||||
|
|
||||||
# Rebrickable API key obtainable at http://rebrickable.com/api/
|
# Rebrickable API key obtainable at http://rebrickable.com/api/
|
||||||
rebrickable_apikey: ~
|
rebrickable_apikey: ~
|
||||||
|
|
||||||
|
# Absolute path to OSMesa port of LDView
|
||||||
|
ldview_bin: /usr/bin/ldview
|
@ -17,13 +17,24 @@ services:
|
|||||||
class: AppBundle\Service\CollectionService
|
class: AppBundle\Service\CollectionService
|
||||||
arguments: ['@doctrine.orm.entity_manager', '@manager.brickset','@manager.rebrickable']
|
arguments: ['@doctrine.orm.entity_manager', '@manager.brickset','@manager.rebrickable']
|
||||||
|
|
||||||
|
service.loader:
|
||||||
|
abstract: true
|
||||||
|
class: AppBundle\Loader\Loader
|
||||||
|
arguments: ['@doctrine.orm.entity_manager']
|
||||||
|
|
||||||
|
service.ldview:
|
||||||
|
class: AppBundle\Service\LDViewService
|
||||||
|
arguments: ['%ldview_bin%', '@oneup_flysystem.ldraw_filesystem']
|
||||||
|
|
||||||
loader.rebrickable:
|
loader.rebrickable:
|
||||||
class: AppBundle\Command\Loader\RebrickableLoader
|
class: AppBundle\Command\Loader\RebrickableLoader
|
||||||
arguments: ['@doctrine.orm.entity_manager', '@manager.rebrickable', '%rebrickable_url%' ]
|
arguments: ['@doctrine.orm.entity_manager', '@manager.rebrickable', '%rebrickable_url%' ]
|
||||||
loader.ldraw:
|
loader.ldraw:
|
||||||
class: AppBundle\Command\Loader\LDrawLoader
|
class: AppBundle\Loader\LDrawLoader
|
||||||
arguments: ['@doctrine.orm.entity_manager', '%kernel.root_dir%/../bin/ldview', '@oneup_flysystem.ldraw_filesystem', '%ldraw_url%']
|
calls:
|
||||||
|
- [setArguments, ['@service.ldview', '%ldraw_url%']]
|
||||||
|
parent: service.loader
|
||||||
|
|
||||||
app.form.filter_set:
|
app.form.filter_set:
|
||||||
class: AppBundle\Form\FilterSetType
|
class: AppBundle\Form\FilterSetType
|
||||||
arguments: ['@manager.brickset']
|
arguments: ['@manager.brickset']
|
||||||
|
38
src/AppBundle/Command/LoadLDRawLibraryCommand.php
Normal file
38
src/AppBundle/Command/LoadLDRawLibraryCommand.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AppBundle\Command;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class LoadLDRawLibraryCommand extends ContainerAwareCommand
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('app:load:ldraw')
|
||||||
|
->setDescription('Loads LDraw library parts')
|
||||||
|
->setHelp('This command allows you to..')
|
||||||
|
->addArgument('ldraw_path', InputArgument::OPTIONAL, 'Path to LDraw library folder');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$ldrawLoader = $this->getContainer()->get('loader.ldraw');
|
||||||
|
$ldrawLoader->setOutput($output);
|
||||||
|
|
||||||
|
//TODO log errors
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (($ldrawPath = $input->getArgument('ldraw_path')) == null) {
|
||||||
|
$ldrawPath = $ldrawLoader->downloadLibrary();
|
||||||
|
}
|
||||||
|
|
||||||
|
$ldrawLoader->loadModels($ldrawPath);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
printf($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,187 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace AppBundle\Command\Loader;
|
|
||||||
|
|
||||||
use AppBundle\Entity\Category;
|
|
||||||
use AppBundle\Entity\Model;
|
|
||||||
use League\Flysystem\Adapter\Local;
|
|
||||||
use League\Flysystem\Filesystem;
|
|
||||||
use Symfony\Component\Asset\Exception\LogicException;
|
|
||||||
use Symfony\Component\Console\Helper\ProgressBar;
|
|
||||||
use Symfony\Component\Finder\Finder;
|
|
||||||
use Symfony\Component\Finder\SplFileInfo;
|
|
||||||
use Symfony\Component\Process\ProcessBuilder;
|
|
||||||
|
|
||||||
class LDrawLoader extends Loader
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var string LDView binary file path
|
|
||||||
*/
|
|
||||||
private $ldview;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Filesystem
|
|
||||||
*/
|
|
||||||
private $ldraw;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \League\Flysystem\Filesystem
|
|
||||||
*/
|
|
||||||
private $dataPath;
|
|
||||||
|
|
||||||
private $ldraw_url;
|
|
||||||
|
|
||||||
public function __construct($em, $ldview, $dataPath, $ldraw_url)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @var $em EntityManager
|
|
||||||
* */
|
|
||||||
$this->em = $em;
|
|
||||||
$this->ldview = $ldview;
|
|
||||||
$this->dataPath = $dataPath;
|
|
||||||
$this->ldraw_url = $ldraw_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function downloadLibrary()
|
|
||||||
{
|
|
||||||
$this->output->writeln('Downloading set_pieces.csv from Rebrickable.com');
|
|
||||||
$temp = $this->downloadFile($this->ldraw_url);
|
|
||||||
$temp_dir = tempnam(sys_get_temp_dir(), 'printabrick.');
|
|
||||||
if (file_exists($temp_dir)) {
|
|
||||||
unlink($temp_dir);
|
|
||||||
}
|
|
||||||
mkdir($temp_dir);
|
|
||||||
$zip = new \ZipArchive();
|
|
||||||
if ($zip->open($temp) != 'true') {
|
|
||||||
echo 'Error :- Unable to open the Zip File';
|
|
||||||
}
|
|
||||||
$zip->extractTo($temp_dir);
|
|
||||||
$zip->close();
|
|
||||||
unlink($temp);
|
|
||||||
|
|
||||||
return $temp_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadModels($LDrawLibrary)
|
|
||||||
{
|
|
||||||
//TODO Refactor, use flysystem
|
|
||||||
$adapter = new Local(getcwd().DIRECTORY_SEPARATOR.$LDrawLibrary);
|
|
||||||
$this->ldraw = new Filesystem($adapter);
|
|
||||||
// $files = $this->ldraw->get('parts')->getContents();
|
|
||||||
|
|
||||||
$finder = new Finder();
|
|
||||||
$files = $finder->files()->name('*.dat')->depth('== 0')->in(getcwd().DIRECTORY_SEPARATOR.$LDrawLibrary.DIRECTORY_SEPARATOR.'parts');
|
|
||||||
|
|
||||||
$progressBar = new ProgressBar($this->output, $files->count());
|
|
||||||
$progressBar->setFormat('very_verbose');
|
|
||||||
$progressBar->setMessage('Loading LDraw library models');
|
|
||||||
$progressBar->setFormat('%message:6s% %current%/%max% [%bar%]%percent:3s%% (%elapsed:6s%/%estimated:-6s%)');
|
|
||||||
$progressBar->start();
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$model = $this->loadPartHeader($file);
|
|
||||||
$model->setFile($this->createStlFile($file)->getPath());
|
|
||||||
|
|
||||||
$this->em->persist($model);
|
|
||||||
$this->em->flush();
|
|
||||||
|
|
||||||
$progressBar->advance();
|
|
||||||
}
|
|
||||||
$progressBar->finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param SplFileInfo $file
|
|
||||||
*
|
|
||||||
* @return Model
|
|
||||||
*/
|
|
||||||
private function loadPartHeader($file)
|
|
||||||
{
|
|
||||||
$handle = fopen($file->getRealPath(), 'r');
|
|
||||||
if ($handle) {
|
|
||||||
$firstLine = false;
|
|
||||||
|
|
||||||
$model = new Model();
|
|
||||||
|
|
||||||
// read lines while line starts with 0 or is empty
|
|
||||||
while (($line = trim(fgets($handle))) !== false && ($line ? $line[0] == '0' : true)) {
|
|
||||||
if ($line !== '') {
|
|
||||||
$line = preg_replace('/^0 /', '', $line);
|
|
||||||
|
|
||||||
// 0 <CategoryName> <PartDescription>
|
|
||||||
if (!$firstLine) {
|
|
||||||
//TODO handle "~Moved to"
|
|
||||||
//TODO "=" - alias name for other part kept for referece
|
|
||||||
//TODO "_" shortcut
|
|
||||||
|
|
||||||
$array = explode(' ', trim($line), 2);
|
|
||||||
$category = isset($array[0]) ? $array[0] : '';
|
|
||||||
$model->setName($line);
|
|
||||||
|
|
||||||
$firstLine = true;
|
|
||||||
}
|
|
||||||
// 0 !CATEGORY <CategoryName>
|
|
||||||
elseif (strpos($line, '!CATEGORY ') === 0) {
|
|
||||||
$category = trim(preg_replace('/^!CATEGORY /', '', $line));
|
|
||||||
}
|
|
||||||
// 0 !KEYWORDS <first keyword>, <second keyword>, ..., <last keyword>
|
|
||||||
elseif (strpos($line, '!KEYWORDS ') === 0) {
|
|
||||||
$keywords = explode(', ', preg_replace('/^!KEYWORDS /', '', $line));
|
|
||||||
}
|
|
||||||
// 0 Name: <Filename>.dat
|
|
||||||
elseif (strpos($line, 'Name: ') === 0) {
|
|
||||||
$model->setNumber(preg_replace('/(^Name: )(.*)(.dat)/', '$2', $line));
|
|
||||||
}
|
|
||||||
// 0 Author: <Realname> [<Username>]
|
|
||||||
elseif (strpos($line, 'Author: ') === 0) {
|
|
||||||
$model->setAuthor(preg_replace('/^Author: /', '', $line));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$cat = $this->em->getRepository('AppBundle:Category')->findOneBy(['name' => $category]);
|
|
||||||
if ($cat == null) {
|
|
||||||
$cat = new Category();
|
|
||||||
$cat->setName($category);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->setCategory($cat);
|
|
||||||
$cat->addModel($model);
|
|
||||||
} else {
|
|
||||||
throw new LogicException('loadHeader error'); //TODO
|
|
||||||
}
|
|
||||||
fclose($handle);
|
|
||||||
|
|
||||||
return $model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param SplFileInfo $file
|
|
||||||
*
|
|
||||||
* @return \League\Flysystem\File
|
|
||||||
*/
|
|
||||||
private function createStlFile($file)
|
|
||||||
{
|
|
||||||
$stlFilename = str_replace('.dat', '.stl', $file->getFilename());
|
|
||||||
|
|
||||||
if (!$this->dataPath->has($stlFilename)) {
|
|
||||||
$builder = new ProcessBuilder();
|
|
||||||
$process = $builder
|
|
||||||
->setPrefix($this->ldview)
|
|
||||||
->setArguments([
|
|
||||||
// $this->ldraw->getAdapter()->getPathPrefix().$file['path'],
|
|
||||||
$file->getRealPath(),
|
|
||||||
'-LDrawDir='.$this->ldraw->getAdapter()->getPathPrefix(),
|
|
||||||
'-ExportFile='.$this->dataPath->getAdapter()->getPathPrefix().$stlFilename,
|
|
||||||
])
|
|
||||||
->getProcess();
|
|
||||||
|
|
||||||
$process->run();
|
|
||||||
|
|
||||||
if (!$process->isSuccessful() || !$this->dataPath->has($stlFilename)) {
|
|
||||||
throw new LogicException($file->getFilename().' : '.$process->getOutput()); //TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->dataPath->get($stlFilename);
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace AppBundle\Controller;
|
namespace AppBundle\Controller;
|
||||||
|
|
||||||
use AppBundle\Entity\Model;
|
use AppBundle\Entity\LDraw\Model;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
||||||
|
115
src/AppBundle/Entity/LDraw/Category.php
Normal file
115
src/AppBundle/Entity/LDraw/Category.php
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AppBundle\Entity\LDraw;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Category.
|
||||||
|
*
|
||||||
|
* @ORM\Table(name="ldraw_category")
|
||||||
|
* @ORM\Entity
|
||||||
|
*/
|
||||||
|
class Category
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="id", type="integer")
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="name", type="string", length=255, unique=true)
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection
|
||||||
|
*
|
||||||
|
* @ORM\OneToMany(targetEntity="AppBundle\Entity\LDraw\Part", mappedBy="category")
|
||||||
|
*/
|
||||||
|
private $parts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BuildingKit constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->parts = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get id.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set name.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return Category
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get name.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get parts.
|
||||||
|
*
|
||||||
|
* @return ArrayCollection
|
||||||
|
*/
|
||||||
|
public function getParts()
|
||||||
|
{
|
||||||
|
return $this->parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Part $part
|
||||||
|
*
|
||||||
|
* @return Category
|
||||||
|
*/
|
||||||
|
public function addPart(Part $part)
|
||||||
|
{
|
||||||
|
$this->parts->add($part);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Part $part
|
||||||
|
*
|
||||||
|
* @return Category
|
||||||
|
*/
|
||||||
|
public function removePart(Part $part)
|
||||||
|
{
|
||||||
|
$this->parts->remove($part);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
114
src/AppBundle/Entity/LDraw/Keyword.php
Normal file
114
src/AppBundle/Entity/LDraw/Keyword.php
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AppBundle\Entity\LDraw;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keyword.
|
||||||
|
*
|
||||||
|
* @ORM\Table(name="ldraw_keyword")
|
||||||
|
* @ORM\Entity
|
||||||
|
*/
|
||||||
|
class Keyword
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="id", type="integer")
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="name", type="string", length=255, unique=true)
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ArrayCollection
|
||||||
|
*
|
||||||
|
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\LDraw\Part", mappedBy="keywords")
|
||||||
|
*/
|
||||||
|
private $parts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keyword constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->parts = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get id.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set name.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return Keyword
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get name.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get models.
|
||||||
|
*
|
||||||
|
* @return ArrayCollection
|
||||||
|
*/
|
||||||
|
public function getParts()
|
||||||
|
{
|
||||||
|
return $this->parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Part $part
|
||||||
|
*
|
||||||
|
* @return Keyword
|
||||||
|
*/
|
||||||
|
public function addPart(Part $part)
|
||||||
|
{
|
||||||
|
$this->parts->add($part);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Part $part
|
||||||
|
*
|
||||||
|
* @return Keyword
|
||||||
|
*/
|
||||||
|
public function removeModel(Part $part)
|
||||||
|
{
|
||||||
|
$this->parts->removeElement($part);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
134
src/AppBundle/Entity/LDraw/Model.php
Normal file
134
src/AppBundle/Entity/LDraw/Model.php
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AppBundle\Entity\LDraw;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model.
|
||||||
|
*
|
||||||
|
* @ORM\Table(name="ldraw_model")
|
||||||
|
* @ORM\Entity
|
||||||
|
*/
|
||||||
|
class Model
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(type="string")
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\Column(type="string", length=255, unique=true)
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(type="string", length=255, nullable=false)
|
||||||
|
*/
|
||||||
|
private $file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(type="string", length=255, nullable=true)
|
||||||
|
*/
|
||||||
|
private $author;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \DateTime
|
||||||
|
*
|
||||||
|
* @ORM\Column(type="datetime", nullable=true)
|
||||||
|
*/
|
||||||
|
private $modified;
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @var Collection
|
||||||
|
// *
|
||||||
|
// * @ORM\OneToMany(targetEntity="AppBundle\Entity\Part", mappedBy="model")
|
||||||
|
// */
|
||||||
|
// private $parts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $id
|
||||||
|
*/
|
||||||
|
public function setId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get id.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFile()
|
||||||
|
{
|
||||||
|
return $this->file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return Model
|
||||||
|
*/
|
||||||
|
public function setFile($file)
|
||||||
|
{
|
||||||
|
$this->file = $file;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set author.
|
||||||
|
*
|
||||||
|
* @param string $author
|
||||||
|
*
|
||||||
|
* @return Model
|
||||||
|
*/
|
||||||
|
public function setAuthor($author)
|
||||||
|
{
|
||||||
|
$this->author = $author;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get author.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getAuthor()
|
||||||
|
{
|
||||||
|
return $this->author;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \DateTime
|
||||||
|
*/
|
||||||
|
public function getModified()
|
||||||
|
{
|
||||||
|
return $this->modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DateTime $modified
|
||||||
|
*
|
||||||
|
* @return Model
|
||||||
|
*/
|
||||||
|
public function setModified($modified)
|
||||||
|
{
|
||||||
|
$this->modified = $modified;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
254
src/AppBundle/Entity/LDraw/Part.php
Normal file
254
src/AppBundle/Entity/LDraw/Part.php
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AppBundle\Entity\LDraw;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part.
|
||||||
|
*
|
||||||
|
* @ORM\Entity
|
||||||
|
* @ORM\Table(name="ldraw_part")
|
||||||
|
*/
|
||||||
|
class Part
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\Column(type="string", length=255, unique=true)
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Type
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\LDraw\Type", inversedBy="parts", cascade={"persist"})
|
||||||
|
*/
|
||||||
|
private $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(type="string", length=255, nullable=true)
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Category
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\LDraw\Category", inversedBy="parts", cascade={"persist"})
|
||||||
|
*/
|
||||||
|
private $category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Part
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\LDraw\Part",cascade={"persist"})
|
||||||
|
*/
|
||||||
|
private $printOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Part
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\LDraw\Part",cascade={"persist"})
|
||||||
|
*/
|
||||||
|
private $aliasOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Model
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\LDraw\Model", cascade={"persist"})
|
||||||
|
*/
|
||||||
|
private $model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection
|
||||||
|
*
|
||||||
|
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\LDraw\Keyword", inversedBy="parts", cascade={"persist"})
|
||||||
|
*/
|
||||||
|
private $keywords;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->keywords = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $id
|
||||||
|
*
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function setId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $type
|
||||||
|
*/
|
||||||
|
public function setType($type)
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Category
|
||||||
|
*/
|
||||||
|
public function getCategory()
|
||||||
|
{
|
||||||
|
return $this->category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $category
|
||||||
|
*
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function setCategory(Category $category)
|
||||||
|
{
|
||||||
|
$this->category = $category;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function getPrintOf()
|
||||||
|
{
|
||||||
|
return $this->printOf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Part $printOf
|
||||||
|
*
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function setPrintOf($printOf)
|
||||||
|
{
|
||||||
|
$this->printOf = $printOf;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function getAliasOf()
|
||||||
|
{
|
||||||
|
return $this->aliasOf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Part $printOf
|
||||||
|
*
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function setAliasOf($aliasOf)
|
||||||
|
{
|
||||||
|
$this->aliasOf = $aliasOf;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Model
|
||||||
|
*/
|
||||||
|
public function getModel()
|
||||||
|
{
|
||||||
|
if (!$this->model) {
|
||||||
|
if ($this->printOf) {
|
||||||
|
return $this->printOf->getModel();
|
||||||
|
} elseif ($this->aliasOf) {
|
||||||
|
return $this->aliasOf->getModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Model $model
|
||||||
|
*
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function setModel($model)
|
||||||
|
{
|
||||||
|
$this->model = $model;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get keywords.
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getKeywords()
|
||||||
|
{
|
||||||
|
return $this->keywords;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Keyword $keyword
|
||||||
|
*
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function addKeyword(Keyword $keyword)
|
||||||
|
{
|
||||||
|
if (!$this->keywords->contains($keyword)) {
|
||||||
|
$this->keywords->add($keyword);
|
||||||
|
$keyword->addPart($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Keyword $keyword
|
||||||
|
*
|
||||||
|
* @return Part
|
||||||
|
*/
|
||||||
|
public function removePart(Keyword $keyword)
|
||||||
|
{
|
||||||
|
$this->keywords->removeElement($keyword);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
105
src/AppBundle/Entity/LDraw/Type.php
Normal file
105
src/AppBundle/Entity/LDraw/Type.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AppBundle\Entity\LDraw;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type.
|
||||||
|
*
|
||||||
|
* @ORM\Table(name="ldraw_type")
|
||||||
|
* @ORM\Entity
|
||||||
|
*/
|
||||||
|
class Type
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="id", type="integer")
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(type="string", length=60, unique=true)
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection
|
||||||
|
*
|
||||||
|
* @ORM\OneToMany(targetEntity="Part", mappedBy="type")
|
||||||
|
*/
|
||||||
|
private $parts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BuildingKit constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->parts = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get parts.
|
||||||
|
*
|
||||||
|
* @return ArrayCollection
|
||||||
|
*/
|
||||||
|
public function getParts()
|
||||||
|
{
|
||||||
|
return $this->parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Part $part
|
||||||
|
*
|
||||||
|
* @return Type
|
||||||
|
*/
|
||||||
|
public function addPart(Part $part)
|
||||||
|
{
|
||||||
|
$this->parts->add($part);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Part $part
|
||||||
|
*
|
||||||
|
* @return Type
|
||||||
|
*/
|
||||||
|
public function removePart(Part $part)
|
||||||
|
{
|
||||||
|
$this->parts->remove($part);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -1,222 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace AppBundle\Entity;
|
|
||||||
|
|
||||||
use Doctrine\Common\Collections\Collection;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Model.
|
|
||||||
*
|
|
||||||
* @ORM\Table(name="model")
|
|
||||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\ModelRepository")
|
|
||||||
*/
|
|
||||||
class Model
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*
|
|
||||||
* @ORM\Column(name="id", type="integer")
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue(strategy="AUTO")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*
|
|
||||||
* @ORM\Column(name="name", type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $name;
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*
|
|
||||||
* @ORM\Column(name="number", type="string", length=255, unique=true)
|
|
||||||
*/
|
|
||||||
private $number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*
|
|
||||||
* @ORM\Column(name="author", type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $author;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*
|
|
||||||
* @ORM\Column(name="file", type="string", length=255, unique=true, nullable=true)
|
|
||||||
*/
|
|
||||||
private $file;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Collection
|
|
||||||
*
|
|
||||||
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Part", mappedBy="model")
|
|
||||||
*/
|
|
||||||
private $parts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Category
|
|
||||||
*
|
|
||||||
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category", inversedBy="models", cascade={"persist"})
|
|
||||||
*/
|
|
||||||
private $category;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get id.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getId()
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $name
|
|
||||||
*/
|
|
||||||
public function setName($name)
|
|
||||||
{
|
|
||||||
$this->name = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set number.
|
|
||||||
*
|
|
||||||
* @param string $number
|
|
||||||
*
|
|
||||||
* @return Model
|
|
||||||
*/
|
|
||||||
public function setNumber($number)
|
|
||||||
{
|
|
||||||
$this->number = $number;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get number.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getNumber()
|
|
||||||
{
|
|
||||||
return $this->number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set author.
|
|
||||||
*
|
|
||||||
* @param string $author
|
|
||||||
*
|
|
||||||
* @return Model
|
|
||||||
*/
|
|
||||||
public function setAuthor($author)
|
|
||||||
{
|
|
||||||
$this->author = $author;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get author.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getAuthor()
|
|
||||||
{
|
|
||||||
return $this->author;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set file.
|
|
||||||
*
|
|
||||||
* @param string $file
|
|
||||||
*
|
|
||||||
* @return Model
|
|
||||||
*/
|
|
||||||
public function setFile($file)
|
|
||||||
{
|
|
||||||
$this->file = $file;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get file.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getFile()
|
|
||||||
{
|
|
||||||
return $this->file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get parts.
|
|
||||||
*
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getParts()
|
|
||||||
{
|
|
||||||
return $this->parts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Part $part
|
|
||||||
*
|
|
||||||
* @return Model
|
|
||||||
*/
|
|
||||||
public function addPart(Part $part)
|
|
||||||
{
|
|
||||||
$this->parts->add($part);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Part $part
|
|
||||||
*
|
|
||||||
* @return Model
|
|
||||||
*/
|
|
||||||
public function removePart(Part $part)
|
|
||||||
{
|
|
||||||
$this->parts->remove($part);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set category.
|
|
||||||
*
|
|
||||||
* @param Category $category
|
|
||||||
*
|
|
||||||
* @return Model
|
|
||||||
*/
|
|
||||||
public function setCategory(Category $category)
|
|
||||||
{
|
|
||||||
$category->addModel($this);
|
|
||||||
$this->category = $category;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get category.
|
|
||||||
*
|
|
||||||
* @return Category
|
|
||||||
*/
|
|
||||||
public function getCategory()
|
|
||||||
{
|
|
||||||
return $this->category;
|
|
||||||
}
|
|
||||||
}
|
|
303
src/AppBundle/Loader/LDrawLoader.php
Normal file
303
src/AppBundle/Loader/LDrawLoader.php
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AppBundle\Loader;
|
||||||
|
|
||||||
|
use AppBundle\Entity\LDraw\Category;
|
||||||
|
use AppBundle\Entity\LDraw\Keyword;
|
||||||
|
use AppBundle\Entity\LDraw\Model;
|
||||||
|
use AppBundle\Entity\LDraw\Part;
|
||||||
|
use AppBundle\Entity\LDraw\Type;
|
||||||
|
use AppBundle\Service\LDViewService;
|
||||||
|
use League\Flysystem\Adapter\Local;
|
||||||
|
use League\Flysystem\Filesystem;
|
||||||
|
use Symfony\Component\Asset\Exception\LogicException;
|
||||||
|
use Symfony\Component\Console\Helper\ProgressBar;
|
||||||
|
use Symfony\Component\Finder\Finder;
|
||||||
|
|
||||||
|
class LDrawLoader extends Loader
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Filesystem
|
||||||
|
*/
|
||||||
|
private $ldraw;
|
||||||
|
|
||||||
|
private $ldraw_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LDViewService
|
||||||
|
*/
|
||||||
|
private $LDViewService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $ldraw_url
|
||||||
|
*/
|
||||||
|
public function setArguments(LDViewService $LDViewService, $ldraw_url)
|
||||||
|
{
|
||||||
|
$this->LDViewService = $LDViewService;
|
||||||
|
$this->ldraw_url = $ldraw_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadLibrary()
|
||||||
|
{
|
||||||
|
$this->output->writeln('Downloading LDraw library form ldraw.org');
|
||||||
|
$temp = $this->downloadFile($this->ldraw_url);
|
||||||
|
$temp_dir = tempnam(sys_get_temp_dir(), 'printabrick.');
|
||||||
|
if (file_exists($temp_dir)) {
|
||||||
|
unlink($temp_dir);
|
||||||
|
}
|
||||||
|
mkdir($temp_dir);
|
||||||
|
$zip = new \ZipArchive();
|
||||||
|
if ($zip->open($temp) != 'true') {
|
||||||
|
echo 'Error :- Unable to open the Zip File';
|
||||||
|
}
|
||||||
|
$zip->extractTo($temp_dir);
|
||||||
|
$zip->close();
|
||||||
|
unlink($temp);
|
||||||
|
|
||||||
|
return $temp_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadModels($LDrawLibrary)
|
||||||
|
{
|
||||||
|
$adapter = new Local($LDrawLibrary);
|
||||||
|
$this->ldraw = new Filesystem($adapter);
|
||||||
|
// $files = $this->ldraw->get('parts')->getContents();
|
||||||
|
|
||||||
|
$files = $this->ldraw->get('parts')->getContents();
|
||||||
|
|
||||||
|
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
|
||||||
|
|
||||||
|
// $finder = new Finder();
|
||||||
|
// $files = $finder->files()->name('*.dat')->depth('== 0')->in(getcwd().DIRECTORY_SEPARATOR.$LDrawLibrary.DIRECTORY_SEPARATOR.'parts');
|
||||||
|
|
||||||
|
$progressBar = new ProgressBar($this->output, count($files));
|
||||||
|
$progressBar->setFormat('very_verbose');
|
||||||
|
$progressBar->setMessage('Loading LDraw library models');
|
||||||
|
$progressBar->setFormat('%message:6s% %current%/%max% [%bar%]%percent:3s%% (%elapsed:6s%/%estimated:-6s%)');
|
||||||
|
$progressBar->start();
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if ($file['type'] == 'file' && $file['extension'] == 'dat') {
|
||||||
|
$header = $this->getPartHeader($file);
|
||||||
|
|
||||||
|
if ($this->fileFilter($header)) {
|
||||||
|
if (null == ($part = $this->em->getRepository(Part::class)->find($header['id']))) {
|
||||||
|
$part = new Part();
|
||||||
|
$part->setId($header['id']);
|
||||||
|
}
|
||||||
|
$part->setName($header['name']);
|
||||||
|
|
||||||
|
if (($category = $this->em->getRepository(Category::class)->findOneBy(['name' => $header['category']])) == null) {
|
||||||
|
$category = new Category();
|
||||||
|
$category->setName($header['category']);
|
||||||
|
}
|
||||||
|
$part->setCategory($category);
|
||||||
|
|
||||||
|
if (($type = $this->em->getRepository(Type::class)->findOneBy(['name' => $header['type']])) == null) {
|
||||||
|
$type = new Type();
|
||||||
|
$type->setName($header['type']);
|
||||||
|
}
|
||||||
|
$part->setType($type);
|
||||||
|
|
||||||
|
if (isset($header['keywords'])) {
|
||||||
|
foreach ($header['keywords'] as $kword) {
|
||||||
|
$kword = trim($kword);
|
||||||
|
if (($keyword = $this->em->getRepository(Keyword::class)->findOneBy(['name' => $kword])) == null) {
|
||||||
|
$keyword = new Keyword();
|
||||||
|
$keyword->setName($kword);
|
||||||
|
}
|
||||||
|
$part->addKeyword($keyword);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($header['print_of_id']) {
|
||||||
|
if (($printParent = $this->em->getRepository(Part::class)->find($header['print_of_id'])) == null) {
|
||||||
|
$printParent = new Part();
|
||||||
|
$printParent->setId($header['print_of_id']);
|
||||||
|
}
|
||||||
|
$part->setPrintOf($printParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($header['alias_of_id']) {
|
||||||
|
if (($aliasParent = $this->em->getRepository(Part::class)->find($header['alias_of_id'])) == null) {
|
||||||
|
$aliasParent = new Part();
|
||||||
|
$aliasParent->setId($header['alias_of_id']);
|
||||||
|
}
|
||||||
|
$part->setAliasOf($aliasParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$header['print_of_id'] && !$header['alias_of_id']) {
|
||||||
|
if (($model = $this->em->getRepository(Model::class)->find($header['id'])) == null) {
|
||||||
|
$model = new Model();
|
||||||
|
$model->setId($header['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$model->setAuthor($header['author']);
|
||||||
|
$model->setModified($header['modified']);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$file = $this->LDViewService->datToStl($file, $this->ldraw)->getPath();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
dump($e);
|
||||||
|
}
|
||||||
|
|
||||||
|
$model->setFile($file);
|
||||||
|
|
||||||
|
$part->setModel($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->em->persist($part);
|
||||||
|
$this->em->flush();
|
||||||
|
$this->em->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$progressBar->advance();
|
||||||
|
}
|
||||||
|
$progressBar->finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fileFilter($header)
|
||||||
|
{
|
||||||
|
if (strpos($header['name'], 'Sticker') !== 0 &&
|
||||||
|
(strpos($header['name'], '~') !== 0 || strpos($header['name'], '~Moved to ') === 0) &&
|
||||||
|
$header['type'] !== 'Subpart') {
|
||||||
|
if (strpos($header['name'], '~Moved to ') === 0) {
|
||||||
|
$filepath = str_replace('\\', DIRECTORY_SEPARATOR, 'parts/'.$header['alias_of_id'].'.dat');
|
||||||
|
|
||||||
|
return $this->fileFilter($this->getPartHeader($this->ldraw->get($filepath)->getMetadata()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getPrinetedParentId($filename)
|
||||||
|
{
|
||||||
|
// nnnPxx, nnnnPxx, nnnnnPxx, nnnaPxx, nnnnaPxx
|
||||||
|
// where (a = alpha, n= numeric, x = alphanumeric)
|
||||||
|
|
||||||
|
if (preg_match('/(^.*)(p[0-9a-z][0-9a-z][0-9a-z]{0,1})$/', $filename, $matches)) {
|
||||||
|
return $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isShortcutPart($filename)
|
||||||
|
{
|
||||||
|
// nnnCnn, nnnnCnn, nnnnnCnn Shortcut assembly of part nnn, nnnn or nnnnn with other parts or formed version of flexible part nnn, nnnn or nnnnn.
|
||||||
|
// nnnCnn-Fn, nnnnCnn-Fn, nnnnnCnn-Fn Positional variant of shortcut assembly of movable parts, comprising part nnn, nnnn or nnnnn with other parts.
|
||||||
|
// where (a = alpha, n= numeric, x = alphanumeric)
|
||||||
|
|
||||||
|
return preg_match('/(^.*)(c[0-9][0-9])(.*)/', $filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAliasParentId($name)
|
||||||
|
{
|
||||||
|
if (preg_match('/^(~Moved to )(.*)$/', $name, $matches)) {
|
||||||
|
return $matches[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAlias($line)
|
||||||
|
{
|
||||||
|
// 1 <colour> x y z a b c d e f g h i <file>
|
||||||
|
|
||||||
|
if (preg_match('/^1(.*) (.*)\.dat$/', $line, $matches)) {
|
||||||
|
return $matches[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getPartHeader($file)
|
||||||
|
{
|
||||||
|
$header = [];
|
||||||
|
|
||||||
|
// $handle = fopen($file->getRealPath(), 'r');
|
||||||
|
|
||||||
|
$handle = $this->ldraw->readStream($file['path']);
|
||||||
|
|
||||||
|
if ($handle) {
|
||||||
|
$firstLine = false;
|
||||||
|
|
||||||
|
while (($line = fgets($handle)) !== false) {
|
||||||
|
$line = trim($line);
|
||||||
|
|
||||||
|
// Comments or META Commands
|
||||||
|
if (strpos($line, '0 ') === 0) {
|
||||||
|
$line = preg_replace('/^0 /', '', $line);
|
||||||
|
|
||||||
|
// 0 <CategoryName> <PartDescription>
|
||||||
|
if (!$firstLine) {
|
||||||
|
$array = explode(' ', trim($line), 2);
|
||||||
|
$header['category'] = isset($array[0]) ? ltrim($array[0], '=_~') : '';
|
||||||
|
$header['name'] = $line;
|
||||||
|
|
||||||
|
$firstLine = true;
|
||||||
|
}
|
||||||
|
// 0 !CATEGORY <CategoryName>
|
||||||
|
elseif (strpos($line, '!CATEGORY ') === 0) {
|
||||||
|
$header['category'] = trim(preg_replace('/^!CATEGORY /', '', $line));
|
||||||
|
}
|
||||||
|
// 0 !KEYWORDS <first keyword>, <second keyword>, ..., <last keyword>
|
||||||
|
elseif (strpos($line, '!KEYWORDS ') === 0) {
|
||||||
|
$header['keywords'] = explode(', ', preg_replace('/^!KEYWORDS /', '', $line));
|
||||||
|
}
|
||||||
|
// 0 Name: <Filename>.dat
|
||||||
|
elseif (strpos($line, 'Name: ') === 0) {
|
||||||
|
$header['id'] = preg_replace('/(^Name: )(.*)(.dat)/', '$2', $line);
|
||||||
|
}
|
||||||
|
// 0 Author: <Realname> [<Username>]
|
||||||
|
elseif (strpos($line, 'Author: ') === 0) {
|
||||||
|
$header['author'] = preg_replace('/^Author: /', '', $line);
|
||||||
|
}
|
||||||
|
// 0 !LDRAW_ORG Part|Subpart|Primitive|48_Primitive|Shortcut (optional qualifier(s)) ORIGINAL|UPDATE YYYY-RR
|
||||||
|
elseif (strpos($line, '!LDRAW_ORG ') === 0) {
|
||||||
|
$type = preg_replace('/(^!LDRAW_ORG )(.*)( UPDATE| ORIGINAL)(.*)/', '$2', $line);
|
||||||
|
$header['type'] = $type;
|
||||||
|
|
||||||
|
// Last modification date in format YYYY-RR
|
||||||
|
$date = preg_replace('/(^!LDRAW_ORG )(.*)( UPDATE | ORIGINAL )(.*)/', '$4', $line);
|
||||||
|
if (preg_match('/^[1-2][0-9]{3}-[0-9]{2}$/', $date)) {
|
||||||
|
$header['modified'] = \DateTime::createFromFormat('Y-m-d H:i:s', $date.'-01 00:00:00');
|
||||||
|
} else {
|
||||||
|
$header['modified'] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif (strpos($line, '1 ') === 0) {
|
||||||
|
if ($header['type'] == 'Part Alias' || $header['type'] == 'Shortcut Physical_Colour' || $header['type'] == 'Shortcut Alias') {
|
||||||
|
// "=" -> Alias name for other part kept for referece - do not include model -> LINK
|
||||||
|
// "_" -> Physical_color - do not include model -> LINK
|
||||||
|
$header['name'] = ltrim($header['name'], '=_');
|
||||||
|
$header['alias_of_id'] = $this->getAlias($line);
|
||||||
|
} elseif ($header['type'] == 'Shortcut') {
|
||||||
|
$header['subparts'][] = $this->getAlias($line);
|
||||||
|
}
|
||||||
|
} elseif ($line != '') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($header['id'])) {
|
||||||
|
$header['print_of_id'] = $this->getPrinetedParentId($header['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($header['name']) && !isset($header['alias_of_id'])) {
|
||||||
|
$header['alias_of_id'] = $this->getAliasParentId($header['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($handle);
|
||||||
|
|
||||||
|
return $header;
|
||||||
|
}
|
||||||
|
throw new LogicException('loadHeader error'); //TODO
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace AppBundle\Command\Loader;
|
namespace AppBundle\Loader;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
use Symfony\Component\Asset\Exception\LogicException;
|
use Symfony\Component\Asset\Exception\LogicException;
|
||||||
@ -8,7 +8,7 @@ use Symfony\Component\Console\Helper\ProgressBar;
|
|||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Debug\Exception\ContextErrorException;
|
use Symfony\Component\Debug\Exception\ContextErrorException;
|
||||||
|
|
||||||
class Loader
|
abstract class Loader
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var EntityManager
|
* @var EntityManager
|
||||||
@ -25,13 +25,23 @@ class Loader
|
|||||||
*/
|
*/
|
||||||
protected $progressBar;
|
protected $progressBar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loader constructor.
|
||||||
|
*
|
||||||
|
* @param EntityManager $em
|
||||||
|
*/
|
||||||
|
public function __construct(EntityManager $em)
|
||||||
|
{
|
||||||
|
$this->em = $em;
|
||||||
|
}
|
||||||
|
|
||||||
public function setOutput(OutputInterface $output)
|
public function setOutput(OutputInterface $output)
|
||||||
{
|
{
|
||||||
$this->output = $output;
|
$this->output = $output;
|
||||||
$this->output->setDecorated(true);
|
$this->output->setDecorated(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function progressCallback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max)
|
protected function progressCallback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max)
|
||||||
{
|
{
|
||||||
switch ($notification_code) {
|
switch ($notification_code) {
|
||||||
case STREAM_NOTIFY_FILE_SIZE_IS:
|
case STREAM_NOTIFY_FILE_SIZE_IS:
|
68
src/AppBundle/Service/LDViewService.php
Normal file
68
src/AppBundle/Service/LDViewService.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AppBundle\Service;
|
||||||
|
|
||||||
|
use League\Flysystem\File;
|
||||||
|
use League\Flysystem\Filesystem;
|
||||||
|
use Symfony\Component\Asset\Exception\LogicException;
|
||||||
|
use Symfony\Component\Process\ProcessBuilder;
|
||||||
|
|
||||||
|
class LDViewService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string LDView binary file path
|
||||||
|
*/
|
||||||
|
private $ldview;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \League\Flysystem\Filesystem
|
||||||
|
*/
|
||||||
|
private $stlStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LDViewService constructor.
|
||||||
|
*
|
||||||
|
* @param string $ldview Path to LDView OSMesa binary file
|
||||||
|
* @param Filesystem $stlStorage Filesystem for generated stl model files
|
||||||
|
*/
|
||||||
|
public function __construct($ldview, $stlStorage)
|
||||||
|
{
|
||||||
|
$this->ldview = $ldview;
|
||||||
|
$this->stlStorage = $stlStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert LDraw model from .dat format to .stl by using LDView
|
||||||
|
* stores created file to $stlStorage filesystem
|
||||||
|
*
|
||||||
|
* @param Filesystem $LDrawDir
|
||||||
|
*
|
||||||
|
* @return File
|
||||||
|
*/
|
||||||
|
public function datToStl($file, $LDrawDir)
|
||||||
|
{
|
||||||
|
$stlFilename = $file['filename'].'.stl';
|
||||||
|
|
||||||
|
if (!$this->stlStorage->has($stlFilename)) {
|
||||||
|
$builder = new ProcessBuilder();
|
||||||
|
$process = $builder
|
||||||
|
->setPrefix($this->ldview)
|
||||||
|
->setArguments([
|
||||||
|
$LDrawDir->getAdapter()->getPathPrefix().$file['path'],
|
||||||
|
'-LDrawDir='.$LDrawDir->getAdapter()->getPathPrefix(),
|
||||||
|
'-ExportFile='.$this->stlStorage->getAdapter()->getPathPrefix().$stlFilename,
|
||||||
|
])
|
||||||
|
->getProcess();
|
||||||
|
|
||||||
|
$process->run();
|
||||||
|
|
||||||
|
if (!$this->stlStorage->has($stlFilename)) {
|
||||||
|
throw new LogicException($file['basename'].': new file not found'); //TODO
|
||||||
|
} elseif (!$process->isSuccessful()) {
|
||||||
|
throw new LogicException($file['basename'].' : '.$process->getOutput()); //TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->stlStorage->get($stlFilename);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user