const { getDummyBase64, getDummyBase64_2 } = require('./utility/dummy') const { base64ToBase64Url } = require('./utility/general') const { getExtensionType } = require('./utility/html_manip') const py_re = require('./utility/sdapi/python_replacement') const Enum = require('./enum') const control_net = require('./utility/tab/control_net') const api = require('./utility/api') //javascript plugin can't read images from local directory so we send a request to local server to read the image file and send it back to plugin as image string base64 async function getInitImage(init_image_name) { console.log('getInitImage(): get Init Image from the server :') const payload = { init_image_name: init_image_name, } // const full_url = 'http://127.0.0.1:8000/getInitImage/' // console.log(full_url) // console.log('getInitImage payload:', payload) // let request = await fetch(full_url, { // method: 'POST', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // }, // body: JSON.stringify(payload), // // "body": payload // }) // let json = await request.json() // console.log('json:') // console.dir(json) // base64data = json.init_image_str // image_src = `data:image/png;base64, ${base64data}` console.warn('this function is deprecated!') const image_src = 'https://im ages.pexels.com/photos/1386604/pexels-photo-1386604.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1' return image_src // console.log(img.src) // let img_blob = await (await fetch(img.src)).blob() // console.log("img_blob:") // console.dir(img_blob) } //REFACTOR: move this function to io.js async function requestSavePng(base64_image, image_name) { try { console.log('requestSavePng():') const uniqueDocumentId = await getUniqueDocumentId() const folder = `${uniqueDocumentId}/init_images` const init_entry = await getInitImagesDir() saveFileInSubFolder(base64_image, folder, image_name) console.warn('this function is deprecated') } catch (e) { console.warn(e) return {} } } async function requestTxt2Img(payload) { try { console.log('requestTxt2Img(): about to send a fetch request') // const full_url = 'http://127.0.0.1:8000/txt2img/' // console.log(full_url) // let request = await fetch(full_url, { // method: 'POST', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // }, // body: JSON.stringify(payload), // // "body": payload // }) // let json = await request.json() let json = await py_re.txt2ImgRequest(payload) console.log('requestTxt2Img json:', json) return json } catch (e) { console.warn(e) return {} } } async function requestImg2Img(payload) { console.log('requestImg2Img(): about to send a fetch request') try { // const full_url = 'http://127.0.0.1:8000/img2img/' // console.log(full_url) // console.log('requestImg2Img payload is: ', payload) // let request = await fetch(full_url, { // method: 'POST', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // }, // body: JSON.stringify(payload), // // "body": payload // }) // let json = await request.json() let json = await py_re.img2ImgRequest(g_sd_url, payload) console.log('requestImg2Img json:') console.dir(json) return json } catch (e) { console.warn(e) return {} } } async function requestProgress() { let json = {} try { console.log('requestProgress: ') const full_url = `${g_sd_url}/sdapi/v1/progress?skip_current_image=false` let request = await fetch(full_url) json = await request.json() console.log('progress json:', json) return json } catch (e) { console.warn(e) // console.log('json: ', json) } } async function requestGetModels() { console.log('requestGetModels: ') let json = [] const full_url = `${g_sd_url}/sdapi/v1/sd-models` try { let request = await fetch(full_url) json = await request.json() console.log('models json:') console.dir(json) } catch (e) { console.warn(`issues requesting from ${full_url}`, e) } return json } async function requestGetSamplers() { 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:', json) } catch (e) { console.warn(e) } return json } async function requestSwapModel(model_title) { console.log('requestSwapModel: ') // const full_url = 'http://127.0.0.1:8000/swapModel' const full_url = `${g_sd_url}/sdapi/v1/options` payload = { sd_model_checkpoint: model_title, } let request = await fetch(full_url, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(payload), // "body": payload }) let json = await request.json() console.log('models json:') console.dir(json) return json } async function requestInterrupt() { const full_url = `${g_sd_url}/sdapi/v1/interrupt` try { console.log('requestInterrupt: ') payload = '' let request = await fetch(full_url, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, // body: JSON.stringify(payload) // "body": payload }) console.log('interrupt request:', request) let json = await request.json() return json } catch (e) { console.warn(e) } } async function getVersionRequest() { // version = "v0.0.0" console.log('requestGetSamplers: ') const current_version = g_version // try { // const full_url = 'http://127.0.0.1:8000/version' // let request = await fetch(full_url) // let json = await request.json() // console.log('version json:', json) // version = json['version'] // return version // } catch (e) { // console.warn(e) // version = 'v0.0.0' // return version // } return current_version } async function changeSdUrl(new_sd_url) { // version = "v0.0.0" console.log('changeSdUrl: new_sd_url:', new_sd_url) try { payload = { sd_url: new_sd_url, } // const full_url = `${g_sd_url}/sd_url/` // console.log('changeSdUrl: payload: ', payload) // let request = await fetch(full_url, { // method: 'POST', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // }, // body: JSON.stringify(payload), // }) g_sd_url = new_sd_url // console.log('changeSdUrl: request: ', request) } catch (e) { console.warn(e) } } // function printTheJSONInPrettyFormat(json) { // // var badJSON = document.getElementById('prettyJSONFormat').value; // // var parseJSON = JSON.parse(badJSON); // // var JSONInPrettyFormat = JSON.stringify(json, undefined, 4); // // return // } async function loadHistory(uniqueDocumentId) { let json = {} try { payload = { uniqueDocumentId: uniqueDocumentId, } json = await py_re.loadHistory(payload) // const full_url = 'http://127.0.0.1:8000/history/load' // let request = await fetch(full_url, { // method: 'POST', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // }, // body: JSON.stringify(payload), // }) // json = await request.json() // console.log('loadHistory:', json) // console.log('loadPromptShortcut: request: ',request) } catch (e) { console.warn(e) } return [json['image_paths'], json['metadata_jsons'], json['base64_images']] } async function loadPromptShortcut() { // console.log('loadPromptShortcut:') let prompt_shortcut_json = {} try { // payload = {} // const full_url = 'http://127.0.0.1:8000/prompt_shortcut/load' // let request = await fetch(full_url, { // method: 'POST', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // }, // body: JSON.stringify(payload), // }) // json = await request.json() prompt_shortcut_json = await py_re.loadPromptShortcut( 'prompt_shortcut.json' ) console.log('loadPromptShortcut:', prompt_shortcut_json) // console.log('loadPromptShortcut: request: ',request) } catch (e) { console.warn(e) prompt_shortcut_json = {} } return prompt_shortcut_json // return json['prompt_shortcut'] } async function savePromptShortcut(prompt_shortcut) { // console.log('loadPromptShortcut:') let json = prompt_shortcut try { // payload = { prompt_shortcut: prompt_shortcut } // const full_url = 'http://127.0.0.1:8000/prompt_shortcut/save' // let request = await fetch(full_url, { // method: 'POST', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // }, // body: JSON.stringify(payload), // }) // json = await request.json() await py_re.savePromptShortcut(json, 'prompt_shortcut.json') console.log('savePromptShortcut:', json) // console.log('loadPromptShortcut: request: ',request) } catch (e) { console.warn(e) } return json['prompt_shortcut'] } async function setInpaintMaskWeight(value) { const full_url = `${g_sd_url}/sdapi/v1/options` try { const payload = { inpainting_mask_weight: value, } await fetch(full_url, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }) } catch (e) { console.warn(e) } } async function requestGetConfig() { console.log('requestGetConfig: ') let json = [] const full_url = `${g_sd_url}/config` try { let request = await fetch(full_url) json = await request.json() console.log('models json:') console.dir(json) } catch (e) { console.warn(`issues requesting from ${full_url}`, e) } return json } async function requestGetOptions() { console.log('requestGetOptions: ') 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) } catch (e) { console.warn(`issues requesting from ${full_url}`, e) } return json } async function imageSearch(keywords) { let json = {} const extension_url = py_re.getExtensionUrl() const full_url = `${extension_url}/search/image/` try { payload = { keywords: keywords, } let request = await fetch(full_url, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }) json = await request.json() console.log('imageSearch:', json) return json['images'] } catch (e) { console.warn(e) } return [] } // async function requestHorde(payload) { // payload = { // prompt: 'string', // params: { // sampler_name: 'k_lms', // toggles: [1, 4], // cfg_scale: 5, // denoising_strength: 0.75, // seed: 'string', // height: 512, // width: 512, // seed_variation: 1, // post_processing: ['GFPGAN'], // karras: false, // tiling: false, // steps: 30, // n: 1, // }, // nsfw: false, // trusted_workers: true, // censor_nsfw: false, // workers: ['4c79ab19-8e6c-4054-83b3-773b7ce71ece'], // models: ['stable_diffusion'], // // source_image: 'string', // // source_processing: 'img2img', // // source_mask: 'string', // r2: true, // shared: false, // } // try { // console.log('requestHorde():') // const full_url = 'https://stablehorde.net/api/v2/generate/async' // // const full_url = 'https://stablehorde.net/api/v2/generate/sync' // console.log(full_url) // let request = await fetch(full_url, { // method: 'POST', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // apikey: '0000000000', // // 'Client-Agent': '4c79ab19-8e6c-4054-83b3-773b7ce71ece', // 'Client-Agent': 'unknown:0:unknown', // }, // body: JSON.stringify(payload), // }) // let json = await request.json() // console.log('requestHorde json:', json) // return json // } catch (e) { // console.warn(e) // return {} // } // } // async function requestHordeCheck(id) { // try { // console.log('requestHordeCheck():') // const base_url = 'https://stablehorde.net/api/v2/generate/check' // const full_url = `${base_url}/${id}` // // const full_url = 'https://stablehorde.net/api/v2/generate/sync' // console.log(full_url) // const payload = {} // let request = await fetch(full_url, { // method: 'GET', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // // 'Client-Agent': '4c79ab19-8e6c-4054-83b3-773b7ce71ece', // 'Client-Agent': 'unknown:0:unknown', // }, // }) // let json = await request.json() // console.log('requestHordeCheck json:', json) // return json // } catch (e) { // console.warn(e) // return {} // } // } // async function requestHordeStatus(id) { // try { // console.log('requestHordeStatus():') // const base_url = 'https://stablehorde.net/api/v2/generate/status' // const full_url = `${base_url}/${id}` // // const full_url = 'https://stablehorde.net/api/v2/generate/sync' // console.log(full_url) // const payload = {} // let request = await fetch(full_url, { // method: 'GET', // headers: { // Accept: 'application/json', // 'Content-Type': 'application/json', // // 'Client-Agent': '4c79ab19-8e6c-4054-83b3-773b7ce71ece', // 'Client-Agent': 'unknown:0:unknown', // }, // }) // let json = await request.json() // console.log('requestHordeStatus json:', json) // return json // } catch (e) { // console.warn(e) // return {} // } // } async function requestExtraSingleImage(payload) { console.log('requestExtraSingleImage(): about to send a fetch request') try { let json = await py_re.extraSingleImageRequest(g_sd_url, payload) console.log('requestExtraSingleImage json:') console.dir(json) return json } catch (e) { console.warn(e) return {} } } async function requestGetUpscalers() { console.log('requestGetUpscalers: ') let json = [] const full_url = `${g_sd_url}/sdapi/v1/upscalers` try { let request = await fetch(full_url) json = await request.json() console.log('upscalers json:') console.dir(json) } catch (e) { console.warn(`issues requesting from ${full_url}`, e) } return json } //REFACTOR: reuse the same code for (requestControlNetTxt2Img,requestControlNetImg2Img) async function requestControlNetTxt2Img(plugin_settings) { console.log('requestControlNetTxt2Img: ') // const full_url = `${g_sd_url}/controlnet/txt2img` const full_url = `${g_sd_url}/sdapi/v1/txt2img` // debugger const control_net_settings = control_net.mapPluginSettingsToControlNet(plugin_settings) let control_networks = [] // let active_control_networks = 0 for (let index = 0; index < g_controlnet_max_models; index++) { if (!control_net.getEnableControlNet(index)) { control_networks[index] = false continue } control_networks[index] = true // debugger if (!control_net_settings['controlnet_units'][index]['input_image']) { app.showAlert('you need to add a valid ControlNet input image') throw 'you need to add a valid ControlNet input image' } if (!control_net_settings['controlnet_units'][index]['module']) { app.showAlert('you need to select a valid ControlNet Module') throw 'you need to select a valid ControlNet Module' } if ( !control_net_settings['controlnet_units'][index]['model'] && !control_net.getModuleDetail()[ control_net_settings['controlnet_units'][index]['module'] ].model_free ) { app.showAlert('you need to select a valid ControlNet Model') throw 'you need to select a valid ControlNet Model' } // active_control_networks++ } let request = await fetch(full_url, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(control_net_settings), }) let json = await request.json() console.log('json:', json) //update the mask in controlNet tab const numOfImages = json['images'].length let numberOfAnnotations = numOfImages - g_generation_session.last_settings.batch_size if (numberOfAnnotations < 0) numberOfAnnotations = 0 const base64_mask = json['images'].slice(numOfImages - numberOfAnnotations) let mask_index = 0 for (let index = 0; index < control_networks.length; index++) { if ( control_networks[index] == false || mask_index >= numberOfAnnotations ) continue html_manip.setControlMaskSrc( base64ToBase64Url(base64_mask[mask_index]), index ) g_generation_session.controlNetMask[index] = base64_mask[mask_index] mask_index++ } // g_generation_session.controlNetMask = base64_mask const standard_response = await py_re.convertToStandardResponse( control_net_settings, json['images'].slice(0, numOfImages - numberOfAnnotations), plugin_settings['uniqueDocumentId'] ) console.log('standard_response:', standard_response) return standard_response } //REFACTOR: reuse the same code for (requestControlNetTxt2Img,requestControlNetImg2Img) async function requestControlNetImg2Img(plugin_settings) { console.log('requestControlNetImg2Img: ') // const full_url = 'http://127.0.0.1:8000/swapModel' // const full_url = `${g_sd_url}/controlnet/img2img` const full_url = `${g_sd_url}/sdapi/v1/img2img` const control_net_settings = control_net.mapPluginSettingsToControlNet(plugin_settings) // let control_networks = 0 let control_networks = [] for (let index = 0; index < g_controlnet_max_models; index++) { if (!control_net.getEnableControlNet(index)) { control_networks[index] = false continue } control_networks[index] = true if (!control_net_settings['controlnet_units'][index]['input_image']) { app.showAlert('you need to add a valid ControlNet input image') throw 'you need to add a valid ControlNet input image' } if (!control_net_settings['controlnet_units'][index]['module']) { app.showAlert('you need to select a valid ControlNet Module') throw 'you need to select a valid ControlNet Module' } if ( !control_net_settings['controlnet_units'][index]['model'] && !control_net.getModuleDetail()[ control_net_settings['controlnet_units'][index]['module'] ].model_free ) { app.showAlert('you need to select a valid ControlNet Model') throw 'you need to select a valid ControlNet Model' } } let request = await fetch(full_url, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(control_net_settings), // body: JSON.stringify(payload), }) let json = await request.json() console.log('json:', json) //update the mask in controlNet tab const numOfImages = json['images'].length let numberOfAnnotations = numOfImages - g_generation_session.last_settings.batch_size if (numberOfAnnotations < 0) numberOfAnnotations = 0 // To fix a bug: when Ultimate SD Upscale is active and running, the detection maps won’t be retrieved. // So set its value to 0 to avoid the result images being loaded in the annotation map interface. if ( scripts.script_store.is_active && scripts.script_store.selected_script_name !== 'None' && scripts.script_store.is_selected_script_available ) { numberOfAnnotations = 0 } const base64_mask = json['images'].slice(numOfImages - numberOfAnnotations) let mask_index = 0 for (let index = 0; index < control_networks.length; index++) { if ( control_networks[index] == false || mask_index >= numberOfAnnotations ) continue html_manip.setControlMaskSrc( base64ToBase64Url(base64_mask[mask_index]), index ) g_generation_session.controlNetMask[index] = base64_mask[mask_index] mask_index++ } // g_generation_session.controlNetMask = base64_mask const standard_response = await py_re.convertToStandardResponse( control_net_settings, json['images'].slice(0, numOfImages - numberOfAnnotations), plugin_settings['uniqueDocumentId'] ) console.log('standard_response:', standard_response) // //get all images except last because it's the mask // for (const image of json['images'].slice(0, -1)) { // await io.IO.base64ToLayer(image) // } return standard_response } 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 } async function requestLoraModels() { const extension_url = py_re.getExtensionUrl() const full_url = `${extension_url}/lora/list` const lora_models = await api.requestGet(full_url) return lora_models } module.exports = { requestTxt2Img, requestImg2Img, getInitImage, requestProgress, requestGetModels, requestSwapModel, requestInterrupt, requestGetSamplers, getVersionRequest, changeSdUrl, loadPromptShortcut, savePromptShortcut, loadHistory, setInpaintMaskWeight, requestGetConfig, requestGetOptions, imageSearch, requestSavePng, // requestHorde, // requestHordeCheck, // requestHordeStatus, requestExtraSingleImage, requestGetUpscalers, requestControlNetTxt2Img, requestControlNetImg2Img, isWebuiRunning, requestLoraModels, }