From 9ca0b5480ed8d398ae2be7ee254d7675d547a6f8 Mon Sep 17 00:00:00 2001 From: butaixianran Date: Sun, 26 Mar 2023 07:30:17 +0800 Subject: [PATCH] v1.6.0 --- README.cn.md | 12 ++ README.md | 34 ++++- icon/.keep | 0 javascript/civitai_helper.js | 122 ++++++++++++++++-- .../__pycache__/civitai.cpython-310.pyc | Bin 9126 -> 9156 bytes .../__pycache__/downloader.cpython-310.pyc | Bin 1972 -> 1997 bytes .../ch_lib/__pycache__/model.cpython-310.pyc | Bin 2639 -> 2693 bytes .../__pycache__/setting.cpython-310.pyc | Bin 1726 -> 1796 bytes .../ch_lib/__pycache__/util.cpython-310.pyc | Bin 2262 -> 2645 bytes scripts/ch_lib/civitai.py | 6 +- scripts/ch_lib/downloader.py | 4 +- scripts/ch_lib/model.py | 4 +- scripts/ch_lib/setting.py | 7 +- scripts/ch_lib/util.py | 44 ++++--- scripts/civitai_helper.py | 45 +++++-- style.css | 9 ++ 16 files changed, 237 insertions(+), 50 deletions(-) create mode 100644 icon/.keep diff --git a/README.cn.md b/README.cn.md index 156ee66..9936cc9 100644 --- a/README.cn.md +++ b/README.cn.md @@ -118,6 +118,18 @@ Stable Diffusion Webui 扩展Civitai助手,用于更轻松的管理和使用Ci ![](img/get_one_model_info.jpg) +## 代理 +**如果你是刚更新新版本,你需要重启SD webui再来使用** + +代理输入框在插件页面最下方。 + +**每次填入或清除代理后,都要保存,并用SDwebui设置页面的Reload UI按钮刷新UI** + +然后所有发到civitai的请求就会用代理。 + +依据使用的代理软件不同,有时候,甚至sock5代理, 也要填入http开头的形式"http://xxxxx"才能生效。 + + ## 其他设置 **保存设置按钮, 会保存扫描模型区域,以及其他设置 这两个区域的选项** diff --git a/README.md b/README.md index 1b70bf0..333abcd 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ Civitai: [Civitai Url](https://civitai.com/models/16768/civitai-helper-sd-webui- * Checking all your local model's new version from Civitai * Download a new version directly into SD model folder (with info+preview) * Modified Built-in "Extra Network" cards, to add the following buttons on each card: - - 🖼: Modified "replace preview" text into this icon + - 🖼️: Modified "replace preview" text into this icon - 🌐: Open this model's Civitai url in a new tab - 💡: Add this model's trigger words to prompt - - 🏷: Use this model's preview image's prompt + - 🏷️: Use this model's preview image's prompt * Above buttons support thumbnail mode of Extra Network * Option to always show additional buttons, to work with touchscreen. @@ -41,9 +41,13 @@ Done. # How to Use ## Update Your SD Webui -This extension need to get extra network's cards id. **Which is added to SD webui since 2023-02-06.** +* v1.6.x works with SD webui version from 2023-03-25 or later, which uses gradio version 3.23.0 +* v1.5.x works with SD webui version from 2023-02-06 - 2023-03-24. + +**Check your SD webui Page's bottom, "gradio" version number** +* If it is v3.23.0 or later, install v1.6.x. +* If it is v3.16.x, install v1.5.7 from [Civitai](https://civitai.com/models/16768/civitai-helper-sd-webui-civitai-extension) -So, if you are using a version earlier than this, you need to update your SD Webui! ## Scanning Models Go to extension tab "Civitai Helper". There is a button called "Scan model". @@ -128,6 +132,20 @@ After clicking button, extension will download that civitai model's info and pre ![](img/get_one_model_info.jpg) +## Proxy +**If you are updating to new version, you need to re-lanuch SD webui before using it.** + +Proxy textbox is at the bottom of extension tab. + +**Each time you fill or clear a proxy value, you need to save setting, and Re-load UI with setting tab's reload button.** + +Then all requests to civitai will use the proxy. + +Sometime, even sock5 proxy, need to be used as "http://xxxxx", depence on which proxy tool you are using. + + + + ## Other Setting **The Save Setting button, will save both "Scan Model"'s setting and other setting.** @@ -136,6 +154,8 @@ After clicking button, extension will download that civitai model's info and pre ![](img/other_setting.jpg) + + ## Preview Image Extra network uses both `model_file.png` and `model_file.preview.png` as preview image. But `model_file.png` has higher priority, because it is created by yourself. @@ -206,6 +226,12 @@ Since v1.5.5, we've already optimized the SHA256 function to the top. So the onl # Change Log +## v1.6.0 +* Fix some UI issues to work with gradio 3.23.0 +* Support Proxy when connecting to civitai. Check document for detail. +* check realpath when opening file, to fix error when using junction +* Fix multiple addtional buttons issue after switching tabs. + ## v1.5.7 * Fix Localization issue for 4 addtional buttons on cards diff --git a/icon/.keep b/icon/.keep new file mode 100644 index 0000000..e69de29 diff --git a/javascript/civitai_helper.js b/javascript/civitai_helper.js index 0b513e2..b5eb664 100644 --- a/javascript/civitai_helper.js +++ b/javascript/civitai_helper.js @@ -1,5 +1,18 @@ "use strict"; + +function ch_convert_file_path_to_url(path){ + let prefix = "file="; + let path_to_url = path.replaceAll('\\', '/'); + return prefix+path_to_url; +} + +function ch_img_node_str(path){ + return ``; +} + + + // send msg to python side by filling a hidden text box // then will click a button to trigger an action // msg is an object, not a string, will be stringify in this function @@ -73,6 +86,17 @@ const get_new_ch_py_msg = (max_count=3) => new Promise((resolve, reject) => { }) +function getActiveTabType() { + const currentTab = get_uiCurrentTabContent(); + switch (currentTab.id) { + case "tab_txt2img": + return "txt2img"; + case "tab_img2img": + return "img2img"; + } + return null; +} + function getActivePrompt() { @@ -300,12 +324,32 @@ onUiLoaded(() => { let model_type_list = ["textual_inversion", "hypernetworks", "checkpoints", "lora"]; let cardid_suffix = "cards"; + //get init py msg + // let init_py_msg_str = get_ch_py_msg(); + // let extension_path = ""; + // if (!init_py_msg_str) { + // console.log("Can not get init_py_msg"); + // } else { + // init_py_msg = JSON.parse(init_py_msg_str); + // if (init_py_msg) { + // extension_path = init_py_msg.extension_path; + // console.log("get extension path: " + extension_path); + // } + // } + + // //icon image node as string + // function icon(icon_name){ + // let icon_path = extension_path+"/icon/"+icon_name; + // return ch_img_node_str(icon_path); + // } + + // update extra network tab pages' cards // * replace "replace preview" text button into an icon // * add 3 button to each card: // - open model url 🌐 // - add trigger words 💡 - // - use preview image's prompt 🏷 + // - use preview image's prompt 🏷️ // notice: javascript can not get response from python side // so, these buttons just sent request to python // then, python side gonna open url and update prompt text box, without telling js side. @@ -320,7 +364,7 @@ onUiLoaded(() => { let btn_thumb_backgroundImage = "none"; let btn_thumb_background = "rgba(0, 0, 0, 0.8)"; - let ch_btn_txts = ['🌐', '💡', '🏷']; + let ch_btn_txts = ['🌐', '💡', '🏷️']; let replace_preview_text = getTranslation("replace preview"); if (!replace_preview_text) { replace_preview_text = "replace preview"; @@ -354,7 +398,50 @@ onUiLoaded(() => { let cards = null; let need_to_add_buttons = false; let is_thumb_mode = false; + + //get current tab + let active_tab_type = getActiveTabType(); + if (!active_tab_type){active_tab_type = "txt2img";} + for (const tab_prefix of tab_prefix_list) { + if (tab_prefix != active_tab_type) {continue;} + + + //find out current selected model type tab + let active_extra_tab_type = ""; + let extra_tabs = gradioApp().getElementById(tab_prefix+"_extra_tabs"); + if (!extra_tabs) {console.log("can not find extra_tabs: " + tab_prefix+"_extra_tabs");} + //get tab buttons + let extra_tab_btns = extra_tabs.firstChild.querySelectorAll("button"); + console.log("find buttons: " + extra_tab_btns.length); + + for (let extra_tab_btn of extra_tab_btns) { + console.log(extra_tab_btn.innerHTML); + if (extra_tab_btn.className.indexOf("selected") >= 0) { + console.log("found active tab: " + extra_tab_btn.innerHTML); + + switch (extra_tab_btn.innerHTML.trim()) { + case "Textual Inversion": + active_extra_tab_type = "ti"; + break; + case "Hypernetworks": + active_extra_tab_type = "hyper"; + break; + case "Checkpoints": + active_extra_tab_type = "ckp"; + break; + case "Lora": + active_extra_tab_type = "lora"; + break; + } + + break; + + + } + } + + for (const js_model_type of model_type_list) { //get model_type for python side switch (js_model_type) { @@ -377,6 +464,15 @@ onUiLoaded(() => { continue; } + + //only handle current sub-tab + if (model_type != active_extra_tab_type) { + continue; + } + + console.log("handle active extra tab"); + + extra_network_id = tab_prefix+"_"+js_model_type+"_"+cardid_suffix; // console.log("searching extra_network_node: " + extra_network_id); extra_network_node = gradioApp().getElementById(extra_network_id); @@ -470,7 +566,7 @@ onUiLoaded(() => { if (replace_preview_btn) { if (replace_preview_btn.innerHTML == replace_preview_text) { need_to_add_buttons = true; - replace_preview_btn.innerHTML = "🖼"; + replace_preview_btn.innerHTML = "🖼️"; if (!is_thumb_mode) { replace_preview_btn.style.fontSize = btn_fontSize; replace_preview_btn.style.margin = btn_margin; @@ -544,7 +640,7 @@ onUiLoaded(() => { let use_preview_prompt_node = document.createElement("a"); use_preview_prompt_node.href = "#"; - use_preview_prompt_node.innerHTML = "🏷"; + use_preview_prompt_node.innerHTML = "🏷️"; if (!is_thumb_mode) { use_preview_prompt_node.style.fontSize = btn_fontSize; use_preview_prompt_node.style.margin = btn_margin; @@ -582,27 +678,31 @@ onUiLoaded(() => { let tab_id = "" let extra_tab = null; let extra_toolbar = null; + let extra_network_refresh_btn = null; //add refresh button to extra network's toolbar for (let prefix of tab_prefix_list) { tab_id = prefix + "_extra_tabs"; extra_tab = gradioApp().getElementById(tab_id); //get toolbar - extra_toolbar = extra_tab.querySelector("div.flex.border-b-2.flex-wrap"); + //get Refresh button + extra_network_refresh_btn = gradioApp().getElementById(prefix+"_extra_refresh"); - if (!extra_toolbar){ - console.log("can not get extra network toolbar for " + tab_id); + + if (!extra_network_refresh_btn){ + console.log("can not get extra network refresh button for " + tab_id); continue; } // add refresh button to toolbar let ch_refresh = document.createElement("button"); - ch_refresh.innerHTML = "Refresh Civitai Helper"; - ch_refresh.title = "Refresh Civitai Helper's model card buttons"; - ch_refresh.className = "gr-button gr-button-lg gr-button-secondary"; + ch_refresh.innerHTML = "🔁"; + ch_refresh.title = "Refresh Civitai Helper's additional buttons"; + ch_refresh.className = "lg secondary gradio-button"; + ch_refresh.style.fontSize = "200%"; ch_refresh.onclick = update_card_for_civitai; - extra_toolbar.appendChild(ch_refresh); + extra_network_refresh_btn.parentNode.appendChild(ch_refresh); } diff --git a/scripts/ch_lib/__pycache__/civitai.cpython-310.pyc b/scripts/ch_lib/__pycache__/civitai.cpython-310.pyc index 5678474b3a08c1abffa7570c94fc3aed50ded675..9659de99982190da55c81db60a3c941c5e7153f0 100644 GIT binary patch delta 1741 zcmb7^T})g>6vuaV@7J=-0=uw$xYzX*9-+XFfVodtv{O6`iebY_$chAh3 zo&Epk%(-8T-x-f)qtS|h_}pEKnGbG82SO}IW1&=Nb|FPOp((npbyHk13^%Z-nacYi z`djN72yd`OV~aHet}_;J13OHND-fH3N%7qb7PJkv6S*#;Hv&$#5^(p>gx<))w4*e# z3i?io(Pw%+Jy3@B20eYjN}CqXdwPy%FWVONsPC~T-BJfsen3d0Kh$-)V)U|J`dCY{ zhxCIsSQL76=-I@78~IVeu&FKu`61{rHK?(L8adKk75V?CcwP0^oj%w5>7KstJZ}|hZ$x=WJa`+B0NQ~Lpcd!^;EQ(wPXI}v8+cOShQj+0 z9|R5oJv5f6rL#sSi&N3)VMFw_(aiek7o)p+01FJD5ojVU+_S$0VGM`^5XKJ!gL0>I zxLtc1!y~2b@VAWh(aFeC*AQmP;yq=_TFZN(jOFkn$UuEk<$d&9Hv@W}O zegfl@z&P*%GFm#9vm7&7#ZO`G72svyRbYZXtv+1;BEpvhys+)eWm9u@#^NK=_rvOW zHbZaK4Af1Ce3J1QJc9ma6LQJ-H61Kf`n~2fV{PMS3AQNO5fD> z2dCvs9kP#?9IkvnQZ@YePNaKj2TuGWXb_PXHM6TuCYv^;(qx3&bfP|auxw*GI%o5| zo62!(#kN+bBYA7~(SW~+y+-Jh`kl&4*i7@wz>k&28@^&idGb}eMfI;>S)-@gdDG^e zp0V?;2;}kmb&^Wq-B&M*Qx={yI7jLja2_bD^}UZ^t}j5x6MJc^(P1m4KO0wqor{=W z@^d26MO4sCE0bOuF6eRLE9;p2D1Fd0$kKGDslAxN+KU3B;^mtuZ_a-{W87*_aqVTx zQ}Y?i%5hoI8g66nRbW>fr28vKyaN=0 zcY((}-fV4P9{t>Udu&^zM85>_i1`{fuv)&fY7iv=oPu8{dEHeEWgmCY-L}|NuNZrZ zY0tVGW%1uDqlo0|;u<2fBu@bgfV|Zq+i|69Pn{E;;(Dt4c20D)JdJG{Ni6;YCX9k3 delta 1592 zcmb7^O>7%g5Xb%O-SxVT;}}PA;(Xa{AZ&m{t!wgCg@%u&qR^&FX(g*oVzQfL6Myl% zNl2QIl&C^IR8^UCrBp~o5fll0KnQWDgy4e2p@_rYKtf2s35f#;0q_4-O)75n;kWZ< z=B?*HZ{B`6c4sV7jzkXl#BXaZYTo@gk_oUPjRvOZy})_)JN*?nJZ&o1{TpnZEojwY z!Jw%w`nlowc9^N%X3S^%CVX-gbaceGS;7ZDd}1AfZHgSzx8YyY*4fU1+rqlwEA=Qo zC%jsu8%m;8Uk_}v2fIwU=fQrur*yIv`awArVs3EW%9|Fa5%nEbM_;KK`bWLYn(3C_ z%X(>7Gw9Di5B;sxDJYvVN_R#TMd*)K6kS(ZXgio>A@S!~x*u$3t@K;4Ewo$51EN_x zO))*5jl+B#cmn7Ko&*e_M_^aseXySbo(7(w8GVpewLX@mZ}fI{n10cF8jc{O11&%+ zb%lD9?JzrlP9OzjfTL6h^=r? zD(|B|!tb+@+O4`F)|f^>L3VJqTo9eD^1<4#k$R@Ripa^@zx5N$h6bZv=JDs?9|VpI zxXMbtu*gTTehGM9I;}UIDt`g%7l9MN7$RD}Qn5;=5#=Z0I}N-7oB_t^^M<2MFT*?~ z;D+qdYGdW<^QxztO)2dnHVo6JO*{1!?9jXx^J6tD@d4YEU5!3egPf=1*o1z%s$Dg0?gk5X z)e(klt#<~psSxOuC>y_5ouTtL5IP3rfW3x#0*B%2^U;l#Ew)r^NG|)sHe3tRPdD3= zY=Ay&%d%+1p^Fyg~ z{4Cu~oxO-57k|H6vE&`#ugNvqx*Hs&*?8luZfTtZ$BQLUO|_UEx#%; zSOAP0j738G$-Am~j`dJsVgVoBm0vhM56p6nWy7_Vh>p2B!Lle+|2u2OI0Vro0&ymyIh@i^RgUa4atA`@!a_RTZ|=f7sFUVB-&{ CcXKfS delta 496 zcmYk3&ubGw6vyA2-Rvg2-OSo1CfkkHLQ#4uBDIJuc<|_53jUz*(jP0DIvJ|M3_0vg z2(}EKq_TTc@K$g7FL?2oKch!Ma3&|`!DqgY_vQNr<`@6YlTngHV9)s>r)Ou$XWT#g zHcBa+`no|)9mtky6p`7$d~-rfGm2eb#WkFO7&%RG20Bz>wLl9sQj$THP`gIW6dRAs z1iSdwe8i1=ZROYagz2Vksix#T(2;}+X;DR=;GETnU^m8+6<(F9s7CQ+uCJKCxILLa zDUsGpy^?)+q}wVfmZ(qJ6d%IV9nBR#MZr}pJBpXM1v*yks;jsQw(4pP2(m@XD(-*^ zawt)!vRCwrjB*-Gt;=;)m#)!um3DwutT*k0RX3FR$7^%UN(T6i55-X5ry*kA~vny?1~(Fqi&=i><~0 zgZuU~{v4a#;JNt`+{KQ$4DR5fxf!ml?%2_KByQPD^cgDyUrzC%7554 HU&FP3THSZ= diff --git a/scripts/ch_lib/__pycache__/model.cpython-310.pyc b/scripts/ch_lib/__pycache__/model.cpython-310.pyc index f8f9ff4905eed70d43a470bee06acc9cd6a1016f..91d674719251c336fadb7e34611c6e9ba54eb507 100644 GIT binary patch delta 463 zcmYLFJ4*vW5Z>9nyWB+%)Feg`O?+a47zAGsEqv61Ac{5;a*75?WZg!|VWE~{F=BoB z0TyEAFR-*vC)$bl11xk#Q3vMR@0;1#nc2tWdCIT(eq4|}7c#-lt^X#WiXU=Im3Oyr zQ2s4q3uDM>8No1>(5N#3DD4f76qyE8b&WZ19T;`|JWN;fg(x_H+-m z`5#pGvdrRzJ?!)|9l(2g9Fq8I_d*Wi&I{!6-MNC|-C1k|U=(lMY2LT Ljv@!=5#q~VAGl!= delta 397 zcmYL@ze)o^5XN`*_Aa@22Z=F?N<0!x$RYm27$qtk!8(P7RwCl1&`2ViElkK&qNNt& z16&?K>}>M@Vtciv;sc22t_p7P+nI0o`(~~(Ph)o5wi862>$c_B?(H`UP5hvTc%U5> zccm^!2tM@51Q`GjLHop~m-IFr&^`?{!A^C2)f~v9#cC;oYtq7PiHNn&8!haxy|@MA zkpJSd_{_39H}cIV0SF?KKqgfJ+KUMYW!?Y+*e9(5BSPzzfdm?m-lSlm?#sD<8^{i; z`ZjoYp_k(Z&#H+I4)vmuQ)M3C^%bx%XUsqeJ>vyjEX3}h`tTSl!N$D&yIhR~jWm#cOp@Mbuc+``noB1_6O5Vbuxiq5OKjC~C bKTT(PR`n%`Nb3k5v9l9-Rh8)BdZPXfMAuaq diff --git a/scripts/ch_lib/__pycache__/setting.cpython-310.pyc b/scripts/ch_lib/__pycache__/setting.cpython-310.pyc index 78c675c6b6ec07e6a55c19acdcce7906d93824aa..2571e3602895f6de1849e3b006b26b59d2ae439a 100644 GIT binary patch delta 743 zcmZvZ&x_MQ6vt;KFKL=4&APJMg3Hj+*jA zm9Z}roNNvT*Kz3aZ2L}IR_Bl~>CLUklQrodv;CS3WF2Q;hH?StK=M7-IyHN93kvoY zX5TJX3VWc^r<3=a{457mVJyEY=FS@4`eTrP7M;f7qfR$Dc%b9qFzG+s8B7Y$(Kv4A zd)6hskw3Rq`KSD)_3nZsXXC^uCN^`7!6 zf$y@Grz~2pkSw7TBGrYH=%b_?t7Xcbp)7RMNUDZeK8Yu~CDb|EJWoQ#OIfGYMU*Qz z^cG4Te37r(E7JwxbFj?jAu;^Z$OXkWaOfSBjAdN%xyVFjWsuoY7{nGLW<&mhJ##Wg zFG-*oE3|Jbz^{}`5|Eg>gfXi&Fwv?gn@w?po>BNunKD2KMMW89cvFj1rE7!6*c2ZIQL2L-_oJczig+mkT3yR%eJguuui zl0UG_bO0d|sW~4W zHcv23F)-D4dCqP1 zLX7=uIObQcIuWh8ZuaSeNsA)uZ>tTOE{=~AWTz2y~r)WJLpfvkr46w@44hw{i{ z_=}+0Rj-Grm_dZ_3}}tFNdS_L773aNR^-O|nc2*`DJ;3oWONrw-6p+8tP&dihwJwM94#4ee`CBO1dWe;K;r@bGh{&afU|;3fF*+e zm#__TxU~s+ua)%&+r>M4V=f~ICAj({Ji)R47M}mpkCmVWA;Ie;c80-C#Nk zYo-I)pfGj{$t7Y=ptIhpe!G`Kvl{sqAD-!T4!MEnggJ?1s;zBICO_ubnH$xyzZg!$ K)Mjf7;nlxR?SLl$ diff --git a/scripts/ch_lib/__pycache__/util.cpython-310.pyc b/scripts/ch_lib/__pycache__/util.cpython-310.pyc index 4bb6cf25f0c611014fcbab0e53bd677475d5cfd1..b1a1954a654d1683c6c9c85e137a09d13e8595dd 100644 GIT binary patch delta 1103 zcmZWnOK)5?6!!7sUe7c0Y9c06HK__{sF)I|JcPu%s)Ufbi4aQEG8*a|awn6_U>i!1 zM-iH^L8?$?*q|3+($T z^jB`~_DAUl*FU!Ds5d#xqKQrq?3IT93x0xS|2=&kzV(07vqzQ>#XNFk0gBJ)SDh)h zvEvSuxJ|E+8LqE19$7XQCU9{;Pdk4z?XVz(DbZjy{8Q9%S>SQnqp1;QqkIn@NI|vdu z1ZzPJ$~fu6&Lb(x$T;Y;Sa6dfoDPnTM0*R(+(p3c!I6KD0z>MEqLx{%*lj+gjt+%6 zk2Tyz=*Oprv~S~GhBBOAkxgO?wm2-!%MMU6fr>S!Oofjt{i*MjHRf&%%UK5zI{ z@p7AGk+FEc{Vd*11}f1eizj;gX`1*Q(Sy4GMy!|g8lD#g+0)DZN3mMgHRQS;py7WN zmy5Zdf!1x`jMmpTFk_Yx%Fv(@G@uw{ViKk4Jgjlu`{CWF4bA_4lZn)*RO_byJZ{4! ze>Wb%o4z2somcQLSs}H_em{SU(qy2M1Dg~72+kbkdcKcUju;+#(1DTpO6KSBl(VqxxCoSaDj5oh`0qk4vxKEN{w)hxy>OgcW$7m)fb`Q&QoJ>3fs-XPcDMimJ53 zR|^VONTdAI_Pz5`%(doQ3wvLVpkv;``e-+N{NQ;Uc3Xq(%o*sg7cUo#Pd`J&9MSn# z`&bkc1w#O$XbLeL&_j|^#ZnftgeX3wuj?s~dBPJ=VwWzHH9r*zi$x-aus~9l&;utC zhuGoS#9g8YM;S68Jvm3Bt6PX$xsQq`UF`1QL?>~^$=6U91cKh50DpsfOJ-ia3Y z=2%QS8SOvORpUF8X2F@eo$*0C-poMjaipQ`PoEiqUgoR*R%#n9#tY+b+HC3DA-4MAgnPP6HK7oM5cRv$OC6&Cur6(_r GmHz?>%$=G5 diff --git a/scripts/ch_lib/civitai.py b/scripts/ch_lib/civitai.py index 77f64bc..9fad166 100644 --- a/scripts/ch_lib/civitai.py +++ b/scripts/ch_lib/civitai.py @@ -43,7 +43,7 @@ def get_model_info_by_hash(hash:str): util.printD("hash is empty") return - r = requests.get(url_dict["hash"]+hash, headers=util.def_headers) + r = requests.get(url_dict["hash"]+hash, headers=util.def_headers, proxies=util.proxies) if not r.ok: if r.status_code == 404: # this is not a civitai model @@ -80,7 +80,7 @@ def get_model_info_by_id(id:str) -> dict: util.printD("id is empty") return - r = requests.get(url_dict["modelId"]+str(id), headers=util.def_headers) + r = requests.get(url_dict["modelId"]+str(id), headers=util.def_headers, proxies=util.proxies) if not r.ok: if r.status_code == 404: # this is not a civitai model @@ -116,7 +116,7 @@ def get_version_info_by_version_id(id:str) -> dict: util.printD("id is empty") return - r = requests.get(url_dict["modelVersionId"]+str(id), headers=util.def_headers) + r = requests.get(url_dict["modelVersionId"]+str(id), headers=util.def_headers, proxies=util.proxies) if not r.ok: if r.status_code == 404: # this is not a civitai model diff --git a/scripts/ch_lib/downloader.py b/scripts/ch_lib/downloader.py index fa24a5d..8febb7f 100644 --- a/scripts/ch_lib/downloader.py +++ b/scripts/ch_lib/downloader.py @@ -31,7 +31,7 @@ def dl(url, folder, filename, filepath): file_path = os.path.join(folder, filename) # first request for header - rh = requests.get(url, stream=True, verify=False, headers=util.def_headers) + rh = requests.get(url, stream=True, verify=False, headers=util.def_headers, proxies=util.proxies) # get file size total_size = 0 total_size = int(rh.headers['Content-Length']) @@ -79,7 +79,7 @@ def dl(url, folder, filename, filepath): headers['User-Agent'] = util.def_headers['User-Agent'] # download with header - r = requests.get(url, stream=True, verify=False, headers=headers) + r = requests.get(url, stream=True, verify=False, headers=headers, proxies=util.proxies) # write to file with open(dl_file_path, "ab") as f: diff --git a/scripts/ch_lib/model.py b/scripts/ch_lib/model.py index 2052006..729012d 100644 --- a/scripts/ch_lib/model.py +++ b/scripts/ch_lib/model.py @@ -49,14 +49,14 @@ def get_custom_model_folder(): # write model info to file def write_model_info(path, model_info): util.printD("Write model info to file: " + path) - with open(path, 'w') as f: + with open(os.path.realpath(path), 'w') as f: f.write(json.dumps(model_info, indent=4)) def load_model_info(path): # util.printD("Load model info from file: " + path) model_info = None - with open(path, 'r') as f: + with open(os.path.realpath(path), 'r') as f: try: model_info = json.load(f) except Exception as e: diff --git a/scripts/ch_lib/setting.py b/scripts/ch_lib/setting.py index b70bad1..aabff85 100644 --- a/scripts/ch_lib/setting.py +++ b/scripts/ch_lib/setting.py @@ -18,6 +18,7 @@ data = { "open_url_with_js": True, "always_display": False, "show_btn_on_thumb": True, + "proxy": "", }, "tool":{ } @@ -79,11 +80,14 @@ def load(): if "show_btn_on_thumb" not in data["general"].keys(): data["general"]["show_btn_on_thumb"] = True + if "proxy" not in data["general"].keys(): + data["general"]["proxy"] = "" + return # save setting from parameter -def save_from_input(max_size_preview, skip_nsfw_preview, open_url_with_js, always_display, show_btn_on_thumb): +def save_from_input(max_size_preview, skip_nsfw_preview, open_url_with_js, always_display, show_btn_on_thumb, proxy): global data data = { "model":{ @@ -94,6 +98,7 @@ def save_from_input(max_size_preview, skip_nsfw_preview, open_url_with_js, alway "open_url_with_js": open_url_with_js, "always_display": always_display, "show_btn_on_thumb": show_btn_on_thumb, + "proxy": proxy, }, "tool":{ } diff --git a/scripts/ch_lib/util.py b/scripts/ch_lib/util.py index c1a233e..28cc4f4 100644 --- a/scripts/ch_lib/util.py +++ b/scripts/ch_lib/util.py @@ -5,11 +5,15 @@ import hashlib import requests import shutil -version = "1.5.7" + +version = "1.6.0" def_headers = {'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148'} +proxies = None + + # print for debugging def printD(msg): print(f"Civitai Helper: {msg}") @@ -29,7 +33,7 @@ def gen_file_sha256(filname): blocksize=1 << 20 h = hashlib.sha256() length = 0 - with open(filname, 'rb') as f: + with open(os.path.realpath(filname), 'rb') as f: for block in read_chunks(f, size=blocksize): length += len(block) h.update(block) @@ -39,33 +43,20 @@ def gen_file_sha256(filname): printD("length: " + str(length)) return hash_value -# def gen_file_sha256(filname): -# printD("Calculate SHA256") -# # force to use Memory Optimized SHA256 -# # In case people don't understand this and uncheck it then stuck their system -# printD("Using Memory Optimized SHA256") -# hash_sha256 = hashlib.sha256() -# with open(filname, "rb") as f: -# for chunk in iter(lambda: f.read(4096), b""): -# hash_sha256.update(chunk) - -# hash_value = hash_sha256.hexdigest() -# printD("sha256: " + hash_value) -# return hash_value # get preview image def download_file(url, path): printD("Downloading file from: " + url) # get file - r = requests.get(url, stream=True, headers=def_headers) + r = requests.get(url, stream=True, headers=def_headers, proxies=proxies) if not r.ok: printD("Get error code: " + str(r.status_code)) printD(r.text) return # write to file - with open(path, 'wb') as f: + with open(os.path.realpath(path), 'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw, f) @@ -93,3 +84,22 @@ def get_subfolders(folder:str) -> list: return subfolders + +# get relative path +def get_relative_path(item_path:str, parent_path:str) -> str: + # printD("item_path:"+item_path) + # printD("parent_path:"+parent_path) + # item path must start with parent_path + if not item_path: + return "" + if not parent_path: + return "" + if not item_path.startswith(parent_path): + return item_path + + relative = item_path[len(parent_path):] + if relative[:1] == "/" or relative[:1] == "\\": + relative = relative[1:] + + # printD("relative:"+relative) + return relative \ No newline at end of file diff --git a/scripts/civitai_helper.py b/scripts/civitai_helper.py index 8419d1c..3c2f6fd 100644 --- a/scripts/civitai_helper.py +++ b/scripts/civitai_helper.py @@ -26,13 +26,35 @@ from scripts.ch_lib import util # init + +# root path +root_path = os.getcwd() + +# extension path +extension_path = scripts.basedir() + model.get_custom_model_folder() setting.load() +# set proxy +if setting.data["general"]["proxy"]: + util.printD("Set Proxy: "+setting.data["general"]["proxy"]) + util.proxies = { + "http": setting.data["general"]["proxy"], + "https": setting.data["general"]["proxy"], + } + + def on_ui_tabs(): # init + # init_py_msg = { + # # relative extension path + # "extension_path": util.get_relative_path(extension_path, root_path), + # } + # init_py_msg_str = json.dumps(init_py_msg) + # get prompt textarea # check modules/ui.py, search for txt2img_paste_fields @@ -62,8 +84,8 @@ def on_ui_tabs(): return [model_info, model_name, model_type, dl_subfolder_drop.update(choices=subfolders), dl_version_drop.update(choices=version_strs)] # ====UI==== - # with gr.Blocks(analytics_enabled=False) as civitai_helper: - with gr.Blocks(css="button {background-color: #228be6}") as civitai_helper: + with gr.Blocks(analytics_enabled=False) as civitai_helper: + # with gr.Blocks(css=".block.padded {padding: 10px !important}") as civitai_helper: # init max_size_preview = setting.data["model"]["max_size_preview"] @@ -71,6 +93,7 @@ def on_ui_tabs(): open_url_with_js = setting.data["general"]["open_url_with_js"] always_display = setting.data["general"]["always_display"] show_btn_on_thumb = setting.data["general"]["show_btn_on_thumb"] + proxy = setting.data["general"]["proxy"] model_types = list(model.folders.keys()) no_info_model_names = civitai.get_model_names_by_input("ckp", False) @@ -80,8 +103,7 @@ def on_ui_tabs(): - # with gr.Tab("Model"): - with gr.Box(): + with gr.Box(elem_classes="ch_box"): with gr.Column(): gr.Markdown("### Scan Models for Civitai") with gr.Row(): @@ -95,20 +117,20 @@ def on_ui_tabs(): scan_model_log_md = gr.Markdown(value="Scanning takes time, just wait. Check console log for detail", elem_id="ch_scan_model_log_md") - with gr.Box(): + with gr.Box(elem_classes="ch_box"): with gr.Column(): gr.Markdown("### Get Model Info from Civitai by URL") gr.Markdown("Use this when scanning can not find a local model on civitai") with gr.Row(): model_type_drop = gr.Dropdown(choices=model_types, label="Model Type", value="ckp", multiselect=False) - empty_info_only_ckb = gr.Checkbox(label="Only Show Models have no Info", value=False, elem_id="cn_empty_info_only_ckb") + empty_info_only_ckb = gr.Checkbox(label="Only Show Models have no Info", value=False, elem_id="cn_empty_info_only_ckb", elem_classes="ch_vpadding") model_name_drop = gr.Dropdown(choices=no_info_model_names, label="Model", value="ckp", multiselect=False) model_url_or_id_txtbox = gr.Textbox(label="Civitai URL", lines=1, value="") get_civitai_model_info_by_id_btn = gr.Button(value="Get Model Info from Civitai", variant="primary") get_model_by_id_log_md = gr.Markdown("") - with gr.Box(): + with gr.Box(elem_classes="ch_box"): with gr.Column(): gr.Markdown("### Download Model") with gr.Row(): @@ -125,7 +147,7 @@ def on_ui_tabs(): dl_civitai_model_by_id_btn = gr.Button(value="3. Download Model", variant="primary") dl_log_md = gr.Markdown(value="Check Console log for Downloading Status") - with gr.Box(): + with gr.Box(elem_classes="ch_box"): with gr.Column(): gr.Markdown("### Check models' new version") with gr.Row(): @@ -134,7 +156,7 @@ def on_ui_tabs(): check_models_new_version_log_md = gr.HTML("It takes time, just wait. Check console log for detail") - with gr.Box(): + with gr.Box(elem_classes="ch_box"): with gr.Column(): gr.Markdown("### Other Setting") with gr.Row(): @@ -142,6 +164,8 @@ def on_ui_tabs(): always_display_ckb = gr.Checkbox(label="Always Display Buttons", value=always_display, elem_id="ch_always_display_ckb") show_btn_on_thumb_ckb = gr.Checkbox(label="Show Button On Thumb Mode", value=show_btn_on_thumb, elem_id="ch_show_btn_on_thumb_ckb") + proxy_txtbox = gr.Textbox(label="Proxy", interactive=True, lines=1, value=proxy, info="format: http://127.0.0.1:port") + save_setting_btn = gr.Button(value="Save Setting") general_log_md = gr.Markdown(value="") @@ -176,7 +200,7 @@ def on_ui_tabs(): check_models_new_version_btn.click(model_action_civitai.check_models_new_version_to_md, inputs=model_types_ckbg, outputs=check_models_new_version_log_md) # Other Setting - save_setting_btn.click(setting.save_from_input, inputs=[max_size_preview_ckb, skip_nsfw_preview_ckb, open_url_with_js_ckb, always_display_ckb, show_btn_on_thumb_ckb], outputs=general_log_md) + save_setting_btn.click(setting.save_from_input, inputs=[max_size_preview_ckb, skip_nsfw_preview_ckb, open_url_with_js_ckb, always_display_ckb, show_btn_on_thumb_ckb, proxy_txtbox], outputs=general_log_md) # js action js_open_url_btn.click(js_action_civitai.open_model_url, inputs=[js_msg_txtbox, open_url_with_js_ckb], outputs=py_msg_txtbox) @@ -190,3 +214,4 @@ def on_ui_tabs(): script_callbacks.on_ui_tabs(on_ui_tabs) + diff --git a/style.css b/style.css index 91a62ea..387156e 100644 --- a/style.css +++ b/style.css @@ -7,3 +7,12 @@ blockquote ol { list-style:decimal; margin:4px 40px; } + +.block.padded.ch_box { + padding: 10px !important; +} + +.block.padded.ch_vpadding { + padding: 10px 0 !important; +} +