backframe 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b82eb2645a15741b2dfda3c0fea9ae60c1d90ed8
4
- data.tar.gz: 32f108b39fe6a99f90b936e4d47964cf9b25f2b2
3
+ metadata.gz: c790128270ae83c43af08ac36a24e55aa5241b8b
4
+ data.tar.gz: 221387ef8f5007debad90f610d3dd2567019995f
5
5
  SHA512:
6
- metadata.gz: e6176bfbbef7a17bdf19d1cefb6bd55f7b015a7b8dba667b2d89a85677612795c99c63503443f7a9874a2a2a3bc141990fa199d5d7a5db49e4623d47527142aa
7
- data.tar.gz: 02130ecd29e535126f3714f75d43b78bf6ccd204399fd80c928b56a874f072c793b06bb1a854cdae6e12065cfb5467b22daf393f5dcc4cf14d5944b6243106ef
6
+ metadata.gz: b712a396fbf157b3b0fb6b3bd796d0711044e3d4c1814709577c9357c7bd04cf3763507b056f6e8937095d4a8e7e4370f626a6519b5b4523f29cb95b05e40afd
7
+ data.tar.gz: 966fe448084e3ea8841b444680f6aaa08639587ca4f6af1a87e3a6a2898750a2b6b2adc3dfa0d877e19f7305fac04b79381f33248522b0014bec85be1ba79dbe
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Backframe
2
2
 
3
+ Backframe is a library of server side bindings for building Rails backends for Reframe apps
4
+
3
5
  ## Development
4
6
 
5
7
  bundle install
6
8
  bundle exec rake spec
9
+
10
+
@@ -1,6 +1,7 @@
1
1
  module Backframe
2
- module API
2
+ module ActsAsAPI
3
3
  class Adapter < ActiveModel::Serializer::Adapter::Attributes
4
+
4
5
  attr_reader :fields, :links
5
6
 
6
7
  def initialize(serializer, options = {})
@@ -23,27 +24,28 @@ module Backframe
23
24
 
24
25
  private
25
26
 
26
- def with_pagination_metadata(records)
27
- {
28
- records: records.map(&method(:select_fields)),
29
- total_records: paginated.total_count,
30
- total_pages: paginated.total_pages,
31
- current_page: paginated.current_page,
32
- links: links
33
- }
34
- end
27
+ def with_pagination_metadata(records)
28
+ {
29
+ records: records.map(&method(:select_fields)),
30
+ total_records: paginated.total_count,
31
+ total_pages: paginated.total_pages,
32
+ current_page: paginated.current_page,
33
+ links: links
34
+ }
35
+ end
35
36
 
36
- def paginated
37
- serializer.object
38
- end
37
+ def paginated
38
+ serializer.object
39
+ end
39
40
 
40
- def select_fields(object)
41
- if fields.present?
42
- object.select { |key, val| fields.include?(key) }
43
- else
44
- object
41
+ def select_fields(object)
42
+ if fields.present?
43
+ object.select { |key, val| fields.include?(key) }
44
+ else
45
+ object
46
+ end
45
47
  end
46
- end
48
+
47
49
  end
48
50
  end
49
51
  end
@@ -1,5 +1,5 @@
1
1
  module Backframe
2
- module API
2
+ module ActsAsAPI
3
3
  module Errors
4
4
  def unauthenticated_request
5
5
  error_response(:unauthenticated, 401)
@@ -24,7 +24,7 @@ module Backframe
24
24
 
25
25
  result = {
26
26
  error: {
27
- message: I18n.t("backframe.api.#{code}", method: request.method),
27
+ message: I18n.t("backframe.acts_as_api.#{code}", method: request.method),
28
28
  status: status
29
29
  }
30
30
  }
@@ -34,7 +34,7 @@ module Backframe
34
34
 
35
35
  def resource_error_response(resource, status = 500)
