wco_models 3.1.0.106 → 3.1.0.108
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/wco/application.css +12 -2
- data/app/controllers/wco/prices_controller.rb +23 -6
- data/app/models/wco/leadset.rb +11 -5
- data/app/models/wco/log.rb +12 -5
- data/app/models/wco/price.rb +4 -3
- data/app/models/wco/profile.rb +3 -1
- data/app/models/wco_hosting/appliance.rb +6 -1
- data/app/models/wco_hosting/appliance_tmpl.rb +58 -19
- data/app/models/wco_hosting/appliance_tmpl_leadset.rb-trash +11 -0
- data/app/models/wco_hosting/domain.rb +6 -11
- data/app/models/wco_hosting/environment.rb +21 -0
- data/app/models/wco_hosting/serverhost.rb +30 -74
- data/app/views/wco/leads/show.haml +2 -5
- data/app/views/wco/leadsets/show.haml +24 -15
- data/app/views/wco_email/conversations/_table.haml +37 -0
- data/app/views/wco_email/email_layouts/_plain.haml +7 -6
- data/app/views/wco_hosting/docker-compose/dc-react.erb +16 -0
- data/app/views/wco_hosting/scripts/create_volume.erb +2 -2
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8706a7b05378bf7a694edf8416487aa9a7920fbb5ed36b7778c04c92b724c02e
|
4
|
+
data.tar.gz: ffe882298978ee235e32685f1af787441600f9080f82de19dc5e1df13848da67
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de578ad03d83e137aad9c554453046707ce8cf7af713adbbc5dbb3e7dfa0e1fc830032bbc9e7d4c39e56a90cfd42637845f302adebe3f0fa28da87c8bcd394b8
|
7
|
+
data.tar.gz: 34aecef5762a97c603d6321bca2bf75c8cf4b4416032a24dbf815288a151ff51556b08cb33620e88c4a9ffd66bd9f35f585b91258af5702f518690d4925cd8bb
|
@@ -5,10 +5,12 @@
|
|
5
5
|
*= require_tree .
|
6
6
|
**/
|
7
7
|
|
8
|
-
.
|
9
|
-
|
8
|
+
.bold {
|
9
|
+
font-weight: bold;
|
10
10
|
}
|
11
11
|
|
12
|
+
|
13
|
+
|
12
14
|
.main-footer {
|
13
15
|
border-top: 2px solid #6395b9;
|
14
16
|
}
|
@@ -24,3 +26,11 @@
|
|
24
26
|
}
|
25
27
|
}
|
26
28
|
}
|
29
|
+
|
30
|
+
.select2 {
|
31
|
+
min-width: 200px;
|
32
|
+
}
|
33
|
+
|
34
|
+
td.tags {
|
35
|
+
min-width: 200px;
|
36
|
+
}
|
@@ -2,11 +2,11 @@
|
|
2
2
|
class Wco::PricesController < Wco::ApplicationController
|
3
3
|
|
4
4
|
def create
|
5
|
-
@price = Wco::Price.new params[:price].permit
|
5
|
+
@price = Wco::Price.new params[:price].permit!
|
6
6
|
authorize! :create, @price
|
7
7
|
|
8
8
|
@price.interval = nil if !params[:price][:interval].present?
|
9
|
-
@product =
|
9
|
+
@product = params[:price][:product_type].constantize.find @price.product_id
|
10
10
|
stripe_product = Stripe::Product.retrieve( @product.product_id )
|
11
11
|
price_hash = {
|
12
12
|
product: stripe_product.id,
|
@@ -17,17 +17,34 @@ class Wco::PricesController < Wco::ApplicationController
|
|
17
17
|
price_hash[:recurring] = { interval: @price.interval }
|
18
18
|
end
|
19
19
|
stripe_price = Stripe::Price.create( price_hash )
|
20
|
-
#
|
20
|
+
# flash_notice 'Created stripe price.'
|
21
|
+
flash_notice stripe_price
|
21
22
|
|
22
|
-
|
23
|
-
@price.product = @product
|
23
|
+
@price.product = @product
|
24
24
|
@price.price_id = stripe_price[:id]
|
25
25
|
if @price.save
|
26
26
|
flash_notice @price
|
27
27
|
else
|
28
28
|
flash_alert @price
|
29
29
|
end
|
30
|
-
|
30
|
+
case @product.class.name
|
31
|
+
when 'WcoHosting::ApplianceTmpl'
|
32
|
+
redirect_to request.referrer || root_path
|
33
|
+
when 'Wco::Product'
|
34
|
+
redirect_to controller: :products, action: :index
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
@price = Wco::Price.find params[:id]
|
40
|
+
authorize! :destroy, @price
|
41
|
+
flag = @price.delete
|
42
|
+
if flag
|
43
|
+
flash_notice 'ok'
|
44
|
+
else
|
45
|
+
flash_alert @price
|
46
|
+
end
|
47
|
+
redirect_to request.referrer || root_path
|
31
48
|
end
|
32
49
|
|
33
50
|
def update
|
data/app/models/wco/leadset.rb
CHANGED
@@ -17,20 +17,26 @@ class Wco::Leadset
|
|
17
17
|
index({ email: 1 }, { name: 'email' })
|
18
18
|
validates :email, uniqueness: { allow_nil: true } # presence: true
|
19
19
|
|
20
|
+
|
21
|
+
has_many :appliances, class_name: '::WcoHosting::Appliance', inverse_of: :leadset
|
22
|
+
has_many :appliance_tmpl_prices, class_name: 'Wco::Price'
|
23
|
+
has_many :environments, class_name: '::WcoHosting::Environment', inverse_of: :leadset
|
24
|
+
has_many :invoices, class_name: 'Wco::Invoice'
|
20
25
|
has_many :leads, class_name: 'Wco::Lead'
|
21
|
-
|
22
|
-
has_many :
|
23
|
-
has_many :subscriptions, class_name: 'Wco::Subscription',
|
26
|
+
|
27
|
+
has_many :profiles, class_name: 'Wco::Profile', inverse_of: :leadset
|
28
|
+
has_many :subscriptions, class_name: 'Wco::Subscription', inverse_of: :leadset
|
24
29
|
has_and_belongs_to_many :tags, class_name: 'Wco::Tag'
|
25
30
|
|
26
|
-
|
31
|
+
|
27
32
|
field :next_invoice_number, type: :integer, default: 100
|
28
33
|
|
29
|
-
has_and_belongs_to_many :serverhosts, class_name: 'WcoHosting::Serverhost' # , inverse_of: :leadset
|
34
|
+
has_and_belongs_to_many :serverhosts, class_name: '::WcoHosting::Serverhost' # , inverse_of: :leadset
|
30
35
|
def next_serverhost
|
31
36
|
serverhosts.first
|
32
37
|
end
|
33
38
|
|
39
|
+
|
34
40
|
##
|
35
41
|
## stripe
|
36
42
|
##
|
data/app/models/wco/log.rb
CHANGED
@@ -6,13 +6,20 @@ class Wco::Log
|
|
6
6
|
include Mongoid::Paranoia
|
7
7
|
store_in collection: 'wco_logs'
|
8
8
|
|
9
|
-
field :
|
9
|
+
field :label, type: :string
|
10
|
+
field :message, type: :string
|
10
11
|
|
11
|
-
|
12
|
-
field :object_id
|
13
|
-
|
14
|
-
field :raw_json, type: Object, default: '{}'
|
12
|
+
belongs_to :obj, polymorphic: true, optional: true
|
15
13
|
|
16
14
|
has_and_belongs_to_many :tags
|
17
15
|
|
16
|
+
def self.puts! message, label, obj: nil
|
17
|
+
create( message: message, label: label, obj: obj )
|
18
|
+
puts "+++ +++ #{label}:"
|
19
|
+
puts message.inspect
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"#{created_at} #{message}"
|
24
|
+
end
|
18
25
|
end
|
data/app/models/wco/price.rb
CHANGED
@@ -5,9 +5,10 @@ class Wco::Price
|
|
5
5
|
include Mongoid::Paranoia
|
6
6
|
store_in collection: 'wco_prices'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
## Wco::Product, WcoHosting::ApplianceTmpl
|
9
|
+
belongs_to :product, polymorphic: true
|
10
|
+
|
11
|
+
belongs_to :appliance_tmpl_leadset, class_name: 'Wco::Leadset', optional: true
|
11
12
|
|
12
13
|
has_many :subscriptions, class_name: 'Wco::Subscription', inverse_of: :price, foreign_key: :wco_price_id
|
13
14
|
|
data/app/models/wco/profile.rb
CHANGED
@@ -5,6 +5,8 @@ class WcoHosting::Appliance
|
|
5
5
|
include Mongoid::Paranoia
|
6
6
|
store_in collection: 'wco_appliances'
|
7
7
|
|
8
|
+
has_many :logs, as: :obj, class_name: 'Wco::Log'
|
9
|
+
|
8
10
|
belongs_to :leadset, class_name: 'Wco::Leadset', inverse_of: :appliances
|
9
11
|
belongs_to :subscription, class_name: 'Wco::Subscription' # , inverse_of: :appliance
|
10
12
|
|
@@ -14,7 +16,7 @@ class WcoHosting::Appliance
|
|
14
16
|
self[:service_name] = host.gsub(".", "_")
|
15
17
|
end
|
16
18
|
|
17
|
-
|
19
|
+
belongs_to :environment, class_name: 'WcoHosting::Environment', inverse_of: :appliances
|
18
20
|
|
19
21
|
field :subdomain
|
20
22
|
field :domain
|
@@ -41,6 +43,9 @@ class WcoHosting::Appliance
|
|
41
43
|
STATE_TERM = 'state-term'
|
42
44
|
field :state, default: STATE_PENDING
|
43
45
|
|
46
|
+
def to_s
|
47
|
+
service_name
|
48
|
+
end
|
44
49
|
end
|
45
50
|
|
46
51
|
|
@@ -24,18 +24,6 @@ class WcoHosting::ApplianceTmpl
|
|
24
24
|
field :volume_zip
|
25
25
|
validates :volume_zip, presence: true
|
26
26
|
|
27
|
-
## Only underscores! These become variable names.
|
28
|
-
# KIND_CRM = 'kind_crm'
|
29
|
-
# KIND_DRUPAL = 'kind_drupal'
|
30
|
-
# KIND_HELLOWORLD = 'kind_helloworld'
|
31
|
-
# KIND_IROWOR = 'kind_irowor'
|
32
|
-
# KIND_JENKINS = 'kind_jenkins'
|
33
|
-
# KIND_MATOMO = 'kind_matomo'
|
34
|
-
# KIND_MOODLE = 'kind_moodle'
|
35
|
-
# KIND_PRESTASHOP = 'kind_prestashop'
|
36
|
-
# KIND_SMT = 'kind_smt'
|
37
|
-
# KIND_WORDPRESS = 'kind_wordpress'
|
38
|
-
|
39
27
|
## 2023-12-08 :: These names are impossible to change already.
|
40
28
|
KIND_CRM = 'crm'
|
41
29
|
KIND_DRUPAL = 'drupal'
|
@@ -45,33 +33,84 @@ class WcoHosting::ApplianceTmpl
|
|
45
33
|
KIND_MATOMO = 'matomo'
|
46
34
|
KIND_MOODLE = 'moodle'
|
47
35
|
KIND_PRESTASHOP = 'prestashop'
|
36
|
+
KIND_REACT = 'react'
|
48
37
|
KIND_SMT = 'smt'
|
49
38
|
KIND_WORDPRESS = 'wordpress'
|
50
39
|
KIND_TRASH = 'trash'
|
51
40
|
KIND_TMP = 'tmp'
|
52
41
|
|
53
42
|
KINDS = [ nil, KIND_CRM, KIND_DRUPAL, KIND_HELLOWORLD, KIND_IROWOR,
|
54
|
-
KIND_JENKINS, KIND_MATOMO, KIND_MOODLE, KIND_PRESTASHOP,
|
43
|
+
KIND_JENKINS, KIND_MATOMO, KIND_MOODLE, KIND_PRESTASHOP,
|
44
|
+
KIND_REACT,
|
45
|
+
KIND_SMT,
|
55
46
|
KIND_WORDPRESS, KIND_TRASH, KIND_TMP ]
|
56
47
|
|
57
|
-
|
58
|
-
# [[nil,nil]] + all.map { |t| [t.kind, t.id] }
|
59
|
-
KINDS
|
60
|
-
end
|
48
|
+
|
61
49
|
|
62
50
|
def self.latest_of kind
|
63
51
|
where({ kind: kind }).order_by({ version: :desc }).first
|
64
52
|
end
|
65
53
|
|
66
54
|
has_many :appliances, class_name: 'WcoHosting::Appliance'
|
67
|
-
|
68
55
|
has_many :subscriptions, as: :product, class_name: 'Wco::Subscription'
|
56
|
+
has_many :prices, as: :product, class_name: 'Wco::Price'
|
57
|
+
|
58
|
+
# has_and_belongs_to_many :leadsets, class_name: 'Wco::Leadset'
|
59
|
+
# has_many :appliance_tmpl_leadsets, class_name: 'WcoHosting::ApplianceTmplLeadset'
|
69
60
|
|
70
61
|
field :product_id # stripe
|
71
62
|
|
72
63
|
# belongs_to :price, class_name: 'Wco::Price', foreign_key: :wco_price_id
|
73
|
-
|
64
|
+
|
74
65
|
field :price_id # stripe
|
66
|
+
attr_accessor :tmp_price_cents
|
67
|
+
attr_accessor :tmp_price_interval
|
68
|
+
before_validation :set_stripe_product_price, on: :create
|
69
|
+
def set_stripe_product_price
|
70
|
+
stripe_product = Stripe::Product.create({ name: "Appliance #{self}" })
|
71
|
+
self.product_id = stripe_product.id
|
72
|
+
|
73
|
+
wco_price = Wco::Price.create!({
|
74
|
+
amount_cents: tmp_price_cents,
|
75
|
+
interval: tmp_price_interval,
|
76
|
+
product_id: stripe_product.id,
|
77
|
+
product: self,
|
78
|
+
})
|
79
|
+
self.prices.push wco_price
|
80
|
+
price_hash = {
|
81
|
+
product: stripe_product.id,
|
82
|
+
unit_amount: tmp_price_cents,
|
83
|
+
currency: 'usd',
|
84
|
+
recurring: {
|
85
|
+
interval: tmp_price_interval,
|
86
|
+
},
|
87
|
+
}
|
88
|
+
stripe_price = Stripe::Price.create( price_hash )
|
89
|
+
self.price_id = stripe_price.id
|
90
|
+
end
|
91
|
+
before_validation :update_stripe_product_price, on: :update
|
92
|
+
def update_stripe_product_price
|
93
|
+
if tmp_price_cents.present?
|
94
|
+
price_hash = {
|
95
|
+
product: product_id,
|
96
|
+
unit_amount: tmp_price_cents,
|
97
|
+
currency: 'usd',
|
98
|
+
recurring: {
|
99
|
+
interval: tmp_price_interval,
|
100
|
+
},
|
101
|
+
}
|
102
|
+
stripe_price = Stripe::Price.create( price_hash )
|
103
|
+
wco_price = Wco::Price.create!({
|
104
|
+
amount_cents: tmp_price_cents,
|
105
|
+
interval: tmp_price_interval,
|
106
|
+
price_id: stripe_price.id,
|
107
|
+
product_id: product_id,
|
108
|
+
product: self,
|
109
|
+
})
|
110
|
+
self.prices.push wco_price
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
75
114
|
|
76
115
|
def to_s
|
77
116
|
"#{kind}-#{version}"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
class WcoHosting::ApplianceTmplLeadset
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
store_in collection: 'wco_appliance_tmpl_leadsets'
|
6
|
+
|
7
|
+
belongs_to :leadset, class_name: 'Wco::Leadset'
|
8
|
+
belongs_to :appliance_tmpl, class_name: 'WcoHosting::ApplianceTmpl'
|
9
|
+
|
10
|
+
end
|
11
|
+
|
@@ -8,18 +8,13 @@ class WcoHosting::Domain
|
|
8
8
|
field :name
|
9
9
|
validates :name, presence: true, uniqueness: true
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
STATE_ACTIVE = 'active'
|
17
|
-
STATE_INACTIVE = 'inactive'
|
18
|
-
STATES = [ 'active', 'inactive' ]
|
19
|
-
field :state, default: STATE_ACTIVE
|
11
|
+
STATUS_ACTIVE = 'active'
|
12
|
+
STATUS_INACTIVE = 'inactive'
|
13
|
+
STATUSES = [ 'active', 'inactive' ]
|
14
|
+
field :status
|
15
|
+
scope :active, ->{ where(status: STATUS_ACTIVE) }
|
20
16
|
|
21
17
|
def self.list
|
22
|
-
[[nil,nil]] +
|
18
|
+
[[nil,nil]] + active.map { |i| [i.name, i.name ] }
|
23
19
|
end
|
24
|
-
|
25
20
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
class WcoHosting::Environment
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
include Mongoid::Paranoia
|
6
|
+
store_in collection: 'wco_environments'
|
7
|
+
|
8
|
+
belongs_to :leadset, class_name: 'Wco::Leadset', inverse_of: :environments
|
9
|
+
|
10
|
+
field :name
|
11
|
+
validates :name, presence: true, uniqueness: true
|
12
|
+
index({ name: -1 }, { unique: true })
|
13
|
+
|
14
|
+
has_many :appliances, class_name: 'WcoHosting::Appliance', inverse_of: :environments
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
@@ -42,6 +42,8 @@ class WcoHosting::Serverhost
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def create_subdomain app
|
45
|
+
@obj = app
|
46
|
+
|
45
47
|
client = DropletKit::Client.new(access_token: DO_TOKEN_1)
|
46
48
|
record = DropletKit::DomainRecord.new(
|
47
49
|
type: 'A',
|
@@ -49,86 +51,64 @@ class WcoHosting::Serverhost
|
|
49
51
|
data: app.serverhost.public_ip,
|
50
52
|
)
|
51
53
|
client.domain_records.create(record, for_domain: app.domain )
|
52
|
-
end
|
53
|
-
|
54
|
-
## obsolete _vp_ 2023-12-23
|
55
|
-
def aws_create_subdomain app
|
56
|
-
ac = ActionController::Base.new
|
57
|
-
ac.instance_variable_set( :@app, app )
|
58
|
-
rendered_str = ac.render_to_string("wco_hosting/scripts/create_subdomain.json")
|
59
|
-
# puts '+++ create_subdomain rendered_str:'; print rendered_str
|
60
|
-
|
61
|
-
file = Tempfile.new('prefix')
|
62
|
-
file.write rendered_str
|
63
|
-
file.close
|
64
54
|
|
65
|
-
|
66
|
-
--hosted-zone-id #{ app.route53_zone } \
|
67
|
-
--change-batch file://#{ file.path } \
|
68
|
-
--profile route53 "
|
69
|
-
do_exec( cmd )
|
55
|
+
Wco::Log.puts! record, 'created subdomain?', obj: @obj
|
70
56
|
end
|
71
57
|
|
72
|
-
|
73
58
|
def add_nginx_site app
|
59
|
+
@obj = app
|
60
|
+
|
74
61
|
ac = ActionController::Base.new
|
75
62
|
ac.instance_variable_set( :@app, app )
|
76
63
|
rendered_str = ac.render_to_string("wco_hosting/scripts/nginx_site.conf")
|
77
|
-
puts '
|
78
|
-
print rendered_str
|
64
|
+
Wco::Log.puts! rendered_str, 'add_nginx_site rendered_str', obj: @obj
|
79
65
|
|
80
66
|
file = Tempfile.new('prefix')
|
81
67
|
file.write rendered_str
|
82
68
|
file.close
|
83
69
|
|
84
70
|
cmd = "scp #{file.path} #{ssh_host}:/etc/nginx/sites-available/#{app.service_name}.conf "
|
85
|
-
|
86
|
-
`#{cmd}`
|
71
|
+
do_exec cmd
|
87
72
|
|
88
73
|
cmd = "ssh #{ssh_host} 'ln -s /etc/nginx/sites-available/#{app.service_name}.conf /etc/nginx/sites-enabled/#{app.service_name}.conf ' "
|
89
|
-
|
90
|
-
`#{cmd}`
|
74
|
+
do_exec cmd
|
91
75
|
|
92
76
|
cmd = "ssh #{ssh_host} 'nginx -s reload ' "
|
93
|
-
|
94
|
-
`#{cmd}`
|
77
|
+
do_exec cmd
|
95
78
|
end
|
96
79
|
|
97
80
|
def add_docker_service app
|
98
|
-
|
81
|
+
@obj = app
|
82
|
+
Wco::Log.puts! nil, '#add_docker_service', obj: @obj
|
99
83
|
|
100
84
|
ac = ActionController::Base.new
|
101
85
|
ac.instance_variable_set( :@app, app )
|
102
86
|
ac.instance_variable_set( :@workdir, WORKDIR )
|
103
87
|
rendered_str = ac.render_to_string("wco_hosting/docker-compose/dc-#{app.tmpl.kind}")
|
104
|
-
puts '
|
105
|
-
print rendered_str
|
88
|
+
Wco::Log.puts! rendered_str, 'add_docker_service rendered_str', obj: @obj
|
106
89
|
|
107
90
|
file = Tempfile.new('prefix')
|
108
91
|
file.write rendered_str
|
109
92
|
file.close
|
110
|
-
puts! file.path, 'file.path'
|
93
|
+
# puts! file.path, 'file.path'
|
111
94
|
|
112
95
|
cmd = "scp #{file.path} #{ssh_host}:#{WORKDIR}/dc-#{app.service_name}.yml "
|
113
|
-
|
114
|
-
`#{cmd}`
|
96
|
+
do_exec cmd
|
115
97
|
|
116
98
|
cmd = "ssh #{ssh_host} 'cd #{WORKDIR} ; \
|
117
99
|
docker compose -f dc-#{app.service_name}.yml up -d #{app.service_name} ; \
|
118
100
|
echo ok #add_docker_service ' "
|
119
|
-
|
120
|
-
`#{cmd}`
|
121
|
-
|
122
|
-
puts "ok '#add_docker_service'"
|
101
|
+
do_exec cmd
|
123
102
|
end
|
124
103
|
|
125
104
|
def create_wordpress_volume app
|
105
|
+
@obj = app
|
106
|
+
|
126
107
|
ac = ActionController::Base.new
|
127
108
|
ac.instance_variable_set( :@app, app )
|
128
109
|
ac.instance_variable_set( :@workdir, WORKDIR )
|
129
110
|
rendered_str = ac.render_to_string("wco_hosting/scripts/create_volume")
|
130
|
-
|
131
|
-
# print rendered_str
|
111
|
+
Wco::Log.puts! rendered_str, 'create_volume rendered_str', obj: @obj
|
132
112
|
|
133
113
|
file = Tempfile.new('prefix')
|
134
114
|
file.write rendered_str
|
@@ -136,26 +116,22 @@ class WcoHosting::Serverhost
|
|
136
116
|
# puts! file.path, 'file.path'
|
137
117
|
|
138
118
|
cmd = "scp #{file.path} #{ssh_host}:#{WORKDIR}/scripts/create_volume"
|
139
|
-
|
140
|
-
`#{cmd}`
|
119
|
+
do_exec cmd
|
141
120
|
|
142
121
|
cmd = "ssh #{ssh_host} 'chmod a+x #{WORKDIR}/scripts/create_volume ; \
|
143
122
|
#{WORKDIR}/wco_hosting/scripts/create_volume ' "
|
144
|
-
|
145
|
-
`#{cmd}`
|
146
|
-
|
147
|
-
puts 'ok #create_volume'
|
123
|
+
do_exec cmd
|
148
124
|
end
|
149
125
|
|
150
126
|
def create_volume app
|
151
|
-
|
127
|
+
@obj = app
|
128
|
+
Wco::Log.puts! app.service_name, 'Serverhost#create_volume', obj: @obj
|
152
129
|
|
153
130
|
ac = ActionController::Base.new
|
154
131
|
ac.instance_variable_set( :@app, app )
|
155
132
|
ac.instance_variable_set( :@workdir, WORKDIR )
|
156
133
|
rendered_str = ac.render_to_string("wco_hosting/scripts/create_volume")
|
157
|
-
puts '
|
158
|
-
print rendered_str
|
134
|
+
Wco::Log.puts! rendered_str, 'create_volume rendered_str', obj: @obj
|
159
135
|
|
160
136
|
file = Tempfile.new('prefix')
|
161
137
|
file.write rendered_str
|
@@ -167,40 +143,20 @@ class WcoHosting::Serverhost
|
|
167
143
|
|
168
144
|
cmd = "ssh #{ssh_host} 'chmod a+x #{WORKDIR}/scripts/create_volume ; #{WORKDIR}/scripts/create_volume ' "
|
169
145
|
do_exec( cmd )
|
170
|
-
|
171
|
-
puts 'ok #create_volume'
|
172
|
-
return done_exec
|
173
|
-
end
|
174
|
-
|
175
|
-
def self.list
|
176
|
-
[[nil,nil]] + all.map { |s| [s.name, s.id] }
|
177
|
-
# all.map { |s| [s.name, s.id] }
|
178
146
|
end
|
179
147
|
|
180
148
|
def do_exec cmd
|
181
|
-
# @
|
182
|
-
# @errors ||= []
|
183
|
-
# @statuses ||= []
|
149
|
+
Wco::Log.puts! cmd, '#do_exec', obj: @obj
|
184
150
|
|
185
|
-
puts! cmd, '#do_exec'
|
186
151
|
stdout, stderr, status = Open3.capture3(cmd)
|
187
152
|
status = status.to_s.split.last.to_i
|
188
|
-
puts
|
189
|
-
puts
|
190
|
-
|
191
|
-
puts "+++ +++ stderr"
|
192
|
-
puts stderr
|
193
|
-
# @errors.push( stderr )
|
194
|
-
puts! status, 'status'
|
195
|
-
# @statuses.push( status )
|
153
|
+
Wco::Log.puts! stdout, 'stdout', obj: @obj
|
154
|
+
Wco::Log.puts! stderr, 'stderr', obj: @obj
|
155
|
+
Wco::Log.puts! status, 'status', obj: @obj
|
196
156
|
end
|
197
157
|
|
198
|
-
def
|
199
|
-
|
200
|
-
|
201
|
-
@statuses ||= []
|
202
|
-
OpenStruct.new( statuses: @statuses, errors: @errors, messages: @messages )
|
158
|
+
def self.list
|
159
|
+
[[nil,nil]] + all.map { |s| [s.name, s.id] }
|
160
|
+
# all.map { |s| [s.name, s.id] }
|
203
161
|
end
|
204
|
-
|
205
|
-
|
206
162
|
end
|
@@ -68,10 +68,7 @@
|
|
68
68
|
|
69
69
|
|
70
70
|
.row
|
71
|
-
.col-md-12.
|
71
|
+
.col-md-12.conversations
|
72
72
|
%h5 Email Conversations (#{@lead.convs.length})
|
73
|
-
|
74
|
-
- @lead.convs.each do |conv|
|
75
|
-
%li
|
76
|
-
= link_to conv.subject, wco_email.conversation_path( conv )
|
73
|
+
= render 'wco_email/conversations/table', convs: @lead.convs
|
77
74
|
|
@@ -13,6 +13,29 @@
|
|
13
13
|
|
14
14
|
%hr
|
15
15
|
|
16
|
+
.row
|
17
|
+
.col-md-6
|
18
|
+
%h5 Prices
|
19
|
+
%ul
|
20
|
+
- @leadset.appliance_tmpl_prices.each do |price|
|
21
|
+
%li
|
22
|
+
.a= price.product
|
23
|
+
= price
|
24
|
+
|
25
|
+
.col-md-6
|
26
|
+
%h5.collapse-expand#subscriptionsList
|
27
|
+
Subscriptions (#{@subscriptions.length})
|
28
|
+
= link_to '[+wco]', new_subscription_path({ customer_id: @leadset.customer_id })
|
29
|
+
%table.bordered
|
30
|
+
%thead
|
31
|
+
%tr
|
32
|
+
%th Name
|
33
|
+
%th Price
|
34
|
+
- @subscriptions.each do |i|
|
35
|
+
%tr
|
36
|
+
%td= i.product.name
|
37
|
+
%td= i.price
|
38
|
+
%hr
|
16
39
|
.row
|
17
40
|
.col-md-6
|
18
41
|
%h5.collapse-expand#invoicesList
|
@@ -30,22 +53,8 @@
|
|
30
53
|
%label (replace ?)
|
31
54
|
= check_box_tag 'replace'
|
32
55
|
= submit_tag 'Go >', data: { confirm: 'Are you sure?' }
|
33
|
-
|
56
|
+
%hr
|
34
57
|
|
35
|
-
.col-md-6
|
36
|
-
%h5.collapse-expand#subscriptionsList
|
37
|
-
Subscriptions (#{@subscriptions.length})
|
38
|
-
= link_to '[+wco]', new_subscription_path({ customer_id: @leadset.customer_id })
|
39
|
-
%table.bordered
|
40
|
-
%thead
|
41
|
-
%tr
|
42
|
-
%th Name
|
43
|
-
%th Price
|
44
|
-
- @subscriptions.each do |i|
|
45
|
-
%tr
|
46
|
-
%td= i.product.name
|
47
|
-
%td= i.price
|
48
|
-
%hr
|
49
58
|
.row
|
50
59
|
%h5.collapse-expand#leads Leads
|
51
60
|
= render '/wco/leads/index', leads: @leads
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
.conversations--table
|
3
|
+
%table.bordered.data-table
|
4
|
+
%thead
|
5
|
+
%th.select-all.nosort
|
6
|
+
.a
|
7
|
+
= check_box_tag :select_all
|
8
|
+
.n-selected -
|
9
|
+
%th.leads leads
|
10
|
+
%th.subject subject, preview
|
11
|
+
%th.tags Tags
|
12
|
+
%th.latest-at latest_at
|
13
|
+
- convs.each_with_index do |conv, idx|
|
14
|
+
%tr
|
15
|
+
%td.select-all
|
16
|
+
.gray= idx+1
|
17
|
+
= check_box_tag 'conversation_ids[]', conv.id.to_s, nil, { class: 'i-sel' }
|
18
|
+
%td.leads.mini
|
19
|
+
-# - conv.from_emails.each do |from|
|
20
|
+
-# = link_to from, wco.lead_path( from )
|
21
|
+
-# %hr
|
22
|
+
- conv.leads.each do |lead|
|
23
|
+
= link_to lead.email, wco.lead_path( lead )
|
24
|
+
%td.subject
|
25
|
+
- if conv.unread?
|
26
|
+
<b>#{link_to conv.subject, wco_email.conversation_path(conv)}</b>
|
27
|
+
- else
|
28
|
+
= link_to conv.subject, wco_email.conversation_path(conv)
|
29
|
+
<b>(#{conv.messages.length})</b>
|
30
|
+
%span.gray= conv.preview
|
31
|
+
%td.tags.mini
|
32
|
+
- conv.tags.each do |tag|
|
33
|
+
.mb-1
|
34
|
+
.Chip= tag.slug
|
35
|
+
%td.latest-at
|
36
|
+
= pp_date conv.latest_at
|
37
|
+
= pp_time conv.latest_at
|
@@ -11,9 +11,10 @@
|
|
11
11
|
-# = @ctx.unsubscribe_url
|
12
12
|
|
13
13
|
- if @ctx.reply_to_message
|
14
|
-
%
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
%blockquote
|
15
|
+
%br
|
16
|
+
%br
|
17
|
+
%br
|
18
|
+
.mini{ style: "font-size: 0.7em; color: gray; text-align: right" } Your previous message is shown below.
|
19
|
+
%hr
|
20
|
+
= raw @ctx.reply_to_message.part_html_sanitized
|
@@ -0,0 +1,16 @@
|
|
1
|
+
version: '3.2'
|
2
|
+
|
3
|
+
services:
|
4
|
+
|
5
|
+
<%= @app.service_name %>:
|
6
|
+
image: <%= @app.tmpl.image %>
|
7
|
+
volumes:
|
8
|
+
- type: bind
|
9
|
+
source: volumes/<%= @app.service_name %>_data
|
10
|
+
target: /var/www/html
|
11
|
+
ports:
|
12
|
+
- <%= @app.port %>:80
|
13
|
+
restart: always
|
14
|
+
|
15
|
+
|
16
|
+
|
@@ -10,8 +10,8 @@ rm -rf __MACOSX
|
|
10
10
|
# curl <%= @app.tmpl.volume_zip %> > <%= @app.kind %>__prototype.zip
|
11
11
|
|
12
12
|
## cache/overwrite
|
13
|
-
[ ! -e <%= @app.kind %>__prototype ] && rm -rf <%= @app.kind %>__prototype && unzip <%= @app.kind %>__prototype.zip
|
14
|
-
# rm -rf <%= @app.kind %>__prototype && unzip <%= @app.kind %>__prototype.zip
|
13
|
+
[ ! -e <%= @app.kind %>__prototype ] && rm -rf <%= @app.kind %>__prototype && unzip -o <%= @app.kind %>__prototype.zip
|
14
|
+
# rm -rf <%= @app.kind %>__prototype && unzip -o <%= @app.kind %>__prototype.zip
|
15
15
|
|
16
16
|
mv <%= @app.kind %>__prototype ./volumes/<%= @app.service_name %>_data
|
17
17
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wco_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.0.
|
4
|
+
version: 3.1.0.108
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Pudeyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-s3
|
@@ -447,7 +447,9 @@ files:
|
|
447
447
|
- app/models/wco_email/unsubscribe.rb
|
448
448
|
- app/models/wco_hosting/appliance.rb
|
449
449
|
- app/models/wco_hosting/appliance_tmpl.rb
|
450
|
+
- app/models/wco_hosting/appliance_tmpl_leadset.rb-trash
|
450
451
|
- app/models/wco_hosting/domain.rb
|
452
|
+
- app/models/wco_hosting/environment.rb
|
451
453
|
- app/models/wco_hosting/serverhost.rb
|
452
454
|
- app/views/layouts/wco/application.haml
|
453
455
|
- app/views/wco/_alerts_notices.haml
|
@@ -592,6 +594,7 @@ files:
|
|
592
594
|
- app/views/wco_email/application_mailer/_footer_unsubscribe.html.erb
|
593
595
|
- app/views/wco_email/application_mailer/_header_logo.html.erb
|
594
596
|
- app/views/wco_email/application_mailer/forwarder_notify.html.erb
|
597
|
+
- app/views/wco_email/conversations/_table.haml
|
595
598
|
- app/views/wco_email/email_layouts/_m20221201react.html.erb
|
596
599
|
- app/views/wco_email/email_layouts/_m20221222merryxmas.html.erb
|
597
600
|
- app/views/wco_email/email_layouts/_m202309_feedback.html.erb
|
@@ -617,6 +620,7 @@ files:
|
|
617
620
|
- app/views/wco_email/email_layouts/_wasyaco_roundborders.html.erb
|
618
621
|
- app/views/wco_hosting/docker-compose/dc-any.erb
|
619
622
|
- app/views/wco_hosting/docker-compose/dc-helloworld.erb
|
623
|
+
- app/views/wco_hosting/docker-compose/dc-react.erb
|
620
624
|
- app/views/wco_hosting/docker-compose/dc-wordpress.erb
|
621
625
|
- app/views/wco_hosting/scripts/create_subdomain.json.erb-trash
|
622
626
|
- app/views/wco_hosting/scripts/create_volume.erb
|