reddit-to-telegram 0.8.1 → 0.10.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/.rubocop.yml +3 -0
- data/Gemfile.lock +6 -7
- data/README.md +34 -45
- data/lib/reddit-to-telegram.rb +1 -0
- data/lib/reddit_to_telegram/configuration.rb +20 -8
- data/lib/reddit_to_telegram/errors.rb +33 -2
- data/lib/reddit_to_telegram/post.rb +20 -17
- data/lib/reddit_to_telegram/reddit/fetch.rb +17 -2
- data/lib/reddit_to_telegram/reddit/output.rb +3 -2
- data/lib/reddit_to_telegram/store/aws_dynamo_db.rb +132 -0
- data/lib/reddit_to_telegram/store/memory.rb +16 -7
- data/lib/reddit_to_telegram/store/temp_file.rb +22 -10
- data/lib/reddit_to_telegram/store.rb +24 -8
- data/lib/reddit_to_telegram/telegram/post/gallery.rb +9 -9
- data/lib/reddit_to_telegram/telegram/post.rb +12 -25
- data/lib/reddit_to_telegram/telegram/prepare_request.rb +30 -20
- data/lib/reddit_to_telegram/version.rb +1 -1
- data/reddit-to-telegram.gemspec +1 -1
- metadata +8 -8
- data/lib/reddit_to_telegram/store/aws_simple_db.rb +0 -123
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00436ff5f5d09c81d76f4d49f3cc3996e983857f1fbff2ad2db006ea014c0e96
|
4
|
+
data.tar.gz: ca6e585387a1165a9dacdee453d4853e531b727f9498918c97675d9484275b6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2ff22eb616b95a99f3046b0c63677f24f7ca0ee1327bb7a51e97a68190b9c39639562024efaca73afa292b24b05188d9abaedba74de491bf708606526895519
|
7
|
+
data.tar.gz: 8658836ee6bb761ff2c75f9cd7c11ea2c2f526604982933d48eced8edf31ac515b8ca3ed97ac34bb515dca7baa21cb3d5de10463e13268519d3b73f8293be8f0
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
reddit-to-telegram (0.
|
5
|
-
aws-sdk-
|
4
|
+
reddit-to-telegram (0.10.0)
|
5
|
+
aws-sdk-dynamodb (~> 1.106)
|
6
6
|
httparty
|
7
7
|
|
8
8
|
GEM
|
@@ -11,15 +11,14 @@ GEM
|
|
11
11
|
ast (2.4.2)
|
12
12
|
aws-eventstream (1.3.0)
|
13
13
|
aws-partitions (1.883.0)
|
14
|
-
aws-sdk-core (3.
|
14
|
+
aws-sdk-core (3.192.1)
|
15
15
|
aws-eventstream (~> 1, >= 1.3.0)
|
16
16
|
aws-partitions (~> 1, >= 1.651.0)
|
17
17
|
aws-sigv4 (~> 1.8)
|
18
18
|
jmespath (~> 1, >= 1.6.1)
|
19
|
-
aws-sdk-
|
20
|
-
aws-sdk-core (~> 3, >= 3.
|
21
|
-
aws-
|
22
|
-
aws-sigv2 (1.2.0)
|
19
|
+
aws-sdk-dynamodb (1.106.0)
|
20
|
+
aws-sdk-core (~> 3, >= 3.191.0)
|
21
|
+
aws-sigv4 (~> 1.1)
|
23
22
|
aws-sigv4 (1.8.0)
|
24
23
|
aws-eventstream (~> 1, >= 1.0.2)
|
25
24
|
httparty (0.21.0)
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
Beware, this is remotely not production-ready, API will change, you'll see lots of bugs and it may break at any time.
|
8
8
|
Be sure to check for gem updates.
|
9
9
|
|
10
|
-
You can set this bot up absolutely for free [via AWS Lambda](https://gist.github.com/dersnek/851c32a6b45eab19f1c8748095b2a481#file-free-rtt-bot-in-aws-lambda).
|
10
|
+
You can set this bot up absolutely for free [via AWS Lambda](https://gist.github.com/dersnek/851c32a6b45eab19f1c8748095b2a481#file-free-rtt-bot-in-aws-lambda), no ruby knowledge required.
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
In your `Gemfile` add:
|
@@ -19,33 +19,33 @@ Then run `bundle install`.
|
|
19
19
|
Or `gem install reddit-to-telegram`. Don't forget to `require` it.
|
20
20
|
|
21
21
|
## Prerequisites
|
22
|
-
- (Optionally) You'll need an [AWS account](https://aws.amazon.com/) to host a free SimpleDB (best available storage type, also default one). I also recommend hosting the bot on AWS lambda, since it would be free.
|
23
|
-
- (Optionally) [Create a Reddit app](https://www.reddit.com/prefs/apps), which would allow more requests to reddit
|
24
22
|
- [Obtain a telegram bot token](https://core.telegram.org/bots/tutorial#obtain-your-bot-token)
|
23
|
+
- (Optionally) You'll need an [AWS account](https://aws.amazon.com/) to host a free DynamoDB (best available storage type, also default one). I also recommend hosting the bot on AWS lambda, since it would be free.
|
24
|
+
- (Optionally) [Create a Reddit app](https://www.reddit.com/prefs/apps), which would allow more requests to reddit
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
| RTT_AWS_ACCESS_KEY_ID | Your AWS access key ID. Needed for AWS SimpleDB storage | No |
|
30
|
-
| RTT_AWS_DOMAIN_NAME | Domain name to use for SimpleDB | No |
|
31
|
-
| RTT_AWS_REGION | AWS region your SimpleDB will be hosted on. Beware, it's not available in all regions. | No |
|
32
|
-
| RTT_AWS_SECRET_ACCESS_KEY | Your AWS access key ID. Needed for AWS SimpleDB storage. | No |
|
33
|
-
| RTT_GOOGLE_API_KEY | Your Google API key to translate posts via Google Translate. | No |
|
34
|
-
| RTT_MAX_STORED_POSTS | Number of posts to store in the database to avoid duplicates, default is 25. | No |
|
35
|
-
| RTT_REDDIT_CLIENT_ID | Reddit app credentials to access API. Reddit allows more authenticated requests. | No |
|
36
|
-
| RTT_REDDIT_CLIENT_SECRET | Reddit app credentials to access API. Reddit allows more authenticated requests. | No |
|
37
|
-
| RTT_STORE_TYPE | Choose between `aws_simple_db`, `memory` or `temp_file`. Default is `aws_simple_db`, so if you're not specifying your AWS credentials, you have to choose another store type. | No |
|
38
|
-
| RTT_TELEGRAM_BOT_TOKEN | The token you've received when you've created a telegram bot. | Yes |
|
39
|
-
| RTT_TELEGRAM_ERROR_CHANNEL_ID | Telegram channel to send errors to (without `@`, only errors from Telegram API responses would be sent for now) | No |
|
40
|
-
| RTT_TEMP_DIR | Directory to write temp files to without trailing `/` | No |
|
26
|
+
It is pretty congifurable, either dynamically or via ENV variables.
|
27
|
+
To assign variables dynamically, set them via `RedditToTelegram.config.variable_name= `, e.g. `RedditToTelegram.config.aws.access_key_id = ...`.
|
28
|
+
You can also create an ENV variable with a corresponding name. Here is the full configuration explained. Required options have a * next to them.
|
41
29
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
30
|
+
Config variable | Corresponding ENV Variable | Description |
|
31
|
+
| ----------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
32
|
+
add_channel_handle | - | Add channel handle to Telegram posts. Accepted values: true or false. Default is false |
|
33
|
+
add_reddit_link | - | Add reddit link to Telegram posts. Accepted values: true or false. Default is false. |
|
34
|
+
logger | - | Which logger to use. You can pass your own ruby logger |
|
35
|
+
on_error | - | What to do when an error happens. Default is :log, but you can also :raise or :ignore |
|
36
|
+
send_errors_to_telegram | - | Also log errors to telegram (besides regular logging). Accepted values: true or false, default is false |
|
37
|
+
translate | - | Translate posts via Google Translate. Leave empty for no translation. More details below |
|
38
|
+
aws.access_key_id | RTT_AWS_ACCESS_KEY_ID | Your AWS access key ID. Needed for AWS DynamoDB storage |
|
39
|
+
aws.region | RTT_AWS_REGION | AWS region your DynamoDB is hosted on |
|
40
|
+
aws.secret_access_key | RTT_AWS_SECRET_ACCESS_KEY | Your AWS access key ID. Needed for AWS DynamoDB storage. |
|
41
|
+
google.api_key | RTT_GOOGLE_API_KEY | Your Google API key to translate posts via Google Translate |
|
42
|
+
reddit.client_id | RTT_REDDIT_CLIENT_ID | Reddit app credentials to access API. Reddit allows more authenticated requests |
|
43
|
+
reddit.client_secret | RTT_REDDIT_CLIENT_SECRET | Reddit app credentials to access API. Reddit allows more authenticated requests |
|
44
|
+
store.max_stored_posts | RTT_MAX_STORED_POSTS | Number of posts to store in the database to avoid duplicates, default is 25 |
|
45
|
+
store.tmp_dir | RTT_TEMP_DIR | Directory to write temp files to without trailing `/` |
|
46
|
+
store.type | RTT_STORE_TYPE | Choose between `aws_dynamo_db`, `memory` or `temp_file`. Default is `aws_dynamo_db`, so if you're not specifying your AWS credentials, you have to choose another store type |
|
47
|
+
telegram.bot_token * | RTT_TELEGRAM_BOT_TOKEN | The token you've received when you've created a telegram bot |
|
48
|
+
telegram.error_channel_id | RTT_TELEGRAM_ERROR_CHANNEL_ID | Telegram channel to send errors to (without `@`, only errors from Telegram API responses would be sent for now) |
|
49
49
|
|
50
50
|
## Usage
|
51
51
|
|
@@ -53,30 +53,19 @@ Check out `lib/configuration` for full configuration.
|
|
53
53
|
2. To fetch latest hot post which hasn't been pushed yet:
|
54
54
|
```
|
55
55
|
RedditToTelegram.hot(
|
56
|
-
|
57
|
-
|
56
|
+
telegram_channel_id_1: :subreddit_name_1,
|
57
|
+
telegram_channel_id_2: :subreddit_name_2
|
58
58
|
)
|
59
59
|
```
|
60
|
-
|
60
|
+
You can push posts from one subreddit to one telegram channel, several-to-one, one-to-several, several-to-several, whatever you like.
|
61
|
+
You can also push one specific post:
|
61
62
|
```
|
62
|
-
RedditToTelegram.from_link("regular_link_to_post"
|
63
|
+
RedditToTelegram.from_link(telegram_channel_id: "regular_link_to_post")
|
63
64
|
```
|
64
65
|
Use `:telegram_channel_id` without the `@`.
|
65
66
|
|
66
|
-
###
|
67
|
+
### Translation
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
RedditToTelegram.
|
71
|
-
{ subreddit_name_1: :telegram_channel_id_1 },
|
72
|
-
translate: :ja
|
73
|
-
)
|
74
|
-
```
|
75
|
-
You can also specify if you want to add reddit link or telegram channel handle to the post text. By default they won't be added.
|
76
|
-
```
|
77
|
-
RedditToTelegram.hot(
|
78
|
-
{ subreddit_name_1: :telegram_channel_id_1 },
|
79
|
-
add_reddit_link: true,
|
80
|
-
add_channel_handle: true
|
81
|
-
)
|
82
|
-
```
|
69
|
+
Translation option is supported.
|
70
|
+
You will have to set `RedditToTelegram.config.translate` to the language key you want to translate to. You can find available languages in [Google Translate docs](https://cloud.google.com/translate/docs/languages).
|
71
|
+
You will also have to set up Google Translate API key assign it to `RedditToTelegram.config.google.api_key`.
|
data/lib/reddit-to-telegram.rb
CHANGED
@@ -5,7 +5,16 @@ require "logger"
|
|
5
5
|
module RedditToTelegram
|
6
6
|
module Configuration
|
7
7
|
class << self
|
8
|
-
attr_writer :
|
8
|
+
attr_writer :add_channel_handle, :add_reddit_link, :logger,
|
9
|
+
:on_error, :send_errors_to_telegram, :translate
|
10
|
+
|
11
|
+
def add_channel_handle
|
12
|
+
@add_channel_handle ||= false
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_reddit_link
|
16
|
+
@add_reddit_link ||= false
|
17
|
+
end
|
9
18
|
|
10
19
|
def logger
|
11
20
|
@logger ||= Logger.new($stdout).tap do |log|
|
@@ -16,11 +25,19 @@ module RedditToTelegram
|
|
16
25
|
def on_error
|
17
26
|
@on_error ||= :log
|
18
27
|
end
|
28
|
+
|
29
|
+
def send_errors_to_telegram
|
30
|
+
@send_errors_to_telegram ||= false
|
31
|
+
end
|
32
|
+
|
33
|
+
def translate
|
34
|
+
@translate ||= nil
|
35
|
+
end
|
19
36
|
end
|
20
37
|
|
21
38
|
class Store
|
22
39
|
DEFAULT_TMP_DIR = "#{Dir.pwd}/tmp".freeze
|
23
|
-
DEFAULT_TYPE = :
|
40
|
+
DEFAULT_TYPE = :aws_dynamo_db
|
24
41
|
|
25
42
|
class << self
|
26
43
|
attr_writer :max_stored_posts, :tmp_dir, :type
|
@@ -40,8 +57,7 @@ module RedditToTelegram
|
|
40
57
|
end
|
41
58
|
|
42
59
|
class AWS
|
43
|
-
ATTRS = %i[access_key_id secret_access_key region
|
44
|
-
DEFAULT_DOMAIN_NAME = "reddit_to_telegram"
|
60
|
+
ATTRS = %i[access_key_id secret_access_key region].freeze
|
45
61
|
|
46
62
|
class << self
|
47
63
|
attr_writer(*ATTRS)
|
@@ -58,10 +74,6 @@ module RedditToTelegram
|
|
58
74
|
@region ||= ENV["RTT_AWS_REGION"]
|
59
75
|
end
|
60
76
|
|
61
|
-
def domain_name
|
62
|
-
@domain_name ||= ENV["RTT_AWS_DOMAIN_NAME"] || DEFAULT_DOMAIN_NAME
|
63
|
-
end
|
64
|
-
|
65
77
|
def set_up?
|
66
78
|
ATTRS.all? { |a| !a.to_s.empty? }
|
67
79
|
end
|
@@ -3,19 +3,50 @@
|
|
3
3
|
module RedditToTelegram
|
4
4
|
class RedditToTelegramError < StandardError; end
|
5
5
|
|
6
|
+
class BadResponseFromTelegram < RedditToTelegramError; end
|
7
|
+
class FailedToCreateDatabaseTable < RedditToTelegramError; end
|
8
|
+
class FailedToFetchFromReddit < RedditToTelegramError; end
|
9
|
+
class FailedToPersistData < RedditToTelegramError; end
|
6
10
|
class InvalidStoreType < RedditToTelegramError; end
|
7
11
|
class MissingConfiguration < RedditToTelegramError; end
|
8
12
|
|
9
13
|
class Errors
|
10
14
|
class << self
|
11
15
|
def new(error, message = nil)
|
16
|
+
log_message = error.to_s
|
17
|
+
log_message += ": #{message}" unless message.nil?
|
18
|
+
|
12
19
|
if Configuration.on_error == :raise
|
13
20
|
raise(error.new(message))
|
14
21
|
elsif Configuration.on_error == :log
|
15
|
-
log_message = error.to_s
|
16
|
-
log_message += ": #{message}" unless message.nil?
|
17
22
|
Configuration.logger.error(log_message)
|
18
23
|
end
|
24
|
+
|
25
|
+
return unless Configuration.send_errors_to_telegram
|
26
|
+
|
27
|
+
push_error_to_telegram(log_message)
|
28
|
+
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def push_error_to_telegram(message)
|
35
|
+
if Configuration.telegram.error_channel_id.to_s.empty?
|
36
|
+
Configuration.logger.warn("Telegram Error Channel ID is not set up, can't send errors there")
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
Telegram::Post.push(
|
41
|
+
{
|
42
|
+
type: :text,
|
43
|
+
text: message,
|
44
|
+
misc: { no_retry: true, disable_link_preview: true }
|
45
|
+
},
|
46
|
+
Configuration.telegram.error_channel_id
|
47
|
+
)
|
48
|
+
|
49
|
+
nil
|
19
50
|
end
|
20
51
|
end
|
21
52
|
end
|
@@ -3,29 +3,29 @@
|
|
3
3
|
module RedditToTelegram
|
4
4
|
class Post
|
5
5
|
class << self
|
6
|
-
def hot(sources
|
6
|
+
def hot(sources)
|
7
7
|
check_config
|
8
|
-
return if sources.empty?
|
9
|
-
|
10
8
|
Store.setup
|
11
9
|
|
12
|
-
sources.each do |
|
13
|
-
|
14
|
-
|
10
|
+
sources.each do |telegram_chat_id, subreddits|
|
11
|
+
Array(subreddits).each do |subreddit|
|
12
|
+
res = Reddit::Fetch.hot(subreddit)
|
13
|
+
handle_res(res, subreddit, telegram_chat_id)
|
14
|
+
end
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def from_link(
|
18
|
+
def from_link(sources)
|
19
19
|
check_config
|
20
|
-
return
|
20
|
+
return unless check_from_link_sources(sources)
|
21
21
|
|
22
22
|
Configuration.store.type = :memory
|
23
23
|
Store.setup
|
24
24
|
|
25
|
-
res = Reddit::Fetch.post(
|
25
|
+
res = Reddit::Fetch.post(sources.values.first)
|
26
26
|
return unless res_ok?(res)
|
27
27
|
|
28
|
-
Telegram::Post.push(res,
|
28
|
+
Telegram::Post.push(res, sources.keys.first)
|
29
29
|
res
|
30
30
|
end
|
31
31
|
|
@@ -35,19 +35,17 @@ module RedditToTelegram
|
|
35
35
|
Errors.new(MissingConfiguration, "Missing Telegram bot token") if Configuration.telegram.bot_token.to_s.empty?
|
36
36
|
end
|
37
37
|
|
38
|
-
def handle_res(res, subreddit, telegram_chat_id
|
38
|
+
def handle_res(res, subreddit, telegram_chat_id)
|
39
39
|
return unless res_ok?(res)
|
40
40
|
|
41
|
-
post =
|
41
|
+
post = Store.posts.next(telegram_chat_id, subreddit, res)
|
42
42
|
|
43
43
|
if post.nil?
|
44
44
|
Configuration.logger.info("Could not find a new post to push")
|
45
45
|
return
|
46
46
|
end
|
47
47
|
|
48
|
-
|
49
|
-
Store::Posts.add(subreddit, post[:id])
|
50
|
-
res
|
48
|
+
Telegram::Post.push(post, telegram_chat_id)
|
51
49
|
end
|
52
50
|
|
53
51
|
def res_ok?(res)
|
@@ -62,8 +60,13 @@ module RedditToTelegram
|
|
62
60
|
end
|
63
61
|
end
|
64
62
|
|
65
|
-
def
|
66
|
-
|
63
|
+
def check_from_link_sources(sources)
|
64
|
+
if !sources.is_a?(Hash) || sources.keys.count != 1 || sources.values.count != 1
|
65
|
+
Errors.new(ArgumentError, "Check documentation on usage")
|
66
|
+
return false
|
67
|
+
end
|
68
|
+
|
69
|
+
true
|
67
70
|
end
|
68
71
|
end
|
69
72
|
end
|
@@ -55,12 +55,22 @@ module RedditToTelegram
|
|
55
55
|
handle_429(func_name, func_args)
|
56
56
|
when 200
|
57
57
|
Output.format_response(res)
|
58
|
+
else
|
59
|
+
Errors.new(FailedToFetchFromReddit, res.to_s)
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
63
|
def handle_401(func_name, func_args)
|
64
|
+
retries_left = func_args.last
|
65
|
+
func_args[func_args.length - 1] = retries_left - 1
|
66
|
+
|
62
67
|
Store::Reddit.token = Auth.token
|
63
|
-
|
68
|
+
|
69
|
+
if retries_left > 0
|
70
|
+
send(func_name, *func_args)
|
71
|
+
else
|
72
|
+
Errors.new(FailedToFetchFromReddit, "Failed to authenticate")
|
73
|
+
end
|
64
74
|
end
|
65
75
|
|
66
76
|
def handle_429(func_name, func_args)
|
@@ -68,7 +78,12 @@ module RedditToTelegram
|
|
68
78
|
|
69
79
|
sleep(10 / retries_left) if retries_left > 0
|
70
80
|
func_args[func_args.length - 1] = retries_left - 1
|
71
|
-
|
81
|
+
|
82
|
+
if retries_left > 0
|
83
|
+
send(func_name, *func_args)
|
84
|
+
else
|
85
|
+
Errors.new(FailedToFetchFromReddit, "Too many requests")
|
86
|
+
end
|
72
87
|
end
|
73
88
|
end
|
74
89
|
end
|
@@ -96,8 +96,9 @@ module RedditToTelegram
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def base_post_format_attrs(data)
|
99
|
-
{ id: data["name"],
|
100
|
-
text: CGI.unescapeHTML(data["title"])
|
99
|
+
{ id: data["name"].split("_")&.dig(1),
|
100
|
+
text: CGI.unescapeHTML(data["title"]),
|
101
|
+
misc: {} }
|
101
102
|
end
|
102
103
|
|
103
104
|
def prepare_gallery_links(data)
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "aws-sdk-dynamodb"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module RedditToTelegram
|
7
|
+
module Store
|
8
|
+
class AWSDynamoDB
|
9
|
+
ITEM_NAME = "cached_data"
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def client
|
13
|
+
@client ||= Aws::DynamoDB::Client.new(
|
14
|
+
access_key_id: Configuration.aws.access_key_id,
|
15
|
+
secret_access_key: Configuration.aws.secret_access_key,
|
16
|
+
region: Configuration.aws.region
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :reddit_token
|
23
|
+
|
24
|
+
def setup
|
25
|
+
check_credentials
|
26
|
+
prepare_db
|
27
|
+
assign_default_values
|
28
|
+
end
|
29
|
+
|
30
|
+
def check_credentials
|
31
|
+
return unless Configuration.store.type == :aws_dynamo_db
|
32
|
+
|
33
|
+
return if Configuration.aws.set_up?
|
34
|
+
|
35
|
+
Errors.new(
|
36
|
+
MissingConfiguration,
|
37
|
+
"Missing AWS credentials. Set them up or change store type to anything other than aws_dynamo_db"
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_post(telegram_chat_id, subreddit, id)
|
42
|
+
assign_empty_values_to_posts(telegram_chat_id, subreddit)
|
43
|
+
|
44
|
+
@posts[telegram_chat_id][subreddit] << id
|
45
|
+
|
46
|
+
if @posts[telegram_chat_id][subreddit].count > Store.max_stored_posts
|
47
|
+
@posts[telegram_chat_id][subreddit].shift
|
48
|
+
end
|
49
|
+
|
50
|
+
persist_posts(telegram_chat_id)
|
51
|
+
end
|
52
|
+
|
53
|
+
def assign_empty_values_to_posts(telegram_chat_id, subreddit)
|
54
|
+
@posts[telegram_chat_id] = {} if @posts[telegram_chat_id].nil?
|
55
|
+
@posts[telegram_chat_id][subreddit] = [] if @posts[telegram_chat_id][subreddit].nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
def persist_posts(telegram_chat_id)
|
59
|
+
res = client.put_item(
|
60
|
+
{
|
61
|
+
item: {
|
62
|
+
"TelegramChannel" => telegram_chat_id.to_s,
|
63
|
+
"Posts" => @posts[telegram_chat_id].to_json
|
64
|
+
},
|
65
|
+
return_consumed_capacity: "TOTAL",
|
66
|
+
table_name: POSTS_TABLE_NAME
|
67
|
+
}
|
68
|
+
)
|
69
|
+
|
70
|
+
Errors.new(FailedToPersistData, "Failed to persist data to DynamoDB") unless res.successful?
|
71
|
+
end
|
72
|
+
|
73
|
+
def dup_post?(telegram_chat_id, subreddit, id)
|
74
|
+
return false if @posts.dig(telegram_chat_id, subreddit).nil?
|
75
|
+
|
76
|
+
@posts[telegram_chat_id][subreddit].include?(id)
|
77
|
+
end
|
78
|
+
|
79
|
+
def load_posts(telegram_chat_id)
|
80
|
+
res = client.get_item(
|
81
|
+
{ key: { "TelegramChannel" => telegram_chat_id.to_s },
|
82
|
+
table_name: POSTS_TABLE_NAME }
|
83
|
+
)
|
84
|
+
@posts[telegram_chat_id] = JSON.parse(res.item["Posts"]).transform_keys(&:to_sym)
|
85
|
+
rescue StandardError
|
86
|
+
@posts[telegram_chat_id] = nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def assign_default_values
|
90
|
+
@reddit_token = ""
|
91
|
+
@posts = {}
|
92
|
+
end
|
93
|
+
|
94
|
+
POSTS_TABLE_NAME = "Posts"
|
95
|
+
POSTS_TABLE_ATTRIBUTES = {
|
96
|
+
attribute_definitions: [
|
97
|
+
{ attribute_name: "TelegramChannel",
|
98
|
+
attribute_type: "S" }
|
99
|
+
],
|
100
|
+
key_schema: [
|
101
|
+
{ attribute_name: "TelegramChannel",
|
102
|
+
key_type: "HASH" }
|
103
|
+
],
|
104
|
+
provisioned_throughput: {
|
105
|
+
read_capacity_units: 1,
|
106
|
+
write_capacity_units: 1
|
107
|
+
},
|
108
|
+
table_name: POSTS_TABLE_NAME
|
109
|
+
}.freeze
|
110
|
+
|
111
|
+
def prepare_db
|
112
|
+
res = client.list_tables
|
113
|
+
return unless res.successful?
|
114
|
+
|
115
|
+
return if res.table_names.include?(POSTS_TABLE_NAME)
|
116
|
+
|
117
|
+
client.create_table(POSTS_TABLE_ATTRIBUTES)
|
118
|
+
|
119
|
+
waited = 0
|
120
|
+
while client.describe_table(table_name: POSTS_TABLE_NAME).table.table_status != "ACTIVE"
|
121
|
+
if waited == 10
|
122
|
+
Errors.new(FailedToCreateDatabaseTable, "Failed to create #{POSTS_TABLE_NAME} table in DynamoDB")
|
123
|
+
break
|
124
|
+
end
|
125
|
+
sleep(1)
|
126
|
+
waited += 1
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -11,17 +11,26 @@ module RedditToTelegram
|
|
11
11
|
@posts = {}
|
12
12
|
|
13
13
|
def setup; end
|
14
|
+
def load_posts(_); end
|
14
15
|
|
15
|
-
def add_post(subreddit, id)
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def add_post(telegram_chat_id, subreddit, id)
|
17
|
+
assign_empty_values_to_posts(telegram_chat_id, subreddit)
|
18
|
+
|
19
|
+
posts[telegram_chat_id][subreddit] << id
|
20
|
+
return unless posts[telegram_chat_id][subreddit].count > Store.max_stored_posts
|
21
|
+
|
22
|
+
posts[telegram_chat_id][subreddit].shift
|
23
|
+
end
|
24
|
+
|
25
|
+
def assign_empty_values_to_posts(telegram_chat_id, subreddit)
|
26
|
+
posts[telegram_chat_id] = {} if posts[telegram_chat_id].nil?
|
27
|
+
posts[telegram_chat_id][subreddit] = [] if posts[telegram_chat_id][subreddit].nil?
|
19
28
|
end
|
20
29
|
|
21
|
-
def dup_post?(subreddit, id)
|
22
|
-
return false if posts
|
30
|
+
def dup_post?(telegram_channel, subreddit, id)
|
31
|
+
return false if posts.dig(telegram_channel, subreddit).nil?
|
23
32
|
|
24
|
-
posts[subreddit].include?(id)
|
33
|
+
posts[telegram_channel][subreddit].include?(id)
|
25
34
|
end
|
26
35
|
|
27
36
|
def posts
|
@@ -17,22 +17,34 @@ module RedditToTelegram
|
|
17
17
|
read_file
|
18
18
|
end
|
19
19
|
|
20
|
+
def load_posts(_); end
|
21
|
+
|
20
22
|
def reddit_token=(val)
|
21
23
|
@reddit_token = val
|
22
24
|
write_file
|
23
25
|
end
|
24
26
|
|
25
|
-
def add_post(subreddit, id)
|
26
|
-
|
27
|
-
|
28
|
-
@posts[
|
27
|
+
def add_post(telegram_chat_id, subreddit, id)
|
28
|
+
assign_empty_values_to_posts(telegram_chat_id, subreddit)
|
29
|
+
|
30
|
+
@posts[telegram_chat_id][subreddit] << id
|
31
|
+
|
32
|
+
if @posts[telegram_chat_id][subreddit].count > Store.max_stored_posts
|
33
|
+
@posts[telegram_chat_id][subreddit].shift
|
34
|
+
end
|
35
|
+
|
29
36
|
write_file
|
30
37
|
end
|
31
38
|
|
32
|
-
def
|
33
|
-
|
39
|
+
def assign_empty_values_to_posts(telegram_chat_id, subreddit)
|
40
|
+
@posts[telegram_chat_id] = {} if @posts[telegram_chat_id].nil?
|
41
|
+
@posts[telegram_chat_id][subreddit] = [] if @posts[telegram_chat_id][subreddit].nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
def dup_post?(telegram_channel, subreddit, id)
|
45
|
+
return false if posts.dig(telegram_channel, subreddit).nil?
|
34
46
|
|
35
|
-
posts[subreddit].include?(id)
|
47
|
+
posts[telegram_channel][subreddit].include?(id)
|
36
48
|
end
|
37
49
|
|
38
50
|
def read_file
|
@@ -43,14 +55,14 @@ module RedditToTelegram
|
|
43
55
|
@reddit_token = data["reddit_token"]
|
44
56
|
@posts = {}
|
45
57
|
data.each do |key, value|
|
46
|
-
@posts[key.split("_").last.to_sym] = value if key.match?(/posts_.+/)
|
58
|
+
@posts[key.split("_").last.to_sym] = value.transform_keys(&:to_sym) if key.match?(/posts_.+/)
|
47
59
|
end
|
48
60
|
end
|
49
61
|
|
50
62
|
def write_file
|
51
63
|
data = { reddit_token: @reddit_token }
|
52
|
-
@posts.each do |
|
53
|
-
data["posts_#{
|
64
|
+
@posts.each do |telegram_chat_id, values|
|
65
|
+
data["posts_#{telegram_chat_id}"] = values
|
54
66
|
end
|
55
67
|
File.open(temp_file_path, "w") { |f| f.write(data.to_json) }
|
56
68
|
end
|
@@ -2,15 +2,12 @@
|
|
2
2
|
|
3
3
|
module RedditToTelegram
|
4
4
|
module Store
|
5
|
-
MAX_STORED_POSTS = Configuration.store.max_stored_posts - 1
|
6
5
|
CLASS_MAP = {
|
7
|
-
|
6
|
+
aws_dynamo_db: "RedditToTelegram::Store::AWSDynamoDB",
|
8
7
|
memory: "RedditToTelegram::Store::Memory",
|
9
8
|
temp_file: "RedditToTelegram::Store::TempFile"
|
10
9
|
}.freeze
|
11
10
|
|
12
|
-
STORE = Object.const_get("RedditToTelegram::Store::AWSSimpleDB")
|
13
|
-
|
14
11
|
class << self
|
15
12
|
attr_accessor :active
|
16
13
|
|
@@ -20,6 +17,18 @@ module RedditToTelegram
|
|
20
17
|
self.active = Object.const_get(CLASS_MAP[Configuration.store.type])
|
21
18
|
active.send(:setup)
|
22
19
|
end
|
20
|
+
|
21
|
+
def max_stored_posts
|
22
|
+
Configuration.store.max_stored_posts - 1
|
23
|
+
end
|
24
|
+
|
25
|
+
def reddit
|
26
|
+
Reddit
|
27
|
+
end
|
28
|
+
|
29
|
+
def posts
|
30
|
+
Posts
|
31
|
+
end
|
23
32
|
end
|
24
33
|
|
25
34
|
class Reddit
|
@@ -36,12 +45,19 @@ module RedditToTelegram
|
|
36
45
|
|
37
46
|
class Posts
|
38
47
|
class << self
|
39
|
-
def add(subreddit, id)
|
40
|
-
Store.active.send(:add_post, subreddit, id)
|
48
|
+
def add(telegram_chat_id, subreddit, id)
|
49
|
+
Store.active.send(:add_post, telegram_chat_id, subreddit, id)
|
50
|
+
end
|
51
|
+
|
52
|
+
def dup?(telegram_chat_id, subreddit, id)
|
53
|
+
Store.active.send(:dup_post?, telegram_chat_id, subreddit, id)
|
41
54
|
end
|
42
55
|
|
43
|
-
def
|
44
|
-
Store.active.send(:
|
56
|
+
def next(telegram_chat_id, subreddit, posts)
|
57
|
+
Store.active.send(:load_posts, telegram_chat_id)
|
58
|
+
new_post = posts.find { |post| !dup?(telegram_chat_id, subreddit, post[:id]) }
|
59
|
+
add(telegram_chat_id, subreddit, new_post[:id]) unless new_post.nil?
|
60
|
+
new_post
|
45
61
|
end
|
46
62
|
end
|
47
63
|
end
|
@@ -5,30 +5,30 @@ module RedditToTelegram
|
|
5
5
|
class Post
|
6
6
|
class Gallery
|
7
7
|
class << self
|
8
|
-
def push_remaining_gallery_data(post, channel, res
|
8
|
+
def push_remaining_gallery_data(post, channel, res)
|
9
9
|
if post[:additional_media]
|
10
|
-
push_remaining_gallery_images(post, channel
|
10
|
+
push_remaining_gallery_images(post, channel)
|
11
11
|
else
|
12
|
-
push_gallery_caption(post, channel, res
|
12
|
+
push_gallery_caption(post, channel, res)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
private
|
17
17
|
|
18
|
-
def push_remaining_gallery_images(post, channel
|
18
|
+
def push_remaining_gallery_images(post, channel)
|
19
19
|
post[:media] = post[:additional_media].first(10)
|
20
20
|
remaining = post.delete(:additional_media).drop(10)
|
21
21
|
post[:additional_media] = remaining unless remaining.empty?
|
22
|
-
Post.push(post, channel
|
22
|
+
Post.push(post, channel)
|
23
23
|
end
|
24
24
|
|
25
|
-
def push_gallery_caption(post, channel, res
|
25
|
+
def push_gallery_caption(post, channel, res)
|
26
26
|
Telegram::Post.push(
|
27
27
|
{ type: :text,
|
28
28
|
id: post[:id],
|
29
|
-
text: post[:text]
|
30
|
-
|
31
|
-
|
29
|
+
text: post[:text],
|
30
|
+
misc: gallery_caption_opts(res) },
|
31
|
+
channel
|
32
32
|
)
|
33
33
|
end
|
34
34
|
|
@@ -19,20 +19,20 @@ module RedditToTelegram
|
|
19
19
|
}.freeze
|
20
20
|
|
21
21
|
class << self
|
22
|
-
def push(post, channel
|
22
|
+
def push(post, channel)
|
23
23
|
res = HTTParty.post(
|
24
24
|
"#{BASE_URI}#{Configuration.telegram.bot_token}/send#{METHOD_MAP[post[:type]]}",
|
25
|
-
**params(post, channel
|
25
|
+
**params(post, channel)
|
26
26
|
)
|
27
27
|
|
28
|
-
handle_response(post, channel, res
|
28
|
+
handle_response(post, channel, res)
|
29
29
|
end
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
-
def params(post, channel
|
33
|
+
def params(post, channel)
|
34
34
|
binary = post.dig(:misc)&.dig(:binary)
|
35
|
-
body = PrepareRequest.body(post, channel
|
35
|
+
body = PrepareRequest.body(post, channel)
|
36
36
|
|
37
37
|
pars = {
|
38
38
|
body: binary ? body : body.to_json,
|
@@ -42,29 +42,16 @@ module RedditToTelegram
|
|
42
42
|
pars
|
43
43
|
end
|
44
44
|
|
45
|
-
def handle_response(post, channel, res
|
46
|
-
|
47
|
-
Gallery.push_remaining_gallery_data(post, channel, res
|
48
|
-
Video.delete_file if post[:type] == :video && post.dig(:misc
|
45
|
+
def handle_response(post, channel, res)
|
46
|
+
log_error(post, channel, res) unless res["ok"]
|
47
|
+
Gallery.push_remaining_gallery_data(post, channel, res) if post[:type] == :gallery
|
48
|
+
Video.delete_file if post[:type] == :video && post.dig(:misc, :binary)
|
49
49
|
res
|
50
50
|
end
|
51
51
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
push(
|
56
|
-
{
|
57
|
-
type: :text,
|
58
|
-
id: post[:id],
|
59
|
-
text: "Channel: @#{channel}\n\nResponse: #{res}"
|
60
|
-
},
|
61
|
-
Configuration.telegram.error_channel_id,
|
62
|
-
opts.merge(
|
63
|
-
add_reddit_link: true,
|
64
|
-
disable_link_preview: true,
|
65
|
-
no_retry: true
|
66
|
-
)
|
67
|
-
)
|
52
|
+
def log_error(post, channel, res)
|
53
|
+
message = "\n\nChannel: #{channel}\n\nPost data: #{post}\n\nResponse: #{res}"
|
54
|
+
Errors.new(BadResponseFromTelegram, message)
|
68
55
|
end
|
69
56
|
end
|
70
57
|
end
|
@@ -4,54 +4,64 @@ module RedditToTelegram
|
|
4
4
|
module Telegram
|
5
5
|
class PrepareRequest
|
6
6
|
class << self
|
7
|
-
def body(post, chat_id
|
8
|
-
body = prepare_body(post, chat_id
|
9
|
-
body[:link_preview_options] = { is_disabled: true } if
|
10
|
-
body[:reply_parameters] = { message_id:
|
7
|
+
def body(post, chat_id)
|
8
|
+
body = prepare_body(post, chat_id)
|
9
|
+
body[:link_preview_options] = { is_disabled: true } if post.dig(:misc, :disable_link_preview)
|
10
|
+
body[:reply_parameters] = { message_id: post[:misc][:reply_to] } if post.dig(:misc, :reply_to)
|
11
11
|
body
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
def prepare_body(post, chat_id
|
16
|
+
def prepare_body(post, chat_id)
|
17
17
|
case post[:type]
|
18
18
|
when :image
|
19
|
-
{ chat_id: "@#{chat_id}", photo: post[:media], caption: prepare_text(post, chat_id
|
19
|
+
{ chat_id: "@#{chat_id}", photo: post[:media], caption: prepare_text(post, chat_id) }
|
20
20
|
when :gallery
|
21
|
-
{ chat_id: "@#{chat_id}", media: prepare_gallery_media(post), caption: prepare_text(post, chat_id
|
21
|
+
{ chat_id: "@#{chat_id}", media: prepare_gallery_media(post), caption: prepare_text(post, chat_id) }
|
22
22
|
when :gif
|
23
|
-
{ chat_id: "@#{chat_id}", animation: post[:media], caption: prepare_text(post, chat_id
|
23
|
+
{ chat_id: "@#{chat_id}", animation: post[:media], caption: prepare_text(post, chat_id) }
|
24
24
|
when :text
|
25
|
-
{ chat_id: "@#{chat_id}", text: prepare_text(post, chat_id
|
25
|
+
{ chat_id: "@#{chat_id}", text: prepare_text(post, chat_id) }
|
26
26
|
when :video
|
27
27
|
{
|
28
28
|
chat_id: "@#{chat_id}",
|
29
29
|
video: prepare_video(post),
|
30
30
|
height: post[:misc][:video_height],
|
31
31
|
width: post[:misc][:video_width],
|
32
|
-
caption: prepare_text(post, chat_id
|
32
|
+
caption: prepare_text(post, chat_id)
|
33
33
|
}
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def prepare_text(post, chat_id
|
37
|
+
def prepare_text(post, chat_id)
|
38
38
|
text = post[:text]
|
39
39
|
|
40
|
-
text =
|
40
|
+
text = translate(text)
|
41
|
+
text = add_reddit_link(text, post)
|
42
|
+
add_channel_handle(text, chat_id)
|
43
|
+
end
|
41
44
|
|
42
|
-
|
43
|
-
|
44
|
-
text += "\n\nhttps://redd.it/#{id}"
|
45
|
-
end
|
45
|
+
def translate(text)
|
46
|
+
return text unless Configuration.translate
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
text += "@#{chat_id}"
|
50
|
-
end
|
48
|
+
Services::Translate.text(text, Configuration.translate)
|
49
|
+
end
|
51
50
|
|
51
|
+
def add_reddit_link(text, post)
|
52
|
+
return text unless Configuration.add_reddit_link
|
53
|
+
|
54
|
+
text += "\n\nhttps://redd.it/#{post[:id]}"
|
52
55
|
text
|
53
56
|
end
|
54
57
|
|
58
|
+
def add_channel_handle(text, chat_id)
|
59
|
+
return text unless Configuration.add_channel_handle
|
60
|
+
|
61
|
+
text += Configuration.add_reddit_link ? "\n" : "\n\n"
|
62
|
+
text + "@#{chat_id}"
|
63
|
+
end
|
64
|
+
|
55
65
|
def prepare_gallery_media(post)
|
56
66
|
Array(post[:media]).map { |link| { type: "photo", media: link } }
|
57
67
|
end
|
data/reddit-to-telegram.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.homepage = "https://github.com/dersnek/reddit-to-telegram"
|
15
15
|
s.license = "MIT"
|
16
16
|
|
17
|
-
s.add_dependency "aws-sdk-
|
17
|
+
s.add_dependency "aws-sdk-dynamodb", "~> 1.106"
|
18
18
|
s.add_dependency "httparty"
|
19
19
|
|
20
20
|
s.add_development_dependency "rubocop"
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reddit-to-telegram
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Tityuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: aws-sdk-
|
14
|
+
name: aws-sdk-dynamodb
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1.106'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1.106'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: httparty
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,7 +75,7 @@ files:
|
|
75
75
|
- lib/reddit_to_telegram/reddit/output/imgur.rb
|
76
76
|
- lib/reddit_to_telegram/services/translate.rb
|
77
77
|
- lib/reddit_to_telegram/store.rb
|
78
|
-
- lib/reddit_to_telegram/store/
|
78
|
+
- lib/reddit_to_telegram/store/aws_dynamo_db.rb
|
79
79
|
- lib/reddit_to_telegram/store/memory.rb
|
80
80
|
- lib/reddit_to_telegram/store/temp_file.rb
|
81
81
|
- lib/reddit_to_telegram/telegram/post.rb
|
@@ -1,123 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "aws-sdk-simpledb"
|
4
|
-
require "json"
|
5
|
-
|
6
|
-
module RedditToTelegram
|
7
|
-
module Store
|
8
|
-
class AWSSimpleDB
|
9
|
-
ITEM_NAME = "cached_data"
|
10
|
-
|
11
|
-
class << self
|
12
|
-
def client
|
13
|
-
@client ||= Aws::SimpleDB::Client.new(
|
14
|
-
access_key_id: Configuration.aws.access_key_id,
|
15
|
-
secret_access_key: Configuration.aws.secret_access_key,
|
16
|
-
region: Configuration.aws.region
|
17
|
-
)
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
attr_reader :reddit_token
|
23
|
-
|
24
|
-
def setup
|
25
|
-
check_credentials
|
26
|
-
create_domain unless client.list_domains.domain_names.include?(Configuration.aws.domain_name)
|
27
|
-
read_db
|
28
|
-
end
|
29
|
-
|
30
|
-
def check_credentials
|
31
|
-
return unless Configuration.store.type == :aws_simple_db
|
32
|
-
|
33
|
-
return if Configuration.aws.set_up?
|
34
|
-
|
35
|
-
Errors.new(
|
36
|
-
MissingConfiguration,
|
37
|
-
"Missing AWS credentials. Set them up or change store type to anything other than aws_simple_db"
|
38
|
-
)
|
39
|
-
end
|
40
|
-
|
41
|
-
def reddit_token=(val)
|
42
|
-
@reddit_token = val
|
43
|
-
write_db
|
44
|
-
end
|
45
|
-
|
46
|
-
def add_post(subreddit, id)
|
47
|
-
@posts[subreddit] = [] if @posts[subreddit].nil?
|
48
|
-
@posts[subreddit] << id
|
49
|
-
@posts[subreddit].shift if @posts[subreddit].count > Store::MAX_STORED_POSTS
|
50
|
-
write_db
|
51
|
-
end
|
52
|
-
|
53
|
-
def dup_post?(subreddit, id)
|
54
|
-
return false if @posts[subreddit].nil?
|
55
|
-
|
56
|
-
@posts[subreddit].include?(id)
|
57
|
-
end
|
58
|
-
|
59
|
-
def read_db
|
60
|
-
res = client.get_attributes(
|
61
|
-
{
|
62
|
-
domain_name: Configuration.aws.domain_name,
|
63
|
-
item_name: "cached_data",
|
64
|
-
consistent_read: true
|
65
|
-
}
|
66
|
-
)
|
67
|
-
|
68
|
-
return assign_default_values if res.attributes.empty?
|
69
|
-
|
70
|
-
assign_values_from_db(res)
|
71
|
-
end
|
72
|
-
|
73
|
-
def assign_values_from_db(data)
|
74
|
-
@reddit_token = data.attributes.find { |a| a.name == "reddit_token" }.value || ""
|
75
|
-
@posts = {}
|
76
|
-
data.attributes.each do |attr|
|
77
|
-
@posts[attr.name.split("_").last.to_sym] = JSON.parse(attr.value) if attr.name.match?(/posts_.+/)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def write_db
|
82
|
-
client.put_attributes(
|
83
|
-
{
|
84
|
-
domain_name: Configuration.aws.domain_name,
|
85
|
-
item_name: ITEM_NAME,
|
86
|
-
attributes: prepare_db_attrs
|
87
|
-
}
|
88
|
-
)
|
89
|
-
end
|
90
|
-
|
91
|
-
def prepare_db_attrs
|
92
|
-
attrs = [
|
93
|
-
{
|
94
|
-
name: "reddit_token",
|
95
|
-
value: @reddit_token,
|
96
|
-
replace: true
|
97
|
-
}
|
98
|
-
]
|
99
|
-
|
100
|
-
@posts.each do |subreddit, values|
|
101
|
-
attrs << { name: "posts_#{subreddit}", value: values.to_json, replace: true }
|
102
|
-
end
|
103
|
-
|
104
|
-
attrs
|
105
|
-
end
|
106
|
-
|
107
|
-
def assign_default_values
|
108
|
-
@reddit_token = ""
|
109
|
-
@posts = {}
|
110
|
-
end
|
111
|
-
|
112
|
-
def create_domain
|
113
|
-
res = client.list_domains
|
114
|
-
return unless res.successful?
|
115
|
-
|
116
|
-
return if res.domain_names.include?(Configuration.aws.domain_name)
|
117
|
-
|
118
|
-
client.create_domain({ domain_name: Configuration.aws.domain_name })
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|