brutalismbot 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5adaf818709e409365f83810ea0ac9a883a0e24c5d91432adcce5c567fe0085d
4
- data.tar.gz: 54010b835fdb82d057b21961fcd14be8e14087c31b49d3084849a101e95126bf
3
+ metadata.gz: 0cf18d4d7ec09728b41cd4bc32f1208565ee8a8e29df981a950cc12a022ebe05
4
+ data.tar.gz: a57aeccee651d4bbd95c8f775af885400b33c00b817759d65ae36129c0e9eaa5
5
5
  SHA512:
6
- metadata.gz: bfe6c521032918f9f0a5f908a4c14cf3f8cb0a8564168c08246c9600146fe8bdd92efd5b910720041d825fc4b8da4bfc72a8b8c6b27faca32fba67f16b488574
7
- data.tar.gz: f8653819c8375a31ac16cd041a82f9d026d1b0e09792b2a99e77946c598a31d25f49cd499fc7349833348368a6253655537d83dfc6dbf6c38611e550f0cd9e7c
6
+ metadata.gz: 19a19b76a2102521cd1280c9b079013adbacc9828e10f1af5983a717e09e6c4f608777e485ab37ba670602d9119e6c29e06c5e67781002143dd93e20f28de652
7
+ data.tar.gz: 7263c86e3380544e031843c750e20f69a7eade16bbea7d73c8953b9eadef8930d846a2b186cdadf1d74b45620127272118abe80dbaaa0f6ae462801eb485ea5d
data/README.md CHANGED
@@ -15,26 +15,27 @@ gem install brutalismbot
15
15
  ## Usage
16
16
 
17
17
  ```ruby
18
- require "aws-sdk-s3"
19
- require "brutalismbot"
18
+ require "brutalismbot/s3"
20
19
 
21
- bucket = Aws::S3::Bucket.new name: "my-bucket"
22
- brutbot = Brutalismbot::S3::Client.new bucket: bucket, prefix: "my/prefix/"
20
+ brutbot = Brutalismbot::S3::Client.new bucket: "my-bucket", prefix: "my/prefix/"
23
21
 
24
22
  # Get latest cached post
25
- brutbot.posts.latest
23
+ post = brutbot.posts.last
26
24
 
27
- # Get latest post as S3 Object
28
- brutbot.posts.max_key
25
+ # Get newest posts
26
+ brutbot.subreddit.posts(:new).all
29
27
 
30
- # Get post-time of latest cached post
31
- limit = brutbot.posts.max_time
32
-
33
- # Get newest post after a given time
34
- brutbot.subreddit.posts(:new).since(time: limit).first
28
+ # Get new posts since latest
29
+ brutbot.subreddit.posts(:new, before: post.fullname).all
35
30
 
36
31
  # Get current top post
37
- brutbot.subreddit.posts(:top).first
32
+ brutbot.subreddit.posts(:top, limit: 1).first
33
+
34
+ # Pull latest posts
35
+ brutbot.posts.pull
36
+
37
+ # Mirror a post to all clients
38
+ brutbot.auths.mirror post
38
39
  ```
39
40
 
40
41
  ## Contributing
