the-city-admin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/lib/api/address.rb +51 -0
  2. data/lib/api/address_list.rb +62 -0
  3. data/lib/api/api_object.rb +100 -0
  4. data/lib/api/barcode.rb +43 -0
  5. data/lib/api/checkin.rb +37 -0
  6. data/lib/api/checkin_list.rb +62 -0
  7. data/lib/api/family.rb +47 -0
  8. data/lib/api/family_member.rb +28 -0
  9. data/lib/api/group.rb +162 -0
  10. data/lib/api/group_address.rb +31 -0
  11. data/lib/api/group_address_list.rb +63 -0
  12. data/lib/api/group_checkin.rb +36 -0
  13. data/lib/api/group_checkin_list.rb +63 -0
  14. data/lib/api/group_event_attendance.rb +28 -0
  15. data/lib/api/group_event_attendance_list.rb +63 -0
  16. data/lib/api/group_export.rb +22 -0
  17. data/lib/api/group_export_list.rb +63 -0
  18. data/lib/api/group_invitation.rb +26 -0
  19. data/lib/api/group_invitation_list.rb +63 -0
  20. data/lib/api/group_list.rb +74 -0
  21. data/lib/api/group_role.rb +27 -0
  22. data/lib/api/group_role_list.rb +62 -0
  23. data/lib/api/group_tag.rb +20 -0
  24. data/lib/api/group_tag_list.rb +62 -0
  25. data/lib/api/metric.rb +50 -0
  26. data/lib/api/metric_list.rb +72 -0
  27. data/lib/api/metric_measurement.rb +29 -0
  28. data/lib/api/metric_measurement_list.rb +62 -0
  29. data/lib/api/role.rb +43 -0
  30. data/lib/api/role_list.rb +73 -0
  31. data/lib/api/skill.rb +21 -0
  32. data/lib/api/skill_list.rb +73 -0
  33. data/lib/api/skilled_user_id_list.rb +73 -0
  34. data/lib/api/skilled_user_list.rb +73 -0
  35. data/lib/api/tag.rb +32 -0
  36. data/lib/api/tag_group_list.rb +73 -0
  37. data/lib/api/tag_list.rb +73 -0
  38. data/lib/api/terminology.rb +32 -0
  39. data/lib/api/terminology_list.rb +73 -0
  40. data/lib/api/user.rb +207 -0
  41. data/lib/api/user_address.rb +31 -0
  42. data/lib/api/user_address_list.rb +62 -0
  43. data/lib/api/user_admin_privilege.rb +28 -0
  44. data/lib/api/user_admin_privilege_list.rb +63 -0
  45. data/lib/api/user_barcode.rb +20 -0
  46. data/lib/api/user_count.rb +40 -0
  47. data/lib/api/user_family_list.rb +71 -0
  48. data/lib/api/user_family_member.rb +28 -0
  49. data/lib/api/user_invitation.rb +26 -0
  50. data/lib/api/user_invitation_list.rb +63 -0
  51. data/lib/api/user_list.rb +72 -0
  52. data/lib/api/user_note.rb +31 -0
  53. data/lib/api/user_note_list.rb +63 -0
  54. data/lib/api/user_process.rb +21 -0
  55. data/lib/api/user_process_list.rb +63 -0
  56. data/lib/api/user_role.rb +34 -0
  57. data/lib/api/user_role_list.rb +74 -0
  58. data/lib/api/user_skill.rb +22 -0
  59. data/lib/api/user_skill_list.rb +74 -0
  60. data/lib/api/web_hook.rb +34 -0
  61. data/lib/api/web_hook_list.rb +74 -0
  62. data/lib/auto_load.rb +23 -0
  63. data/lib/cachers/cache_adapter.rb +50 -0
  64. data/lib/cachers/file/json_cache.rb +135 -0
  65. data/lib/common.rb +124 -0
  66. data/lib/exceptions.rb +5 -0
  67. data/lib/readers/address_list_reader.rb +21 -0
  68. data/lib/readers/address_reader.rb +22 -0
  69. data/lib/readers/api_reader.rb +28 -0
  70. data/lib/readers/checkin_list_reader.rb +21 -0
  71. data/lib/readers/checkin_reader.rb +22 -0
  72. data/lib/readers/family_reader.rb +21 -0
  73. data/lib/readers/group_address_list_reader.rb +25 -0
  74. data/lib/readers/group_checkin_list_reader.rb +25 -0
  75. data/lib/readers/group_event_attendance_list_reader.rb +25 -0
  76. data/lib/readers/group_export_list_reader.rb +25 -0
  77. data/lib/readers/group_invitation_list_reader.rb +23 -0
  78. data/lib/readers/group_list_reader.rb +25 -0
  79. data/lib/readers/group_reader.rb +21 -0
  80. data/lib/readers/group_role_list_reader.rb +23 -0
  81. data/lib/readers/group_tag_list_reader.rb +23 -0
  82. data/lib/readers/metric_list_reader.rb +22 -0
  83. data/lib/readers/metric_measurement_list_reader.rb +21 -0
  84. data/lib/readers/metric_measurement_reader.rb +22 -0
  85. data/lib/readers/metric_reader.rb +21 -0
  86. data/lib/readers/role_list_reader.rb +21 -0
  87. data/lib/readers/skill_list_reader.rb +21 -0
  88. data/lib/readers/skilled_user_id_list_reader.rb +22 -0
  89. data/lib/readers/skilled_user_list_reader.rb +22 -0
  90. data/lib/readers/tag_group_list_reader.rb +22 -0
  91. data/lib/readers/tag_list_reader.rb +22 -0
  92. data/lib/readers/tag_reader.rb +22 -0
  93. data/lib/readers/terminology_list_reader.rb +22 -0
  94. data/lib/readers/terminology_reader.rb +22 -0
  95. data/lib/readers/user_address_list_reader.rb +25 -0
  96. data/lib/readers/user_admin_privilege_list_reader.rb +23 -0
  97. data/lib/readers/user_count_reader.rb +32 -0
  98. data/lib/readers/user_family_list_reader.rb +24 -0
  99. data/lib/readers/user_invitation_list_reader.rb +23 -0
  100. data/lib/readers/user_list_reader.rb +25 -0
  101. data/lib/readers/user_note_list_reader.rb +23 -0
  102. data/lib/readers/user_process_list_reader.rb +23 -0
  103. data/lib/readers/user_reader.rb +24 -0
  104. data/lib/readers/user_role_list_reader.rb +23 -0
  105. data/lib/readers/user_skill_list_reader.rb +23 -0
  106. data/lib/readers/web_hook_list_reader.rb +21 -0
  107. data/lib/the_city_admin.rb +82 -0
  108. data/lib/writers/api_writer.rb +54 -0
  109. data/lib/writers/family_writer.rb +25 -0
  110. data/lib/writers/group_address_writer.rb +32 -0
  111. data/lib/writers/group_writer.rb +25 -0
  112. data/lib/writers/metric_measurement_writer.rb +25 -0
  113. data/lib/writers/metric_writer.rb +29 -0
  114. data/lib/writers/skill_writer.rb +25 -0
  115. data/lib/writers/tag_writer.rb +27 -0
  116. data/lib/writers/terminology_writer.rb +19 -0
  117. data/lib/writers/user_address_writer.rb +32 -0
  118. data/lib/writers/user_admin_privilege_writer.rb +24 -0
  119. data/lib/writers/user_invitation_writer.rb +23 -0
  120. data/lib/writers/user_note_writer.rb +25 -0
  121. data/lib/writers/user_role_writer.rb +28 -0
  122. data/lib/writers/user_skill_writer.rb +23 -0
  123. data/lib/writers/user_writer.rb +46 -0
  124. data/lib/writers/web_hook_writer.rb +20 -0
  125. metadata +184 -0
