northpass 0.0.2

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 (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