Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
dc4882e
add authentication by token
brachetti Jul 12, 2016
7d0aca5
include a sign=true parameter
brachetti Jul 12, 2016
960c4b1
use https
brachetti Jul 12, 2016
4c5e8c9
add v2 groups
brachetti Jul 12, 2016
6d077f0
include file
brachetti Jul 12, 2016
9f47cd4
use version 3 api for groups
brachetti Jul 12, 2016
9498a79
rescue json parse
brachetti Jul 12, 2016
537b276
acutally include v3 groups definition
brachetti Jul 12, 2016
8d299fb
new call self/groups
brachetti Jul 12, 2016
31ac319
build collection differently for self/groups
brachetti Jul 12, 2016
46123c3
rename self_groups to the meetup own name of member groups
brachetti Jul 12, 2016
65bdd3a
smarter errors
brachetti Jul 12, 2016
e9b5485
fixed tests
brachetti Jul 12, 2016
6b00ebc
fix test behaviour
brachetti Jul 12, 2016
a53cbe2
add topic_categories
brachetti Jul 13, 2016
a8d0d9f
correct type for topic_categories
brachetti Jul 13, 2016
6597642
topic_categories using api version 2
brachetti Jul 13, 2016
890705d
add raw meta data
brachetti Jul 13, 2016
75cf4fd
actually have an attribute raw_meta on collection
brachetti Jul 13, 2016
1650e26
show headers when no data was received (possible throttling)
brachetti Jul 14, 2016
6b231c6
add group profile call
brachetti Jul 26, 2016
8e9aa4d
add group profile call
brachetti Jul 26, 2016
564ef8d
test correct var
brachetti Jul 26, 2016
856b73e
make urlparams work
brachetti Jul 26, 2016
4bc1ed3
fix replacing urlparams
brachetti Jul 26, 2016
af9869b
replace only with strings
brachetti Jul 26, 2016
6ce362c
use correct url
brachetti Jul 26, 2016
d30a7b5
add singular resources
brachetti Jul 26, 2016
18ffe0c
reference singular resource by current class
brachetti Jul 26, 2016
79bb67f
format right result
brachetti Jul 26, 2016
2bcb3f6
use link_header to paginate v3 api endpoints
brachetti Jul 26, 2016
f527719
require link_header for real
brachetti Jul 26, 2016
458210e
find pair by array
brachetti Jul 26, 2016
6c86b10
use href of next link to paginate
brachetti Jul 26, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ spec/reports
test/tmp
test/version_tmp
tmp
.idea

9 changes: 7 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ PATH
remote: .
specs:
rMeetup (1.1.0)
json
json (~> 1.8.2)
link_header

GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.1.3)
json (1.8.1)
json (1.8.3)
link_header (0.0.8)
rake (10.1.1)
rspec (2.8.0)
rspec-core (~> 2.8.0)
Expand All @@ -27,3 +29,6 @@ DEPENDENCIES
rMeetup!
rake
rspec

BUNDLED WITH
1.12.5
30 changes: 26 additions & 4 deletions lib/rmeetup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module RMeetup
# RMeetup Errors
class NotConfiguredError < StandardError
def initialize
super "Please provide your Meetup API key before fetching data."
super "Please provide your Meetup API key or token before fetching data."
end
end

Expand All @@ -28,7 +28,10 @@ def initialize(type)
# different fetcher classes who are responsible for fetching
# and parsing their own responses.
class Client
FETCH_TYPES = [:topics, :cities, :members, :rsvps, :events, :groups, :comments, :photos]
FETCH_TYPES = [
:topics, :cities, :members, :rsvps, :events, :groups, :comments,
:photos, :member_groups, :topic_categories, :group_profile_list, :group_profile_member
]

# Meetup API Key
# Get one at http://www.meetup.com/meetup_api/key/
Expand All @@ -38,6 +41,11 @@ class Client
def self.api_key; @@api_key; end;
def self.api_key=(key); @@api_key = key; end;

# Meetup Oauth Token
@@token = nil
def self.token; @@token; end;
def self.token=(token); @@token = token; end;