@@ -0,0 +1,57 @@
1
+ module Brutalismbot
2
+ class Auth < Hash
3
+ def channel_id
4
+ dig "incoming_webhook", "channel_id"
5
+ end
6
+
7
+ def post(body:, dryrun:nil)
8
+ uri = URI.parse webhook_url
9
+ ssl = uri.scheme == "https"
10
+ req = Net::HTTP::Post.new uri, "content-type" => "application/json"
11
+ req.body = body
12
+ Brutalismbot.logger.info "POST #{dryrun ? "DRYRUN " : ""}#{uri}"
13
+ if dryrun
14
+ Net::HTTPOK.new "1.1", "204", "ok"
15
+ else
16
+ Net::HTTP.start(uri.host, uri.port, use_ssl: ssl) do |http|
17
+ http.request req
18
+ end
19
+ end
20
+ end
21
+
22
+ def team_id
23
+ dig "team_id"
24
+ end
25
+
26
+ def webhook_url
27
+ dig "incoming_webhook", "url"
28
+ end
29
+
30
+ class << self
31
+ def stub
32
+ bot_id = "B#{SecureRandom.alphanumeric(8).upcase}"
33
+ channel_id = "C#{SecureRandom.alphanumeric(8).upcase}"
34
+ team_id = "T#{SecureRandom.alphanumeric(8).upcase}"
35
+ user_id = "U#{SecureRandom.alphanumeric(8).upcase}"
36
+ Auth[{
37
+ "ok" => true,
38
+ "access_token" => "<token>",
39
+ "scope" => "identify,incoming-webhook",
40
+ "user_id" => user_id,
41
+ "team_name" => "My Team",
42
+ "team_id" => team_id,
43
+ "incoming_webhook" => {
44
+ "channel" => "#brutalism",
45
+ "channel_id" => channel_id,
46
+ "configuration_url" => "https://my-team.slack.com/services/#{bot_id}",
47
+ "url" => "https://hooks.slack.com/services/#{team_id}/#{bot_id}/1234567890abcdef12345678",
48
+ },
49
+ "scopes" => [
50
+ "identify",
51
+ "incoming-webhook",
52
+ ],
53
+ }]
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,94 @@
1
+ module Brutalismbot
2
+ class Post < Hash
3
+ def created_after?(time)
4
+ created_utc.to_i > time.to_i
5
+ end
6
+
7
+ def created_utc
8
+ Time.at(dig("data", "created_utc").to_i).utc
9
+ end
10
+
11
+ def fullname
12
+ "#{kind}_#{id}"
13
+ end
14
+
15
+ def id
16
+ dig "data", "id"
17
+ end
18
+
19
+ def kind
20
+ dig "kind"
21
+ end
22
+
23
+ def permalink
24
+ dig "data", "permalink"
25
+ end
26
+
27
+ def title
28
+ dig "data", "title"
29
+ end
30
+
31
+ def to_slack
32
+ {
33
+ blocks: [
34
+ {
35
+ type: "image",
36
+ title: {
37
+ type: "plain_text",
38
+ text: "/r/brutalism",
39
+ emoji: true,
40
+ },
41
+ image_url: url,
42
+ alt_text: title,
43
+ },
44
+ {
45
+ type: "context",
46
+ elements: [
47
+ {
48
+ type: "mrkdwn",
49
+ text: "<https://reddit.com#{permalink}|#{title}>",
50
+ },
51
+ ],
52
+ },
53
+ ],
54
+ }
55
+ end
56
+
57
+ def url
58
+ images = dig "data", "preview", "images"
59
+ source = images.map{|x| x["source"] }.compact.max do |a,b|
60
+ a.slice("width", "height").values <=> b.slice("width", "height").values
61
+ end
62
+ CGI.unescapeHTML source.dig("url")
63
+ rescue NoMethodError
64
+ dig("data", "media_metadata")&.values&.first&.dig("s", "u")
65
+ end
66
+
67
+ class << self
68
+ def stub
69
+ created_utc = Time.now.utc - rand(86400) - 86400
70
+ post_id = SecureRandom.alphanumeric(6).downcase
71
+ permalink_id = SecureRandom.alphanumeric.downcase
72
+ image_id = SecureRandom.alphanumeric
73
+ Post[{
74
+ "kind" => "t3",
75
+ "data" => {
76
+ "id" => post_id,
77
+ "created_utc" => created_utc.to_i,
78
+ "permalink" => "/r/brutalism/comments/#{permalink_id}/test/",
79
+ "title" => "Post to /r/brutalism",
80
+ "preview" => {
81
+ "images" => [
82
+ {
83
+ "source" => {
84
+ "url" => "https://preview.redd.it/#{image_id}.jpg",
85
+ }
86
+ }
87
+ ]
88
+ }
89
+ }
90
+ }]
91
+ end
92
+ end
93
+ end
94
+ end
@@ -5,10 +5,10 @@ module Brutalismbot
5
5
 
6
6
  def initialize(endpoint:nil, user_agent:nil)
