diff --git a/.env.test b/.env.test index 5c939e805..d479be1ac 100644 --- a/.env.test +++ b/.env.test @@ -8,8 +8,8 @@ call_tool_api_key=xyz storage=s3 amazon_region=us-west-1 -amazon_bucket=actioncenter-staging -amazon_bucket_url=actioncentertest.s3-us-west-1.amazonaws.com +amazon_bucket=actioncenter-test +amazon_bucket_url=actioncenter-testurl.s3-us-west-1.amazonaws.com supporters_api_key=xyz supporters_host=https://civicrm.test diff --git a/.gitignore b/.gitignore index 156f76604..a3e9e0020 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ public/webshims # Ignore dotenv file /.env +/public/uploads diff --git a/Gemfile b/Gemfile index 1549c9190..be69a65e8 100644 --- a/Gemfile +++ b/Gemfile @@ -42,7 +42,8 @@ source "https://rails-assets.org" do end # File upload -gem "kt-paperclip", "~> 6" +gem "carrierwave", "~> 3.0" +gem "fog-aws" # Email preformatting gem "nokogiri", "~> 1" # Required for premailer-rails diff --git a/Gemfile.lock b/Gemfile.lock index 4de5d5578..eb9831e82 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -152,10 +152,16 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) + carrierwave (3.0.7) + activemodel (>= 6.0.0) + activesupport (>= 6.0.0) + addressable (~> 2.6) + image_processing (~> 1.1) + marcel (~> 1.0.0) + ssrf_filter (~> 1.0) cgi (0.4.1) chartkick (3.4.2) chronic (0.10.2) - climate_control (0.2.0) cocoon (1.2.15) concurrent-ruby (1.2.3) connection_pool (2.4.1) @@ -196,6 +202,7 @@ GEM email_validator (1.6.0) activemodel erubi (1.12.0) + excon (0.110.0) execjs (2.9.1) factory_bot (6.2.1) activesupport (>= 5.0.0) @@ -211,6 +218,22 @@ GEM activerecord (>= 4.1.0) fastly (2.5.3) ffi (1.16.2) + fog-aws (3.22.0) + fog-core (~> 2.1) + fog-json (~> 1.1) + fog-xml (~> 0.1) + fog-core (2.4.0) + builder + excon (~> 0.71) + formatador (>= 0.2, < 2.0) + mime-types + fog-json (1.2.0) + fog-core + multi_json (~> 1.10) + fog-xml (0.1.4) + fog-core + nokogiri (>= 1.5.11, < 2.0.0) + formatador (1.1.0) friendly_id (5.5.0) activerecord (>= 4.0.0) geocoder (1.8.2) @@ -234,6 +257,9 @@ GEM multi_xml (>= 0.5.2) i18n (1.14.1) concurrent-ruby (~> 1.0) + image_processing (1.12.2) + mini_magick (>= 4.9.5, < 5) + ruby-vips (>= 2.0.17, < 3) invisible_captcha (0.13.0) rails (>= 3.2.0) iso_country_codes (0.7.8) @@ -242,12 +268,6 @@ GEM activesupport (>= 5.0.0) jmespath (1.6.2) json (2.6.3) - kt-paperclip (6.4.2) - activemodel (>= 4.2.0) - activesupport (>= 4.2.0) - mime-types - mimemagic (~> 0.3.0) - terrapin (~> 0.6.0) language_server-protocol (3.17.0.3) loofah (2.22.0) crass (~> 1.0.2) @@ -263,9 +283,7 @@ GEM mime-types (3.5.1) mime-types-data (~> 3.2015) mime-types-data (3.2023.0808) - mimemagic (0.3.10) - nokogiri (~> 1) - rake + mini_magick (4.12.0) mini_mime (1.1.5) mini_portile2 (2.8.5) minitest (5.22.2) @@ -414,6 +432,8 @@ GEM rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) ruby-progressbar (1.13.0) + ruby-vips (2.2.1) + ffi (~> 1.12) ruby2_keywords (0.0.5) rubyzip (2.3.2) safely_block (0.4.0) @@ -454,8 +474,7 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - terrapin (0.6.0) - climate_control (>= 0.0.3, < 1.0) + ssrf_filter (1.1.2) thor (1.3.0) tilt (2.3.0) timeout (0.4.1) @@ -505,6 +524,7 @@ DEPENDENCIES bundler (>= 1.8.4) byebug capybara (~> 3) + carrierwave (~> 3.0) chartkick (~> 3) cocoon (~> 1) counter_culture (~> 2.0) @@ -519,6 +539,7 @@ DEPENDENCIES factory_bot_rails (~> 6.2) fast_inserter (~> 2.0) fastly (~> 2) + fog-aws friendly_id (~> 5.0) going_postal (~> 0) gravatar-ultimate (~> 2) @@ -527,7 +548,6 @@ DEPENDENCIES invisible_captcha (~> 0) iso_country_codes (~> 0) jbuilder (~> 2) - kt-paperclip (~> 6) nokogiri (~> 1) oauth (~> 0) pg (~> 1.1) diff --git a/app/assets/javascripts/application/gallery.js b/app/assets/javascripts/application/gallery.js index 92ead348d..1e0699e6a 100644 --- a/app/assets/javascripts/application/gallery.js +++ b/app/assets/javascripts/application/gallery.js @@ -24,9 +24,9 @@ $(function() { }); } - attachGalleryImage('#image-gallery', '#action_page_featured_image', '#attached-featured_image'); - attachGalleryImage('#image-gallery', '#action_page_background_image', '#attached-background_image'); - attachGalleryImage('#image-gallery', '#action_page_og_image', '#attached-og_image'); + attachGalleryImage('#image-gallery', '#action_page_remote_featured_image_url', '#attached-featured_image'); + attachGalleryImage('#image-gallery', '#action_page_remote_background_image_url', '#attached-background_image'); + attachGalleryImage('#image-gallery', '#action_page_remote_og_image_url', '#attached-og_image'); $('.tweet-target').each(function(i, target) { attachGalleryImage('#image-gallery', $(target).find('.image-input'), target); diff --git a/app/assets/stylesheets/action_page.scss b/app/assets/stylesheets/action_page.scss index 6ace3a726..7a30dde8c 100644 --- a/app/assets/stylesheets/action_page.scss +++ b/app/assets/stylesheets/action_page.scss @@ -1236,25 +1236,6 @@ html.js #affiliations { } } -.partner-logos { - display: flex; - align-items: center; - justify-content: space-evenly; - flex-wrap: wrap; - @media screen and (min-width: $lg) { - flex-wrap: nowrap; - } - img { - width: 100%; - height: auto; - max-width: 200px; - padding: 1em; - @media screen and (min-width: $md) { - padding: 0 1em; - } - } -} - #congress-message-create { position: relative; diff --git a/app/controllers/admin/action_pages_controller.rb b/app/controllers/admin/action_pages_controller.rb index 296a5678b..7f11f6eed 100644 --- a/app/controllers/admin/action_pages_controller.rb +++ b/app/controllers/admin/action_pages_controller.rb @@ -72,10 +72,6 @@ def edit_partners end def update - @actionPage.background_image = nil if params[:destroy_background_image] - @actionPage.featured_image = nil if params[:destroy_featured_image] - @actionPage.og_image = nil if params[:destroy_og_image] - @actionPage.update(action_page_params) if (institutions_params[:reset] && institutions_params[:reset] == "1") || (institutions_params[:category] && @actionPage.institutions.empty?) @@ -175,9 +171,9 @@ def set_partners def action_page_params params.require(:action_page).permit( - :title, :summary, :description, :category_id, :related_content_url, :featured_image, + :title, :summary, :description, :category_id, :related_content_url, :remote_featured_image_url, :enable_call, :enable_petition, :enable_email, :enable_tweet, - :enable_congress_message, :og_title, :og_image, :share_message, :published, + :enable_congress_message, :og_title, :remote_og_image_url, :share_message, :published, :call_campaign_id, :what_to_say, :redirect_url, :email_text, :enable_redirect, :victory, :victory_message, :archived_redirect_action_page_id, :archived, :status, partner_ids: [], diff --git a/app/models/action_page.rb b/app/models/action_page.rb index 6177e401a..3c1de0d97 100644 --- a/app/models/action_page.rb +++ b/app/models/action_page.rb @@ -1,5 +1,4 @@ class ActionPage < ApplicationRecord - extend AmazonCredentials extend FriendlyId include PgSearch::Model @@ -46,18 +45,10 @@ class ActionPage < ApplicationRecord :call_campaign, :congress_message_campaign, :affiliation_types, :partnerships, reject_if: :all_blank - has_attached_file :featured_image, amazon_credentials.merge(default_url: "missing.png") - has_attached_file :background_image, amazon_credentials - has_attached_file :og_image, amazon_credentials - validates_media_type_spoof_detection :featured_image, - if: -> { featured_image.present? && featured_image_file_name_came_from_user? } - validates_media_type_spoof_detection :background_image, - if: -> { background_image.present? && background_image_file_name_came_from_user? } - validates_media_type_spoof_detection :og_image, - if: -> { og_image.present? && og_image_file_name_came_from_user? } - do_not_validate_attachment_file_type %i[featured_image background_image og_image] - - # validates_length_of :og_title, maximum: 65 + mount_uploader :featured_image, ActionPageImageUploader, mount_on: :featured_image_file_name + mount_uploader :background_image, ActionPageImageUploader, mount_on: :background_image_file_name + mount_uploader :og_image, ActionPageImageUploader, mount_on: :og_image_file_name + after_save :no_drafts_on_homepage after_save :set_congress_tag, if: -> { enable_congress_message } diff --git a/app/models/partner.rb b/app/models/partner.rb index 170b0dadf..703d73799 100644 --- a/app/models/partner.rb +++ b/app/models/partner.rb @@ -1,15 +1,10 @@ class Partner < ApplicationRecord - extend AmazonCredentials acts_as_paranoid has_many :subscriptions has_many :users has_many :partnerships has_many :action_pages, through: :partnerships - has_attached_file :logo, amazon_credentials - validates_media_type_spoof_detection :logo, - if: -> { logo.present? && logo_file_name_came_from_user? } - do_not_validate_attachment_file_type [:logo] validates :code, uniqueness: true def to_csv(options = {}) diff --git a/app/models/source_file.rb b/app/models/source_file.rb index 3bc2eed72..8574ae639 100644 --- a/app/models/source_file.rb +++ b/app/models/source_file.rb @@ -41,7 +41,7 @@ def full_url if ENV["amazon_bucket_url"] "https://#{ENV['amazon_bucket_url']}/#{key}" else # we have to build the url up from amazon information - "https://#{ENV['amazon_bucket']}.#{AmazonCredentials.build_s3_host_name}/#{key}" + "https://#{ENV['amazon_bucket']}.s3-#{Rails.application.secrets.amazon_region}.amazonaws.com/#{key}" end end diff --git a/app/models/tweet_target.rb b/app/models/tweet_target.rb index 7af6dce98..bdb5d43bc 100644 --- a/app/models/tweet_target.rb +++ b/app/models/tweet_target.rb @@ -1,32 +1,7 @@ class TweetTarget < ApplicationRecord - extend AmazonCredentials - require "open-uri" - belongs_to :tweet - has_attached_file :image, amazon_credentials - validates_media_type_spoof_detection :image, if: -> { image_file_name.present? } - do_not_validate_attachment_file_type :image - after_save :attach_twitter_image def url "https://twitter.com/#{twitter_id}" end - - delegate :url, to: :image, prefix: true - - def attach_twitter_image - delay.attach_twitter_image_without_delay if image_file_name.nil? && Twitter.has_api_keys? - end - - def attach_twitter_image_without_delay - access_token = Twitter.prepare_access_token Rails.application.secrets.twitter_oauth_token, Rails.application.secrets.twitter_oauth_token_secret - - # ref: https://dev.twitter.com/overview/general/user-profile-images-and-banners - response = access_token.request(:get, "https://api.twitter.com/1.1/users/show.json?screen_name=#{twitter_id}") - user_info = JSON.parse response.body - user_image_url = user_info["profile_image_url_https"].gsub("_normal.", "_bigger.") - - self.image = URI.parse(user_image_url) - save - end end diff --git a/app/uploaders/action_page_image_uploader.rb b/app/uploaders/action_page_image_uploader.rb new file mode 100644 index 000000000..43a5ffa3d --- /dev/null +++ b/app/uploaders/action_page_image_uploader.rb @@ -0,0 +1,27 @@ +class ActionPageImageUploader < CarrierWave::Uploader::Base + storage :fog + # cache_storage :file + + def default_url(*args) + "missing.png" + end + + def store_dir + "#{model.class.to_s.pluralize.underscore}/#{mounted_as.to_s.pluralize}/#{id_partition}/#{style}" + end + + # we could set this here or config/initializers/carrier_wave.rb + def asset_host + Rails.application.secrets.amazon_bucket_url.present? ? "https://#{Rails.application.secrets.amazon_bucket_url}" : super + end + + private + + def style + version_name || "original" + end + + def id_partition # mimics paperclips mapping function + ("%09d" % model.id).scan(/\d{3}/).join("/") + end +end diff --git a/app/views/action_page/_meta_tags.html.erb b/app/views/action_page/_meta_tags.html.erb index 382706cc6..5136ff61d 100644 --- a/app/views/action_page/_meta_tags.html.erb +++ b/app/views/action_page/_meta_tags.html.erb @@ -1,7 +1,7 @@ <% summary = strip_tags stripdown(@actionPage.summary) -%> <% - image_url = if @actionPage.image.try(:exists?) - image_url(@actionPage.image.to_s) + image_url = if @actionPage.image.present? + image_url(@actionPage.image.url) else image_url("og-image-default.png") end diff --git a/app/views/action_page/_partner_logos.html.erb b/app/views/action_page/_partner_logos.html.erb deleted file mode 100644 index 250bfcb64..000000000 --- a/app/views/action_page/_partner_logos.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -<% if @actionPage.partners.present? && @actionPage.partners.any? { |p| p.logo.present? } %> -

