wco_models 3.1.0.189 → 3.1.0.190

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
  SHA256:
3
- metadata.gz: 6d7aa099d022824fbef4b0fae04c43b89a70ab7e232e70fce561f268c8733084
4
- data.tar.gz: 4b7b8bb274105b8ab5dd52c5705e5cab7e2f16a1d4e43d59434c62ddaa87fa0d
3
+ metadata.gz: d49f77b6a2706b11084a327dcfedb56bf887ba04bf71e23f66ecff2749abc069
4
+ data.tar.gz: 15bf5266b05ad0116ff87266d7f242dc840b9b773c668d37dcda649e13528a0b
5
5
  SHA512:
6
- metadata.gz: 856d7b8285233d1a98b6874c493e6b015da8c8723da597576fb28d0716f190a1a41ea673c18920cca10e12791cb1e08d7f3d4fcb0b3b352dd3562838c406ab5c
7
- data.tar.gz: 65badfb5507f336f56d25fe963a5eb8a743186d410cfa4910bdc8fd952c25fa9bcea54df61bfa63511dd63c94715b5846c311dcc4e19b3462be0ae1f8d603596
6
+ metadata.gz: daf54c6e2d1b5c220eaadc56aa00a8b185b2f635fdb5960de233d7b8c39d788abc7b15c10eea0d7b174a0219608e64a606f1d2a44e71e79828264f093fd371d0
7
+ data.tar.gz: 96ab243124e389910b3d19a0e007d711d8300fcb80960411f3141b436af760a7c6d5e8c2fa3715c8b91caa0ee47ea8aace500582012f849b6b988c433ab58bd7
@@ -0,0 +1,9 @@
1
+
2
+ class Wco::Api::TagsController < Wco::ApiController
3
+
4
+ def index
5
+ authorize! :index, Wco::Tag
6
+ @tags = Wco::Tag.all()
7
+ end
8
+
9
+ end
@@ -10,7 +10,6 @@ class Wco::ApiController < ActionController::Base
10
10
  private
11
11
 
12
12
  def decode_jwt
13
- byebug
14
13
  out = JWT.decode params[:jwt_token], nil, false
15
14
  email = out[0]['email']
16
15
  user = User.find_by({ email: email })
@@ -30,16 +30,21 @@ class Wco::Tag
30
30
  find_or_create_by({ slug: INBOX })
31
31
  end
32
32
 
33
- TRASH = 'trash'
34
- def self.trash
35
- find_or_create_by({ slug: TRASH })
36
- end
37
-
38
33
  SPAM = 'spam'
39
34
  def self.spam
40
35
  find_or_create_by({ slug: SPAM })
41
36
  end
42
37
 
38
+ NOT_SPAM = 'not-spam'
39
+ def self.not_spam
40
+ find_or_create_by({ slug: NOT_SPAM })
41
+ end
42
+
43
+ TRASH = 'trash'
44
+ def self.trash
45
+ find_or_create_by({ slug: TRASH })
46
+ end
47
+
43
48
  def to_s
44
49
  slug
45
50
  end
@@ -1,4 +1,5 @@
1
1
 
2
+
2
3
  ##
3
4
  ## 2023-03-04 _vp_ When I receive one.
4
5
  ##
@@ -10,9 +11,6 @@ class WcoEmail::EmailFilter
10
11
 
11
12
  PAGE_PARAM_NAME = :filters_page
12
13
 
13
- FIELD_OPTS = [ :subject, :from, :to, :to_and_cc, :body, ]
14
- MATCHTYPE_OPTS = [ :regex, :exact_insensitive, ]
15
-
16
14
  field :from_regex
17
15
  field :from_exact
18
16
  field :subject_regex
@@ -23,13 +21,22 @@ class WcoEmail::EmailFilter
23
21
  field :skip_from_regex
24
22
  field :skip_to_exact
25
23
 
26
- has_many :email_filter_conditions
27
- has_many :email_filter_skip_conditions, class_name: 'WcoEmail::EmailFilterCondition'
24
+ has_many :actions, class_name: '::WcoEmail::EmailFilterAction', inverse_of: :email_filter
25
+ accepts_nested_attributes_for :actions, allow_destroy: true
26
+
27
+ ## 'and' - all conditions must match, for filter to match
28
+ has_many :conditions, class_name: '::WcoEmail::EmailFilterCondition', inverse_of: :email_filter
29
+ accepts_nested_attributes_for :conditions, allow_destroy: true
30
+
31
+ ## 'and' - all conditions must match, for filter to match
32
+ has_many :skip_conditions, class_name: '::WcoEmail::EmailFilterCondition', inverse_of: :email_skip_filter
33
+ accepts_nested_attributes_for :skip_conditions, allow_destroy: true
28
34
 
