this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Testing enhancements to the bot and queue manager.

+83 -4
+3
README.md
··· 161 161 - `/send` - Post the next image in the queue immediately 162 162 - `/schedule [cron]` - Set posting schedule using cron syntax 163 163 - `/setcount [number]` - Set number of images per post interval 164 + - `/shuffle` - Toggle shuffle mode (randomizes queue after each post) 164 165 - `/clear` - Clear the entire queue 165 166 - `/cleancache` - Clean expired items from media cache 166 167 - `/announce` - Create a new announcement ··· 179 180 - **Item Removal**: Remove specific items from the queue with a single click 180 181 - **Reordering**: Move any item to the top of the queue to be posted next 181 182 - **Pagination**: Easily navigate through pages of queued items 183 + - **Shuffle Mode**: Automatically randomize the queue after each post with `/shuffle` command 182 184 183 185 The interface shows important information about each queued item including: 184 186 - Item position in queue ··· 206 208 - [x] SoFurry Scraper 207 209 - [x] Weasyl Scraper 208 210 - [x] Interactive Graphical Queue Manager 211 + - [x] Add shuffle mode for queue 209 212 - [ ] Add perceptual hashing 210 213 - [ ] Redo Queue Manager 211 214 - [ ] Redo Bluesky Module
+22 -3
bot/telegramBot.js
··· 47 47 /cleancache - Clean expired items from media cache 48 48 /announce - Create a new announcement 49 49 /announcements - Manage existing announcements 50 + /shuffle - Toggle shuffle mode (shuffles queue after each post) 50 51 /update - Update bot from GitHub repository (owner only) 51 52 52 53 Send any link to a supported site to add it to the queue. ··· 243 244 244 245 this.bot.sendMessage(chatId, `Queue cleared (${queueLength} items removed).`); 245 246 }); 246 - 247 + 248 + // Command to toggle shuffle mode 249 + this.bot.onText(/\/shuffle/, async (msg) => { 250 + const chatId = msg.chat.id; 251 + 252 + if (!this.isAuthorized(msg.from.id)) { 253 + this.bot.sendMessage(chatId, 'You are not authorized to use this command.'); 254 + return; 255 + } 256 + 257 + const isEnabled = queueManager.toggleShuffleMode(); 258 + 259 + if (isEnabled) { 260 + this.bot.sendMessage(chatId, '🔀 Shuffle mode enabled! Queue will be randomized after each post.'); 261 + } else { 262 + this.bot.sendMessage(chatId, '📋 Shuffle mode disabled. Queue will maintain its order.'); 263 + } 264 + }); 265 + 247 266 // Command to manually trigger an update from GitHub 248 267 this.bot.onText(/\/update/, async (msg) => { 249 268 const chatId = msg.chat.id; ··· 360 379 chatId, 361 380 "Here's a preview of your announcement with formatting:", 362 381 { parse_mode: 'Markdown' } 363 - ); 382 + ), 364 383 365 384 // Send the actual preview 366 385 await this.bot.sendMessage( ··· 815 834 ] 816 835 } 817 836 } 818 - ); 837 + ); 819 838 } 820 839 break; 821 840 }
+58 -1
queue/queueManager.js
··· 14 14 this.autoSaveInterval = null; 15 15 this.queueData = { queue: [] }; 16 16 this.postServices = ['telegram']; 17 + this.shuffleMode = false; // Whether queue should be shuffled after item removal 17 18 18 19 // Add Discord to services if enabled 19 20 if (config.discord?.enabled) { ··· 233 234 if (allPosted) { 234 235 const removed = this.queueData.queue.splice(index, 1)[0]; 235 236 console.log(`All services posted item: ${removed.title}, removed from queue`); 237 + 238 + // If shuffle mode is enabled and there are items remaining in the queue, shuffle them 239 + if (this.shuffleMode && this.queueData.queue.length > 1) { 240 + await this.shuffleQueue(); 241 + } else { 242 + await this.saveQueueToDisk(); 243 + } 244 + } else { 245 + await this.saveQueueToDisk(); 236 246 } 237 247 238 - await this.saveQueueToDisk(); 239 248 return true; 240 249 } catch (error) { 241 250 console.error('Error marking item as posted:', error); ··· 409 418 async shutdown() { 410 419 this.stopScheduler(); 411 420 return this.saveQueueToDisk(); 421 + } 422 + 423 + /** 424 + * Toggle shuffle mode on/off 425 + * @returns {boolean} - New state of shuffle mode 426 + */ 427 + toggleShuffleMode() { 428 + this.shuffleMode = !this.shuffleMode; 429 + console.log(`Queue shuffle mode ${this.shuffleMode ? 'enabled' : 'disabled'}`); 430 + return this.shuffleMode; 431 + } 432 + 433 + /** 434 + * Get current state of shuffle mode 435 + * @returns {boolean} - Current state of shuffle mode 436 + */ 437 + isShuffleModeEnabled() { 438 + return this.shuffleMode; 439 + } 440 + 441 + /** 442 + * Shuffle the remaining items in the queue using Fisher-Yates algorithm 443 + * @returns {Promise<boolean>} - Whether shuffle was successful 444 + */ 445 + async shuffleQueue() { 446 + try { 447 + if (this.queueData.queue.length <= 1) { 448 + // No need to shuffle if queue is empty or has only one item 449 + return true; 450 + } 451 + 452 + const queue = this.queueData.queue; 453 + 454 + // Fisher-Yates (Knuth) shuffle algorithm 455 + for (let i = queue.length - 1; i > 0; i--) { 456 + // Generate random index between 0 and i (inclusive) 457 + const j = Math.floor(Math.random() * (i + 1)); 458 + // Swap elements at i and j 459 + [queue[i], queue[j]] = [queue[j], queue[i]]; 460 + } 461 + 462 + console.log(`Queue shuffled (${queue.length} items)`); 463 + await this.saveQueueToDisk(); 464 + return true; 465 + } catch (error) { 466 + console.error('Error shuffling queue:', error); 467 + return false; 468 + } 412 469 } 413 470 } 414 471