Who We Are

-
- <%= image_tag "EFF_Monogram-red" %> - <% @actionPage.partners.each do |partner| %> - <%= image_tag partner.logo.url if partner.logo.present? %> - <% end %> -
-<% end %> diff --git a/app/views/action_page/index.atom.builder b/app/views/action_page/index.atom.builder index 20788a34a..6b300b7ae 100644 --- a/app/views/action_page/index.atom.builder +++ b/app/views/action_page/index.atom.builder @@ -5,8 +5,11 @@ atom_feed do |feed| @actionPages.each do |actionPage| feed.entry(actionPage) do |entry| - entry.link(rel: "enclosure", type: actionPage.featured_image.content_type || "image/png", - href: URI.join(root_url, image_path(actionPage.featured_image))) + entry.link( + rel: "enclosure", + type: (actionPage.featured_image.content_type.presence || "image/png"), + href: URI.join(root_url, image_path(actionPage.featured_image.url)) + ) entry.title(actionPage.title) entry.summary(markdown(actionPage.summary), type: "html") diff --git a/app/views/action_page/index.json.jbuilder b/app/views/action_page/index.json.jbuilder index 761f1f25b..db98d0fbc 100644 --- a/app/views/action_page/index.json.jbuilder +++ b/app/views/action_page/index.json.jbuilder @@ -4,7 +4,7 @@ json.array! @actionPages do |actionPage| json.summary markdown actionPage.summary if actionPage.featured_image_file_name json.featured_image do - json.alt image_alt actionPage.featured_image_file_name + json.alt actionPage.featured_image_file_name.titleize json.url image_url actionPage.featured_image end end diff --git a/app/views/action_page/show.html.erb b/app/views/action_page/show.html.erb index 8a72a51a8..52fdca997 100644 --- a/app/views/action_page/show.html.erb +++ b/app/views/action_page/show.html.erb @@ -13,8 +13,6 @@ <%= image_tag(@actionPage.featured_image.url) %> <%= markdown @actionPage.summary -%> - <%= render "action_page/partner_logos" %> - <% if @actionPage.enable_petition? && @petition && @petition.description.present? && !@actionPage.description.include?('``` letter') -%> <%= render(partial: "action_page/letter", layout: false) %> <% end -%> diff --git a/app/views/admin/action_pages/_gallery.html.erb b/app/views/admin/action_pages/_gallery.html.erb index 1bb4d0102..5022f32d7 100644 --- a/app/views/admin/action_pages/_gallery.html.erb +++ b/app/views/admin/action_pages/_gallery.html.erb @@ -1,6 +1,8 @@