redd 0.8.8 → 0.9.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/CONTRIBUTING.md +63 -0
  4. data/Guardfile +7 -0
  5. data/README.md +6 -5
  6. data/Rakefile +1 -1
  7. data/TODO.md +423 -0
  8. data/bin/console +91 -77
  9. data/bin/guard +2 -0
  10. data/lib/redd.rb +7 -5
  11. data/lib/redd/api_client.rb +2 -3
  12. data/lib/redd/auth_strategies/auth_strategy.rb +7 -2
  13. data/lib/redd/auth_strategies/script.rb +7 -0
  14. data/lib/redd/auth_strategies/userless.rb +7 -0
  15. data/lib/redd/auth_strategies/web.rb +6 -1
  16. data/lib/redd/client.rb +0 -3
  17. data/lib/redd/errors.rb +56 -0
  18. data/lib/redd/middleware.rb +10 -8
  19. data/lib/redd/models/access.rb +30 -18
  20. data/lib/redd/models/comment.rb +185 -27
  21. data/lib/redd/models/front_page.rb +16 -36
  22. data/lib/redd/models/gildable.rb +1 -1
  23. data/lib/redd/models/inboxable.rb +13 -3
  24. data/lib/redd/models/listing.rb +27 -6
  25. data/lib/redd/models/live_thread.rb +76 -23
  26. data/lib/redd/models/live_update.rb +46 -0
  27. data/lib/redd/models/messageable.rb +1 -1
  28. data/lib/redd/models/mod_action.rb +59 -0
  29. data/lib/redd/models/model.rb +23 -0
  30. data/lib/redd/models/moderatable.rb +6 -6
  31. data/lib/redd/models/modmail.rb +61 -0
  32. data/lib/redd/models/modmail_conversation.rb +154 -0
  33. data/lib/redd/models/modmail_message.rb +35 -0
  34. data/lib/redd/models/more_comments.rb +29 -5
  35. data/lib/redd/models/multireddit.rb +63 -20
  36. data/lib/redd/models/paginated_listing.rb +113 -0
  37. data/lib/redd/models/postable.rb +11 -13
  38. data/lib/redd/models/private_message.rb +78 -11
  39. data/lib/redd/models/replyable.rb +2 -2
  40. data/lib/redd/models/reportable.rb +14 -0
  41. data/lib/redd/models/searchable.rb +2 -2
  42. data/lib/redd/models/self.rb +17 -0
  43. data/lib/redd/models/session.rb +75 -31
  44. data/lib/redd/models/submission.rb +309 -56
  45. data/lib/redd/models/subreddit.rb +330 -103
  46. data/lib/redd/models/trophy.rb +34 -0
  47. data/lib/redd/models/user.rb +185 -46
  48. data/lib/redd/models/wiki_page.rb +37 -16
  49. data/lib/redd/utilities/error_handler.rb +13 -13
  50. data/lib/redd/utilities/unmarshaller.rb +7 -5
  51. data/lib/redd/version.rb +1 -1
  52. data/redd.gemspec +18 -15
  53. metadata +82 -16
  54. data/lib/redd/error.rb +0 -53
  55. data/lib/redd/models/basic_model.rb +0 -80
  56. data/lib/redd/models/lazy_model.rb +0 -75
  57. data/lib/redd/models/mod_mail.rb +0 -142
  58. data/lib/redd/utilities/stream.rb +0 -61
