brutalismbot 1.8.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +8 -8
 - data/lib/brutalismbot/client.rb +3 -1
 - data/lib/brutalismbot/posts/client.rb +11 -6
 - data/lib/brutalismbot/reddit/post.rb +43 -100
 - data/lib/brutalismbot/reddit/resource.rb +4 -2
 - data/lib/brutalismbot/reddit/stub.rb +22 -7
 - data/lib/brutalismbot/slack/auth.rb +5 -1
 - data/lib/brutalismbot/slack/client.rb +38 -4
 - data/lib/brutalismbot/twitter/client.rb +46 -7
 - data/lib/brutalismbot/version.rb +1 -1
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b7a72ed65ec740aef21cb54256d7f8f9b9e3128a039eb217711ee02c372683bf
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 75b2ebef6b98ec94b716fe00cb1f657b386e9d9c40d89211b37443c8f0d98fb0
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 80fb1a88e38e9d1fc5988d7586aebd1859339cf9c3bcd67b08cb7a587f5b0c6c0ab6c13db295f2569c19088637ade5a5e2a28c7ed7064ed57a63e5329a1747b5
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: eca017057b7c3a4d0c2d184ea8a328af49e319d96ac02f42e51977a65a5677e31fedd770a484c960c78e5b1f5bcc1ed834c0239ebc9bd12c7d6f320ea24bbe9b
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -16,27 +16,27 @@ gem install brutalismbot 
     | 
|
| 
       16 
16 
     | 
    
         
             
            ## Usage
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
            ```ruby
         
     | 
| 
       19 
     | 
    
         
            -
            require "brutalismbot 
     | 
| 
      
 19 
     | 
    
         
            +
            require "brutalismbot"
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
      
 21 
     | 
    
         
            +
            bot = Brutalismbot::Client.new
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
            # Get latest cached post
         
     | 
| 
       24 
     | 
    
         
            -
            post =  
     | 
| 
      
 24 
     | 
    
         
            +
            post = bot.posts.last
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            # Get newest posts
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 27 
     | 
    
         
            +
            bot.reddit.list(:new).all
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            # Get new posts since latest
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
            bot.reddit.list(:new, before: post.fullname).all
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
            # Get current top post
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
      
 33 
     | 
    
         
            +
            bot.reddit.list(:top, limit: 1).first
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
            # Pull latest posts
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 36 
     | 
    
         
            +
            bot.pull
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         
             
            # Mirror a post to all clients
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
            bot.push post
         
     | 
| 
       40 
40 
     | 
    
         
             
            ```
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
            ## Contributing
         
     | 
    
        data/lib/brutalismbot/client.rb
    CHANGED
    
    
| 
         @@ -15,7 +15,8 @@ module Brutalismbot 
     | 
|
| 
       15 
15 
     | 
    
         
             
                  end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                  def key_for(post)
         
     | 
| 
       18 
     | 
    
         
            -
                     
     | 
| 
      
 18 
     | 
    
         
            +
                    path = post.created_utc.strftime("year=%Y/month=%Y-%m/day=%Y-%m-%d/%s.json")
         
     | 
| 
      
 19 
     | 
    
         
            +
                    File.join(@prefix, path)
         
     | 
| 
       19 
20 
     | 
    
         
             
                  end
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
22 
     | 
    
         
             
                  def get(**options)
         
     | 
| 
         @@ -27,7 +28,7 @@ module Brutalismbot 
     | 
|
| 
       27 
28 
     | 
    
         
             
                  end
         
     | 
| 
       28 
29 
     | 
    
         | 
| 
       29 
30 
     | 
    
         
             
                  def list(**options)
         
     | 
| 
       30 
     | 
    
         
            -
                    super 
     | 
| 
      
 31 
     | 
    
         
            +
                    super do |object|
         
     | 
| 
       31 
