Merge branch 'master' into skylight
This commit is contained in:
commit
24656a9f8f
37
Gemfile
37
Gemfile
|
@ -21,37 +21,38 @@ gem 'paperclip', '~> 5.1'
|
|||
gem 'paperclip-av-transcoder'
|
||||
gem 'aws-sdk', '>= 2.0'
|
||||
|
||||
gem 'http'
|
||||
gem 'httplog'
|
||||
gem 'addressable'
|
||||
gem 'nokogiri'
|
||||
gem 'link_header'
|
||||
gem 'ostatus2'
|
||||
gem 'goldfinger'
|
||||
gem 'devise'
|
||||
gem 'devise-two-factor'
|
||||
gem 'doorkeeper'
|
||||
gem 'rabl'
|
||||
gem 'rqrcode'
|
||||
gem 'twitter-text'
|
||||
gem 'ox'
|
||||
gem 'oj'
|
||||
gem 'hiredis'
|
||||
gem 'redis', '~>3.2', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'fast_blank'
|
||||
gem 'goldfinger'
|
||||
gem 'hiredis'
|
||||
gem 'htmlentities'
|
||||
gem 'simple_form'
|
||||
gem 'will_paginate'
|
||||
gem 'http'
|
||||
gem 'http_accept_language'
|
||||
gem 'httplog'
|
||||
gem 'link_header'
|
||||
gem 'nokogiri'
|
||||
gem 'oj'
|
||||
gem 'ostatus2'
|
||||
gem 'ox'
|
||||
gem 'rabl'
|
||||
gem 'rack-attack'
|
||||
gem 'rack-cors', require: 'rack/cors'
|
||||
gem 'rack-timeout'
|
||||
gem 'rails-settings-cached'
|
||||
gem 'redis', '~>3.2', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'rqrcode'
|
||||
gem 'ruby-oembed', require: 'oembed'
|
||||
gem 'sidekiq'
|
||||
gem 'sidekiq-unique-jobs'
|
||||
gem 'rails-settings-cached'
|
||||
gem 'simple-navigation'
|
||||
gem 'simple_form'
|
||||
gem 'statsd-instrument'
|
||||
gem 'ruby-oembed', require: 'oembed'
|
||||
gem 'rack-timeout'
|
||||
gem 'twitter-text'
|
||||
gem 'tzinfo-data'
|
||||
gem 'will_paginate'
|
||||
|
||||
gem 'react-rails'
|
||||
gem 'browserify-rails'
|
||||
|
|
|
@ -184,6 +184,7 @@ GEM
|
|||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
http-form_data (1.0.1)
|
||||
http_accept_language (2.1.0)
|
||||
http_parser.rb (0.6.0)
|
||||
httplog (0.3.2)
|
||||
colorize
|
||||
|
@ -478,6 +479,7 @@ DEPENDENCIES
|
|||
hiredis
|
||||
htmlentities
|
||||
http
|
||||
http_accept_language
|
||||
httplog
|
||||
i18n-tasks (~> 0.9.6)
|
||||
jquery-rails
|
||||
|
@ -529,4 +531,4 @@ RUBY VERSION
|
|||
ruby 2.3.1p112
|
||||
|
||||
BUNDLED WITH
|
||||
1.14.3
|
||||
1.14.5
|
||||
|
|
|
@ -2,54 +2,71 @@ const pt = {
|
|||
"column_back_button.label": "Voltar",
|
||||
"lightbox.close": "Fechar",
|
||||
"loading_indicator.label": "Carregando...",
|
||||
"status.mention": "Menção",
|
||||
"status.delete": "Deletar",
|
||||
"status.mention": "Mencionar @{name}",
|
||||
"status.delete": "Eliminar",
|
||||
"status.reply": "Responder",
|
||||
"status.reblog": "Reblogar",
|
||||
"status.favourite": "Favoritar",
|
||||
"status.reblogged_by": "{name} reblogou",
|
||||
"video_player.toggle_sound": "Alterar som",
|
||||
"account.mention": "Menção",
|
||||
"status.reblog": "Partilhar",
|
||||
"status.favourite": "Adicionar aos favoritos",
|
||||
"status.reblogged_by": "{name} partilhou",
|
||||
"status.sensitive_warning": "Conteúdo sensível",
|
||||
"status.sensitive_toggle": "Clique para ver",
|
||||
"status.show_more": "Mostrar mais",
|
||||
"status.show_less": "Mostrar menos",
|
||||
"status.open": "Expandir",
|
||||
"status.report": "Reportar @{name}",
|
||||
"video_player.toggle_sound": "Ligar/Desligar som",
|
||||
"account.mention": "Mencionar @{name}",
|
||||
"account.edit_profile": "Editar perfil",
|
||||
"account.unblock": "Desbloquear",
|
||||
"account.unfollow": "Unfollow",
|
||||
"account.block": "Bloquear",
|
||||
"account.unblock": "Não bloquear @{name}",
|
||||
"account.unfollow": "Não seguir",
|
||||
"account.block": "Bloquear @{name}",
|
||||
"account.follow": "Seguir",
|
||||
"account.block": "Bloquear",
|
||||
"account.posts": "Posts",
|
||||
"account.follows": "Segue",
|
||||
"account.followers": "Seguidores",
|
||||
"account.follows_you": "Segue você",
|
||||
"account.follows_you": "É teu seguidor",
|
||||
"account.requested": "A aguardar aprovação",
|
||||
"getting_started.heading": "Primeiros passos",
|
||||
"getting_started.about_addressing": "Podes seguir pessoas se sabes o nome de usuário deles e o domínio em que estão entrando um endereço similar a e-mail no campo no topo da barra lateral.",
|
||||
"getting_started.about_addressing": "Podes seguir pessoas se sabes o nome de usuário deles e o domínio em que estão colocando um endereço similar a e-mail no campo no topo da barra lateral.",
|
||||
"getting_started.about_shortcuts": "Se o usuário alvo está no mesmo domínio, só o nome funcionará. A mesma regra se aplica a mencionar pessoas nas postagens.",
|
||||
"getting_started.about_developer": "O desenvolvedor desse projeto pode ser seguido em Gargron@mastodon.social",
|
||||
"getting_started.open_source_notice": "Mastodon é software de fonte aberta. Podes contribuir ou repostar problemas no GitHub do projecto: {github}. {apps}.",
|
||||
"column.home": "Home",
|
||||
"column.mentions": "Menções",
|
||||
"column.community": "Local",
|
||||
"column.public": "Público",
|
||||
"tabs_bar.compose": "Compôr",
|
||||
"column.notifications": "Notificações",
|
||||
"tabs_bar.compose": "Criar",
|
||||
"tabs_bar.home": "Home",
|
||||
"tabs_bar.mentions": "Menções",
|
||||
"tabs_bar.public": "Público",
|
||||
"tabs_bar.notifications": "Notificações",
|
||||
"compose_form.placeholder": "Que estás pensando?",
|
||||
"compose_form.placeholder": "Em que estás a pensar?",
|
||||
"compose_form.publish": "Publicar",
|
||||
"compose_form.sensitive": "Marcar conteúdo como sensível",
|
||||
"compose_form.unlisted": "Modo não-listado",
|
||||
"compose_form.sensitive": "Media com conteúdo sensível",
|
||||
"compose_form.spoiler": "Esconder texto com aviso",
|
||||
"compose_form.private": "Tornar privado",
|
||||
"compose_form.privacy_disclaimer": "O teu conteúdo privado vai ser partilhado com os utilizadores do {domains}. Confias {domainsCount, plural, one {neste servidor} other {nestes servidores}}? A privacidade só funciona em instâncias do Mastodon. Se {domains} {domainsCount, plural, one {não é uma instância} other {não são instâncias}}, não existem indicadores da privacidade da tua partilha, e podem ser partilhados com outros.",
|
||||
"compose_form.unlisted": "Não mostrar na listagem pública",
|
||||
"navigation_bar.edit_profile": "Editar perfil",
|
||||
"navigation_bar.preferences": "Preferências",
|
||||
"navigation_bar.public_timeline": "Timeline Pública",
|
||||
"navigation_bar.logout": "Logout",
|
||||
"navigation_bar.community_timeline": "Local",
|
||||
"navigation_bar.public_timeline": "Público",
|
||||
"navigation_bar.logout": "Sair",
|
||||
"reply_indicator.cancel": "Cancelar",
|
||||
"search.placeholder": "Busca",
|
||||
"search.placeholder": "Pesquisar",
|
||||
"search.account": "Conta",
|
||||
"search.hashtag": "Hashtag",
|
||||
"upload_button.label": "Adicionar media",
|
||||
"upload_form.undo": "Desfazer",
|
||||
"notification.follow": "{name} seguiu você",
|
||||
"notification.favourite": "{name} favoritou seu post",
|
||||
"notification.reblog": "{name} reblogou o seu post",
|
||||
"notification.mention": "{name} mecionou você"
|
||||
"upload_form.undo": "Anular",
|
||||
"notification.follow": "{name} seguiu-te",
|
||||
"notification.favourite": "{name} adicionou o teu post aos favoritos",
|
||||
"notification.reblog": "{name} partilhou o teu post",
|
||||
"notification.mention": "{name} mencionou-te",
|
||||
"notifications.column_settings.alert": "Notificações no computador",
|
||||
"notifications.column_settings.show": "Mostrar nas colunas",
|
||||
"notifications.column_settings.follow": "Novos seguidores:",
|
||||
"notifications.column_settings.favourite": "Favoritos:",
|
||||
"notifications.column_settings.mention": "Menções:",
|
||||
"notifications.column_settings.reblog": "Partilhas:",
|
||||
};
|
||||
|
||||
export default pt;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::AccountsController < ApiController
|
||||
before_action -> { doorkeeper_authorize! :read }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
|
||||
before_action -> { doorkeeper_authorize! :read }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute, :update_credentials]
|
||||
before_action -> { doorkeeper_authorize! :follow }, only: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
|
||||
before_action -> { doorkeeper_authorize! :write }, only: [:update_credentials]
|
||||
before_action :require_user!, except: [:show, :following, :followers, :statuses]
|
||||
before_action :set_account, except: [:verify_credentials, :suggestions, :search]
|
||||
before_action :set_account, except: [:verify_credentials, :update_credentials, :suggestions, :search]
|
||||
|
||||
respond_to :json
|
||||
|
||||
|
@ -15,6 +16,14 @@ class Api::V1::AccountsController < ApiController
|
|||
render action: :show
|
||||
end
|
||||
|
||||
def update_credentials
|
||||
@account = current_user.account
|
||||
|
||||
@account.update_attributes!(account_params)
|
||||
|
||||
render action: :show
|
||||
end
|
||||
|
||||
def following
|
||||
results = Follow.where(account: @account).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
|
||||
accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h
|
||||
|
@ -135,4 +144,8 @@ class Api::V1::AccountsController < ApiController
|
|||
def statuses_pagination_params(core_params)
|
||||
params.permit(:limit, :only_media, :exclude_replies).merge(core_params)
|
||||
end
|
||||
|
||||
def account_params
|
||||
@account_params ||= params.permit(:display_name, :note, :avatar, :header)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,6 +26,8 @@ module Localized
|
|||
end
|
||||
|
||||
def default_locale
|
||||
ENV.fetch('DEFAULT_LOCALE') { I18n.default_locale }
|
||||
ENV.fetch('DEFAULT_LOCALE') {
|
||||
http_accept_language.compatible_language_from(I18n.available_locales) || I18n.default_locale
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module AboutHelper
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Admin::DomainBlocksHelper
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Admin::PubsubhubbubHelper
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module AuthorizeFollowHelper
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module TagsHelper
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module XrdHelper
|
||||
end
|
|
@ -19,11 +19,16 @@ class FetchRemoteAccountService < BaseService
|
|||
xml = Nokogiri::XML(body)
|
||||
xml.encoding = 'utf-8'
|
||||
|
||||
url_parts = Addressable::URI.parse(url)
|
||||
username = xml.at_xpath('//xmlns:author/xmlns:name').try(:content)
|
||||
domain = url_parts.host
|
||||
email = xml.at_xpath('//xmlns:author/xmlns:email').try(:content)
|
||||
if email.nil?
|
||||
url_parts = Addressable::URI.parse(url)
|
||||
username = xml.at_xpath('//xmlns:author/xmlns:name').try(:content)
|
||||
domain = url_parts.host
|
||||
else
|
||||
username, domain = email.split('@')
|
||||
end
|
||||
|
||||
return nil if username.nil?
|
||||
return nil if username.nil? || domain.nil?
|
||||
|
||||
Rails.logger.debug "Going to webfinger #{username}@#{domain}"
|
||||
|
||||
|
|
|
@ -163,6 +163,7 @@ Rails.application.routes.draw do
|
|||
collection do
|
||||
get :relationships
|
||||
get :verify_credentials
|
||||
patch :update_credentials
|
||||
get :search
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
# config/app.yml for rails-settings-cached
|
||||
#
|
||||
# This file contains default values, and does not need to be edited
|
||||
# when configuring an instance. These settings may be changed by an
|
||||
# Administrator using the Web UI.
|
||||
#
|
||||
# For more information, see docs/Running-Mastodon/Administration-guide.md
|
||||
#
|
||||
defaults: &defaults
|
||||
site_title: 'Mastodon'
|
||||
site_description: ''
|
||||
|
|
|
@ -30,7 +30,7 @@ API overview
|
|||
- [Instance](#instance)
|
||||
- [Mention](#mention)
|
||||
- [Notification](#notification)
|
||||
- [Relationships](#relationships)
|
||||
- [Relationship](#relationship)
|
||||
- [Results](#results)
|
||||
- [Status](#status)
|
||||
- [Tag](#tag)
|
||||
|
@ -85,6 +85,17 @@ Returns an [Account](#account).
|
|||
|
||||
Returns the authenticated user's [Account](#account).
|
||||
|
||||
#### Updating the current user:
|
||||
|
||||
PATCH /api/v1/accounts/update_credentials
|
||||
|
||||
Form data:
|
||||
|
||||
- `display_name`: The name to display in the user's profile
|
||||
- `note`: A new biography for the user
|
||||
- `avatar`: A base64 encoded image to display as the user's avatar (e.g. `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUoAAADrCAYAAAA...`)
|
||||
- `header`: A base64 encoded image to display as the user's header image (e.g. `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUoAAADrCAYAAAA...`)
|
||||
|
||||
#### Getting an account's followers:
|
||||
|
||||
GET /api/v1/accounts/:id/followers
|
||||
|
@ -456,7 +467,7 @@ ___
|
|||
| `acct` | Equals `username` for local users, includes `@domain` for remote ones |
|
||||
| `id` | Account ID |
|
||||
|
||||
### Notifications
|
||||
### Notification
|
||||
|
||||
| Attribute | Description |
|
||||
| ------------------------ | ----------- |
|
||||
|
@ -464,9 +475,9 @@ ___
|
|||
| `type` | One of: "mention", "reblog", "favourite", "follow" |
|
||||
| `created_at` | The time the notification was created |
|
||||
| `account` | The [Account](#account) sending the notification to the user |
|
||||
| `status` | The [Status](#status) associated with the notification, if applicible |
|
||||
| `status` | The [Status](#status) associated with the notification, if applicable |
|
||||
|
||||
### Relationships
|
||||
### Relationship
|
||||
|
||||
| Attribute | Description |
|
||||
| ------------------------ | ----------- |
|
||||
|
@ -516,7 +527,7 @@ ___
|
|||
| `tags` | An array of [Tags](#tag) |
|
||||
| `application` | [Application](#application) from which the status was posted |
|
||||
|
||||
### Tags
|
||||
### Tag
|
||||
|
||||
| Attribute | Description |
|
||||
| ------------------------ | ----------- |
|
||||
|
|
|
@ -24,6 +24,39 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #update_credentials' do
|
||||
it 'returns http success' do
|
||||
expect(user.account.avatar).not_to exist
|
||||
expect(user.account.header).not_to exist
|
||||
|
||||
avatar = File.read(Rails.root.join('app', 'assets', 'images', 'logo.png'))
|
||||
header = File.read(Rails.root.join('app', 'assets', 'images', 'mastodon-getting-started.png'))
|
||||
params = {
|
||||
display_name: "Alice Isn't Dead",
|
||||
note: "Hi!\n\nToot toot!",
|
||||
avatar: "data:image/png;base64,#{Base64.encode64(avatar)}",
|
||||
header: "data:image/png;base64,#{Base64.encode64(header)}"
|
||||
}
|
||||
patch :update_credentials, params: params
|
||||
expect(response).to have_http_status(:success)
|
||||
|
||||
user.reload
|
||||
|
||||
expect(user.account.display_name).to eq("Alice Isn't Dead")
|
||||
expect(user.account.note).to eq("Hi!\n\nToot toot!")
|
||||
expect(user.account.avatar).to exist
|
||||
expect(user.account.header).to exist
|
||||
end
|
||||
|
||||
it 'respects Account validations' do
|
||||
note = "This is too long. " * 10
|
||||
error = { error: 'The account could not be updated: Note is too long (maximum is 160 characters)' }.to_json
|
||||
patch :update_credentials, params: { note: note }
|
||||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
expect(response.body).to eq(error)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #statuses' do
|
||||
it 'returns http success' do
|
||||
get :statuses, params: { id: user.account.id }
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AboutHelper, type: :helper do
|
||||
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::DomainBlocksHelper, type: :helper do
|
||||
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::PubsubhubbubHelper, type: :helper do
|
||||
|
||||
end
|
|
@ -1,5 +1,19 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ApplicationHelper, type: :helper do
|
||||
describe ApplicationHelper do
|
||||
describe 'active_nav_class' do
|
||||
it 'returns active when on the current page' do
|
||||
allow(helper).to receive(:current_page?).and_return(true)
|
||||
|
||||
result = helper.active_nav_class("/test")
|
||||
expect(result).to eq "active"
|
||||
end
|
||||
|
||||
it 'returns empty string when not on current page' do
|
||||
allow(helper).to receive(:current_page?).and_return(false)
|
||||
|
||||
result = helper.active_nav_class("/test")
|
||||
expect(result).to eq ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AuthorizeFollowHelper, type: :helper do
|
||||
|
||||
end
|
|
@ -2,7 +2,17 @@ require 'rails_helper'
|
|||
|
||||
RSpec.describe StreamEntriesHelper, type: :helper do
|
||||
describe '#display_name' do
|
||||
pending
|
||||
it 'uses the display name when it exists' do
|
||||
account = Account.new(display_name: "Display", username: "Username")
|
||||
|
||||
expect(helper.display_name(account)).to eq "Display"
|
||||
end
|
||||
|
||||
it 'uses the username when display name is nil' do
|
||||
account = Account.new(display_name: nil, username: "Username")
|
||||
|
||||
expect(helper.display_name(account)).to eq "Username"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#avatar_for_status_url' do
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe TagsHelper, type: :helper do
|
||||
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe XrdHelper, type: :helper do
|
||||
|
||||
end
|
Reference in a new issue