web-connect 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|