biovision 0.0.200518.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +214 -0
- data/Rakefile +22 -0
- data/app/assets/config/biovision_manifest.js +1 -0
- data/app/assets/images/biovision/components/carousel/arrow-left.svg +4 -0
- data/app/assets/images/biovision/components/carousel/arrow-right.svg +4 -0
- data/app/assets/images/biovision/icons/breadcrumb-hover.svg +1 -0
- data/app/assets/images/biovision/icons/breadcrumb.svg +1 -0
- data/app/assets/images/biovision/icons/components/contact.svg +26 -0
- data/app/assets/images/biovision/icons/components/content.svg +20 -0
- data/app/assets/images/biovision/icons/components/users.svg +21 -0
- data/app/assets/images/biovision/icons/key.svg +16 -0
- data/app/assets/images/biovision/icons/log_in.svg +15 -0
- data/app/assets/images/biovision/icons/log_out.svg +15 -0
- data/app/assets/images/biovision/icons/messages/error.svg +14 -0
- data/app/assets/images/biovision/icons/messages/info.svg +8 -0
- data/app/assets/images/biovision/icons/messages/success.svg +12 -0
- data/app/assets/images/biovision/icons/messages/warning.svg +13 -0
- data/app/assets/images/biovision/icons/settings.svg +41 -0
- data/app/assets/images/biovision/placeholders/16x9.svg +11 -0
- data/app/assets/images/biovision/placeholders/1x1.svg +11 -0
- data/app/assets/images/biovision/placeholders/3x2.svg +11 -0
- data/app/assets/images/biovision/placeholders/user.svg +15 -0
- data/app/assets/stylesheets/biovision/admin.scss +6 -0
- data/app/assets/stylesheets/biovision/admin/components.scss +59 -0
- data/app/assets/stylesheets/biovision/admin/default.scss +57 -0
- data/app/assets/stylesheets/biovision/admin/layout.scss +95 -0
- data/app/assets/stylesheets/biovision/admin/vars.scss +56 -0
- data/app/assets/stylesheets/biovision/biovision.scss +134 -0
- data/app/assets/stylesheets/biovision/biovision/messages.scss +41 -0
- data/app/assets/stylesheets/biovision/components/carousel.scss +53 -0
- data/app/assets/stylesheets/biovision/components/forms.scss +85 -0
- data/app/assets/stylesheets/biovision/components/hamburger.scss +56 -0
- data/app/assets/stylesheets/biovision/components/lists.scss +91 -0
- data/app/assets/stylesheets/biovision/default.scss +57 -0
- data/app/assets/stylesheets/biovision/themes/default_theme.scss +2 -0
- data/app/assets/stylesheets/biovision/themes/default_theme/components.scss +3 -0
- data/app/assets/stylesheets/biovision/themes/default_theme/layout.scss +44 -0
- data/app/assets/stylesheets/biovision/themes/default_theme/layout/footer.scss +0 -0
- data/app/assets/stylesheets/biovision/themes/default_theme/layout/header.scss +39 -0
- data/app/assets/stylesheets/biovision/vars.scss +53 -0
- data/app/controllers/admin/agents_controller.rb +15 -0
- data/app/controllers/admin/components_controller.rb +174 -0
- data/app/controllers/admin/index_controller.rb +11 -0
- data/app/controllers/admin/ip_addresses_controller.rb +15 -0
- data/app/controllers/admin_controller.rb +14 -0
- data/app/controllers/authentication_controller.rb +79 -0
- data/app/controllers/concerns/authentication.rb +45 -0
- data/app/controllers/index_controller.rb +8 -0
- data/app/controllers/my/confirmations_controller.rb +2 -0
- data/app/controllers/my/index_controller.rb +8 -0
- data/app/controllers/my/profiles_controller.rb +128 -0
- data/app/controllers/my/recoveries_controller.rb +2 -0
- data/app/helpers/biovision_components_helper.rb +14 -0
- data/app/helpers/users_helper.rb +11 -0
- data/app/lib/biovision/components/base_component.rb +177 -0
- data/app/lib/biovision/components/component_settings.rb +30 -0
- data/app/lib/biovision/components/privilege_handler.rb +77 -0
- data/app/lib/biovision/components/track_component.rb +9 -0
- data/app/lib/biovision/components/users/authentication.rb +47 -0
- data/app/lib/biovision/components/users/code_handler.rb +23 -0
- data/app/lib/biovision/components/users/profile_handler.rb +12 -0
- data/app/lib/biovision/components/users/registration_handler.rb +99 -0
- data/app/lib/biovision/components/users_component.rb +47 -0
- data/app/lib/biovision/notifiers/base_notifier.rb +69 -0
- data/app/lib/biovision/notifiers/socialization_notifier.rb +31 -0
- data/app/lib/biovision/notifiers/users_notifier.rb +15 -0
- data/app/models/agent.rb +35 -0
- data/app/models/biovision_component.rb +45 -0
- data/app/models/biovision_component_user.rb +21 -0
- data/app/models/browser.rb +34 -0
- data/app/models/code.rb +71 -0
- data/app/models/concerns/checkable.rb +22 -0
- data/app/models/concerns/flat_priority.rb +50 -0
- data/app/models/concerns/has_language.rb +10 -0
- data/app/models/concerns/has_owner.rb +22 -0
- data/app/models/concerns/has_simple_image.rb +18 -0
- data/app/models/concerns/has_track.rb +10 -0
- data/app/models/concerns/has_uuid.rb +12 -0
- data/app/models/concerns/meta_texts.rb +16 -0
- data/app/models/concerns/nested_priority.rb +58 -0
- data/app/models/concerns/required_unique_name.rb +16 -0
- data/app/models/concerns/required_unique_slug.rb +15 -0
- data/app/models/concerns/toggleable.rb +33 -0
- data/app/models/foreign_site.rb +34 -0
- data/app/models/foreign_user.rb +21 -0
- data/app/models/ip_address.rb +31 -0
- data/app/models/language.rb +31 -0
- data/app/models/login_attempt.rb +35 -0
- data/app/models/metric.rb +48 -0
- data/app/models/metric_value.rb +11 -0
- data/app/models/notification.rb +37 -0
- data/app/models/simple_image.rb +47 -0
- data/app/models/simple_image_tag.rb +30 -0
- data/app/models/simple_image_tag_image.rb +13 -0
- data/app/models/token.rb +96 -0
- data/app/models/user.rb +136 -0
- data/app/models/user_language.rb +15 -0
- data/app/uploaders/simple_image_uploader.rb +96 -0
- data/app/uploaders/user_image_uploader.rb +58 -0
- data/app/views/admin/agents/_nav_item.html.erb +6 -0
- data/app/views/admin/agents/entity/_in_list.html.erb +6 -0
- data/app/views/admin/agents/index.html.erb +13 -0
- data/app/views/admin/components/_list.html.erb +12 -0
- data/app/views/admin/components/entity/_links.html.erb +35 -0
- data/app/views/admin/components/entity/_section.html.erb +12 -0
- data/app/views/admin/components/index.html.erb +12 -0
- data/app/views/admin/components/links/_track.html.erb +2 -0
- data/app/views/admin/components/links/_users.html.erb +11 -0
- data/app/views/admin/components/privileges.html.erb +20 -0
- data/app/views/admin/components/privileges/_component_user.html.erb +17 -0
- data/app/views/admin/components/privileges/_links.html.erb +35 -0
- data/app/views/admin/components/privileges/_privilege_flag.html.erb +28 -0
- data/app/views/admin/components/privileges/_users.html.erb +23 -0
- data/app/views/admin/components/settings.html.erb +39 -0
- data/app/views/admin/components/settings/_new_parameter.html.erb +46 -0
- data/app/views/admin/components/settings/_parameters.html.erb +20 -0
- data/app/views/admin/components/settings/_setting.html.erb +18 -0
- data/app/views/admin/components/settings/_settings.html.erb +31 -0
- data/app/views/admin/components/show.html.erb +14 -0
- data/app/views/admin/index/index.html.erb +14 -0
- data/app/views/admin/ip_addresses/_nav_item.html.erb +6 -0
- data/app/views/admin/ip_addresses/entity/_in_list.html.erb +6 -0
- data/app/views/admin/ip_addresses/index.html.erb +13 -0
- data/app/views/admin/unauthorized.html.erb +19 -0
- data/app/views/authentication/_form.html.erb +40 -0
- data/app/views/authentication/failed.js.erb +3 -0
- data/app/views/authentication/new.html.erb +21 -0
- data/app/views/index/index.html.erb +0 -0
- data/app/views/layouts/admin.html.erb +23 -0
- data/app/views/layouts/admin/_breadcrumbs.html.erb +8 -0
- data/app/views/layouts/admin/_footer.html.erb +10 -0
- data/app/views/layouts/admin/_header.html.erb +18 -0
- data/app/views/layouts/admin/header/_logo.html.erb +3 -0
- data/app/views/layouts/application/_footer.html.erb +8 -0
- data/app/views/layouts/application/_header.html.erb +9 -0
- data/app/views/layouts/application/header/_authentication.html.erb +13 -0
- data/app/views/my/index/index.html.erb +0 -0
- data/app/views/my/profiles/closed.html.erb +12 -0
- data/app/views/my/profiles/new.html.erb +17 -0
- data/app/views/my/profiles/new/_form.html.erb +147 -0
- data/app/views/shared/_breadcrumbs.html.erb +8 -0
- data/app/views/shared/_cookie_notification.html.erb +4 -0
- data/app/views/shared/_flash_messages.html.erb +7 -0
- data/app/views/shared/_meta_texts.html.erb +31 -0
- data/app/views/shared/_nothing_found.html.erb +1 -0
- data/app/views/shared/_pagination.jbuilder +15 -0
- data/app/views/shared/admin/_list.html.erb +19 -0
- data/app/views/shared/admin/_list_with_priority.html.erb +19 -0
- data/app/views/shared/admin/_toggleable.html.erb +8 -0
- data/app/views/shared/entity/_list_of_errors.html.erb +7 -0
- data/app/views/shared/forms/errors.js.erb +5 -0
- data/config/initializers/carrierwave.rb +27 -0
- data/config/initializers/pluralization.rb +2 -0
- data/config/locales/biovision-ru.yml +90 -0
- data/config/locales/components-ru.yml +81 -0
- data/config/locales/track-ru.yml +40 -0
- data/config/locales/users-ru.yml +130 -0
- data/config/routes.rb +75 -0
- data/db/migrate/20191228000000_create_biovision_components.rb +72 -0
- data/db/migrate/20200224000000_create_track_component.rb +59 -0
- data/db/migrate/20200224000010_create_users_component.rb +189 -0
- data/db/migrate/20200404000000_create_simple_images.rb +54 -0
- data/lib/biovision.rb +9 -0
- data/lib/biovision/base_methods.rb +167 -0
- data/lib/biovision/engine.rb +40 -0
- data/lib/biovision/version.rb +5 -0
- data/lib/tasks/biovision_tasks.rake +4 -0
- metadata +392 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Component notification for user
|
4
|
+
#
|
5
|
+
# Attributes:
|
6
|
+
# biovision_component_id [BiovisionComponent]
|
7
|
+
# created_at [DateTime]
|
8
|
+
# data [jsonb]
|
9
|
+
# email_sent [boolean]
|
10
|
+
# read [boolean]
|
11
|
+
# updated_at [DateTime]
|
12
|
+
# user_id [User]
|
13
|
+
# uuid [uuid]
|
14
|
+
class Notification < ApplicationRecord
|
15
|
+
include HasOwner
|
16
|
+
include HasUuid
|
17
|
+
|
18
|
+
belongs_to :biovision_component
|
19
|
+
belongs_to :user
|
20
|
+
|
21
|
+
scope :recent, -> { order('id desc') }
|
22
|
+
scope :unread, -> { where(read: false) }
|
23
|
+
scope :not_sent, -> { where(email_sent: false) }
|
24
|
+
scope :data_id, ->(v) { where("cast(data->>'id' as integer) = ?", v) }
|
25
|
+
scope :data_type, ->(v) { where("data->>'type' = ?", v) }
|
26
|
+
scope :list_for_owner, ->(v) { owned_by(v).recent }
|
27
|
+
|
28
|
+
# @param [User] user
|
29
|
+
# @param [Integer] page
|
30
|
+
def self.page_for_owner(user, page = 1)
|
31
|
+
list_for_owner(user).page(page)
|
32
|
+
end
|
33
|
+
|
34
|
+
def component_slug
|
35
|
+
biovision_component.slug
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Universal simple image
|
4
|
+
#
|
5
|
+
# Attributes:
|
6
|
+
# agent_id [Agent], optional
|
7
|
+
# biovision_component_id [BiovisionComponent]
|
8
|
+
# caption [string], optional
|
9
|
+
# created_at [DateTime]
|
10
|
+
# image [SimpleImageUploader]
|
11
|
+
# image_alt_text [string]
|
12
|
+
# ip_address_id [IpAddress], optional
|
13
|
+
# object_count [integer]
|
14
|
+
# source_link [string], optional
|
15
|
+
# source_name [string], optional
|
16
|
+
# updated_at [DateTime]
|
17
|
+
# user_id [User], optional
|
18
|
+
# uuid [uuid]
|
19
|
+
# data [jsonb]
|
20
|
+
class SimpleImage < ApplicationRecord
|
21
|
+
include Checkable
|
22
|
+
include HasOwner
|
23
|
+
include HasTrack
|
24
|
+
include HasUuid
|
25
|
+
|
26
|
+
CAPTION_LIMIT = 255
|
27
|
+
LINK_LIMIT = 255
|
28
|
+
NAME_LIMIT = 255
|
29
|
+
META_LIMIT = 255
|
30
|
+
|
31
|
+
belongs_to :biovision_component
|
32
|
+
belongs_to :user, optional: true
|
33
|
+
|
34
|
+
validates_presence_of :image
|
35
|
+
validates_length_of :caption, maximum: CAPTION_LIMIT
|
36
|
+
validates_length_of :image_alt_text, maximum: META_LIMIT
|
37
|
+
validates_length_of :source_link, maximum: LINK_LIMIT
|
38
|
+
validates_length_of :source_name, maximum: NAME_LIMIT
|
39
|
+
|
40
|
+
def self.entity_parameters
|
41
|
+
%i[caption image image_alt_text source_link source_name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def name
|
45
|
+
caption.blank? ? File.basename(image.path) : caption
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Tag for simple image
|
4
|
+
#
|
5
|
+
# Attributes:
|
6
|
+
# created_at [DateTime]
|
7
|
+
# name [string]
|
8
|
+
# simple_images_count [integer]
|
9
|
+
# updated_at [DateTime]
|
10
|
+
class SimpleImageTag < ApplicationRecord
|
11
|
+
include Checkable
|
12
|
+
NAME_LIMIT = 100
|
13
|
+
|
14
|
+
has_many :simple_image_tag_images, dependent: :delete_all
|
15
|
+
|
16
|
+
before_validation :normalize_name
|
17
|
+
validates_uniqueness_of :name, case_sensitive: false
|
18
|
+
|
19
|
+
scope :list_for_administration, -> { order('name asc') }
|
20
|
+
|
21
|
+
def self.entity_parameters
|
22
|
+
%i[name]
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def normalize_name
|
28
|
+
self.name = name.to_s[0..NAME_LIMIT]
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Link between simple image and tag
|
4
|
+
#
|
5
|
+
# Attributes:
|
6
|
+
# simple_image_id [SimpleImage]
|
7
|
+
# simple_image_tag_id [SimpleImageTag]
|
8
|
+
class SimpleImageTagImage < ApplicationRecord
|
9
|
+
belongs_to :simple_image
|
10
|
+
belongs_to :simple_image_tag, counter_cache: :simple_images_count
|
11
|
+
|
12
|
+
validates_uniqueness_of :simple_image_tag_id, scope: :simple_image_id
|
13
|
+
end
|
data/app/models/token.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Authentication token
|
4
|
+
#
|
5
|
+
# Attributes:
|
6
|
+
# active [boolean]
|
7
|
+
# agent_id [Agent], optional
|
8
|
+
# created_at [DateTime]
|
9
|
+
# ip_address_id [IpAddress], optional
|
10
|
+
# last_used [datetime]
|
11
|
+
# updated_at [DateTime]
|
12
|
+
# user_id [User]
|
13
|
+
# token [string]
|
14
|
+
class Token < ApplicationRecord
|
15
|
+
include Checkable
|
16
|
+
include HasOwner
|
17
|
+
include HasTrack
|
18
|
+
include Toggleable
|
19
|
+
|
20
|
+
TOKEN_LIMIT = 255
|
21
|
+
|
22
|
+
toggleable :active
|
23
|
+
|
24
|
+
has_secure_token
|
25
|
+
|
26
|
+
belongs_to :user
|
27
|
+
validates_uniqueness_of :token
|
28
|
+
validates_length_of :token, maximum: TOKEN_LIMIT
|
29
|
+
|
30
|
+
scope :recent, -> { order('last_used desc nulls last') }
|
31
|
+
scope :active, ->(f) { where(active: f.to_i.positive?) unless f.blank? }
|
32
|
+
scope :filtered, ->(f) { with_user_id(f[:user_id]).active(f[:active]) }
|
33
|
+
scope :list_for_administration, -> { recent }
|
34
|
+
scope :list_for_owner, ->(u) { owned_by(u).recent }
|
35
|
+
|
36
|
+
# @param [Integer] page
|
37
|
+
# @param [Hash] filter
|
38
|
+
def self.page_for_administration(page = 1, filter = {})
|
39
|
+
filtered(filter).list_for_administration.page(page)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param [User] user
|
43
|
+
# @param [Integer] page
|
44
|
+
def self.page_for_owner(user, page = 1)
|
45
|
+
list_for_owner(user).page(page)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.entity_parameters
|
49
|
+
%i[active]
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.creation_parameters
|
53
|
+
entity_parameters + %i[user_id]
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param [String] input
|
57
|
+
def self.[](input)
|
58
|
+
find_by(token: input.to_s.split(':')[1].to_s)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @param [String] input
|
62
|
+
# @param [Boolean] touch_user
|
63
|
+
def self.user_by_token(input, touch_user = false)
|
64
|
+
return if input.blank?
|
65
|
+
|
66
|
+
pair = input.split(':')
|
67
|
+
user_by_pair(pair[0], pair[1], touch_user)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param [Integer] user_id
|
71
|
+
# @param [String] token
|
72
|
+
# @param [Boolean] touch_user
|
73
|
+
def self.user_by_pair(user_id, token, touch_user = false)
|
74
|
+
instance = find_by(user_id: user_id, token: token, active: true)
|
75
|
+
return if instance.nil?
|
76
|
+
|
77
|
+
instance.update_columns(last_used: Time.now)
|
78
|
+
instance.user.update_columns(last_seen: Time.now) if touch_user
|
79
|
+
instance.user
|
80
|
+
end
|
81
|
+
|
82
|
+
def name
|
83
|
+
"[#{id}] #{user.profile_name}"
|
84
|
+
end
|
85
|
+
|
86
|
+
# @param [User] user
|
87
|
+
def editable_by?(user)
|
88
|
+
return true if owned_by?(user)
|
89
|
+
|
90
|
+
Biovision::Components::UsersComponent[user].allow?('edit')
|
91
|
+
end
|
92
|
+
|
93
|
+
def cookie_pair
|
94
|
+
"#{user_id}:#{token}"
|
95
|
+
end
|
96
|
+
end
|
data/app/models/user.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# User
|
4
|
+
#
|
5
|
+
# Attributes:
|
6
|
+
# agent_id [Agent], optional
|
7
|
+
# allow_mail [boolean]
|
8
|
+
# balance [integer]
|
9
|
+
# banned [boolean]
|
10
|
+
# birthday [date], optional
|
11
|
+
# bot [boolean]
|
12
|
+
# consent [boolean]
|
13
|
+
# created_at [DateTime]
|
14
|
+
# data [jsonb]
|
15
|
+
# deleted [boolean]
|
16
|
+
# email [string], optional
|
17
|
+
# email_confirmed [boolean]
|
18
|
+
# image [UserImageUploader]
|
19
|
+
# inviter_id [User], optional
|
20
|
+
# ip_address_id [IpAddress], optional
|
21
|
+
# language_id [Language], optional
|
22
|
+
# last_seen [datetime], optional
|
23
|
+
# notice [string], optional
|
24
|
+
# password_digest [string]
|
25
|
+
# phone_confirmed [boolean]
|
26
|
+
# primary_id [User], optional
|
27
|
+
# screen_name [string]
|
28
|
+
# slug [string]
|
29
|
+
# super_user [boolean]
|
30
|
+
# phone [string], optional
|
31
|
+
# referral_link [string]
|
32
|
+
# updated_at [DateTime]
|
33
|
+
# uuid [uuid]
|
34
|
+
class User < ApplicationRecord
|
35
|
+
include Checkable
|
36
|
+
include HasLanguage
|
37
|
+
include HasSimpleImage
|
38
|
+
include HasTrack
|
39
|
+
include HasUuid
|
40
|
+
include Toggleable
|
41
|
+
|
42
|
+
EMAIL_LIMIT = 250
|
43
|
+
EMAIL_PATTERN = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z0-9][-a-z0-9]+)\z/i.freeze
|
44
|
+
NOTICE_LIMIT = 255
|
45
|
+
PHONE_LIMIT = 50
|
46
|
+
SLUG_LIMIT = 250
|
47
|
+
|
48
|
+
toggleable :banned, :allow_mail, :email_confirmed, :phone_confirmed
|
49
|
+
|
50
|
+
has_secure_password
|
51
|
+
mount_uploader :image, UserImageUploader
|
52
|
+
|
53
|
+
belongs_to :inviter, class_name: User.to_s, optional: true
|
54
|
+
has_many :invitees, class_name: User.to_s, foreign_key: :inviter_id, dependent: :nullify
|
55
|
+
has_many :tokens, dependent: :delete_all
|
56
|
+
has_many :codes, dependent: :delete_all
|
57
|
+
has_many :foreign_users, dependent: :delete_all
|
58
|
+
has_many :login_attempts, dependent: :delete_all
|
59
|
+
has_many :user_languages, dependent: :delete_all
|
60
|
+
|
61
|
+
before_validation :normalize_slug
|
62
|
+
|
63
|
+
validates_acceptance_of :consent
|
64
|
+
validates_presence_of :screen_name
|
65
|
+
validates_format_of :email, with: EMAIL_PATTERN, allow_blank: true
|
66
|
+
validates :screen_name, uniqueness: { case_sensitive: false }
|
67
|
+
validates :email, uniqueness: { case_sensitive: false }, allow_nil: true
|
68
|
+
validates_length_of :slug, maximum: SLUG_LIMIT
|
69
|
+
validates_length_of :screen_name, maximum: SLUG_LIMIT
|
70
|
+
validates_length_of :email, maximum: EMAIL_LIMIT
|
71
|
+
validates_length_of :phone, maximum: PHONE_LIMIT
|
72
|
+
validates_length_of :notice, maximum: NOTICE_LIMIT
|
73
|
+
|
74
|
+
scope :bots, ->(f) { where(bot: f.to_i.positive?) unless f.blank? }
|
75
|
+
scope :email_like, ->(v) { where('email ilike ?', "%#{v}%") unless v.blank? }
|
76
|
+
scope :with_email, ->(v) { where('lower(email) = lower(?)', v) }
|
77
|
+
|
78
|
+
def self.profile_parameters
|
79
|
+
%i[image allow_mail birthday consent]
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.sensitive_parameters
|
83
|
+
%i[email phone password password_confirmation]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Параметры при регистрации
|
87
|
+
def self.new_profile_parameters
|
88
|
+
profile_parameters + sensitive_parameters + %i[screen_name]
|
89
|
+
end
|
90
|
+
|
91
|
+
# Administrative parameters
|
92
|
+
def self.entity_parameters
|
93
|
+
flags = %i[banned bot email_confirmed phone_confirmed foreign_slug]
|
94
|
+
|
95
|
+
new_profile_parameters + flags + %i[screen_name notice balance]
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.ids_range
|
99
|
+
min = User.minimum(:id).to_i
|
100
|
+
max = User.maximum(:id).to_i
|
101
|
+
(min..max)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Name to be shown as profile
|
105
|
+
#
|
106
|
+
# This can be redefined for cases when something other than screen name should
|
107
|
+
# be used.
|
108
|
+
#
|
109
|
+
# @return [String]
|
110
|
+
def profile_name
|
111
|
+
screen_name
|
112
|
+
end
|
113
|
+
|
114
|
+
def name_for_letter
|
115
|
+
data.dig('profile', 'name').blank? ? profile_name : data['profile']['name']
|
116
|
+
end
|
117
|
+
|
118
|
+
# @param [TrueClass|FalseClass] include_patronymic
|
119
|
+
def full_name(include_patronymic = false)
|
120
|
+
result = [name_for_letter]
|
121
|
+
result << data.dig('profile', 'patronymic').to_s.strip if include_patronymic
|
122
|
+
result << data.dig('profile', 'surname').to_s.strip
|
123
|
+
result.compact.join(' ')
|
124
|
+
end
|
125
|
+
|
126
|
+
def can_receive_letters?
|
127
|
+
allow_mail? && !email.blank?
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def normalize_slug
|
133
|
+
self.slug = screen_name.to_s if slug.nil?
|
134
|
+
self.slug = slug.to_s.downcase
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Language for user
|
4
|
+
#
|
5
|
+
# Attributes:
|
6
|
+
# created_at [DateTime]
|
7
|
+
# language_id [Language]
|
8
|
+
# updated_at [DateTime]
|
9
|
+
# user_id [User]
|
10
|
+
class UserLanguage < ApplicationRecord
|
11
|
+
include HasOwner
|
12
|
+
|
13
|
+
belongs_to :user
|
14
|
+
belongs_to :language
|
15
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Uploader for universal simple images
|
4
|
+
class SimpleImageUploader < CarrierWave::Uploader::Base
|
5
|
+
include CarrierWave::MiniMagick
|
6
|
+
|
7
|
+
storage :file
|
8
|
+
|
9
|
+
def store_dir
|
10
|
+
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{path_slug}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def default_url(*)
|
14
|
+
ActionController::Base.helpers.asset_path('biovision/placeholders/1x1.svg')
|
15
|
+
end
|
16
|
+
|
17
|
+
version :hd, if: :raster_image? do
|
18
|
+
resize_to_fit(1920, 1920)
|
19
|
+
end
|
20
|
+
|
21
|
+
version :large, from_version: :hd, if: :raster_image? do
|
22
|
+
resize_to_fit(1280, 1280)
|
23
|
+
end
|
24
|
+
|
25
|
+
version :medium, from_version: :large, if: :raster_image? do
|
26
|
+
resize_to_fit(640, 640)
|
27
|
+
end
|
28
|
+
|
29
|
+
version :small, from_version: :medium, if: :raster_image? do
|
30
|
+
resize_to_fit(320, 320)
|
31
|
+
end
|
32
|
+
|
33
|
+
version :preview, from_version: :small, if: :raster_image? do
|
34
|
+
resize_to_fit(160, 160)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Add a white list of extensions which are allowed to be uploaded.
|
38
|
+
# For images you might use something like this:
|
39
|
+
def extension_whitelist
|
40
|
+
%w[jpg jpeg png svg svgz]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Text for image alt attribute
|
44
|
+
#
|
45
|
+
# @param [String] default
|
46
|
+
# @return [String]
|
47
|
+
def alt_text(default = '')
|
48
|
+
method_name = "#{mounted_as}_alt_text".to_sym
|
49
|
+
if model.respond_to?(method_name)
|
50
|
+
model.send(method_name)
|
51
|
+
else
|
52
|
+
default
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param [SanitizedFile]
|
57
|
+
def raster_image?(new_file)
|
58
|
+
!new_file.extension.match?(/svgz?\z/i)
|
59
|
+
end
|
60
|
+
|
61
|
+
def raster?
|
62
|
+
!File.extname(path).match?(/\.svgz?\z/i)
|
63
|
+
end
|
64
|
+
|
65
|
+
def preview_url
|
66
|
+
raster? ? preview.url : url
|
67
|
+
end
|
68
|
+
|
69
|
+
def small_url
|
70
|
+
raster? ? small.url : url
|
71
|
+
end
|
72
|
+
|
73
|
+
def medium_url
|
74
|
+
raster? ? medium.url : url
|
75
|
+
end
|
76
|
+
|
77
|
+
def large_url
|
78
|
+
raster? ? large.url : url
|
79
|
+
end
|
80
|
+
|
81
|
+
def hd_url
|
82
|
+
raster? ? hd.url : url
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def path_slug
|
88
|
+
if model.respond_to?(:uuid)
|
89
|
+
uuid = model&.uuid.to_s
|
90
|
+
"#{uuid[0..2]}/#{uuid[3..5]}/#{uuid[6..7]}/#{uuid}"
|
91
|
+
else
|
92
|
+
id = model&.id.to_i
|
93
|
+
"#{id / 1000}/#{id}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|