diff --git a/enum.js b/enum.js index 8007064..b4df230 100644 --- a/enum.js +++ b/enum.js @@ -5,6 +5,13 @@ const clickTypeEnum = { SecondClick: 'second_click', //when we click a thumbnail that is active/ has orange border } +const AutomaticStatusEnum = { + NoApi: 'no_api', + Offline: 'offline', + RunningNoApi: 'running_no_api', + RunningWithApi: 'running_with_api', +} + const ViewerObjectTypeEnum = { OutputImage: 'output_image', InitImage: 'init_image', @@ -13,5 +20,6 @@ const ViewerObjectTypeEnum = { module.exports = { clickTypeEnum, + AutomaticStatusEnum, ViewerObjectTypeEnum, } diff --git a/index.js b/index.js index 1b879c1..dad9d43 100644 --- a/index.js +++ b/index.js @@ -39,7 +39,11 @@ const dummy = require('./utility/dummy') const general = require('./utility/general') const thumbnail = require('./thumbnail') const note = require('./utility/notification') +const sampler_data = require('./utility/sampler') + let g_horde_generator = new horde_native.hordeGenerator() +let g_automatic_status = Enum.AutomaticStatusEnum['Offline'] +let g_models_status = false //REFACTOR: move to session.js async function hasSessionSelectionChanged() { @@ -341,25 +345,65 @@ function tempDisableElement(element, time) { element.style.cursor = 'default' }, time) } + +//REFACTOR: move to the notfication.js +async function displayNotification(automatic_status) { + if (automatic_status === Enum.AutomaticStatusEnum['RunningWithApi']) { + //do nothing + } else if ( + g_automatic_status === Enum.AutomaticStatusEnum['RunningNoApi'] + ) { + await note.Notification.webuiAPIMissing() + } else if (g_automatic_status === Enum.AutomaticStatusEnum['Offline']) { + await note.Notification.webuiIsOffline() + } +} +//REFACTOR: move to sdapi.js +async function checkAutoStatus() { + try { + const options = await g_sd_options_obj.getOptions() + if (options) { + //means both automatic1111 and proxy server are online + html_manip.setAutomaticStatus('connected', 'disconnected') + g_automatic_status = Enum.AutomaticStatusEnum['RunningWithApi'] + // html_manip.setProxyServerStatus('connected','disconnected') + } else { + html_manip.setAutomaticStatus('disconnected', 'connected') + if (await sdapi.isWebuiRunning()) { + //running with no api + g_automatic_status = Enum.AutomaticStatusEnum['RunningNoApi'] + // await note.Notification.webuiAPIMissing() + } else { + //not running and of course no api + g_automatic_status = Enum.AutomaticStatusEnum['Offline'] + // await note.Notification.webuiIsOffline() + } + + return g_automatic_status + } + } catch (e) { + console.warn(e) + } + return g_automatic_status +} + //REFACTOR: move to ui.js async function refreshUI() { try { const b_proxy_server_status = await updateVersionUI() if (b_proxy_server_status) { html_manip.setProxyServerStatus('connected', 'disconnected') + // g_automatic_status = Enum.AutomaticStatusEnum['RunningWithApi'] } else { html_manip.setProxyServerStatus('disconnected', 'connected') } + g_automatic_status = await checkAutoStatus() + await displayNotification(g_automatic_status) + const bSamplersStatus = await initSamplers() - if (bSamplersStatus) { - //means both automatic1111 and proxy server are online - html_manip.setAutomaticStatus('connected', 'disconnected') - // html_manip.setProxyServerStatus('connected','disconnected') - } else { - html_manip.setAutomaticStatus('disconnected', 'connected') - } - await refreshModels() + + g_models_status = await refreshModels() await refreshExtraUpscalers() //get the latest options await g_sd_options_obj.getOptions() @@ -381,8 +425,13 @@ async function refreshUI() { } //REFACTOR: move to generation_settings.js async function refreshModels() { + let b_result = false try { g_models = await sdapi.requestGetModels() + if (g_models.length > 0) { + b_result = true + } + // const models_menu_element = document.getElementById('mModelsMenu') // models_menu_element.value = "" document.getElementById('mModelsMenu').innerHTML = '' @@ -399,8 +448,10 @@ async function refreshModels() { .appendChild(menu_item_element) } } catch (e) { + b_result = false console.warn(e) } + return b_result } //REFACTOR: move to generation_settings.js async function refreshExtraUpscalers() { @@ -454,8 +505,14 @@ async function initSamplers() { let sampler_group = document.getElementById('sampler_group') sampler_group.innerHTML = '' - const samplers = await sdapi.requestGetSamplers() - for (sampler of samplers) { + let samplers = await sdapi.requestGetSamplers() + if (!samplers) { + //if we failed to get the sampler list from auto1111, use the list stored in sampler.js + + samplers = sampler_data.samplers + } + + for (let sampler of samplers) { console.log(sampler) // sampler.name // Euler @@ -703,6 +760,7 @@ let g_viewer_manager = new viewer.ViewerManager() //***********Start: init function calls */ async function initPlugin() { + const bSamplersStatus = await initSamplers() //initialize the sampler await refreshUI() await displayUpdate() // promptShortcutExample() @@ -715,8 +773,8 @@ initPlugin() // updateVersionUI() // refreshUI() // displayUpdate() -// // promptShortcutExample() // loadPromptShortcut() +// // promptShortcutExample() //***********End: init function calls */ @@ -1827,6 +1885,7 @@ function updateMetadata(new_metadata) { async function getSettings() { let payload = {} + try { const extension_type = html_manip.getExtensionType() // get the extension type const selectionInfo = await psapi.getSelectionInfoExe() @@ -1884,7 +1943,10 @@ async function getSettings() { ) console.log('Check2') + //Note: store the sampler names in json file if auto is offline or auto api is unmounted + const sampler_name = html_manip.getCheckedSamplerName() + const mode = html_manip.getMode() const b_restore_faces = document.getElementById('chRestoreFaces').checked @@ -2207,6 +2269,20 @@ async function easyModeGenerate(mode) { return false } + const backend_type = html_manip.getBackendType() + if ( + backend_type === backendTypeEnum['Auto1111'] || + backend_type === backendTypeEnum['Auto1111HordeExtension'] + ) { + g_automatic_status = await checkAutoStatus() + await displayNotification(g_automatic_status) + if ( + g_automatic_status === Enum.AutomaticStatusEnum['Offline'] || + g_automatic_status === Enum.AutomaticStatusEnum['RunningNoApi'] + ) { + return false + } + } let active_layer = await app.activeDocument.activeLayers[0] // store the active layer so we could reselected after the session end clean up //make sure you have selection area active on the canvas diff --git a/sdapi_py_re.js b/sdapi_py_re.js index d112645..23dca7d 100644 --- a/sdapi_py_re.js +++ b/sdapi_py_re.js @@ -160,14 +160,18 @@ async function requestGetModels() { } async function requestGetSamplers() { - console.log('requestGetSamplers: ') - - const full_url = `${g_sd_url}/sdapi/v1/samplers` - let request = await fetch(full_url) - let json = await request.json() - console.log('samplers json:') - console.dir(json) + let json = null + try { + console.log('requestGetSamplers: ') + const full_url = `${g_sd_url}/sdapi/v1/samplers` + let request = await fetch(full_url) + json = await request.json() + console.log('samplers json:') + console.dir(json) + } catch (e) { + console.warn(e) + } return json } @@ -403,10 +407,14 @@ async function requestGetConfig() { } async function requestGetOptions() { console.log('requestGetOptions: ') - let json = [] + let json = null const full_url = `${g_sd_url}/sdapi/v1/options` try { let request = await fetch(full_url) + if (request.status === 404) { + return null + } + json = await request.json() console.log('models json:') console.dir(json) @@ -589,6 +597,21 @@ async function requestGetUpscalers() { return json } +async function isWebuiRunning() { + console.log('isWebuiRunning: ') + let json = [] + const full_url = `${g_sd_url}/user` + try { + let request = await fetch(full_url) + json = await request.json() + console.log('json:') + console.dir(json) + } catch (e) { + console.warn(`issues requesting from ${full_url}`, e) + return false + } + return true +} module.exports = { requestTxt2Img, requestImg2Img, @@ -613,4 +636,5 @@ module.exports = { // requestHordeStatus, requestExtraSingleImage, requestGetUpscalers, + isWebuiRunning, } diff --git a/utility/html_manip.js b/utility/html_manip.js index 351ce7b..846df53 100644 --- a/utility/html_manip.js +++ b/utility/html_manip.js @@ -323,9 +323,13 @@ function getSamplerElementByName(sampler_name) { function getCheckedSamplerName() { //we assume that the samplers exist and loaded in html //return the name of the first checked sampler - return [...document.getElementsByClassName('rbSampler')].filter( - (e) => e.checked == true - )[0].value + try { + return [...document.getElementsByClassName('rbSampler')].filter( + (elm) => elm.checked == true + )[0].value + } catch (e) { + console.warn(e) + } } function getMode() { return [...document.getElementsByClassName('rbMode')].filter( diff --git a/utility/sampler.js b/utility/sampler.js new file mode 100644 index 0000000..fd278db --- /dev/null +++ b/utility/sampler.js @@ -0,0 +1,117 @@ +samplers = [ + { + name: 'Euler a', + aliases: ['k_euler_a', 'k_euler_ancestral'], + options: {}, + }, + { + name: 'Euler', + aliases: ['k_euler'], + options: {}, + }, + { + name: 'LMS', + aliases: ['k_lms'], + options: {}, + }, + { + name: 'Heun', + aliases: ['k_heun'], + options: {}, + }, + { + name: 'DPM2', + aliases: ['k_dpm_2'], + options: { + discard_next_to_last_sigma: 'True', + }, + }, + { + name: 'DPM2 a', + aliases: ['k_dpm_2_a'], + options: { + discard_next_to_last_sigma: 'True', + }, + }, + { + name: 'DPM++ 2S a', + aliases: ['k_dpmpp_2s_a'], + options: {}, + }, + { + name: 'DPM++ 2M', + aliases: ['k_dpmpp_2m'], + options: {}, + }, + { + name: 'DPM++ SDE', + aliases: ['k_dpmpp_sde'], + options: {}, + }, + { + name: 'DPM fast', + aliases: ['k_dpm_fast'], + options: {}, + }, + { + name: 'DPM adaptive', + aliases: ['k_dpm_ad'], + options: {}, + }, + { + name: 'LMS Karras', + aliases: ['k_lms_ka'], + options: { + scheduler: 'karras', + }, + }, + { + name: 'DPM2 Karras', + aliases: ['k_dpm_2_ka'], + options: { + scheduler: 'karras', + discard_next_to_last_sigma: 'True', + }, + }, + { + name: 'DPM2 a Karras', + aliases: ['k_dpm_2_a_ka'], + options: { + scheduler: 'karras', + discard_next_to_last_sigma: 'True', + }, + }, + { + name: 'DPM++ 2S a Karras', + aliases: ['k_dpmpp_2s_a_ka'], + options: { + scheduler: 'karras', + }, + }, + { + name: 'DPM++ 2M Karras', + aliases: ['k_dpmpp_2m_ka'], + options: { + scheduler: 'karras', + }, + }, + { + name: 'DPM++ SDE Karras', + aliases: ['k_dpmpp_sde_ka'], + options: { + scheduler: 'karras', + }, + }, + { + name: 'DDIM', + aliases: [], + options: {}, + }, + { + name: 'PLMS', + aliases: [], + options: {}, + }, +] + +module.exports = { samplers }