mirror of
https://github.com/ToxicCrack/PrintABrick.git
synced 2025-05-21 06:30:10 -07:00
Merged branch feat/ldraw-loader into dev
This commit is contained in:
commit
0b589ba2ca
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,3 +18,4 @@
|
||||
/node_modules/
|
||||
/app/Resources/assets/semantic/dist
|
||||
/web/resources/
|
||||
.php_cs.cache
|
||||
|
18
.php_cs
Normal file
18
.php_cs
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->in(__DIR__.'/src');
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setRules([
|
||||
'@Symfony' => true,
|
||||
'combine_consecutive_unsets' => true,
|
||||
'linebreak_after_opening_tag' => true,
|
||||
'no_multiline_whitespace_before_semicolons' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_useless_return' => true,
|
||||
'ordered_imports' => true,
|
||||
'phpdoc_order' => true,
|
||||
'array_syntax' => array('syntax' => 'short'),
|
||||
])
|
||||
->setFinder($finder);
|
12
README.md
12
README.md
@ -15,3 +15,15 @@ For full requirements see Symfony 3.2 [docs](http://symfony.com/doc/3.2/referenc
|
||||
|
||||
###Installing
|
||||
|
||||
####Back-end
|
||||
1. Make sure your system meets the application requirements
|
||||
2. Install dependencies via [Composer](https://getcomposer.org/), `$ composer install`
|
||||
|
||||
####Front-end
|
||||
1. Install dependencies via [npm](https://www.npmjs.com/), `$ npm install`
|
||||
2. Compile assets by running [Gulp](http://gulpjs.com/) default task, `$ gulp default`
|
||||
|
||||
####Database
|
||||
1. Set application parameters in *app/config/parameters.yml*
|
||||
2. Generate empty database by running command `$ php bin/console doctrine:database:create`
|
||||
|
@ -17,6 +17,7 @@ class AppKernel extends Kernel
|
||||
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
|
||||
new AppBundle\AppBundle(),
|
||||
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
|
||||
new Oneup\FlysystemBundle\OneupFlysystemBundle(),
|
||||
];
|
||||
|
||||
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
|
||||
|
92
app/Resources/assets/javascripts/ModelViewer.js
Normal file
92
app/Resources/assets/javascripts/ModelViewer.js
Normal file
@ -0,0 +1,92 @@
|
||||
ModelViewer = function() {
|
||||
var container;
|
||||
var camera, scene, cameraTarget, renderer, controls, object;
|
||||
var width, height;
|
||||
|
||||
this.init = function(containerId) {
|
||||
container = document.getElementById(containerId);
|
||||
|
||||
if (document.defaultView && document.defaultView.getComputedStyle) {
|
||||
width = parseFloat(document.defaultView.getComputedStyle(container,null).getPropertyValue('width'));
|
||||
height = parseFloat(document.defaultView.getComputedStyle(container,null).getPropertyValue('height'));
|
||||
} else {
|
||||
width = parseFloat(container.currentStyle.width);
|
||||
height = parseFloat(container.currentStyle.height);
|
||||
}
|
||||
|
||||
|
||||
camera = new THREE.PerspectiveCamera(45, width/height, 0.1, 1000);
|
||||
camera.position.set(-2, 2, 0.8);
|
||||
camera.lookAt(new THREE.Vector3(0, 3, 0));
|
||||
|
||||
scene = new THREE.Scene();
|
||||
scene.fog = new THREE.FogExp2(0x000000, 0.001);
|
||||
|
||||
|
||||
var grid = new THREE.GridHelper( 30, 70 );
|
||||
grid.position.set(30/70,-0.5,30/70);
|
||||
scene.add( grid );
|
||||
|
||||
// Lights
|
||||
|
||||
light = new THREE.DirectionalLight( 0xffffff );
|
||||
light.position.set( 1, 1, 1 );
|
||||
scene.add( light );
|
||||
|
||||
light = new THREE.DirectionalLight( 0x002288 );
|
||||
light.position.set( -1, -1, -1 );
|
||||
scene.add( light );
|
||||
|
||||
|
||||
scene.add( new THREE.AmbientLight( 0xf0f0f0 ));
|
||||
scene.background = new THREE.Color( 0x000000 );
|
||||
|
||||
// renderer
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setClearColor( scene.fog.color );
|
||||
renderer.setPixelRatio( window.devicePixelRatio );
|
||||
renderer.setSize( width, height );
|
||||
renderer.gammaInput = true;
|
||||
renderer.gammaOutput = true;
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.shadowMap.renderReverseSided = false;
|
||||
|
||||
container.appendChild(renderer.domElement);
|
||||
|
||||
controls = new THREE.OrbitControls( camera, renderer.domElement );
|
||||
controls.addEventListener( 'change', this.render ); // add this only if there is no animation loop (requestAnimationFrame)
|
||||
// controls.enableDamping = true;
|
||||
// controls.dampingFactor = 0.25;
|
||||
controls.enableZoom = true;
|
||||
|
||||
};
|
||||
|
||||
this.loadStl = function(model) {
|
||||
var loader = new THREE.STLLoader();
|
||||
loader.load(model, function (geometry) {
|
||||
var material = new THREE.MeshPhongMaterial({color: 0xaaaaaa, shininess:200, specular: 0x333333, shading: THREE.FlatShading});
|
||||
|
||||
var mesh = new THREE.Mesh(geometry, material);
|
||||
mesh.position.set(0, 0.5, 0);
|
||||
mesh.rotation.set(Math.PI, 0, 0);
|
||||
mesh.castShadow = true;
|
||||
mesh.receiveShadow = true;
|
||||
scene.add(mesh);
|
||||
|
||||
renderer.render(scene, camera);
|
||||
});
|
||||
};
|
||||
|
||||
this.animate = function() {
|
||||
|
||||
requestAnimationFrame( this.animate );
|
||||
|
||||
controls.update(); // required if controls.enableDamping = true, or if controls.autoRotate = true
|
||||
|
||||
this.render();
|
||||
};
|
||||
|
||||
this.render = function() {
|
||||
renderer.render(scene, camera);
|
||||
};
|
||||
};
|
@ -1,491 +0,0 @@
|
||||
/**
|
||||
* @author aleeper / http://adamleeper.com/
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author gero3 / https://github.com/gero3
|
||||
*
|
||||
* Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
|
||||
*
|
||||
* Supports both binary and ASCII encoded files, with automatic detection of type.
|
||||
*
|
||||
* Limitations:
|
||||
* Binary decoding supports "Magics" color format (http://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL).
|
||||
* There is perhaps some question as to how valid it is to always assume little-endian-ness.
|
||||
* ASCII decoding assumes file is UTF-8. Seems to work for the examples...
|
||||
*
|
||||
* Usage:
|
||||
* var loader = new THREE.STLLoader();
|
||||
* loader.load( './models/stl/slotted_disk.stl', function ( geometry ) {
|
||||
* scene.add( new THREE.Mesh( geometry ) );
|
||||
* });
|
||||
*
|
||||
* For binary STLs geometry might contain colors for vertices. To use it:
|
||||
* // use the same code to load STL as above
|
||||
* if (geometry.hasColors) {
|
||||
* material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
|
||||
* } else { .... }
|
||||
* var mesh = new THREE.Mesh( geometry, material );
|
||||
*/
|
||||
|
||||
|
||||
THREE.STLLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.STLLoader.prototype = {
|
||||
|
||||
constructor: THREE.STLLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.XHRLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data ) {
|
||||
|
||||
var isBinary = function () {
|
||||
|
||||
var expect, face_size, n_faces, reader;
|
||||
reader = new DataView( binData );
|
||||
face_size = ( 32 / 8 * 3 ) + ( ( 32 / 8 * 3 ) * 3 ) + ( 16 / 8 );
|
||||
n_faces = reader.getUint32( 80, true );
|
||||
expect = 80 + ( 32 / 8 ) + ( n_faces * face_size );
|
||||
|
||||
if ( expect === reader.byteLength ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// some binary files will have different size from expected,
|
||||
// checking characters higher than ASCII to confirm is binary
|
||||
var fileLength = reader.byteLength;
|
||||
for ( var index = 0; index < fileLength; index ++ ) {
|
||||
|
||||
if ( reader.getUint8( index, false ) > 127 ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
var binData = this.ensureBinary( data );
|
||||
|
||||
return isBinary()
|
||||
? this.parseBinary( binData )
|
||||
: this.parseASCII( this.ensureString( data ) );
|
||||
|
||||
},
|
||||
|
||||
parseBinary: function ( data ) {
|
||||
|
||||
var reader = new DataView( data );
|
||||
var faces = reader.getUint32( 80, true );
|
||||
|
||||
var r, g, b, hasColors = false, colors;
|
||||
var defaultR, defaultG, defaultB, alpha;
|
||||
|
||||
// process STL header
|
||||
// check for default color in header ("COLOR=rgba" sequence).
|
||||
|
||||
for ( var index = 0; index < 80 - 10; index ++ ) {
|
||||
|
||||
if ( ( reader.getUint32( index, false ) == 0x434F4C4F /*COLO*/ ) &&
|
||||
( reader.getUint8( index + 4 ) == 0x52 /*'R'*/ ) &&
|
||||
( reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) ) {
|
||||
|
||||
hasColors = true;
|
||||
colors = new Float32Array( faces * 3 * 3 );
|
||||
|
||||
defaultR = reader.getUint8( index + 6 ) / 255;
|
||||
defaultG = reader.getUint8( index + 7 ) / 255;
|
||||
defaultB = reader.getUint8( index + 8 ) / 255;
|
||||
alpha = reader.getUint8( index + 9 ) / 255;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var dataOffset = 84;
|
||||
var faceLength = 12 * 4 + 2;
|
||||
|
||||
var offset = 0;
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
var vertices = new Float32Array( faces * 3 * 3 );
|
||||
var normals = new Float32Array( faces * 3 * 3 );
|
||||
|
||||
for ( var face = 0; face < faces; face ++ ) {
|
||||
|
||||
var start = dataOffset + face * faceLength;
|
||||
var normalX = reader.getFloat32( start, true );
|
||||
var normalY = reader.getFloat32( start + 4, true );
|
||||
var normalZ = reader.getFloat32( start + 8, true );
|
||||
|
||||
if ( hasColors ) {
|
||||
|
||||
var packedColor = reader.getUint16( start + 48, true );
|
||||
|
||||
if ( ( packedColor & 0x8000 ) === 0 ) {
|
||||
|
||||
// facet has its own unique color
|
||||
|
||||
r = ( packedColor & 0x1F ) / 31;
|
||||
g = ( ( packedColor >> 5 ) & 0x1F ) / 31;
|
||||
b = ( ( packedColor >> 10 ) & 0x1F ) / 31;
|
||||
|
||||
} else {
|
||||
|
||||
r = defaultR;
|
||||
g = defaultG;
|
||||
b = defaultB;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 1; i <= 3; i ++ ) {
|
||||
|
||||
var vertexstart = start + i * 12;
|
||||
|
||||
vertices[ offset ] = reader.getFloat32( vertexstart, true );
|
||||
vertices[ offset + 1 ] = reader.getFloat32( vertexstart + 4, true );
|
||||
vertices[ offset + 2 ] = reader.getFloat32( vertexstart + 8, true );
|
||||
|
||||
normals[ offset ] = normalX;
|
||||
normals[ offset + 1 ] = normalY;
|
||||
normals[ offset + 2 ] = normalZ;
|
||||
|
||||
if ( hasColors ) {
|
||||
|
||||
colors[ offset ] = r;
|
||||
colors[ offset + 1 ] = g;
|
||||
colors[ offset + 2 ] = b;
|
||||
|
||||
}
|
||||
|
||||
offset += 3;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
|
||||
geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
|
||||
|
||||
if ( hasColors ) {
|
||||
|
||||
geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
|
||||
geometry.hasColors = true;
|
||||
geometry.alpha = alpha;
|
||||
|
||||
}
|
||||
|
||||
return geometry;
|
||||
|
||||
},
|
||||
|
||||
parseASCII: function ( data ) {
|
||||
|
||||
var geometry, length, normal, patternFace, patternNormal, patternVertex, result, text;
|
||||
geometry = new THREE.Geometry();
|
||||
patternFace = /facet([\s\S]*?)endfacet/g;
|
||||
|
||||
while ( ( result = patternFace.exec( data ) ) !== null ) {
|
||||
|
||||
text = result[ 0 ];
|
||||
patternNormal = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
|
||||
|
||||
while ( ( result = patternNormal.exec( text ) ) !== null ) {
|
||||
|
||||
normal = new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) );
|
||||
|
||||
}
|
||||
|
||||
patternVertex = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
|
||||
|
||||
while ( ( result = patternVertex.exec( text ) ) !== null ) {
|
||||
|
||||
geometry.vertices.push( new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) ) );
|
||||
|
||||
}
|
||||
|
||||
length = geometry.vertices.length;
|
||||
|
||||
geometry.faces.push( new THREE.Face3( length - 3, length - 2, length - 1, normal ) );
|
||||
|
||||
}
|
||||
|
||||
geometry.computeBoundingBox();
|
||||
geometry.computeBoundingSphere();
|
||||
|
||||
return geometry;
|
||||
|
||||
},
|
||||
|
||||
ensureString: function ( buf ) {
|
||||
|
||||
if ( typeof buf !== "string" ) {
|
||||
|
||||
var array_buffer = new Uint8Array( buf );
|
||||
var strArray = [];
|
||||
for ( var i = 0; i < buf.byteLength; i ++ ) {
|
||||
|
||||
strArray.push(String.fromCharCode( array_buffer[ i ] )); // implicitly assumes little-endian
|
||||
|
||||
}
|
||||
return strArray.join('');
|
||||
|
||||
} else {
|
||||
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
ensureBinary: function ( buf ) {
|
||||
|
||||
if ( typeof buf === "string" ) {
|
||||
|
||||
var array_buffer = new Uint8Array( buf.length );
|
||||
for ( var i = 0; i < buf.length; i ++ ) {
|
||||
|
||||
array_buffer[ i ] = buf.charCodeAt( i ) & 0xff; // implicitly assumes little-endian
|
||||
|
||||
}
|
||||
return array_buffer.buffer || array_buffer;
|
||||
|
||||
} else {
|
||||
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if ( typeof DataView === 'undefined' ) {
|
||||
|
||||
DataView = function( buffer, byteOffset, byteLength ) {
|
||||
|
||||
this.buffer = buffer;
|
||||
this.byteOffset = byteOffset || 0;
|
||||
this.byteLength = byteLength || buffer.byteLength || buffer.length;
|
||||
this._isString = typeof buffer === "string";
|
||||
|
||||
};
|
||||
|
||||
DataView.prototype = {
|
||||
|
||||
_getCharCodes: function( buffer, start, length ) {
|
||||
|
||||
start = start || 0;
|
||||
length = length || buffer.length;
|
||||
var end = start + length;
|
||||
var codes = [];
|
||||
for ( var i = start; i < end; i ++ ) {
|
||||
|
||||
codes.push( buffer.charCodeAt( i ) & 0xff );
|
||||
|
||||
}
|
||||
return codes;
|
||||
|
||||
},
|
||||
|
||||
_getBytes: function ( length, byteOffset, littleEndian ) {
|
||||
|
||||
var result;
|
||||
|
||||
// Handle the lack of endianness
|
||||
if ( littleEndian === undefined ) {
|
||||
|
||||
littleEndian = this._littleEndian;
|
||||
|
||||
}
|
||||
|
||||
// Handle the lack of byteOffset
|
||||
if ( byteOffset === undefined ) {
|
||||
|
||||
byteOffset = this.byteOffset;
|
||||
|
||||
} else {
|
||||
|
||||
byteOffset = this.byteOffset + byteOffset;
|
||||
|
||||
}
|
||||
|
||||
if ( length === undefined ) {
|
||||
|
||||
length = this.byteLength - byteOffset;
|
||||
|
||||
}
|
||||
|
||||
// Error Checking
|
||||
if ( typeof byteOffset !== 'number' ) {
|
||||
|
||||
throw new TypeError( 'DataView byteOffset is not a number' );
|
||||
|
||||
}
|
||||
|
||||
if ( length < 0 || byteOffset + length > this.byteLength ) {
|
||||
|
||||
throw new Error( 'DataView length or (byteOffset+length) value is out of bounds' );
|
||||
|
||||
}
|
||||
|
||||
if ( this.isString ) {
|
||||
|
||||
result = this._getCharCodes( this.buffer, byteOffset, byteOffset + length );
|
||||
|
||||
} else {
|
||||
|
||||
result = this.buffer.slice( byteOffset, byteOffset + length );
|
||||
|
||||
}
|
||||
|
||||
if ( ! littleEndian && length > 1 ) {
|
||||
|
||||
if ( Array.isArray( result ) === false ) {
|
||||
|
||||
result = Array.prototype.slice.call( result );
|
||||
|
||||
}
|
||||
|
||||
result.reverse();
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
},
|
||||
|
||||
// Compatibility functions on a String Buffer
|
||||
|
||||
getFloat64: function ( byteOffset, littleEndian ) {
|
||||
|
||||
var b = this._getBytes( 8, byteOffset, littleEndian ),
|
||||
|
||||
sign = 1 - ( 2 * ( b[ 7 ] >> 7 ) ),
|
||||
exponent = ( ( ( ( b[ 7 ] << 1 ) & 0xff ) << 3 ) | ( b[ 6 ] >> 4 ) ) - ( ( 1 << 10 ) - 1 ),
|
||||
|
||||
// Binary operators such as | and << operate on 32 bit values, using + and Math.pow(2) instead
|
||||
mantissa = ( ( b[ 6 ] & 0x0f ) * Math.pow( 2, 48 ) ) + ( b[ 5 ] * Math.pow( 2, 40 ) ) + ( b[ 4 ] * Math.pow( 2, 32 ) ) +
|
||||
( b[ 3 ] * Math.pow( 2, 24 ) ) + ( b[ 2 ] * Math.pow( 2, 16 ) ) + ( b[ 1 ] * Math.pow( 2, 8 ) ) + b[ 0 ];
|
||||
|
||||
if ( exponent === 1024 ) {
|
||||
|
||||
if ( mantissa !== 0 ) {
|
||||
|
||||
return NaN;
|
||||
|
||||
} else {
|
||||
|
||||
return sign * Infinity;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( exponent === - 1023 ) {
|
||||
|
||||
// Denormalized
|
||||
return sign * mantissa * Math.pow( 2, - 1022 - 52 );
|
||||
|
||||
}
|
||||
|
||||
return sign * ( 1 + mantissa * Math.pow( 2, - 52 ) ) * Math.pow( 2, exponent );
|
||||
|
||||
},
|
||||
|
||||
getFloat32: function ( byteOffset, littleEndian ) {
|
||||
|
||||
var b = this._getBytes( 4, byteOffset, littleEndian ),
|
||||
|
||||
sign = 1 - ( 2 * ( b[ 3 ] >> 7 ) ),
|
||||
exponent = ( ( ( b[ 3 ] << 1 ) & 0xff ) | ( b[ 2 ] >> 7 ) ) - 127,
|
||||
mantissa = ( ( b[ 2 ] & 0x7f ) << 16 ) | ( b[ 1 ] << 8 ) | b[ 0 ];
|
||||
|
||||
if ( exponent === 128 ) {
|
||||
|
||||
if ( mantissa !== 0 ) {
|
||||
|
||||
return NaN;
|
||||
|
||||
} else {
|
||||
|
||||
return sign * Infinity;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( exponent === - 127 ) {
|
||||
|
||||
// Denormalized
|
||||
return sign * mantissa * Math.pow( 2, - 126 - 23 );
|
||||
|
||||
}
|
||||
|
||||
return sign * ( 1 + mantissa * Math.pow( 2, - 23 ) ) * Math.pow( 2, exponent );
|
||||
|
||||
},
|
||||
|
||||
getInt32: function ( byteOffset, littleEndian ) {
|
||||
|
||||
var b = this._getBytes( 4, byteOffset, littleEndian );
|
||||
return ( b[ 3 ] << 24 ) | ( b[ 2 ] << 16 ) | ( b[ 1 ] << 8 ) | b[ 0 ];
|
||||
|
||||
},
|
||||
|
||||
getUint32: function ( byteOffset, littleEndian ) {
|
||||
|
||||
return this.getInt32( byteOffset, littleEndian ) >>> 0;
|
||||
|
||||
},
|
||||
|
||||
getInt16: function ( byteOffset, littleEndian ) {
|
||||
|
||||
return ( this.getUint16( byteOffset, littleEndian ) << 16 ) >> 16;
|
||||
|
||||
},
|
||||
|
||||
getUint16: function ( byteOffset, littleEndian ) {
|
||||
|
||||
var b = this._getBytes( 2, byteOffset, littleEndian );
|
||||
return ( b[ 1 ] << 8 ) | b[ 0 ];
|
||||
|
||||
},
|
||||
|
||||
getInt8: function ( byteOffset ) {
|
||||
|
||||
return ( this.getUint8( byteOffset ) << 24 ) >> 24;
|
||||
|
||||
},
|
||||
|
||||
getUint8: function ( byteOffset ) {
|
||||
|
||||
return this._getBytes( 1, byteOffset )[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -1,76 +1,6 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<div id="welcome">
|
||||
<h1><span>Welcome to</span> Symfony {{ constant('Symfony\\Component\\HttpKernel\\Kernel::VERSION') }}</h1>
|
||||
</div>
|
||||
|
||||
<div id="status">
|
||||
<p>
|
||||
<svg id="icon-status" width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68z" fill="#759E1A"/></svg>
|
||||
|
||||
Your application is now ready. You can start working on it at:
|
||||
<code>{{ base_dir }}</code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="next">
|
||||
<h2>What's next?</h2>
|
||||
<p>
|
||||
<svg id="icon-book" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="-12.5 9 64 64" enable-background="new -12.5 9 64 64" xml:space="preserve">
|
||||
<path fill="#AAA" d="M6.8,40.8c2.4,0.8,4.5-0.7,4.9-2.5c0.2-1.2-0.3-2.1-1.3-3.2l-0.8-0.8c-0.4-0.5-0.6-1.3-0.2-1.9
|
||||
c0.4-0.5,0.9-0.8,1.8-0.5c1.3,0.4,1.9,1.3,2.9,2.2c-0.4,1.4-0.7,2.9-0.9,4.2l-0.2,1c-0.7,4-1.3,6.2-2.7,7.5
|
||||
c-0.3,0.3-0.7,0.5-1.3,0.6c-0.3,0-0.4-0.3-0.4-0.3c0-0.3,0.2-0.3,0.3-0.4c0.2-0.1,0.5-0.3,0.4-0.8c0-0.7-0.6-1.3-1.3-1.3
|
||||
c-0.6,0-1.4,0.6-1.4,1.7s1,1.9,2.4,1.8c0.8,0,2.5-0.3,4.2-2.5c2-2.5,2.5-5.4,2.9-7.4l0.5-2.8c0.3,0,0.5,0.1,0.8,0.1
|
||||
c2.4,0.1,3.7-1.3,3.7-2.3c0-0.6-0.3-1.2-0.9-1.2c-0.4,0-0.8,0.3-1,0.8c-0.1,0.6,0.8,1.1,0.1,1.5c-0.5,0.3-1.4,0.6-2.7,0.4l0.3-1.3
|
||||
c0.5-2.6,1-5.7,3.2-5.8c0.2,0,0.8,0,0.8,0.4c0,0.2,0,0.2-0.2,0.5c-0.2,0.3-0.3,0.4-0.2,0.7c0,0.7,0.5,1.1,1.2,1.1
|
||||
c0.9,0,1.2-1,1.2-1.4c0-1.2-1.2-1.8-2.6-1.8c-1.5,0.1-2.8,0.9-3.7,2.1c-1.1,1.3-1.8,2.9-2.3,4.5c-0.9-0.8-1.6-1.8-3.1-2.3
|
||||
c-1.1-0.7-2.3-0.5-3.4,0.3c-0.5,0.4-0.8,1-1,1.6c-0.4,1.5,0.4,2.9,0.8,3.4l0.9,1c0.2,0.2,0.6,0.8,0.4,1.5c-0.3,0.8-1.2,1.3-2.1,1
|
||||
c-0.4-0.2-1-0.5-0.9-0.9c0.1-0.2,0.2-0.3,0.3-0.5s0.1-0.3,0.1-0.3c0.2-0.6-0.1-1.4-0.7-1.6c-0.6-0.2-1.2,0-1.3,0.8
|
||||
C4.3,38.4,4.7,40,6.8,40.8z M46.1,20.9c0-4.2-3.2-7.5-7.1-7.5h-3.8C34.8,10.8,32.7,9,30.2,9L-2.3,9.1c-2.8,0.1-4.9,2.4-4.9,5.4
|
||||
L-7,58.6c0,4.8,8.1,13.9,11.6,14.1l34.7-0.1c3.9,0,7-3.4,7-7.6L46.1,20.9z M-0.3,36.4c0-8.6,6.5-15.6,14.5-15.6
|
||||
c8,0,14.5,7,14.5,15.6S22.1,52,14.2,52C6.1,52-0.3,45-0.3,36.4z M42.1,65.1c0,1.8-1.5,3.1-3.1,3.1H4.6c-0.7,0-3-1.8-4.5-4.4h30.4
|
||||
c2.8,0,5-2.4,5-5.4V17.9h3.7c1.6,0,2.9,1.4,2.9,3.1V65.1L42.1,65.1z"/>
|
||||
</svg>
|
||||
|
||||
Read the documentation to learn
|
||||
<a href="http://symfony.com/doc/{{ constant('Symfony\\Component\\HttpKernel\\Kernel::VERSION')[:3] }}/book/page_creation.html">
|
||||
How to create your first page in Symfony
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block stylesheets %}
|
||||
<style>
|
||||
body { background: #F5F5F5; font: 18px/1.5 sans-serif; }
|
||||
h1, h2 { line-height: 1.2; margin: 0 0 .5em; }
|
||||
h1 { font-size: 36px; }
|
||||
h2 { font-size: 21px; margin-bottom: 1em; }
|
||||
p { margin: 0 0 1em 0; }
|
||||
a { color: #0000F0; }
|
||||
a:hover { text-decoration: none; }
|
||||
code { background: #F5F5F5; max-width: 100px; padding: 2px 6px; word-wrap: break-word; }
|
||||
#wrapper { background: #FFF; margin: 1em auto; max-width: 800px; width: 95%; }
|
||||
#container { padding: 2em; }
|
||||
#welcome, #status { margin-bottom: 2em; }
|
||||
#welcome h1 span { display: block; font-size: 75%; }
|
||||
#icon-status, #icon-book { float: left; height: 64px; margin-right: 1em; margin-top: -4px; width: 64px; }
|
||||
#icon-book { display: none; }
|
||||
|
||||
@media (min-width: 768px) {
|
||||
#wrapper { width: 80%; margin: 2em auto; }
|
||||
#icon-book { display: inline-block; }
|
||||
#status a, #next a { display: block; }
|
||||
|
||||
@-webkit-keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
|
||||
@keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
|
||||
.sf-toolbar { opacity: 0; -webkit-animation: fade-in 1s .2s forwards; animation: fade-in 1s .2s forwards;}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
33
app/Resources/views/part/detail.html.twig
Normal file
33
app/Resources/views/part/detail.html.twig
Normal file
@ -0,0 +1,33 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
{{ dump(part) }}
|
||||
|
||||
{{ dump(localPart) }}
|
||||
|
||||
<div id="model" style="height: 300px; width: 300px; padding: 5px; display: inline-block"></div>
|
||||
<img src="{{ part.partImgUrl }}">
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
|
||||
<script type="text/javascript" src="{{ asset('resources/js/three.js') }}"></script>
|
||||
|
||||
<script type="text/javascript" src="{{ asset('resources/js/OrbitControls.js') }}"></script>
|
||||
|
||||
<script type="text/javascript" src="{{ asset('resources/js/ModelViewer.js') }}"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.onload = function() {
|
||||
modelView = new ModelViewer();
|
||||
modelView.init('model');
|
||||
{% if localPart.model is defined %}
|
||||
modelView.loadStl('{{ path('download_model', {'id' : localPart.model.id })}}');
|
||||
{% endif %}
|
||||
modelView.render();
|
||||
};
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,7 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
{{ dump(part) }}
|
||||
|
||||
{% endblock %}
|
@ -7,6 +7,11 @@ imports:
|
||||
# http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
|
||||
parameters:
|
||||
locale: en
|
||||
rebrickable_url:
|
||||
pieces: 'http://rebrickable.com/files/pieces.csv.gz'
|
||||
sets: 'http://rebrickable.com/files/sets.csv.gz'
|
||||
set_pieces: 'http://rebrickable.com/files/set_pieces.csv.gz'
|
||||
ldraw_url: 'http://www.ldraw.org/library/updates/completeCA.zip'
|
||||
|
||||
framework:
|
||||
#esi: ~
|
||||
@ -76,3 +81,12 @@ knp_menu:
|
||||
templating: false
|
||||
# the renderer to use, list is also available by default
|
||||
default_renderer: twig
|
||||
|
||||
oneup_flysystem:
|
||||
adapters:
|
||||
ldraw_adapter:
|
||||
local:
|
||||
directory: "%kernel.root_dir%/../var/data/ldraw"
|
||||
filesystems:
|
||||
ldraw:
|
||||
adapter: ldraw_adapter
|
@ -13,12 +13,16 @@ services:
|
||||
class: AppBundle\Api\Manager\RebrickableManager
|
||||
arguments: ['@client.rebrickable']
|
||||
|
||||
app.collection_service:
|
||||
sevice.collection:
|
||||
class: AppBundle\Service\CollectionService
|
||||
arguments: ['@doctrine.orm.entity_manager', '@manager.brickset','@manager.rebrickable']
|
||||
app.model_loader_service:
|
||||
class: AppBundle\Service\ModelLoaderService
|
||||
arguments: ['@doctrine.orm.entity_manager','%kernel.root_dir%/../var/data/LDrawLibrary', '@manager.rebrickable']
|
||||
|
||||
loader.rebrickable:
|
||||
class: AppBundle\Command\Loader\RebrickableLoader
|
||||
arguments: ['@doctrine.orm.entity_manager', '@manager.rebrickable', '%rebrickable_url%' ]
|
||||
loader.ldraw:
|
||||
class: AppBundle\Command\Loader\LDrawLoader
|
||||
arguments: ['@doctrine.orm.entity_manager', '%kernel.root_dir%/../bin/ldview', '@oneup_flysystem.ldraw_filesystem', '%ldraw_url%']
|
||||
|
||||
app.form.filter_set:
|
||||
class: AppBundle\Form\FilterSetType
|
||||
|
BIN
bin/ldview
Normal file
BIN
bin/ldview
Normal file
Binary file not shown.
30
bin/php-cs-fixer-hook.sh
Normal file
30
bin/php-cs-fixer-hook.sh
Normal file
@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
# To use this hook you need to install php-cs-fixer
|
||||
# Copy this file to ./git/hooks/pre-commit to get it working.
|
||||
|
||||
ROOT=""
|
||||
|
||||
echo "php-cs-fixer pre commit hook start"
|
||||
|
||||
PHP_CS_FIXER="vendor/bin/php-cs-fixer"
|
||||
HAS_PHP_CS_FIXER=false
|
||||
|
||||
if [ -x vendor/bin/php-cs-fixer ]; then
|
||||
HAS_PHP_CS_FIXER=true
|
||||
fi
|
||||
|
||||
if $HAS_PHP_CS_FIXER; then
|
||||
git status --porcelain | grep -e '^[AM]\(.*\).php$' | cut -c 3- | while read line; do
|
||||
$PHP_CS_FIXER fix --config=$ROOT/.php_cs --verbose "$line";
|
||||
git add "$line";
|
||||
done
|
||||
else
|
||||
echo ""
|
||||
echo "Please install php-cs-fixer, e.g.:"
|
||||
echo ""
|
||||
echo " composer require --dev friendsofphp/php-cs-fixer"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "php-cs-fixer pre commit hook finish"
|
@ -23,11 +23,13 @@
|
||||
"sensio/framework-extra-bundle": "^3.0.2",
|
||||
"incenteev/composer-parameter-handler": "^2.0",
|
||||
"guzzlehttp/guzzle": "^6.2",
|
||||
"knplabs/knp-menu-bundle": "^2.0"
|
||||
"knplabs/knp-menu-bundle": "^2.0",
|
||||
"oneup/flysystem-bundle": "^1.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"sensio/generator-bundle": "^3.0",
|
||||
"symfony/phpunit-bridge": "^3.0"
|
||||
"symfony/phpunit-bridge": "^3.0",
|
||||
"friendsofphp/php-cs-fixer": "^2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"symfony-scripts": [
|
||||
|
418
composer.lock
generated
418
composer.lock
generated
@ -4,8 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "5ce1afc2e13970cdfddedeb899ae01a1",
|
||||
"content-hash": "f88eedfb311bae0ebb9f759a2d044707",
|
||||
"content-hash": "54b7bfc7ee85ba1c5bb4cd9f7d9cfa60",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@ -73,7 +72,7 @@
|
||||
"docblock",
|
||||
"parser"
|
||||
],
|
||||
"time": "2015-08-31 12:32:49"
|
||||
"time": "2015-08-31T12:32:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
@ -143,7 +142,7 @@
|
||||
"cache",
|
||||
"caching"
|
||||
],
|
||||
"time": "2016-10-29 11:16:17"
|
||||
"time": "2016-10-29T11:16:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
@ -209,7 +208,7 @@
|
||||
"collections",
|
||||
"iterator"
|
||||
],
|
||||
"time": "2015-04-14 22:21:58"
|
||||
"time": "2015-04-14T22:21:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/common",
|
||||
@ -282,7 +281,7 @@
|
||||
"persistence",
|
||||
"spl"
|
||||
],
|
||||
"time": "2016-11-30 16:50:46"
|
||||
"time": "2016-11-30T16:50:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
@ -353,7 +352,7 @@
|
||||
"persistence",
|
||||
"queryobject"
|
||||
],
|
||||
"time": "2016-09-09 19:13:33"
|
||||
"time": "2016-09-09T19:13:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/doctrine-bundle",
|
||||
@ -434,7 +433,7 @@
|
||||
"orm",
|
||||
"persistence"
|
||||
],
|
||||
"time": "2016-08-10 15:35:22"
|
||||
"time": "2016-08-10T15:35:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/doctrine-cache-bundle",
|
||||
@ -522,7 +521,7 @@
|
||||
"cache",
|
||||
"caching"
|
||||
],
|
||||
"time": "2016-01-26 17:28:51"
|
||||
"time": "2016-01-26T17:28:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
@ -589,7 +588,7 @@
|
||||
"singularize",
|
||||
"string"
|
||||
],
|
||||
"time": "2015-11-06 14:35:42"
|
||||
"time": "2015-11-06T14:35:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
@ -643,7 +642,7 @@
|
||||
"constructor",
|
||||
"instantiate"
|
||||
],
|
||||
"time": "2015-06-14 21:17:01"
|
||||
"time": "2015-06-14T21:17:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/lexer",
|
||||
@ -697,7 +696,7 @@
|
||||
"lexer",
|
||||
"parser"
|
||||
],
|
||||
"time": "2014-09-09 13:34:57"
|
||||
"time": "2014-09-09T13:34:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
@ -773,7 +772,7 @@
|
||||
"database",
|
||||
"orm"
|
||||
],
|
||||
"time": "2016-12-18 15:42:34"
|
||||
"time": "2016-12-18T15:42:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
@ -835,7 +834,7 @@
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2016-10-08 15:01:37"
|
||||
"time": "2016-10-08T15:01:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
@ -886,7 +885,7 @@
|
||||
"keywords": [
|
||||
"promise"
|
||||
],
|
||||
"time": "2016-12-20 10:07:11"
|
||||
"time": "2016-12-20T10:07:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
@ -944,7 +943,7 @@
|
||||
"stream",
|
||||
"uri"
|
||||
],
|
||||
"time": "2016-06-24 23:00:38"
|
||||
"time": "2016-06-24T23:00:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "incenteev/composer-parameter-handler",
|
||||
@ -995,7 +994,7 @@
|
||||
"keywords": [
|
||||
"parameters management"
|
||||
],
|
||||
"time": "2015-11-10 17:04:01"
|
||||
"time": "2015-11-10T17:04:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jdorn/sql-formatter",
|
||||
@ -1045,7 +1044,7 @@
|
||||
"highlight",
|
||||
"sql"
|
||||
],
|
||||
"time": "2014-01-12 16:20:24"
|
||||
"time": "2014-01-12T16:20:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "knplabs/knp-menu",
|
||||
@ -1111,7 +1110,7 @@
|
||||
"menu",
|
||||
"tree"
|
||||
],
|
||||
"time": "2016-09-22 07:36:19"
|
||||
"time": "2016-09-22T07:36:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "knplabs/knp-menu-bundle",
|
||||
@ -1168,7 +1167,90 @@
|
||||
"keywords": [
|
||||
"menu"
|
||||
],
|
||||
"time": "2016-09-22 12:24:40"
|
||||
"time": "2016-09-22T12:24:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "1.0.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "1b5c4a0031697f46e779a9d1b309c2e1b24daeab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1b5c4a0031697f46e779a9d1b309c2e1b24daeab",
|
||||
"reference": "1b5c4a0031697f46e779a9d1b309c2e1b24daeab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
"conflict": {
|
||||
"league/flysystem-sftp": "<1.0.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-fileinfo": "*",
|
||||
"mockery/mockery": "~0.9",
|
||||
"phpspec/phpspec": "^2.2",
|
||||
"phpunit/phpunit": "~4.8"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-fileinfo": "Required for MimeType",
|
||||
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
|
||||
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
|
||||
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
|
||||
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
|
||||
"league/flysystem-copy": "Allows you to use Copy.com storage",
|
||||
"league/flysystem-dropbox": "Allows you to use Dropbox storage",
|
||||
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
|
||||
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
|
||||
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
|
||||
"league/flysystem-webdav": "Allows you to use WebDAV storage",
|
||||
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Flysystem\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Frank de Jonge",
|
||||
"email": "info@frenky.net"
|
||||
}
|
||||
],
|
||||
"description": "Filesystem abstraction: Many filesystems, one API.",
|
||||
"keywords": [
|
||||
"Cloud Files",
|
||||
"WebDAV",
|
||||
"abstraction",
|
||||
"aws",
|
||||
"cloud",
|
||||
"copy.com",
|
||||
"dropbox",
|
||||
"file systems",
|
||||
"files",
|
||||
"filesystem",
|
||||
"filesystems",
|
||||
"ftp",
|
||||
"rackspace",
|
||||
"remote",
|
||||
"s3",
|
||||
"sftp",
|
||||
"storage"
|
||||
],
|
||||
"time": "2016-10-19T20:38:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
@ -1246,7 +1328,86 @@
|
||||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2016-11-26 00:15:39"
|
||||
"time": "2016-11-26T00:15:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "oneup/flysystem-bundle",
|
||||
"version": "1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/1up-lab/OneupFlysystemBundle.git",
|
||||
"reference": "5b8b5896d6981127b5c55e7620d10dabb86778bc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/1up-lab/OneupFlysystemBundle/zipball/5b8b5896d6981127b5c55e7620d10dabb86778bc",
|
||||
"reference": "5b8b5896d6981127b5c55e7620d10dabb86778bc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"league/flysystem": "^1.0.14",
|
||||
"php": ">=5.4.0",
|
||||
"symfony/framework-bundle": "~2.0|~3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"league/flysystem-aws-s3-v2": "~1.0",
|
||||
"league/flysystem-cached-adapter": "~1.0",
|
||||
"league/flysystem-copy": "~1.0",
|
||||
"league/flysystem-dropbox": "~1.0",
|
||||
"league/flysystem-gridfs": "~1.0",
|
||||
"league/flysystem-memory": "~1.0",
|
||||
"league/flysystem-rackspace": "~1.0",
|
||||
"league/flysystem-sftp": "~1.0",
|
||||
"league/flysystem-webdav": "~1.0",
|
||||
"league/flysystem-ziparchive": "~1.0",
|
||||
"litipk/flysystem-fallback-adapter": "~0.1",
|
||||
"phpunit/phpunit": "4.4.*",
|
||||
"symfony/browser-kit": "~2.0|~3.0",
|
||||
"symfony/finder": "~2.0|~3.0",
|
||||
"twistor/flysystem-stream-wrapper": "~1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-fileinfo": "Required for MimeType",
|
||||
"league/flysystem-aws-s3-v2": "Use S3 storage with AWS SDK v2",
|
||||
"league/flysystem-aws-s3-v3": "Use S3 storage with AWS SDK v3",
|
||||
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
|
||||
"league/flysystem-copy": "Allows you to use Copy.com storage",
|
||||
"league/flysystem-dropbox": "Use Dropbox storage",
|
||||
"league/flysystem-gridfs": "Allows you to use GridFS adapter",
|
||||
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
|
||||
"league/flysystem-sftp": "Allows SFTP server storage via phpseclib",
|
||||
"league/flysystem-webdav": "Allows you to use WebDAV storage",
|
||||
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
|
||||
"litipk/flysystem-fallback-adapter": "Allows you to use a fallback filesystem",
|
||||
"twistor/flysystem-stream-wrapper": "Allows you to use stream wrapper"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Oneup\\FlysystemBundle\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jim Schmid",
|
||||
"email": "js@1up.io",
|
||||
"homepage": "http://1up.io",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Integrates Flysystem filesystem abstraction library to your Symfony2 project.",
|
||||
"homepage": "http://1up.io",
|
||||
"keywords": [
|
||||
"Flysystem",
|
||||
"Symfony2",
|
||||
"abstraction",
|
||||
"filesystem"
|
||||
],
|
||||
"time": "2016-12-04T12:16:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
@ -1294,7 +1455,7 @@
|
||||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2016-11-07 23:38:38"
|
||||
"time": "2016-11-07T23:38:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
@ -1340,7 +1501,7 @@
|
||||
"psr",
|
||||
"psr-6"
|
||||
],
|
||||
"time": "2016-08-06 20:24:11"
|
||||
"time": "2016-08-06T20:24:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
@ -1390,7 +1551,7 @@
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"time": "2016-08-06 14:39:51"
|
||||
"time": "2016-08-06T14:39:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
@ -1437,7 +1598,7 @@
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2016-10-10 12:19:37"
|
||||
"time": "2016-10-10T12:19:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sensio/distribution-bundle",
|
||||
@ -1489,7 +1650,7 @@
|
||||
"configuration",
|
||||
"distribution"
|
||||
],
|
||||
"time": "2016-12-06 07:29:27"
|
||||
"time": "2016-12-06T07:29:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sensio/framework-extra-bundle",
|
||||
@ -1557,7 +1718,7 @@
|
||||
"annotations",
|
||||
"controllers"
|
||||
],
|
||||
"time": "2016-12-14 08:30:06"
|
||||
"time": "2016-12-14T08:30:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sensiolabs/security-checker",
|
||||
@ -1601,7 +1762,7 @@
|
||||
}
|
||||
],
|
||||
"description": "A security checker for your composer.lock",
|
||||
"time": "2016-09-23 18:09:57"
|
||||
"time": "2016-09-23T18:09:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
@ -1654,7 +1815,7 @@
|
||||
"mail",
|
||||
"mailer"
|
||||
],
|
||||
"time": "2016-11-24 01:01:23"
|
||||
"time": "2016-11-24T01:01:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/monolog-bundle",
|
||||
@ -1714,7 +1875,7 @@
|
||||
"log",
|
||||
"logging"
|
||||
],
|
||||
"time": "2016-11-06 18:54:50"
|
||||
"time": "2016-11-06T18:54:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-apcu",
|
||||
@ -1767,7 +1928,7 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14 01:06:16"
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-icu",
|
||||
@ -1825,7 +1986,7 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14 01:06:16"
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
@ -1884,7 +2045,7 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14 01:06:16"
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php56",
|
||||
@ -1940,7 +2101,7 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14 01:06:16"
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php70",
|
||||
@ -1999,7 +2160,7 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14 01:06:16"
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-util",
|
||||
@ -2051,7 +2212,7 @@
|
||||
"polyfill",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14 01:06:16"
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/swiftmailer-bundle",
|
||||
@ -2110,7 +2271,7 @@
|
||||
],
|
||||
"description": "Symfony SwiftmailerBundle",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2016-12-20 04:44:33"
|
||||
"time": "2016-12-20T04:44:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/symfony",
|
||||
@ -2252,7 +2413,7 @@
|
||||
"keywords": [
|
||||
"framework"
|
||||
],
|
||||
"time": "2016-12-13 13:20:15"
|
||||
"time": "2016-12-13T13:20:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
@ -2313,10 +2474,127 @@
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2016-12-13 17:28:18"
|
||||
"time": "2016-12-13T17:28:18+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
|
||||
"reference": "f3baf72eb2f58bf275b372540f5b47d25aed910f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/f3baf72eb2f58bf275b372540f5b47d25aed910f",
|
||||
"reference": "f3baf72eb2f58bf275b372540f5b47d25aed910f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-tokenizer": "*",
|
||||
"php": "^5.3.6 || >=7.0 <7.2",
|
||||
"sebastian/diff": "^1.1",
|
||||
"symfony/console": "^2.3 || ^3.0",
|
||||
"symfony/event-dispatcher": "^2.1 || ^3.0",
|
||||
"symfony/filesystem": "^2.4 || ^3.0",
|
||||
"symfony/finder": "^2.2 || ^3.0",
|
||||
"symfony/polyfill-php54": "^1.0",
|
||||
"symfony/process": "^2.3 || ^3.0",
|
||||
"symfony/stopwatch": "^2.5 || ^3.0"
|
||||
},
|
||||
"conflict": {
|
||||
"hhvm": "<3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"gecko-packages/gecko-php-unit": "^2.0",
|
||||
"phpunit/phpunit": "^4.5|^5",
|
||||
"satooshi/php-coveralls": "^1.0"
|
||||
},
|
||||
"bin": [
|
||||
"php-cs-fixer"
|
||||
],
|
||||
"type": "application",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpCsFixer\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Dariusz Rumiński",
|
||||
"email": "dariusz.ruminski@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "A tool to automatically fix PHP code style",
|
||||
"time": "2016-12-01T06:18:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
"version": "1.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||
"reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
|
||||
"reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kore Nordmann",
|
||||
"email": "mail@kore-nordmann.de"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
}
|
||||
],
|
||||
"description": "Diff implementation",
|
||||
"homepage": "https://github.com/sebastianbergmann/diff",
|
||||
"keywords": [
|
||||
"diff"
|
||||
],
|
||||
"time": "2015-12-08T07:14:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sensio/generator-bundle",
|
||||
"version": "v3.1.2",
|
||||
@ -2367,7 +2645,7 @@
|
||||
}
|
||||
],
|
||||
"description": "This bundle generates code for you",
|
||||
"time": "2016-12-05 16:01:19"
|
||||
"time": "2016-12-05T16:01:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/phpunit-bridge",
|
||||
@ -2425,7 +2703,65 @@
|
||||
],
|
||||
"description": "Symfony PHPUnit Bridge",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-12-12 13:31:08"
|
||||
"time": "2016-12-12T13:31:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php54",
|
||||
"version": "v1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php54.git",
|
||||
"reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0",
|
||||
"reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php54\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
23
gulpfile.js
23
gulpfile.js
@ -17,11 +17,32 @@ gulp.task('css', function() {
|
||||
.pipe(gulp.dest('web/resources/css'));
|
||||
});
|
||||
|
||||
gulp.task('three', function() {
|
||||
gulp.src([
|
||||
'node_modules/three/build/three.js',
|
||||
'node_modules/three/examples/js/libs/stats.min.js',
|
||||
'node_modules/three/examples/js/loaders/STLLoader.js',
|
||||
])
|
||||
.pipe(plugins.concat('three.js'))
|
||||
.pipe(gulp.dest('web/resources/js'));
|
||||
|
||||
gulp.src([
|
||||
'node_modules/three/examples/js/controls/OrbitControls.js',
|
||||
])
|
||||
.pipe(plugins.concat('OrbitControls.js'))
|
||||
.pipe(gulp.dest('web/resources/js'));
|
||||
|
||||
gulp.src([
|
||||
'app/Resources/assets/javascripts/ModelViewer.js',
|
||||
])
|
||||
.pipe(plugins.concat('ModelViewer.js'))
|
||||
.pipe(gulp.dest('web/resources/js'));
|
||||
});
|
||||
|
||||
gulp.task('js', function() {
|
||||
return gulp.src([
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'app/Resources/assets/semantic/dist/semantic.js',
|
||||
'node_modules//three/build/three.js'
|
||||
])
|
||||
.pipe(plugins.concat('main.js'))
|
||||
.pipe(gulp.dest('web/resources/js'));
|
||||
|
@ -23,7 +23,7 @@ class Brickset extends \SoapClient
|
||||
/**
|
||||
* @var array The defined classes
|
||||
*/
|
||||
private static $classmap = array(
|
||||
private static $classmap = [
|
||||
'sets' => Set::class,
|
||||
'additionalImages' => AdditionalImage::class,
|
||||
'instructions' => Instructions::class,
|
||||
@ -31,14 +31,14 @@ class Brickset extends \SoapClient
|
||||
'themes' => Theme::class,
|
||||
'subthemes' => Subtheme::class,
|
||||
'years' => Year::class,
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $apikey Brickset API key
|
||||
* @param array $options A array of config values
|
||||
* @param string $wsdl The wsdl file to use
|
||||
*/
|
||||
public function __construct($apikey, $wsdl = null, array $options = array())
|
||||
public function __construct($apikey, $wsdl = null, array $options = [])
|
||||
{
|
||||
$this->apiKey = $apikey;
|
||||
|
||||
@ -238,11 +238,10 @@ class Brickset extends \SoapClient
|
||||
return false;
|
||||
} elseif (strpos($response, 'ERROR:') === 0) {
|
||||
return false;
|
||||
} else {
|
||||
$this->userHash = $response;
|
||||
|
||||
return true;
|
||||
}
|
||||
$this->userHash = $response;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,7 +57,7 @@ class Review
|
||||
/**
|
||||
* Review constructor.
|
||||
*/
|
||||
function __construct()
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
@ -88,12 +88,11 @@ class Review
|
||||
{
|
||||
if ($this->datePosted == null) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
return new \DateTime($this->datePosted);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try {
|
||||
return new \DateTime($this->datePosted);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -848,12 +848,11 @@ class Set
|
||||
{
|
||||
if ($this->lastUpdated == null) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
return new \DateTime($this->lastUpdated);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try {
|
||||
return new \DateTime($this->lastUpdated);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,7 @@ class Part
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
@ -185,6 +186,7 @@ class Part
|
||||
{
|
||||
$this->category = $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
@ -200,6 +202,7 @@ class Part
|
||||
{
|
||||
$this->colors = $colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
|
@ -52,13 +52,12 @@ class Rebrickable
|
||||
throw new LogicException('Invalid API Key');
|
||||
} elseif ($content === 'NOSET' || $content === 'NOPART') {
|
||||
return null;
|
||||
} else {
|
||||
return $content;
|
||||
}
|
||||
} else {
|
||||
|
||||
return $content;
|
||||
}
|
||||
//TODO
|
||||
throw new LogicException($response->getStatusCode());
|
||||
}
|
||||
} catch (ConnectException $e) {
|
||||
//TODO
|
||||
throw new LogicException($e->getMessage());
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
namespace AppBundle\Api\Manager;
|
||||
|
||||
use AppBundle\Api\Client\Rebrickable\Rebrickable;
|
||||
use AppBundle\Api\Client\Rebrickable\Converter\PartPropertyNameConverter;
|
||||
use AppBundle\Api\Client\Rebrickable\Entity\Color;
|
||||
use AppBundle\Api\Client\Rebrickable\Entity\Part;
|
||||
use AppBundle\Api\Client\Rebrickable\Entity\Set;
|
||||
use AppBundle\Api\Client\Rebrickable\Converter\PartPropertyNameConverter;
|
||||
use AppBundle\Api\Client\Rebrickable\Rebrickable;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||
@ -33,10 +33,10 @@ class RebrickableManager
|
||||
|
||||
private function getSerializer()
|
||||
{
|
||||
$encoders = array(new JsonEncoder());
|
||||
$encoders = [new JsonEncoder()];
|
||||
$nameConverter = new PartPropertyNameConverter();
|
||||
$objectNormalizer = new ObjectNormalizer(null, $nameConverter);
|
||||
$normalizers = array($objectNormalizer, new ArrayDenormalizer());
|
||||
$normalizers = [$objectNormalizer, new ArrayDenormalizer()];
|
||||
$serializer = new Serializer($normalizers, $encoders);
|
||||
|
||||
return $serializer;
|
||||
|
43
src/AppBundle/Command/LoadLibraryCommand.php
Normal file
43
src/AppBundle/Command/LoadLibraryCommand.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?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 LoadLibraryCommand extends ContainerAwareCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('app:load:library')
|
||||
->setDescription('Loads LDraw library parts')
|
||||
->setHelp('This command allows you to..')
|
||||
->addArgument('ldraw', InputArgument::OPTIONAL, 'Path to LDraw library folder');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$ldrawLoader = $this->getContainer()->get('loader.ldraw');
|
||||
$ldrawLoader->setOutput($output);
|
||||
|
||||
$rebrickableLoader = $this->getContainer()->get('loader.rebrickable');
|
||||
$rebrickableLoader->setOutput($output);
|
||||
|
||||
try {
|
||||
$ldrawLoader->loadModels($input->getArgument('ldraw'));
|
||||
|
||||
$rebrickableLoader->loadColors();
|
||||
|
||||
$rebrickableLoader->loadParts();
|
||||
|
||||
$rebrickableLoader->loadBuildingKits();
|
||||
|
||||
$rebrickableLoader->loadPartBuildingKits();
|
||||
} catch (\Exception $e) {
|
||||
printf($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Command;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class LoadRebrickableCommand extends ContainerAwareCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('app:loadRebrickable')
|
||||
->setDescription('Loads Rebrickable csv data')
|
||||
->setHelp('This command allows you to..')
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$modelLoader = $this->getContainer()->get('app.model_loader_service');
|
||||
|
||||
try {
|
||||
$modelLoader->loadColors();
|
||||
|
||||
$modelLoader->loadParts($output);
|
||||
|
||||
$modelLoader->loadBuildingKits($output);
|
||||
|
||||
$modelLoader->loadPartBuildingKits($output);
|
||||
} catch (\Exception $e) {
|
||||
printf($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
187
src/AppBundle/Command/Loader/LDrawLoader.php
Normal file
187
src/AppBundle/Command/Loader/LDrawLoader.php
Normal file
@ -0,0 +1,187 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
72
src/AppBundle/Command/Loader/Loader.php
Normal file
72
src/AppBundle/Command/Loader/Loader.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Command\Loader;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Asset\Exception\LogicException;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Debug\Exception\ContextErrorException;
|
||||
|
||||
class Loader
|
||||
{
|
||||
/**
|
||||
* @var EntityManager
|
||||
*/
|
||||
protected $em;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* @var ProgressBar
|
||||
*/
|
||||
protected $progressBar;
|
||||
|
||||
public function setOutput(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
$this->output->setDecorated(true);
|
||||
}
|
||||
|
||||
private function progressCallback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max)
|
||||
{
|
||||
switch ($notification_code) {
|
||||
case STREAM_NOTIFY_FILE_SIZE_IS:
|
||||
$this->progressBar = new ProgressBar($this->output);
|
||||
$this->progressBar->setBarWidth(100);
|
||||
$this->progressBar->start($bytes_max);
|
||||
break;
|
||||
case STREAM_NOTIFY_PROGRESS:
|
||||
$this->progressBar->setProgress($bytes_transferred);
|
||||
break;
|
||||
case STREAM_NOTIFY_COMPLETED:
|
||||
$this->progressBar->setProgress($bytes_transferred);
|
||||
$this->progressBar->finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function downloadFile($url)
|
||||
{
|
||||
$temp = tempnam(sys_get_temp_dir(), 'printabrick.');
|
||||
|
||||
$ctx = stream_context_create([], [
|
||||
'notification' => [$this, 'progressCallback'],
|
||||
]);
|
||||
|
||||
try {
|
||||
if (false === file_put_contents($temp, fopen($url, 'r', 0, $ctx))) {
|
||||
throw new LogicException('error writing file'); //TODO
|
||||
}
|
||||
} catch (ContextErrorException $e) {
|
||||
throw new LogicException('wrong url'); //TODO
|
||||
} catch (\Exception $e) {
|
||||
throw new LogicException('exception: '.$e->getMessage()); //TODO
|
||||
}
|
||||
|
||||
return $temp;
|
||||
}
|
||||
}
|
@ -1,114 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Service;
|
||||
namespace AppBundle\Command\Loader;
|
||||
|
||||
use AppBundle\Api\Manager\RebrickableManager;
|
||||
use AppBundle\Entity\BuildingKit;
|
||||
use AppBundle\Entity\Category;
|
||||
use AppBundle\Entity\Color;
|
||||
use AppBundle\Entity\Keyword;
|
||||
use AppBundle\Entity\Model;
|
||||
use AppBundle\Entity\BuildingKit;
|
||||
use AppBundle\Entity\Part;
|
||||
use AppBundle\Entity\Part_BuildingKit;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Component\Asset\Exception\LogicException;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
|
||||
class ModelLoaderService
|
||||
//TODO Refactor
|
||||
class RebrickableLoader extends Loader
|
||||
{
|
||||
private $STLlib;
|
||||
|
||||
/**
|
||||
* @var EntityManager
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @var RebrickableManager
|
||||
*/
|
||||
private $rebrickableManager;
|
||||
|
||||
private $rebrickable_url;
|
||||
|
||||
/**
|
||||
* ModelLoaderService constructor.
|
||||
*/
|
||||
public function __construct($em, $STLlib, $rebrickableManager)
|
||||
public function __construct($em, $rebrickableManager, $rebrickable_url)
|
||||
{
|
||||
$this->STLlib = $STLlib;
|
||||
$this->em = $em;
|
||||
$this->rebrickableManager = $rebrickableManager;
|
||||
$this->rebrickable_url = $rebrickable_url;
|
||||
}
|
||||
|
||||
// LDraw
|
||||
|
||||
public function loadModels($LDrawLibrary)
|
||||
public function loadPartBuildingKits()
|
||||
{
|
||||
$finder = new Finder();
|
||||
$files = $finder->files()->name('*.dat')->depth('== 0')->in(getcwd().'/'.$LDrawLibrary.'/parts');
|
||||
$this->output->writeln('Downloading set_pieces.csv from Rebrickable.com');
|
||||
$file = $this->downloadFile('compress.zlib://'.$this->rebrickable_url['set_pieces']);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$this->loadModelHeader($file);
|
||||
}
|
||||
}
|
||||
|
||||
private function loadModelHeader(SplFileInfo $fileInfo)
|
||||
{
|
||||
$handle = fopen($fileInfo->getRealPath(), 'r');
|
||||
if ($handle) {
|
||||
$firstLine = fgets($handle);
|
||||
$description = trim(substr($firstLine, 2));
|
||||
$model = new Model();
|
||||
$model->setFile($fileInfo->getFilename());
|
||||
$p['category'] = explode(' ', trim($description))[0];
|
||||
|
||||
//TODO handle ~Moved to
|
||||
|
||||
while (!feof($handle)) {
|
||||
$line = trim(fgets($handle));
|
||||
if ($line && ($line[0] == '1')) {
|
||||
break;
|
||||
} elseif ($line && ($line[0] == '0' && strpos($line, '!CATEGORY '))) {
|
||||
$p['category'] = trim(explode('!CATEGORY ', $line)[1]);
|
||||
} elseif ($line && ($line[0] == '0' && strpos($line, '!KEYWORDS '))) {
|
||||
$keywords = explode(',', explode('!KEYWORDS ', $line)[1]);
|
||||
foreach ($keywords as $k) {
|
||||
$p['keywords'][] = trim($k);
|
||||
}
|
||||
} elseif ($line && ($line[0] == '0' && strpos($line, 'Name: '))) {
|
||||
$model->setNumber(trim(explode('.dat', explode('Name: ', $line)[1])[0]));
|
||||
} elseif ($line && ($line[0] == '0' && strpos($line, 'Author: '))) {
|
||||
$model->setAuthor(explode('Author: ', $line)[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->em->persist($model);
|
||||
$this->em->flush();
|
||||
} else {
|
||||
throw new LogicException('loadHeader error'); //TODO
|
||||
}
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
// Rebrickable
|
||||
|
||||
public function loadPartBuildingKits($output)
|
||||
{
|
||||
$partRepository = $this->em->getRepository('AppBundle:Part');
|
||||
$buldingKitRepository = $this->em->getRepository('AppBundle:BuildingKit');
|
||||
$colorRepository = $this->em->getRepository('AppBundle:Color');
|
||||
|
||||
$setPieces = tempnam(sys_get_temp_dir(), 'printabrick.');
|
||||
file_put_contents($setPieces, fopen('compress.zlib://http://rebrickable.com/files/set_pieces.csv.gz', 'r'));
|
||||
|
||||
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
|
||||
|
||||
if (($handle = fopen($setPieces, 'r')) !== false) {
|
||||
$this->output->writeln('Loading set_pieces.csv into Database');
|
||||
if (($handle = fopen($file, 'r')) !== false) {
|
||||
$header = fgetcsv($handle, 200, ',');
|
||||
|
||||
// create a new progress bar (50 units)
|
||||
$progress = new ProgressBar($output, intval(exec("wc -l '$setPieces'")));
|
||||
$progress = new ProgressBar($this->output, intval(exec("wc -l '$file'"))); //TODO replace wc-l
|
||||
$progress->setFormat('very_verbose');
|
||||
$progress->setBarWidth(50);
|
||||
$progress->start();
|
||||
@ -144,26 +83,26 @@ class ModelLoaderService
|
||||
$this->em->clear();
|
||||
fclose($handle);
|
||||
$progress->finish();
|
||||
$progress->clear();
|
||||
}
|
||||
|
||||
unlink($setPieces);
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
public function loadBuildingKits($output)
|
||||
public function loadBuildingKits()
|
||||
{
|
||||
$keywordRepository = $this->em->getRepository('AppBundle:Keyword');
|
||||
$this->output->writeln('Downloading sets.csv from Rebrickable.com');
|
||||
$file = $this->downloadFile('compress.zlib://'.$this->rebrickable_url['sets']);
|
||||
|
||||
$sets = tempnam(sys_get_temp_dir(), 'printabrick.');
|
||||
file_put_contents($sets, fopen('compress.zlib://http://rebrickable.com/files/sets.csv.gz', 'r'));
|
||||
$keywordRepository = $this->em->getRepository('AppBundle:Keyword');
|
||||
|
||||
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
|
||||
|
||||
if (($handle = fopen($sets, 'r')) !== false) {
|
||||
$this->output->writeln('Loading sets.csv into Database');
|
||||
if (($handle = fopen($file, 'r')) !== false) {
|
||||
$header = fgetcsv($handle, 500, ',');
|
||||
|
||||
// create a new progress bar (50 units)
|
||||
$progress = new ProgressBar($output, intval(exec("wc -l '$sets'")));
|
||||
$progress = new ProgressBar($this->output, intval(exec("wc -l '$file'"))); //TODO replace wc-l
|
||||
$progress->setFormat('very_verbose');
|
||||
$progress->setBarWidth(50);
|
||||
$progress->start();
|
||||
@ -206,24 +145,23 @@ class ModelLoaderService
|
||||
fclose($handle);
|
||||
|
||||
$progress->finish();
|
||||
$progress->clear();
|
||||
}
|
||||
unlink($sets);
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
public function loadParts($output)
|
||||
public function loadParts()
|
||||
{
|
||||
$pieces = tempnam(sys_get_temp_dir(), 'printabrick.');
|
||||
file_put_contents($pieces, fopen('compress.zlib://http://rebrickable.com/files/pieces.csv.gz', 'r'));
|
||||
$this->output->writeln('Downloading pieces.csv from Rebrickable.com');
|
||||
$file = $this->downloadFile('compress.zlib://'.$this->rebrickable_url['pieces']);
|
||||
|
||||
$categoryRepository = $this->em->getRepository('AppBundle:Category');
|
||||
|
||||
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
|
||||
|
||||
if (($handle = fopen($pieces, 'r')) !== false) {
|
||||
|
||||
$this->output->writeln('Loading pieces.csv into Database');
|
||||
if (($handle = fopen($file, 'r')) !== false) {
|
||||
// create a new progress bar (50 units)
|
||||
$progress = new ProgressBar($output, intval(exec("wc -l '$pieces'")));
|
||||
$progress = new ProgressBar($this->output, intval(exec("wc -l '$file'"))); //TODO replace wc-l
|
||||
$progress->setFormat('very_verbose');
|
||||
$progress->setBarWidth(50);
|
||||
$progress->start();
|
||||
@ -256,14 +194,15 @@ class ModelLoaderService
|
||||
fclose($handle);
|
||||
|
||||
$progress->finish();
|
||||
$progress->clear();
|
||||
}
|
||||
|
||||
unlink($pieces);
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
public function loadColors()
|
||||
{
|
||||
$this->output->writeln('Loading colors into Database');
|
||||
|
||||
$rb_colors = $this->rebrickableManager->getColors();
|
||||
|
||||
foreach ($rb_colors as $rb_color) {
|
||||
@ -283,10 +222,10 @@ class ModelLoaderService
|
||||
{
|
||||
$modelRepository = $this->em->getRepository('AppBundle:Model');
|
||||
|
||||
if (strpos($part->getNumber(), 'p')) {
|
||||
$model = $modelRepository->findOneBy(['number' => $part->getNumber()]);
|
||||
|
||||
if (!$model && strpos($part->getNumber(), 'p')) {
|
||||
$model = $modelRepository->findOneBy(['number' => explode('p', $part->getNumber())[0]]);
|
||||
} else {
|
||||
$model = $modelRepository->findOneBy(['number' => $part->getNumber()]);
|
||||
}
|
||||
|
||||
return $model;
|
@ -13,9 +13,7 @@ class DefaultController extends Controller
|
||||
*/
|
||||
public function indexAction(Request $request)
|
||||
{
|
||||
// replace this example code with whatever you need
|
||||
return $this->render('default/index.html.twig', [
|
||||
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
43
src/AppBundle/Controller/DownloadController.php
Normal file
43
src/AppBundle/Controller/DownloadController.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Controller;
|
||||
|
||||
use AppBundle\Entity\Model;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/download")
|
||||
*/
|
||||
class DownloadController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/model/{id}", name="download_model")
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function modelAction(Model $model)
|
||||
{
|
||||
$ldraw_filesystem = $this->get('oneup_flysystem.ldraw_filesystem');
|
||||
|
||||
if ($ldraw_filesystem->has($model->getFile())) {
|
||||
$response = new BinaryFileResponse($ldraw_filesystem->getAdapter()->getPathPrefix().$model->getFile());
|
||||
$response->headers->set('Content-Type', 'application/vnd.ms-pki.stl');
|
||||
|
||||
// Create the disposition of the file
|
||||
$disposition = $response->headers->makeDisposition(
|
||||
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
|
||||
$model->getFile()
|
||||
);
|
||||
|
||||
$response->headers->set('Content-Disposition', $disposition);
|
||||
|
||||
return $response;
|
||||
}
|
||||
throw new FileNotFoundException($model->getFile());
|
||||
}
|
||||
}
|
28
src/AppBundle/Controller/PartController.php
Normal file
28
src/AppBundle/Controller/PartController.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Controller;
|
||||
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
|
||||
/**
|
||||
* @Route("/rebrickable/part")
|
||||
*/
|
||||
class PartController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/{id}", name="part_detail")
|
||||
*/
|
||||
public function detailAction($id)
|
||||
{
|
||||
$part = $this->get('manager.rebrickable')->getPart($id);
|
||||
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$localPart = $em->getRepository('AppBundle:Part')->findOneBy(['number' => $id]);
|
||||
|
||||
return $this->render('part/detail.html.twig', [
|
||||
'part' => $part,
|
||||
'localPart' => $localPart,
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
|
||||
/**
|
||||
* @Route("rebrickable/parts")
|
||||
*/
|
||||
class PartsController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/{id}", name="part_detail")
|
||||
*/
|
||||
public function detailAction($id)
|
||||
{
|
||||
$part = $this->get('manager.rebrickable')->getPartById($id);
|
||||
|
||||
return $this->render('parts/detail.html.twig', [
|
||||
'part' => $part,
|
||||
]);
|
||||
}
|
||||
}
|
@ -8,12 +8,12 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* @Route("/brickset/sets")
|
||||
* @Route("/brickset/set")
|
||||
*/
|
||||
class SetsController extends Controller
|
||||
class SetController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/", name="sets_browse")
|
||||
* @Route("/", name="set_browse")
|
||||
*/
|
||||
public function browseAction(Request $request)
|
||||
{
|
||||
@ -32,7 +32,7 @@ class SetsController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->render('sets/browse.html.twig', [
|
||||
return $this->render('set/browse.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'sets' => $sets,
|
||||
]);
|
||||
@ -43,13 +43,10 @@ class SetsController extends Controller
|
||||
*/
|
||||
public function detailAction(Request $request, $id, $name = null)
|
||||
{
|
||||
$set = $this->get('manager.brickset')->getSetById($id);;
|
||||
$set = $this->get('manager.brickset')->getSetById($id);
|
||||
|
||||
$parts = $this->get('app.collection_service')->getSet($set->getNumber().'-'.$set->getNumberVariant())->getParts();
|
||||
|
||||
return $this->render('sets/detail.html.twig', [
|
||||
return $this->render('set/detail.html.twig', [
|
||||
'set' => $set,
|
||||
'parts' => $parts,
|
||||
]);
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* BuildingKit
|
||||
* BuildingKit.
|
||||
*
|
||||
* @ORM\Table(name="building_kit")
|
||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\BuildingKitRepository")
|
||||
@ -74,9 +74,8 @@ class BuildingKit
|
||||
$this->keywords = new ArrayCollection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get id
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -105,9 +104,8 @@ class BuildingKit
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set name
|
||||
* Set name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
@ -121,7 +119,7 @@ class BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -131,9 +129,9 @@ class BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Set year
|
||||
* Set year.
|
||||
*
|
||||
* @param integer $year
|
||||
* @param int $year
|
||||
*
|
||||
* @return BuildingKit
|
||||
*/
|
||||
@ -145,7 +143,7 @@ class BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Get year
|
||||
* Get year.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -175,7 +173,7 @@ class BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parts
|
||||
* Get parts.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
@ -209,7 +207,7 @@ class BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Get keywords
|
||||
* Get keywords.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
|
@ -5,10 +5,9 @@ namespace AppBundle\Entity;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
|
||||
/**
|
||||
* Category
|
||||
* Category.
|
||||
*
|
||||
* @ORM\Table(name="category")
|
||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository")
|
||||
@ -54,9 +53,8 @@ class Category
|
||||
$this->parts = new ArrayCollection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get id
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -66,7 +64,7 @@ class Category
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name
|
||||
* Set name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
@ -80,7 +78,7 @@ class Category
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -90,7 +88,7 @@ class Category
|
||||
}
|
||||
|
||||
/**
|
||||
* Get models
|
||||
* Get models.
|
||||
*
|
||||
* @return ArrayCollection
|
||||
*/
|
||||
@ -124,7 +122,7 @@ class Category
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parts
|
||||
* Get parts.
|
||||
*
|
||||
* @return ArrayCollection
|
||||
*/
|
||||
|
@ -6,7 +6,7 @@ use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Color
|
||||
* Color.
|
||||
*
|
||||
* @ORM\Table(name="color")
|
||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\ColorRepository")
|
||||
@ -43,7 +43,7 @@ class Color
|
||||
private $part_building_kits;
|
||||
|
||||
/**
|
||||
* Set id
|
||||
* Set id.
|
||||
*
|
||||
* @var int
|
||||
*
|
||||
@ -57,7 +57,7 @@ class Color
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -67,7 +67,7 @@ class Color
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name
|
||||
* Set name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
@ -81,7 +81,7 @@ class Color
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -91,7 +91,7 @@ class Color
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rgb
|
||||
* Set rgb.
|
||||
*
|
||||
* @param string $rgb
|
||||
*
|
||||
@ -105,7 +105,7 @@ class Color
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rgb
|
||||
* Get rgb.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -123,7 +123,6 @@ class Color
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Part_BuildingKit $part_building_kit
|
||||
*
|
||||
* @return Color
|
||||
@ -148,11 +147,10 @@ class Color
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->part_building_kits = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Keyword
|
||||
* Keyword.
|
||||
*
|
||||
* @ORM\Table(name="keyword")
|
||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\KeywordRepository")
|
||||
@ -44,9 +44,8 @@ class Keyword
|
||||
$this->building_kits = new ArrayCollection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get id
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -56,7 +55,7 @@ class Keyword
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name
|
||||
* Set name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
@ -70,7 +69,7 @@ class Keyword
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -110,5 +109,4 @@ class Keyword
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Model
|
||||
* Model.
|
||||
*
|
||||
* @ORM\Table(name="model")
|
||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\ModelRepository")
|
||||
@ -22,6 +22,12 @@ class Model
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="name", type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $name;
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
@ -53,13 +59,12 @@ class Model
|
||||
/**
|
||||
* @var Category
|
||||
*
|
||||
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category", inversedBy="models")
|
||||
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category", inversedBy="models", cascade={"persist"})
|
||||
*/
|
||||
private $category;
|
||||
|
||||
|
||||
/**
|
||||
* Get id
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -69,7 +74,23 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Set number
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set number.
|
||||
*
|
||||
* @param string $number
|
||||
*
|
||||
@ -83,7 +104,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number
|
||||
* Get number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -93,7 +114,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Set author
|
||||
* Set author.
|
||||
*
|
||||
* @param string $author
|
||||
*
|
||||
@ -107,7 +128,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get author
|
||||
* Get author.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -117,7 +138,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file
|
||||
* Set file.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
@ -131,7 +152,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file
|
||||
* Get file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -141,7 +162,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parts
|
||||
* Get parts.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
@ -175,7 +196,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Set category
|
||||
* Set category.
|
||||
*
|
||||
* @param Category $category
|
||||
*
|
||||
@ -190,7 +211,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get category
|
||||
* Get category.
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
namespace AppBundle\Entity;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Part_BuildingKit
|
||||
* Part_BuildingKit.
|
||||
*
|
||||
* @ORM\Table(name="part__building_kit")
|
||||
* @ORM\Entity(repositoryClass="AppBundle\Repository\Part_BuildingKitRepository")
|
||||
@ -57,9 +56,8 @@ class Part_BuildingKit
|
||||
*/
|
||||
private $building_kit;
|
||||
|
||||
|
||||
/**
|
||||
* Get id
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -69,9 +67,9 @@ class Part_BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Set count
|
||||
* Set count.
|
||||
*
|
||||
* @param integer $count
|
||||
* @param int $count
|
||||
*
|
||||
* @return Part_BuildingKit
|
||||
*/
|
||||
@ -83,7 +81,7 @@ class Part_BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count
|
||||
* Get count.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -93,7 +91,7 @@ class Part_BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Set color
|
||||
* Set color.
|
||||
*
|
||||
* @param Color $color
|
||||
*
|
||||
@ -107,7 +105,7 @@ class Part_BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Get color
|
||||
* Get color.
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
@ -117,9 +115,9 @@ class Part_BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type
|
||||
* Set type.
|
||||
*
|
||||
* @param boolean $type
|
||||
* @param bool $type
|
||||
*
|
||||
* @return Part_BuildingKit
|
||||
*/
|
||||
@ -131,7 +129,7 @@ class Part_BuildingKit
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type
|
||||
* Get type.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@ -181,6 +179,4 @@ class Part_BuildingKit
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -26,36 +26,35 @@ class FilterSetType extends AbstractType
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add("theme", ChoiceType::class, [
|
||||
->add('theme', ChoiceType::class, [
|
||||
'choices' => $this->bricksetManager->getThemes(),
|
||||
'choice_label' => function(Theme $theme = null) {
|
||||
'choice_label' => function (Theme $theme = null) {
|
||||
return $theme ? $theme->getTheme().' ('.$theme->getSetCount().')' : '';
|
||||
},
|
||||
'placeholder' => '',
|
||||
'required' => false
|
||||
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
$formModifier = function (Form $form, Theme $theme = null) {
|
||||
$subthemes = null === $theme ? [] : $this->bricksetManager->getSubthemesByTheme($theme);
|
||||
$years = null === $theme ? [] : $this->bricksetManager->getYearsByTheme($theme);
|
||||
|
||||
$form->add("subtheme", ChoiceType::class, [
|
||||
$form->add('subtheme', ChoiceType::class, [
|
||||
'choices' => $subthemes,
|
||||
'choice_label' => function(Subtheme $subtheme = null) {
|
||||
'choice_label' => function (Subtheme $subtheme = null) {
|
||||
return $subtheme ? $subtheme->getSubtheme() : '';
|
||||
},
|
||||
'placeholder' => '',
|
||||
'required' => false
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
$form->add("years", ChoiceType::class, [
|
||||
$form->add('years', ChoiceType::class, [
|
||||
'choices' => $years,
|
||||
'choice_label' => function(Year $year = null) {
|
||||
'choice_label' => function (Year $year = null) {
|
||||
return $year ? $year->getYear() : '';
|
||||
},
|
||||
'placeholder' => '',
|
||||
'required' => false
|
||||
'required' => false,
|
||||
]);
|
||||
};
|
||||
|
||||
@ -76,6 +75,6 @@ class FilterSetType extends AbstractType
|
||||
}
|
||||
);
|
||||
|
||||
$builder->add('submit',SubmitType::class);
|
||||
$builder->add('submit', SubmitType::class);
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ class Builder
|
||||
]);
|
||||
|
||||
$menu->addChild('Sets', [
|
||||
'route' => 'sets_browse',
|
||||
'route' => 'set_browse',
|
||||
]);
|
||||
|
||||
return $menu;
|
||||
|
@ -5,7 +5,7 @@ namespace AppBundle\Repository;
|
||||
use AppBundle\Entity\Part;
|
||||
|
||||
/**
|
||||
* BuildingSetRepository
|
||||
* BuildingSetRepository.
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
|
@ -2,10 +2,8 @@
|
||||
|
||||
namespace AppBundle\Repository;
|
||||
|
||||
use AppBundle\Entity\Category;
|
||||
|
||||
/**
|
||||
* CategoryRepository
|
||||
* CategoryRepository.
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace AppBundle\Repository;
|
||||
|
||||
/**
|
||||
* ColorRepository
|
||||
* ColorRepository.
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace AppBundle\Repository;
|
||||
|
||||
/**
|
||||
* KeywordRepository
|
||||
* KeywordRepository.
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace AppBundle\Repository;
|
||||
|
||||
/**
|
||||
* ModelRepository
|
||||
* ModelRepository.
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace AppBundle\Repository;
|
||||
|
||||
/**
|
||||
* PartRepository
|
||||
* PartRepository.
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace AppBundle\Repository;
|
||||
|
||||
/**
|
||||
* Part_BuildingKitRepository
|
||||
* Part_BuildingKitRepository.
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
|
Loading…
x
Reference in New Issue
Block a user