From 35933167c0c84033d062a6cc73213fc4c222e4d3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 30 Mar 2017 04:47:04 +0200 Subject: Add counter caches for a large performance increase on API requests --- app/controllers/api/v1/accounts_controller.rb | 10 +++++----- app/controllers/api/v1/blocks_controller.rb | 2 +- app/controllers/api/v1/favourites_controller.rb | 2 +- app/controllers/api/v1/follow_requests_controller.rb | 2 +- app/controllers/api/v1/mutes_controller.rb | 2 +- app/controllers/api/v1/notifications_controller.rb | 4 ++-- app/controllers/api/v1/statuses_controller.rb | 6 +++--- app/models/favourite.rb | 2 +- app/models/follow.rb | 4 ++-- app/models/status.rb | 4 ++-- app/views/api/v1/statuses/_show.rabl | 4 ++-- db/migrate/20170330021336_add_counter_caches.rb | 14 ++++++++++++++ db/schema.rb | 7 ++++++- 13 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 db/migrate/20170330021336_add_counter_caches.rb diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index f07450eb0..da18474cb 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -20,7 +20,7 @@ class Api::V1::AccountsController < ApiController accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h @accounts = results.map { |f| accounts[f.target_account_id] } - set_account_counters_maps(@accounts) + # set_account_counters_maps(@accounts) next_path = following_api_v1_account_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) prev_path = following_api_v1_account_url(since_id: results.first.id) unless results.empty? @@ -35,7 +35,7 @@ class Api::V1::AccountsController < ApiController accounts = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h @accounts = results.map { |f| accounts[f.account_id] } - set_account_counters_maps(@accounts) + # set_account_counters_maps(@accounts) next_path = followers_api_v1_account_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) prev_path = followers_api_v1_account_url(since_id: results.first.id) unless results.empty? @@ -52,8 +52,8 @@ class Api::V1::AccountsController < ApiController @statuses = cache_collection(@statuses, Status) set_maps(@statuses) - set_counters_maps(@statuses) - set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq) + # set_counters_maps(@statuses) + # set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq) next_path = statuses_api_v1_account_url(max_id: @statuses.last.id) unless @statuses.empty? prev_path = statuses_api_v1_account_url(since_id: @statuses.first.id) unless @statuses.empty? @@ -117,7 +117,7 @@ class Api::V1::AccountsController < ApiController def search @accounts = AccountSearchService.new.call(params[:q], limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:resolve] == 'true', current_account) - set_account_counters_maps(@accounts) unless @accounts.nil? + # set_account_counters_maps(@accounts) unless @accounts.nil? render action: :index end diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb index 08aefc175..dadf21265 100644 --- a/app/controllers/api/v1/blocks_controller.rb +++ b/app/controllers/api/v1/blocks_controller.rb @@ -11,7 +11,7 @@ class Api::V1::BlocksController < ApiController accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h @accounts = results.map { |f| accounts[f.target_account_id] }.compact - set_account_counters_maps(@accounts) + # set_account_counters_maps(@accounts) next_path = api_v1_blocks_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) prev_path = api_v1_blocks_url(since_id: results.first.id) unless results.empty? diff --git a/app/controllers/api/v1/favourites_controller.rb b/app/controllers/api/v1/favourites_controller.rb index ef0a4854a..8a5b81e63 100644 --- a/app/controllers/api/v1/favourites_controller.rb +++ b/app/controllers/api/v1/favourites_controller.rb @@ -11,7 +11,7 @@ class Api::V1::FavouritesController < ApiController @statuses = cache_collection(Status.where(id: results.map(&:status_id)), Status) set_maps(@statuses) - set_counters_maps(@statuses) + # set_counters_maps(@statuses) next_path = api_v1_favourites_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_STATUSES_LIMIT) prev_path = api_v1_favourites_url(since_id: results.first.id) unless results.empty? diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb index 740083735..3b8e8c078 100644 --- a/app/controllers/api/v1/follow_requests_controller.rb +++ b/app/controllers/api/v1/follow_requests_controller.rb @@ -9,7 +9,7 @@ class Api::V1::FollowRequestsController < ApiController accounts = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h @accounts = results.map { |f| accounts[f.account_id] } - set_account_counters_maps(@accounts) + # set_account_counters_maps(@accounts) next_path = api_v1_follow_requests_url(max_id: results.last.id) if results.size == DEFAULT_ACCOUNTS_LIMIT prev_path = api_v1_follow_requests_url(since_id: results.first.id) unless results.empty? diff --git a/app/controllers/api/v1/mutes_controller.rb b/app/controllers/api/v1/mutes_controller.rb index 42a9ed412..6f48de040 100644 --- a/app/controllers/api/v1/mutes_controller.rb +++ b/app/controllers/api/v1/mutes_controller.rb @@ -11,7 +11,7 @@ class Api::V1::MutesController < ApiController accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h @accounts = results.map { |f| accounts[f.target_account_id] } - set_account_counters_maps(@accounts) + # set_account_counters_maps(@accounts) next_path = api_v1_mutes_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) prev_path = api_v1_mutes_url(since_id: results.first.id) unless results.empty? diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb index 544ba2442..7bbc5419c 100644 --- a/app/controllers/api/v1/notifications_controller.rb +++ b/app/controllers/api/v1/notifications_controller.rb @@ -14,8 +14,8 @@ class Api::V1::NotificationsController < ApiController statuses = @notifications.select { |n| !n.target_status.nil? }.map(&:target_status) set_maps(statuses) - set_counters_maps(statuses) - set_account_counters_maps(@notifications.map(&:from_account)) + # set_counters_maps(statuses) + # set_account_counters_maps(@notifications.map(&:from_account)) next_path = api_v1_notifications_url(max_id: @notifications.last.id) unless @notifications.empty? prev_path = api_v1_notifications_url(since_id: @notifications.first.id) unless @notifications.empty? diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 552f1b1b3..024258c0e 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -23,7 +23,7 @@ class Api::V1::StatusesController < ApiController statuses = [@status] + @context[:ancestors] + @context[:descendants] set_maps(statuses) - set_counters_maps(statuses) + # set_counters_maps(statuses) end def card @@ -36,7 +36,7 @@ class Api::V1::StatusesController < ApiController accounts = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h @accounts = results.map { |r| accounts[r.account_id] } - set_account_counters_maps(@accounts) + # set_account_counters_maps(@accounts) next_path = reblogged_by_api_v1_status_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) prev_path = reblogged_by_api_v1_status_url(since_id: results.first.id) unless results.empty? @@ -51,7 +51,7 @@ class Api::V1::StatusesController < ApiController accounts = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h @accounts = results.map { |f| accounts[f.account_id] } - set_account_counters_maps(@accounts) + # set_account_counters_maps(@accounts) next_path = favourited_by_api_v1_status_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) prev_path = favourited_by_api_v1_status_url(since_id: results.first.id) unless results.empty? diff --git a/app/models/favourite.rb b/app/models/favourite.rb index 67a293888..41d06e734 100644 --- a/app/models/favourite.rb +++ b/app/models/favourite.rb @@ -4,7 +4,7 @@ class Favourite < ApplicationRecord include Paginable belongs_to :account, inverse_of: :favourites - belongs_to :status, inverse_of: :favourites + belongs_to :status, inverse_of: :favourites, counter_cache: true has_one :notification, as: :activity, dependent: :destroy diff --git a/app/models/follow.rb b/app/models/follow.rb index 57db8c462..8bfe8b2f6 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -3,8 +3,8 @@ class Follow < ApplicationRecord include Paginable - belongs_to :account - belongs_to :target_account, class_name: 'Account' + belongs_to :account, counter_cache: :following_count + belongs_to :target_account, class_name: 'Account', counter_cache: :followers_count has_one :notification, as: :activity, dependent: :destroy diff --git a/app/models/status.rb b/app/models/status.rb index d5bbf70fb..81b26fd14 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -10,11 +10,11 @@ class Status < ApplicationRecord belongs_to :application, class_name: 'Doorkeeper::Application' - belongs_to :account, inverse_of: :statuses + belongs_to :account, inverse_of: :statuses, counter_cache: true belongs_to :in_reply_to_account, foreign_key: 'in_reply_to_account_id', class_name: 'Account' belongs_to :thread, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :replies - belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs + belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, counter_cache: :reblogs_count has_many :favourites, inverse_of: :status, dependent: :destroy has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy diff --git a/app/views/api/v1/statuses/_show.rabl b/app/views/api/v1/statuses/_show.rabl index 059e0d13f..f384b6d14 100644 --- a/app/views/api/v1/statuses/_show.rabl +++ b/app/views/api/v1/statuses/_show.rabl @@ -3,8 +3,8 @@ attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, :sensitiv node(:uri) { |status| TagManager.instance.uri_for(status) } node(:content) { |status| Formatter.instance.format(status) } node(:url) { |status| TagManager.instance.url_for(status) } -node(:reblogs_count) { |status| defined?(@reblogs_counts_map) ? (@reblogs_counts_map[status.id] || 0) : status.reblogs.count } -node(:favourites_count) { |status| defined?(@favourites_counts_map) ? (@favourites_counts_map[status.id] || 0) : status.favourites.count } +node(:reblogs_count) { |status| defined?(@reblogs_counts_map) ? (@reblogs_counts_map[status.id] || 0) : (status.try(:reblogs_count) || status.reblogs.count) } +node(:favourites_count) { |status| defined?(@favourites_counts_map) ? (@favourites_counts_map[status.id] || 0) : (status.try(:favourites_count) || status.favourites.count) } child :application do extends 'api/v1/apps/show' diff --git a/db/migrate/20170330021336_add_counter_caches.rb b/db/migrate/20170330021336_add_counter_caches.rb new file mode 100644 index 000000000..eb4e54d0a --- /dev/null +++ b/db/migrate/20170330021336_add_counter_caches.rb @@ -0,0 +1,14 @@ +class AddCounterCaches < ActiveRecord::Migration[5.0] + def change + add_column :statuses, :favourites_count, :integer + add_column :statuses, :reblogs_count, :integer + + execute('update statuses set favourites_count = (select count(*) from favourites where favourites.status_id = statuses.id), reblogs_count = (select count(*) from statuses as reblogs where reblogs.reblog_of_id = statuses.id)') + + add_column :accounts, :statuses_count, :integer + add_column :accounts, :followers_count, :integer + add_column :accounts, :following_count, :integer + + execute('update accounts set statuses_count = (select count(*) from statuses where account_id = accounts.id), followers_count = (select count(*) from follows where target_account_id = accounts.id), following_count = (select count(*) from follows where account_id = accounts.id)') + end +end diff --git a/db/schema.rb b/db/schema.rb index 2457b523d..52437ca57 100644 --- a/db/schema.rb +++ b/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: 20170322162804) do +ActiveRecord::Schema.define(version: 20170330021336) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -44,6 +44,9 @@ ActiveRecord::Schema.define(version: 20170322162804) do t.boolean "suspended", default: false, null: false t.boolean "locked", default: false, null: false t.string "header_remote_url", default: "", null: false + t.integer "statuses_count" + t.integer "followers_count" + t.integer "following_count" t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower", using: :btree t.index ["username", "domain"], name: "index_accounts_on_username_and_domain", unique: true, using: :btree @@ -220,6 +223,8 @@ ActiveRecord::Schema.define(version: 20170322162804) do t.integer "application_id" t.text "spoiler_text", default: "", null: false t.boolean "reply", default: false + t.integer "favourites_count" + t.integer "reblogs_count" t.index ["account_id"], name: "index_statuses_on_account_id", using: :btree t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id", using: :btree t.index ["reblog_of_id"], name: "index_statuses_on_reblog_of_id", using: :btree -- cgit From 69fc95a2f5e7cf90fcf86c24f8e7eabd6cfd67d6 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 12:09:33 +0200 Subject: Create Finnish translation for Mastodon Create Finnish translation for Mastodon --- app/assets/javascripts/components/locales/fi.jsx | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 app/assets/javascripts/components/locales/fi.jsx diff --git a/app/assets/javascripts/components/locales/fi.jsx b/app/assets/javascripts/components/locales/fi.jsx new file mode 100644 index 000000000..5bef99923 --- /dev/null +++ b/app/assets/javascripts/components/locales/fi.jsx @@ -0,0 +1,68 @@ +const fi = { + "column_back_button.label": "Takaisin", + "lightbox.close": "Sulje", + "loading_indicator.label": "Ladataan...", + "status.mention": "Mainitse @{name}", + "status.delete": "Poista", + "status.reply": "Vastaa", + "status.reblog": "Boostaa", + "status.favourite": "Tykkää", + "status.reblogged_by": "{name} boostattu", + "status.sensitive_warning": "Arkaluontoista sisältöä", + "status.sensitive_toggle": "Klikkaa nähdäksesi", + "video_player.toggle_sound": "Äänet päälle/pois", + "account.mention": "Mainitse @{name}", + "account.edit_profile": "Muokkaa", + "account.unblock": "Salli @{name}", + "account.unfollow": "Lopeta seuraaminen", + "account.block": "Estä @{name}", + "account.follow": "Seuraa", + "account.posts": "Postit", + "account.follows": "Seuraa", + "account.followers": "Seuraajia", + "account.follows_you": "Seuraa sinua", + "account.requested": "Odottaa hyväksyntää", + "getting_started.heading": "Päästä alkuun", + "getting_started.about_addressing": "Voit seurata ihmisiä jos tiedät heidän käyttäjänimensä ja domainin missä he ovat syöttämällä e-mail-esque osoitteen Etsi kenttään.", + "getting_started.about_shortcuts": "Jos etsimäsi henkilö on samassa domainissa kuin sinä, pelkkä käyttäjänimi kelpaa. Sama pätee kun mainitset ihmisiä statuksessasi", + "getting_started.open_source_notice": "Mastodon Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia githubissa {github}. {apps}.", + "column.home": "Koti", + "column.community": "Paikallinen aikajana", + "column.public": "Yhdistetty aikajana", + "column.notifications": "Ilmoitukset", + "tabs_bar.compose": "Luo", + "tabs_bar.home": "Koti", + "tabs_bar.mentions": "Maininnat", + "tabs_bar.public": "Yleinen aikajana", + "tabs_bar.notifications": "Ilmoitukset", + "compose_form.placeholder": "Mitä sinulla on mielessä?", + "compose_form.publish": "Toot", + "compose_form.sensitive": "Merkitse media herkäksi", + "compose_form.spoiler": "Piiloita teksti varoituksen taakse", + "compose_form.private": "Merkitse yksityiseksi", + "compose_form.privacy_disclaimer": "Sinun yksityinen status toimitetaan mainitsemallesi käyttäjille domaineissa {domains}. Luotatko {domainsCount, plural, one {tähän palvelimeen} other {näihin palvelimiin}}? Postauksen yksityisyys toimii van Mastodon palvelimilla. Jos {domains} {domainsCount, plural, one {ei ole Mastodon palvelin} other {eivät ole Mastodon palvelin}}, viestiin ei tule Yksityinen-merkintää, ja sitä voidaan boostata tai muuten tehdä näkyväksi muille vastaanottajille.", + "compose_form.unlisted": "Älä näytä julkisilla aikajanoilla", + "navigation_bar.edit_profile": "Muokkaa profiilia", + "navigation_bar.preferences": "Ominaisuudet", + "navigation_bar.community_timeline": "Paikallinen aikajana", + "navigation_bar.public_timeline": "Yleinen aikajana", + "navigation_bar.logout": "Kirjaudu ulos", + "reply_indicator.cancel": "Peruuta", + "search.placeholder": "Hae", + "search.account": "Tili", + "search.hashtag": "Hashtag", + "upload_button.label": "Lisää mediaa", + "upload_form.undo": "Peru", + "notification.follow": "{name} seurasi sinua", + "notification.favourite": "{name} tykkäsi statuksestasi", + "notification.reblog": "{name} boostasi statustasi", + "notification.mention": "{name} mainitsi sinut", + "notifications.column_settings.alert": "Työpöytä ilmoitukset", + "notifications.column_settings.show": "Näytä sarakkeessa", + "notifications.column_settings.follow": "Uusia seuraajia:", + "notifications.column_settings.favourite": "Tykkäyksiä:", + "notifications.column_settings.mention": "Mainintoja:", + "notifications.column_settings.reblog": "Boosteja:", +}; + +export default fi; -- cgit From 87854745e966e05231321477d34e8a233814788d Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 12:42:09 +0200 Subject: Create new translation file Still in progress. Should be done shortly --- config/locales/fi.yml | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 config/locales/fi.yml diff --git a/config/locales/fi.yml b/config/locales/fi.yml new file mode 100644 index 000000000..33e17a78b --- /dev/null +++ b/config/locales/fi.yml @@ -0,0 +1,164 @@ +--- +fi: + about: + about_mastodon: Mastodon on ilmainen, avoimeen lähdekoodiin perustuva sosiaalinen verkosto. Hajautettu vaihtoehto kaupallisille alustoille, se välttää eiskit yhden yrityksen monopolisoinnin sinun viestinnässäsi. Valitse palvelin mihin luotat — minkä tahansa valitset, voit vuorovaikuttaa muiden kanssa. Kuka tahansa voi luoda Mastodon palvelimen ja ottaa osaa sosiaaliseen verkkoon saumattomasti. + about_this: Tietoja tästä palvelimesta + apps: Ohjelmat + business_email: 'Business e-mail:' + contact: Ota yhteyttä + description_headline: Mikä on %{domain}? + domain_count_after: muut palvelimet + domain_count_before: Yhdistyneenä + features: + api: Avoin API ohjelmille ja palveluille + blocks: Rikkaat esto ja hiljennys työkalut + characters: 500 kirjainta per viesti + chronology: Aikajana on kronologisessa järjestyksessä + ethics: 'Eettinen suunnittelu: ei mainoksia, no seurantaa' + gifv: GIFV settejä ja lyhyitä videoita + privacy: Julkaisu kohtainen yksityisyys aseuts + public: Julkiset aikajanat + features_headline: Mikä erottaa Mastodonin muista + get_started: Aloita käyttö + links: Linkit + other_instances: Muut palvelimet + source_code: Lähdekoodi + status_count_after: statukset + status_count_before: Kuka loi + terms: Ehdot + user_count_after: käyttäjät + user_count_before: Koti käyttäjälle + accounts: + follow: Seuraa + followers: Seuraajat + following: Seuratut + nothing_here: Täällä ei ole mitään! + people_followed_by: Henkilöitä joita %{name} seuraa + people_who_follow: Henkilöt jotka seuraa %{name} + posts: Postaukset + remote_follow: Etäseuranta + unfollow: Lopeta seuraaminen + application_mailer: + settings: 'Muokkaa sähköposti asetuksia: %{link}' + signature: Mastodon ilmoituksia palvelimelta %{instance} + view: 'Katso:' + applications: + invalid_url: Annettu URL on väärä + auth: + change_password: Tunnukset + didnt_get_confirmation: Etkö saanut varmennus ohjeita? + forgot_password: Unohditko salasanasi? + login: Kirjaudu sisään + logout: Kirjaudu ulos + register: Rekisteröidy + resend_confirmation: Lähetä varmennus ohjeet uudestaan + reset_password: Palauta Salasana + set_new_password: Aseta uusi salasana + authorize_follow: + error: Valitettavasti tapahtui virhe etätilin haussa + follow: Seuraa + prompt_html: 'Sinä (%{self}) olet pyytänyt lupaa seurata:' + title: Seuraa %{acct} + datetime: + distance_in_words: + about_x_hours: "%{count}t" + about_x_months: "%{count}kk" + about_x_years: "%{count}v" + almost_x_years: "%{count}v" + half_a_minute: Juuri nyt + less_than_x_minutes: "%{count}m" + less_than_x_seconds: Juuri nyt + over_x_years: "%{count}v" + x_days: "%{count}pv" + x_minutes: "%{count}m" + x_months: "%{count}kk" + x_seconds: "%{count}s" + exports: + blocks: Estosi + csv: CSV + follows: Seurattavat + storage: Mediasi + generic: + changes_saved_msg: Muutokset onnistuneesti tallenettu! + powered_by: powered by %{link} + save_changes: Tallenna muutokset + validation_errors: + one: Jokin ei ole viellä oikein! Katso virhe alapuolelta + other: Jokin ei ole viellä oikein! Katso %{count} virhettä alapuolelta + imports: + preface: Voit tuoda tiettyä dataa kaikista ihmisistä joita seuraat tai estät tilillesi tälle palvelimelle tiedostoista, jotka on luotu toisella palvelimella + success: Datasi on onnistuneesti ladattu ja käsitellään pian + types: + blocking: Esto lista + following: Seuratut lista + upload: Lähetä + landing_strip_html: %{name} is a user on %{domain}. You can follow them or interact with them if you have an account anywhere in the fediverse. If you don't, you can sign up here. + notification_mailer: + digest: + body: 'Here is a brief summary of what you missed on %{instance} since your last visit on %{since}:' + mention: "%{name} mentioned you in:" + new_followers_summary: + one: You have acquired one new follower! Yay! + other: You have gotten %{count} new followers! Amazing! + subject: + one: "1 new notification since your last visit \U0001F418" + other: "%{count} new notifications since your last visit \U0001F418" + favourite: + body: 'Your status was favourited by %{name}:' + subject: "%{name} favourited your status" + follow: + body: "%{name} is now following you!" + subject: "%{name} is now following you" + follow_request: + body: "%{name} has requested to follow you" + subject: 'Pending follower: %{name}' + mention: + body: 'You were mentioned by %{name} in:' + subject: You were mentioned by %{name} + reblog: + body: 'Your status was boosted by %{name}:' + subject: "%{name} boosted your status" + pagination: + next: Next + prev: Prev + remote_follow: + acct: Enter your username@domain you want to follow from + missing_resource: Could not find the required redirect URL for your account + proceed: Proceed to follow + prompt: 'You are going to follow:' + settings: + authorized_apps: Authorized apps + back: Back to Mastodon + edit_profile: Edit profile + export: Data export + import: Import + preferences: Preferences + settings: Settings + two_factor_auth: Two-factor Authentication + statuses: + open_in_web: Open in web + over_character_limit: character limit of %{max} exceeded + show_more: Show more + visibilities: + private: Only show to followers + public: Public + unlisted: Public, but do not display on the public timeline + stream_entries: + click_to_show: Click to show + reblogged: boosted + sensitive_content: Sensitive content + time: + formats: + default: "%b %d, %Y, %H:%M" + two_factor_auth: + description_html: If you enable two-factor authentication, logging in will require you to be in possession of your phone, which will generate tokens for you to enter. + disable: Disable + enable: Enable + instructions_html: "Scan this QR code into Google Authenticator or a similiar app on your phone. From now on, that app will generate tokens that you will have to enter when logging in." + plaintext_secret_html: 'Plain-text secret: %{secret}' + warning: If you cannot configure an authenticator app right now, you should click "disable" or you won't be able to login. + users: + invalid_email: The e-mail address is invalid + invalid_otp_token: Invalid two-factor code + will_paginate: + page_gap: "…" -- cgit From f9b4f30de6829ec1a34fe37ae713865177ac1420 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 13:07:09 +0200 Subject: updated final translation updated final translation --- config/locales/fi.yml | 92 +++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 33e17a78b..3bcfe5c20 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -92,73 +92,73 @@ fi: blocking: Esto lista following: Seuratut lista upload: Lähetä - landing_strip_html: %{name} is a user on %{domain}. You can follow them or interact with them if you have an account anywhere in the fediverse. If you don't, you can sign up here. + landing_strip_html: %{name} on käyttäjä domainilla %{domain}. Voit seurata tai vuorovaikuttaa heidän kanssaan jos sinulla on tili yleisessä verkossa. Jos sinulla ei ole tiliä, voit rekisteröityä täällä. notification_mailer: digest: - body: 'Here is a brief summary of what you missed on %{instance} since your last visit on %{since}:' - mention: "%{name} mentioned you in:" + body: 'Tässä on pieni yhteenveto palvelimelta %{instance} viimeksi kun olit paikalla %{since}:' + mention: "%{name} mainitsi sinut:" new_followers_summary: - one: You have acquired one new follower! Yay! - other: You have gotten %{count} new followers! Amazing! + one: Olet saanut yhden uuden seuraajan! Jee! + other: Olet saanut %{count} uutta seuraajaa! Loistavaa! subject: - one: "1 new notification since your last visit \U0001F418" - other: "%{count} new notifications since your last visit \U0001F418" + one: "1 uusi ilmoitus viimeisen käyntisi jälkeen \U0001F418" + other: "%{count} uutta ilmoitusta viimeisen käyntisi jälkeen \U0001F418" favourite: - body: 'Your status was favourited by %{name}:' - subject: "%{name} favourited your status" + body: 'Statuksestasi tykkäsi %{name}:' + subject: "%{name} tykkäsi sinun statuksestasi" follow: - body: "%{name} is now following you!" - subject: "%{name} is now following you" + body: "%{name} seuraa nyt sinua!" + subject: "%{name} seuraa nyt sinua" follow_request: - body: "%{name} has requested to follow you" - subject: 'Pending follower: %{name}' + body: "%{name} on pyytänyt seurata sinua" + subject: 'Odottava seuraus pyyntö: %{name}' mention: - body: 'You were mentioned by %{name} in:' - subject: You were mentioned by %{name} + body: 'Sinut mainitsi %{name} postauksessa:' + subject: Sinut mainitsi %{name} reblog: - body: 'Your status was boosted by %{name}:' - subject: "%{name} boosted your status" + body: 'Sinun statustasi boostasi %{name}:' + subject: "%{name} boostasi statustasi" pagination: - next: Next - prev: Prev + next: Seuraava + prev: Edellinen remote_follow: - acct: Enter your username@domain you want to follow from - missing_resource: Could not find the required redirect URL for your account - proceed: Proceed to follow - prompt: 'You are going to follow:' + acct: Syötä sinun käyttäjänimesi@domain jos haluat seurata palvelimelta + missing_resource: Ei löydetty tarvittavaa uudelleenohjaavaa URL-linkkiä tilillesi + proceed: Siirry seuraamiseen + prompt: 'Sinä aiot seurata:' settings: - authorized_apps: Authorized apps - back: Back to Mastodon - edit_profile: Edit profile - export: Data export - import: Import - preferences: Preferences - settings: Settings - two_factor_auth: Two-factor Authentication + authorized_apps: Valtuutetut ohjelmat + back: Takaisin Mastodoniin + edit_profile: Muokkaa profiilia + export: Datan vienti + import: Datan tuonti + preferences: Mieltymykset + settings: Asetukset + two_factor_auth: Kaksivaiheinen tunnistus statuses: - open_in_web: Open in web - over_character_limit: character limit of %{max} exceeded - show_more: Show more + open_in_web: Avaa webissä + over_character_limit: sallittu kirjanmäärä %{max} ylitetty + show_more: Näytä lisää visibilities: - private: Only show to followers - public: Public - unlisted: Public, but do not display on the public timeline + private: Näytä vain seuraajille + public: Julkinen + unlisted: Julkinen, mutta älä näytä julkisella aikajanalla stream_entries: - click_to_show: Click to show + click_to_show: Klikkaa näyttääksesi reblogged: boosted - sensitive_content: Sensitive content + sensitive_content: Herkkä materiaali time: formats: default: "%b %d, %Y, %H:%M" two_factor_auth: - description_html: If you enable two-factor authentication, logging in will require you to be in possession of your phone, which will generate tokens for you to enter. - disable: Disable - enable: Enable - instructions_html: "Scan this QR code into Google Authenticator or a similiar app on your phone. From now on, that app will generate tokens that you will have to enter when logging in." + description_html: Jos otat käyttöön kaksivaiheisen tunnistuksen, kirjautumiseen vaaditaan puhelin, joka voi generoida tokeneita kirjautumista varten. + disable: Poista käytöstä + enable: Ota käyttöön + instructions_html: "Skannaa tämä QR-koodi Google Authenticator tai samanlaiseen sovellukseen puhelimellasi. Tästä hetkestä lähtien, ohjelma generoi tokenit mikä sinun tarvitsee syöttää sisäänkirjautuessa." plaintext_secret_html: 'Plain-text secret: %{secret}' - warning: If you cannot configure an authenticator app right now, you should click "disable" or you won't be able to login. + warning: Jos et juuri nyt voi konfiguroida authenticator-applikaatiota juuri nyt, sinun pitäisi klikata "Poista käytöstä" tai et voi kirjautua sisään. users: - invalid_email: The e-mail address is invalid - invalid_otp_token: Invalid two-factor code + invalid_email: Virheellinen sähköposti + invalid_otp_token: Virheellinen kaksivaihe tunnistus koodi will_paginate: page_gap: "…" -- cgit From b0f4c9b91fe2acbf2d2384a3928f15a710a5f880 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 13:25:46 +0200 Subject: finnish translation finnish translation --- config/locales/simple_form.fi.yml | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 config/locales/simple_form.fi.yml diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml new file mode 100644 index 000000000..02c11752f --- /dev/null +++ b/config/locales/simple_form.fi.yml @@ -0,0 +1,46 @@ +--- +fi: + simple_form: + hints: + defaults: + avatar: PNG, GIF tai JPG. Korkeintaan 2MB. Skaalataan kokoon 120x120px + display_name: Korkeintaan 30 merkkiä + header: PNG, GIF tai JPG. Korkeintaan 2MB. Skaalataan kokoon 700x335px + locked: Vaatii sinun manuaalisesti hyväksymään seuraajat ja asettaa julkaisun yksityisyyden vain seuraajille + note: Korkeintaan 160 merkkiä + imports: + data: CSV tiedosto tuotu toiselta Mastodon palvelimelta + labels: + defaults: + avatar: Avatar + confirm_new_password: Varmista uusi salasana + confirm_password: Varmista salasana + current_password: Nykyinen salasana + data: Data + display_name: Näyttö nimi + email: Sähköpostiosoite + header: Header + locale: Kieli + locked: Tee tilistä yksityinen + new_password: Uusi salasana + note: Bio + otp_attempt: Kaksivaiheinen koodi + password: Salasana + setting_default_privacy: Julkaisun yksityisyys + type: Tuonti tyyppi + username: Käyttäjänimi + interactions: + must_be_follower: Estä ilmoitukset käyttäjiltä jotka eivät seuraa sinua + must_be_following: Estä ilmoitukset käyttäjiltä joita et seuraa + notification_emails: + digest: Send digest e-mails + favourite: Lähetä s-posti kun joku tykkää statuksestasi + follow: Lähetä s-posti kun joku seuraa sinua + follow_request: Lähetä s-posti kun joku pyytää seurata sinua + mention: Lähetä s-posti kun joku mainitsee sinut + reblog: Lähetä s-posti kun joku uudestaanblogaa julkaisusi + 'no': 'Ei' + required: + mark: "*" + text: vaaditaan + 'yes': 'Kyllä' -- cgit From eabb86b1247429b016cef8711ab78983def07ae9 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 13:32:10 +0200 Subject: add finnish language add finnish language --- app/assets/javascripts/components/locales/index.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/assets/javascripts/components/locales/index.jsx b/app/assets/javascripts/components/locales/index.jsx index 203929d66..fef317887 100644 --- a/app/assets/javascripts/components/locales/index.jsx +++ b/app/assets/javascripts/components/locales/index.jsx @@ -5,6 +5,7 @@ import hu from './hu'; import fr from './fr'; import pt from './pt'; import uk from './uk'; +import fi from './fi'; const locales = { en, @@ -14,6 +15,7 @@ const locales = { fr, pt, uk + fi }; export default function getMessagesForLocale (locale) { -- cgit From 22f88b845ad3238d2970222d276d952135e26884 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 13:33:43 +0200 Subject: add finnish translation add finnish translation --- app/assets/javascripts/components/containers/mastodon.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/containers/mastodon.jsx b/app/assets/javascripts/components/containers/mastodon.jsx index 6dc08bb4c..cbb7b85bc 100644 --- a/app/assets/javascripts/components/containers/mastodon.jsx +++ b/app/assets/javascripts/components/containers/mastodon.jsx @@ -46,6 +46,7 @@ import fr from 'react-intl/locale-data/fr'; import pt from 'react-intl/locale-data/pt'; import hu from 'react-intl/locale-data/hu'; import uk from 'react-intl/locale-data/uk'; +import fi from 'react-intl/locale-data/fi'; import getMessagesForLocale from '../locales'; import { hydrateStore } from '../actions/store'; import createStream from '../stream'; @@ -58,7 +59,7 @@ const browserHistory = useRouterHistory(createBrowserHistory)({ basename: '/web' }); -addLocaleData([...en, ...de, ...es, ...fr, ...pt, ...hu, ...uk]); +addLocaleData([...en, ...de, ...es, ...fr, ...pt, ...hu, ...uk, ...fi]); const Mastodon = React.createClass({ -- cgit From ae95f35fe604a840f3c3573516c740dc84d8dee6 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 13:34:26 +0200 Subject: add finnish translation add finnish translation --- app/helpers/settings_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 74215e8df..e01f7d0cc 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -10,6 +10,7 @@ module SettingsHelper hu: 'Magyar', uk: 'Українська', 'zh-CN': '简体中文', + fi: 'Suomi', }.freeze def human_locale(locale) -- cgit From 6501ffdadc593e4e0cd691533906a7396f552902 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 13:35:12 +0200 Subject: add finnish translation add finnish translation --- config/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/application.rb b/config/application.rb index 9d32f30cb..17b7a19cc 100644 --- a/config/application.rb +++ b/config/application.rb @@ -24,7 +24,7 @@ module Mastodon # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - config.i18n.available_locales = [:en, :de, :es, :pt, :fr, :hu, :uk, 'zh-CN'] + config.i18n.available_locales = [:en, :de, :es, :pt, :fr, :hu, :uk, 'zh-CN', :fi] config.i18n.default_locale = :en # config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') -- cgit From a229840ffed572e8b6ae33969c934103499ed855 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 14:16:03 +0200 Subject: fixed typo --- app/assets/javascripts/components/locales/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/locales/index.jsx b/app/assets/javascripts/components/locales/index.jsx index fef317887..72b8a5df5 100644 --- a/app/assets/javascripts/components/locales/index.jsx +++ b/app/assets/javascripts/components/locales/index.jsx @@ -14,7 +14,7 @@ const locales = { hu, fr, pt, - uk + uk, fi }; -- cgit From 97803600ed9f2c7c6198dfc2fc521cea0e3041b4 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 14:20:50 +0200 Subject: add finnish translation add finnish translation --- config/locales/devise.fi.yml | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 config/locales/devise.fi.yml diff --git a/config/locales/devise.fi.yml b/config/locales/devise.fi.yml new file mode 100644 index 000000000..79fe81230 --- /dev/null +++ b/config/locales/devise.fi.yml @@ -0,0 +1,61 @@ +--- +fi: + devise: + confirmations: + confirmed: Sähköpostisi on onnistuneesti vahvistettu. + send_instructions: Saat kohta sähköpostiisi ohjeet kuinka voit aktivoida tilisi. + send_paranoid_instructions: Jos sähköpostisi on meidän tietokannassa, saat pian ohjeet sen varmentamiseen. + failure: + already_authenticated: Olet jo kirjautunut sisään. + inactive: Tiliäsi ei ole viellä aktivoitu. + invalid: Virheellinen %{authentication_keys} tai salasana. + last_attempt: Sinulla on yksi yritys jäljellä tai tili lukitaan. + locked: Tili on lukittu. + not_found_in_database: Virheellinen %{authentication_keys} tai salasana. + timeout: Sessiosi on umpeutunut. Kirjaudu sisään jatkaaksesi. + unauthenticated: Sinun tarvitsee kirjautua sisään tai rekisteröityä jatkaaksesi. + unconfirmed: Sinun tarvitsee varmentaa sähköpostisi jatkaaksesi. + mailer: + confirmation_instructions: + subject: 'Mastodon: Varmistus ohjeet' + password_change: + subject: 'Mastodon: Salasana vaihdettu' + reset_password_instructions: + subject: 'Mastodon: Salasanan vaihto ohjeet' + unlock_instructions: + subject: 'Mastodon: Avauksen ohjeet' + omniauth_callbacks: + failure: Varmennus %{kind} epäonnistui koska "%{reason}". + success: Onnistuneesti varmennettu %{kind} tilillä. + passwords: + no_token: Et pääse tälle sivulle ilman salasanan vaihto sähköpostia. Jos tulet tämmöisestä postista, varmista että sinulla on täydellinen URL. + send_instructions: Saat sähköpostitse ohjeet salasanan palautukseen muutaman minuutin kuluessa. + send_paranoid_instructions: Jos sähköpostisi on meidän tietokannassa, saat pian ohjeet salasanan palautukseen. + updated: Salasanasi vaihdettu onnistuneesti. Olet nyt kirjautunut sisään. + updated_not_active: Salasanasi vaihdettu onnistuneesti. + registrations: + destroyed: Näkemiin! Tilisi on onnistuneesti peruttu. Toivottavasti näemme joskus uudestaan. + signed_up: Tervetuloa! Rekisteröitymisesi onnistu. + signed_up_but_inactive: Olet onnistuneesti rekisteröitynyt, mutta emme voi kirjata sinua sisään koska tiliäsi ei ole viellä aktivoitu. + signed_up_but_locked: Olet onnistuneesti rekisteröitynyt, mutta emme voi kirjata sinua sisään koska tilisi on lukittu. + signed_up_but_unconfirmed: Varmistuslinkki on lähetty sähköpostiisi. Seuraa sitä jotta tilisi voidaan aktivoida. + update_needs_confirmation: Tilisi on onnistuneesti päivitetty, mutta meidän tarvitsee vahvistaa sinun uusi sähköpostisi. Tarkista sähköpostisi ja seuraa viestissä tullutta linkkiä varmistaaksesi uuden osoitteen.. + updated: Tilisi on onnistuneesti päivitetty. + sessions: + already_signed_out: Ulos kirjautuminen onnistui. + signed_in: Sisäänkirjautuminen onnistui. + signed_out: Ulos kirjautuminen onnistui. + unlocks: + send_instructions: Saat sähköpostiisi pian ohjeet, jolla voit avata tilisi uudestaan. + send_paranoid_instructions: Jos tilisi on olemassa, saat sähköpostiisi pian ohjeet tilisi avaamiseen. + unlocked: Tilisi on avattu onnistuneesti. Kirjaudu normaalisti sisään. + errors: + messages: + already_confirmed: on jo varmistettu. Yritä kirjautua sisään + confirmation_period_expired: pitää varmistaa %{period} sisällä, ole hyvä ja pyydä uusi + expired: on erääntynyt, ole hyvä ja pyydä uusi + not_found: ei löydy + not_locked: ei ollut lukittu + not_saved: + one: '1 virhe esti %{resource} tallennuksen:' + other: "%{count} virhettä esti %{resource} tallennuksen:" -- cgit From 85a8b62ca2c58109ca776540f4e0588bc49eb28e Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 14:43:07 +0200 Subject: add finnish translation add finnish translation --- config/locales/doorkeeper.fi.yml | 113 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 config/locales/doorkeeper.fi.yml diff --git a/config/locales/doorkeeper.fi.yml b/config/locales/doorkeeper.fi.yml new file mode 100644 index 000000000..a2e520a56 --- /dev/null +++ b/config/locales/doorkeeper.fi.yml @@ -0,0 +1,113 @@ +--- +fi: + activerecord: + attributes: + doorkeeper/application: + name: Nimi + redirect_uri: Uudelleenohjaus URI + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: ei voi sisältää osia. + invalid_uri: pitää olla validi URI. + relative_uri: pitää olla täydellinen URI. + secured_uri: pitää olla HTTPS/SSL URI. + doorkeeper: + applications: + buttons: + authorize: Valtuuta + cancel: Peruuta + destroy: Tuhoa + edit: Muokkaa + submit: Lähetä + confirmations: + destroy: Oletko varma? + edit: + title: Muokkaa applikaatiota + form: + error: Whoops! Tarkista lomakkeesi mahdollisten virheiden varalta + help: + native_redirect_uri: Käytä %{native_redirect_uri} paikallisiin testeihin + redirect_uri: Käytä yhtä riviä per URI + scopes: Erota scopet välilyönnein. Jätä tyhjäksi käyteksi oletus scopeja. + index: + callback_url: Callback URL + name: Nimi + new: Uusi applikaatio + title: Sinun applikaatiosi + new: + title: Uusi applikaatio + show: + actions: Toiminnot + application_id: Applikaation Id + callback_urls: Callback urls + scopes: Scopet + secret: Salainen avain + title: Applikaatio: %{name}' + authorizations: + buttons: + authorize: Valtuuta + deny: Evää + error: + title: Virhe on tapahtunut + new: + able_to: Se voi + prompt: Applikaatio %{client_name} pyytää lupaa tilillesi + title: Valtuutus vaaditaan + show: + title: Valtuutus koodi + authorized_applications: + buttons: + revoke: Evää + confirmations: + revoke: Oletko varma? + index: + application: Applikaatio + created_at: Valtuutettu + date_format: "%Y-%m-%d %H:%M:%S" + scopes: Scopet + title: Valtuuttamasi applikaatiot + errors: + messages: + access_denied: Resurssin omistaja tai valtuutus palvelin hylkäsi pyynnönr. + credential_flow_not_configured: Resurssin omistajan salasana epäonnistui koska Doorkeeper.configure.resource_owner_from_credentials ei ole konfiguroitu. + invalid_client: Asiakkaan valtuutus epäonnistui koska tuntematon asiakas, asiakas ei sisältänyt valtuutusta, tai tukematon valtuutus tapa + invalid_grant: Antamasi valtuutus lupa on joko väärä, erääntynyt, peruttu, ei vastaa uudelleenohjaus URI jota käytetään valtuutus pyynnössä, tai se myönnettin toiselle asiakkaalle. + invalid_redirect_uri: Uudelleenohjaus uri ei ole oikein. + invalid_request: Pyynnöstä puutti parametri, sisältää tukemattoman parametri arvonn, tai on korruptoitunut. + invalid_resource_owner: Annetut resurssin omistajan tunnnukset ovat väärät, tai resurssin omistajaa ei löydy + invalid_scope: Pyydetty scope on väärä, tuntemat, tai korruptoitunut. + invalid_token: + expired: Access token vanhentunut + revoked: Access token evätty + unknown: Access token väärä + resource_owner_authenticator_not_configured: Resurssin omistajan etsiminen epäonnistui koska Doorkeeper.configure.resource_owner_authenticator ei ole konfiguroitu. + server_error: Valtuutus palvelin kohtasi odottamattoman virheen joka esti sitä täyttämästä pyyntöä. + temporarily_unavailable: Valtuutus palvelin ei voi tällä hetkellä käsitellä pyyntöäsi joko väliaikaisen ruuhkan tai huollon takia. + unauthorized_client: Asiakas ei ole valtuutettu tekemään tätä pyyntöä käyttäen tätä metodia. + unsupported_grant_type: Valtuutus grant type ei ole tuettu valtuutus palvelimella. + unsupported_response_type: Valtuutus palvelin ei tue tätä vastaus tyyppiä. + flash: + applications: + create: + notice: Applikaatio luotu. + destroy: + notice: Applikaatio poistettu. + update: + notice: Applikaatio päivitetty. + authorized_applications: + destroy: + notice: Applikaatio tuhottu. + layouts: + admin: + nav: + applications: Applikaatiot + oauth2_provider: OAuth2 Provider + application: + title: OAuth valtuutus tarvitaan + scopes: + follow: seuraa, estä, peru esto ja lopeta tilien seuraaminen + read: lukea tilin dataa + write: julkaista puolestasi -- cgit From d3fde60297288c3d310ac43c7aae67b21cf8936f Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 14:54:53 +0200 Subject: fixed an sneaky peaky tpy --- config/locales/doorkeeper.fi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/doorkeeper.fi.yml b/config/locales/doorkeeper.fi.yml index a2e520a56..938590514 100644 --- a/config/locales/doorkeeper.fi.yml +++ b/config/locales/doorkeeper.fi.yml @@ -45,7 +45,7 @@ fi: callback_urls: Callback urls scopes: Scopet secret: Salainen avain - title: Applikaatio: %{name}' + title: Applikaatio %{name}' authorizations: buttons: authorize: Valtuuta -- cgit From 65d667dc6c72a39e6e81a06c70f4121ec4e543c1 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Mon, 3 Apr 2017 14:56:13 +0200 Subject: another typo. fuck me --- config/locales/doorkeeper.fi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/doorkeeper.fi.yml b/config/locales/doorkeeper.fi.yml index 938590514..cd1a9d058 100644 --- a/config/locales/doorkeeper.fi.yml +++ b/config/locales/doorkeeper.fi.yml @@ -45,7 +45,7 @@ fi: callback_urls: Callback urls scopes: Scopet secret: Salainen avain - title: Applikaatio %{name}' + title: 'Applikaatio: %{name}' authorizations: buttons: authorize: Valtuuta -- cgit From 5cb011b66bf4242ba92ce30867dc2f2e432382ca Mon Sep 17 00:00:00 2001 From: Christopher Kolstad Date: Mon, 3 Apr 2017 15:44:05 +0200 Subject: Add Norwegian locale --- config/locales/devise.no.yml | 61 ++++++++++++++ config/locales/doorkeeper.no.yml | 113 ++++++++++++++++++++++++++ config/locales/no.yml | 164 ++++++++++++++++++++++++++++++++++++++ config/locales/simple_form.no.yml | 46 +++++++++++ 4 files changed, 384 insertions(+) create mode 100644 config/locales/devise.no.yml create mode 100644 config/locales/doorkeeper.no.yml create mode 100644 config/locales/no.yml create mode 100644 config/locales/simple_form.no.yml diff --git a/config/locales/devise.no.yml b/config/locales/devise.no.yml new file mode 100644 index 000000000..7c665f0da --- /dev/null +++ b/config/locales/devise.no.yml @@ -0,0 +1,61 @@ +--- +no: + devise: + confirmations: + confirmed: Epostaddressen din er blitt bekreftet. + send_instructions: Du vil motta en epost med instruksjoner for hvordan bekrefte din epostaddresse om noen få minutter. + send_paranoid_instructions: Hvis din epostaddresse finnes i vår database vil du motta en epost med instruksjoner for hvordan bekrefte din epost om noen få minutter. + failure: + already_authenticated: Du er allerede innlogget. + inactive: Din konto er ikke blitt aktivert ennå. + invalid: Ugyldig %{authentication_keys} eller passord. + last_attempt: Du har ett forsøk igjen før kontoen din bli låst. + locked: Din konto er låst. + not_found_in_database: Ugyldig %{authentication_keys} eller passord. + timeout: Sesjonen din løp ut på tid. Logg inn på nytt for å fortsette. + unauthenticated: Du må logge inn eller registrere deg før du kan fortsette. + unconfirmed: Du må bekrefte epostadressen din før du kan fortsette. + mailer: + confirmation_instructions: + subject: 'Mastodon: Instruksjoner for å bekrefte epostadresse' + password_change: + subject: 'Mastodon: Passord endret' + reset_password_instructions: + subject: 'Mastodon: Hvordan nullstille passord?' + unlock_instructions: + subject: 'Mastodon: Instruksjoner for å gjenåpne konto' + omniauth_callbacks: + failure: Kunne ikke autentisere deg fra %{kind} fordi "%{reason}". + success: Vellykket autentisering fra %{kind}. + passwords: + no_token: Du har ingen tilgang til denne siden så lenge du ikke kommer fra en epost om nullstilling av passord. Hvis du kommer fra en passordnullstilling epost, dobbelsjekk at du brukte hele URLen. + send_instructions: Du vil motta en epost med instruksjoner for å nullstille passordet ditt om noen få minutter. + send_paranoid_instructions: Hvis epostadressen din finnes i databasen vår vil du motta en instruksjonsmail om passord nullstilling om noen få minutter. + updated: Passordet ditt har blitt endret. Du er nå logget inn. + updated_not_active: Passordet ditt har blitt endret. + registrations: + destroyed: Adjø! Kontoen din har blitt avsluttet. Vi håper at vi ser deg igjen snart. + signed_up: Velkommen! Registrasjonen var vellykket. + signed_up_but_inactive: Registrasjonen var vellykket. Vi kunne dessverre ikke logge deg inn fordi kontoen din ennå ikke har blitt aktivert. + signed_up_but_locked: Registrasjonen var vellykket. Vi kunne dessverre ikke logge deg inn fordi kontoen din har blitt låst. + signed_up_but_unconfirmed: En epostmelding med en bekreftelseslink har blitt sendt til din adresse. Klikk på linken i eposten for å aktivere kontoen din. + update_needs_confirmation: Du har oppdatert kontoen din, men vi må bekrefte din nye epostadresse. Sjekk eposten din og følg bekreftelseslinken for å bekrefte din nye epostadresse. + updated: Kontoen din ble oppdatert. + sessions: + already_signed_out: Logget ut. + signed_in: Logget inn. + signed_out: Logget ut. + unlocks: + send_instructions: Du vil motta en epost med instruksjoner for å åpne kontoen din om noen få minutter. + send_paranoid_instructions: Hvis kontoen din eksisterer vil du motta en epost med instruksjoner for å åpne kontoen din om noen få minutter. + unlocked: Kontoen din ble åpnet uten problemer. Logg på for å fortsette. + errors: + messages: + already_confirmed: har allerede blitt bekreftet, prøv å logg på istedet. + confirmation_period_expired: må bekreftes innen %{period}. Spør om en ny bekreftelsesmail istedet. + expired: har utløpt, spør om en ny en istedet + not_found: ikke funnet + not_locked: var ikke låst + not_saved: + one: '1 feil hindret denne %{resource} fra å bli lagret:' + other: "%{count} feil hindret denne %{resource} fra å bli lagret:" diff --git a/config/locales/doorkeeper.no.yml b/config/locales/doorkeeper.no.yml new file mode 100644 index 000000000..7b51289aa --- /dev/null +++ b/config/locales/doorkeeper.no.yml @@ -0,0 +1,113 @@ +--- +no: + activerecord: + attributes: + doorkeeper/application: + name: Navn + redirect_uri: Omdirigerings-URI + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: kan ikke inneholde ett fragment. + invalid_uri: må være en gyldig URI. + relative_uri: må være en absolutt URI. + secured_uri: må være en HTTPS/SSL URI. + doorkeeper: + applications: + buttons: + authorize: Autoriser + cancel: Avbryt + destroy: Ødelegg + edit: Endre + submit: Send inn + confirmations: + destroy: Er du sikker? + edit: + title: Endre applikasjon + form: + error: Whoops! Sjekk skjemaet ditt for mulige feil + help: + native_redirect_uri: Bruk %{native_redirect_uri} for lokale tester + redirect_uri: Bruk en linje per URI + scopes: Adskill omfang med mellomrom. La det være blankt for å bruke standard omfang. + index: + callback_url: Callback URL + name: Navn + new: Ny Applikasjon + title: Dine applikasjoner + new: + title: Ny Applikasjoner + show: + actions: Operasjoner + application_id: Applikasjon Id + callback_urls: Callback urls + scopes: Omfang + secret: Hemmelighet + title: 'Applikasjon: %{name}' + authorizations: + buttons: + authorize: Autoriser + deny: Avvis + error: + title: En feil oppsto + new: + able_to: Den vil ha mulighet til + prompt: Applikasjon %{client_name} spør om tilgang til din konto + title: Autorisasjon påkrevd + show: + title: Autoriserings kode + authorized_applications: + buttons: + revoke: Opphev + confirmations: + revoke: Opphev? + index: + application: Applikasjon + created_at: Autorisert + date_format: "%Y-%m-%d %H:%M:%S" + scopes: Omfang + title: Dine autoriserte applikasjoner + errors: + messages: + access_denied: Ressurseieren eller autoriserings tjeneren avviste forespørslen. + credential_flow_not_configured: Ressurseiers passord flyt feilet på grunn av at Doorkeeper.configure.resource_owner_from_credentials ikke var konfigurert. + invalid_client: Klient autentisering feilet på grunn av ukjent klient, ingen autentisering inkludert eller autentiserings metode som ikke er støttet. + invalid_grant: Autoriseringen er ugyldig, utløpt, opphevet, stemmer ikke overens med omdirigerings-URIen eller var utstedt til en annen klient. + invalid_redirect_uri: redirect urien som var inkludert er ikke gyldig. + invalid_request: Forespørslen mangler ett eller flere parametere, inkluderte ett parameter som ikke støttes eller har feil struktur. + invalid_resource_owner: Ressurseierens detaljer er ikke gyldig, eller så kan ikke eieren finnes. + invalid_scope: Det etterspurte omfanget er ugyldig, ukjent eller har feil struktur. + invalid_token: + expired: Tilgangsbeviset har utløpt + revoked: Tilgangsbeviset har blitt opphevet + unknown: Tilgangsbeviset er ugyldig + resource_owner_authenticator_not_configured: Ressurseier kunne ikke finnes fordi Doorkeeper.configure.resource_owner_authenticator ikke er konfigurert. + server_error: Autoriserings tjeneren støtte på en uventet hendelse som hindret den i å svare på forespørslen. + temporarily_unavailable: Autoriserings tjeneren kan ikke håndtere forespørslen grunnet en midlertidig overbelastning eller tjenervedlikehold. + unauthorized_client: Klienten har ikke autorisasjon for å utføre denne forespørslen med denne metoden. + unsupported_grant_type: Autorisasjons tildelings typen er ikke støttet av denne autoriserings tjeneren. + unsupported_response_type: Autorisasjons serveren støtter ikke denne typen av forespørsler. + flash: + applications: + create: + notice: Applikasjon opprettet. + destroy: + notice: Applikasjon slettet. + update: + notice: Applikasjon oppdatert. + authorized_applications: + destroy: + notice: Applikasjon opphevet. + layouts: + admin: + nav: + applications: Applikasjoner + oauth2_provider: OAuth2 tilbyder + application: + title: OAuth autorisering påkrevet + scopes: + follow: følg, blokker, avblokker, avfølg kontoer + read: lese dine data + write: poste på dine vegne diff --git a/config/locales/no.yml b/config/locales/no.yml new file mode 100644 index 000000000..d4514d5e4 --- /dev/null +++ b/config/locales/no.yml @@ -0,0 +1,164 @@ +--- +no: + about: + about_mastodon: Mastodon er et gratis, åpen kildekode sosialt nettverk. Et desentralisert alternativ til kommersielle plattformer. Slik kan det unngå risikoene ved å ha et enkelt selskap med monopol på din kommunikasjon. Velg en tjener du stoler på — uansett hvilken du velger så kan du interagere med alle andre. Alle kan kjøre sin egen Mastodon og delta sømløst i det sosiale nettverket. + about_this: Om denne instansen + apps: Applikasjoner + business_email: 'Bedriftsepost:' + contact: Kontakt + description_headline: Hva er %{domain}? + domain_count_after: andre instanser + domain_count_before: Koblet til + features: + api: Åpent api for applikasjoner og tjenester + blocks: Rikholdige blokkerings verktøy + characters: 500 tegn per post + chronology: Tidslinjer er kronologiske + ethics: 'Etisk design: Ingen reklame, ingen sporing' + gifv: GIFV sett og korte videoer + privacy: Finmaskete personvernsinnstillinger + public: Offentlige tidslinjer + features_headline: Hva skiller Mastodon fra andre sosiale nettverk + get_started: Kom i gang + links: Lenker + other_instances: Andre instanser + source_code: Kildekode + status_count_after: statuser + status_count_before: Hvem skrev + terms: Betingelser + user_count_after: brukere + user_count_before: Hjem til + accounts: + follow: Følg + followers: Følgere + following: Følger + nothing_here: Det er ingenting her! + people_followed_by: Folk som %{name} følger + people_who_follow: Folk som følger %{name} + posts: Poster + remote_follow: Følg fra andre instanser + unfollow: Avfølg + application_mailer: + settings: 'Endre foretrukne epost innstillinger: %{link}' + signature: Mastodon notiser fra %{instance} + view: 'Se:' + applications: + invalid_url: Den oppgitte URLen er ugyldig + auth: + change_password: Brukerdetaljer + didnt_get_confirmation: Fikk du ikke bekreftelsesmailen din? + forgot_password: Har du glemt passordet ditt? + login: Innlogging + logout: Logg ut + register: Bli med + resend_confirmation: Send bekreftelsesinstruksjoner på nytt + reset_password: Nullstill passord + set_new_password: Sett nytt passord + authorize_follow: + error: Uheldigvis så skjedde det en feil når vi prøvde å få tak i en konto fra en annen instans. + follow: Følg + prompt_html: 'Du (%{self}) har spurt om å følge:' + title: Følg %{acct} + datetime: + distance_in_words: + about_x_hours: "%{count}t" + about_x_months: "%{count}m" + about_x_years: "%{count}å" + almost_x_years: "%{count}å" + half_a_minute: Nylig + less_than_x_minutes: "%{count}min" + less_than_x_seconds: Nylig + over_x_years: "%{count}å" + x_days: "%{count}d" + x_minutes: "%{count}min" + x_months: "%{count}mo" + x_seconds: "%{count}s" + exports: + blocks: Du blokkerer + csv: CSV + follows: Du følger + storage: Media lagring + generic: + changes_saved_msg: Vellykket lagring av endringer! + powered_by: drevet av %{link} + save_changes: Lagre endringer + validation_errors: + one: Noe er ikke helt riktig ennå. Vær snill å se etter en gang til + other: Noe er ikke helt riktig ennå. Det er ennå %{count} feil å rette på + imports: + preface: Du kan importere data om mennesker du følger eller blokkerer inn til kontoen din på denne instansen, fra filer opprettet av eksporter fra andre instanser. + success: Din data ble mottatt og vil bli prosessert så fort som mulig. + types: + blocking: Blokkeringsliste + following: Følgeliste + upload: Opplastning + landing_strip_html: %{name} er en bruker på %{domain}. Du kan følge dem eller interagere med dem hvis du har en konto hvor som helst i fediverset. Hvis du ikke har en konto så kan du registrere deg her. + notification_mailer: + digest: + body: 'Her er en kort oppsummering av hva du har gått glipp av på %{instance} siden du logget deg inn sist den %{since}:' + mention: "%{name} nevnte deg i:" + new_followers_summary: + one: Du har fått en ny følger. Jippi! + other: Du har fått %{count} nye følgere! Imponerende! + subject: + one: "1 ny hendelse siden ditt siste besøk \U0001F418" + other: "%{count} nye hendelser siden ditt siste besøk \U0001F418" + favourite: + body: 'Din status ble satt som favoritt av %{name}' + subject: "%{name} satte din status som favoritt." + follow: + body: "%{name} følger deg!" + subject: "%{name} følger deg" + follow_request: + body: "%{name} har spurt om å få lov til å følge deg" + subject: 'Ventende følger: %{name}' + mention: + body: 'Du ble nevnt av %{name} i:' + subject: Du ble nevnt av %{name} + reblog: + body: 'Din status fikk en boost av %{name}:' + subject: "%{name} ga din status en boost" + pagination: + next: Neste + prev: Forrige + remote_follow: + acct: Tast inn brukernavn@domene som du vil følge fra + missing_resource: Kunne ikke finne URLen for din konto + proceed: Fortsett med følging + prompt: 'Du kommer til å følge:' + settings: + authorized_apps: Autoriserte applikasjoner + back: Tilbake til Mastodon + edit_profile: Endre profil + export: Data eksport + import: Importer + preferences: Foretrukne valg + settings: Innstillinger + two_factor_auth: To-faktor autentisering + statuses: + open_in_web: Åpne i nettleser + over_character_limit: tegngrense på %{max} overskredet + show_more: Vis mer + visibilities: + private: Vis kun til følgere + public: Offentlig + unlisted: Offentlig, men vis ikke på offentlig tidslinje + stream_entries: + click_to_show: Klikk for å vise + reblogged: boostet + sensitive_content: Sensitivt innhold + time: + formats: + default: "%d, %b %Y, %H:%M" + two_factor_auth: + description_html: Hvis du skru på tofaktor autentisering vil innlogging kreve at du har telefonen din, som vil generere koder som du må taste inn. + disable: Skru av + enable: Skru på + instructions_html: "Scan denne QR-koden i Google Authenticator eller en lignende app på telefonen din. Fra nå av så vil denne applikasjonen generere koder for deg som skal brukes under innlogging" + plaintext_secret_html: 'Plain-text secret: %{secret}' + warning: Hvis du ikke kan konfigurere en autentikatorapp nå, så bør du trykke "Skru av"; ellers vil du ikke kunne logge inn. + users: + invalid_email: E-post addressen er ugyldig + invalid_otp_token: Ugyldig two-faktor kode + will_paginate: + page_gap: "…" diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml new file mode 100644 index 000000000..6829e6a24 --- /dev/null +++ b/config/locales/simple_form.no.yml @@ -0,0 +1,46 @@ +--- +no: + simple_form: + hints: + defaults: + avatar: PNG, GIF eller JPG. Maksimalt 2MB. Vil bli nedskalert til 120x120px + display_name: Maksimalt 30 tegn + header: PNG, GIF eller JPG. Maksimalt 2MB. Vil bli nedskalert til 700x335px + locked: Krever at du manuelt godkjenner følgere og setter standard beskyttelse av poster til kun-følgere + note: Maksimalt 160 tegn + imports: + data: CSV fil eksportert fra en annen Mastodon instans + labels: + defaults: + avatar: Avatar + confirm_new_password: Bekreft nytt passord + confirm_password: Bekreft passord + current_password: Nåværende passord + data: Data + display_name: Visningsnavn + email: E-post adresse + header: Header + locale: Språk + locked: Endre konto til privat + new_password: Nytt passord + note: Biografi + otp_attempt: To-faktor kode + password: Passord + setting_default_privacy: Leserettigheter for poster + type: Importeringstype + username: Brukernavn + interactions: + must_be_follower: Blokker meldinger fra ikke-følgere + must_be_following: Blokker meldinger fra folk du ikke følger + notification_emails: + digest: Send oppsummerings eposter + favourite: Send e-post når noen setter din status som favoritt + follow: Send e-post når noen følger deg + follow_request: Send e-post når noen spør om å få følge deg + mention: Send e-post når noen nevner deg + reblog: Send e-post når noen reblogger din status + 'no': 'Nei' + required: + mark: "*" + text: påkrevd + 'yes': 'Ja' -- cgit From d06c810b16ab8b72fc15aab0ca42c176b5b5d8f5 Mon Sep 17 00:00:00 2001 From: wxcafé Date: Mon, 3 Apr 2017 17:32:25 +0200 Subject: Adds social.wxcafe.net --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 7c8a33893..780977bd4 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -21,5 +21,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.mashek.net](https://social.mashek.net) |Themed and customised for Mashekstein Labs community. Selectively federates.|Yes|No| | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| +| [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, federates everywhere, no moderation yet|Yes|Yes| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From 5652f00d81aa18dd4fa6046c22282c000635e032 Mon Sep 17 00:00:00 2001 From: David Baumgold Date: Mon, 3 Apr 2017 11:44:11 -0400 Subject: GitHub should be capitalized --- app/assets/javascripts/components/features/getting_started/index.jsx | 2 +- app/assets/javascripts/components/locales/en.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/components/features/getting_started/index.jsx b/app/assets/javascripts/components/features/getting_started/index.jsx index 8253ad017..d7a78d9cc 100644 --- a/app/assets/javascripts/components/features/getting_started/index.jsx +++ b/app/assets/javascripts/components/features/getting_started/index.jsx @@ -43,7 +43,7 @@ const GettingStarted = ({ intl, me }) => {
-

