lib/rest-gw2/client.rb in rest-gw2-0.2.0 vs lib/rest-gw2/client.rb in rest-gw2-0.4.0
- old
+ new
@@ -63,10 +63,121 @@
worlds = get('v2/worlds', :ids => me['world'])
guilds = guilds_detail(me['guilds'])
me.merge('world' => world_detail(worlds.first), 'guilds' => guilds)
end
+ # https://wiki.guildwars2.com/wiki/API:2/guild/:id/stash
+ def stash_with_detail gid, opts={}
+ stash = get("v2/guild/#{gid}/stash")
+ uids = stash.map{ |u| u['upgrade_id'] }.join(',')
+ upgrades = get('v2/guild/upgrades', :ids => uids)
+ bags = bags_with_detail(stash)
+
+ upgrades.zip(bags).map do |(u, b)|
+ u.merge('inventory' => b['inventory'])
+ end
+ end
+
+ # https://wiki.guildwars2.com/wiki/API:2/guild/:id/treasury
+ def treasury_with_detail gid, opts={}
+ with_item_detail("v2/guild/#{gid}/treasury") do |items|
+ items.map do |i|
+ i.merge('id' => i['item_id'])
+ end
+ end
+ end
+
+ # https://wiki.guildwars2.com/wiki/API:2/characters
+ def get_character name, opts={}
+ get("v2/characters/#{RC::Middleware.escape(name)}", {}, opts)
+ end
+
+ # https://wiki.guildwars2.com/wiki/API:2/characters
+ def characters_with_detail opts={}
+ chars = get('v2/characters', {}, opts).map do |name|
+ get_character(name, opts)
+ end
+
+ guilds = chars.map do |c|
+ get_guild(c['guild']) if c['guild']
+ end
+
+ chars.zip(guilds).map do |(c, g)|
+ c['guild'] = g
+ c
+ end.sort_by{ |c| -c['age'] }
+ end
+
+ def bags_with_detail bags, opts={}
+ detail = expand_item_detail(
+ bags + bags.flat_map{ |c| c && c['inventory'] }, opts)
+ detail.shift(bags.size).map do |b|
+ b && b.merge('inventory' => detail.shift(b['size']))
+ end
+ end
+
+ # https://wiki.guildwars2.com/wiki/API:2/colors
+ # https://wiki.guildwars2.com/wiki/API:2/account/dyes
+ def dyes_with_detail opts={}
+ mine = get('v2/account/dyes', opts)
+ get('v2/colors').each_slice(100).map do |slice|
+ slice.join(',')
+ end.map do |ids|
+ with_item_detail('v2/colors', :ids => ids) do |colors|
+ colors.map{ |c| c.merge('id' => c['item'], 'color_id' => c['id']) }
+ end
+ end.flatten.map do |color|
+ color['count'] = if mine.include?(color['color_id'])
+ 1
+ else
+ 0
+ end
+ color
+ end.sort_by{ |c| c['categories'] }
+ end
+
+ # https://wiki.guildwars2.com/wiki/API:2/account/skins
+ def skins_with_detail opts={}
+ mine = get('v2/account/skins', {}, opts)
+ all_skins.flatten.map do |skin|
+ skin['count'] = if mine.include?(skin['id'])
+ 1
+ else
+ 0
+ end
+ skin['nolink'] = true
+ skin
+ end.sort_by{ |s| s['name'] || '' }
+ end
+
+ # https://wiki.guildwars2.com/wiki/API:2/skins
+ def all_skins
+ get('v2/skins').each_slice(100).map do |slice|
+ get('v2/skins', :ids => slice.join(','))
+ end
+ end
+
+ # https://wiki.guildwars2.com/wiki/API:2/minis
+ # https://wiki.guildwars2.com/wiki/API:2/account/minis
+ def minis_with_detail opts={}
+ mine = get('v2/account/minis', {}, opts)
+ get('v2/minis').each_slice(100).map do |slice|
+ slice.join(',')
+ end.map do |ids|
+ with_item_detail('v2/minis', :ids => ids) do |minis|
+ minis.map{ |m| m.merge('id' => m['item_id'], 'mini_id' => m['id']) }
+ end
+ end.flatten.map do |mini|
+ mini['count'] = if mine.include?(mini['mini_id'])
+ 1
+ else
+ 0
+ end
+ mini
+ end.sort_by{ |m| m['order'] }
+ end
+
# https://wiki.guildwars2.com/wiki/API:2/account/wallet
# https://wiki.guildwars2.com/wiki/API:2/currencies
def wallet_with_detail opts={}
wallet = get('v2/account/wallet', {}, opts)
ids = wallet.map{ |w| w['id'] }.join(',')
@@ -74,26 +185,13 @@
wallet.map do |currency|
currency.merge(currencies[currency['id']].first)
end.sort_by{ |c| c['order'] }
end
- # https://wiki.guildwars2.com/wiki/API:2/items
- # https://wiki.guildwars2.com/wiki/API:2/commerce/prices
def with_item_detail path, query={}, opts={}, &block
block ||= :itself.to_proc
- items = block.call(get(path, query, opts))
- ids = items.map{ |i| i && i['id'] }
-
- detail = ids.compact.each_slice(100).map do |slice|
- query = {:ids => slice.join(',')}
- [get('v2/items', query),
- get('v2/commerce/prices', query, opts)]
- end.flatten.group_by{ |i| i['id'] }
-
- items.map do |i|
- i && detail[i['id']].inject(i, &:merge).merge('count' => i['count'])
- end
+ expand_item_detail(block.call(get(path, query, opts)), opts)
end
# https://wiki.guildwars2.com/wiki/API:2/commerce/transactions
def transactions_with_detail path, query={}, opts={}
with_item_detail("v2/commerce/transactions/#{path}",
@@ -107,19 +205,63 @@
def transactions_with_detail_compact path, query={}, opts={}
transactions_with_detail(path, query, opts).inject([]) do |ret, trans|
last = ret.last
if last && last['item_id'] == trans['item_id'] &&
last['price'] == trans['price']
- last['count'] += trans['count']
+ last['count'] += trans['count']
else
ret << trans
end
ret
end
end
+ # https://wiki.guildwars2.com/wiki/API:2/items
+ # https://wiki.guildwars2.com/wiki/API:2/commerce/prices
+ def expand_item_detail items, opts={}
+ skins = all_skins
+ detail = item_detail_group_by_id(items, opts)
+ upgrades = extract_items_in_slots(items, opts, 'upgrades', 'infusions')
+
+ skins_detail = skins.flatten.group_by{ |s| s['id'] }
+ items.map do |i|
+ next i unless data = i && detail[i['id']]
+ s = i['skin']
+ u = i['upgrades']
+ f = i['infusions']
+ i.merge(data).merge(
+ 'count' => i['count'] || 1,
+ 'skin' => s && skins_detail[s].first,
+ 'upgrades' => u && u.flat_map(&upgrades.method(:[])),
+ 'infusions' => f && f.flat_map(&upgrades.method(:[])))
+ end
+ end
+
private
+ def item_detail_group_by_id items, opts={}
+ items.map{ |i| i && i['id'] }.compact.each_slice(100).map do |slice|
+ q = {:ids => slice.join(',')}
+ [get('v2/items', q),
+ get('v2/commerce/prices', q, {:error_detector => false}.merge(opts))]
+ end.flat_map(&:itself).map(&:to_a).flatten.group_by{ |i| i['id'] }.
+ inject({}){ |r, (id, v)| r[id] = v.inject(&:merge); r }
+ # this is probably a dirty way to workaround converting hashes to arrays
+ end
+
+ def extract_items_in_slots items, opts, *slots
+ upgrades = items.flat_map do |i|
+ if i
+ i.values_at(*slots).flatten.compact.map do |id|
+ {'id' => id}
+ end
+ else
+ []
+ end
+ end
+ item_detail_group_by_id(upgrades, opts)
+ end
+
# https://wiki.guildwars2.com/wiki/API:2/worlds
def world_detail world
region = case r = world['id'] / 1000
when 1
'North America'
@@ -143,13 +285,13 @@
"#{world['name']} (#{world['population']}) / #{region} (#{lang})"
end
# https://wiki.guildwars2.com/wiki/API:1/guild_details
def guilds_detail guilds
- guilds.map do |gid|
- get('v1/guild_details', :guild_id => gid)
- end.map do |guild|
- "#{guild['guild_name']} [#{guild['tag']}]"
- end
+ guilds.map(&method(:get_guild))
+ end
+
+ def get_guild gid
+ get('v1/guild_details', :guild_id => gid)
end
})
end