29
- has_and_belongs_to_many :action_tmpls, class_name: 'Wco::OfficeActionTemplate'
30
- has_and_belongs_to_many :leadsets, class_name: 'Wco::Leadset'
31
35
 
32
- belongs_to :tag, class_name: 'Wco::Tag', inverse_of: :email_filters, optional: true
36
+ has_and_belongs_to_many :action_tmpls, class_name: '::Wco::OfficeActionTemplate'
37
+ has_and_belongs_to_many :leadsets, class_name: '::Wco::Leadset'
38
+
39
+ belongs_to :tag, class_name: '::Wco::Tag', inverse_of: :email_filters, optional: true
33
40
 
34
41
  KIND_AUTORESPOND_TMPL = 'autorespond-template'
35
42
  KIND_AUTORESPOND_EACT = 'autorespond-email-action'
@@ -46,10 +53,45 @@ class WcoEmail::EmailFilter
46
53
  field :kind
47
54
 
48
55
 
49
- belongs_to :email_template, class_name: 'WcoEmail::EmailTemplate', optional: true
50
- belongs_to :email_action_template, class_name: 'WcoEmail::EmailActionTemplate', optional: true
56
+ belongs_to :email_template, class_name: '::WcoEmail::EmailTemplate', optional: true
57
+ belongs_to :email_action_template, class_name: '::WcoEmail::EmailActionTemplate', optional: true
58
+
59
+ ## @TODO: change to has_and_belongs_to_many, test-driven.
60
+ has_many :conversations, class_name: '::WcoEmail::Conversation', inverse_of: :filter
61
+
62
+ def to_s
63
+ "EmailFilter: #{from_regex} #{from_exact} #{conditions.map { |c| c.to_s }.join }"
64
+ end
65
+ def to_s_full
66
+ # inn = ""
67
+ # inn = "#{inn}#{conditions.map { |c| c.to_s_full }.join }" if conditions.present?
68
+ # inn = "#{inn}#{skip_conditions.map { |c| c.to_s_full }.join }" if skip_conditions.present?
69
+ out =<<-AOL
70
+ <EmailFilter #{from_regex} #{from_exact}>
71
+ #{conditions.map { |c| c.to_s_full( indent: 2) }.join }
72
+ #{skip_conditions.map { |c| c.to_s_full( indent: 2) }.join }
73
+ #{actions.map { |c| c.to_s_full( indent: 2) }.join }
74
+ </EmailFilter>"
75
+ AOL
76
+ while out.match(/\n\n/) do
77
+ out = out.gsub(/\n\n/, "\n")
78
+ end
79
+ out
80
+ end
81
+
82
+ def to_xml
83
+ attrs = ''
84
+ children = ''
85
+ if from_regex || from_exact
86
+ attrs = "#{attrs} from=#{from_regex}#{from_exact}"
87
+ end
88
+ if conditions.present?
89
+ children = "#{children}#{conditions.map { |c| c.to_s }.join('') }"
90
+ end
91
+ return "<EF #{attrs}>#{children}</EF>\n"
92
+ end
51
93
 
52
- has_many :conversations, class_name: 'WcoEmail::Conversation', inverse_of: :filter
53
94
 
54
- end
55
95
 
96
+ end
97
+ ::EF = WcoEmail::EmailFilter
@@ -0,0 +1,46 @@
1
+
2
+ class WcoEmail::EmailFilterAction
3
+ include Mongoid::Document
4
+ include Mongoid::Timestamps
5
+ store_in collection: 'email_filter_actions'
6
+
7
+ belongs_to :email_filter
8
+
9
+ KIND_EXE = 'exe'
10
+ KIND_REMOVE_TAG = ::WcoEmail::ACTION_REMOVE_TAG
11
+ KIND_ADD_TAG = ::WcoEmail::ACTION_ADD_TAG
12
+ KIND_AUTORESPOND = ::WcoEmail::ACTION_AUTORESPOND
13
+ KIND_SCHEDULE_EMAIL_ACTION = 'autorespond-email-action'
14
+ KIND_REMOVE_EMAIL_ACTION = 'remove-email-action'
15
+ field :kind
16
+
17
+ field :value # the id of a tag, or email template, or email action
18
+
19
+
20
+ before_validation :check_value
21
+ def check_value
22
+ case kind
23
+ when KIND_AUTORESPOND
24
+ existing = WcoEmail::EmailTemplate.where({ id: value }).first
25
+ if !existing
26
+ errors.add( :base, 'missing EmailTemplate id when creating an EmailFilterAction' )
27
+ throw :abort
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+ def to_s
34
+ "<EFA #{kind} #{value} />\n"
35
+ end
36
+ def to_s_full indent: 0
37
+ _value = value
38
+ if [ KIND_ADD_TAG, KIND_REMOVE_TAG ].include?( kind )
39
+ _value = Wco::Tag.find( value )
40
+ end
41
+ if [ KIND_AUTORESPOND ].include?( kind )
42
+ _value = WcoEmail::EmailTemplate.find( value )
43
+ end
44
+ "#{" " * indent }<EmailFilterAction #{kind} `#{_value}` />\n"
45
+ end
46
+ end
@@ -5,13 +5,39 @@ class WcoEmail::EmailFilterCondition
5
5
  include Mongoid::Paranoia