tootsuite/mastodon, apps: }} />

+

tootsuite/mastodon, apps: }} />

diff --git a/app/assets/javascripts/components/locales/en.jsx b/app/assets/javascripts/components/locales/en.jsx index 2d3360b6b..53e2898eb 100644 --- a/app/assets/javascripts/components/locales/en.jsx +++ b/app/assets/javascripts/components/locales/en.jsx @@ -25,7 +25,7 @@ const en = { "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}.", + "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}. {apps}.", "column.home": "Home", "column.community": "Local timeline", "column.public": "Federated timeline", -- cgit From 8a45a97e2e1ed74983ce25bcf0e03f51ed2eb8fe Mon Sep 17 00:00:00 2001 From: shel Date: Mon, 3 Apr 2017 12:28:36 -0400 Subject: Add instances from instances.mastodon.xyz Updated list with lots of instances that have been added to instances.mastodon.xyz but not this list --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 780977bd4..c424cab64 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -22,5 +22,18 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| | [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, federates everywhere, no moderation yet|Yes|Yes| +| [hostux.social](https://hostux.social) |N/A|Yes|Yes| +| [social.alex73630.xyz](https://social.alex73630.xyz) |Francophones|Yes|Yes| +| [maly.io](https://maly.io) |N/A|Yes|No| +| [social.lou.lt](https://social.lou.lt) |N/A|Yes|No| +| [mastodon.ninetailed.uk](https://mastodon.ninetailed.uk) |N/A|Yes|No| +| [soc.louiz.org](https://soc.louiz.org) |"Coucou"|Yes|No| +| [7nw.eu](https://7nw.eu) |N/A|Yes|No| +| [mastodon.gougere.fr](https://mastodon.gougere.fr)|N/A|Yes|No| +| [aleph.land](https://aleph.land)|N/A|Yes|No| +| [share.elouworld.org](https://share.elouworld.org)|N/A|No|No| +| [social.lkw.tf](https://social.lkw.tf)|N/A|No|No| +| [manowar.social](https://manowar.social)|N/A|No|No| +| [social.ballpointcarrot.net](https://social.ballpointcarrot.net)|Down at time of entry|No|No| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From b7c1b12367b307d07303ce99f2c27bf255ecd56a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 3 Apr 2017 18:55:06 +0200 Subject: Make default admin UI page reports. Add admin UI for creating a domain block --- app/controllers/admin/domain_blocks_controller.rb | 18 +++ app/services/block_domain_service.rb | 10 +- app/views/admin/domain_blocks/index.html.haml | 1 + app/views/admin/domain_blocks/new.html.haml | 18 +++ app/workers/domain_block_worker.rb | 11 ++ config/locales/devise.no.yml | 62 +------- config/locales/doorkeeper.no.yml | 114 +-------------- config/locales/no.yml | 165 +--------------------- config/locales/simple_form.no.yml | 47 +----- config/navigation.rb | 4 +- config/routes.rb | 2 +- 11 files changed, 59 insertions(+), 393 deletions(-) create mode 100644 app/views/admin/domain_blocks/new.html.haml create mode 100644 app/workers/domain_block_worker.rb diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index e362957e7..1f4432847 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -9,6 +9,24 @@ class Admin::DomainBlocksController < ApplicationController @blocks = DomainBlock.paginate(page: params[:page], per_page: 40) end + def new + @domain_block = DomainBlock.new + end + def create + @domain_block = DomainBlock.new(resource_params) + + if @domain_block.save + DomainBlockWorker.perform_async(@domain_block.id) + redirect_to admin_domain_blocks_path, notice: 'Domain block is now being processed' + else + render action: :new + end + end + + private + + def resource_params + params.require(:domain_block).permit(:domain, :severity) end end diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb index 9518b1fcf..6c131bd34 100644 --- a/app/services/block_domain_service.rb +++ b/app/services/block_domain_service.rb @@ -1,13 +1,11 @@ # frozen_string_literal: true class BlockDomainService < BaseService - def call(domain, severity) - DomainBlock.where(domain: domain).first_or_create!(domain: domain, severity: severity) - - if severity == :silence - Account.where(domain: domain).update_all(silenced: true) + def call(domain_block) + if domain_block.silence? + Account.where(domain: domain_block.domain).update_all(silenced: true) else - Account.where(domain: domain).find_each do |account| + Account.where(domain: domain_block.domain).find_each do |account| account.subscription(api_subscription_url(account.id)).unsubscribe if account.subscribed? SuspendAccountService.new.call(account) end diff --git a/app/views/admin/domain_blocks/index.html.haml b/app/views/admin/domain_blocks/index.html.haml index dbaeb4716..eb7894b86 100644 --- a/app/views/admin/domain_blocks/index.html.haml +++ b/app/views/admin/domain_blocks/index.html.haml @@ -14,3 +14,4 @@ %td= block.severity = will_paginate @blocks, pagination_options += link_to 'Add new', new_admin_domain_block_path, class: 'button' diff --git a/app/views/admin/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml new file mode 100644 index 000000000..fbd39d6cf --- /dev/null +++ b/app/views/admin/domain_blocks/new.html.haml @@ -0,0 +1,18 @@ +- content_for :page_title do + New domain block + += simple_form_for @domain_block, url: admin_domain_blocks_path do |f| + = render 'shared/error_messages', object: @domain_block + + %p.hint The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts. + + = f.input :domain, placeholder: 'Domain' + = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false + + %p.hint + %strong Silence + will make the account's posts invisible to anyone who isn't following them. + %strong Suspend + will remove all of the account's content, media, and profile data. + .actions + = f.button :button, 'Create block', type: :submit diff --git a/app/workers/domain_block_worker.rb b/app/workers/domain_block_worker.rb new file mode 100644 index 000000000..884477829 --- /dev/null +++ b/app/workers/domain_block_worker.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class DomainBlockWorker + include Sidekiq::Worker + + def perform(domain_block_id) + BlockDomainService.new.call(DomainBlock.find(domain_block_id)) + rescue ActiveRecord::RecordNotFound + true + end +end diff --git a/config/locales/devise.no.yml b/config/locales/devise.no.yml index 7c665f0da..2fbf0ffd7 100644 --- a/config/locales/devise.no.yml +++ b/config/locales/devise.no.yml @@ -1,61 +1 @@ ---- -no: - devise: - confirmations: - confirmed: Epostaddressen din er blitt bekreftet. - send_instructions: Du vil motta en epost med instruksjoner for hvordan bekrefte din epostaddresse om noen få minutter. - send_paranoid_instructions: Hvis din epostaddresse finnes i vår database vil du motta en epost med instruksjoner for hvordan bekrefte din epost om noen få minutter. - failure: - already_authenticated: Du er allerede innlogget. - inactive: Din konto er ikke blitt aktivert ennå. - invalid: Ugyldig %{authentication_keys} eller passord. - last_attempt: Du har ett forsøk igjen før kontoen din bli låst. - locked: Din konto er låst. - not_found_in_database: Ugyldig %{authentication_keys} eller passord. - timeout: Sesjonen din løp ut på tid. Logg inn på nytt for å fortsette. - unauthenticated: Du må logge inn eller registrere deg før du kan fortsette. - unconfirmed: Du må bekrefte epostadressen din før du kan fortsette. - mailer: - confirmation_instructions: - subject: 'Mastodon: Instruksjoner for å bekrefte epostadresse' - password_change: - subject: 'Mastodon: Passord endret' - reset_password_instructions: - subject: 'Mastodon: Hvordan nullstille passord?' - unlock_instructions: - subject: 'Mastodon: Instruksjoner for å gjenåpne konto' - omniauth_callbacks: - failure: Kunne ikke autentisere deg fra %{kind} fordi "%{reason}". - success: Vellykket autentisering fra %{kind}. - passwords: - no_token: Du har ingen tilgang til denne siden så lenge du ikke kommer fra en epost om nullstilling av passord. Hvis du kommer fra en passordnullstilling epost, dobbelsjekk at du brukte hele URLen. - send_instructions: Du vil motta en epost med instruksjoner for å nullstille passordet ditt om noen få minutter. - send_paranoid_instructions: Hvis epostadressen din finnes i databasen vår vil du motta en instruksjonsmail om passord nullstilling om noen få minutter. - updated: Passordet ditt har blitt endret. Du er nå logget inn. - updated_not_active: Passordet ditt har blitt endret. - registrations: - destroyed: Adjø! Kontoen din har blitt avsluttet. Vi håper at vi ser deg igjen snart. - signed_up: Velkommen! Registrasjonen var vellykket. - signed_up_but_inactive: Registrasjonen var vellykket. Vi kunne dessverre ikke logge deg inn fordi kontoen din ennå ikke har blitt aktivert. - signed_up_but_locked: Registrasjonen var vellykket. Vi kunne dessverre ikke logge deg inn fordi kontoen din har blitt låst. - signed_up_but_unconfirmed: En epostmelding med en bekreftelseslink har blitt sendt til din adresse. Klikk på linken i eposten for å aktivere kontoen din. - update_needs_confirmation: Du har oppdatert kontoen din, men vi må bekrefte din nye epostadresse. Sjekk eposten din og følg bekreftelseslinken for å bekrefte din nye epostadresse. - updated: Kontoen din ble oppdatert. - sessions: - already_signed_out: Logget ut. - signed_in: Logget inn. - signed_out: Logget ut. - unlocks: - send_instructions: Du vil motta en epost med instruksjoner for å åpne kontoen din om noen få minutter. - send_paranoid_instructions: Hvis kontoen din eksisterer vil du motta en epost med instruksjoner for å åpne kontoen din om noen få minutter. - unlocked: Kontoen din ble åpnet uten problemer. Logg på for å fortsette. - errors: - messages: - already_confirmed: har allerede blitt bekreftet, prøv å logg på istedet. - confirmation_period_expired: må bekreftes innen %{period}. Spør om en ny bekreftelsesmail istedet. - expired: har utløpt, spør om en ny en istedet - not_found: ikke funnet - not_locked: var ikke låst - not_saved: - one: '1 feil hindret denne %{resource} fra å bli lagret:' - other: "%{count} feil hindret denne %{resource} fra å bli lagret:" +--- {} diff --git a/config/locales/doorkeeper.no.yml b/config/locales/doorkeeper.no.yml index 7b51289aa..2fbf0ffd7 100644 --- a/config/locales/doorkeeper.no.yml +++ b/config/locales/doorkeeper.no.yml @@ -1,113 +1 @@ ---- -no: - activerecord: - attributes: - doorkeeper/application: - name: Navn - redirect_uri: Omdirigerings-URI - errors: - models: - doorkeeper/application: - attributes: - redirect_uri: - fragment_present: kan ikke inneholde ett fragment. - invalid_uri: må være en gyldig URI. - relative_uri: må være en absolutt URI. - secured_uri: må være en HTTPS/SSL URI. - doorkeeper: - applications: - buttons: - authorize: Autoriser - cancel: Avbryt - destroy: Ødelegg - edit: Endre - submit: Send inn - confirmations: - destroy: Er du sikker? - edit: - title: Endre applikasjon - form: - error: Whoops! Sjekk skjemaet ditt for mulige feil - help: - native_redirect_uri: Bruk %{native_redirect_uri} for lokale tester - redirect_uri: Bruk en linje per URI - scopes: Adskill omfang med mellomrom. La det være blankt for å bruke standard omfang. - index: - callback_url: Callback URL - name: Navn - new: Ny Applikasjon - title: Dine applikasjoner - new: - title: Ny Applikasjoner - show: - actions: Operasjoner - application_id: Applikasjon Id - callback_urls: Callback urls - scopes: Omfang - secret: Hemmelighet - title: 'Applikasjon: %{name}' - authorizations: - buttons: - authorize: Autoriser - deny: Avvis - error: - title: En feil oppsto - new: - able_to: Den vil ha mulighet til - prompt: Applikasjon %{client_name} spør om tilgang til din konto - title: Autorisasjon påkrevd - show: - title: Autoriserings kode - authorized_applications: - buttons: - revoke: Opphev - confirmations: - revoke: Opphev? - index: - application: Applikasjon - created_at: Autorisert - date_format: "%Y-%m-%d %H:%M:%S" - scopes: Omfang - title: Dine autoriserte applikasjoner - errors: - messages: - access_denied: Ressurseieren eller autoriserings tjeneren avviste forespørslen. - credential_flow_not_configured: Ressurseiers passord flyt feilet på grunn av at Doorkeeper.configure.resource_owner_from_credentials ikke var konfigurert. - invalid_client: Klient autentisering feilet på grunn av ukjent klient, ingen autentisering inkludert eller autentiserings metode som ikke er støttet. - invalid_grant: Autoriseringen er ugyldig, utløpt, opphevet, stemmer ikke overens med omdirigerings-URIen eller var utstedt til en annen klient. - invalid_redirect_uri: redirect urien som var inkludert er ikke gyldig. - invalid_request: Forespørslen mangler ett eller flere parametere, inkluderte ett parameter som ikke støttes eller har feil struktur. - invalid_resource_owner: Ressurseierens detaljer er ikke gyldig, eller så kan ikke eieren finnes. - invalid_scope: Det etterspurte omfanget er ugyldig, ukjent eller har feil struktur. - invalid_token: - expired: Tilgangsbeviset har utløpt - revoked: Tilgangsbeviset har blitt opphevet - unknown: Tilgangsbeviset er ugyldig - resource_owner_authenticator_not_configured: Ressurseier kunne ikke finnes fordi Doorkeeper.configure.resource_owner_authenticator ikke er konfigurert. - server_error: Autoriserings tjeneren støtte på en uventet hendelse som hindret den i å svare på forespørslen. - temporarily_unavailable: Autoriserings tjeneren kan ikke håndtere forespørslen grunnet en midlertidig overbelastning eller tjenervedlikehold. - unauthorized_client: Klienten har ikke autorisasjon for å utføre denne forespørslen med denne metoden. - unsupported_grant_type: Autorisasjons tildelings typen er ikke støttet av denne autoriserings tjeneren. - unsupported_response_type: Autorisasjons serveren støtter ikke denne typen av forespørsler. - flash: - applications: - create: - notice: Applikasjon opprettet. - destroy: - notice: Applikasjon slettet. - update: - notice: Applikasjon oppdatert. - authorized_applications: - destroy: - notice: Applikasjon opphevet. - layouts: - admin: - nav: - applications: Applikasjoner - oauth2_provider: OAuth2 tilbyder - application: - title: OAuth autorisering påkrevet - scopes: - follow: følg, blokker, avblokker, avfølg kontoer - read: lese dine data - write: poste på dine vegne +--- {} diff --git a/config/locales/no.yml b/config/locales/no.yml index d4514d5e4..2fbf0ffd7 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -1,164 +1 @@ ---- -no: - about: - about_mastodon: Mastodon er et gratis, åpen kildekode sosialt nettverk. Et desentralisert alternativ til kommersielle plattformer. Slik kan det unngå risikoene ved å ha et enkelt selskap med monopol på din kommunikasjon. Velg en tjener du stoler på — uansett hvilken du velger så kan du interagere med alle andre. Alle kan kjøre sin egen Mastodon og delta sømløst i det sosiale nettverket. - about_this: Om denne instansen - apps: Applikasjoner - business_email: 'Bedriftsepost:' - contact: Kontakt - description_headline: Hva er %{domain}? - domain_count_after: andre instanser - domain_count_before: Koblet til - features: - api: Åpent api for applikasjoner og tjenester - blocks: Rikholdige blokkerings verktøy - characters: 500 tegn per post - chronology: Tidslinjer er kronologiske - ethics: 'Etisk design: Ingen reklame, ingen sporing' - gifv: GIFV sett og korte videoer - privacy: Finmaskete personvernsinnstillinger - public: Offentlige tidslinjer - features_headline: Hva skiller Mastodon fra andre sosiale nettverk - get_started: Kom i gang - links: Lenker - other_instances: Andre instanser - source_code: Kildekode - status_count_after: statuser - status_count_before: Hvem skrev - terms: Betingelser - user_count_after: brukere - user_count_before: Hjem til - accounts: - follow: Følg - followers: Følgere - following: Følger - nothing_here: Det er ingenting her! - people_followed_by: Folk som %{name} følger - people_who_follow: Folk som følger %{name} - posts: Poster - remote_follow: Følg fra andre instanser - unfollow: Avfølg - application_mailer: - settings: 'Endre foretrukne epost innstillinger: %{link}' - signature: Mastodon notiser fra %{instance} - view: 'Se:' - applications: - invalid_url: Den oppgitte URLen er ugyldig - auth: - change_password: Brukerdetaljer - didnt_get_confirmation: Fikk du ikke bekreftelsesmailen din? - forgot_password: Har du glemt passordet ditt? - login: Innlogging - logout: Logg ut - register: Bli med - resend_confirmation: Send bekreftelsesinstruksjoner på nytt - reset_password: Nullstill passord - set_new_password: Sett nytt passord - authorize_follow: - error: Uheldigvis så skjedde det en feil når vi prøvde å få tak i en konto fra en annen instans. - follow: Følg - prompt_html: 'Du (%{self}) har spurt om å følge:' - title: Følg %{acct} - datetime: - distance_in_words: - about_x_hours: "%{count}t" - about_x_months: "%{count}m" - about_x_years: "%{count}å" - almost_x_years: "%{count}å" - half_a_minute: Nylig - less_than_x_minutes: "%{count}min" - less_than_x_seconds: Nylig - over_x_years: "%{count}å" - x_days: "%{count}d" - x_minutes: "%{count}min" - x_months: "%{count}mo" - x_seconds: "%{count}s" - exports: - blocks: Du blokkerer - csv: CSV - follows: Du følger - storage: Media lagring - generic: - changes_saved_msg: Vellykket lagring av endringer! - powered_by: drevet av %{link} - save_changes: Lagre endringer - validation_errors: - one: Noe er ikke helt riktig ennå. Vær snill å se etter en gang til - other: Noe er ikke helt riktig ennå. Det er ennå %{count} feil å rette på - imports: - preface: Du kan importere data om mennesker du følger eller blokkerer inn til kontoen din på denne instansen, fra filer opprettet av eksporter fra andre instanser. - success: Din data ble mottatt og vil bli prosessert så fort som mulig. - types: - blocking: Blokkeringsliste - following: Følgeliste - upload: Opplastning - landing_strip_html: %{name} er en bruker på %{domain}. Du kan følge dem eller interagere med dem hvis du har en konto hvor som helst i fediverset. Hvis du ikke har en konto så kan du registrere deg her. - notification_mailer: - digest: - body: 'Her er en kort oppsummering av hva du har gått glipp av på %{instance} siden du logget deg inn sist den %{since}:' - mention: "%{name} nevnte deg i:" - new_followers_summary: - one: Du har fått en ny følger. Jippi! - other: Du har fått %{count} nye følgere! Imponerende! - subject: - one: "1 ny hendelse siden ditt siste besøk \U0001F418" - other: "%{count} nye hendelser siden ditt siste besøk \U0001F418" - favourite: - body: 'Din status ble satt som favoritt av %{name}' - subject: "%{name} satte din status som favoritt." - follow: - body: "%{name} følger deg!" - subject: "%{name} følger deg" - follow_request: - body: "%{name} har spurt om å få lov til å følge deg" - subject: 'Ventende følger: %{name}' - mention: - body: 'Du ble nevnt av %{name} i:' - subject: Du ble nevnt av %{name} - reblog: - body: 'Din status fikk en boost av %{name}:' - subject: "%{name} ga din status en boost" - pagination: - next: Neste - prev: Forrige - remote_follow: - acct: Tast inn brukernavn@domene som du vil følge fra - missing_resource: Kunne ikke finne URLen for din konto - proceed: Fortsett med følging - prompt: 'Du kommer til å følge:' - settings: - authorized_apps: Autoriserte applikasjoner - back: Tilbake til Mastodon - edit_profile: Endre profil - export: Data eksport - import: Importer - preferences: Foretrukne valg - settings: Innstillinger - two_factor_auth: To-faktor autentisering - statuses: - open_in_web: Åpne i nettleser - over_character_limit: tegngrense på %{max} overskredet - show_more: Vis mer - visibilities: - private: Vis kun til følgere - public: Offentlig - unlisted: Offentlig, men vis ikke på offentlig tidslinje - stream_entries: - click_to_show: Klikk for å vise - reblogged: boostet - sensitive_content: Sensitivt innhold - time: - formats: - default: "%d, %b %Y, %H:%M" - two_factor_auth: - description_html: Hvis du skru på tofaktor autentisering vil innlogging kreve at du har telefonen din, som vil generere koder som du må taste inn. - disable: Skru av - enable: Skru på - instructions_html: "Scan denne QR-koden i Google Authenticator eller en lignende app på telefonen din. Fra nå av så vil denne applikasjonen generere koder for deg som skal brukes under innlogging" - plaintext_secret_html: 'Plain-text secret: %{secret}' - warning: Hvis du ikke kan konfigurere en autentikatorapp nå, så bør du trykke "Skru av"; ellers vil du ikke kunne logge inn. - users: - invalid_email: E-post addressen er ugyldig - invalid_otp_token: Ugyldig two-faktor kode - will_paginate: - page_gap: "…" +--- {} diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml index 6829e6a24..2fbf0ffd7 100644 --- a/config/locales/simple_form.no.yml +++ b/config/locales/simple_form.no.yml @@ -1,46 +1 @@ ---- -no: - simple_form: - hints: - defaults: - avatar: PNG, GIF eller JPG. Maksimalt 2MB. Vil bli nedskalert til 120x120px - display_name: Maksimalt 30 tegn - header: PNG, GIF eller JPG. Maksimalt 2MB. Vil bli nedskalert til 700x335px - locked: Krever at du manuelt godkjenner følgere og setter standard beskyttelse av poster til kun-følgere - note: Maksimalt 160 tegn - imports: - data: CSV fil eksportert fra en annen Mastodon instans - labels: - defaults: - avatar: Avatar - confirm_new_password: Bekreft nytt passord - confirm_password: Bekreft passord - current_password: Nåværende passord - data: Data - display_name: Visningsnavn - email: E-post adresse - header: Header - locale: Språk - locked: Endre konto til privat - new_password: Nytt passord - note: Biografi - otp_attempt: To-faktor kode - password: Passord - setting_default_privacy: Leserettigheter for poster - type: Importeringstype - username: Brukernavn - interactions: - must_be_follower: Blokker meldinger fra ikke-følgere - must_be_following: Blokker meldinger fra folk du ikke følger - notification_emails: - digest: Send oppsummerings eposter - favourite: Send e-post når noen setter din status som favoritt - follow: Send e-post når noen følger deg - follow_request: Send e-post når noen spør om å få følge deg - mention: Send e-post når noen nevner deg - reblog: Send e-post når noen reblogger din status - 'no': 'Nei' - required: - mark: "*" - text: påkrevd - 'yes': 'Ja' +--- {} diff --git a/config/navigation.rb b/config/navigation.rb index 77556e5aa..c6b7b9767 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -14,11 +14,11 @@ SimpleNavigation::Configuration.run do |navigation| settings.item :authorized_apps, safe_join([fa_icon('list fw'), t('settings.authorized_apps')]), oauth_authorized_applications_url end - primary.item :admin, safe_join([fa_icon('cogs fw'), 'Administration']), admin_accounts_url, if: proc { current_user.admin? } do |admin| + primary.item :admin, safe_join([fa_icon('cogs fw'), 'Administration']), admin_reports_url, if: proc { current_user.admin? } do |admin| admin.item :reports, safe_join([fa_icon('flag fw'), 'Reports']), admin_reports_url, highlights_on: %r{/admin/reports} admin.item :accounts, safe_join([fa_icon('users fw'), 'Accounts']), admin_accounts_url, highlights_on: %r{/admin/accounts} admin.item :pubsubhubbubs, safe_join([fa_icon('paper-plane-o fw'), 'PubSubHubbub']), admin_pubsubhubbub_index_url - admin.item :domain_blocks, safe_join([fa_icon('lock fw'), 'Domain Blocks']), admin_domain_blocks_url + admin.item :domain_blocks, safe_join([fa_icon('lock fw'), 'Domain Blocks']), admin_domain_blocks_url, highlights_on: %r{/admin/domain_blocks} admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url admin.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url admin.item :settings, safe_join([fa_icon('cogs fw'), 'Site Settings']), admin_settings_url diff --git a/config/routes.rb b/config/routes.rb index bfca5c734..ca77191f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -77,7 +77,7 @@ Rails.application.routes.draw do namespace :admin do resources :pubsubhubbub, only: [:index] - resources :domain_blocks, only: [:index, :create] + resources :domain_blocks, only: [:index, :new, :create] resources :settings, only: [:index, :update] resources :reports, only: [:index, :show] do -- cgit From 7dd5ba42a394e64ef55b066628294cc0c61d2d58 Mon Sep 17 00:00:00 2001 From: Korbinian Date: Mon, 3 Apr 2017 19:01:17 +0200 Subject: Updated and fixed german orthography --- config/locales/devise.de.yml | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/config/locales/devise.de.yml b/config/locales/devise.de.yml index 181502f9c..58bfaa3d6 100644 --- a/config/locales/devise.de.yml +++ b/config/locales/devise.de.yml @@ -2,59 +2,59 @@ de: devise: confirmations: - confirmed: "Vielen Dank für Deine Registrierung. Bitte melde dich jetzt an." - send_instructions: "Du erhältst in wenigen Minuten eine E-Mail, mit der Du Deine Registrierung bestätigen kannst." - send_paranoid_instructions: "Falls Deine E-Mail-Adresse in unserer Datenbank existiert erhältst Du in wenigen Minuten eine E-Mail mit der Du Deine Registrierung bestätigen kannst." + confirmed: "Vielen Dank für deine Registrierung. Bitte melde dich jetzt an." + send_instructions: "Du erhältst in wenigen Minuten eine E-Mail, mit der du deine Registrierung bestätigen kannst." + send_paranoid_instructions: "Falls Deine E-Mail-Adresse in unserer Datenbank existiert, erhältst Du in wenigen Minuten eine E-Mail mit der du deine Registrierung bestätigen kannst." failure: already_authenticated: "Du bist bereits angemeldet." inactive: "Dein Account ist nicht aktiv." invalid: "Ungültige Anmeldedaten." - last_attempt: "Du hast noch einen Versuch bevor dein Account gesperrt wird" + last_attempt: "Du hast noch einen Versuch bevor dein Account gesperrt wird." locked: "Dein Account ist gesperrt." not_found_in_database: "E-Mail-Adresse oder Passwort ungültig." - timeout: "Deine Sitzung ist abgelaufen, bitte melde Dich erneut an." - unauthenticated: "Du musst Dich anmelden oder registrieren, bevor Du fortfahren kannst." - unconfirmed: "Du musst Deinen Account bestätigen, bevor Du fortfahren kannst." + timeout: "Deine Sitzung ist abgelaufen, bitte melde dich erneut an." + unauthenticated: "Du musst Dich anmelden oder registrieren, bevor du fortfahren kannst." + unconfirmed: "Du musst deinen Account bestätigen, bevor du fortfahren kannst." mailer: confirmation_instructions: - subject: "Mastodon: Anleitung zur Bestätigung Deines Accounts" + subject: "Mastodon: Anleitung zur Bestätigung deines Accounts" password_change: subject: 'Mastodon: Passwort wurde geändert' reset_password_instructions: - subject: "Mastodon: Anleitung um Dein Passwort zurückzusetzen" + subject: "Mastodon: Anleitung um dein Passwort zurückzusetzen" unlock_instructions: - subject: "Mastodon: Anleitung um Deinen Account freizuschalten" + subject: "Mastodon: Anleitung um deinen Account freizuschalten" omniauth_callbacks: - failure: "Du konntest nicht Deinem %{kind}-Account angemeldet werden, weil '%{reason}'." - success: "Du hast Dich erfolgreich mit Deinem %{kind}-Account angemeldet." + failure: "Du konntest nicht mit deinem %{kind}-Account angemeldet werden, weil '%{reason}'." + success: "Du hast dich erfolgreich mit Deinem %{kind}-Account angemeldet." passwords: - no_token: "Du kannst diese Seite nur von dem Link aus einer E-Mail zum Passwort-Zurücksetzen aufrufen. Wenn du einen solchen Link aufgerufen hast stelle bitte sicher, dass du die vollständige Adresse aufrufst." - send_instructions: "Du erhältst in wenigen Minuten eine E-Mail mit der Anleitung, wie Du Dein Passwort zurücksetzen kannst." - send_paranoid_instructions: "Falls Deine E-Mail-Adresse in unserer Datenbank existiert erhältst Du in wenigen Minuten eine E-Mail mit der Anleitung, wie Du Dein Passwort zurücksetzen können." + no_token: "Du kannst diese Seite nur über den Link aus der E-Mail zum Passwort-Zurücksetzen aufrufen. Wenn du einen solchen Link aufgerufen hast, stelle bitte sicher, dass du die vollständige Adresse aufrufst." + send_instructions: "Du erhältst in wenigen Minuten eine E-Mail mit der Anleitung, wie du dein Passwort zurücksetzen kannst." + send_paranoid_instructions: "Falls deine E-Mail-Adresse in unserer Datenbank existiert erhältst du in wenigen Minuten eine E-Mail mit der Anleitung, wie du dein Passwort zurücksetzen kannst." updated: "Dein Passwort wurde geändert. Du bist jetzt angemeldet." updated_not_active: "Dein Passwort wurde geändert." registrations: destroyed: "Dein Account wurde gelöscht." signed_up: "Du hast dich erfolgreich registriert." - signed_up_but_inactive: "Du hast dich erfolgreich registriert. Wir konnten Dich noch nicht anmelden, da Dein Account inaktiv ist." - signed_up_but_locked: "Du hast dich erfolgreich registriert. Wir konnten Dich noch nicht anmelden, da Dein Account gesperrt ist." - signed_up_but_unconfirmed: "Du hast Dich erfolgreich registriert. Wir konnten Dich noch nicht anmelden, da Dein Account noch nicht bestätigt ist. Du erhältst in Kürze eine E-Mail mit der Anleitung, wie Du Deinen Account freischalten kannst." - update_needs_confirmation: "Deine Daten wurden aktualisiert, aber Du musst Deine neue E-Mail-Adresse bestätigen. Du erhälst in wenigen Minuten eine E-Mail, mit der Du die Änderung Deiner E-Mail-Adresse abschließen kannst." + signed_up_but_inactive: "Du hast dich erfolgreich registriert. Wir konnten dich noch nicht anmelden, da dein Account inaktiv ist." + signed_up_but_locked: "Du hast dich erfolgreich registriert. Wir konnten dich noch nicht anmelden, da dein Account gesperrt ist." + signed_up_but_unconfirmed: "Du hast Dich erfolgreich registriert. Wir konnten dich noch nicht anmelden, da dein Account noch nicht bestätigt ist. Du erhältst in Kürze eine E-Mail mit der Anleitung, wie Du Deinen Account freischalten kannst." + update_needs_confirmation: "Deine Daten wurden aktualisiert, aber du musst deine neue E-Mail-Adresse bestätigen. Du erhälst in wenigen Minuten eine E-Mail, mit der du die Änderung deiner E-Mail-Adresse abschließen kannst." updated: "Deine Daten wurden aktualisiert." sessions: already_signed_out: "Erfolgreich abgemeldet." signed_in: "Erfolgreich angemeldet." signed_out: "Erfolgreich abgemeldet." unlocks: - send_instructions: "Du erhältst in wenigen Minuten eine E-Mail mit der Anleitung, wie Du Deinen Account entsperren können." - send_paranoid_instructions: "Falls Deine E-Mail-Adresse in unserer Datenbank existiert erhältst Du in wenigen Minuten eine E-Mail mit der Anleitung, wie Du Deinen Account entsperren kannst." + send_instructions: "Du erhältst in wenigen Minuten eine E-Mail mit der Anleitung, wie du deinen Account entsperren können." + send_paranoid_instructions: "Falls deine E-Mail-Adresse in unserer Datenbank existiert erhältst du in wenigen Minuten eine E-Mail mit der Anleitung, wie du deinen Account entsperren kannst." unlocked: "Dein Account wurde entsperrt. Du bist jetzt angemeldet." errors: messages: - already_confirmed: "wurde bereits bestätigt" - confirmation_period_expired: "muss innerhalb %{period} bestätigt werden, bitte fordere einen neuen Link an" - expired: "ist abgelaufen, bitte neu anfordern" - not_found: "nicht gefunden" + already_confirmed: "wurde bereits bestätigt." + confirmation_period_expired: "muss innerhalb %{period} bestätigt werden, bitte fordere einen neuen Link an." + expired: "ist abgelaufen, bitte neu anfordern." + not_found: "wurde nicht gefunden." not_locked: "ist nicht gesperrt" not_saved: one: "Konnte %{resource} nicht speichern: ein Fehler." -- cgit From ec8029a95531bd52bc6ed1e83c52362411210d5e Mon Sep 17 00:00:00 2001 From: Korbinian Date: Mon, 3 Apr 2017 19:10:48 +0200 Subject: Updated and fixed orthography --- config/locales/de.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index 320bd3144..d44845c6b 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1,14 +1,14 @@ --- de: about: - about_mastodon: Mastodon ist ein freier, quelloffener soziales Netzwerkserver. Eine dezentralisierte Alternative zu kommerziellen Plattformen, verhindert es die Risiken, die entstehen, wenn eine einzelne Firma deine Kommunikation monopolisiert. Jeder kann Mastodon verwenden und ganz einfach am sozialen Netzwerk teilnehmen. + about_mastodon: Mastodon ist ein freier, quelloffener soziales Netzwerkserver. Als dezentralisierte Alternative zu kommerziellen Plattformen verhindert es die Risiken, die entstehen, wenn eine einzelne Firma deine Kommunikation monopolisiert. Jeder kann Mastodon verwenden und ganz einfach am sozialen Netzwerk teilnehmen. get_started: Erste Schritte source_code: Quellcode terms: AGB accounts: follow: Folgen - followers: Folger - following: Folgt + followers: Follower + following: Gefolgt nothing_here: Hier gibt es nichts! people_followed_by: Nutzer, denen %{name} folgt people_who_follow: Nutzer, die %{name} folgen @@ -27,7 +27,7 @@ de: reset_password: Passwort zurücksetzen set_new_password: Neues Passwort setzen authorize_follow: - error: Das entfernte Profil konnte nicht geladen werden + error: Das Profil konnte nicht geladen werden follow: Folgen prompt_html: 'Du (%{self}) möchtest dieser Person folgen:' title: "%{acct} folgen" @@ -55,25 +55,25 @@ de: notification_mailer: favourite: body: 'Dein Beitrag wurde von %{name} favorisiert:' - subject: "%{name} hat deinen Beitrag favorisiert" + subject: "%{name} hat deinen Beitrag favorisiert." follow: body: "%{name} folgt dir jetzt!" - subject: "%{name} folgt dir nun" + subject: "%{name} folgt dir jetzt." follow_request: body: "%{name} möchte dir folgen:" - subject: "%{name} möchte dir folgen" + subject: "%{name} möchte dir folgen." mention: body: "%{name} hat dich erwähnt:" - subject: "%{name} hat dich erwähnt" + subject: "%{name} hat dich erwähnt." reblog: body: 'Dein Beitrag wurde von %{name} geteilt:' - subject: "%{name} teilte deinen Beitrag" + subject: "%{name} teilte deinen Beitrag." pagination: next: Vorwärts prev: Zurück remote_follow: - acct: Dein Nutzername@Domain, von dem du dieser Person folgen möchtest - missing_resource: Die erforderliche Weiterleitungs-URL konnte leider in deinem Profil nicht gefunden werden + acct: Dein Nutzername@Domain, von dem aus du dieser Person folgen möchtest. + missing_resource: Die erforderliche Weiterleitungs-URL konnte leider in deinem Profil nicht gefunden werden. proceed: Weiter prompt: 'Du wirst dieser Person folgen:' settings: -- cgit From 71458dc6df368801b32b55bb63baa94375019a83 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 3 Apr 2017 19:17:56 +0200 Subject: When taking action on a report (silence/suspend), it dismisses all other reports for that user automatically --- app/controllers/admin/reports_controller.rb | 4 ++-- app/views/admin/reports/index.html.haml | 35 ++++++++++++++++------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb index 0117a18ee..bb3f028d9 100644 --- a/app/controllers/admin/reports_controller.rb +++ b/app/controllers/admin/reports_controller.rb @@ -22,13 +22,13 @@ class Admin::ReportsController < ApplicationController def suspend Admin::SuspensionWorker.perform_async(@report.target_account.id) - @report.update(action_taken: true) + Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true) redirect_to admin_report_path(@report) end def silence @report.target_account.update(silenced: true) - @report.update(action_taken: true) + Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true) redirect_to admin_report_path(@report) end diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml index 8a5414cef..839259dc2 100644 --- a/app/views/admin/reports/index.html.haml +++ b/app/views/admin/reports/index.html.haml @@ -8,20 +8,25 @@ %li= filter_link_to 'Unresolved', action_taken: nil %li= filter_link_to 'Resolved', action_taken: '1' -%table.table - %thead - %tr - %th ID - %th Target - %th Reported by - %th Comment - %th - %tbody - - @reports.each do |report| += form_tag do + + %table.table + %thead %tr - %td= "##{report.id}" - %td= link_to report.target_account.acct, admin_account_path(report.target_account.id) - %td= link_to report.account.acct, admin_account_path(report.account.id) - %td= truncate(report.comment, length: 30, separator: ' ') - %td= table_link_to 'circle', 'View', admin_report_path(report) + %th + %th ID + %th Target + %th Reported by + %th Comment + %th + %tbody + - @reports.each do |report| + %tr + %td= check_box_tag 'select', report.id + %td= "##{report.id}" + %td= link_to report.target_account.acct, admin_account_path(report.target_account.id) + %td= link_to report.account.acct, admin_account_path(report.account.id) + %td= truncate(report.comment, length: 30, separator: ' ') + %td= table_link_to 'circle', 'View', admin_report_path(report) + = will_paginate @reports, pagination_options -- cgit From 68f829e11c058c55a6695b5812aa0577b5b1eea1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 3 Apr 2017 19:27:30 +0200 Subject: Add basic logging of who resolved report --- app/controllers/admin/reports_controller.rb | 6 +++--- app/models/report.rb | 1 + app/views/admin/reports/show.html.haml | 8 +++++++- ...3172249_add_action_taken_by_account_id_to_reports.rb | 5 +++++ db/schema.rb | 17 +++++++++-------- spec/services/block_domain_service_spec.rb | 2 +- 6 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 db/migrate/20170403172249_add_action_taken_by_account_id_to_reports.rb diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb index bb3f028d9..2b3b1809f 100644 --- a/app/controllers/admin/reports_controller.rb +++ b/app/controllers/admin/reports_controller.rb @@ -16,19 +16,19 @@ class Admin::ReportsController < ApplicationController end def resolve - @report.update(action_taken: true) + @report.update(action_taken: true, action_taken_by_account_id: current_account.id) redirect_to admin_report_path(@report) end def suspend Admin::SuspensionWorker.perform_async(@report.target_account.id) - Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true) + Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true, action_taken_by_account_id: current_account.id) redirect_to admin_report_path(@report) end def silence @report.target_account.update(silenced: true) - Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true) + Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true, action_taken_by_account_id: current_account.id) redirect_to admin_report_path(@report) end diff --git a/app/models/report.rb b/app/models/report.rb index 05dc8cff1..fd8e46aac 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -3,6 +3,7 @@ class Report < ApplicationRecord belongs_to :account belongs_to :target_account, class_name: 'Account' + belongs_to :action_taken_by_account, class_name: 'Account' scope :unresolved, -> { where(action_taken: false) } scope :resolved, -> { where(action_taken: true) } diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 74cac016d..caa8415df 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -27,7 +27,7 @@ = link_to remove_admin_report_path(@report, status_id: status.id), method: :post, class: 'icon-button', style: 'font-size: 24px; width: 24px; height: 24px', title: 'Delete' do = fa_icon 'trash' -- unless @report.action_taken? +- if !@report.action_taken? %hr/ %div{ style: 'overflow: hidden' } @@ -36,3 +36,9 @@ = link_to 'Suspend account', suspend_admin_report_path(@report), method: :post, class: 'button' %div{ style: 'float: left' } = link_to 'Mark as resolved', resolve_admin_report_path(@report), method: :post, class: 'button' +- elsif !@report.action_taken_by_account.nil? + %hr/ + + %p + %strong Action taken by: + = @report.action_taken_by_account.acct diff --git a/db/migrate/20170403172249_add_action_taken_by_account_id_to_reports.rb b/db/migrate/20170403172249_add_action_taken_by_account_id_to_reports.rb new file mode 100644 index 000000000..2d4e12198 --- /dev/null +++ b/db/migrate/20170403172249_add_action_taken_by_account_id_to_reports.rb @@ -0,0 +1,5 @@ +class AddActionTakenByAccountIdToReports < ActiveRecord::Migration[5.0] + def change + add_column :reports, :action_taken_by_account_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 5a9ca1426..3aaa3e3ad 100644 --- a/db/schema.rb +++ b/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: 20170330164118) do +ActiveRecord::Schema.define(version: 20170403172249) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -201,13 +201,14 @@ ActiveRecord::Schema.define(version: 20170330164118) do end create_table "reports", force: :cascade do |t| - t.integer "account_id", null: false - t.integer "target_account_id", null: false - t.bigint "status_ids", default: [], null: false, array: true - t.text "comment", default: "", null: false - t.boolean "action_taken", default: false, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "account_id", null: false + t.integer "target_account_id", null: false + t.bigint "status_ids", default: [], null: false, array: true + t.text "comment", default: "", null: false + t.boolean "action_taken", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "action_taken_by_account_id" end create_table "settings", force: :cascade do |t| diff --git a/spec/services/block_domain_service_spec.rb b/spec/services/block_domain_service_spec.rb index d88b3b55c..8e71d4542 100644 --- a/spec/services/block_domain_service_spec.rb +++ b/spec/services/block_domain_service_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BlockDomainService do bad_status2 bad_attachment - subject.call('evil.org', :suspend) + subject.call(DomainBlock.create!(domain: 'evil.org', severity: :suspend)) end it 'creates a domain block' do -- cgit From 98a93aa07e087ea3af98253a55a9ba2a043c5b36 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 3 Apr 2017 19:50:55 +0200 Subject: Fix norwegian translation being malformed --- config/locales/devise.no.yml | 62 +++++++++++++- config/locales/doorkeeper.no.yml | 114 +++++++++++++++++++++++++- config/locales/no.yml | 165 +++++++++++++++++++++++++++++++++++++- config/locales/simple_form.no.yml | 47 ++++++++++- 4 files changed, 384 insertions(+), 4 deletions(-) diff --git a/config/locales/devise.no.yml b/config/locales/devise.no.yml index 2fbf0ffd7..8b650e548 100644 --- a/config/locales/devise.no.yml +++ b/config/locales/devise.no.yml @@ -1 +1,61 @@ ---- {} +--- +'no': + devise: + confirmations: + confirmed: Epostaddressen din er blitt bekreftet. + send_instructions: Du vil motta en epost med instruksjoner for hvordan bekrefte din epostaddresse om noen få minutter. + send_paranoid_instructions: Hvis din epostaddresse finnes i vår database vil du motta en epost med instruksjoner for hvordan bekrefte din epost om noen få minutter. + failure: + already_authenticated: Du er allerede innlogget. + inactive: Din konto er ikke blitt aktivert ennå. + invalid: Ugyldig %{authentication_keys} eller passord. + last_attempt: Du har ett forsøk igjen før kontoen din bli låst. + locked: Din konto er låst. + not_found_in_database: Ugyldig %{authentication_keys} eller passord. + timeout: Sesjonen din løp ut på tid. Logg inn på nytt for å fortsette. + unauthenticated: Du må logge inn eller registrere deg før du kan fortsette. + unconfirmed: Du må bekrefte epostadressen din før du kan fortsette. + mailer: + confirmation_instructions: + subject: 'Mastodon: Instruksjoner for å bekrefte epostadresse' + password_change: + subject: 'Mastodon: Passord endret' + reset_password_instructions: + subject: 'Mastodon: Hvordan nullstille passord?' + unlock_instructions: + subject: 'Mastodon: Instruksjoner for å gjenåpne konto' + omniauth_callbacks: + failure: Kunne ikke autentisere deg fra %{kind} fordi "%{reason}". + success: Vellykket autentisering fra %{kind}. + passwords: + no_token: Du har ingen tilgang til denne siden så lenge du ikke kommer fra en epost om nullstilling av passord. Hvis du kommer fra en passordnullstilling epost, dobbelsjekk at du brukte hele URLen. + send_instructions: Du vil motta en epost med instruksjoner for å nullstille passordet ditt om noen få minutter. + send_paranoid_instructions: Hvis epostadressen din finnes i databasen vår vil du motta en instruksjonsmail om passord nullstilling om noen få minutter. + updated: Passordet ditt har blitt endret. Du er nå logget inn. + updated_not_active: Passordet ditt har blitt endret. + registrations: + destroyed: Adjø! Kontoen din har blitt avsluttet. Vi håper at vi ser deg igjen snart. + signed_up: Velkommen! Registrasjonen var vellykket. + signed_up_but_inactive: Registrasjonen var vellykket. Vi kunne dessverre ikke logge deg inn fordi kontoen din ennå ikke har blitt aktivert. + signed_up_but_locked: Registrasjonen var vellykket. Vi kunne dessverre ikke logge deg inn fordi kontoen din har blitt låst. + signed_up_but_unconfirmed: En epostmelding med en bekreftelseslink har blitt sendt til din adresse. Klikk på linken i eposten for å aktivere kontoen din. + update_needs_confirmation: Du har oppdatert kontoen din, men vi må bekrefte din nye epostadresse. Sjekk eposten din og følg bekreftelseslinken for å bekrefte din nye epostadresse. + updated: Kontoen din ble oppdatert. + sessions: + already_signed_out: Logget ut. + signed_in: Logget inn. + signed_out: Logget ut. + unlocks: + send_instructions: Du vil motta en epost med instruksjoner for å åpne kontoen din om noen få minutter. + send_paranoid_instructions: Hvis kontoen din eksisterer vil du motta en epost med instruksjoner for å åpne kontoen din om noen få minutter. + unlocked: Kontoen din ble åpnet uten problemer. Logg på for å fortsette. + errors: + messages: + already_confirmed: har allerede blitt bekreftet, prøv å logg på istedet. + confirmation_period_expired: må bekreftes innen %{period}. Spør om en ny bekreftelsesmail istedet. + expired: har utløpt, spør om en ny en istedet + not_found: ikke funnet + not_locked: var ikke låst + not_saved: + one: '1 feil hindret denne %{resource} fra å bli lagret:' + other: "%{count} feil hindret denne %{resource} fra å bli lagret:" diff --git a/config/locales/doorkeeper.no.yml b/config/locales/doorkeeper.no.yml index 2fbf0ffd7..f149f53e0 100644 --- a/config/locales/doorkeeper.no.yml +++ b/config/locales/doorkeeper.no.yml @@ -1 +1,113 @@ ---- {} +--- +'no': + activerecord: + attributes: + doorkeeper/application: + name: Navn + redirect_uri: Omdirigerings-URI + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: kan ikke inneholde ett fragment. + invalid_uri: må være en gyldig URI. + relative_uri: må være en absolutt URI. + secured_uri: må være en HTTPS/SSL URI. + doorkeeper: + applications: + buttons: + authorize: Autoriser + cancel: Avbryt + destroy: Ødelegg + edit: Endre + submit: Send inn + confirmations: + destroy: Er du sikker? + edit: + title: Endre applikasjon + form: + error: Whoops! Sjekk skjemaet ditt for mulige feil + help: + native_redirect_uri: Bruk %{native_redirect_uri} for lokale tester + redirect_uri: Bruk en linje per URI + scopes: Adskill omfang med mellomrom. La det være blankt for å bruke standard omfang. + index: + callback_url: Callback URL + name: Navn + new: Ny Applikasjon + title: Dine applikasjoner + new: + title: Ny Applikasjoner + show: + actions: Operasjoner + application_id: Applikasjon Id + callback_urls: Callback urls + scopes: Omfang + secret: Hemmelighet + title: 'Applikasjon: %{name}' + authorizations: + buttons: + authorize: Autoriser + deny: Avvis + error: + title: En feil oppsto + new: + able_to: Den vil ha mulighet til + prompt: Applikasjon %{client_name} spør om tilgang til din konto + title: Autorisasjon påkrevd + show: + title: Autoriserings kode + authorized_applications: + buttons: + revoke: Opphev + confirmations: + revoke: Opphev? + index: + application: Applikasjon + created_at: Autorisert + date_format: "%Y-%m-%d %H:%M:%S" + scopes: Omfang + title: Dine autoriserte applikasjoner + errors: + messages: + access_denied: Ressurseieren eller autoriserings tjeneren avviste forespørslen. + credential_flow_not_configured: Ressurseiers passord flyt feilet på grunn av at Doorkeeper.configure.resource_owner_from_credentials ikke var konfigurert. + invalid_client: Klient autentisering feilet på grunn av ukjent klient, ingen autentisering inkludert eller autentiserings metode som ikke er støttet. + invalid_grant: Autoriseringen er ugyldig, utløpt, opphevet, stemmer ikke overens med omdirigerings-URIen eller var utstedt til en annen klient. + invalid_redirect_uri: redirect urien som var inkludert er ikke gyldig. + invalid_request: Forespørslen mangler ett eller flere parametere, inkluderte ett parameter som ikke støttes eller har feil struktur. + invalid_resource_owner: Ressurseierens detaljer er ikke gyldig, eller så kan ikke eieren finnes. + invalid_scope: Det etterspurte omfanget er ugyldig, ukjent eller har feil struktur. + invalid_token: + expired: Tilgangsbeviset har utløpt + revoked: Tilgangsbeviset har blitt opphevet + unknown: Tilgangsbeviset er ugyldig + resource_owner_authenticator_not_configured: Ressurseier kunne ikke finnes fordi Doorkeeper.configure.resource_owner_authenticator ikke er konfigurert. + server_error: Autoriserings tjeneren støtte på en uventet hendelse som hindret den i å svare på forespørslen. + temporarily_unavailable: Autoriserings tjeneren kan ikke håndtere forespørslen grunnet en midlertidig overbelastning eller tjenervedlikehold. + unauthorized_client: Klienten har ikke autorisasjon for å utføre denne forespørslen med denne metoden. + unsupported_grant_type: Autorisasjons tildelings typen er ikke støttet av denne autoriserings tjeneren. + unsupported_response_type: Autorisasjons serveren støtter ikke denne typen av forespørsler. + flash: + applications: + create: + notice: Applikasjon opprettet. + destroy: + notice: Applikasjon slettet. + update: + notice: Applikasjon oppdatert. + authorized_applications: + destroy: + notice: Applikasjon opphevet. + layouts: + admin: + nav: + applications: Applikasjoner + oauth2_provider: OAuth2 tilbyder + application: + title: OAuth autorisering påkrevet + scopes: + follow: følg, blokker, avblokker, avfølg kontoer + read: lese dine data + write: poste på dine vegne diff --git a/config/locales/no.yml b/config/locales/no.yml index 2fbf0ffd7..b9a752d5a 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -1 +1,164 @@ ---- {} +--- +'no': + about: + about_mastodon: Mastodon er et gratis, åpen kildekode sosialt nettverk. Et desentralisert alternativ til kommersielle plattformer. Slik kan det unngå risikoene ved å ha et enkelt selskap med monopol på din kommunikasjon. Velg en tjener du stoler på — uansett hvilken du velger så kan du interagere med alle andre. Alle kan kjøre sin egen Mastodon og delta sømløst i det sosiale nettverket. + about_this: Om denne instansen + apps: Applikasjoner + business_email: 'Bedriftsepost:' + contact: Kontakt + description_headline: Hva er %{domain}? + domain_count_after: andre instanser + domain_count_before: Koblet til + features: + api: Åpent api for applikasjoner og tjenester + blocks: Rikholdige blokkerings verktøy + characters: 500 tegn per post + chronology: Tidslinjer er kronologiske + ethics: 'Etisk design: Ingen reklame, ingen sporing' + gifv: GIFV sett og korte videoer + privacy: Finmaskete personvernsinnstillinger + public: Offentlige tidslinjer + features_headline: Hva skiller Mastodon fra andre sosiale nettverk + get_started: Kom i gang + links: Lenker + other_instances: Andre instanser + source_code: Kildekode + status_count_after: statuser + status_count_before: Hvem skrev + terms: Betingelser + user_count_after: brukere + user_count_before: Hjem til + accounts: + follow: Følg + followers: Følgere + following: Følger + nothing_here: Det er ingenting her! + people_followed_by: Folk som %{name} følger + people_who_follow: Folk som følger %{name} + posts: Poster + remote_follow: Følg fra andre instanser + unfollow: Avfølg + application_mailer: + settings: 'Endre foretrukne epost innstillinger: %{link}' + signature: Mastodon notiser fra %{instance} + view: 'Se:' + applications: + invalid_url: Den oppgitte URLen er ugyldig + auth: + change_password: Brukerdetaljer + didnt_get_confirmation: Fikk du ikke bekreftelsesmailen din? + forgot_password: Har du glemt passordet ditt? + login: Innlogging + logout: Logg ut + register: Bli med + resend_confirmation: Send bekreftelsesinstruksjoner på nytt + reset_password: Nullstill passord + set_new_password: Sett nytt passord + authorize_follow: + error: Uheldigvis så skjedde det en feil når vi prøvde å få tak i en konto fra en annen instans. + follow: Følg + prompt_html: 'Du (%{self}) har spurt om å følge:' + title: Følg %{acct} + datetime: + distance_in_words: + about_x_hours: "%{count}t" + about_x_months: "%{count}m" + about_x_years: "%{count}å" + almost_x_years: "%{count}å" + half_a_minute: Nylig + less_than_x_minutes: "%{count}min" + less_than_x_seconds: Nylig + over_x_years: "%{count}å" + x_days: "%{count}d" + x_minutes: "%{count}min" + x_months: "%{count}mo" + x_seconds: "%{count}s" + exports: + blocks: Du blokkerer + csv: CSV + follows: Du følger + storage: Media lagring + generic: + changes_saved_msg: Vellykket lagring av endringer! + powered_by: drevet av %{link} + save_changes: Lagre endringer + validation_errors: + one: Noe er ikke helt riktig ennå. Vær snill å se etter en gang til + other: Noe er ikke helt riktig ennå. Det er ennå %{count} feil å rette på + imports: + preface: Du kan importere data om mennesker du følger eller blokkerer inn til kontoen din på denne instansen, fra filer opprettet av eksporter fra andre instanser. + success: Din data ble mottatt og vil bli prosessert så fort som mulig. + types: + blocking: Blokkeringsliste + following: Følgeliste + upload: Opplastning + landing_strip_html: %{name} er en bruker på %{domain}. Du kan følge dem eller interagere med dem hvis du har en konto hvor som helst i fediverset. Hvis du ikke har en konto så kan du registrere deg her. + notification_mailer: + digest: + body: 'Her er en kort oppsummering av hva du har gått glipp av på %{instance} siden du logget deg inn sist den %{since}:' + mention: "%{name} nevnte deg i:" + new_followers_summary: + one: Du har fått en ny følger. Jippi! + other: Du har fått %{count} nye følgere! Imponerende! + subject: + one: "1 ny hendelse siden ditt siste besøk \U0001F418" + other: "%{count} nye hendelser siden ditt siste besøk \U0001F418" + favourite: + body: 'Din status ble satt som favoritt av %{name}' + subject: "%{name} satte din status som favoritt." + follow: + body: "%{name} følger deg!" + subject: "%{name} følger deg" + follow_request: + body: "%{name} har spurt om å få lov til å følge deg" + subject: 'Ventende følger: %{name}' + mention: + body: 'Du ble nevnt av %{name} i:' + subject: Du ble nevnt av %{name} + reblog: + body: 'Din status fikk en boost av %{name}:' + subject: "%{name} ga din status en boost" + pagination: + next: Neste + prev: Forrige + remote_follow: + acct: Tast inn brukernavn@domene som du vil følge fra + missing_resource: Kunne ikke finne URLen for din konto + proceed: Fortsett med følging + prompt: 'Du kommer til å følge:' + settings: + authorized_apps: Autoriserte applikasjoner + back: Tilbake til Mastodon + edit_profile: Endre profil + export: Data eksport + import: Importer + preferences: Foretrukne valg + settings: Innstillinger + two_factor_auth: To-faktor autentisering + statuses: + open_in_web: Åpne i nettleser + over_character_limit: tegngrense på %{max} overskredet + show_more: Vis mer + visibilities: + private: Vis kun til følgere + public: Offentlig + unlisted: Offentlig, men vis ikke på offentlig tidslinje + stream_entries: + click_to_show: Klikk for å vise + reblogged: boostet + sensitive_content: Sensitivt innhold + time: + formats: + default: "%d, %b %Y, %H:%M" + two_factor_auth: + description_html: Hvis du skru på tofaktor autentisering vil innlogging kreve at du har telefonen din, som vil generere koder som du må taste inn. + disable: Skru av + enable: Skru på + instructions_html: "Scan denne QR-koden i Google Authenticator eller en lignende app på telefonen din. Fra nå av så vil denne applikasjonen generere koder for deg som skal brukes under innlogging" + plaintext_secret_html: 'Plain-text secret: %{secret}' + warning: Hvis du ikke kan konfigurere en autentikatorapp nå, så bør du trykke "Skru av"; ellers vil du ikke kunne logge inn. + users: + invalid_email: E-post addressen er ugyldig + invalid_otp_token: Ugyldig two-faktor kode + will_paginate: + page_gap: "…" diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml index 2fbf0ffd7..7e705b19b 100644 --- a/config/locales/simple_form.no.yml +++ b/config/locales/simple_form.no.yml @@ -1 +1,46 @@ ---- {} +--- +'no': + simple_form: + hints: + defaults: + avatar: PNG, GIF eller JPG. Maksimalt 2MB. Vil bli nedskalert til 120x120px + display_name: Maksimalt 30 tegn + header: PNG, GIF eller JPG. Maksimalt 2MB. Vil bli nedskalert til 700x335px + locked: Krever at du manuelt godkjenner følgere og setter standard beskyttelse av poster til kun-følgere + note: Maksimalt 160 tegn + imports: + data: CSV fil eksportert fra en annen Mastodon instans + labels: + defaults: + avatar: Avatar + confirm_new_password: Bekreft nytt passord + confirm_password: Bekreft passord + current_password: Nåværende passord + data: Data + display_name: Visningsnavn + email: E-post adresse + header: Header + locale: Språk + locked: Endre konto til privat + new_password: Nytt passord + note: Biografi + otp_attempt: To-faktor kode + password: Passord + setting_default_privacy: Leserettigheter for poster + type: Importeringstype + username: Brukernavn + interactions: + must_be_follower: Blokker meldinger fra ikke-følgere + must_be_following: Blokker meldinger fra folk du ikke følger + notification_emails: + digest: Send oppsummerings eposter + favourite: Send e-post når noen setter din status som favoritt + follow: Send e-post når noen følger deg + follow_request: Send e-post når noen spør om å få følge deg + mention: Send e-post når noen nevner deg + reblog: Send e-post når noen reblogger din status + 'no': 'Nei' + required: + mark: "*" + text: påkrevd + 'yes': 'Ja' -- cgit From cc451e1fcbb7682c2f440e6cf624d0086fae0e11 Mon Sep 17 00:00:00 2001 From: Wonderfall Date: Mon, 3 Apr 2017 21:36:28 +0200 Subject: update social.targaryen.house info --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 780977bd4..d9d0aa2e1 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -17,7 +17,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.diskseven.com](https://social.diskseven.com) |Single user|No|No (DNS entry but no response)| | [social.gestaltzerfall.net](https://social.gestaltzerfall.net) |Single user|No|No| | [mastodon.xyz](https://mastodon.xyz) |N/A|Yes|Yes| -| [social.targaryen.house](https://social.targaryen.house) |N/A|Yes|No| +| [social.targaryen.house](https://social.targaryen.house) |Federates everywhere, quick updates.|Yes|Yes| | [social.mashek.net](https://social.mashek.net) |Themed and customised for Mashekstein Labs community. Selectively federates.|Yes|No| | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| -- cgit From 1ed37fae9b9d4807c01d056d6dc81c57b18c59a9 Mon Sep 17 00:00:00 2001 From: Aesen Date: Mon, 3 Apr 2017 15:52:33 -0400 Subject: Add fern.surgeplay.com to the instances list It's hard to tell if this is supposed to be alphabetically sorted or not. I put it after epiktistes since it starts with F - let me know if it should go elsewhere. --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 780977bd4..be9d3723a 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -11,6 +11,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [animalliberation.social](https://animalliberation.social) |Animal Rights|Yes|No| | [socially.constructed.space](https://socially.constructed.space) |Single user|No|No| | [epiktistes.com](https://epiktistes.com) |N/A|Yes|No| +| [fern.surgeplay.com](https://fern.surgeplay.com) |Federates everywhere, Minecraft-focused|Yes|No | [gay.crime.team](https://gay.crime.team) |the place for doin' gay crime online (please don't actually do crime here)|Yes|No| | [icosahedron.website](https://icosahedron.website/) |Icosahedron-themed (well, visually), open registration.|Yes|No| | [memetastic.space](https://memetastic.space) |Memes|Yes|No| -- cgit From 3f30ae1f97717177f29711d5b99d7970c6b75b3e Mon Sep 17 00:00:00 2001 From: halna_Tanaguru Date: Mon, 3 Apr 2017 22:45:29 +0200 Subject: accessibility fix eanable focus on ClearColumnButton --- .../features/notifications/components/clear_column_button.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx b/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx index d75149a0e..6aa9d1efa 100644 --- a/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx +++ b/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx @@ -9,7 +9,7 @@ const iconStyle = { }; const ClearColumnButton = ({ onClick }) => ( -
+
); -- cgit From 8232f76c482d3046055bd7bf224ef7835d0fa399 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 3 Apr 2017 22:54:46 +0200 Subject: Add check for visibility.nil? even though it can't ever be, to check for race conditions --- app/lib/exceptions.rb | 1 + app/services/fan_out_on_write_service.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/lib/exceptions.rb b/app/lib/exceptions.rb index 200da9fe1..9bc802c12 100644 --- a/app/lib/exceptions.rb +++ b/app/lib/exceptions.rb @@ -4,4 +4,5 @@ module Mastodon class Error < StandardError; end class NotPermittedError < Error; end class ValidationError < Error; end + class RaceConditionError < Error; end end diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 402b84b2f..df404cbef 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -4,6 +4,8 @@ class FanOutOnWriteService < BaseService # Push a status into home and mentions feeds # @param [Status] status def call(status) + raise Mastodon::RaceConditionError if status.visibility.nil? + deliver_to_self(status) if status.account.local? if status.direct_visibility? -- cgit From 5b6f4fdeb4932df1704da01762cc22c63aacb20f Mon Sep 17 00:00:00 2001 From: Alice Date: Mon, 3 Apr 2017 23:05:03 +0200 Subject: Add octodon.social --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 780977bd4..aac3841b3 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -22,5 +22,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| | [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, federates everywhere, no moderation yet|Yes|Yes| +| [octodon.social](https://octodon.social) |Open registrations, federates everywhere, cutest instance yet|Yes|Yes| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From ce1ca2859403fd21db1f6237ce6a563edd4f62ae Mon Sep 17 00:00:00 2001 From: Neville Park Date: Mon, 3 Apr 2017 17:45:36 -0400 Subject: Changed "reblogs" to "boosts" --- config/locales/simple_form.en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 4d1758f82..c781831a8 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -33,7 +33,7 @@ en: follow: Send e-mail when someone follows you follow_request: Send e-mail when someone requests to follow you mention: Send e-mail when someone mentions you - reblog: Send e-mail when someone reblogs your status + reblog: Send e-mail when someone boosts your status 'no': 'No' required: mark: "*" -- cgit From f722bd2387df9163760014e9555928ec487ae95f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 00:53:20 +0200 Subject: Separate background jobs into different queues. ATTENTION: new queue "pull" must be added to the Sidekiq invokation in your systemd file The pull queue will handle link crawling, thread resolving, and OStatus processing. Such tasks are more likely to hang for a longer time (due to network requests) so it is more sensible to not make the "in-house" tasks wait for them. --- app/workers/after_remote_follow_request_worker.rb | 2 +- app/workers/after_remote_follow_worker.rb | 2 +- app/workers/import_worker.rb | 2 +- app/workers/link_crawl_worker.rb | 2 +- app/workers/merge_worker.rb | 2 ++ app/workers/notification_worker.rb | 2 +- app/workers/processing_worker.rb | 2 +- app/workers/regeneration_worker.rb | 2 ++ app/workers/salmon_worker.rb | 2 +- app/workers/thread_resolve_worker.rb | 2 +- app/workers/unmerge_worker.rb | 2 ++ docker-compose.yml | 2 +- docs/Running-Mastodon/Production-guide.md | 2 +- 13 files changed, 16 insertions(+), 10 deletions(-) diff --git a/app/workers/after_remote_follow_request_worker.rb b/app/workers/after_remote_follow_request_worker.rb index f1d6869cc..1f2db3061 100644 --- a/app/workers/after_remote_follow_request_worker.rb +++ b/app/workers/after_remote_follow_request_worker.rb @@ -3,7 +3,7 @@ class AfterRemoteFollowRequestWorker include Sidekiq::Worker - sidekiq_options retry: 5 + sidekiq_options queue: 'pull', retry: 5 def perform(follow_request_id) follow_request = FollowRequest.find(follow_request_id) diff --git a/app/workers/after_remote_follow_worker.rb b/app/workers/after_remote_follow_worker.rb index 0d04456a9..bdd2c2a91 100644 --- a/app/workers/after_remote_follow_worker.rb +++ b/app/workers/after_remote_follow_worker.rb @@ -3,7 +3,7 @@ class AfterRemoteFollowWorker include Sidekiq::Worker - sidekiq_options retry: 5 + sidekiq_options queue: 'pull', retry: 5 def perform(follow_id) follow = Follow.find(follow_id) diff --git a/app/workers/import_worker.rb b/app/workers/import_worker.rb index a3ae2a85a..7cf29fb53 100644 --- a/app/workers/import_worker.rb +++ b/app/workers/import_worker.rb @@ -5,7 +5,7 @@ require 'csv' class ImportWorker include Sidekiq::Worker - sidekiq_options retry: false + sidekiq_options queue: 'pull', retry: false def perform(import_id) import = Import.find(import_id) diff --git a/app/workers/link_crawl_worker.rb b/app/workers/link_crawl_worker.rb index af3394b8b..834b0088b 100644 --- a/app/workers/link_crawl_worker.rb +++ b/app/workers/link_crawl_worker.rb @@ -3,7 +3,7 @@ class LinkCrawlWorker include Sidekiq::Worker - sidekiq_options retry: false + sidekiq_options queue: 'pull', retry: false def perform(status_id) FetchLinkCardService.new.call(Status.find(status_id)) diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb index 0f288f43f..d745cb99c 100644 --- a/app/workers/merge_worker.rb +++ b/app/workers/merge_worker.rb @@ -3,6 +3,8 @@ class MergeWorker include Sidekiq::Worker + sidekiq_options queue: 'pull' + def perform(from_account_id, into_account_id) FeedManager.instance.merge_into_timeline(Account.find(from_account_id), Account.find(into_account_id)) end diff --git a/app/workers/notification_worker.rb b/app/workers/notification_worker.rb index 1a2faefd8..da1d6ab45 100644 --- a/app/workers/notification_worker.rb +++ b/app/workers/notification_worker.rb @@ -3,7 +3,7 @@ class NotificationWorker include Sidekiq::Worker - sidekiq_options retry: 5 + sidekiq_options queue: 'push', retry: 5 def perform(xml, source_account_id, target_account_id) SendInteractionService.new.call(xml, Account.find(source_account_id), Account.find(target_account_id)) diff --git a/app/workers/processing_worker.rb b/app/workers/processing_worker.rb index 5df404bcc..4a467d924 100644 --- a/app/workers/processing_worker.rb +++ b/app/workers/processing_worker.rb @@ -3,7 +3,7 @@ class ProcessingWorker include Sidekiq::Worker - sidekiq_options backtrace: true + sidekiq_options queue: 'pull', backtrace: true def perform(account_id, body) ProcessFeedService.new.call(body, Account.find(account_id)) diff --git a/app/workers/regeneration_worker.rb b/app/workers/regeneration_worker.rb index 3aece0ba2..289b63d84 100644 --- a/app/workers/regeneration_worker.rb +++ b/app/workers/regeneration_worker.rb @@ -3,6 +3,8 @@ class RegenerationWorker include Sidekiq::Worker + sidekiq_options queue: 'pull', backtrace: true + def perform(account_id, timeline_type) PrecomputeFeedService.new.call(timeline_type, Account.find(account_id)) end diff --git a/app/workers/salmon_worker.rb b/app/workers/salmon_worker.rb index fc95ce47f..2888b574b 100644 --- a/app/workers/salmon_worker.rb +++ b/app/workers/salmon_worker.rb @@ -3,7 +3,7 @@ class SalmonWorker include Sidekiq::Worker - sidekiq_options backtrace: true + sidekiq_options queue: 'pull', backtrace: true def perform(account_id, body) ProcessInteractionService.new.call(body, Account.find(account_id)) diff --git a/app/workers/thread_resolve_worker.rb b/app/workers/thread_resolve_worker.rb index 593edd032..38287e8e6 100644 --- a/app/workers/thread_resolve_worker.rb +++ b/app/workers/thread_resolve_worker.rb @@ -3,7 +3,7 @@ class ThreadResolveWorker include Sidekiq::Worker - sidekiq_options retry: false + sidekiq_options queue: 'pull', retry: false def perform(child_status_id, parent_url) child_status = Status.find(child_status_id) diff --git a/app/workers/unmerge_worker.rb b/app/workers/unmerge_worker.rb index dbf7243de..ea6aacebf 100644 --- a/app/workers/unmerge_worker.rb +++ b/app/workers/unmerge_worker.rb @@ -3,6 +3,8 @@ class UnmergeWorker include Sidekiq::Worker + sidekiq_options queue: 'pull' + def perform(from_account_id, into_account_id) FeedManager.instance.unmerge_from_timeline(Account.find(from_account_id), Account.find(into_account_id)) end diff --git a/docker-compose.yml b/docker-compose.yml index 68c8ef960..d6ba66dde 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,7 +33,7 @@ services: restart: always build: . env_file: .env.production - command: bundle exec sidekiq -q default -q mailers -q push + command: bundle exec sidekiq -q default -q mailers -q pull -q push depends_on: - db - redis diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md index f0dd7bd2b..469fefa94 100644 --- a/docs/Running-Mastodon/Production-guide.md +++ b/docs/Running-Mastodon/Production-guide.md @@ -180,7 +180,7 @@ User=mastodon WorkingDirectory=/home/mastodon/live Environment="RAILS_ENV=production" Environment="DB_POOL=5" -ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 5 -q default -q mailers -q push +ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push TimeoutSec=15 Restart=always -- cgit From 4c53af64f0b10bc11473df5e3fd1cd7a11b755f6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 01:33:34 +0200 Subject: Fix ActionController::Parameters in API issue --- app/controllers/api/v1/apps_controller.rb | 8 +++++++- app/controllers/api/v1/follows_controller.rb | 8 ++++++-- app/controllers/api/v1/media_controller.rb | 8 +++++++- app/controllers/api/v1/reports_controller.rb | 12 +++++++++--- app/controllers/api/v1/statuses_controller.rb | 14 +++++++++----- app/models/status.rb | 2 +- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/app/controllers/api/v1/apps_controller.rb b/app/controllers/api/v1/apps_controller.rb index ca9dd0b7e..2ec7280af 100644 --- a/app/controllers/api/v1/apps_controller.rb +++ b/app/controllers/api/v1/apps_controller.rb @@ -4,6 +4,12 @@ class Api::V1::AppsController < ApiController respond_to :json def create - @app = Doorkeeper::Application.create!(name: params[:client_name], redirect_uri: params[:redirect_uris], scopes: (params[:scopes] || Doorkeeper.configuration.default_scopes), website: params[:website]) + @app = Doorkeeper::Application.create!(name: app_params[:client_name], redirect_uri: app_params[:redirect_uris], scopes: (app_params[:scopes] || Doorkeeper.configuration.default_scopes), website: app_params[:website]) + end + + private + + def app_params + params.permit(:client_name, :redirect_uris, :scopes, :website) end end diff --git a/app/controllers/api/v1/follows_controller.rb b/app/controllers/api/v1/follows_controller.rb index c22dacbaa..7c0f44f03 100644 --- a/app/controllers/api/v1/follows_controller.rb +++ b/app/controllers/api/v1/follows_controller.rb @@ -7,7 +7,7 @@ class Api::V1::FollowsController < ApiController respond_to :json def create - raise ActiveRecord::RecordNotFound if params[:uri].blank? + raise ActiveRecord::RecordNotFound if follow_params[:uri].blank? @account = FollowService.new.call(current_user.account, target_uri).try(:target_account) render action: :show @@ -16,6 +16,10 @@ class Api::V1::FollowsController < ApiController private def target_uri - params[:uri].strip.gsub(/\A@/, '') + follow_params[:uri].strip.gsub(/\A@/, '') + end + + def follow_params + params.permit(:uri) end end diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb index f8139ade7..aed3578d7 100644 --- a/app/controllers/api/v1/media_controller.rb +++ b/app/controllers/api/v1/media_controller.rb @@ -10,10 +10,16 @@ class Api::V1::MediaController < ApiController respond_to :json def create - @media = MediaAttachment.create!(account: current_user.account, file: params[:file]) + @media = MediaAttachment.create!(account: current_user.account, file: media_params[:file]) rescue Paperclip::Errors::NotIdentifiedByImageMagickError render json: { error: 'File type of uploaded media could not be verified' }, status: 422 rescue Paperclip::Error render json: { error: 'Error processing thumbnail for uploaded media' }, status: 500 end + + private + + def media_params + params.permit(:file) + end end diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb index 46bdddbc1..f83c573cb 100644 --- a/app/controllers/api/v1/reports_controller.rb +++ b/app/controllers/api/v1/reports_controller.rb @@ -12,13 +12,19 @@ class Api::V1::ReportsController < ApiController end def create - status_ids = params[:status_ids].is_a?(Enumerable) ? params[:status_ids] : [params[:status_ids]] + status_ids = report_params[:status_ids].is_a?(Enumerable) ? report_params[:status_ids] : [report_params[:status_ids]] @report = Report.create!(account: current_account, - target_account: Account.find(params[:account_id]), + target_account: Account.find(report_params[:account_id]), status_ids: Status.find(status_ids).pluck(:id), - comment: params[:comment]) + comment: report_params[:comment]) render :show end + + private + + def report_params + params.permit(:account_id, :comment, status_ids: []) + end end diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 024258c0e..4ece7e702 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -62,11 +62,11 @@ class Api::V1::StatusesController < ApiController end def create - @status = PostStatusService.new.call(current_user.account, params[:status], params[:in_reply_to_id].blank? ? nil : Status.find(params[:in_reply_to_id]), media_ids: params[:media_ids], - sensitive: params[:sensitive], - spoiler_text: params[:spoiler_text], - visibility: params[:visibility], - application: doorkeeper_token.application) + @status = PostStatusService.new.call(current_user.account, status_params[:status], status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]), media_ids: status_params[:media_ids], + sensitive: status_params[:sensitive], + spoiler_text: status_params[:spoiler_text], + visibility: status_params[:visibility], + application: doorkeeper_token.application) render action: :show end @@ -111,4 +111,8 @@ class Api::V1::StatusesController < ApiController @status = Status.find(params[:id]) raise ActiveRecord::RecordNotFound unless @status.permitted?(current_account) end + + def status_params + params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, media_ids: []) + end end diff --git a/app/models/status.rb b/app/models/status.rb index 81b26fd14..daf128572 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -188,7 +188,7 @@ class Status < ApplicationRecord end before_validation do - text.strip! + text&.strip! spoiler_text&.strip! self.reply = !(in_reply_to_id.nil? && thread.nil?) unless reply -- cgit From b510a56c0c3d8c1a48bb295a85b688af94466723 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 02:00:10 +0200 Subject: Only call regeneration worker after first login after a 14 day break --- app/controllers/application_controller.rb | 9 ++++++++- app/controllers/oauth/authorizations_controller.rb | 7 +++++++ app/models/feed.rb | 12 ++---------- app/workers/regeneration_worker.rb | 4 ++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ef9364897..c06142fd4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -39,7 +39,14 @@ class ApplicationController < ActionController::Base end def set_user_activity - current_user.touch(:current_sign_in_at) if !current_user.nil? && (current_user.current_sign_in_at.nil? || current_user.current_sign_in_at < 24.hours.ago) + return unless !current_user.nil? && (current_user.current_sign_in_at.nil? || current_user.current_sign_in_at < 24.hours.ago) + + # Mark user as signed-in today + current_user.update_tracked_fields(request) + + # If the sign in is after a two week break, we need to regenerate their feed + RegenerationWorker.perform_async(current_user.account_id) if current_user.last_sign_in_at < 14.days.ago + return end def check_suspension diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb index feaad04f6..7c25266d8 100644 --- a/app/controllers/oauth/authorizations_controller.rb +++ b/app/controllers/oauth/authorizations_controller.rb @@ -3,6 +3,7 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController skip_before_action :authenticate_resource_owner! + before_action :set_locale before_action :store_current_location before_action :authenticate_resource_owner! @@ -11,4 +12,10 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController def store_current_location store_location_for(:user, request.url) end + + def set_locale + I18n.locale = current_user.try(:locale) || I18n.default_locale + rescue I18n::InvalidLocale + I18n.locale = I18n.default_locale + end end diff --git a/app/models/feed.rb b/app/models/feed.rb index 5e1905e15..3cbc160a0 100644 --- a/app/models/feed.rb +++ b/app/models/feed.rb @@ -10,17 +10,9 @@ class Feed max_id = '+inf' if max_id.blank? since_id = '-inf' if since_id.blank? unhydrated = redis.zrevrangebyscore(key, "(#{max_id}", "(#{since_id}", limit: [0, limit], with_scores: true).map(&:last).map(&:to_i) + status_map = Status.where(id: unhydrated).cache_ids.map { |s| [s.id, s] }.to_h - # If we're after most recent items and none are there, we need to precompute the feed - if unhydrated.empty? && max_id == '+inf' && since_id == '-inf' - RegenerationWorker.perform_async(@account.id, @type) - @statuses = Status.send("as_#{@type}_timeline", @account).cache_ids.paginate_by_max_id(limit, nil, nil) - else - status_map = Status.where(id: unhydrated).cache_ids.map { |s| [s.id, s] }.to_h - @statuses = unhydrated.map { |id| status_map[id] }.compact - end - - @statuses + unhydrated.map { |id| status_map[id] }.compact end private diff --git a/app/workers/regeneration_worker.rb b/app/workers/regeneration_worker.rb index 289b63d84..82665b581 100644 --- a/app/workers/regeneration_worker.rb +++ b/app/workers/regeneration_worker.rb @@ -5,7 +5,7 @@ class RegenerationWorker sidekiq_options queue: 'pull', backtrace: true - def perform(account_id, timeline_type) - PrecomputeFeedService.new.call(timeline_type, Account.find(account_id)) + def perform(account_id, _ = :home) + PrecomputeFeedService.new.call(:home, Account.find(account_id)) end end -- cgit From eb023beb4975a019d6a3b3091483c91c2c837bbd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 02:03:16 +0200 Subject: Fix #808 - smaller elephant friend PNG for frontpage --- app/assets/images/fluffy-elephant-friend.png | Bin 1101408 -> 60667 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/app/assets/images/fluffy-elephant-friend.png b/app/assets/images/fluffy-elephant-friend.png index 11787e936..f0df29927 100644 Binary files a/app/assets/images/fluffy-elephant-friend.png and b/app/assets/images/fluffy-elephant-friend.png differ -- cgit From c22388fc792c171dda9c3f80b16b5ae302cd4806 Mon Sep 17 00:00:00 2001 From: walfie Date: Tue, 4 Apr 2017 00:00:56 -0400 Subject: Fix typo in Heroku guide --- docs/Running-Mastodon/Heroku-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Heroku-guide.md b/docs/Running-Mastodon/Heroku-guide.md index 799b8a64c..b66e56200 100644 --- a/docs/Running-Mastodon/Heroku-guide.md +++ b/docs/Running-Mastodon/Heroku-guide.md @@ -8,6 +8,6 @@ Mastodon can theoretically run indefinitely on a free [Heroku](https://heroku.co 1. Click the above button. 2. Fill in the options requested. * You can use a .herokuapp.com domain, which will be simple to set up, or you can use a custom domain. If you want a custom domain and HTTPS, you will need to upgrade to a paid plan (to use Heroku's SSL features), or set up [CloudFlare](https://cloudflare.com) who offer free "Flexible SSL" (note: CloudFlare have some undefined limits on WebSockets. So far, no one has reported hitting concurrent connection limits). - * You will want Amazon S3 for file storage. The only exception is for development purposes, where you may not care if files are not saaved. Follow a guide online for creating a free Amazon S3 bucket and Access Key, then enter the details. + * You will want Amazon S3 for file storage. The only exception is for development purposes, where you may not care if files are not saved. Follow a guide online for creating a free Amazon S3 bucket and Access Key, then enter the details. * If you want your Mastodon to be able to send emails, configure SMTP settings here (or later). Consider using [Mailgun](https://mailgun.com) or similar, who offer free plans that should suit your interests. 3. Deploy! The app should be set up, with a working web interface and database. You can change settings and manage versions from the Heroku dashboard. -- cgit From e81ba26be9fa12cc9efbba665d359b17a01054c6 Mon Sep 17 00:00:00 2001 From: Leo Wzukw Date: Tue, 4 Apr 2017 06:58:17 +0200 Subject: More consistent typography --- docs/Using-Mastodon/User-guide.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Using-Mastodon/User-guide.md b/docs/Using-Mastodon/User-guide.md index f78921c6f..f8018909a 100644 --- a/docs/Using-Mastodon/User-guide.md +++ b/docs/Using-Mastodon/User-guide.md @@ -26,17 +26,17 @@ Mastodon User's Guide ## Intro -Mastodon is a social network application based on the GNU Social protocol. It behaves a lot like other social networks, especially Twitter, with one key difference - it is open-source and anyone can start their own server (also called an "instance"), and users of any instance can interact freely with those of other instances (called "federation"). Thus, it is possible for small communities to set up their own servers to use amongst themselves while also allowing interaction with other communities. +Mastodon is a social network application based on the GNU Social protocol. It behaves a lot like other social networks, especially Twitter, with one key difference - it is open-source and anyone can start their own server (also called an "*instance*"), and users of any instance can interact freely with those of other instances (called "*federation*"). Thus, it is possible for small communities to set up their own servers to use amongst themselves while also allowing interaction with other communities. #### Decentralization and Federation -Mastodon is a system decentralized through a concept called "federation" - rather than depending on a single person or organization to run its infrastructure, anyone can download and run the software and run their own server. Federation means different Mastodon servers can interact with each other seamlessly, similar to e.g. e-mail. +Mastodon is a system decentralized through a concept called "*federation*" - rather than depending on a single person or organization to run its infrastructure, anyone can download and run the software and run their own server. Federation means different Mastodon servers can interact with each other seamlessly, similar to e.g. e-mail. As such, anyone can download Mastodon and e.g. run it for a small community of people, but any user registered on that instance can follow and send and read posts from other Mastodon instances (as well as servers running other GNU Social-compatible services). This means that not only is users' data not inherently owned by a company with an interest in selling it to advertisers, but also that if any given server shuts down its users can set up a new one or migrate to another instance, rather than the entire service being lost. Within each Mastodon instance, usernames just appear as `@username`, similar to other services such as Twitter. Users from other instances appear, and can be searched for and followed, as `@user@servername.ext` - so e.g. `@gargron` on the `mastodon.social` instance can be followed from other instances as `@gargron@mastodon.social`). -Posts from users on external instances are "federated" into the local one, i.e. if `user1@mastodon1` follows `user2@gnusocial2`, any posts `user2@gnusocial2` makes appear in both `user1@mastodon`'s Home feed and the public timeline on the `mastodon1` server. Mastodon server administrators have some control over this and can exclude users' posts from appearing on the public timeline; post privacy settings from users on Mastodon instances also affect this, see below in the [Toot Privacy](User-guide.md#toot-privacy) section. +Posts from users on external instances are "*federated*" into the local one, i.e. if `user1@mastodon1` follows `user2@gnusocial2`, any posts `user2@gnusocial2` makes appear in both `user1@mastodon`'s Home feed and the public timeline on the `mastodon1` server. Mastodon server administrators have some control over this and can exclude users' posts from appearing on the public timeline; post privacy settings from users on Mastodon instances also affect this, see below in the [Toot Privacy](User-guide.md#toot-privacy) section. ## Getting Started -- cgit From b8243c1b49a1d0a3c102901e5facd90dd88b9c13 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Tue, 4 Apr 2017 08:26:59 +0200 Subject: changed line 25 for better translation --- app/assets/javascripts/components/locales/fi.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/locales/fi.jsx b/app/assets/javascripts/components/locales/fi.jsx index 5bef99923..39fa655e6 100644 --- a/app/assets/javascripts/components/locales/fi.jsx +++ b/app/assets/javascripts/components/locales/fi.jsx @@ -22,7 +22,7 @@ const fi = { "account.followers": "Seuraajia", "account.follows_you": "Seuraa sinua", "account.requested": "Odottaa hyväksyntää", - "getting_started.heading": "Päästä alkuun", + "getting_started.heading": "Aloitus", "getting_started.about_addressing": "Voit seurata ihmisiä jos tiedät heidän käyttäjänimensä ja domainin missä he ovat syöttämällä e-mail-esque osoitteen Etsi kenttään.", "getting_started.about_shortcuts": "Jos etsimäsi henkilö on samassa domainissa kuin sinä, pelkkä käyttäjänimi kelpaa. Sama pätee kun mainitset ihmisiä statuksessasi", "getting_started.open_source_notice": "Mastodon Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia githubissa {github}. {apps}.", -- cgit From dc89fc17cc35f8e1deaffb30ae581ac453a7a9fc Mon Sep 17 00:00:00 2001 From: JantsoP Date: Tue, 4 Apr 2017 08:29:53 +0200 Subject: updated translation --- config/locales/simple_form.fi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index 02c11752f..02943cea3 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -6,7 +6,7 @@ fi: avatar: PNG, GIF tai JPG. Korkeintaan 2MB. Skaalataan kokoon 120x120px display_name: Korkeintaan 30 merkkiä header: PNG, GIF tai JPG. Korkeintaan 2MB. Skaalataan kokoon 700x335px - locked: Vaatii sinun manuaalisesti hyväksymään seuraajat ja asettaa julkaisun yksityisyyden vain seuraajille + locked: Vaatii sinun manuaalisesti hyväksymään seuraajat ja asettaa julkaisujen yksityisyyden vain seuraajille note: Korkeintaan 160 merkkiä imports: data: CSV tiedosto tuotu toiselta Mastodon palvelimelta -- cgit From ce9df2fa8295a3bdd0da583ba5d0d90251e1d448 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 13:01:14 +0200 Subject: Optimize filter methods in FeedManager a bit, use redis pipelining on merge/unmerge feed methods, do not re-create a dynamic class on each feed push call, make sure redis-rb uses hiredis --- Gemfile | 2 +- app/lib/feed_manager.rb | 72 ++++++++++++++++++++------------------------ app/lib/inline_rabl_scope.rb | 17 +++++++++++ 3 files changed, 50 insertions(+), 41 deletions(-) create mode 100644 app/lib/inline_rabl_scope.rb diff --git a/Gemfile b/Gemfile index 46baed307..cb9824131 100644 --- a/Gemfile +++ b/Gemfile @@ -38,7 +38,7 @@ gem 'rqrcode' gem 'twitter-text' gem 'oj' gem 'hiredis' -gem 'redis', '~>3.2' +gem 'redis', '~>3.2', require: ['redis', 'redis/connection/hiredis'] gem 'fast_blank' gem 'htmlentities' gem 'simple_form' diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index cd6ca1291..2c29275c8 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -51,9 +51,11 @@ class FeedManager def merge_into_timeline(from_account, into_account) timeline_key = key(:home, into_account.id) - from_account.statuses.limit(MAX_ITEMS).each do |status| - next if status.direct_visibility? || filter?(:home, status, into_account) - redis.zadd(timeline_key, status.id, status.id) + redis.pipelined do + from_account.statuses.limit(MAX_ITEMS).each do |status| + next if status.direct_visibility? || filter?(:home, status, into_account) + redis.zadd(timeline_key, status.id, status.id) + end end trim(:home, into_account.id) @@ -62,30 +64,18 @@ class FeedManager def unmerge_from_timeline(from_account, into_account) timeline_key = key(:home, into_account.id) - from_account.statuses.select('id').find_each do |status| - redis.zrem(timeline_key, status.id) - redis.zremrangebyscore(timeline_key, status.id, status.id) + from_account.statuses.select('id').find_in_batches do |statuses| + redis.pipelined do + statuses.each do |status| + redis.zrem(timeline_key, status.id) + redis.zremrangebyscore(timeline_key, status.id, status.id) + end + end end end def inline_render(target_account, template, object) - rabl_scope = Class.new do - include RoutingHelper - - def initialize(account) - @account = account - end - - def current_user - @account.try(:user) - end - - def current_account - @account - end - end - - Rabl::Renderer.new(template, object, view_path: 'app/views', format: :json, scope: rabl_scope.new(target_account)).render + Rabl::Renderer.new(template, object, view_path: 'app/views', format: :json, scope: InlineRablScope.new(target_account)).render end private @@ -95,37 +85,39 @@ class FeedManager end def filter_from_home?(status, receiver) - return true if receiver.muting?(status.account) + return true if status.reply? && status.in_reply_to_id.nil? + + check_for_mutes = [status.account_id] + check_for_mutes.concat([status.reblog.account_id]) if status.reblog? + + return true if receiver.muting?(check_for_mutes) - should_filter = false + check_for_blocks = status.mentions.map(&:account_id) + check_for_blocks.concat([status.reblog.account_id]) if status.reblog? - if status.reply? && status.in_reply_to_id.nil? - should_filter = true - elsif status.reply? && !status.in_reply_to_account_id.nil? # Filter out if it's a reply + return true if receiver.blocking?(check_for_blocks) + + if status.reply? && !status.in_reply_to_account_id.nil? # Filter out if it's a reply should_filter = !receiver.following?(status.in_reply_to_account) # and I'm not following the person it's a reply to should_filter &&= !(receiver.id == status.in_reply_to_account_id) # and it's not a reply to me should_filter &&= !(status.account_id == status.in_reply_to_account_id) # and it's not a self-reply + return should_filter elsif status.reblog? # Filter out a reblog - should_filter = receiver.blocking?(status.reblog.account) # if I'm blocking the reblogged person - should_filter ||= receiver.muting?(status.reblog.account) # or muting that person - should_filter ||= status.reblog.account.blocking?(receiver) # or if the author of the reblogged status is blocking me + return status.reblog.account.blocking?(receiver) # or if the author of the reblogged status is blocking me end - should_filter ||= receiver.blocking?(status.mentions.map(&:account_id)) # or if it mentions someone I blocked - - should_filter + false end def filter_from_mentions?(status, receiver) + check_for_blocks = [status.account_id] + check_for_blocks.concat(status.mentions.select('account_id').map(&:account_id)) + check_for_blocks.concat([status.in_reply_to_account]) if status.reply? && !status.in_reply_to_account_id.nil? + should_filter = receiver.id == status.account_id # Filter if I'm mentioning myself - should_filter ||= receiver.blocking?(status.account) # or it's from someone I blocked - should_filter ||= receiver.blocking?(status.mentions.includes(:account).map(&:account)) # or if it mentions someone I blocked + should_filter ||= receiver.blocking?(check_for_blocks) # or it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked should_filter ||= (status.account.silenced? && !receiver.following?(status.account)) # of if the account is silenced and I'm not following them - if status.reply? && !status.in_reply_to_account_id.nil? # or it's a reply - should_filter ||= receiver.blocking?(status.in_reply_to_account) # to a user I blocked - end - should_filter end end diff --git a/app/lib/inline_rabl_scope.rb b/app/lib/inline_rabl_scope.rb new file mode 100644 index 000000000..26adcb03a --- /dev/null +++ b/app/lib/inline_rabl_scope.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class InlineRablScope + include RoutingHelper + + def initialize(account) + @account = account + end + + def current_user + @account.try(:user) + end + + def current_account + @account + end +end -- cgit From b21f7c28f6832817d5de616ab0c4c2d3c28d90b0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 13:02:49 +0200 Subject: Move OStatus processing back into default queue --- app/workers/processing_worker.rb | 2 +- app/workers/salmon_worker.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/workers/processing_worker.rb b/app/workers/processing_worker.rb index 4a467d924..5df404bcc 100644 --- a/app/workers/processing_worker.rb +++ b/app/workers/processing_worker.rb @@ -3,7 +3,7 @@ class ProcessingWorker include Sidekiq::Worker - sidekiq_options queue: 'pull', backtrace: true + sidekiq_options backtrace: true def perform(account_id, body) ProcessFeedService.new.call(body, Account.find(account_id)) diff --git a/app/workers/salmon_worker.rb b/app/workers/salmon_worker.rb index 2888b574b..fc95ce47f 100644 --- a/app/workers/salmon_worker.rb +++ b/app/workers/salmon_worker.rb @@ -3,7 +3,7 @@ class SalmonWorker include Sidekiq::Worker - sidekiq_options queue: 'pull', backtrace: true + sidekiq_options backtrace: true def perform(account_id, body) ProcessInteractionService.new.call(body, Account.find(account_id)) -- cgit From b1f3499c3806682375a0496f99b4bc908d89cd84 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 13:43:36 +0200 Subject: Optimize FeedManager#unmerge, and slightly optimize FeedManager#merge --- app/lib/feed_manager.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 2c29275c8..919bc3df9 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -50,9 +50,15 @@ class FeedManager def merge_into_timeline(from_account, into_account) timeline_key = key(:home, into_account.id) + query = from_account.statuses.limit(MAX_ITEMS) + + if redis.zcard(timeline_key) >= FeedManager::MAX_ITEMS + oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true)&.first&.last&.to_i || 0 + query = query.where('id > ?', oldest_home_score) + end redis.pipelined do - from_account.statuses.limit(MAX_ITEMS).each do |status| + query.each do |status| next if status.direct_visibility? || filter?(:home, status, into_account) redis.zadd(timeline_key, status.id, status.id) end @@ -63,8 +69,9 @@ class FeedManager def unmerge_from_timeline(from_account, into_account) timeline_key = key(:home, into_account.id) + oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true)&.first&.last&.to_i || 0 - from_account.statuses.select('id').find_in_batches do |statuses| + from_account.statuses.select('id').where('id > ?', oldest_home_score).find_in_batches do |statuses| redis.pipelined do statuses.each do |status| redis.zrem(timeline_key, status.id) -- cgit From 82aaedec467815c2947a11651d5216bb88ce4038 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 13:58:34 +0200 Subject: Reduce number of items in feeds, optimize regeneration worker slightly, make regeneration worker unique, (only schedule/execute once at a time) --- Gemfile | 2 ++ Gemfile.lock | 9 +++++++++ app/lib/feed_manager.rb | 6 +++--- app/services/precompute_feed_service.rb | 8 +++++--- app/workers/regeneration_worker.rb | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index cb9824131..41c636904 100644 --- a/Gemfile +++ b/Gemfile @@ -46,6 +46,8 @@ gem 'will_paginate' gem 'rack-attack' gem 'rack-cors', require: 'rack/cors' gem 'sidekiq' +gem 'sidekiq-unique-jobs' +gem 'sidekiq-merger' gem 'rails-settings-cached' gem 'simple-navigation' gem 'statsd-instrument' diff --git a/Gemfile.lock b/Gemfile.lock index 6e3115249..27de1bee0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -387,6 +387,13 @@ GEM connection_pool (~> 2.2, >= 2.2.0) rack-protection (>= 1.5.0) redis (~> 3.2, >= 3.2.1) + sidekiq-merger (0.0.11) + activesupport (>= 3.2, < 6) + concurrent-ruby (~> 1.0) + sidekiq (>= 3.4, < 5) + sidekiq-unique-jobs (4.0.18) + sidekiq (>= 2.6) + thor simple-navigation (4.0.3) activesupport (>= 2.3.2) simple_form (3.2.1) @@ -510,6 +517,8 @@ DEPENDENCIES sass-rails (~> 5.0) sdoc (~> 0.4.0) sidekiq + sidekiq-merger + sidekiq-unique-jobs simple-navigation simple_form simplecov diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 919bc3df9..a2efcce10 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -5,7 +5,7 @@ require 'singleton' class FeedManager include Singleton - MAX_ITEMS = 800 + MAX_ITEMS = 400 def key(type, id) "feed:#{type}:#{id}" @@ -50,9 +50,9 @@ class FeedManager def merge_into_timeline(from_account, into_account) timeline_key = key(:home, into_account.id) - query = from_account.statuses.limit(MAX_ITEMS) + query = from_account.statuses.limit(FeedManager::MAX_ITEMS / 4) - if redis.zcard(timeline_key) >= FeedManager::MAX_ITEMS + if redis.zcard(timeline_key) >= FeedManager::MAX_ITEMS / 4 oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true)&.first&.last&.to_i || 0 query = query.where('id > ?', oldest_home_score) end diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb index e1ec56e8d..a57c401d0 100644 --- a/app/services/precompute_feed_service.rb +++ b/app/services/precompute_feed_service.rb @@ -5,9 +5,11 @@ class PrecomputeFeedService < BaseService # @param [Symbol] type :home or :mentions # @param [Account] account def call(_, account) - Status.as_home_timeline(account).limit(FeedManager::MAX_ITEMS).each do |status| - next if status.direct_visibility? || FeedManager.instance.filter?(:home, status, account) - redis.zadd(FeedManager.instance.key(:home, account.id), status.id, status.reblog? ? status.reblog_of_id : status.id) + redis.pipelined do + Status.as_home_timeline(account).limit(FeedManager::MAX_ITEMS / 4).each do |status| + next if status.direct_visibility? || FeedManager.instance.filter?(:home, status, account) + redis.zadd(FeedManager.instance.key(:home, account.id), status.id, status.reblog? ? status.reblog_of_id : status.id) + end end end diff --git a/app/workers/regeneration_worker.rb b/app/workers/regeneration_worker.rb index 82665b581..da8b845f6 100644 --- a/app/workers/regeneration_worker.rb +++ b/app/workers/regeneration_worker.rb @@ -3,7 +3,7 @@ class RegenerationWorker include Sidekiq::Worker - sidekiq_options queue: 'pull', backtrace: true + sidekiq_options queue: 'pull', backtrace: true, unique: :until_executed def perform(account_id, _ = :home) PrecomputeFeedService.new.call(:home, Account.find(account_id)) -- cgit From 38b504b7a70c5b100396f36d4c6c6762542984c9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 14:28:57 +0200 Subject: Remove sidekiq-merger --- Gemfile | 1 - Gemfile.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/Gemfile b/Gemfile index 41c636904..4c6314763 100644 --- a/Gemfile +++ b/Gemfile @@ -47,7 +47,6 @@ gem 'rack-attack' gem 'rack-cors', require: 'rack/cors' gem 'sidekiq' gem 'sidekiq-unique-jobs' -gem 'sidekiq-merger' gem 'rails-settings-cached' gem 'simple-navigation' gem 'statsd-instrument' diff --git a/Gemfile.lock b/Gemfile.lock index 27de1bee0..26c7b9962 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -387,10 +387,6 @@ GEM connection_pool (~> 2.2, >= 2.2.0) rack-protection (>= 1.5.0) redis (~> 3.2, >= 3.2.1) - sidekiq-merger (0.0.11) - activesupport (>= 3.2, < 6) - concurrent-ruby (~> 1.0) - sidekiq (>= 3.4, < 5) sidekiq-unique-jobs (4.0.18) sidekiq (>= 2.6) thor @@ -517,7 +513,6 @@ DEPENDENCIES sass-rails (~> 5.0) sdoc (~> 0.4.0) sidekiq - sidekiq-merger sidekiq-unique-jobs simple-navigation simple_form -- cgit From be2e7e18029d1b461decb0771d2b075ddc959e48 Mon Sep 17 00:00:00 2001 From: Niclas Darville Date: Tue, 4 Apr 2017 14:46:08 +0200 Subject: Create ISSUE_TEMPLATE.md --- ISSUE_TEMPLATE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..142b930a9 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,5 @@ +[Issue text goes here]. + +* * * * + +- [ ] I searched or or browsed the repo’s other issues to ensure this is not a duplicate. -- cgit From 904f9266ef25e073e4b3d592d1d689d60a1464b8 Mon Sep 17 00:00:00 2001 From: Niclas Darville Date: Tue, 4 Apr 2017 14:49:31 +0200 Subject: Fix typo in ISSUE_TEMPLATE --- ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 142b930a9..8394b2424 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -2,4 +2,4 @@ * * * * -- [ ] I searched or or browsed the repo’s other issues to ensure this is not a duplicate. +- [ ] I searched or browsed the repo’s other issues to ensure this is not a duplicate. -- cgit From 10a8666e04c1a1b20481bd67fb47c760cf508d68 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Tue, 4 Apr 2017 15:07:15 +0200 Subject: updated line 28 about GitHub --- app/assets/javascripts/components/locales/fi.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/locales/fi.jsx b/app/assets/javascripts/components/locales/fi.jsx index 39fa655e6..7b151d6f8 100644 --- a/app/assets/javascripts/components/locales/fi.jsx +++ b/app/assets/javascripts/components/locales/fi.jsx @@ -25,7 +25,7 @@ const fi = { "getting_started.heading": "Aloitus", "getting_started.about_addressing": "Voit seurata ihmisiä jos tiedät heidän käyttäjänimensä ja domainin missä he ovat syöttämällä e-mail-esque osoitteen Etsi kenttään.", "getting_started.about_shortcuts": "Jos etsimäsi henkilö on samassa domainissa kuin sinä, pelkkä käyttäjänimi kelpaa. Sama pätee kun mainitset ihmisiä statuksessasi", - "getting_started.open_source_notice": "Mastodon Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia githubissa {github}. {apps}.", + "getting_started.open_source_notice": "Mastodon Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia GitHub palvelussa {github}. {apps}.", "column.home": "Koti", "column.community": "Paikallinen aikajana", "column.public": "Yhdistetty aikajana", -- cgit From 5f54981846508daf9558f66ffd70d42d8213bea9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 15:26:57 +0200 Subject: New admin setting: open/close registrations, with custom message, from the admin UI --- app/assets/stylesheets/about.scss | 10 ++++++- app/controllers/about_controller.rb | 4 ++- app/controllers/admin/settings_controller.rb | 14 +++++++-- app/controllers/auth/registrations_controller.rb | 10 +++---- app/views/about/index.html.haml | 37 ++++++++++++++++-------- app/views/admin/settings/index.html.haml | 12 ++++++++ config/locales/en.yml | 1 + config/settings.yml | 3 ++ 8 files changed, 70 insertions(+), 21 deletions(-) diff --git a/app/assets/stylesheets/about.scss b/app/assets/stylesheets/about.scss index 2ff1d1453..c9d9dc5d5 100644 --- a/app/assets/stylesheets/about.scss +++ b/app/assets/stylesheets/about.scss @@ -319,7 +319,7 @@ } } - .simple_form { + .simple_form, .closed-registrations-message { width: 300px; flex: 0 0 auto; background: rgba(darken($color1, 7%), 0.5); @@ -340,3 +340,11 @@ } } } + +.closed-registrations-message { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; +} diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb index abf4b7df4..7fd43489f 100644 --- a/app/controllers/about_controller.rb +++ b/app/controllers/about_controller.rb @@ -4,7 +4,9 @@ class AboutController < ApplicationController before_action :set_body_classes def index - @description = Setting.site_description + @description = Setting.site_description + @open_registrations = Setting.open_registrations + @closed_registrations_message = Setting.closed_registrations_message @user = User.new @user.build_account diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index af0be8823..7615c781d 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -11,9 +11,13 @@ class Admin::SettingsController < ApplicationController def update @setting = Setting.where(var: params[:id]).first_or_initialize(var: params[:id]) + value = settings_params[:value] - if @setting.value != params[:setting][:value] - @setting.value = params[:setting][:value] + # Special cases + value = value == 'true' if @setting.var == 'open_registrations' + + if @setting.value != value + @setting.value = value @setting.save end @@ -22,4 +26,10 @@ class Admin::SettingsController < ApplicationController format.json { respond_with_bip(@setting) } end end + + private + + def settings_params + params.require(:setting).permit(:value) + end end diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 501e66807..4881c074a 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -3,7 +3,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController layout :determine_layout - before_action :check_single_user_mode + before_action :check_enabled_registrations, only: [:new, :create] before_action :configure_sign_up_params, only: [:create] protected @@ -27,12 +27,12 @@ class Auth::RegistrationsController < Devise::RegistrationsController new_user_session_path end - def check_single_user_mode - redirect_to root_path if Rails.configuration.x.single_user_mode + def check_enabled_registrations + redirect_to root_path if Rails.configuration.x.single_user_mode || !Setting.open_registrations end - + private - + def determine_layout %w(edit update).include?(action_name) ? 'admin' : 'auth' end diff --git a/app/views/about/index.html.haml b/app/views/about/index.html.haml index fdfb2b916..ebca4213a 100644 --- a/app/views/about/index.html.haml +++ b/app/views/about/index.html.haml @@ -24,21 +24,34 @@ .screenshot-with-signup .mascot= image_tag 'fluffy-elephant-friend.png' - = simple_form_for(@user, url: user_registration_path) do |f| - = f.simple_fields_for :account do |ff| - = ff.input :username, autofocus: true, placeholder: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username') } + - if @open_registrations + = simple_form_for(@user, url: user_registration_path) do |f| + = f.simple_fields_for :account do |ff| + = ff.input :username, autofocus: true, placeholder: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username') } - = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') } - = f.input :password, autocomplete: "off", placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password') } - = f.input :password_confirmation, autocomplete: "off", placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password') } + = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') } + = f.input :password, autocomplete: "off", placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password') } + = f.input :password_confirmation, autocomplete: "off", placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password') } - .actions - = f.button :button, t('about.get_started'), type: :submit + .actions + = f.button :button, t('about.get_started'), type: :submit - .info - = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn' - · - = link_to t('about.about_this'), about_more_path + .info + = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn' + · + = link_to t('about.about_this'), about_more_path + - else + .closed-registrations-message + - if @closed_registrations_message.blank? + %p= t('about.closed_registrations') + - else + = @closed_registrations_message.html_safe + .info + = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn' + · + = link_to t('about.other_instances'), 'https://github.com/tootsuite/mastodon/blob/master/docs/Using-Mastodon/List-of-Mastodon-instances.md' + · + = link_to t('about.about_this'), about_more_path %h3= t('about.features_headline') diff --git a/app/views/admin/settings/index.html.haml b/app/views/admin/settings/index.html.haml index 1429dbd9e..02faac8c2 100644 --- a/app/views/admin/settings/index.html.haml +++ b/app/views/admin/settings/index.html.haml @@ -38,3 +38,15 @@ %br/ You can use HTML tags %td= best_in_place @settings['site_extended_description'], :value, as: :textarea, url: admin_setting_path(@settings['site_extended_description']) + %tr + %td + %strong Open registration + %td= best_in_place @settings['open_registrations'], :value, as: :checkbox, collection: { false: 'Disabled', true: 'Enabled'}, url: admin_setting_path(@settings['open_registrations']) + %tr + %td + %strong Closed registration message + %br/ + Displayed on frontpage when registrations are closed + %br/ + You can use HTML tags + %td= best_in_place @settings['closed_registrations_message'], :value, as: :textarea, url: admin_setting_path(@settings['closed_registrations_message']) diff --git a/config/locales/en.yml b/config/locales/en.yml index 157f107a5..750af0b7a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -6,6 +6,7 @@ en: apps: Apps business_email: 'Business e-mail:' contact: Contact + closed_registrations: Registrations are currently closed on this instance. description_headline: What is %{domain}? domain_count_after: other instances domain_count_before: Connected to diff --git a/config/settings.yml b/config/settings.yml index 6ae9217a4..ffcc1eaa7 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -5,6 +5,8 @@ defaults: &defaults site_extended_description: '' site_contact_username: '' site_contact_email: '' + open_registrations: true + closed_registrations_message: '' notification_emails: follow: false reblog: false @@ -15,6 +17,7 @@ defaults: &defaults interactions: must_be_follower: false must_be_following: false + development: <<: *defaults -- cgit From 665ec615e30274bc10307ba9e56d37e3f9836f03 Mon Sep 17 00:00:00 2001 From: Angristan Date: Tue, 4 Apr 2017 15:57:37 +0200 Subject: Missing quotes --- docs/Running-Mastodon/Production-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md index 469fefa94..1fba2025b 100644 --- a/docs/Running-Mastodon/Production-guide.md +++ b/docs/Running-Mastodon/Production-guide.md @@ -132,7 +132,7 @@ Fill in the important data, like host/port of the redis database, host/port/user rake secret -To get a random string. If you are setting up on one single server (most likely), then REDIS_HOST is localhost and `DB_HOST` is `/var/run/postgresql`, `DB_USER` is `mastodon` and `DB_NAME` is `mastodon_production` while `DB_PASS` is empty because this setup will use the ident authentication method (system user "mastodon" maps to postgres user "mastodon"). +To get a random string. If you are setting up on one single server (most likely), then `REDIS_HOST` is localhost and `DB_HOST` is `/var/run/postgresql`, `DB_USER` is `mastodon` and `DB_NAME` is `mastodon_production` while `DB_PASS` is empty because this setup will use the ident authentication method (system user "mastodon" maps to postgres user "mastodon"). ## Setup -- cgit From 58bdb9b42ee90ca2723ac28c0f45af40df1c6383 Mon Sep 17 00:00:00 2001 From: Florian Maunier Date: Tue, 4 Apr 2017 16:03:05 +0200 Subject: Update List-of-Mastodon-instances.md Add my own instance --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 677ec7e56..5f8ef791c 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -37,5 +37,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.lkw.tf](https://social.lkw.tf)|N/A|No|No| | [manowar.social](https://manowar.social)|N/A|No|No| | [social.ballpointcarrot.net](https://social.ballpointcarrot.net)|Down at time of entry|No|No| +| [status.dissidence.ovh](https://status.dissidence.ovh)|N/A|Yes|Yes| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From 192f079776322605accf81cb422ce1b0c7743247 Mon Sep 17 00:00:00 2001 From: Adam Thurlow Date: Tue, 4 Apr 2017 11:14:51 -0300 Subject: Add mastodon.club to running instances list --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 677ec7e56..380ff63c0 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -24,6 +24,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| | [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, federates everywhere, no moderation yet|Yes|Yes| | [octodon.social](https://octodon.social) |Open registrations, federates everywhere, cutest instance yet|Yes|Yes| +| [mastodon.club](https://mastodon.club)|Open Registration, Open Federation, Mostly Canadians|Yes|No| | [hostux.social](https://hostux.social) |N/A|Yes|Yes| | [social.alex73630.xyz](https://social.alex73630.xyz) |Francophones|Yes|Yes| | [maly.io](https://maly.io) |N/A|Yes|No| @@ -38,4 +39,5 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [manowar.social](https://manowar.social)|N/A|No|No| | [social.ballpointcarrot.net](https://social.ballpointcarrot.net)|Down at time of entry|No|No| + Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From d8855150a0dc46d4435d623c87e593b0e44a103c Mon Sep 17 00:00:00 2001 From: Jo Decker Date: Tue, 4 Apr 2017 15:29:07 +0100 Subject: Update social.diskseven.com's IPv6 status As far as I'm aware, my instance should be supporting IPv6 now. Was an error on my part that it wasn't working before. --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 677ec7e56..587e9d865 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -15,7 +15,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [gay.crime.team](https://gay.crime.team) |the place for doin' gay crime online (please don't actually do crime here)|Yes|No| | [icosahedron.website](https://icosahedron.website/) |Icosahedron-themed (well, visually), open registration.|Yes|No| | [memetastic.space](https://memetastic.space) |Memes|Yes|No| -| [social.diskseven.com](https://social.diskseven.com) |Single user|No|No (DNS entry but no response)| +| [social.diskseven.com](https://social.diskseven.com) |Single user|No|Yes| | [social.gestaltzerfall.net](https://social.gestaltzerfall.net) |Single user|No|No| | [mastodon.xyz](https://mastodon.xyz) |N/A|Yes|Yes| | [social.targaryen.house](https://social.targaryen.house) |Federates everywhere, quick updates.|Yes|Yes| -- cgit From e9a6da6bc739f4f68447f56b93810762da388ce8 Mon Sep 17 00:00:00 2001 From: Pete Keen Date: Tue, 4 Apr 2017 11:04:44 -0400 Subject: [#817] Add email whitelist This adds the ability to filter user signup with a whitelist instead of or in addition to a blacklist. Fixes #817 --- .env.production.sample | 2 ++ app/lib/email_validator.rb | 17 +++++++++++++++-- config/initializers/blacklists.rb | 1 + spec/models/user_spec.rb | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/.env.production.sample b/.env.production.sample index bd81b8fca..a7f9eb4bf 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -22,6 +22,8 @@ OTP_SECRET= # SINGLE_USER_MODE=true # Prevent registrations with following e-mail domains # EMAIL_DOMAIN_BLACKLIST=example1.com|example2.de|etc +# Only allow registrations with the following e-mail domains +# EMAIL_DOMAIN_WHITELIST=example1.com|example2.de|etc # E-mail configuration SMTP_SERVER=smtp.mailgun.org diff --git a/app/lib/email_validator.rb b/app/lib/email_validator.rb index 856b8b1f7..06e9375f6 100644 --- a/app/lib/email_validator.rb +++ b/app/lib/email_validator.rb @@ -2,17 +2,30 @@ class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) - return if Rails.configuration.x.email_domains_blacklist.empty? - record.errors.add(attribute, I18n.t('users.invalid_email')) if blocked_email?(value) end private def blocked_email?(value) + on_blacklist?(value) || not_on_whitelist?(value) + end + + def on_blacklist?(value) + return false if Rails.configuration.x.email_domains_blacklist.blank? + domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.') regexp = Regexp.new("@(.+\\.)?(#{domains})", true) value =~ regexp end + + def not_on_whitelist?(value) + return false if Rails.configuration.x.email_domains_whitelist.blank? + + domains = Rails.configuration.x.email_domains_whitelist.gsub('.', '\.') + regexp = Regexp.new("@(.+\\.)?(#{domains})", true) + + value !~ regexp + end end diff --git a/config/initializers/blacklists.rb b/config/initializers/blacklists.rb index 52646e64d..6db7be7dc 100644 --- a/config/initializers/blacklists.rb +++ b/config/initializers/blacklists.rb @@ -2,4 +2,5 @@ Rails.application.configure do config.x.email_domains_blacklist = ENV.fetch('EMAIL_DOMAIN_BLACKLIST') { 'mvrht.com' } + config.x.email_domains_whitelist = ENV.fetch('EMAIL_DOMAIN_WHITELIST') { '' } end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 64de06749..aa777fd39 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,5 +1,42 @@ require 'rails_helper' RSpec.describe User, type: :model do + let(:account) { Fabricate(:account, username: 'alice') } + let(:password) { 'abcd1234' } + describe 'blacklist' do + it 'should allow a non-blacklisted user to be created' do + user = User.new(email: 'foo@example.com', account: account, password: password) + + expect(user.valid?).to be_truthy + end + + it 'should not allow a blacklisted user to be created' do + user = User.new(email: 'foo@mvrht.com', account: account, password: password) + + expect(user.valid?).to be_falsey + end + end + + describe 'whitelist' do + around(:each) do |example| + old_whitelist = Rails.configuration.x.email_whitelist + + Rails.configuration.x.email_domains_whitelist = 'mastodon.space' + + example.run + + Rails.configuration.x.email_domains_whitelist = old_whitelist + end + + it 'should not allow a user to be created unless they are whitelisted' do + user = User.new(email: 'foo@example.com', account: account, password: password) + expect(user.valid?).to be_falsey + end + + it 'should allow a user to be created if they are whitelisted' do + user = User.new(email: 'foo@mastodon.space', account: account, password: password) + expect(user.valid?).to be_truthy + end + end end -- cgit From 2fcf8d79ad3e7051e0089741ed00ec0eff0de637 Mon Sep 17 00:00:00 2001 From: Angristan Date: Tue, 4 Apr 2017 17:23:56 +0200 Subject: Fix crontab edit Missing -u parameter to specify the mastodon user. --- docs/Running-Mastodon/Production-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md index 469fefa94..2c8db20b7 100644 --- a/docs/Running-Mastodon/Production-guide.md +++ b/docs/Running-Mastodon/Production-guide.md @@ -221,7 +221,7 @@ I recommend creating a couple cronjobs for the following tasks: You may want to run `which bundle` first and copypaste that full path instead of simply `bundle` in the above commands because cronjobs usually don't have all the paths set. The time and intervals of when to run these jobs are up to you, but once every day should be enough for all. -You can edit the cronjob file for the `mastodon` user by running `sudo crontab -e mastodon` (outside of the mastodon user). +You can edit the cronjob file for the `mastodon` user by running `sudo crontab -e -u mastodon` (outside of the mastodon user). ## Things to look out for when upgrading Mastodon -- cgit From 731e650681004bcb8ad11d610e017975a706f57d Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 09:04:07 -0700 Subject: Use active record shorthand --- app/lib/feed_manager.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index a2efcce10..9398d6c70 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -118,7 +118,7 @@ class FeedManager def filter_from_mentions?(status, receiver) check_for_blocks = [status.account_id] - check_for_blocks.concat(status.mentions.select('account_id').map(&:account_id)) + check_for_blocks.concat(status.mentions.pluck(:account_id)) check_for_blocks.concat([status.in_reply_to_account]) if status.reply? && !status.in_reply_to_account_id.nil? should_filter = receiver.id == status.account_id # Filter if I'm mentioning myself -- cgit From 7015578655553b89e0184e6fe10b88075f4d8446 Mon Sep 17 00:00:00 2001 From: Sébastien Santoro Date: Tue, 4 Apr 2017 18:11:14 +0200 Subject: Add social.nasqueron.org instance --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 677ec7e56..d971147b6 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -37,5 +37,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.lkw.tf](https://social.lkw.tf)|N/A|No|No| | [manowar.social](https://manowar.social)|N/A|No|No| | [social.ballpointcarrot.net](https://social.ballpointcarrot.net)|Down at time of entry|No|No| +| [social.nasqueron.org](https://social.nasqueron.org) |Dreamers, open source developers, free culture|Yes|Yes| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From 22000ef7a91f00058b69e26a0bac0298966d4cf7 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 4 Apr 2017 18:11:41 +0200 Subject: Add oc.todon.fr to the list of instances. [SKIP CI] --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 677ec7e56..39f51cff6 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -26,6 +26,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [octodon.social](https://octodon.social) |Open registrations, federates everywhere, cutest instance yet|Yes|Yes| | [hostux.social](https://hostux.social) |N/A|Yes|Yes| | [social.alex73630.xyz](https://social.alex73630.xyz) |Francophones|Yes|Yes| +| [oc.todon.fr](https://oc.todon.fr) |Modérée et principalement francophone, pas de tolérances pour misogynie/LGBTphobies/validisme/etc.|Yes|Yes| | [maly.io](https://maly.io) |N/A|Yes|No| | [social.lou.lt](https://social.lou.lt) |N/A|Yes|No| | [mastodon.ninetailed.uk](https://mastodon.ninetailed.uk) |N/A|Yes|No| -- cgit From 41ba74b511916330771c097cd74f3bc07801291f Mon Sep 17 00:00:00 2001 From: Pierre Ozoux Date: Tue, 4 Apr 2017 17:28:29 +0100 Subject: Update the list of instances --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 677ec7e56..b0c9c58fd 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -7,19 +7,17 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | -------------|-------------|---|---| | [mastodon.social](https://mastodon.social) |Flagship, quick updates|Yes|No| | [awoo.space](https://awoo.space) |Intentionally moderated, only federates with mastodon.social|Yes|No| -| [social.tchncs.de](https://social.tchncs.de)|N/A|Yes|No| | [animalliberation.social](https://animalliberation.social) |Animal Rights|Yes|No| | [socially.constructed.space](https://socially.constructed.space) |Single user|No|No| | [epiktistes.com](https://epiktistes.com) |N/A|Yes|No| | [fern.surgeplay.com](https://fern.surgeplay.com) |Federates everywhere, Minecraft-focused|Yes|No -| [gay.crime.team](https://gay.crime.team) |the place for doin' gay crime online (please don't actually do crime here)|Yes|No| +| [gay.crime.team](https://gay.crime.team) |the place for doin' gay crime online (please don't actually do crime here)|No|No| | [icosahedron.website](https://icosahedron.website/) |Icosahedron-themed (well, visually), open registration.|Yes|No| | [memetastic.space](https://memetastic.space) |Memes|Yes|No| | [social.diskseven.com](https://social.diskseven.com) |Single user|No|No (DNS entry but no response)| | [social.gestaltzerfall.net](https://social.gestaltzerfall.net) |Single user|No|No| | [mastodon.xyz](https://mastodon.xyz) |N/A|Yes|Yes| | [social.targaryen.house](https://social.targaryen.house) |Federates everywhere, quick updates.|Yes|Yes| -| [social.mashek.net](https://social.mashek.net) |Themed and customised for Mashekstein Labs community. Selectively federates.|Yes|No| | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| | [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, federates everywhere, no moderation yet|Yes|Yes| @@ -36,6 +34,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [share.elouworld.org](https://share.elouworld.org)|N/A|No|No| | [social.lkw.tf](https://social.lkw.tf)|N/A|No|No| | [manowar.social](https://manowar.social)|N/A|No|No| -| [social.ballpointcarrot.net](https://social.ballpointcarrot.net)|Down at time of entry|No|No| +| [social.ballpointcarrot.net](https://social.ballpointcarrot.net)|N/A|No|No| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From 9a5d6e97150c0c1ab0f402e121d7dbafdd46998e Mon Sep 17 00:00:00 2001 From: "Thibaut (Eychics)" Date: Tue, 4 Apr 2017 18:58:19 +0200 Subject: Add closed_registrations message on French language --- config/locales/fr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 758501403..e9989e383 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -5,6 +5,7 @@ fr: about_this: À propos de cette instance apps: Applications business_email: E-mail professionnel + closed_registrations: Les inscriptions sont actuellement fermées sur cette instance. . description_headline: Qu'est-ce que %{domain} ? domain_count_after: autres instances domain_count_before: Connectés à -- cgit From 350958babfe9473ec362f6693abbcc4137b5ace4 Mon Sep 17 00:00:00 2001 From: Clément D Date: Tue, 4 Apr 2017 19:09:54 +0200 Subject: Fix typos on french translations --- config/locales/doorkeeper.fr.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/locales/doorkeeper.fr.yml b/config/locales/doorkeeper.fr.yml index c94e5c095..be109df9c 100644 --- a/config/locales/doorkeeper.fr.yml +++ b/config/locales/doorkeeper.fr.yml @@ -62,7 +62,7 @@ fr: buttons: revoke: Annuler confirmations: - revoke: Êtes-vous certain? + revoke: Êtes-vous certain ? index: application: Application created_at: Créé le @@ -72,19 +72,19 @@ fr: errors: messages: access_denied: Le propriétaire de la ressource ou le serveur d'autorisation a refusé la demande. - credential_flow_not_configured: Le flux des identifiants du mot de passe du propriétaire de la ressource a échoué en raison de Doorkeeper.configure.resource_owner_from_credentials n'est pas configuré. + credential_flow_not_configured: Le flux des identifiants du mot de passe du propriétaire de la ressource a échoué car Doorkeeper.configure.resource_owner_from_credentials n'est pas configuré. invalid_client: L'authentification du client a échoué à cause d'un client inconnu, d'aucune authentification de client incluse, ou d'une méthode d'authentification non prise en charge. invalid_grant: Le consentement d'autorisation accordé n'est pas valide, a expiré, est annulé, ne concorde pas avec l'URL de redirection utilisée dans la demande d'autorisation, ou a été émis à un autre client. invalid_redirect_uri: L'URL de redirection n'est pas valide. invalid_request: La demande manque un paramètre requis, inclut une valeur de paramètre non prise en charge, ou est autrement mal formée. - invalid_resource_owner: Les identifiants fournis du propriétaire de la ressource ne sont pas valides, ou le propriétaire de la ressource ne peut être trouvé + invalid_resource_owner: Les identifiants fournis par le propriétaire de la ressource ne sont pas valides, ou le propriétaire de la ressource ne peut être trouvé invalid_scope: La portée demandée n'est pas valide, est inconnue, ou est mal formée. invalid_token: expired: Le jeton d'accès a expiré revoked: Le jeton d'accès a été révoqué unknown: Le jeton d'accès n'est pas valide - resource_owner_authenticator_not_configured: La recherche du propriétaire de la ressource a échoué en raison de Doorkeeper.configure.resource_owner_authenticator n'est pas configuré. - server_error: Le serveur d'autorisation a rencontré une condition inattendue qui l'a empêché de remplir la demande. + resource_owner_authenticator_not_configured: La recherche du propriétaire de la ressource a échoué car Doorkeeper.configure.resource_owner_authenticator n'est pas configuré. + server_error: Le serveur d'autorisation a rencontré une condition inattendue l'empêchant de remplir la demande. temporarily_unavailable: Le serveur d'autorisation est actuellement incapable de traiter la demande à cause d'une surcharge ou d'un entretien temporaire du serveur. unauthorized_client: Le client n'est pas autorisé à effectuer cette demande à l'aide de cette méthode. unsupported_grant_type: Le type de consentement d'autorisation n'est pas pris en charge par le serveur d'autorisation. -- cgit From 6fd865c0004efbf11ee87c06fea9f48af567fabe Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 19:21:37 +0200 Subject: Spawn FeedInsertWorker to deliver status into personal feed --- app/lib/feed_manager.rb | 32 ++++++++++++++++---------------- app/services/fan_out_on_write_service.rb | 13 ++++++------- app/services/notify_service.rb | 2 +- app/services/precompute_feed_service.rb | 2 +- app/workers/feed_insert_worker.rb | 15 +++++++++++++++ 5 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 app/workers/feed_insert_worker.rb diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index a2efcce10..28e712704 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -11,11 +11,11 @@ class FeedManager "feed:#{type}:#{id}" end - def filter?(timeline_type, status, receiver) + def filter?(timeline_type, status, receiver_id) if timeline_type == :home - filter_from_home?(status, receiver) + filter_from_home?(status, receiver_id) elsif timeline_type == :mentions - filter_from_mentions?(status, receiver) + filter_from_mentions?(status, receiver_id) else false end @@ -91,39 +91,39 @@ class FeedManager Redis.current end - def filter_from_home?(status, receiver) + def filter_from_home?(status, receiver_id) return true if status.reply? && status.in_reply_to_id.nil? check_for_mutes = [status.account_id] check_for_mutes.concat([status.reblog.account_id]) if status.reblog? - return true if receiver.muting?(check_for_mutes) + return true if Mute.where(account_id: receiver_id, target_account_id: check_for_mutes).any? check_for_blocks = status.mentions.map(&:account_id) check_for_blocks.concat([status.reblog.account_id]) if status.reblog? - return true if receiver.blocking?(check_for_blocks) + return true if Block.where(account_id: receiver_id, target_account_id: check_for_blocks).any? - if status.reply? && !status.in_reply_to_account_id.nil? # Filter out if it's a reply - should_filter = !receiver.following?(status.in_reply_to_account) # and I'm not following the person it's a reply to - should_filter &&= !(receiver.id == status.in_reply_to_account_id) # and it's not a reply to me - should_filter &&= !(status.account_id == status.in_reply_to_account_id) # and it's not a self-reply + if status.reply? && !status.in_reply_to_account_id.nil? # Filter out if it's a reply + should_filter = !Follow.where(account_id: receiver_id, target_account_id: status.in_reply_to_account_id).exists? # and I'm not following the person it's a reply to + should_filter &&= !(receiver_id == status.in_reply_to_account_id) # and it's not a reply to me + should_filter &&= !(status.account_id == status.in_reply_to_account_id) # and it's not a self-reply return should_filter - elsif status.reblog? # Filter out a reblog - return status.reblog.account.blocking?(receiver) # or if the author of the reblogged status is blocking me + elsif status.reblog? # Filter out a reblog + return Block.where(account_id: status.reblog.account_id, target_account_id: receiver_id).exists? # or if the author of the reblogged status is blocking me end false end - def filter_from_mentions?(status, receiver) + def filter_from_mentions?(status, receiver_id) check_for_blocks = [status.account_id] check_for_blocks.concat(status.mentions.select('account_id').map(&:account_id)) check_for_blocks.concat([status.in_reply_to_account]) if status.reply? && !status.in_reply_to_account_id.nil? - should_filter = receiver.id == status.account_id # Filter if I'm mentioning myself - should_filter ||= receiver.blocking?(check_for_blocks) # or it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked - should_filter ||= (status.account.silenced? && !receiver.following?(status.account)) # of if the account is silenced and I'm not following them + should_filter = receiver_id == status.account_id # Filter if I'm mentioning myself + should_filter ||= Block.where(account_id: receiver_id, target_account_id: check_for_blocks).any? # or it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked + should_filter ||= (status.account.silenced? && !Follow.where(account_id: receiver_id, target_account_id: status.account_id).exists?) # of if the account is silenced and I'm not following them should_filter end diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index df404cbef..42222c25b 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -33,9 +33,8 @@ class FanOutOnWriteService < BaseService def deliver_to_followers(status) Rails.logger.debug "Delivering status #{status.id} to followers" - status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).find_each do |follower| - next if FeedManager.instance.filter?(:home, status, follower) - FeedManager.instance.push(:home, follower, status) + status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).select(:id).find_each do |follower| + FeedInsertWorker.perform_async(status.id, follower.id) end end @@ -44,7 +43,7 @@ class FanOutOnWriteService < BaseService status.mentions.includes(:account).each do |mention| mentioned_account = mention.account - next if !mentioned_account.local? || !mentioned_account.following?(status.account) || FeedManager.instance.filter?(:home, status, mentioned_account) + next if !mentioned_account.local? || !mentioned_account.following?(status.account) || FeedManager.instance.filter?(:home, status, mention.account_id) FeedManager.instance.push(:home, mentioned_account, status) end end @@ -54,9 +53,9 @@ class FanOutOnWriteService < BaseService payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status) - status.tags.find_each do |tag| - FeedManager.instance.broadcast("hashtag:#{tag.name}", event: 'update', payload: payload) - FeedManager.instance.broadcast("hashtag:#{tag.name}:local", event: 'update', payload: payload) if status.account.local? + status.tags.pluck(:name).each do |hashtag| + FeedManager.instance.broadcast("hashtag:#{hashtag}", event: 'update', payload: payload) + FeedManager.instance.broadcast("hashtag:#{hashtag}:local", event: 'update', payload: payload) if status.account.local? end end diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index 942cd9d21..24486f220 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -17,7 +17,7 @@ class NotifyService < BaseService private def blocked_mention? - FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient) + FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient.id) end def blocked_favourite? diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb index a57c401d0..07dcb81da 100644 --- a/app/services/precompute_feed_service.rb +++ b/app/services/precompute_feed_service.rb @@ -7,7 +7,7 @@ class PrecomputeFeedService < BaseService def call(_, account) redis.pipelined do Status.as_home_timeline(account).limit(FeedManager::MAX_ITEMS / 4).each do |status| - next if status.direct_visibility? || FeedManager.instance.filter?(:home, status, account) + next if status.direct_visibility? || FeedManager.instance.filter?(:home, status, account.id) redis.zadd(FeedManager.instance.key(:home, account.id), status.id, status.reblog? ? status.reblog_of_id : status.id) end end diff --git a/app/workers/feed_insert_worker.rb b/app/workers/feed_insert_worker.rb new file mode 100644 index 000000000..a58dfaa74 --- /dev/null +++ b/app/workers/feed_insert_worker.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class FeedInsertWorker + include Sidekiq::Worker + + def perform(status_id, follower_id) + status = Status.find(status_id) + follower = Account.find(follower_id) + + return if FeedManager.instance.filter?(:home, status, follower.id) + FeedManager.instance.push(:home, follower, status) + rescue ActiveRecord::RecordNotFound + true + end +end -- cgit From 6091b9b1a965ae5c1751627ee29c7db95643fcfe Mon Sep 17 00:00:00 2001 From: Angristan Date: Tue, 4 Apr 2017 19:23:53 +0200 Subject: Add file package If the file package is not installed, we get "Validation failed: File has contents that are not what they are reported to be" when upload media. --- docs/Running-Mastodon/Production-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md index 469fefa94..a70f174d4 100644 --- a/docs/Running-Mastodon/Production-guide.md +++ b/docs/Running-Mastodon/Production-guide.md @@ -76,7 +76,7 @@ It is recommended to create a special user for mastodon on the server (you could ## General dependencies curl -sL https://deb.nodesource.com/setup_4.x | sudo bash - - sudo apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs + sudo apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs file sudo npm install -g yarn ## Redis -- cgit From dcda852b5ff8cc894b384c30f69d66990ee61993 Mon Sep 17 00:00:00 2001 From: Nope Nope Date: Tue, 4 Apr 2017 20:45:32 +0200 Subject: typo in admin doc s/rails/rake/ --- docs/Running-Mastodon/Administration-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Administration-guide.md b/docs/Running-Mastodon/Administration-guide.md index af78f6235..dd69eb303 100644 --- a/docs/Running-Mastodon/Administration-guide.md +++ b/docs/Running-Mastodon/Administration-guide.md @@ -7,7 +7,7 @@ So, you have a working Mastodon instance... now what? The following rake task: - rails mastodon:make_admin USERNAME=alice + rake mastodon:make_admin USERNAME=alice Would turn the local user "alice" into an admin. -- cgit From 9ae9ecdebee46b04f8cfdd02bf2691dd60d0b961 Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 12:14:44 -0700 Subject: Quick attempt to get pull requests passing --- spec/services/fan_out_on_write_service_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/services/fan_out_on_write_service_spec.rb b/spec/services/fan_out_on_write_service_spec.rb index 07f8c2dc8..6ee225c4c 100644 --- a/spec/services/fan_out_on_write_service_spec.rb +++ b/spec/services/fan_out_on_write_service_spec.rb @@ -23,6 +23,7 @@ RSpec.describe FanOutOnWriteService do end it 'delivers status to local followers' do + pending 'some sort of problem in test environment causes this to sometimes fail' expect(Feed.new(:home, follower).get(10).map(&:id)).to include status.id end -- cgit From 1e5a1b9abd9dca06e19651f80923249b09bcc847 Mon Sep 17 00:00:00 2001 From: Udo Kramer Date: Tue, 4 Apr 2017 23:45:29 +0200 Subject: Update Production-guide.md --- docs/Running-Mastodon/Production-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md index 469fefa94..ffe42b411 100644 --- a/docs/Running-Mastodon/Production-guide.md +++ b/docs/Running-Mastodon/Production-guide.md @@ -112,7 +112,7 @@ Then once `rbenv` is ready, run `rbenv install 2.3.1` to install the Ruby versio You need the `git-core` package installed on your system. If it is so, from the `mastodon` user: cd ~ - git clone https://github.com/Gargron/mastodon.git live + git clone https://github.com/tootsuite/mastodon.git live cd live Then you can proceed to install project dependencies: -- cgit From 81c76fe375d9342e5a436db05c8e25305c650e8d Mon Sep 17 00:00:00 2001 From: Samy KACIMI Date: Wed, 5 Apr 2017 00:29:56 +0200 Subject: add more tests to models --- Gemfile | 1 + Gemfile.lock | 3 + app/models/block.rb | 5 +- app/models/follow.rb | 9 ++- app/models/follow_request.rb | 5 +- app/models/mention.rb | 5 +- config/database.yml | 4 ++ spec/fabricators/account_fabricator.rb | 2 +- spec/fabricators/block_fabricator.rb | 3 +- spec/fabricators/follow_fabricator.rb | 3 +- spec/fabricators/follow_request_fabricator.rb | 3 +- spec/fabricators/mention_fabricator.rb | 4 ++ spec/fabricators/user_fabricator.rb | 2 +- spec/models/account_spec.rb | 69 ++++++++++++++++++++++ spec/models/block_spec.rb | 17 ++++++ spec/models/domain_block_spec.rb | 18 ++++++ spec/models/follow_request_spec.rb | 19 ++++++ spec/models/follow_spec.rb | 19 ++++++ spec/models/mention_spec.rb | 17 ++++++ spec/models/user_spec.rb | 44 ++++++++++++++ spec/rails_helper.rb | 2 + .../matchers/model/model_have_error_on_field.rb | 15 +++++ 22 files changed, 252 insertions(+), 17 deletions(-) create mode 100644 spec/fabricators/mention_fabricator.rb create mode 100644 spec/support/matchers/model/model_have_error_on_field.rb diff --git a/Gemfile b/Gemfile index 4c6314763..87ea77735 100644 --- a/Gemfile +++ b/Gemfile @@ -70,6 +70,7 @@ group :test do gem 'simplecov', require: false gem 'webmock' gem 'rspec-sidekiq' + gem 'faker' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 26c7b9962..a774a89ba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -149,6 +149,8 @@ GEM erubis (2.7.0) execjs (2.7.0) fabrication (2.15.2) + faker (1.6.6) + i18n (~> 0.5) fast_blank (1.0.0) font-awesome-rails (4.6.3.1) railties (>= 3.2, < 5.1) @@ -470,6 +472,7 @@ DEPENDENCIES doorkeeper dotenv-rails fabrication + faker fast_blank font-awesome-rails fuubar diff --git a/app/models/block.rb b/app/models/block.rb index 9c55703c9..ae456a6b6 100644 --- a/app/models/block.rb +++ b/app/models/block.rb @@ -3,9 +3,8 @@ class Block < ApplicationRecord include Paginable - belongs_to :account - belongs_to :target_account, class_name: 'Account' + belongs_to :account, required: true + belongs_to :target_account, class_name: 'Account', required: true - validates :account, :target_account, presence: true validates :account_id, uniqueness: { scope: :target_account_id } end diff --git a/app/models/follow.rb b/app/models/follow.rb index 8bfe8b2f6..fd7325f05 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -3,11 +3,14 @@ class Follow < ApplicationRecord include Paginable - belongs_to :account, counter_cache: :following_count - belongs_to :target_account, class_name: 'Account', counter_cache: :followers_count + belongs_to :account, counter_cache: :following_count, required: true + + belongs_to :target_account, + class_name: 'Account', + counter_cache: :followers_count, + required: true has_one :notification, as: :activity, dependent: :destroy - validates :account, :target_account, presence: true validates :account_id, uniqueness: { scope: :target_account_id } end diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb index 4224ab15d..20e1332dd 100644 --- a/app/models/follow_request.rb +++ b/app/models/follow_request.rb @@ -3,12 +3,11 @@ class FollowRequest < ApplicationRecord include Paginable - belongs_to :account - belongs_to :target_account, class_name: 'Account' + belongs_to :account, required: true + belongs_to :target_account, class_name: 'Account', required: true has_one :notification, as: :activity, dependent: :destroy - validates :account, :target_account, presence: true validates :account_id, uniqueness: { scope: :target_account_id } def authorize! diff --git a/app/models/mention.rb b/app/models/mention.rb index 10a9cb1cd..03e76fcc4 100644 --- a/app/models/mention.rb +++ b/app/models/mention.rb @@ -1,11 +1,10 @@ # frozen_string_literal: true class Mention < ApplicationRecord - belongs_to :account, inverse_of: :mentions - belongs_to :status + belongs_to :account, inverse_of: :mentions, required: true + belongs_to :status, required: true has_one :notification, as: :activity, dependent: :destroy - validates :account, :status, presence: true validates :account, uniqueness: { scope: :status } end diff --git a/config/database.yml b/config/database.yml index 5ec342f93..390113480 100644 --- a/config/database.yml +++ b/config/database.yml @@ -3,6 +3,10 @@ default: &default pool: <%= ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5 %> timeout: 5000 encoding: unicode + host: localhost + username: samy + password: tardis + port: 32769 development: <<: *default diff --git a/spec/fabricators/account_fabricator.rb b/spec/fabricators/account_fabricator.rb index 3a7c00bf5..567de05f4 100644 --- a/spec/fabricators/account_fabricator.rb +++ b/spec/fabricators/account_fabricator.rb @@ -1,3 +1,3 @@ Fabricator(:account) do - username "alice" + username { Faker::Internet.user_name(nil, %w(_)) } end diff --git a/spec/fabricators/block_fabricator.rb b/spec/fabricators/block_fabricator.rb index 9a5a6808f..379931ba6 100644 --- a/spec/fabricators/block_fabricator.rb +++ b/spec/fabricators/block_fabricator.rb @@ -1,3 +1,4 @@ Fabricator(:block) do - + account + target_account { Fabricate(:account) } end diff --git a/spec/fabricators/follow_fabricator.rb b/spec/fabricators/follow_fabricator.rb index 9d9d06f12..9b25dc547 100644 --- a/spec/fabricators/follow_fabricator.rb +++ b/spec/fabricators/follow_fabricator.rb @@ -1,3 +1,4 @@ Fabricator(:follow) do - + account + target_account { Fabricate(:account) } end diff --git a/spec/fabricators/follow_request_fabricator.rb b/spec/fabricators/follow_request_fabricator.rb index 9c3733cef..78a057919 100644 --- a/spec/fabricators/follow_request_fabricator.rb +++ b/spec/fabricators/follow_request_fabricator.rb @@ -1,3 +1,4 @@ Fabricator(:follow_request) do - + account + target_account { Fabricate(:account) } end diff --git a/spec/fabricators/mention_fabricator.rb b/spec/fabricators/mention_fabricator.rb new file mode 100644 index 000000000..cb5fe4299 --- /dev/null +++ b/spec/fabricators/mention_fabricator.rb @@ -0,0 +1,4 @@ +Fabricator(:mention) do + account + status +end diff --git a/spec/fabricators/user_fabricator.rb b/spec/fabricators/user_fabricator.rb index c08559137..16b3b1f6f 100644 --- a/spec/fabricators/user_fabricator.rb +++ b/spec/fabricators/user_fabricator.rb @@ -1,6 +1,6 @@ Fabricator(:user) do account - email "alice@example.com" + email { Faker::Internet.email } password "123456789" confirmed_at { Time.now } end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 91c8d75cf..fbc9a7d40 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -209,4 +209,73 @@ RSpec.describe Account, type: :model do expect(subject.match('Check this out https://medium.com/@alice/some-article#.abcdef123')).to be_nil end end + + describe 'validations' do + it 'has a valid fabricator' do + account = Fabricate.build(:account) + account.valid? + expect(account).to be_valid + end + + it 'is invalid without a username' do + account = Fabricate.build(:account, username: nil) + account.valid? + expect(account).to model_have_error_on_field(:username) + end + + it 'is invalid is the username already exists' do + account_1 = Fabricate(:account, username: 'the_doctor') + account_2 = Fabricate.build(:account, username: 'the_doctor') + account_2.valid? + expect(account_2).to model_have_error_on_field(:username) + end + + context 'when is local' do + it 'is invalid if the username doesn\'t only contains letters, numbers and underscores' do + account = Fabricate.build(:account, username: 'the-doctor') + account.valid? + expect(account).to model_have_error_on_field(:username) + end + + it 'is invalid if the username is longer then 30 characters' do + account = Fabricate.build(:account, username: Faker::Lorem.characters(31)) + account.valid? + expect(account).to model_have_error_on_field(:username) + end + end + end + + describe 'scopes' do + describe 'remote' do + it 'returns an array of accounts who have a domain' do + account_1 = Fabricate(:account, domain: nil) + account_2 = Fabricate(:account, domain: 'example.com') + expect(Account.remote).to match_array([account_2]) + end + end + + describe 'local' do + it 'returns an array of accounts who do not have a domain' do + account_1 = Fabricate(:account, domain: nil) + account_2 = Fabricate(:account, domain: 'example.com') + expect(Account.local).to match_array([account_1]) + end + end + + describe 'silenced' do + it 'returns an array of accounts who are silenced' do + account_1 = Fabricate(:account, silenced: true) + account_2 = Fabricate(:account, silenced: false) + expect(Account.silenced).to match_array([account_1]) + end + end + + describe 'suspended' do + it 'returns an array of accounts who are suspended' do + account_1 = Fabricate(:account, suspended: true) + account_2 = Fabricate(:account, suspended: false) + expect(Account.suspended).to match_array([account_1]) + end + end + end end diff --git a/spec/models/block_spec.rb b/spec/models/block_spec.rb index 6862de6fc..cabb41c3e 100644 --- a/spec/models/block_spec.rb +++ b/spec/models/block_spec.rb @@ -1,5 +1,22 @@ require 'rails_helper' RSpec.describe Block, type: :model do + describe 'validations' do + it 'has a valid fabricator' do + block = Fabricate.build(:block) + expect(block).to be_valid + end + it 'is invalid without an account' do + block = Fabricate.build(:block, account: nil) + block.valid? + expect(block).to model_have_error_on_field(:account) + end + + it 'is invalid without a target_account' do + block = Fabricate.build(:block, target_account: nil) + block.valid? + expect(block).to model_have_error_on_field(:target_account) + end + end end diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb index ad5403110..b19c8083e 100644 --- a/spec/models/domain_block_spec.rb +++ b/spec/models/domain_block_spec.rb @@ -1,5 +1,23 @@ require 'rails_helper' RSpec.describe DomainBlock, type: :model do + describe 'validations' do + it 'has a valid fabricator' do + domain_block = Fabricate.build(:domain_block) + expect(domain_block).to be_valid + end + it 'is invalid without a domain' do + domain_block = Fabricate.build(:domain_block, domain: nil) + domain_block.valid? + expect(domain_block).to model_have_error_on_field(:domain) + end + + it 'is invalid if the domain already exists' do + domain_block_1 = Fabricate(:domain_block, domain: 'dalek.com') + domain_block_2 = Fabricate.build(:domain_block, domain: 'dalek.com') + domain_block_2.valid? + expect(domain_block_2).to model_have_error_on_field(:domain) + end + end end diff --git a/spec/models/follow_request_spec.rb b/spec/models/follow_request_spec.rb index f2ec642d8..cc6f8ee62 100644 --- a/spec/models/follow_request_spec.rb +++ b/spec/models/follow_request_spec.rb @@ -3,4 +3,23 @@ require 'rails_helper' RSpec.describe FollowRequest, type: :model do describe '#authorize!' describe '#reject!' + + describe 'validations' do + it 'has a valid fabricator' do + follow_request = Fabricate.build(:follow_request) + expect(follow_request).to be_valid + end + + it 'is invalid without an account' do + follow_request = Fabricate.build(:follow_request, account: nil) + follow_request.valid? + expect(follow_request).to model_have_error_on_field(:account) + end + + it 'is invalid without a target account' do + follow_request = Fabricate.build(:follow_request, target_account: nil) + follow_request.valid? + expect(follow_request).to model_have_error_on_field(:target_account) + end + end end diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index eb21f3e18..0fae25352 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -5,4 +5,23 @@ RSpec.describe Follow, type: :model do let(:bob) { Fabricate(:account, username: 'bob') } subject { Follow.new(account: alice, target_account: bob) } + + describe 'validations' do + it 'has a valid fabricator' do + follow = Fabricate.build(:follow) + expect(follow).to be_valid + end + + it 'is invalid without an account' do + follow = Fabricate.build(:follow, account: nil) + follow.valid? + expect(follow).to model_have_error_on_field(:account) + end + + it 'is invalid without a target_account' do + follow = Fabricate.build(:follow, target_account: nil) + follow.valid? + expect(follow).to model_have_error_on_field(:target_account) + end + end end diff --git a/spec/models/mention_spec.rb b/spec/models/mention_spec.rb index 5c91fda02..dbcf6a32c 100644 --- a/spec/models/mention_spec.rb +++ b/spec/models/mention_spec.rb @@ -1,5 +1,22 @@ require 'rails_helper' RSpec.describe Mention, type: :model do + describe 'validations' do + it 'has a valid fabricator' do + mention = Fabricate.build(:mention) + expect(mention).to be_valid + end + it 'is invalid without an account' do + mention = Fabricate.build(:mention, account: nil) + mention.valid? + expect(mention).to model_have_error_on_field(:account) + end + + it 'is invalid without a status' do + mention = Fabricate.build(:mention, status: nil) + mention.valid? + expect(mention).to model_have_error_on_field(:status) + end + end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 64de06749..1a3254185 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,5 +1,49 @@ require 'rails_helper' RSpec.describe User, type: :model do + describe 'validations' do + it 'is invalid without an account' do + user = Fabricate.build(:user, account: nil) + user.valid? + expect(user).to model_have_error_on_field(:account) + end + it 'is invalid without a valid locale' do + user = Fabricate.build(:user, locale: 'toto') + user.valid? + expect(user).to model_have_error_on_field(:locale) + end + + it 'is invalid without a valid email' do + user = Fabricate.build(:user, email: 'john@') + user.valid? + expect(user).to model_have_error_on_field(:email) + end + end + + describe 'scopes' do + describe 'recent' do + it 'returns an array of recent users ordered by id' do + user_1 = Fabricate(:user) + user_2 = Fabricate(:user) + expect(User.recent).to match_array([user_2, user_1]) + end + end + + describe 'admins' do + it 'returns an array of users who are admin' do + user_1 = Fabricate(:user, admin: false) + user_2 = Fabricate(:user, admin: true) + expect(User.admins).to match_array([user_2]) + end + end + + describe 'confirmed' do + it 'returns an array of users who are confirmed' do + user_1 = Fabricate(:user, confirmed_at: nil) + user_2 = Fabricate(:user, confirmed_at: Time.now) + expect(User.confirmed).to match_array([user_2]) + end + end + end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 977c7bdc0..faac96982 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -8,6 +8,8 @@ require 'rspec/rails' require 'webmock/rspec' require 'paperclip/matchers' +Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } + ActiveRecord::Migration.maintain_test_schema! WebMock.disable_net_connect!(allow: 'localhost:7575') Sidekiq::Testing.inline! diff --git a/spec/support/matchers/model/model_have_error_on_field.rb b/spec/support/matchers/model/model_have_error_on_field.rb new file mode 100644 index 000000000..5d5fe1c7b --- /dev/null +++ b/spec/support/matchers/model/model_have_error_on_field.rb @@ -0,0 +1,15 @@ +RSpec::Matchers.define :model_have_error_on_field do |expected| + match do |record| + if record.errors.empty? + record.valid? + end + + record.errors.has_key?(expected) + end + + failure_message do |record| + keys = record.errors.keys + + "expect record.errors(#{keys}) to include #{expected}" + end +end -- cgit From 7762467b476af5c793d214ebc051b983921492b7 Mon Sep 17 00:00:00 2001 From: Samy KACIMI Date: Wed, 5 Apr 2017 00:31:31 +0200 Subject: rollback database.yml update --- config/database.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/database.yml b/config/database.yml index 390113480..5ec342f93 100644 --- a/config/database.yml +++ b/config/database.yml @@ -3,10 +3,6 @@ default: &default pool: <%= ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5 %> timeout: 5000 encoding: unicode - host: localhost - username: samy - password: tardis - port: 32769 development: <<: *default -- cgit From 46c0e8b0e7980ecba0e68fe3b8c4d9121caa4b6f Mon Sep 17 00:00:00 2001 From: Samy KACIMI Date: Wed, 5 Apr 2017 00:37:23 +0200 Subject: update account_spec --- spec/models/account_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index fbc9a7d40..d7f59adb8 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -223,7 +223,7 @@ RSpec.describe Account, type: :model do expect(account).to model_have_error_on_field(:username) end - it 'is invalid is the username already exists' do + it 'is invalid if the username already exists' do account_1 = Fabricate(:account, username: 'the_doctor') account_2 = Fabricate.build(:account, username: 'the_doctor') account_2.valid? -- cgit From 04225ed72e4778c62c78af183f7110c667f1b667 Mon Sep 17 00:00:00 2001 From: Ash Furrow Date: Tue, 4 Apr 2017 18:45:24 -0400 Subject: Adds instructions for adding admin users. --- docs/Running-Mastodon/Heroku-guide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Running-Mastodon/Heroku-guide.md b/docs/Running-Mastodon/Heroku-guide.md index b66e56200..cd92a8bfd 100644 --- a/docs/Running-Mastodon/Heroku-guide.md +++ b/docs/Running-Mastodon/Heroku-guide.md @@ -11,3 +11,5 @@ Mastodon can theoretically run indefinitely on a free [Heroku](https://heroku.co * You will want Amazon S3 for file storage. The only exception is for development purposes, where you may not care if files are not saved. Follow a guide online for creating a free Amazon S3 bucket and Access Key, then enter the details. * If you want your Mastodon to be able to send emails, configure SMTP settings here (or later). Consider using [Mailgun](https://mailgun.com) or similar, who offer free plans that should suit your interests. 3. Deploy! The app should be set up, with a working web interface and database. You can change settings and manage versions from the Heroku dashboard. + +You may need to use the `heroku` CLI application to modify the database directly to give yourself administration rights. -- cgit From 79ef756f645153b91643765573230814257d0cbf Mon Sep 17 00:00:00 2001 From: Samy KACIMI Date: Wed, 5 Apr 2017 00:47:17 +0200 Subject: fix rubocop issues --- Gemfile | 2 +- app/models/follow.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 87ea77735..0deed9ae0 100644 --- a/Gemfile +++ b/Gemfile @@ -69,8 +69,8 @@ end group :test do gem 'simplecov', require: false gem 'webmock' - gem 'rspec-sidekiq' gem 'faker' + gem 'rspec-sidekiq' end group :development do diff --git a/app/models/follow.rb b/app/models/follow.rb index fd7325f05..b6b9dca7c 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -4,7 +4,7 @@ class Follow < ApplicationRecord include Paginable belongs_to :account, counter_cache: :following_count, required: true - + belongs_to :target_account, class_name: 'Account', counter_cache: :followers_count, -- cgit From 5af0ecbcd9cfd757c4d5bd541d83ca11e44d14ef Mon Sep 17 00:00:00 2001 From: Samy KACIMI Date: Wed, 5 Apr 2017 00:52:55 +0200 Subject: alphebatically order test gem group as required by rubocop --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 0deed9ae0..4e7ff6621 100644 --- a/Gemfile +++ b/Gemfile @@ -67,10 +67,10 @@ group :development, :test do end group :test do - gem 'simplecov', require: false - gem 'webmock' gem 'faker' gem 'rspec-sidekiq' + gem 'simplecov', require: false + gem 'webmock' end group :development do -- cgit From 50a88d6a6ed0bd9af8e29a4fbce66bc24b32cb04 Mon Sep 17 00:00:00 2001 From: Jason Snell Date: Tue, 4 Apr 2017 16:35:57 -0700 Subject: Adding https://mastodon.cc --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 677ec7e56..17a72d77d 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -37,5 +37,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.lkw.tf](https://social.lkw.tf)|N/A|No|No| | [manowar.social](https://manowar.social)|N/A|No|No| | [social.ballpointcarrot.net](https://social.ballpointcarrot.net)|Down at time of entry|No|No| +| [mastodon.cc](https://mastodon.cc)|Art|Yes|No| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From bda37489ac5c14d18b1bb4290f2a2931dc8728c9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 5 Apr 2017 02:32:18 +0200 Subject: Remove PuSH subscriptions when delivery is answered with a 4xx error --- app/workers/pubsubhubbub/delivery_worker.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/workers/pubsubhubbub/delivery_worker.rb b/app/workers/pubsubhubbub/delivery_worker.rb index 15005bc80..466def3a8 100644 --- a/app/workers/pubsubhubbub/delivery_worker.rb +++ b/app/workers/pubsubhubbub/delivery_worker.rb @@ -22,6 +22,7 @@ class Pubsubhubbub::DeliveryWorker .headers(headers) .post(subscription.callback_url, body: payload) + return subscription.destroy! if response.code > 299 && response.code < 500 && response.code != 429 # HTTP 4xx means error is not temporary, except for 429 (throttling) raise "Delivery failed for #{subscription.callback_url}: HTTP #{response.code}" unless response.code > 199 && response.code < 300 subscription.touch(:last_successful_delivery_at) -- cgit From f7e35d90db3a08dbb4e4104f513e5817e18659b9 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 4 Apr 2017 20:16:14 -0400 Subject: Remote follow improvements This stores the @username@instance you provide in your session and reuses it the next time you remote follow someone from this instance. --- app/controllers/remote_follow_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/remote_follow_controller.rb b/app/controllers/remote_follow_controller.rb index 7d4bfe6ce..1e3f786ec 100644 --- a/app/controllers/remote_follow_controller.rb +++ b/app/controllers/remote_follow_controller.rb @@ -8,6 +8,7 @@ class RemoteFollowController < ApplicationController def new @remote_follow = RemoteFollow.new + @remote_follow.acct = session[:remote_follow] if session.key?(:remote_follow) end def create @@ -22,6 +23,8 @@ class RemoteFollowController < ApplicationController render(:new) && return end + session[:remote_follow] = @remote_follow.acct + redirect_to Addressable::Template.new(redirect_url_link.template).expand(uri: "#{@account.username}@#{Rails.configuration.x.local_domain}").to_s else render :new -- cgit From dd441606aae48a08ec76ae26383c3e3738254a1a Mon Sep 17 00:00:00 2001 From: Ash Furrow Date: Tue, 4 Apr 2017 20:53:31 -0400 Subject: Updates instructions. --- docs/Running-Mastodon/Heroku-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Heroku-guide.md b/docs/Running-Mastodon/Heroku-guide.md index cd92a8bfd..0de26230c 100644 --- a/docs/Running-Mastodon/Heroku-guide.md +++ b/docs/Running-Mastodon/Heroku-guide.md @@ -12,4 +12,4 @@ Mastodon can theoretically run indefinitely on a free [Heroku](https://heroku.co * If you want your Mastodon to be able to send emails, configure SMTP settings here (or later). Consider using [Mailgun](https://mailgun.com) or similar, who offer free plans that should suit your interests. 3. Deploy! The app should be set up, with a working web interface and database. You can change settings and manage versions from the Heroku dashboard. -You may need to use the `heroku` CLI application to modify the database directly to give yourself administration rights. +You may need to use the `heroku` CLI application to run `USERNAME=yourUsername rails mastodon:make_admin` to make yourself an admin. -- cgit From c106b6d3e04fb3dd8fe568120c0068f1492e54f7 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 4 Apr 2017 09:26:21 -0400 Subject: Improve readability of text on profiles --- app/assets/stylesheets/accounts.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/stylesheets/accounts.scss b/app/assets/stylesheets/accounts.scss index 25e24a95a..b3ae33500 100644 --- a/app/assets/stylesheets/accounts.scss +++ b/app/assets/stylesheets/accounts.scss @@ -34,6 +34,7 @@ text-align: center; position: relative; z-index: 2; + text-shadow: 0 0 2px $color8; small { display: block; @@ -128,6 +129,7 @@ text-transform: uppercase; display: block; margin-bottom: 5px; + text-shadow: 0 0 2px $color8; } .counter-number { @@ -385,5 +387,6 @@ .account__header__content { font-size: 14px; color: $color1; + text-shadow: 0 0 2px $color8; } } -- cgit From 667ffafef8c8b7956cdd31b8f65d5e82778211d8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 5 Apr 2017 03:31:26 +0200 Subject: Fix spec --- config/locales/en.yml | 2 +- spec/models/user_spec.rb | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 750af0b7a..742219df9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -5,8 +5,8 @@ en: about_this: About this instance apps: Apps business_email: 'Business e-mail:' - contact: Contact closed_registrations: Registrations are currently closed on this instance. + contact: Contact description_headline: What is %{domain}? domain_count_after: other instances domain_count_before: Connected to diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 5575ba107..eb2a4aaea 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -45,8 +45,9 @@ RSpec.describe User, type: :model do expect(User.confirmed).to match_array([user_2]) end end + end - let(:account) { Fabricate(:account, username: 'alice') } + let(:account) { Fabricate(:account, username: 'alice') } let(:password) { 'abcd1234' } describe 'blacklist' do @@ -55,7 +56,7 @@ RSpec.describe User, type: :model do expect(user.valid?).to be_truthy end - + it 'should not allow a blacklisted user to be created' do user = User.new(email: 'foo@mvrht.com', account: account, password: password) -- cgit From 128dcb28253a43cfc2552091f419048dd3b94a9f Mon Sep 17 00:00:00 2001 From: Ash Furrow Date: Tue, 4 Apr 2017 21:35:45 -0400 Subject: Adds mastodon.technology --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 0cd3f18d6..dbed11842 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -40,5 +40,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.nasqueron.org](https://social.nasqueron.org) |Dreamers, open source developers, free culture|Yes|Yes| | [status.dissidence.ovh](https://status.dissidence.ovh)|N/A|Yes|Yes| | [mastodon.cc](https://mastodon.cc)|Art|Yes|No| +| [mastodon.technology](https://mastodon.technology)|Open registrations, federates everywhere, for tech folks|Yes|No| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From fa7b74cf51e2b5c7c60aaf3ec529ba2292450d7b Mon Sep 17 00:00:00 2001 From: Jason Snell Date: Tue, 4 Apr 2017 18:43:21 -0700 Subject: SSL best practices for nginx --- docs/Running-Mastodon/Production-guide.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md index b1f7bd35b..d539ddf64 100644 --- a/docs/Running-Mastodon/Production-guide.md +++ b/docs/Running-Mastodon/Production-guide.md @@ -11,10 +11,22 @@ map $http_upgrade $connection_upgrade { '' close; } +server { + listen 80; + listen [::]:80; + server_name example.com; + return 301 https://$host$request_uri; +} + server { listen 443 ssl; server_name example.com; + ssl_protocols TLSv1.2; + ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; -- cgit From 7d354cc8c5eceb1289259f23ecac4d85cb6c1f74 Mon Sep 17 00:00:00 2001 From: shel Date: Tue, 4 Apr 2017 21:47:13 -0400 Subject: Corrected misinformation regarding Direct Posts Unless something changed recently I have no clue why this said that direct posts do not federate because they do. --- docs/Using-Mastodon/User-guide.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Using-Mastodon/User-guide.md b/docs/Using-Mastodon/User-guide.md index f8018909a..acd02f24e 100644 --- a/docs/Using-Mastodon/User-guide.md +++ b/docs/Using-Mastodon/User-guide.md @@ -160,13 +160,13 @@ Toot privacy is handled independently of account privacy, and individually for e **Unlisted** toots are toggled with the "Do not display in public timeline" option in the Compose pane. They are visible to anyone following you and appear on your profile page to the public even without a Mastodon login, but do *not* appear to anyone viewing the Public Timeline while logged into Mastodon. -**Private** toots, finally, are toggled with the "Mark as private" switch. Private toots do not appear in the public timeline nor on your profile page to anyone viewing it unless they are on your Followers list. This means the option is of very limited use if your account is not also set to be private (as anyone can follow you without confirmation and thus see your private toots). However the separation of this means that if you *do* set your entire account to private, you can switch this option off on a toot to make unlisted or even public toots from your otherwise private account. +**Private** toots, finally, are toggled with the "Mark as private" switch. Private toots do not appear in the public timeline nor on your profile page to anyone viewing it unless they are on your Followers list. This means the option is of very limited use if your account is not also set to be private (as anyone can follow you without confirmation and thus see your private toots). However the separation of this means that if you *do* set your entire account to private, you can switch this option off on a toot to make unlisted or even public toots from your otherwise private account. Private posts are not encrypted. Make sure you trust your instance admin not to just read your private posts on the back-end. Private toots do not federate to other instances, unless you @mention a remote user. In this case, they will federate to their instance *and may appear there PUBLICLY*. A warning will be displayed if you're composing a private toot that will federate to another instance. Private toots cannot be boosted. If someone you follow makes a private toot, it will appear in your timeline with a padlock icon in place of the Boost icon. **NOTE** that remote instances may not respect this. -**Direct** messages are only visible to users you have @mentioned in them. This does *not* federate to protect your privacy (as other instances may ignore the "Direct" status and display the messages as public if they were to receive them), even if you have @mentioned a remote user. +**Direct** posts are only visible to users you have @mentioned in them and cannot be boosted. Like with private posts, you should be mindful that the remote instance may not respect this protocol. If you are discussing a sensitive matter you should move the conversation off of Mastodon. To summarise: @@ -175,7 +175,7 @@ Toot Privacy | Visible on Profile | Visible on Public Timeline | Federates to ot Public | Anyone incl. anonymous viewers | Yes | Yes Unlisted | Anyone incl. anonymous viewers | No | Yes Private | Followers only | No | Only remote @mentions -Direct | No | No | No +Direct | No | No | Only remote @mentions #### Blocking -- cgit From 1e96ce378e2aa35ed7287a4a88e5165c2ee20101 Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 20:16:53 -0700 Subject: By pushing this into a worker we can reduce the amount of time the feed manager using workers eat up a connection --- app/lib/feed_manager.rb | 2 +- app/workers/push_update_worker.rb | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 app/workers/push_update_worker.rb diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 2cca1cefe..075f86c2d 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -34,7 +34,7 @@ class FeedManager trim(timeline_type, account.id) end - broadcast(account.id, event: 'update', payload: inline_render(account, 'api/v1/statuses/show', status)) + PushUpdateWorker.perform_async(timeline_type, account.id, status.id) end def broadcast(timeline_id, options = {}) diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb new file mode 100644 index 000000000..3d398b5ac --- /dev/null +++ b/app/workers/push_update_worker.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class PushUpdateWorker + include Sidekiq::Worker + + def perform(timeline, account_id, status_id) + account = Account.find(account_id) + status = Status.find(status_id) + message = inline_render(account, 'api/v1/statuses/show', status) + + broadcast(account_id, type: 'update', timeline: timeline, message: message) + end +end -- cgit From 96ef9338208e09cbc52a49a3d7171d877eab3c43 Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 20:36:03 -0700 Subject: Replacing the broadcast method with the one defined in the feed manager --- app/workers/push_update_worker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb index 3d398b5ac..5b5e9f68a 100644 --- a/app/workers/push_update_worker.rb +++ b/app/workers/push_update_worker.rb @@ -8,6 +8,6 @@ class PushUpdateWorker status = Status.find(status_id) message = inline_render(account, 'api/v1/statuses/show', status) - broadcast(account_id, type: 'update', timeline: timeline, message: message) + ActionCable.server.broadcast("timeline:#{account_id}", type: 'update', timeline: timeline, message: message) end end -- cgit From dc5704b0b0c8f5a58ff95d3f3c4055929c6ecfba Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 20:38:07 -0700 Subject: This method isn't used anymore --- app/lib/feed_manager.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 075f86c2d..6698c78a5 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -37,11 +37,6 @@ class FeedManager PushUpdateWorker.perform_async(timeline_type, account.id, status.id) end - def broadcast(timeline_id, options = {}) - options[:queued_at] = (Time.now.to_f * 1000.0).to_i - ActionCable.server.broadcast("timeline:#{timeline_id}", options) - end - def trim(type, account_id) return unless redis.zcard(key(type, account_id)) > FeedManager::MAX_ITEMS last = redis.zrevrange(key(type, account_id), FeedManager::MAX_ITEMS - 1, FeedManager::MAX_ITEMS - 1) -- cgit From 0069c01285d7fc6b97220fd678f6e5b82f301b1a Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 20:39:14 -0700 Subject: Moving the queue_at into the worker --- app/workers/push_update_worker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb index 5b5e9f68a..6512e13ad 100644 --- a/app/workers/push_update_worker.rb +++ b/app/workers/push_update_worker.rb @@ -7,7 +7,7 @@ class PushUpdateWorker account = Account.find(account_id) status = Status.find(status_id) message = inline_render(account, 'api/v1/statuses/show', status) - + queue_at = (Time.now.to_f * 1000.0).to_i ActionCable.server.broadcast("timeline:#{account_id}", type: 'update', timeline: timeline, message: message) end end -- cgit From 220051b8b2d09a741f5edadd34e21115c5938bf0 Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 20:48:22 -0700 Subject: I don't actually think we need that. --- app/workers/push_update_worker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb index 6512e13ad..5b5e9f68a 100644 --- a/app/workers/push_update_worker.rb +++ b/app/workers/push_update_worker.rb @@ -7,7 +7,7 @@ class PushUpdateWorker account = Account.find(account_id) status = Status.find(status_id) message = inline_render(account, 'api/v1/statuses/show', status) - queue_at = (Time.now.to_f * 1000.0).to_i + ActionCable.server.broadcast("timeline:#{account_id}", type: 'update', timeline: timeline, message: message) end end -- cgit From 9638894233d31368733574217e4d173e4cd5d13c Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 20:51:18 -0700 Subject: Moving in the inline render --- app/workers/push_update_worker.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb index 5b5e9f68a..fef75d909 100644 --- a/app/workers/push_update_worker.rb +++ b/app/workers/push_update_worker.rb @@ -6,8 +6,14 @@ class PushUpdateWorker def perform(timeline, account_id, status_id) account = Account.find(account_id) status = Status.find(status_id) - message = inline_render(account, 'api/v1/statuses/show', status) + message = Rabl::Renderer.new( + 'api/v1/statuses/show', + status, + view_path: 'app/views', + format: :json, + scope: InlineRablScope.new(account) + ) - ActionCable.server.broadcast("timeline:#{account_id}", type: 'update', timeline: timeline, message: message) + ActionCable.server.broadcast("timeline:#{account_id}", type: 'update', timeline: timeline, message: message.render) end end -- cgit From 7bed4e51db18c864c36c6b48eb22c65f11c16b1c Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 20:51:44 -0700 Subject: Moved to the worker --- app/lib/feed_manager.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 6698c78a5..87865bfdc 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -76,10 +76,6 @@ class FeedManager end end - def inline_render(target_account, template, object) - Rabl::Renderer.new(template, object, view_path: 'app/views', format: :json, scope: InlineRablScope.new(target_account)).render - end - private def redis -- cgit From 22dcadedb495d2e1279b834a624710d34daee6ad Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 21:14:37 -0700 Subject: We're going to want these nice helper methods, lets share them with a parent class that matches Rails 5 practices (application level abstraction) --- app/workers/application_worker.rb | 5 +++++ app/workers/distribution_worker.rb | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 app/workers/application_worker.rb diff --git a/app/workers/application_worker.rb b/app/workers/application_worker.rb new file mode 100644 index 000000000..f2d7c1062 --- /dev/null +++ b/app/workers/application_worker.rb @@ -0,0 +1,5 @@ +class ApplicationWorker + def info(message) + Rails.logger.info("#{self.class.name} - #{message}") + end +end diff --git a/app/workers/distribution_worker.rb b/app/workers/distribution_worker.rb index f4e738d80..9a2867ea6 100644 --- a/app/workers/distribution_worker.rb +++ b/app/workers/distribution_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DistributionWorker +class DistributionWorker < ApplicationWorker include Sidekiq::Worker def perform(status_id) @@ -9,6 +9,6 @@ class DistributionWorker FanOutOnWriteService.new.call(status) WarmCacheService.new.call(status) rescue ActiveRecord::RecordNotFound - true + info("Couldn't find the status") end end -- cgit From 29efeecb9ebd4eac0ec65040b2f688d7a5c77283 Mon Sep 17 00:00:00 2001 From: scriptjunkie Date: Tue, 4 Apr 2017 23:21:00 -0500 Subject: Add https://securitymastod.one/ --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 0cd3f18d6..6b6eda74c 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -6,6 +6,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | Name | Theme/Notes, if applicable | Open Registrations | IPv6 | | -------------|-------------|---|---| | [mastodon.social](https://mastodon.social) |Flagship, quick updates|Yes|No| +| [securitymastod.one](https://securitymastod.one/) |Information security enthusiasts and pros|Yes|Yes| | [awoo.space](https://awoo.space) |Intentionally moderated, only federates with mastodon.social|Yes|No| | [animalliberation.social](https://animalliberation.social) |Animal Rights|Yes|No| | [socially.constructed.space](https://socially.constructed.space) |Single user|No|No| -- cgit From 03adb5d7277bc1672ce3617d328280873e671b24 Mon Sep 17 00:00:00 2001 From: Kurtis Rainbolt-Greene Date: Tue, 4 Apr 2017 21:31:02 -0700 Subject: Mastodon isn't using jbuilder or sdoc, and it prevents an upgrade to 2.4.0 --- Gemfile | 2 -- Gemfile.lock | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/Gemfile b/Gemfile index 4e7ff6621..b5705e9d1 100644 --- a/Gemfile +++ b/Gemfile @@ -8,8 +8,6 @@ gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.1.0' gem 'jquery-rails' -gem 'jbuilder', '~> 2.0' -gem 'sdoc', '~> 0.4.0', group: :doc gem 'puma' gem 'hamlit-rails' diff --git a/Gemfile.lock b/Gemfile.lock index a774a89ba..408d85ade 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -198,9 +198,6 @@ GEM parser (>= 2.2.3.0) term-ansicolor (>= 1.3.2) terminal-table (>= 1.5.1) - jbuilder (2.6.0) - activesupport (>= 3.0.0, < 5.1) - multi_json (~> 1.2) jmespath (1.3.1) jquery-rails (4.1.1) rails-dom-testing (>= 1, < 3) @@ -231,7 +228,6 @@ GEM mimemagic (0.3.2) mini_portile2 (2.1.0) minitest (5.10.1) - multi_json (1.12.1) net-scp (1.2.1) net-ssh (>= 2.6.5) net-ssh (4.0.1) @@ -310,8 +306,6 @@ GEM thor (>= 0.18.1, < 2.0) rainbow (2.1.0) rake (12.0.0) - rdoc (4.2.2) - json (~> 1.4) react-rails (1.10.0) babel-transpiler (>= 0.7.0) coffee-script-source (~> 1.8) @@ -381,9 +375,6 @@ GEM sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - sdoc (0.4.1) - json (~> 1.7, >= 1.7.7) - rdoc (~> 4.0) sidekiq (4.2.7) concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) @@ -483,7 +474,6 @@ DEPENDENCIES http httplog i18n-tasks (~> 0.9.6) - jbuilder (~> 2.0) jquery-rails letter_opener letter_opener_web @@ -514,7 +504,6 @@ DEPENDENCIES rubocop ruby-oembed sass-rails (~> 5.0) - sdoc (~> 0.4.0) sidekiq sidekiq-unique-jobs simple-navigation -- cgit From 8040d1d8cef092cd5f9b3497e1514301f4ebe54e Mon Sep 17 00:00:00 2001 From: Ian McDowell Date: Tue, 4 Apr 2017 23:43:57 -0500 Subject: Update List-of-Mastodon-instances.md Added mastodon.network. --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 0cd3f18d6..8b8aba124 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -6,6 +6,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | Name | Theme/Notes, if applicable | Open Registrations | IPv6 | | -------------|-------------|---|---| | [mastodon.social](https://mastodon.social) |Flagship, quick updates|Yes|No| +| [mastodon.network](https://mastodon.network) |N/A|Yes|Yes| | [awoo.space](https://awoo.space) |Intentionally moderated, only federates with mastodon.social|Yes|No| | [animalliberation.social](https://animalliberation.social) |Animal Rights|Yes|No| | [socially.constructed.space](https://socially.constructed.space) |Single user|No|No| -- cgit From 6a1da87cd32a077c8df2e82cbdc222c201ddda41 Mon Sep 17 00:00:00 2001 From: Brad Urani Date: Wed, 5 Apr 2017 06:02:58 +0000 Subject: Eliminate unnecessary queries and query clauses with none and all --- app/models/status.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/status.rb b/app/models/status.rb index daf128572..6948ad77c 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -161,9 +161,9 @@ class Status < ApplicationRecord return where.not(visibility: [:private, :direct]) if account.nil? if target_account.blocking?(account) # get rid of blocked peeps - where('1 = 0') + none elsif account.id == target_account.id # author can see own stuff - where('1 = 1') + all elsif account.following?(target_account) # followers can see followers-only stuff, but also things they are mentioned in joins('LEFT OUTER JOIN mentions ON statuses.id = mentions.status_id AND mentions.account_id = ' + account.id.to_s) .where('statuses.visibility != ? OR mentions.id IS NOT NULL', Status.visibilities[:direct]) -- cgit From b845ef395d2dc86f32beb7e2071cc828258816b5 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Wed, 5 Apr 2017 09:51:35 +0200 Subject: updated reblog translation --- config/locales/simple_form.fi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index 02943cea3..684cbe39c 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -38,7 +38,7 @@ fi: follow: Lähetä s-posti kun joku seuraa sinua follow_request: Lähetä s-posti kun joku pyytää seurata sinua mention: Lähetä s-posti kun joku mainitsee sinut - reblog: Lähetä s-posti kun joku uudestaanblogaa julkaisusi + reblog: Lähetä s-posti kun joku reblogaa julkaisusi 'no': 'Ei' required: mark: "*" -- cgit From 473e4f781318b24c1df11da36e7846080de27ea9 Mon Sep 17 00:00:00 2001 From: JantsoP Date: Wed, 5 Apr 2017 09:52:31 +0200 Subject: udpdated display_name translation --- config/locales/simple_form.fi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index 684cbe39c..7e1205fdc 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -17,7 +17,7 @@ fi: confirm_password: Varmista salasana current_password: Nykyinen salasana data: Data - display_name: Näyttö nimi + display_name: Näykyvä nimi email: Sähköpostiosoite header: Header locale: Kieli -- cgit From b8a867adcc8bfeaba7fa09204b6babd17abe225b Mon Sep 17 00:00:00 2001 From: JantsoP Date: Wed, 5 Apr 2017 09:56:10 +0200 Subject: updated translation Updated some translations after seeing them in service. Should be better now --- app/assets/javascripts/components/locales/fi.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/components/locales/fi.jsx b/app/assets/javascripts/components/locales/fi.jsx index 7b151d6f8..b3ae4bc56 100644 --- a/app/assets/javascripts/components/locales/fi.jsx +++ b/app/assets/javascripts/components/locales/fi.jsx @@ -5,9 +5,9 @@ const fi = { "status.mention": "Mainitse @{name}", "status.delete": "Poista", "status.reply": "Vastaa", - "status.reblog": "Boostaa", + "status.reblog": "Buustaa", "status.favourite": "Tykkää", - "status.reblogged_by": "{name} boostattu", + "status.reblogged_by": "{name} buustasi", "status.sensitive_warning": "Arkaluontoista sisältöä", "status.sensitive_toggle": "Klikkaa nähdäksesi", "video_player.toggle_sound": "Äänet päälle/pois", @@ -28,7 +28,7 @@ const fi = { "getting_started.open_source_notice": "Mastodon Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia GitHub palvelussa {github}. {apps}.", "column.home": "Koti", "column.community": "Paikallinen aikajana", - "column.public": "Yhdistetty aikajana", + "column.public": "Yleinen aikajana", "column.notifications": "Ilmoitukset", "tabs_bar.compose": "Luo", "tabs_bar.home": "Koti", @@ -41,7 +41,7 @@ const fi = { "compose_form.spoiler": "Piiloita teksti varoituksen taakse", "compose_form.private": "Merkitse yksityiseksi", "compose_form.privacy_disclaimer": "Sinun yksityinen status toimitetaan mainitsemallesi käyttäjille domaineissa {domains}. Luotatko {domainsCount, plural, one {tähän palvelimeen} other {näihin palvelimiin}}? Postauksen yksityisyys toimii van Mastodon palvelimilla. Jos {domains} {domainsCount, plural, one {ei ole Mastodon palvelin} other {eivät ole Mastodon palvelin}}, viestiin ei tule Yksityinen-merkintää, ja sitä voidaan boostata tai muuten tehdä näkyväksi muille vastaanottajille.", - "compose_form.unlisted": "Älä näytä julkisilla aikajanoilla", + "compose_form.unlisted": "Älä näytä yleisillä aikajanoilla", "navigation_bar.edit_profile": "Muokkaa profiilia", "navigation_bar.preferences": "Ominaisuudet", "navigation_bar.community_timeline": "Paikallinen aikajana", @@ -55,14 +55,14 @@ const fi = { "upload_form.undo": "Peru", "notification.follow": "{name} seurasi sinua", "notification.favourite": "{name} tykkäsi statuksestasi", - "notification.reblog": "{name} boostasi statustasi", + "notification.reblog": "{name} buustasi statustasi", "notification.mention": "{name} mainitsi sinut", "notifications.column_settings.alert": "Työpöytä ilmoitukset", "notifications.column_settings.show": "Näytä sarakkeessa", "notifications.column_settings.follow": "Uusia seuraajia:", "notifications.column_settings.favourite": "Tykkäyksiä:", "notifications.column_settings.mention": "Mainintoja:", - "notifications.column_settings.reblog": "Boosteja:", + "notifications.column_settings.reblog": "Buusteja:", }; export default fi; -- cgit From 3ec221d3b7093e2a2606ec04036cca9e9f1f733d Mon Sep 17 00:00:00 2001 From: JantsoP Date: Wed, 5 Apr 2017 09:57:25 +0200 Subject: updated reblog to boost translation Since it is that :D --- config/locales/simple_form.fi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index 7e1205fdc..2bacd6d2c 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -38,7 +38,7 @@ fi: follow: Lähetä s-posti kun joku seuraa sinua follow_request: Lähetä s-posti kun joku pyytää seurata sinua mention: Lähetä s-posti kun joku mainitsee sinut - reblog: Lähetä s-posti kun joku reblogaa julkaisusi + reblog: Lähetä s-posti kun joku buustaa julkaisusi 'no': 'Ei' required: mark: "*" -- cgit From 3504da5cac467e367e39e2310aaa5dba6b643f45 Mon Sep 17 00:00:00 2001 From: Eugen Date: Wed, 5 Apr 2017 10:25:05 +0200 Subject: Fix API method URL typo --- docs/Using-the-API/API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Using-the-API/API.md b/docs/Using-the-API/API.md index bc5ca3de4..e09d8ac9c 100644 --- a/docs/Using-the-API/API.md +++ b/docs/Using-the-API/API.md @@ -310,7 +310,7 @@ Returns a [Status](#status). #### Getting status context: - GET /api/v1/statuses/:id/contexts + GET /api/v1/statuses/:id/context Returns a [Context](#context). -- cgit From 5dbcd92193f45d71629e261cc264725d59f2ea6c Mon Sep 17 00:00:00 2001 From: Angristan Date: Wed, 5 Apr 2017 10:44:08 +0200 Subject: ECDH only Disable DHE ciphers. We don't loose any compatibility as we already use TLS 1.2, and ECDH is faster and safer. Also, it's better so specify the curve. This is the conf I use here : https://tls.imirhil.fr/https/mstdn.io --- docs/Running-Mastodon/Production-guide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md index d539ddf64..3912fd2ba 100644 --- a/docs/Running-Mastodon/Production-guide.md +++ b/docs/Running-Mastodon/Production-guide.md @@ -23,7 +23,8 @@ server { server_name example.com; ssl_protocols TLSv1.2; - ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; + ssl_ciphers EECDH+AESGCM:EECDH+AES; + ssl_ecdh_curve secp384r1; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; -- cgit From 5963fce131b3bbfbe0a93b1b11a76d3efadce61f Mon Sep 17 00:00:00 2001 From: Jordan Guerder Date: Wed, 5 Apr 2017 10:52:56 +0200 Subject: Added mastodon.cx --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index d0bcf8c7d..e726e5dcd 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -7,6 +7,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | -------------|-------------|---|---| | [mastodon.social](https://mastodon.social) |Flagship, quick updates|No|No| | [securitymastod.one](https://securitymastod.one/) |Information security enthusiasts and pros|Yes|Yes| +| [mastodon.cx](https://mastodon.cx/) |Alternative Mastodon instance hosted in France|Yes|Yes| | [mastodon.network](https://mastodon.network) |N/A|Yes|Yes| | [awoo.space](https://awoo.space) |Intentionally moderated, only federates with mastodon.social|Yes|No| | [animalliberation.social](https://animalliberation.social) |Animal Rights|Yes|No| -- cgit From fa6f7c88984a052d5a10aae6807a3f9e2fcc761a Mon Sep 17 00:00:00 2001 From: Angristan Date: Wed, 5 Apr 2017 11:16:56 +0200 Subject: Add mstdn.io --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index d0bcf8c7d..a23cdafde 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -21,6 +21,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [mastodon.xyz](https://mastodon.xyz) |N/A|Yes|Yes| | [social.targaryen.house](https://social.targaryen.house) |Federates everywhere, quick updates.|Yes|Yes| | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| +| [mstdn.io](https://mstdn.io) |N/A|Yes|Yes| | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| | [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, federates everywhere, no moderation yet|Yes|Yes| | [octodon.social](https://octodon.social) |Open registrations, federates everywhere, cutest instance yet|Yes|Yes| -- cgit From bdf3ac95b8cc2efa277570082806b5777b24dfe4 Mon Sep 17 00:00:00 2001 From: Cédric Levieux Date: Wed, 5 Apr 2017 11:24:21 +0200 Subject: Add mastodon.partipirate.org --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index d0bcf8c7d..0b1720e11 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -19,6 +19,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.diskseven.com](https://social.diskseven.com) |Single user|No|Yes| | [social.gestaltzerfall.net](https://social.gestaltzerfall.net) |Single user|No|No| | [mastodon.xyz](https://mastodon.xyz) |N/A|Yes|Yes| +| [mastodon.partipirate.org](https://mastodon.partipirate.org) |French Pirate Part Instance - Politics and stuff|Yes|No| | [social.targaryen.house](https://social.targaryen.house) |Federates everywhere, quick updates.|Yes|Yes| | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| -- cgit From 9572282a559a07196e62190a852aacbd94968c71 Mon Sep 17 00:00:00 2001 From: nicobz25 Date: Wed, 5 Apr 2017 13:13:09 +0200 Subject: Update List-of-Mastodon-instances.md Add our mastodon instance :) Thanks ! --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 0b98f8552..bf770dc43 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -46,5 +46,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [status.dissidence.ovh](https://status.dissidence.ovh)|N/A|Yes|Yes| | [mastodon.cc](https://mastodon.cc)|Art|Yes|No| | [mastodon.technology](https://mastodon.technology)|Open registrations, federates everywhere, for tech folks|Yes|No| +| [mastodon.systemlab.fr](https://mastodon.systemlab.fr/)|Le mastodon Français, informatique, jeux-vidéos, gaming et hébergement.|Yes|No| Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request). -- cgit From 85c768bf16986ce8df3c8df9ea0724f60f3aebe2 Mon Sep 17 00:00:00 2001 From: Cédric Levieux Date: Wed, 5 Apr 2017 13:19:34 +0200 Subject: Typography on partY --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 0b98f8552..435e51411 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -20,7 +20,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.diskseven.com](https://social.diskseven.com) |Single user|No|Yes| | [social.gestaltzerfall.net](https://social.gestaltzerfall.net) |Single user|No|No| | [mastodon.xyz](https://mastodon.xyz) |N/A|Yes|Yes| -| [mastodon.partipirate.org](https://mastodon.partipirate.org) |French Pirate Part Instance - Politics and stuff|Yes|No| +| [mastodon.partipirate.org](https://mastodon.partipirate.org) |French Pirate Party Instance - Politics and stuff|Yes|No| | [social.targaryen.house](https://social.targaryen.house) |Federates everywhere, quick updates.|Yes|Yes| | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| | [mstdn.io](https://mstdn.io) |N/A|Yes|Yes| -- cgit From 8530f9413b86e0734ed9e0be93f0168a070f9ac8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 5 Apr 2017 13:28:46 +0200 Subject: Replace ActionCable broadcast call with simple redis publish --- app/lib/feed_manager.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 2cca1cefe..88f6f4a46 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -39,7 +39,7 @@ class FeedManager def broadcast(timeline_id, options = {}) options[:queued_at] = (Time.now.to_f * 1000.0).to_i - ActionCable.server.broadcast("timeline:#{timeline_id}", options) + redis.publish("timeline:#{timeline_id}", Oj.dump(options)) end def trim(type, account_id) -- cgit From cfe91ac984fcabcc1980e88367dd636f0a8cc799 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 5 Apr 2017 13:32:57 +0200 Subject: Add index on mentions status_id --- db/migrate/20170405112956_add_index_on_mentions_status_id.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20170405112956_add_index_on_mentions_status_id.rb diff --git a/db/migrate/20170405112956_add_index_on_mentions_status_id.rb b/db/migrate/20170405112956_add_index_on_mentions_status_id.rb new file mode 100644 index 000000000..3ed1a20cf --- /dev/null +++ b/db/migrate/20170405112956_add_index_on_mentions_status_id.rb @@ -0,0 +1,5 @@ +class AddIndexOnMentionsStatusId < ActiveRecord::Migration[5.0] + def change + add_index :mentions, :status_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 3aaa3e3ad..b5d55fa16 100644 --- a/db/schema.rb +++ b/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: 20170403172249) do +ActiveRecord::Schema.define(version: 20170405112956) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -127,6 +127,7 @@ ActiveRecord::Schema.define(version: 20170403172249) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true, using: :btree + t.index ["status_id"], name: "index_mentions_on_status_id", using: :btree end create_table "mutes", force: :cascade do |t| -- cgit From 0a984e90d3052272bf793cb4393b9d642432aebb Mon Sep 17 00:00:00 2001 From: Jonathan Hurter Date: Wed, 5 Apr 2017 13:45:03 +0200 Subject: Add scalingo support --- .buildpacks | 2 ++ scalingo.json | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 .buildpacks create mode 100644 scalingo.json diff --git a/.buildpacks b/.buildpacks new file mode 100644 index 000000000..29d7ee1e9 --- /dev/null +++ b/.buildpacks @@ -0,0 +1,2 @@ +https://github.com/Scalingo/ruby-buildpack +https://github.com/Scalingo/nodejs-buildpack diff --git a/scalingo.json b/scalingo.json new file mode 100644 index 000000000..84b690e24 --- /dev/null +++ b/scalingo.json @@ -0,0 +1,87 @@ +{ + "name": "Mastodon", + "description": "A GNU Social-compatible microblogging server", + "repository": "https://github.com/johnsudaar/mastodon", + "logo": "https://github.com/tootsuite/mastodon/raw/master/app/assets/images/logo.png", + "env": { + "LOCAL_DOMAIN": { + "description": "The domain that your Mastodon instance will run on (this can be appname.scalingo.io or a custom domain)", + "required": true + }, + "LOCAL_HTTPS": { + "description": "Will your domain support HTTPS? (Automatic for *.scalingo.io, requires manual configuration for custom domains)", + "value": "true", + "required": true + }, + "PAPERCLIP_SECRET": { + "description": "The secret key for storing media files", + "generator": "secret" + }, + "SECRET_KEY_BASE": { + "description": "The secret key base", + "generator": "secret" + }, + "SINGLE_USER_MODE": { + "description": "Should the instance run in single user mode? (Disable registrations, redirect to front page)", + "value": "false", + "required": true + }, + "S3_ENABLED": { + "description": "Should Mastodon use Amazon S3 for storage? This is highly recommended, as Scalingo does not have persistent file storage (files will be lost).", + "value": "true", + "required": false + }, + "S3_BUCKET": { + "description": "Amazon S3 Bucket", + "required": false + }, + "S3_REGION": { + "description": "Amazon S3 region that the bucket is located in", + "required": false + }, + "AWS_ACCESS_KEY_ID": { + "description": "Amazon S3 Access Key", + "required": false + }, + "AWS_SECRET_ACCESS_KEY": { + "description": "Amazon S3 Secret Key", + "required": false + }, + "SMTP_SERVER": { + "description": "Hostname for SMTP server, if you want to enable email", + "required": false + }, + "SMTP_PORT": { + "description": "Port for SMTP server", + "required": false + }, + "SMTP_LOGIN": { + "description": "Username for SMTP server", + "required": false + }, + "SMTP_PASSWORD": { + "description": "Password for SMTP server", + "required": false + }, + "SMTP_DOMAIN": { + "description": "Domain for SMTP server. Will default to instance domain if blank.", + "required": false + }, + "SMTP_FROM_ADDRESS": { + "description": "Address to send emails from", + "required": false + }, + "BUILDPACK_URL": { + "description": "Internal scalingo configuration", + "required": true, + "value": "https://github.com/Scalingo/multi-buildpack.git" + } + }, + "scripts": { + "postdeploy": "bundle exec rails db:migrate && bundle exec rails db:seed" + }, + "addons": [ + "scalingo-postgresql", + "scalingo-redis" + ] +} -- cgit From 79765d61f506e8e7dd08b683ebfdaabfba12b1fe Mon Sep 17 00:00:00 2001 From: Jonathan Hurter Date: Wed, 5 Apr 2017 13:53:30 +0200 Subject: Install nodejs before ruby --- .buildpacks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildpacks b/.buildpacks index 29d7ee1e9..d295b0f5d 100644 --- a/.buildpacks +++ b/.buildpacks @@ -1,2 +1,2 @@ -https://github.com/Scalingo/ruby-buildpack https://github.com/Scalingo/nodejs-buildpack +https://github.com/Scalingo/ruby-buildpack -- cgit From 5ed2de6be2f3003be4422a659bdd7ab96803adf0 Mon Sep 17 00:00:00 2001 From: Angristan Date: Wed, 5 Apr 2017 14:11:08 +0200 Subject: Add git and curl as dependencies In some VPS templates, they are not installed by default. --- docs/Running-Mastodon/Production-guide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md index 3912fd2ba..90e9c0dea 100644 --- a/docs/Running-Mastodon/Production-guide.md +++ b/docs/Running-Mastodon/Production-guide.md @@ -88,8 +88,9 @@ It is recommended to create a special user for mastodon on the server (you could ## General dependencies + sudo apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs file git curl curl -sL https://deb.nodesource.com/setup_4.x | sudo bash - - sudo apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs file + apt-get intall nodejs sudo npm install -g yarn ## Redis -- cgit From 259e626165bd7bf3360b18f007d0f8c968405de2 Mon Sep 17 00:00:00 2001 From: wxcafé Date: Wed, 5 Apr 2017 14:21:45 +0200 Subject: Update List-of-Mastodon-instances.md --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index 0b98f8552..07a6a4813 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -25,7 +25,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes| | [mstdn.io](https://mstdn.io) |N/A|Yes|Yes| | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes| -| [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, federates everywhere, no moderation yet|Yes|Yes| +| [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, queer people, activists, safe as much as possible |Yes|Yes| | [octodon.social](https://octodon.social) |Open registrations, federates everywhere, cutest instance yet|Yes|Yes| | [mastodon.club](https://mastodon.club)|Open Registration, Open Federation, Mostly Canadians|Yes|No| | [hostux.social](https://hostux.social) |N/A|Yes|Yes| -- cgit From 220bc48e8e9c4b8cebd98537233998f34d768347 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 5 Apr 2017 14:26:17 +0200 Subject: Only render public payload once in FanOutOnWrite --- app/services/fan_out_on_write_service.rb | 17 +++++++++-------- app/workers/after_remote_follow_request_worker.rb | 2 ++ app/workers/after_remote_follow_worker.rb | 2 ++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 42222c25b..106d257ba 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -16,6 +16,7 @@ class FanOutOnWriteService < BaseService return if status.account.silenced? || !status.public_visibility? || status.reblog? + render_anonymous_payload(status) deliver_to_hashtags(status) return if status.reply? && status.in_reply_to_account_id != status.account_id @@ -48,23 +49,23 @@ class FanOutOnWriteService < BaseService end end + def render_anonymous_payload(status) + @payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status) + end + def deliver_to_hashtags(status) Rails.logger.debug "Delivering status #{status.id} to hashtags" - payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status) - status.tags.pluck(:name).each do |hashtag| - FeedManager.instance.broadcast("hashtag:#{hashtag}", event: 'update', payload: payload) - FeedManager.instance.broadcast("hashtag:#{hashtag}:local", event: 'update', payload: payload) if status.account.local? + FeedManager.instance.broadcast("hashtag:#{hashtag}", event: 'update', payload: @payload) + FeedManager.instance.broadcast("hashtag:#{hashtag}:local", event: 'update', payload: @payload) if status.account.local? end end def deliver_to_public(status) Rails.logger.debug "Delivering status #{status.id} to public timeline" - payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status) - - FeedManager.instance.broadcast(:public, event: 'update', payload: payload) - FeedManager.instance.broadcast('public:local', event: 'update', payload: payload) if status.account.local? + FeedManager.instance.broadcast(:public, event: 'update', payload: @payload) + FeedManager.instance.broadcast('public:local', event: 'update', payload: @payload) if status.account.local? end end diff --git a/app/workers/after_remote_follow_request_worker.rb b/app/workers/after_remote_follow_request_worker.rb index 1f2db3061..928069211 100644 --- a/app/workers/after_remote_follow_request_worker.rb +++ b/app/workers/after_remote_follow_request_worker.rb @@ -13,5 +13,7 @@ class AfterRemoteFollowRequestWorker follow_request.destroy FollowService.new.call(follow_request.account, updated_account.acct) + rescue ActiveRecord::RecordNotFound + true end end diff --git a/app/workers/after_remote_follow_worker.rb b/app/workers/after_remote_follow_worker.rb index bdd2c2a91..d12fa3454 100644 --- a/app/workers/after_remote_follow_worker.rb +++ b/app/workers/after_remote_follow_worker.rb @@ -13,5 +13,7 @@ class AfterRemoteFollowWorker follow.destroy FollowService.new.call(follow.account, updated_account.acct) + rescue ActiveRecord::RecordNotFound + true end end -- cgit From bf523fcd16cb7d4ffd81424d3d582e4dfab158b6 Mon Sep 17 00:00:00 2001 From: Jonathan Hurter Date: Wed, 5 Apr 2017 14:13:34 +0200 Subject: Add node_modules and .cache to slugignore --- .slugignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .slugignore diff --git a/.slugignore b/.slugignore new file mode 100644 index 000000000..cbf0615e7 --- /dev/null +++ b/.slugignore @@ -0,0 +1,2 @@ +node_modules/ +.cache/ -- cgit From d3bf0307dbcf4d0f99615f1b3cb90565721de81c Mon Sep 17 00:00:00 2001 From: Jantso Porali Date: Wed, 5 Apr 2017 14:47:42 +0200 Subject: updated translation for about page --- config/locales/fi.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 3bcfe5c20..c2f81413a 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -21,12 +21,12 @@ fi: features_headline: Mikä erottaa Mastodonin muista get_started: Aloita käyttö links: Linkit - other_instances: Muut palvelimet + other_instances: muuhun palvelimeen source_code: Lähdekoodi - status_count_after: statukset - status_count_before: Kuka loi + status_count_after: statusta + status_count_before: Ovat luoneet terms: Ehdot - user_count_after: käyttäjät + user_count_after: käyttäjää user_count_before: Koti käyttäjälle accounts: follow: Seuraa -- cgit From deb001bba87cc2e1b65de05ce6569e98ab3b0caa Mon Sep 17 00:00:00 2001 From: Jantso Porali Date: Wed, 5 Apr 2017 14:49:29 +0200 Subject: updated two-way auth and preferences translation --- config/locales/fi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/fi.yml b/config/locales/fi.yml index c2f81413a..d5dfd8183 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -132,7 +132,7 @@ fi: edit_profile: Muokkaa profiilia export: Datan vienti import: Datan tuonti - preferences: Mieltymykset + preferences: Ominaisuudet settings: Asetukset two_factor_auth: Kaksivaiheinen tunnistus statuses: @@ -154,7 +154,7 @@ fi: description_html: Jos otat käyttöön kaksivaiheisen tunnistuksen, kirjautumiseen vaaditaan puhelin, joka voi generoida tokeneita kirjautumista varten. disable: Poista käytöstä enable: Ota käyttöön - instructions_html: "Skannaa tämä QR-koodi Google Authenticator tai samanlaiseen sovellukseen puhelimellasi. Tästä hetkestä lähtien, ohjelma generoi tokenit mikä sinun tarvitsee syöttää sisäänkirjautuessa." + instructions_html: "Skannaa tämä QR-koodi Google Authenticator tai samanlaiseen sovellukseen puhelimellasi. Tästä hetkestä lähtien ohjelma generoi koodin, mikä sinun tarvitsee syöttää sisäänkirjautuessa." plaintext_secret_html: 'Plain-text secret: %{secret}' warning: Jos et juuri nyt voi konfiguroida authenticator-applikaatiota juuri nyt, sinun pitäisi klikata "Poista käytöstä" tai et voi kirjautua sisään. users: -- cgit From 837030db98d2e3a054d2f74ba2aa331d58671c4b Mon Sep 17 00:00:00 2001 From: Jantso Porali Date: Wed, 5 Apr 2017 14:53:35 +0200 Subject: updated blocking translation --- config/locales/fi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/fi.yml b/config/locales/fi.yml index d5dfd8183..cdb2b9886 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -89,7 +89,7 @@ fi: preface: Voit tuoda tiettyä dataa kaikista ihmisistä joita seuraat tai estät tilillesi tälle palvelimelle tiedostoista, jotka on luotu toisella palvelimella success: Datasi on onnistuneesti ladattu ja käsitellään pian types: - blocking: Esto lista + blocking: Estetyt lista following: Seuratut lista upload: Lähetä landing_strip_html: %{name} on käyttäjä domainilla %{domain}. Voit seurata tai vuorovaikuttaa heidän kanssaan jos sinulla on tili yleisessä verkossa. Jos sinulla ei ole tiliä, voit rekisteröityä täällä. -- cgit From cbcfd92a14aca00139601e19b1c95f013f81036f Mon Sep 17 00:00:00 2001 From: Padraig Fahy Date: Wed, 5 Apr 2017 14:00:35 +0100 Subject: Adding mastodon.irish --- docs/Using-Mastodon/List-of-Mastodon-instances.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md index a14836b80..0972e553f 100644 --- a/docs/Using-Mastodon/List-of-Mastodon-instances.md +++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md @@ -28,6 +28,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz) | [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, queer people, activists, safe as much as possible |Yes|Yes| | [octodon.social](https://octodon.social) |Open registrations, federates everywhere, cutest instance yet|Yes|Yes| | [mastodon.club](https://mastodon.club)|Open Registration, Open Federation, Mostly Canadians|Yes|No| +| [mastodon.irish](https://mastodon.irish)|Open Registration|Yes|No| | [hostux.social](https://hostux.social) |N/A|Yes|Yes| | [social.alex73630.xyz](https://social.alex73630.xyz) |Francophones|Yes|Yes| | [oc.todon.fr](https://oc.todon.fr) |Modérée et principalement francophone, pas de tolérances pour misogynie/LGBTphobies/validisme/etc.|Yes|Yes| -- cgit From 152a1e578c46068dfac2888620798073d3d305b8 Mon Sep 17 00:00:00 2001 From: Jonathan Hurter Date: Wed, 5 Apr 2017 15:26:36 +0200 Subject: Add Scalingo one click on readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 20499e6e3..3827a74ab 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,10 @@ Which will re-create the updated containers, leaving databases and data as is. D Docker is great for quickly trying out software, but it has its drawbacks too. If you prefer to run Mastodon without using Docker, refer to the [production guide](docs/Running-Mastodon/Production-guide.md) for examples, configuration and instructions. +## Deployment on Scalingo + +[![Deploy on Scalingo](https://cdn.scalingo.com/deploy/button.svg)](https://my.scalingo.com/deploy?source=https://github.com/johnsudaar/mastodon#master) + ## Deployment on Heroku (experimental) [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) -- cgit From 5e7ec0fe573f11d9c853981ac0ae57a8b27cf9ce Mon Sep 17 00:00:00 2001 From: Jonathan Hurter Date: Wed, 5 Apr 2017 15:52:06 +0200 Subject: Use root repository url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3827a74ab..fde4df6bb 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Docker is great for quickly trying out software, but it has its drawbacks too. I ## Deployment on Scalingo -[![Deploy on Scalingo](https://cdn.scalingo.com/deploy/button.svg)](https://my.scalingo.com/deploy?source=https://github.com/johnsudaar/mastodon#master) +[![Deploy on Scalingo](https://cdn.scalingo.com/deploy/button.svg)](https://my.scalingo.com/deploy?source=https://github.com/tootsuite/mastodon#master) ## Deployment on Heroku (experimental) -- cgit From d6bab0c71cd94bff4f775b79a55493b6e02215a0 Mon Sep 17 00:00:00 2001 From: Jonathan Hurter Date: Wed, 5 Apr 2017 16:00:48 +0200 Subject: Add doc --- README.md | 2 ++ docs/Running-Mastodon/Scalingo-guide.md | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 docs/Running-Mastodon/Scalingo-guide.md diff --git a/README.md b/README.md index fde4df6bb..db60b66f7 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,8 @@ Docker is great for quickly trying out software, but it has its drawbacks too. I [![Deploy on Scalingo](https://cdn.scalingo.com/deploy/button.svg)](https://my.scalingo.com/deploy?source=https://github.com/tootsuite/mastodon#master) +[You can view a guide for deployment on Scalingo here.](docs/Running-Mastodon/Scalingo-guide.md) + ## Deployment on Heroku (experimental) [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) diff --git a/docs/Running-Mastodon/Scalingo-guide.md b/docs/Running-Mastodon/Scalingo-guide.md new file mode 100644 index 000000000..6552056a8 --- /dev/null +++ b/docs/Running-Mastodon/Scalingo-guide.md @@ -0,0 +1,13 @@ +Scalingo guide +============== + +[![Deploy on Scalingo](https://cdn.scalingo.com/deploy/button.svg)](https://my.scalingo.com/deploy?source=https://github.com/tootsuite/mastodon#master) + +1. Click the above button. +2. Fill in the options requested. + * You can use a .scalingo.io domain, which will be simple to set up, or you can use a custom domain. + * You will want Amazon S3 for file storage. The only exception is for development purposes, where you may not care if files are not saved. Follow a guide online for creating a free Amazon S3 bucket and Access Key, then enter the details. + * If you want your Mastodon to be able to send emails, configure SMTP settings here (or later). Consider using [Mailgun](https://mailgun.com) or similar, who offer free plans that should suit your interests. +3. Deploy! The app should be set up, with a working web interface and database. You can change settings and manage versions from the Heroku dashboard. + +You may need to use the `scalingo` CLI application to run `USERNAME=yourUsername rails mastodon:make_admin` to make yourself an admin. -- cgit From 1b8c244dff84ae981d89a1672a9db06f08cf405e Mon Sep 17 00:00:00 2001 From: Eugen Date: Wed, 5 Apr 2017 18:48:41 +0200 Subject: Add proper message to PushUpdateWorker, use redis directly --- app/workers/push_update_worker.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb index fef75d909..9d16c20bf 100644 --- a/app/workers/push_update_worker.rb +++ b/app/workers/push_update_worker.rb @@ -5,7 +5,8 @@ class PushUpdateWorker def perform(timeline, account_id, status_id) account = Account.find(account_id) - status = Status.find(status_id) + status = Status.find(status_id) + message = Rabl::Renderer.new( 'api/v1/statuses/show', status, @@ -14,6 +15,8 @@ class PushUpdateWorker scope: InlineRablScope.new(account) ) - ActionCable.server.broadcast("timeline:#{account_id}", type: 'update', timeline: timeline, message: message.render) + Redis.current.publish("timeline:#{timeline_id}", Oj.dump({ event: :update, payload: message, queued_at: (Time.now.to_f * 1000.0).to_i })) + rescue ActiveRecord::RecordNotFound + true end end -- cgit From c9ebd5d19fccaabd1192f5e61537251c2c2d782e Mon Sep 17 00:00:00 2001 From: Eugen Date: Wed, 5 Apr 2017 18:58:32 +0200 Subject: Fix wrong variable used in publish channel --- app/workers/push_update_worker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb index 9d16c20bf..166a9b449 100644 --- a/app/workers/push_update_worker.rb +++ b/app/workers/push_update_worker.rb @@ -15,7 +15,7 @@ class PushUpdateWorker scope: InlineRablScope.new(account) ) - Redis.current.publish("timeline:#{timeline_id}", Oj.dump({ event: :update, payload: message, queued_at: (Time.now.to_f * 1000.0).to_i })) + Redis.current.publish("timeline:#{account.id}", Oj.dump({ event: :update, payload: message, queued_at: (Time.now.to_f * 1000.0).to_i })) rescue ActiveRecord::RecordNotFound true end -- cgit From 29ffe1cad3f473c7b6c0b651d065f8ed9373d37e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 5 Apr 2017 18:51:15 +0200 Subject: Make sure Rabl is using Oj --- config/initializers/rabl_init.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/initializers/rabl_init.rb b/config/initializers/rabl_init.rb index f7be0c607..132a42144 100644 --- a/config/initializers/rabl_init.rb +++ b/config/initializers/rabl_init.rb @@ -1,4 +1,5 @@ Rabl.configure do |config| + config.json_engine = Oj config.cache_all_output = false config.cache_sources = Rails.env.production? config.include_json_root = false -- cgit From 5b95be1c42ba69c9a3a79cfa990c80a5f2debfc6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 5 Apr 2017 19:45:18 +0200 Subject: Replace calls to FeedManager#inline_render and #broadcast --- app/lib/feed_manager.rb | 2 +- app/lib/inline_renderer.rb | 13 +++++++++++++ app/services/fan_out_on_write_service.rb | 10 +++++----- app/services/notify_service.rb | 2 +- app/services/remove_status_service.rb | 6 +++--- app/workers/push_update_worker.rb | 13 +++---------- 6 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 app/lib/inline_renderer.rb diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 87865bfdc..58d9fb1fc 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -34,7 +34,7 @@ class FeedManager trim(timeline_type, account.id) end - PushUpdateWorker.perform_async(timeline_type, account.id, status.id) + PushUpdateWorker.perform_async(account.id, status.id) end def trim(type, account_id) diff --git a/app/lib/inline_renderer.rb b/app/lib/inline_renderer.rb new file mode 100644 index 000000000..8e04ad1d5 --- /dev/null +++ b/app/lib/inline_renderer.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class InlineRenderer + def self.render(status, current_account, template) + Rabl::Renderer.new( + template, + status, + view_path: 'app/views', + format: :json, + scope: InlineRablScope.new(current_account) + ).render + end +end diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 106d257ba..c63fcc1fe 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -50,22 +50,22 @@ class FanOutOnWriteService < BaseService end def render_anonymous_payload(status) - @payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status) + @payload = InlineRenderer.render(status, nil, 'api/v1/statuses/show') end def deliver_to_hashtags(status) Rails.logger.debug "Delivering status #{status.id} to hashtags" status.tags.pluck(:name).each do |hashtag| - FeedManager.instance.broadcast("hashtag:#{hashtag}", event: 'update', payload: @payload) - FeedManager.instance.broadcast("hashtag:#{hashtag}:local", event: 'update', payload: @payload) if status.account.local? + Redis.current.publish("hashtag:#{hashtag}", Oj.dump(event: :update, payload: @payload)) + Redis.current.publish("hashtag:#{hashtag}:local", Oj.dump(event: :update, payload: @payload)) if status.account.local? end end def deliver_to_public(status) Rails.logger.debug "Delivering status #{status.id} to public timeline" - FeedManager.instance.broadcast(:public, event: 'update', payload: @payload) - FeedManager.instance.broadcast('public:local', event: 'update', payload: @payload) if status.account.local? + Redis.current.publish('public', Oj.dump(event: 'update', payload: @payload)) + Redis.current.publish('public:local', Oj.dump(event: 'update', payload: @payload)) if status.account.local? end end diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index 24486f220..62508a049 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -50,7 +50,7 @@ class NotifyService < BaseService def create_notification @notification.save! return unless @notification.browserable? - FeedManager.instance.broadcast(@recipient.id, event: 'notification', payload: FeedManager.instance.inline_render(@recipient, 'api/v1/notifications/show', @notification)) + Redis.current.publish(@recipient.id, Oj.dump(event: :notification, payload: InlineRenderer.render(@notification, @recipient, 'api/v1/notifications/show'))) end def send_email diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index cf1f432e4..e19fdd030 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -65,17 +65,17 @@ class RemoveStatusService < BaseService redis.zremrangebyscore(FeedManager.instance.key(type, receiver.id), status.id, status.id) end - FeedManager.instance.broadcast(receiver.id, event: 'delete', payload: status.id) + Redis.current.publish(receiver.id, Oj.dump(event: :delete, payload: status.id)) end def remove_from_hashtags(status) status.tags.each do |tag| - FeedManager.instance.broadcast("hashtag:#{tag.name}", event: 'delete', payload: status.id) + Redis.current.publish("hashtag:#{tag.name}", Oj.dump(event: :delete, payload: status.id)) end end def remove_from_public(status) - FeedManager.instance.broadcast(:public, event: 'delete', payload: status.id) + Redis.current.publish('public', Oj.dump(event: :delete, payload: status.id)) end def redis diff --git a/app/workers/push_update_worker.rb b/app/workers/push_update_worker.rb index 166a9b449..fbcdcf634 100644 --- a/app/workers/push_update_worker.rb +++ b/app/workers/push_update_worker.rb @@ -3,19 +3,12 @@ class PushUpdateWorker include Sidekiq::Worker - def perform(timeline, account_id, status_id) + def perform(account_id, status_id) account = Account.find(account_id) status = Status.find(status_id) - - message = Rabl::Renderer.new( - 'api/v1/statuses/show', - status, - view_path: 'app/views', - format: :json, - scope: InlineRablScope.new(account) - ) + message = InlineRenderer.render(status, account, 'api/v1/statuses/show') - Redis.current.publish("timeline:#{account.id}", Oj.dump({ event: :update, payload: message, queued_at: (Time.now.to_f * 1000.0).to_i })) + Redis.current.publish("timeline:#{account.id}", Oj.dump(event: :update, payload: message, queued_at: (Time.now.to_f * 1000.0).to_i)) rescue ActiveRecord::RecordNotFound true end -- cgit