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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -1
- data/CONTRIBUTING.md +63 -0
- data/Guardfile +7 -0
- data/README.md +6 -5
- data/Rakefile +1 -1
- data/TODO.md +423 -0
- data/bin/console +91 -77
- data/bin/guard +2 -0
- data/lib/redd.rb +7 -5
- data/lib/redd/api_client.rb +2 -3
- data/lib/redd/auth_strategies/auth_strategy.rb +7 -2
- data/lib/redd/auth_strategies/script.rb +7 -0
- data/lib/redd/auth_strategies/userless.rb +7 -0
- data/lib/redd/auth_strategies/web.rb +6 -1
- data/lib/redd/client.rb +0 -3
- data/lib/redd/errors.rb +56 -0
- data/lib/redd/middleware.rb +10 -8
- data/lib/redd/models/access.rb +30 -18
- data/lib/redd/models/comment.rb +185 -27
- data/lib/redd/models/front_page.rb +16 -36
- data/lib/redd/models/gildable.rb +1 -1
- data/lib/redd/models/inboxable.rb +13 -3
- data/lib/redd/models/listing.rb +27 -6
- data/lib/redd/models/live_thread.rb +76 -23
- data/lib/redd/models/live_update.rb +46 -0
- data/lib/redd/models/messageable.rb +1 -1
- data/lib/redd/models/mod_action.rb +59 -0
- data/lib/redd/models/model.rb +23 -0
- data/lib/redd/models/moderatable.rb +6 -6
- data/lib/redd/models/modmail.rb +61 -0
- data/lib/redd/models/modmail_conversation.rb +154 -0
- data/lib/redd/models/modmail_message.rb +35 -0
- data/lib/redd/models/more_comments.rb +29 -5
- data/lib/redd/models/multireddit.rb +63 -20
- data/lib/redd/models/paginated_listing.rb +113 -0
- data/lib/redd/models/postable.rb +11 -13
- data/lib/redd/models/private_message.rb +78 -11
- data/lib/redd/models/replyable.rb +2 -2
- data/lib/redd/models/reportable.rb +14 -0
- data/lib/redd/models/searchable.rb +2 -2
- data/lib/redd/models/self.rb +17 -0
- data/lib/redd/models/session.rb +75 -31
- data/lib/redd/models/submission.rb +309 -56
- data/lib/redd/models/subreddit.rb +330 -103
- data/lib/redd/models/trophy.rb +34 -0
- data/lib/redd/models/user.rb +185 -46
- data/lib/redd/models/wiki_page.rb +37 -16
- data/lib/redd/utilities/error_handler.rb +13 -13
- data/lib/redd/utilities/unmarshaller.rb +7 -5
- data/lib/redd/version.rb +1 -1
- data/redd.gemspec +18 -15
- metadata +82 -16
- data/lib/redd/error.rb +0 -53
- data/lib/redd/models/basic_model.rb +0 -80
- data/lib/redd/models/lazy_model.rb +0 -75
- data/lib/redd/models/mod_mail.rb +0 -142
- data/lib/redd/utilities/stream.rb +0 -61
data/lib/redd/models/mod_mail.rb
DELETED
@@ -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
|