#@markdown # Install/Update AUTOMATIC1111 repo
from IPython.utils import capture
from IPython.display import clear_output
from subprocess import getoutput
import ipywidgets as widgets
import sys
import fileinput
import os
import time
import base64
import gdown
from gdown.download import get_url_from_gdrive_confirmation
import requests
from urllib.request import urlopen, Request
from urllib.parse import urlparse, parse_qs, unquote
from tqdm import tqdm
import six


blsaphemy=base64.b64decode(("ZWJ1aQ==").encode('ascii')).decode('ascii')

if not os.path.exists("/content/gdrive"):
  print('Gdrive not connected, using temporary colab storage ...')
  time.sleep(4)
  mainpth="MyDrive"
  !mkdir -p /content/gdrive/$mainpth
  Shared_Drive=""

if Shared_Drive!="" and not os.path.exists("/content/gdrive/Shareddrives"):
  print('Shared drive not detected, using default MyDrive')
  mainpth="MyDrive"

with capture.capture_output() as cap:
  def inf(msg, style, wdth): inf = widgets.Button(description=msg, disabled=True, button_style=style, layout=widgets.Layout(min_width=wdth));display(inf)
  fgitclone = "git clone --depth 1"
  %mkdir -p /content/gdrive/$mainpth/sd
  %cd /content/gdrive/$mainpth/sd
  !git clone -q --branch master https://github.com/AUTOMATIC1111/stable-diffusion-w$blsaphemy
  !mkdir -p /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/cache/
  os.environ['TRANSFORMERS_CACHE']=f"/content/gdrive/{mainpth}/sd/stable-diffusion-w"+blsaphemy+"/cache"
  os.environ['TORCH_HOME'] = f"/content/gdrive/{mainpth}/sd/stable-diffusion-w"+blsaphemy+"/cache"

with capture.capture_output() as cap:
  %cd /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/
  !git reset --hard
  !git checkout master
  time.sleep(1)
  !rm webui.sh
  !git pull
clear_output()
inf('\u2714 Done','success', '50px')

#@markdown ---

#@markdown # Requirements

print('Installing requirements...')

with capture.capture_output() as cap:
  %cd /content/
  !wget -q -i https://raw.githubusercontent.com/TheLastBen/fast-stable-diffusion/main/Dependencies/A1111.txt
  !dpkg -i *.deb
  if not os.path.exists('/content/gdrive/'+mainpth+'/sd/stablediffusiond'): #restore later
    !tar -C /content/gdrive/$mainpth --zstd -xf sd_mrep.tar.zst
  !tar -C / --zstd -xf gcolabdeps.tar.zst
  !rm *.deb | rm *.zst | rm *.txt
  if not os.path.exists('gdrive/'+mainpth+'/sd/libtcmalloc/libtcmalloc_minimal.so.4'):
    %env CXXFLAGS=-std=c++14
    !wget -q https://github.com/gperftools/gperftools/releases/download/gperftools-2.5/gperftools-2.5.tar.gz && tar zxf gperftools-2.5.tar.gz && mv gperftools-2.5 gperftools
    !wget -q https://github.com/TheLastBen/fast-stable-diffusion/raw/main/AUTOMATIC1111_files/Patch
    %cd /content/gperftools
    !patch -p1 < /content/Patch
    !./configure --enable-minimal --enable-libunwind --enable-frame-pointers --enable-dynamic-sized-delete-support --enable-sized-delete --enable-emergency-malloc; make -j4
    !mkdir -p /content/gdrive/$mainpth/sd/libtcmalloc && cp .libs/libtcmalloc*.so* /content/gdrive/$mainpth/sd/libtcmalloc
    %env LD_PRELOAD=/content/gdrive/$mainpth/sd/libtcmalloc/libtcmalloc_minimal.so.4
    %cd /content
    !rm *.tar.gz Patch && rm -r /content/gperftools
  else:
    %env LD_PRELOAD=/content/gdrive/$mainpth/sd/libtcmalloc/libtcmalloc_minimal.so.4

  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
  os.environ['PYTHONWARNINGS'] = 'ignore'
  !sed -i 's@text = _formatwarnmsg(msg)@text =\"\"@g' /usr/lib/python3.10/warnings.py

