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.

twitter.rb 2.3KB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. require 'twitter'
  2. require 'twitter-text'
  3. require 'sanitize'
  4. require 'cgi'
  5. require 'ostruct'
  6. ::Twitter::Validation::MAX_LENGTH = 280
  7. class CrossPost
  8. class Twitter
  9. def initialize(config)
  10. settings = config[:settings]
  11. @posts = config[:posts]
  12. @users = config[:users]
  13. config = {
  14. consumer_key: settings['twitter.consumer.key'],
  15. consumer_secret: settings['twitter.consumer.secret'],
  16. access_token: settings['twitter.access.token'],
  17. access_token_secret: settings['twitter.access.secret']
  18. }
  19. @client = ::Twitter::REST::Client.new config
  20. @stream = ::Twitter::Streaming::Client.new config
  21. end
  22. def post(content, media = [], id:, reply_to:)
  23. reply_to = OpenStruct.new id: reply_to unless reply_to.respond_to? :id
  24. media = media.collect { |f| @client.upload f }
  25. parts = split content
  26. unless media.empty?
  27. first, *parts = parts
  28. reply_to = @client.update first, media_ids: media.join(','), in_reply_to_status: reply_to
  29. end
  30. parts.each { |p| reply_to = @client.update p, in_reply_to_status: reply_to }
  31. reply_to = reply_to.id if reply_to.respond_to? :id
  32. @posts[id] = reply_to
  33. end
  34. WHITESPACE_TAGS = {
  35. 'br' => { before: "\n", after: '' },
  36. 'div' => { before: "\n", after: "\n" },
  37. 'p' => { before: "\n", after: "\n" }
  38. }.freeze
  39. def post_status(status)
  40. content = status.content
  41. content = Sanitize.clean(content, whitespace_elements: WHITESPACE_TAGS).strip
  42. content = CGI.unescape_html content
  43. @users.each do |mastodon, twitter|
  44. content = content.gsub /@\b#{mastodon}\b/, "@#{twitter}"
  45. end
  46. media = status.media_attachments.collect { |f| open f.url }
  47. LOGGER.info { 'Sending to twitter' }
  48. LOGGER.debug { " Content: #{content}" }
  49. LOGGER.debug { " Attachments: #{media.size}" }
  50. reply = status.in_reply_to_id
  51. reply_to = reply ? @posts[reply] : nil
  52. self.post content, media, id: status.id, reply_to: reply_to
  53. media.each do |f|
  54. f.close
  55. f.unlink
  56. end
  57. end
  58. private
  59. def split(text)
  60. parts = []
  61. part = ''
  62. words = text.split /\ /
  63. words.each do |word|
  64. old_part = part
  65. part += ' ' unless part == ''
  66. part += word
  67. invalid = ::Twitter::Validation.tweet_invalid? part
  68. if invalid
  69. parts << old_part
  70. part = word
  71. end
  72. end
  73. parts << part unless part == ''
  74. parts
  75. end
  76. end
  77. end