mastodon-api 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mastodon.rb +2 -0
  3. data/lib/mastodon/access_token.rb +21 -0
  4. data/lib/mastodon/account.rb +44 -2
  5. data/lib/mastodon/app.rb +8 -1
  6. data/lib/mastodon/card.rb +41 -0
  7. data/lib/mastodon/client.rb +8 -1
  8. data/lib/mastodon/conversation.rb +25 -0
  9. data/lib/mastodon/emoji.rb +21 -0
  10. data/lib/mastodon/entities/app.rb +12 -0
  11. data/lib/mastodon/entities/hashtag.rb +12 -0
  12. data/lib/mastodon/entities/media.rb +13 -1
  13. data/lib/mastodon/entities/mention.rb +1 -1
  14. data/lib/mastodon/field.rb +18 -0
  15. data/lib/mastodon/filter.rb +29 -0
  16. data/lib/mastodon/hashtag.rb +19 -0
  17. data/lib/mastodon/instance.rb +33 -0
  18. data/lib/mastodon/list.rb +15 -0
  19. data/lib/mastodon/media.rb +16 -2
  20. data/lib/mastodon/notification.rb +30 -0
  21. data/lib/mastodon/relationship.rb +23 -2
  22. data/lib/mastodon/rest/accounts.rb +52 -9
  23. data/lib/mastodon/rest/api.rb +24 -0
  24. data/lib/mastodon/rest/apps.rb +7 -0
  25. data/lib/mastodon/rest/conversations.rb +34 -0
  26. data/lib/mastodon/rest/custom_emojis.rb +16 -0
  27. data/lib/mastodon/rest/domain_blocks.rb +32 -0
  28. data/lib/mastodon/rest/endorsements.rb +36 -0
  29. data/lib/mastodon/rest/filters.rb +61 -0
  30. data/lib/mastodon/rest/instances.rb +28 -0
  31. data/lib/mastodon/rest/lists.rb +77 -0
  32. data/lib/mastodon/rest/media.rb +17 -3
  33. data/lib/mastodon/rest/notifications.rb +34 -0
  34. data/lib/mastodon/rest/relationships.rb +68 -1
  35. data/lib/mastodon/rest/reports.rb +20 -0
  36. data/lib/mastodon/rest/request.rb +7 -3
  37. data/lib/mastodon/rest/scheduled_statuses.rb +43 -0
  38. data/lib/mastodon/rest/search.rb +20 -0
  39. data/lib/mastodon/rest/statuses.rb +57 -5
  40. data/lib/mastodon/rest/suggestions.rb +13 -2
  41. data/lib/mastodon/rest/timelines.rb +19 -0
  42. data/lib/mastodon/rest/utils.rb +3 -3
  43. data/lib/mastodon/results.rb +18 -0
  44. data/lib/mastodon/scheduled_status.rb +25 -0
  45. data/lib/mastodon/status.rb +49 -4
  46. data/lib/mastodon/streaming/client.rb +96 -0
  47. data/lib/mastodon/streaming/connection.rb +44 -0
  48. data/lib/mastodon/streaming/events/filters_change.rb +7 -0
  49. data/lib/mastodon/streaming/events/status_delete.rb +16 -0
  50. data/lib/mastodon/streaming/message_parser.rb +23 -0
  51. data/lib/mastodon/streaming/response.rb +42 -0
  52. data/lib/mastodon/version.rb +2 -2
  53. data/mastodon.gemspec +5 -3
  54. metadata +68 -9
@@ -0,0 +1,18 @@
1
+ require 'mastodon/account'
2
+ require 'mastodon/status'
3
+ require 'mastodon/hashtag'
4
+
5
+ module Mastodon
6
+ class Results < Mastodon::Base
7
+ # @!attribute [r] accounts
8
+ # @return [Mastodon::Collection<Mastodon::Account>]
9
+ # @!attribute [r] statuses
10
+ # @return [Mastodon::Collection<Mastodon::Status>]
11
+ # @!attribute [r] hashtags
12
+ # @return [Mastodon::Collection<Mastodon::Hashtag>]
13
+
14
+ collection_attr_reader :accounts, Mastodon::Account
15
+ collection_attr_reader :statuses, Mastodon::Status
16
+ collection_attr_reader :hashtags, Mastodon::Hashtag
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ require 'mastodon/entities/media'
2
+
3
+ module Mastodon
4
+ class ScheduledStatus < Mastodon::Base
5
+ # @!attribute [r] id
6
+ # @return [String]
7
+ # @!attribute [r] scheduled_at
8
+ # @return [String]
9
+ # @!attribute [r] params
10
+ # @return [Hash]
11
+ # @!attribute [r] media_attachments
12
+ # @return [Mastodon::Collection<Mastodon::Entities::Media>]
13
+
14
+ normal_attr_reader :id,
15
+ :scheduled_at,
16
+ :params
17
+
18
+ collection_attr_reader :media_attachments, Mastodon::Entities::Media
19
+
20
+ def initialize(attributes = {})
21
+ attributes.fetch('id')
22
+ super
23
+ end
24
+ end
25
+ end
@@ -1,13 +1,21 @@
1
1
  require 'mastodon/account'
