# encoding: utf-8 require_relative 'communication' require_relative 'urls' require 'open-uri' require 'delegate' module MxHero::API class PaginatedElements < SimpleDelegator attr_reader :total_elements, :total_pages, :actual_page def initialize(paginable, total_elements, total_pages, actual_page) super(paginable) @total_elements = total_elements @total_pages = total_pages @actual_page = actual_page end end class Groups include Communication include Urls attr_reader :domain def initialize(domain, config = {}) @domain = domain @service_url = config[:api_url] @username = config[:username] @password = config[:password] @verbose = config[:verbose] || false end # Retrieve all the groups # # @params pagination info. Ex.: page: 2, per_page: 10 or simple page: 2 # # @return [PaginatedElement] that contains an array of Group elements # Basically its an Array with instances of [MxHero::API::Group] with the methods total_elements, total_pages and actual_page # def all(pagination = { page: nil, per_page: nil }) response = call(:get, groups_url(pagination)) paginate_wrap(response) do |hash| hash[:elements].map { |e| Group.new(e) } end end # Save a new group # # @param group [MxHero::API::Group] # # @return [MxHero::API::Response] def save(group) group.domain = domain wrap_response_from call(:post, groups_url, group.to_json) end # Delete the group # # @param group_name [String] # # @return [MxHero::API::Response] with content empty. # In case on error, may be one of the following: # + domain.group.not.found : Inexistent group def delete(group_name) response = call(:delete, group_url(group_name), nil, throw_exception: false) wrap_response_from response end # Retrieve all the accounts for one group # # @param group_name [String] # @param options [Hash] pagination options (page and/or per_page) # # @return [MxHero::API::PaginatedElements] the list of accounts [MxHero::API::Account] # def accounts(group_name, options = { per_page: nil, page: nil }) response = call(:get, group_accounts_url(group_name, options)) paginate_wrap response do |hash| hash[:elements].map { |e| Account.new(e) } end end # Add an account to a group # # @param group_name [String] # @param account_name [String] # # @return [MxHero::API::Response] with content empty. # In case on error, may be one of the following: # + domain.account.not.found : Inexistent account # + domain.group.account.already.has.group : Try to add an account to a group when already is in that def add_account(group_name, account_name) response = call(:post, group_add_accounts_url(group_name, account_name), nil, throw_exception: false) wrap_response_from response end # @param group_name [String] # @param account_name [String] # # @return [MxHero::API::Response] with content empty. # In case on error, may be one of the following: # + domain.account.not.found : Inexistent account # + domain.group.account.not.in.group : Try to remove an account that is not in the group # def remove_account(group_name, account_name) response = call(:delete, group_remove_accounts_url(group_name, account_name), nil, throw_exception: false) wrap_response_from response end private def paginate_wrap(response, &block) raise 'an error ocurred when try to communicate with the API' if response.status != 200 hash = json_parse(response.content) PaginatedElements.new(block ? block.call(hash) : hash[:elements], hash[:totalElements], hash[:totalPages], hash[:actualPage]) end def wrap_response_from(response) content = (200..299).include?(response.code) ? group_from(response) : json_parse(response.content) Response.new(response.status, content) end def group_from(response) return nil if response.content.nil? || response.content.empty? hash = json_parse response.content Group.new hash end def parse_elements(hash) hash[:elements].map { |e| Group.new(e) } end def groups_url(pagination = {}) domain_by_id_url(domain) + 'groups' + pagination_query(pagination) end def pagination_query(params = { page: nil, per_page: nil }) return '' unless params[:page] || params[:per_page] '?' + [].tap do |section| section << "limit=#{params[:per_page]}" if params[:per_page] section << "offset=#{params[:page]}" if params[:page] end.join('&') end def group_url(group_name) groups_url + "/#{URI::encode(group_name)}" end def group_accounts_url(group_name, pagination = {}) group_url(group_name) + "/accounts" + pagination_query(pagination) end def group_add_accounts_url(group_name, account_name) group_accounts_url(group_name) + "/#{account_name}/add" end def group_remove_accounts_url(group_name, account_name) group_accounts_url(group_name) + "/#{account_name}/remove" end end end