Skip to content
Snippets Groups Projects
Commit 7300dcd6 authored by Benedikt's avatar Benedikt
Browse files

added code

parent 59e7dae6
Branches
No related tags found
No related merge requests found
Showing with 453 additions and 29 deletions
dcc-viewer/node_modules/
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="c3d759c9-e9f8-41d4-b9b5-ef12db68e70c" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/src/components/accordionComponent.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/components/tabComponent.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/ui/adminRenderer.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/ui/jsonTreeViewer.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/ui/measurementRenderer.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/public/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/public/index.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/public/styles.css" beforeDir="false" afterPath="$PROJECT_DIR$/public/styles.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/globalData.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/globalData.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/xmlToJson.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/xmlToJson.js" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="JavaScript File" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 6
}</component>
<component name="ProjectId" id="2tLWdqlIz5X4SCSwK5EjWvfiZtG" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"JavaScript Debug.Debug Vite.executor": "Run",
"JavaScript Debug.dccViewer.executor": "Debug",
"JavaScript Debug.index.html.executor": "Run",
"Node.js.vite.config.js.executor": "Run",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true",
"git-widget-placeholder": "main",
"last_opened_file_path": "/home/seeger01/Downloads/de-6.4.jar",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "http.proxy",
"ts.external.directory.path": "/home/seeger01/Downloads/WebStorm-243.24978.60/plugins/javascript-plugin/jsLanguageServicesImpl/external",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RunManager">
<configuration name="dccViewer" type="JavascriptDebugType" uri="http://localhost:5173/">
<method v="2" />
</configuration>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-d6986cc7102b-76f8388c3a79-JavaScript-WS-243.24978.60" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="c3d759c9-e9f8-41d4-b9b5-ef12db68e70c" name="Changes" comment="" />
<created>1740131925655</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1740131925655</updated>
<workItem from="1740131927264" duration="102000" />
<workItem from="1740132052064" duration="10000" />
<workItem from="1740132146315" duration="24000" />
<workItem from="1740132175271" duration="89000" />
<workItem from="1740158794192" duration="1155000" />
<workItem from="1740380748268" duration="2676000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>
\ No newline at end of file
{
"name": "dcc-viewer",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "dcc-viewer",
"version": "1.0.0",
"dependencies": {
"xml-js": "^1.6.11"
}
},
"node_modules/sax": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
"license": "ISC"
},
"node_modules/xml-js": {
"version": "1.6.11",
"resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz",
"integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==",
"license": "MIT",
"dependencies": {
"sax": "^1.2.4"
},
"bin": {
"xml-js": "bin/cli.js"
}
}
}
}
{
"name": "dcc-viewer",
"version": "1.0.0",
"scripts": { "dev": "vite" },
"dependencies": { "xml2js": "^0.4.23" }
}
\ No newline at end of file
"scripts": {
"dev": "vite"
},
"dependencies": {
"xml-js": "^1.6.11"
}
}
<!DOCTYPE html>
<html lang='en'>
<html lang="en">
<head>
<meta charset='UTF-8'>
<meta charset="UTF-8">
<title>DCC Viewer</title>
<script type='module' src='/src/main.js'></script>
<link rel='stylesheet' href='/styles.css'>
<script type="module" src="/src/main.js"></script>
<link rel="stylesheet" href="/public/styles.css">
</head>
<body>
<input type='file' id='file-input' accept='.xml'>
<button id='theme-toggle'>Toggle Theme</button>
<select id='language-select'>
<option value='en'>English</option>
<option value='de'>German</option>
</select>
<div id='json-container'></div>
<h1>DCC Viewer</h1>
<input type="file" id="file-input" accept=".xml">
<div id="admin-data-container"></div>
<div id="measurement-data-container"></div>
</body>
</html>
\ No newline at end of file
</html>
body { font-family: Arial, sans-serif; }
.dark-mode { background-color: black; color: white; }
\ No newline at end of file
.accordion-header {
background-color: #f0f0f0;
border: none;
padding: 10px;
cursor: pointer;
width: 100%;
text-align: left;
}
.accordion-content {
display: none;
padding: 10px;
}
.accordion-content.open {
display: block;
}
.tabs {
display: flex;
gap: 10px;
}
.tabs button {
padding: 5px 10px;
cursor: pointer;
}
.tab-content {
border: 1px solid #ddd;
padding: 10px;
}
export function createAccordion(title, contentElement) {
const container = document.createElement('div');
container.classList.add('accordion');
const header = document.createElement('button');
header.textContent = title;
header.classList.add('accordion-header');
const content = document.createElement('div');
content.classList.add('accordion-content');
content.appendChild(contentElement);
header.addEventListener('click', () => {
content.classList.toggle('open');
});
container.appendChild(header);
container.appendChild(content);
return container;
}
export function createTabs(tabsData) {
const container = document.createElement('div');
container.classList.add('tabs-container');
const tabs = document.createElement('div');
tabs.classList.add('tabs');
const contentContainer = document.createElement('div');
contentContainer.classList.add('tab-content');
tabsData.forEach((tab, index) => {
const button = document.createElement('button');
button.textContent = tab.title;
button.addEventListener('click', () => {
contentContainer.innerHTML = '';
contentContainer.appendChild(tab.content);
});
tabs.appendChild(button);
if (index === 0) {
contentContainer.appendChild(tab.content);
}
});
container.appendChild(tabs);
container.appendChild(contentContainer);
return container;
}
export const globalData = {};
\ No newline at end of file
export const globalData = {
dcc: null // This will hold the parsed DCC JSON data
};
\ No newline at end of file
import { convertXMLToJSON } from './xmlToJson.js';
import { JSONTreeViewer } from './components/JSONTreeViewer.js';
import { globalData } from './globalData.js';
import { renderAdministrativeData } from './ui/adminRenderer.js';
import { renderMeasurementResults } from './ui/measurementRenderer.js';
const fileInput = document.getElementById('file-input');
const container = document.getElementById('json-container');
fileInput.addEventListener('change', async (event) => {
const file = event.target.files?.[0];
......@@ -11,10 +12,12 @@ fileInput.addEventListener('change', async (event) => {
const reader = new FileReader();
reader.onload = async () => {
const xmlString = reader.result;
const jsonData = await convertXMLToJSON(xmlString);
const viewer = new JSONTreeViewer(jsonData);
container.innerHTML = '';
container.appendChild(viewer.render());
globalData.dcc = await convertXMLToJSON(xmlString); // Store DCC globally
console.log("DCC Data Loaded:", globalData.dcc);
renderAdministrativeData(globalData.dcc.administrativeData);
renderMeasurementResults(globalData.dcc.measurementResults);
};
reader.readAsText(file);
});
\ No newline at end of file
});
import { createAccordion } from '../components/accordionComponent.js';
import { JSONTreeViewer } from './jsonTreeViewer.js';
import { globalData } from '../globalData.js';
export function renderAdministrativeData() {
const container = document.getElementById('admin-data-container');
container.innerHTML = ''; // Clear previous content
const dccRoot = globalData.dcc?.['dcc:digitalCalibrationCertificate'];
if (!dccRoot) {
container.innerHTML = "<p>No Digital Calibration Certificate Found</p>";
return;
}
const adminData = dccRoot?.['dcc:administrativeData'];
if (!adminData) {
container.innerHTML = "<p>No Administrative Data Found</p>";
return;
}
// 🔹 SOFTWARE SECTION
const softwareContainer = document.createElement('div');
const softwareList = (adminData?.['dcc:dccSoftware']?.['dcc:software'] || []).map(software => {
return `
<div>
<strong>${software?.['dcc:name']?.['dcc:content'] || 'Unknown Software'}</strong>
(v${software?.['dcc:release'] || 'N/A'}) - ${software?.['dcc:type'] || 'N/A'}
</div>
`;
}).join('');
softwareContainer.innerHTML = `<h3>Software Used</h3>${softwareList}`;
// 🔹 CORE DATA SECTION
const coreData = adminData?.['dcc:coreData'] || {};
const coreDataContainer = document.createElement('div');
coreDataContainer.innerHTML = `
<h3>Core Data</h3>
<p><strong>Country:</strong> ${coreData?.['dcc:countryCodeISO3166_1']?._text || 'N/A'}</p>
<p><strong>Languages:</strong> ${Array.isArray(coreData?.['dcc:usedLangCodeISO639_1'])
? coreData['dcc:usedLangCodeISO639_1'].map(lang => lang._text).join(', ')
: coreData?.['dcc:usedLangCodeISO639_1']?._text || 'N/A'}</p>
<p><strong>Unique Identifier:</strong> ${coreData?.['dcc:uniqueIdentifier']?._text || 'N/A'}</p>
<p><strong>Issue Date:</strong> ${coreData?.['dcc:issueDate']?._text || 'N/A'}</p>
`;
// 🔹 CALIBRATION LAB
const labInfo = adminData?.['dcc:calibrationLaboratory']?.['dcc:contact'] || {};
const labContainer = document.createElement('div');
labContainer.innerHTML = `
<h3>Calibration Laboratory</h3>
<p><strong>Name:</strong> ${labInfo?.['dcc:name']?.['dcc:content']?._text || 'N/A'}</p>
<p><strong>Email:</strong> ${labInfo?.['dcc:eMail']?._text || 'N/A'}</p>
<p><strong>Phone:</strong> ${labInfo?.['dcc:phone']?._text || 'N/A'}</p>
`;
// 🔹 RESPONSIBLE PERSONS
const responsiblePersons = (adminData?.['dcc:respPersons']?.['dcc:respPerson'] || []).map(person => {
return `<p>${person?.['dcc:person']?.['dcc:name']?.['dcc:content']?._text || 'Unknown Person'}
${person?.['dcc:mainSigner'] ? '(Main Signer)' : ''}</p>`;
}).join('');
const responsibleContainer = document.createElement('div');
responsibleContainer.innerHTML = `<h3>Responsible Persons</h3>${responsiblePersons}`;
// 🔹 ADD SECTIONS TO ACCORDION
container.appendChild(createAccordion("Software Used", softwareContainer));
container.appendChild(createAccordion("Core Data", coreDataContainer));
container.appendChild(createAccordion("Calibration Laboratory", labContainer));
container.appendChild(createAccordion("Responsible Persons", responsibleContainer));
// 🔹 JSON DEBUG VIEW
container.appendChild(createAccordion("Raw JSON Data (Debug)", new JSONTreeViewer(adminData).render()));
}
export class JSONTreeViewer {
constructor(data) {
this.data = data;
}
render() {
const container = document.createElement('pre');
container.textContent = JSON.stringify(this.data, null, 2);
return container;
}
}
import { createTabs } from '../components/tabComponent.js';
import { JSONTreeViewer } from './jsonTreeViewer.js';
import { globalData } from '../globalData.js';
export function renderMeasurementResults() {
const container = document.getElementById('measurement-data-container');
container.innerHTML = ''; // Clear previous content
const dccRoot = globalData.dcc?.['dcc:digitalCalibrationCertificate'];
if (!dccRoot) {
container.innerHTML = "<p>No Digital Calibration Certificate Found</p>";
return;
}
const measurements = dccRoot?.['dcc:measurementResults'];
if (!measurements || !measurements['dcc:measurementResult']) {
container.innerHTML = "<p>No Measurement Results Found</p>";
return;
}
const tabs = (Array.isArray(measurements['dcc:measurementResult']) ?
measurements['dcc:measurementResult'] : [measurements['dcc:measurementResult']]
).map((result, index) => {
const resultContainer = document.createElement('div');
// 🔹 Measurement Methods
const methods = result?.['dcc:usedMethods']?.['dcc:usedMethod'] || [];
const methodsList = (Array.isArray(methods) ? methods : [methods]).map(method => `
<p><strong>${method?.['dcc:name']?.['dcc:content']?._text || 'Unknown Method'}</strong>:
${method?.['dcc:description']?.['dcc:content']?._text || 'No description'}</p>
`).join('');
// 🔹 Measurement Equipment
const equipments = result?.['dcc:measuringEquipments']?.['dcc:measuringEquipment'] || [];
const equipmentList = (Array.isArray(equipments) ? equipments : [equipments]).map(eq => `
<p><strong>${eq?.['dcc:name']?.['dcc:content']?._text || 'Unknown Equipment'}</strong>
- ${eq?.['dcc:model']?._text || 'N/A'}</p>
`).join('');
// 🔹 Measurement Results
const results = result?.['dcc:results']?.['dcc:result'] || [];
const resultsList = (Array.isArray(results) ? results : [results]).map(res => `
<h4>${res?.['dcc:name']?.['dcc:content']?._text || 'Unknown Result'}</h4>
<pre>${JSON.stringify(res['dcc:data'], null, 2)}</pre>
`).join('');
resultContainer.innerHTML = `
<h3>Measurement Methods</h3>${methodsList}
<h3>Equipment Used</h3>${equipmentList}
<h3>Results</h3>${resultsList}
`;
return {
title: `Measurement ${index + 1}`,
content: resultContainer
};
});
container.appendChild(createTabs(tabs));
// 🔹 JSON DEBUGGING VIEW
container.appendChild(createTabs([{ title: "Raw JSON", content: new JSONTreeViewer(measurements).render() }]));
}
import { parseStringPromise } from 'xml2js';
import { xml2json } from 'xml-js';
export async function convertXMLToJSON(xmlString) {
return parseStringPromise(xmlString, { explicitArray: false, mergeAttrs: true });
}
\ No newline at end of file
export function convertXMLToJSON(xmlString) {
const jsonData = xml2json(xmlString, { compact: true, spaces: 2 });
return JSON.parse(jsonData);
}
{
"src/main.js": "import { convertXMLToJSON } from './xmlToJson.js';\nimport { globalData } from './globalData.js';\nimport { renderAdministrativeData } from './ui/adminRenderer.js';\nimport { renderMeasurementResults } from './ui/measurementRenderer.js';\n\nconst fileInput = document.getElementById('file-input');\n\nfileInput.addEventListener('change', async (event) => {\n const file = event.target.files?.[0];\n if (!file) return;\n\n const reader = new FileReader();\n reader.onload = async () => {\n const xmlString = reader.result;\n globalData.dcc = await convertXMLToJSON(xmlString); // Store DCC globally\n\n console.log(\"DCC Data Loaded:\", globalData.dcc);\n\n renderAdministrativeData(globalData.dcc.administrativeData);\n renderMeasurementResults(globalData.dcc.measurementResults);\n };\n reader.readAsText(file);\n});\n",
"src/xmlToJson.js": "import { xml2json } from 'xml-js';\n\nexport function convertXMLToJSON(xmlString) {\n const jsonData = xml2json(xmlString, { compact: true, spaces: 2 });\n return JSON.parse(jsonData);\n}\n",
"src/idRegistry.js": "export const idRegistry = {};",
"src/globalData.js": "export const globalData = {\n dcc: null // This will hold the parsed DCC JSON data\n};",
"src/globalOptions.js": "export const globalOptions = { preferredLanguage: 'en' };",
"src/viewerRegistry.js": "import { JSONTreeViewer } from './components/JSONTreeViewer.js';\n\nexport function getViewerForElement() {\n return JSONTreeViewer;\n}",
"src/utils.js": "export function getLocalizedText(elements) {\n if (!Array.isArray(elements)) return elements;\n return elements[0]._ || '';\n}",
"src/components/BaseViewer.js": "export class BaseViewer {\n constructor(sectionData) {\n this.sectionData = sectionData;\n }\n render() {\n throw new Error('render() must be implemented in subclasses');\n }\n}",
"src/components/JSONTreeViewer.js": "import { BaseViewer } from './BaseViewer.js';\n\nexport class JSONTreeViewer extends BaseViewer {\n render() {\n const container = document.createElement('pre');\n container.textContent = JSON.stringify(this.sectionData, null, 2);\n return container;\n }\n}",
"src/components/accordionComponent.js": "export function createAccordion(title, contentElement) {\n const container = document.createElement('div');\n container.classList.add('accordion');\n\n const header = document.createElement('button');\n header.textContent = title;\n header.classList.add('accordion-header');\n\n const content = document.createElement('div');\n content.classList.add('accordion-content');\n content.appendChild(contentElement);\n\n header.addEventListener('click', () => {\n content.classList.toggle('open');\n });\n\n container.appendChild(header);\n container.appendChild(content);\n return container;\n}\n",
"src/components/tabComponent.js": "export function createTabs(tabsData) {\n const container = document.createElement('div');\n container.classList.add('tabs-container');\n\n const tabs = document.createElement('div');\n tabs.classList.add('tabs');\n\n const contentContainer = document.createElement('div');\n contentContainer.classList.add('tab-content');\n\n tabsData.forEach((tab, index) => {\n const button = document.createElement('button');\n button.textContent = tab.title;\n button.addEventListener('click', () => {\n contentContainer.innerHTML = '';\n contentContainer.appendChild(tab.content);\n });\n\n tabs.appendChild(button);\n\n if (index === 0) {\n contentContainer.appendChild(tab.content);\n }\n });\n\n container.appendChild(tabs);\n container.appendChild(contentContainer);\n return container;\n}\n",
"src/ui/languageSelector.js": "import { globalOptions } from '../globalOptions.js';\n\nconst languageSelect = document.getElementById('language-select');\nlanguageSelect.addEventListener('change', (event) => {\n globalOptions.preferredLanguage = event.target.value;\n});",
"src/ui/themeSwitcher.js": "const themeToggle = document.getElementById('theme-toggle');\nthemeToggle.addEventListener('click', () => {\n document.body.classList.toggle('dark-mode');\n});",
"src/ui/adminRenderer.js": "import { createAccordion } from '../components/accordionComponent.js';\nimport { JSONTreeViewer } from './jsonTreeViewer.js';\n\nexport function renderAdministrativeData(adminData) {\n const container = document.getElementById('admin-data-container');\n container.innerHTML = ''; // Clear previous content\n\n if (!adminData) {\n container.innerHTML = \"<p>No Administrative Data Found</p>\";\n return;\n }\n\n const jsonViewer = new JSONTreeViewer(adminData);\n const accordion = createAccordion(\"Administrative Data\", jsonViewer.render());\n\n container.appendChild(accordion);\n}\n",
"src/ui/measurementRenderer.js": "import { createTabs } from '../components/tabComponent.js';\nimport { JSONTreeViewer } from './jsonTreeViewer.js';\n\nexport function renderMeasurementResults(measurements) {\n const container = document.getElementById('measurement-data-container');\n container.innerHTML = ''; // Clear previous content\n\n if (!measurements || !measurements.measurementResult) {\n container.innerHTML = \"<p>No Measurement Results Found</p>\";\n return;\n }\n\n const tabs = measurements.measurementResult.map((result, index) => ({\n title: `Result ${index + 1}`,\n content: new JSONTreeViewer(result).render()\n }));\n\n const tabsComponent = createTabs(tabs);\n container.appendChild(tabsComponent);\n}\n",
"src/ui/jsonTreeViewer.js": "export class JSONTreeViewer {\n constructor(data) {\n this.data = data;\n }\n\n render() {\n const container = document.createElement('pre');\n container.textContent = JSON.stringify(this.data, null, 2);\n return container;\n }\n}\n",
"public/index.html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>DCC Viewer</title>\n <script type=\"module\" src=\"/src/main.js\"></script>\n <link rel=\"stylesheet\" href=\"/public/styles.css\">\n</head>\n<body>\n<h1>DCC Viewer</h1>\n\n<input type=\"file\" id=\"file-input\" accept=\".xml\">\n\n<div id=\"admin-data-container\"></div>\n<div id=\"measurement-data-container\"></div>\n</body>\n</html>\n",
"public/styles.css": ".accordion-header {\n background-color: #f0f0f0;\n border: none;\n padding: 10px;\n cursor: pointer;\n width: 100%;\n text-align: left;\n}\n\n.accordion-content {\n display: none;\n padding: 10px;\n}\n\n.accordion-content.open {\n display: block;\n}\n\n.tabs {\n display: flex;\n gap: 10px;\n}\n\n.tabs button {\n padding: 5px 10px;\n cursor: pointer;\n}\n\n.tab-content {\n border: 1px solid #ddd;\n padding: 10px;\n}\n"
}
\ No newline at end of file
import os
import json
# Define the root folder of your project
PROJECT_ROOT = "dcc-viewer"
# File extensions to include
INCLUDE_EXTENSIONS = {".js", ".html", ".css"}
# Folders to exclude
EXCLUDE_FOLDERS = {"node_modules", "dist", ".git", ".idea", ".vite"}
def scan_project(directory):
project_data = {}
for root, dirs, files in os.walk(directory):
# Remove excluded folders from traversal
dirs[:] = [d for d in dirs if d not in EXCLUDE_FOLDERS]
for file in files:
if any(file.endswith(ext) for ext in INCLUDE_EXTENSIONS):
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, directory)
try:
with open(file_path, "r", encoding="utf-8") as f:
project_data[relative_path] = f.read()
except Exception as e:
print(f"Error reading {file_path}: {e}")
return project_data
# Run the scan and save as JSON
if __name__ == "__main__":
project_json = scan_project(PROJECT_ROOT)
with open("project_snapshot.json", "w", encoding="utf-8") as json_file:
json.dump(project_json, json_file, indent=4, ensure_ascii=False)
print("✅ Project snapshot saved to project_snapshot.json")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment