You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

277 lines
11 KiB

import os, logging
DEBUG = os.environ.get('DEBUG')
logging.basicConfig(
#filename='protovax.log', encoding='utf-8',
format='[%(asctime)s] %(levelname)s %(module)s/%(funcName)s - %(message)s',
level=logging.DEBUG if DEBUG else logging.INFO)
import asyncio
import requests
import random
import json
import base64
import time
import re
from PIL import Image
from datetime import datetime, timezone, timedelta
from io import BytesIO
from telethon import TelegramClient, events
import secrets
PROTOSPACE = -1001298858490
JASON = 172033414
TANNER = 79316791
TANNERBOT_MICROSCOPY = -1001886549266
scope_subject = ''
client = TelegramClient('data/dreamer.session', secrets.TG_API_ID, secrets.TG_API_HASH)
def snap_size(size):
VALID_SIZES = [512, 576, 640, 704, 768, 832, 896, 960, 1024]
for s in VALID_SIZES:
if s >= size:
return s
def dreamer(prompt, steps=30, seed=1234, height=512, width=512):
url = secrets.DREAM_API
#sd_settings_json = '{"fn_index":12,"data":["","","None","None",30,"Euler a",false,false,1,1,7,-1,-1,0,0,0,false,512,512,false,false,0.7,"None",false,"Seed","","Steps","",true,false,false,null,"",null,"",""],"session_hash":"qpydye2zzsh"}'
sd_settings_json = '{"fn_index":12,"data":["","","None","None",30,"Euler a",false,false,1,1,7,-1,-1,0,0,0,false,512,512,false,false,0.7,"None",false,false,null,"","Seed","","Nothing","",true,false,null,"",""],"session_hash":"qpydye2zzsh"}'
sd_settings = json.loads(sd_settings_json)
sd_settings['data'][0] = prompt
sd_settings['data'][4] = steps
sd_settings['data'][11] = seed
sd_settings['data'][17] = snap_size(height)
sd_settings['data'][18] = snap_size(width)
if width > 512 or height > 512:
# highres fix
sd_settings['data'][19] = True
logging.info('Dreaming of: %s', prompt)
try:
res = requests.post(url, json=sd_settings, timeout=40)
res.raise_for_status()
res = res.json()
return res
except BaseException as e:
logging.error('Problem dreaming {}: {} - {}'.format(url, e.__class__.__name__, str(e)))
return None
async def message_handler(event):
global scope_subject
text = event.raw_text
chat = event.chat_id
sender = await event.get_sender()
if not event.sender:
return
if event.message.fwd_from:
return
name = getattr(sender, 'first_name', None)
if not name:
return
command = ''
data = ''
reply = ''
reply_file = None
if text.startswith('! '):
text = text[2:]
elif text.startswith('!'):
text = text[1:]
else:
return
if ' ' in text:
command = text.split(' ', 1)[0]
data = text.split(' ', 1)[1]
else:
command = text
command = command.lower()
#!setscope
if command == 'setscope' and data:
if not reply and sender.id != TANNER:
reply = '> do !scope to look under the microscope'
await event.reply(reply)
if not reply:
scope_subject = data
now = datetime.now(tz=timezone.utc) - timedelta(seconds=1)
reply = '> ' + scope_subject
reply_file = 'frames/' + now.strftime('image%S.jpg')
reply_msg = await event.reply(reply, file=reply_file, link_preview=False)
await reply_msg.forward_to(TANNERBOT_MICROSCOPY)
#!scope
if command == 'scope':
logging.info('Chat: {:<14} | ID: {:<6} | User: {} {} | Command: {} | Data: {}'.format(chat, event.id, name, sender.id, command, data or 'None'))
if not reply:
now = datetime.now(tz=timezone.utc) - timedelta(seconds=1)
reply = '> ' + scope_subject
reply_file = 'frames/' + now.strftime('image%S.jpg')
reply_msg = await event.reply(reply, file=reply_file, link_preview=False)
#!dream
if command == 'dream':
logging.info('Chat: {:<14} | ID: {:<6} | User: {} {} | Command: {} | Data: {}'.format(chat, event.id, name, sender.id, command, data or 'None'))
if not reply and chat == PROTOSPACE:
reply = '> please join {} to dream'.format(secrets.PROTODREAM_URL)
#if not reply and sender.id == JASON:
# reply = '> no.'
to_send = ''
if not reply and data:
to_send = data
if not reply and not to_send and event.message.is_reply:
reply_msg = await event.get_reply_message()
to_send = reply_msg.raw_text
if not reply and '> ' in to_send:
reply = '> sounds like a bad !dream'
if not reply and len(to_send) > 500:
reply = '> impressive. very nice. let\'s see Paul Allen\'s prompt.'
if not reply and not to_send:
reply = '> usage: !dream [prompt] [options]'
reply += '\n> or reply to a someone with !dream'
reply += '\n> default options:'
reply += '\n> steps:30 (20-40)'
reply += '\n> height:512 (512-1024)'
reply += '\n> width:512 (512-1024)'
reply += '\n> seed:number'
reply += '\n> favourites: https://t.me/+UyMF3ArBe4pmYzQ5'
if not reply:
settings = {
'steps': 30,
'height': 512,
'width': 512,
'seed': random.randint(11111, 19999),
}
maximums = {
'steps': 40,
'height': 1024,
'width': 1024,
}
minimums = {
'steps': 20,
'height': 512,
'width': 512,
}
for match in re.findall('((\w+)[:=](\d+))', to_send):
whole = match[0]
setting = match[1]
value = int(match[2])
to_send = to_send.replace(whole, '').replace(' ', ' ')
if setting in maximums and value > maximums[setting]:
reply = '> {} should be <= {}'.format(setting, maximums[setting])
break
if setting in minimums and value < minimums[setting]:
reply = '> {} should be >= {}'.format(setting, minimums[setting])
break
if setting in settings:
settings[setting] = value
if not reply:
try:
to_send = to_send.replace('@', '')
to_send = to_send.replace('!', '')
to_send = to_send.strip()
prompt = to_send
if len(str(settings['seed'])) == 4:
enhancements1 = [
', fantasy, intricate, elegant, digital painting, concept art, sharp focus, illustration by greg rutkowski, 4k',
', synthwave style, artstation, detailed, award winning, dramatic lighting, miami vice, oil on canvas',
', highly detailed painting by dustin nguyen, akihiko yoshida, greg tocchini, 4 k, trending on artstation, 8 k',
', cinematic lighting, insanely detailed, intricate, artstation, cgsociety, painted by simon stalenhag, concept art, illustration, sharp focus',
', photorealistic, highly detailed, illustration, lifelike, highly detailed, intricate, octane render, sharp focus, cyberpunk',
', by ghibli, makoto shinkai, bright and transparent animation style, anime art wallpaper 4 k, trending on artstation',
', painterly, sharp focus, illustration, art by lois royo',
', in the style of gta cover art, by stephen bliss, trending on artstation, pixiv, 8 k',
', d & d, fantasy concept art, octane render, 8 k',
', peter mohrbacher, charlie bowater, artstation, craig mullins, cinematic, digital painting, deviantart, cinematic lighting, 4 k',
', tristan eaton, victo ngai, maxfield parrish, artgerm, koons, ryden, intricated details',
', by soul bass, kawase hasui, moebius and edward hopper, colorful flat surreal design, xray hd, 8 k',
', manga cover art, detailed color portrait, artstation trending, 8 k',
', a hacker hologram by penny patricia poppycock, pixabay contest winner, holography, irridescent, photoillustration, maximalist vaporwave - n 9',
', breathtaking, epic, stunning, gorgeous, much detail, much wow, cgsociety, wlop, pixiv, behance, deviantart, masterpiece',
', sharp focus, dynamic lighting, elegant, harmony, beauty, masterpiece, by roberto ferry, illustration, blue background',
', ultradetailed environment, sharp focus, cinematic lighting, by alphonse maria mucha and kim jung gi',
', concept art by jama jurabaev, cinematic shot, trending on artstation, high quality, brush stroke, hyperspace, vibrant colors',
', hyper detailed, sharp focus, bokeh, unreal engine, ray tracing, cute, fantasy, sci fi, purple lights, tiny, small',
', fancy, ultra detailed, brush strokes, digital painting, cinematic, yoshitaka amano, andy warhol, ultra realistic',
', by tsuyoshi nagano, illustration, cinematic lighting, hyperdetailed, 8 k, symmetrical, frostbite 3 engine, cryengine, dof, trending on artstation, digital art, crepuscular ray',
', retrowave, tonal separation, black background, neon, black, glitch, strong contrast, pinterest, trending on artstation',
', basic background, krenz cushart, mucha, ghibli, by joaquin sorolla rhads leyendecker, by ohara koson',
]
if ',' not in prompt:
prompt += enhancements1[settings['seed'] % len(enhancements1)]
elif str(settings['seed'])[0] == '1':
pass
start = time.time()
dream_res = dreamer(prompt, **settings)
finish = time.time()
url_enc = dream_res['data'][0][0]
b64_str = url_enc[22:]
reply_file = base64.decodebytes(bytes(b64_str, 'utf-8'))
latency = finish - start
reply = '> generated "{}" for {} in {} s with seed:{} steps:{}'.format(
to_send,
name,
str(latency)[:3],
settings['seed'],
settings['steps']
)
except BaseException as e:
logging.exception(e)
reply = '> error'
await event.reply(reply, file=reply_file, link_preview=False)
@client.on(events.MessageEdited)
async def message_edited(event):
await message_handler(event)
@client.on(events.NewMessage)
async def new_message(event):
await message_handler(event)
client.start()
client.run_until_disconnected()