36
36
  result = {
37
- message: I18n.t('backframe.api.resource_error', request: request),
37
+ message: I18n.t('backframe.acts_as_api.resource_error', request: request),
38
38
  errors: resource.errors,
39
39
  status: status
40
40
  }
@@ -1,5 +1,5 @@
1
1
  module Backframe
2
- module API
2
+ module ActsAsAPI
3
3
  module Headers
4
4
  def set_expiration_header
5
5
  headers['Last-Modified'] = Time.now.httpdate
@@ -1,5 +1,5 @@
1
1
  module Backframe
2
- module API
2
+ module ActsAsAPI
3
3
  module Page
4
4
  DEFAULT_PAGE = 1
5
5
  DEFAULT_PER_PAGE = 100
@@ -35,85 +35,67 @@ module Backframe
35
35
  args[:page] ||= DEFAULT_PAGE
36
36
  args[:per_page] ||= DEFAULT_PER_PAGE
37
37
 
38
-
39
- collection = collection.page(args[:page]).per(args[:per_page])
40
- fields = (args.key?(:fields)) ? args[:fields].split(',').map(&:to_sym) : serializer._attributes
38
+ collection = (params[:format] == 'json') ? collection.page(args[:page]).per(args[:per_page]) : collection.all
41
39
 
42
40
  respond_to do |format|
43
41
  format.json {
42
+ fields = (args.key?(:fields)) ? args[:fields].split(',').map(&:to_sym) : serializer._attributes
44
43
  render json: collection,
45
44
  content_type: 'application/json',
46
- adapter: Backframe::API::Adapter,
45
+ adapter: Backframe::ActsAsAPI::Adapter,
47
46
  fields: fields,
48
- links: pagination_links(collection, args[:per_page], args[:page])
47
+ links: pagination_links(collection, args[:per_page], args[:page]),
48
+ status: 200
49
49
  }
50
50
  format.csv {
51
- content_type = (args.key?(:plain)) ? 'text/plain' : 'text/csv'
51
+ fields = expand_fields(collection, serializer, fields)
52
+ content_type = (args.key?(:download) && args[:download] == 'false') ? 'text/plain' : 'text/csv'
52
53
  render :text => collection_to_csv(collection, serializer, fields, ","), :content_type => content_type, :status => 200
53
54
  }
54
55
  format.tsv {
55
- content_type = (args.key?(:plain)) ? 'text/plain' : 'text/tab-separated-values'
56
+ fields = expand_fields(collection, serializer, fields)
57
+ content_type = (args.key?(:download) && args[:download] == 'false') ? 'text/plain' : 'text/tab-separated-values'
56
58
  render :text => collection_to_csv(collection, serializer, fields, "\t"), :content_type => content_type, :status => 200
57
59
  }
58
- format.xls {
59
- content_type = (args.key?(:plain)) ? 'text/xml' : 'application/xls'
60
- render :text => collection_to_xls(collection, serializer, fields), :content_type => content_type, :status => 200
61
- }
62
60
  format.xlsx {
63
- content_type = (args.key?(:plain)) ? 'text/xml' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
64
- render :text => collection_to_xls(collection, serializer, fields), :content_type => content_type, :status => 200
61
+ fields = expand_fields(collection, serializer, fields)
62
+ render :text => collection_to_xls(collection, serializer, fields), :content_type => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', :status => 200
65
63
  }
66
64
  end
67
65
  end
68
66
 