data/lib/auto_load.rb ADDED
@@ -0,0 +1,23 @@
1
+ module TheCity
2
+
3
+ require THECITY_LIB_DIR + '/exceptions.rb'
4
+
5
+ api_path = THECITY_LIB_DIR + '/api/'
6
+ require api_path + 'api_object.rb'
7
+ Dir["#{api_path}/*.rb"].each { |f| require(f) }
8
+
9
+ cache_path = THECITY_LIB_DIR + '/cachers/'
10
+ require cache_path + 'cache_adapter.rb'
11
+
12
+ cache_file_path = THECITY_LIB_DIR + '/cachers/file/'
13
+ Dir["#{cache_file_path}/*.rb"].each { |f| require(f) }
14
+
15
+ readers_path = THECITY_LIB_DIR + '/readers/'
16
+ require readers_path + 'api_reader.rb'
17
+ Dir["#{readers_path}/*.rb"].each { |f| require(f) }
18
+
19
+ writers_path = THECITY_LIB_DIR + '/writers/'
20
+ require writers_path + 'api_writer.rb'
21
+ Dir["#{writers_path}/*.rb"].each { |f| require(f) }
22
+
23
+ end
@@ -0,0 +1,50 @@
1
+ module TheCity
2
+
3
+ # This adapter is the standard for all caching objects.
4
+ class CacheAdapter
5
+
6
+ # Constructor
7
+ def initialize()
8
+ end
9
+
10
+
11
+ # Save data to the cache.
12
+ #
13
+ # * <b>key</b> The key to use to save the cache.
14
+ # * <b>data</b> The JSON data to be saved.
15
+ # * <b>expire_on (optional)</b> The datetime to expire the cache.
16
+ #
17
+ # Returns true on success or a string error message on false.
18
+ def save_data(key, data, expire_on = nil)
19
+ raise 'The save_data method must be implemented'
20
+ end
21
+
22
+
23
+ # Get the data from the cache.
24
+ #
25
+ # * <b>key</b> The key to use to get the cache.
26
+ #
27
+ # Returns the data for the key in the same way it was stored.
28
+ def get_data(key)
29
+ raise 'The get_data method must be implemented'
30
+ end
31
+
32
+
33
+ # Expire the cache.
34
+ #
35
+ # * <b>key</b> The key to use to expire the cache.
36
+ def expire_cache!(key)
37
+ raise 'The expire_cache method must be implemented'
38
+ end
39
+
40
+
41
+ # Check if the cache has expired.
42
+ #
43
+ # * <b>key</b> The key to use to check if the cache has expired.
44
+ def is_cache_expired?(key)
45
+ raise 'The is_cache_expired method must be implemented'
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,135 @@
1
+ # Project:: Admin-Ruby
2
+ # File:: json_cache.rb
3
+
4
+ require 'fileutils'
5
+
6
+
7
+ module TheCity
8
+
9
+ # This class caches the data in a JSON file.
10
+ class JsonCache < CacheAdapter
11
+
12
+ # Constructor.
13
+ def initialize()
14
+ super
15
+ @cache_dir = THECITY_STORAGE_DIR + subdomain + '/';
16
+ end
17
+
18
+
19
+ # Save data to the cache.
20
+ #
21
+ # @param string key The key to use to save the cache.
22
+ # @param string data The JSON data to be saved.
23
+ # @param string expire_in The number of seconds to pass before expiring the cache.
24
+ #
25
+ # @return mixed Returns true on success or a string error message on false.
26
+ def save_data(key, data, expire_in = nil)
27
+ expire_in = 3600 if expire_in.nil? # 3600 seconds = 1 hour
28
+ expire_in += Time.now.to_i
29
+
30
+ _create_cache_directory_if_needed
31
+ expire_cache!(key)
32
+
33
+ filename = "#{key}-#{expire_in}-json.cache"
34
+
35
+ begin
36
+ File.open(@cache_dir + filename, 'w') {|f| f.write( Marshal.dump(data) ) }
37
+ rescue
38
+ return 'Unable to write to file'
39
+ end
40
+
41
+ return true
42
+ end
43
+
44
+
45
+ # Get the file name where the cache is stored.
46
+ #
47
+ # @param string $key The key used for the cache.
48
+ #
49
+ # @return mixed Returns the name of the cache file if found or false.
50
+ def get_cache_file(key)
51
+ _find_file_key(key)
52
+ end
53
+
54
+
55
+ # Get the data from the cache.
56
+ #
57
+ # @param string key The key to use to get the cache.
58
+ #
59
+ # @return JSON data.
60
+ def get_data(key)
61
+ filename = _find_file_key(key)
62
+ return nil if filename.nil?
63
+ file = File.open(@cache_dir + filename, "rb")
64
+ contents = file.read
65
+ return Marshal.load(contents)
66
+ end
67
+
68
+
69
+ # Expire the cache.
70
+ #
71
+ # @param string key The key to use to expire the cache.
72
+ #
73
+ # @throws Exception if unable to remove cache file.
74
+ def expire_cache!(key)
75
+ file = _find_file_key(key)
76
+ unless file.nil?
77
+ begin
78
+ File.unlink(@cache_dir + file)
79
+ rescue
80
+ raise new Exception("Unable to remove cache file: $file")
81
+ end
82
+ end
83
+ end
84
+
85
+
86
+ # Check if the cache has expired.
87
+ #
88
+ # @param string key The key to use to check if the cache has expired.
89
+ #
90
+ # @return boolean If the cache does not exist or is expired then true, otherwise false.
91
+ def is_cache_expired?(key)
92
+ time_stamp_position = 1;
93
+ fname = _find_file_key(key)
94
+ return true if fname.nil?
95
+
96
+ fname_a = fname.split('-')
97
+ if Time.now.to_i > fname_a[time_stamp_position].to_i
98
+ return true
99
+ end
100
+
101
+ return false;
102
+ end
103
+
104
+
105
+ private
106
+
107
+
108
+ # @ignore
109
+ def _create_cache_directory_if_needed
110
+ unless File.exist?( @cache_dir )
111
+ unless FileUtils.mkdir_p( @cache_dir )
112
+ raise new Exception('Failed to create cache directory')
113
+ end
114
+ end
115
+ end
116
+
117
+
118
+ # @ignore
119
+ def _find_file_key(key)
120
+ if File.exist?(@cache_dir)
121
+ return Dir.entries( @cache_dir ).detect{ |f| f.include?("#{key}-") }
122
+ end
123
+ return nil
124
+ end
125
+
126
+
127
+ # @ignore
128
+ def _all_cache_files(key)
129
+ Dir.entries( @cache_dir ).select{ |f| f.include?("-json.cache") }
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+
data/lib/common.rb ADDED
@@ -0,0 +1,124 @@
1
+ module TheCity
2
+ require 'cgi'
3
+
4
+ def self.admin_request(method, path, params = {})
5
+ # data_params = params.inject({}) {|h, (k,v)| h.update({k => v.nil? ? v : v.to_s})}
6
+ # flattened_params = self._flatten_params(data_params)
7
+
8
+ flattened_params = self._flatten_params(params)
9
+
10
+ # puts "############################"
11
+ # puts "flattened_params: #{flattened_params}"
12
+ # puts "############################"
13
+
14
+ headers = self._build_admin_headers(method, path, flattened_params)
15
+ url = THE_CITY_ADMIN_PATH+path
16
+
17
+ response =
18
+ case method
19
+ when :post
20
+ Typhoeus::Request.post(url, {:headers => headers, :params => flattened_params})
21
+ when :get
22
+ Typhoeus::Request.get(url, {:headers => headers, :params => flattened_params})
23
+ when :put
24
+ Typhoeus::Request.put(url, {:headers => headers, :params => flattened_params})
25
+ when :delete
26
+ Typhoeus::Request.delete(url, {:headers => headers, :params => flattened_params})
27
+ end
28
+
29
+ unless response.success?
30
+ if response.curl_error_message != 'No error'
31
+ raise TheCityExceptions::UnableToConnectToTheCity.new(response.curl_error_message)
32
+ else
33
+ begin
34
+ error_messages = JSON.parse(response.body)['error_message']
35
+ rescue
36
+ raise TheCityExceptions::UnknownErrorConnectingToTheCity.new('Unknown error when connecting to The City')
37
+ else
38
+ raise TheCityExceptions::TheCityResponseError.new(error_messages)
39
+ end
40
+ end
41
+ end
42
+
43
+ response
44
+ end
45
+
46
+
47
+ def self._flatten_params(params, prefix='')
48
+ retval = []
49
+ if params.instance_of?(Array)
50
+ if params.empty?
51
+ retval << self._flatten_params('', "#{prefix.to_s}[0]")
52
+ else
53
+ params.each_with_index do |value, indx|
54
+ retval << self._flatten_params(value, "#{prefix.to_s}[#{indx}]")
55
+ end
56
+ end
57
+ elsif params.instance_of?(Hash)
58
+ params.each do |key, value|
59
+ retval << self._flatten_params(value, prefix.empty? ? key.to_s : "#{prefix}[#{key.to_s}]")
60
+ end
61
+ else # assume string
62
+ retval << "#{prefix}=#{params}"
63
+ end
64
+
65
+ if prefix.empty?
66
+ hvals = {}
67
+ retval.flatten.sort.each { |v| hvals[v.split('=')[0]] = v.split('=')[1] }
68
+ hvals
69
+ else
70
+ retval.flatten.sort
71
+ end
72
+ #retval.flatten.sort
73
+ end
74
+
75
+
76
+
77
+ def self._build_admin_headers(method, path, params)
78
+ # get_vars = '?' + params.to_a.sort.collect { |kv_pair| "#{kv_pair[0]}=#{kv_pair[1]}" }.join('&')
79
+ # get_vars = '' if get_vars == '?'
80
+
81
+
82
+ get_vars = '?' + params.to_a.sort.collect { |kv_pair|
83
+ if kv_pair[1].class == Array
84
+ puts "ARRAY"
85
+ kv_pair[1].each_with_index do |v, indx|
86
+ "#{kv_pair[0]}[#{indx}]=#{v}"
87
+ end
88
+ else
89
+ "#{kv_pair[0]}=#{kv_pair[1]}"
90
+ end
91
+ }.join('&')
92
+ get_vars = '' if get_vars == '?'
93
+
94
+
95
+ # puts "############################"
96
+ # puts "params: #{params}"
97
+ # puts '------------'
98
+ # puts "get_vars: #{get_vars}"
99
+ # puts "############################"
100
+
101
+ method_request = method.to_s.upcase
102
+ url = THE_CITY_ADMIN_PATH + path + get_vars
103
+ current_time = Time.now.to_i.to_s
104
+ string_to_sign = current_time.to_s + method_request + url
105
+ unencoded_hmac = OpenSSL::HMAC.digest('sha256', TheCity::AdminApi::API_KEY, string_to_sign)
106
+ unescaped_hmac = Base64.encode64(unencoded_hmac).chomp
107
+ hmac_signature = CGI.escape(unescaped_hmac)
108
+
109
+ headers = {'X-City-Sig' => hmac_signature,
110
+ 'X-City-User-Token' => TheCity::AdminApi::API_TOKEN,
111
+ 'X-City-Time' => current_time,
112
+ 'Accept' => 'application/vnd.thecity.admin.v1+json'}
113
+
114
+
115
+ # This is causing issues.... not sure if it is needed (docs might be lieing)
116
+ # if [:post, :put].include?(method)
117
+ # headers['Content-Type'] = 'application/json'
118
+ # headers['Content-Length'] = params.to_json.length
119
+ # end
120
+
121
+ headers
122
+ end
123
+
124
+ end
data/lib/exceptions.rb ADDED
@@ -0,0 +1,5 @@
1
+ module TheCityExceptions
2
+ class UnableToConnectToTheCity < StandardError; end
3
+ class UnknownErrorConnectingToTheCity < StandardError; end
4
+ class TheCityResponseError < StandardError; end
5
+ end
@@ -0,0 +1,21 @@
1
+ module TheCity
2
+
3
+ class AddressListReader < ApiReader
4
+
5
+ # Constructor.
6
+ #
7
+ # @param options A hash of options for requesting data from the server.
8
+ # @param [CacheAdapter] cacher (optional) The cacher to be used to cache data.
9
+ def initialize(options = {}, cacher = nil)
10
+ page = options[:page] || 1
11
+ @class_key = "address_list_#{page}"
12
+ @url_data_path = "/addresses"
13
+ @url_data_params = {:page => page}
14
+
15
+ # The object to store and load the cache.
16
+ @cacher = cacher unless cacher.nil?
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,22 @@
1
+ module TheCity
2
+
3
+ class AddressReader < ApiReader
4
+
5
+ # Constructor.
6
+ #
7
+ # @param address_id The ID of the address to load.
8
+ # @param options (optional) Options for including more information.
9
+ # @param [CacheAdapter] cacher (optional) The cacher to be used to cache data.
10
+ def initialize(address_id, options = {}, cacher = nil)
11
+ @class_key = "address_#{address_id}"
12
+ @url_data_path = "/addresses/#{address_id}"
13
+
14
+ # The object to store and load the cache.
15
+ @cacher = cacher unless cacher.nil?
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+
22
+
@@ -0,0 +1,28 @@
1
+ module TheCity
2
+
3
+ # This adapter is the standard for all loading objects.
4
+ class ApiReader
5
+
6
+ # Constructor
7
+ # def initialize
8
+ # end
9
+
10
+ # Loads the list
11
+ #
12
+ # @return the data loaded in a JSON object.
13
+ def load_feed
14
+ if !@cacher.nil? and !@cacher.is_cache_expired?( @class_key )
15
+ data = @cacher.get_data( @class_key )
16
+ else
17
+ @url_data_params ||= {}
18
+ response = TheCity::admin_request(:get, @url_data_path, @url_data_params)
19
+ data = JSON.parse(response.body)
20
+ @cacher.save_data(@class_key, data) unless @cacher.nil?
21
+ end
22
+
23
+ return data
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,21 @@
1
+ module TheCity
2
+
3
+ class CheckinListReader < ApiReader
4
+
5
+ # Constructor.
6
+ #
7
+ # @param options A hash of options for requesting data from the server.
8
+ # @param [CacheAdapter] cacher (optional) The cacher to be used to cache data.
9
+ def initialize(options = {}, cacher = nil)
10
+ page = options[:page] || 1
11
+ @class_key = "checkin_list_#{page}"
12
+ @url_data_path = "/checkins"
13
+ @url_data_params = {:page => page}
14
+
15
+ # The object to store and load the cache.
16
+ @cacher = cacher unless cacher.nil?
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,22 @@
1
+ module TheCity
2
+
3
+ class CheckinReader < ApiReader
4
+
5
+ # Constructor.
6
+ #
7
+ # @param checkin_id The ID of the checkin to load.
8
+ # @param options (optional) Options for including more information.
9
+ # @param [CacheAdapter] cacher (optional) The cacher to be used to cache data.
10
+ def initialize(checkin_id, options = {}, cacher = nil)
11
+ @class_key = "checkin_#{tag_id}"
12
+ @url_data_path = "/checkins/#{tag_id}"
13
+
14
+ # The object to store and load the cache.
15
+ @cacher = cacher unless cacher.nil?
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+
22
+