7
7
  @endpoint = endpoint
8
- @user_agent = user_agent
8
+ @user_agent = user_agent || "Brutalismbot #{VERSION}"
9
9
  end
10
10
 
11
- def posts(resource, **params)
11
+ def posts(resource, params = {})
12
12
  url = File.join @endpoint, "#{resource}.json"
13
13
  qry = URI.encode_www_form params
14
14
  uri = URI.parse "#{url}?#{qry}"
@@ -19,11 +19,10 @@ module Brutalismbot
19
19
  class PostCollection
20
20
  include Enumerable
21
21
 
22
- def initialize(uri:, user_agent:, min_time:nil)
22
+ def initialize(uri:, user_agent:)
23
23
  @uri = uri
24
24
  @ssl = uri.scheme == "https"
25
25
  @user_agent = user_agent
26
- @min_time = min_time.to_i
27
26
  end
28
27
 
29
28
  def each
@@ -32,22 +31,26 @@ module Brutalismbot
32
31
  request = Net::HTTP::Get.new @uri, "user-agent" => @user_agent
33
32
  response = JSON.parse http.request(request).body
34
33
  children = response.dig("data", "children") || []
35
- children.reverse.each do |child|
36
- post = Brutalismbot::Post[child]
37
- yield post if post.created_after time: @min_time
34
+ children.each do |child|
35
+ post = Post[child]
36
+ yield post
38
37
  end
39
38
  end
40
39
  end
41
40
 
42
- def since(time:)
43
- PostCollection.new uri: @uri, user_agent: @user_agent, min_time: time
41
+ def all
42
+ to_a
43
+ end
44
+
45
+ def last
46
+ to_a.last
44
47
  end
45
48
  end
46
49
 
47
50
  class Brutalism < Subreddit
48
51
  def initialize(endpoint:nil, user_agent:nil)
49
- super endpoint: endpoint || "https://www.reddit.com/r/brutalism",
50
- user_agent: user_agent || "Brutalismbot #{Brutalismbot::VERSION}"
52
+ endpoint ||= "https://www.reddit.com/r/brutalism"
53
+ super
51
54
  end
52
55
  end
53
56
  end
@@ -1,121 +1,173 @@
1
+ require "aws-sdk-s3"
2
+
3
+ require "brutalismbot"
4
+
1
5
  module Brutalismbot
2
6
  module S3
3
- class Collection
7
+ class Prefix
4
8
  include Enumerable
5
9
 
6
- attr_reader :bucket, :prefix
7
-
8
- def initialize(bucket:nil, prefix:nil)
9
- @bucket = bucket || ::Aws::S3::Bucket.new(name: ENV["S3_BUCKET"])
10
- @prefix = prefix || ENV["S3_PREFIX"]
11
- end
12
-
13
- def each
14
- Brutalismbot.logger.info "GET s3://#{@bucket.name}/#{@prefix}*"
15
- @bucket.objects(prefix: @prefix).each do |object|
16
- yield object
10
+ attr_reader :prefix, :client
11
+
12
+ def initialize(bucket:nil, prefix:nil, client:nil, stub_responses:nil)
13
+ @bucket = bucket || "brutalismbot"
14
+ @prefix = prefix || "data/v1/"
15
+ @client = client || Aws::S3::Client.new(stub_responses: stub_responses || false)
16
+ if stub_responses
17
+ @auths = 3.times.map{ Auth.stub }
18
+ @posts = 3.times.map{ Post.stub }.sort{|a,b| a.created_utc <=> b.created_utc }
19
+ @client.stub_responses :delete_object
20
+ @client.stub_responses :list_objects, -> (context) { stub_list_objects context }
21
+ @client.stub_responses :get_object, -> (context) { stub_get_object context }
17
22
  end
18
23
  end
19
24
 
