reddit-to-telegram 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64c3e44dd622e534404baf7a42ecd2bfab3c6a61ae0fb662f9803e674c626dcf
4
- data.tar.gz: f7f48164b5746abded0025b5025e0b295e7c4f3287b65d2d2a58fd04bd8a577b
3
+ metadata.gz: 141226c6670a9b95e6ec4f7a9e74da982ed135ac22d57173c39625d4c1acfb11
4
+ data.tar.gz: 05c3a7b11a49162ed3742abfa3b2ea38a39048393133f9e1b16130b6c8c747ec
5
5
  SHA512:
6
- metadata.gz: e2e562fbb1831955bb921311e963c02ed3dbf6a05e46d93fb729a2604b15397f0dda97afee91c1fd967d83b5196a4ff311cf286b352e4e6cf5a59e15e2cb537d
7
- data.tar.gz: 644e1ef22281b1ba0a97c419a321c1ec9f00e3e71b41d25c998a6e9a7820c60bff9e38c2eec7f514c23962671d7460ec546ac129d6f31a5fcda5ad4f0af010be
6
+ metadata.gz: bca6427e5ab1fe8fd76f2e11f0b0101f624f37874915b056731385ba74f4b584aed9b7180b7ae380227db1745b15538ecdd2df4cdbf0c8b0f0ecabed17e571d5
7
+ data.tar.gz: bd53e70c0a7587af11fc27016e236205b4966ba5c4cd2bdfad1eedc72170abe035ad21945dc2c9933198608e8517053f7e467733cb36acf8c36c4efdcf198879
data/README.md CHANGED
@@ -7,6 +7,8 @@
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).
11
+
10
12
  ## Installation
11
13
  In your `Gemfile` add:
12
14
  ```
@@ -40,10 +42,10 @@ To run it, you'll need some env variables set.
40
42
 
41
43
  You can also set them dynamically:
42
44
  ```
43
- RedditToTelegram::Variables.aws.access_key_id =
44
- RedditToTelegram::Variables.telegram.bot_token =
45
+ RedditToTelegram.config.aws.access_key_id =
46
+ RedditToTelegram.config.telegram.bot_token =
45
47
  ```
46
- Check out `lib/variables` for list of all available variables.
48
+ Check out `lib/configuration` for full configuration.
47
49
 
48
50
  ## Usage
49
51
 
@@ -57,7 +59,7 @@ RedditToTelegram.hot(
57
59
  ```
58
60
  Or to push one specific post (the only thing you need to set up for this is your telegram bot token):
59
61
  ```
60
- RedditToTelegram.single("regular_link_to_post", :telegram_channel_id)
62
+ RedditToTelegram.from_link("regular_link_to_post", :telegram_channel_id)
61
63
  ```
62
64
  Use `:telegram_channel_id` without the `@`.
63
65
 
@@ -1,18 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "reddit_to_telegram/post"
4
- require_relative "reddit_to_telegram/version"
3
+ Dir["#{File.dirname(__FILE__)}/reddit_to_telegram/**/*.rb"].each { |file| require file }
5
4
 
6
5
  module RedditToTelegram
7
6
  class << self
8
7
  extend Forwardable
9
8
 
10
- def_delegators :post, :hot, :single
9
+ def_delegators :post, :hot, :from_link
11
10
 
12
11
  def post
13
12
  Post
14
13
  end
15
14
 
15
+ def config
16
+ Configuration
17
+ end
18
+
16
19
  def version
17
20
  VERSION
18
21
  end
@@ -1,26 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "logger"
4
+
3
5
  module RedditToTelegram
4
- module Variables
6
+ module Configuration
5
7
  class << self
6
- def aws
7
- RedditToTelegram::Variables::AWS
8
- end
9
-
10
- def google
11
- RedditToTelegram::Variables::Google
12
- end
13
-
14
- def reddit
15
- RedditToTelegram::Variables::Reddit
16
- end
8
+ attr_writer :logger, :on_error
17
9
 
18
- def store
19
- RedditToTelegram::Variables::Store
10
+ def logger
11
+ @logger ||= Logger.new($stdout).tap do |log|
12
+ log.progname = "RedditToTelegram"
13
+ end
20
14
  end
