backframe 0.0.49 → 1.0.0

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +16 -0
  3. data/.gitignore +2 -2
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +1156 -0
  6. data/Gemfile +9 -13
  7. data/README.md +133 -4
  8. data/Rakefile +3 -7
  9. data/backframe.gemspec +10 -11
  10. data/circle.yml +5 -2
  11. data/lib/backframe.rb +21 -34
  12. data/lib/backframe/mime.rb +4 -0
  13. data/lib/backframe/query.rb +48 -0
  14. data/lib/backframe/query/sort.rb +29 -0
  15. data/lib/backframe/railtie.rb +1 -16
  16. data/lib/backframe/response.rb +60 -0
  17. data/lib/backframe/response/adapter/csv.rb +39 -0
  18. data/lib/backframe/response/adapter/json.rb +53 -0
  19. data/lib/backframe/response/adapter/xlsx.rb +41 -0
  20. data/lib/backframe/response/adapter/xml.rb +37 -0
  21. data/lib/backframe/response/collection.rb +43 -0
  22. data/lib/backframe/response/fields.rb +62 -0
  23. data/lib/backframe/response/record.rb +38 -0
  24. data/lib/backframe/service.rb +60 -0
  25. data/lib/backframe/service/result/base.rb +24 -0
  26. data/lib/backframe/service/result/failure.rb +21 -0
  27. data/lib/backframe/service/result/success.rb +21 -0
  28. data/lib/backframe/version.rb +1 -1
  29. data/spec/fixtures/active_record.rb +22 -0
  30. data/spec/fixtures/models.rb +25 -0
  31. data/spec/fixtures/queries.rb +28 -0
  32. data/spec/fixtures/seeds.rb +12 -0
  33. data/spec/fixtures/serializers.rb +23 -0
  34. data/spec/fixtures/services.rb +26 -0
  35. data/spec/query/sort_spec.rb +47 -0
  36. data/spec/query_spec.rb +63 -0
  37. data/spec/response/adapter/csv_spec.rb +47 -0
  38. data/spec/response/adapter/json_spec.rb +66 -0
  39. data/spec/response/adapter/xlsx_spec.rb +59 -0
  40. data/spec/response/adapter/xml_spec.rb +63 -0
  41. data/spec/response/fields_spec.rb +45 -0
  42. data/spec/response/record_spec.rb +45 -0
  43. data/spec/response_spec.rb +153 -0
  44. data/spec/service/result/failure_spec.rb +16 -0
  45. data/spec/service/result/sucess_spec.rb +17 -0
  46. data/spec/service_spec.rb +16 -0
  47. data/spec/spec_helper.rb +15 -52
  48. metadata +78 -81
  49. data/lib/backframe/actioncontroller/acts_as_activation.rb +0 -70
  50. data/lib/backframe/actioncontroller/acts_as_api.rb +0 -39
  51. data/lib/backframe/actioncontroller/acts_as_api/adapter.rb +0 -53
  52. data/lib/backframe/actioncontroller/acts_as_api/errors.rb +0 -48
  53. data/lib/backframe/actioncontroller/acts_as_api/headers.rb +0 -11
  54. data/lib/backframe/actioncontroller/acts_as_api/page.rb +0 -181
  55. data/lib/backframe/actioncontroller/acts_as_reset.rb +0 -86
  56. data/lib/backframe/actioncontroller/acts_as_resource.rb +0 -92
  57. data/lib/backframe/actioncontroller/acts_as_resource/actions.rb +0 -100
  58. data/lib/backframe/actioncontroller/acts_as_session.rb +0 -80
  59. data/lib/backframe/activerecord/acts_as_activable.rb +0 -50
  60. data/lib/backframe/activerecord/acts_as_distinct.rb +0 -49
  61. data/lib/backframe/activerecord/acts_as_enum.rb +0 -62
  62. data/lib/backframe/activerecord/acts_as_orderable.rb +0 -40
  63. data/lib/backframe/activerecord/acts_as_percent.rb +0 -46
  64. data/lib/backframe/activerecord/acts_as_phone.rb +0 -59
  65. data/lib/backframe/activerecord/acts_as_user.rb +0 -101
  66. data/lib/backframe/activerecord/default_values.rb +0 -32
  67. data/lib/backframe/activerecord/filter_sort.rb +0 -79
  68. data/lib/backframe/activerecord/migration.rb +0 -25
  69. data/lib/backframe/image_cache/image_cache.rb +0 -45
  70. data/lib/backframe/image_cache/lib/asset.rb +0 -109
  71. data/lib/backframe/image_cache/lib/cache.rb +0 -67
  72. data/lib/backframe/image_cache/lib/conversions.rb +0 -132
  73. data/lib/backframe/models/activation.rb +0 -60
  74. data/lib/backframe/models/activity.rb +0 -40
  75. data/lib/backframe/models/reset.rb +0 -59
  76. data/lib/backframe/models/story.rb +0 -9
  77. data/lib/backframe/serializers/activity_serializer.rb +0 -44
  78. data/spec/backframe/acts_as_api_spec.rb +0 -225
  79. data/spec/backframe/acts_as_resource_spec.rb +0 -178
  80. data/spec/support/example_factory.rb +0 -9
  81. data/spec/support/example_serializer.rb +0 -3
  82. data/spec/support/schema.rb +0 -8