clear_output()
inf('\u2714 Done','success', '50px')

#@markdown ---
#@markdown # ControlNet
from torch.hub import download_url_to_file
from urllib.parse import urlparse
import re
from subprocess import run

XL_Model = "None" #@param [ "None", "All", "Canny", "Depth", "Sketch", "OpenPose", "Recolor"]

v1_Model = "None" #@param [ "None", "All (21GB)", "Canny", "Depth", "Lineart", "MLSD", "Normal", "OpenPose", "Scribble", "Seg", "ip2p", "Shuffle", "Inpaint", "Softedge", "Lineart_Anime", "Tile", "T2iadapter_Models"]

v2_Model = "None" #@param [ "None", "All", "Canny", "Depth", "HED", "OpenPose", "Scribble"]

#@markdown - Download/update ControlNet extension and its models

def download(url, model_dir):

    filename = os.path.basename(urlparse(url).path)
    pth = os.path.abspath(os.path.join(model_dir, filename))
    if not os.path.exists(pth):
        print('Downloading: '+os.path.basename(url))
        download_url_to_file(url, pth, hash_prefix=None, progress=True)
    else:
      print(f"The model {filename} already exists")


Canny='https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/diffusers_xl_canny_mid.safetensors'
Depth='https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/diffusers_xl_depth_mid.safetensors'
Sketch='https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sai_xl_sketch_256lora.safetensors'
OpenPose='https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/thibaud_xl_openpose_256lora.safetensors'
Recolor='https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sai_xl_recolor_128lora.safetensors'


with capture.capture_output() as cap:
  %cd /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/extensions
  if not os.path.exists('sd-w'+blsaphemy+'-controlnet'):
    !git clone https://github.com/Mikubill/sd-w$blsaphemy-controlnet.git
    %cd /content
  else:
    %cd sd-w$blsaphemy-controlnet
    !git reset --hard
    !git pull
    %cd /content

mdldir='/content/gdrive/'+mainpth+'/sd/stable-diffusion-w'+blsaphemy+'/extensions/sd-w'+blsaphemy+'-controlnet/models'
for filename in os.listdir(mdldir):
  if "_sd14v1" in filename:
    renamed = re.sub("_sd14v1", "-fp16", filename)
    os.rename(os.path.join(mdldir, filename), os.path.join(mdldir, renamed))

!wget -q -O CN_models.txt https://github.com/TheLastBen/fast-stable-diffusion/raw/main/AUTOMATIC1111_files/CN_models.txt
!wget -q -O CN_models_v2.txt https://github.com/TheLastBen/fast-stable-diffusion/raw/main/AUTOMATIC1111_files/CN_models_v2.txt
!wget -q -O CN_models_XL.txt https://github.com/TheLastBen/fast-stable-diffusion/raw/main/AUTOMATIC1111_files/CN_models_XL.txt


with open("CN_models.txt", 'r') as f:
  mdllnk = f.read().splitlines()
with open("CN_models_v2.txt", 'r') as d:
  mdllnk_v2 = d.read().splitlines()
with open("CN_models_XL.txt", 'r') as d:
  mdllnk_XL = d.read().splitlines()

!rm CN_models.txt CN_models_v2.txt CN_models_XL.txt


if XL_Model == "All":
  for lnk_XL in mdllnk_XL:
      download(lnk_XL, mdldir)
  clear_output()
  inf('\u2714 Done','success', '50px')

elif XL_Model == "None":
    pass
    clear_output()
    inf('\u2714 Done','success', '50px')