# requested Meetup API Version
# If set, the gem will attempt to use this
# version of the API. If not set, the maximum
Expand All @@ -64,15 +72,29 @@ def self.fetch(type, options = {})

protected
def self.default_options
if token
token_option
else
key_option
end
end

def self.token_option
{
:access_token => token
}
end

def self.key_option
{
:key => api_key
:key => api_key
}
end

# Raise an error if RMeetup has not been
# provided with an api key
def self.check_configuration!
raise NotConfiguredError.new unless api_key
raise NotConfiguredError.new unless api_key || token
end
end
end
3 changes: 2 additions & 1 deletion lib/rmeetup/collection.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module RMeetup
class Collection < Array
attr_accessor :page_size, :total_results
attr_accessor :page_size, :total_results, :raw_meta
attr_writer :current_page

def self.build(response)
Expand All @@ -12,6 +12,7 @@ def self.build(response)
collection.page_size = request_parameters['page'] ? request_parameters['page'].to_i : nil
collection.total_results = response['meta']['total_count'].to_i
collection.current_page = request_parameters['offset'] ? (request_parameters['offset'].to_i + 1) : 1
collection.raw_meta = response['meta']

# Load the collection with all
# of the results we passed in
Expand Down
66 changes: 39 additions & 27 deletions lib/rmeetup/fetcher.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,50 @@
require "rmeetup/fetcher/base"
require "rmeetup/fetcher/topics"
require "rmeetup/fetcher/cities"
require "rmeetup/fetcher/members"
require "rmeetup/fetcher/rsvps"
require "rmeetup/fetcher/events"
require "rmeetup/fetcher/groups"
require "rmeetup/fetcher/comments"
require "rmeetup/fetcher/photos"
require 'rmeetup/fetcher/base'
require 'rmeetup/fetcher/topics'
require 'rmeetup/fetcher/topic_categories'
require 'rmeetup/fetcher/cities'
require 'rmeetup/fetcher/members'
require 'rmeetup/fetcher/rsvps'
require 'rmeetup/fetcher/events'
require 'rmeetup/fetcher/groups'
require 'rmeetup/fetcher/group_profile_member'
require 'rmeetup/fetcher/group_profile_list'
require 'rmeetup/fetcher/member_groups'
require 'rmeetup/fetcher/comments'
require 'rmeetup/fetcher/photos'

module RMeetup
module Fetcher

class << self
# Return a fetcher for given type/API version
def for(type, api_version = nil)
return case type.to_sym
when :topics
Topics.new(api_version)
when :cities
Cities.new(api_version)
when :members
Members.new(api_version)
when :rsvps
Rsvps.new(api_version)
when :events
Events.new(api_version)
when :groups
Groups.new(api_version)
when :comments
Comments.new(api_version)
when :photos
Photos.new(api_version)
when :topics
Topics.new(api_version)
when :topic_categories
TopicCategories.new(api_version)
when :cities
Cities.new(api_version)
when :members
Members.new(api_version)
when :rsvps
Rsvps.new(api_version)
when :events
Events.new(api_version)
when :groups
Groups.new(api_version)
when :member_groups
MemberGroups.new(api_version)
when :comments
Comments.new(api_version)
when :photos
Photos.new(api_version)
when :group_profile_list
GroupProfileList.new(api_version)
when :group_profile_member
GroupProfileMember.new(api_version)
end
end
end
end
end
end
93 changes: 78 additions & 15 deletions lib/rmeetup/fetcher/base.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'link_header'

module RMeetup
module Fetcher
class ApiError < StandardError
Expand All @@ -18,11 +20,18 @@ def initialize
# will inherit from.
class Base
MAX_API_VERSION = nil
MIN_API_VERSION = nil
SINGULAR_RESOURCE = false
def initialize(api_version = nil)
@api_version = if api_version
self.class::MAX_API_VERSION && [api_version, self.class::MAX_API_VERSION].min
[api_version, self.class::MAX_API_VERSION].min if self.class::MAX_API_VERSION
else
self.class::MAX_API_VERSION
# if self.class::MIN_API_VERSION
# self.class::MIN_API_VERSION
# else
# self.class::MAX_API_VERSION
# end
self.class::MIN_API_VERSION ? self.class::MIN_API_VERSION : self.class::MAX_API_VERSION
end
@type = nil
end
Expand All @@ -34,19 +43,64 @@ def initialize(api_version = nil)
# for the request.
def fetch(options = {})
url = build_url(options)

