fix: resolve lonely if ESLint warning
This commit is contained in:
+26
-13
@@ -5,22 +5,29 @@ Helper scripts for vault automation and web content capture.
|
||||
## Available Scripts
|
||||
|
||||
### Attachment Management
|
||||
|
||||
These are primarily called via npm/pnpm commands in package.json:
|
||||
|
||||
- `update-attachment-links.js` - Updates note links after moving attachments
|
||||
- `fix-renamed-links.js` - Fixes links after renaming files
|
||||
|
||||
### Web Content Capture
|
||||
|
||||
**Note**: These scripts require API keys to function:
|
||||
|
||||
#### firecrawl-scrape.sh
|
||||
|
||||
Scrapes a single URL and saves as markdown.
|
||||
|
||||
```bash
|
||||
# Requires FIRECRAWL_API_KEY environment variable
|
||||
.scripts/firecrawl-scrape.sh <url> <output_file>
|
||||
```
|
||||
|
||||
#### firecrawl-batch.sh
|
||||
|
||||
Scrapes multiple URLs and auto-generates filenames.
|
||||
|
||||
```bash
|
||||
# Requires FIRECRAWL_API_KEY environment variable
|
||||
.scripts/firecrawl-batch.sh <url1> <url2> <url3>
|
||||
@@ -28,8 +35,11 @@ Scrapes multiple URLs and auto-generates filenames.
|
||||
```
|
||||
|
||||
### Transcript Extraction
|
||||
|
||||
#### transcript-extract.sh
|
||||
|
||||
Extracts transcripts from YouTube videos.
|
||||
|
||||
```bash
|
||||
.scripts/transcript-extract.sh <youtube-url>
|
||||
```
|
||||
@@ -38,21 +48,22 @@ Extracts transcripts from YouTube videos.
|
||||
|
||||
Run these from the vault root with `pnpm`:
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `attachments:list` | Show first 20 unprocessed attachments |
|
||||
| `attachments:count` | Count unprocessed attachments |
|
||||
| `attachments:organized` | Count files in Organized folder |
|
||||
| `attachments:unprocessed` | Same as count |
|
||||
| `attachments:refs <file>` | Find references to a specific file |
|
||||
| `attachments:sizes` | Show 20 largest attachment files |
|
||||
| `attachments:orphans` | Find unreferenced attachments |
|
||||
| `attachments:recent` | Show files added in last 7 days |
|
||||
| `attachments:create-organized` | Create the Organized subfolder |
|
||||
| Command | Description |
|
||||
| ------------------------------ | ------------------------------------- |
|
||||
| `attachments:list` | Show first 20 unprocessed attachments |
|
||||
| `attachments:count` | Count unprocessed attachments |
|
||||
| `attachments:organized` | Count files in Organized folder |
|
||||
| `attachments:unprocessed` | Same as count |
|
||||
| `attachments:refs <file>` | Find references to a specific file |
|
||||
| `attachments:sizes` | Show 20 largest attachment files |
|
||||
| `attachments:orphans` | Find unreferenced attachments |
|
||||
| `attachments:recent` | Show files added in last 7 days |
|
||||
| `attachments:create-organized` | Create the Organized subfolder |
|
||||
|
||||
## Setup Requirements
|
||||
|
||||
### For Web Scraping
|
||||
|
||||
1. Get a Firecrawl API key from [firecrawl.dev](https://firecrawl.dev)
|
||||
2. Add to your shell profile:
|
||||
```bash
|
||||
@@ -60,11 +71,13 @@ Run these from the vault root with `pnpm`:
|
||||
```
|
||||
|
||||
### For Transcript Extraction
|
||||
|
||||
- Requires `yt-dlp` and `jq` installed:
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
brew install yt-dlp jq
|
||||
|
||||
|
||||
# Linux
|
||||
apt-get install yt-dlp jq
|
||||
```
|
||||
@@ -81,4 +94,4 @@ Run these from the vault root with `pnpm`:
|
||||
- Scripts assume Unix-like environment (macOS/Linux)
|
||||
- Windows users may need WSL or Git Bash
|
||||
- All paths are relative to vault root
|
||||
- Check script comments for additional requirements
|
||||
- Check script comments for additional requirements
|
||||
|
||||
@@ -3,85 +3,95 @@
|
||||
/**
|
||||
* Fixes attachment links after files have been renamed
|
||||
* Usage: node .scripts/fix-renamed-links.js <old-name> <new-name>
|
||||
*
|
||||
*
|
||||
* This properly handles the case where files are renamed, not just moved
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const args = process.argv.slice(2)
|
||||
|
||||
if (args.length !== 2) {
|
||||
console.log('Usage: node .scripts/fix-renamed-links.js <old-filename> <new-filename>');
|
||||
console.log('Example: node .scripts/fix-renamed-links.js "CleanShot 2025-01-01.png" "Project Screenshot.png"');
|
||||
process.exit(1);
|
||||
console.log(
|
||||
'Usage: node .scripts/fix-renamed-links.js <old-filename> <new-filename>',
|
||||
)
|
||||
console.log(
|
||||
'Example: node .scripts/fix-renamed-links.js "CleanShot 2025-01-01.png" "Project Screenshot.png"',
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const [oldName, newName] = args;
|
||||
const newPath = `05 Attachments/Organized/${newName}`;
|
||||
const [oldName, newName] = args
|
||||
const newPath = `05 Attachments/Organized/${newName}`
|
||||
|
||||
console.log(`Fixing links: ${oldName} → ${newName}`);
|
||||
console.log(`Fixing links: ${oldName} → ${newName}`)
|
||||
|
||||
// Function to walk directory
|
||||
function walkDir(dir, callback) {
|
||||
fs.readdirSync(dir).forEach(f => {
|
||||
const dirPath = path.join(dir, f);
|
||||
const isDirectory = fs.statSync(dirPath).isDirectory();
|
||||
if (isDirectory) {
|
||||
// Skip node_modules, .git
|
||||
if (!f.includes('node_modules') && !f.includes('.git')) {
|
||||
walkDir(dirPath, callback);
|
||||
}
|
||||
} else {
|
||||
callback(path.join(dir, f));
|
||||
}
|
||||
});
|
||||
fs.readdirSync(dir).forEach((f) => {
|
||||
const dirPath = path.join(dir, f)
|
||||
const isDirectory = fs.statSync(dirPath).isDirectory()
|
||||
if (isDirectory) {
|
||||
// Skip node_modules, .git
|
||||
if (!f.includes('node_modules') && !f.includes('.git')) {
|
||||
walkDir(dirPath, callback)
|
||||
}
|
||||
} else {
|
||||
callback(path.join(dir, f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Process all markdown files
|
||||
let updatedCount = 0;
|
||||
const updatedFiles = [];
|
||||
let updatedCount = 0
|
||||
const updatedFiles = []
|
||||
|
||||
walkDir('.', (filepath) => {
|
||||
if (filepath.endsWith('.md')) {
|
||||
let content = fs.readFileSync(filepath, 'utf8');
|
||||
const originalContent = content;
|
||||
|
||||
// Escape special regex characters in filename
|
||||
const escapedOld = oldName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
// Pattern 1: ![[oldname]] without path
|
||||
const pattern1 = new RegExp(`!\\[\\[${escapedOld}\\]\\]`, 'g');
|
||||
content = content.replace(pattern1, `![[${newPath}]]`);
|
||||
|
||||
// Pattern 2: ![[05 Attachments/oldname]]
|
||||
const pattern2 = new RegExp(`!\\[\\[05 Attachments/${escapedOld}\\]\\]`, 'g');
|
||||
content = content.replace(pattern2, `![[${newPath}]]`);
|
||||
|
||||
// Pattern 3: [[oldname]] without ! (for PDFs and other non-embedded)
|
||||
const pattern3 = new RegExp(`(?<!!)\\[\\[${escapedOld}\\]\\]`, 'g');
|
||||
content = content.replace(pattern3, `[[${newPath}]]`);
|
||||
|
||||
// Pattern 4: [[05 Attachments/oldname]] without !
|
||||
const pattern4 = new RegExp(`(?<!!)\\[\\[05 Attachments/${escapedOld}\\]\\]`, 'g');
|
||||
content = content.replace(pattern4, `[[${newPath}]]`);
|
||||
|
||||
// Write back if changed
|
||||
if (content !== originalContent) {
|
||||
fs.writeFileSync(filepath, content, 'utf8');
|
||||
updatedFiles.push(filepath);
|
||||
updatedCount++;
|
||||
}
|
||||
if (filepath.endsWith('.md')) {
|
||||
let content = fs.readFileSync(filepath, 'utf8')
|
||||
const originalContent = content
|
||||
|
||||
// Escape special regex characters in filename
|
||||
const escapedOld = oldName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
|
||||
// Pattern 1: ![[oldname]] without path
|
||||
const pattern1 = new RegExp(`!\\[\\[${escapedOld}\\]\\]`, 'g')
|
||||
content = content.replace(pattern1, `![[${newPath}]]`)
|
||||
|
||||
// Pattern 2: ![[05 Attachments/oldname]]
|
||||
const pattern2 = new RegExp(
|
||||
`!\\[\\[05 Attachments/${escapedOld}\\]\\]`,
|
||||
'g',
|
||||
)
|
||||
content = content.replace(pattern2, `![[${newPath}]]`)
|
||||
|
||||
// Pattern 3: [[oldname]] without ! (for PDFs and other non-embedded)
|
||||
const pattern3 = new RegExp(`(?<!!)\\[\\[${escapedOld}\\]\\]`, 'g')
|
||||
content = content.replace(pattern3, `[[${newPath}]]`)
|
||||
|
||||
// Pattern 4: [[05 Attachments/oldname]] without !
|
||||
const pattern4 = new RegExp(
|
||||
`(?<!!)\\[\\[05 Attachments/${escapedOld}\\]\\]`,
|
||||
'g',
|
||||
)
|
||||
content = content.replace(pattern4, `[[${newPath}]]`)
|
||||
|
||||
// Write back if changed
|
||||
if (content !== originalContent) {
|
||||
fs.writeFileSync(filepath, content, 'utf8')
|
||||
updatedFiles.push(filepath)
|
||||
updatedCount++
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
// Report results
|
||||
if (updatedCount > 0) {
|
||||
console.log(`\nUpdated ${updatedCount} files:`);
|
||||
updatedFiles.forEach(file => console.log(` - ${file}`));
|
||||
console.log(`\nUpdated ${updatedCount} files:`)
|
||||
updatedFiles.forEach((file) => console.log(` - ${file}`))
|
||||
} else {
|
||||
console.log('\nNo files needed updating');
|
||||
console.log('\nNo files needed updating')
|
||||
}
|
||||
|
||||
console.log('\nDone!');
|
||||
console.log('\nDone!')
|
||||
|
||||
@@ -3,104 +3,127 @@
|
||||
/**
|
||||
* Updates attachment links in markdown files after files are moved to Organized folder
|
||||
* Usage: node .scripts/update-attachment-links.js [specific-file.ext]
|
||||
*
|
||||
*
|
||||
* If no argument provided, updates all files in Organized folder
|
||||
* If specific filename provided, only updates references to that file
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
const organizedDir = '05 Attachments/Organized';
|
||||
const args = process.argv.slice(2);
|
||||
const specificFile = args[0];
|
||||
const organizedDir = '05 Attachments/Organized'
|
||||
const args = process.argv.slice(2)
|
||||
const specificFile = args[0]
|
||||
|
||||
// Get list of files to update references for
|
||||
let filesToUpdate = [];
|
||||
let filesToUpdate = []
|
||||
|
||||
if (specificFile) {
|
||||
// Update references for a specific file
|
||||
filesToUpdate = [specificFile];
|
||||
console.log(`Updating references for: ${specificFile}`);
|
||||
// Update references for a specific file
|
||||
filesToUpdate = [specificFile]
|
||||
console.log(`Updating references for: ${specificFile}`)
|
||||
} else if (fs.existsSync(organizedDir)) {
|
||||
// Update references for all files in Organized folder
|
||||
filesToUpdate = fs.readdirSync(organizedDir)
|
||||
console.log(`Found ${filesToUpdate.length} files in Organized folder`)
|
||||
} else {
|
||||
// Update references for all files in Organized folder
|
||||
if (fs.existsSync(organizedDir)) {
|
||||
filesToUpdate = fs.readdirSync(organizedDir);
|
||||
console.log(`Found ${filesToUpdate.length} files in Organized folder`);
|
||||
} else {
|
||||
console.log('Organized folder does not exist yet');
|
||||
process.exit(0);
|
||||
}
|
||||
console.log('Organized folder does not exist yet')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// Function to walk directory
|
||||
function walkDir(dir, callback) {
|
||||
fs.readdirSync(dir).forEach(f => {
|
||||
const dirPath = path.join(dir, f);
|
||||
const isDirectory = fs.statSync(dirPath).isDirectory();
|
||||
if (isDirectory) {
|
||||
// Skip node_modules, .git, and the Organized folder itself
|
||||
if (!f.includes('node_modules') && !f.includes('.git') && dirPath !== organizedDir) {
|
||||
walkDir(dirPath, callback);
|
||||
}
|
||||
} else {
|
||||
callback(path.join(dir, f));
|
||||
}
|
||||
});
|
||||
fs.readdirSync(dir).forEach((f) => {
|
||||
const dirPath = path.join(dir, f)
|
||||
const isDirectory = fs.statSync(dirPath).isDirectory()
|
||||
if (isDirectory) {
|
||||
// Skip node_modules, .git, and the Organized folder itself
|
||||
if (
|
||||
!f.includes('node_modules') &&
|
||||
!f.includes('.git') &&
|
||||
dirPath !== organizedDir
|
||||
) {
|
||||
walkDir(dirPath, callback)
|
||||
}
|
||||
} else {
|
||||
callback(path.join(dir, f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Process all markdown files
|
||||
let updatedCount = 0;
|
||||
const updatedFiles = [];
|
||||
let updatedCount = 0
|
||||
const updatedFiles = []
|
||||
|
||||
walkDir('.', (filepath) => {
|
||||
if (filepath.endsWith('.md')) {
|
||||
let content = fs.readFileSync(filepath, 'utf8');
|
||||
const originalContent = content;
|
||||
|
||||
// For each file to update, fix references
|
||||
filesToUpdate.forEach(filename => {
|
||||
// Escape special regex characters in filename
|
||||
const escapedFile = filename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
// Pattern 1: ![[filename]] without path
|
||||
const pattern1 = new RegExp(`!\\[\\[${escapedFile}\\]\\]`, 'g');
|
||||
content = content.replace(pattern1, `![[05 Attachments/Organized/${filename}]]`);
|
||||
|
||||
// Pattern 2: ![[05 Attachments/filename]] (file in root being moved)
|
||||
const pattern2 = new RegExp(`!\\[\\[05 Attachments/${escapedFile}\\]\\]`, 'g');
|
||||
content = content.replace(pattern2, `![[05 Attachments/Organized/${filename}]]`);
|
||||
|
||||
// Pattern 3: [[filename]] without ! (for PDFs and other non-embedded links)
|
||||
// Only if not already pointing to Organized
|
||||
const pattern3 = new RegExp(`\\[\\[${escapedFile}\\]\\]`, 'g');
|
||||
const pattern3Organized = new RegExp(`\\[\\[05 Attachments/Organized/${escapedFile}\\]\\]`, 'g');
|
||||
|
||||
// Only replace if not already pointing to Organized and not preceded by !
|
||||
if (!pattern3Organized.test(content)) {
|
||||
content = content.replace(pattern3, `[[05 Attachments/Organized/${filename}]]`);
|
||||
}
|
||||
|
||||
// Pattern 4: [[05 Attachments/filename]] without !
|
||||
const pattern4 = new RegExp(`\\[\\[05 Attachments/${escapedFile}\\]\\]`, 'g');
|
||||
content = content.replace(pattern4, `[[05 Attachments/Organized/${filename}]]`);
|
||||
});
|
||||
|
||||
// Write back if changed
|
||||
if (content !== originalContent) {
|
||||
fs.writeFileSync(filepath, content, 'utf8');
|
||||
updatedFiles.push(filepath);
|
||||
updatedCount++;
|
||||
}
|
||||
if (filepath.endsWith('.md')) {
|
||||
let content = fs.readFileSync(filepath, 'utf8')
|
||||
const originalContent = content
|
||||
|
||||
// For each file to update, fix references
|
||||
filesToUpdate.forEach((filename) => {
|
||||
// Escape special regex characters in filename
|
||||
const escapedFile = filename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
|
||||
// Pattern 1: ![[filename]] without path
|
||||
const pattern1 = new RegExp(`!\\[\\[${escapedFile}\\]\\]`, 'g')
|
||||
content = content.replace(
|
||||
pattern1,
|
||||
`![[05 Attachments/Organized/${filename}]]`,
|
||||
)
|
||||
|
||||
// Pattern 2: ![[05 Attachments/filename]] (file in root being moved)
|
||||
const pattern2 = new RegExp(
|
||||
`!\\[\\[05 Attachments/${escapedFile}\\]\\]`,
|
||||
'g',
|
||||
)
|
||||
content = content.replace(
|
||||
pattern2,
|
||||
`![[05 Attachments/Organized/${filename}]]`,
|
||||
)
|
||||
|
||||
// Pattern 3: [[filename]] without ! (for PDFs and other non-embedded links)
|
||||
// Only if not already pointing to Organized
|
||||
const pattern3 = new RegExp(`\\[\\[${escapedFile}\\]\\]`, 'g')
|
||||
const pattern3Organized = new RegExp(
|
||||
`\\[\\[05 Attachments/Organized/${escapedFile}\\]\\]`,
|
||||
'g',
|
||||
)
|
||||
|
||||
// Only replace if not already pointing to Organized and not preceded by !
|
||||
if (!pattern3Organized.test(content)) {
|
||||
content = content.replace(
|
||||
pattern3,
|
||||
`[[05 Attachments/Organized/${filename}]]`,
|
||||
)
|
||||
}
|
||||
|
||||
// Pattern 4: [[05 Attachments/filename]] without !
|
||||
const pattern4 = new RegExp(
|
||||
`\\[\\[05 Attachments/${escapedFile}\\]\\]`,
|
||||
'g',
|
||||
)
|
||||
content = content.replace(
|
||||
pattern4,
|
||||
`[[05 Attachments/Organized/${filename}]]`,
|
||||
)
|
||||
})
|
||||
|
||||
// Write back if changed
|
||||
if (content !== originalContent) {
|
||||
fs.writeFileSync(filepath, content, 'utf8')
|
||||
updatedFiles.push(filepath)
|
||||
updatedCount++
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
// Report results
|
||||
if (updatedCount > 0) {
|
||||
console.log(`\nUpdated ${updatedCount} files:`);
|
||||
updatedFiles.forEach(file => console.log(` - ${file}`));
|
||||
console.log(`\nUpdated ${updatedCount} files:`)
|
||||
updatedFiles.forEach((file) => console.log(` - ${file}`))
|
||||
} else {
|
||||
console.log('\nNo files needed updating');
|
||||
console.log('\nNo files needed updating')
|
||||
}
|
||||
|
||||
console.log('\nDone!');
|
||||
console.log('\nDone!')
|
||||
|
||||
Reference in New Issue
Block a user