Uploads for admin site settings (#4913)
* Improve OpenGraph tags for about pages * Add thumbnail admin setting * Fix error * Fix up
This commit is contained in:
		| @@ -14,6 +14,7 @@ module Admin | ||||
|       open_deletion | ||||
|       timeline_preview | ||||
|       bootstrap_timeline_accounts | ||||
|       thumbnail | ||||
|     ).freeze | ||||
|  | ||||
|     BOOLEAN_SETTINGS = %w( | ||||
| @@ -22,14 +23,23 @@ module Admin | ||||
|       timeline_preview | ||||
|     ).freeze | ||||
|  | ||||
|     UPLOAD_SETTINGS = %w( | ||||
|       thumbnail | ||||
|     ).freeze | ||||
|  | ||||
|     def edit | ||||
|       @admin_settings = Form::AdminSettings.new | ||||
|     end | ||||
|  | ||||
|     def update | ||||
|       settings_params.each do |key, value| | ||||
|         setting = Setting.where(var: key).first_or_initialize(var: key) | ||||
|         setting.update(value: value_for_update(key, value)) | ||||
|         if UPLOAD_SETTINGS.include?(key) | ||||
|           upload = SiteUpload.where(var: key).first_or_initialize(var: key) | ||||
|           upload.update(file: value) | ||||
|         else | ||||
|           setting = Setting.where(var: key).first_or_initialize(var: key) | ||||
|           setting.update(value: value_for_update(key, value)) | ||||
|         end | ||||
|       end | ||||
|  | ||||
|       flash[:notice] = I18n.t('generic.changes_saved_msg') | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 25 KiB | 
							
								
								
									
										
											BIN
										
									
								
								app/javascript/images/preview.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/javascript/images/preview.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 285 KiB | 
							
								
								
									
										44
									
								
								app/models/site_upload.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/models/site_upload.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| # frozen_string_literal: true | ||||