32 
     | 
    
         
             
                      Brutalismbot.logger.info("GET s3://#{@bucket}/#{object.key}")
         
     | 
| 
       32 
33 
     | 
    
         
             
                      Reddit::Post.parse(object.get.body.read)
         
     | 
| 
       33 
34 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -54,10 +55,14 @@ module Brutalismbot 
     | 
|
| 
       54 
55 
     | 
    
         
             
                  end
         
     | 
| 
       55 
56 
     | 
    
         | 
| 
       56 
57 
     | 
    
         
             
                  def push(post, dryrun:nil)
         
     | 
| 
       57 
     | 
    
         
            -
                     
     | 
| 
       58 
     | 
    
         
            -
                    Brutalismbot.logger.info("PUT #{"DRYRUN " if dryrun}s3://#{ 
     | 
| 
       59 
     | 
    
         
            -
                    @client.put_object( 
     | 
| 
       60 
     | 
    
         
            -
                     
     | 
| 
      
 58 
     | 
    
         
            +
                    key = key_for(post)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    Brutalismbot.logger.info("PUT #{"DRYRUN " if dryrun}s3://#{@bucket}/#{key}")
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @client.put_object(bucket: @bucket, key: key, body: post.to_json) unless dryrun
         
     | 
| 
      
 61 
     | 
    
         
            +
                    {
         
     | 
| 
      
 62 
     | 
    
         
            +
                      bucket: @bucket,
         
     | 
| 
      
 63 
     | 
    
         
            +
                      key:    key,
         
     | 
| 
      
 64 
     | 
    
         
            +
                      url:    post.permalink,
         
     | 
| 
      
 65 
     | 
    
         
            +
                    }
         
     | 
| 
       61 
66 
     | 
    
         
             
                  end
         
     | 
| 
       62 
67 
     | 
    
         
             
                end
         
     | 
| 
       63 
68 
     | 
    
         
             
              end
         
     | 
| 
         @@ -39,131 +39,74 @@ module Brutalismbot 
     | 
|
| 
       39 
39 
     | 
    
         
             
                    "#<#{self.class} #{data["permalink"]}>"
         
     | 
| 
       40 
40 
     | 
    
         
             
                  end
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
      
 42 
     | 
    
         
            +
                  def is_gallery?
         
     | 
| 
      
 43 
     | 
    
         
            +
                    data["is_gallery"] || false
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       42 
46 
     | 
    
         
             
                  def is_self?
         
     | 
| 
       43 
     | 
    
         
            -
                    data["is_self"]
         
     | 
| 
      
 47 
     | 
    
         
            +
                    data["is_self"] || false
         
     | 
| 
       44 
48 
     | 
    
         
             
                  end
         
     | 
| 
       45 
49 
     | 
    
         | 
| 
       46 
50 
     | 
    
         
             
                  def kind
         
     | 
| 
       47 
51 
     | 
    
         
             
                    @item["kind"]
         
     | 
| 
       48 
52 
     | 
    
         
             
                  end
         
     | 
| 
       49 
53 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                  def  
     | 
| 
       51 
     | 
    
         
            -
                     
     | 
| 
       52 
     | 
    
         
            -
                  end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                  def media_url
         
     | 
| 
       55 
     | 
    
         
            -
                    # Use URL if it's an image
         
     | 
| 
       56 
     | 
    
         
            -
                    if mime_type.start_with?("image/")
         
     | 
| 
       57 
     | 
    
         
            -
                      data["url"]
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                    # Extract preview image URL
         
     | 
| 
       60 
     | 
    
         
            -
                    else
         
     | 
| 
       61 
     | 
    
         
            -
                      images = data.dig("preview", "images") || {}
         
     | 
| 
       62 
     | 
    
         
            -
                      source = images.map{|x| x["source"] }.compact.max do |a,b|
         
     | 
| 
       63 
     | 
    
         
            -
                        a.slice("width", "height").values <=> b.slice("width", "height").values
         
     | 
| 
       64 
     | 
    
         
            -
                      end
         
     | 
| 
       65 
     | 
    
         
            -
                      CGI.unescape_html(source["url"])
         
     | 
| 
       66 
     | 
    
         
            -
                    end
         
     | 
| 
       67 
     | 
    
         
            -
                  end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                  def mime_type
         
     | 
| 
       70 
     | 
    
         
            -
                    @mime_type ||= begin
         
     | 
| 
       71 
     | 
    
         
            -
                      uri = URI.parse(data["url"])
         
     | 
| 
       72 
     | 
    
         
            -
                      ssl = uri.scheme == "https"
         
     | 
| 
       73 
     | 
    
         
            -
                      Brutalismbot.logger.info("HEAD #{uri}")
         
     | 
| 
       74 
     | 
    
         
            -
                      Net::HTTP.start(uri.host, uri.port, use_ssl: ssl) do |http|
         
     | 
| 
       75 
     | 
    
         
            -
                        req = Net::HTTP::Head.new(uri)
         
     | 
| 
       76 
     | 
    
         
            -
                        http.request(req)["Content-Type"]
         
     | 
| 
       77 
     | 
    
         
            -
                      end
         
     | 
| 
       78 
     | 
    
         
            -
                    end
         
     | 
| 
       79 
     | 
    
         
            -
                  end
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
                  def mime_type=(value)
         
     | 
| 
       82 
     | 
    
         
            -
                    @mime_type = value
         
     | 
| 
       83 
     | 
    
         
            -
                  end
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                  def path
         
     | 
| 
       86 
     | 
    
         
            -
                    created_utc.strftime("year=%Y/month=%Y-%m/day=%Y-%m-%d/%s.json")
         
     | 
| 
      
 54 
     | 
    
         
            +
                  def media_metadata
         
     | 
| 
      
 55 
     | 
    
         
            +
                    data["media_metadata"]
         
     | 
| 
       87 
56 
     | 
    
         
             
                  end
         
     | 
| 
       88 
57 
     | 
    
         | 
| 
       89 
58 
     | 
    
         
             
                  def permalink
         
     | 
| 
       90 
59 
     | 
    
         
             
                    "https://reddit.com#{data["permalink"]}"
         
     | 
| 
       91 
60 
     | 
    
         
             
                  end
         
     | 
| 
       92 
61 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
                  def  
     | 
| 
       94 
     | 
    
         
            -
                     
     | 
| 
      
 62 
     | 
    
         
            +
                  def preview_images
         
     | 
| 
      
 63 
     | 
    
         
            +
                    data.dig("preview", "images")
         
     | 
| 
       95 
64 
     | 
    
         
             
                  end
         
     | 
| 
       96 
65 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
                  def  
     | 
| 
       98 
     | 
    
         
            -
                     
     | 
| 
       99 
     | 
    
         
            -
                    prefix ||= ENV["POSTS_S3_PREFIX"] || "data/v1/posts/"
         
     | 
| 
       100 
     | 
    
         
            -
                    {
         
     | 
| 
       101 
     | 
    
         
            -
                      bucket: bucket,
         
     | 
| 
       102 
     | 
    
         
            -
                      key: File.join(*[prefix, path].compact),
         
     | 
| 
       103 
     | 
    
         
            -
                      body: to_json,
         
     | 
| 
       104 
     | 
    
         
            -
                    }
         
     | 
| 
      
 66 
     | 
    
         
            +
                  def title
         
     | 
| 
      
 67 
     | 
    
         
            +
                    CGI.unescape_html(data["title"])
         
     | 
| 
       105 
68 
     | 
    
         
             
                  end
         
     | 
| 
       106 
69 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
                  def  
     | 
| 
       108 
     | 
    
         
            -
                     
     | 
| 
      
 70 
     | 
    
         
            +
                  def url
         
     | 
| 
      
 71 
     | 
    
         
            +
                    data["url"]
         
     | 
| 
       109 
72 
     | 
    
         
             
                  end
         
     | 
| 
       110 
73 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
                   
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
                     
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
      
 74 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 75 
     | 
    
         
            +
                  # Get media URLs for post
         
     | 
| 
      
 76 
     | 
    
         
            +
                  def media_urls(&block)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    if is_gallery?
         
     | 
| 
      
 78 
     | 
    
         
            +
                      media_urls_gallery(&block)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    elsif preview_images
         
     | 
| 
      
 80 
     | 
    
         
            +
                      media_urls_preview(&block)
         
     | 
| 
      
 81 
     | 
    
         
            +
                    else
         
     | 
| 
      
 82 
     | 
    
         
            +
                      []
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
       116 
84 
     | 
    
         
             
                  end
         
     | 
| 
       117 
85 
     | 
    
         | 
| 
       118 
     | 
    
         
            -
                   
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
      
 86 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 87 
     | 
    
         
            +
                  # S3 path
         
     | 
| 
      
 88 
     | 
    
         
            +
                  def path
         
     | 
| 
      
 89 
     | 
    
         
            +
                    created_utc.strftime("year=%Y/month=%Y-%m/day=%Y-%m-%d/%s.json")
         
     | 
| 
       120 
90 
     | 
    
         
             
                  end
         
     | 
| 
       121 
91 
     | 
    
         | 
| 
       122 
92 
     | 
    
         
             
                  private
         
     | 
| 
       123 
93 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
                   
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
                            {
         
     | 
| 
       141 
     | 
    
         
            -
                              type: "mrkdwn",
         
     | 
| 
       142 
     | 
    
         
            -
                              text: "<#{permalink}|#{title}>",
         
     | 
| 
       143 
     | 
    
         
            -
                            },
         
     | 
| 
       144 
     | 
    
         
            -
                          ],
         
     | 
| 
       145 
     | 
    
         
            -
                        },
         
     | 
