thecity 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3 -0
  3. data/LICENSE.md +45 -0
  4. data/README.md +170 -0
  5. data/Rakefile +11 -0
  6. data/lib/the_city/account.rb +32 -0
  7. data/lib/the_city/api/accounts.rb +34 -0
  8. data/lib/the_city/api/client.rb +136 -0
  9. data/lib/the_city/api/events.rb +55 -0
  10. data/lib/the_city/api/groups.rb +41 -0
  11. data/lib/the_city/api/needs.rb +51 -0
  12. data/lib/the_city/api/oauth.rb +50 -0
  13. data/lib/the_city/api/prayers.rb +51 -0
  14. data/lib/the_city/api/request/multipart_with_file.rb +36 -0
  15. data/lib/the_city/api/response/parse_json.rb +27 -0
  16. data/lib/the_city/api/response/raise_error.rb +28 -0
  17. data/lib/the_city/api/topics.rb +51 -0
  18. data/lib/the_city/api/users.rb +78 -0
  19. data/lib/the_city/api/utils.rb +58 -0
  20. data/lib/the_city/arguments.rb +11 -0
  21. data/lib/the_city/base.rb +133 -0
  22. data/lib/the_city/client.rb +94 -0
  23. data/lib/the_city/collection.rb +130 -0
  24. data/lib/the_city/content.rb +29 -0
  25. data/lib/the_city/error/argument_arror.rb +8 -0
  26. data/lib/the_city/error/bad_gateway.rb +10 -0
  27. data/lib/the_city/error/bad_request.rb +10 -0
  28. data/lib/the_city/error/configuration_error.rb +8 -0
  29. data/lib/the_city/error/forbidden.rb +10 -0
  30. data/lib/the_city/error/gateway_timeout.rb +10 -0
  31. data/lib/the_city/error/internal_server_error.rb +10 -0
  32. data/lib/the_city/error/not_acceptable.rb +10 -0
  33. data/lib/the_city/error/not_found.rb +10 -0
  34. data/lib/the_city/error/service_unavailable.rb +10 -0
  35. data/lib/the_city/error/too_many_requests.rb +12 -0
  36. data/lib/the_city/error/unauthorized.rb +10 -0
  37. data/lib/the_city/error/unprocessable_entity.rb +10 -0
  38. data/lib/the_city/error.rb +66 -0
  39. data/lib/the_city/event.rb +11 -0
  40. data/lib/the_city/group.rb +6 -0
  41. data/lib/the_city/need.rb +10 -0
  42. data/lib/the_city/permissions.rb +21 -0
  43. data/lib/the_city/prayer.rb +10 -0
  44. data/lib/the_city/rate_limit.rb +17 -0
  45. data/lib/the_city/terminology.rb +39 -0
  46. data/lib/the_city/time.rb +67 -0
  47. data/lib/the_city/token.rb +16 -0
  48. data/lib/the_city/topic.rb +10 -0
  49. data/lib/the_city/user.rb +41 -0
  50. data/lib/the_city/version.rb +18 -0
  51. data/lib/the_city.rb +15 -0
  52. data/thecity.gemspec +28 -0
  53. metadata +172 -0
