ish_models 0.0.33.194 → 0.0.33.195
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ish/email_campaign.rb +12 -12
- data/lib/ish/email_context.rb +24 -27
- data/lib/ish/email_template.rb +19 -9
- data/lib/ish_models.rb +5 -1
- data/lib/office/email_action.rb +23 -0
- data/lib/office/email_conversation.rb +52 -0
- data/lib/office/email_filter.rb +24 -0
- data/lib/office/email_message.rb +87 -38
- data/lib/office/email_message_stub.rb +23 -0
- data/lib/office/scheduled_email_action.rb +48 -0
- data/lib/report.rb +1 -1
- metadata +6 -11
- data/lib/ish/trash/email_campaign.rb +0 -28
- data/lib/ish/trash/lead.rb +0 -52
- data/lib/ish/trash/lead.rb-bk +0 -38
- data/lib/office/action.rb +0 -44
- data/lib/trash/app_model2.rb +0 -21
- data/lib/trash/city.rb-bk +0 -100
- data/lib/trash/event.rb +0 -28
- data/lib/trash/site.rb +0 -99
- data/lib/trash/tag_trash.rb +0 -73
- data/lib/trash/venue.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b70a61ff2f74f6f8660cd7b745fafb8ee48107d58e1657fbaa4cbafede5dc5cc
|
4
|
+
data.tar.gz: 3830845cb028c10381b18c1d9ed2088d62363193ec87f0b3935a5765c40067ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5386670c8bde4fab552ce911b51bdc8e2afcbfce9f70acf8a14d411d64fd9a546d5fb1c6e506e4d279be2b07f35e36a3ab9c20812a899cded954411ffcf61cb2
|
7
|
+
data.tar.gz: d868d099370aa28c5b082ea6a1235732f281220ac197ef8cd994e73f7e87eac7dea2c6e6bad405d9be369b441a9e15e7478b35959f4acbda44e94c66a39062a1
|
data/lib/ish/email_campaign.rb
CHANGED
@@ -44,18 +44,18 @@ class Ish::EmailCampaign
|
|
44
44
|
end
|
45
45
|
|
46
46
|
|
47
|
-
##
|
48
|
-
## For templating:
|
49
|
-
##
|
50
|
-
## commonly: name, companyName
|
51
|
-
field :tmpl, type: Hash, default: {}
|
52
|
-
def body_templated
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
47
|
+
# ##
|
48
|
+
# ## For templating:
|
49
|
+
# ##
|
50
|
+
# ## commonly: name, companyName
|
51
|
+
# field :tmpl, type: Hash, default: {}
|
52
|
+
# def body_templated
|
53
|
+
# out = email_template.body
|
54
|
+
# tmpl.each do |k, v|
|
55
|
+
# out.gsub!("{#{k}}", v)
|
56
|
+
# end
|
57
|
+
# out
|
58
|
+
# end
|
59
59
|
|
60
60
|
#
|
61
61
|
# For tracking
|
data/lib/ish/email_context.rb
CHANGED
@@ -10,15 +10,15 @@ class Ish::EmailContext
|
|
10
10
|
## @TODO: probably rename it to slug
|
11
11
|
field :slug
|
12
12
|
validates_uniqueness_of :slug, allow_nil: true
|
13
|
-
def title
|
14
|
-
slug
|
15
|
-
end
|
16
13
|
|
17
14
|
PAGE_PARAM_NAME = 'email_contexts_page'
|
18
15
|
|
19
|
-
FROM_EMAILS = %w|
|
20
|
-
|
21
|
-
|
16
|
+
FROM_EMAILS = %w|
|
17
|
+
hello@infiniteshelter.com no-reply@infiniteshelter.com
|
18
|
+
piousbox@gmail.com
|
19
|
+
victor@piousbox.com no-reply@piousbox.com
|
20
|
+
admin@wasya.co hello@wasya.co no-reply@wasya.co victor@wasya.co
|
21
|
+
|;
|
22
22
|
field :from_email
|
23
23
|
validates_presence_of :from_email
|
24
24
|
def self.from_email_list
|
@@ -29,9 +29,9 @@ class Ish::EmailContext
|
|
29
29
|
validates_presence_of :subject
|
30
30
|
|
31
31
|
field :body
|
32
|
-
# validates_presence_of :body ## With plain type, there is no body but there are variables for templating.
|
33
32
|
|
34
33
|
belongs_to :email_template
|
34
|
+
belongs_to :scheduled_email_action, class_name: '::Office::ScheduledEmailAction', optional: true
|
35
35
|
|
36
36
|
field :rendered_str
|
37
37
|
|
@@ -46,34 +46,31 @@ class Ish::EmailContext
|
|
46
46
|
Ish::EmailContext.where( sent_at: nil )
|
47
47
|
end
|
48
48
|
|
49
|
-
def self.
|
50
|
-
new.
|
49
|
+
def self.scheduled
|
50
|
+
new.scheduled
|
51
51
|
end
|
52
|
-
def
|
52
|
+
def scheduled
|
53
53
|
# or({ :send_at.lte => Time.now }, { :send_at => nil }) ## This won't work b/c I need draft state!
|
54
54
|
Ish::EmailContext.where({ :send_at.lte => Time.now })
|
55
55
|
end
|
56
56
|
|
57
|
+
## @deprecated: use self.lead
|
58
|
+
# field :to_email
|
59
|
+
# validates_presence_of :to_email
|
57
60
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
## commonly: name, companyName
|
62
|
-
field :tmpl, type: Hash, default: {}
|
63
|
-
def body_templated
|
64
|
-
out = email_template.body
|
65
|
-
tmpl.each do |k, v|
|
66
|
-
out.gsub!("{#{k}}", v)
|
67
|
-
end
|
68
|
-
out
|
61
|
+
field :lead_id
|
62
|
+
def lead
|
63
|
+
Lead.find lead_id
|
69
64
|
end
|
70
65
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
#
|
75
|
-
# For tracking
|
76
|
-
#
|
66
|
+
##
|
67
|
+
## For tracking / utm
|
68
|
+
##
|
77
69
|
attr_reader :tid
|
78
70
|
|
71
|
+
def get_binding
|
72
|
+
@lead = lead()
|
73
|
+
binding()
|
74
|
+
end
|
75
|
+
|
79
76
|
end
|
data/lib/ish/email_template.rb
CHANGED
@@ -4,20 +4,30 @@ class ::Ish::EmailTemplate
|
|
4
4
|
include Mongoid::Timestamps
|
5
5
|
|
6
6
|
field :slug
|
7
|
-
validates_uniqueness_of :slug
|
7
|
+
validates_uniqueness_of :slug
|
8
8
|
validates_presence_of :slug
|
9
9
|
|
10
|
-
field :
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
field :layout, type: :string, default: 'plain'
|
11
|
+
LAYOUTS = %w| plain
|
12
|
+
m20221201react m20221222merryxmas
|
13
|
+
marketing_react_1
|
14
|
+
marketing_ror_1 marketing_ror_2
|
15
|
+
marketing_wordpres_1 marketing_wordpress_2
|
16
|
+
piousbox_roundborders
|
17
|
+
plain
|
18
|
+
wasyaco_roundborders |
|
17
19
|
|
18
20
|
field :subject
|
19
21
|
field :body
|
20
22
|
field :from_email
|
21
23
|
|
24
|
+
## 2023-03-04 _vp_ This works!
|
25
|
+
def get_binding
|
26
|
+
@lead = Lead.where( email: 'stub@wasya.co' ).first
|
27
|
+
binding()
|
28
|
+
end
|
29
|
+
|
30
|
+
has_many :email_actions
|
31
|
+
|
22
32
|
end
|
23
|
-
|
33
|
+
::Tmpl = ::Ish::EmailTemplate
|
data/lib/ish_models.rb
CHANGED
@@ -67,8 +67,12 @@ require 'photo'
|
|
67
67
|
require 'report'
|
68
68
|
require 'video'
|
69
69
|
|
70
|
-
require 'office/
|
70
|
+
require 'office/email_action'
|
71
|
+
require 'office/email_conversation'
|
72
|
+
require 'office/email_filter'
|
71
73
|
require 'office/email_message'
|
74
|
+
require 'office/email_message_stub'
|
75
|
+
require 'office/scheduled_email_action'
|
72
76
|
|
73
77
|
|
74
78
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
##
|
3
|
+
## 2023-03-04 _vp_ When I receive one.
|
4
|
+
## 2023-03-04 _vp_ Also when I send one, forever.
|
5
|
+
##
|
6
|
+
class Office::EmailAction
|
7
|
+
include Mongoid::Document
|
8
|
+
include Mongoid::Timestamps
|
9
|
+
|
10
|
+
field :slug, type: :string
|
11
|
+
validates :slug, uniqueness: true, allow_nil: true
|
12
|
+
|
13
|
+
belongs_to :email_template, class_name: '::Ish::EmailTemplate'
|
14
|
+
|
15
|
+
field :next_in_days, type: :string
|
16
|
+
field :next_at_time, type: :string
|
17
|
+
|
18
|
+
belongs_to :prev_email_action, class_name: '::Office::EmailAction', optional: true, inverse_of: :next_email_actions
|
19
|
+
has_many :next_email_actions, class_name: '::Office::EmailAction', inverse_of: :prev_email_action
|
20
|
+
|
21
|
+
has_many :scheduled_email_actions, class_name: '::Office::ScheduledEmailAction'
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
class Office::EmailConversation
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
include Mongoid::Paranoia
|
6
|
+
|
7
|
+
STATE_UNREAD = 'state_unread'
|
8
|
+
STATE_READ = 'state_read'
|
9
|
+
STATES = [ STATE_UNREAD, STATE_READ ]
|
10
|
+
field :state
|
11
|
+
|
12
|
+
field :subject
|
13
|
+
field :latest_at
|
14
|
+
|
15
|
+
field :lead_ids, type: :array, default: []
|
16
|
+
def leads
|
17
|
+
Lead.find( lead_ids )
|
18
|
+
end
|
19
|
+
|
20
|
+
field :term_ids, type: :array, default: []
|
21
|
+
def tags
|
22
|
+
WpTag.find( term_ids )
|
23
|
+
end
|
24
|
+
|
25
|
+
has_many :email_messages
|
26
|
+
def email_messages
|
27
|
+
Office::EmailMessage.where( email_conversation_id: self.id )
|
28
|
+
end
|
29
|
+
|
30
|
+
## Copied from email_message
|
31
|
+
field :wp_term_ids, type: Array, default: []
|
32
|
+
## Tested manually ok, does not pass the spec. @TODO: hire to make pass spec? _vp_ 2023-03-07
|
33
|
+
def add_tag tag
|
34
|
+
if WpTag == tag.class
|
35
|
+
self[:wp_term_ids] = self[:wp_term_ids].push(tag.id).uniq
|
36
|
+
self.save!
|
37
|
+
else
|
38
|
+
throw "#add_tag expects a WpTag as the only parameter."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def remove_tag tag
|
42
|
+
if WpTag == tag.class
|
43
|
+
self[:wp_term_ids].delete( tag.id )
|
44
|
+
self.save!
|
45
|
+
else
|
46
|
+
throw "#remove_tag expects a WpTag as the only parameter."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
# EmailConversation = Office::EmailConversation
|
52
|
+
Conv = Office::EmailConversation
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
##
|
3
|
+
## 2023-03-04 _vp_ When I receive one.
|
4
|
+
##
|
5
|
+
class Office::EmailFilter
|
6
|
+
include Mongoid::Document
|
7
|
+
include Mongoid::Timestamps
|
8
|
+
|
9
|
+
field :from_regex
|
10
|
+
field :body_regex
|
11
|
+
|
12
|
+
KIND_SKIP_INBOX = 'skip-inbox'
|
13
|
+
KIND_AUTORESPOND = 'autorespond'
|
14
|
+
KINDS = [ nil, KIND_SKIP_INBOX, KIND_AUTORESPOND ]
|
15
|
+
field :kind
|
16
|
+
|
17
|
+
STATE_ACTIVE = 'active'
|
18
|
+
STATE_INACTIVE = 'inactive'
|
19
|
+
STATES = [ STATE_ACTIVE, STATE_INACTIVE ]
|
20
|
+
field :state, type: :string, default: STATE_ACTIVE
|
21
|
+
scope :active, ->{ where( state: STATE_ACTIVE ) }
|
22
|
+
|
23
|
+
end
|
24
|
+
|
data/lib/office/email_message.rb
CHANGED
@@ -7,6 +7,13 @@ class Office::EmailMessage
|
|
7
7
|
include Mongoid::Timestamps
|
8
8
|
|
9
9
|
field :raw, type: :string
|
10
|
+
|
11
|
+
field :message_id, type: :string # MESSAGE-ID
|
12
|
+
validates_uniqueness_of :message_id
|
13
|
+
index({ message_id: 1 }, { unique: true, name: "message_id_idx" })
|
14
|
+
|
15
|
+
field :in_reply_to_id, type: :string
|
16
|
+
|
10
17
|
field :object_key, type: :string ## aka 'filename', use with bucket name + prefix
|
11
18
|
# validates_presence_of :object_key
|
12
19
|
field :object_path, type: :string ## A routable s3 url
|
@@ -16,19 +23,47 @@ class Office::EmailMessage
|
|
16
23
|
field :part_html
|
17
24
|
# attachments ?
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
from.join(", ")
|
26
|
+
def lead
|
27
|
+
Lead.find_by email: from
|
22
28
|
end
|
23
29
|
|
24
|
-
field :
|
25
|
-
field :
|
26
|
-
field :
|
30
|
+
field :from, type: :string
|
31
|
+
field :froms, type: Array, default: []
|
32
|
+
field :to, type: :string
|
33
|
+
field :tos, type: Array, default: []
|
34
|
+
field :ccs, type: Array, default: []
|
35
|
+
field :bccs, type: Array, default: []
|
36
|
+
|
27
37
|
field :date, type: DateTime
|
28
38
|
def received_at
|
29
39
|
date
|
30
40
|
end
|
31
41
|
|
42
|
+
## Copied to email_conversation
|
43
|
+
field :wp_term_ids, type: Array, default: []
|
44
|
+
## Tested manually ok, does not pass the spec. @TODO: hire to make pass spec? _vp_ 2023-03-07
|
45
|
+
def add_tag tag
|
46
|
+
if WpTag == tag.class
|
47
|
+
self[:wp_term_ids] = self[:wp_term_ids].push(tag.id).uniq
|
48
|
+
self.save!
|
49
|
+
else
|
50
|
+
throw "#add_tag expects a WpTag as the only parameter."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
def remove_tag tag
|
54
|
+
if WpTag == tag.class
|
55
|
+
self[:wp_term_ids].delete( tag.id )
|
56
|
+
self.save!
|
57
|
+
else
|
58
|
+
throw "#remove_tag expects a WpTag as the only parameter."
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
belongs_to :email_conversation
|
63
|
+
def conv
|
64
|
+
email_conversation
|
65
|
+
end
|
66
|
+
|
32
67
|
## @TODO: reimplement, look at footer instead.
|
33
68
|
def name
|
34
69
|
return 'associate'
|
@@ -39,39 +74,53 @@ class Office::EmailMessage
|
|
39
74
|
from[0].split('@')[1]
|
40
75
|
end
|
41
76
|
|
42
|
-
def
|
43
|
-
|
44
|
-
|
45
|
-
::
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
## action.match_from = '@synchrony.com'
|
66
|
-
def apply_actions
|
67
|
-
triggers = Office::Action.active.where({ channel: 'email' })
|
68
|
-
triggers.each do |trigger|
|
69
|
-
if self.from_str.match(/#{trigger.match_from}/i)
|
70
|
-
trigger.actions do |action|
|
71
|
-
Office::Action.call( action[:method], { msg: self }.merge( action[:params] ))
|
72
|
-
end
|
73
|
-
end
|
77
|
+
def apply_filter filter
|
78
|
+
case filter.kind
|
79
|
+
when ::Office::EmailFilter::KIND_SKIP_INBOX
|
80
|
+
self.remove_tag( ::WpTag.email_inbox_tag )
|
81
|
+
when ::Office::EmailFilter::KIND_AUTORESPOND
|
82
|
+
Ish::EmailContext.create({
|
83
|
+
email_template: ::Tmpl.find_by_slug( filter.email_template_slug ),
|
84
|
+
lead: lead,
|
85
|
+
})
|
86
|
+
# when 'autorespond-remind'
|
87
|
+
# Office::EmailAction.create({
|
88
|
+
# tmpl_slug: 'require-sign-nda',
|
89
|
+
# next_in_days: -> { rand(1..5) },
|
90
|
+
# next_at_time: ->{ rand(8..16).hours + rand(1..59).minutes },
|
91
|
+
# next_action: 're-remind-sign-nda',
|
92
|
+
# })
|
93
|
+
# Ish::EmailContext.create({
|
94
|
+
# email_template: ::Tmpl.find_by_slug( filter.email_template_slug ),
|
95
|
+
# lead: lead,
|
96
|
+
# })
|
97
|
+
else
|
98
|
+
raise "unknown filter kind: #{filter.kind}"
|
74
99
|
end
|
75
100
|
end
|
76
101
|
|
77
102
|
end
|
103
|
+
::Msg = Office::EmailMessage
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
## trash _vp_ 2023-03-07
|
108
|
+
# def process
|
109
|
+
# Aws.config[:credentials] = Aws::Credentials.new(
|
110
|
+
# ::S3_CREDENTIALS[:access_key_id],
|
111
|
+
# ::S3_CREDENTIALS[:secret_access_key]
|
112
|
+
# )
|
113
|
+
# s3 = Aws::S3::Client.new
|
114
|
+
# obj = s3.get_object({
|
115
|
+
# bucket: 'ish-ses',
|
116
|
+
# key: self.object_key
|
117
|
+
# })
|
118
|
+
# obj2 = obj.body.read
|
119
|
+
# mail = Mail.read_from_string( obj2 )
|
120
|
+
# self.from = mail.from
|
121
|
+
# self.to = mail.to
|
122
|
+
# self.subject = mail.subject
|
123
|
+
# self.date = mail.date
|
124
|
+
# self.raw = obj2
|
125
|
+
# self.save
|
126
|
+
# end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
##
|
3
|
+
## Only object_key, object_path, no validations.
|
4
|
+
##
|
5
|
+
class Office::EmailMessageStub
|
6
|
+
include Mongoid::Document
|
7
|
+
include Mongoid::Timestamps
|
8
|
+
|
9
|
+
STATE_PENDING = 'state_pending'
|
10
|
+
STATE_PROCESSED = 'state_processed'
|
11
|
+
STATES = [ STATE_PENDING, STATE_PROCESSED ]
|
12
|
+
field :state, type: :string, default: STATE_PENDING
|
13
|
+
|
14
|
+
field :object_key, type: :string ## aka 'filename', use with bucket name + prefix
|
15
|
+
validates_presence_of :object_key
|
16
|
+
|
17
|
+
field :object_path, type: :string ## A routable s3 url ## @TODO: remove this field. _vp_ 2023-03-07
|
18
|
+
# validates_presence_of :object_path ## only need object_key == message_id
|
19
|
+
|
20
|
+
field :term_ids, type: :array, default: []
|
21
|
+
|
22
|
+
end
|
23
|
+
Stub = EMS = Office::EmailMessageStub
|
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
##
|
3
|
+
## 2023-03-04 _vp_ An instance of an EmailAction.
|
4
|
+
##
|
5
|
+
class Office::ScheduledEmailAction
|
6
|
+
include Mongoid::Document
|
7
|
+
include Mongoid::Timestamps
|
8
|
+
include Mongoid::Paranoia
|
9
|
+
|
10
|
+
field :lead_id, type: :integer
|
11
|
+
def lead
|
12
|
+
Lead.find( lead_id )
|
13
|
+
end
|
14
|
+
|
15
|
+
STATE_ACTIVE = 'active'
|
16
|
+
STATE_INACTIVE = 'inactive'
|
17
|
+
STATES = [ STATE_ACTIVE, STATE_INACTIVE ]
|
18
|
+
field :state, type: :string
|
19
|
+
scope :active, ->{ where( state: STATE_ACTIVE ) }
|
20
|
+
|
21
|
+
belongs_to :email_action, class_name: '::Office::EmailAction'
|
22
|
+
has_many :email_contexts, class_name: '::Ish::EmailContext'
|
23
|
+
|
24
|
+
field :perform_at, type: :timestamp
|
25
|
+
|
26
|
+
end
|
27
|
+
::Sch = Office::ScheduledEmailAction
|
28
|
+
|
29
|
+
## @TODO: herehere 2023-03-04 _vp_ Currently Working on this
|
30
|
+
=begin
|
31
|
+
::Sch.active.where( :perform_at.lte => Time.now ) do |sch|
|
32
|
+
next_a = sch.next_email_action
|
33
|
+
|
34
|
+
if sch.next_actions.present?
|
35
|
+
sch.next_actions.each do |next_a|
|
36
|
+
next_sch_a = ::Office::ScheduledEmailAction.new({
|
37
|
+
email_action: next_a
|
38
|
+
|
39
|
+
next_time = Time.now + eval( sch.next_in_days )
|
40
|
+
next_time.time = eval( sch.next_at_time )
|
41
|
+
sch.update_attribute( :perform_at, next_time )
|
42
|
+
end
|
43
|
+
else
|
44
|
+
sch.update_attribute( state: STATE_INACTIVE )
|
45
|
+
end
|
46
|
+
=end
|
47
|
+
|
48
|
+
|
data/lib/report.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ish_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.33.
|
4
|
+
version: 0.0.33.195
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- piousbox
|
@@ -138,25 +138,20 @@ files:
|
|
138
138
|
- lib/ish/payment.rb
|
139
139
|
- lib/ish/premium_item.rb
|
140
140
|
- lib/ish/railtie.rb
|
141
|
-
- lib/ish/trash/email_campaign.rb
|
142
|
-
- lib/ish/trash/lead.rb
|
143
|
-
- lib/ish/trash/lead.rb-bk
|
144
141
|
- lib/ish/user_profile.rb
|
145
142
|
- lib/ish/utils.rb
|
146
143
|
- lib/ish_models.rb
|
147
144
|
- lib/mongoid/votable.rb
|
148
145
|
- lib/mongoid/voter.rb
|
149
146
|
- lib/newsitem.rb
|
150
|
-
- lib/office/
|
147
|
+
- lib/office/email_action.rb
|
148
|
+
- lib/office/email_conversation.rb
|
149
|
+
- lib/office/email_filter.rb
|
151
150
|
- lib/office/email_message.rb
|
151
|
+
- lib/office/email_message_stub.rb
|
152
|
+
- lib/office/scheduled_email_action.rb
|
152
153
|
- lib/photo.rb
|
153
154
|
- lib/report.rb
|
154
|
-
- lib/trash/app_model2.rb
|
155
|
-
- lib/trash/city.rb-bk
|
156
|
-
- lib/trash/event.rb
|
157
|
-
- lib/trash/site.rb
|
158
|
-
- lib/trash/tag_trash.rb
|
159
|
-
- lib/trash/venue.rb
|
160
155
|
- lib/video.rb
|
161
156
|
homepage: https://wasya.co
|
162
157
|
licenses:
|
@@ -1,28 +0,0 @@
|
|
1
|
-
|
2
|
-
class Ish::EmailCampaign
|
3
|
-
include Mongoid::Document
|
4
|
-
include Mongoid::Timestamps
|
5
|
-
|
6
|
-
store_in :collection => 'ish_campaign'
|
7
|
-
|
8
|
-
belongs_to :profile, :class_name => 'Ish::UserProfile'
|
9
|
-
|
10
|
-
has_and_belongs_to_many :leads, :class_name => 'Ish::Lead'
|
11
|
-
has_and_belongs_to_many :unsubscribe_leads, :class_name => 'Ish::Lead'
|
12
|
-
|
13
|
-
field :subject
|
14
|
-
field :body
|
15
|
-
|
16
|
-
## @TODO: tags instead?
|
17
|
-
field :is_done, :type => Boolean, :default => false
|
18
|
-
field :is_trash, :type => Boolean, :default => false
|
19
|
-
field :tag # 'hired_com_ror', not enumerated for now _vp_ 20180103
|
20
|
-
|
21
|
-
## @TODO: sent on, scheduled_on, ...
|
22
|
-
field :applied_on, :type => Time
|
23
|
-
|
24
|
-
## Need tracking!
|
25
|
-
|
26
|
-
## this looks like an email_context, copy from there.
|
27
|
-
|
28
|
-
end
|
data/lib/ish/trash/lead.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# Lead
|
4
|
-
# _vp_ 20171204
|
5
|
-
#
|
6
|
-
class Ish::Lead
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::Timestamps
|
9
|
-
|
10
|
-
store_in :collection => 'ish_leads'
|
11
|
-
|
12
|
-
belongs_to :profile, :class_name => '::Ish::UserProfile'
|
13
|
-
|
14
|
-
has_and_belongs_to_many :campaigns, :class_name => '::Ish::Campaign', :inverse_of => :leads
|
15
|
-
has_and_belongs_to_many :unsubscribe_campaigns, :class_name => '::Ish::Campaign', :inverse_of => :unsubscribe_leads
|
16
|
-
|
17
|
-
field :email
|
18
|
-
field :job_url
|
19
|
-
field :company_url
|
20
|
-
field :website_html
|
21
|
-
field :yelp_url
|
22
|
-
|
23
|
-
field :company
|
24
|
-
validates_uniqueness_of :company
|
25
|
-
index({ :company => -1 })
|
26
|
-
|
27
|
-
field :description
|
28
|
-
|
29
|
-
STATES = %w( considering applied )
|
30
|
-
field :state, :type => String
|
31
|
-
|
32
|
-
field :is_done, :type => Boolean, :default => false
|
33
|
-
field :is_trash, :type => Boolean, :default => false
|
34
|
-
|
35
|
-
field :applied_on, :type => Time
|
36
|
-
|
37
|
-
field :tag, :type => String # 'hired_com_ror', not enumerated for now _vp_ 20180103
|
38
|
-
field :location
|
39
|
-
|
40
|
-
field :raw_phone, :type => String
|
41
|
-
def phone= which
|
42
|
-
write_attribute :raw_phone, which
|
43
|
-
write_attribute :phone, which.gsub(/\D/, '').to_i
|
44
|
-
end
|
45
|
-
field :phone, :type => Integer
|
46
|
-
field :address, :type => String
|
47
|
-
|
48
|
-
# If I crawl on 20180724, I add "20180724" here, so I don't crawl in the same way again.
|
49
|
-
field :extra, :type => Array, :default => []
|
50
|
-
|
51
|
-
end
|
52
|
-
|
data/lib/ish/trash/lead.rb-bk
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# Lead
|
4
|
-
# _vp_ 20171204
|
5
|
-
#
|
6
|
-
class Ish::Lead
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::Timestamps
|
9
|
-
|
10
|
-
store_in :collection => 'ish_leads'
|
11
|
-
|
12
|
-
# field :email
|
13
|
-
# field :company_url
|
14
|
-
# field :yelp_url
|
15
|
-
|
16
|
-
# # company name
|
17
|
-
# field :company
|
18
|
-
# validates_uniqueness_of :company
|
19
|
-
# index({ :company => -1 })
|
20
|
-
|
21
|
-
# field :description # comment, actually
|
22
|
-
|
23
|
-
field :is_done, :type => Boolean, :default => false
|
24
|
-
field :is_trash, :type => Boolean, :default => false
|
25
|
-
|
26
|
-
field :tag, :type => String # 'hired_com_ror', not enumerated for now _vp_ 20180103
|
27
|
-
# field :location
|
28
|
-
|
29
|
-
field :raw_phone, :type => String
|
30
|
-
def phone= which
|
31
|
-
write_attribute :raw_phone, which
|
32
|
-
write_attribute :phone, which.gsub(/\D/, '').to_i
|
33
|
-
end
|
34
|
-
field :phone, :type => Integer
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
|
data/lib/office/action.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
|
2
|
-
##
|
3
|
-
## Such actions as auto-responder.
|
4
|
-
##
|
5
|
-
class Office::Action
|
6
|
-
include Mongoid::Document
|
7
|
-
include Mongoid::Timestamps
|
8
|
-
|
9
|
-
field :status, type: String, default: 'active'
|
10
|
-
field :channel, type: String ## eg 'email'
|
11
|
-
field :match_from, type: String ## eg '@synchrony.com', '*@synchrony.com$'
|
12
|
-
|
13
|
-
scope :active, -> { where( status: 'active' ) }
|
14
|
-
|
15
|
-
## eg [ { 'method': 'create_lead', 'params': {} },
|
16
|
-
## { 'method': 'autorespond', 'params': {}, ... ]
|
17
|
-
field :actions, type: Array, default: []
|
18
|
-
|
19
|
-
def self.create_lead params
|
20
|
-
msg = params[:msg]
|
21
|
-
leadset = Leadset.find_or_create_by({ company_url: msg.company_url })
|
22
|
-
lead = Lead.new({
|
23
|
-
email: msg.from_str,
|
24
|
-
name: msg.name,
|
25
|
-
leadset: leadset,
|
26
|
-
})
|
27
|
-
lead.save
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.autorespond params
|
31
|
-
msg = params[:msg]
|
32
|
-
email_template = ::Ish::EmailTemplate.find_by!({ slug: '20230207-autorespond' })
|
33
|
-
email_ctx = ::Ish::EmailContext.new({
|
34
|
-
to_email: '',
|
35
|
-
subject: '',
|
36
|
-
from_email: '',
|
37
|
-
body: '',
|
38
|
-
email_template_id: email_template.id.to_s,
|
39
|
-
})
|
40
|
-
email_ctx.save!
|
41
|
-
IshManager::OfficeMailer.send_context_email( email_ctx ).deliver_later
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
data/lib/trash/app_model2.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
|
2
|
-
# @deprecated, remove
|
3
|
-
class Ish::AppModel2
|
4
|
-
include ::Mongoid::Document
|
5
|
-
include ::Mongoid::Timestamps
|
6
|
-
|
7
|
-
field :is_public, :type => Boolean, :default => false
|
8
|
-
field :is_trash, :type => Boolean, :default => false
|
9
|
-
|
10
|
-
default_scope ->{ where({ :is_public => true, :is_trash => false }).order_by({ :created_at => :desc }) }
|
11
|
-
|
12
|
-
field :x, :type => Float
|
13
|
-
field :y, :type => Float
|
14
|
-
|
15
|
-
def self.list conditions = { :is_trash => false }
|
16
|
-
out = self.where( conditions ).order_by( :created_at => :desc )
|
17
|
-
[['', nil]] + out.map { |item| [ "#{item.created_at.strftime('%Y%m%d')} #{item.name}", item.id ] }
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
end
|
data/lib/trash/city.rb-bk
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
class City
|
2
|
-
include ::Mongoid::Document
|
3
|
-
include ::Mongoid::Timestamps
|
4
|
-
|
5
|
-
field :name, :type => String
|
6
|
-
field :description, :type => String, :default => 'The description of this city'
|
7
|
-
|
8
|
-
field :cityname, :type => String
|
9
|
-
validates :cityname, :uniqueness => true, :allow_nil => false, :presence => true
|
10
|
-
def slug; cityname; end
|
11
|
-
def slug= s; cityname = s; end
|
12
|
-
|
13
|
-
field :x, :type => Float
|
14
|
-
field :y, :type => Float
|
15
|
-
|
16
|
-
field :deleted_at, type: Time
|
17
|
-
def self.all
|
18
|
-
self.where( deleted_at: nil, is_active: true ).order_by( name: :desc )
|
19
|
-
end
|
20
|
-
|
21
|
-
belongs_to :country, :optional => true
|
22
|
-
|
23
|
-
has_many :events
|
24
|
-
has_many :galleries
|
25
|
-
has_many :photos
|
26
|
-
has_many :reports
|
27
|
-
has_many :venues
|
28
|
-
has_many :videos
|
29
|
-
has_and_belongs_to_many :tags
|
30
|
-
|
31
|
-
has_many :current_users, :class_name => '::Ish::UserProfile', :inverse_of => :current_city
|
32
|
-
has_many :newsitems
|
33
|
-
|
34
|
-
has_many :current_users, :class_name => '::Ish::UserProfile', :inverse_of => :current_city
|
35
|
-
has_one :profile_photo, :class_name => 'Photo', :inverse_of => :profile_city
|
36
|
-
has_one :guide, :class_name => '::Ish::UserProfile', :inverse_of => :guide_city
|
37
|
-
|
38
|
-
has_many :features
|
39
|
-
|
40
|
-
field :calendar_frame, :type => String
|
41
|
-
field :is_active, type: Boolean, default: true
|
42
|
-
|
43
|
-
default_scope ->{ order_by({ :name => :asc }) }
|
44
|
-
|
45
|
-
def self.list
|
46
|
-
out = self.order_by( :name => :asc )
|
47
|
-
# no_city = City.where( :cityname => 'no_city' ).first || City.create( :cityname => 'no_city', :name => 'No City' )
|
48
|
-
[['', nil]] + out.map { |item| [ item.name, item.id ] }
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.list_citynames lang = 'en'
|
52
|
-
out = self.order_by( :name => :asc )
|
53
|
-
[['', nil]] + out.map { |item| [ item['name_'+lang], item.cityname ] }
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.clear
|
57
|
-
if Rails.env.test?
|
58
|
-
City.all.each { |r| r.remove }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.n_features
|
63
|
-
4
|
64
|
-
end
|
65
|
-
def n_features
|
66
|
-
4
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
|
-
def j_reports args = {}
|
71
|
-
out = []
|
72
|
-
self.reports.each do |r|
|
73
|
-
rr = r.clone
|
74
|
-
rr[:username] = r.user.username
|
75
|
-
rr.created_at = r.created_at # pretty_date( r.created_at )
|
76
|
-
rr[:tag_name] = r.tag.name unless r.tag.blank?
|
77
|
-
rr[:tag_name] ||= ''
|
78
|
-
out << rr
|
79
|
-
end
|
80
|
-
return out
|
81
|
-
end
|
82
|
-
|
83
|
-
def self.for_homepage
|
84
|
-
cities = City.all.order_by( :name => :asc )
|
85
|
-
cities = cities.delete_if do |c|
|
86
|
-
( false == c.is_feature ) && ( 0 == c.galleries.length ) && ( 0 == c.reports.length )
|
87
|
-
end
|
88
|
-
return cities
|
89
|
-
end
|
90
|
-
|
91
|
-
def self.method_missing name, *args, &block
|
92
|
-
city = City.where( :cityname => name ).first
|
93
|
-
return city if city
|
94
|
-
super
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
|
data/lib/trash/event.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
|
2
|
-
class Event
|
3
|
-
|
4
|
-
include Mongoid::Document
|
5
|
-
include Mongoid::Timestamps
|
6
|
-
|
7
|
-
field :name, :type => String
|
8
|
-
validates :name, :presence => true, :uniqueness => true
|
9
|
-
|
10
|
-
field :eventname, :type => String
|
11
|
-
validates :eventname, :presence => true, :uniqueness => true
|
12
|
-
|
13
|
-
field :description, :type => String
|
14
|
-
|
15
|
-
field :date, :type => DateTime
|
16
|
-
validates :date, :presence => true
|
17
|
-
|
18
|
-
belongs_to :city
|
19
|
-
validates :city, :presence => true
|
20
|
-
|
21
|
-
field :x, :type => Float
|
22
|
-
field :y, :type => Float
|
23
|
-
|
24
|
-
has_one :profile_photo, :class_name => 'Photo', :inverse_of => :profile_event
|
25
|
-
has_many :photos
|
26
|
-
|
27
|
-
end
|
28
|
-
|
data/lib/trash/site.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
class Site
|
2
|
-
|
3
|
-
include Mongoid::Document
|
4
|
-
include Mongoid::Timestamps
|
5
|
-
|
6
|
-
field :domain, :type => String
|
7
|
-
validates_presence_of :domain
|
8
|
-
|
9
|
-
field :lang, :type => String, :default => 'en'
|
10
|
-
# validates :lang, { :uniqueness => :true, :scope => :domain }
|
11
|
-
|
12
|
-
field :title
|
13
|
-
field :subhead
|
14
|
-
field :description
|
15
|
-
field :home_redirect_path
|
16
|
-
|
17
|
-
field :n_features, :type => Integer, :default => 4
|
18
|
-
field :n_newsitems, :type => Integer, :default => 20
|
19
|
-
field :newsitems_per_page, :type => Integer, :default => 10 # this is used. _vp_ 20171025
|
20
|
-
field :play_videos_in_preview, :type => Boolean, :default => true
|
21
|
-
|
22
|
-
# denormalized
|
23
|
-
field :n_reports, :type => Integer
|
24
|
-
field :n_galleries, :type => Integer
|
25
|
-
|
26
|
-
field :is_video_enabled, :type => Boolean, :default => false
|
27
|
-
field :is_resume_enabled, :type => Boolean, :default => false
|
28
|
-
field :is_ads_enabled, :type => Boolean, :default => true
|
29
|
-
field :is_trash, :type => Boolean, :default => false
|
30
|
-
field :is_primary, :type => Boolean, :default => false
|
31
|
-
field :is_private, :type => Boolean, :default => false
|
32
|
-
field :private_user_emails, :type => Array, :default => []
|
33
|
-
|
34
|
-
field :homepage_layout, :type => String, :default => 'show'
|
35
|
-
field :layout, :type => String, :default => 'application'
|
36
|
-
|
37
|
-
has_many :reports
|
38
|
-
has_many :galleries
|
39
|
-
has_many :tags
|
40
|
-
has_many :videos
|
41
|
-
has_many :newsitems, :order => :created_at.desc
|
42
|
-
has_many :issues, :class_name => 'Ish::Issue'
|
43
|
-
has_many :features, :order => :created_at.desc
|
44
|
-
|
45
|
-
default_scope ->{ where({ :is_trash => false }).order_by({ :domain => :asc, :lang => :asc }) }
|
46
|
-
|
47
|
-
set_callback :create, :before do |doc|
|
48
|
-
if Site.where( :lang => doc.lang, :domain => doc.domain ).length > 0
|
49
|
-
false
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
set_callback :update, :before do |doc|
|
54
|
-
possible_duplicate = Site.where( :lang => doc.lang, :domain => doc.domain ).first
|
55
|
-
if possible_duplicate.blank?
|
56
|
-
true
|
57
|
-
elsif doc.id != possible_duplicate.id
|
58
|
-
false
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
LANGUAGES = [ 'en', 'ru', 'pt' ]
|
63
|
-
|
64
|
-
# manager uses it.
|
65
|
-
def self.list
|
66
|
-
out = self.all.order_by( :domain => :asc, :lang => :asc )
|
67
|
-
[['Select Site', nil]] + out.map { |item| [ "#{item.domain} #{item.lang}", item.id ] }
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.mobi
|
71
|
-
Site.where( :domain => 'travel-guide.mobi', :lang => 'en' ).first
|
72
|
-
end
|
73
|
-
|
74
|
-
def n_reports
|
75
|
-
self.reports.unscoped.where( :is_trash => false ).length
|
76
|
-
end
|
77
|
-
|
78
|
-
def n_private_reports
|
79
|
-
self.reports.unscoped.where( :is_public => false, :is_trash => false ).length
|
80
|
-
end
|
81
|
-
|
82
|
-
def its_locales
|
83
|
-
Site.where( :domain => self.domain ).map { |s| s.lang.to_sym }
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.Tgm
|
87
|
-
Site.find_by( :domain => 'travel-guide.mobi', :lang => :en )
|
88
|
-
end
|
89
|
-
def self.sedux
|
90
|
-
site = Site.where( :domain => 'sedux.local' ).first
|
91
|
-
site ||= Site.where( :domain => 'sedux.net' ).first
|
92
|
-
site
|
93
|
-
end
|
94
|
-
|
95
|
-
def name
|
96
|
-
"#{domain}/#{lang}"
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
data/lib/trash/tag_trash.rb
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
class TagTrash
|
2
|
-
include Mongoid::Document
|
3
|
-
include Mongoid::Timestamps
|
4
|
-
include Ish::Utils
|
5
|
-
|
6
|
-
field :name, :type => String
|
7
|
-
validates :name, uniqueness: true, presence: true, allow_nil: false # @TODO: tags should only be unique globally, and per-user.
|
8
|
-
|
9
|
-
field :slug
|
10
|
-
validates :slug, uniqueness: true, presence: true, allow_nil: false
|
11
|
-
|
12
|
-
field :descr, :type => String, :default => ''
|
13
|
-
|
14
|
-
field :is_public, :type => Boolean, :default => true
|
15
|
-
field :is_trash, :type => Boolean, :default => false
|
16
|
-
field :is_feature, :type => Boolean, :default => false
|
17
|
-
|
18
|
-
field :weight, :type => Integer, :default => 10
|
19
|
-
|
20
|
-
has_many :children_tags, :class_name => 'Tag', :inverse_of => :parent_tag
|
21
|
-
belongs_to :parent_tag, :class_name => 'Tag', :inverse_of => :children_tags, :optional => true
|
22
|
-
|
23
|
-
has_many :features
|
24
|
-
has_many :newsitems
|
25
|
-
|
26
|
-
belongs_to :site, :optional => true
|
27
|
-
belongs_to :city, :optional => true
|
28
|
-
|
29
|
-
has_and_belongs_to_many :venues
|
30
|
-
has_and_belongs_to_many :cities
|
31
|
-
has_and_belongs_to_many :galleries
|
32
|
-
has_and_belongs_to_many :reports
|
33
|
-
has_and_belongs_to_many :videos
|
34
|
-
has_and_belongs_to_many :maps, class_name: 'Gameui::Map'
|
35
|
-
|
36
|
-
before_validation :set_slug
|
37
|
-
|
38
|
-
def self.clear
|
39
|
-
if Rails.env.test?
|
40
|
-
Tag.each { |r| r.remove }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.no_parent
|
45
|
-
Tag.where( :parent_tag_id => nil )
|
46
|
-
end
|
47
|
-
|
48
|
-
# the first blank used to be disabled, not anymore _vp_ 20180418
|
49
|
-
def self.list
|
50
|
-
out = Tag.unscoped.order_by( :name => :asc )
|
51
|
-
return( [['', nil]] + out.map { |item| [ item.name, item.id ] } )
|
52
|
-
end
|
53
|
-
|
54
|
-
# @deprecated, there will be no reports or galleries in tags. There will be only features and newsitems
|
55
|
-
def self.n_items
|
56
|
-
10
|
57
|
-
end
|
58
|
-
def self.n_reports
|
59
|
-
4
|
60
|
-
end
|
61
|
-
def self.n_galleries
|
62
|
-
4
|
63
|
-
end
|
64
|
-
def self.n_videos
|
65
|
-
4
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.n_features
|
69
|
-
4
|
70
|
-
end
|
71
|
-
field :n_features, type: Integer, default: 4
|
72
|
-
|
73
|
-
end
|
data/lib/trash/venue.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
class Venue
|
2
|
-
include ::Mongoid::Document
|
3
|
-
include ::Mongoid::Timestamps
|
4
|
-
include Ish::Utils
|
5
|
-
|
6
|
-
field :address
|
7
|
-
|
8
|
-
field :name, :type => String
|
9
|
-
validates :name, :uniqueness => true, :allow_nil => false
|
10
|
-
|
11
|
-
field :slug
|
12
|
-
validates :slug, :uniqueness => true, :allow_nil => false
|
13
|
-
before_validation :set_slug
|
14
|
-
|
15
|
-
field :subhead
|
16
|
-
field :descr
|
17
|
-
|
18
|
-
field :is_trash, :type => Boolean, :default => false
|
19
|
-
scope :fresh, ->{ where({ :is_trash => false }) }
|
20
|
-
scope :trash, ->{ where({ :is_trash => true }) }
|
21
|
-
|
22
|
-
field :is_public, :type => Boolean, :default => true
|
23
|
-
scope :public, ->{ where({ :is_public => true }) }
|
24
|
-
scope :not_public, ->{ where({ :is_public => false }) }
|
25
|
-
|
26
|
-
field :is_feature, :type => Boolean, :default => false
|
27
|
-
|
28
|
-
field :x, :type => Float
|
29
|
-
field :y, :type => Float
|
30
|
-
|
31
|
-
field :lang, :type => String, :default => 'en'
|
32
|
-
|
33
|
-
belongs_to :city
|
34
|
-
# belongs_to :owner, :class_name => 'User', :inverse_of => :owned_venue
|
35
|
-
validates :city, :allow_nil => false, :presence => true
|
36
|
-
|
37
|
-
has_and_belongs_to_many :tags
|
38
|
-
|
39
|
-
has_and_belongs_to_many :users
|
40
|
-
|
41
|
-
has_one :profile_photo, :class_name => 'Photo', :inverse_of => :profile_venue
|
42
|
-
|
43
|
-
has_many :reports
|
44
|
-
has_many :galleries
|
45
|
-
has_many :photos
|
46
|
-
has_many :newsitems
|
47
|
-
has_many :features
|
48
|
-
|
49
|
-
PER_PAGE = 6
|
50
|
-
|
51
|
-
def self.list conditions = { :is_trash => false }
|
52
|
-
out = self.where( conditions).order_by( :name => :asc )
|
53
|
-
[['', nil]] + out.map { |item| [ item.name, item.id ] }
|
54
|
-
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
set_callback :save, :before do |doc|
|
59
|
-
if doc.city
|
60
|
-
city.touch
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.types
|
65
|
-
return []
|
66
|
-
# if 'en' == @locale
|
67
|
-
# [ 'Hotels', 'Restaurants', 'Bars' ]
|
68
|
-
# else
|
69
|
-
# [ 'Hotels', 'Restaurants', 'Bars' ]
|
70
|
-
# end
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.n_features
|
74
|
-
6
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|