@ -0,0 +1,68 @@ | |||
const bg = { | |||
"column_back_button.label": "Назад", | |||
"lightbox.close": "Затвори", | |||
"loading_indicator.label": "Зареждане...", | |||
"status.mention": "Споменаване", | |||
"status.delete": "Изтриване", | |||
"status.reply": "Отговор", | |||
"status.reblog": "Споделяне", | |||
"status.favourite": "Предпочитани", | |||
"status.reblogged_by": "{name} сподели", | |||
"status.sensitive_warning": "Деликатно съдържание", | |||
"status.sensitive_toggle": "Покажи", | |||
"video_player.toggle_sound": "Звук", | |||
"account.mention": "Споменаване", | |||
"account.edit_profile": "Редактирай профила си", | |||
"account.unblock": "Не блокирай", | |||
"account.unfollow": "Не следвай", | |||
"account.block": "Блокирай", | |||
"account.follow": "Последвай", | |||
"account.posts": "Публикации", | |||
"account.follows": "Следвам", | |||
"account.followers": "Последователи", | |||
"account.follows_you": "Твой последовател", | |||
"account.requested": "В очакване на одобрение", | |||
"getting_started.heading": "Първи стъпки", | |||
"getting_started.about_addressing": "Можеш да последваш потребител, ако знаеш потребителското му име и домейна, на който се намира, като в полето за търсене ги въведеш по този начин: име@домейн", | |||
"getting_started.about_shortcuts": "Ако с търсения потребител се намирате на един и същ домейн, достатъчно е да въведеш само името. Същото важи и за споменаване на хора в публикации.", | |||
"getting_started.about_developer": "Можеш да потърсиш разработчика на този проект като: Gargron@mastodon.social", | |||
"getting_started.open_source_notice": "Mastodon е софтуер с отворен код. Можеш да помогнеш или да докладваш за проблеми в Github: {github}.", | |||
"column.home": "Начало", | |||
"column.mentions": "Споменавания", | |||
"column.public": "Публичен канал", | |||
"column.notifications": "Известия", | |||
"tabs_bar.compose": "Съставяне", | |||
"tabs_bar.home": "Начало", | |||
"tabs_bar.mentions": "Споменавания", | |||
"tabs_bar.public": "Публичен канал", | |||
"tabs_bar.notifications": "Известия", | |||
"compose_form.placeholder": "Какво си мислиш?", | |||
"compose_form.publish": "Раздумай", | |||
"compose_form.sensitive": "Отбележи съдържанието като деликатно", | |||
"compose_form.spoiler": "Скрий текста зад предупреждение", | |||
"compose_form.private": "Отбележи като поверително", | |||
"compose_form.privacy_disclaimer": "Поверителни публикации ще бъдат изпратени до споменатите потребители на {domains}. Доверяваш ли се на {domainsCount, plural, one {that server} other {those servers}}, че няма да издаде твоята публикация?", | |||
"compose_form.unlisted": "Не показвай в публичния канал", | |||
"navigation_bar.edit_profile": "Редактирай профил", | |||
"navigation_bar.preferences": "Предпочитания", | |||
"navigation_bar.public_timeline": "Публичен канал", | |||
"navigation_bar.logout": "Излизане", | |||
"reply_indicator.cancel": "Отказ", | |||
"search.placeholder": "Търсене", | |||
"search.account": "Акаунт", | |||
"search.hashtag": "Хаштаг", | |||
"upload_button.label": "Добави медия", | |||
"upload_form.undo": "Отмяна", | |||
"notification.follow": "{name} те последва", | |||
"notification.favourite": "{name} хареса твоята публикация", | |||
"notification.reblog": "{name} сподели твоята публикация", | |||
"notification.mention": "{name} те спомена", | |||
"notifications.column_settings.alert": "Десктоп известия", | |||
"notifications.column_settings.show": "Покажи в колона", | |||
"notifications.column_settings.follow": "Нови последователи:", | |||
"notifications.column_settings.favourite": "Предпочитани:", | |||
"notifications.column_settings.mention": "Споменавания:", | |||
"notifications.column_settings.reblog": "Споделяния:", | |||
}; | |||
export default en; |
@ -1,72 +1,129 @@ | |||
/** | |||
* Note for Contributors: | |||
* This file (en.jsx) serve as a template for other languages. | |||
* To make other contributors' life easier, please REMEMBER: | |||
* 1. to add your new string here; and | |||
* 2. to remove old strings that are no longer needed; and | |||
* 3. to sort the strings by the key. | |||
* Thanks! | |||
*/ | |||
const en = { | |||
"column_back_button.label": "Back", | |||
"lightbox.close": "Close", | |||
"loading_indicator.label": "Loading...", | |||
"status.mention": "Mention @{name}", | |||
"status.delete": "Delete", | |||
"status.reply": "Reply", | |||
"status.reblog": "Boost", | |||
"status.favourite": "Favourite", | |||
"status.reblogged_by": "{name} boosted", | |||
"status.sensitive_warning": "Sensitive content", | |||
"status.sensitive_toggle": "Click to view", | |||
"status.show_more": "Show more", | |||
"status.show_less": "Show less", | |||
"status.open": "Expand this status", | |||
"status.report": "Report @{name}", | |||
"video_player.toggle_sound": "Toggle sound", | |||
"account.mention": "Mention @{name}", | |||
"account.edit_profile": "Edit profile", | |||
"account.unblock": "Unblock @{name}", | |||
"account.unfollow": "Unfollow", | |||
"account.block": "Block @{name}", | |||
"account.disclaimer": "This user is from another instance. This number may be larger.", | |||
"account.edit_profile": "Edit profile", | |||
"account.follow": "Follow", | |||
"account.posts": "Posts", | |||
"account.follows": "Follows", | |||
"account.followers": "Followers", | |||
"account.follows_you": "Follows you", | |||
"account.follows": "Follows", | |||
"account.mention": "Mention @{name}", | |||
"account.mute": "Mute @{name}", | |||
"account.posts": "Posts", | |||
"account.report": "Report @{name}", | |||
"account.requested": "Awaiting approval", | |||
"getting_started.heading": "Getting started", | |||
"getting_started.about_addressing": "You can follow people if you know their username and the domain they are on by entering an e-mail-esque address into the search form.", | |||
"getting_started.about_shortcuts": "If the target user is on the same domain as you, just the username will work. The same rule applies to mentioning people in statuses.", | |||
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}. {apps}.", | |||
"column.home": "Home", | |||
"account.unblock": "Unblock @{name}", | |||
"account.unfollow": "Unfollow", | |||
"account.unmute": "Unmute @{name}", | |||
"boost_modal.combo": "You can press {combo} to skip this next time", | |||
"column_back_button.label": "Back", | |||
"column.blocks": "Blocked users", | |||
"column.community": "Local timeline", | |||
"column.public": "Federated timeline", | |||
"column.favourites": "Favourites", | |||
"column.follow_requests": "Follow requests", | |||
"column.home": "Home", | |||
"column.notifications": "Notifications", | |||
"tabs_bar.compose": "Compose", | |||
"tabs_bar.home": "Home", | |||
"tabs_bar.mentions": "Mentions", | |||
"tabs_bar.public": "Federated timeline", | |||
"tabs_bar.notifications": "Notifications", | |||
"column.public": "Federated timeline", | |||
"compose_form.placeholder": "What is on your mind?", | |||
"compose_form.privacy_disclaimer": "Your private status will be delivered to mentioned users on {domains}. Do you trust {domainsCount, plural, one {that server} other {those servers}}? Post privacy only works on Mastodon instances. If {domains} {domainsCount, plural, one {is not a Mastodon instance} other {are not Mastodon instances}}, there will be no indication that your post is private, and it may be boosted or otherwise made visible to unintended recipients.", | |||
"compose_form.publish": "Toot", | |||
"compose_form.sensitive": "Mark media as sensitive", | |||
"compose_form.spoiler_placeholder": "Content warning", | |||
"compose_form.spoiler": "Hide text behind warning", | |||
"compose_form.private": "Mark as private", | |||
"compose_form.privacy_disclaimer": "Your private status will be delivered to mentioned users on {domains}. Do you trust {domainsCount, plural, one {that server} other {those servers}}? Post privacy only works on Mastodon instances. If {domains} {domainsCount, plural, one {is not a Mastodon instance} other {are not Mastodon instances}}, there will be no indication that your post is private, and it may be boosted or otherwise made visible to unintended recipients.", | |||
"compose_form.unlisted": "Do not display on public timelines", | |||
"emoji_button.label": "Insert emoji", | |||
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", | |||
"empty_column.hashtag": "There is nothing in this hashtag yet.", | |||
"empty_column.home.public_timeline": "the public timeline", | |||
"empty_column.home": "You aren't following anyone yet. Visit {public} or use search to get started and meet other users.", | |||
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.", | |||
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up", | |||
"follow_request.authorize": "Authorize", | |||
"follow_request.reject": "Rejec", | |||
"getting_started.apps": "Various apps are available", | |||
"getting_started.heading": "Getting started", | |||
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}. {apps}.", | |||
"home.column_settings.advanced": "Advanced", | |||
"home.column_settings.basic": "Basic", | |||
"home.column_settings.filter_regex": "Filter out by regular expressions", | |||
"home.column_settings.show_reblogs": "Show boosts", | |||
"home.column_settings.show_replies": "Show replies", | |||
"home.settings": "Column settings", | |||
"lightbox.close": "Close", | |||
"loading_indicator.label": "Loading...", | |||
"media_gallery.toggle_visible": "Toggle visibility", | |||
"missing_indicator.label": "Not found", | |||
"navigation_bar.blocks": "Blocked users", | |||
"navigation_bar.community_timeline": "Local timeline", | |||
"navigation_bar.edit_profile": "Edit profile", | |||
"navigation_bar.favourites": "Favourites", | |||
"navigation_bar.follow_requests": "Follow requests", | |||
"navigation_bar.info": "Extended information", | |||
"navigation_bar.logout": "Logout", | |||
"navigation_bar.preferences": "Preferences", | |||
"navigation_bar.community_timeline": "Local timeline", | |||
"navigation_bar.public_timeline": "Federated timeline", | |||
"navigation_bar.logout": "Logout", | |||
"reply_indicator.cancel": "Cancel", | |||
"search.placeholder": "Search", | |||
"search.account": "Account", | |||
"search.hashtag": "Hashtag", | |||
"upload_button.label": "Add media", | |||
"upload_form.undo": "Undo", | |||
"notification.follow": "{name} followed you", | |||
"notification.favourite": "{name} favourited your status", | |||
"notification.follow": "{name} followed you", | |||
"notification.reblog": "{name} boosted your status", | |||
"notification.mention": "{name} mentioned you", | |||
"notifications.clear_confirmation": "Are you sure you want to clear all your notifications?", | |||
"notifications.clear": "Clear notifications", | |||
"notifications.column_settings.alert": "Desktop notifications", | |||
"notifications.column_settings.show": "Show in column", | |||
"notifications.column_settings.follow": "New followers:", | |||
"notifications.column_settings.favourite": "Favourites:", | |||
"notifications.column_settings.follow": "New followers:", | |||
"notifications.column_settings.mention": "Mentions:", | |||
"notifications.column_settings.reblog": "Boosts:", | |||
"notifications.column_settings.show": "Show in column", | |||
"notifications.column_settings.sound": "Play sound", | |||
"notifications.settings": "Column settings", | |||
"privacy.change": "Adjust status privacy", | |||
"privacy.direct.long": "Post to mentioned users only", | |||
"privacy.direct.short": "Direct", | |||
"privacy.private.long": "Post to followers only", | |||
"privacy.private.short": "Private", | |||
"privacy.public.long": "Post to public timelines", | |||
"privacy.public.short": "Public", | |||
"privacy.unlisted.long": "Do not show in public timelines", | |||
"privacy.unlisted.short": "Unlisted", | |||
"reply_indicator.cancel": "Cancel", | |||
"report.heading": "New report", | |||
"report.placeholder": "Additional comments", | |||
"report.submit": "Submit", | |||
"report.target": "Reporting", | |||
"search_results.total": "{count} {count, plural, one {result} other {results}}", | |||
"search.placeholder": "Search", | |||
"search.status_by": "Status by {name}", | |||
"status.delete": "Delete", | |||
"status.favourite": "Favourite", | |||
"status.load_more": "Load more", | |||
"status.media_hidden": "Media hidden", | |||
"status.mention": "Mention @{name}", | |||
"status.open": "Expand this status", | |||
"status.reblog": "Boost", | |||
"status.reblogged_by": "{name} boosted", | |||
"status.reply": "Reply", | |||
"status.report": "Report @{name}", | |||
"status.sensitive_toggle": "Click to view", | |||
"status.sensitive_warning": "Sensitive content", | |||
"status.show_less": "Show less", | |||
"status.show_more": "Show more", | |||
"tabs_bar.compose": "Compose", | |||
"tabs_bar.federated_timeline": "Federated", | |||
"tabs_bar.home": "Home", | |||
"tabs_bar.local_timeline": "Local", | |||
"tabs_bar.notifications": "Notifications", | |||
"upload_area.title": "Drag & drop to upload", | |||
"upload_button.label": "Add media", | |||
"upload_form.undo": "Undo", | |||
"upload_progress.label": "Uploading...", | |||
"video_player.toggle_sound": "Toggle sound", | |||
"video_player.toggle_visible": "Toggle visibility", | |||
}; | |||
export default en; |
@ -0,0 +1,23 @@ | |||
# frozen_string_literal: true | |||
module Admin | |||
class SilencesController < BaseController | |||
before_action :set_account | |||
def create | |||
@account.update(silenced: true) | |||
redirect_to admin_accounts_path | |||
end | |||
def destroy | |||
@account.update(silenced: false) | |||
redirect_to admin_accounts_path | |||
end | |||
private | |||
def set_account | |||
@account = Account.find(params[:account_id]) | |||
end | |||
end | |||
end |
@ -0,0 +1,23 @@ | |||
# frozen_string_literal: true | |||
module Admin | |||
class SuspensionsController < BaseController | |||
before_action :set_account | |||
def create | |||
Admin::SuspensionWorker.perform_async(@account.id) | |||
redirect_to admin_accounts_path | |||
end | |||
def destroy | |||
@account.update(suspended: false) | |||
redirect_to admin_accounts_path | |||
end | |||
private | |||
def set_account | |||
@account = Account.find(params[:account_id]) | |||
end | |||
end | |||
end |
@ -0,0 +1,13 @@ | |||
# frozen_string_literal: true | |||
module WellKnown | |||
class HostMetaController < ApplicationController | |||
def show | |||
@webfinger_template = "#{webfinger_url}?resource={uri}" | |||
respond_to do |format| | |||
format.xml { render content_type: 'application/xrd+xml' } | |||
end | |||
end | |||
end | |||
end |
@ -0,0 +1,43 @@ | |||
# frozen_string_literal: true | |||
module WellKnown | |||
class WebfingerController < ApplicationController | |||
def show | |||
@account = Account.find_local!(username_from_resource) | |||
@canonical_account_uri = @account.to_webfinger_s | |||
@magic_key = pem_to_magic_key(@account.keypair.public_key) | |||
respond_to do |format| | |||
format.xml { render content_type: 'application/xrd+xml' } | |||
format.json { render content_type: 'application/jrd+json' } | |||
end | |||
rescue ActiveRecord::RecordNotFound | |||
head 404 | |||
end | |||
private | |||
def username_from_resource | |||
WebfingerResource.new(resource_param).username | |||
end | |||
def pem_to_magic_key(public_key) | |||
modulus, exponent = [public_key.n, public_key.e].map do |component| | |||
result = [] | |||
until component.zero? | |||
result << [component % 256].pack('C') | |||
component >>= 8 | |||
end | |||
result.reverse.join | |||
end | |||
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.') | |||
end | |||
def resource_param | |||
params.require(:resource) | |||
end | |||
end | |||
end |
@ -1,55 +0,0 @@ | |||
# frozen_string_literal: true | |||
class XrdController < ApplicationController | |||
before_action :set_default_format_xml, only: :host_meta | |||
def host_meta | |||
@webfinger_template = "#{webfinger_url}?resource={uri}" | |||
respond_to do |format| | |||
format.xml { render content_type: 'application/xrd+xml' } | |||
end | |||
end | |||
def webfinger | |||
@account = Account.find_local!(username_from_resource) | |||
@canonical_account_uri = @account.to_webfinger_s | |||
@magic_key = pem_to_magic_key(@account.keypair.public_key) | |||
respond_to do |format| | |||
format.xml { render content_type: 'application/xrd+xml' } | |||
format.json { render content_type: 'application/jrd+json' } | |||
end | |||
rescue ActiveRecord::RecordNotFound | |||
head 404 | |||
end | |||
private | |||
def set_default_format_xml | |||
request.format = 'xml' if request.headers['HTTP_ACCEPT'].nil? && params[:format].nil? | |||
end | |||
def username_from_resource | |||
WebfingerResource.new(resource_param).username | |||
end | |||
def pem_to_magic_key(public_key) | |||
modulus, exponent = [public_key.n, public_key.e].map do |component| | |||
result = [] | |||
until component.zero? | |||
result << [component % 256].pack('C') | |||
component >>= 8 | |||
end | |||
result.reverse.join | |||
end | |||
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.') | |||
end | |||
def resource_param | |||
params.require(:resource) | |||
end | |||
end |
@ -0,0 +1,36 @@ | |||
# frozen_string_literal: true | |||
class AccountFilter | |||
attr_reader :params | |||
def initialize(params) | |||
@params = params | |||
end | |||
def results | |||
scope = Account.alphabetic | |||
params.each do |key, value| | |||
scope = scope.merge scope_for(key, value) | |||
end | |||
scope | |||
end | |||
def scope_for(key, value) | |||
case key | |||
when /local/ | |||
Account.local | |||
when /remote/ | |||
Account.remote | |||
when /by_domain/ | |||
Account.where(domain: value) | |||
when /silenced/ | |||
Account.silenced | |||
when /recent/ | |||
Account.recent | |||
when /suspended/ | |||
Account.suspended | |||
else | |||
raise "Unknown filter: #{key}" | |||
end | |||
end | |||
end |
@ -0,0 +1,169 @@ | |||
--- | |||
bg: | |||
about: | |||
about_mastodon: Mastodon е <em>безплатен</em> сървър с <em>отворен код</em> за социални мрежи. Като <em>децентрализирана</em> алтернатива на комерсиалните платформи, той позволява избягването на риска от монополизация на твоята комуникация от единични компании. Изберете си сървър, на който се доверявате, и ще можете да контактувате с всички останали. Всеки може да пусне Mastodon и лесно да вземе участие в <em>социалната мрежа</em>. | |||
about_this: За тази инстанция | |||
apps: Приложения | |||
business_email: 'Служебен e-mail:' | |||
closed_registrations: В момента регистрациите за тази инстанция са затворени. | |||
contact: За контакти | |||
description_headline: Какво е %{domain}? | |||
domain_count_after: други инстанции | |||
domain_count_before: Свързани към | |||
features: | |||
api: Отворено API за приложения и услуги | |||
blocks: Богат на инструменти за блокиране и заглушаване | |||
characters: Публикации от 500 символа | |||
chronology: Публикациите се показват хронологично | |||
ethics: 'Етичен дизайн: без реклами и проследяване' | |||
gifv: GIFV комплекти и кратки видео клипове | |||
privacy: Настройване на поверителността за всяка публикация | |||
public: Публични канали | |||
features_headline: Какво откроява Mastodon | |||
get_started: Първи стъпки | |||
links: Връзки | |||
other_instances: Други инстанции | |||
source_code: Програмен код | |||
status_count_after: публикации | |||
status_count_before: Написали | |||
terms: Условия | |||
user_count_after: потребители | |||
user_count_before: Дом на | |||
accounts: | |||
follow: Последвай | |||
followers: Последователи | |||
following: Следва | |||
nothing_here: Тук няма никого! | |||
people_followed_by: Хора, които %{name} следва | |||
people_who_follow: Хора, които следват %{name} | |||
posts: Публикации | |||
remote_follow: Последвай | |||
unfollow: Не следвай | |||
application_mailer: | |||
settings: 'Промяна на предпочитанията за e-mail: %{link}' | |||
signature: Mastodon известия от %{instance} | |||
view: 'Преглед:' | |||
applications: | |||
invalid_url: Предоставеният URL е невалиден | |||
auth: | |||
change_password: Идентификационни данни | |||
didnt_get_confirmation: Не получих инструкции за потвърждение | |||
forgot_password: Забравих си паролата | |||
login: Влизане | |||
logout: Излизане | |||
register: Регистрация | |||
resend_confirmation: Изпрати отново инструкции за потвърждение | |||
reset_password: Подновяване на паролата | |||
set_new_password: Задай нова парола | |||
authorize_follow: | |||
error: Възникна грешка в откриването на потребителя | |||
follow: Последвай | |||
prompt_html: '(<strong>%{self}</strong>), молбата ти беше изпратена до:' | |||
title: Последвай %{acct} | |||
datetime: | |||
distance_in_words: | |||
about_x_hours: "%{count} ч." | |||
about_x_months: "%{count} м." | |||
about_x_years: "%{count} г." | |||
almost_x_years: "%{count} г." | |||
half_a_minute: Току-що | |||
less_than_x_minutes: "%{count} мин." | |||
less_than_x_seconds: Току-що | |||
over_x_years: "%{count} г." | |||
x_days: "%{count} дни" | |||
x_minutes: "%{count} мин." | |||
x_months: "%{count} м." | |||
x_seconds: "%{count} сек." | |||
exports: | |||
blocks: Вашите блокирания | |||
csv: CSV | |||
follows: Вашите следвания | |||
storage: Съхранение на мултимедия | |||
generic: | |||
changes_saved_msg: Успешно запазване на промените! | |||
powered_by: поддържано от %{link} | |||
save_changes: Запази промените | |||
validation_errors: | |||
one: Нещо все още не е наред! Моля, прегледай грешката по-долу | |||
other: Нещо все още не е наред! Моля, прегледай грешките по-долу | |||
imports: | |||
preface: Можеш да импортираш някои данни, като например всички хора, които следваш или блокираш в акаунта си на тази инстанция, от файлове, създадени чрез експорт в друга инстанция. | |||
success: Твоите данни бяха успешно качени и ще бъдат обработени впоследствие. | |||
types: | |||
blocking: Списък на блокираните | |||
following: Списък на последователите | |||
upload: Качване | |||
landing_strip_html: <strong>%{name}</strong> е потребител от <strong>%{domain}</strong>. Можеш да ги следваш, или да контактуваш с тях, ако имаш акаунт където и да е из федерираната вселена на Mastodon. Ако нямаш акаунт, можеш да си <a href="%{sign_up_path}">създадеш ето тук</a>. | |||
notification_mailer: | |||
digest: | |||
body: 'Ето кратко резюме на нещата, които се случиха от последното ти посещение в %{instance} на %{since}:' | |||
mention: "%{name} те спомена в:" | |||
new_followers_summary: | |||
one: Имаш един нов последовател! Ура! | |||
other: Имаш %{count} нови последователи! Изумително! | |||
subject: | |||
one: "1 ново известие от последното ти посещение \U0001F418" | |||
other: "%{count} нови известия от последното ти посещение \U0001F418" | |||
favourite: | |||
body: 'Публикацията ти беше харесана от %{name}:' | |||
subject: "%{name} хареса твоята публикация" | |||
follow: | |||
body: "%{name} те последва!" | |||
subject: "%{name} те последва" | |||
follow_request: | |||
body: "%{name} помоли за разрешение да те последва" | |||
subject: 'Чакащ последовател: %{name}' | |||
mention: | |||
body: '%{name} те спомена в:' | |||
subject: '%{name} те спомена' | |||
reblog: | |||
body: 'Твоята публикация беше споделена от %{name}:' | |||
subject: "%{name} сподели публикацията ти" | |||
pagination: | |||
next: Напред | |||
prev: Назад | |||
remote_follow: | |||
acct: Въведи потребителско_име@домейн, от които искаш да следваш | |||
missing_resource: Неуспешно търсене на нужния URL за пренасочване за твоя акаунт | |||
proceed: Започни следване | |||
prompt: 'Ще последваш:' | |||
settings: | |||
authorized_apps: Упълномощени приложения | |||
back: Обратно към Mastodon | |||
edit_profile: Редактирай профила си | |||
export: Експортиране на данни | |||
import: Импортиране | |||
preferences: Предпочитания | |||
settings: Настройки | |||
two_factor_auth: Двустепенно удостоверяване | |||
statuses: | |||
open_in_web: Отвори в уеб | |||
over_character_limit: прехвърлен лимит от %{max} символа | |||
show_more: Покажи повече | |||
visibilities: | |||
private: Покажи само на последователите си | |||
public: Публично | |||
unlisted: Публично, но не показвай в публичния канал | |||
stream_entries: | |||
click_to_show: Покажи | |||
reblogged: споделено | |||
sensitive_content: Деликатно съдържание | |||
time: | |||
formats: | |||
default: "%d %b, %Y, %H:%M" | |||
two_factor_auth: | |||
description_html: При активация на <strong>двустепенно удостоверяване</strong>, за да влезеш в приложението, ще трябва да използваш телефона си. През него ще се генерира код, който да въвеждаш при влизане. | |||
disable: Деактивирай | |||
enable: Активирай | |||
instructions_html: "<strong>Сканирай този QR код с Google Authenticator или подобно приложение от своя телефон</strong>. Oтсега нататък, това приложение ще генерира код, който ще трябва да въвеждаш при всяко влизане." | |||
plaintext_secret_html: "Тайна в обикновен текст: <samp>%{secret}</samp>" | |||
warning: Ако не можеш да настроиш приложението за удостверяване сега, избери "Деактивирай". В противен случай, няма да можеш да влезеш в акаунта си. | |||
users: | |||
invalid_email: E-mail адресът е невалиден | |||
invalid_otp_token: Невалиден код | |||
will_paginate: | |||
page_gap: "…" | |||
media_attachments: | |||
validations: | |||
too_many: Не мога да прикача повече от 4 файла | |||
images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения |
@ -0,0 +1,61 @@ | |||
--- | |||
bg: | |||
devise: | |||
confirmations: | |||
confirmed: Твоят профил беше успешно потвърден. Влизането в профила е успешно. | |||
send_instructions: Ще получиш писмо с инструкции как да потвърдиш своя профил до няколко минути. | |||
send_paranoid_instructions: Ако твоят имейл адрес съществува в базата ни, ще получиш там инструкции как да потвърдиш своя профил. | |||
failure: | |||
already_authenticated: Вече си вътре в профила си. | |||
inactive: Профилът ти все още не е активиран. | |||
invalid: Невалиден имейл адрес или парола. | |||
last_attempt: Разполагаш с още един опит преди профилът ти да бъде заключен. | |||
locked: Профилът ти е заключен. | |||
not_found_in_database: "Невалидни стойности за %{authentication_keys} или парола." | |||
timeout: Сесията ти изтече, моля влез отново, за да продължиш. | |||
unauthenticated: Преди да продължиш, трябва да влезеш в профила си или да се регистрираш. | |||
unconfirmed: Преди да продължиш, трябва да потвърдиш регистрацията си. | |||
mailer: | |||
confirmation_instructions: | |||
subject: 'Mastodon: Инструкции за потвърждаване' | |||
password_change: | |||
subject: 'Mastodon: Паролата е променена' | |||
reset_password_instructions: | |||
subject: 'Инструкции за смяна на паролата' | |||
unlock_instructions: | |||
subject: 'Инструкции за отключване' | |||
omniauth_callbacks: | |||
failure: "Не успяхме да те упълномощим чрез %{kind}, защото \"%{reason}\"." | |||
success: "Успешно упълномощаване чрез %{kind} профил." | |||
passwords: | |||
no_token: Може да достъпваш тази страница само от имейл за промяна на паролата. Ако тази страница е отворена от такъв имейл, увери се, че използваш целия URL-адрес, който сме ти изпратили. | |||
send_instructions: Ще получиш писмо с инструкции как да промениш паролата си до няколко минути. | |||
send_paranoid_instructions: Ако твоят имейл адрес съществува в базата ни, ще получиш там инструкции за промяна на своята парола. | |||
updated: Паролата ти беше променена успешно. Влизането в профила е успешно. | |||
updated_not_active: Паролата ти беше променена успешно. | |||
registrations: | |||
destroyed: Довиждане! Твоят профил беше успешно изтрит. Надяваме се скоро да те видим отново. | |||
signed_up: Привет! Регистрирацията ти е успешна. | |||
signed_up_but_inactive: Регистрирацията ти е успешна. Въпреки това, не можеш да влезеш в профила си, защото той все още не е потвърден. | |||
signed_up_but_locked: Регистрирацията ти е успешна. Въпреки това, не можеш да влезеш в профила си, защото той е заключен. | |||
signed_up_but_unconfirmed: Писмо с връзка за потвърждаване на профила ти беше изпратено на твоя имейл адрес. Моля, отвори връзката, за да активираш своя профил. | |||
update_needs_confirmation: Профилът ти е успешно променен, но ние трябва да проверим твоя нов имейл адрес. Моля, провери пощата си и отвори връзката за потвърждаване на новия адрес. | |||
updated: Профилът ти е успешно променен. | |||
sessions: | |||
already_signed_out: Успешно излизане от профила. | |||
signed_in: Успешно влизане. | |||
signed_out: Успешно излизане. | |||
unlocks: | |||
send_instructions: Ще получиш писмо с инструкции как да отключиш профила си до няколко минути. | |||
send_paranoid_instructions: Ако твоят профил съществува в базата ни, на своя имейл адрес ще получиш инструкции за отключването му до няколко минути. | |||
unlocked: Твоят профил беше отключен успешно. За да продължиш, влез в него. | |||
errors: | |||
messages: | |||
already_confirmed: е вече потвърден, моля опитай да влезеш в профила си с него | |||
confirmation_period_expired: "трябва да се потвърди в рамките на %{period}, моля направи нова заявка за потвърждение" | |||
expired: е изтекъл, моля заяви нов | |||
not_found: не е намерен | |||
not_locked: не бе заключен | |||
not_saved: | |||
one: "Една грешка попречи този %{resource} да бъде записан:" | |||
other: "%{count} грешки попречиха този %{resource} да бъде записан:" |
@ -0,0 +1,113 @@ | |||
--- | |||
bg: | |||
activerecord: | |||
attributes: | |||
doorkeeper/application: | |||
name: Име | |||
redirect_uri: URI за пренасочване | |||
errors: | |||
models: | |||
doorkeeper/application: | |||
attributes: | |||
redirect_uri: | |||
fragment_present: не може да съдържа фрагмент. | |||
invalid_uri: трябва да е валидно URI. | |||
relative_uri: трябва да е абсолютно URI. | |||
secured_uri: трябва да е HTTPS/SSL URI. | |||
doorkeeper: | |||
applications: | |||
buttons: | |||
authorize: Упълномощаване | |||
cancel: Отказ | |||
destroy: Унищожаване | |||
edit: Редакция | |||
submit: Изпращане | |||
confirmations: | |||
destroy: Потвърждаваш ли изтриването? | |||
edit: | |||
title: Редактиране на приложението | |||
form: | |||
error: О, не! Провери формата за възможни грешки | |||
help: | |||
native_redirect_uri: Изполвай %{native_redirect_uri} за локални тестове | |||
redirect_uri: Използвай един ред за всяко URI | |||
scopes: Разделяй диапазоните с интервал. Остави празно, за да използваш диапазона по подразбиране. | |||
index: | |||
callback_url: URL за обратно повикване | |||
name: Име | |||
new: Ново приложение | |||
title: Твоите приложения | |||
new: | |||
title: Ново приложение | |||
show: | |||
actions: Действия | |||
application_id: Идентификатор на приложението | |||
callback_urls: URL-и за обратно повикване | |||
scopes: Диапазони | |||
secret: Тайна | |||
title: 'Приложение: %{name}' | |||
authorizations: | |||
buttons: | |||
authorize: Упълномощаване | |||
deny: Отказ | |||
error: | |||
title: Възникна грешка | |||
new: | |||
able_to: Ще е възможно | |||
prompt: Приложението %{client_name} заявява достъп до твоя акаунт | |||
title: Изисква се упълномощаване | |||
show: | |||
title: Код за упълномощаване | |||
authorized_applications: | |||
buttons: | |||
revoke: Отмяна | |||
confirmations: | |||
revoke: Потвърждаваш ли отмяната? | |||
index: | |||
application: Приложение | |||
created_at: Създадено на | |||
date_format: "%Y-%m-%d %H:%M:%S" | |||
scopes: Диапазони | |||
title: Твоите упълномощени приложения | |||
errors: | |||
messages: | |||
access_denied: Заявката беше отказана от собственика на ресурса или от сървъра за упълномощаване. | |||
credential_flow_not_configured: Resource Owner Password Credentials предизвика грешка, заради това, че настройките за Doorkeeper.configure.resource_owner_from_credentials липсват. | |||
invalid_client: Удостоверяването на клиента предизвика грешка, поради непознат клиент, липсващо клиентско удостоверяване, или заради това, че методът на удостоверяване не се поддържа. | |||
invalid_grant: Предоставеното удостоверение за достъп е невалидно, изтекло, отхвърлено, не съвпада с пренасочващото URI, използвано в заявката за удостоверение, или е бил издадено от друг клиент. | |||
invalid_redirect_uri: Наличното пренасочващо URI е невалидно. | |||
invalid_request: Заявката е с липсващ задължителен параметър, включва стойност на параметъра, която не се поддържа, или е изкривена по друг начин. | |||
invalid_resource_owner: Предоставените идентификационни данни на притежателя на ресурса са невалидни, или притежателят не може да бъде намерен. | |||
invalid_scope: Заявеният диапазон е невалиден, неизвестен или изкривен. | |||
invalid_token: | |||
expired: Маркерът за достъп изтече | |||
revoked: Маркерът за достъп беше отхвърлен | |||
unknown: Маркерът за достъп е невалиден | |||
resource_owner_authenticator_not_configured: Намирането на Resource Owner се провали поради липса на конфигурация на Doorkeeper.configure.resource_owner_authenticator. | |||
server_error: Сървърът за удостоверяване попадна на неочаквано условие, което предотврати изпълнението на заявката. | |||
temporarily_unavailable: Сървърът за удостоверяване не може да се справи със заявката в момента поради временно претоварване или профилактика на сървъра. | |||
unauthorized_client: Клиентът не е удостоверен да изпълни заявката по този начин. | |||
unsupported_grant_type: Типът на удостоврението за достъп не се поддържа от сървъра за удостоверяване. | |||
unsupported_response_type: Удостоверяващият сървър не поддържа този тип отговор. | |||
flash: | |||
applications: | |||
create: | |||
notice: Приложението е създадено. | |||
destroy: | |||
notice: Приложението е изтрито. | |||
update: | |||
notice: Приложението е обновено. | |||
authorized_applications: | |||
destroy: | |||
notice: Приложението е отказано. | |||
layouts: | |||
admin: | |||
nav: | |||
applications: Приложения | |||
oauth2_provider: OAuth2 доставчик | |||
application: | |||
title: Нужно е упълномощаване по OAuth | |||
scopes: | |||
follow: следването, блокирането, деблокирането и отмяната на следването на акаунтите | |||
read: четенето на данните от твоя акаунт | |||
write: публикуването от твое име |
@ -0,0 +1,46 @@ | |||
--- | |||
bg: | |||
simple_form: | |||
hints: | |||
defaults: | |||
avatar: PNG, GIF или JPG. До 2MB. Ще бъде смалена до 120x120 пиксела | |||
display_name: До 30 символа | |||
header: PNG, GIF или JPG. До 2MB. Ще бъде смалена до 700x335 пиксела | |||
locked: Изисква ръчно одобрение на последователите. По подразбиране, публикациите са достъпни само до последователи. | |||
note: До 160 символа | |||
imports: | |||
data: CSV файл, експортиран от друга инстанция на Mastodon | |||
labels: | |||
defaults: | |||
avatar: Аватар | |||
confirm_new_password: Потвърди новата парола | |||
confirm_password: Потвърди паролата | |||
current_password: Текуща парола | |||
data: Данни | |||
display_name: Показвано име | |||
email: E-mail адрес | |||
header: Заглавен ред | |||
locale: Език | |||
locked: Направи акаунта поверителен | |||
new_password: Нова парола | |||
note: Био | |||
otp_attempt: Двустепенен код | |||
password: Парола | |||
setting_default_privacy: Поверителност на публикациите | |||
type: Тип на импортиране | |||
username: Потребителско име | |||
interactions: | |||
must_be_follower: Блокирай известия от не-последователи | |||
must_be_following: Блокирай известия от хора, които не следваш | |||
notification_emails: | |||
digest: Изпращай извлечения на съобщенията | |||
favourite: Изпращай e-mail, когато някой хареса твоя публикация | |||
follow: Изпращай e-mail, когато някой те последва | |||
follow_request: Изпращай e-mail, когато някой пожелае да те последва | |||
mention: Изпращай e-mail, когато някой те спомене | |||
reblog: Изпращай e-mail, когато някой сподели твоя публикация | |||
'no': 'Не' | |||
required: | |||
mark: "*" | |||
text: задължително | |||
'yes': 'Да' |
@ -0,0 +1,24 @@ | |||
require 'rails_helper' | |||
describe Admin::SilencesController do | |||
let(:account) { Fabricate(:account) } | |||
before do | |||
sign_in Fabricate(:user, admin: true), scope: :user | |||
end | |||
describe 'POST #create' do | |||
it 'redirects to admin accounts page' do | |||
post :create, params: { account_id: account.id } | |||
expect(response).to redirect_to(admin_accounts_path) | |||
end | |||
end | |||
describe 'DELETE #destroy' do | |||
it 'redirects to admin accounts page' do | |||
delete :destroy, params: { account_id: account.id } | |||
expect(response).to redirect_to(admin_accounts_path) | |||
end | |||
end | |||
end |
@ -0,0 +1,24 @@ | |||
require 'rails_helper' | |||
describe Admin::SuspensionsController do | |||
let(:account) { Fabricate(:account) } | |||
before do | |||
sign_in Fabricate(:user, admin: true), scope: :user | |||
end | |||
describe 'POST #create' do | |||
it 'redirects to admin accounts page' do | |||
post :create, params: { account_id: account.id } | |||
expect(response).to redirect_to(admin_accounts_path) | |||
end | |||
end | |||
describe 'DELETE #destroy' do | |||
it 'redirects to admin accounts page' do | |||
delete :destroy, params: { account_id: account.id } | |||
expect(response).to redirect_to(admin_accounts_path) | |||
end | |||
end | |||
end |
@ -0,0 +1,13 @@ | |||
require 'rails_helper' | |||
describe WellKnown::HostMetaController, type: :controller do | |||
render_views | |||
describe 'GET #show' do | |||
it 'returns http success' do | |||
get :show, format: :xml | |||
expect(response).to have_http_status(:success) | |||
end | |||
end | |||
end |
@ -0,0 +1,21 @@ | |||
require 'rails_helper' | |||
describe WellKnown::WebfingerController, type: :controller do | |||
render_views | |||
describe 'GET #show' do | |||
let(:alice) { Fabricate(:account, username: 'alice') } | |||
it 'returns http success when account can be found' do | |||
get :show, params: { resource: alice.to_webfinger_s }, format: :json | |||
expect(response).to have_http_status(:success) | |||
end | |||
it 'returns http not found when account cannot be found' do | |||
get :show, params: { resource: 'acct:not@existing.com' }, format: :json | |||
expect(response).to have_http_status(:not_found) | |||
end | |||
end | |||
end |
@ -1,26 +0,0 @@ | |||
require 'rails_helper' | |||
RSpec.describe XrdController, type: :controller do | |||
render_views | |||
describe 'GET #host_meta' do | |||
it 'returns http success' do | |||
get :host_meta | |||
expect(response).to have_http_status(:success) | |||
end | |||
end | |||
describe 'GET #webfinger' do | |||
let(:alice) { Fabricate(:account, username: 'alice') } | |||
it 'returns http success when account can be found' do | |||
get :webfinger, params: { resource: alice.to_webfinger_s }, format: :json | |||
expect(response).to have_http_status(:success) | |||
end | |||
it 'returns http not found when account cannot be found' do | |||
get :webfinger, params: { resource: 'acct:not@existing.com' }, format: :json | |||
expect(response).to have_http_status(:not_found) | |||
end | |||
end | |||
end |
@ -0,0 +1,31 @@ | |||
require 'rails_helper' | |||
describe AccountFilter do | |||
describe 'with empty params' do | |||
it 'defaults to alphabetic account list' do | |||
filter = AccountFilter.new({}) | |||
expect(filter.results).to eq Account.alphabetic | |||
end | |||
end | |||
describe 'with invalid params' do | |||
it 'raises with key error' do | |||
filter = AccountFilter.new(wrong: true) | |||
expect { filter.results }.to raise_error(/wrong/) | |||
end | |||
end | |||
describe 'with valid params' do | |||
it 'combines filters on Account' do | |||
filter = AccountFilter.new(by_domain: 'test.com', silenced: true) | |||
allow(Account).to receive(:where).and_return(Account.none) | |||
allow(Account).to receive(:silenced).and_return(Account.none) | |||
filter.results | |||
expect(Account).to have_received(:where).with(domain: 'test.com') | |||
expect(Account).to have_received(:silenced) | |||
end | |||
end | |||
end |
@ -0,0 +1,12 @@ | |||
require "rails_helper" | |||
describe "The host_meta route" do | |||
describe "requested without accepts headers" do | |||
it "returns an xml response" do | |||
get host_meta_url | |||
expect(response).to have_http_status(:success) | |||
expect(response.content_type).to eq "application/xrd+xml" | |||
end | |||
end | |||
end |
@ -0,0 +1,15 @@ | |||
require 'rails_helper' | |||
describe 'the host-meta route' do | |||
it 'routes to correct place with xml format' do | |||
expect(get('/.well-known/host-meta')). | |||
to route_to('well_known/host_meta#show', format: 'xml') | |||
end | |||
end | |||
describe 'the webfinger route' do | |||
it 'routes to correct place with json format' do | |||
expect(get('/.well-known/webfinger')). | |||
to route_to('well_known/webfinger#show', format: 'json') | |||
end | |||
end |