else:
  download(globals()[XL_Model], mdldir)
  clear_output()
  inf('\u2714 Done','success', '50px')


Canny='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_canny.pth'
Depth='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11f1p_sd15_depth.pth'
Lineart='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_lineart.pth'
MLSD='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_mlsd.pth'
Normal='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_normalbae.pth'
OpenPose='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_openpose.pth'
Scribble='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_scribble.pth'
Seg='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_seg.pth'
ip2p='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11e_sd15_ip2p.pth'
Shuffle='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11e_sd15_shuffle.pth'
Inpaint='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_inpaint.pth'
Softedge='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_softedge.pth'
Lineart_Anime='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15s2_lineart_anime.pth'
Tile='https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11f1e_sd15_tile.pth'


with capture.capture_output() as cap:
  cfgnames=[os.path.basename(url).split('.')[0]+'.yaml' for url in mdllnk_v2]
  %cd /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/extensions/sd-w$blsaphemy-controlnet/models
  for name in cfgnames:
      run(['cp', 'cldm_v21.yaml', name])
  %cd /content

if v1_Model == "All (21GB)":
  for lnk in mdllnk:
      download(lnk, mdldir)
  clear_output()

elif v1_Model == "T2iadapter_Models":
  mdllnk=list(filter(lambda x: 't2i' in x, mdllnk))
  for lnk in mdllnk:
      download(lnk, mdldir)
  clear_output()

elif v1_Model == "None":
    pass
    clear_output()

else:
  download(globals()[v1_Model], mdldir)
  clear_output()

Canny='https://huggingface.co/thibaud/controlnet-sd21/resolve/main/control_v11p_sd21_canny.safetensors'
Depth='https://huggingface.co/thibaud/controlnet-sd21/resolve/main/control_v11p_sd21_depth.safetensors'
HED='https://huggingface.co/thibaud/controlnet-sd21/resolve/main/control_v11p_sd21_hed.safetensors'
OpenPose='https://huggingface.co/thibaud/controlnet-sd21/resolve/main/control_v11p_sd21_openposev2.safetensors'
Scribble='https://huggingface.co/thibaud/controlnet-sd21/resolve/main/control_v11p_sd21_scribble.safetensors'


if v2_Model == "All":
  for lnk_v2 in mdllnk_v2:
      download(lnk_v2, mdldir)
  clear_output()
  inf('\u2714 Done','success', '50px')

elif v2_Model == "None":
    pass
    clear_output()
    inf('\u2714 Done','success', '50px')

else:
  download(globals()[v2_Model], mdldir)
  clear_output()
  inf('\u2714 Done','success', '50px')

  #@markdown ---
#@markdown # Start Stable-Diffusion
from IPython.utils import capture
import time
import sys
import fileinput
from pyngrok import ngrok, conf
import re


Use_Cloudflare_Tunnel = False #@param {type:"boolean"}
#@markdown - Offers better gradio responsivity

Ngrok_token = "" #@param {type:"string"}

#@markdown - Input your ngrok token if you want to use ngrok server

User = "" #@param {type:"string"}
Password= "" #@param {type:"string"}
#@markdown - Add credentials to your Gradio interface (optional)

auth=f"--gradio-auth {User}:{Password}"
if User =="" or Password=="":
  auth=""