| 
       146 
     | 
    
         
            -
                      ],
         
     | 
| 
       147 
     | 
    
         
            -
                    }
         
     | 
| 
       148 
     | 
    
         
            -
                  end
         
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
                  def to_slack_text
         
     | 
| 
       151 
     | 
    
         
            -
                    {
         
     | 
| 
       152 
     | 
    
         
            -
                      blocks: [
         
     | 
| 
       153 
     | 
    
         
            -
                        {
         
     | 
| 
       154 
     | 
    
         
            -
                          type: "section",
         
     | 
| 
       155 
     | 
    
         
            -
                          text: {
         
     | 
| 
       156 
     | 
    
         
            -
                            type: "mrkdwn",
         
     | 
| 
       157 
     | 
    
         
            -
                            text: "<#{permalink}|#{title}>",
         
     | 
| 
       158 
     | 
    
         
            -
                          },
         
     | 
| 
       159 
     | 
    
         
            -
                          accessory: {
         
     | 
| 
       160 
     | 
    
         
            -
                            type: "image",
         
     | 
| 
       161 
     | 
    
         
            -
                            image_url: "https://brutalismbot.com/logo-red-ppl.png",
         
     | 
| 
       162 
     | 
    
         
            -
                            alt_text: "/r/brutalism",
         
     | 
| 
       163 
     | 
    
         
            -
                          },
         
     | 
| 
       164 
     | 
    
         
            -
                        },
         
     | 
| 
       165 
     | 
    
         
            -
                      ],
         
     | 
| 
       166 
     | 
    
         
            -
                    }
         
     | 