69
- def collection_to_csv(collection, serializer, fields, separator)
70
- rows = []
71
- line = []
72
- headers = []
73
- collection.each do |record|
74
- headers = []
75
- line = []
76
- serialized = OpenStruct.new(ActiveModel::SerializableResource.new(record).as_json)
77
- fields.each do |fullkey|
78
- value = serialized
79
- fullkey.to_s.split(".").each do |key|
80
- if value.respond_to?(key)
81
- value = value.send(key)
82
- if value.is_a?(Time)
83
- value = value.strftime("%F %T")
84
- elsif value.is_a?(Date)
85
- value = value.strftime("%F")
86
- elsif value.is_a?(Hash)
87
- value = OpenStruct.new(value)
88
- else
89
- value = value.to_s
90
- end
91
- else
92
- value = nil
93
- end
94
- end
95
- if !value.is_a?(OpenStruct)
96
- headers << fullkey
97
- line << value
98
- end
67
+ def expand_fields(collection, serializer, fields)
68
+ if fields.present?
69
+ fields.split(',').map(&:to_s)
70
+ else
71
+ serialized = serializer.new(collection.first).attributes
72
+ flatten_hash_keys(serialized)
73
+ end
74
+ end
75
+
76
+ def flatten_hash_keys(hash, prefix = '')
77
+ keys = []
78
+ hash.each do |key, value|
79
+ fullkey = (!prefix.empty?) ? "#{prefix}.#{key}" : key
80
+ if value.is_a?(Hash)
81
+ keys.concat(flatten_hash_keys(value, fullkey))
82
+ else
83
+ keys << fullkey.to_s
99
84
  end
100
- rows << line.join(separator)
101
85
  end
102
- rows.unshift(headers.join(separator))
103
- rows.join("\n")
86
+ keys
104
87
  end
105
88
 
106
- def collection_to_xls(collection, serializer, fields)
107
- filename = SecureRandom.hex(32).to_s.upcase[0,16]
108
- workbook = WriteXLSX.new(filename)
109
- worksheet = workbook.add_worksheet
110
- row = 0
111
- col = 0
112
- fields.each_with_index do |key, col|
113
- worksheet.write(row, col, key)
89
+ def collection_to_array(collection, serializer, fields)
90
+ rows = []
91
+ cols = []
92
+ row = []
93
+ fields.each do |key|
94
+ row << key
114
95
  end
115
- collection.all.each_with_index do |record, index|
116
- row = index + 1
96
+ rows << row
97
+ collection.all.each do |record|
98
+ row = []
117
99
  serialized = serializer.new(record).attributes
118
100
  fields.each_with_index do |fullkey, col|
119
101
  value = serialized
@@ -133,9 +115,33 @@ module Backframe
133
115
  value = 'true'
134
116
  elsif value.is_a?(FalseClass)
135
117
  value = 'false'
118
+ elsif value.is_a?(NilClass)
119
+ value = ''
136
120
  end
137
- value = (!value.is_a?(String)) ? '' : value
138
- worksheet.write(row, col, value)
121
+ row << "#{value}"
122
+ end
123
+ rows << row
124
+ end
125
+ rows
126
+ end
127
+
128
+ def collection_to_csv(collection, serializer, fields, separator)
129
+ output = []
130
+ rows = collection_to_array(collection, serializer, fields)
131
+ rows.each do |row|
132
+ output << row.join(separator)
133
+ end
134
+ output.join("\n")
135
+ end
136
+
137
+ def collection_to_xls(collection, serializer, fields)
138
+ filename = SecureRandom.hex(32).to_s.upcase[0,16]
139
+ workbook = WriteXLSX.new(filename)
140
+ worksheet = workbook.add_worksheet
141
+ rows = collection_to_array(collection, serializer, fields)
142
+ rows.each_with_index do |row, i|
143
+ row.each_with_index do |col, j|
144
+ worksheet.write(i, j, col)
139
145
  end
140
146
  end
141
147
  workbook.close
@@ -2,13 +2,13 @@ require 'active_support'
2
2
  require 'active_support/inflector'
3
3
  require 'active_model_serializers'
4
4
 
5
- require 'backframe/api/adapter'
6
- require 'backframe/api/errors'
7
- require 'backframe/api/headers'
8
- require 'backframe/api/page'
5
+ require 'backframe/acts_as_api/adapter'
6
+ require 'backframe/acts_as_api/errors'
7
+ require 'backframe/acts_as_api/headers'
8
+ require 'backframe/acts_as_api/page'
9
9
 
10
10
  module Backframe