| # == Schema Information | ||||
| # | ||||
| # Table name: site_uploads | ||||
| # | ||||
| #  id                :integer          not null, primary key | ||||
| #  var               :string           default(""), not null | ||||
| #  file_file_name    :string | ||||
| #  file_content_type :string | ||||
| #  file_file_size    :integer | ||||
| #  file_updated_at   :datetime | ||||
| #  meta              :json | ||||
| #  created_at        :datetime         not null | ||||
| #  updated_at        :datetime         not null | ||||
| # | ||||
|  | ||||
| class SiteUpload < ApplicationRecord | ||||
|   has_attached_file :file | ||||
|  | ||||
|   validates_attachment_content_type :file, content_type: /\Aimage\/.*\z/ | ||||
|   validates :var, presence: true, uniqueness: true | ||||
|  | ||||
|   before_save :set_meta | ||||
|   after_commit :clear_cache | ||||
|  | ||||
|   def cache_key | ||||
|     "site_uploads/#{var}" | ||||
|   end | ||||
|  | ||||
|   private | ||||
|  | ||||
|   def set_meta | ||||
|     tempfile = file.queued_for_write[:original] | ||||
|  | ||||
|     return if tempfile.nil? | ||||
|  | ||||
|     geometry  = Paperclip::Geometry.from_file(tempfile) | ||||
|     self.meta = { width: geometry.width.to_i, height: geometry.height.to_i } | ||||
|   end | ||||
|  | ||||
|   def clear_cache | ||||
|     Rails.cache.delete(cache_key) | ||||
|   end | ||||
| end | ||||
| @@ -35,4 +35,8 @@ class InstancePresenter | ||||
|   def source_url | ||||
|     Mastodon::Version.source_url | ||||
|   end | ||||
|  | ||||
|   def thumbnail | ||||
|     @thumbnail ||= Rails.cache.fetch('site_uploads/thumbnail') { SiteUpload.find_by(var: 'thumbnail') } | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| # frozen_string_literal: true | ||||
|  | ||||
| class REST::InstanceSerializer < ActiveModel::Serializer | ||||
|   include RoutingHelper | ||||
|  | ||||
|   attributes :uri, :title, :description, :email, | ||||
|              :version, :urls, :stats | ||||
|              :version, :urls, :stats, :thumbnail | ||||
|  | ||||
|   def uri | ||||
|     Rails.configuration.x.local_domain | ||||
| @@ -24,6 +26,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer | ||||
|     Mastodon::Version.to_s | ||||
|   end | ||||
|  | ||||
|   def thumbnail | ||||
|     full_asset_url(instance_presenter.thumbnail.file.url) if instance_presenter.thumbnail | ||||
|   end | ||||
|  | ||||
|   def stats | ||||
|     { | ||||
|       user_count: instance_presenter.user_count, | ||||
|   | ||||
							
								
								
									
										10
									
								
								app/views/about/_og.html.haml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/views/about/_og.html.haml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| - thumbnail = @instance_presenter.thumbnail | ||||
| = opengraph 'og:site_name', t('about.hosted_on', domain: site_hostname) | ||||
| = opengraph 'og:url', about_url | ||||
| = opengraph 'og:type', 'website' | ||||
| = opengraph 'og:title', @instance_presenter.site_title | ||||
| = opengraph 'og:description', strip_tags(@instance_presenter.site_description.presence || t('about.about_mastodon_html')) | ||||
| = opengraph 'og:image', full_asset_url(thumbnail&.file&.url || asset_pack_path('preview.jpg', protocol: :request)) | ||||
| = opengraph 'og:image:width', thumbnail ? thumbnail.meta['width'] : '1200' | ||||
| = opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630' | ||||
| = opengraph 'twitter:card', 'summary_large_image' | ||||
| @@ -3,16 +3,7 @@ | ||||
|  | ||||
| - content_for :header_tags do | ||||
|   = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous' | ||||
|  | ||||
|   %meta{ property: 'og:site_name', content: site_title }/ | ||||
|   %meta{ property: 'og:url', content: about_url }/ | ||||
|   %meta{ property: 'og:type', content: 'website' }/ | ||||
|   %meta{ property: 'og:title', content: site_hostname }/ | ||||
|   %meta{ property: 'og:description', content: strip_tags(@instance_presenter.site_description.presence || t('about.about_mastodon_html')) }/ | ||||
|   %meta{ property: 'og:image', content: asset_pack_path('mastodon_small.jpg', protocol: :request) }/ | ||||
|   %meta{ property: 'og:image:width', content: '400' }/ | ||||
|   %meta{ property: 'og:image:height', content: '400' }/ | ||||
|   %meta{ property: 'twitter:card', content: 'summary' }/ | ||||
|   = render partial: 'og' | ||||
|  | ||||
| .landing-page | ||||
|   .header-wrapper.compact | ||||
|   | ||||
| @@ -4,16 +4,7 @@ | ||||
| - content_for :header_tags do | ||||
|   %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json) | ||||
|   = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous' | ||||
|  | ||||
|   %meta{ property: 'og:site_name', content: site_title }/ | ||||
|   %meta{ property: 'og:url', content: about_url }/ | ||||
|   %meta{ property: 'og:type', content: 'website' }/ | ||||
|   %meta{ property: 'og:title', content: site_hostname }/ | ||||
|   %meta{ property: 'og:description', content: strip_tags(@instance_presenter.site_description.presence || t('about.about_mastodon_html')) }/ | ||||
|   %meta{ property: 'og:image', content: asset_pack_path('mastodon_small.jpg', protocol: :request) }/ | ||||
|   %meta{ property: 'og:image:width', content: '400' }/ | ||||
|   %meta{ property: 'og:image:height', content: '400' }/ | ||||
|   %meta{ property: 'twitter:card', content: 'summary' }/ | ||||
|   = render partial: 'og' | ||||
|  | ||||
| .landing-page | ||||
|   .header-wrapper | ||||
|   | ||||
| @@ -10,6 +10,11 @@ | ||||
|  | ||||
|   %hr/ | ||||
|  | ||||
|   .fields-group | ||||
|     = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: t('admin.settings.thumbnail.desc_html') | ||||
|  | ||||
|   %hr/ | ||||
|  | ||||
|   .fields-group | ||||
|     = f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html') | ||||
|  | ||||
|   | ||||
| @@ -195,6 +195,9 @@ en: | ||||
|         desc_html: You can write your own privacy policy, terms of service or other legalese. You can use HTML tags | ||||
|         title: Custom terms of service | ||||
|       site_title: Instance name | ||||
|       thumbnail: | ||||
|         desc_html: Used for previews via OpenGraph and API. 1200x630px recommended | ||||
|         title: Instance thumbnail | ||||
|       timeline_preview: | ||||
|         desc_html: Display public timeline on landing page | ||||
|         title: Timeline preview | ||||
|   | ||||
							
								
								
									
										10
									
								
								db/migrate/20170913000752_create_site_uploads.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								db/migrate/20170913000752_create_site_uploads.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| class CreateSiteUploads < ActiveRecord::Migration[5.1] | ||||