| 
      
 94 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 95 
     | 
    
         
            +
                  # Get media URLs from gallery
         
     | 
| 
      
 96 
     | 
    
         
            +
                  def media_urls_gallery(&block)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    media_metadata.values.map do |image|
         
     | 
| 
      
 98 
     | 
    
         
            +
                      url = block_given? ? yield(image) : image.dig("s", "u")
         
     | 
| 
      
 99 
     | 
    
         
            +
                      CGI.unescape_html(url) unless url.nil?
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end.compact
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 104 
     | 
    
         
            +
                  # Get media URLs from previews
         
     | 
| 
      
 105 
     | 
    
         
            +
                  def media_urls_preview(&block)
         
     | 
| 
      
 106 
     | 
    
         
            +
                    preview_images.map do |image|
         
     | 
| 
      
 107 
     | 
    
         
            +
                      url = block_given? ? yield(image) : image.dig("source", "url")
         
     | 
| 
      
 108 
     | 
    
         
            +
                      CGI.unescape_html(url) unless url.nil?
         
     | 
| 
      
 109 
     | 
    
         
            +
                    end.compact
         
     | 
| 
       167 
110 
     | 
    
         
             
                  end
         
     | 
| 
       168 
111 
     | 
    
         
             
                end
         
     | 
| 
       169 