21
15
 
22
- def telegram
23
- RedditToTelegram::Variables::Telegram
16
+ def on_error
17
+ @on_error ||= :log
24
18
  end
25
19
  end
26
20
 
@@ -115,5 +109,19 @@ module RedditToTelegram
115
109
  end
116
110
  end
117
111
  end
112
+
113
+ class << self
114
+ NESTED_CONFIG = {
115
+ aws: AWS,
116
+ google: Google,
117
+ reddit: Reddit,
118
+ store: Store,
119
+ telegram: Telegram
120
+ }.freeze
121
+
122
+ NESTED_CONFIG.each do |key, value|
123
+ define_method(key) { value }
124
+ end
125
+ end
118
126
  end
119
127
  end
@@ -2,6 +2,21 @@
2
2
 
3
3
  module RedditToTelegram
4
4
  class RedditToTelegramError < StandardError; end
5
+
5
6
  class InvalidStoreType < RedditToTelegramError; end
6
- class MissingVariables < RedditToTelegramError; end
7
+ class MissingConfiguration < RedditToTelegramError; end
8
+
9
+ class Errors
10
+ class << self
11
+ def new(error, message = nil)
12
+ if Configuration.on_error == :raise
13
+ raise(error.new(message))
14
+ elsif Configuration.on_error == :log
15
+ log_message = error.to_s
16
+ log_message += ": #{message}" unless message.nil?
17
+ Configuration.logger.error(log_message)
18
+ end
19
+ end
20
+ end
21
+ end
7
22
  end
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "reddit/fetch"
4
- require_relative "store"
5
- require_relative "telegram/post"
6
- require_relative "variables"
7
-
8
3
  module RedditToTelegram
9
4
  class Post
10
5
  class << self
11
6
  def hot(sources, opts = {})
7
+ check_config
12
8
  return if sources.empty?
13
9
 
14
10
  Store.setup
@@ -19,21 +15,28 @@ module RedditToTelegram
19
15
  end
20
16
  end
21
17
 
22
- def single(link, telegram_chat_id, opts = {})
18
+ def from_link(link, telegram_chat_id, opts = {})
19
+ check_config
23
20
  return if link.empty?
24
21
 
25
- Variables.store.type = :memory
22
+ Configuration.store.type = :memory
26
23
  Store.setup
27
24
 
28
25
  res = Reddit::Fetch.post(link)
26
+ return unless res_ok?(res)
27
+
29
28
  Telegram::Post.push(res, telegram_chat_id, opts)
30
29
  res
31
30
  end
32
31
 
33
32
  private
34
33
 
34
+ def check_config
35
+ Errors.new(MissingConfiguration, "Missing Telegram bot token") if Configuration.telegram.bot_token.to_s.empty?
36
+ end
37
+
35
38
  def handle_res(res, subreddit, telegram_chat_id, opts = {})
36
- return if res.nil?
39
+ return unless res_ok?(res)
37
40
 
38
41
  post = find_new_post(subreddit, res)
39
42
  return if post.nil?
@@ -43,6 +46,18 @@ module RedditToTelegram
43
46
  res
44
47
  end
45
48
 
49
+ def res_ok?(res)
50
+ if res.nil?
51
+ Configuration.logger.warn("Could not fetch Reddit post")
52
+ false
53
+ elsif res[:type].nil?
54
+ Configuration.logger.warn("Could not determine Reddit post type")
55
+ false
56
+ else
57
+ true
58
+ end
59
+ end
60
+
46
61
  def find_new_post(subreddit, posts)
47
62
  posts.find { |post| !Store::Posts.dup?(subreddit, post[:id]) }
48
63
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "httparty"
4
- require_relative "../variables"
5
4
 
6
5
  module RedditToTelegram
7
6
  module Reddit
@@ -18,7 +17,7 @@ module RedditToTelegram
18
17
  URI,
19
18
  body: PARAMS,
20
19
  headers: HEADERS,
