badgeville_berlin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/.yardoc/checksums +17 -0
  5. data/.yardoc/objects/root.dat +0 -0
  6. data/.yardoc/proxy_types +0 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.md +7 -0
  9. data/README.md +150 -0
  10. data/README_ADVANCED.md +120 -0
  11. data/Rakefile +11 -0
  12. data/badgeville.gemspec +36 -0
  13. data/doc/BadgevilleBerlin.html +131 -0
  14. data/doc/BadgevilleBerlin/Activity.html +135 -0
  15. data/doc/BadgevilleBerlin/ActivityDefinition.html +135 -0
  16. data/doc/BadgevilleBerlin/BaseResource.html +462 -0
  17. data/doc/BadgevilleBerlin/Config.html +280 -0
  18. data/doc/BadgevilleBerlin/Errors.html +276 -0
  19. data/doc/BadgevilleBerlin/Group.html +135 -0
  20. data/doc/BadgevilleBerlin/Leaderboard.html +135 -0
  21. data/doc/BadgevilleBerlin/Player.html +135 -0
  22. data/doc/BadgevilleBerlin/Reward.html +135 -0
  23. data/doc/BadgevilleBerlin/RewardDefinition.html +135 -0
  24. data/doc/BadgevilleBerlin/Site.html +135 -0
  25. data/doc/BadgevilleBerlin/Track.html +135 -0
  26. data/doc/BadgevilleBerlin/User.html +135 -0
  27. data/doc/BadgevilleBerlinJsonFormat.html +530 -0
  28. data/doc/_index.html +285 -0
  29. data/doc/class_list.html +47 -0
  30. data/doc/css/common.css +1 -0
  31. data/doc/css/full_list.css +53 -0
  32. data/doc/css/style.css +320 -0
  33. data/doc/file.README.html +182 -0
  34. data/doc/file_list.html +49 -0
  35. data/doc/frames.html +13 -0
  36. data/doc/index.html +182 -0
  37. data/doc/js/app.js +205 -0
  38. data/doc/js/full_list.js +150 -0
  39. data/doc/js/jquery.js +16 -0
  40. data/doc/method_list.html +118 -0
  41. data/doc/top-level-namespace.html +103 -0
  42. data/examples/.DS_Store +0 -0
  43. data/examples/shell/.DS_Store +0 -0
  44. data/examples/shell/lib/.DS_Store +0 -0
  45. data/examples/shell/lib/berlin_shell.rb +34 -0
  46. data/examples/shell/lib/berlin_shell/.DS_Store +0 -0
  47. data/examples/shell/lib/berlin_shell/cd.rb +17 -0
  48. data/examples/shell/lib/berlin_shell/core.rb +118 -0
  49. data/examples/shell/lib/berlin_shell/ls.rb +72 -0
  50. data/examples/shell/lib/berlin_shell/prompt.rb +39 -0
  51. data/examples/shell/shell_demo.rb +319 -0
  52. data/examples/shell/spec/integration/basic_spec.rb +7 -0
  53. data/lib/.yardoc/checksums +0 -0
  54. data/lib/.yardoc/objects/root.dat +0 -0
  55. data/lib/.yardoc/proxy_types +0 -0
  56. data/lib/badgeville_berlin.rb +24 -0
  57. data/lib/badgeville_berlin/.yardoc/checksums +0 -0
  58. data/lib/badgeville_berlin/.yardoc/objects/root.dat +0 -0
  59. data/lib/badgeville_berlin/.yardoc/proxy_types +0 -0
  60. data/lib/badgeville_berlin/activity.rb +5 -0
  61. data/lib/badgeville_berlin/activity_definition.rb +5 -0
  62. data/lib/badgeville_berlin/base_resource.rb +68 -0
  63. data/lib/badgeville_berlin/config.rb +36 -0
  64. data/lib/badgeville_berlin/doc/_index.html +84 -0
  65. data/lib/badgeville_berlin/doc/class_list.html +47 -0
  66. data/lib/badgeville_berlin/doc/css/common.css +1 -0
  67. data/lib/badgeville_berlin/doc/css/full_list.css +53 -0
  68. data/lib/badgeville_berlin/doc/css/style.css +320 -0
  69. data/lib/badgeville_berlin/doc/file_list.html +46 -0
  70. data/lib/badgeville_berlin/doc/frames.html +13 -0
  71. data/lib/badgeville_berlin/doc/index.html +84 -0
  72. data/lib/badgeville_berlin/doc/js/app.js +205 -0
  73. data/lib/badgeville_berlin/doc/js/full_list.js +150 -0
  74. data/lib/badgeville_berlin/doc/js/jquery.js +16 -0
  75. data/lib/badgeville_berlin/doc/method_list.html +46 -0
  76. data/lib/badgeville_berlin/doc/top-level-namespace.html +93 -0
  77. data/lib/badgeville_berlin/errors.rb +28 -0
  78. data/lib/badgeville_berlin/formats/badgeville_berlin_json_format.rb +55 -0
  79. data/lib/badgeville_berlin/group.rb +5 -0
  80. data/lib/badgeville_berlin/leaderboard.rb +5 -0
  81. data/lib/badgeville_berlin/player.rb +5 -0
  82. data/lib/badgeville_berlin/reward.rb +5 -0
  83. data/lib/badgeville_berlin/reward_definition.rb +5 -0
  84. data/lib/badgeville_berlin/site.rb +5 -0
  85. data/lib/badgeville_berlin/track.rb +5 -0
  86. data/lib/badgeville_berlin/user.rb +5 -0
  87. data/lib/badgeville_berlin/version.rb +3 -0
  88. data/lib/doc/_index.html +84 -0
  89. data/lib/doc/class_list.html +47 -0
  90. data/lib/doc/css/common.css +1 -0
  91. data/lib/doc/css/full_list.css +53 -0
  92. data/lib/doc/css/style.css +320 -0
  93. data/lib/doc/file_list.html +46 -0
  94. data/lib/doc/frames.html +13 -0
  95. data/lib/doc/index.html +84 -0
  96. data/lib/doc/js/app.js +205 -0
  97. data/lib/doc/js/full_list.js +150 -0
  98. data/lib/doc/js/jquery.js +16 -0
  99. data/lib/doc/method_list.html +46 -0
  100. data/lib/doc/top-level-namespace.html +93 -0
  101. data/spec/factories.rb +54 -0
  102. data/spec/integration/activity_spec.rb +0 -0
  103. data/spec/integration/basic_spec.rb +68 -0
  104. data/spec/integration/player_spec.rb +6 -0
  105. data/spec/integration/site_spec.rb +11 -0
  106. data/spec/integration/user_spec.rb +3 -0
  107. data/spec/response_json.yml +36 -0
  108. data/spec/spec_helper.rb +60 -0
  109. data/spec/unit/badgeville_berlin_json_format_spec.rb +68 -0
  110. data/spec/unit/base_resource_spec.rb +47 -0
  111. data/spec/unit/config_spec.rb +65 -0
  112. data/spec/unit/errors_spec.rb +47 -0
  113. data/spec/use_case/readme_use_case_spec.rb +262 -0
  114. metadata +286 -0