112 
     | 
    
         
             
              end
         
     | 
| 
         @@ -26,8 +26,10 @@ module Brutalismbot 
     | 
|
| 
       26 
26 
     | 
    
         
             
                      children.each do |child|
         
     | 
| 
       27 
27 
     | 
    
         
             
                        item = child.transform_keys(&:to_sym)
         
     | 
| 
       28 
28 
     | 
    
         
             
                        post = Post.new(**item)
         
     | 
| 
       29 
     | 
    
         
            -
                         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
                        unless post.is_self?
         
     | 
| 
      
 30 
     | 
    
         
            +
                          Brutalismbot.logger.warn("NO MEDIA URLs for #{post.permalink}") if post.media_urls.empty?
         
     | 
| 
      
 31 
     | 
    
         
            +
                          yield post
         
     | 
| 
      
 32 
     | 
    
         
            +
                        end
         
     | 
| 
       31 
33 
     | 
    
         
             
                      end
         
     | 
| 
       32 
34 
     | 
    
         
             
                    end
         
     | 
| 
       33 
35 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -17,6 +17,28 @@ module Brutalismbot 
     | 
|
| 
       17 
17 
     | 
    
         
             
                          permalink:   "/r/brutalism/comments/#{permalink_id}/test/",
         
     | 
| 
       18 
18 
     | 
    
         
             
                          title:       "Post to /r/brutalism",
         
     | 
| 
       19 
19 
     | 
    
         
             
                          url:         "https://image.host/#{image_id}.jpg",
         
     | 
| 
      
 20 
     | 
    
         
            +
                          media_metadata: {
         
     | 
| 
      
 21 
     | 
    
         
            +
                            abcdef: {
         
     | 
| 
      
 22 
     | 
    
         
            +
                              s: {
         
     | 
| 
      
 23 
     | 
    
         
            +
                                u: "https://preview.image.host/#{image_id}_1.jpg",
         
     | 
| 
      
 24 
     | 
    
         
            +
                              },
         
     | 
| 
      
 25 
     | 
    
         
            +
                              p: [
         
     | 
| 
      
 26 
     | 
    
         
            +
                                {x: 1, y: 1, u: "https://preview.image.host/#{image_id}_1.jpg"},
         
     | 
| 
      
 27 
     | 
    
         
            +
                                {x: 2, y: 2, u: "https://preview.image.host/#{image_id}_2.jpg"},
         
     | 
| 
      
 28 
     | 
    
         
            +
                                {x: 3, y: 3, u: "https://preview.image.host/#{image_id}_3.jpg"},
         
     | 
| 
      
 29 
     | 
    
         
            +
                              ],
         
     | 
| 
      
 30 
     | 
    
         
            +
                            },
         
     | 
| 
      
 31 
     | 
    
         
            +
                            ghijkl: {
         
     | 
| 
      
 32 
     | 
    
         
            +
                              s: {
         
     | 
| 
      
 33 
     | 
    
         
            +
                                u: "https://preview.image.host/#{image_id}_2.jpg",
         
     | 
| 
      
 34 
     | 
    
         
            +
                              },
         
     | 
| 
      
 35 
     | 
    
         
            +
                              p: [
         
     | 
| 
      
 36 
     | 
    
         
            +
                                {x: 1, y: 1, u: "https://preview.image.host/#{image_id}_1.jpg"},
         
     | 
| 
      
 37 
     | 
    
         
            +
                                {x: 2, y: 2, u: "https://preview.image.host/#{image_id}_2.jpg"},
         
     | 
| 
      
 38 
     | 
    
         
            +
                                {x: 3, y: 3, u: "https://preview.image.host/#{image_id}_3.jpg"},
         
     | 
| 
      
 39 
     | 
    
         
            +
                              ],
         
     | 
| 
      
 40 
     | 
    
         
            +
                            },
         
     | 
| 
      
 41 
     | 
    
         
            +
                          },
         
     | 
