the-city-admin 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+