web-connect 0.1.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.
- checksums.yaml +7 -0
- data/README.md +1 -0
- data/Rakefile +3 -0
- data/lib/netfira/web_connect/components/checksum.rb +19 -0
- data/lib/netfira/web_connect/components/guid.rb +11 -0
- data/lib/netfira/web_connect/components/octa_word.rb +73 -0
- data/lib/netfira/web_connect/components.rb +1 -0
- data/lib/netfira/web_connect/configuration.rb +33 -0
- data/lib/netfira/web_connect/db_schema/20140514_support.rb +38 -0
- data/lib/netfira/web_connect/db_schema/20140515_alpha.rb +106 -0
- data/lib/netfira/web_connect/events.rb +14 -0
- data/lib/netfira/web_connect/migration/base_methods.rb +59 -0
- data/lib/netfira/web_connect/migration/refinements.rb +16 -0
- data/lib/netfira/web_connect/migration.rb +101 -0
- data/lib/netfira/web_connect/model/record/digests.rb +24 -0
- data/lib/netfira/web_connect/model/record/events.rb +35 -0
- data/lib/netfira/web_connect/model/record/file_record.rb +79 -0
- data/lib/netfira/web_connect/model/record/materialization.rb +59 -0
- data/lib/netfira/web_connect/model/record/relations.rb +51 -0
- data/lib/netfira/web_connect/model/record/sendable.rb +29 -0
- data/lib/netfira/web_connect/model/record/serializer.rb +56 -0
- data/lib/netfira/web_connect/model/record/translated_string.rb +42 -0
- data/lib/netfira/web_connect/model/record/translation.rb +58 -0
- data/lib/netfira/web_connect/model/record/translations.rb +63 -0
- data/lib/netfira/web_connect/model/record/tree.rb +13 -0
- data/lib/netfira/web_connect/model/record.rb +132 -0
- data/lib/netfira/web_connect/model/relation/events.rb +34 -0
- data/lib/netfira/web_connect/model/relation.rb +67 -0
- data/lib/netfira/web_connect/model/support.rb +13 -0
- data/lib/netfira/web_connect/model.rb +33 -0
- data/lib/netfira/web_connect/models/image.rb +48 -0
- data/lib/netfira/web_connect/models/order.rb +5 -0
- data/lib/netfira/web_connect/models/order_line.rb +13 -0
- data/lib/netfira/web_connect/models/support/setting.rb +31 -0
- data/lib/netfira/web_connect/models/support/shop/settings.rb +42 -0
- data/lib/netfira/web_connect/models/support/shop.rb +22 -0
- data/lib/netfira/web_connect/models/support/table.rb +5 -0
- data/lib/netfira/web_connect/models.rb +73 -0
- data/lib/netfira/web_connect/rack_app/action.rb +66 -0
- data/lib/netfira/web_connect/rack_app/action_helpers/data_types.rb +22 -0
- data/lib/netfira/web_connect/rack_app/action_helpers/env_importer.rb +59 -0
- data/lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb +23 -0
- data/lib/netfira/web_connect/rack_app/actions/version_1/not_supported.rb +11 -0
- data/lib/netfira/web_connect/rack_app/actions/version_8/checksums.rb +14 -0
- data/lib/netfira/web_connect/rack_app/actions/version_8/commit/records.rb +45 -0
- data/lib/netfira/web_connect/rack_app/actions/version_8/commit/relations.rb +48 -0
- data/lib/netfira/web_connect/rack_app/actions/version_8/commit.rb +33 -0
- data/lib/netfira/web_connect/rack_app/actions/version_8/files.rb +21 -0
- data/lib/netfira/web_connect/rack_app/actions/version_8/info.rb +18 -0
- data/lib/netfira/web_connect/rack_app/actions/version_8/settings.rb +79 -0
- data/lib/netfira/web_connect/rack_app/exceptions/http_exception.rb +44 -0
- data/lib/netfira/web_connect/rack_app/exceptions.rb +6 -0
- data/lib/netfira/web_connect/rack_app.rb +56 -0
- data/lib/netfira/web_connect/request_filter.rb +66 -0
- data/lib/netfira/web_connect/schema/table.rb +58 -0
- data/lib/netfira/web_connect/schema.rb +22 -0
- data/lib/netfira/web_connect/version.rb +5 -0
- data/lib/netfira/web_connect.rb +82 -0
- data/lib/netfira.rb +10 -0
- data/lib/web_connect.rb +1 -0
- metadata +246 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d2700cd5cc5eadda85a187ac4d92b4b8eb1901d1
|
4
|
+
data.tar.gz: 8be1511337716328f72746dd70235f058c767d24
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 08968c7e607aa00cd578d97df1e2aecf320a3f1dfc6be796d3846166b04d1e5824921a0f22249115f0d739bc43398918a5311e5b7a5ab38394696fedba100b54
|
7
|
+
data.tar.gz: 3d621b56728b17482bc46ce4802bd045712541baa0ea37a0dda47d2076ec05a9c8d20297c0a1f80af4d7455109b2527f37efac37ed4763b99bdb81bbe87dc1c4
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
This gem provides connectivity between your app and Netfira products.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Netfira::WebConnect
|
4
|
+
class Checksum < OctaWord
|
5
|
+
|
6
|
+
def self.of(data)
|
7
|
+
new Digest::MD5.digest(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
def =~(what)
|
11
|
+
if what.is_a?(self.class)
|
12
|
+
b == what.b
|
13
|
+
else
|
14
|
+
b == self.class.of(what).b
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
class Netfira::WebConnect::OctaWord
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def from_binary(digest)
|
8
|
+
new digest
|
9
|
+
end
|
10
|
+
|
11
|
+
alias_method :from, :from_binary
|
12
|
+
|
13
|
+
def from_base64(digest)
|
14
|
+
new (digest[0..21] << '==').unpack('m').first
|
15
|
+
end
|
16
|
+
|
17
|
+
def from_hex(digest)
|
18
|
+
new [digest].pack('H*')
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(binary_digest)
|
24
|
+
@binary = binary_digest.b
|
25
|
+
end
|
26
|
+
|
27
|
+
def binary
|
28
|
+
@binary
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :b, :binary
|
32
|
+
|
33
|
+
def hex
|
34
|
+
@binary.unpack('H*')[0]
|
35
|
+
end
|
36
|
+
|
37
|
+
def base64
|
38
|
+
[@binary].pack('m0')[0..21]
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
base64
|
43
|
+
end
|
44
|
+
|
45
|
+
def inspect
|
46
|
+
"#{self.class.name.demodulize}: #{base64}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def eql?(other)
|
50
|
+
case other
|
51
|
+
when Netfira::WebConnect::OctaWord then b == other.b
|
52
|
+
when String
|
53
|
+
case other.length
|
54
|
+
when 16 then other == b
|
55
|
+
when 22 then other == base64
|
56
|
+
when 32 then other == hex
|
57
|
+
else false
|
58
|
+
end
|
59
|
+
else false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
alias_method :==, :eql?
|
64
|
+
|
65
|
+
def as_json(options = nil)
|
66
|
+
base64
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
# Subclasses:
|
72
|
+
require_relative 'guid'
|
73
|
+
require_relative 'checksum'
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'components/octa_word'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Netfira::WebConnect
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
attr_accessor :db_table_prefix, :file_store, :authenticator, :custom_fields,
|
5
|
+
:time_zone, :materialize_when_db_changed
|
6
|
+
|
7
|
+
attr_reader :logger, :db
|
8
|
+
|
9
|
+
def initialize(defaults = nil)
|
10
|
+
defaults.each{ |k, v| __send__ :"#{k}=", v } if defaults
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_authenticate(proc = nil, &block)
|
14
|
+
authenticator = proc || block
|
15
|
+
raise 'Authenticator must take exactly two arguments (shop ID and password)' unless authenticator.arity == 2
|
16
|
+
self.authenticator = authenticator
|
17
|
+
end
|
18
|
+
|
19
|
+
def db=(details)
|
20
|
+
@db = details
|
21
|
+
if details
|
22
|
+
Model.establish_connection details
|
23
|
+
Models.materialize if materialize_when_db_changed && !Netfira::WebConnect.needs_migration?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def logger=(logger)
|
28
|
+
@logger = logger
|
29
|
+
Model.logger = logger if logger
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Support < Netfira::WebConnect::Migration
|
2
|
+
using Refinements
|
3
|
+
|
4
|
+
def change
|
5
|
+
|
6
|
+
create_table :_tables do |t|
|
7
|
+
t.string :name, limit: 50, indexed: true
|
8
|
+
t.string :origin_key, limit: 20
|
9
|
+
t.boolean :file
|
10
|
+
t.boolean :writable
|
11
|
+
t.boolean :sendable
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table :_shops do |t|
|
15
|
+
t.string :name
|
16
|
+
t.index :name, unique: true
|
17
|
+
end
|
18
|
+
|
19
|
+
Netfira::WebConnect::Models::Shop.create id: 0
|
20
|
+
|
21
|
+
create_table :_settings do |t|
|
22
|
+
t.references :shop
|
23
|
+
t.string :key
|
24
|
+
t.binary :value, limit: 0x10000
|
25
|
+
t.string :content_type
|
26
|
+
end
|
27
|
+
|
28
|
+
create_table :_custom_fields do |t|
|
29
|
+
t.references :shop
|
30
|
+
t.references :table
|
31
|
+
t.references :record
|
32
|
+
t.string :key
|
33
|
+
t.binary :value, limit: 0x10000
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
class Alpha < Netfira::WebConnect::Migration
|
2
|
+
using Refinements
|
3
|
+
|
4
|
+
def change
|
5
|
+
|
6
|
+
def product(t)
|
7
|
+
t.decimal :unit_price, precision: 12, scale: 4
|
8
|
+
t.decimal :unit_tax, precision: 12, scale: 4
|
9
|
+
t.localized_string :part
|
10
|
+
t.localized_string :description
|
11
|
+
end
|
12
|
+
|
13
|
+
def buyer(t)
|
14
|
+
t.string :name
|
15
|
+
t.string :contact
|
16
|
+
t.string :email, limit: 100
|
17
|
+
t.string :phone, limit: 30
|
18
|
+
t.string :fax, limit: 30
|
19
|
+
%w[billing_ shipping_].each do |type|
|
20
|
+
t.string :"#{type}address_1", limit: 150
|
21
|
+
t.string :"#{type}address_2", limit: 150
|
22
|
+
t.string :"#{type}city", limit: 150
|
23
|
+
t.string :"#{type}state", limit: 150
|
24
|
+
t.string :"#{type}country", limit: 2
|
25
|
+
t.string :"#{type}post_code", limit: 20
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
create_record_table :products, with_l10n: true do |t|
|
31
|
+
product t
|
32
|
+
|
33
|
+
t.localized_string :category
|
34
|
+
t.localized_string :long_description, limit: 0x10000
|
35
|
+
|
36
|
+
t.decimal :stock, precision: 12, scale: 4
|
37
|
+
t.string :stock_text
|
38
|
+
|
39
|
+
t.integer :length
|
40
|
+
t.integer :height
|
41
|
+
t.integer :width
|
42
|
+
t.decimal :weight, precision: 14, scale: 3
|
43
|
+
|
44
|
+
t.boolean :show_on_website
|
45
|
+
end
|
46
|
+
|
47
|
+
create_record_table :categories, with_l10n: true do |t|
|
48
|
+
t.integer :parent_id
|
49
|
+
t.localized_string :name
|
50
|
+
end
|
51
|
+
|
52
|
+
create_record_table :buyers, origin_key: :nf_code do |t|
|
53
|
+
buyer t
|
54
|
+
|
55
|
+
t.binary :pin, limit: 255
|
56
|
+
t.boolean :website_access
|
57
|
+
t.boolean :allow_products
|
58
|
+
t.boolean :restrict_products
|
59
|
+
end
|
60
|
+
|
61
|
+
create_record_table :orders, sendable: true do |t|
|
62
|
+
t.string :nf_code
|
63
|
+
buyer t
|
64
|
+
|
65
|
+
t.string :buyer_reference
|
66
|
+
t.string :currency_code, limit: 3
|
67
|
+
|
68
|
+
t.string :shipping_method
|
69
|
+
t.decimal :shipping_price, precision: 12, scale: 4
|
70
|
+
t.decimal :shipping_tax, precision: 12, scale: 4
|
71
|
+
t.string :shipping_account
|
72
|
+
t.string :shipping_password
|
73
|
+
|
74
|
+
t.string :payment_method
|
75
|
+
t.boolean :payment_received
|
76
|
+
t.string :payment_reference
|
77
|
+
t.string :payment_error_code, limit: 16
|
78
|
+
|
79
|
+
t.string :comment, limit: 0x10000
|
80
|
+
end
|
81
|
+
|
82
|
+
create_record_table :order_lines, writable: true do |t|
|
83
|
+
t.string :product_id
|
84
|
+
product t
|
85
|
+
|
86
|
+
t.references :order
|
87
|
+
t.decimal :quantity, precision: 12, scale: 4
|
88
|
+
t.string :comment, limit: 0x10000
|
89
|
+
end
|
90
|
+
|
91
|
+
create_file_table :images do |t|
|
92
|
+
t.float :focus_point_top
|
93
|
+
t.float :focus_point_left
|
94
|
+
t.integer :size
|
95
|
+
t.integer :width
|
96
|
+
t.integer :height
|
97
|
+
end
|
98
|
+
create_file_table :attachments
|
99
|
+
|
100
|
+
create_relation_table :products, :images
|
101
|
+
create_relation_table :products, :categories
|
102
|
+
create_relation_table :products, :attachments
|
103
|
+
create_relation_table :products, :buyers
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Netfira::WebConnect
|
2
|
+
|
3
|
+
def self.event_delegates
|
4
|
+
@event_delegates ||= []
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.dispatch_event(event, *args)
|
8
|
+
target = :"on_#{event}"
|
9
|
+
event_delegates.map do |delegate|
|
10
|
+
delegate.__send__(target, *args) if delegate.respond_to? target
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Netfira::WebConnect
|
2
|
+
|
3
|
+
def self.migrate
|
4
|
+
force_db_connection { ActiveRecord::Migrator.migrate migrations_dir }
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.rollback
|
8
|
+
force_db_connection { ActiveRecord::Migrator.rollback migrations_dir }
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.needs_migration?
|
12
|
+
original = ActiveRecord::Migrator.migrations_paths
|
13
|
+
ActiveRecord::Migrator.migrations_paths = [migrations_dir]
|
14
|
+
result = force_db_connection { ActiveRecord::Migrator.needs_migration? }
|
15
|
+
ActiveRecord::Migrator.migrations_paths = original
|
16
|
+
result
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def self.migrations_dir
|
22
|
+
@migrations_dir ||= ROOT.join('web_connect/db_schema').to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
# This method tricks ActiveRecord into using the connection for Netfira::WebConnect::Model
|
26
|
+
# instead of the ActiveRecord::Base connection, which it's hard-wired to do for migrations
|
27
|
+
# and other tasks. Two methods are backed up and replaced, then restored after yield. Those
|
28
|
+
# methods are identical to the originals, except they specify `Model` in place of `self`.
|
29
|
+
def self.force_db_connection
|
30
|
+
|
31
|
+
# Save the original methods
|
32
|
+
originals = [:connection_pool, :retrieve_connection, :schema_migrations_table_name].map do |name|
|
33
|
+
[name, ActiveRecord::Base.method(name)]
|
34
|
+
end.to_h
|
35
|
+
|
36
|
+
# Add some new methods
|
37
|
+
class << ActiveRecord::Base
|
38
|
+
def connection_pool
|
39
|
+
connection_handler.retrieve_connection_pool(Model) or raise ActiveRecord::ConnectionNotEstablished
|
40
|
+
end
|
41
|
+
def retrieve_connection
|
42
|
+
connection_handler.retrieve_connection(Model)
|
43
|
+
end
|
44
|
+
def schema_migrations_table_name
|
45
|
+
Netfira::WebConnect.schema_migrations_table_name
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Run the given block
|
50
|
+
result = yield
|
51
|
+
|
52
|
+
# Restore the original methods
|
53
|
+
originals.each { |name, method| ActiveRecord::Base.define_singleton_method name, method }
|
54
|
+
|
55
|
+
# Return the result of the given block
|
56
|
+
result
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Netfira::WebConnect::Migration
|
2
|
+
module Refinements
|
3
|
+
|
4
|
+
class << self
|
5
|
+
attr_accessor :running_migration
|
6
|
+
end
|
7
|
+
|
8
|
+
refine ActiveRecord::ConnectionAdapters::TableDefinition do
|
9
|
+
|
10
|
+
def localized_string(*args)
|
11
|
+
Refinements.running_migration.add_localized_string(args) or string *args
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Netfira::WebConnect
|
4
|
+
class Migration < ActiveRecord::Migration
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :log_to_stdout
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_localized_string(args)
|
11
|
+
@l10n_buffer << args if @l10n_buffer
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_table(table_name, options = {}, &block)
|
15
|
+
super table_prefix(table_name), options, &block
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_record_table(table_name, options = {})
|
19
|
+
Refinements.running_migration = self
|
20
|
+
@l10n_buffer = options[:with_l10n] && []
|
21
|
+
options[:writable] ||= options[:sendable]
|
22
|
+
create_table table_name, options do |t|
|
23
|
+
t.string options[:origin_key] || :"#{table_name.to_s.singularize}_id", index: true unless options[:writable]
|
24
|
+
yield t
|
25
|
+
t.references :shop
|
26
|
+
if options[:sendable]
|
27
|
+
t.binary :guid, index: true
|
28
|
+
t.integer :delivery_status, default: 0, limit: 3, index: true
|
29
|
+
end
|
30
|
+
t.binary :digest, limit: 16
|
31
|
+
t.timestamps
|
32
|
+
end
|
33
|
+
if @l10n_buffer
|
34
|
+
create_l10n_table table_name do |t|
|
35
|
+
@l10n_buffer.each do |args|
|
36
|
+
t.string *args
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
add_table_def table_name, options
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_l10n_table(table_name)
|
44
|
+
create_table l10n_suffix(table_name) do |t|
|
45
|
+
t.references table_name.to_s.singularize.to_sym, index: true
|
46
|
+
t.string :language, limit: 20, index: true
|
47
|
+
yield t
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_file_table(table_name)
|
52
|
+
create_table table_name do |t|
|
53
|
+
t.references :shop
|
54
|
+
t.string :file_name, index: true
|
55
|
+
t.string :locale
|
56
|
+
yield t if block_given?
|
57
|
+
t.binary :checksum, limit: 16
|
58
|
+
t.binary :digest, limit: 16
|
59
|
+
t.timestamps
|
60
|
+
end
|
61
|
+
add_table_def table_name, {}, true
|
62
|
+
end
|
63
|
+
|
64
|
+
def create_relation_table(first, second)
|
65
|
+
first, second = [first, second].sort
|
66
|
+
create_table :"#{first}_to_#{second}" do |t|
|
67
|
+
t.references first.to_s.singularize, second.to_s.singularize, index: true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_table_def(table_name, options, is_file = false)
|
72
|
+
Models::Table.create options.select{|k| %i[origin_key writable sendable].include? k}.merge name: table_name,
|
73
|
+
file: is_file
|
74
|
+
end
|
75
|
+
|
76
|
+
def write(text = '')
|
77
|
+
if verbose
|
78
|
+
puts text if Migration.log_to_stdout
|
79
|
+
Netfira::WebConnect.logger.info text
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def schema_migrations_table_name
|
84
|
+
Netfira::WebConnect.schema_migrations_table_name
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def l10n_suffix(name = '')
|
90
|
+
Netfira::WebConnect.db_table_l10n_suffix name
|
91
|
+
end
|
92
|
+
|
93
|
+
def table_prefix(name = '')
|
94
|
+
Netfira::WebConnect.db_table_prefix name
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
require_relative 'migration/refinements'
|
101
|
+
require_relative 'migration/base_methods'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Netfira::WebConnect
|
2
|
+
class Model::Record
|
3
|
+
|
4
|
+
module Digests
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
before_save :write_digest
|
9
|
+
end
|
10
|
+
|
11
|
+
def digest
|
12
|
+
changed? ? Checksum.of(to_s) : Checksum.new(self[:digest])
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def write_digest
|
18
|
+
self.digest = digest.b
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Netfira::WebConnect
|
2
|
+
class Model::Record
|
3
|
+
module Events
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
around_save :dispatch_create_or_update
|
8
|
+
before_destroy :dispatch_destroy
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def dispatch_create_or_update
|
14
|
+
previous = persisted? && changed_attributes.map do |key, value|
|
15
|
+
# TODO: solve this type casting issue without guessing by attribute names!
|
16
|
+
value = Checksum.new(value) if value and (key == 'checksum' or key == 'digest')
|
17
|
+
[key, value]
|
18
|
+
end.to_h
|
19
|
+
yield
|
20
|
+
as_readonly do
|
21
|
+
if previous
|
22
|
+
Netfira::WebConnect.dispatch_event "update_#{self.class.single_name}", self, previous
|
23
|
+
else
|
24
|
+
Netfira::WebConnect.dispatch_event "create_#{self.class.single_name}", self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def dispatch_destroy
|
30
|
+
as_readonly { Netfira::WebConnect.dispatch_event "delete_#{self.class.single_name}", self }
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'paperclip'
|
2
|
+
|
3
|
+
Paperclip.interpolates :shop_id do |record, x|
|
4
|
+
record.instance.shop_id
|
5
|
+
end
|
6
|
+
|
7
|
+
Paperclip.interpolates :model_type do |record, x|
|
8
|
+
record.instance.class.name.demodulize.underscore.pluralize
|
9
|
+
end
|
10
|
+
|
11
|
+
module Netfira::WebConnect
|
12
|
+
class Model::Record::FileRecord
|
13
|
+
include Paperclip::Glue
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
def table_name
|
18
|
+
self == Model::Record::FileRecord ? Models::Table.table_name : super
|
19
|
+
end
|
20
|
+
|
21
|
+
def origin_key
|
22
|
+
:file_name
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
after_initialize :set_file_defaults
|
28
|
+
|
29
|
+
def <<(input)
|
30
|
+
if input.is_a? Model::Record
|
31
|
+
super input
|
32
|
+
else
|
33
|
+
self.data = input
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def checksum
|
38
|
+
bin = self[:checksum]
|
39
|
+
@checksum ||= bin && Checksum.new(bin)
|
40
|
+
end
|
41
|
+
|
42
|
+
def checksum=(value)
|
43
|
+
@checksum = nil
|
44
|
+
self[:checksum] = Checksum === value ? value.b : value
|
45
|
+
end
|
46
|
+
|
47
|
+
def data
|
48
|
+
attachment.present? ? Paperclip.io_adapters.for(attachment) : nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def data=(value)
|
52
|
+
self.attachment = value
|
53
|
+
value.rewind
|
54
|
+
self.checksum = Checksum.of(value.read)
|
55
|
+
end
|
56
|
+
|
57
|
+
def attachment_file_name
|
58
|
+
file_name
|
59
|
+
end
|
60
|
+
|
61
|
+
def attachment_file_name=(value)
|
62
|
+
self.file_name = value
|
63
|
+
end
|
64
|
+
|
65
|
+
def attachment_file_size
|
66
|
+
size
|
67
|
+
end
|
68
|
+
|
69
|
+
def attachment_file_size=(value)
|
70
|
+
self.size = value
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def set_file_defaults
|
76
|
+
self.locale ||= shop.locale
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Netfira::WebConnect
|
2
|
+
class Model::Record
|
3
|
+
module Materialization
|
4
|
+
|
5
|
+
def materialize(name, has_languages, props)
|
6
|
+
|
7
|
+
# Get a reference to the record class, creating it if it doesn't exist
|
8
|
+
klass = begin
|
9
|
+
Models.const_get name
|
10
|
+
rescue NameError
|
11
|
+
Models.const_set name, Class.new(props.file ? FileRecord : self)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Give the model access to properties from the `tables` table
|
15
|
+
klass.instance_variable_set :@table_props, props
|
16
|
+
|
17
|
+
# Add a reference to the record's shop
|
18
|
+
shop_relation = name.underscore.pluralize.to_sym
|
19
|
+
klass.belongs_to :shop,
|
20
|
+
class_name: 'Netfira::WebConnect::Models::Shop',
|
21
|
+
inverse_of: shop_relation
|
22
|
+
|
23
|
+
# Add a has-many to Shop so we can do Shop.first.products etc
|
24
|
+
Models::Shop.has_many shop_relation, inverse_of: :shop
|
25
|
+
|
26
|
+
# Set up access to localised fields
|
27
|
+
if has_languages
|
28
|
+
Model::Record::Translation.materialize klass
|
29
|
+
klass.include Model::Record::Translations
|
30
|
+
translated_attributes = klass::Translation.attribute_names.reject do |attribute|
|
31
|
+
(%w[id language] << "#{klass.single_name}_id").include? attribute
|
32
|
+
end
|
33
|
+
translated_attributes.each do |attribute|
|
34
|
+
klass.__send__ :define_method, :"#{attribute}" do
|
35
|
+
self.get_translated_string attribute.to_sym
|
36
|
+
end
|
37
|
+
klass.__send__ :define_method, :"#{attribute}=" do |value|
|
38
|
+
self.set_translated_string attribute.to_sym, value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Set up tree behaviour (parent/child relations)
|
44
|
+
klass.include Model::Record::Tree if klass.tree?
|
45
|
+
|
46
|
+
# Set up sendable behaviour
|
47
|
+
klass.include Model::Record::Sendable if klass.sendable?
|
48
|
+
|
49
|
+
# Set up file record behaviour
|
50
|
+
if klass.has_file?
|
51
|
+
klass.has_attached_file :attachment, Netfira::WebConnect.file_store
|
52
|
+
klass.do_not_validate_attachment_file_type :attachment
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|