21
- basic_auth: { username: Variables.reddit.client_id, password: Variables.reddit.client_secret }
20
+ basic_auth: { username: Configuration.reddit.client_id, password: Configuration.reddit.client_secret }
22
21
  )["access_token"]
23
22
  end
24
23
  end
@@ -1,10 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "httparty"
4
- require_relative "auth"
5
- require_relative "output"
6
- require_relative "../store"
7
- require_relative "../variables"
8
4
 
9
5
  module RedditToTelegram
10
6
  module Reddit
@@ -14,7 +10,7 @@ module RedditToTelegram
14
10
  BASE_URI = "https://oauth.reddit.com/r"
15
11
  WEBSITE_URI = "https://www.reddit.com/r"
16
12
  QUERY_FOR_POST = { g: "GLOBAL" }.freeze
17
- QUERY_FOR_SUBREDDIT = QUERY_FOR_POST.merge(limit: Variables.store.max_stored_posts).freeze
13
+ QUERY_FOR_SUBREDDIT = QUERY_FOR_POST.merge(limit: Configuration.store.max_stored_posts).freeze
18
14
  BASE_HEADERS = {
19
15
  "Content-Type" => "application/json",
20
16
  "Accept" => "application/json"
@@ -28,6 +24,7 @@ module RedditToTelegram
28
24
  query: QUERY_FOR_SUBREDDIT,
29
25
  headers:
30
26
  )
27
+
31
28
  handle_response(res, hot: [subreddit, retries_left])
32
29
  end
33
30
 
@@ -41,6 +38,7 @@ module RedditToTelegram
41
38
  query: QUERY_FOR_POST,
42
39
  headers:
43
40
  )
41
+
44
42
  handle_response(res, post: [link, retries_left])
45
43
  end
46
44
 
@@ -43,7 +43,7 @@ module RedditToTelegram
43
43
  end
44
44
 
45
45
  def format_imgur_post(data, video_url, width)