6
6
  store_in collection: 'office_email_filter_conditions'
7
7
 
8
- belongs_to :email_filter, inverse_of: :email_filter_conditions
9
- belongs_to :email_filter_skip, inverse_of: :email_filter_skip_conditions
8
+ belongs_to :email_filter, class_name: '::WcoEmail::EmailFilter', inverse_of: :conditions, optional: true
9
+ belongs_to :email_skip_filter, class_name: '::WcoEmail::EmailFilter', inverse_of: :skip_conditions, optional: true
10
10
 
11
+ ## see WcoEmail::FIELD_*
11
12
  field :field
12
- field :matchtype
13
- field :value
13
+ validates :field, presence: true
14
+
15
+ OPERATOR_EQUALS = WcoEmail::OPERATOR_EQUALS
16
+ OPERATOR_HAS_TAG = WcoEmail::OPERATOR_HAS_TAG
17
+ OPERATOR_NOT_HAS_TAG = WcoEmail::OPERATOR_NOT_HAS_TAG
18
+ field :operator, type: String
19
+ validates :operator, presence: true
14
20
 
21
+ field :value
22
+ validates :value, presence: true
15
23
 
24
+ def to_s
25
+ "<EFC #{field} #{operator} #{value} />"
26
+ end
27
+ def to_s_full indent: 0
28
+ _value = value
29
+ if [ OPERATOR_HAS_TAG, OPERATOR_NOT_HAS_TAG ].include?( operator )
30
+ _value = Wco::Tag.find( value )
31
+ end
32
+ "#{" " * indent }<EmailFilterCondition #{field} #{operator} `#{_value}` />\n"
33
+ end
16
34
  end
17
35
 
36
+ =begin
37
+
38
+ ## not whitelisted
39
+ tag = Wco::Tag.find_by({ slug: 'known-leadsets' })
40
+ out = @company.tags.include?( tag )
41
+ !out
42
+
43
+ =end
@@ -124,7 +124,27 @@ class WcoEmail::Message
124
124
  })
125
125
 
126
126
  else
127
- raise "unknown filter kind: #{filter.kind}"
127
+ if filter.actions.present?
128
+ filter.actions.each do |act|
129
+ case act.kind
130
+ when ::WcoEmail::ACTION_REMOVE_TAG
131
+ this_tag = Wco::Tag.find( act.value )
132
+ conv.tags -= [ this_tag ]
133
+ when ::WcoEmail::ACTION_ADD_TAG
134
+ this_tag = Wco::Tag.find( act.value )
135
+ conv.tags += [ this_tag ]
136
+ when ::WcoEmail::ACTION_AUTORESPOND
137
+ this_template = WcoEmail::EmailTemplate.find( act.value )
138
+ WcoEmail::Context.create!({
139
+ email_template: this_template,
140
+ lead_id: lead.id,
141
+ send_at: Time.now,
142
+ })
143
+ end
144
+ end
145
+ else
146
+ raise "unknown filter kind: #{filter.kind}"
147
+ end
128
148
  end
129
149
 
130
150
  conv.save!
@@ -57,7 +57,7 @@ class WcoEmail::MessageStub
57
57
  raw = @client.get_object( bucket: stub.bucket, key: stub.object_key ).body.read
58
58
  raw = raw.encode('utf-8', invalid: :replace, undef: :replace, replace: '_' )
59
59
  the_mail = Mail.new( raw )
60
- puts! the_mail, 'the_mail'
60
+ # puts! the_mail, 'the_mail'
61
61
 
62
62
  message_id = the_mail.header['message-id']&.decoded
63
63
  message_id ||= "#{the_mail.date&.iso8601}::#{the_mail.from}"
@@ -199,6 +199,20 @@ class WcoEmail::MessageStub
199
199
  reason = 'subject_exact'
200
200
  end
201
201
 