@@ -1,142 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'basic_model'
4
- require_relative 'subreddit'
5
-
6
- module Redd
7
- module Models
8
- # A container for the new modmail.
9
- # XXX: Instead of making ModMail a dumb container, could it be a lazy wrapper for #unread_count?
10
- class ModMail < BasicModel
11
- # Represents a conversation in the new modmail.
12
- # TODO: add modmail-specific user type
13
- class Conversation < LazyModel
14
- # Get a Conversation from its id.
15
- # @param id [String] the base36 id (e.g. abc123)
16
- # @return [Conversation]
17
- def self.from_id(client, id)
18
- new(client, id: id)
19
- end
20
-
21
- # Add a reply to the ongoing conversation.
22
- def reply(body, hidden: false, internal: false)
23
- # TODO: merge response into the conversation
24
- @client.post(
25
- "/api/mod/conversations/#{get_attribute(:id)}",
26
- body: body, isAuthorHidden: hidden, isInternal: internal
27
- ).body
28
- end
29
-
30
- # Mark this conversation as read.
31
- def mark_as_read
32
- @client.post('/api/mod/conversations/read', conversationIds: [get_attribute(:id)])
33
- end
34
-
35
- # Mark this conversation as unread.
36
- def mark_as_unread
37
- @client.post('/api/mod/conversations/unread', conversationIds: [get_attribute(:id)])
38
- end
39
-
40
- # Mark this conversation as archived.
41
- def archive
42
- perform_action(:post, 'archive')
43
- end
44
-
45
- # Removed this conversation from archived.
46
- def unarchive
47
- perform_action(:post, 'unarchive')
48
- end
49
-
50
- # Highlight this conversation.
51
- def highlight
52
- perform_action(:post, 'highlight')
53
- end
54
-
55
- # Remove the highlight on this conversation.
56
- def unhighlight
57
- perform_action(:delete, 'highlight')
58
- end
59
-
60
- # Mute this conversation.
61
- def mute
62
- perform_action(:post, 'mute')
63
- end
64
-
65
- # Unmute this conversation.
66
- def unmute
67
- perform_action(:post, 'unmute')
68
- end
69
-
70
- private
71
-
72
- def default_loader
73
- response = @client.get("/api/mod/conversations/#{@attributes[:id]}").body
74
- response[:conversation].merge(
75
- messages: response[:messages].values.map { |m| Message.new(@client, m) },
76
- user: response[:user],
77
- mod_actions: response[:modActions]
78
- )
79
- end
80
-
81
- # Perform an action on a conversation.
82
- # @param method [:post, :delete] the method to use
83
- # @param action [String] the name of the action
84
- def perform_action(method, action)
85
- @client.send(method, "/api/mod/conversations/#{id}/#{action}")
86
- end
87
- end
88
-
89
- # A conversation message.
90
- class Message < BasicModel; end
91
-
92
- # @return [#highlighted, #notifications, #archived, #new, #inprogress, #mod] the number of
93
- # unread messages in each category
94
- def unread_count
95
- BasicModel.new(nil, @client.get('/api/mod/conversations/unread/count').body)
96
- end
97
-
98
- # @return [Array<Subreddit>] moderated subreddits that are enrolled in the new modmail
99
- def enrolled
100
- @client.get('/api/mod/conversations/subreddits').body[:subreddits].map do |_, s|
101
- Subreddit.new(@client, s.merge(last_updated: s.delete(:lastUpdated)))
102
- end
103
- end
104
-
105
- # Get the conversations
106
- # @param subreddits [Subreddit, Array<Subreddit>] the subreddits to limit to
107
- # @param params [Hash] additional request parameters
108
- # @option params [String] :after base36 modmail conversation id
109
- # @option params [Integer] :limit an integer (default: 25)
110
- # @option params [:recent, :mod, :user, :unread] :sort the sort order
111
- # @option params [:new, :inprogress, :mod, :notifications, :archived, :highlighted, :all]
112
- # :state the state to limit the conversations by
113
- def conversations(subreddits: nil, **params)
114
- params[:entity] = Array(subreddits).map(&:display_name).join(',') if subreddits
115
- @client.get('/api/mod/conversations', **params).body[:conversations].map do |_, conv|
116
- Conversation.new(@client, conv)
117
- end
118
- end
119
-
120
- # Create a new conversation.
121
- # @param from [Subreddit] the subreddit to send the conversation from
122
- # @param to [User] the person to send the message to
123
- # @param subject [String] the message subject
124
- # @param body [String] the message body
125
- # @return [Conversation] the created conversation
126
- def create(from:, to:, subject:, body:, hidden: false)
127
- Conversation.new(@client, @client.post(
128
- '/api/mod/conversations',
129
- srName: from.display_name, to: to.name,
130
- subject: subject, body: body, isAuthorHidden: hidden
131
- ).body[:conversation])
132
- end
133
-
134
- # Get a conversation from its base36 id.
135
- # @param id [String] the conversation's id
136
- # @return [Conversation]
137
- def get(id)
138
- Conversation.from_id(@client, id)
139
- end
140
- end
141
- end
142
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Redd
4
- module Utilities
5
- # A forward-expading listing of items that can be enumerated forever.
6
- class Stream
7
- # A simple fixed-size ring buffer.
8
- class RingBuffer
9
- def initialize(size)
10
- @size = size
11
- @backing_array = Array.new(size)
12
- @pointer = 0
13
- end
14
-
15
- def include?(el)
16
- @backing_array.include?(el)
17
- end
18
-
19
- def add(el)
20
- @backing_array[@pointer] = el
21
- @pointer = (@pointer + 1) % @size
22
- end
23
- end
24
-
25
- # Create a streamer.
26
- # @yield [Models::Listing]
27
- # @yieldparam previous [Models::Listing] the result of the last request
28
- # @yieldreturn [Models::Listing] the models after the latest one
29
- def initialize(&block)
30
- @loader = block
31
- @buffer = RingBuffer.new(100)
32
- @previous = nil
33
- end
34
-
35
- # Make another request to reddit, yielding new elements.
36
- # @yield [element] an element from the listings returned by the loader
37
- def next_request
38
- # Get the elements from the loader before the `latest` element
39
- listing = @loader.call(@previous)
40
- # If there's nothing new to process, request again.
41
- return if listing.empty?
42
- # Iterate over the new elements, oldest to newest.
43
- listing.reverse_each do |el|
44
- next if @buffer.include?(el.name)
45
- yield el
46
- @buffer.add(el.name)
47
- end
48
- # Store the last successful listing
49
- @previous = listing
50
- end
51
-
52
- # Loop forever, yielding the elements from the loader
53
- # @yield [element] an element from the listings returned by the loader
54
- def stream
55
- loop do
56
- next_request { |el| yield el }
57
- end
58
- end
59
- end
60
- end
61
- end