11
- module API
11
+ module ActsAsAPI
12
12
  extend ActiveSupport::Concern
13
13
 
14
14
  class_methods do
@@ -1,5 +1,5 @@
1
1
  module Backframe
2
- module Resource
2
+ module ActsAsResource
3
3
  module Actions
4
4
  module Index
5
5
  def index
@@ -15,7 +15,7 @@ module Backframe
15
15
  Activity.create!(subject: current_user, text: 'created {object1}', object1: @item)
16
16
  end
17
17
 
18
- render json: @item, status: 201, adapter: Backframe::API::Adapter
18
+ render json: @item, status: 201, adapter: Backframe::ActsAsAPI::Adapter
19
19
  else
20
20
  resource_error_response(@item, 422)
21
21
  end
@@ -24,7 +24,7 @@ module Backframe
24
24
 
25
25
  module Show
26
26
  def show
27
- render json: @item, adapter: Backframe::API::Adapter
27
+ render json: @item, adapter: Backframe::ActsAsAPI::Adapter
28
28
  end
29
29
  end
30
30
 
@@ -51,7 +51,7 @@ module Backframe
51
51
  Activity.create!(subject: current_user, text: 'updated {object1}', object1: @item)
52
52
  end
53
53
 
54
- render json: @item, adapter: Backframe::API::Adapter
54
+ render json: @item, adapter: Backframe::ActsAsAPI::Adapter
55
55
  else
56
56
  resource_error_response(@item, 422)
57
57
  end
@@ -66,7 +66,7 @@ module Backframe
66
66
  records = update_all_params.map(&method(:update_record))
67
67
  end
68
68
 
69
- render json: records, adapter: Backframe::API::Adapter
69
+ render json: records, adapter: Backframe::ActsAsAPI::Adapter
70
70
  end
71
71
 
72
72
  private
@@ -1,9 +1,9 @@
1
1
  require 'active_support'
2
2
 
3
- require 'backframe/resource/actions'
3
+ require 'backframe/acts_as_resource/actions'
4
4
 
5
5
  module Backframe
6
- module Resource
6
+ module ActsAsResource
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  class_methods do
@@ -13,19 +13,29 @@ module Backframe
13
13
  field = args[0]
14
14
  arguments = args[1]
15
15
 
16
- if arguments.key?(:default)
17
- after_initialize :init_status, :if => Proc.new { |d| d.new_record? }
18
- end
19
16
 
20
17
  if arguments.key?(:required)
18
+
21
19
  validates_presence_of field
20
+
22
21
  end
23
22
 
24
- if arguments.key?(:in)
25
- validates_inclusion_of field, :in => arguments[:in]
23
+ if arguments.key?(:default)
24
+
25
+ after_initialize "init_#{field}_status".to_sym, :if => Proc.new { |d| d.new_record? }
26
+
27
+ class_eval <<-EOV
28
+ def init_#{field}_status
29
+ self.#{field} ||= '#{arguments[:default]}'
30
+ end
31
+ EOV
32
+
26
33
  end
27
34
 
28
35
  if arguments.key?(:in)
36
+
37
+ validates_inclusion_of field, :in => arguments[:in]
38
+
29
39
  arguments[:in].each do |status|
30
40
  class_eval <<-EOV
31
41
  scope :#{status}, -> { where(:status => '#{status}') }
@@ -35,14 +45,7 @@ module Backframe
35
45
  end
36
46
  EOV
37
47
  end
38
- end
39
48
 
40
- if arguments.key?(:default)
41
- class_eval <<-EOV
42
- def init_status
43
- self.#{field} ||= '#{arguments[:default]}'
44
- end
45
- EOV
46
49
  end
47
50
 
48
51
  end
@@ -8,7 +8,7 @@ module Backframe
8
8
  conditions = []
9
9
  params = []
10
10
  fields.each do |field|