@@ -1,46 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- module ActsAsPercent
5
-
6
- extend ActiveSupport::Concern
7
-
8
- def self.included(base)
9
- base.send :extend, ClassMethods
10
- end
11
-
12
- module ClassMethods
13
-
14
- def acts_as_percent(entity)
15
-
16
- class_eval <<-EOV
17
-
18
- after_initialize :uncast_percent_#{entity}, :if => Proc.new { |c| c.#{entity}.present? }
19
- before_save :cast_percent_#{entity}, :if => Proc.new { |c| c.#{entity}.present? }
20
- after_save :uncast_percent_#{entity}, :if => Proc.new { |c| c.#{entity}.present? }
21
-
22
- def raw_#{entity}
23
- self.#{entity} / 100.00
24
- end
25
-
26
- private
27
-
28
- def uncast_percent_#{entity}
29
- self.#{entity} = self.#{entity} * 100.00
30
- end
31
-
32
- def cast_percent_#{entity}
33
- self.#{entity} = self.#{entity} / 100.00
34
- end
35
-
36
- EOV
37
-
38
- end
39
-
40
- end
41
-
42
- end
43
- end
44
-
45
-
46
-
@@ -1,59 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'phony'
4
-
5
- module Backframe
6
- module ActsAsPhone
7
-
8
- extend ActiveSupport::Concern
9
-
10
- def self.included(base)
11
- base.send :extend, ClassMethods
12
- end
13
-
14
- module ClassMethods
15
-
16
- def acts_as_phone(entity)
17
-
18
- class_eval <<-EOV
19
-
20
- after_initialize :uncast_phone_#{entity}, :if => Proc.new { |c| !c.new_record? && c.#{entity}.present? }
21
- before_save :cast_phone_#{entity}, :if => Proc.new { |c| c.#{entity}.present? }
22
- after_save :uncast_phone_#{entity}, :if => Proc.new { |c| c.#{entity}.present? }
23
-
24
- validate :validates_phone_#{entity}, :if => Proc.new { |c| c.#{entity}.present? }
25
-
26
- private
27
-
28
- def uncast_phone_#{entity}
29
- self.#{entity} = self.#{entity}[0]+'-'+self.#{entity}[1,3]+'-'+self.#{entity}[4,3]+'-'+self.#{entity}[7,4]
30
- end
31
-
32
- def cast_phone_#{entity}
33
- self.#{entity} = #{entity}_to_international(self.#{entity})
34
- end
35
-
36
- def validates_phone_#{entity}
37
- testvalue = #{entity}_to_international(self.#{entity})
38
- if !Phony.plausible?(testvalue)
39
- self.errors.add(:#{entity}, 'invalid #{entity} number')
40
- end
41
- end
42
-
43
- def #{entity}_to_international(value)
44
- newvalue = value.gsub('(', '').gsub(')', '').gsub('.', '').gsub('-', '').gsub(' ', '')
45
- newvalue = (newvalue.length == 10) ? '1'+value : value
46
- Phony.normalize(newvalue)
47
- end
48
-
49
- EOV
50
-
51
- end
52
-
53
- end
54
-
55
- end
56
- end
57
-
58
-
59
-
@@ -1,101 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- module ActsAsUser
5
- extend ActiveSupport::Concern
6
-
7
- def self.included(base)
8
- base.send :extend, ClassMethods
9
- end
10
-
11
- module ClassMethods
12
-
13
- def acts_as_user(*args)
14
- arguments = args[0] || {}
15
-
16
- reset = arguments[:reset] || 'Backframe::Reset'
17
- activation = arguments[:activation] || 'Backframe::Activation'
18
-
19
- attr_accessor :password, :change_password, :set_password, :old_password, :new_password, :confirm_password, :confirm_email
20
-
21
- has_many :activations, :class_name => activation, :dependent => :destroy, :as => :user
22
- has_many :resets, :class_name => reset, :dependent => :destroy, :as => :user
23
-
24
- after_validation :set_new_password, :if => Proc.new { |u| u.new_password.present? }
25
- after_create :activate
26
-
27
- validates_presence_of :first_name, :last_name, :email
28
- validate :validate_password, :if => Proc.new { |u| u.change_password.present? || u.set_password.present? }
29
-
30
- class_eval <<-EOV
31
- def full_name
32
- self.first_name+' '+self.last_name
33
- end
34
-
35
- def rfc822
36
- self.full_name+' <'+self.email+'>'
37
- end
38
-
39
- def locked_out?
40
- self.signin_locked_at.present? && self.signin_locked_at > Time.now.ago(5.minutes)
41
- end
42
-
43
- def signin(status)
44
- if status == :success
45
- self.signin_locked_at = nil
46
- self.signin_attempts = 0
47
- elsif status == :failed
48
- self.signin_attempts += 1
49
- if self.signin_attempts >= 5
50
- self.signin_attempts = 0
51
- self.signin_locked_at = Time.now
52
- end
53
- end
54
- self.save
55
- end
56
-
57
- def authenticate(password)
58
- self.password_hash == BCrypt::Engine.hash_secret(password, self.password_salt)
59
- end
60
-
61
- def password=(password)
62
- @password = password
63
- self.password_salt = BCrypt::Engine.generate_salt
64
- self.password_hash = BCrypt::Engine.hash_secret(password, self.password_salt)
65
- end
66
-
67
- def password
68
- @password
69
- end
70
-
71
- def validate_password
72
- if self.change_password && self.old_password.blank?
73
- return self.errors.add(:old_password, I18n.t('activerecord.errors.messages.blank'))
74
- elsif self.change_password && !authenticate(self.old_password)
75
- return self.errors.add(:old_password, I18n.t(:user_invalid_old_password))
76
- elsif self.new_password.blank? || self.confirm_password.blank?
77
- return self.errors.add(:new_password, I18n.t(:user_unconfirmed_password))
78
- elsif self.confirm_password != self.new_password
79
- return self.errors.add(:new_password, I18n.t(:user_unmatching_passwords))
80
- end
81
- end
82
-
83
- def set_new_password
84
- self.password = self.new_password
85
- end
86
-
87
- def activate
88
- self.activations.create
89
- end
90
-
91
- def reset
92
- self.resets.create
93
- end
94
-
95
- EOV
96
-
97
- end
98
-
99
- end
100
- end
101
- end
@@ -1,32 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- module DefaultValues
5
- extend ActiveSupport::Concern
6
-
7
- def self.included(base)
8
- base.send :extend, ClassMethods
9
- end
10
-
11
- module ClassMethods
12
-
13
- def default_values(*args)
14
-
15
- arguments = args[0] || {}
16
-
17
- after_initialize :set_default_values, :if => Proc.new { |o| o.new_record? }
18
-
19
- class_eval <<-EOV
20
-
21
- def set_default_values
22
- self.attributes = #{arguments.symbolize_keys.to_s}
23
- end
24
-
25
- EOV
26
-
27
-
28
- end
29
-
30
- end
31
- end
32
- end
@@ -1,79 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- module FilterSort
5
- extend ActiveSupport::Concern
6
-
7
- class_methods do
8
- def filter_query(relation, filters, fields)
9
- if filters.key?(:q)
10
- conditions = []
11
- params = []
12
- fields.each do |field|
13
- column = (field.match(/.*\..*/)) ? field : "\"#{self.table_name}\".\"#{field}\""
14
- conditions << "LOWER(#{column}::VARCHAR) LIKE ?"
15
- params << '%'+filters[:q].downcase+'%'
16
- end
17
- args = params.unshift(conditions.join(' OR '))
18
- relation = relation.where(args)
19
- end
20
- relation
21
- end
22
-
23
- def filter_range(relation, filters, start_date, end_date = nil)
24
- end_date ||= start_date
25
- if filters.key?(:start_date) && filters.key?(:end_date)
26
- relation = relation.where("\"#{self.table_name}\".\"#{start_date}\" <= ? AND \"#{self.table_name}\".\"#{end_date}\" >= ?", filters[:end_date], filters[:start_date])
27
- end
28
- relation
29
- end
30
-
31
- def filter_boolean(relation, filters, field)
32
- if filters.key?(field)
33
- relation = relation.where("\"#{self.table_name}\".\"#{field}\" = ?", true) if ["1","true"].include?(filters[field].to_s)
34
- relation = relation.where("\"#{self.table_name}\".\"#{field}\" = ?", false) if ["0","false"].include?(filters[field].to_s)
35
- end
36
- relation
37
- end
38
-
39
- def filter_status(relation, filters, field, value)
40
- if filters.key?(value)
41
- relation = relation.where("\"#{self.table_name}\".\"#{field}\" = ?", value) if ["1","true"].include?(filters[value].to_s)
42
- relation = relation.where("\"#{self.table_name}\".\"#{field}\" != ?", value) if ["0","false"].include?(filters[value].to_s)
43
- end
44
- relation
45
- end
46
-
47
- def sort(relation, key = nil, order = nil)
48
- self._sort(relation, key, order, 'created_at', 'desc', [self])
49
- end
50
-
51
- def _sort(relation, key, order, default_key = 'created_at', default_order = 'desc', included = nil)
52
- sortfields = {}
53
- sortjoins = {}
54
- self.columns.each do |column|
55
- sortfields[column.name] = "\"#{self.table_name}\".\"#{column.name}\""
56
- end
57
- model_table = self.table_name
58
- associations = self.reflect_on_all_associations(:belongs_to)
59
- associations.each do |association|
60
- if !(association.options.key?(:polymorphic) && association.options[:polymorphic])
61
- association_name = association.name
62
- association_table = association.class_name.constantize.table_name
63
- association_foreign_key = association.foreign_key
64
- sortjoins["#{association.name}"] = "LEFT OUTER JOIN \"#{association_table}\" #{association_name} ON (\"#{association_name}\".\"id\" = \"#{model_table}\".\"#{association_foreign_key}\")"
65
- association.class_name.constantize.columns.each do |column|
66
- sortfields["#{association_name}.#{column.name}"] = "\"#{association_name}\".\"#{column.name}\""
67
- end
68
- end
69
- end
70
- key = (key.present? && sortfields.has_key?(key)) ? key : default_key
71
- order = (order.present?) ? order : default_order
72
- if parts = key.match(/(\w*)\.(\w*)/)
73
- relation = relation.joins(sortjoins[parts[1]])
74
- end
75
- relation.order("#{sortfields[key]} #{order}")
76
- end
77
- end
78
- end
79
- end
@@ -1,25 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- module Migration
5
- extend ActiveSupport::Concern
6
-
7
- def self.included(base)
8
- base.send :extend, ClassMethods
9
- end
10
-
11
- module ClassMethods
12
-
13
- def add_foreign_key_index(from, to, column)
14
- add_foreign_key(from, to, :column => column)
15
- add_index(from, column)
16
- end
17
-
18
- def remove_foreign_key_index(from, column)
19
- add_index(from, column)
20
- add_foreign_key(from, :column => column)
21
- end
22
-
23
- end
24
- end
25
- end
@@ -1,45 +0,0 @@
1
- require 'backframe/image_cache/lib/asset'
2
- require 'backframe/image_cache/lib/cache'
3
- require 'backframe/image_cache/lib/conversions'
4
-
5
- module Backframe
6
-
7
- module ImageCache
8
-
9
- class Base
10
-
11
- def asset(filepath, conversions)
12
- Backframe::ImageCache::Asset.new(filepath, conversions).process
13
- end
14
-
15
- def cached(filepath, conversions)
16
- Backframe::ImageCache::Cache.new(filepath, conversions).process
17
- end
18
-
19
- def path(filepath, conversions)
20
- string = Backframe::ImageCache::Conversions.new(conversions).to_s
21
- filekey = filepath || 'default.jpg'
22
- "/imagecache/#{string}/#{filekey}"
23
- end
24
-
25
- def url(filepath, conversions)
26
- Rails.application.config.root_url + path(filepath, conversions)
27
- end
28
-
29
- def http_url(filepath, conversions)
30
- url(filepath, conversions).gsub('https', 'http')
31
- end
32
-
33
- def cdn_url(filepath, conversions)
34
- Rails.application.config.cdn_url + path(filepath, conversions)
35
- end
36
-
37
- def http_cdn_url(filepath, conversions)
38
- cdn_url(filepath, conversions).gsub('https', 'http')
39
- end
40
-
41
- end
42
-
43
- end
44
-
45
- end
@@ -1,109 +0,0 @@
1
- require 'stringio'
2
-
3
- module Backframe
4
-
5
- module ImageCache
6
-
7
- class Asset
8
-
9
- def initialize(filepath, conversions)
10
- @filepath = filepath
11
- @conversions = conversions
12
- end
13
-
14
- def process
15
- normalized = Backframe::ImageCache::Conversions.new(conversions)
16
- if filepath.present?
17
- fullpath = fullpath(filepath)
18
- content_type = content_type(filepath)
19
- data = download(fullpath)
20
- oriented = auto_orient(data)
21
- command = expand(normalized)
22
- converted = execute(oriented, command)
23
- else
24
- converted = default_asset
25
- end
26
- compressed = compress(converted)
27
- OpenStruct.new({ :success => true, :data => compressed, :content_type => content_type })
28
- end
29
-
30
- private
31
-
32
- attr_reader :filepath, :conversions
33
-
34
- def fullpath(path)
35
- File.exist?("#{Rails.root}/public/#{path}") ? "#{Rails.root}/public/#{path}" : "#{Rails.application.config.cdn_url}/#{path}"
36
- end
37
-
38
- def download(path)
39
- open(path).read
40
- end
41
-
42
- def auto_orient(data)
43
- execute(data, '-auto-orient')
44
- end
45
-
46
- def content_type(filepath)
47
- ext = extension(filepath)
48
- "image/#{ext}"
49
- end
50
-
51
- def extension(filepath)
52
- filepath.match(/.*\.([a-z]*)$/)[1]
53
- end
54
-
55
- def expand(conversions)
56
- command = []
57
- conversions.to_a.each do |conversion|
58
- if conversion.key?(:fit)
59
- width = conversion[:fit][:width] * conversion[:density]
60
- height = conversion[:fit][:height] * conversion[:density]
61
- command << "-resize \"#{width}x#{height}^\" -gravity center -crop '#{width}x#{height}+0+0'"
62
- elsif conversion.key?(:height)
63
- height = conversion[:height] * conversion[:density]
64
- command << "-resize \"x#{height}\""
65
- elsif conversion.key?(:width)
66
- width = conversion[:width] * conversion[:density]
67
- command << "-resize \"#{width}\""
68
- elsif conversion.key?(:crop)
69
- command << "-crop '#{parts[1]}x#{parts[2]}+#{parts[3]}+#{parts[4]}'"
70
- end
71
- end
72
- command.join(' ')
73
- end
74
-
75
- def default_asset
76
- path = "#{Rails.root}/tmp/canvas.png"
77
- command = "convert 10x10 canvas:#EEEEEE #{conversions} '#{path}'"
78
- Rails.logger.debug(command)
79
- output = `#{command}`
80
- IO.read(path)
81
- end
82
-
83
- #################### UTILITIES ####################
84
-
85
- def tmpfile(data)
86
- filename = SecureRandom.hex(32).to_s.upcase[0,8]
87
- tmpfile = Tempfile.new(filename, :encoding => 'ascii-8bit')
88
- tmpfile.write(data)
89
- tmpfile.close if tmpfile && !tmpfile.closed?
90
- tmpfile
91
- end
92
-
93
- def execute(data, command)
94
- tmpfile = tmpfile(data)
95
- command = "convert '#{tmpfile.path}' #{command} '#{tmpfile.path}'"
96
- Rails.logger.debug(command)
97
- output = `#{command}`
98
- IO.read(tmpfile.path)
99
- end
100
-
101
- def compress(data)
102
- ActiveSupport::Gzip.compress(data)
103
- end
104
-
105
- end
106
-
107
- end
108
-
109
- end