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