2
2
  require 'mastodon/entities/media'
3
3
  require 'mastodon/entities/mention'
4
+ require 'mastodon/entities/app'
5
+ require 'mastodon/entities/hashtag'
6
+ require 'mastodon/emoji'
7
+ require 'mastodon/card'
4
8
 
5
9
  module Mastodon
6
10
  class Status < Mastodon::Base
7
11
  # @!attribute [r] id
8
- # @return [Integer]
12
+ # @return [String]
9
13
  # @!attribute [r] in_reply_to_id
10
- # @return [Integer]
14
+ # @return [String]
15
+ # @!attribute [r] in_reply_to_account_id
16
+ # @return [String]
17
+ # @!attribute [r] spoiler_text
18
+ # @return [String]
11
19
  # @!attribute [r] content
12
20
  # @return [String]
13
21
  # @!attribute [r] url
@@ -20,28 +28,65 @@ module Mastodon
20
28
  # @return [Integer]
21
29
  # @!attribute [r] favourites_count
22
30
  # @return [Integer]
31
+ # @!attribute [r] visibility
32
+ # @return [String]
33
+ # @!attribute [r] language
34
+ # @return [String]
23
35
  # @!attribute [r] account
24
36
  # @return [Mastodon::Account]
25
37
  # @!attribute [r] reblog
26
38
  # @return [Mastodon::Status]
39
+ # @!attribute [r] application
40
+ # @return [Mastodon::Entities::App]
27
41
  # @!attribute [r] favourited?
28
42
  # @return [Boolean]
29
43
  # @!attribute [r] reblogged?
30
44
  # @return [Boolean]
45
+ # @!attribute [r] sensitive?
46
+ # @return [Boolean]
47
+ # @!attribute [r] muted?
48
+ # @return [Boolean]
49
+ # @!attribute [r] pinned?
50
+ # @return [Boolean]
31
51
  # @!attribute [r] media_attachments
32
52
  # @return [Mastodon::Collection<Mastodon::Entities::Media>]
33
53
  # @!attribute [r] mentions
34
54
  # @return [Mastodon::Collection<Mastodon::Entities::Mention>]
55
+ # @!attribute [r] tags
56
+ # @return [Mastodon::Collection<Mastodon::Entities::Hashtag>]
57
+ # @!attribute [r] emojis
58
+ # @return [Mastodon::Collection<Mastodon::Emoji>]
59
+ # @!attribute [r] card
60
+ # @return [Mastodon::Card]
35
61
 
36
- normal_attr_reader :id, :content, :in_reply_to_id, :url, :uri, :created_at, :reblogs_count, :favourites_count
62
+ normal_attr_reader :id,
63
+ :content,
64
+ :in_reply_to_id,
65
+ :in_reply_to_account_id,
66
+ :url,
67
+ :uri,
68
+ :created_at,
69
+ :reblogs_count,
70
+ :favourites_count,
71
+ :visibility,
72
+ :spoiler_text,
73
+ :language
37
74
 
38
- predicate_attr_reader :favourited, :reblogged
75
+ predicate_attr_reader :favourited,
76
+ :reblogged,
77
+ :sensitive,
78
+ :muted,
79
+ :pinned
39
80
 
40
81
  object_attr_reader :account, Mastodon::Account
41
82
  object_attr_reader :reblog, Mastodon::Status
83
+ object_attr_reader :application, Mastodon::Entities::App
84
+ object_attr_reader :card, Mastodon::Card
42
85
 
