mastodon-api 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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