20
- def put(body:, key:, dryrun:nil)
21
- if dryrun
22
- Brutalismbot.logger.info "PUT DRYRUN s3://#{@bucket.name}/#{key}"
23
- else
24
- Brutalismbot.logger.info "PUT s3://#{@bucket.name}/#{key}"
25
- @bucket.put_object key: key, body: body
26
- end
25
+ def each
26
+ bucket.objects(prefix: @prefix).each{|x| yield x }
27
+ end
28
+
29
+ def all
30
+ to_a
31
+ end
32
+
33
+ def bucket(options = {})
34
+ options[:name] ||= @bucket
35
+ options[:client] ||= @client
36
+ Aws::S3::Bucket.new options
37
+ end
38
+
39
+ def delete(object)
40
+ key = key_for object
41
+ Brutalismbot.logger.info "DELETE #{"DRYRUN " if stubbed?}s3://#{@bucket}/#{key}"
42
+ bucket.delete_objects delete: {objects: [{key: key}]}
43
+ end
44
+
45
+ def put(object)
46
+ key = key_for object
47
+ Brutalismbot.logger.info "PUT #{"DRYRUN " if stubbed?}s3://#{@bucket}/#{key}"
48
+ bucket.put_object key: key, body: object.to_json
49
+ end
50
+
51
+ def stubbed?
52
+ @client.config.stub_responses
53
+ end
54
+
55
+ def stub_list_objects(context)
56
+ {
57
+ contents: if context.params[:prefix] =~ /auths\//
58
+ @auths.map do |auth|
59
+ File.join(
60
+ @prefix,
61
+ "auths",
62
+ "team=#{auth.team_id}",
63
+ "channel=#{auth.channel_id}",
64
+ "oauth.json",
65
+ )
66
+ end
67
+ elsif context.params[:prefix] =~ /posts\//
68
+ @posts.map do |post|
69
+ File.join(
70
+ @prefix,
71
+ "posts",
72
+ post.created_utc.strftime("year=%Y/month=%Y-%m/day=%Y-%m-%d/%s.json"),
73
+ )
74
+ end
75
+ end.select do |key|
76
+ key.start_with? context.params[:prefix]
77
+ end.map do |key|
78
+ {
79
+ key: key
80
+ }
81
+ end
82
+ }
83
+ end
84
+
85
+ def stub_get_object(context)
86
+ {
87
+ body: if context.params[:key] =~ /auths\//
88
+ @auths.select do |auth|
89
+ File.join(
90
+ @prefix,
91
+ "auths",
92
+ "team=#{auth.team_id}",
93
+ "channel=#{auth.channel_id}",
94
+ "oauth.json",
95
+ ) == context.params[:key]
96
+ end.first
97
+ elsif context.params[:key] =~ /posts\//
98
+ @posts.select do |post|
99
+ File.join(
100
+ @prefix,
101
+ "posts",
102
+ post.created_utc.strftime("year=%Y/month=%Y-%m/day=%Y-%m-%d/%s.json"),
103
+ ) == context.params[:key]
104
+ end.first
105
+ end.to_json
106
+ }
27
107
  end
28
108
  end
29
109
 
30
- class Client < Collection
31
- def subreddit(endpoint:nil, user_agent:nil)
32
- Brutalismbot::R::Brutalism.new endpoint:endpoint, user_agent: user_agent
33
- end
34
-
110
+ class Client < Prefix
35
111
  def auths
36
- AuthCollection.new bucket: @bucket, prefix: "#{@prefix}auths/"
112
+ prefix = File.join @prefix, "auths/"
113
+ AuthCollection.new bucket: @bucket, prefix: prefix, client: @client
37
114
  end
38
115
 
39
116
  def posts
40
- PostCollection.new bucket: @bucket, prefix: "#{@prefix}posts/"
117
+ prefix = File.join @prefix, "posts/"
118
+ PostCollection.new bucket: @bucket, prefix: prefix, client: @client
41
119
  end
42
- end
43
120
 
44
- class AuthCollection < Collection
45
- def each
46
- super do |object|
47
- yield Brutalismbot::Auth[JSON.parse object.get.body.read]
48
- end
121
+ def subreddit(endpoint:nil, user_agent:nil)
122
+ R::Brutalism.new endpoint:endpoint, user_agent: user_agent
49
123
  end
124
+ end
50
125
 