43
86
  collection_attr_reader :media_attachments, Mastodon::Entities::Media
44
87
  collection_attr_reader :mentions, Mastodon::Entities::Mention
88
+ collection_attr_reader :emojis, Mastodon::Emoji
89
+ collection_attr_reader :tags, Mastodon::Entities::Hashtag
45
90
 
46
91
  def initialize(attributes = {})
47
92
  attributes.fetch('id')
@@ -0,0 +1,96 @@
1
+ require 'http/request'
2
+ require 'mastodon/client'
3
+ require 'mastodon/streaming/connection'
4
+ require 'mastodon/streaming/message_parser'
5
+ require 'mastodon/streaming/response'
6
+
7
+ module Mastodon
8
+ module Streaming
9
+ class Client < Mastodon::Client
10
+ attr_writer :connection
11
+
12
+ # Initializes a new Client object
13
+ #
14
+ # @param options [Hash] A customizable set of options.
15
+ # @option options [String] :tcp_socket_class A class that Connection will use to create a new TCP socket.
16
+ # @option options [String] :ssl_socket_class A class that Connection will use to create a new SSL socket.
17
+ # @return [Mastodon::Streaming::Client]
18
+ def initialize(options = {})
19
+ super
20
+ options[:using_ssl] ||= base_url =~ /^https/
21
+ @connection = Streaming::Connection.new(options)
22
+ end
23
+
24
+ # Streams messages for a single user
25
+ #
26
+ # @yield [Mastodon::Status, Mastodon::Notification, Mastodon::Streaming::Events::StatusDelete, Mastodon::Streaming::Events::FiltersChange] A stream of Mastodon objects.
27
+ def user(options = {}, &block)
28
+ stream('user', options, &block)
29
+ end
30
+
31
+ # Returns statuses that contain the specified hashtag
32
+ #
33
+ # @yield [Mastodon::Status, Mastodon::Streaming::Events::StatusDelete] A stream of Mastodon objects.
34
+ def hashtag(tag, options = {}, &block)
35
+ stream('hashtag', { tag: tag }.merge(options), &block)
36
+ end
37
+
38
+ # Returns all public statuses
39
+ #
40
+ # @yield [Mastodon::Status, Mastodon::Streaming::Events::StatusDelete] A stream of Mastodon objects.
41
+ def public(options = {}, &block)
42
+ stream('public', options, &block)
43
+ end
44
+
45
+ # Returns conversations for a single user
46
+ #
47
+ # @yield [Mastodon::Conversation] A stream of Mastodon objects.
48
+ def direct(options = {}, &block)
49
+ stream('direct', options, &block)
50
+ end
51
+
52
+ #
53
+ # Calls an arbitrary streaming endpoint and returns the results
54
+ # @yield [Mastodon::Status, Mastodon::Notification, Mastodon::Streaming::DeletedStatus] A stream of Mastodon objects.
55
+ def stream(path, options = {}, &block)
56
+ request(:get, "/api/v1/streaming/#{path}", options, &block)
57
+ end
58
+
59
+ # Set a Proc to be run when connection established.
60
+ def before_request(&block)
61
+ if block_given?
62
+ @before_request = block
63
+ self
64
+ elsif instance_variable_defined?(:@before_request)
65
+ @before_request
66
+ else
67
+ proc {}
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def request(method, path, params)
74
+ before_request.call
75
+
76
+ uri = Addressable::URI.parse(base_url + path)
77
+ headers = Mastodon::Headers.new(self).request_headers
78
+ request = HTTP::Request.new(verb: method, uri: uri + '?' + to_url_params(params), headers: headers)
79
+
80
+ response = Streaming::Response.new do |type, data|
81
+ if item = Streaming::MessageParser.parse(type, data) # rubocop:disable AssignmentInCondition
82
+ yield(item)
83
+ end
84
+ end
85
+
86
+ @connection.stream(request, response)
87
+ end
88
+
89
+ def to_url_params(params)
90
+ uri = Addressable::URI.new
91
+ uri.query_values = params
92
+ uri.query
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,44 @@
1
+ require 'http/parser'
2
+ require 'openssl'
3
+ require 'resolv'
4
+
5
+ module Mastodon
6
+ module Streaming
7
+ class Connection
8
+ attr_reader :tcp_socket_class, :ssl_socket_class
9
+
10
+ def initialize(options = {})
11
+ @tcp_socket_class = options.fetch(:tcp_socket_class) { TCPSocket }
12
+ @ssl_socket_class = options.fetch(:ssl_socket_class) { OpenSSL::SSL::SSLSocket }
13
+ @using_ssl = options.fetch(:using_ssl) { false }
14
+ end
15
+
16
+ def stream(request, response)
17
+ client = connect(request)
18
+
19
+ request.stream(client)
20
+
21
+ while body = client.readpartial(1024) # rubocop:disable AssignmentInCondition
22
+ response << body
23
+ end
24
+ end
25
+
26
+ def connect(request)
27
+ client = new_tcp_socket(request.socket_host, request.socket_port)
28
+
29
+ return client if !@using_ssl || (!@using_ssl && request.using_proxy?)
30
+
31
+ client_context = OpenSSL::SSL::SSLContext.new
32
+ ssl_client = @ssl_socket_class.new(client, client_context)
33
+
34
+ ssl_client.connect
35
+ end
36
+
37
+ private
38
+
39
+ def new_tcp_socket(host, port)
40
+ @tcp_socket_class.new(Resolv.getaddress(host), port)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,7 @@
1
+ module Mastodon
2
+ module Streaming
3
+ module Events
4
+ class FiltersChange; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ module Mastodon
2
+ module Streaming
3
+ module Events
4
+ class StatusDelete
5
+ # @!attribute [r] id
6
+ # @return [Integer]
7
+
8
+ attr_reader :id
9
+
10
+ def initialize(id)
11
+ @id = id.to_i
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ require 'mastodon/status'
2
+ require 'mastodon/conversation'
3
+ require 'mastodon/streaming/events/filters_change'
4
+ require 'mastodon/streaming/events/status_delete'
5
+
6
+ module Mastodon
7
+ module Streaming
8
+ class MessageParser
9
+ MESSAGE_TYPES = {
10
+ 'update' => Status,
11
+ 'notification' => Notification,
12
+ 'conversation' => Conversation,
13
+ 'delete' => Events::StatusDelete,
14
+ 'filters_changed' => Events::FiltersChange,
15
+ }.freeze
16
+
17
+ def self.parse(type, data)
18
+ klass = MESSAGE_TYPES[type]
19
+ klass.new(data) if klass
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ require 'buftok'
2
+ require 'http'
3
+ require 'json'
4
+ require 'mastodon/error'
5
+
6
+ module Mastodon
7
+ module Streaming
8
+ class Response
9
+ # Initializes a new Response object
10
+ #
11
+ # @return [Mastodon::Streaming::Response]
12
+ def initialize(&block)
13
+ @block = block
14
+ @parser = Http::Parser.new(self)
15
+ @tokenizer = BufferedTokenizer.new("\n\n")
16
+ @match = Regexp.new(/event: ([a-z]+)\ndata: (.+)/m)
17
+ end
18
+
19
+ def <<(data)
20
+ @parser << data
21
+ end
22
+
23
+ # @note this does get called
24
+ def on_headers_complete(_headers)
25
+ error = Mastodon::Error::ERRORS[@parser.status_code]
26
+ raise error if error
27
+ end
28
+
29
+ def on_body(data)
30
+ @tokenizer.extract(data).each do |line|
31
+ has_data = @match.match(line)
32
+ next if has_data.nil?
33
+
34
+ type = has_data[1]
35
+ data = has_data[2]
36
+
37
+ @block.call(type, JSON.parse(data))
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -3,11 +3,11 @@ module Mastodon
3
3
  module_function
