mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-14 08:19:05 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e4afccd9d | ||
|
|
0876a06e45 | ||
|
|
43caf1fa5f | ||
|
|
2c0d756ad9 | ||
|
|
f06cba3f60 |
@@ -36,7 +36,8 @@ OTP_SECRET=
|
|||||||
# E-mail configuration
|
# E-mail configuration
|
||||||
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
|
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
|
||||||
# If you want to use an SMTP server without authentication (e.g local Postfix relay)
|
# If you want to use an SMTP server without authentication (e.g local Postfix relay)
|
||||||
# then set SMTP_AUTH_METHOD to 'none' and leave SMTP_LOGIN and SMTP_PASSWORD blank
|
# then set SMTP_AUTH_METHOD to 'none' and *comment* SMTP_LOGIN and SMTP_PASSWORD.
|
||||||
|
# Leaving them blank is not enough for authentication method 'none'.
|
||||||
SMTP_SERVER=smtp.mailgun.org
|
SMTP_SERVER=smtp.mailgun.org
|
||||||
SMTP_PORT=587
|
SMTP_PORT=587
|
||||||
SMTP_LOGIN=
|
SMTP_LOGIN=
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
language: ruby
|
language: ruby
|
||||||
cache: bundler
|
cache: bundler
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
@@ -24,8 +26,9 @@ bundler_args: --without development production --retry=3 --jobs=3
|
|||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
|
- sudo add-apt-repository -y ppa:mc3man/trusty-media
|
||||||
- sudo apt-get -qq update
|
- sudo apt-get -qq update
|
||||||
- sudo apt-get -qq install g++-4.8
|
- sudo apt-get -qq install g++-4.8 ffmpeg
|
||||||
install:
|
install:
|
||||||
- nvm install
|
- nvm install
|
||||||
- npm install -g yarn
|
- npm install -g yarn
|
||||||
|
|||||||
3
Gemfile
3
Gemfile
@@ -62,9 +62,6 @@ gem 'react-rails'
|
|||||||
gem 'browserify-rails'
|
gem 'browserify-rails'
|
||||||
gem 'autoprefixer-rails'
|
gem 'autoprefixer-rails'
|
||||||
|
|
||||||
gem 'skylight'
|
|
||||||
gem 'sidekiq-skylight'
|
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'rspec-rails'
|
gem 'rspec-rails'
|
||||||
gem 'pry-rails'
|
gem 'pry-rails'
|
||||||
|
|||||||
@@ -401,9 +401,6 @@ GEM
|
|||||||
connection_pool (~> 2.2, >= 2.2.0)
|
connection_pool (~> 2.2, >= 2.2.0)
|
||||||
rack-protection (>= 1.5.0)
|
rack-protection (>= 1.5.0)
|
||||||
redis (~> 3.2, >= 3.2.1)
|
redis (~> 3.2, >= 3.2.1)
|
||||||
sidekiq-skylight (0.2.0)
|
|
||||||
sidekiq (>= 3.3.0)
|
|
||||||
skylight (>= 0.5.2)
|
|
||||||
sidekiq-unique-jobs (5.0.0)
|
sidekiq-unique-jobs (5.0.0)
|
||||||
sidekiq (>= 4.0)
|
sidekiq (>= 4.0)
|
||||||
thor
|
thor
|
||||||
@@ -417,8 +414,6 @@ GEM
|
|||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
simplecov-html (~> 0.10.0)
|
simplecov-html (~> 0.10.0)
|
||||||
simplecov-html (0.10.0)
|
simplecov-html (0.10.0)
|
||||||
skylight (1.2.0)
|
|
||||||
activesupport (>= 3.0.0)
|
|
||||||
slop (3.6.0)
|
slop (3.6.0)
|
||||||
sprockets (3.7.1)
|
sprockets (3.7.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
@@ -537,12 +532,10 @@ DEPENDENCIES
|
|||||||
ruby-oembed
|
ruby-oembed
|
||||||
sass-rails (~> 5.0)
|
sass-rails (~> 5.0)
|
||||||
sidekiq
|
sidekiq
|
||||||
sidekiq-skylight
|
|
||||||
sidekiq-unique-jobs
|
sidekiq-unique-jobs
|
||||||
simple-navigation
|
simple-navigation
|
||||||
simple_form
|
simple_form
|
||||||
simplecov
|
simplecov
|
||||||
skylight
|
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
statsd-instrument
|
statsd-instrument
|
||||||
twitter-text
|
twitter-text
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ const es = {
|
|||||||
"column.community": "Historia local",
|
"column.community": "Historia local",
|
||||||
"column.public": "Historia federada",
|
"column.public": "Historia federada",
|
||||||
"column.notifications": "Notificaciones",
|
"column.notifications": "Notificaciones",
|
||||||
|
"column.blocks": "Usuarios bloqueados",
|
||||||
|
"column.favourites": "Favoritos",
|
||||||
|
"column.follow_requests": "Solicitudes para seguirte",
|
||||||
|
"column.mutes": "Usuarios silenciados",
|
||||||
"tabs_bar.compose": "Redactar",
|
"tabs_bar.compose": "Redactar",
|
||||||
"tabs_bar.home": "Inicio",
|
"tabs_bar.home": "Inicio",
|
||||||
"tabs_bar.mentions": "Menciones",
|
"tabs_bar.mentions": "Menciones",
|
||||||
@@ -56,6 +60,8 @@ const es = {
|
|||||||
"navigation_bar.blocks": "Usuarios bloqueados",
|
"navigation_bar.blocks": "Usuarios bloqueados",
|
||||||
"navigation_bar.info": "Información adicional",
|
"navigation_bar.info": "Información adicional",
|
||||||
"navigation_bar.logout": "Cerrar sesión",
|
"navigation_bar.logout": "Cerrar sesión",
|
||||||
|
"navigation_bar.follow_requests": "Solicitudes para seguirte",
|
||||||
|
"navigation_bar.mutes": "Usuarios silenciados",
|
||||||
"reply_indicator.cancel": "Cancelar",
|
"reply_indicator.cancel": "Cancelar",
|
||||||
"search.placeholder": "Buscar",
|
"search.placeholder": "Buscar",
|
||||||
"search.account": "Cuenta",
|
"search.account": "Cuenta",
|
||||||
|
|||||||
@@ -11,28 +11,32 @@ const nl = {
|
|||||||
"status.sensitive_warning": "Gevoelige inhoud",
|
"status.sensitive_warning": "Gevoelige inhoud",
|
||||||
"status.sensitive_toggle": "Klik om te zien",
|
"status.sensitive_toggle": "Klik om te zien",
|
||||||
"video_player.toggle_sound": "Geluid in-/uitschakelen",
|
"video_player.toggle_sound": "Geluid in-/uitschakelen",
|
||||||
"account.mention": "@{name} vermelden",
|
"account.mention": "Vermeld @{name}",
|
||||||
"account.edit_profile": "Profiel bewerken",
|
"account.edit_profile": "Profiel bewerken",
|
||||||
"account.unblock": "@{name} deblokkeren",
|
"account.unblock": "Deblokkeer @{name}",
|
||||||
"account.unfollow": "Ontvolgen",
|
"account.unfollow": "Ontvolgen",
|
||||||
"account.block": "@{name} blokkeren",
|
"account.block": "Blokkeer @{name}",
|
||||||
"account.follow": "Volgen",
|
"account.follow": "Volgen",
|
||||||
"account.posts": "Berichten",
|
"account.posts": "Berichten",
|
||||||
"account.follows": "Volgt",
|
"account.follows": "Volgt",
|
||||||
"account.followers": "Volgers",
|
"account.followers": "Volgers",
|
||||||
"account.follows_you": "Volgt jou",
|
"account.follows_you": "Volgt jou",
|
||||||
"account.requested": "Wacht op goedkeuring",
|
"account.requested": "Wacht op goedkeuring",
|
||||||
"account.mute": "@{name} negeren",
|
"account.mute": "Negeer @{name}",
|
||||||
"account.unmute": "@{name} niet meer negeren",
|
"account.unmute": "Negeer @{name} niet meer",
|
||||||
"account.report": "Report @{name}",
|
"account.report": "Rapporteer @{name}",
|
||||||
"getting_started.heading": "Beginnen",
|
"getting_started.heading": "Beginnen",
|
||||||
"getting_started.about_addressing": "Je kunt mensen volgen als je hun gebruikersnaam en het domein van hun server kent. Voer hiervoor het e-mailachtige adres in het zoekveld in.",
|
"getting_started.about_addressing": "Je kunt mensen volgen als je hun gebruikersnaam en het domein van hun server kent. Voer hiervoor het e-mailachtige adres in het zoekveld in.",
|
||||||
"getting_started.about_shortcuts": "Als de gezochte gebruiker op hetzelfde domein zit als jijzelf, is invoeren van de gebruikersnaam genoeg. Dat geldt ook als je mensen in toots wilt vermelden.",
|
"getting_started.about_shortcuts": "Als de gezochte gebruiker op hetzelfde domein zit als jijzelf, is invoeren van de gebruikersnaam genoeg. Dat geldt ook als je mensen in toots wilt vermelden.",
|
||||||
"getting_started.open_source_notice": "Mastodon is open-sourcesoftware. Je kunt bijdragen of problemen melden op GitHub via {github}. {apps}.",
|
"getting_started.open_source_notice": "Mastodon is open-sourcesoftware. Je kunt bijdragen of problemen melden op GitHub via {github}. {apps}.",
|
||||||
|
"getting_started.apps": "Er zijn meerdere apps beschikbaar",
|
||||||
"column.home": "Jouw tijdlijn",
|
"column.home": "Jouw tijdlijn",
|
||||||
"column.community": "Lokale tijdlijn",
|
"column.community": "Lokale tijdlijn",
|
||||||
"column.public": "Globale tijdlijn",
|
"column.public": "Globale tijdlijn",
|
||||||
"column.notifications": "Meldingen",
|
"column.notifications": "Meldingen",
|
||||||
|
"column.favourites": "Favorieten",
|
||||||
|
"column.blocks": "Geblokkeerde gebruikers",
|
||||||
|
"column.mutes": "Genegeerde gebruikers",
|
||||||
"tabs_bar.compose": "Schrijven",
|
"tabs_bar.compose": "Schrijven",
|
||||||
"tabs_bar.home": "Jouw tijdlijn",
|
"tabs_bar.home": "Jouw tijdlijn",
|
||||||
"tabs_bar.mentions": "Vermeldingen",
|
"tabs_bar.mentions": "Vermeldingen",
|
||||||
@@ -44,7 +48,7 @@ const nl = {
|
|||||||
"compose_form.spoiler": "Tekst achter waarschuwing verbergen",
|
"compose_form.spoiler": "Tekst achter waarschuwing verbergen",
|
||||||
"compose_form.spoiler_placeholder": "Waarschuwingstekst",
|
"compose_form.spoiler_placeholder": "Waarschuwingstekst",
|
||||||
"compose_form.private": "Als privé markeren",
|
"compose_form.private": "Als privé markeren",
|
||||||
"compose_form.privacy_disclaimer": "Jouw privétoot wordt afgeleverd aan de vermelde gebruikers op {domains}. Vertrouw jij {domainsCount, plural, one {that server} andere {those servers}}? Het privé plaatsen van toots werkt alleen op Mastodon-servers. Als {domains} {domainsCount, plural, een {is not a Mastodon instance} andere {are not Mastodon instances}}, dan wordt er niet aangegeven dat de toot besloten is, waardoor het kan worden geboost of op een andere manier zichtbaar wordt gemaakt voor mensen waarvoor het niet was bedoeld.",
|
"compose_form.privacy_disclaimer": "Jouw privétoot wordt afgeleverd aan de vermelde gebruikers op {domains}. Vertrouw jij {domainsCount, plural, one {die server} other {die servers}}? Het privé plaatsen van toots werkt alleen op Mastodon-servers. Wanneer {domains} {domainsCount, plural, one {geen Mastodon-server is} other {geen Mastodon-servers zijn}}, dan wordt er niet aangegeven dat de toot privé is, waardoor het kan worden geboost of op een andere manier zichtbaar wordt gemaakt voor mensen waarvoor het niet was bedoeld.",
|
||||||
"compose_form.unlisted": "Niet op openbare tijdlijnen tonen",
|
"compose_form.unlisted": "Niet op openbare tijdlijnen tonen",
|
||||||
"navigation_bar.edit_profile": "Profiel bewerken",
|
"navigation_bar.edit_profile": "Profiel bewerken",
|
||||||
"navigation_bar.preferences": "Voorkeuren",
|
"navigation_bar.preferences": "Voorkeuren",
|
||||||
@@ -55,6 +59,7 @@ const nl = {
|
|||||||
"navigation_bar.blocks": "Geblokkeerde gebruikers",
|
"navigation_bar.blocks": "Geblokkeerde gebruikers",
|
||||||
"navigation_bar.mutes": "Genegeerde gebruikers",
|
"navigation_bar.mutes": "Genegeerde gebruikers",
|
||||||
"navigation_bar.logout": "Afmelden",
|
"navigation_bar.logout": "Afmelden",
|
||||||
|
"navigation_bar.favourites": "Favorieten",
|
||||||
"reply_indicator.cancel": "Annuleren",
|
"reply_indicator.cancel": "Annuleren",
|
||||||
"search.placeholder": "Zoeken",
|
"search.placeholder": "Zoeken",
|
||||||
"search.account": "Account",
|
"search.account": "Account",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class Account < ApplicationRecord
|
|||||||
|
|
||||||
# Local users
|
# Local users
|
||||||
has_one :user, inverse_of: :account
|
has_one :user, inverse_of: :account
|
||||||
validates :username, presence: true, format: { with: /\A[a-z0-9_]+\z/i, message: 'only letters, numbers and underscores' }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }, if: 'local?'
|
validates :username, presence: true, format: { with: /\A[a-z0-9_]+\z/i }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }, if: 'local?'
|
||||||
validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
|
validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
|
||||||
|
|
||||||
# Avatar upload
|
# Avatar upload
|
||||||
|
|||||||
@@ -106,13 +106,18 @@ class MediaAttachment < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def set_type_and_extension
|
def set_type_and_extension
|
||||||
if file.blank?
|
|
||||||
self.type = :unknown
|
|
||||||
else
|
|
||||||
self.type = VIDEO_MIME_TYPES.include?(file_content_type) ? :video : :image
|
self.type = VIDEO_MIME_TYPES.include?(file_content_type) ? :video : :image
|
||||||
extension = Paperclip::Interpolations.content_type_extension(file, :original)
|
extension = appropriate_extension
|
||||||
basename = Paperclip::Interpolations.basename(file, :original)
|
basename = Paperclip::Interpolations.basename(file, :original)
|
||||||
file.instance_write :file_name, [basename, extension].delete_if(&:empty?).join('.')
|
file.instance_write :file_name, [basename, extension].delete_if(&:empty?).join('.')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def appropriate_extension
|
||||||
|
mime_type = MIME::Types[file.content_type]
|
||||||
|
|
||||||
|
extensions_for_mime_type = mime_type.empty? ? [] : mime_type.first.extensions
|
||||||
|
original_extension = Paperclip::Interpolations.extension(file, :original)
|
||||||
|
|
||||||
|
extensions_for_mime_type.include?(original_extension) ? original_extension : extensions_for_mime_type.first
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class Status < ApplicationRecord
|
|||||||
validates :uri, uniqueness: true, unless: 'local?'
|
validates :uri, uniqueness: true, unless: 'local?'
|
||||||
validates :text, presence: true, unless: 'reblog?'
|
validates :text, presence: true, unless: 'reblog?'
|
||||||
validates_with StatusLengthValidator
|
validates_with StatusLengthValidator
|
||||||
validates :reblog, uniqueness: { scope: :account, message: 'of status already exists' }, if: 'reblog?'
|
validates :reblog, uniqueness: { scope: :account }, if: 'reblog?'
|
||||||
|
|
||||||
default_scope { order('id desc') }
|
default_scope { order('id desc') }
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
class ProcessingWorker
|
class ProcessingWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options queue: 'pull', backtrace: true
|
sidekiq_options backtrace: true
|
||||||
|
|
||||||
def perform(account_id, body)
|
def perform(account_id, body)
|
||||||
ProcessFeedService.new.call(body, Account.find(account_id))
|
ProcessFeedService.new.call(body, Account.find(account_id))
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
class SalmonWorker
|
class SalmonWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options queue: 'pull', backtrace: true
|
sidekiq_options backtrace: true
|
||||||
|
|
||||||
def perform(account_id, body)
|
def perform(account_id, body)
|
||||||
ProcessInteractionService.new.call(body, Account.find(account_id))
|
ProcessInteractionService.new.call(body, Account.find(account_id))
|
||||||
|
|||||||
12
config/activerecord.en.yml
Normal file
12
config/activerecord.en.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
en:
|
||||||
|
activerecord:
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
account:
|
||||||
|
attributes:
|
||||||
|
username:
|
||||||
|
invalid: only letters, numbers and underscores
|
||||||
|
status:
|
||||||
|
attributes:
|
||||||
|
reblog:
|
||||||
|
taken: of status already exists
|
||||||
12
config/activerecord.ja.yml
Normal file
12
config/activerecord.ja.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
ja:
|
||||||
|
activerecord:
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
account:
|
||||||
|
attributes:
|
||||||
|
username:
|
||||||
|
invalid: アルファベット・数値・アンダーバー(_)で入力してください
|
||||||
|
status:
|
||||||
|
attributes:
|
||||||
|
reblog:
|
||||||
|
taken: のブーストはすでに存在します
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
lock '3.8.0'
|
lock '3.8.0'
|
||||||
|
|
||||||
|
set :repo_url, ENV.fetch('REPO', 'https://github.com/tootsuite/mastodon.git')
|
||||||
|
set :branch, ENV.fetch('BRANCH', 'master')
|
||||||
|
|
||||||
set :application, 'mastodon'
|
set :application, 'mastodon'
|
||||||
set :repo_url, 'https://github.com/tootsuite/mastodon.git'
|
|
||||||
set :branch, 'skylight'
|
|
||||||
set :rbenv_type, :user
|
set :rbenv_type, :user
|
||||||
set :rbenv_ruby, File.read('.ruby-version').strip
|
set :rbenv_ruby, File.read('.ruby-version').strip
|
||||||
set :migration_role, :app
|
set :migration_role, :app
|
||||||
set :conditional_migrate, true
|
|
||||||
|
|
||||||
append :linked_files, '.env.production'
|
append :linked_files, '.env.production', 'public/robots.txt'
|
||||||
append :linked_dirs, 'vendor/bundle', 'public/system'
|
append :linked_dirs, 'vendor/bundle', 'node_modules', 'public/system'
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ module Paperclip
|
|||||||
def make
|
def make
|
||||||
num_frames = identify('-format %n :file', file: file.path).to_i
|
num_frames = identify('-format %n :file', file: file.path).to_i
|
||||||
|
|
||||||
return file unless options[:style] == :original && num_frames > 1
|
unless options[:style] == :original && num_frames > 1
|
||||||
|
tmp_file = Paperclip::TempfileFactory.new.generate(attachment.instance.file_file_name)
|
||||||
|
tmp_file << file.read
|
||||||
|
return tmp_file
|
||||||
|
end
|
||||||
|
|
||||||
final_file = Paperclip::Transcoder.make(file, options, attachment)
|
final_file = Paperclip::Transcoder.make(file, options, attachment)
|
||||||
|
|
||||||
|
|||||||
BIN
spec/fixtures/files/attachment.gif
vendored
Normal file
BIN
spec/fixtures/files/attachment.gif
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
@@ -1,5 +1,27 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe MediaAttachment, type: :model do
|
RSpec.describe MediaAttachment, type: :model do
|
||||||
|
describe 'animated gif conversion' do
|
||||||
|
let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('avatar.gif')) }
|
||||||
|
|
||||||
|
it 'sets type to gifv' do
|
||||||
|
expect(media.type).to eq 'gifv'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'converts original file to mp4' do
|
||||||
|
expect(media.file_content_type).to eq 'video/mp4'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'non-animated gif non-conversion' do
|
||||||
|
let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('attachment.gif')) }
|
||||||
|
|
||||||
|
it 'sets type to image' do
|
||||||
|
expect(media.type).to eq 'image'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'leaves original file as-is' do
|
||||||
|
expect(media.file_content_type).to eq 'image/gif'
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user