| 
       20 
42 
     | 
    
         
             
                          preview: {
         
     | 
| 
       21 
43 
     | 
    
         
             
                            images: [
         
     | 
| 
       22 
44 
     | 
    
         
             
                              {
         
     | 
| 
         @@ -26,13 +48,6 @@ module Brutalismbot 
     | 
|
| 
       26 
48 
     | 
    
         
             
                                  height: 1000,
         
     | 
| 
       27 
49 
     | 
    
         
             
                                },
         
     | 
| 
       28 
50 
     | 
    
         
             
                              },
         
     | 
| 
       29 
     | 
    
         
            -
                              {
         
     | 
| 
       30 
     | 
    
         
            -
                                source: {
         
     | 
| 
       31 
     | 
    
         
            -
                                  url: "https://preview.image.host/#{image_id}_small.jpg",
         
     | 
| 
       32 
     | 
    
         
            -
                                  width: 500,
         
     | 
| 
       33 
     | 
    
         
            -
                                  height: 500,
         
     | 
| 
       34 
     | 
    
         
            -
                                }
         
     | 
| 
       35 
     | 
    
         
            -
                              }
         
     | 
| 
       36 
51 
     | 
    
         
             
                            ],
         
     | 
| 
       37 
52 
     | 
    
         
             
                          },
         
     | 
| 
       38 
53 
     | 
    
         
             
                        },
         
     | 
| 
         @@ -31,20 +31,26 @@ module Brutalismbot 
     | 
|
| 
       31 
31 
     | 
    
         
             
                  end
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                  def list(**options)
         
     | 
| 
       34 
     | 
    
         
            -
                    super 
     | 
| 
      
 34 
     | 
    
         
            +
                    super do |object|
         
     | 
| 
       35 
35 
     | 
    
         
             
                      Brutalismbot.logger.info("GET s3://#{@bucket}/#{object.key}")
         
     | 
| 
       36 
36 
     | 
    
         
             
                      Auth.parse(object.get.body.read)
         
     | 
| 
       37 
37 
     | 
    
         
             
                    end
         
     | 
| 
       38 