4
4
 
5
5
  def major
6
- 1
6
+ 2
7
7
  end
8
8
 
9
9
  def minor
10
- 1
10
+ 0
11
11
  end
12
12
 
13
13
  def patch
@@ -14,8 +14,10 @@ Gem::Specification.new do |spec|
14
14
  spec.require_paths = %w(lib)
15
15
  spec.version = Mastodon::Version
16
16
 
17
- spec.add_dependency 'http', '~> 2.0'
18
- spec.add_dependency 'addressable', '~> 2.4'
17
+ spec.add_dependency 'http', '~> 3.3'
18
+ spec.add_dependency 'oj', '~> 3.7'
19
+ spec.add_dependency 'addressable', '~> 2.6'
20
+ spec.add_dependency 'buftok', '~> 0'
19
21
 
20
- spec.add_development_dependency 'bundler', '~> 1.0'
22
+ spec.add_development_dependency 'bundler', '~> 1.7'
21
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mastodon-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eugen Rochko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-04 00:00:00.000000000 Z
11
+ date: 2019-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -16,42 +16,70 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '3.3'
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: '2.0'
26
+ version: '3.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.7'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: addressable
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '2.4'
47
+ version: '2.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: buftok
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
34
62
  type: :runtime
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: '2.4'
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: bundler
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: '1.0'
75
+ version: '1.7'
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: '1.0'
82
+ version: '1.7'
55
83
  description: A ruby interface to the Mastodon API
