rublox 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,49 +1,40 @@
1
- # frozen_string_literal: true
2
-
3
- require "time"
4
-
5
- require "rublox/derive/user"
6
-
7
- module Rublox
8
- # @note This class is handled internally by the public interface such as
9
- # {Client#user_from_id}. You should not be creating it yourself.
10
- # The {FullUser} class corresponds to a full user response you can get via
11
- # https://users.roblox.com/v1/users/userId. You can use it to get information
12
- # about users.
13
- #
14
- # See {User} for methods you can call on users!
15
- class FullUser
16
- include User
17
-
18
- # @return [Integer] the user's ID
19
- attr_reader :id
20
-
21
- # @return [String] the user's username
22
- attr_reader :username
23
-
24
- # @return [String] the user's display name
25
- attr_reader :display_name
26
-
27
- # @return [String] the user's profile description
28
- attr_reader :description
29
-
30
- # @return [true, false] is the user banned?
31
- attr_reader :banned
32
-
33
- # @return [Time] the user's join date
34
- attr_reader :join_date
35
-
36
- # @param data [Hash]
37
- # @param client [Client]
38
- def initialize(data, client)
39
- @id = data["id"]
40
- @username = data["name"]
41
- @display_name = data["displayName"]
42
- @description = data["description"]
43
- @banned = data["banned"]
44
- @join_date = Time.iso8601(data["created"])
45
-
46
- @client = client
47
- end
48
- end
49
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "rublox/derive/user"
4
+
5
+ module Rublox
6
+ module Models
7
+ class FullUser
8
+ include Derive::User
9
+
10
+ # @return [String]
11
+ attr_reader :description
12
+ # @return [Time]
13
+ attr_reader :created
14
+ # @return [Boolean]
15
+ attr_reader :is_banned
16
+ # @return [String?]
17
+ attr_reader :external_app_display_name
18
+ # @return [Boolean]
19
+ attr_reader :has_verified_badge
20
+ # @return [Integer]
21
+ attr_reader :id
22
+ # @return [String]
23
+ attr_reader :name
24
+ # @return [String]
25
+ attr_reader :display_name
26
+
27
+ # @!visibility private
28
+ def initialize(data)
29
+ @description = data["description"]
30
+ @created = Time.iso8601(data["created"])
31
+ @is_banned = data["isBanned"]
32
+ @external_app_display_name = data["externalAppDisplayName"]
33
+ @has_verified_badge = data["hasVerifiedBadge"]
34
+ @id = data["id"]
35
+ @name = data["name"]
36
+ @display_name = data["displayName"]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,62 +1,26 @@
1
- # frozen_string_literal: true
2
-
3
- require "rublox/models/limited_user"
4
-
5
- module Rublox
6
- # @note This class is handled internally by the public interface such as
7
- # {FullGroup#shout}. You should not be creating it yourself.
8
- # The {GroupShout} class corresponds to a shout response. You can use it to get
9
- # and set information about group shouts.
10
- class GroupShout
11
- # @return [String] the shout's body
12
- attr_reader :body
13
-
14
- # @return [LimitedUser, nil] the user that made the shout, can be nil if the
15
- # shout has no poster
16
- attr_reader :poster
17
-
18
- # @param data [Hash]
19
- # @param client [Client]
20
- # @param group_id [Integer]
21
- def initialize(data, client, group_id)
22
- @body = data["body"]
23
- @poster = LimitedUser.new(data["poster"], client) if data["poster"]
24
-
25
- @group_id = group_id
26
- @client = client
27
- end
28
-
29
- # Sends a new shout.
30
- # @example
31
- # client = Rublox::Client.new
32
- # group = client.group_from_id(1)
33
- # group.shout.send_shout("new shout")
34
- # @param new_shout [String] the body of the new shout
35
- # @return [void]
36
- def send_shout(new_shout)
37
- @client.http_client.patch(
38
- URL.endpoint("groups", "v1/groups/#{@group_id}/status"),
39
- json: {
40
- message: new_shout
41
- }
42
- )
43
- end
44
-
45
- # Clears the group shout. Same as calling {#send_shout} with an empty string.
46
- # @example
47
- # client = Rublox::Client.new
48
- # group = client.group_from_id(1)
49
- # group.shout.clear
50
- # # same as
51
- # group.shout.send_shout("")
52
- # @return [void]
53
- def clear
54
- send_shout("")
55
- end
56
-
57
- # @return [GroupShout] A new group shout object with updated information.
58
- def refresh
59
- @client.group_from_id(@group_id).shout
60
- end
61
- end
62
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "rublox/models/skinny_user"
4
+
5
+ module Rublox
6
+ module Models
7
+ class GroupShout
8
+ # @return [String]
9
+ attr_reader :body
10
+ # @return [SkinnyUser]
11
+ attr_reader :poster
12
+ # @return [Time]
13
+ attr_reader :created
14
+ # @return [Time]
15
+ attr_reader :updated
16
+
17
+ # @!visibility private
18
+ def initialize(data)
19
+ @body = data["body"]
20
+ @poster = SkinnyUser.new(data["poster"])
21
+ @created = Time.iso8601(data["created"])
22
+ @updated = Time.iso8601(data["updated"])
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,98 +1,59 @@
1
- # frozen_string_literal: true
2
-
3
- require "time"
4
-
5
- module Rublox
6
- # The state of the presence.
7
- #
8
- # Can be offline, online/on the website, playing a game, developing on studio.
9
- module PresenceType
10
- # The user is/was offline.
11
- OFFLINE = :Offline
12
- # The user is/was online (this also applies to the website).
13
- ONLINE = :Online
14
- # The user is/was playing a game.
15
- GAME = :"In game"
16
- # The user is/was developing on studio.
17
- STUDIO = :"In Studio"
18
-
19
- # @!visibility private
20
- PRESENCE_MAP = [
21
- OFFLINE,
22
- ONLINE,
23
- GAME,
24
- STUDIO
25
- ].freeze
26
-
27
- # Convert the Roblox PresenceType enum response to rublox's PresenceType
28
- # equivalent.
29
- # @!visibility private
30
- # @param enum [Integer]
31
- # @return [Symbol]
32
- def self.enum_to_presence_type(enum)
33
- PRESENCE_MAP[enum]
34
- end
35
- end
36
-
37
- # @note This class is handled internally by the public interface such as
38
- # {Client#user_presence_from_id}. You should not be creating it yourself.
39
- # The {Presence} class corresponds to a response you can get via
40
- # https://presence.roblox.com/v1/presence/users. You can use it to get information
41
- # about the presence states of users.
42
- class Presence
43
- # @return [PresenceType] the current presence type
44
- attr_reader :presence_type
45
-
46
- # @return [PresenceType] the last presence type of the user
47
- attr_reader :last_presence_type
48
-
49
- # @note Unlike it sounds, this is not a numerical ID like of a user. It's a
50
- # randomly generated string with hexadecimal numbers containing the server's
51
- # job ID (which looks like "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"), it can be
52
- # also accessed in-game via the game.JobId property.
53
- # @return [String, nil] the job ID of the game last played by the user.
54
- attr_reader :game_job_id
55
-
56
- # @return [Time] the date at which the user was last online
57
- attr_reader :last_online_date
58
-
59
- def initialize(data, client)
60
- @presence_type = PresenceType.enum_to_presence_type(data["userPresenceType"])
61
- @last_location = data["lastLocation"]
62
- @place_id = data["placeId"]
63
- @root_place_id = data["rootPlaceId"]
64
- @game_job_id = data["gameId"]
65
- @universe_id = data["universeId"]
66
- @user_id = data["userId"]
67
- @last_online_date = Time.iso8601(data["lastOnline"])
68
-
69
- @client = client
70
- end
71
-
72
- # @todo add Place class
73
- # @return [Place, nil] the place last visited by the user, can be nil if the
74
- # user has never played a game
75
- def place
76
- return unless @place_id
77
- end
78
-
79
- # @todo add Place class
80
- # @return [Place, nil] the root of the place last visited by the user, can
81
- # be nil if the user has never played a game
82
- def root_place
83
- return unless @root_place_id
84
- end
85
-
86
- # @todo add Universe class
87
- # @return [Universe, nil] the universe of the place last visited by the user,
88
- # can be nil if the user has never played a game
89
- def universe
90
- return unless @universe_id
91
- end
92
-
93
- # @return [FullUser] the user tied to the presence
94
- def user
95
- @client.user_from_id(@user_id)
96
- end
97
- end
98
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "rublox/derive/model"
4
+ require "rublox/bases/base_user"
5
+
6
+ module Rublox
7
+ module Models
8
+ module PresenceType
9
+ OFFLINE = :offline
10
+ ONLINE = :online
11
+ IN_GAME = :in_game
12
+ IN_STUDIO = :in_studio
13
+
14
+ PRESENCE_MAP = [
15
+ OFFLINE,
16
+ ONLINE,
17
+ IN_GAME,
18
+ IN_STUDIO
19
+ ].freeze
20
+ private_constant :PRESENCE_MAP
21
+
22
+ # @!visibility private
23
+ def self.get(enum)
24
+ PRESENCE_MAP[enum]
25
+ end
26
+ end
27
+
28
+ class Presence
29
+ include Derive::Model
30
+
31
+ # @return [PresenceType]
32
+ attr_reader :user_presence_type
33
+ # @return [String]
34
+ attr_reader :last_location
35
+ # attr_reader :place_id
36
+ # attr_reader :root_place_id
37
+ # attr_reader :game_id
38
+ # attr_reader :universe_id
39
+ # @return [Bases::BaseUser]
40
+ attr_reader :user
41
+ # @return [Time]
42
+ attr_reader :last_online
43
+
44
+ # @!visibility private
45
+ def initialize(data)
46
+ @user_presence_type = PresenceType.get(data["userPresenceType"])
47
+ @last_location = data["lastLocation"]
48
+ # @place_id = data["placeId"]
49
+ # @root_place_id = data["rootPlaceId"]
50
+ # @game_id = data["gameId"]
51
+ # @universe_id = data["universeId"]
52
+ @user = Bases::BaseUser.new(data["userId"])
53
+ @last_online = Time.iso8601(data["lastOnline"])
54
+
55
+ @id = @user_id
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rublox/derive/user"
4
+
5
+ module Rublox
6
+ module Models
7
+ class SkinnyUser
8
+ include Derive::User
9
+
10
+ # @return [Integer]
11
+ attr_reader :id
12
+ # @return [String]
13
+ attr_reader :name
14
+ # @return [String]
15
+ attr_reader :display_name
16
+ # @return [Boolean]
17
+ attr_reader :has_verified_badge
18
+
19
+ # @!visibility private
20
+ def initialize(data)
21
+ @id = data["id"] || data["userId"]
22
+ @name = data["name"] || data["username"]
23
+ @display_name = data["displayName"]
24
+ @has_verified_badge = data["hasVerifiedBadge"]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "http"
4
+ require "json"
5
+
6
+ require "rublox/util/errors"
7
+
8
+ module Rublox
9
+ module APIHelper
10
+ @client = HTTP::Client.new
11
+
12
+ # @!visibility private
13
+ def self.roblosecurity=(roblosecurity)
14
+ @client = @client.cookies(
15
+ {
16
+ ".ROBLOSECURITY" => roblosecurity
17
+ }
18
+ )
19
+ end
20
+
21
+ def self.get(url, *args)
22
+ request(:get, url, *args)
23
+ end
24
+
25
+ def self.post(url, *args)
26
+ request(:post, url, *args)
27
+ end
28
+
29
+ def self.patch(url, *args)
30
+ request(:patch, url, *args)
31
+ end
32
+
33
+ def self.delete(url, *args)
34
+ request(:delete, url, *args)
35
+ end
36
+
37
+ def self.request(method, url, *args)
38
+ response = @client.request(method, url, *args)
39
+ case response.status
40
+ when 200
41
+ JSON.parse(response.body)
42
+ when 403
43
+ if JSON.parse(response.body).any? { |error| error.code.zero? }
44
+ @client = @client.headers(
45
+ {
46
+ "x-csrf-token" => response.headers
47
+ }
48
+ )
49
+ end
50
+ when 401
51
+ raise Errors::InvalidROBLOSECURITYError
52
+ else
53
+ raise Errors::UnhandledStatusCodeError.new(response, get_errors_from_response(response))
54
+ end
55
+ end
56
+
57
+ def self.get_errors_from_response(response)
58
+ body = JSON.parse(response.body)
59
+ rescue JSON::ParserError
60
+ "\ncould not parse errors, raw body:\n#{response.body}\n"
61
+ else
62
+ body["errors"].reduce("") do |error_message, error|
63
+ error_message + "\tCode: #{error['code']}\n\tMessage: #{error['message']}\n\n"
64
+ end
65
+ end
66
+
67
+ private_class_method :request, :get_errors_from_response
68
+ end
69
+ end
@@ -1,109 +1,44 @@
1
- # frozen_string_literal: true
2
-
3
- module Rublox
4
- # This module contains errors that can be raised by rublox methods.
5
- module Errors
6
- # Exception raised when a user cannot be found.
7
- class UserNotFoundError < StandardError
8
- # @return [Integer, "(no ID information provided)"] the given user's ID
9
- attr_reader :user_id
10
-
11
- # @return [String, "(no username information provided)"] the given user's
12
- # username
13
- attr_reader :user_username
14
-
15
- # @param user_id [Integer]
16
- # @param username [String, nil]
17
- def initialize(
18
- user_id = "(no ID information provided)",
19
- username = "(no username information provided)"
20
- )
21
- @user_id = user_id
22
- @user_username = username
23
- super("The user of ID #{user_id} and username #{username} could not be found.")
24
- end
25
- end
26
-
27
- # Exception raised when a group cannot be found.
28
- class GroupNotFoundError < StandardError
29
- # @return [Integer] the given group's ID
30
- attr_reader :group_id
31
-
32
- # @param group_id [Integer]
33
- def initialize(group_id)
34
- @group_id = group_id
35
- super("The group of ID #{group_id} could not be found.")
36
- end
37
- end
38
-
39
- # Exception raised when a user's presence cannot be found.
40
- class PresenceNotFoundError < StandardError
41
- # @return [Integer] the presence user's ID
42
- attr_reader :user_id
43
-
44
- def initialize(user_id)
45
- @user_id = user_id
46
- super("The presence of the user with ID #{user_id} could not be found.")
47
- end
48
- end
49
-
50
- # Exception raised when a user is not part of a group.
51
- class MemberNotFoundError < StandardError
52
- # @return [Integer] the given user's ID
53
- attr_reader :user_id
54
-
55
- # @return [Integer] the given group's ID
56
- attr_reader :group_id
57
-
58
- # @param id [Integer]
59
- # @param group_id [Integer]
60
- def initialize(id, group_id)
61
- @user_id = id
62
- @group_id = group_id
63
- super("The user of ID #{id} is not part of this group of ID #{group_id}")
64
- end
65
- end
66
-
67
- # Exception raised when a role doesn't exist.
68
- class RoleNotFoundError < StandardError
69
- # @return [Integer] the given role's ID
70
- attr_reader :role_id
71
-
72
- # @return [Integer] the given group's ID
73
- attr_reader :group_id
74
-
75
- # @param role_id [Integer]
76
- # @param group_id [Integer]
77
- def initialize(role_id, group_id)
78
- @role_id = role_id
79
- @group_id = group_id
80
- super("The role of ID #{role_id} does not exist in group of ID #{group_id}.")
81
- end
82
- end
83
-
84
- # Exception raised when an unhandled status code is returned.
85
- class UnhandledStatusCodeError < StandardError
86
- # @return [HTTP::Response::Status] the unhandled status code
87
- attr_reader :status_code
88
-
89
- # @return [String] a string containing all the errors returned by the API
90
- # neatly formatted
91
- attr_reader :errors
92
-
93
- # @param status_code [Integer]
94
- # @param errors [String, nil]
95
- def initialize(status_code, errors = "")
96
- super("Unhandled status code #{status_code}.\nRoblox errors:\n#{errors}")
97
- @status_code = status_code
98
- @errors = errors
99
- end
100
- end
101
-
102
- # Exception raised when an invalid .ROBLOSECURITY cookie is used.
103
- class InvalidROBLOSECURITYError < StandardError
104
- def initialize
105
- super("A valid .ROBLOSECURITY cookie needs to be passed to Rublox's constructor for this action.")
106
- end
107
- end
108
- end
109
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Rublox
4
+ module Errors
5
+ # This error is raised when a user couldn't be found
6
+ class UserNotFoundError < StandardError
7
+ end
8
+
9
+ # This error is raised when a group couldn't be found
10
+ class GroupNotFoundError < StandardError
11
+ end
12
+
13
+ # This error is raised when one of the provided user IDs are invalid, or if a user ID is repeated
14
+ class PresenceRequestError < StandardError
15
+ # @!visibility private
16
+ def initialize
17
+ super("An invalid or repeated user ID was provided")
18
+ end
19
+ end
20
+
21
+ # This error is raised when an error returned by the Roblox API should be dealt by the user
22
+ class UnhandledStatusCodeError < StandardError
23
+ # @return [HTTP::Response] the response object
24
+ attr_reader :response
25
+ # @return [String] a formatted string of errors returned by the Roblox API
26
+ attr_reader :errors
27
+
28
+ # @!visibility private
29
+ def initialize(response, errors)
30
+ super("Unhandled status code #{response.status}.\nRoblox errors:\n#{errors}")
31
+ @response = response
32
+ @errors = errors
33
+ end
34
+ end
35
+
36
+ # This error is raised when a method that requires authenticated is called without a valid .ROBLOSECURITY cookie set
37
+ class InvalidROBLOSECURITYError < StandardError
38
+ # @!visibility private
39
+ def initialize
40
+ super("A valid .ROBLOSECURITY cookie needs to be passed to Rublox for this action.")
41
+ end
42
+ end
43
+ end
44
+ end