Files
nairobi/app/models/setting.rb
Senén Rodero Rodríguez f8835debae Move logic from key definition to views
Before this change, two important things depend on the format of each key,
where to render it in the administration panel and which kind of interface
to use for each setting. Following this strategy led us to a very complex
code, very difficult to maintain or modify. So, we do not want to depend
on the setting key structure anymore to decide how or where to render each
setting.

With this commit, we get rid of the key format-based rules. Now we render
each setting explicitly passing to it the type and the tab where it belongs.
2024-01-25 18:29:38 +01:00

224 lines
7.7 KiB
Ruby

class Setting < ApplicationRecord
validates :key, presence: true, uniqueness: true
default_scope { order(id: :asc) }
def prefix
key.split(".").first
end
def enabled?
value.present?
end
def content_type_group
key.split(".").second
end
class << self
def [](key)
where(key: key).pick(:value).presence
end
def []=(key, value)
setting = find_by(key: key) || new(key: key)
setting.value = value.presence
setting.save!
end
def rename_key(from:, to:)
if where(key: to).empty?
value = where(key: from).pick(:value).presence
create!(key: to, value: value)
end
remove(from)
end
def remove(key)
setting = find_by(key: key)
setting.destroy if setting.present?
end
def accepted_content_types_for(group)
mime_content_types = Setting["uploads.#{group}.content_types"]&.split(" ") || []
Setting.mime_types[group].select { |_, content_type| mime_content_types.include?(content_type) }.keys
end
def mime_types
{
"images" => {
"jpg" => "image/jpeg",
"png" => "image/png",
"gif" => "image/gif"
},
"documents" => {
"pdf" => "application/pdf",
"doc" => "application/msword",
"docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"xls" => "application/x-ole-storage",
"xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"csv" => "text/plain",
"zip" => "application/zip"
}
}
end
def defaults
{
"feature.featured_proposals": nil,
"feature.facebook_login": true,
"feature.google_login": true,
"feature.twitter_login": true,
"feature.wordpress_login": false,
"feature.public_stats": true,
"feature.signature_sheets": true,
"feature.user.recommendations": true,
"feature.user.recommendations_on_debates": true,
"feature.user.recommendations_on_proposals": true,
"feature.user.skip_verification": "true",
"feature.community": true,
"feature.map": nil,
"feature.allow_attached_documents": true,
"feature.allow_images": true,
"feature.help_page": true,
"feature.remote_translations": nil,
"feature.translation_interface": nil,
"feature.remote_census": nil,
"feature.valuation_comment_notification": true,
"feature.graphql_api": true,
"feature.sdg": true,
"feature.machine_learning": false,
"feature.remove_investments_supports": true,
"homepage.widgets.feeds.debates": true,
"homepage.widgets.feeds.processes": true,
"homepage.widgets.feeds.proposals": true,
# Code to be included at the top (inside <body>) of every page
"html.per_page_code_body": "",
# Code to be included at the top (inside <head>) of every page (useful for tracking)
"html.per_page_code_head": "",
"map.latitude": 51.48,
"map.longitude": 0.0,
"map.zoom": 10,
"process.debates": true,
"process.proposals": true,
"process.polls": true,
"process.budgets": true,
"process.legislation": true,
"proposals.successful_proposal_id": nil,
"proposals.poll_short_title": nil,
"proposals.poll_description": nil,
"proposals.poll_link": nil,
"proposals.email_short_title": nil,
"proposals.email_description": nil,
"proposals.poster_short_title": nil,
"proposals.poster_description": nil,
# Images and Documents
"uploads.images.title.min_length": 4,
"uploads.images.title.max_length": 80,
"uploads.images.min_width": 0,
"uploads.images.min_height": 475,
"uploads.images.max_size": 1,
"uploads.images.content_types": "image/jpeg",
"uploads.documents.max_amount": 3,
"uploads.documents.max_size": 3,
"uploads.documents.content_types": "application/pdf",
# Names for the moderation console, as a hint for moderators
# to know better how to assign users with official positions
"official_level_1_name": I18n.t("seeds.settings.official_level_1_name"),
"official_level_2_name": I18n.t("seeds.settings.official_level_2_name"),
"official_level_3_name": I18n.t("seeds.settings.official_level_3_name"),
"official_level_4_name": I18n.t("seeds.settings.official_level_4_name"),
"official_level_5_name": I18n.t("seeds.settings.official_level_5_name"),
"max_ratio_anon_votes_on_debates": 50,
"max_votes_for_debate_edit": 1000,
"max_votes_for_proposal_edit": 1000,
"comments_body_max_length": 1000,
"proposal_code_prefix": "CONSUL",
"votes_for_proposal_success": 10000,
"months_to_archive_proposals": 12,
# Users with this email domain will automatically be marked as level 1 officials
# Emails under the domain's subdomains will also be included
"email_domain_for_officials": "",
"facebook_handle": nil,
"instagram_handle": nil,
"telegram_handle": nil,
"twitter_handle": nil,
"twitter_hashtag": nil,
"youtube_handle": nil,
"org_name": default_org_name,
"meta_title": nil,
"meta_description": nil,
"meta_keywords": nil,
"proposal_notification_minimum_interval_in_days": 3,
"direct_message_max_per_day": 3,
"mailer_from_name": default_org_name,
"mailer_from_address": default_mailer_from_address,
"min_age_to_participate": 16,
"hot_score_period_in_days": 31,
"related_content_score_threshold": -0.3,
"featured_proposals_number": 3,
"feature.dashboard.notification_emails": nil,
"machine_learning.comments_summary": false,
"machine_learning.related_content": false,
"machine_learning.tags": false,
"postal_codes": "",
"remote_census.general.endpoint": "",
"remote_census.request.method_name": "",
"remote_census.request.structure": "",
"remote_census.request.document_type": "",
"remote_census.request.document_number": "",
"remote_census.request.date_of_birth": "",
"remote_census.request.postal_code": "",
"remote_census.response.date_of_birth": "",
"remote_census.response.postal_code": "",
"remote_census.response.district": "",
"remote_census.response.gender": "",
"remote_census.response.name": "",
"remote_census.response.surname": "",
"remote_census.response.valid": "",
"sdg.process.debates": true,
"sdg.process.proposals": true,
"sdg.process.polls": true,
"sdg.process.budgets": true,
"sdg.process.legislation": true
}
end
def default_org_name
Tenant.current&.name || default_main_org_name
end
def default_main_org_name
"CONSUL DEMOCRACY"
end
def default_mailer_from_address
"noreply@#{Tenant.current_host.presence || "consuldemocracy.dev"}"
end
def reset_defaults
defaults.each { |name, value| self[name] = value }
end
def add_new_settings
defaults.each do |name, value|
self[name] = value unless find_by(key: name)
end
end
def force_presence_date_of_birth?
Setting["feature.remote_census"].present? &&
Setting["remote_census.request.date_of_birth"].present?
end
def force_presence_postal_code?
Setting["feature.remote_census"].present? &&
Setting["remote_census.request.postal_code"].present?
end
def archived_proposals_date_limit
Setting["months_to_archive_proposals"].to_i.months.ago
end
end
end