html_generator.py 4.9 KB

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