reddit-to-telegram 0.3.0 → 0.4.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: e6c7b26fa99c0cd58ee1e6bc13e4bc357d20aa30c3efbc4ca1df02a75948afbc
4
- data.tar.gz: '00183a34218ed5e32012af4b7614438bec200ecf1443cb3a5f4db649aa8dac19'
3
+ metadata.gz: cf7cd73ace4a26347b3bdca75b782e28d635617d2952d33cf39ef7ee015a64cf
4
+ data.tar.gz: b1bee46a1cf4f490b58258d321e4e6949c393c0d116a5be638b34feadf85b713
5
5
  SHA512:
6
- metadata.gz: 1f5a3a2c3d03f37ff932245225e84c7ffd35c79051db95816598323456e95fa88ab710f66f1b01e9927b897db4df2227cc1a44673431e0eee655be8f5bde897a
7
- data.tar.gz: 43a98d11dc600a57ede04ff2d6279373a3965be64b27084d761e9ffc3f943f4e94147e0f0293504d33ad6ae857ef4cb117f1a0c53964157b533f4240efe62d63
6
+ metadata.gz: 073d10eb8a45293ed6aa3c8b6779f50965655accfc234cd89ea43c628f71c93448835457c220fcafa20a17e7ef517f61389a102c1c2dca031e853751d62bbe01
7
+ data.tar.gz: e53497c36c061d3ba2758e3dddb97c358d2a62bc8c2469ac2417da83991e0675718b1109ff25f2daa61403aaf6c26757aa49aee89e5de7b1af1d89dd402bfa24
data/.rubocop.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  Metrics/MethodLength:
2
2
  Max: 20
3
3
 
4
+ Naming/VariableNumber:
5
+ Enabled: false
6
+
4
7
  Style/Documentation:
5
8
  Enabled: false
6
9
 
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  #### Fetches hot posts from chosen subreddits and pushes them to Telegram channels.
6
6
 
7
- Beware, this is remotely not production-ready, you'll see lots of bugs and it may break at any time.
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
10
  ## Installation
@@ -14,12 +14,12 @@ gem "reddit-to-telegram"
14
14
  ```
15
15
  Then run `bundle install`.
16
16
 
17
- Or `gem install reddit-to-telegram`, but don't forget to `require` it first then.
17
+ Or `gem install reddit-to-telegram`. Don't forget to `require` it.
18
18
 
19
19
  ## Prerequisites
20
- - You need an AWS account to host a free SimpleDB (memory and local file storage options are available, but no way to switch for now)
21
- - (Optionally) Create a Reddit app, which would allow more requests to reddit
22
- - [Obtain](https://core.telegram.org/bots/tutorial#obtain-your-bot-token) a telegram bot token
20
+ - (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.
21
+ - (Optionally) [Create a Reddit app](https://www.reddit.com/prefs/apps), which would allow more requests to reddit
22
+ - [Obtain a telegram bot token](https://core.telegram.org/bots/tutorial#obtain-your-bot-token)
23
23
 
24
24
  To run it, you'll need some env variables set.
25
25
  ```
@@ -45,12 +45,19 @@ Check out `lib/variables` for list of all available variables.
45
45
  ## Usage
46
46
 
47
47
  1. Add the bot as administrator to Telegram channels you'd like to post to.
48
- 2.
48
+ 2a. To fetch latest hot post which hasn't been pushed yet:
49
49
  ```
50
- RedditToTelegram.post(
50
+ RedditToTelegram.hot(
51
51
  subreddit_name_1: :telegram_channel_id_1,
52
52
  subreddit_name_2: :telegram_channel_id_2
53
53
  )
54
-
54
+ ```
55
+ 2b. To push one specific post:
56
+ ```
57
+ RedditToTelegram.single("regular_link_to_post", :telegram_channel_id)
55
58
  ```
56
59
  Use `:telegram_channel_id` without the `@`.
60
+
61
+ ## Planned features
62
+ - Upload Imgur gifv links as videos/gifs
63
+ - Error handling
@@ -1,39 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "pry"
4
-
5
- require_relative "reddit_to_telegram/reddit/fetch"
6
- require_relative "reddit_to_telegram/store"
7
- require_relative "reddit_to_telegram/telegram/post"
3
+ require_relative "reddit_to_telegram/post"
8
4
  require_relative "reddit_to_telegram/version"