11
- conditions << "LOWER(#{field}::VARCHAR) LIKE ?"
11
+ conditions << "LOWER(\"#{self.table_name}\".\"#{field}\"::VARCHAR) LIKE ?"
12
12
  params << '%'+filters[:q].downcase+'%'
13
13
  end
14
14
  args = params.unshift(conditions.join(' OR '))
@@ -20,15 +20,23 @@ module Backframe
20
20
  def filter_range(relation, filters, start_date, end_date = nil)
21
21
  end_date ||= start_date
22
22
  if filters.key?(:start_date) && filters.key?(:end_date)
23
- relation = relation.where("#{self.table_name}.#{start_date} <= ? AND #{self.table_name}.#{end_date} >= ?", filters[:end_date], filters[:start_date])
23
+ relation = relation.where("\"#{self.table_name}\".\"#{start_date}\" <= ? AND \"#{self.table_name}\".\"#{end_date}\" >= ?", filters[:end_date], filters[:start_date])
24
24
  end
25
25
  relation
26
26
  end
27
27
 
28
28
  def filter_boolean(relation, filters, field)
29
29
  if filters.key?(field)
30
- relation = relation.where(:field => true) if filters[field] == 1
31
- relation = relation.where(:field => false) if filters[field] == 0
30
+ relation = relation.where("\"#{self.table_name}\".\"#{field}\" = ?", true) if ["1","true"].include?(filters[field].to_s)
31
+ relation = relation.where("\"#{self.table_name}\".\"#{field}\" = ?", false) if ["0","false"].include?(filters[field].to_s)
32
+ end
33
+ relation
34
+ end
35
+
36
+ def filter_status(relation, filters, field, value)
37
+ if filters.key?(value)
38
+ relation = relation.where("\"#{self.table_name}\".\"#{field}\" = ?", value) if ["1","true"].include?(filters[value].to_s)
39
+ relation = relation.where("\"#{self.table_name}\".\"#{field}\" = ?", value) if ["0","false"].include?(filters[value].to_s)
32
40
  end
33
41
  relation
34
42
  end
@@ -4,7 +4,6 @@ module Backframe
4
4
 
5
5
  def register_types
6
6
  ::Mime::Type.register('text/tab-separated-values', :tsv)
7
- ::Mime::Type.register('application/vnd.ms-excel', :xls)
8
7
  ::Mime::Type.register('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', :xlsx)
9
8
  end
10
9
  end
@@ -1,12 +1,12 @@
1
1
  module Backframe
2
2
  class Railtie < ::Rails::Railtie
3
3
  initializer 'backframe' do |_app|
4
- ActionController::Base.send(:include, Backframe::API)
5
- ActionController::Base.send(:include, Backframe::Resource)
6
- ActiveRecord::Base.send(:include, Backframe::FilterSort)
4
+ ActionController::Base.send(:include, Backframe::ActsAsAPI)
5
+ ActionController::Base.send(:include, Backframe::ActsAsResource)
7
6
  ActiveRecord::Base.send(:include, Backframe::ActsAsOrderable)
8
- ActiveRecord::Base.send(:include, Backframe::ActsAsUser)
9
7
  ActiveRecord::Base.send(:include, Backframe::ActsAsStatus)
8
+ ActiveRecord::Base.send(:include, Backframe::ActsAsUser)
9
+ ActiveRecord::Base.send(:include, Backframe::FilterSort)
10
10
  ActiveRecord::Migration.send(:include, Backframe::Migration)
11
11
  Backframe::Mime.register_types
12
12
  end
@@ -1,3 +1,3 @@
1
1
  module Backframe
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
data/lib/backframe.rb CHANGED
@@ -1,8 +1,9 @@
1
- require 'backframe/api'
2
1
  require 'backframe/mime'
3
- require 'backframe/resource'
2
+ require 'backframe/acts_as_resource'
4
3
  require 'backframe/filter_sort'
5
4
  require 'backframe/acts_as_orderable'
5
+ require 'backframe/acts_as_api'
6
+ require 'backframe/acts_as_resource'
6
7
  require 'backframe/acts_as_status'