@@ -0,0 +1,118 @@
1
+ module BadgevilleBerlin::Shell
2
+ class Core
3
+
4
+ class << self
5
+ attr_accessor 'sites', 'working_path_parts', 'cache'
6
+ end
7
+
8
+ self.sites = []
9
+ self.working_path_parts = {:site => nil, :object => nil, :item => nil}
10
+ self.cache = {:site => nil, :item => nil}
11
+
12
+ @@objects = {
13
+ "Activity" => BadgevilleBerlin::Activity,
14
+ "ActivityDefinition" => BadgevilleBerlin::ActivityDefinition,
15
+ "Group" => BadgevilleBerlin::Group,
16
+ "Leaderboard" => BadgevilleBerlin::Leaderboard,
17
+ "Player" => BadgevilleBerlin::Player,
18
+ "Reward" => BadgevilleBerlin::Reward,
19
+ "RewardDefinition" => BadgevilleBerlin::RewardDefinition,
20
+ "Track" => BadgevilleBerlin::Track,
21
+ "User" => BadgevilleBerlin::User
22
+ }
23
+
24
+ def self.objects
25
+ @@objects
26
+ end
27
+
28
+ def self.working_path
29
+ path = "/"
30
+ [:site, :object, :item].each do |index|
31
+ if Core.working_path_parts[index] != nil
32
+ path += Core.working_path_parts[index] + "/"
33
+ end
34
+ end
35
+ return path
36
+ end
37
+
38
+ def self.parse_path (path)
39
+ if !path.match /^\// # Relative Path
40
+ path = Core.working_path + path
41
+ end
42
+ path = path.sub(/^\/*/,"").sub(/\/$/,"") # Trim /
43
+ parts = path.split("/")
44
+
45
+ # Handle ../../
46
+ parts_clean = []
47
+ parts.each_index do |i|
48
+ if parts[i] == '..'
49
+ parts_clean.delete_at(parts_clean.length - 1)
50
+ elsif parts[i] != '.'
51
+ parts_clean.push(parts[i])
52
+ end
53
+ end
54
+
55
+ return {:site => parts_clean[0], :object => parts_clean[1], :item => parts_clean[2]}
56
+ end
57
+
58
+ def self.find_prefix (prefix, list)
59
+ found = false
60
+ list.each do |item|
61
+ if item.id
62
+ if item.id.match /^ + prefix + /
63
+ return item
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ def self.valid_path_parts (path_parts)
70
+ if path_parts[:site] == nil
71
+ return true
72
+ end
73
+
74
+ # Validate site
75
+ site = self.is_site_cached(path_parts[:site])
76
+ if !site
77
+ begin
78
+ site = BadgevilleBerlin::Site.find(path_parts[:site])
79
+ self.cache[:site] = site
80
+ rescue
81
+ return false
82
+ end
83
+ end
84
+
85
+ # Validate Object
86
+ if path_parts[:object] != nil && !Core.objects[path_parts[:object]]
87
+ return false
88
+ end
89
+
90
+ # Validate item
91
+ if path_parts[:item] != nil && !self.is_item_cached(path_parts[:item])
92
+ begin
93
+ item = Core.objects[path_parts[:object]].find(path_parts[:item]) # currently only works for id
94
+ self.cache[:item] = item
95
+ rescue
96
+ return false
97
+ end
98
+ end
99
+
100
+ return true
101
+ end
102
+
103
+ def self.is_site_cached (site)
104
+ if self.cache[:site] == nil
105
+ return false
106
+ end
107
+ return (self.cache[:site].attributes[:url] == site || self.cache[:site].attributes[:_id] == site) ? self.cache[:site] : false
108
+ end
109
+
110
+ def self.is_item_cached (item)
111
+ if self.cache[:item] == nil
112
+ return false
113
+ end
114
+ return (cache[:item].attributes[:email] == item || cache[:item].attributes[:_id] == item) ? cache[:item] : false
115
+ end
116
+
117
+ end
118
+ end
@@ -0,0 +1,72 @@
1
+ module BadgevilleBerlin::Shell
2
+ class LS
3
+ @@spacer = "\n"
4
+
5
+ def self.execute (path)
6
+ path_parts = (path == nil) ? Core.working_path_parts : Core.parse_path(path)
7
+
8
+ if !Core.valid_path_parts(path_parts)
9
+ say "Path is not valid."
10
+ return
11
+ end
12
+
13
+ if path_parts[:site] == nil
14
+ items = self.get_sites
15
+ elsif path_parts[:object] == nil
16
+ items = self.get_objects
17
+ elsif path_parts[:item] == nil
18
+ items = self.get_items(path_parts)
19
+ else
20
+ items = self.get_details(path_parts)
21
+ end
22
+
23
+ say items.join(@@spacer)
24
+ end
25
+
26
+ def self.get_sites
27
+ items = []
28
+ page = 1
29
+ while true
30
+ sites = BadgevilleBerlin::Site.find(:all, :params => {:page => page, :per_page => 50})
31
+ if sites.empty?
32
+ break
33
+ else
34
+ sites.each do |site|
35
+ Core.sites.push(site)
36
+ end
37
+ page = page + 1
38
+ end
39
+ end
40
+ Core.sites.each do |site|
41
+ items.push(site.id + " (" + site.url + ")")
42
+ end
43
+
44
+ return items
45
+ end
46
+
47
+ def self.get_objects ()
48
+ items = []
49
+ Core.objects.each do |name, obj|
50
+ items.push(name)
51
+ end
52
+ return items
53
+ end
54
+
55
+ def self.get_items (path_parts)
56
+ items = []
57
+ params = {}
58
+ params[:site] = path_parts[:site]
59
+ Core.objects[path_parts[:object]].find(:all, params).each do |item|
60
+ # Use ID, but try to add email then name if available
61
+ items.push((item.attributes["_id"] || item.attributes["id"]) + (item.attributes["email"] ? " (" + item.attributes["email"] + ")" : (item.attributes["name"] ? " (" + item.attributes["name"] + ")" : "") ))
62
+ end
63
+ return items
64
+ end
65
+
66
+ def self.get_details (path_parts)
67
+ items = []
68
+ items.push(Core.objects[path_parts[:object]].find(path_parts[:item]).to_yaml)
69
+ return items
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,39 @@
1
+ module BadgevilleBerlin::Shell
2
+ class Prompt
3
+ def self.listen
4
+ instructions = ask(Core.working_path + " >> " ).split(" ", 2)
5
+
6
+ if instructions.empty?
7
+ return true
8
+ end
9
+
10
+ case instructions[0].downcase
11
+ when 'exit'
12
+ say 'Goodbye!'
13
+ return false
14
+
15
+ when 'ls'
16
+ begin
17
+ LS.execute(instructions[1])
18
+ rescue
19
+ say('ls failed')
20
+ end
21
+
22
+ when 'cd'
23
+ CD.execute(instructions[1])
24
+
25
+ when 'rm'
26
+ Commands.rm(instructions[1])
27
+
28
+ when 'touch'
29
+ Commands.touch(instructions[1])
30
+
31
+ when "pwd"
32
+ Commands.pwd
33
+ else
34
+ end
35
+
36
+ return true
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,319 @@
1
+ require "rubygems"
2
+ require "ruby-debug"
3
+ require "badgeville_berlin"
4
+ require "highline/import"
5
+
6
+ # We created a shell using the Berlin Gem. In other words, we have created a terminal for the publisher module.
7
+ #
8
+ # 1.
9
+ # P: A client needs a list of sites within their network.
10
+ # A: ls /
11
+ #
12
+ # 2.
13
+ # P: A client needs a list of players within a site.
14
+ # A: cd /staging.widgets.badgeville.com/Player
15
+ # P: To get player details
16
+ # A: ls 4d8bb5e8d0c0b35cd7000002
17
+ #
18
+ # 3.
19
+ # P: A client may also list leaderboards
20
+ # A: ls
21
+
22
+ module BerlinShell
23
+ HOST = "hostname"
24
+ APIKEY = "api_key"
25
+ NETWORK_ID = "network_id"
26
+ ENDPOINT = "/api/berlin/"
27
+ SPACER = "\n"
28
+ BadgevilleBerlin::Config.conf(:host_name => 'http://' + HOST + '/', :api_key => APIKEY)
29
+ say "Connected to " + HOST
30
+
31
+ @@bv_objs = {
32
+ "Activity" => BadgevilleBerlin::Activity,
33
+ "ActivityDefinition" => BadgevilleBerlin::ActivityDefinition,
34
+ "Group" => BadgevilleBerlin::Group,
35
+ "Leaderboard" => BadgevilleBerlin::Leaderboard,
36
+ "Player" => BadgevilleBerlin::Player,
37
+ "Reward" => BadgevilleBerlin::Reward,
38
+ "RewardDefinition" => BadgevilleBerlin::RewardDefinition,
39
+ "Site" => BadgevilleBerlin::Site,
40
+ "Track" => BadgevilleBerlin::Track,
41
+ "User" => BadgevilleBerlin::User
42
+ }
43
+ @@sites = BadgevilleBerlin::Site.find(:all)
44
+ @@working_path_parts = ["Staging"]
45
+ @@item = nil
46
+
47
+ def self.item
48
+ @@item
49
+ end
50
+ def self.item=(item)
51
+ @@item = item
52
+ end
53
+
54
+ def self.bv_objs
55
+ @@bv_objs
56
+ end
57
+
58
+ def self.sites
59
+ @@sites
60
+ end
61
+
62
+ def self.sites=(sites)
63
+ @@sites = sites
64
+ end
65
+
66
+ # Site/Object/ID, touch ABC.COM/player/; touch {email: name: etc,}
67
+ def self.working_path_parts
68
+ @@working_path_parts
69
+ end
70
+ def self.working_path_parts=(parts)
71
+ @@working_path_parts = parts
72
+ end
73
+
74
+ def self.parse_path (path)
75
+ if path == "/"
76
+ path = "/Staging"
77
+ end
78
+
79
+ # Handle ../
80
+ if ((path == "../" || path == "..") && BerlinShell.working_path_parts.length > 1)
81
+ BerlinShell.working_path_parts.pop
82
+ path = ""
83
+ end
84
+
85
+ if !path.match /^\// # Relative Path
86
+ path = BerlinShell.working_path_parts.join("/") + "/" + path
87
+ elsif !path.match /^\/Staging/ # Absolute Path w.out /Site
88
+ path = "/Staging" + path
89
+ end
90
+
91
+ path = path.sub(/^\/*/,"").sub(/\/$/,"") # Trim /
92
+ parts = path.split("/")
93
+
94
+ parts
95
+ end
96
+
97
+ def self.find_prefix (prefix, list)
98
+ found = false
99
+ list.each do |item|
100
+ if item.id
101
+ if item.id.match /^ + prefix + /
102
+ return item
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def self.valid_path_parts (parts)
109
+ if parts.length == 1
110
+ return true
111
+ end
112
+
113
+ # Validate site
114
+ if !get_site(parts[1])
115
+ return false
116
+ end
117
+
118
+ # Validate Object
119
+ if parts[2] && !BerlinShell.bv_objs[parts[2]]
120
+ return false
121
+ end
122
+
123
+ # Validate item
124
+ if parts[3]
125
+ # needs to be coded
126
+ end
127
+
128
+ return true
129
+ end
130
+
131
+ def self.get_site (needle)
132
+ found = false
133
+ BerlinShell.sites.each do |site|
134
+ if site.url == needle || site.id == needle
135
+ found = site
136
+ end
137
+ end
138
+ return found
139
+ end
140
+
141
+
142
+ class Commands
143
+ def self.ls (path)
144
+ path_parts = (path == nil) ? BerlinShell.working_path_parts : BerlinShell.parse_path(path)
145
+ items = []
146
+ if !BerlinShell.valid_path_parts(path_parts)
147
+ say "Path is not valid."
148
+ return
149
+ end
150
+
151
+ case path_parts.length
152
+ when 1 # List Sites
153
+ page = 1
154
+ while true
155
+ sites = BadgevilleBerlin::Site.find(:all, :params => {:page => page, :per_page => 50 })
156
+ if sites.empty?
157
+ break
158
+ else
159
+ sites.each do|site|
160
+ BerlinShell.sites.push(site)
161
+ end
162
+ page = page + 1
163
+ end
164
+ end
165
+
166
+ BerlinShell.sites.each do |site|
167
+ items.push(site.id + " (" + site.url + ")")
168
+ end
169
+ when 2 # List Objects
170
+ BerlinShell.bv_objs.each do |name, obj|
171
+ items.push(name)
172
+ end
173
+ when 3 # List Items
174
+
175
+ params = {}
176
+ case path_parts[2]
177
+ when "User"
178
+ puts "ls user"
179
+ page = 1
180
+ while true
181
+ users = BadgevilleBerlin::User.find(:all, :params => {:page => page, :per_page => 50 })
182
+ if users.empty?
183
+ break
184
+ else
185
+ users.each do|user|
186
+ items.push("#{user.attributes["_id"]} (#{user.attributes["email"]}) #{user.attributes["name"]}")
187
+ end
188
+ page = page + 1
189
+ end
190
+ end
191
+ else
192
+ params[:site] = path_parts[1]
193
+ BerlinShell.bv_objs[path_parts[2]].find(:all, params).each do |item|
194
+ # Use ID, but try to add email then name if available
195
+ items.push((item.attributes["_id"] || item.attributes["id"]) + (item.attributes["email"] ? " (" + item.attributes["email"] + ")" : (item.attributes["name"] ? " (" + item.attributes["name"] + ")" : "") ))
196
+ end
197
+ end
198
+ when 4 # List Details
199
+ items.push(BerlinShell.bv_objs[path_parts[2]].find(path_parts[3]).to_yaml)
200
+ end
201
+
202
+ say items.join(SPACER)
203
+ end
204
+
205
+ def self.cd (path)
206
+ if (path == nil)
207
+ say ("Missing argument.")
208
+ return
209
+ end
210
+ path_parts = BerlinShell.parse_path(path)
211
+ if BerlinShell.valid_path_parts(path_parts)
212
+ BerlinShell.working_path_parts = path_parts
213
+ else
214
+ say "Path is not valid."
215
+ end
216
+ end
217
+
218
+ def self.touch(args)
219
+
220
+ #write touch
221
+ begin
222
+ param_hash = eval(args)
223
+ rescue
224
+ say "Arguments for touch must be a hash (e.g. {\"name\" => \"site\", \"url\" => \"url.com\"})"
225
+ return
226
+ end
227
+
228
+ path_parts = BerlinShell.working_path_parts
229
+ part = path_parts[path_parts.length-1]
230
+
231
+ merged_hash = {}
232
+ if part == "User" || part == "Site"
233
+ merged_hash = {:network_id => NETWORK_ID}
234
+ elsif part == "Player" || part == "ActivityDefinition" || part == "RewardDefinition"
235
+ merged_hash = {:site_id => path_parts[1]}
236
+ end
237
+ param_hash = param_hash.merge(merged_hash)
238
+
239
+
240
+ if path_parts.length == 4
241
+ say "You cannot create an attribute on a record"
242
+ elsif path_parts.length == 2
243
+ say "Have to be inside a model dir to create a record."
244
+ else
245
+ begin
246
+ object = "BadgevilleBerlin::#{part}".constantize.new(param_hash)
247
+ success = object.save
248
+ rescue
249
+ say("You passed invalid arguments to create a #{part}.")
250
+ return
251
+ end
252
+
253
+ if success
254
+ puts object
255
+ say "Successfully created #{part} with arguments #{args}"
256
+ else
257
+ say "Failed to create #{part}."
258
+ end
259
+ end
260
+ end
261
+
262
+ def self.rm (id)
263
+ if (id == nil)
264
+ say ("Missing argument.")
265
+ end
266
+
267
+ path_parts = BerlinShell.working_path_parts
268
+ part = path_parts[path_parts.length-1]
269
+
270
+ if path_parts.length == 4
271
+ puts "You cannot delete attributes on a record"
272
+ else
273
+ begin
274
+ #check that record still exists remotely (race condition)
275
+ object = "BadgevilleBerlin::#{part}".constantize.find(id)
276
+ valid_id = true
277
+ rescue
278
+ say("You passed in an invalid #{part} id or property.")
279
+ end
280
+ "BadgevilleBerlin::#{part}".constantize.delete(id) unless valid_id.nil?
281
+ puts "Successfully deleted #{part} #{id}" unless valid_id.nil?
282
+ end
283
+ end
284
+
285
+ def self.pwd
286
+ say( BerlinShell.working_path_parts.join("/") + "/")
287
+ end
288
+
289
+ end
290
+
291
+ while true
292
+ inputs = ask("/" + @@working_path_parts.join("/") + "/ >> " ).split(" ", 2)
293
+
294
+ if inputs.empty?
295
+ next
296
+ end
297
+
298
+ case inputs[0].downcase
299
+ when "exit"
300
+ abort("Goodbye!")
301
+ when "ls"
302
+ begin
303
+ Commands.ls(inputs[1])
304
+ rescue
305
+ say("Unable to ls.")
306
+ end
307
+ when "cd"
308
+ Commands.cd(inputs[1])
309
+ when "rm"
310
+ Commands.rm(inputs[1])
311
+ when "touch"
312
+ Commands.touch(inputs[1])
313
+ when "pwd"
314
+ Commands.pwd
315
+ else
316
+ end
317
+ end
318
+
319
+ end