|   def change | ||||
|     create_table :site_uploads do |t| | ||||
|       t.string :var, default: '', null: false, index: { unique: true } | ||||
|       t.attachment :file | ||||
|       t.json :meta | ||||
|       t.timestamps | ||||
|     end | ||||
|   end | ||||
| end | ||||
							
								
								
									
										14
									
								
								db/schema.rb
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								db/schema.rb
									
									
									
									
									
								
							| @@ -10,7 +10,7 @@ | ||||
| # | ||||
| # It's strongly recommended that you check this file into your version control system. | ||||
|  | ||||
| ActiveRecord::Schema.define(version: 20170905165803) do | ||||
| ActiveRecord::Schema.define(version: 20170913000752) do | ||||
|  | ||||
|   # These are extensions that must be enabled in order to support this database | ||||
|   enable_extension "plpgsql" | ||||
| @@ -288,6 +288,18 @@ ActiveRecord::Schema.define(version: 20170905165803) do | ||||
|     t.index ["thing_type", "thing_id", "var"], name: "index_settings_on_thing_type_and_thing_id_and_var", unique: true | ||||
|   end | ||||
|  | ||||
|   create_table "site_uploads", force: :cascade do |t| | ||||
|     t.string "var", default: "", null: false | ||||
|     t.string "file_file_name" | ||||
|     t.string "file_content_type" | ||||
|     t.integer "file_file_size" | ||||
|     t.datetime "file_updated_at" | ||||
|     t.json "meta" | ||||
|     t.datetime "created_at", null: false | ||||
|     t.datetime "updated_at", null: false | ||||
|     t.index ["var"], name: "index_site_uploads_on_var", unique: true | ||||
|   end | ||||
|  | ||||
|   create_table "status_pins", force: :cascade do |t| | ||||
|     t.bigint "account_id", null: false | ||||
|     t.bigint "status_id", null: false | ||||
|   | ||||
							
								
								
									
										3
									
								
								spec/fabricators/site_upload_fabricator.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								spec/fabricators/site_upload_fabricator.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| Fabricator(:site_upload) do | ||||
|  | ||||
| end | ||||
							
								
								
									
										5
									
								
								spec/models/site_upload_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								spec/models/site_upload_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| require 'rails_helper' | ||||
|  | ||||
| RSpec.describe SiteUpload, type: :model do | ||||
|  | ||||
| end | ||||
| @@ -15,15 +15,16 @@ describe 'about/show.html.haml', without_verify_partial_doubles: true do | ||||
|                                 version_number: '1.0', | ||||
|                                 source_url: 'https://github.com/tootsuite/mastodon', | ||||
|                                 open_registrations: false, | ||||
|                                 thumbnail: nil, | ||||
|                                 closed_registrations_message: 'yes') | ||||
|     assign(:instance_presenter, instance_presenter) | ||||
|     render | ||||
|  | ||||
|     header_tags = view.content_for(:header_tags) | ||||
|  | ||||
|     expect(header_tags).to match(%r{<meta content='.+' property='og:title'>}) | ||||
|     expect(header_tags).to match(%r{<meta content='website' property='og:type'>}) | ||||
|     expect(header_tags).to match(%r{<meta content='.+' property='og:image'>}) | ||||
|     expect(header_tags).to match(%r{<meta content='http://.+' property='og:url'>}) | ||||
|     expect(header_tags).to match(%r{<meta content=".+" property="og:title" />}) | ||||
|     expect(header_tags).to match(%r{<meta content="website" property="og:type" />}) | ||||
|     expect(header_tags).to match(%r{<meta content=".+" property="og:image" />}) | ||||
|     expect(header_tags).to match(%r{<meta content="http://.+" property="og:url" />}) | ||||
|   end | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user