9
5
 
10
6
  module RedditToTelegram
11
7
  class << self
12
- def post(sources)
13
- return if sources.empty?
14
-
15
- Store.setup
16
-
17
- sources.each do |subreddit, telegram_chat_id|
18
- res = Reddit::Fetch.hot(subreddit)
19
- handle_res(res, subreddit, telegram_chat_id)
20
- end
21
- end
22
-
23
- private
24
-
25
- def handle_res(res, subreddit, telegram_chat_id)
26
- return if res.nil?
8
+ extend Forwardable
27
9
 
28
- post = find_new_post(subreddit, res)
29
- return if post.nil?
10
+ def_delegators :post, :hot, :single
30
11
 
31
- Telegram::Post.push(post, telegram_chat_id)
32
- Store::Posts.add(subreddit, post[:id])
12
+ def post
13
+ Post
33
14
  end
34
15
 
35
- def find_new_post(subreddit, posts)
36
- posts.find { |post| !Store::Posts.dup?(subreddit, post[:id]) }
16
+ def version
17
+ VERSION
37
18
  end
38
19
  end
39
20
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "reddit/fetch"
4
+ require_relative "store"
5
+ require_relative "telegram/post"
6
+ require_relative "variables"
7
+
8
+ module RedditToTelegram
9
+ class Post
10
+ class << self
11
+ def hot(sources)
12
+ return if sources.empty?
13
+
14
+ Store.setup
15
+
16
+ sources.each do |subreddit, telegram_chat_id|
17
+ res = Reddit::Fetch.hot(subreddit)
18
+ handle_res(res, subreddit, telegram_chat_id)
19
+ end
20
+ end
21
+
22
+ def single(link, telegram_chat_id)
23
+ return if link.empty?
24
+
25
+ Variables.store.type = :memory
26
+ Store.setup
27
+
28
+ res = Reddit::Fetch.post(link)
29
+ Telegram::Post.push(res, telegram_chat_id)
30
+ end
31
+
32
+ private
33
+
34
+ def handle_res(res, subreddit, telegram_chat_id)
35
+ return if res.nil?
36
+
37
+ post = find_new_post(subreddit, res)
38
+ return if post.nil?
39
+
40
+ Telegram::Post.push(post, telegram_chat_id)
41
+ Store::Posts.add(subreddit, post[:id])
42
+ end
43
+
44
+ def find_new_post(subreddit, posts)
45
+ posts.find { |post| !Store::Posts.dup?(subreddit, post[:id]) }
46
+ end
47
+ end
48
+ end
49
+ end
@@ -12,7 +12,9 @@ module RedditToTelegram
12
12
  include HTTParty
13
13
 
14
14
  BASE_URI = "https://oauth.reddit.com/r"
