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.

114 lines
2.7KB

  1. import time
  2. from inky import InkyPHAT
  3. from PIL import Image, ImageFont, ImageDraw
  4. from mastodon import Mastodon
  5. from HTMLParser import HTMLParser
  6. from UserDict import UserDict
  7. from ConfigParser import RawConfigParser
  8. config = RawConfigParser()
  9. config.read('toot-reader.cfg')
  10. mastodon = Mastodon(
  11. access_token=config.get('server', 'token'),
  12. api_base_url='https://' + config.get('server', 'host')
  13. )
  14. class MLStripper(HTMLParser):
  15. def __init__(self):
  16. self.reset()
  17. self.fed = []
  18. def handle_starttag(self, tag, attrs):
  19. if tag == 'br':
  20. self.fed.append(" ")
  21. def handle_endtag(self, tag):
  22. if tag == 'p':
  23. self.fed.append(" ")
  24. def handle_data(self, d):
  25. self.fed.append(d)
  26. def get_data(self):
  27. print self.fed
  28. return ''.join(self.fed)
  29. class Toot:
  30. def __init__(self, toot):
  31. self.toot = toot
  32. self.html = MLStripper()
  33. def title(self):
  34. return self.toot['reblog']['account']['acct'] if self.toot['reblog'] else self.toot['account']['acct']
  35. def content(self):
  36. self.html.feed(self.toot['content'])
  37. content = self.html.get_data().strip().split(' ')
  38. self.html.reset()
  39. return content
  40. class InkyDraw:
  41. def __init__(self):
  42. self.inky = InkyPHAT("black")
  43. self.font = ImageFont.truetype('fonts/elec.ttf', 10)
  44. self.reset()
  45. def reset(self):
  46. self.y = 0
  47. self.image = Image.new("P", (self.inky.WIDTH, self.inky.HEIGHT))
  48. self.draw = ImageDraw.Draw(self.image)
  49. def title(self, title):
  50. w, h = self.font.getsize(title)
  51. x = (self.inky.WIDTH / 2) - (w / 2)
  52. self.draw.rectangle([(0, self.y), (self.inky.WIDTH, h)], self.inky.BLACK);
  53. self.draw.text((x, 0), title, self.inky.WHITE, self.font)
  54. self.y = h + 2
  55. def body(self, body):
  56. lines = [[]]
  57. max_h = 0
  58. for word in body:
  59. lines[-1].append(word)
  60. w, h = self.font.getsize(' '.join(lines[-1]))
  61. max_h = h if h > max_h else max_h
  62. if w > self.inky.WIDTH:
  63. lines[-1].pop()
  64. lines.append([])
  65. lines[-1].append(word)
  66. lines = [" ".join(line) for line in lines]
  67. for line in lines:
  68. self.draw.text((0, self.y), line, self.inky.BLACK, self.font)
  69. self.y += max_h
  70. def finish(self):
  71. # I happen to want this upside-down
  72. self.image = self.image.transpose(Image.ROTATE_180)
  73. self.inky.set_image(self.image)
  74. self.inky.show()
  75. self.reset()
  76. def update(draw, last_id):
  77. toot = mastodon.timeline(limit=1)[0]
  78. toot_id = toot['id']
  79. if itoot_id == last_id:
  80. return toot_id
  81. toot = Toot(toot)
  82. draw.title(toot.title())
  83. draw.body(toot.content())
  84. draw.finish()
  85. return toot_id
  86. if __name__ == '__main__':
  87. draw = InkyDraw()
  88. last_id = 0
  89. while True:
  90. last_id = update(draw, last_id)
  91. time.sleep(30)