diff --git a/app/Resources/views/brickset/instructions.html.twig b/app/Resources/views/brickset/instructions.html.twig
index 43c983d..5e64733 100644
--- a/app/Resources/views/brickset/instructions.html.twig
+++ b/app/Resources/views/brickset/instructions.html.twig
@@ -17,7 +17,7 @@
{% for instruction in instructions %}
{{ instruction.description }} |
- {{ utils.bytesToSize( remoteSize(instruction.uRL)) }} |
+ {{ remoteSize(instruction.uRL) | bytesToSize }} |
{{ remoteFilename(instruction.uRL) }} |
{% endfor %}
diff --git a/app/Resources/views/macros/utils.html.twig b/app/Resources/views/macros/utils.html.twig
index 36850dd..e69de29 100644
--- a/app/Resources/views/macros/utils.html.twig
+++ b/app/Resources/views/macros/utils.html.twig
@@ -1,21 +0,0 @@
-{#http://stackoverflow.com/a/15303004#}
-{% macro bytesToSize(bytes) %}
- {% spaceless %}
- {% set kilobyte = 1024 %}
- {% set megabyte = kilobyte * 1024 %}
- {% set gigabyte = megabyte * 1024 %}
- {% set terabyte = gigabyte * 1024 %}
-
- {% if bytes < kilobyte %}
- {{ bytes ~ ' B' }}
- {% elseif bytes < megabyte %}
- {{ (bytes / kilobyte)|number_format(2, '.') ~ ' KB' }}
- {% elseif bytes < gigabyte %}
- {{ (bytes / megabyte)|number_format(2, '.') ~ ' MB' }}
- {% elseif bytes < terabyte %}
- {{ (bytes / gigabyte)|number_format(2, '.') ~ ' GB' }}
- {% else %}
- {{ (bytes / terabyte)|number_format(2, '.') ~ ' TB' }}
- {% endif %}
- {% endspaceless %}
-{% endmacro %}
\ No newline at end of file
diff --git a/app/config/config.yml b/app/config/config.yml
index 9bf88c9..ab7ca80 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -8,7 +8,7 @@ imports:
parameters:
locale: en
# rebrickable csv files root URL (http://rebrickable.com/media/downloads/ or local dir containing csv files)
- rebrickable_csv_url: 'http://rebrickable.com/media/downloads/'
+ rebrickable_downloads_url: 'http://rebrickable.com/media/downloads/'
framework:
#esi: ~
@@ -65,13 +65,13 @@ doctrine:
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
-# Swiftmailer Configuration
-swiftmailer:
- transport: "%mailer_transport%"
- host: "%mailer_host%"
- username: "%mailer_user%"
- password: "%mailer_password%"
- spool: { type: memory }
+## Swiftmailer Configuration
+#swiftmailer:
+# transport: "%mailer_transport%"
+# host: "%mailer_host%"
+# username: "%mailer_user%"
+# password: "%mailer_password%"
+# spool: { type: memory }
knp_menu:
twig:
@@ -97,7 +97,7 @@ liip_imagine:
filesystem_service: oneup_flysystem.media_filesystem
rebrickable:
stream:
- wrapper: 'http://m.rebrickable.com/media/'
+ wrapper: 'http://rebrickable.com/media/'
resolvers:
default:
diff --git a/app/config/service/manager.yml b/app/config/service/manager.yml
deleted file mode 100644
index 9e4a3f5..0000000
--- a/app/config/service/manager.yml
+++ /dev/null
@@ -1 +0,0 @@
-services:
\ No newline at end of file
diff --git a/app/config/service/service.yml b/app/config/service/service.yml
index 7eb05a6..f800491 100644
--- a/app/config/service/service.yml
+++ b/app/config/service/service.yml
@@ -2,15 +2,10 @@ services:
app.twig_extension:
class: AppBundle\Twig\AppExtension
public: false
- arguments: ['@api.manager.rebrickable']
+ arguments: ['@api.manager.rebrickable', '@app.transformer.format']
tags:
- { name: twig.extension }
- app.relation.mapper:
- class: AppBundle\Utils\RelationMapper
- arguments:
- - ['%kernel.root_dir%/Resources/relations']
-
service.renderer.stl:
class: AppBundle\Service\StlRendererService
arguments: ['%kernel.root_dir%/Resources/povray_layout/layout.tmpl', '%povray_bin%','%stl2pov_bin%']
diff --git a/app/config/service/util.yml b/app/config/service/util.yml
new file mode 100644
index 0000000..b044eed
--- /dev/null
+++ b/app/config/service/util.yml
@@ -0,0 +1,8 @@
+services:
+ app.transformer.format:
+ class: AppBundle\Transformer\FormatTransformer
+
+ app.relation.mapper:
+ class: AppBundle\Util\RelationMapper
+ arguments:
+ - ['%kernel.root_dir%/Resources/relations']
diff --git a/app/config/services.yml b/app/config/services.yml
index ed103c2..5125d4d 100644
--- a/app/config/services.yml
+++ b/app/config/services.yml
@@ -2,7 +2,7 @@ imports:
- { resource: service/repository.yml }
- { resource: service/api.yml }
- { resource: service/loader.yml }
- - { resource: service/manager.yml }
+ - { resource: service/util.yml }
- { resource: service/service.yml }
- { resource: service/form.yml }
- { resource: service/menu.yml }
\ No newline at end of file
diff --git a/src/AppBundle/Transformer/FormatTransformer.php b/src/AppBundle/Transformer/FormatTransformer.php
new file mode 100644
index 0000000..0691092
--- /dev/null
+++ b/src/AppBundle/Transformer/FormatTransformer.php
@@ -0,0 +1,18 @@
+rebrickableAPIManager = $rebrickableAPIManager;
+ $this->formatTransformer = $formatTransformer;
}
public function getFilters()
@@ -24,6 +29,7 @@ class AppExtension extends \Twig_Extension
return [
new \Twig_SimpleFilter('partImage', [$this, 'partImage']),
new \Twig_SimpleFilter('setImage', [$this, 'setImage']),
+ new \Twig_SimpleFilter('bytesToSize', [$this, 'bytesToSize']),
];
}
@@ -37,7 +43,7 @@ class AppExtension extends \Twig_Extension
public function partImage($number, $color = null)
{
- return '/parts/ldraw/'.($color ? $color : '-1').'/'.$number.'.png';
+ return '/parts/ldraw/'.($color !== null ? $color : '-1').'/'.$number.'.png';
}
public function setImage($number)
@@ -45,6 +51,10 @@ class AppExtension extends \Twig_Extension
return '/sets/'.strtolower($number).'.jpg';
}
+ public function bytesToSize($bytes, $precision = 2) {
+ return $this->formatTransformer->bytesToSize($bytes, $precision);
+ }
+
public function remoteSize($url)
{
$ch = curl_init($url);
diff --git a/src/AppBundle/Util/LDModelParser.php b/src/AppBundle/Util/LDModelParser.php
new file mode 100644
index 0000000..adcddeb
--- /dev/null
+++ b/src/AppBundle/Util/LDModelParser.php
@@ -0,0 +1,206 @@
+ string
+ * 'name' => string
+ * 'category' => string
+ * 'keywords' => []
+ * 'author' => string
+ * 'modified' => DateTime
+ * 'type' => string
+ * 'subparts' => [],
+ * 'licence' => string
+ * ].
+ *
+ * LDraw.org Standards: Official Library Header Specification (http://www.ldraw.org/article/398.html)
+ *
+ * @throws ErrorParsingLineException
+ *
+ * @return array
+ */
+ public function parse($string)
+ {
+ $model = [
+ 'id' => null,
+ 'name' => null,
+ 'category' => null,
+ 'keywords' => [],
+ 'author' => null,
+ 'modified' => null,
+ 'type' => null,
+ 'subparts' => [],
+ 'parent' => null,
+ 'license' => null,
+ ];
+
+ $firstLine = false;
+ foreach(explode("\n", $string) as $line) {
+ $line = trim($line);
+
+ // Comments or META Commands
+ if (strpos($line, '0 ') === 0) {
+ $line = preg_replace('/^0 /', '', $line);
+
+ // 0
+ if (!$firstLine) {
+ $array = explode(' ', ltrim(trim($line, 2), '=_~'));
+ $model['category'] = isset($array[0]) ? $array[0] : '';
+ $model['name'] = preg_replace('/ {2,}/', ' ', ltrim($line, '=_'));
+
+ $firstLine = true;
+ }
+ // 0 !CATEGORY
+ elseif (strpos($line, '!CATEGORY ') === 0) {
+ $model['category'] = trim(preg_replace('/^!CATEGORY /', '', $line));
+ }
+ // 0 !KEYWORDS , , ...,
+ elseif (strpos($line, '!KEYWORDS ') === 0) {
+ $model['keywords'] = explode(', ', preg_replace('/^!KEYWORDS /', '', $line));
+ }
+ // 0 Name: .dat
+ elseif (strpos($line, 'Name: ') === 0 && !isset($header['id'])) {
+ $model['id'] = preg_replace('/(^Name: )(.*)(.dat)/', '$2', $line);
+ }
+ // 0 Author: []
+ elseif (strpos($line, 'Author: ') === 0) {
+ $model['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);
+
+ $model['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)) {
+ $model['modified'] = \DateTime::createFromFormat('Y-m-d H:i:s', $date.'-01 00:00:00');
+ }
+ }
+ // 0 !LICENSE Redistributable under CCAL version 2.0 : see CAreadme.txt | 0 !LICENSE Not redistributable : see NonCAreadme.txt
+ elseif (strpos($line, '!LICENSE ') === 0) {
+ $model['license'] = preg_replace('/(^!LICENSE )(.*) : (.*)$/', '$2', $line);
+ }
+ } elseif (strpos($line, '1 ') === 0) {
+ $id = strtolower($this->getReferencedModelNumber($line));
+
+ if (isset($model['subparts'][$id])) {
+ $model['subparts'][$id] = $model['subparts'][$id] + 1;
+ } else {
+ $model['subparts'][$id] = 1;
+ }
+ } elseif (!empty($line) && !in_array($line[0], ['2', '3', '4', '5'])) {
+ throw new ErrorParsingLineException($model['id'],$line);
+ }
+ }
+
+ if ($this->isSticker($model['name'], $model['id'])) {
+ $model['type'] = 'Sticker';
+ } elseif (count($model['subparts']) == 1 && in_array($model['type'], ['Part Alias', 'Shortcut Physical_Colour', 'Shortcut Alias', 'Part Physical_Colour'])) {
+ $model['parent'] = array_keys($model['subparts'])[0];
+ } elseif (($parent = $this->getPrintedModelParentNumber($model['id'])) && !in_array($model['type'], ['48_Primitive', '8_Primitive', 'Primitive', 'Subpart'])) {
+ $model['type'] = 'Printed';
+ $model['parent'] = $parent;
+ } elseif ($parent = $this->getObsoleteModelParentNumber($model['name'])) {
+ $model['parent'] = $parent;
+ }
+
+ return $model;
+ }
+
+ /**
+ * Get file reference from part line.
+ *
+ * Line type 1 is a sub-file reference. The generic format is:
+ * 1 x y z a b c d e f g h i
+ *
+ * LDraw.org Standards: File Format 1.0.2 (http://www.ldraw.org/article/218.html)
+ *
+ * @param $line
+ *
+ * @return string|null Filename of referenced part
+ */
+ public function getReferencedModelNumber($line)
+ {
+ $line = ($line);
+
+ if (preg_match('/^1(.*) (.*)\.dat$/', strtolower($line), $matches)) {
+ return str_replace('\\', DIRECTORY_SEPARATOR, $matches[2]);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get printed part parent id.
+ *
+ * part name in format:
+ * nnnPxx, nnnnPxx, nnnnnPxx, nnnaPxx, nnnnaPxx (a = alpha, n= numeric, x = alphanumeric)
+ *
+ * http://www.ldraw.org/library/tracker/ref/numberfaq/
+ *
+ * @param $id
+ *
+ * @return string|null LDraw number of printed part parent
+ */
+ public function getPrintedModelParentNumber($id)
+ {
+ if (preg_match('/(^.*)(p[0-9a-z]{2,3})$/', $id, $matches)) {
+ return $matches[1];
+ }
+
+ return null;
+ }
+
+ /**
+ * Check if part is shortcut part of stricker and part.
+ *
+ * part name in format:
+ * nnnDnn, nnnnDnn, nnnnnDnn (a = alpha, n= numeric, x = alphanumeric)
+ *
+ * http://www.ldraw.org/library/tracker/ref/numberfaq/
+ *
+ * @param $name
+ * @param $number
+ *
+ * @return bool
+ */
+ public function isSticker($name, $number)
+ {
+ if (strpos($name, 'Sticker') === 0) {
+ return true;
+ }
+
+ // Check if in format n*Daa == sticker
+ return preg_match('/(^.*)(d[0-9]{2})$/', $number);
+ }
+
+ /**
+ * Get parent of obsolete part kept for reference.
+ *
+ * part description in format:
+ * ~Moved to {new_number}
+ *
+ * http://www.ldraw.org/article/398.html (Appendix II (02-Oct-06))
+ *
+ * @param $name
+ *
+ * @return string|null Filename of referenced part
+ */
+ public function getObsoleteModelParentNumber($name)
+ {
+ if (preg_match('/^(~Moved to )(.*)$/', $name, $matches)) {
+ return str_replace('\\', DIRECTORY_SEPARATOR, $matches[2]);
+ }
+
+ return null;
+ }
+}
diff --git a/src/AppBundle/Utils/RelationMapper.php b/src/AppBundle/Util/RelationMapper.php
similarity index 98%
rename from src/AppBundle/Utils/RelationMapper.php
rename to src/AppBundle/Util/RelationMapper.php
index 257a8d4..940493a 100644
--- a/src/AppBundle/Utils/RelationMapper.php
+++ b/src/AppBundle/Util/RelationMapper.php
@@ -1,6 +1,6 @@
string
- * 'name' => string
- * 'category' => string
- * 'keywords' => []
- * 'author' => string
- * 'modified' => DateTime
- * 'type' => string
- * 'subparts' => [],
- * 'licence' => string
- * ].
- *
- * LDraw.org Standards: Official Library Header Specification (http://www.ldraw.org/article/398.html)
- *
- * @throws FileNotFoundException|ParseErrorException
- *
- * @return array
- */
- public function parse($file)
- {
- if (file_exists($file)) {
- $model = [
- 'id' => null,
- 'name' => null,
- 'category' => null,
- 'keywords' => [],
- 'author' => null,
- 'modified' => null,
- 'type' => null,
- 'subparts' => [],
- 'parent' => null,
- 'license' => null,
- ];
-
- try {
- $handle = fopen($file, 'r');
-
- 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
- if (!$firstLine) {
- $array = explode(' ', ltrim(trim($line, 2), '=_~'));
- $model['category'] = isset($array[0]) ? $array[0] : '';
- $model['name'] = preg_replace('/ {2,}/', ' ', ltrim($line, '=_'));
-
- $firstLine = true;
- }
- // 0 !CATEGORY
- elseif (strpos($line, '!CATEGORY ') === 0) {
- $model['category'] = trim(preg_replace('/^!CATEGORY /', '', $line));
- }
- // 0 !KEYWORDS , , ...,
- elseif (strpos($line, '!KEYWORDS ') === 0) {
- $model['keywords'] = explode(', ', preg_replace('/^!KEYWORDS /', '', $line));
- }
- // 0 Name: .dat
- elseif (strpos($line, 'Name: ') === 0 && !isset($header['id'])) {
- $model['id'] = preg_replace('/(^Name: )(.*)(.dat)/', '$2', $line);
- }
- // 0 Author: []
- elseif (strpos($line, 'Author: ') === 0) {
- $model['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);
-
- $model['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)) {
- $model['modified'] = \DateTime::createFromFormat('Y-m-d H:i:s', $date.'-01 00:00:00');
- }
- }
- // 0 !LICENSE Redistributable under CCAL version 2.0 : see CAreadme.txt | 0 !LICENSE Not redistributable : see NonCAreadme.txt
- elseif (strpos($line, '!LICENSE ') === 0) {
- $model['license'] = preg_replace('/(^!LICENSE )(.*) : (.*)$/', '$2', $line);
- }
- } elseif (strpos($line, '1 ') === 0) {
- $id = strtolower($this->getReferencedModelNumber($line));
-
- if (isset($model['subparts'][$id])) {
- $model['subparts'][$id] = $model['subparts'][$id] + 1;
- } else {
- $model['subparts'][$id] = 1;
- }
- } elseif (!empty($line) && !in_array($line[0], ['2', '3', '4', '5'])) {
- throw new ErrorParsingLineException($file,$line);
- }
- }
-
- if ($this->isSticker($model['name'], $model['id'])) {
- $model['type'] = 'Sticker';
- } elseif (count($model['subparts']) == 1 && in_array($model['type'], ['Part Alias', 'Shortcut Physical_Colour', 'Shortcut Alias', 'Part Physical_Colour'])) {
- $model['parent'] = array_keys($model['subparts'])[0];
- } elseif (($parent = $this->getPrintedModelParentNumber($model['id'])) && !in_array($model['type'], ['48_Primitive', '8_Primitive', 'Primitive', 'Subpart'])) {
- $model['type'] = 'Printed';
- $model['parent'] = $parent;
- } elseif ($parent = $this->getObsoleteModelParentNumber($model['name'])) {
- $model['type'] = 'Alias';
- $model['parent'] = $parent;
- }
-
- fclose($handle);
-
- return $model;
- }
- } catch (\Exception $exception) {
- throw new ParseErrorException($file);
- }
- }
- throw new FileNotFoundException($file);
- }
-
- /**
- * Get file reference from part line.
- *
- * Line type 1 is a sub-file reference. The generic format is:
- * 1 x y z a b c d e f g h i
- *
- * LDraw.org Standards: File Format 1.0.2 (http://www.ldraw.org/article/218.html)
- *
- * @param $line
- *
- * @return string|null Filename of referenced part
- */
- public function getReferencedModelNumber($line)
- {
- $line = ($line);
-
- if (preg_match('/^1(.*) (.*)\.dat$/', strtolower($line), $matches)) {
- return str_replace('\\', DIRECTORY_SEPARATOR, $matches[2]);
- }
-
- return null;
- }
-
- /**
- * Get printed part parent id.
- *
- * part name in format:
- * nnnPxx, nnnnPxx, nnnnnPxx, nnnaPxx, nnnnaPxx (a = alpha, n= numeric, x = alphanumeric)
- *
- * http://www.ldraw.org/library/tracker/ref/numberfaq/
- *
- * @param $id
- *
- * @return string|null LDraw number of printed part parent
- */
- public function getPrintedModelParentNumber($id)
- {
- if (preg_match('/(^.*)(p[0-9a-z]{2,3})$/', $id, $matches)) {
- return $matches[1];
- }
-
- return null;
- }
-
- /**
- * Check if part is shortcut part of stricker and part.
- *
- * part name in format:
- * nnnDnn, nnnnDnn, nnnnnDnn (a = alpha, n= numeric, x = alphanumeric)
- *
- * http://www.ldraw.org/library/tracker/ref/numberfaq/
- *
- * @param $name
- * @param $number
- *
- * @return bool
- */
- public function isSticker($name, $number)
- {
- if (strpos($name, 'Sticker') === 0) {
- return true;
- }
-
- // Check if in format n*Daa == sticker
- return preg_match('/(^.*)(d[0-9]{2})$/', $number);
- }
-
- /**
- * Get parent of obsolete part kept for reference.
- *
- * part description in format:
- * ~Moved to {new_number}
- *
- * http://www.ldraw.org/article/398.html (Appendix II (02-Oct-06))
- *
- * @param $name
- *
- * @return string|null Filename of referenced part
- */
- public function getObsoleteModelParentNumber($name)
- {
- if (preg_match('/^(~Moved to )(.*)$/', $name, $matches)) {
- return str_replace('\\', DIRECTORY_SEPARATOR, $matches[2]);
- }
-
- return null;
- }
-}