restiny 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/restiny/character.rb +17 -0
- data/lib/restiny/client.rb +134 -0
- data/lib/restiny/constants.rb +12 -0
- data/lib/restiny/manifest.rb +139 -0
- data/lib/restiny/membership.rb +29 -0
- data/lib/restiny/user.rb +31 -0
- data/lib/restiny/version.rb +5 -0
- data/lib/restiny.rb +11 -0
- metadata +149 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e2ff82944ba14279df69b4c5e8d151a4d0b18c5176273af3ed68142327473993
|
4
|
+
data.tar.gz: a214d550713959f482943f2120d491a91227f46599ab5f5da46e55abed7174be
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 269e932d167058936ac4ccc092493b72da71026dbf5947467367671e2a64421496f0f9d40b99962eb1f1dc416754734ed241dfaaee53440ea03bee610efdb2d2
|
7
|
+
data.tar.gz: def65d2d7fc397ca3e833a6eec1b922d78639d7c800f763f4e15740a9bde08d8e2e36e5db020dd9654594575c11b1f1c078d3d57f0b9f1eb1bbaf2197e70729a
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Restiny
|
4
|
+
class Character
|
5
|
+
attr_accessor :id, :playtime, :light_level, :stats, :emblem, :progression
|
6
|
+
|
7
|
+
def initialize(id:, session_playtime:, total_playtime:, light_level:, stats:, emblem:, progression:)
|
8
|
+
@id = id
|
9
|
+
@playtime = { session: session_playtime, total: total_playtime }
|
10
|
+
@light_level = light_level
|
11
|
+
@stats = stats
|
12
|
+
@emblem = emblem
|
13
|
+
@progression = progression
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'faraday/follow_redirects'
|
5
|
+
|
6
|
+
module Restiny
|
7
|
+
class Client
|
8
|
+
BUNGIE_URL = "https://www.bungie.net"
|
9
|
+
API_BASE_URL = BUNGIE_URL + "/Platform"
|
10
|
+
|
11
|
+
attr_accessor :api_key, :manifest
|
12
|
+
|
13
|
+
def initialize(api_key)
|
14
|
+
@api_key = api_key
|
15
|
+
end
|
16
|
+
|
17
|
+
# Manifest methods
|
18
|
+
|
19
|
+
def download_manifest(locale = 'en')
|
20
|
+
response = get("/Destiny2/Manifest/")
|
21
|
+
|
22
|
+
manifest_path = response.body.dig('Response', 'mobileWorldContentPaths', locale)
|
23
|
+
raise "Unable to determine manifest URL" if manifest_path.nil?
|
24
|
+
|
25
|
+
Manifest.download(BUNGIE_URL + manifest_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Profile methods
|
29
|
+
|
30
|
+
def get_profile(membership_id, membership_type, components = [])
|
31
|
+
raise "You must provide at least one component" if components.empty?
|
32
|
+
|
33
|
+
component_query = components.join(",")
|
34
|
+
response = get("/Destiny2/#{membership_type}/Profile/#{membership_id}?components=#{component_query}")
|
35
|
+
|
36
|
+
{}.tap do |output|
|
37
|
+
components.each do |component|
|
38
|
+
case component.downcase
|
39
|
+
when 'characters'
|
40
|
+
output[:characters] = parse_profile_characters_response(response)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Account methods
|
47
|
+
|
48
|
+
def get_user_by_bungie_name(full_display_name, membership_type = PLATFORM_ALL)
|
49
|
+
display_name, display_name_code = full_display_name.split('#')
|
50
|
+
raise "You must provide a valid Bungie name" if display_name.nil? || display_name_code.nil?
|
51
|
+
|
52
|
+
params = {
|
53
|
+
displayName: display_name,
|
54
|
+
displayNameCode: display_name_code
|
55
|
+
}
|
56
|
+
|
57
|
+
response = post("/Destiny2/SearchDestinyPlayerByBungieName/#{membership_type}/", params)
|
58
|
+
result = response.body.dig('Response')
|
59
|
+
|
60
|
+
return [] if result.nil?
|
61
|
+
|
62
|
+
Restiny::User.new(
|
63
|
+
display_name: result[0]['bungieGlobalDisplayName'],
|
64
|
+
display_name_code: result[0]['bungieGlobalDisplayNameCode'],
|
65
|
+
memberships: result
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
def search_users(name, page = 0)
|
70
|
+
params = { displayNamePrefix: name }
|
71
|
+
response = post("/User/Search/GlobalName/#{page}", params).body
|
72
|
+
return [] if response.nil?
|
73
|
+
|
74
|
+
search_results = response.dig('Response', 'searchResults')
|
75
|
+
return [] if search_results.nil?
|
76
|
+
|
77
|
+
search_results.map do |user|
|
78
|
+
Restiny::User.new(
|
79
|
+
display_name: user['bungieGlobalDisplayName'],
|
80
|
+
display_name_code: user['bungieGlobalDisplayNameCode'],
|
81
|
+
memberships: user['destinyMemberships']
|
82
|
+
)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def get(endpoint_url, params = {})
|
87
|
+
connection.get(API_BASE_URL + endpoint_url, params)
|
88
|
+
end
|
89
|
+
|
90
|
+
def post(endpoint_url, body, headers = {})
|
91
|
+
connection.post(API_BASE_URL + endpoint_url, body, headers)
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def parse_profile_characters_response(response)
|
97
|
+
characters = response.body.dig('Response', 'characters', 'data')
|
98
|
+
return [] if characters.nil?
|
99
|
+
|
100
|
+
result = []
|
101
|
+
|
102
|
+
[].tap do |result|
|
103
|
+
characters.each_value do |character|
|
104
|
+
result << Restiny::Character.new(
|
105
|
+
id: character['characterId'],
|
106
|
+
session_playtime: character['minutesPlayedThisSession'],
|
107
|
+
total_playtime: character['minutesPlayedTotal'],
|
108
|
+
light_level: character['light'],
|
109
|
+
stats: [],
|
110
|
+
emblem: [],
|
111
|
+
progression: character['progression']
|
112
|
+
)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def default_headers
|
118
|
+
{
|
119
|
+
'User-Agent': "restiny v#{Restiny::VERSION}",
|
120
|
+
'X-API-KEY': @api_key
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
def connection
|
125
|
+
@connection ||= Faraday.new(headers: default_headers) do |faraday|
|
126
|
+
faraday.request :json
|
127
|
+
faraday.request :url_encoded
|
128
|
+
faraday.response :json
|
129
|
+
faraday.response :follow_redirects
|
130
|
+
faraday.response :raise_error
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
PLATFORM_ALL = -1
|
4
|
+
PLATFORM_XBOX = 1
|
5
|
+
PLATFORM_PSN = 2
|
6
|
+
PLATFORM_STEAM = 3
|
7
|
+
PLATFORM_EPIC = 6
|
8
|
+
|
9
|
+
COMPONENT_TYPE_PROFILES = 'Profiles'.freeze
|
10
|
+
COMPONENT_TYPE_PROFILE_INVENTORIES = 'ProfileInventories'.freeze
|
11
|
+
COMPONENT_TYPE_CHARACTERS = 'Characters'.freeze
|
12
|
+
COMPONENT_TYPE_CHARACTER_INVENTORIES = 'CharacterInventories'.freeze
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string/literal: true
|
2
|
+
|
3
|
+
require 'down'
|
4
|
+
require 'json'
|
5
|
+
require 'sqlite3'
|
6
|
+
require 'zip'
|
7
|
+
|
8
|
+
module Restiny
|
9
|
+
class Manifest
|
10
|
+
TABLES = {
|
11
|
+
'DestinyAchievementDefinition': { item: 'achievement', items: 'achievements' },
|
12
|
+
'DestinyActivityDefinition': { item: 'activity', items: 'activities' },
|
13
|
+
'DestinyActivityGraphDefinition': { item: 'activity_graph', items: 'activity_graphs' },
|
14
|
+
'DestinyActivityModeDefinition': { item: 'activity_modes', items: 'activity_modes' },
|
15
|
+
'DestinyActivityModifierDefinition': { item: 'activity_modifier', items: 'activity_modifiers' },
|
16
|
+
'DestinyActivityTypeDefinition': { item: 'activity_type', items: 'activity_types' },
|
17
|
+
'DestinyArtifactDefinition': { item: 'artifact', items: 'artifacts' },
|
18
|
+
'DestinyBondDefinition': { item: 'bond', items: 'bonds' },
|
19
|
+
'DestinyBreakerTypeDefinition': { item: 'breaker_type', items: 'breaker_types' },
|
20
|
+
'DestinyChecklistDefinition': { item: 'checklist', items: 'checklists' },
|
21
|
+
'DestinyClassDefinition': { item: 'class', items: 'classes' },
|
22
|
+
'DestinyCollectibleDefinition': { item: 'collectible', items: 'collectibles' },
|
23
|
+
'DestinyDamageTypeDefinition': { item: 'damage_type', items: 'damage_types' },
|
24
|
+
'DestinyDestinationDefinition': { item: 'destination', items: 'destinations' },
|
25
|
+
'DestinyEnergyTypeDefinition': { item: 'energy_type', items: 'energy_types' },
|
26
|
+
'DestinyEquipmentSlotDefinition': { item: 'eqiupment_slot', items: 'equipment_slots' },
|
27
|
+
'DestinyEventCardDefinition': { item: 'event_card', items: 'event_cards' },
|
28
|
+
'DestinyFactionDefinition': { item: 'faction', items: 'factions' },
|
29
|
+
'DestinyGenderDefinition': { item: 'gender', items: 'genders' },
|
30
|
+
'DestinyHistoricalStatsDefinition': { item: 'historical_stat', items: 'historical_stats' },
|
31
|
+
'DestinyInventoryBucketDefinition': { item: 'inventory_bucket', items: 'inventory_buckets' },
|
32
|
+
'DestinyInventoryItemDefinition': { item: 'inventory_item', items: 'inventory_items' },
|
33
|
+
'DestinyItemCategoryDefinition': { item: 'item_category', items: 'item_categories' },
|
34
|
+
'DestinyItemTierTypeDefinition': { item: 'item_tier_type', items: 'item_tier_types' },
|
35
|
+
'DestinyLocationDefinition': { item: 'location', items: 'locations' },
|
36
|
+
'DestinyLoreDefinition': { item: 'lore', items: 'lore_entries' },
|
37
|
+
'DestinyMaterialRequirementSetDefinition': { item: 'material_requirement_set', items: 'material_requirement_sets' },
|
38
|
+
'DestinyMedalTierDefinition': { item: 'medal_tier', items: 'medal_tiers' },
|
39
|
+
'DestinyMetricDefinition': { item: 'metric', items: 'metrics' },
|
40
|
+
'DestinyMilestoneDefinition': { item: 'milestone', items: 'milestones' },
|
41
|
+
'DestinyObjectiveDefinition': { item: 'objective', items: 'objectives' },
|
42
|
+
'DestinyPlaceDefinition': { item: 'place', items: 'places' },
|
43
|
+
'DestinyPlugSetDefinition': { item: 'plug_set', items: 'plug_sets' },
|
44
|
+
'DestinyPowerCapDefinition': { item: 'power_cap', items: 'power_caps' },
|
45
|
+
'DestinyPresentationNodeDefinition': { item: 'presentation_node', items: 'presentation_nodes' },
|
46
|
+
'DestinyProgressionDefinition': { item: 'progression', items: 'progression_data' },
|
47
|
+
'DestinyProgressionLevelRequirementDefinition': { item: 'progression_level_requirement', items: 'progression_level_requirements' },
|
48
|
+
'DestinyRaceDefinition': { item: 'race', items: 'races' },
|
49
|
+
'DestinyRecordDefinition': { item: 'record', items: 'records' },
|
50
|
+
'DestinyReportReasonCategoryDefinition': { item: 'report_reason_category', items: 'report_reason_categories' },
|
51
|
+
'DestinyRewardSourceDefinition': { item: 'reward_source', items: 'reward_sources' },
|
52
|
+
'DestinySackRewardItemListDefinition': { item: 'sack_reward_item_list', items: 'sack_reward_item_lists' },
|
53
|
+
'DestinySandboxPatternDefinition': { item: 'sandbox_pattern', items: 'sandbox_patterns' },
|
54
|
+
'DestinySandboxPerkDefinition': { item: 'sandbox_perk', items: 'sandbox_perks' },
|
55
|
+
'DestinySeasonDefinition': { item: 'season', items: 'seasons' },
|
56
|
+
'DestinySeasonPassDefinition': { item: 'season_pass', items: 'season_passes' },
|
57
|
+
'DestinySocketCategoryDefinition': { item: 'socket_category', items: 'socket_categories' },
|
58
|
+
'DestinySocketTypeDefinition': { item: 'socket_type', items: 'socket_types' },
|
59
|
+
'DestinyStatDefinition': { item: 'stat', items: 'stats' },
|
60
|
+
'DestinyStatGroupDefinition': { item: 'stat_group', items: 'stat_groups' },
|
61
|
+
'DestinyTalentGridDefinition': { item: 'talent_grid', items: 'talent_grids' },
|
62
|
+
'DestinyTraitCategoryDefinition': { item: 'trait_category', items: 'trait_categories' },
|
63
|
+
'DestinyTraitDefinition': { item: 'trait', items: 'traits' },
|
64
|
+
'DestinyUnlockDefinition': { item: 'unlock', items: 'unlocks' },
|
65
|
+
'DestinyVendorDefinition': { item: 'vendor', items: 'vendors' },
|
66
|
+
'DestinyVendorGroupDefinition': { item: 'vendor_group', items: 'vendor_groups' }
|
67
|
+
}
|
68
|
+
|
69
|
+
attr_reader :file_path
|
70
|
+
|
71
|
+
TABLES.each do |table_name, method_names|
|
72
|
+
define_method method_names[:item] do |id|
|
73
|
+
query_table(table_name, id: id)[0]
|
74
|
+
end
|
75
|
+
|
76
|
+
define_method method_names[:items] do |limit: nil|
|
77
|
+
query_table(table_name, limit: limit)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.download(url)
|
82
|
+
zipped_file = Down.download(url)
|
83
|
+
manifest_path = zipped_file.path + ".db"
|
84
|
+
|
85
|
+
Zip::File.open(zipped_file) { |file| file.first.extract(manifest_path) }
|
86
|
+
|
87
|
+
self.new(manifest_path)
|
88
|
+
rescue Down::Error
|
89
|
+
raise "Unable to download the manifest from Bungie"
|
90
|
+
rescue Zip::Error
|
91
|
+
raise "Unable to unzip the manifest file"
|
92
|
+
end
|
93
|
+
|
94
|
+
def initialize(file_path)
|
95
|
+
raise "You must provide the file path for the manifest file" if file_path.empty?
|
96
|
+
|
97
|
+
@database = SQLite3::Database.new(file_path, results_as_hash: true)
|
98
|
+
@file_path = file_path
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def self.clean_row_keys(row_hash)
|
104
|
+
OpenStruct.new.tap do |output|
|
105
|
+
row_hash.each_pair do |key, value|
|
106
|
+
key = key.gsub(/(\B[A-Z])/, '_\1') if key =~ /\B[A-Z]/
|
107
|
+
output[key.downcase] = if value.is_a?(Hash)
|
108
|
+
clean_row_keys(value)
|
109
|
+
else
|
110
|
+
value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def query_table(table_name, id: nil, limit: nil)
|
117
|
+
query = "SELECT json FROM #{table_name}"
|
118
|
+
bindings = []
|
119
|
+
|
120
|
+
if id
|
121
|
+
query << " WHERE id=?"
|
122
|
+
bindings << id
|
123
|
+
end
|
124
|
+
|
125
|
+
query << " ORDER BY json_extract(json, '$.index')" unless id
|
126
|
+
|
127
|
+
if limit
|
128
|
+
query << " LIMIT ?"
|
129
|
+
bindings << limit
|
130
|
+
end
|
131
|
+
|
132
|
+
@database.execute(query, bindings).map do |row|
|
133
|
+
Manifest::clean_row_keys(JSON.parse(row['json'])) unless row['json'].nil?
|
134
|
+
end
|
135
|
+
rescue SQLite3::Exception => e
|
136
|
+
raise "Error while querying the manifest (#{e})"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Restiny
|
4
|
+
class Membership
|
5
|
+
attr_reader :id, :type, :cross_save_override, :icon_path, :is_public, :types
|
6
|
+
|
7
|
+
def self.platform(type)
|
8
|
+
case type
|
9
|
+
when PLATFORM_XBOX
|
10
|
+
:xbox
|
11
|
+
when PLATFORM_PSN
|
12
|
+
:playstation
|
13
|
+
when PLATFORM_STEAM
|
14
|
+
:steam
|
15
|
+
when PLATFORM_EPIC
|
16
|
+
:epic
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(id:, type:, cross_save_override:, icon_path:, is_public:, types:)
|
21
|
+
@id = id
|
22
|
+
@type = type
|
23
|
+
@cross_save_override = cross_save_override
|
24
|
+
@icon_path = icon_path
|
25
|
+
@is_public = is_public
|
26
|
+
@types = types
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/restiny/user.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Restiny
|
4
|
+
class User
|
5
|
+
attr_reader :display_name, :display_name_code, :memberships
|
6
|
+
|
7
|
+
def initialize(display_name:, display_name_code:, memberships:)
|
8
|
+
@display_name = display_name
|
9
|
+
@display_name_code = display_name_code
|
10
|
+
|
11
|
+
self.memberships = memberships
|
12
|
+
end
|
13
|
+
|
14
|
+
def memberships=(raw_memberships)
|
15
|
+
@memberships = {}
|
16
|
+
|
17
|
+
raw_memberships.each do |ship|
|
18
|
+
platform = Restiny::Membership.platform(ship['membershipType'])
|
19
|
+
|
20
|
+
@memberships[platform] = Restiny::Membership.new(
|
21
|
+
id: ship['membershipId'],
|
22
|
+
type: ship['membershipType'],
|
23
|
+
cross_save_override: ship['crossSaveOverride'],
|
24
|
+
icon_path: ship['iconPath'],
|
25
|
+
is_public: ship['isPublic'],
|
26
|
+
types: ship['applicableMembershipTypes']
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/restiny.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(__dir__)
|
4
|
+
|
5
|
+
require 'restiny/version'
|
6
|
+
require 'restiny/constants'
|
7
|
+
require 'restiny/client'
|
8
|
+
require 'restiny/manifest'
|
9
|
+
require 'restiny/user'
|
10
|
+
require 'restiny/membership'
|
11
|
+
require 'restiny/character'
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: restiny
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Bogan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-02-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday-follow_redirects
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: down
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.4'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubyzip
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.3'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 12.3.3
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 12.3.3
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.10'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.10'
|
111
|
+
description: A gem for interacting with Bungie's Destiny API.
|
112
|
+
email:
|
113
|
+
- d+restiny@waferbaby.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- lib/restiny.rb
|
119
|
+
- lib/restiny/character.rb
|
120
|
+
- lib/restiny/client.rb
|
121
|
+
- lib/restiny/constants.rb
|
122
|
+
- lib/restiny/manifest.rb
|
123
|
+
- lib/restiny/membership.rb
|
124
|
+
- lib/restiny/user.rb
|
125
|
+
- lib/restiny/version.rb
|
126
|
+
homepage: http://github.com/waferbaby/restiny
|
127
|
+
licenses:
|
128
|
+
- MIT
|
129
|
+
metadata: {}
|
130
|
+
post_install_message:
|
131
|
+
rdoc_options: []
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
requirements: []
|
145
|
+
rubygems_version: 3.1.6
|
146
|
+
signing_key:
|
147
|
+
specification_version: 4
|
148
|
+
summary: A Destiny API gem
|
149
|
+
test_files: []
|