46
- RedditToTelegram::Reddit::Output.send(
46
+ Reddit::Output.send(
47
47
  :base_post_format_attrs, data
48
48
  ).merge(
49
49
  {
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "cgi"
4
- require_relative "output/imgur"
5
4
 
6
5
  module RedditToTelegram
7
6
  module Reddit
@@ -23,6 +22,12 @@ module RedditToTelegram
23
22
 
24
23
  def format_post(post)
25
24
  data = post["data"]
25
+
26
+ unless data["removed_by_category"].nil?
27
+ Configuration.logger.warn("Reddit post was removed")
28
+ return
29
+ end
30
+
26
31
  if data["post_hint"] == "image"
27
32
  format_image_post(data)
28
33
  elsif data["post_hint"] == "link"
@@ -49,7 +54,7 @@ module RedditToTelegram
49
54
 
50
55
  base_post_format_attrs(data).merge(
51
56
  { type: :text,
52
- text: "#{data['title']}\n\n#{data['url']}" }
57
+ text: "#{CGI.unescapeHTML(data['title'])}\n\n#{data['url']}" }
53
58
  )
54
59
  end
55
60
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "httparty"
4
- require_relative "../store"
5
4
 
6
5
  module RedditToTelegram
7
6
  module Services
@@ -19,7 +18,7 @@ module RedditToTelegram
19
18
  BASE_URI,
20
19
  body: body(string, target_language),
21
20
  headers: HEADERS.merge(
22
- "X-goog-api-key" => Variables.google.api_key
21
+ "X-goog-api-key" => Configuration.google.api_key
23
22
  )
24
23
  )
25
24
  res.dig("data", "translations")&.first&.dig("translatedText")
@@ -28,9 +27,9 @@ module RedditToTelegram
28
27
  private
29
28
 
30
29
  def check
31
- return if Variables.google.set_up?
30
+ return if Configuration.google.set_up?
32
31
 
33
- raise(MissingVariables.new("Missing Google credentials. Set them up or disable translation"))
32
+ Errors.new(MissingConfiguration, "Missing Google credentials. Set them up or disable translation")
34
33
  end
35
34
 
36
35
  def body(string, target_language)
@@ -2,8 +2,6 @@
2
2
 
3
3
  require "aws-sdk-simpledb"
4
4
  require "json"
5
- require_relative "../errors"
6
- require_relative "../variables"
7
5
 
8
6
  module RedditToTelegram
9
7
  module Store
@@ -13,9 +11,9 @@ module RedditToTelegram
13
11
  class << self
14
12
  def client
15
13
  @client ||= Aws::SimpleDB::Client.new(
16
- access_key_id: Variables.aws.access_key_id,
17
- secret_access_key: Variables.aws.secret_access_key,
18
- region: Variables.aws.region
14
+ access_key_id: Configuration.aws.access_key_id,
15
+ secret_access_key: Configuration.aws.secret_access_key,
16
+ region: Configuration.aws.region
19
17
  )
20
18
  end
21
19
 
@@ -25,17 +23,19 @@ module RedditToTelegram
25
23
 
26
24
  def setup
27
25
  check_credentials
28
- create_domain unless client.list_domains.domain_names.include?(Variables.aws.domain_name)
26
+ create_domain unless client.list_domains.domain_names.include?(Configuration.aws.domain_name)
29
27
  read_db
30
28
  end
31
29
 
32
30
  def check_credentials
33
- return unless Variables.store.type == :aws_simple_db
31
+ return unless Configuration.store.type == :aws_simple_db
34
32
 
35
- return if Variables.aws.set_up?
33
+ return if Configuration.aws.set_up?
36
34
 
37
- raise(MissingVariables.new("Missing AWS credentials. "\
38
- "Set them up or change store type to anything other than aws_simple_db"))
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
39
  end
40
40
 
41
41
  def reddit_token=(val)
@@ -59,7 +59,7 @@ module RedditToTelegram
59
59
  def read_db
60
60
  res = client.get_attributes(
61
61
  {
62
- domain_name: Variables.aws.domain_name,
62
+ domain_name: Configuration.aws.domain_name,
63
63
  item_name: "cached_data",
64
64
  consistent_read: true
65
65
  }
@@ -81,7 +81,7 @@ module RedditToTelegram
81
81
  def write_db
82
82
  client.put_attributes(
83
83
  {
84
- domain_name: Variables.aws.domain_name,
84
+ domain_name: Configuration.aws.domain_name,
85
85
  item_name: ITEM_NAME,
86
86
  attributes: prepare_db_attrs
87
87
  }
@@ -113,9 +113,9 @@ module RedditToTelegram
113
113
  res = client.list_domains
114
114
  return unless res.successful?
115
115
 
116
- return if res.domain_names.include?(Variables.aws.domain_name)
116
+ return if res.domain_names.include?(Configuration.aws.domain_name)
117
117
 
118
- client.create_domain({ domain_name: Variables.aws.domain_name })
118
+ client.create_domain({ domain_name: Configuration.aws.domain_name })
119
119
  end
120
120
  end
121
121
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "json"
4
- require_relative "../variables"
5
4
 
6
5
  module RedditToTelegram
7
6
  module Store
@@ -62,7 +61,7 @@ module RedditToTelegram
62
61
  end
63
62
 
64
63
  def temp_file_path
65
- "#{Variables.store.tmp_dir}/store.json"
64
+ "#{Configuration.store.tmp_dir}/store.json"
66
65
  end
67
66
  end
68
67
  end
@@ -1,14 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "errors"
4
- require_relative "store/aws_simple_db"
5
- require_relative "store/memory"
6
- require_relative "store/temp_file"
7
- require_relative "variables"
8
-
9
3
  module RedditToTelegram
10
4
  module Store
11
- MAX_STORED_POSTS = Variables.store.max_stored_posts - 1
5
+ MAX_STORED_POSTS = Configuration.store.max_stored_posts - 1
12
6
  CLASS_MAP = {
13
7
  aws_simple_db: "RedditToTelegram::Store::AWSSimpleDB",
14
8
  memory: "RedditToTelegram::Store::Memory",
@@ -21,9 +15,9 @@ module RedditToTelegram
21
15
  attr_accessor :active
22
16
 
23
17
  def setup
24
- raise(InvalidStoreType.new) unless CLASS_MAP.keys.include?(Variables.store.type)
18
+ Errors.new(InvalidStoreType) unless CLASS_MAP.keys.include?(Configuration.store.type)
25
19
 
26
- self.active = Object.const_get(CLASS_MAP[RedditToTelegram::Variables.store.type])
20
+ self.active = Object.const_get(CLASS_MAP[Configuration.store.type])
27
21
  active.send(:setup)
28
22
  end
29
23
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../post"
4
-
5
3
  module RedditToTelegram
6
4
  module Telegram
7
5
  class Post
@@ -25,7 +23,7 @@ module RedditToTelegram
25
23
  end
26
24
 
27
25
  def push_gallery_caption(post, channel, res, opts = {})
28
- Post.push(
26
+ Telegram::Post.push(
29
27
  { type: :text,
30
28
  id: post[:id],
31
29
  text: post[:text] },
@@ -1,10 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "httparty"
4
- require_relative "post/gallery"
5
- require_relative "prepare_request"
6
- require_relative "video"
7
- require_relative "../variables"
8
4
 
9
5
  module RedditToTelegram
10
6
  module Telegram
@@ -25,7 +21,7 @@ module RedditToTelegram
25
21
  class << self
26
22
  def push(post, channel, opts = {})
27
23
  res = HTTParty.post(
28
- "#{BASE_URI}#{Variables.telegram.bot_token}/send#{METHOD_MAP[post[:type]]}",
24
+ "#{BASE_URI}#{Configuration.telegram.bot_token}/send#{METHOD_MAP[post[:type]]}",
29
25
  **params(post, channel, opts)
30
26
  )
31
27
 
@@ -54,7 +50,7 @@ module RedditToTelegram
54
50
  end
55
51
 
56
52
  def push_error(post, channel, res, opts = {})
57
- return if Variables.telegram.error_channel_id.to_s.empty?
53
+ return if Configuration.telegram.error_channel_id.to_s.empty?
58
54
 
59
55
  push(
60
56
  {
@@ -62,7 +58,7 @@ module RedditToTelegram
62
58
  id: post[:id],
63
59
  text: "Channel: @#{channel}\n\nResponse: #{res}"
64
60
  },
65
- Variables.telegram.error_channel_id,
61
+ Configuration.telegram.error_channel_id,
66
62
  opts.merge(
67
63
  add_reddit_link: true,
68
64
  disable_link_preview: true,
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "video"
4
- require_relative "../services/translate"
5
-
6
3
  module RedditToTelegram
7
4
  module Telegram
8
5
  class PrepareRequest
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "open-uri"
4
- require_relative "../variables"
5
4
 
6
5
  module RedditToTelegram
7
6
  module Telegram
@@ -23,7 +22,7 @@ module RedditToTelegram
23
22
  end
24
23
 
25
24
  def temp_video_path
26
- "#{Variables.store.tmp_dir}/video.mp4"
25
+ "#{Configuration.store.tmp_dir}/video.mp4"
27
26
  end
28
27
  end
29
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RedditToTelegram
4
- VERSION = "0.7.2"
4
+ VERSION = "0.8.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reddit-to-telegram
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.8.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-02 00:00:00.000000000 Z
11
+ date: 2024-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-simpledb
@@ -66,6 +66,7 @@ files:
66
66
  - LICENSE
67
67
  - README.md
68
68
  - lib/reddit-to-telegram.rb
69
+ - lib/reddit_to_telegram/configuration.rb
69
70
  - lib/reddit_to_telegram/errors.rb
70
71
  - lib/reddit_to_telegram/post.rb
71
72
  - lib/reddit_to_telegram/reddit/auth.rb
@@ -81,7 +82,6 @@ files:
81
82
  - lib/reddit_to_telegram/telegram/post/gallery.rb
82
83
  - lib/reddit_to_telegram/telegram/prepare_request.rb
83
84
  - lib/reddit_to_telegram/telegram/video.rb
84
- - lib/reddit_to_telegram/variables.rb
85
85
  - lib/reddit_to_telegram/version.rb
86
86
  - reddit-to-telegram.gemspec
87
87
  - tmp/.keep