56
84
  email: eugen@zeonfederated.com
57
85
  executables: []
@@ -59,29 +87,60 @@ extensions: []
59
87
  extra_rdoc_files: []
60
88
  files:
61
89
  - lib/mastodon.rb
90
+ - lib/mastodon/access_token.rb
62
91
  - lib/mastodon/account.rb
63
92
  - lib/mastodon/app.rb
64
93
  - lib/mastodon/base.rb
94
+ - lib/mastodon/card.rb
65
95
  - lib/mastodon/client.rb
66
96
  - lib/mastodon/collection.rb
97
+ - lib/mastodon/conversation.rb
98
+ - lib/mastodon/emoji.rb
99
+ - lib/mastodon/entities/app.rb
100
+ - lib/mastodon/entities/hashtag.rb
67
101
  - lib/mastodon/entities/media.rb
68
102
  - lib/mastodon/entities/mention.rb
69
103
  - lib/mastodon/error.rb
104
+ - lib/mastodon/field.rb
105
+ - lib/mastodon/filter.rb
106
+ - lib/mastodon/hashtag.rb
70
107
  - lib/mastodon/headers.rb
108
+ - lib/mastodon/instance.rb
109
+ - lib/mastodon/list.rb
71
110
  - lib/mastodon/media.rb
111
+ - lib/mastodon/notification.rb
72
112
  - lib/mastodon/relationship.rb
73
113
  - lib/mastodon/rest/accounts.rb
74
114
  - lib/mastodon/rest/api.rb
75
115
  - lib/mastodon/rest/apps.rb
76
116
  - lib/mastodon/rest/client.rb
117
+ - lib/mastodon/rest/conversations.rb
118
+ - lib/mastodon/rest/custom_emojis.rb
119
+ - lib/mastodon/rest/domain_blocks.rb
120
+ - lib/mastodon/rest/endorsements.rb
121
+ - lib/mastodon/rest/filters.rb
122
+ - lib/mastodon/rest/instances.rb
123
+ - lib/mastodon/rest/lists.rb
77
124
  - lib/mastodon/rest/media.rb
125
+ - lib/mastodon/rest/notifications.rb
78
126
  - lib/mastodon/rest/relationships.rb
127
+ - lib/mastodon/rest/reports.rb
79
128
  - lib/mastodon/rest/request.rb
129
+ - lib/mastodon/rest/scheduled_statuses.rb
130
+ - lib/mastodon/rest/search.rb
80
131
  - lib/mastodon/rest/statuses.rb
81
132
  - lib/mastodon/rest/suggestions.rb
82
133
  - lib/mastodon/rest/timelines.rb
83
134
  - lib/mastodon/rest/utils.rb
135
+ - lib/mastodon/results.rb
136
+ - lib/mastodon/scheduled_status.rb
84
137
  - lib/mastodon/status.rb
138
+ - lib/mastodon/streaming/client.rb
139
+ - lib/mastodon/streaming/connection.rb
140
+ - lib/mastodon/streaming/events/filters_change.rb
141
+ - lib/mastodon/streaming/events/status_delete.rb
142
+ - lib/mastodon/streaming/message_parser.rb
143
+ - lib/mastodon/streaming/response.rb
85
144
  - lib/mastodon/version.rb
86
145
  - mastodon.gemspec
87
146
  homepage: https://github.com/tootsuite/mastodon-api
@@ -104,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
163
  version: '0'
105
164
  requirements: []
106
165
  rubyforge_project:
107
- rubygems_version: 2.4.5.1
166
+ rubygems_version: 2.6.13
108
167
  signing_key:
109
168
  specification_version: 4
110
169
  summary: A ruby interface to the Mastodon API