@@ -0,0 +1,29 @@
1
+ require 'the_city/time'
2
+
3
+ module TheCity
4
+ # Base class for The City content types: Topics, Events, Prayers, Needs, and Albums
5
+ #
6
+ # @!attribute [r] title
7
+ # @return [String] The title of the post.
8
+ # @!attribute [r] body
9
+ # @return [String] The body text of the post.
10
+ # @!attribute [r] id
11
+ # @return [Integer] The id associated with the church account.
12
+ # @!attribute [r] group
13
+ # @return [TheCity::Group] The group where the content originated.
14
+ # @!attribute [r] author
15
+ # @return [TheCity::User] The user who posted the content.
16
+
17
+ class Content < TheCity::Base
18
+ include TheCity::Time
19
+ attr_reader :id, :title, :body
20
+ object_attr_reader :User, :user
21
+ object_attr_reader :Group, :group
22
+
23
+ # def user
24
+ # @user
25
+ # end
26
+ alias author user
27
+
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ class ArgumentError < ::ArgumentError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 502
6
+ class BadGateway < TheCity::Error
7
+ HTTP_STATUS_CODE = 502
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 400
6
+ class BadRequest < TheCity::Error
7
+ HTTP_STATUS_CODE = 400
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ class ConfigurationError < ::ArgumentError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 403
6
+ class Forbidden < TheCity::Error
7
+ HTTP_STATUS_CODE = 403
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 504
6
+ class GatewayTimeout < TheCity::Error
7
+ HTTP_STATUS_CODE = 504
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 500
6
+ class InternalServerError < TheCity::Error
7
+ HTTP_STATUS_CODE = 500
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 406
6
+ class NotAcceptable < TheCity::Error
7
+ HTTP_STATUS_CODE = 406
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 404
6
+ class NotFound < TheCity::Error
7
+ HTTP_STATUS_CODE = 404
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 503
6
+ class ServiceUnavailable < TheCity::Error
7
+ HTTP_STATUS_CODE = 503
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 429
6
+ class TooManyRequests < TheCity::Error
7
+ HTTP_STATUS_CODE = 429
8
+ end
9
+ EnhanceYourCalm = TooManyRequests
10
+ RateLimited = TooManyRequests
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 401
6
+ class Unauthorized < TheCity::Error
7
+ HTTP_STATUS_CODE = 401
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/error'
2
+
3
+ module TheCity
4
+ class Error
5
+ # Raised when The City returns the HTTP status code 422
6
+ class UnprocessableEntity < TheCity::Error
7
+ HTTP_STATUS_CODE = 422
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,66 @@
1
+ require 'the_city/rate_limit'
2
+
3
+ module TheCity
4
+ # Custom error class for rescuing from all The City API errors
5
+ class Error < StandardError
6
+ attr_reader :rate_limit, :wrapped_exception, :code
7
+
8
+ # Create a new error from an HTTP response
9
+ #
10
+ # @param response [Hash]
11
+ # @return [TheCity::Error]
12
+ def self.from_response(response={})
13
+ error, code = parse_error(response[:body])
14
+ new(error, response[:response_headers], code)
15
+ end
16
+
17
+ # @return [Hash]
18
+ def self.errors
19
+ @errors ||= descendants.inject({}) do |hash, klass|
20
+ hash[klass::HTTP_STATUS_CODE] = klass
21
+ hash
22
+ end
23
+ end
24
+
25
+ # @return [Array]
26
+ def self.descendants
27
+ @descendants ||= []
28
+ end
29
+
30
+ # @return [Array]
31
+ def self.inherited(descendant)
32
+ descendants << descendant
33
+ end
34
+
35
+ # Initializes a new Error object
36
+ #
37
+ # @param exception [Exception, String]
38
+ # @param response_headers [Hash]
39
+ # @param code [Integer]
40
+ # @return [TheCity::Error]
41
+ def initialize(exception=$!, response_headers={}, code=nil)
42
+ @rate_limit = TheCity::RateLimit.new(response_headers)
43
+ @wrapped_exception = exception
44
+ @code = code
45
+ exception.respond_to?(:message) ? super(exception.message) : super(exception.to_s)
46
+ end
47
+
48
+ private
49
+
50
+ def self.parse_error(body)
51
+ if body.nil?
52
+ ['', nil]
53
+ elsif body[:error]
54
+ [body[:error], nil]
55
+ elsif body[:errors]
56
+ first = Array(body[:errors]).first
57
+ if first.is_a?(Hash)
58
+ [first[:message].chomp, first[:code]]
59
+ else
60
+ [first.chomp, nil]
61
+ end
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,11 @@
1
+ require 'the_city/content'
2
+
3
+ module TheCity
4
+
5
+ # class for content of type 'Event'
6
+ #
7
+ class Event < TheCity::Content
8
+ attr_reader :timezone
9
+ end
10
+
11
+ end
@@ -0,0 +1,6 @@
1
+ module TheCity
2
+ class Group < TheCity::Base
3
+ attr_reader :name, :type, :id, :profile_picture, :role_title, :primary_campus
4
+
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/content'
2
+
3
+ module TheCity
4
+
5
+ # class for content of type 'Need'
6
+ #
7
+ class Need < TheCity::Content
8
+ end
9
+
10
+ end
@@ -0,0 +1,21 @@
1
+ module TheCity
2
+ # The permissions associated with the current user
3
+ #
4
+ # @!attribute [r] can_list_in_plaza
5
+ # @return [Boolean] The name of the church, 'Grace Church'.
6
+ # @!attribute [r] member
7
+ # @return [Boolean] The subdomain used to access this account, subdomain.onthecity.org
8
+ # @!attribute [r] staff
9
+ # @return [Boolean] The id associated with the church account
10
+ # @!attribute [r] admin
11
+ # @return [Boolean] The id associated with the church account
12
+ # @!attribute [r] can_create_in_group_ids
13
+ # @return [Hash] The id associated with the church account
14
+ # @!attribute [r] admin_privileges
15
+ # @return [Array] An array of admin privileges the user has on the current account
16
+
17
+ class Permissions < TheCity::Base
18
+ attr_reader :can_list_in_plaza, :member, :staff, :admin, :can_create_in_group_ids, :admin_privileges
19
+
20
+ end
21
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/content'
2
+
3
+ module TheCity
4
+
5
+ # class for content of type 'Prayer'
6
+ #
7
+ class Prayer < TheCity::Content
8
+ end
9
+
10
+ end
@@ -0,0 +1,17 @@
1
+ module TheCity
2
+ class RateLimit < TheCity::Base
3
+
4
+ # @return [Integer]
5
+ def limit
6
+ limit = @attrs['x-rate-limit-limit']
7
+ limit.to_i if limit
8
+ end
9
+
10
+ # @return [Integer]
11
+ def remaining
12
+ remaining = @attrs['x-rate-limit-remaining']
13
+ remaining.to_i if remaining
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ module TheCity
2
+ # The terminology overrides for a City account
3
+ #
4
+ # @!attribute [r] connect
5
+ # @return [String] The name this account uses for Connect groups.
6
+ # @!attribute [r] campus
7
+ # @return [String] The name this account uses for Campus groups.
8
+ # @!attribute [r] redemption
9
+ # @return [String] The name this account uses for Redemption groups.
10
+ # @!attribute [r] seed
11
+ # @return [String] The name this account uses for Seed groups.
12
+ # @!attribute [r] band
13
+ # @return [String] The name this account uses for Band groups.
14
+ # @!attribute [r] other
15
+ # @return [String] The name this account uses for Other groups.
16
+ # @!attribute [r] neighborhood
17
+ # @return [String] The name this account uses for Neighborhood groups.
18
+ # @!attribute [r] network
19
+ # @return [String] The name this account uses for Network groups.
20
+ # @!attribute [r] leader
21
+ # @return [String] The name this account uses for Leader groups.
22
+ # @!attribute [r] community
23
+ # @return [String] The name this account uses for Community groups.
24
+ # @!attribute [r] service
25
+ # @return [String] The name this account uses for Service groups.
26
+ # @!attribute [r] church
27
+ # @return [String] The name this account uses for the Church group.
28
+ # @!attribute [r] staff
29
+ # @return [String] The label this account uses for 'Staff'.
30
+ # @!attribute [r] member
31
+ # @return [String] The label this account uses for 'Member'.
32
+ # @!attribute [r] pledge
33
+ # @return [String] The label this account uses for 'Pledge'.
34
+ class Terminology < TheCity::Base
35
+ attr_reader :connect, :campus, :redemption, :member, :seed,
36
+ :church, :service, :community, :staff, :pledge, :leader,
37
+ :neighborhood, :other, :network, :band
38
+ end
39
+ end
@@ -0,0 +1,67 @@
1
+ require 'time'
2
+ #require 'tzinfo'
3
+ #require 'tzinfo-data'
4
+
5
+ module TheCity
6
+ module Time
7
+
8
+ # Time when the object was created
9
+ #
10
+ # @return [Time]
11
+ def created_at
12
+ @created_at ||= parse_or_at(@attrs[:created_at]) if @attrs[:created_at]
13
+ end
14
+
15
+ def created?
16
+ !!@attrs[:created_at]
17
+ end
18
+
19
+ # Time when the object was updated
20
+ #
21
+ # @return [Time]
22
+ def updated_at
23
+ @updated_at ||= parse_or_at(@attrs[:updated_at]) if @attrs[:updated_at]
24
+ end
25
+
26
+ def updated?
27
+ !!@attrs[:updated_at]
28
+ end
29
+
30
+ # Time when the object starts
31
+ #
32
+ # @return [Time]
33
+ def starting_at
34
+ @starting_at ||= parse_or_at(@attrs[:starting_at]) if @attrs[:starting_at]
35
+ end
36
+
37
+ def started?
38
+ !!@attrs[:starting_at] and starting_at <= Time.now
39
+ end
40
+
41
+ # Time when the object ends
42
+ #
43
+ # @return [Time]
44
+ def ending_at
45
+ @ending_at ||= parse_or_at(@attrs[:ending_at]) if @attrs[:ending_at]
46
+ end
47
+
48
+ def ended?
49
+ !!@attrs[:ending_at] and ending_at <= Time.now
50
+ end
51
+
52
+ private
53
+
54
+ def parse_or_at(time)
55
+ begin
56
+ if time.is_a? Integer
57
+ return Time.at(time).utc
58
+ else
59
+ return Time.parse(time).utc
60
+ end
61
+ rescue
62
+ return nil
63
+ end
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,16 @@
1
+ require 'the_city/base'
2
+
3
+ module TheCity
4
+ class Token < TheCity::Base
5
+ attr_reader :access_token, :token_type
6
+ alias to_s access_token
7
+
8
+ BEARER_TYPE = "bearer"
9
+
10
+ # @return [Boolean]
11
+ def bearer?
12
+ @attrs[:token_type] == BEARER_TYPE
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ require 'the_city/content'
2
+
3
+ module TheCity
4
+
5
+ # class for content of type 'Topic'
6
+ #
7
+ class Topic < TheCity::Content
8
+ end
9
+
10
+ end
@@ -0,0 +1,41 @@
1
+ module TheCity
2
+ class User < TheCity::Base
3
+ extend Forwardable
4
+
5
+ attr_reader :id, :name, :profile_picture, :gender
6
+ attr_writer :permissions
7
+
8
+ def_delegators :@permissions, :member?, :staff?, :admin?
9
+
10
+ # Returns the groups that the user belongs to
11
+ #
12
+ # @return [Array<TheCity::Group>]
13
+ def groups
14
+ memoize(:groups) do
15
+ Array(@attrs[:groups]).map do |g|
16
+ TheCity::Group.new(g)
17
+ end
18
+ end
19
+ end
20
+
21
+ # Returns the permissions for the current user
22
+ #
23
+ # @return [TheCity::Permissions]
24
+ def permissions
25
+ @permissions ||= @client.permissions if (@client and @client.current_user.id == id)
26
+ end
27
+
28
+ # def member?
29
+ # permissions.member? rescue false
30
+ # end
31
+
32
+ # def staff?
33
+ # permissions.staff? rescue false
34
+ # end
35
+
36
+ # def admin?
37
+ # permissions.admin? rescue false
38
+ # end
39
+
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ module TheCity
2
+ class Version
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ PATCH = 2
6
+ PRE = nil
7
+
8
+ class << self
9
+
10
+ # @return [String]
11
+ def to_s
12
+ [MAJOR, MINOR, PATCH, PRE].compact.join('.')
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
data/lib/the_city.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'uri'
2
+
3
+ require 'the_city/base'
4
+ require 'the_city/api/client'
5
+
6
+ require 'the_city/collection'
7
+ require 'the_city/rate_limit'
8
+ require 'the_city/terminology'
9
+ require 'the_city/permissions'
10
+
11
+ require 'the_city/account'
12
+ require 'the_city/user'
13
+ require 'the_city/group'
14
+ require 'the_city/topic'
15
+
data/thecity.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'the_city/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.add_dependency 'faraday', ['>= 0.8', '< 0.10']
7
+ spec.add_dependency 'http', '~> 0.5.0'
8
+ spec.add_dependency 'http_parser.rb', '~> 0.5.3'
9
+ spec.add_dependency 'json', '~> 1.8'
10
+ #spec.add_dependency 'simple_oauth', '~> 0.2.0'
11
+ #spec.add_dependency 'tzinfo', '~> 1.0.1'
12
+ #spec.add_dependency 'tzinfo-data', "~> 1.2013.4"
13
+ spec.add_development_dependency 'bundler', '~> 1.0'
14
+ spec.authors = ["robertleib"]
15
+ spec.description = %q{A Ruby interface to The City API.}
16
+ spec.email = ["robert.leib@gmail.com"]
17
+ spec.files = %w(CHANGELOG.md LICENSE.md README.md Rakefile thecity.gemspec)
18
+ spec.files += Dir.glob("lib/**/*.rb")
19
+ spec.files += Dir.glob("spec/**/*")
20
+ spec.homepage = 'http://github.com/robertleib/thecity-ruby/'
21
+ spec.licenses = ['MIT']
22
+ spec.name = 'thecity'
23
+ spec.require_paths = ['lib']
24
+ spec.required_rubygems_version = '>= 1.3.5'
25
+ spec.summary = spec.description
26
+ spec.test_files = Dir.glob("spec/**/*")
27
+ spec.version = TheCity::Version
28
+ end