northpass 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.pairs +16 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.ocra +7 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +100 -0
  9. data/Rakefile +36 -0
  10. data/bin/sk +10 -0
  11. data/bin/sk_gui +8 -0
  12. data/circle.yml +8 -0
  13. data/config/ca-bundle.crt +3894 -0
  14. data/config/color_scheme.css.erb +91 -0
  15. data/config/fixtures.yml +255 -0
  16. data/config/learning.html.erb +43 -0
  17. data/config/learning_color_scheme.css.erb +70 -0
  18. data/config/locale.yml +110 -0
  19. data/config/school_website.html.erb +37 -0
  20. data/lib/schoolkeep.rb +16 -0
  21. data/lib/schoolkeep/cli.rb +135 -0
  22. data/lib/schoolkeep/client.rb +54 -0
  23. data/lib/schoolkeep/fixture.rb +130 -0
  24. data/lib/schoolkeep/fixture/stubs.rb +106 -0
  25. data/lib/schoolkeep/gui_client.rb +99 -0
  26. data/lib/schoolkeep/scribble.rb +480 -0
  27. data/lib/schoolkeep/scribble/methods/app.rb +17 -0
  28. data/lib/schoolkeep/scribble/methods/collection_each.rb +3 -0
  29. data/lib/schoolkeep/scribble/methods/display_search_form.rb +28 -0
  30. data/lib/schoolkeep/scribble/methods/filter_parameter_value.rb +11 -0
  31. data/lib/schoolkeep/scribble/methods/hide_search_box.rb +17 -0
  32. data/lib/schoolkeep/scribble/methods/l.rb +13 -0
  33. data/lib/schoolkeep/scribble/methods/limit.rb +11 -0
  34. data/lib/schoolkeep/scribble/methods/no_filter_selected_class.rb +19 -0
  35. data/lib/schoolkeep/scribble/methods/pluralize.rb +32 -0
  36. data/lib/schoolkeep/scribble/methods/query_parameter_value.rb +11 -0
  37. data/lib/schoolkeep/scribble/methods/script.rb +45 -0
  38. data/lib/schoolkeep/scribble/methods/t.rb +25 -0
  39. data/lib/schoolkeep/server.rb +132 -0
  40. data/lib/schoolkeep/template.rb +67 -0
  41. data/lib/schoolkeep/template_names.rb +24 -0
  42. data/lib/schoolkeep/version.rb +3 -0
  43. data/lib/schoolkeep/views/asset_cache.rb +34 -0
  44. data/lib/schoolkeep/views/color_scheme.rb +19 -0
  45. data/lib/schoolkeep/views/layout.rb +72 -0
  46. data/media/schoolkeep.ico +0 -0
  47. data/media/sk-144.gif +0 -0
  48. data/media/sk-16.gif +0 -0
  49. data/media/sk-57.gif +0 -0
  50. data/media/sk-72.gif +0 -0
  51. data/schoolkeep.gemspec +28 -0
  52. data/spec/cli_spec.rb +70 -0
  53. data/spec/features/cli_spec.rb +51 -0
  54. data/spec/features/client_spec.rb +48 -0
  55. data/spec/fixture_spec.rb +68 -0
  56. data/spec/methods/filter_parameter_value_spec.rb +28 -0
  57. data/spec/methods/pluralize_spec.rb +41 -0
  58. data/spec/methods/query_parameter_value_spec.rb +26 -0
  59. data/spec/methods/script_spec.rb +52 -0
  60. data/spec/methods/t_spec.rb +33 -0
  61. data/spec/server_spec.rb +81 -0
  62. data/spec/spec_helper.rb +48 -0
  63. data/spec/views/asset_cache_spec.rb +24 -0
  64. data/spec/views/color_scheme_spec.rb +15 -0
  65. metadata +223 -0