38 
     | 
    
         
             
                  end
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                  def push( 
     | 
| 
      
 40 
     | 
    
         
            +
                  def push(post, webhook_url, dryrun:nil)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    blocks = blocks_for(post)
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       41 
43 
     | 
    
         
             
                    Brutalismbot.logger.info("POST #{"DRYRUN " if dryrun}#{webhook_url}")
         
     | 
| 
       42 
44 
     | 
    
         
             
                    unless dryrun
         
     | 
| 
       43 
45 
     | 
    
         
             
                      uri = URI.parse(webhook_url)
         
     | 
| 
       44 
46 
     | 
    
         
             
                      ssl = uri.scheme == "https"
         
     | 
| 
       45 
47 
     | 
    
         
             
                      req = Net::HTTP::Post.new(uri, "content-type" => "application/json")
         
     | 
| 
       46 
     | 
    
         
            -
                      req.body =  
     | 
| 
       47 
     | 
    
         
            -
                      Net::HTTP.start(uri.host, uri.port, use_ssl: ssl)  
     | 
| 
      
 48 
     | 
    
         
            +
                      req.body = { blocks: blocks }.to_json
         
     | 
| 
      
 49 
     | 
    
         
            +
                      Net::HTTP.start(uri.host, uri.port, use_ssl: ssl) do |http|
         
     | 
| 
      
 50 
     | 
    
         
            +
                        http.request(req)
         
     | 
| 
      
 51 
     | 
    
         
            +
                      end.tap do |res|
         
     | 
| 
      
 52 
     | 
    
         
            +
                        Brutalismbot.logger.error("RESPONSE [#{res.code}] #{res.body}") unless res.kind_of?(Net::HTTPSuccess)
         
     | 
| 
      
 53 
     | 
    
         
            +
                      end
         
     | 
| 
       48 
54 
     | 
    
         
             
                    else
         
     | 
| 
       49 
55 
     | 
    
         
             
                      Net::HTTPOK.new("1.1", "204", "ok")
         
     | 
| 
       50 
56 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -58,6 +64,34 @@ module Brutalismbot 
     | 
|
| 
       58 
64 
     | 
    
         
             
                      object.delete unless dryrun
         
     | 
| 
       59 
65 
     | 
    
         
             
                    end
         
     | 
| 
       60 
66 
     | 
    
         
             
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  private
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  def blocks_for(post)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    post.media_urls.map do |media_url|
         
     | 
| 
      
 72 
     | 
    
         
            +
                      [
         
     | 
| 
      
 73 
     | 
    
         
            +
                        {
         
     | 
| 
      
 74 
     | 
    
         
            +
                          type: "image",
         
     | 
| 
      
 75 
     | 
    
         
            +
                          title: {
         
     | 
| 
      
 76 
     | 
    
         
            +
                            type: "plain_text",
         
     | 
| 
      
 77 
     | 
    
         
            +
                            text: "/r/brutalism",
         
     | 
| 
      
 78 
     | 
    
         
            +
                            emoji: true,
         
     | 
| 
      
 79 
     | 
    
         
            +
                          },
         
     | 
| 
      
 80 
     | 
    
         
            +
                          image_url: media_url,
         
     | 
| 
      
 81 
     | 
    
         
            +
                          alt_text: post.title,
         
     | 
| 
      
 82 
     | 
    
         
            +
                        },
         
     | 
| 
      
 83 
     | 
    
         
            +
                        {
         
     | 
| 
      
 84 
     | 
    
         
            +
                          type: "context",
         
     | 
| 
      
 85 
     | 
    
         
            +
                          elements: [
         
     | 
| 
      
 86 
     | 
    
         
            +
                            {
         
     | 
| 
      
 87 
     | 
    
         
            +
                              type: "mrkdwn",
         
     | 
| 
      
 88 
     | 
    
         
            +
                              text: "<#{post.permalink}|#{post.title}>",
         
     | 
| 
      
 89 
     | 
    
         
            +
                            },
         
     | 
| 
      
 90 
     | 
    
         
            +
                          ],
         
     | 
| 
      
 91 
     | 
    
         
            +
                        },
         
     | 
| 
      
 92 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 93 
     | 
    
         
            +
                    end.flatten
         
     | 
| 
      
 94 
     | 
    
         
            +
                  end
         
     | 
| 
       61 
95 
     | 
    
         
             
                end
         
     | 
| 
       62 
96 
     | 
    
         
             
              end
         
     | 
| 
       63 
97 
     | 
    
         
             
            end
         
     | 
| 
         @@ -19,16 +19,55 @@ module Brutalismbot 
     | 
|
| 
       19 
19 
     | 
    
         
             
                    end
         
     | 
| 
       20 
20 
     | 
    
         
             
                  end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                  def push( 
     | 
| 
       23 
     | 
    
         
            -
                     
     | 
| 
      
 22 
     | 
    
         
            +
                  def push(post, dryrun:nil)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    opts = {}
         
     | 
| 
      
 24 
     | 
    
         
            +
                    slices_for(post).each_with_index.map do |slice, index|
         
     | 
| 
      
 25 
     | 
    
         
            +
                      status, media = slice
         
     | 
| 
       24 
26 
     | 
    
         
             
                      Brutalismbot.logger.info("PUSH #{"DRYRUN " if dryrun}twitter://@brutalismbot")
         
     | 
| 
       25 
     | 
    
         
            -
                       
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                       
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 27 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 28 
     | 
    
         
            +
                        res = @client.update_with_media(status, media, opts)
         
     | 
| 
      
 29 
     | 
    
         
            +
                        opts[:in_reply_to_status_id] = res.id
         
     | 
| 
      
 30 
     | 
    
         
            +
                      rescue ::Twitter::Error::BadRequest => err
         
     | 
| 
      
 31 
     | 
    
         
            +
                        if err.message =~ /Image file size must be <= \d+ bytes/
         
     | 
| 
      
 32 
     | 
    
         
            +
                          Brutalismbot.logger.warn("IMAGE TOO LARGE - RETRYING WITH PREVIEWS")
         
     | 
| 
      
 33 
     | 
    
         
            +
                          res = push_preview(post, opts, index)
         
     | 
| 
      
 34 
     | 
    
         
            +
                          opts[:in_reply_to_status_id] = res.id
         
     | 
| 
      
 35 
     | 
    
         
            +
                        end
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end unless dryrun
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                      res&.id
         
     | 
| 
       30 
39 
     | 
    
         
             
                    end
         
     | 
| 
       31 
40 
     | 
    
         
             
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  private
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  def push_preview(post, opts, index)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    status, media = slices_for(post) do |i|
         
     | 
| 
      
 46 
     | 
    
         
            +
                      i["p"].max {|a,b|  a["x"] * a["y"] <=> b["x"] * b["y"] }["u"]
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end.to_a[index]
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @client.update_with_media(status, media, opts)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def slices_for(post, &block)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    status = status_for(post)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    media_urls = post.media_urls(&block)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    case media_urls.count % 4
         
     | 
| 
      
 55 
     | 
    
         
            +
                    when 1 then media_urls.each_slice(3).to_a
         
     | 
| 
      
 56 
     | 
    
         
            +
                    when 2 then media_urls.each_slice(3).to_a
         
     | 
| 
      
 57 
     | 
    
         
            +
                    else media_urls.each_slice(4).to_a
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end.map do |media_urls_slice|
         
     | 
| 
      
 59 
     | 
    
         
            +
                      media_urls_slice.map do |media_url|
         
     | 
| 
      
 60 
     | 
    
         
            +
                        Brutalismbot.logger.info("GET #{media_url}")
         
     | 
| 
      
 61 
     | 
    
         
            +
                        URI.open(media_url)
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end.zip([status]).map(&:reverse)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  def status_for(post)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    max = 280 - post.permalink.length - 1
         
     | 
| 
      
 68 
     | 
    
         
            +
                    status = post.title.length <= max ? post.title : "#{post.title[0...max - 1]}…"
         
     | 
| 
      
 69 
     | 
    
         
            +
                    status << "\n#{post.permalink}"
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
       32 
71 
     | 
    
         
             
                end
         
     | 
| 
       33 
72 
     | 
    
         
             
              end
         
     | 
| 
       34 
73 
     | 
    
         
             
            end
         
     | 
    
        data/lib/brutalismbot/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: brutalismbot
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.0.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Alexander Mancevice
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2020- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-10-02 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: twitter
         
     |