conjoin 0.0.1 → 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.
@@ -0,0 +1,97 @@
1
+ require 'r18n-core'
2
+
3
+ # https://github.com/ai/r18n
4
+ module Conjoin
5
+ module I18N
6
+ include R18n::Helpers
7
+
8
+ def self.setup(app)
9
+ app.settings[:default_locale] = 'en-US'
10
+ app.settings[:translations] = File.join(app.root, 'i18n')
11
+ ::R18n::Filters.off :untranslated
12
+ ::R18n::Filters.on :untranslated_html
13
+ if Conjoin.env.test? or Conjoin.env.development?
14
+ ::R18n.clear_cache!
15
+ end
16
+ end
17
+
18
+ def set_locale(req, force_default = false)
19
+ ::R18n.set do
20
+ ::R18n::I18n.default = settings[:default_locale]
21
+ locale = get_locale_from_host
22
+ # You can add support for path language info :) Just do it and pull request it ;)
23
+ # locale = get_locale_from_path if locale.nil?
24
+ if locale.nil? and not force_default
25
+ locales = ::R18n::I18n.parse_http req.env['HTTP_ACCEPT_LANGUAGE']
26
+ if req.params['locale']
27
+ locales.insert 0, req.params['locale']
28
+ elsif req.session['locale']
29
+ locales.insert 0, req.session['locale']
30
+ end
31
+ else
32
+ locales = []
33
+ locales << locale
34
+ locales << settings[:default_locale]
35
+ end
36
+ ::R18n::I18n.new locales, settings[:translations]
37
+ end
38
+ end
39
+
40
+ def get_locale_from_host
41
+ # auxiliar method to get locale from the subdomain (assuming it is a valid locale).
42
+ data = req.host.split('.')[0]
43
+ data if ::R18n::Locale.exists? data
44
+ end
45
+ end
46
+ end
47
+
48
+ module R18n
49
+ class << self
50
+ def t(*params)
51
+ if params.first.is_a? String
52
+ params.first.split('.').inject(get.t) { |h, k| h[k.to_sym] }
53
+ else
54
+ get.t(*params)
55
+ end
56
+ end
57
+ end
58
+
59
+ # Override
60
+ # https://github.com/ai/r18n/blob/master/r18n-core/lib/r18n-core/locale.rb#L152
61
+ class Locale
62
+ # Convert +object+ to String. It support Fixnum, Bignum, Float, Time, Date
63
+ # and DateTime.
64
+ #
65
+ # For time classes you can set +format+ in standard +strftime+ form,
66
+ # <tt>:full</tt> (“01 Jule, 2009”), <tt>:human</tt> (“yesterday”),
67
+ # <tt>:standard</tt> (“07/01/09”) or <tt>:month</tt> for standalone month
68
+ # name. Default format is <tt>:standard</tt>.
69
+ def localize(obj, format = nil, *params)
70
+ case obj
71
+ when Integer
72
+ format_integer(obj)
73
+ when Float, BigDecimal
74
+ format_float(obj.to_f)
75
+ when Time, DateTime, Date
76
+ return strftime(obj, format) if format.is_a? String
77
+ return month_standalone[obj.month - 1] if :month == format
78
+ return obj.to_s if :human == format and not params.first.is_a? I18n
79
+
80
+ type = obj.is_a?(Date) ? 'date' : 'time'
81
+ format = :standard unless format
82
+
83
+ unless respond_to? "format_#{type}_#{format}"
84
+ raise ArgumentError, "Unknown time formatter #{format}"
85
+ end
86
+
87
+ send "format_#{type}_#{format}", obj, *params
88
+ else
89
+ obj.to_s
90
+ end
91
+ end
92
+
93
+ def format_time_time time, *params
94
+ format_time(time)[1..-1]
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,8 @@
1
+ require_relative 'radio'
2
+
3
+ module Conjoin
4
+ module FormBuilder
5
+ class BooleanInput < RadioInput
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class CheckboxInput < Input
4
+ def display
5
+ options[:value] = 'on' if data.value == true
6
+ options[:checked] = 'checked' if data.value
7
+ options[:type] = :checkbox
8
+ options[:class].gsub!(/form-control/, '')
9
+
10
+ super
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class DateInput < Input
4
+ def display
5
+ options[:date] = true
6
+ options[:value] = R18n.l options[:value]
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class DecimalInput < Input
4
+ def display
5
+ super
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class FileInput < Input
4
+ def display
5
+ key = options[:s3_upload_path].call(record)
6
+
7
+ mab do
8
+ unless options[:value]
9
+ div id: id, name: options[:name], class: 'file s3-uploader', value: options[:value]
10
+ end
11
+ input id: id, type: :hidden, name: options[:name], class: 'form-control file s3-uploader', value: options[:value]
12
+ text! S3Uploader.js_button(id, key, options[:callback_url], options[:callback_params])
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class HiddenInput < Input
4
+ def display
5
+ options[:type] = :hidden
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class IntegerInput < Input
4
+ def display
5
+ super
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class PasswordInput < Input
4
+ def display
5
+ options[:type] = :password
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,35 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class RadioInput < Input
4
+ def display
5
+ options[:type] = :radio
6
+ options[:class].gsub!(/form-control/, '')
7
+
8
+ radios = options[:radios] || [:yes, :no]
9
+
10
+ opts = options.dup
11
+
12
+ mab do
13
+ div class: 'form-control' do
14
+ radios.each_with_index do |name, i|
15
+ name = name.to_s
16
+ opts[:value] = name
17
+ opts[:id] = "#{options[:id]}_#{i}"
18
+
19
+ if (opts[:value] == 'no' and data.value == false) \
20
+ or (opts[:value] == 'yes' and data.value == true) \
21
+ or (opts[:value] == data.value)
22
+ opts[:checked] = 'checked'
23
+ else
24
+ opts.delete :checked
25
+ end
26
+
27
+ input opts
28
+ span name.humanize
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,67 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class SelectInput < Input
4
+ @select_options = {}
5
+
6
+ def display
7
+ mab do
8
+ # automatically add a prompt by default
9
+ options[:prompt] = true unless options.key? :prompt
10
+ options[:class] += ' select2'
11
+ selected_value = options.delete :value
12
+
13
+ select options do
14
+ if prompt = options.delete(:prompt)
15
+ opts = {
16
+ value: ''
17
+ }
18
+ opts['selected'] = 'selected' unless selected_value
19
+ option opts do
20
+ text prompt.to_s == 'true' ? 'Please Choose One.' : prompt
21
+ end
22
+ end
23
+
24
+ if not options[:group]
25
+ select_options.each do |name, value|
26
+ option render_opts(value, selected_value, opts) do
27
+ text name.titleize
28
+ end
29
+ end
30
+ else
31
+ select_options.each do |group_select, group|
32
+ optgroup label: group.to_s.titleize do
33
+ group_select.each do |value, name|
34
+ option render_opts(value, selected_value, opts) do
35
+ text name.titleize
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ def render_opts value, selected_value, opts
46
+ opts = {
47
+ value: value
48
+ }
49
+ if selected_value.is_a? ActiveRecord::Associations::CollectionProxy
50
+ opts['selected'] = 'selected' if selected_value.map(&:id).include? value
51
+ else
52
+ opts['selected'] = 'selected' if selected_value == value.to_s
53
+ end
54
+
55
+ opts
56
+ end
57
+
58
+ def self.select_options
59
+ @select_options
60
+ end
61
+
62
+ def select_options
63
+ self.class.select_options.invert
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,68 @@
1
+ require_relative 'select'
2
+
3
+ module Conjoin
4
+ module FormBuilder
5
+ class StateInput < SelectInput
6
+ @select_options = {
7
+ 'AL' => 'Alabama',
8
+ 'AK' => 'Alaska',
9
+ 'AS' => 'America Samoa',
10
+ 'AZ' => 'Arizona',
11
+ 'AR' => 'Arkansas',
12
+ 'CA' => 'California',
13
+ 'CO' => 'Colorado',
14
+ 'CT' => 'Connecticut',
15
+ 'DE' => 'Delaware',
16
+ 'DC' => 'District of Columbia',
17
+ 'FM' => 'Micronesia',
18
+ 'FL' => 'Florida',
19
+ 'GA' => 'Georgia',
20
+ 'GU' => 'Guam',
21
+ 'HI' => 'Hawaii',
22
+ 'ID' => 'Idaho',
23
+ 'IL' => 'Illinois',
24
+ 'IN' => 'Indiana',
25
+ 'IA' => 'Iowa',
26
+ 'KS' => 'Kansas',
27
+ 'KY' => 'Kentucky',
28
+ 'LA' => 'Louisiana',
29
+ 'ME' => 'Maine',
30
+ 'MH' => 'Islands',
31
+ 'MD' => 'Maryland',
32
+ 'MA' => 'Massachusetts',
33
+ 'MI' => 'Michigan',
34
+ 'MN' => 'Minnesota',
35
+ 'MS' => 'Mississippi',
36
+ 'MO' => 'Missouri',
37
+ 'MT' => 'Montana',
38
+ 'NE' => 'Nebraska',
39
+ 'NV' => 'Nevada',
40
+ 'NH' => 'New Hampshire',
41
+ 'NJ' => 'New Jersey',
42
+ 'NM' => 'New Mexico',
43
+ 'NY' => 'New York',
44
+ 'NC' => 'North Carolina',
45
+ 'ND' => 'North Dakota',
46
+ 'OH' => 'Ohio',
47
+ 'OK' => 'Oklahoma',
48
+ 'OR' => 'Oregon',
49
+ 'PW' => 'Palau',
50
+ 'PA' => 'Pennsylvania',
51
+ 'PR' => 'Puerto Rico',
52
+ 'RI' => 'Rhode Island',
53
+ 'SC' => 'South Carolina',
54
+ 'SD' => 'South Dakota',
55
+ 'TN' => 'Tennessee',
56
+ 'TX' => 'Texas',
57
+ 'UT' => 'Utah',
58
+ 'VT' => 'Vermont',
59
+ 'VI' => 'Virgin Island',
60
+ 'VA' => 'Virginia',
61
+ 'WA' => 'Washington',
62
+ 'WV' => 'West Virginia',
63
+ 'WI' => 'Wisconsin',
64
+ 'WY' => 'Wyoming'
65
+ }
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,9 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class StringInput < Input
4
+ def display
5
+ super
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Conjoin
2
+ module FormBuilder
3
+ class TimeInput < Input
4
+ def display
5
+ options[:time] = true
6
+ options[:value] = app.l options[:value], :time
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ require "rack/protection"
2
+
3
+ module Conjoin
4
+ class Middleware
5
+ class << self
6
+ # taken from
7
+ # https://github.com/rkh/rack-protection/blob/master/lib/rack/protection.rb#L20
8
+ def new app, options = {}
9
+ # except = Array options[:except]
10
+ # use_these = Array options[:use]
11
+ Rack::Builder.new do
12
+ if not Conjoin.env.mounted?
13
+ use Rack::Session::Cookie, secret: ENV['SECRET_BASE_KEY']
14
+ end
15
+ # we need to disable session_hijacking because IE uses different headers
16
+ # for ajax request over standard ones.
17
+ # https://github.com/rkh/rack-protection/issues/11#issuecomment-9005539
18
+ use Rack::Protection, except: :session_hijacking
19
+
20
+ if not Conjoin.env.mounted? and Conjoin.env.development?
21
+ require 'rack-livereload'
22
+ use Rack::LiveReload
23
+ use Rack::Reloader
24
+ end
25
+
26
+ if Conjoin.env.test? or Conjoin.env.development?
27
+ require 'better_errors'
28
+ use BetterErrors::Middleware
29
+ # require 'pry'
30
+ # require 'pry-rescue'
31
+ # use PryRescue::Rack
32
+ end
33
+
34
+ # continue running the application
35
+ run app
36
+ end.to_app
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,117 @@
1
+ # https://gist.github.com/rmw/2710460
2
+ require 'hashie'
3
+
4
+ class Hash
5
+ # options:
6
+ # :exclude => [keys] - keys need to be symbols
7
+ def to_ostruct(options = {})
8
+ convert_to_ostruct_recursive(self, options)
9
+ end
10
+
11
+ def with_sym_keys
12
+ # self.inject({}) { |memo, (k,v)| memo[k.to_sym] = v; memo }
13
+ self.each_with_object({}) { |(k,v), memo| memo[k.to_sym] = v }
14
+ end
15
+
16
+ private
17
+
18
+ def convert_to_ostruct_recursive(obj, options)
19
+ result = obj
20
+ if result.is_a? Hash
21
+ result = result.dup.with_sym_keys
22
+ result.each do |key, val|
23
+ result[key] = convert_to_ostruct_recursive(val, options) unless options[:exclude].try(:include?, key)
24
+ end
25
+ result = OpenStruct.new result
26
+ elsif result.is_a? Array
27
+ result = result.map { |r| convert_to_ostruct_recursive(r, options) }
28
+ end
29
+ return result
30
+ end
31
+ end
32
+
33
+ class HashIndifferent < Hash
34
+ include Hashie::Extensions::MergeInitializer
35
+ include Hashie::Extensions::IndifferentAccess
36
+ end
37
+
38
+ class OpenStruct
39
+ def to_hash options = {}
40
+ convert_to_hash_recursive(self, options)
41
+ end
42
+
43
+ private
44
+
45
+ def convert_to_hash_recursive(obj, options)
46
+ result = obj
47
+ if result.is_a? OpenStruct
48
+ result = result.dup.to_h.with_sym_keys
49
+ result.each do |key, val|
50
+ result[key] = convert_to_hash_recursive(val, options) unless options[:exclude].try(:include?, key)
51
+ end
52
+ result = HashIndifferent.new result
53
+ elsif result.is_a? Array
54
+ result = result.map { |r| convert_to_hash_recursive(r, options) }
55
+ end
56
+ return result
57
+ end
58
+ end
59
+
60
+ # require 'spec_helper'
61
+ #
62
+ # describe Hash do
63
+ #
64
+ # describe "#to_ostruct_recursive" do
65
+ # describe "replace a nested hash" do
66
+ # before do
67
+ # @h = { :a => { :b => { :c => 1 } } }
68
+ # @o = @h.to_ostruct_recursive
69
+ # end
70
+ # it "should be an OpenStruct" do
71
+ # @o.is_a?(OpenStruct).should be_true
72
+ # end
73
+ # it "should have a nested OpenStruct" do
74
+ # @o.a.should be
75
+ # @o.a.is_a?(OpenStruct).should be_true
76
+ # end
77
+ # it "should have a nested nested OpenStruct" do
78
+ # @o.a.b.should be
79
+ # @o.a.b.is_a?(OpenStruct).should be_true
80
+ # end
81
+ # it "should have a nested nested nested value of 1" do
82
+ # @o.a.b.c.should be
83
+ # @o.a.b.c.should == 1
84
+ # end
85
+ # describe "exclude a key from being converted to an OpenStruct" do
86
+ # before do
87
+ # @o_exclude = @h.to_ostruct_recursive({ :exclude => [:b] })
88
+ # end
89
+ # it "should be an OpenStruct" do
90
+ # @o.is_a?(OpenStruct).should be_true
91
+ # end
92
+ # it "should have a nested OpenStruct" do
93
+ # @o.a.is_a?(OpenStruct).should be_true
94
+ # end
95
+ # it "should have a nested nested Hash" do
96
+ # @o_exclude.a.b.is_a?(Hash).should be_true
97
+ # @o_exclude.a.b.should == { :c => 1 }
98
+ # end
99
+ # end
100
+ # end
101
+ # describe "replace a nest hash in an array" do
102
+ # before do
103
+ # @h = { :a => [ {:a1 => 1 } ] }
104
+ # @o = @h.to_ostruct_recursive
105
+ # end
106
+ # it "should be an OpenStruct" do
107
+ # @o.is_a?(OpenStruct).should be_true
108
+ # end
109
+ # it "should have an array with 1 struct" do
110
+ # @o.a.is_a?(Array).should be_true
111
+ # @o.a.size.should == 1
112
+ # @o.a.first.is_a?(OpenStruct).should be_true
113
+ # @o.a.first.a1.should == 1
114
+ # end
115
+ # end
116
+ # end
117
+ # end