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