json = get_response(url)
data = JSON.parse(json)

data = fetch_with_pagination(url)

# Check to see if the api returned an error
raise ApiError.new(data['details'],url) if data.has_key?('problem')

collection = RMeetup::Collection.build(data)

raise ApiError.new(data['details'],url) if data.is_a? Hash and data.has_key?('problem')

collection = build_collection(data)

# Format each result in the collection and return it
collection.map!{|result| format_result(result)}
if collection.is_a? Hash
format_result(collection)
else
collection.map!{|result| format_result(result)}
end
end


def fetch_with_pagination(url, data = nil)
response = get_response(url)
json = response.body
data = if data.nil?
JSON.parse(json) rescue {}
else
data + JSON.parse(json) rescue {}
end

raise ApiError.new("Received no data, header was #{response.header.to_hash.inspect}", url) if data.is_a? Hash and data.empty?

if response.header.key? 'link'
link_header = LinkHeader.parse(response.header['link'])
if next_link = link_header.find_link(['rel', 'next'])
return fetch_with_pagination(next_link.href, data)
end
end

return data
end

def replace_url_params(url, options)
url unless url.include?(':')

options.each_key do |key|
if url[":#{key}"]
url[":#{key}"] = options[key].to_s
end
end

url
end

def build_collection(data)
if self.class::SINGULAR_RESOURCE
data
else
RMeetup::Collection.build(data)
end
end

protected
# OVERRIDE this method to format a result section
# as per Result type.
Expand All @@ -57,14 +111,23 @@ def format_result(result)
end

def build_url(options)
url = replace_url_params(base_url, options)
options = encode_options(options)
check_url_for_missing_parameters!(url)

base_url + params_for(options)
url + params_for(options)
end

def base_url

def check_url_for_missing_parameters!(url)
test_match = url.match(/:\w+/)
if test_match
raise ApiError.new("Need to supply more urlparameters, missing are: #{test_match.to_a.join(', ')}", url)
end
end

def base_url
versioned_url = "#{@api_version}/" if @api_version.to_i > 1
"http://api.meetup.com/#{versioned_url}#{@type}.json/"
"https://api.meetup.com/#{versioned_url}#{@type}.json/"
end

# Create a query string from an options hash
Expand All @@ -84,7 +147,7 @@ def encode_options(options)
end

def get_response(url)
Net::HTTP.get_response(URI.parse(url)).body || raise(NoResponseError.new)
Net::HTTP.get_response(URI.parse(url)) || raise(NoResponseError.new)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rmeetup/fetcher/events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def initialize(api_version = nil)
@type = :events
end

# Turn the result hash into a Event Class
# Turn the result hash into an Event Class
def format_result(result)
if @api_version == 1
RMeetup::Type::V1::Event.new(result)
Expand Down
25 changes: 25 additions & 0 deletions lib/rmeetup/fetcher/group_profile_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module RMeetup
module Fetcher
class GroupProfileList < Base
MAX_API_VERSION = 3
MIN_API_VERSION = 3
def initialize(api_version = nil)
super(api_version) # no support for API versioning yet
@type = 'group/members'
end

# Turn the result hash into a Group Class
def format_result(result)
RMeetup::Type::V3::GroupProfile.new(result)
end

def base_url
'https://api.meetup.com/:urlname/members'
end

def build_collection(data)
data
end
end
end
end
22 changes: 22 additions & 0 deletions lib/rmeetup/fetcher/group_profile_member.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module RMeetup
module Fetcher
class GroupProfileMember < Base
MAX_API_VERSION = 3
MIN_API_VERSION = 3
SINGULAR_RESOURCE = true
def initialize(api_version = nil)
super(api_version) # no support for API versioning yet
@type = 'group/members/member_id'
end

# Turn the result hash into a Group Class
def format_result(result)
RMeetup::Type::V3::GroupProfile.new(result)
end

def base_url
'https://api.meetup.com/:urlname/members/:member_id'
end
end
end
end
Loading