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,110 @@
1
+ en:
2
+ custom_templates:
3
+ _footer:
4
+ connect: Connect
5
+ contact: Contact
6
+ email: Email
7
+ need_help: Need help?
8
+ overview: Overview
9
+ powered_by_html: This school is powered by <a href="https://northpass.com">SchoolKeep</a>
10
+ _header:
11
+ all_toolkits: All toolkits
12
+ cancel: Cancel
13
+ courses: All Courses
14
+ home: Home
15
+ log_in: Log In
16
+ log_out: Log Out
17
+ my_content:
18
+ all: All
19
+ course: My Courses
20
+ filter_by_category: Filter by category
21
+ learning_experience: My Learning Experiences
22
+ module: My Modules
23
+ resource: My Resources
24
+ toolkit: My Toolkits
25
+ workshop: My Workshops
26
+ my_courses: My Courses
27
+ my_profile: My Profile
28
+ results:
29
+ one: result
30
+ many: results
31
+ search_placeholder: Search by keyword
32
+ search_title: A search requires a min. 3 characters
33
+ course_cover:
34
+ scheduled_info: Will be available on
35
+ exit: Exit
36
+ course_details:
37
+ buy_course: Buy Course
38
+ buy:
39
+ course: Buy Course
40
+ learning_experience: Buy Learning Experience
41
+ module: Buy Module
42
+ resource: Buy Resource
43
+ toolkit: Buy Toolkit
44
+ workshop: Buy Workshop
45
+ coupon_apply_label: Apply coupon to course
46
+ coupon_submit: Apply
47
+ enroll: Enroll
48
+ go_to:
49
+ course: Go to Course
50
+ learning_experience: Go to Learning Experience
51
+ module: Go to Module
52
+ resource: Go to Resource
53
+ toolkit: Go to Toolkit
54
+ workshop: Go to Workshop
55
+ # DEPRECATE go_to_course on the new school website templates
56
+ go_to_course: Go to Course
57
+ instructor:
58
+ one: Instructor
59
+ many: Instructors
60
+ instructor_bio_title:
61
+ one: About the Instructor
62
+ many: About the Instructors
63
+ start: Start Course
64
+ tabs:
65
+ # DEPRECATE about on the new templates
66
+ about: About the Course
67
+ about_label:
68
+ course: About the Course
69
+ learning_experience: About the Learning Experience
70
+ module: About the Module
71
+ resource: About the Resource
72
+ toolkit: About the Toolkit
73
+ workshop: About the Workshop
74
+ # DEPRECATE syllabus on the new templates
75
+ syllabus: Course Syllabus
76
+ outline_label:
77
+ course: Course Syllabus
78
+ learning_experience: Learning Experience Syllabus
79
+ module: Module Syllabus
80
+ resource: Resource Syllabus
81
+ toolkit: Toolkit Syllabus
82
+ workshop: Workshop Syllabus
83
+ course_index:
84
+ quick_start: Start
85
+ # DEPRECATE view_course on the new templates
86
+ view_course: View Course
87
+ view:
88
+ course: View Course
89
+ learning_experience: View Learning Experience
90
+ module: View Module
91
+ resource: View Resource
92
+ toolkit: View Toolkit
93
+ workshop: View Workshop
94
+ homepage:
95
+ discover_catalog: Discover Catalog
96
+ quick_start: Start
97
+ view_course: View Course
98
+ my_content:
99
+ all: All
100
+ filter_by_category: Filter by category
101
+ not_found:
102
+ headline: Whoops, sorry about that.
103
+ home: Back to home
104
+ subheadline: It looks like the page you're looking for no longer exists. Please check the URL and notify us of any inconsistencies.
105
+ title: Page not found
106
+ server_error:
107
+ title: Sorry, something went wrong
108
+ headline: Whoops, sorry about that.
109
+ subheadline: An error occurred in the application and this page could not be displayed. Our team has been notified. Sorry for the inconvenience.
110
+ home: Back to home
@@ -0,0 +1,37 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title><%= @school.name %></title>
6
+
7
+ <% if @school.favicon_url.nil? || @school.favicon_url == "" %>
8
+ <link href="<%= asset_url("/assets/sw-favicon.ico") %>" rel="shortcut icon" type="image/vnd.microsoft.icon" />
9
+ <% else %>
10
+ <link href="<%= @school.favicon_url %>" rel="shortcut icon" type="image/vnd.microsoft.icon" />
11
+ <% end %>
12
+
13
+ <%= render_skt "_head" %>
14
+
15
+ <script src="<%= asset_url("/assets/external_apis.js") %>"></script>
16
+ <script src="<%= asset_url("/assets/apis/apis.js") %>"></script>
17
+ </head>
18
+
19
+ <body class="<%= body_classes %>">
20
+
21
+ <%= render_skt "_header", variables: { display_search_form: @display_search_form } %>
22
+
23
+ <div class="main-content">
24
+ <%= body %>
25
+ </div>
26
+
27
+ <%= render_skt "_footer" %>
28
+
29
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
30
+ <script src="<%= asset_url("/assets/school_website/application.js") %>"></script>
31
+ <script type="text/javascript">
32
+ // Fixes a bug where font's don't load on Chrome
33
+ // https://github.com/SchoolKeep/schoolkeep/pull/511
34
+ $(function() { $("body").hide().show(); });
35
+ </script>
36
+ </body>
37
+ </html>
@@ -0,0 +1,16 @@
1
+ require "schoolkeep/version"
2
+ require "schoolkeep/template_names"
3
+
4
+ module Schoolkeep
5
+ GEM_ROOT = File.expand_path("../../", __FILE__)
6
+ API_URL = "https://api.northpass.com"
7
+ ASSET_HOST = "https://app.northpass.com"
8
+
9
+ class << self
10
+ attr_writer :api_url
11
+
12
+ def api_url
13
+ @api_url ||= ENV["SK_API_URL"] || API_URL
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,135 @@
1
+ require "thor"
2
+ require "schoolkeep/client"
3
+
4
+ module Schoolkeep
5
+ class CLI < Thor
6
+ desc "upload [TEMPLATE_PATH]", "upload a specific template"
7
+ option :dir, desc: "specify location of templates"
8
+ option :engine, desc: "specify what handlienegner: sktl or liquid", default: "sktl"
9
+ option :quiet, type: :boolean, default: false, desc: "silence all output"
10
+ option :all, type: :boolean, default: false, desc: "upload all templates"
11
+ def upload(path = nil)
12
+ unless ENV["SK_API_KEY"]
13
+ abort set_color("Set the env variable SK_API_KEY in order to upload files", :red)
14
+ end
15
+ unless %w(sktl liquid).include?(options[:engine])
16
+ abort set_color("Invalid engine flag. Allowed values: sktl, liquid", :red)
17
+ end
18
+
19
+ client = Client.new(ENV["SK_API_KEY"])
20
+ engine = options[:engine]
21
+
22
+ if options[:all] || options[:dir]
23
+ templates = Dir.glob(File.join(options[:dir] || "templates", "*.#{engine}"))
24
+ elsif path
25
+ templates = Dir.glob(path)
26
+ else
27
+ abort set_color("missing template path as argument", :red)
28
+ end
29
+
30
+ if templates.count == 0
31
+ abort set_color("No sktl templates found, no files will be uploaded", :yellow)
32
+ end
33
+
34
+ template_names = templates.map { |t| File.basename(t, ".#{engine}") }
35
+ invalid_templates = template_names - TEMPLATE_NAMES
36
+ if invalid_templates.size > 0
37
+ abort set_color("invalid templates: #{invalid_templates.join(", ")}", :yellow)
38
+ end
39
+
40
+ templates.each do |template_path|
41
+ name = File.basename(template_path, ".#{engine}")
42
+ response = client.upload(name, template_path, engine)
43
+ if response.success?
44
+ say("uploaded #{name}", :green) unless options[:quiet]
45
+ else
46
+ abort set_color("upload failed: Server responded with #{response.status} #{response.body}", :red)
47
+ end
48
+ end
49
+ end
50
+
51
+ desc "reset [CUSTOM_TEMPLATE]", "reset specified custom_template"
52
+ option :all, type: :boolean, default: false, desc: "reset all templates"
53
+ option :quiet, type: :boolean, default: false, desc: "silence all output"
54
+ def reset(template_path = nil)
55
+ unless ENV["SK_API_KEY"]
56
+ abort set_color("Set the env variable SK_API_KEY in order to upload files", :red)
57
+ end
58
+
59
+ client = Client.new(ENV["SK_API_KEY"])
60
+
61
+ if options[:all]
62
+ template_names = TEMPLATE_NAMES
63
+ else
64
+ template_names = [File.basename(template_path, ".sktl")]
65
+ end
66
+
67
+ invalid_templates = template_names - TEMPLATE_NAMES
68
+ if invalid_templates.size > 0
69
+ abort set_color("invalid template names: #{invalid_templates.join(", ")}", :yellow)
70
+ end
71
+
72
+ template_names.each do |name|
73
+ client.delete(name)
74
+ say("reset #{name}", :green) unless options[:quiet]
75
+ end
76
+ end
77
+
78
+ desc "server", "serve local templates"
79
+ option :dir, type: :string, default: "."
80
+ option :port, type: :numeric, default: 4000
81
+ option :quiet, type: :boolean, default: false
82
+ option :asset_host, type: :string, default: ASSET_HOST
83
+ def server
84
+ require "schoolkeep/server"
85
+ server = Server.new(
86
+ dir: options[:dir],
87
+ port: options[:port],
88
+ quiet: options[:quiet],
89
+ asset_host: options[:asset_host]
90
+ )
91
+ trap "INT" do server.shutdown end
92
+ server.start
93
+ end
94
+
95
+ desc "generate-fixtures", "create fixture file"
96
+ option :dir, type: :string, default: "."
97
+ def generate_fixtures
98
+ require "schoolkeep/fixture"
99
+ FileUtils.mkdir_p(File.join(options[:dir], "config"))
100
+ fixture_path = File.join(options[:dir], "/config/fixtures.yml")
101
+ if File.exists?(fixture_path)
102
+ unless yes? set_color("#{fixture_path} already exists, are you sure you want to overwrite? [y/n]", :yellow)
103
+ abort set_color("aborting fixture generation", :red)
104
+ end
105
+ end
106
+ FileUtils.copy_file(Fixture::GEM_FIXTURE_PATH, fixture_path)
107
+ say "#{fixture_path} has been generated", :green
108
+ end
109
+
110
+ desc "download-fixtures", "download your fixtures"
111
+ option :dir, type: :string, default: "."
112
+ def download_fixtures
113
+ unless ENV["SK_API_KEY"]
114
+ abort set_color("Set the env variable SK_API_KEY in order to download the fixtures", :red)
115
+ end
116
+
117
+ client = Client.new(ENV["SK_API_KEY"])
118
+
119
+ response = client.get_fixtures
120
+ if response.success?
121
+ FileUtils.mkdir_p(File.join(options[:dir], "config"))
122
+ File.write(File.join(options[:dir], "config/fixtures.yml"), response.body)
123
+ true
124
+ else
125
+ abort set_color("download failed: Server responded with #{response.status} #{response.body}", :red)
126
+ end
127
+ end
128
+
129
+ desc "gui", "launch the gui"
130
+ def gui
131
+ require "schoolkeep/gui_client"
132
+ Schoolkeep::GuiClient.new
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,54 @@
1
+ require "schoolkeep"
2
+ require "faraday"
3
+
4
+ module Schoolkeep
5
+ class Client
6
+ attr_reader :api_key
7
+
8
+ class InvalidTemplateName < StandardError; end
9
+
10
+ def initialize(api_key)
11
+ @api_key = api_key
12
+ end
13
+
14
+ def upload(name, path, engine)
15
+ unless TEMPLATE_NAMES.include? name
16
+ raise InvalidTemplateName.new("#{name} is an invalid template")
17
+ end
18
+ connection.post "/v1/custom_templates.json", {
19
+ custom_template: {
20
+ name: name,
21
+ body: Faraday::UploadIO.new(path, 'text/plain; charset=utf-8'),
22
+ engine: engine
23
+ }
24
+ }
25
+ end
26
+
27
+ def delete(name)
28
+ unless TEMPLATE_NAMES.include? name
29
+ raise InvalidTemplateName.new("#{name} is an invalid template")
30
+ end
31
+ connection.delete "/v1/custom_templates.json", {
32
+ id: name
33
+ }
34
+ end
35
+
36
+ def get_fixtures
37
+ connection.get "/v1/fixtures.yaml"
38
+ end
39
+
40
+ private
41
+
42
+ def connection
43
+ @conenction ||= Faraday.new(
44
+ url: Schoolkeep.api_url,
45
+ ssl: { ca_file: File.join(GEM_ROOT, "config/ca-bundle.crt") }
46
+ ) do |faraday|
47
+ faraday.headers["X-Api-Key"] = api_key
48
+ faraday.request :multipart
49
+ faraday.request :url_encoded
50
+ faraday.adapter Faraday.default_adapter
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,130 @@
1
+ require "schoolkeep"
2
+ require "yaml"
3
+ require "schoolkeep/fixture/stubs"
4
+
5
+ module Schoolkeep
6
+ class Fixture
7
+ MAPPING = {
8
+ activities: LearnerSyllabuses::Activity,
9
+ apps: OpenStruct,
10
+ color_palette: ColorScheme,
11
+ commerce: BaseApp,
12
+ course: SchoolWebsite::CourseDecorator,
13
+ course_catalog: SchoolWebsite::CourseCatalogDecorator,
14
+ courses: SchoolWebsite::CourseDecorator,
15
+ current_learner: Learner,
16
+ current_person: Person,
17
+ current_school: School,
18
+ current_student: Learner,
19
+ custom_page: CustomPage,
20
+ filterable_categories: CategoryDecorator,
21
+ footer_navigations: WebsiteNavigation,
22
+ header_navigations: WebsiteNavigation,
23
+ homepage: Homepage,
24
+ instructors: Partnerships::Educator,
25
+ learner_syllabus: LearnerSyllabuses::Syllabus,
26
+ multiple_languages: BaseApp,
27
+ my_content: SchoolWebsite::MyContentDecorator,
28
+ params: ActionController::Parameters,
29
+ preview_banner: String,
30
+ published_featured_courses: SchoolWebsite::CourseDecorator,
31
+ published_sections: Section,
32
+ routes: Schools::Routes,
33
+ search_result: Search::CatalogResult,
34
+ sections: LearnerSyllabuses::Section,
35
+ social_media_links: SocialMediaLink,
36
+ syllabus_activities: LearnerSyllabuses::Activity,
37
+ website_footer: WebsiteFooter
38
+ }
39
+
40
+ KEY_MAPPING = {
41
+ syllabus_activities: :activities
42
+ }
43
+
44
+ GEM_FIXTURE_PATH = File.join(GEM_ROOT, "config/fixtures.yml")
45
+
46
+ attr_accessor :fixture_path
47
+
48
+ def initialize(fixture_path)
49
+ @fixture_path = fixture_path
50
+ end
51
+
52
+ def for(name, overrides: {})
53
+ fixtures = uncasted_globals.merge(gem_fixtures["templates"][name] || {})
54
+
55
+ if dev_fixtures["templates"]
56
+ fixtures.merge!(dev_fixtures["templates"][name] || {})
57
+ end
58
+
59
+ fixtures.merge!(overrides)
60
+
61
+ cast(fixtures).merge(template_name: File.basename(name, ".html.sktl"))
62
+ end
63
+
64
+ def globals
65
+ cast(uncasted_globals)
66
+ end
67
+
68
+ private
69
+
70
+ def uncasted_globals
71
+ gem_fixtures["globals"].merge(dev_fixtures["globals"] || {})
72
+ end
73
+
74
+ def uncasted_models
75
+ gem_fixtures["models"].merge(dev_fixtures["models"] || {})
76
+ end
77
+
78
+ def dev_fixtures
79
+ @dev_fixtures ||= if File.exist?(fixture_path.to_s)
80
+ YAML.load_file(fixture_path.to_s)
81
+ else
82
+ {}
83
+ end
84
+ end
85
+
86
+ def gem_fixtures
87
+ @gem_fixtures ||= YAML.load_file(GEM_FIXTURE_PATH)
88
+ end
89
+
90
+ def cast(values, key = nil)
91
+ key &&= key.to_sym
92
+
93
+ if values.is_a?(Symbol)
94
+ values = uncasted_models[values.to_s]
95
+ end
96
+
97
+ if values.is_a? Array
98
+ values = values.map do |value|
99
+ cast(value, key)
100
+ end
101
+ else
102
+ if values.is_a? Hash
103
+ values = values.each_with_object({}) do |(child_key, value), hash|
104
+ child_key &&= child_key.to_sym
105
+
106
+ hash[KEY_MAPPING[child_key] || child_key] = cast(value, child_key)
107
+ end
108
+ end
109
+
110
+ if MAPPING[key]
111
+ values = MAPPING[key].new(values)
112
+ end
113
+ end
114
+
115
+ values
116
+ end
117
+
118
+ class << self
119
+ attr_accessor :default_path
120
+
121
+ def for(name, overrides: {})
122
+ new(default_path).for(name, overrides: overrides)
123
+ end
124
+
125
+ def globals
126
+ new(default_path).globals
127
+ end
128
+ end
129
+ end
130
+ end