chore: remove dead migration and one-off scripts
This commit is contained in:
@@ -1,69 +0,0 @@
|
|||||||
# Formatter Replacement Progress
|
|
||||||
|
|
||||||
## Components Completed ✅
|
|
||||||
1. DebtBreakdown.svelte - Replaced formatCurrency function
|
|
||||||
2. EnhancedBalance.svelte - Replaced formatCurrency function (with Math.abs wrapper)
|
|
||||||
|
|
||||||
## Remaining Files to Update
|
|
||||||
|
|
||||||
### Components (3 files)
|
|
||||||
- [ ] PaymentModal.svelte - Has formatCurrency function
|
|
||||||
- [ ] SplitMethodSelector.svelte - Has inline .toFixed() calls
|
|
||||||
- [ ] BarChart.svelte - Has inline .toFixed() calls
|
|
||||||
- [ ] IngredientsPage.svelte - Has .toFixed() for recipe calculations
|
|
||||||
|
|
||||||
### Cospend Pages (7 files)
|
|
||||||
- [ ] routes/cospend/+page.svelte - Has formatCurrency function
|
|
||||||
- [ ] routes/cospend/payments/+page.svelte - Has formatCurrency function
|
|
||||||
- [ ] routes/cospend/payments/view/[id]/+page.svelte - Has formatCurrency and .toFixed()
|
|
||||||
- [ ] routes/cospend/payments/add/+page.svelte - Has .toFixed() and .toLocaleString()
|
|
||||||
- [ ] routes/cospend/payments/edit/[id]/+page.svelte - Has multiple .toFixed() calls
|
|
||||||
- [ ] routes/cospend/recurring/+page.svelte - Has formatCurrency function
|
|
||||||
- [ ] routes/cospend/recurring/edit/[id]/+page.svelte - Has .toFixed() and .toLocaleString()
|
|
||||||
- [ ] routes/cospend/settle/+page.svelte - Has formatCurrency function
|
|
||||||
|
|
||||||
## Replacement Strategy
|
|
||||||
|
|
||||||
### Pattern 1: Identical formatCurrency functions
|
|
||||||
```typescript
|
|
||||||
// OLD
|
|
||||||
function formatCurrency(amount) {
|
|
||||||
return new Intl.NumberFormat('de-CH', {
|
|
||||||
style: 'currency',
|
|
||||||
currency: 'CHF'
|
|
||||||
}).format(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NEW
|
|
||||||
import { formatCurrency } from '$lib/utils/formatters';
|
|
||||||
// Usage: formatCurrency(amount, 'CHF', 'de-CH')
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pattern 2: .toFixed() for currency display
|
|
||||||
```typescript
|
|
||||||
// OLD
|
|
||||||
{payment.amount.toFixed(2)}
|
|
||||||
|
|
||||||
// NEW
|
|
||||||
import { formatNumber } from '$lib/utils/formatters';
|
|
||||||
{formatNumber(payment.amount, 2, 'de-CH')}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pattern 3: .toLocaleString() for dates
|
|
||||||
```typescript
|
|
||||||
// OLD
|
|
||||||
nextDate.toLocaleString('de-CH', { weekday: 'long', ... })
|
|
||||||
|
|
||||||
// NEW
|
|
||||||
import { formatDateTime } from '$lib/utils/formatters';
|
|
||||||
formatDateTime(nextDate, 'de-CH', { weekday: 'long', ... })
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pattern 4: Exchange rate display (4 decimals)
|
|
||||||
```typescript
|
|
||||||
// OLD
|
|
||||||
{exchangeRate.toFixed(4)}
|
|
||||||
|
|
||||||
// NEW
|
|
||||||
{formatNumber(exchangeRate, 4, 'de-CH')}
|
|
||||||
```
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Script to replace inline formatCurrency functions with shared formatter utilities
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
files_to_update = [
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/+page.svelte",
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/payments/+page.svelte",
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/payments/view/[id]/+page.svelte",
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/recurring/+page.svelte",
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/settle/+page.svelte",
|
|
||||||
]
|
|
||||||
|
|
||||||
def process_file(filepath):
|
|
||||||
print(f"Processing: {filepath}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(filepath, 'r', encoding='utf-8') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
original_content = content
|
|
||||||
|
|
||||||
# Check if already has the import
|
|
||||||
has_formatter_import = 'from \'$lib/utils/formatters\'' in content or 'from "$lib/utils/formatters"' in content
|
|
||||||
|
|
||||||
# Find the <script> tag
|
|
||||||
script_match = re.search(r'(<script[^>]*>)', content)
|
|
||||||
if not script_match:
|
|
||||||
print(f" ⚠️ No <script> tag found")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Add import if not present
|
|
||||||
if not has_formatter_import:
|
|
||||||
script_tag = script_match.group(1)
|
|
||||||
# Find where to insert (after <script> tag)
|
|
||||||
script_end = script_match.end()
|
|
||||||
|
|
||||||
# Get existing imports to find the right place
|
|
||||||
imports_section_match = re.search(r'<script[^>]*>(.*?)(?:\n\n|\n export|\n let)', content, re.DOTALL)
|
|
||||||
if imports_section_match:
|
|
||||||
imports_end = imports_section_match.end() - len(imports_section_match.group(0).split('\n')[-1])
|
|
||||||
insert_pos = imports_end
|
|
||||||
else:
|
|
||||||
insert_pos = script_end
|
|
||||||
|
|
||||||
new_import = "\n import { formatCurrency } from '$lib/utils/formatters';"
|
|
||||||
content = content[:insert_pos] + new_import + content[insert_pos:]
|
|
||||||
print(f" ✓ Added import")
|
|
||||||
|
|
||||||
# Remove the formatCurrency function definition
|
|
||||||
# Pattern for the function with different variations
|
|
||||||
patterns = [
|
|
||||||
r'\n function formatCurrency\(amount\) \{\n return new Intl\.NumberFormat\(\'de-CH\',\s*\{\n\s*style:\s*\'currency\',\n\s*currency:\s*\'CHF\'\n\s*\}\)\.format\(amount\);\n \}',
|
|
||||||
r'\n function formatCurrency\(amount,\s*currency\s*=\s*\'CHF\'\) \{\n return new Intl\.NumberFormat\(\'de-CH\',\s*\{\n\s*style:\s*\'currency\',\n\s*currency:\s*currency\n\s*\}\)\.format\(amount\);\n \}',
|
|
||||||
]
|
|
||||||
|
|
||||||
for pattern in patterns:
|
|
||||||
if re.search(pattern, content):
|
|
||||||
content = re.sub(pattern, '', content)
|
|
||||||
print(f" ✓ Removed formatCurrency function")
|
|
||||||
break
|
|
||||||
|
|
||||||
# Check if content changed
|
|
||||||
if content != original_content:
|
|
||||||
with open(filepath, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(content)
|
|
||||||
print(f" ✅ Updated successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f" ⚠️ No changes needed")
|
|
||||||
return False
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f" ❌ Error: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def main():
|
|
||||||
print("=" * 60)
|
|
||||||
print("Replacing formatCurrency functions with shared utilities")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
success_count = 0
|
|
||||||
for filepath in files_to_update:
|
|
||||||
if process_file(filepath):
|
|
||||||
success_count += 1
|
|
||||||
print()
|
|
||||||
|
|
||||||
print("=" * 60)
|
|
||||||
print(f"Summary: {success_count}/{len(files_to_update)} files updated")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
import { dbConnect } from '../src/utils/db';
|
|
||||||
import { Exercise } from '../src/models/Exercise';
|
|
||||||
|
|
||||||
// ExerciseDB API configuration
|
|
||||||
const RAPIDAPI_KEY = process.env.RAPIDAPI_KEY || 'your-rapidapi-key-here';
|
|
||||||
const RAPIDAPI_HOST = 'exercisedb.p.rapidapi.com';
|
|
||||||
const BASE_URL = 'https://exercisedb.p.rapidapi.com';
|
|
||||||
|
|
||||||
interface ExerciseDBExercise {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
gifUrl: string;
|
|
||||||
bodyPart: string;
|
|
||||||
equipment: string;
|
|
||||||
target: string;
|
|
||||||
secondaryMuscles: string[];
|
|
||||||
instructions: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchFromExerciseDB(endpoint: string): Promise<any> {
|
|
||||||
const response = await fetch(`${BASE_URL}${endpoint}`, {
|
|
||||||
headers: {
|
|
||||||
'X-RapidAPI-Key': RAPIDAPI_KEY,
|
|
||||||
'X-RapidAPI-Host': RAPIDAPI_HOST
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to fetch from ExerciseDB: ${response.status} ${response.statusText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function scrapeAllExercises(): Promise<void> {
|
|
||||||
console.log('🚀 Starting ExerciseDB scraping...');
|
|
||||||
|
|
||||||
try {
|
|
||||||
await dbConnect();
|
|
||||||
console.log('✅ Connected to database');
|
|
||||||
|
|
||||||
// Fetch all exercises
|
|
||||||
console.log('📡 Fetching exercises from ExerciseDB...');
|
|
||||||
const exercises: ExerciseDBExercise[] = await fetchFromExerciseDB('/exercises?limit=2000');
|
|
||||||
|
|
||||||
console.log(`📊 Found ${exercises.length} exercises`);
|
|
||||||
|
|
||||||
let imported = 0;
|
|
||||||
let skipped = 0;
|
|
||||||
let errors = 0;
|
|
||||||
|
|
||||||
for (const exercise of exercises) {
|
|
||||||
try {
|
|
||||||
// Check if exercise already exists
|
|
||||||
const existingExercise = await Exercise.findOne({ exerciseId: exercise.id });
|
|
||||||
|
|
||||||
if (existingExercise) {
|
|
||||||
skipped++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine difficulty based on equipment and complexity
|
|
||||||
let difficulty: 'beginner' | 'intermediate' | 'advanced' = 'intermediate';
|
|
||||||
|
|
||||||
if (exercise.equipment === 'body weight') {
|
|
||||||
difficulty = 'beginner';
|
|
||||||
} else if (exercise.equipment.includes('barbell') || exercise.equipment.includes('olympic')) {
|
|
||||||
difficulty = 'advanced';
|
|
||||||
} else if (exercise.equipment.includes('dumbbell') || exercise.equipment.includes('cable')) {
|
|
||||||
difficulty = 'intermediate';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new exercise
|
|
||||||
const newExercise = new Exercise({
|
|
||||||
exerciseId: exercise.id,
|
|
||||||
name: exercise.name,
|
|
||||||
gifUrl: exercise.gifUrl,
|
|
||||||
bodyPart: exercise.bodyPart.toLowerCase(),
|
|
||||||
equipment: exercise.equipment.toLowerCase(),
|
|
||||||
target: exercise.target.toLowerCase(),
|
|
||||||
secondaryMuscles: exercise.secondaryMuscles.map(m => m.toLowerCase()),
|
|
||||||
instructions: exercise.instructions,
|
|
||||||
difficulty,
|
|
||||||
isActive: true
|
|
||||||
});
|
|
||||||
|
|
||||||
await newExercise.save();
|
|
||||||
imported++;
|
|
||||||
|
|
||||||
if (imported % 100 === 0) {
|
|
||||||
console.log(`⏳ Imported ${imported} exercises...`);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`❌ Error importing exercise ${exercise.name}:`, error);
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('✅ Scraping completed!');
|
|
||||||
console.log(`📈 Summary: ${imported} imported, ${skipped} skipped, ${errors} errors`);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('💥 Scraping failed:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateExistingExercises(): Promise<void> {
|
|
||||||
console.log('🔄 Updating existing exercises...');
|
|
||||||
|
|
||||||
try {
|
|
||||||
await dbConnect();
|
|
||||||
|
|
||||||
const exercises: ExerciseDBExercise[] = await fetchFromExerciseDB('/exercises?limit=2000');
|
|
||||||
|
|
||||||
let updated = 0;
|
|
||||||
|
|
||||||
for (const exercise of exercises) {
|
|
||||||
try {
|
|
||||||
const existingExercise = await Exercise.findOne({ exerciseId: exercise.id });
|
|
||||||
|
|
||||||
if (existingExercise) {
|
|
||||||
// Update with new data from API
|
|
||||||
existingExercise.name = exercise.name;
|
|
||||||
existingExercise.gifUrl = exercise.gifUrl;
|
|
||||||
existingExercise.bodyPart = exercise.bodyPart.toLowerCase();
|
|
||||||
existingExercise.equipment = exercise.equipment.toLowerCase();
|
|
||||||
existingExercise.target = exercise.target.toLowerCase();
|
|
||||||
existingExercise.secondaryMuscles = exercise.secondaryMuscles.map(m => m.toLowerCase());
|
|
||||||
existingExercise.instructions = exercise.instructions;
|
|
||||||
|
|
||||||
await existingExercise.save();
|
|
||||||
updated++;
|
|
||||||
|
|
||||||
if (updated % 100 === 0) {
|
|
||||||
console.log(`⏳ Updated ${updated} exercises...`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`❌ Error updating exercise ${exercise.name}:`, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`✅ Updated ${updated} exercises`);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('💥 Update failed:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getExerciseStats(): Promise<void> {
|
|
||||||
try {
|
|
||||||
await dbConnect();
|
|
||||||
|
|
||||||
const totalExercises = await Exercise.countDocuments();
|
|
||||||
const activeExercises = await Exercise.countDocuments({ isActive: true });
|
|
||||||
|
|
||||||
const bodyParts = await Exercise.distinct('bodyPart');
|
|
||||||
const equipment = await Exercise.distinct('equipment');
|
|
||||||
const targets = await Exercise.distinct('target');
|
|
||||||
|
|
||||||
console.log('📊 Exercise Database Stats:');
|
|
||||||
console.log(` Total exercises: ${totalExercises}`);
|
|
||||||
console.log(` Active exercises: ${activeExercises}`);
|
|
||||||
console.log(` Body parts: ${bodyParts.length} (${bodyParts.join(', ')})`);
|
|
||||||
console.log(` Equipment types: ${equipment.length}`);
|
|
||||||
console.log(` Target muscles: ${targets.length}`);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('💥 Stats failed:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CLI interface
|
|
||||||
const command = process.argv[2];
|
|
||||||
|
|
||||||
switch (command) {
|
|
||||||
case 'scrape':
|
|
||||||
scrapeAllExercises()
|
|
||||||
.then(() => process.exit(0))
|
|
||||||
.catch(() => process.exit(1));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'update':
|
|
||||||
updateExistingExercises()
|
|
||||||
.then(() => process.exit(0))
|
|
||||||
.catch(() => process.exit(1));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'stats':
|
|
||||||
getExerciseStats()
|
|
||||||
.then(() => process.exit(0))
|
|
||||||
.catch(() => process.exit(1));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
console.log('Usage: tsx scripts/scrape-exercises.ts [command]');
|
|
||||||
console.log('Commands:');
|
|
||||||
console.log(' scrape - Import all exercises from ExerciseDB');
|
|
||||||
console.log(' update - Update existing exercises with latest data');
|
|
||||||
console.log(' stats - Show database statistics');
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Script to update formatCurrency calls to include CHF and de-CH parameters
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
files_to_update = [
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/+page.svelte",
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/payments/+page.svelte",
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/payments/view/[id]/+page.svelte",
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/recurring/+page.svelte",
|
|
||||||
"/home/alex/.local/src/homepage/src/routes/cospend/settle/+page.svelte",
|
|
||||||
]
|
|
||||||
|
|
||||||
def process_file(filepath):
|
|
||||||
print(f"Processing: {filepath}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(filepath, 'r', encoding='utf-8') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
original_content = content
|
|
||||||
changes = 0
|
|
||||||
|
|
||||||
# Pattern 1: formatCurrency(amount) -> formatCurrency(amount, 'CHF', 'de-CH')
|
|
||||||
# But skip if already has parameters
|
|
||||||
def replace_single_param(match):
|
|
||||||
amount = match.group(1)
|
|
||||||
# Check if amount already contains currency parameter (contains comma followed by quote)
|
|
||||||
if ", '" in amount or ', "' in amount:
|
|
||||||
return match.group(0) # Already has parameters, skip
|
|
||||||
return f"formatCurrency({amount}, 'CHF', 'de-CH')"
|
|
||||||
|
|
||||||
content, count1 = re.subn(
|
|
||||||
r'formatCurrency\(([^)]+)\)',
|
|
||||||
replace_single_param,
|
|
||||||
content
|
|
||||||
)
|
|
||||||
changes += count1
|
|
||||||
|
|
||||||
if changes > 0:
|
|
||||||
with open(filepath, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(content)
|
|
||||||
print(f" ✅ Updated {changes} formatCurrency calls")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f" ⚠️ No changes needed")
|
|
||||||
return False
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f" ❌ Error: {e}")
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
return False
|
|
||||||
|
|
||||||
def main():
|
|
||||||
print("=" * 60)
|
|
||||||
print("Updating formatCurrency calls with CHF and de-CH params")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
success_count = 0
|
|
||||||
for filepath in files_to_update:
|
|
||||||
if process_file(filepath):
|
|
||||||
success_count += 1
|
|
||||||
print()
|
|
||||||
|
|
||||||
print("=" * 60)
|
|
||||||
print(f"Summary: {success_count}/{len(files_to_update)} files updated")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user