RE: [Tool/Web] Get specific part by id out or LDraw with all needed files included
2022-06-24, 15:01 (This post was last modified: 2022-06-24, 15:02 by Christoph Reum.)
2022-06-24, 15:01 (This post was last modified: 2022-06-24, 15:02 by Christoph Reum.)
(2022-06-24, 14:54)Orion Pobursky Wrote: Awesome, thanks for this tool. I plan to have this functionality in the update to the PT software but since this is still quite a ways off, this tool will fill that gap quite nicely.
Also, Studio uses LDraw. While Studio isn't typically the first choice amongst the regulars here, Studio discussions are welcome.
I can share you my very dirty PHP code (I am just an system-engineer, no professional developer

The php file expects the ldraw folder beneath ldraw/ directory
PHP Code:
<?php
//error_reporting(E_ALL);
//https://www.ldraw.org/library/updates/complete.zip
function preg_grep_keys($pattern, $input, $flags = 0) {
return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags)));
}
function getSubPartAssemblies($part) {
global $zip;
if(is_file(getcwd().'/ldraw/parts/'.$part.'.dat')) {
$ldrawPath = getcwd().'/ldraw/parts/';
$ldrawPath2 = 'CustomParts/parts/';
}
else {
$ldrawPath = getcwd().'/ldraw/p/';
$ldrawPath2 = 'CustomParts/p/';
}
$zip->addFile($ldrawPath.$part.'.dat', $ldrawPath2.$part.'.dat');
$tmpDatContentArray = file($ldrawPath.$part.'.dat');
foreach($tmpDatContentArray as $line) {
$line = str_replace("\n","",$line);
preg_match_all('/.*[\s](.*\.dat)/', $line, $subAssemblyArray, PREG_SET_ORDER, 0);
if (count($subAssemblyArray) > 0) {
foreach($subAssemblyArray as $subAssemblyLine) {
$subPart = str_replace("\\","/",$subAssemblyLine[1]);
$subPart = str_replace(".dat","",$subPart);
if ($subPart != $part) {
getSubPartAssemblies($subPart);
}
}
}
}
}
function searchPart($part) {
preg_match("/^([\d]{1,}).*?$/",$part,$strippedPartArray, PREG_OFFSET_CAPTURE);
$strippedPart = $strippedPartArray[1][0];
$partsListContent = file_get_contents(getcwd().'/ldraw/parts.lst');
preg_match_all('/^(.*?)[\s]+(.*)$/m', $partsListContent, $partsListArray, PREG_SET_ORDER, 0);
foreach($partsListArray as $tmpPart) {
$partsArray[$tmpPart[1]] = $tmpPart[2];
}
$findings = preg_grep_keys("/^".$strippedPart.".*/", $partsArray);
return $findings;
}
if ($_GET["part"]) {
$mainPart = str_replace('.dat','',$_GET["part"]);
$zip = new ZipArchive;
if(is_file(getcwd().'/tmp/'.$mainPart.'.zip')) {
unlink(getcwd().'/tmp/'.$mainPart.'.zip');
}
$zip->open(getcwd().'/tmp/'.$mainPart.'.zip', ZipArchive::CREATE);
$zip->addFile(getcwd().'/ldraw/CAlicense.txt', 'CAlicense.txt');
$zip->addFile(getcwd().'/ldraw/CAreadme.txt', 'CAreadme.txt');
$zip->addFile(getcwd().'/ldraw/Readme.txt', 'Readme.txt');
$zip->addFile(getcwd().'/ldraw/parts/'.$mainPart.'.dat', 'CustomParts/parts/'.$mainPart.'.dat');
getSubPartAssemblies($mainPart);
$zip->close();
header('Content-type: application/zip');
header('Content-Transfer-Encoding: Binary');
header('Content-Disposition: attachment; filename='.$mainPart.".zip");
header("Content-Length: " . filesize(getcwd().'/tmp/'.$mainPart.".zip"));
readfile(getcwd().'/tmp/'.$mainPart.".zip");
}
else {
echo "<!DOCTYPE html>";
echo "<html>";
echo "<head>";
echo "<meta charset=\"utf-8\">";
echo "<meta name=\"viewport\" content=\"width=device-width\"/>";
echo "<style>";
echo "@media (prefers-color-scheme: dark) {";
echo " body {";
echo " background-color: black;";
echo " color: white;";
echo " }";
echo "}";
echo "body {";
echo " background-color: white;";
echo " color: black;";
echo " overflow: auto;";
echo "}";
echo "</style>";
echo "</head>";
echo "<body>";
if (!$_POST) {
echo "<h1>LDraw to Studio Exporter</h1>";
echo "<div align=left style=\"float:center; clear: both;border-style: dashed; margin-bottom: 2em; padding: 1em;\">";
echo "<p>This tool is designed to import parts which are available in LDraw, but not in Studio. From the LDraw part number, it zips all relevant sub elements (there can be many!) into a part pack.</p>";
echo "<h3>How to use this downloader</h3>";
echo "<div align=center style=\"background-color:#FF7777\">Disclaimer: Some Bricklink part numbers won't work, please search in LDraw library below!</div>";
echo "<ol>";
echo "<li>Visit the LDraw Homepage's part lookup: <a href=\"https://www.ldraw.org/parts/official-part-lookup.html\" target=\"_blank\">https://www.ldraw.org/parts/official-part-lookup.html</a></li>";
echo "<li>Search for your part of choice & copy the number</li>";
echo "<li>Enter this number into the below searchfield </li>";
echo "<li>A list of all fitting parts from the catalogue will show up - clicking the entries will create a zip package with just the needed parts</li>";
echo "<li>To use the packs, unzip them and place their contents in your \"<i><b>C:\Users\{your username}\AppData\Local\Stud.io\CustomParts</b></i>\" (Windows).<br />The parts will then be available in Custom Parts palette of Studio.</li>";
echo "</ol>";
echo "</div>";
echo "<form action=".$_SERVER['PHP_SELF']." method=\"POST\">";
echo "<div align=center style=\"float:center; clear: both; font-size:1.5em;\">";
echo "Part Number: <input style=\"font-size:1.5em;\" type=\"text\" name=\"part\" /> <input type=\"submit\" style=\"font-size:1.5em;\"/>";
echo "</div>";
}
else {
$partText = searchPart($_POST['part']);
echo "<div style=\"float:center; clear: both; font-size:1.5em;\">";
echo "<p align=center><a href=\"".$_SERVER['PHP_SELF']."\">Back to search</a></p>";
echo "<ul>";
foreach($partText as $tmpPartName => $tmpPartDesc) {
echo "<li><a href=\"".$_SERVER['PHP_SELF']."?part=".str_replace(".dat","",$tmpPartName)."\" target=\"_new\">".str_replace(".dat","",$tmpPartName).".zip - ".$tmpPartDesc."</a></li>";
}
echo "<ul>";
echo "</div>";
}
echo "<div align=center style=\"float:center; clear: both; margin-top: 4em; font-size:0.7em;\">";
echo "<div align=left style=\"float:center; clear: both;border-style: dashed; margin-bottom: 2em; padding: 1em;\">";
echo "<h4>Legal Information</h4>";
echo "<p><b>LDraw™ Parts Library</b> is licenced under <a href=\"https://creativecommons.org/licenses/by/4.0/\"><b>Creative Commons Attribution Licence 4.0 (CC BY 4.0)</b></a></p>";
echo "<p><b>LDraw™</b> is a completely unofficial, community run free CAD system which represents official parts produced by the LEGO company.</p>";
echo "<p><b>LDraw™</b> is a trademark owned and licensed by the Estate of James Jessiman</p>";
echo "<p><b>LDraw™</b> website can be visited at <a href=\"https://www.ldraw.org/\">https://www.ldraw.org/</a></p>";
echo "<p><b>Studio</b> software is copyrighted to LEGO BrickLink, Inc.</p>";
echo "<p><b>LEGO®</b> and <b>Bricklink®</b> are a registered trademark of the LEGO Group, which does not sponsor, endorse, or authorize this site. Visit the official Lego website at <a href=\"http://www.lego.com/\">http://www.lego.com</a></p>";
echo "</div>";
echo "Tool written by <a href=\"https://www.reum.it/\" target=\"_blank\">Christoph Reum</a>";
echo "</div>";
echo "</form>";
echo "</body>";
echo "<html>";
}
?>