Refactor findChar to utils - Refactor and move finChar to utils, instead of slashcommands function - Refactor scrapers to use actual init functionality
| @@ -230,7 +230,7 @@ import { MacrosParser, evaluateMacros, getLastMessageId } from './scripts/macros | ||
| 230 | 230 | import { currentUser, setUserControls } from './scripts/user.js'; |
| 231 | 231 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js'; |
| 232 | 232 | import { renderTemplate, renderTemplateAsync } from './scripts/templates.js'; |
| 233 | 233 | import { initScrapers, ScraperManager } from './scripts/scrapers.js'; |
| 234 | 234 | import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js'; |
| 235 | 235 | import { SlashCommand } from './scripts/slash-commands/SlashCommand.js'; |
| 236 | 236 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js'; |
| @@ -959,6 +959,7 @@ async function firstLoadInit() { | ||
| 959 | 959 | initCfg(); |
| 960 | 960 | initLogprobs(); |
| 961 | 961 | initInputMarkdown(); |
| 962 | + initScrapers(); | |
| 962 | 963 | doDailyExtensionUpdatesCheck(); |
| 963 | 964 | await hideLoader(); |
| 964 | 965 | await fixViewport(); |
| @@ -2,7 +2,7 @@ import { callPopup, eventSource, event_types, generateRaw, getRequestHeaders, ma | ||
| 2 | 2 | import { dragElement, isMobile } from '../../RossAscends-mods.js'; |
| 3 | 3 | import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplateAsync } from '../../extensions.js'; |
| 4 | 4 | import { loadMovingUIState, power_user } from '../../power-user.js'; |
| 5 | 5 | import { onlyUnique, debounce, getCharaFilename, trimToEndSentence, trimToStartSentence, waitUntilCondition, findChar } from '../../utils.js'; |
| 6 | 6 | import { hideMutedSprites } from '../../group-chats.js'; |
| 7 | 7 | import { isJsonSchemaSupported } from '../../textgen-settings.js'; |
| 8 | 8 | import { debounce_timeout } from '../../constants.js'; |
| @@ -12,7 +12,6 @@ import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from ' | ||
| 12 | 12 | import { isFunctionCallingSupported } from '../../openai.js'; |
| 13 | 13 | import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js'; |
| 14 | 14 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 15 | -import { findChar } from '../../slash-commands.js'; | |
| 16 | 15 | export { MODULE_NAME }; |
| 17 | 16 | |
| 18 | 17 | const MODULE_NAME = 'expressions'; |
| @@ -13,6 +13,7 @@ import { isValidUrl } from './utils.js'; | ||
| 13 | 13 | * @property {string} description |
| 14 | 14 | * @property {string} iconClass |
| 15 | 15 | * @property {boolean} iconAvailable |
| 16 | + * @property {() => Promise<void>} [init=null] | |
| 16 | 17 | * @property {() => Promise<boolean>} isAvailable |
| 17 | 18 | * @property {() => Promise<File[]>} scrape |
| 18 | 19 | */ |
| @@ -42,6 +43,10 @@ export class ScraperManager { | ||
| 42 | 43 | return; |
| 43 | 44 | } |
| 44 | 45 | |
| 46 | + if (scraper.init) { | |
| 47 | + scraper.init(); | |
| 48 | + } | |
| 49 | + | |
| 45 | 50 | ScraperManager.#scrapers.push(scraper); |
| 46 | 51 | } |
| 47 | 52 | |
| @@ -462,7 +467,9 @@ class YouTubeScraper { | ||
| 462 | 467 | this.description = 'Download a transcript from a YouTube video.'; |
| 463 | 468 | this.iconClass = 'fa-brands fa-youtube'; |
| 464 | 469 | this.iconAvailable = true; |
| 470 | + } | |
| 465 | 471 | |
| 472 | + async init() { | |
| 466 | 473 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 467 | 474 | name: 'yt-script', |
| 468 | 475 | callback: async (args, url) => { |
| @@ -564,9 +571,11 @@ class YouTubeScraper { | ||
| 564 | 571 | } |
| 565 | 572 | } |
| 566 | 573 | |
| 574 | +export function initScrapers() { | |
| 567 | 575 | ScraperManager.registerDataBankScraper(new FileScraper()); |
| 568 | 576 | ScraperManager.registerDataBankScraper(new Notepad()); |
| 569 | 577 | ScraperManager.registerDataBankScraper(new WebScraper()); |
| 570 | 578 | ScraperManager.registerDataBankScraper(new MediaWikiScraper()); |
| 571 | 579 | ScraperManager.registerDataBankScraper(new FandomScraper()); |
| 572 | 580 | ScraperManager.registerDataBankScraper(new YouTubeScraper()); |
| 581 | +} | |
| @@ -55,7 +55,7 @@ import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockStat | ||
| 55 | 55 | import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; |
| 56 | 56 | import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js'; |
| 57 | 57 | import { decodeTextTokens, getAvailableTokenizers, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, selectTokenizer } from './tokenizers.js'; |
| 58 | 58 | import { debounce, delay, equalsIgnoreCaseAndAccents, findChar, isFalseBoolean, isTrueBoolean, showFontAwesomePicker, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js'; |
| 59 | 59 | import { registerVariableCommands, resolveVariable } from './variables.js'; |
| 60 | 60 | import { background_settings } from './backgrounds.js'; |
| 61 | 61 | import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js'; |
| @@ -68,10 +68,8 @@ import { SlashCommandNamedArgumentAssignment } from './slash-commands/SlashComma | ||
| 68 | 68 | import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js'; |
| 69 | 69 | import { POPUP_TYPE, Popup, callGenericPopup } from './popup.js'; |
| 70 | 70 | import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 71 | -import { SlashCommandDebugController } from './slash-commands/SlashCommandDebugController.js'; | |
| 72 | 71 | import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js'; |
| 73 | 72 | import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js'; |
| 74 | -import { getTagsList } from './tags.js'; | |
| 75 | 73 | export { |
| 76 | 74 | executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand, |
| 77 | 75 | }; |
| @@ -2969,29 +2967,6 @@ async function deleteMessagesByNameCallback(_, name) { | ||
| 2969 | 2967 | return ''; |
| 2970 | 2968 | } |
| 2971 | 2969 | |
| 2972 | -function findCharacterIndex(name) { | |
| 2973 | - const matchTypes = [ | |
| 2974 | - (a, b) => a === b, | |
| 2975 | - (a, b) => a.startsWith(b), | |
| 2976 | - (a, b) => a.includes(b), | |
| 2977 | - ]; | |
| 2978 | - | |
| 2979 | - const exactAvatarMatch = characters.findIndex(x => x.avatar === name); | |
| 2980 | - | |
| 2981 | - if (exactAvatarMatch !== -1) { | |
| 2982 | - return exactAvatarMatch; | |
| 2983 | - } | |
| 2984 | - | |
| 2985 | - for (const matchType of matchTypes) { | |
| 2986 | - const index = characters.findIndex(x => matchType(x.name.toLowerCase(), name.toLowerCase())); | |
| 2987 | - if (index !== -1) { | |
| 2988 | - return index; | |
| 2989 | - } | |
| 2990 | - } | |
| 2991 | - | |
| 2992 | - return -1; | |
| 2993 | -} | |
| 2994 | - | |
| 2995 | 2970 | async function goToCharacterCallback(_, name) { |
| 2996 | 2971 | if (!name) { |
| 2997 | 2972 | console.warn('WARN: No character name provided for /go command'); |
| @@ -3238,77 +3213,6 @@ export function getNameAndAvatarForMessage(character, name = null) { | ||
| 3238 | 3213 | }; |
| 3239 | 3214 | } |
| 3240 | 3215 | |
| 3241 | -/** | |
| 3242 | - * Finds a character by name, with optional filtering and precedence for avatars | |
| 3243 | - * @param {object} [options={}] - The options for the search | |
| 3244 | - * @param {string?} [options.name=null] - The name to search for | |
| 3245 | - * @param {boolean} [options.allowAvatar=true] - Whether to allow searching by avatar | |
| 3246 | - * @param {boolean} [options.insensitive=true] - Whether the search should be case insensitive | |
| 3247 | - * @param {string[]?} [options.filteredByTags=null] - Tags to filter characters by | |
| 3248 | - * @param {boolean} [options.preferCurrentChar=true] - Whether to prefer the current character(s) | |
| 3249 | - * @param {boolean} [options.quiet=false] - Whether to suppress warnings | |
| 3250 | - * @returns {any?} - The found character or null if not found | |
| 3251 | - */ | |
| 3252 | -export function findChar({ name = null, allowAvatar = true, insensitive = true, filteredByTags = null, preferCurrentChar = true, quiet = false } = {}) { | |
| 3253 | - const matches = (char) => (allowAvatar && char.avatar === name) || (insensitive ? equalsIgnoreCaseAndAccents(char.name, name) : char.name === name); | |
| 3254 | - | |
| 3255 | - // Filter characters by tags if provided | |
| 3256 | - let filteredCharacters = characters; | |
| 3257 | - if (filteredByTags) { | |
| 3258 | - filteredCharacters = characters.filter(char => { | |
| 3259 | - const charTags = getTagsList(char.avatar, false); | |
| 3260 | - return filteredByTags.every(tagName => charTags.some(x => x.name == tagName)); | |
| 3261 | - }); | |
| 3262 | - } | |
| 3263 | - | |
| 3264 | - // Get the current character(s) | |
| 3265 | - /** @type {any[]} */ | |
| 3266 | - const currentChars = selected_group ? groups.find(group => group.id === selected_group)?.members.map(member => filteredCharacters.find(char => char.avatar === member)) | |
| 3267 | - : [filteredCharacters.find(char => characters[this_chid]?.avatar === char.avatar)]; | |
| 3268 | - | |
| 3269 | - // If we have a current char and prefer it, return that if it matches | |
| 3270 | - if (preferCurrentChar) { | |
| 3271 | - const preferredCharSearch = currentChars.filter(matches); | |
| 3272 | - if (preferredCharSearch.length > 1) { | |
| 3273 | - if (!quiet) toastr.warning(`Multiple characters found for name "${name}" and given conditions.`); | |
| 3274 | - else console.warn(`Multiple characters found for name "${name}". Returning the first match.`); | |
| 3275 | - } | |
| 3276 | - if (preferredCharSearch.length) { | |
| 3277 | - return preferredCharSearch[0]; | |
| 3278 | - } | |
| 3279 | - } | |
| 3280 | - | |
| 3281 | - // If allowAvatar is true, search by avatar first | |
| 3282 | - if (allowAvatar && name) { | |
| 3283 | - const characterByAvatar = filteredCharacters.find(char => char.avatar === name); | |
| 3284 | - if (characterByAvatar) { | |
| 3285 | - return characterByAvatar; | |
| 3286 | - } | |
| 3287 | - } | |
| 3288 | - | |
| 3289 | - // Search for matching characters by name | |
| 3290 | - const matchingCharacters = name ? filteredCharacters.filter(matches) : filteredCharacters; | |
| 3291 | - if (matchingCharacters.length > 1) { | |
| 3292 | - if (!quiet) toastr.warning(`Multiple characters found for name "${name}" and given conditions.`); | |
| 3293 | - else console.warn(`Multiple characters found for name "${name}". Returning the first match.`); | |
| 3294 | - } | |
| 3295 | - | |
| 3296 | - return matchingCharacters[0] || null; | |
| 3297 | -} | |
| 3298 | - | |
| 3299 | -/** | |
| 3300 | - * Gets the index of a character based on the character object | |
| 3301 | - * @param {object} char - The character object to find the index for | |
| 3302 | - * @throws {Error} If the character is not found | |
| 3303 | - * @returns {number} The index of the character in the characters array | |
| 3304 | - */ | |
| 3305 | -export function getCharIndex(char) { | |
| 3306 | - if (!char) throw new Error('Character is undefined'); | |
| 3307 | - const index = characters.findIndex(c => c.avatar === char.avatar); | |
| 3308 | - if (index === -1) throw new Error(`Character not found: ${char.avatar}`); | |
| 3309 | - return index; | |
| 3310 | -} | |
| 3311 | - | |
| 3312 | 3216 | export async function sendMessageAs(args, text) { |
| 3313 | 3217 | if (!text) { |
| 3314 | 3218 | return ''; |
| @@ -15,7 +15,7 @@ import { | ||
| 15 | 15 | import { FILTER_TYPES, FILTER_STATES, DEFAULT_FILTER_STATE, isFilterState, FilterHelper } from './filters.js'; |
| 16 | 16 | |
| 17 | 17 | import { groupCandidatesFilter, groups, selected_group } from './group-chats.js'; |
| 18 | 18 | import { download, onlyUnique, parseJsonFile, uuidv4, getSortableDelay, flashHighlight, equalsIgnoreCaseAndAccents, includesIgnoreCaseAndAccents, removeFromArray, getFreeName, debounce, findChar } from './utils.js'; |
| 19 | 19 | import { power_user } from './power-user.js'; |
| 20 | 20 | import { SlashCommandParser } from './slash-commands/SlashCommandParser.js'; |
| 21 | 21 | import { SlashCommand } from './slash-commands/SlashCommand.js'; |
| @@ -26,7 +26,6 @@ import { debounce_timeout } from './constants.js'; | ||
| 26 | 26 | import { INTERACTABLE_CONTROL_CLASS } from './keyboard.js'; |
| 27 | 27 | import { commonEnumProviders } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 28 | 28 | import { renderTemplateAsync } from './templates.js'; |
| 29 | -import { findChar } from './slash-commands.js'; | |
| 30 | 29 | |
| 31 | 30 | export { |
| 32 | 31 | TAG_FOLDER_TYPES, |
| @@ -51,7 +50,6 @@ export { | ||
| 51 | 50 | removeTagFromMap, |
| 52 | 51 | }; |
| 53 | 52 | |
| 54 | -/** @typedef {import('../scripts/popup.js').Popup} Popup */ | |
| 55 | 53 | /** @typedef {import('../script.js').Character} Character */ |
| 56 | 54 | |
| 57 | 55 | const CHARACTER_FILTER_SELECTOR = '#rm_characters_block .rm_tag_filter'; |
| @@ -1,10 +1,12 @@ | ||
| 1 | 1 | import { getContext } from './extensions.js'; |
| 2 | 2 | import { characters, getRequestHeaders, this_chid } from '../script.js'; |
| 3 | 3 | import { isMobile } from './RossAscends-mods.js'; |
| 4 | 4 | import { collapseNewlines } from './power-user.js'; |
| 5 | 5 | import { debounce_timeout } from './constants.js'; |
| 6 | 6 | import { Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js'; |
| 7 | 7 | import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js'; |
| 8 | +import { getTagsList } from './tags.js'; | |
| 9 | +import { groups, selected_group } from './group-chats.js'; | |
| 8 | 10 | |
| 9 | 11 | /** |
| 10 | 12 | * Pagination status string template. |
| @@ -2110,3 +2112,74 @@ export async function showFontAwesomePicker(customList = null) { | ||
| 2110 | 2112 | } |
| 2111 | 2113 | return null; |
| 2112 | 2114 | } |
| 2115 | + | |
| 2116 | +/** | |
| 2117 | + * Finds a character by name, with optional filtering and precedence for avatars | |
| 2118 | + * @param {object} [options={}] - The options for the search | |
| 2119 | + * @param {string?} [options.name=null] - The name to search for | |
| 2120 | + * @param {boolean} [options.allowAvatar=true] - Whether to allow searching by avatar | |
| 2121 | + * @param {boolean} [options.insensitive=true] - Whether the search should be case insensitive | |
| 2122 | + * @param {string[]?} [options.filteredByTags=null] - Tags to filter characters by | |
| 2123 | + * @param {boolean} [options.preferCurrentChar=true] - Whether to prefer the current character(s) | |
| 2124 | + * @param {boolean} [options.quiet=false] - Whether to suppress warnings | |
| 2125 | + * @returns {any?} - The found character or null if not found | |
| 2126 | + */ | |
| 2127 | +export function findChar({ name = null, allowAvatar = true, insensitive = true, filteredByTags = null, preferCurrentChar = true, quiet = false } = {}) { | |
| 2128 | + const matches = (char) => (allowAvatar && char.avatar === name) || (insensitive ? equalsIgnoreCaseAndAccents(char.name, name) : char.name === name); | |
| 2129 | + | |
| 2130 | + // Filter characters by tags if provided | |
| 2131 | + let filteredCharacters = characters; | |
| 2132 | + if (filteredByTags) { | |
| 2133 | + filteredCharacters = characters.filter(char => { | |
| 2134 | + const charTags = getTagsList(char.avatar, false); | |
| 2135 | + return filteredByTags.every(tagName => charTags.some(x => x.name == tagName)); | |
| 2136 | + }); | |
| 2137 | + } | |
| 2138 | + | |
| 2139 | + // Get the current character(s) | |
| 2140 | + /** @type {any[]} */ | |
| 2141 | + const currentChars = selected_group ? groups.find(group => group.id === selected_group)?.members.map(member => filteredCharacters.find(char => char.avatar === member)) | |
| 2142 | + : [filteredCharacters.find(char => characters[this_chid]?.avatar === char.avatar)]; | |
| 2143 | + | |
| 2144 | + // If we have a current char and prefer it, return that if it matches | |
| 2145 | + if (preferCurrentChar) { | |
| 2146 | + const preferredCharSearch = currentChars.filter(matches); | |
| 2147 | + if (preferredCharSearch.length > 1) { | |
| 2148 | + if (!quiet) toastr.warning(`Multiple characters found for name "${name}" and given conditions.`); | |
| 2149 | + else console.warn(`Multiple characters found for name "${name}". Returning the first match.`); | |
| 2150 | + } | |
| 2151 | + if (preferredCharSearch.length) { | |
| 2152 | + return preferredCharSearch[0]; | |
| 2153 | + } | |
| 2154 | + } | |
| 2155 | + | |
| 2156 | + // If allowAvatar is true, search by avatar first | |
| 2157 | + if (allowAvatar && name) { | |
| 2158 | + const characterByAvatar = filteredCharacters.find(char => char.avatar === name); | |
| 2159 | + if (characterByAvatar) { | |
| 2160 | + return characterByAvatar; | |
| 2161 | + } | |
| 2162 | + } | |
| 2163 | + | |
| 2164 | + // Search for matching characters by name | |
| 2165 | + const matchingCharacters = name ? filteredCharacters.filter(matches) : filteredCharacters; | |
| 2166 | + if (matchingCharacters.length > 1) { | |
| 2167 | + if (!quiet) toastr.warning(`Multiple characters found for name "${name}" and given conditions.`); | |
| 2168 | + else console.warn(`Multiple characters found for name "${name}". Returning the first match.`); | |
| 2169 | + } | |
| 2170 | + | |
| 2171 | + return matchingCharacters[0] || null; | |
| 2172 | +} | |
| 2173 | + | |
| 2174 | +/** | |
| 2175 | + * Gets the index of a character based on the character object | |
| 2176 | + * @param {object} char - The character object to find the index for | |
| 2177 | + * @throws {Error} If the character is not found | |
| 2178 | + * @returns {number} The index of the character in the characters array | |
| 2179 | + */ | |
| 2180 | +export function getCharIndex(char) { | |
| 2181 | + if (!char) throw new Error('Character is undefined'); | |
| 2182 | + const index = characters.findIndex(c => c.avatar === char.avatar); | |
| 2183 | + if (index === -1) throw new Error(`Character not found: ${char.avatar}`); | |
| 2184 | + return index; | |
| 2185 | +} | |