15
- QUERY = { g: "GLOBAL", limit: Variables.store.max_stored_posts }.freeze
15
+ WEBSITE_URI = "https://www.reddit.com/r"
16
+ QUERY_FOR_POST = { g: "GLOBAL" }.freeze
17
+ QUERY_FOR_SUBREDDIT = QUERY_FOR_POST.merge(limit: Variables.store.max_stored_posts).freeze
16
18
  BASE_HEADERS = {
17
19
  "Content-Type" => "application/json",
18
20
  "Accept" => "application/json"
@@ -23,26 +25,50 @@ module RedditToTelegram
23
25
  headers = BASE_HEADERS.merge("Authorization" => "Bearer #{Store::Reddit.token}")
24
26
  res = HTTParty.get(
25
27
  "#{BASE_URI}/#{subreddit}/hot.json",
26
- query: QUERY,
28
+ query: QUERY_FOR_SUBREDDIT,
27
29
  headers:
28
30
  )
29
- handle_response(res, subreddit, retries_left)
31
+ handle_response(res, hot: [subreddit, retries_left])
32
+ end
33
+
34
+ def post(link, retries_left = 5)
35
+ headers = BASE_HEADERS.merge("Authorization" => "Bearer #{Store::Reddit.token}")
36
+ res = HTTParty.get(
37
+ "#{link.gsub('www', 'oauth')}.json",
38
+ query: QUERY_FOR_POST,
39
+ headers:
40
+ )
41
+ handle_response(res, post: retries_left)
30
42
  end
31
43
 
32
44
  private
33
45
 
34
- def handle_response(res, subreddit, retries_left)
46
+ def handle_response(res, func)
47
+ func_name = func.keys.first
48
+ func_args = Array(func.values.first)
49
+
35
50
  case res.code
36
51
  when 401
37
- Store::Reddit.token = Auth.token
38
- hot(subreddit, retries_left) if retries_left > 0
52
+ handle_401(func_name, func_args)
39
53
  when 429
40
- sleep(10 / retries_left) if retries_left > 0
41
- hot(subreddit, retries_left - 1) if retries_left > 0
54
+ handle_429(func_name, func_args)
42
55
  when 200
43
56
  Output.format_response(res)
44
57
  end
45
58
  end
59
+
60
+ def handle_401(func_name, func_args)
61
+ Store::Reddit.token = Auth.token
62
+ send(func_name, *func_args) if func_args.last > 0
63
+ end
64
+
65
+ def handle_429(func_name, func_args)
66
+ retries_left = func_args.last
67
+
68
+ sleep(10 / retries_left) if retries_left > 0
69
+ func_args[func_args.length - 1] = retries_left - 1
70
+ send(func_name, *func_args) if retries_left > 0
71
+ end
46
72
  end
47
73
  end
48
74
  end
@@ -1,10 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "cgi"
4
+
3
5
  module RedditToTelegram
4
6
  module Reddit
5
7
  class Output
6
8
  class << self
7
9
  def format_response(res)
10
+ return format_post(res[0]["data"]["children"][0]) if single_post?(res)
11
+
8
12
  posts = res["data"]["children"]
9
13
  posts.reject! { |post| post["data"]["stickied"] == true }
10
14
  posts.map { |post| format_post(post) }.compact
@@ -12,6 +16,10 @@ module RedditToTelegram
12
16
 
13
17
  private
14
18
 
19
+ def single_post?(res)
20
+ res.parsed_response.is_a?(Array) && res[0]["data"]["dist"] == 1
21
+ end
22
+
15
23
  def format_post(post)
16
24
  data = post["data"]
17
25
  if data["post_hint"] == "image"
@@ -61,7 +69,9 @@ module RedditToTelegram
61
69
  type: :video,
62
70
  media: video_url,
63
71
  misc: {
64
- binary: video_data["has_audio"] || false
72
+ binary: video_data["has_audio"] || false,
73
+ video_height: video_data["height"],
74
+ video_width: video_data["width"]
65
75
  }
66
76
  }
67
77
  )
@@ -69,12 +79,14 @@ module RedditToTelegram
69
79
 
70
80
  def base_post_format_attrs(data)
71
81
  { id: data["name"],
72
- text: data["title"] }
82
+ text: CGI.unescapeHTML(data["title"]) }
73
83
  end
74
84
 
75
85
  def prepare_gallery_links(data)
76
- data["media_metadata"].map do |image|
77
- image[1]["p"][0]["u"].split("?").first.gsub("preview", "i")
86
+ data["gallery_data"]["items"].map do |image|
87
+ data["media_metadata"].find do |key, _|
88
+ key == image["media_id"]
89
+ end[1]["s"]["u"].split("?").first.gsub("preview", "i")
78
90
  end
79
91
  end
80
92
  end
@@ -15,7 +15,13 @@ module RedditToTelegram
15
15
  when :text
16
16
  { chat_id: "@#{chat_id}", text: prepare_text(post, chat_id) }
17
17
  when :video
18
- { chat_id: "@#{chat_id}", video: prepare_video(post), caption: prepare_text(post, chat_id) }
18
+ {
19
+ chat_id: "@#{chat_id}",
20
+ video: prepare_video(post),
21
+ height: post[:misc][:video_height],
22
+ width: post[:misc][:video_width],
23
+ caption: prepare_text(post, chat_id)
24
+ }
19
25
  end
20
26
  end
21
27
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RedditToTelegram
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.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.3.0
4
+ version: 0.4.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-01-29 00:00:00.000000000 Z
11
+ date: 2024-01-30 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
  - README.md
67
67
  - lib/reddit-to-telegram.rb
68
68
  - lib/reddit_to_telegram/errors.rb
69
+ - lib/reddit_to_telegram/post.rb
69
70
  - lib/reddit_to_telegram/reddit/auth.rb
70
71
  - lib/reddit_to_telegram/reddit/fetch.rb
71
72
  - lib/reddit_to_telegram/reddit/output.rb