diff --git a/src/UndertaleApp.py b/src/UndertaleApp.py index 275eb7c..99ac14e 100644 --- a/src/UndertaleApp.py +++ b/src/UndertaleApp.py @@ -10,7 +10,7 @@ from flask.ext.compress import Compress from PIL import Image, ImageDraw, ImageFont -from personalities import apply_personality +from personalities import apply_personality, PersonalityOverrideException from imgurpython import ImgurClient @@ -63,7 +63,7 @@ def _indent(line_num, line): return '* ' + line -def getFontForCharacter(character): +def get_font_for_character(character): font_dir = os.path.join(app.root_path, 'static', 'css', 'fonts') if character.lower() == 'sans': return ImageFont.load(os.path.join(font_dir, 'a skele-ton.pil')) @@ -83,54 +83,57 @@ def chunks(lst, length, max_chunks=3): left -= 1 -def dialogBox(portraits, text, fnt, doIndent=True): +def get_character_from_portrait(src): + return os.path.basename(os.path.dirname(src)).lower() + + +def dialogBox(portraits, text): textChunks = list(chunks(text.split('\n'), 3)) orig_size = Size(298, 4 + 84 * len(textChunks)) # mode = '1' is black and white img = Image.new(b'1', orig_size) draw = ImageDraw.Draw(img) draw.fontmode = b'1' - for boxNum, (portrait_src, textChunk) in enumerate(zip(portraits, textChunks)): + for boxNum, (portrait_src, text_chunk) in enumerate(zip(portraits, textChunks)): + character = get_character_from_portrait(portrait_src) + apply_personality(' '.join(text_chunk), character) + box_text = [_clean_text(line, character) for line in text_chunk] + fnt = get_font_for_character(character) y_offset = 84 * boxNum draw.rectangle((4, 4 + y_offset, 294, 80 + y_offset), fill=1) draw.rectangle((7, 7 + y_offset, 291, 77 + y_offset), fill=0) img.paste(Image.open(portrait_src.lstrip('/')), (13, 12 + y_offset)) - for row, line in enumerate(textChunk[:3]): + for row, line in enumerate(box_text[:3]): if app.debug: print('"{}"'.format(repr(line)), draw.textsize(line, font=fnt)) draw.text((77, y_offset + 16 + row * 18), - _indent(row, line) if doIndent else line, + _indent(row, line) if character != 'papyrus' else line, fill=1, font=fnt) return img.resize(Size(orig_size.x * 2, orig_size.y * 2)) @app.route('/submit', methods=['GET']) def makeDialogBox(): - character = request.args.get('character').lower() - text = _clean_text(request.args.get('text'), character) - imgData = apply_personality(text, character) - if imgData is None: + text = request.args.get('text') + try: mood_imgs = request.args.getlist('moodImg') if app.debug: print(mood_imgs) - box = dialogBox( - mood_imgs, - text, - getFontForCharacter(character), - doIndent=(character != 'papyrus') - ) + box = dialogBox(mood_imgs, text) stream = StringIO() box.save(stream, format='png', optimize=True) - imgData = b64encode(stream.getvalue()) + img_data = b64encode(stream.getvalue()) @after_this_request def cleanup(response): stream.close() return response + except PersonalityOverrideException as override_response: + img_data = override_response.img_data if app.debug: - print(imgData) - return imgData + print(img_data) + return img_data @app.route('/imgur_id', methods=['GET']) diff --git a/src/personalities.py b/src/personalities.py index 03e389a..2a255d3 100644 --- a/src/personalities.py +++ b/src/personalities.py @@ -11,21 +11,25 @@ MAX_TEXT = 210 +class PersonalityOverrideException(Exception): + def __init__(self, img_data): + self.img_data = img_data + + def apply_personality(text, character): char = CHARACTERS[character.lower()] try: text.encode(char.encoding) except UnicodeEncodeError: - return char.no_language() + raise PersonalityOverrideException(char.no_language()) else: lowertext = text.lower() if any(word in lowertext for word in NAUGHTY_WORDS): - return char.naughty_word() + raise PersonalityOverrideException(char.naughty_word()) elif lowertext.startswith(COPYPASTA_START): - return char.copypasta() + raise PersonalityOverrideException(char.copypasta()) elif len(text) > MAX_TEXT: - return char.too_long() - return None + raise PersonalityOverrideException(char.too_long()) class Character(object): diff --git a/src/static/js/UndertaleDialog.elm b/src/static/js/UndertaleDialog.elm index 4aa3c05..5c86003 100644 --- a/src/static/js/UndertaleDialog.elm +++ b/src/static/js/UndertaleDialog.elm @@ -111,7 +111,11 @@ titleImgMap root address = ] [ mapArea [ 606, 43, 626, 61 ] "hOI!" <| Either.Right - <| ( address, ChooseMood Character.Temmie (defaultSprite root Character.Temmie) ) + <| ( address + , UpdateDialogs + <| DialogBoxes.SetImages Character.Temmie + <| defaultSprite root Character.Temmie + ) ] @@ -164,7 +168,10 @@ characterButton address staticRoot c = _ -> button - [ onClick address <| ChooseMood c (defaultSprite staticRoot c) + [ onClick address + <| UpdateDialogs + <| DialogBoxes.SetImages c + <| defaultSprite staticRoot c , style flatButton ] [ img [ src <| defaultSprite staticRoot c ] [] ] @@ -190,7 +197,9 @@ moodButton address root c n = spriteStr = spriteNumber root c n in button - [ onClick address <| ChooseMood c spriteStr + [ onClick address + <| UpdateDialogs + <| DialogBoxes.SetImages c spriteStr , style flatButton ] [ img [ src <| spriteStr ] [] ] @@ -409,7 +418,6 @@ type Action = NoOp () | EnterCheatCode (Set.Set Char) | ActivateEXMode - | ChooseMood Character.Name String | UpdateDialogs DialogBoxes.Action | SetScriptRoot String | SetStaticRoot String @@ -444,28 +452,19 @@ update action model = , none ) - ChooseMood c s -> - let - ( newBoxes, moveCursor ) = DialogBoxes.update (DialogBoxes.SetImages c s) model.dialogs - in - ( { model - | selection = Just c - , dialogs = newBoxes - , imageData = Nothing - } - , toFocusEffect - model.focusMailbox.address - { elementId = textBoxId 1 - , moveCursorToEnd = moveCursor - } - ) - UpdateDialogs action -> let ( newBoxes, moveCursor ) = DialogBoxes.update action model.dialogs in ( { model - | dialogs = newBoxes + | selection = + case action of + DialogBoxes.SetImages c s -> + Just c + + _ -> + model.selection + , dialogs = newBoxes , imageData = Nothing } , toFocusEffect @@ -541,9 +540,7 @@ getDialogBoxImg model = Just c -> Http.url (getSubmitUrl model.scriptRoot) - ([ ( "character", toString c ) - , ( "text", DialogBoxes.concat model.dialogs ) - ] + ([ ( "text", DialogBoxes.concat model.dialogs ) ] ++ (List.map ((,) "moodImg") <| DialogBoxes.getImgSrcs model.dialogs) ) |> Http.getString