|
| 1 | +require('node-env-file')(require('path').resolve __dirname, '../.env') |
| 2 | +{ MongoClient } = require 'mongodb' |
| 3 | +path = require 'path' |
| 4 | +{ indexForSearch } = require '../src/api/apps/articles/model/distribute' |
| 5 | +Article = require '../src/api/apps/articles/model/index.js' |
| 6 | +search = require '../src/api/lib/search_client' |
| 7 | +asyncLib = require 'async' |
| 8 | + |
| 9 | +env = require 'node-env-file' |
| 10 | +switch process.env.NODE_ENV |
| 11 | + when 'test' then env path.resolve __dirname, '../.env.test' |
| 12 | + when 'production', 'staging' then '' |
| 13 | + else env path.resolve __dirname, '../.env' |
| 14 | + |
| 15 | +# Check for dry-run flag |
| 16 | +isDryRun = process.argv.includes('--dry-run') |
| 17 | + |
| 18 | +console.log('=' .repeat(80)) |
| 19 | +console.log('REINDEXING VIDEO ARTICLES') |
| 20 | +if isDryRun |
| 21 | + console.log('🔍 DRY RUN MODE - No changes will be made') |
| 22 | +console.log('=' .repeat(80)) |
| 23 | +console.log('Environment:', process.env.NODE_ENV || 'development') |
| 24 | +console.log('MongoDB URL:', process.env.MONGOHQ_URL ? 'Configured' : 'NOT CONFIGURED') |
| 25 | +console.log('Search Configuration:') |
| 26 | +console.log(' - URL:', process.env.SEARCH_URL || 'NOT CONFIGURED') |
| 27 | +console.log(' - Index Name:', search.index) |
| 28 | +console.log(' - Index Suffix:', process.env.SEARCH_INDEX_SUFFIX || 'production') |
| 29 | +if isDryRun |
| 30 | + console.log('Mode: DRY RUN (use without --dry-run flag to perform actual reindexing)') |
| 31 | +console.log('=' .repeat(80)) |
| 32 | +console.log() |
| 33 | + |
| 34 | +main = -> |
| 35 | + startTime = Date.now() |
| 36 | + console.log('Connecting to MongoDB...') |
| 37 | + |
| 38 | + client = new MongoClient(process.env.MONGOHQ_URL) |
| 39 | + client.connect() |
| 40 | + .then (client) -> |
| 41 | + console.log('✓ Connected to MongoDB successfully') |
| 42 | + db = client.db() |
| 43 | + console.log('✓ Database connection established') |
| 44 | + return db.collection('articles') |
| 45 | + .then (articlesCollection) -> |
| 46 | + console.log('✓ Articles collection accessed') |
| 47 | + console.log('Fetching video articles (published: true, layout: video)...') |
| 48 | + |
| 49 | + # Find only published video articles |
| 50 | + articlesCollection.find({ |
| 51 | + layout: 'video' |
| 52 | + published: true |
| 53 | + }).sort({ published_at: -1 }).toArray() |
| 54 | + .then (articles) -> |
| 55 | + console.log('✓ Found ' + articles.length + ' video articles to reindex') |
| 56 | + console.log() |
| 57 | + |
| 58 | + if articles.length is 0 |
| 59 | + console.log('No video articles found. Exiting.') |
| 60 | + return client.close().then -> process.exit(0) |
| 61 | + |
| 62 | + # Show sample of articles to be reindexed |
| 63 | + console.log('Articles to be reindexed:') |
| 64 | + for article in articles |
| 65 | + hasMedia = article.media?.url? |
| 66 | + status = if hasMedia then '✓' else '✗ NO MEDIA URL' |
| 67 | + console.log(" #{status} #{article.title} (#{article._id})") |
| 68 | + console.log() |
| 69 | + |
| 70 | + if isDryRun |
| 71 | + console.log('🔍 DRY RUN MODE: Skipping actual indexing') |
| 72 | + console.log('✅ Connection successful!') |
| 73 | + console.log('✅ Found ' + articles.length + ' video articles that would be reindexed') |
| 74 | + console.log() |
| 75 | + console.log('To perform actual reindexing, run without the --dry-run flag') |
| 76 | + return client.close().then -> process.exit(0) |
| 77 | + |
| 78 | + console.log('Starting indexing process...') |
| 79 | + console.log() |
| 80 | + |
| 81 | + new Promise (resolve, reject) -> |
| 82 | + processedCount = 0 |
| 83 | + errorCount = 0 |
| 84 | + successCount = 0 |
| 85 | + |
| 86 | + asyncLib.mapSeries articles, (article, cb) -> |
| 87 | + processedCount++ |
| 88 | + console.log("=" .repeat(80)) |
| 89 | + console.log("[#{processedCount}/#{articles.length}] Processing: #{article.title}") |
| 90 | + console.log(" Article ID: #{article._id}") |
| 91 | + console.log(" Layout: #{article.layout}") |
| 92 | + console.log(" Published: #{article.published}") |
| 93 | + console.log(" Has media.url: #{!!article.media?.url}") |
| 94 | + |
| 95 | + indexWorker article, (err) -> |
| 96 | + if err |
| 97 | + errorCount++ |
| 98 | + console.error(" ✗ ERROR indexing article: #{err.message}") |
| 99 | + else |
| 100 | + successCount++ |
| 101 | + console.log(" ✓ Successfully indexed") |
| 102 | + console.log() |
| 103 | + cb(null) # Continue even if there's an error |
| 104 | + , (err, results) -> |
| 105 | + resolve({ results, errorCount, successCount, processedCount }) |
| 106 | + .then ({ results, errorCount, successCount, processedCount }) -> |
| 107 | + endTime = Date.now() |
| 108 | + duration = Math.round((endTime - startTime) / 1000) |
| 109 | + |
| 110 | + console.log('=' .repeat(80)) |
| 111 | + console.log('REINDEXING COMPLETE') |
| 112 | + console.log('=' .repeat(80)) |
| 113 | + console.log('📊 Summary:') |
| 114 | + console.log(" - Total processed: #{processedCount}") |
| 115 | + console.log(" - Successfully indexed: #{successCount}") |
| 116 | + console.log(" - Errors: #{errorCount}") |
| 117 | + console.log(" - Duration: #{duration} seconds") |
| 118 | + console.log('=' .repeat(80)) |
| 119 | + console.log() |
| 120 | + console.log('Closing database connection...') |
| 121 | + |
| 122 | + client.close() |
| 123 | + .then -> |
| 124 | + console.log('✓ Database connection closed successfully') |
| 125 | + console.log() |
| 126 | + console.log('✅ Script completed!') |
| 127 | + if errorCount > 0 |
| 128 | + console.log('⚠️ Some errors occurred. Check logs above.') |
| 129 | + process.exit(1) |
| 130 | + else |
| 131 | + process.exit(0) |
| 132 | + .catch (err) -> |
| 133 | + console.error('✗ Error closing database connection:', err) |
| 134 | + process.exit(1) |
| 135 | + .catch (err) -> |
| 136 | + console.error('=' .repeat(80)) |
| 137 | + console.error('✗ FATAL ERROR') |
| 138 | + console.error('=' .repeat(80)) |
| 139 | + console.error('Error:', err.message) |
| 140 | + console.error('Stack:', err.stack) |
| 141 | + console.error('=' .repeat(80)) |
| 142 | + |
| 143 | + client.close() |
| 144 | + .then -> process.exit(1) |
| 145 | + .catch -> process.exit(1) |
| 146 | + |
| 147 | +indexWorker = (article, cb) -> |
| 148 | + try |
| 149 | + articlePresent = Article.present(article) |
| 150 | + |
| 151 | + indexForSearch articlePresent, (err) -> |
| 152 | + if err |
| 153 | + cb(err) |
| 154 | + else |
| 155 | + cb() |
| 156 | + catch err |
| 157 | + cb(err) |
| 158 | + |
| 159 | +console.log('Initializing video article reindexing...') |
| 160 | +if isDryRun |
| 161 | + console.log('Running in DRY RUN mode - no changes will be made') |
| 162 | +console.log() |
| 163 | +main() |
0 commit comments