XMPP bot written in Python https://gitlab.com/XRevan86/hptoad
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.

60 lines
2.3KB

  1. # -*- python -*-
  2. import asyncio
  3. import bs4
  4. import functools
  5. import lxml
  6. import re
  7. import requests
  8. class Plugin:
  9. _html_regexp = re.compile(r"(https?://[^\"\s>]+)")
  10. @asyncio.coroutine
  11. def chat_message(self, body, nick, from_id, is_admin):
  12. loop = asyncio.get_event_loop()
  13. result = {}
  14. urls = self._html_regexp.findall(body)
  15. if urls:
  16. result["handled"] = True
  17. mime_types = ("application/xhtml+xml", "application/xml",
  18. "text/html", "text/xml")
  19. reply = ""
  20. for url in urls:
  21. try:
  22. req = yield from \
  23. loop.run_in_executor(None,
  24. functools.partial(requests.get,
  25. url,
  26. stream=True))
  27. if req.headers["content-type"].startswith(mime_types):
  28. # Handle a case when no charset is defined for text/html.
  29. if req.headers["content-type"].startswith("text/") and \
  30. not "charset=" in req.headers["content-type"]:
  31. req.encoding = None
  32. if not req.encoding:
  33. req.encoding = req.apparent_encoding
  34. contents = title = ""
  35. for i in req.iter_content(chunk_size=128,
  36. decode_unicode=True):
  37. contents += i
  38. soup = bs4.BeautifulSoup(contents, "lxml")
  39. if soup and soup.title:
  40. if soup.title.string == title:
  41. req.close()
  42. break
  43. title = soup.title.string
  44. if title:
  45. if reply:
  46. reply += "\n"
  47. reply += "Link: %s" % title
  48. except Exception as e:
  49. result["error"] = "Title fetch: %s" % str(e)
  50. result["reply"] = reply
  51. else:
  52. result["handled"] = False
  53. return result