diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..f8ad42c0 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,3 @@ +npm run test && \ +npm run file-size && \ +git add . diff --git a/package-lock.json b/package-lock.json index 6bb8adf1..ab9d9fbd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,14 +10,16 @@ "@eslint/js": "^9.1.1", "@stylistic/eslint-plugin-js": "^1.8.0", "editorconfig-checker": "^5.1.1", + "get-mp3-duration": "^1.0.0", "globals": "^15.1.0", "html-minifier-terser": "^7.1.0", + "husky": "^9.0.11", "js-yaml": "^4.1.0", "minify-xml": "^4.4.1" }, "engines": { - "node": ">=20", - "npm": ">=10" + "node": "20", + "npm": "10" } }, "node_modules/@11ty/dependency-tree": { @@ -1595,6 +1597,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-mp3-duration": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-mp3-duration/-/get-mp3-duration-1.0.0.tgz", + "integrity": "sha512-SiTppS0shvqCJ8rky8E1Yi9thLoTTGq3Tjc4n4pmjo8BMuiQFN3cCfiaWmRFk/8TjhOQhPwrpJZJDvOcbPVwrw==", + "dev": true + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1813,6 +1821,21 @@ "node": ">= 6" } }, + "node_modules/husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true, + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", diff --git a/package.json b/package.json index d68ecf12..a85384da 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "cover": "cd src && rsync --archive --compress cover.png wst@web-standards.ru:/var/www/web-standards.ru/podcast/", "feed": "cd dist && rsync --archive --compress index.xml wst@web-standards.ru:/var/www/web-standards.ru/podcast/feed/", "deploy": "npm run mp3 && npm run cover && npm run feed", - "new": "node scripts/new.js" + "new": "node scripts/new.js", + "file-size": "node scripts/file-size.js", + "prepare": "husky || true" }, "engines": { "node": "20", @@ -20,8 +22,10 @@ "@eslint/js": "^9.1.1", "@stylistic/eslint-plugin-js": "^1.8.0", "editorconfig-checker": "^5.1.1", + "get-mp3-duration": "^1.0.0", "globals": "^15.1.0", "html-minifier-terser": "^7.1.0", + "husky": "^9.0.11", "js-yaml": "^4.1.0", "minify-xml": "^4.4.1" } diff --git a/scripts/file-size.js b/scripts/file-size.js new file mode 100644 index 00000000..30fc8c4b --- /dev/null +++ b/scripts/file-size.js @@ -0,0 +1,53 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import getMP3Duration from 'get-mp3-duration'; + +function isFileExist(filePath) { + try { + fs.statSync(filePath); + return true; + } catch { + return false; + } +} + +const folderDataPath = path.join('src', 'episodes'); +const folderMediaPath = path.join('src', 'mp3'); + +const dir = fs.opendirSync(folderDataPath, { + encoding: 'utf-8', + withFileTypes: true, +}); + +try { + let item = null; + + while ((item = dir.readSync())) { + if (!item.isDirectory()) { + continue; + } + + const episodeFolder = path.join(item.path, item.name); + const dataFilePath = path.join(episodeFolder, 'index.json'); + + if (isFileExist(dataFilePath)) { + continue; + } + + const mediaFilePath = path.join(folderMediaPath, item.name + '.mp3'); + + if (!isFileExist(mediaFilePath)) { + console.log(`Файл '${mediaFilePath}' не найден`); + continue; + } + + const fileBuffer = fs.readFileSync(mediaFilePath); + const fileSize = fileBuffer.byteLength; + const duration = getMP3Duration(fileBuffer); + + const dataToSave = JSON.stringify({ fileSize, duration }, null, '\t'); + fs.writeFileSync(dataFilePath, dataToSave, 'utf-8'); + } +} finally { + dir.closeSync(); +}