51
- def remove(team:, dryrun:nil)
52
- prefix = "#{@prefix}team=#{team}/"
53
- Brutalismbot.logger.info "GET s3://#{@bucket.name}/#{prefix}*"
54
- @bucket.objects(prefix: prefix).map do |object|
55
- if dryrun
56
- Brutalismbot.logger.info "DELETE DRYRUN s3://#{@bucket.name}/#{object.key}"
57
- else
58
- Brutalismbot.logger.info "DELETE s3://#{@bucket.name}/#{object.key}"
59
- object.delete
60
- end
61
- end
126
+ class AuthCollection < Prefix
127
+ def each
128
+ super{|x| yield Auth[JSON.parse x.get.body.read] }
62
129
  end
63
130
 
64
- def mirror(body:, dryrun:nil)
65
- map{|auth| auth.post body: body, dryrun: dryrun }
131
+ def key_for(auth)
132
+ File.join @prefix, "team=#{auth.team_id}/channel=#{auth.channel_id}/oauth.json"
66
133
  end
67
134
 
68
- def put(auth:, dryrun:nil)
69
- key = "#{@prefix}team=#{auth.team_id}/channel=#{auth.channel_id}/oauth.json"
70
- super key: key, body: auth.to_json, dryrun: dryrun
135
+ def mirror(post, options = {})
136
+ options[:body] = post.to_slack.to_json
137
+ map{|x| x.post options }
71
138
  end
72
139
  end
73
140
 
74
- class PostCollection < Collection
141
+ class PostCollection < Prefix
75
142
  def each
76
- super do |object|
77
- yield Brutalismbot::Post[JSON.parse object.get.body.read]
78
- end
143
+ super{|x| yield Post[JSON.parse x.get.body.read] }
79
144
  end
80
145
 
81
- def latest
82
- Brutalismbot::Post[JSON.parse max_key.get.body.read]
146
+ def key_for(post)
147
+ File.join @prefix, post.created_utc.strftime("year=%Y/month=%Y-%m/day=%Y-%m-%d/%s.json")
83
148
  end
84
149
 
85
- def max_key
150
+ def last
86
151
  # Dig for max key
87
- prefix = prefix_for time: Time.now.utc
88
- Brutalismbot.logger.info "GET s3://#{@bucket.name}/#{prefix}*"
152
+ prefix = Time.now.utc.strftime "#{@prefix}year=%Y/month=%Y-%m/day=%Y-%m-%d/"
153
+ Brutalismbot.logger.info "GET s3://#{@bucket}/#{prefix}*"
89
154
 
90
155
  # Go up a level in prefix if no keys found
91
- until (keys = @bucket.objects(prefix: prefix)).any?
156
+ until (keys = bucket.objects(prefix: prefix)).any?
92
157
  prefix = prefix.split(/[^\/]+\/\z/).first
93
- Brutalismbot.logger.info "GET s3://#{@bucket.name}/#{prefix}*"
158
+ Brutalismbot.logger.info "GET s3://#{@bucket}/#{prefix}*"
94
159
  end
95
160
 
96
- # Return max by key
97
- keys.max{|a,b| a.key <=> b.key }
98
- end
99
-
100
- def max_time
101
- max_key.key.match(/(\d+).json\z/).to_a.last.to_i
102
- end
103
-
104
- def prefix_for(time:)
105
- time = Time.at(time.to_i).utc
106
- year = time.strftime '%Y'
107
- month = time.strftime '%Y-%m'
108
- day = time.strftime '%Y-%m-%d'
109
- "#{@prefix}year=#{year}/month=#{month}/day=#{day}/"
110
- end
161
+ # Get max by key
162
+ max_key = keys.max{|a,b| a.key <=> b.key }
111
163
 
112
- def put(post:, dryrun:nil)
113
- key = "#{prefix_for time: post.created_utc}#{post.created_utc.to_i}.json"
114
- super key: key, body: post.to_json, dryrun: dryrun
164
+ # Parse as Post
165
+ Post[JSON.parse max_key.get.body.read]
115
166
  end
116
167
 
