res=conn.execute("""SELECT count(*), prompt.id, daily_cycles, daily_cycles-coalesce(cast(sum((86400-(strftime('%s')-completed_at))/86400*(number*inference_steps/quality)) as int), 0) AS balance, coalesce(86400-(STRFTIME('%s')-max(completed_at)), 0) AS remaining_time, CAST(sum(number*inference_steps/quality)/24 AS integer) AS hourly_gain FROM user
buttons=[Button.inline(f"🚫 No image",f"msg_but:no_image"),]
ifconn.execute('SELECT * FROM prompt WHERE user_id = ? ORDER BY id DESC LIMIT 1',(ev.input_sender.user_id,)).fetchone():
buttons.append(Button.inline(f"📋 Copy your last prompt",f"copy_last"))
awaitedit_or_respond(ev,'Creating a new prompt!\nSend me an image, an e621 link, or just press on "No image" if you want to only use a text prompt.\n\n⚠️ From now on, we will use BB95 instead of yiffy-e18! Pino daeni and other tags are not valid anymore. ⚠️',buttons=buttons)
conn.execute('INSERT INTO pending_prompt(user_id, seed) VALUES (?, ?)',(ev.input_sender.user_id,randint(0,1000000)))
conn.execute('UPDATE user SET pending_action = \'initial_image\' WHERE id = ?',(ev.input_sender.user_id,))
conn.execute('DELETE FROM pending_prompt WHERE user_id = ?',(ev.input_sender.user_id,))
conn.execute('INSERT INTO pending_prompt SELECT user_id, image, prompt, detail, negative_prompt, inference_steps, number, ?, blend, prompt_e6, image_e6, resolution, crop, hires FROM prompt WHERE user_id = ? ORDER BY id DESC LIMIT 1',(randint(0,1000000),ev.input_sender.user_id))
awaitedit_prompt(ev)
asyncdefstep_two(ev):
msg=awaitev.respond("Please give me a prompt to use.\n\nThis is a phrase, or a list of e621 tags, or a link to an e621 post to use as a source.\nYou can increase weight on some tags by enclosing them with ((brackets)).\n\nIf you're starting off from an image, please make sure the tags accurately describe the picture for the best results.\n\nSome examples:\n"+
'- "chunie wolf ((athletic male)) solo (abs) pecs standing topless swimwear"\n'+
'- "a digital drawing by chunie of a fox smiling at the side of a swimming pool, wearing swimwear and with white fur and grey ears"\n'+
awaitev.respond('Something went wrong. Try /start again.')
return
iffield=='number':
try:
data=int(data)
assertdata<=4
assertdata>0
except:
awaitev.respond('You can only generate between 1 and 4 images. Try again:')
raiseevents.StopPropagation
ifdata*pending_prompt['inference_steps']>200:
awaitev.respond(f"You have choosen to generate {data} images with {pending_prompt['inference_steps']} cycles, resulting in a total {data*pending_prompt['inference_steps']} cycles. If you want to increase the number of generated images, reduce the cycles so that the total is below 200.")
awaitev.respond('Level of detail must be between 2 and 20. We suggest using 7.5 for best results.')
raiseevents.StopPropagation
iffield=='crop':
data=data.lower()
ifdatanotin['yes','no']:
awaitev.respond('Answer for this question must be yes or no.')
raiseevents.StopPropagation
iffield=='hires':
data=data.lower()
ifdatanotin['yes','no']:
awaitev.respond('Answer for this question must be yes or no.')
raiseevents.StopPropagation
iffield=='blend':
try:
data=float(data)
assertdata>=0.3
assertdata<=0.9
except:
awaitev.respond('Level of blend must be between 0.3 and 0.9.')
raiseevents.StopPropagation
iffield=='inference_steps':
try:
data=int(data)
assertdata>=20
assertdata<=200
assertdata%10==0
except:
awaitev.respond('Generation time must be an integer between 20 and 200, a multiple of 10.')
raiseevents.StopPropagation
ifdata*pending_prompt['number']>200:
awaitev.respond(f"You have choosen to generate {pending_prompt['number']} images with {data} cycles, a total {pending_prompt['number']*data} cycles. If you want to increase the cycles, reduce the number of generated images so that the total is below 200.")
return
iffield=='image':
conn.execute('UPDATE pending_prompt SET image_e6 = NULL WHERE user_id = ?',(ev.input_sender.user_id,))
avg_comp_time=conn.execute('SELECT avg(aa) FROM (SELECT abs(queued_at-started_at) AS aa FROM prompt WHERE queued_at IS NOT NULL AND completed_at IS NOT NULL ORDER BY id DESC LIMIT 10)').fetchone()
avg_wait=conn.execute("SELECT avg(strftime('%s', 'now')-queued_at) AS aa FROM prompt WHERE queued_at IS NOT NULL AND is_done IS NULL").fetchone()
min_max_wait=conn.execute("SELECT max(strftime('%s', 'now')-queued_at), min(strftime('%s', 'now')-queued_at) FROM prompt WHERE queued_at IS NOT NULL AND is_done IS NULL").fetchone()
waiting_usrs=conn.execute("SELECT count(*) FROM prompt WHERE is_done IS NULL").fetchone()
avg_speed=conn.execute("SELECT avg(aa) FROM (SELECT (inference_steps*number)/abs(completed_at-started_at) AS aa FROM prompt WHERE started_at IS NOT NULL AND completed_at IS NOT NULL ORDER BY id DESC LIMIT 10)").fetchone()
awaitev.respond("\n".join([
f"👯♂️ {waiting_usrs[0]} people are waiting in the queue",
f"{'🔴'ifint(avg_comp_time[0]/60)>20else('🟡'ifint(avg_comp_time[0]/60)>3else'🟢')} Average queue-to-result time: <strong>{int(avg_comp_time[0]/60)} minutes</strong>.",
f"{'🔴'ifint(min_max_wait[0]/60)>20else('🟡'ifint(min_max_wait[0]/60)>5else'🟢')} Current queue duration: {int(min_max_wait[1]/60)}~{int(min_max_wait[0]/60)} minutes",
queue=conn.execute("""SELECT prompt.id, inference_steps*number AS cycles, strftime('%s', 'now')-prompt.queued_at AS wait, prompt.started_at, user.name FROM prompt
prompt=conn.execute('SELECT * FROM prompt WHERE is_done IS NULL AND user_id = ?',(ev.input_sender.user_id,)).fetchone()
ifnotprompt:
awaitedit_or_respond(ev,'You don\'t have pending prompts :)\n/new for a new one')
raiseevents.StopPropagation
avg_comp_time=conn.execute('SELECT avg(aa) FROM (SELECT abs(queued_at-started_at) AS aa FROM prompt WHERE queued_at IS NOT NULL AND completed_at IS NOT NULL ORDER BY id DESC LIMIT 10)').fetchone()
behind_you=conn.execute('SELECT count(*) FROM prompt WHERE is_done IS NULL AND id > ?',(prompt['id'],)).fetchone()[0]
front_you=conn.execute('SELECT count(*) FROM prompt WHERE is_done IS NULL AND id < ?',(prompt['id'],)).fetchone()[0]
ifnew_message:
awaitclient.send_message(ev.sender,f"Your position in the queue:\n{behind_you} behind you, {front_you} in front of you\n{'🫥'*behind_you}😃{'🫥'*front_you}\n\nCurrent average wait time: {int(avg_comp_time[0]/60)} minutes",buttons=[[Button.inline(f"👯 Refresh queue",f"queue")]])
else:
awaitedit_or_respond(ev,f"Your position in the queue:\n{behind_you} behind you, {front_you} in front of you\n{'🫥'*behind_you}😃{'🫥'*front_you}\n\nCurrent average wait time: {int(avg_comp_time[0]/60)} minutes",buttons=[[Button.inline(f"👯 Refresh queue",f"queue")]])
awaitev.respond(f"Sorry. You only have {usage['balance']} cycles left out of the {user['daily_cycles']} 🌀 you can use every day. You can use /cycles to have more info on how many cycles you can use.")
conn.execute('INSERT INTO prompt SELECT NULL, NULL, NULL, *, ?, NULL, NULL, ? FROM pending_prompt WHERE user_id = ?',(time(),quality,ev.input_sender.user_id)).fetchone()
conn.execute('DELETE FROM pending_prompt WHERE user_id = ?',(ev.input_sender.user_id,))
prompt=conn.execute('SELECT * FROM prompt WHERE user_id = ? AND is_done IS NULL ORDER BY id DESC LIMIT 1',(ev.input_sender.user_id,)).fetchone()
awaitedit_or_respond(ev,
"\n".join([f"✅ Your prompt {prompt['id']} has been scheduled and will be generated soon!\n",
f"<strong>You spent {prompt['number']*prompt['inference_steps']} cycle/bs. You have {int(usage['balance']-((prompt['inference_steps']*prompt['number'])/quality))} left for today.</strong>"]),parse_mode='HTML')
awaitqueue(ev,new_message=True)
awaitclient.send_message(client.log_channel_id,f"New prompt #{prompt['id']} by {ev.input_sender.user_id}{get_display_name(ev.sender)}\n\n{prompt['prompt']}",
self.log.error(f"Tried to insert a duplicate task while confirming!!!")
print(task,client.queue._queue)
return
client.queue.put_nowait(task)
awaitstart_queue(ev)
raiseevents.StopPropagation
desc={
'seed':'The seed must be a whole number between 0 and 1000000. It defines the random noise which will be used to begin generation - two images with the same seed will be identical. Write it or get the one from the previous generation.',
'image':'Upload an image, give me an e621 link or just delete the current one.',
'prompt':'A list of e621 tags, a phrase or an e621 link to use as a prompt for your image',
'negative_prompt':'A list of e621 tags you don\'t want to see. Do not put - in front of the tags',
'number':'Number of images to generate. Write a value or press the buttons.',
'detail':'The detail (aka "guidance scale") can be set between 2 and 50. Lower values will create softer images, while higher values will create images with a lot of contrast and perhaps distortion. Write a value or press the buttons.',
'inference_steps':'Define the amount of time, in "cycles", to spend generating the images.\nHigher time usually means higher quality but only if the tags are good enough. Try around ~40/image.',
'blend':'0.0 to 1.0, the amount of transformation to apply on the base image. The higher the value, the more the result image will be different than the source.',
'resolution':'The width and height of the final image.',
'crop':'Do you want to crop the base image so that it matches the generated image resolution?',
'hires':'Do you want to receive a high res image at the end of the generation? (it will take more time)',
}
desc_buttons={
'seed':[Button.inline(f"Get from last prompt",f"msg_but:last_prompt"),],
user=conn.execute("SELECT * FROM user WHERE id = ?",(ev.input_sender.user_id,)).fetchone()
usage=get_credits(ev.input_sender.user_id)
awaitev.respond(f"Hello {user['name']}. You have {usage['balance']}/{user['daily_cycles']} cycles left."+(f"\nYou are currently earning {usage['hourly_gain']} cycles/hour. Full amount in {int(usage['remaining_time']/3600)}h{int((usage['remaining_time']/60)%60):0>2}m{int(usage['remaining_time']%60):0>2}s."ifusage['remaining_time']else''))
awaitev.respond(conn.execute('UPDATE user SET daily_cycles = ? WHERE id = ?',(int(ev.message.raw_text.split('')[1]),int(ev.message.raw_text.split('')[2]))))
awaitclient.send_message(int(ev.message.raw_text.split('')[1]),f"Congrats! You can now use {ev.message.raw_text.split('')[2]} cycles/day. Have fun!")
pending_prompt=conn.execute('SELECT 1 FROM pending_prompt WHERE user_id = ?',(ev.input_sender.user_id,)).fetchone()
ifnotpending_prompt:
awaitev.edit('You cannot edit a prompt that doesn\'t exist anymore.')
return
conn.execute('UPDATE user SET pending_action = ? WHERE id = ?',(field,ev.input_sender.user_id))
awaitev.respond(f"Please tell me the value for <strong>{field}</strong>.{chr(10)+chr(10)+desc[field]iffieldindescelse''}",parse_mode='HTML',buttons=desc_buttons.get(field,None))
awaitev.respond(f'Hello, and welcome to ai621. This bot can be used to generate yiff. Before beginning, keep in mind that:\n\n1. Images are public, no abusive stuff\n2. Using the bot maliciously or with multiple alts will lead to a ban\n3. The images generated by the bot are of public domain.\nGenerate a new prompt with /new\n\nDiscussion: @ai621chat\nWebsite: https://ai621.foxo.me/')
if__name__=='__main__':
qqq=conn.execute("""SELECT used, user.daily_cycles, prompt.id, inference_steps*number AS cycles, strftime('%s', 'now')-prompt.queued_at AS wait, prompt.started_at, user.name FROM prompt
(r"\b(loli|shota|cub|young|age difference|preteen|underage|child|teen)\b",'Trying to generate cub art will probably make you banned. I warned you.',0.001),
(r"\b(scat|poop|shit|piss|urine|pooping|rape)\b",'Some of the tags you sent will be ignored because they were also blacklisted on e621.',0.75),
(r"\({3,}",'No need to use that many (((parenthesis))). That will give you a worse image.',0.9),
(r"\[{3,}",'Square [braces] will reduce the enphasis on a tag.',1.0),
(r"\W#",'There is no need to put # in front of tags. That\'ll worsen the quality of the image',0.9),
(r"[👎👍🌀🌱💎]","If you copy prompts from the channel, at least copy <strong>only</strong> the prompt.",0.001)
comments.append(f"Your prompt doesn't even contain one tag from e621.")
eliflen(found_tags)<6:
quality*=0.8
comments.append(f"Found only {len(found_tags)} tags in your prompt. The AI knows ~{int(sum(found_tags.values())/len(found_tags))} images from e621 with these tags.")
else:
comments.append(f"Found {len(found_tags)} tags in your prompt. The AI knows ~{int(sum(found_tags.values())/len(found_tags))} images from e621 with these tags.")
forpattern,comment,valueinregexes:
match=re.search(pattern,prompt)
ifmatch:
quality*=value
comments.append(comment)
ifquality<1:
comments.append(f"Because of these issues, you will consume {(1/quality):.2f}x the amount of usual cycles.")
awaitself.client.send_message(prompt['user_id'],f"While trying to generate your prompt we encountered an error: {data['detail']}\n\nThis might mean a bad combination of parameters, or issues on our sifde. We will retry a couple of times just in case.")
failed=True
self.client.conn.execute('UPDATE prompt SET is_error = 1, is_done = 1, completed_at = ? WHERE id = ?',(time(),prompt['id']))