Commit e2f7f32a authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre Committed by Stan Hu

Add support for Bitbucket pagination when fetching collections

parent f1f5863b
module Bitbucket
class Collection < Enumerator
def initialize(paginator)
super() do |yielder|
loop do
paginator.next.each { |item| yielder << item }
end
end
lazy
end
def method_missing(method, *args)
return super unless self.respond_to?(method)
self.send(method, *args) do |item|
block_given? ? yield(item) : item
end
end
end
end
module Bitbucket
class Page
attr_reader :attrs, :items
def initialize(raw, type)
@attrs = parse_attrs(raw)
@items = parse_values(raw, representation_class(type))
end
def next?
attrs.fetch(:next, false)
end
def next
attrs.fetch(:next)
end
private
def parse_attrs(raw)
attrs = %w(size page pagelen next previous)
attrs.map { |attr| { attr.to_sym => raw[attr] } }.reduce(&:merge)
end
def parse_values(raw, representation_class)
return [] if raw['values'].nil? || !raw['values'].is_a?(Array)
raw['values'].map { |hash| representation_class.new(hash) }
end
def representation_class(type)
class_name = "Bitbucket::Representation::#{type.to_s.camelize}"
class_name.constantize
end
end
end
module Bitbucket
class Paginator
PAGE_LENGTH = 50 # The minimum length is 10 and the maximum is 100.
def initialize(connection, url, type)
@connection = connection
@type = type
@url = url
@page = nil
connection.query(pagelen: PAGE_LENGTH, sort: :created_on)
end
def next
raise StopIteration unless has_next_page?
@page = fetch_next_page
@page.items
end
private
attr_reader :connection, :page, :url, :type
def has_next_page?
page.nil? || page.next?
end
def page_url
page.nil? ? url : page.next
end
def fetch_next_page
parsed_response = connection.get(page_url)
Page.new(parsed_response, type)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment