import gradio as gr
import requests
import subprocess
import os
from huggingface_hub import whoami
from huggingface_hub import HfApi
from huggingface_hub import login
import random
import time
api=HfApi()
FILE_TYPES = ["Embedding", "Stable Diffusion Model", "Lora", "Lycoris"]
def duplicate(source_url, preview_url, model_id, dst_repo, token, repo_type, nsfw, make_pr):
dir="/home/user/apps/downloads/"+str(int(time.time()))+str(random.getrandbits(8))
try:
_ = whoami(token)
# ^ this will throw if token is invalid
# make sure the user fills out the other required paths.
if not source_url:
raise Exception("You haven't chosen a file to download!")
if not dst_repo:
raise Exception("You haven't chosen a repo to download to")
login(token=token)
# keep things separate, partly in case people download different files with same name (`download.zip`). Especially, it also allows saving filename to work
subprocess.check_call([r"mkdir","-p",dir])
subprocess.check_call([r"aria2c","-x16","--split=16",source_url,"--dir",dir])
filename=os.listdir(dir)[0].rsplit('.',1)[0]
if not model_id=="":
apiurl="https://civitai.com/api/v1/model-versions/"+model_id
subprocess.check_call(["wget",apiurl,"-O",f"{dir}/{filename}.civitai.info"])
apimd=f"\n\n[api response]({apiurl})"
else:
apimd=""
if not preview_url=="":
subprocess.check_call(["wget",preview_url,"-O",f"{dir}/{filename}.preview.png"])
previewhtml=f' Here\'s your preview:'
previewmd=f'\n\n![preview]({preview_url})'
else:
previewmd=""
previewhtml=""
match repo_type:
case "Embedding":
repopath="/embeddings"
case "Stable Diffusion Model":
repopath="/models/Stable-diffusion"
case "Lora":
repopath="/models/Lora/Lora"
case "Lycoris":
repopath="/models/Lora/Lycoris"
if nsfw==True:
repopath=repopath+"/nsfw"
commitmessage=f"{filename} (nsfw)"
previewhtml=previewhtml+"
now isn't that a lovely picture?"
else:
commitmessage=filename
ret=api.upload_folder(
folder_path=dir,
path_in_repo=repopath,
repo_id=dst_repo,
repo_type="model",
commit_message=commitmessage,
commit_description="source: "+source_url+apimd+previewmd,
create_pr=make_pr
)
# now clean up
subprocess.check_call([r"rm","-rf",dir])
return (
f'Find your commit at the top of your commits, or your pull request here.{previewhtml}'
)
except Exception as e:
subprocess.check_call([r"rm","-rf",dir])
blames=["grandma","my boss","your boss","God","you","you. It's *all* your fault.","the pope"]
blameweights=(1,1,1,1,4,2,1)
excuses=["I blame it all on "+random.choices(blames,weights=blameweights)[0],"It's my fault, sorry.","I did it on purpose.","That file doesn't want to be downloaded.","You nincompoop!"]
excusesweights=(12,1,1,2,3)
excuse=random.choices(excuses,weights=excusesweights)[0]
return (
f"""
### Error 😢😢😢
{e}
""" + excuse+"",
None,
)
interface = gr.Interface(
fn=duplicate,
inputs=[
gr.Textbox(label="Source URL", info="Source URL for model file. FP32 unpruned preferred, but you can upload multiple versions. Safetensors preferred, but not really important.", placeholder="https://civitai.com/api/download/models/4324322534?garbageextrastuff"),
gr.Textbox(label="Preview URL", info="URL for model preview on civitai. High resolution with generation data preferred, you can upload an alternate separately without the .preview part in the filename, this will override the preview. Will be renamed to modelprefix.preview.png, regardless of actual format; this is what civitai unofficial extemsion wants.", placeholder="https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/df8e24d7-4094-42cf-0d8f-a50afd28f800/00143-3805918203.jpeg"),
gr.Textbox(label="Model ID", info="You can get this from the source URL", placeholder="model ID (e.g. 4324322534)"),
gr.Textbox(label="Destination repository",value="mirroring/civitai_mirror"),
gr.Textbox(label="Access Token", info="Write access token (write access required)", type="password"),
gr.Dropdown(label="File type", info="What type of model is this? If it's not a stable diffusion model, Lora, lycoris, or embedding, upload it separately. (for example, if you've got a VAE)", choices=FILE_TYPES, value="Stable Diffusion Model"),
gr.Checkbox(label="NSFW model?", info="check if the model is intended for nsfw, or creates such images on its own. Places file in the /nsfw subdirectory.",value=False),
gr.Checkbox(label="Pull Request?", info="uncheck if you have write access and want to merge your file directly",value=True),
],
outputs=[
gr.Markdown(label="output")
],
title="Download a civitai model to your repo!",
description="Download a model from Civitai to your repo on HF. Hopefully will soon parse the modelid from the download url, then get the preview automatically from the api response (lets be realistic, this will never happen); in the meantime you need to provide the model id number from the download url , and the location of the preview file.\n\nThis Space is a an experimental demo.",
article="
Find your write token at token settings
", allow_flagging="never", live=False, # since i keep wondering, this prevents it from running again automatically when an input changes ) interface.launch(enable_queue=True)