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:
Eugen Rochko 2017-09-14 00:04:30 +02:00 committed by GitHub
parent 06f26e09b4
commit 9239e4ce4d
16 changed files with 123 additions and 28 deletions

View File

@ -14,6 +14,7 @@ module Admin
open_deletion open_deletion
timeline_preview timeline_preview
bootstrap_timeline_accounts bootstrap_timeline_accounts
thumbnail
).freeze ).freeze
BOOLEAN_SETTINGS = %w( BOOLEAN_SETTINGS = %w(
@ -22,15 +23,24 @@ module Admin
timeline_preview timeline_preview
).freeze ).freeze
UPLOAD_SETTINGS = %w(
thumbnail
).freeze
def edit def edit
@admin_settings = Form::AdminSettings.new @admin_settings = Form::AdminSettings.new
end end
def update def update
settings_params.each do |key, value| settings_params.each do |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 = Setting.where(var: key).first_or_initialize(var: key)
setting.update(value: value_for_update(key, value)) setting.update(value: value_for_update(key, value))
end end
end
flash[:notice] = I18n.t('generic.changes_saved_msg') flash[:notice] = I18n.t('generic.changes_saved_msg')
redirect_to edit_admin_settings_path redirect_to edit_admin_settings_path

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

44
app/models/site_upload.rb Normal file
View 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

View File

@ -35,4 +35,8 @@ class InstancePresenter
def source_url def source_url
Mastodon::Version.source_url Mastodon::Version.source_url
end end
def thumbnail
@thumbnail ||= Rails.cache.fetch('site_uploads/thumbnail') { SiteUpload.find_by(var: 'thumbnail') }
end
end end

View File

@ -1,8 +1,10 @@
# frozen_string_literal: true # frozen_string_literal: true
class REST::InstanceSerializer < ActiveModel::Serializer class REST::InstanceSerializer < ActiveModel::Serializer
include RoutingHelper
attributes :uri, :title, :description, :email, attributes :uri, :title, :description, :email,
:version, :urls, :stats :version, :urls, :stats, :thumbnail
def uri def uri
Rails.configuration.x.local_domain Rails.configuration.x.local_domain
@ -24,6 +26,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer
Mastodon::Version.to_s Mastodon::Version.to_s
end end
def thumbnail
full_asset_url(instance_presenter.thumbnail.file.url) if instance_presenter.thumbnail
end
def stats def stats
{ {
user_count: instance_presenter.user_count, user_count: instance_presenter.user_count,

View 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'

View File

@ -3,16 +3,7 @@
- content_for :header_tags do - content_for :header_tags do
= javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous' = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
= render partial: 'og'
%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' }/
.landing-page .landing-page
.header-wrapper.compact .header-wrapper.compact

View File

@ -4,16 +4,7 @@
- content_for :header_tags do - content_for :header_tags do
%script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json) %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
= javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous' = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
= render partial: 'og'
%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' }/
.landing-page .landing-page
.header-wrapper .header-wrapper

View File

@ -10,6 +10,11 @@
%hr/ %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 .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') = f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html')

View File

@ -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 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 title: Custom terms of service
site_title: Instance name site_title: Instance name
thumbnail:
desc_html: Used for previews via OpenGraph and API. 1200x630px recommended
title: Instance thumbnail
timeline_preview: timeline_preview:
desc_html: Display public timeline on landing page desc_html: Display public timeline on landing page
title: Timeline preview title: Timeline preview

View 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

View File

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # 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 # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" 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 t.index ["thing_type", "thing_id", "var"], name: "index_settings_on_thing_type_and_thing_id_and_var", unique: true
end 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| create_table "status_pins", force: :cascade do |t|
t.bigint "account_id", null: false t.bigint "account_id", null: false
t.bigint "status_id", null: false t.bigint "status_id", null: false

View File

@ -0,0 +1,3 @@
Fabricator(:site_upload) do
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe SiteUpload, type: :model do
end

View File

@ -15,15 +15,16 @@ describe 'about/show.html.haml', without_verify_partial_doubles: true do
version_number: '1.0', version_number: '1.0',
source_url: 'https://github.com/tootsuite/mastodon', source_url: 'https://github.com/tootsuite/mastodon',
open_registrations: false, open_registrations: false,
thumbnail: nil,
closed_registrations_message: 'yes') closed_registrations_message: 'yes')
assign(:instance_presenter, instance_presenter) assign(:instance_presenter, instance_presenter)
render render
header_tags = view.content_for(:header_tags) 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=".+" property="og:title" />})
expect(header_tags).to match(%r{<meta content='website' property='og:type'>}) 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=".+" property="og:image" />})
expect(header_tags).to match(%r{<meta content='http://.+' property='og:url'>}) expect(header_tags).to match(%r{<meta content="http://.+" property="og:url" />})
end end
end end