117
- def update(posts:, dryrun:nil)
118
- posts.map{|post| put post: post, dryrun: dryrun }
168
+ def pull(options = {})
169
+ options[:before] ||= last.fullname
170
+ R::Brutalism.new.posts(:new, options).reverse_each.map{|x| put x }
119
171
  end
120
172
  end
121
173
  end
@@ -1,3 +1,3 @@
1
1
  module Brutalismbot
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/brutalismbot.rb CHANGED
@@ -1,9 +1,12 @@
1
- require "brutalismbot/r"
2
- require "brutalismbot/s3"
3
- require "brutalismbot/version"
4
1
  require "logger"
2
+ require "securerandom"
5
3
  require "net/https"
6
4
 
5
+ require "brutalismbot/auth"
6
+ require "brutalismbot/post"
7
+ require "brutalismbot/r"
8
+ require "brutalismbot/version"
9
+
7
10
  module Brutalismbot
8
11
  class << self
9
12
  @@config = {}
@@ -28,87 +31,4 @@ module Brutalismbot
28
31
 
29
32
  class Error < StandardError
30
33
  end
31
-
32
- class Auth < Hash
33
- def channel_id
34
- dig "incoming_webhook", "channel_id"
35
- end
36
-
37
- def post(body:, dryrun:nil)
38
- uri = URI.parse webhook_url
39
- ssl = uri.scheme == "https"
40
- Net::HTTP.start(uri.host, uri.port, use_ssl: ssl) do |http|
41
- if dryrun
42
- Brutalismbot.logger.info "POST DRYRUN #{uri}"
43
- else
44
- Brutalismbot.logger.info "POST #{uri}"
45
- req = Net::HTTP::Post.new uri, "content-type" => "application/json"
46
- req.body = body
47
- http.request req
48
- end
49
- end
50
- end
51
-
52
- def team_id
53
- dig "team_id"
54
- end
55
-
56
- def webhook_url
57
- dig "incoming_webhook", "url"
58
- end
59
- end
60
-
61
- class Post < Hash
62
- def created_after(time:)
63
- created_utc.to_i > time.to_i
64
- end
65
-
66
- def created_utc
67
- Time.at(dig("data", "created_utc").to_i).utc
68
- end
69
-
70
- def permalink
71
- dig "data", "permalink"
72
- end
73
-
74
- def title
75
- dig "data", "title"
76
- end
77
-
78
- def to_slack
79
- {
80
- blocks: [
81
- {
82
- type: "image",
83
- title: {
84
- type: "plain_text",
85
- text: "/r/brutalism",
86
- emoji: true,
87
- },
88
- image_url: url,
89
- alt_text: title,
90
- },
91
- {
92
- type: "context",
93
- elements: [
94
- {
95
- type: "mrkdwn",
96
- text: "<https://reddit.com#{permalink}|#{title}>",
97
- },
98
- ],
99
- },
100
- ],
101
- }
102
- end
103
-
104
- def url
105
- images = dig "data", "preview", "images"
106
- source = images.map{|x| x["source"] }.compact.max do |a,b|
107
- a.slice("width", "height").values <=> b.slice("width", "height").values
108
- end
109
- CGI.unescapeHTML source.dig("url")
110
- rescue NoMethodError
111
- dig("data", "media_metadata")&.values&.first&.dig("s", "u")
112
- end
113
- end
114
34
  end
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: 0.4.0
4
+ version: 0.5.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: 2019-06-15 00:00:00.000000000 Z
11
+ date: 2019-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-s3
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.16'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.6'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.6'
111
125
  description: 'A Slack app that mirrors posts from /r/brutalism to a #channel of your
112
126
  choosing using incoming webhooks.'
113
127
  email:
@@ -119,6 +133,8 @@ files:
119
133
  - LICENSE.txt
120
134
  - README.md
121
135
  - lib/brutalismbot.rb
136
+ - lib/brutalismbot/auth.rb
137
+ - lib/brutalismbot/post.rb
122
138
  - lib/brutalismbot/r.rb
123
139
  - lib/brutalismbot/s3.rb
124
140
  - lib/brutalismbot/version.rb