with capture.capture_output() as cap:
  %cd /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/modules/
  !wget -q -O extras.py https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-w$blsaphemy/master/modules/extras.py
  !wget -q -O sd_models.py https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-w$blsaphemy/master/modules/sd_models.py
  !wget -q -O /usr/local/lib/python3.10/dist-packages/gradio/blocks.py https://raw.githubusercontent.com/TheLastBen/fast-stable-diffusion/main/AUTOMATIC1111_files/blocks.py
  %cd /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/
  
  !sed -i 's@shared.opts.data\["sd_model_checkpoint"] = checkpoint_info.title@shared.opts.data\["sd_model_checkpoint"] = checkpoint_info.title;model.half()@' /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/modules/sd_models.py
  #!sed -i 's@ui.create_ui().*@ui.create_ui();shared.demo.queue(concurrency_count=999999,status_update_rate=0.1)@' /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/webui.py
  !sed -i "s@map_location='cpu'@map_location='cuda'@" /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/modules/extras.py

  !sed -i 's@possible_sd_paths =.*@possible_sd_paths = [\"/content/gdrive/{mainpth}/sd/stablediffusion\"]@' /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/modules/paths.py
  !sed -i 's@\.\.\/@src/@g' /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/modules/paths.py
  !sed -i 's@src/generative-models@generative-models@g' /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/modules/paths.py

  !sed -i 's@print(\"No module.*@@' /content/gdrive/$mainpth/sd/stablediffusion/ldm/modules/diffusionmodules/model.py
  !sed -i 's@\["sd_model_checkpoint"\]@\["sd_model_checkpoint", "sd_vae", "CLIP_stop_at_last_layers", "inpainting_mask_weight", "initial_noise_multiplier"\]@g' /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/modules/shared.py

share=''
if Ngrok_token!="":
  ngrok.kill()
  srv=ngrok.connect(7860, pyngrok_config=conf.PyngrokConfig(auth_token=Ngrok_token) , bind_tls=True).public_url

  for line in fileinput.input('/usr/local/lib/python3.10/dist-packages/gradio/blocks.py', inplace=True):
    if line.strip().startswith('self.server_name ='):
        line = f'            self.server_name = "{srv[8:]}"\n'
    if line.strip().startswith('self.protocol = "https"'):
        line = '            self.protocol = "https"\n'
    if line.strip().startswith('if self.local_url.startswith("https") or self.is_colab'):
        line = ''
    if line.strip().startswith('else "http"'):
        line = ''
    sys.stdout.write(line)

elif Use_Cloudflare_Tunnel:
  with capture.capture_output() as cap:
    !pkill cloudflared
    time.sleep(4)
    !nohup cloudflared tunnel --url http://localhost:7860 > /content/srv.txt 2>&1 &
    time.sleep(4)
    with open('/content/srv.txt', "r") as file: text = file.read()
    srv= re.findall(r"https?://(?:\S+?\.)?trycloudflare\.com\S*", text)[0]

    for line in fileinput.input('/usr/local/lib/python3.10/dist-packages/gradio/blocks.py', inplace=True):
      if line.strip().startswith('self.server_name ='):
          line = f'            self.server_name = "{srv[8:]}"\n'
      if line.strip().startswith('self.protocol = "https"'):
          line = '            self.protocol = "https"\n'
      if line.strip().startswith('if self.local_url.startswith("https") or self.is_colab'):
          line = ''
      if line.strip().startswith('else "http"'):
          line = ''
      sys.stdout.write(line)

    !rm /content/srv.txt

else:
  share='--share'

ckptdir=''
if os.path.exists('/content/temp_models'):
  ckptdir='--ckpt-dir /content/temp_models'

try:
  model
  if os.path.isfile(model):
    !python /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/webui.py $share --api --disable-safe-unpickle --enable-insecure-extension-access --no-download-sd-model --no-half-vae  --ckpt "$model" --xformers $auth --disable-console-progressbars --upcast-sampling $ckptdir
  else:
    !python /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/webui.py $share --api --disable-safe-unpickle --enable-insecure-extension-access --no-download-sd-model --no-half-vae  --ckpt-dir "$model" --xformers $auth --disable-console-progressbars --upcast-sampling
except:
   !python /content/gdrive/$mainpth/sd/stable-diffusion-w$blsaphemy/webui.py $share --api --disable-safe-unpickle --enable-insecure-extension-access --no-download-sd-model --no-half-vae --xformers $auth --disable-console-progressbars --upcast-sampling $ckptdir