html_generator.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. '''
  2. This is a library for formatting GPT-4chan and chat outputs as nice HTML.
  3. '''
  4. import os
  5. import re
  6. from pathlib import Path
  7. import markdown
  8. from PIL import Image
  9. # This is to store the paths to the thumbnails of the profile pictures
  10. image_cache = {}
  11. def generate_basic_html(s):
  12. with open(Path(__file__).resolve().parent / '../css/html_readable_style.css', 'r') as f:
  13. css = f.read()
  14. s = '\n'.join([f'<p>{line}</p>' for line in s.split('\n')])
  15. s = f'<style>{css}</style><div class="container">{s}</div>'
  16. return s
  17. def process_post(post, c):
  18. t = post.split('\n')
  19. number = t[0].split(' ')[1]
  20. if len(t) > 1:
  21. src = '\n'.join(t[1:])
  22. else:
  23. src = ''
  24. src = re.sub('>', '&gt;', src)
  25. src = re.sub('(&gt;&gt;[0-9]*)', '<span class="quote">\\1</span>', src)
  26. src = re.sub('\n', '<br>\n', src)
  27. src = f'<blockquote class="message">{src}\n'
  28. src = f'<span class="name">Anonymous </span> <span class="number">No.{number}</span>\n{src}'
  29. return src
  30. def generate_4chan_html(f):
  31. with open(Path(__file__).resolve().parent / '../css/html_4chan_style.css', 'r') as css_f:
  32. css = css_f.read()
  33. posts = []
  34. post = ''
  35. c = -2
  36. for line in f.splitlines():
  37. line += "\n"
  38. if line == '-----\n':
  39. continue
  40. elif line.startswith('--- '):
  41. c += 1
  42. if post != '':
  43. src = process_post(post, c)
  44. posts.append(src)
  45. post = line
  46. else:
  47. post += line
  48. if post != '':
  49. src = process_post(post, c)
  50. posts.append(src)
  51. for i in range(len(posts)):
  52. if i == 0:
  53. posts[i] = f'<div class="op">{posts[i]}</div>\n'
  54. else:
  55. posts[i] = f'<div class="reply">{posts[i]}</div>\n'
  56. output = ''
  57. output += f'<style>{css}</style><div id="parent"><div id="container">'
  58. for post in posts:
  59. output += post
  60. output += '</div></div>'
  61. output = output.split('\n')
  62. for i in range(len(output)):
  63. output[i] = re.sub(r'^(&gt;(.*?)(<br>|</div>))', r'<span class="greentext">\1</span>', output[i])
  64. output[i] = re.sub(r'^<blockquote class="message">(&gt;(.*?)(<br>|</div>))', r'<blockquote class="message"><span class="greentext">\1</span>', output[i])
  65. output = '\n'.join(output)
  66. return output
  67. def get_image_cache(path):
  68. cache_folder = Path("cache")
  69. if not cache_folder.exists():
  70. cache_folder.mkdir()
  71. mtime = os.stat(path).st_mtime
  72. if (path in image_cache and mtime != image_cache[path][0]) or (path not in image_cache):
  73. img = Image.open(path)
  74. img.thumbnail((200, 200))
  75. output_file = Path(f'cache/{path.name}_cache.png')
  76. img.convert('RGB').save(output_file, format='PNG')
  77. image_cache[path] = [mtime, output_file.as_posix()]
  78. return image_cache[path][1]
  79. def load_html_image(paths):
  80. for str_path in paths:
  81. path = Path(str_path)
  82. if path.exists():
  83. return f'<img src="file/{get_image_cache(path)}">'
  84. return ''
  85. def generate_chat_html(history, name1, name2, character):
  86. with open(Path(__file__).resolve().parent / '../css/html_cai_style.css', 'r') as f:
  87. css = f.read()
  88. output = f'<style>{css}</style><div class="chat" id="chat">'
  89. img_bot = load_html_image([f"characters/{character}.{ext}" for ext in ['png', 'jpg', 'jpeg']] + ["img_bot.png","img_bot.jpg","img_bot.jpeg"])
  90. img_me = load_html_image(["img_me.png", "img_me.jpg", "img_me.jpeg"])
  91. for i,_row in enumerate(history[::-1]):
  92. row = [markdown.markdown(re.sub(r"(.)```", r"\1\n```", entry), extensions=['fenced_code']) for entry in _row]
  93. output += f"""
  94. <div class="message">
  95. <div class="circle-bot">
  96. {img_bot}
  97. </div>
  98. <div class="text">
  99. <div class="username">
  100. {name2}
  101. </div>
  102. <div class="message-body">
  103. {row[1]}
  104. </div>
  105. </div>
  106. </div>
  107. """
  108. if not (i == len(history)-1 and len(row[0]) == 0):
  109. output += f"""
  110. <div class="message">
  111. <div class="circle-you">
  112. {img_me}
  113. </div>
  114. <div class="text">
  115. <div class="username">
  116. {name1}
  117. </div>
  118. <div class="message-body">
  119. {row[0]}
  120. </div>
  121. </div>
  122. </div>
  123. """
  124. output += "</div>"
  125. return output