123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- require 'twitter'
- require 'twitter-text'
- require 'sanitize'
- require 'cgi'
- require 'ostruct'
-
- ::Twitter::Validation::MAX_LENGTH = 280
-
- class CrossPost
- class Twitter
- def initialize(config)
- settings = config[:settings]
- @posts = config[:posts]
- @users = config[:users]
-
- config = {
- consumer_key: settings['twitter.consumer.key'],
- consumer_secret: settings['twitter.consumer.secret'],
- access_token: settings['twitter.access.token'],
- access_token_secret: settings['twitter.access.secret']
- }
- @client = ::Twitter::REST::Client.new config
- @stream = ::Twitter::Streaming::Client.new config
- end
-
- def post(content, media = [], id:, reply_to:)
- reply_to = OpenStruct.new id: reply_to unless reply_to.respond_to? :id
-
- media = media.collect { |f| @client.upload f }
- parts = split content
- unless media.empty?
- first, *parts = parts
- reply_to = @client.update first, media_ids: media.join(','), in_reply_to_status: reply_to
- end
- parts.each { |p| reply_to = @client.update p, in_reply_to_status: reply_to }
-
- reply_to = reply_to.id if reply_to.respond_to? :id
- @posts[id] = reply_to
- end
-
- WHITESPACE_TAGS = {
- 'br' => { before: "\n", after: '' },
- 'div' => { before: "\n", after: "\n" },
- 'p' => { before: "\n", after: "\n" }
- }.freeze
-
- def post_status(status)
- content = status.content
- content = Sanitize.clean(content, whitespace_elements: WHITESPACE_TAGS).strip
- content = CGI.unescape_html content
-
- @users.each do |mastodon, twitter|
- content = content.gsub /@\b#{mastodon}\b/, "@#{twitter}"
- end
-
- media = status.media_attachments.collect { |f| open f.url }
-
- LOGGER.info { 'Sending to twitter' }
- LOGGER.debug { " Content: #{content}" }
- LOGGER.debug { " Attachments: #{media.size}" }
-
- reply = status.in_reply_to_id
- reply_to = reply ? @posts[reply] : nil
- self.post content, media, id: status.id, reply_to: reply_to
-
- media.each do |f|
- f.close
- f.unlink
- end
- end
-
- private
-
- def split(text)
- parts = []
- part = ''
- words = text.split /\ /
- words.each do |word|
- old_part = part
- part += ' ' unless part == ''
- part += word
-
- invalid = ::Twitter::Validation.tweet_invalid? part
- if invalid
- parts << old_part
- part = word
- end
- end
- parts << part unless part == ''
- parts
- end
- end
- end
|