moostodon 0.1.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.
- checksums.yaml +7 -0
- data/lib/mastodon.rb +8 -0
- data/lib/mastodon/account.rb +62 -0
- data/lib/mastodon/app.rb +19 -0
- data/lib/mastodon/base.rb +52 -0
- data/lib/mastodon/card.rb +43 -0
- data/lib/mastodon/client.rb +32 -0
- data/lib/mastodon/collection.rb +30 -0
- data/lib/mastodon/emoji.rb +14 -0
- data/lib/mastodon/entities/app.rb +15 -0
- data/lib/mastodon/entities/hashtag.rb +15 -0
- data/lib/mastodon/entities/media.rb +31 -0
- data/lib/mastodon/entities/mention.rb +17 -0
- data/lib/mastodon/error.rb +37 -0
- data/lib/mastodon/headers.rb +20 -0
- data/lib/mastodon/instance.rb +25 -0
- data/lib/mastodon/list.rb +17 -0
- data/lib/mastodon/media.rb +37 -0
- data/lib/mastodon/notification.rb +32 -0
- data/lib/mastodon/relationship.rb +38 -0
- data/lib/mastodon/rest/accounts.rb +71 -0
- data/lib/mastodon/rest/api.rb +29 -0
- data/lib/mastodon/rest/apps.rb +28 -0
- data/lib/mastodon/rest/client.rb +13 -0
- data/lib/mastodon/rest/instances.rb +19 -0
- data/lib/mastodon/rest/media.rb +42 -0
- data/lib/mastodon/rest/notifications.rb +19 -0
- data/lib/mastodon/rest/relationships.rb +77 -0
- data/lib/mastodon/rest/request.rb +54 -0
- data/lib/mastodon/rest/search.rb +28 -0
- data/lib/mastodon/rest/statuses.rb +130 -0
- data/lib/mastodon/rest/suggestions.rb +19 -0
- data/lib/mastodon/rest/timelines.rb +47 -0
- data/lib/mastodon/rest/utils.rb +42 -0
- data/lib/mastodon/results.rb +19 -0
- data/lib/mastodon/status.rb +94 -0
- data/lib/mastodon/streaming/client.rb +103 -0
- data/lib/mastodon/streaming/connection.rb +47 -0
- data/lib/mastodon/streaming/deleted_status.rb +17 -0
- data/lib/mastodon/streaming/message_parser.rb +21 -0
- data/lib/mastodon/streaming/response.rb +45 -0
- data/lib/mastodon/version.rb +32 -0
- data/moostodon.gemspec +25 -0
- metadata +156 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mastodon
|
4
|
+
class List < Mastodon::Base
|
5
|
+
# @!attribute [r] id
|
6
|
+
# @return [String]
|
7
|
+
# @!attribute [r] title
|
8
|
+
# @return [String]
|
9
|
+
|
10
|
+
normal_attr_reader :id, :title
|
11
|
+
|
12
|
+
def initialize(attributes = {})
|
13
|
+
attributes.fetch('id')
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mastodon
|
4
|
+
class Media < Mastodon::Base
|
5
|
+
# @!attribute [r] id
|
6
|
+
# @return [String]
|
7
|
+
# @!attribute [r] type
|
8
|
+
# @return [String] Image or video
|
9
|
+
# @!attribute [r] url
|
10
|
+
# @return [String] Full file URL
|
11
|
+
# @!attribute [r] remote_url
|
12
|
+
# @return [String]
|
13
|
+
# @!attribute [r] preview_url
|
14
|
+
# @return [String] URL to preview image
|
15
|
+
# @!attribute [r] text_url
|
16
|
+
# @return [String] URL that can be put into status body and will
|
17
|
+
# redirect to the status/media
|
18
|
+
# @!attribute [r] meta
|
19
|
+
# @return [Hash]
|
20
|
+
# @!attribute [r] description
|
21
|
+
# @return [String]
|
22
|
+
|
23
|
+
normal_attr_reader :id,
|
24
|
+
:type,
|
25
|
+
:url,
|
26
|
+
:remote_url,
|
27
|
+
:preview_url,
|
28
|
+
:text_url,
|
29
|
+
:meta,
|
30
|
+
:description
|
31
|
+
|
32
|
+
def initialize(attributes = {})
|
33
|
+
attributes.fetch('id')
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mastodon
|
4
|
+
class Notification < Mastodon::Base
|
5
|
+
# @!attribute [r] id
|
6
|
+
# @return [String]
|
7
|
+
# @!attribute [r] type
|
8
|
+
# @return [String]
|
9
|
+
# @!attribute [r] created_at
|
10
|
+
# @return [String]
|
11
|
+
# @!attribute [r] account
|
12
|
+
# @return [Mastodon::Account]
|
13
|
+
# @!attribute [r] status
|
14
|
+
# @return [Mastodon::Status]
|
15
|
+
|
16
|
+
normal_attr_reader :id, :type, :created_at
|
17
|
+
|
18
|
+
object_attr_reader :account, Mastodon::Account
|
19
|
+
object_attr_reader :status, Mastodon::Status
|
20
|
+
|
21
|
+
def initialize(attributes = {})
|
22
|
+
attributes.fetch('id')
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
# Does this notification include a status?
|
27
|
+
# @return [Boolean] true if a status is included, false otherwise
|
28
|
+
def status?
|
29
|
+
attributes.key?('status')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mastodon
|
4
|
+
# Relationships. Purpose still to be found out (by Maxine Michalski)
|
5
|
+
class Relationship < Mastodon::Base
|
6
|
+
# @!attribute [r] id
|
7
|
+
# @return [String] Account ID
|
8
|
+
# @!attribute [r] following?
|
9
|
+
# @return [Boolean]
|
10
|
+
# @!attribute [r] followed_by?
|
11
|
+
# @return [Boolean]
|
12
|
+
# @!attribute [r] blocking?
|
13
|
+
# @return [Boolean]
|
14
|
+
# @!attribute [r] muting?
|
15
|
+
# @return [Boolean]
|
16
|
+
# @!attribute [r] muting_notifications?
|
17
|
+
# @return [Boolean]
|
18
|
+
# @!attribute [r] requested?
|
19
|
+
# @return [Boolean]
|
20
|
+
# @!attribute [r] domain_blocking?
|
21
|
+
# @return [Boolean]
|
22
|
+
|
23
|
+
normal_attr_reader :id
|
24
|
+
|
25
|
+
predicate_attr_reader :following,
|
26
|
+
:followed_by,
|
27
|
+
:blocking,
|
28
|
+
:muting,
|
29
|
+
:muting_notifications,
|
30
|
+
:requested,
|
31
|
+
:domain_blocking
|
32
|
+
|
33
|
+
def initialize(attributes = {})
|
34
|
+
attributes.fetch('id')
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mastodon/rest/utils'
|
4
|
+
require 'mastodon/account'
|
5
|
+
|
6
|
+
module Mastodon
|
7
|
+
module REST
|
8
|
+
module Accounts
|
9
|
+
include Mastodon::REST::Utils
|
10
|
+
|
11
|
+
# Retrieve account of authenticated user
|
12
|
+
# @return [Mastodon::Account]
|
13
|
+
def verify_credentials
|
14
|
+
perform_request_with_object(:get, '/api/v1/accounts/verify_credentials',
|
15
|
+
{}, Mastodon::Account)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Update authenticated account attributes
|
19
|
+
# @param options [Hash]
|
20
|
+
# @option options display_name [String] The name to display in the
|
21
|
+
# user's profile
|
22
|
+
# @option options note [String] A new biography for the user
|
23
|
+
# @option options avatar [String] A base64 encoded image to display as
|
24
|
+
# the user's avatar
|
25
|
+
# @option options header [String] A base64 encoded image to display as
|
26
|
+
# the user's header image
|
27
|
+
# @return [Mastodon::Account]
|
28
|
+
def update_credentials(opts = {})
|
29
|
+
perform_request_with_object(:patch,
|
30
|
+
'/api/v1/accounts/update_credentials',
|
31
|
+
opts, Mastodon::Account)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Retrieve account
|
35
|
+
# @param id [Integer]
|
36
|
+
# @return [Mastodon::Account]
|
37
|
+
def account(id)
|
38
|
+
perform_request_with_object(:get, "/api/v1/accounts/#{id}", {},
|
39
|
+
Mastodon::Account)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get a list of followers
|
43
|
+
# @param id [Integer]
|
44
|
+
# @return [Mastodon::Collection<Mastodon::Account>]
|
45
|
+
def followers(id)
|
46
|
+
perform_request_with_collection(:get,
|
47
|
+
"/api/v1/accounts/#{id}/followers",
|
48
|
+
{}, Mastodon::Account)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get a list of followed accounts
|
52
|
+
# @param id [Integer]
|
53
|
+
# @return [Mastodon::Collection<Mastodon::Account>]
|
54
|
+
def following(id)
|
55
|
+
perform_request_with_collection(:get,
|
56
|
+
"/api/v1/accounts/#{id}/following",
|
57
|
+
{}, Mastodon::Account)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Follow a remote user
|
61
|
+
# @param uri [String] The URI of the remote user, in the format of
|
62
|
+
# username@domain
|
63
|
+
# @return [Mastodon::Account]
|
64
|
+
def follow_by_uri(uri)
|
65
|
+
perform_request_with_object(:post,
|
66
|
+
'/api/v1/follows', { uri: uri },
|
67
|
+
Mastodon::Account)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mastodon/rest/statuses'
|
4
|
+
require 'mastodon/rest/accounts'
|
5
|
+
require 'mastodon/rest/timelines'
|
6
|
+
require 'mastodon/rest/notifications'
|
7
|
+
require 'mastodon/rest/search'
|
8
|
+
require 'mastodon/rest/relationships'
|
9
|
+
require 'mastodon/rest/media'
|
10
|
+
require 'mastodon/rest/suggestions'
|
11
|
+
require 'mastodon/rest/apps'
|
12
|
+
require 'mastodon/rest/instances'
|
13
|
+
|
14
|
+
module Mastodon
|
15
|
+
module REST
|
16
|
+
module API
|
17
|
+
include Mastodon::REST::Statuses
|
18
|
+
include Mastodon::REST::Accounts
|
19
|
+
include Mastodon::REST::Timelines
|
20
|
+
include Mastodon::REST::Notifications
|
21
|
+
include Mastodon::REST::Search
|
22
|
+
include Mastodon::REST::Relationships
|
23
|
+
include Mastodon::REST::Media
|
24
|
+
include Mastodon::REST::Suggestions
|
25
|
+
include Mastodon::REST::Apps
|
26
|
+
include Mastodon::REST::Instances
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mastodon/rest/utils'
|
4
|
+
require 'mastodon/app'
|
5
|
+
|
6
|
+
module Mastodon
|
7
|
+
module REST
|
8
|
+
module Apps
|
9
|
+
include Mastodon::REST::Utils
|
10
|
+
|
11
|
+
# Register a new OAuth client app on the target instance
|
12
|
+
# @param name [String]
|
13
|
+
# @param redirect_uri [String]
|
14
|
+
# @param scopes [String]
|
15
|
+
# @param website [String]
|
16
|
+
# @return [Mastodon::App]
|
17
|
+
def create_app(name, redirect_uri, scopes = 'read', website = nil)
|
18
|
+
perform_request_with_object(:post, '/api/v1/apps',
|
19
|
+
{
|
20
|
+
client_name: name,
|
21
|
+
redirect_uris: redirect_uri,
|
22
|
+
scopes: scopes,
|
23
|
+
website: website
|
24
|
+
}, Mastodon::App)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mastodon/rest/utils'
|
4
|
+
require 'mastodon/instance'
|
5
|
+
|
6
|
+
module Mastodon
|
7
|
+
module REST
|
8
|
+
module Instances
|
9
|
+
include Mastodon::REST::Utils
|
10
|
+
|
11
|
+
# Retrieve the current instance. Does not require authentication
|
12
|
+
# @return [Mastodon::Instance]
|
13
|
+
def instance
|
14
|
+
perform_request_with_object(:get, '/api/v1/instance', {},
|
15
|
+
Mastodon::Instance)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mastodon/rest/utils'
|
4
|
+
require 'mastodon/media'
|
5
|
+
|
6
|
+
module Mastodon
|
7
|
+
module REST
|
8
|
+
module Media
|
9
|
+
include Mastodon::REST::Utils
|
10
|
+
|
11
|
+
# Upload a media file
|
12
|
+
# @param file [File, StringIO, HTTP::FormData::File] file to
|
13
|
+
# upload. Will be converted to HTTP::FormData::File before upload
|
14
|
+
# @param description [String] A text description of the image, to be
|
15
|
+
# along with the image.
|
16
|
+
# @return [Mastodon::Media]
|
17
|
+
def upload_media(file, description = nil)
|
18
|
+
file = if file.is_a?(HTTP::FormData::File)
|
19
|
+
file
|
20
|
+
else
|
21
|
+
HTTP::FormData::File.new(file)
|
22
|
+
end
|
23
|
+
payload = { file: file }
|
24
|
+
payload[:description] = description unless description.nil?
|
25
|
+
perform_request_with_object(:post, '/api/v1/media', payload,
|
26
|
+
Mastodon::Media)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Update a media description, can only be updated while it's not
|
30
|
+
# associated to a status
|
31
|
+
# @param media_id [Integer] Id of the media, returned by upload_media
|
32
|
+
# @param description [String] A text description of the image, to be
|
33
|
+
# along with the image.
|
34
|
+
# @return [Mastodon::Media]
|
35
|
+
def update_media_description(media_id, description)
|
36
|
+
perform_request_with_object(:put, "/api/v1/media/#{media_id}",
|
37
|
+
{ description: description },
|
38
|
+
Mastodon::Media)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mastodon/rest/utils'
|
4
|
+
require 'mastodon/notification'
|
5
|
+
|
6
|
+
module Mastodon
|
7
|
+
module REST
|
8
|
+
module Notifications
|
9
|
+
include Mastodon::REST::Utils
|
10
|
+
|
11
|
+
# Get a list of notifications for the authenticated user
|
12
|
+
# @return [Mastodon::Collection<Mastodon::Notification>]
|
13
|
+
def notifications
|
14
|
+
perform_request_with_collection(:get, '/api/v1/notifications', {},
|
15
|
+
Mastodon::Notification)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mastodon/rest/utils'
|
4
|
+
require 'mastodon/relationship'
|
5
|
+
|
6
|
+
module Mastodon
|
7
|
+
module REST
|
8
|
+
module Relationships
|
9
|
+
include Mastodon::REST::Utils
|
10
|
+
|
11
|
+
# Get the relationships of authenticated user towards given other users
|
12
|
+
# @param ids [Integer]
|
13
|
+
# @return [Mastodon::Collection<Mastodon::Relationship>]
|
14
|
+
def relationships(*ids)
|
15
|
+
perform_request_with_collection(:get, '/api/v1/accounts/relationships',
|
16
|
+
array_param(:id, ids),
|
17
|
+
Mastodon::Relationship)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Follow a user
|
21
|
+
# @param id [Integer]
|
22
|
+
# @return [Mastodon::Relationship]
|
23
|
+
def follow(id)
|
24
|
+
perform_request_with_object(:post, "/api/v1/accounts/#{id}/follow",
|
25
|
+
{}, Mastodon::Relationship)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Follow a remote user
|
29
|
+
# @param uri [String] username@domain of the person you want to follow
|
30
|
+
# @return [Mastodon::Account]
|
31
|
+
def remote_follow(uri)
|
32
|
+
perform_request_with_object(:post, '/api/v1/follows', { uri: uri },
|
33
|
+
Mastodon::Account)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Unfollow a user
|
37
|
+
# @param id [Integer]
|
38
|
+
# @return [Mastodon::Relationship]
|
39
|
+
def unfollow(id)
|
40
|
+
perform_request_with_object(:post, "/api/v1/accounts/#{id}/unfollow",
|
41
|
+
{}, Mastodon::Relationship)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Block a user
|
45
|
+
# @param id [Integer]
|
46
|
+
# @return [Mastodon::Relationship]
|
47
|
+
def block(id)
|
48
|
+
perform_request_with_object(:post, "/api/v1/accounts/#{id}/block",
|
49
|
+
{}, Mastodon::Relationship)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Unblock a user
|
53
|
+
# @param id [Integer]
|
54
|
+
# @return [Mastodon::Relationship]
|
55
|
+
def unblock(id)
|
56
|
+
perform_request_with_object(:post, "/api/v1/accounts/#{id}/unblock",
|
57
|
+
{}, Mastodon::Relationship)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Mute a user
|
61
|
+
# @param id [Integer]
|
62
|
+
# @return [Mastodon::Relationship]
|
63
|
+
def mute(id)
|
64
|
+
perform_request_with_object(:post, "/api/v1/accounts/#{id}/mute",
|
65
|
+
{}, Mastodon::Relationship)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Unmute a user
|
69
|
+
# @param id [Integer]
|
70
|
+
# @return [Mastodon::Relationship]
|
71
|
+
def unmute(id)
|
72
|
+
perform_request_with_object(:post, "/api/v1/accounts/#{id}/unmute",
|
73
|
+
{}, Mastodon::Relationship)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'addressable/uri'
|
4
|
+
require 'http'
|
5
|
+
require 'oj'
|
6
|
+
require 'mastodon/error'
|
7
|
+
require 'mastodon/headers'
|
8
|
+
|
9
|
+
module Mastodon
|
10
|
+
module REST
|
11
|
+
class Request
|
12
|
+
def initialize(client, request_method, path, options = {})
|
13
|
+
@client = client
|
14
|
+
@request_method = request_method
|
15
|
+
@uri = Addressable::URI.parse(@client.base_url + path)
|
16
|
+
@headers = Mastodon::Headers.new(@client).request_headers
|
17
|
+
@path = @uri.path
|
18
|
+
@options = options
|
19
|
+
# rubocop:disable GuardClause
|
20
|
+
if @options.is_a?(Hash) && @options[:headers]
|
21
|
+
@headers = @options.delete(:headers).merge @headers
|
22
|
+
end
|
23
|
+
# rubocop:enable GuardClause
|
24
|
+
end
|
25
|
+
|
26
|
+
def perform
|
27
|
+
options_key = @request_method == :get ? :params : :form
|
28
|
+
response = http_client.headers(@headers)
|
29
|
+
.public_send(@request_method, @uri.to_s,
|
30
|
+
options_key => @options)
|
31
|
+
|
32
|
+
STDERR.puts response.body if ENV['DEBUG'] == 'true'
|
33
|
+
|
34
|
+
r_body = response.body.empty? ? '' : Oj.load(response.to_s, mode: :null)
|
35
|
+
fail_or_return(response.code, r_body)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def fail_or_return(code, body)
|
41
|
+
if Mastodon::Error::ERRORS.include?(code)
|
42
|
+
raise Mastodon::Error::ERRORS[code].from_response(body)
|
43
|
+
end
|
44
|
+
body
|
45
|
+
end
|
46
|
+
|
47
|
+
def http_client
|
48
|
+
HTTP.timeout(:per_operation, connect: @client.timeout[:connect],
|
49
|
+
read: @client.timeout[:read],
|
50
|
+
write: @client.timeout[:write])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|