@@ -0,0 +1,106 @@
1
+ require "ostruct"
2
+
3
+ module Partnerships
4
+ class Educator < Class.new(OpenStruct)
5
+ end
6
+ end
7
+
8
+ Course = Class.new(OpenStruct)
9
+ Locale = Class.new(OpenStruct)
10
+
11
+ module ActionController
12
+ class Parameters < Class.new(Hash)
13
+ end
14
+ end
15
+
16
+ CategoryDecorator = Class.new(OpenStruct)
17
+
18
+ module SchoolWebsite
19
+ class CourseDecorator < Course
20
+ def progress_text(_)
21
+ super()
22
+ end
23
+ end
24
+
25
+ ActivityDecorator = Class.new(OpenStruct)
26
+ CourseCatalogDecorator = Class.new(OpenStruct)
27
+ MyContentDecorator = Class.new(OpenStruct)
28
+ UpcomingRegisteredEventsDecorator = Class.new(OpenStruct)
29
+ TrainingSessionsDecorator = Class.new(OpenStruct)
30
+ TrainingSessionDecorator = Class.new(OpenStruct)
31
+ end
32
+
33
+ class Learner < Class.new(OpenStruct)
34
+ def access_course?(_)
35
+ enrolled_in_course(_)
36
+ end
37
+
38
+ def enrolled_in_course?(_)
39
+ super()
40
+ end
41
+ end
42
+
43
+ class Person < Class.new(OpenStruct)
44
+ def access_course?(_)
45
+ enrolled_in_course(_)
46
+ end
47
+
48
+ def enrolled_in_course?(_)
49
+ super()
50
+ end
51
+ end
52
+
53
+ module Schools
54
+ class Routes < Class.new(OpenStruct)
55
+ end
56
+ end
57
+
58
+ module Search
59
+ class CatalogResult < Class.new(OpenStruct)
60
+ end
61
+ end
62
+
63
+ module LearnerSyllabuses
64
+ ActivitiesCollection = Class.new(OpenStruct)
65
+ Activity = Class.new(OpenStruct)
66
+ Section = Class.new(OpenStruct)
67
+ SectionsCollection = Class.new(OpenStruct)
68
+ Syllabus = Class.new(OpenStruct)
69
+ end
70
+
71
+ module Draper
72
+ class CollectionDecorator < Array
73
+ alias :count :size
74
+ end
75
+ end
76
+
77
+ module ActiveRecord
78
+ module Associations
79
+ class CollectionProxy < Array
80
+ end
81
+ end
82
+ end
83
+
84
+ class Array
85
+ alias :count :size
86
+ end
87
+
88
+ class ColorScheme < Class.new(OpenStruct)
89
+ def initialize(*args)
90
+ super
91
+ to_h.each do |method_name, _|
92
+ define_singleton_method "#{method_name}?" do
93
+ val = send(method_name)
94
+ val != "" && !val.nil?
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ require "schoolkeep/scribble"
101
+ Scribble::Registry.for Array do
102
+ method :count
103
+ end
104
+
105
+ Schoolkeep::Scribble.stub = true
106
+ Schoolkeep::Scribble.register_models
@@ -0,0 +1,99 @@
1
+ require "tk"
2
+ require "schoolkeep/server"
3
+
4
+ module Schoolkeep
5
+ class GuiClient
6
+ def initialize
7
+ choose_templates_directory_button
8
+ templates_directory_field
9
+ server_toggle_button
10
+
11
+ if not defined?(Ocra)
12
+ Tk.mainloop
13
+ end
14
+ end
15
+
16
+ def root
17
+ @root ||= TkRoot.new do
18
+ title "SchoolKeep Local Dev Server"
19
+ minsize 400, 100
20
+ iconphoto(
21
+ *%w(144 72 57 16).map do |size|
22
+ TkPhotoImage.new("file" => "media/sk-#{size}.gif")
23
+ end
24
+ )
25
+ end
26
+ end
27
+
28
+ def server_toggle_button
29
+ gui_client = self
30
+ @server_toggle_button ||= TkButton.new(root) do
31
+ text "Start Server"
32
+ command do
33
+ gui_client.toggle_server
34
+ end
35
+ pack
36
+ end
37
+ end
38
+
39
+ def templates_directory_frame
40
+ @templates_directory_frame ||= TkFrame.new(root) do
41
+ pack "side" => "top"
42
+ end
43
+ end
44
+
45
+ def templates_directory_field
46
+ @templates_directory_field ||= TkEntry.new(templates_directory_frame) do
47
+ pack "side" => "left"
48
+ end
49
+ end
50
+
51
+ def choose_templates_directory_button
52
+ gui_client = self
53
+ @choose_templates_directory_button ||= TkButton.new(templates_directory_frame) do
54
+ text "Choose Templates Directory"
55
+ command do
56
+ dir = gui_client.templates_directory_field.get
57
+ if dir == ""
58
+ dir = ENV["HOME"]
59
+ end
60
+ gui_client.templates_directory_field.set Tk::chooseDirectory("initialdir" => dir)
61
+ end
62
+ pack "side" => "right"
63
+ end
64
+ end
65
+
66
+ def toggle_server
67
+ if @server
68
+ server_stop
69
+ else
70
+ server_start
71
+ end
72
+ end
73
+
74
+ def server_start
75
+ templates_directory_field.state "readonly"
76
+ choose_templates_directory_button.state "disabled"
77
+ @server = Thread.new {
78
+ server = Server.new(
79
+ dir: templates_directory_field.get,
80
+ quiet: true
81
+ )
82
+ begin
83
+ server.start
84
+ ensure
85
+ server.shutdown
86
+ end
87
+ }
88
+ server_toggle_button.text "Stop Server"
89
+ end
90
+
91
+ def server_stop
92
+ @server.kill
93
+ @server = nil
94
+ server_toggle_button.text "Start Server"
95
+ templates_directory_field.state "normal"
96
+ choose_templates_directory_button.state "normal"
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,480 @@
1
+ require "scribble"
2
+ require "ostruct"
3
+ require "cgi"
4
+ require "schoolkeep/scribble/methods/app"
5
+ require "schoolkeep/scribble/methods/collection_each"
6
+ require "schoolkeep/scribble/methods/display_search_form"
7
+ require "schoolkeep/scribble/methods/filter_parameter_value"
8
+ require "schoolkeep/scribble/methods/hide_search_box"
9
+ require "schoolkeep/scribble/methods/l"
10
+ require "schoolkeep/scribble/methods/limit"
11
+ require "schoolkeep/scribble/methods/no_filter_selected_class"
12
+ require "schoolkeep/scribble/methods/pluralize"
13
+ require "schoolkeep/scribble/methods/query_parameter_value"
14
+ require "schoolkeep/scribble/methods/script"
15
+ require "schoolkeep/scribble/methods/t"
16
+
17
+ Scribble::Registry.for Enumerable do
18
+ to_boolean { any? }
19
+
20
+ method :any?
21
+
22
+ # Logical operators
23
+ method :or, Object, cast: 'to_boolean'
24
+ method :and, Object, cast: 'to_boolean'
25
+
26
+ # Equality
27
+ method :equals, Enumerable, as: '=='
28
+ method :differs, Enumerable, as: '!='
29
+ method :equals, Object, returns: false
30
+ method :differs, Object, returns: true
31
+ end
32
+
33
+ Scribble::Registry.for ActiveRecord::Associations::CollectionProxy do
34
+ to_boolean { any? }
35
+
36
+ # Logical operators
37
+ method :or, Object, cast: 'to_boolean'
38
+ method :and, Object, cast: 'to_boolean'
39
+
40
+ # Equality
41
+ method :equals, ActiveRecord::Associations::CollectionProxy, as: '=='
42
+ method :differs, ActiveRecord::Associations::CollectionProxy, as: '!='
43
+ method :equals, Object, returns: false
44
+ method :differs, Object, returns: true
45
+ end
46
+
47
+ Scribble::Registry.for Draper::CollectionDecorator do
48
+ method :count
49
+ method :any?
50
+ end
51
+
52
+ module Schoolkeep
53
+ module Scribble
54
+ class << self
55
+ attr_accessor :stub
56
+
57
+ def register_models
58
+ if stub
59
+ models.each do |class_name, args|
60
+ begin
61
+ constantize(class_name)
62
+ rescue NameError
63
+ Object.const_set(class_name, Class.new(OpenStruct))
64
+ end
65
+ end
66
+ end
67
+
68
+ models.each do |class_name, args|
69
+ register_model(class_name, *args)
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def register_model(class_name, boolean, block)
76
+ ::Scribble::Registry.instance.class_names.delete_if do |klass, name|
77
+ name == class_name
78
+ end
79
+
80
+ ::Scribble::Registry.instance.methods.reject! do |method|
81
+ method.receiver_class.name == class_name
82
+ end
83
+
84
+ klass = constantize(class_name)
85
+
86
+ ::Scribble::Registry.for klass do
87
+ name class_name
88
+ to_boolean { boolean }
89
+
90
+ # Logical operators
91
+ method :or, Object, cast: 'to_boolean'
92
+ method :and, Object, cast: 'to_boolean'
93
+
94
+ # Equality
95
+ method :equals, klass, as: '=='
96
+ method :differs, klass, as: '!='
97
+ method :equals, Object, returns: false
98
+ method :differs, Object, returns: true
99
+ end
100
+
101
+ ::Scribble::Registry.for klass, &block
102
+ end
103
+
104
+ def models
105
+ @models ||= {}
106
+ end
107
+
108
+ def register(class_name, boolean: true, &block)
109
+ models[class_name.to_s] = [boolean, block]
110
+ end
111
+
112
+ def constantize(camel_cased_word)
113
+ names = camel_cased_word.split('::')
114
+
115
+ # Trigger a builtin NameError exception including the ill-formed constant in the message.
116
+ Object.const_get(camel_cased_word) if names.empty?
117
+
118
+ # Remove the first blank element in case of '::ClassName' notation.
119
+ names.shift if names.size > 1 && names.first.empty?
120
+
121
+ names.inject(Object) do |constant, name|
122
+ if constant == Object
123
+ constant.const_get(name)
124
+ else
125
+ candidate = constant.const_get(name)
126
+ next candidate if constant.const_defined?(name, false)
127
+ next candidate unless Object.const_defined?(name)
128
+
129
+ # Go down the ancestors to check it it's owned
130
+ # directly before we reach Object or the end of ancestors.
131
+ constant = constant.ancestors.inject do |const, ancestor|
132
+ break const if ancestor == Object
133
+ break ancestor if ancestor.const_defined?(name, false)
134
+ const
135
+ end
136
+
137
+ # owner is in Object, so raise
138
+ constant.const_get(name, false)
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ register :Category do
145
+ method :active?
146
+ method :link
147
+ method :name
148
+ end
149
+
150
+ register :CustomPage do
151
+ to_string { "custom_page: #{page_title}" }
152
+
153
+ # Attributes
154
+ method :page_title
155
+ method :headline
156
+ method :subheadline
157
+ method :image_url
158
+ method :content
159
+ end
160
+
161
+ register :School do
162
+ to_string { "school: #{name}" }
163
+
164
+ # Attributes
165
+ method :disable_social_share?
166
+ method :filterable_categories # DEPRECATED
167
+ method :filtering_enabled?
168
+ method :has_custom_styles?
169
+ method :locales
170
+ method :logo_navigation_url
171
+ method :logo_url
172
+ method :my_content_label
173
+ method :my_content_path # DEPRECATED
174
+ method :name
175
+ method :public
176
+ method :search_enabled?
177
+ method :show_powered_by_school_keep?
178
+ method :sso_enabled?
179
+ end
180
+
181
+ register :WebsiteNavigation do
182
+ to_string { "website navigation: #{name}" }
183
+
184
+ method :name
185
+ method :path
186
+ method :external?
187
+ end
188
+
189
+ register :WebsiteFooter do
190
+ to_string { "website footer" }
191
+
192
+ method :show_navigation_links?
193
+ method :show_social_media_links?
194
+ method :show_customer_service_email?
195
+ method :school_customer_service_email
196
+ method :social_media_links
197
+ end
198
+
199
+ register :SocialMediaLink do
200
+ to_string { "social media link: #{name}" }
201
+
202
+ method :link
203
+ method :name
204
+ end
205
+
206
+ register :Course do
207
+ to_string { "course: #{name}" }
208
+
209
+ method :course_category_names
210
+ method :full_description
211
+ method :has_outline?
212
+ method :name
213
+ method :payment_required?
214
+ method :published_sections
215
+ method :ribbon
216
+ method :short_description
217
+ method :show_events?
218
+ end
219
+
220
+ register :VirtualEventSessionSummary do
221
+ to_string { "virtual event session summary" }
222
+
223
+ method :virtual_event_name
224
+ method :provider_logo_url
225
+ method :virtual_event_start_url
226
+ method :starts_at
227
+ method :ends_at
228
+ method :join_link
229
+ end
230
+
231
+ register "Search::CatalogResult" do
232
+ method :count
233
+ end
234
+
235
+ register "SchoolWebsite::MyContentDecorator" do
236
+ to_string { "my content decorator" }
237
+
238
+ method :courses
239
+ method :headline
240
+ method :subheadline
241
+ end
242
+
243
+ register :Section do
244
+ to_string { "section: #{name}" }
245
+
246
+ method :name
247
+ method :activities
248
+ end
249
+
250
+ register "SchoolWebsite::ActivityDecorator" do
251
+ method :completed?
252
+ method :list_class
253
+ method :milestone?
254
+ method :path
255
+ method :title
256
+ end
257
+
258
+ register "SchoolWebsite::CourseDecorator" do
259
+ to_string { "course decorator: #{name}" }
260
+
261
+ method :about_label
262
+ method :buy_label
263
+ method :course_attempts_path
264
+ method :cover_path
265
+ method :details_path
266
+ method :details_url
267
+ method :enrollment_url
268
+ method :featured_image_url
269
+ method :formatted_price
270
+ method :forum_path
271
+ method :go_to_label
272
+ method :has_forum?
273
+ method :instructor_names
274
+ method :instructors
275
+ method :instructors_title
276
+ method :virtual_events_title
277
+ method :learner_can_retake?
278
+ method :list_image_url
279
+ method :new_order_path
280
+ method :outline_label
281
+ method :outline_path
282
+ method :partnership_names
283
+ method :partnerships
284
+ method :progress
285
+ method :progress_bar
286
+ method :progress_text, Person
287
+ method :progress_title
288
+ method :promo_video_embed
289
+ method :register_for_events
290
+ method :retake_course
291
+ method :social_links
292
+ method :start_or_continue
293
+ method :superscript
294
+ method :upcoming_event_sessions
295
+ method :view_label
296
+ method :virtual_events_path
297
+ method :discover_events_path
298
+ end
299
+
300
+ register "SchoolWebsite::CourseCatalogDecorator" do
301
+ to_string { "course decorator: #{name}" }
302
+
303
+ method :headline
304
+ method :headline_empty_collection
305
+ method :subheadline
306
+ method :subheadline_empty_collection
307
+ end
308
+
309
+ register "SchoolWebsite::UpcomingRegisteredEventsDecorator" do
310
+ method :sessions
311
+ method :additional_sessions?
312
+ end
313
+
314
+ register "SchoolWebsite::TrainingSessionsDecorator" do
315
+ method :head
316
+ method :tail
317
+ end
318
+
319
+ register "SchoolWebsite::TrainingSessionDecorator" do
320
+ method :status
321
+ method :title
322
+ method :starts_at
323
+ method :waiting?
324
+ method :pending?
325
+ method :join_url
326
+ method :logmein?
327
+ method :in_person?
328
+ method :room_name
329
+ method :location_name
330
+ end
331
+
332
+ register "Partnerships::Educator" do
333
+ to_string { "partnership: #{name}" }
334
+
335
+ method :image_url
336
+ method :name
337
+ method :title
338
+ method :bio
339
+ end
340
+
341
+ register "LearnerSyllabuses::SectionsCollection" do
342
+ end
343
+
344
+ register "LearnerSyllabuses::ActivitiesCollection" do
345
+ end
346
+
347
+ register "LearnerSyllabuses::Section" do
348
+ method :activities
349
+ method :name
350
+ method :published_at
351
+ method :will_be_published?
352
+ end
353
+
354
+ register "LearnerSyllabuses::Activity" do
355
+ method :completed?
356
+ method :list_class
357
+ method :locked?
358
+ method :milestone?
359
+ method :path
360
+ method :title
361
+ end
362
+
363
+ register "LearnerSyllabuses::Syllabus" do
364
+ method :sections
365
+ end
366
+
367
+ register :Learner do
368
+ to_string { "learner: #{name}" }
369
+
370
+ # Attributes
371
+ method :access_course?, Course
372
+ method :enrolled_in_course?, Course
373
+ method :filterable_categories
374
+ method :my_content_label
375
+ method :name
376
+ method :email
377
+ method :sso_uid
378
+ method :id
379
+ method :upcoming_registered_events
380
+ end
381
+
382
+ register :Person do
383
+ to_string { "learner: #{name}" }
384
+
385
+ # Attributes
386
+ method :access_course?, Course
387
+ method :enrolled_in_course?, Course
388
+ method :filterable_categories
389
+ method :my_content_label
390
+ method :name
391
+ method :email
392
+ method :sso_uid
393
+ method :id
394
+ method :upcoming_registered_events
395
+ end
396
+
397
+ register :GuestLearner, boolean: false do
398
+ to_string { "guest learner" }
399
+
400
+ method :access_course?, Course
401
+ method :enrolled_in_course?, Course
402
+ method :filterable_categories
403
+ method :my_content_label
404
+ method :name
405
+ method :email
406
+ method :sso_uid
407
+ method :id
408
+ method :upcoming_registered_events
409
+ end
410
+
411
+ register :GuestPerson, boolean: false do
412
+ to_string { "guest learner" }
413
+
414
+ method :access_course?, Course
415
+ method :enrolled_in_course?, Course
416
+ method :filterable_categories
417
+ method :my_content_label
418
+ method :name
419
+ method :email
420
+ method :sso_uid
421
+ method :id
422
+ method :upcoming_registered_events
423
+ end
424
+
425
+ register :Homepage do
426
+ to_string { "homepage" }
427
+
428
+ method :headline
429
+ method :subheadline
430
+ method :artwork_url
431
+ method :featured_courses_headline
432
+ method :featured_courses_subheadline
433
+ method :published_featured_courses
434
+ end
435
+
436
+ register "Schools::Routes" do
437
+ to_string { "school routes" }
438
+
439
+ method :my_courses_path
440
+ method :my_content_path
441
+ method :my_profile_path
442
+ method :log_out_path
443
+ method :log_in_path
444
+ method :sign_up_path
445
+
446
+ method :color_scheme_path
447
+ method :custom_styles_path
448
+ method :schoolkeep_v3_styles_url
449
+ method :school_website_search_path
450
+ end
451
+
452
+ register "ColorScheme" do
453
+ to_string { "Color Scheme" }
454
+
455
+ method :background_color
456
+ method :background_font_color
457
+ method :button_color
458
+ method :button_font_color
459
+ method :button_hover_color
460
+ method :banner_font_color
461
+ method :header_color
462
+ method :header_font_color
463
+ method :header_font_hover_color
464
+ end
465
+
466
+ register "BaseApp" do
467
+ to_string { "Base App" }
468
+
469
+ method :active?
470
+ method :inactive?
471
+ end
472
+
473
+ register :Locale do
474
+ to_string { "Locale" }
475
+
476
+ method :code
477
+ method :name
478
+ end
479
+ end
480
+ end