202
+ filter.conditions.each do |cond|
203
+ case cond.field
204
+ when WcoEmail::FIELD_LEADSET
205
+ if cond.operator == WcoEmail::OPERATOR_NOT_HAS_TAG
206
+ this_tag = Wco::Tag.find cond.value
207
+ if leadset.tags.include?( this_tag )
208
+ ;
209
+ else
210
+ reason = "condition leadset not-has-tag #{this_tag} NOT met"
211
+ end
212
+ end
213
+ end
214
+ end
215
+
202
216
  if reason
203
217
  puts! "Applying filter #{filter} to conv #{@message.conversation} for matching #{reason}" if DEBUG
204
218
 
@@ -30,6 +30,8 @@ class WcoHosting::ApplianceTmpl
30
30
  # file.close
31
31
  # end
32
32
 
33
+ field :docker_compose_erb, type: :string
34
+
33
35
  field :stdout, type: :string, default: ''
34
36
  field :stderr, type: :string, default: ''
35
37
 
@@ -0,0 +1,7 @@
1
+
2
+ json.tags do
3
+ json.array! @tags do |tag|
4
+ json.label tag.to_s
5
+ json.value tag.id.to_s
6
+ end
7
+ end
@@ -16,7 +16,7 @@
16
16
  %label schwab_refresh_token
17
17
  = f.text_field :schwab_refresh_token
18
18
  .field
19
- %label schwab_access_token
19
+ %label schwab_id_token
20
20
  = f.text_field :schwab_id_token
21
21
 
22
22
  .actions
data/config/routes.rb CHANGED
@@ -7,6 +7,8 @@ Wco::Engine.routes.draw do
7
7
 
8
8
  get 'obf', to: 'obfuscated_redirects#show' ## testing only.
9
9
  get 'obf/:id', to: 'obfuscared_redirects#show'
10
+
11
+ get 'tags', to: 'tags#index'
10
12
  end
11
13
 
12
14
  get 'application/tinymce', to: 'application#tinymce'
data/lib/wco_models.rb CHANGED
@@ -31,7 +31,24 @@ INACTIVE = 'inactive'
31
31
  STATUSES = [ nil, ACTIVE, INACTIVE ]
32
32
 
33
33
  module Wco; end
34
- module WcoEmail; end
34
+
35
+ module WcoEmail
36
+ ACTION_ADD_TAG = 'add-tag'
37
+ ACTION_AUTORESPOND = 'autorespond-template'
38
+ ACTION_REMOVE_TAG = 'remove-tag'
39
+
40
+ FIELD_BODY = 'body'
41
+ FIELD_EXE = 'exe'
42
+ FIELD_FROM = 'from'
43
+ FIELD_LEADSET = 'leadset'
44
+ FIELD_SUBJECT = 'subject'
45
+ FIELD_TO = 'to'
46
+
47
+ OPERATOR_EQUALS = 'equals'
48
+ OPERATOR_HAS_TAG = 'has-tag'
49
+ OPERATOR_NOT_HAS_TAG = 'not-has-tag'
50
+ end
51
+
35
52
  module WcoHosting; end
36
53
 
37
54
  class Wco::HTTParty
@@ -40,4 +57,3 @@ class Wco::HTTParty
40
57
  end
41
58
 
42
59
  ActiveSupport.escape_html_entities_in_json = true
43
-
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.189
4
+ version: 3.1.0.190
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-11-30 00:00:00.000000000 Z
11
+ date: 2025-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ahoy_matey
@@ -429,6 +429,7 @@ files:
429
429
  - app/assets/stylesheets/wco/videos.scss
430
430
  - app/controllers/wco/api/leads_controller.rb
431
431
  - app/controllers/wco/api/obfuscated_redirects_controller.rb
432
+ - app/controllers/wco/api/tags_controller.rb
432
433
  - app/controllers/wco/api_controller.rb
433
434
  - app/controllers/wco/application_controller.rb
434
435
  - app/controllers/wco/galleries_controller.rb
@@ -499,6 +500,7 @@ files:
499
500
  - app/models/wco_email/email_action_template.rb
500
501
  - app/models/wco_email/email_action_template_tie.rb
501
502
  - app/models/wco_email/email_filter.rb
503
+ - app/models/wco_email/email_filter_action.rb
502
504
  - app/models/wco_email/email_filter_condition.rb
503
505
  - app/models/wco_email/email_template.rb
504
506
  - app/models/wco_email/message.rb
@@ -525,6 +527,7 @@ files:
525
527
  - app/views/wco/_search.haml
526
528
  - app/views/wco/_select_all.haml
527
529
  - app/views/wco/api/leads/index_hash.jbuilder
530
+ - app/views/wco/api/tags/index.json.jbuilder
528
531
  - app/views/wco/application/_alerts_notices.haml
529
532
  - app/views/wco/application/_auth_widget.haml
530
533
  - app/views/wco/application/_debug.haml