7
8
  require 'backframe/acts_as_user'
8
9
  require 'backframe/migration'
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Backframe::API', type: :controller do
3
+ describe 'Backframe::ActsAsAPI', type: :controller do
4
4
  controller do
5
- include Backframe::API
5
+ include Backframe::ActsAsAPI
6
6
  acts_as_api
7
7
 
8
8
  def base_api_url
@@ -13,7 +13,7 @@ describe 'Backframe::API', type: :controller do
13
13
  describe 'error handlng' do
14
14
  before { get :index }
15
15
 
16
- context 'resource not found' do
16
+ context 'acts_as_resource not found' do
17
17
  controller do
18
18
  def index
19
19
  raise ActiveRecord::RecordNotFound
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Backframe::Resource', type: :controller do
3
+ describe 'Backframe::ActsAsResource', type: :controller do
4
4
  controller do
5
- include Backframe::API
6
- include Backframe::Resource
5
+ include Backframe::ActsAsAPI
6
+ include Backframe::ActsAsResource
7
7
 
8
8
  acts_as_api
9
9
  acts_as_resource 'Example', allowed: [:a, :b, :c]
data/spec/spec_helper.rb CHANGED
@@ -45,7 +45,7 @@ module Helpers
45
45
  end
46
46
 
47
47
  def serialize(value, opts = {})
48
- opts[:adapter] ||= Backframe::API::Adapter
48
+ opts[:adapter] ||= Backframe::ActsAsAPI::Adapter
49
49
  ActiveModel::SerializableResource.new(value, opts).as_json
50
50
  end
51
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backframe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Kops
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-04-28 00:00:00.000000000 Z
12
+ date: 2016-05-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: write_xlsx
@@ -94,23 +94,23 @@ files:
94
94
  - Rakefile
95
95
  - backframe.gemspec
96
96
  - lib/backframe.rb
97
+ - lib/backframe/acts_as_api.rb
98
+ - lib/backframe/acts_as_api/adapter.rb
99
+ - lib/backframe/acts_as_api/errors.rb
100
+ - lib/backframe/acts_as_api/headers.rb
101
+ - lib/backframe/acts_as_api/page.rb
97
102
  - lib/backframe/acts_as_orderable.rb
103
+ - lib/backframe/acts_as_resource.rb
104
+ - lib/backframe/acts_as_resource/actions.rb
98
105
  - lib/backframe/acts_as_status.rb
99
106
  - lib/backframe/acts_as_user.rb
100
- - lib/backframe/api.rb
101
- - lib/backframe/api/adapter.rb
102
- - lib/backframe/api/errors.rb
103
- - lib/backframe/api/headers.rb
104
- - lib/backframe/api/page.rb
105
107
  - lib/backframe/filter_sort.rb
106
108
  - lib/backframe/migration.rb
107
109
  - lib/backframe/mime.rb
108
110
  - lib/backframe/railtie.rb
109
- - lib/backframe/resource.rb
110
- - lib/backframe/resource/actions.rb
111
111
  - lib/backframe/version.rb
112
- - spec/backframe/api_spec.rb
113
- - spec/backframe/resource_spec.rb
112
+ - spec/backframe/acts_as_api_spec.rb
113
+ - spec/backframe/acts_as_resource_spec.rb
114
114
  - spec/spec_helper.rb
115
115
  - spec/support/example.rb
116
116
  - spec/support/example_factory.rb
@@ -140,8 +140,8 @@ signing_key:
140
140
  specification_version: 4
141
141
  summary: Backframe
142
142
  test_files:
143
- - spec/backframe/api_spec.rb
144
- - spec/backframe/resource_spec.rb
143
+ - spec/backframe/acts_as_api_spec.rb
144
+ - spec/backframe/acts_as_resource_spec.rb
145
145
  - spec/spec_helper.rb
146
146
  - spec/support/example.rb
147
147
  - spec/support/example_factory.rb