diff --git a/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-header.hbs b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-header.hbs
index e65ce13500..77ea532816 100644
--- a/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-header.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-header.hbs
@@ -1,5 +1,9 @@
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
- {{{label}}}
+ {{#if forceEscape}}
+ {{label}}
+ {{else}}
+ {{{label}}}
+ {{/if}}
diff --git a/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-row.hbs b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-row.hbs
index fc0df65835..984d709151 100644
--- a/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-row.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-row.hbs
@@ -2,5 +2,11 @@
{{{template}}}
{{else}}
{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
- {{{label}}}
+
+ {{#if forceEscape}}
+ {{label}}
+ {{else}}
+ {{{label}}}
+ {{/if}}
+
{{/if}}
diff --git a/app/assets/javascripts/select-kit/templates/components/tag-drop/tag-drop-header.hbs b/app/assets/javascripts/select-kit/templates/components/tag-drop/tag-drop-header.hbs
index 7e3ea1baf4..440988e3ef 100644
--- a/app/assets/javascripts/select-kit/templates/components/tag-drop/tag-drop-header.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/tag-drop/tag-drop-header.hbs
@@ -1,5 +1,9 @@
- {{{label}}}
+ {{#if forceEscape}}
+ {{label}}
+ {{else}}
+ {{{label}}}
+ {{/if}}
{{d-icon caretIcon class="caret-icon fa-fw"}}
diff --git a/app/assets/javascripts/wizard/test/test_helper.js b/app/assets/javascripts/wizard/test/test_helper.js
index 1d2ddbdb16..0b7e04d877 100644
--- a/app/assets/javascripts/wizard/test/test_helper.js
+++ b/app/assets/javascripts/wizard/test/test_helper.js
@@ -7,6 +7,7 @@
//= require handlebars
//= require ember.debug
//= require ember-template-compiler
+//= require qunit/qunit/qunit
//= require ember-qunit
//= require ember-shim
//= require wizard-application
diff --git a/app/controllers/admin/flags_controller.rb b/app/controllers/admin/flags_controller.rb
index 63f2ffdc24..a58dbaafcc 100644
--- a/app/controllers/admin/flags_controller.rb
+++ b/app/controllers/admin/flags_controller.rb
@@ -73,6 +73,14 @@ class Admin::FlagsController < Admin::AdminController
post_action_type = PostAction.post_action_type_for_post(post.id)
+ if !post_action_type
+ render_json_error(
+ I18n.t("flags.errors.already_handled"),
+ status: 409
+ )
+ return
+ end
+
keep_post = ['silenced', 'suspended', 'keep'].include?(params[:action_on_post])
delete_post = params[:action_on_post] == "delete"
restore_post = params[:action_on_post] == "restore"
diff --git a/app/controllers/drafts_controller.rb b/app/controllers/drafts_controller.rb
index aa8840bd05..43def37185 100644
--- a/app/controllers/drafts_controller.rb
+++ b/app/controllers/drafts_controller.rb
@@ -10,36 +10,32 @@ class DraftsController < ApplicationController
user = fetch_user_from_params
+ unless user == current_user
+ raise Discourse::InvalidAccess
+ end
+
opts = {
user: user,
offset: params[:offset],
limit: params[:limit]
}
- help_key = "user_activity.no_drafts"
-
- if user == current_user
- stream = Draft.stream(opts)
- stream.each do |d|
- parsed_data = JSON.parse(d.data)
- if parsed_data
- if parsed_data['reply']
- d.raw = parsed_data['reply']
- end
- if parsed_data['categoryId'].present? && !d.category_id.present?
- d.category_id = parsed_data['categoryId']
- end
+ stream = Draft.stream(opts)
+ stream.each do |d|
+ parsed_data = JSON.parse(d.data)
+ if parsed_data
+ if parsed_data['reply']
+ d.raw = parsed_data['reply']
+ end
+ if parsed_data['categoryId'].present? && !d.category_id.present?
+ d.category_id = parsed_data['categoryId']
end
end
-
- help_key += ".self"
- else
- help_key += ".others"
end
render json: {
drafts: stream ? serialize_data(stream, DraftSerializer) : [],
- no_results_help: I18n.t(help_key)
+ no_results_help: I18n.t("user_activity.no_drafts.self")
}
end
diff --git a/app/controllers/metadata_controller.rb b/app/controllers/metadata_controller.rb
index 2305936dc6..1374eb57e2 100644
--- a/app/controllers/metadata_controller.rb
+++ b/app/controllers/metadata_controller.rb
@@ -27,8 +27,8 @@ class MetadataController < ApplicationController
display: display,
orientation: 'any',
start_url: Discourse.base_uri.present? ? "#{Discourse.base_uri}/" : '.',
- background_color: "##{ColorScheme.hex_for_name('secondary')}",
- theme_color: "##{ColorScheme.hex_for_name('header_background')}",
+ background_color: "##{ColorScheme.hex_for_name('secondary', view_context.scheme_id)}",
+ theme_color: "##{ColorScheme.hex_for_name('header_background', view_context.scheme_id)}",
icons: [
{
src: logo,
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index 092c6a4dc9..922e4767e3 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -72,7 +72,7 @@ class UploadsController < ApplicationController
content_type: MiniMime.lookup_by_filename(upload.original_filename)&.content_type,
}
opts[:disposition] = "inline" if params[:inline]
- opts[:disposition] ||= "attachment" unless FileHelper.is_image?(upload.original_filename)
+ opts[:disposition] ||= "attachment" unless FileHelper.is_supported_image?(upload.original_filename)
send_file(Discourse.store.path_for(upload), opts)
else
render_404
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 6ad17dfbce..2f6a1456c3 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -362,6 +362,12 @@ module ApplicationHelper
end
end
+ def scheme_id
+ return if theme_ids.blank?
+ theme = Theme.find_by(id: theme_ids.first)
+ theme&.color_scheme_id
+ end
+
def current_homepage
current_user&.user_option&.homepage || SiteSetting.anonymous_homepage
end
diff --git a/app/jobs/regular/crawl_topic_link.rb b/app/jobs/regular/crawl_topic_link.rb
index 15c0c01ad0..54abf0a110 100644
--- a/app/jobs/regular/crawl_topic_link.rb
+++ b/app/jobs/regular/crawl_topic_link.rb
@@ -26,7 +26,7 @@ module Jobs
# Special case: Images
# If the link is to an image, put the filename as the title
- if FileHelper.is_image?(topic_link.url)
+ if FileHelper.is_supported_image?(topic_link.url)
uri = URI(topic_link.url)
filename = File.basename(uri.path)
crawled = (TopicLink.where(id: topic_link.id).update_all(["title = ?, crawled_at = CURRENT_TIMESTAMP", filename]) == 1)
diff --git a/app/models/admin_dashboard_next_general_data.rb b/app/models/admin_dashboard_next_general_data.rb
index 5cff33db70..f2137c4712 100644
--- a/app/models/admin_dashboard_next_general_data.rb
+++ b/app/models/admin_dashboard_next_general_data.rb
@@ -1,14 +1,6 @@
class AdminDashboardNextGeneralData < AdminDashboardNextData
- def reports
- @reports ||= %w{
- users_by_type
- users_by_trust_level
- }
- end
-
def get_json
{
- reports: self.class.reports(reports).compact,
updated_at: Time.zone.now.as_json
}
end
diff --git a/app/models/color_scheme.rb b/app/models/color_scheme.rb
index 9a47a14952..434765bef0 100644
--- a/app/models/color_scheme.rb
+++ b/app/models/color_scheme.rb
@@ -186,14 +186,16 @@ class ColorScheme < ActiveRecord::Base
new_color_scheme
end
- def self.lookup_hex_for_name(name)
- enabled_color_scheme = Theme.where(id: SiteSetting.default_theme_id).first&.color_scheme
+ def self.lookup_hex_for_name(name, scheme_id = nil)
+ enabled_color_scheme = find_by(id: scheme_id) if scheme_id
+ enabled_color_scheme ||= Theme.where(id: SiteSetting.default_theme_id).first&.color_scheme
(enabled_color_scheme || base).colors.find { |c| c.name == name }.try(:hex) || "nil"
end
- def self.hex_for_name(name)
- hex_cache[name] ||= lookup_hex_for_name(name)
- hex_cache[name] == "nil" ? nil : hex_cache[name]
+ def self.hex_for_name(name, scheme_id = nil)
+ cache_key = scheme_id ? name + "_#{scheme_id}" : name
+ hex_cache[cache_key] ||= lookup_hex_for_name(name, scheme_id)
+ hex_cache[cache_key] == "nil" ? nil : hex_cache[cache_key]
end
def colors=(arr)
diff --git a/app/models/post_action.rb b/app/models/post_action.rb
index b20d0650c4..67043291ca 100644
--- a/app/models/post_action.rb
+++ b/app/models/post_action.rb
@@ -633,7 +633,7 @@ class PostAction < ActiveRecord::Base
def self.post_action_type_for_post(post_id)
post_action = PostAction.find_by(deferred_at: nil, post_id: post_id, post_action_type_id: PostActionType.notify_flag_types.values, deleted_at: nil)
- PostActionType.types[post_action.post_action_type_id]
+ PostActionType.types[post_action.post_action_type_id] if post_action
end
def self.target_moderators
diff --git a/app/models/report.rb b/app/models/report.rb
index dd36975790..8ca5bf8fd8 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -176,6 +176,13 @@ class Report
report.error = :timeout
end
rescue Exception => e
+ # ensures that if anything unexpected prevents us from
+ # creating a report object we fail elegantly and log an error
+ if !report
+ Rails.logger.error("Couldn’t create report `#{type}`: <#{e.class} #{e.message}>")
+ return nil
+ end
+
report.error = :exception
# given reports can be added by plugins we don’t want dashboard failures
diff --git a/app/models/stylesheet_cache.rb b/app/models/stylesheet_cache.rb
index 52f6ef337e..b25fc51fa2 100644
--- a/app/models/stylesheet_cache.rb
+++ b/app/models/stylesheet_cache.rb
@@ -3,7 +3,8 @@ class StylesheetCache < ActiveRecord::Base
MAX_TO_KEEP = 50
- def self.add(target, digest, content, source_map)
+ def self.add(target, digest, content, source_map, max_to_keep: nil)
+ max_to_keep ||= MAX_TO_KEEP
old_logger = ActiveRecord::Base.logger
return false if where(target: target, digest: digest).exists?
@@ -15,16 +16,19 @@ class StylesheetCache < ActiveRecord::Base
success = create(target: target, digest: digest, content: content, source_map: source_map)
count = StylesheetCache.count
- if count > MAX_TO_KEEP
+ if count > max_to_keep
remove_lower = StylesheetCache
.where(target: target)
- .limit(MAX_TO_KEEP)
+ .limit(max_to_keep)
.order('id desc')
.pluck(:id)
.last
- DB.exec("DELETE FROM stylesheet_cache where id < :id", id: remove_lower)
+ DB.exec(<<~SQL, id: remove_lower, target: target)
+ DELETE FROM stylesheet_cache
+ WHERE id < :id AND target = :target
+ SQL
end
success
diff --git a/app/models/theme.rb b/app/models/theme.rb
index 71a4f793d5..467cc060fe 100644
--- a/app/models/theme.rb
+++ b/app/models/theme.rb
@@ -51,6 +51,7 @@ class Theme < ActiveRecord::Base
remove_from_cache!
clear_cached_settings!
+ ColorScheme.hex_cache.clear
end
after_destroy do
@@ -72,6 +73,7 @@ class Theme < ActiveRecord::Base
end
Theme.expire_site_cache!
+ ColorScheme.hex_cache.clear
end
after_commit ->(theme) do
diff --git a/app/models/upload.rb b/app/models/upload.rb
index 140922862e..947481cb2f 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -112,7 +112,7 @@ class Upload < ActiveRecord::Base
end
def fix_dimensions!
- return if !FileHelper.is_image?("image.#{extension}")
+ return if !FileHelper.is_supported_image?("image.#{extension}")
path =
if local?
@@ -219,7 +219,7 @@ class Upload < ActiveRecord::Base
upload.sha1 = Upload.generate_digest(path)
end
# optimize if image
- FileHelper.optimize_image!(path) if FileHelper.is_image?(File.basename(path))
+ FileHelper.optimize_image!(path) if FileHelper.is_supported_image?(File.basename(path))
# store to new location & update the filesize
File.open(path) do |f|
upload.url = Discourse.store.store_upload(f, upload)
diff --git a/app/services/search_indexer.rb b/app/services/search_indexer.rb
index 04dc32b697..f76b9037e8 100644
--- a/app/services/search_indexer.rb
+++ b/app/services/search_indexer.rb
@@ -167,6 +167,8 @@ class SearchIndexer
class HtmlScrubber < Nokogiri::XML::SAX::Document
+ DIACRITICS ||= /([\u0300-\u036f]|[\u1AB0-\u1AFF]|[\u1DC0-\u1DFF]|[\u20D0-\u20FF])/
+
def self.strip_diacritics(str)
s = str.unicode_normalize(:nfkd)
s.gsub!(DIACRITICS, "")
@@ -196,12 +198,12 @@ class SearchIndexer
attributes = Hash[*attributes.flatten]
ATTRIBUTES.each do |name|
- characters(attributes[name]) if attributes[name].present?
+ if attributes[name].present?
+ characters(attributes[name]) unless name == "href" && UrlHelper.is_local(attributes[name])
+ end
end
end
- DIACRITICS ||= /([\u0300-\u036f]|[\u1AB0-\u1AFF]|[\u1DC0-\u1DFF]|[\u20D0-\u20FF])/
-
def characters(str)
str = HtmlScrubber.strip_diacritics(str) if @strip_diacritics
scrubbed << " #{str} "
diff --git a/app/views/layouts/_head.html.erb b/app/views/layouts/_head.html.erb
index ee36992e6c..8edde92a2b 100644
--- a/app/views/layouts/_head.html.erb
+++ b/app/views/layouts/_head.html.erb
@@ -9,7 +9,7 @@
<%- if (SiteSetting.apple_touch_icon_url != "/images/default-apple-touch-icon.png") && SiteSetting.apple_touch_icon_url.present? %>
<%- end %>
-
+
<% if mobile_view? %>
<% else %>
diff --git a/app/views/qunit/index.html.erb b/app/views/qunit/index.html.erb
index 1ada1ae163..0515dfc0d6 100644
--- a/app/views/qunit/index.html.erb
+++ b/app/views/qunit/index.html.erb
@@ -2,9 +2,7 @@
QUnit Test Runner
- <%= stylesheet_link_tag "qunit" %>
<%= stylesheet_link_tag "test_helper" %>
- <%= javascript_include_tag "qunit" %>
<%= javascript_include_tag "test_helper" %>
<%= csrf_meta_tags %>
diff --git a/app/views/wizard/qunit.html.erb b/app/views/wizard/qunit.html.erb
index 31755ff4d8..02c510ae8c 100644
--- a/app/views/wizard/qunit.html.erb
+++ b/app/views/wizard/qunit.html.erb
@@ -2,10 +2,8 @@
QUnit Test Runner
- <%= stylesheet_link_tag "qunit" %>
<%= stylesheet_link_tag "test_helper" %>
<%= discourse_stylesheet_link_tag :wizard, theme_ids: nil %>
- <%= javascript_include_tag "qunit" %>
<%= javascript_include_tag "wizard/test/test_helper" %>
<%= csrf_meta_tags %>
diff --git a/config/locales/client.ar.yml b/config/locales/client.ar.yml
index ee39319494..aea80facd5 100644
--- a/config/locales/client.ar.yml
+++ b/config/locales/client.ar.yml
@@ -543,7 +543,7 @@ ar:
categories:
all: "كل الأقسام"
no_subcategory: "لا شيء"
- category: "قسم"
+ category: "تصنيف"
category_list: "أعرض قائمة الأقسام"
reorder:
title: "إعادة ترتيب الأقسام"
@@ -613,6 +613,7 @@ ar:
notifications: "الإشعارات"
statistics: "الأحصائيات"
desktop_notifications:
+ label: "الإشعارات الحية"
not_supported: "نأسف، لا يدعم المتصفّح الإشعارات."
perm_default: "فعّل الإشعارات"
perm_denied_btn: "رُفض التّصريح"
@@ -824,7 +825,7 @@ ar:
email_private_messages: "أرسل إلي رسالة إلكترونية عندما يبعث أحدهم رسالة إلي"
email_always: "أرسل إلي الاشعارات عبر البريد حتى ولو كنت متّصلًا"
other_settings: "أخرى"
- categories_settings: "الأقسام"
+ categories_settings: "التصنيفات"
new_topic_duration:
label: "اعتبر الموضوعات جديدة لو"
not_viewed: "لم أطالعها بعد"
@@ -952,6 +953,7 @@ ar:
most_liked_users: "أكثر من أعجبه"
most_replied_to_users: "أكثر من رد عليه"
no_likes: "لا يوجد إعجابات بعد."
+ top_categories: "أفضل التصنيفات"
ip_address:
title: "عنوان IP الأخير"
registration_ip_address:
@@ -1733,7 +1735,7 @@ ar:
title: 'دعوة'
username_placeholder: "اسم المستخدم"
action: 'أرسل دعوة'
- help: 'ادعُ الغير إلى هذا الموضوع عبر البريد الإلكترونيّ أو الإشعارات'
+ help: 'دعوة الآخرين إلى هذا الموضوع عبر البريد الإلكتروني أو الإشعارات'
to_forum: "سنُرسل بريد إلكترني يتيح لصديقك الانضمام مباشرةً بنقر رابط فيه، تسجيل الدخول غير مطلوب."
sso_enabled: "أدخل اسم مَن تريد دعوته إلى هذا الموضوع."
to_topic_blank: "أدخل اسم او عنوان بريد الشخص الذي تريد دعوته إلى هذا الموضوع."
@@ -1885,7 +1887,7 @@ ar:
attachment_download_requires_login: "عذرا، عليك تسجيل الدخول لتحميل المرفقات."
abandon:
confirm: "أمتأكد من التخلي عن المنشور؟"
- no_value: "لا، أبقها"
+ no_value: "لا، أبقه"
yes_value: "نعم، لا أريده"
via_email: "وصل هذا المنشور عبر البريد"
via_auto_generated_email: "وصل هذا المنشور عبر بريد مولّد آلياً"
@@ -2087,7 +2089,7 @@ ar:
all: 'كل الأقسام'
edit: 'تعديل'
edit_long: "تعديل"
- view: 'أظهار الموضوعات في القسم'
+ view: 'أظهار المواضيع في القسم'
general: 'عام'
settings: 'اعدادات'
topic_template: "إطار الموضوع"
@@ -2097,9 +2099,9 @@ ar:
tags_placeholder: "(اختياري) قائمة الأوسمة المسموح بها"
tag_groups_placeholder: "(اختياريّ) قائمة مجموعات الأوسمة المسموح بها"
topic_featured_link_allowed: "اسمح بالروابط المُميزة بهذا القسم."
- delete: 'احذف القسم'
- create: 'قسم جديد'
- create_long: 'أنشئ قسم جديد'
+ delete: 'احذف التصنيف'
+ create: 'تصنيف جديد'
+ create_long: 'أنشئ تصنيف جديد'
save: 'احفظ القسم'
slug: 'عنوان القسم في الURL'
slug_placeholder: '(اختياريّ) كلمات مفصولة-بشرطة للعنوان'
@@ -2115,8 +2117,8 @@ ar:
foreground_color: "لون المقدمة"
name_placeholder: "كلمة أو كلمتين على الأكثر"
color_placeholder: "أيّ لون متوافق مع الانترنت"
- delete_confirm: "هل تريد فعلاً حذف هذا القسم؟"
- delete_error: "حدث خطأ في حذف القسم."
+ delete_confirm: "هل تريد فعلاً حذف هذا تصنيف؟"
+ delete_error: "حدث خطأ أثناء حذف هذا التصنيف"
list: "عرض الأقسام"
no_description: "من فضلك أضف وصفا لهذا القسم."
change_in_category_topic: "عدّل الوصف"
diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml
index f1047c0452..f7754f1174 100644
--- a/config/locales/client.de.yml
+++ b/config/locales/client.de.yml
@@ -162,6 +162,7 @@ de:
ap_southeast_1: "Asien-Pazifik (Singapur)"
ap_southeast_2: "Asien-Pazifik (Sydney)"
cn_north_1: "China (Peking)"
+ cn_northwest_1: "China (Ningxia)"
eu_central_1: "EU (Frankfurt)"
eu_west_1: "EU (Irland)"
eu_west_2: "EU (London)"
@@ -520,7 +521,7 @@ de:
topic_stat_sentence:
one: "%{count} neues Thema seit 1 %{unit}."
other: "%{count} neue Themen seit 1 %{unit}."
- more: "(%{count}mehr) …"
+ more: " (%{count} weitere) …"
ip_lookup:
title: IP-Adressen-Abfrage
hostname: Hostname
diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml
index 287961cc3b..834bd3a396 100644
--- a/config/locales/client.fi.yml
+++ b/config/locales/client.fi.yml
@@ -162,6 +162,7 @@ fi:
ap_southeast_1: "Aasia ja Tyynimeri (Singapore)"
ap_southeast_2: "Aasia ja Tyynimeri (Sydney)"
cn_north_1: "Kiina (Peking)"
+ cn_northwest_1: "Kiina (Ningxia)"
eu_central_1: "EU (Frankfurt)"
eu_west_1: "EU (Irlanti)"
eu_west_2: "EU (Lontoo)"
@@ -196,6 +197,7 @@ fi:
privacy_policy: "Tietosuojaseloste"
privacy: "Tietosuoja"
tos: "Käyttöehdot"
+ rules: "Säännöt"
mobile_view: "Mobiilinäkymä"
desktop_view: "Työpöytänäkymä"
you: "Sinä"
@@ -536,6 +538,7 @@ fi:
post_count: "# viestiä"
confirm_delete_other_accounts: "Oletko varma, että haluat poistaa nämä tunnukset?"
powered_by: "voimanlähteenä 1ipinfo.io"
+ copied: "kopioitu"
user_fields:
none: "(valitse vaihtoehto)"
user:
@@ -639,6 +642,7 @@ fi:
revoke_access: "Peru käyttöoikeus"
undo_revoke_access: "Peru käyttöoikeuden peruminen"
api_approved: "Sallittu:"
+ api_last_used_at: "Viimeksi käytetty:"
theme: "Teema"
home: "Oletusnäkymä"
staged: "Esikäyttäjä"
@@ -777,6 +781,18 @@ fi:
any: "mikä tahansa"
password_confirmation:
title: "Salasana uudelleen"
+ auth_tokens:
+ title: "Viimeksi käytetyt laitteet"
+ title_logs: "Todennusloki"
+ ip_address: "IP-osoite"
+ created: "Luotu"
+ first_seen: "Ensimmäinen vierailu"
+ last_seen: "Viimeisin vierailu"
+ operating_system: "Käyttöjärjestelmä"
+ location: "Paikka"
+ action: "Toimi"
+ login: "Kirjaudu sisään"
+ logout: "Kirjaudu ulos kaikkialta"
last_posted: "Viimeisin viesti"
last_emailed: "Viimeksi lähetetty sähköpostitse"
last_seen: "Nähty"
@@ -1008,6 +1024,8 @@ fi:
hide_session: "Muistuta huomenna"
hide_forever: "ei kiitos"
hidden_for_session: "OK, kysyn huomenna uudestaan. Voit aina myös käyttää 'Kirjaudu sisään' -linkkiä luodaksesi tilin."
+ intro: "Hei! Vaikuttaa siltä, että olet pitänyt keskusteluista, muttet ole luonut käyttäjätiliä."
+ value_prop: "Kun luot tilin, muistamme mitä olet lukenut, jotta voit aina palata keskusteluissa takaisin oikeaan kohtaan. Saat myös ilmoituksia - palstalla näkyviä ja sähköpostiisi saapuvia - kun joku vastaa sinulle. Ja voit myös tykätä viesteistä. :heartbeat:"
summary:
enabled_description: "Tarkastelet tiivistelmää tästä ketjusta, sen mielenkiintoisimpia viestejä käyttäjien toiminnan perusteella."
description: "Vastauksia on {{replyCount}} kpl."
@@ -1021,6 +1039,8 @@ fi:
disable: "Näytä poistetut viestit"
private_message_info:
title: "Viesti"
+ invite: "Kutsu muita..."
+ edit: "Lisää tai poista..."
leave_message: "Haluatko varmasti poistua yksityiskeskustelusta?"
remove_allowed_user: "Haluatko varmasti poistaa käyttäjän {{name}} tästä keskustelusta?"
remove_allowed_group: "Haluatko varmasti poistaa käyttäjän {{name}} tästä viestiketjusta?"
@@ -1156,6 +1176,7 @@ fi:
default_header_text: Valitse...
no_content: Ei osumia
filter_placeholder: Hae...
+ filter_placeholder_with_any: Etsi tai luo...
create: "Luo: '{{content}}'"
max_content_reached:
one: "Voit valita vain {{count}} kohteen."
@@ -1305,6 +1326,9 @@ fi:
shared_draft:
label: "Jaettu luonnos"
desc: "Luonnostele ketju, joka näkyy vain henkilökunnalle"
+ toggle_topic_bump:
+ label: "Ketjun nosto päälle/pois"
+ desc: "Vastaa muuttamatta ketjun päiväysleimaa"
notifications:
tooltip:
regular:
@@ -1609,7 +1633,7 @@ fi:
auto_close: "Ketju suljetaan ajastetusti %{timeLeft}."
auto_publish_to_category: "Ketju julkaistaan alueella #%{categoryName} %{timeLeft}."
auto_close_based_on_last_post: "Ketju sulkeutuu %{duration} kuluttua viimeisimmästä viestistä."
- auto_delete: "Ketju poistetaan ajastetusti %{timeLeft} kuluttua."
+ auto_delete: "Ketju poistetaan ajastetusti %{timeLeft}."
auto_reminder: "Sinua muistutetaan tästä ketjusta %{timeLeft}."
auto_close_title: 'Automaattisen sulkemisen asetukset'
auto_close_immediate:
@@ -1692,6 +1716,7 @@ fi:
reset_read: "Poista tieto lukemisista"
make_public: "Tee ketjusta julkinen"
make_private: "Muuta yksityiskeskusteluksi"
+ reset_bump_date: "Palauta ketjun päiväysleima"
feature:
pin: "Kiinnitä ketju"
unpin: "Poista ketjun kiinnitys"
@@ -2569,6 +2594,7 @@ fi:
disabled: Pois käytöstä
timeout_error: Kyselyssä kestää liian kauan. Valitse lyhyempi ajanjakso.
exception_error: "Pahoittelut, kyselyä tehtäessä tapahtui virhe"
+ too_many_requests: Olet tehnyt näin liian monta kertaa. Odota ennen kuin yrität uudelleen.
reports:
trend_title: "%{percent} muutos. Nyt %{current}, viime jaksossa %{prev}."
today: "Tänään"
@@ -2935,9 +2961,16 @@ fi:
revert: "Peru muutokset"
revert_confirm: "Haluatko varmasti peruuttaa muutokset?"
theme:
+ theme: "Teema"
+ component: "Osa"
+ components: "Osat"
import_theme: "Tuo teema"
customize_desc: "Mukauta:"
title: "Teemat"
+ modal_title: "Luo teema"
+ create: "Luo"
+ create_type: "Tyyppi:"
+ create_name: "Nimi:"
long_title: "Muuta sivustosi värejä, CSS:ää ja HTML-sisältöä"
edit: "Muokkaa"
edit_confirm: "Tämä on ulkoinen teema. Jos muokkaat CSS:ää tai HTML:ää, muutokset kumoutuvat kun päivität teeman."
@@ -2952,6 +2985,10 @@ fi:
color_scheme_select: "Valitse teemalle värit"
custom_sections: "Mukautetut osiot:"
theme_components: "Teeman osat"
+ switch_component: "Muuta teemaksi"
+ switch_component_alert: "Oletko varma että haluat muuttaa teeman osan teemaksi. Siitä tulee itsenäinen teema ja se ei ole enää tytärteema millekään teemalle."
+ switch_theme: "Muuta teeman osaksi"
+ switch_theme_alert: "Oletko varma, että haluat muuttaa teeman teeman osaksi? Tällöin se ei ole enää emoteema millekään teeman osalle."
uploads: "Lataukset"
no_uploads: "Voit ladata teemaasi liitteitä kuten fontteja ja kuvia"
add_upload: "Lisää tiedosto"
@@ -2974,6 +3011,7 @@ fi:
public_key: "Anna repositorioon pääsy seuraavalle julkiselle avaimelle:"
about_theme: "Tietoa teemasta"
license: "Lisenssi"
+ component_of: "Teemojen osa:"
update_to_latest: "Päivitä tuoreimpaan"
check_for_updates: "Hae päivityksiä"
updating: "Päivitetään..."
@@ -2981,9 +3019,11 @@ fi:
add: "Lisää"
theme_settings: "Teeman asetukset"
no_settings: "Teemalla ei ole asetuksia."
+ empty: "Ei mitään"
commits_behind:
one: "Teema on yhden muutoksen perässä!"
other: "Teema on {{count}} muutosta perässä!"
+ compare_commits: "(Näytä uudet muutokset)"
scss:
text: "CSS"
title: "Lisää mukautettua CSS:ää, hyväksymme käyvät CSS- ja SCSS-tyylit"
diff --git a/config/locales/client.pl_PL.yml b/config/locales/client.pl_PL.yml
index bd231ab53b..81fecab50b 100644
--- a/config/locales/client.pl_PL.yml
+++ b/config/locales/client.pl_PL.yml
@@ -1044,6 +1044,8 @@ pl_PL:
hide_session: "Przypomnij mi jutro"
hide_forever: "nie, dziękuję"
hidden_for_session: "Ok, zapytamy jutro. Pamiętaj, że konto możesz w każdej chwili założyć klikając na 'Logowanie'."
+ intro: "Hej! Wygląda na to, że zainteresowała Cię ta dyskusja, ale nie posiadasz jeszcze konta."
+ value_prop: "Jeśli założysz konto, będziemy pamiętać dokładnie to, co przeczytałeś, więc zawsze wrócisz tam, gdzie ostatnio opuściłeś temat. Otrzymasz również powiadomienia, tutaj i za pośrednictwem poczty email, gdy ktoś Ci odpowie. Możesz również polubić posty, aby dzielić się miłością. :heartpulse:"
summary:
enabled_description: "Przeglądasz podsumowanie tego tematu: widoczne są jedynie najbardziej wartościowe wpisy zdaniem uczestników. "
description: "Jest {{replyCount}} odpowiedzi."
diff --git a/config/locales/client.pt_BR.yml b/config/locales/client.pt_BR.yml
index b4abe691d0..0d2b4aee44 100644
--- a/config/locales/client.pt_BR.yml
+++ b/config/locales/client.pt_BR.yml
@@ -256,14 +256,14 @@ pt_BR:
new_private_message: "Novo rascunho de mensagem privada"
topic_reply: "Resposta preliminar"
topic_count_latest:
- one: "Veja {{conta}} tópicos novos ou atualizados"
- other: "Veja {{conta}} tópicos novos ou atualizados"
+ one: "Veja {{count}} tópicos novos ou atualizados"
+ other: "Veja {{count}} tópicos novos ou atualizados"
topic_count_unread:
- one: "Veja {{conta}} tópicos não lidos."
- other: "Veja {{conta}} tópicos não lidos."
+ one: "Veja {{count}} tópicos não lidos."
+ other: "Veja {{count}} tópicos não lidos."
topic_count_new:
- one: "Veja {{conta}} novos tópicos."
- other: "Veja {{conta}} novos tópicos."
+ one: "Veja {{count}} novos tópicos."
+ other: "Veja {{count}} novos tópicos."
preview: "pré-visualização"
cancel: "cancelar"
save: "Salvar mudanças"
diff --git a/config/locales/server.ar.yml b/config/locales/server.ar.yml
index 134473c7cf..0d4ac1510d 100644
--- a/config/locales/server.ar.yml
+++ b/config/locales/server.ar.yml
@@ -1044,8 +1044,6 @@ ar:
s3_cdn_url: "URL لـCDN يستخدم لكل أصول s3 (مثال: https://cdn.somewhere.com). تحذير : بعد تغيير هذا الإعداد يجب عمل rebake لكل المشاركات القديمة."
avatar_sizes: "قائمة أحجام الرمزية إنشاؤه تلقائيا."
external_system_avatars_enabled: "استخدم خدمات الهه النظام الخارجي "
- default_opengraph_image_url: "عنوان رابط صورة ال اوبن جراف الثابتة"
- twitter_summary_large_image_url: "عنوان الURL للصورة الافتراضية لكارت الملخص علي تويتر ( يجب ان تكون علي الاقل بعرض 280 بكسل و ارتفاع 150 بكسل )"
allow_all_attachments_for_group_messages: "اسمح بجميع ملحقات البريد للرسائل الجماعيه "
enable_flash_video_onebox: "فعّل تضمين روابط swf وflv (أدوبي فلاش) في لوحات المعاينة. تحذير: قد يتسبّب بمخاطر أمنيّة."
default_invitee_trust_level: "مستوى الثقة الإفتراضي (0-4) للأعضاء المدعوين."
@@ -1194,7 +1192,6 @@ ar:
slug_generation_method: "اختر طريقه توليد سبيكه . 'مشفره' سوف تقوم بتوليد سلسله مئويه مشفره.'لاشي' سوف يعطل السبيكه"
enable_emoji: "فعّل الإيموجي"
emoji_set: "كيف تريد أن تبدو الإيموجي؟"
- enforce_square_emoji: "أجبِر النّسبة الباعيّة لكلّ الإيموجي لتكون مربّعة."
approve_post_count: "عدد المنشورات للمستخدم الجديد او الاساسي يجب ان تتم الموافقه عليه "
approve_unless_trust_level: "مشاركات للأعضاء أدنى من مستوى الثقة هذا يجب أن تتم الموافقة عليها."
default_email_direct: "ارسل بريد الكتروني عندما يقوم احدهم بالرد/الاقتباس الي/ذكر او دعوه مستخدم افتراضيا"
diff --git a/config/locales/server.bg.yml b/config/locales/server.bg.yml
index 188ca7a851..136a24f24e 100644
--- a/config/locales/server.bg.yml
+++ b/config/locales/server.bg.yml
@@ -837,7 +837,6 @@ bg:
slug_generation_method: "Изберете метод за генериране на URL. 'кодирано' ще използва букви URL, кодирани с проценти. 'не' ще откаже генерацията като цяло."
enable_emoji: "Разреши емотикони"
emoji_set: "Как бихте искали да е вашата емотикона?"
- enforce_square_emoji: "Направи квадратни всички емотикони."
approve_unless_trust_level: "Постовете на потребители с по-ниско от това ниво на доверие трябва да бъдат одобрени"
default_email_direct: "Изпращай имейл по подразбиране, когато някой цитира, отговаря на публикацията или споменава името на потребителя."
default_email_mailing_list_mode: "Изпращай ми имейл по подразбиране за всяка нова публикация."
diff --git a/config/locales/server.ca.yml b/config/locales/server.ca.yml
index b7c4aaadbd..4f13297583 100644
--- a/config/locales/server.ca.yml
+++ b/config/locales/server.ca.yml
@@ -926,8 +926,6 @@ ca:
avatar_sizes: "Llista de mides d'avatar generades automàticament."
external_system_avatars_enabled: "Fes servir un servei extern de sistema d'avatars."
external_system_avatars_url: "Adreça URL del sitema extern de servei d'avatars. Les substitucions permeses són {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "Adreça URL del protocol opengraph d'imatge per defecte."
- twitter_summary_large_image_url: "Adreça URL del resum de la targeta d'imatge per defecte de Twitter (hauria de fer almenys 280px d'amplada i com a míimim 150px d'alçada)."
allow_all_attachments_for_group_messages: "Permet tots els adjunts de correu per a missatges de grup."
enable_flash_video_onebox: "Habilita la incrustació d'enllaços swf i flv (Adobe Flash) emmarcats. ATENCIÓ: això pot comportar riscos de seguretat."
default_invitee_trust_level: "Nivell de confiança per defecte (0-4) per a persones convidades."
@@ -1119,7 +1117,6 @@ ca:
slug_generation_method: "Tria un mètode de generació d'adreces amigables. 'encoded' generarà un percentatge de codificació. 'none' anul·larà totalment l'adreça amigable."
enable_emoji: "Activa emojo"
emoji_set: "Com t'agradaria el teu emoji?"
- enforce_square_emoji: "Força una relació d'aspecte quadrat per a tots els emojis."
approve_post_count: "Cal aprovar la quantitat de publicacions d'una persona usuària nova o bàsica"
approve_unless_trust_level: "Cal aprovar les publicacions per a persones usuàries amb aquest nivell de confiança"
approve_new_topics_unless_trust_level: "Cal aprovar els nous temes per a persones amb aquest nivell de confiança"
diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml
index 218cc54934..cca9301661 100644
--- a/config/locales/server.da.yml
+++ b/config/locales/server.da.yml
@@ -870,7 +870,6 @@ da:
max_flags_per_day: "Maksimalt antal flagmarkeringer per bruger per dag."
clean_orphan_uploads_grace_period_hours: "Grace-periode (i timer) før et forældreløst upload bliver fjernet."
purge_deleted_uploads_grace_period_days: "Grace-periode (i dage) før et slettet upload bliver fjernet."
- twitter_summary_large_image_url: "URL til standard Twitter Summary Card billede (skal være mindst 280px i bredden og mindst 150px i højden)."
tl1_requires_topics_entered: "Hvor mange emner en ny bruger skal læse før vedkommende forfremmes til tillidsniveau 1."
tl1_requires_read_posts: "Hvor mange indlæg en ny bruger skal læse før vedkommende forfremmes til tillidsniveau 1."
tl1_requires_time_spent_mins: "Hvor mange minutter en ny bruger skal læse indlæg før vedkommende forfremmes til tillidsniveau 1."
diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml
index 22b21031a7..887cbc2cf8 100644
--- a/config/locales/server.de.yml
+++ b/config/locales/server.de.yml
@@ -702,7 +702,6 @@ de:
others: "Keine Antworten."
no_drafts:
self: "Du hast keine Entwürfe; beginne eine Antwort in einem beliebigen Thema und es wird automatisch als neuer Entwurf gespeichert."
- others: "Du hast keine Berechtigung die Entwürfe dieses Benutzers zu sehen."
topic_flag_types:
spam:
title: 'Spam'
@@ -763,6 +762,9 @@ de:
session_info: "Informationen zur Benutzersitzung lesen"
read: "Alles lesen"
write: "Alles schreiben"
+ flags:
+ errors:
+ already_handled: "Die Meldung wurde bereits bearbeitet"
reports:
default:
labels:
@@ -1503,7 +1505,6 @@ de:
enable_emoji: "Aktiviere emoji"
enable_emoji_shortcuts: "Geläufige Text-Smileys wie :) :p :( werden in Emojis umgewandelt"
emoji_set: "Welche Emoji sollen es sein?"
- enforce_square_emoji: "Emojis immer mit quadratischem Seitenverhältnis darstellen."
emoji_autocomplete_min_chars: "Erforderliche Minimalanzahl von Zeichen, um das Popup zur Emoji-Autovervollständigung zu öffnen."
approve_post_count: "Anzahl der Beiträge eines neuen Benutzer oder Anwärters, die genehmigt werden müssen"
approve_unless_trust_level: "Beiträge von Benutzer unterhalb dieser Vertrauensstufe müssen genehmigt werden"
diff --git a/config/locales/server.el.yml b/config/locales/server.el.yml
index 4f70d032e8..259cb0e32e 100644
--- a/config/locales/server.el.yml
+++ b/config/locales/server.el.yml
@@ -1015,8 +1015,6 @@ el:
avatar_sizes: "Κατάλογος από αυτόματα δημιουργημένα μεγέθη άβαταρ."
external_system_avatars_enabled: "Χρησιμοποιήσε εξωτερική υπηρεσία για avatars."
external_system_avatars_url: "URL της εξωτερικής υπηρεσίας avatars. Επιτρεπτές αντικαταστάσεις είναι {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "Η διεύθυνση URL της προεπιλεγμένης εικόνας opengraph."
- twitter_summary_large_image_url: "Η διεύθυνση URL της εικόνας της προκαθορισμένης συνοπτικής κάρτας του Twitter (θα πρέπει να είναι τουλάχιστον 280px σε πλάτος, και τουλάχιστον 150px σε ύψος)."
allow_all_attachments_for_group_messages: "Επιτρέπονται όλοι οι τύποι συνημμένων αρχείων σε ομαδικά μηνύματα."
png_to_jpg_quality: "Ποιότητα των αποθηκευμένων αρχείων JPG (1 χαμηλή ποιότητα, 99 μέγιστη ποιότητα, 100 για απενεργοποίηση)."
allow_staff_to_upload_any_file_in_pm: "Επίτρεψε στο προσωπικό να ανεβάζει οποιοδήποτε τύπο αρχείου στα πμ"
@@ -1224,7 +1222,6 @@ el:
slug_generation_method: "Επιλέξτε μια μέθοδο παραγωγής slug. «Κωδικοποιημένη» θα δημιουργήσει μια συμβολοσειρά για ποσοστιαία κωδικοποίηση. «Κανένα» θα απενεργοποιήσει τα slug."
enable_emoji: "Ενεργοποίηση emoji"
emoji_set: "Πως θα ήθελες το emoji σου;"
- enforce_square_emoji: "Αναγκαστική εφαρμογή τετράγωνων διαστάσεων σε όλα τα emoji."
approve_post_count: "Ο όγκος των αναρτήσεων ενός καινούριου ή βασικού χρήστη που θα πρέπει να εγκριθεί."
approve_unless_trust_level: "Οι αναρτήσεις για χρήστες κάτω από αυτό το επίπεδο εμπιστοσύνης πρέπει να εγκριθούν"
approve_new_topics_unless_trust_level: "Τα καινούρια νήματα για χρήστες κάτω από αυτό το επίπεδο εμπιστοσύνης πρέπει να εγκριθούν."
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 4e2767a502..761176b97f 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -796,7 +796,6 @@ en:
others: "No replies."
no_drafts:
self: "You have no drafts; begin composing a reply in any topic and it will be auto-saved as a new draft."
- others: "You do not have permission to see drafts for this user."
topic_flag_types:
spam:
@@ -864,6 +863,9 @@ en:
read: "Read all"
write: "Write all"
+ flags:
+ errors:
+ already_handled: "Flag was already handled"
reports:
default:
labels:
@@ -1726,7 +1728,6 @@ en:
enable_emoji: "Enable emoji"
enable_emoji_shortcuts: "Common smiley text such as :) :p :( will be converted to emojis"
emoji_set: "How would you like your emoji?"
- enforce_square_emoji: "Force a square aspect ratio to all emojis."
emoji_autocomplete_min_chars: "Minimum number of characters required to trigger autocomplete emoji popup"
approve_post_count: "The amount of posts from a new or basic user that must be approved"
diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml
index d349691671..2ae7b70111 100644
--- a/config/locales/server.es.yml
+++ b/config/locales/server.es.yml
@@ -722,7 +722,6 @@ es:
others: "Sin respuestas."
no_drafts:
self: "No tienes ningún borrador; empieza a escribir una respuesta en cualquier tema y se guardará automáticamente como nuevo borrador."
- others: "No tienes permisos para ver los borradores de este usuario."
topic_flag_types:
spam:
title: 'Spam'
@@ -1522,7 +1521,6 @@ es:
enable_emoji: "Habilitar emoji"
enable_emoji_shortcuts: "Texto común de emoticones como :) :p :( serán convertidos a emojis"
emoji_set: "¿De qué tipo os gustan los emoji?"
- enforce_square_emoji: "Forzar una relación de aspecto cuadrada para todos los emojis."
emoji_autocomplete_min_chars: "Número mínimo de caracteres necesarios para que aparezca el diálogo de selección de emoji"
approve_post_count: "La cantidad de posts que deben ser aprobados de usuarios nuevos o de nivel básico"
approve_unless_trust_level: "Los posts de usuarios con un nivel de confianza inferior a este deberán ser aprobados"
diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml
index 0129ac2c7c..dabef08ef0 100644
--- a/config/locales/server.fa_IR.yml
+++ b/config/locales/server.fa_IR.yml
@@ -977,8 +977,6 @@ fa_IR:
avatar_sizes: "لیست اندازههای آواتار که به صورت خودکار تولید شده است."
external_system_avatars_enabled: "استفاده از سرویس آواتار خارجی."
external_system_avatars_url: "لینک سرویس آواتار خارجی. تغییرات مجاز {username} {first_letter} {color} {size} هستند"
- default_opengraph_image_url: "لینک تصویر پیشفرض اپنگراف"
- twitter_summary_large_image_url: "لینک پیشفرض خلاصه توییتر و تصویر (باید حداقل 280 در 150 پیکسل باشد)"
allow_all_attachments_for_group_messages: "اجازهی ضمیمه فایل در ایمیل پیامهای گروهی."
png_to_jpg_quality: "کیفیت تبدیل فایلهای JPG (1 کمترین کیفیت، 99 بالاترین کیفیت، 100 برای غیرفعال)"
allow_staff_to_upload_any_file_in_pm: "به مدیران اجازه بده که هر فایلی در پیغام خصوصی آپلود کنند."
@@ -1177,7 +1175,6 @@ fa_IR:
slug_generation_method: "یک روش ایجاد نام یکتا انتخاب کنید. 'encoded' رشتهای شامل درصد ایجاد میکند. 'none' اسم یکتا را به صورت کلی غیرفعال مینماید."
enable_emoji: "فعالسازی شکلک"
emoji_set: "میخواهید شکلک شما چطور باشد؟"
- enforce_square_emoji: "تحمیل نسبت ابعاد مربع به تمام شکلکها. "
approve_post_count: "تعداد نوشتههای کاربر جدید که باید تایید شود."
approve_unless_trust_level: "نوشتهها برای کاربران پایین تر از این سطح اعتماد نیاز به تایید دارد. "
approve_new_topics_unless_trust_level: "موضوعات جدید برای کاربرانی با کمتر از این سطح اعتماد باید تایید شود"
diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml
index 9d49627688..9c07e639d8 100644
--- a/config/locales/server.fi.yml
+++ b/config/locales/server.fi.yml
@@ -629,6 +629,17 @@ fi:
email_login:
invalid_token: "Pahoittelut, tämä sisäänkirjautumislinkki on liian vanha. Paina 'Kirjaudu sisään' nappia ja valitse 'Unohdin salasanani' saadaksesi uuden linkin."
title: "Sähköpostikirjautuminen"
+ user_auth_tokens:
+ devices:
+ android: 'Android-laite'
+ linux: 'Linux-tietokone'
+ windows: 'Windows-tietokone'
+ mac: 'Mac'
+ iphone: 'iPhone'
+ ipad: 'iPad'
+ ipod: 'iPod'
+ mobile: 'Mobiililaite'
+ unknown: 'Tuntematon laite'
change_email:
confirmed: "Sähköpostiosoite päivitetty."
please_continue: "Jatka sivustolle %{site_name}"
@@ -712,7 +723,6 @@ fi:
others: "Ei vastauksia."
no_drafts:
self: "Sinulla ei ole luonnoksia. Aloita kirjoittamaan viestiä mihin tahansa ketjuun niin se tallentuu automaattiseksi uudeksi luonnokseksi."
- others: "Et voi nähdä tämän käyttäjän luonnoksia."
topic_flag_types:
spam:
title: 'Roskaposti'
@@ -1128,6 +1138,7 @@ fi:
maximum_session_age: "Käyttäjä pysyy sisäänkirjautuneena n tuntia vierailunsa jälkeen"
ga_universal_tracking_code: "Google Universal analytics (analytics.js) seurantakoodi, esim.: UA-12345678-9; katso http://google.com/analytics"
ga_universal_domain_name: "Google Universal analytics (analytics.js) verkkotunnus, esim.: osoite.fi; katso http://google.com/analytics"
+ ga_universal_auto_link_domains: "Ota käyttöön verkkotunnusten välinen seurantapalvelu Google Universal Analytics (analytics.js). Poisvieviin näiden verkkotunnusten linkkeihin lisätään client id -tunniste. Katso lisää Googlen Cross-Domain Tracking -oppaasta."
gtm_container_id: "Google Tag Manager -säiliön ID. Esim: GTM-ABCDEF"
enable_escaped_fragments: "Käytä Googlen Ajax-sivustoille tarkoitettua API:a, jos webcrawleria ei tunnisteta. Katso https://developers.google.com/webmasters/ajax-crawling/docs/learn-more"
allow_moderators_to_create_categories: "Salli valvojien luoda uusia alueita"
@@ -1263,8 +1274,6 @@ fi:
external_system_avatars_url: "Ulkoisen avatarpalvelun URL. Sallitut vaihdokset ovat {username} {first_letter} {color} {size}"
selectable_avatars_enabled: "Pakota käyttäjä valitsemaan avatarinsa listalta."
selectable_avatars: "Avatarit, joista käyttäjä voi valita."
- default_opengraph_image_url: "Oletuksena käytettävän opengraph-kuvan URL."
- twitter_summary_large_image_url: "Oletuksena käytettävän Twitter-tiivistelmäkortin kuva (tulisi olla leveydeltään ainakin 280 px leveä ja 150 px korkea)."
allow_all_attachments_for_group_messages: "Salli kaikki sähköpostiliitteet ryhmäviesteissä."
png_to_jpg_quality: "Muunnetun JPG-tiedoston laatu (1 on huonoin laatu, 99 on paras laatu, 100 ottaa pois käytöstä)."
allow_staff_to_upload_any_file_in_pm: "Salli henkilökunnan ladata minkätyyppisiä liitteitä tahansa yksityisviesteihin."
@@ -1492,7 +1501,6 @@ fi:
slug_generation_method: "Valitse polkulyhenteen luomisen metodi. 'encoded' käyttää prosenttikoodausta, 'none' poistaa polkulyhenteet käytöstä."
enable_emoji: "Ota emoji käyttöön"
emoji_set: "Millaiset emojit haluat?"
- enforce_square_emoji: "Pakota neliö kuvasuhteeksi kaikille emojille."
approve_post_count: "Viestien lukumäärä, joka tarkastetaan uusilta käyttäjiltä ja haastajilta."
approve_unless_trust_level: "Tätä luottamustasoa alhaisempien käyttäjien viestit tarkastetaan"
approve_new_topics_unless_trust_level: "Tätä luottamustasoa alhaisempien käyttäjien aloittamat ketjut tarkastetaan"
diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml
index f0c4fccea3..f80db36eb8 100644
--- a/config/locales/server.fr.yml
+++ b/config/locales/server.fr.yml
@@ -722,7 +722,6 @@ fr:
others: "Aucune réponse."
no_drafts:
self: "Vous n'avez pas d'ébauche; commencez à répondre à un sujet et la réponse sera automatiquement sauvegardée comme nouvelle ébauche."
- others: "Vous n'avez pas la permission de consulter les ébauches de cet utilisateur."
topic_flag_types:
spam:
title: 'Spam'
@@ -1523,7 +1522,6 @@ fr:
enable_emoji: "Activer les emojis"
enable_emoji_shortcuts: "Les textes de smiley courants :) :p :( seront convertis en emojis"
emoji_set: "Comment aimeriez-vous vos emoji ?"
- enforce_square_emoji: "Forcer tous les Emojis à être carrés."
emoji_autocomplete_min_chars: "Nombre minimum de caractères nécessaires pour invoquer la fenêtre contextuelle d'emoji"
approve_post_count: "Le nombre de messages d'un utilisateur nouveau ou basique devant être approuvés"
approve_unless_trust_level: "Les messages des utilisateurs qui n'ont pas atteint ce niveau de confiance doivent être approuvés"
diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml
index 4be76b3b7d..5dc18b1662 100644
--- a/config/locales/server.he.yml
+++ b/config/locales/server.he.yml
@@ -1061,8 +1061,6 @@ he:
avatar_sizes: "רשימה של גדלי דמויות שנוצרת אוטומטית."
external_system_avatars_enabled: "שימוש בשירות של מערכת אווטארים חיצונית."
external_system_avatars_url: "כתובת של שירות דמויות חיצוני. החלפות מותרות הן {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "URL ברירת המחדל של תמונת opengraph."
- twitter_summary_large_image_url: "URL של תמונה מסיכום ברירת המחדל מטוויטר (צריכה להיות ברוחב לפחות 280 פיקסלים ובגובה של לפחות 150 פיקסלים)."
allow_all_attachments_for_group_messages: "אפשרו צירוף קבצים להודעות לקבוצות."
png_to_jpg_quality: "האיכות של קובץ JPG שמומר (1 הנמוכה ביותר, 99 הטובה ביותר, 100 לניטרול)."
allow_staff_to_upload_any_file_in_pm: "אפשרו לחברי צוות להעלות כל קובץ בהודעה פרטית."
@@ -1261,7 +1259,6 @@ he:
slug_generation_method: "בחרו צורת ייצור slug. צורה של 'encoded' תגרום למחרוזות עם קידוד אחוזים. 'none' ינטרל slug לחלוטין."
enable_emoji: "הפעלת emoji"
emoji_set: "איך אתם אוהבים את ה-emoji שלכם?"
- enforce_square_emoji: "חובת מימדים ריבועיים בכל ה-emojis."
approve_post_count: "מספר הפוסטים ממשתמשים חדשים או בסיסיים שחייבים לאשר אותם"
approve_unless_trust_level: "פוסטים של משתמשים מתחת לרמת אמון זו חייבים לעבור אישור"
approve_new_topics_unless_trust_level: "נושאים חדשים עבור משתמשים מתחת לרמת אמון זו חייבים להיות מאושרים"
diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml
index 293e36912b..f8adcce74d 100644
--- a/config/locales/server.it.yml
+++ b/config/locales/server.it.yml
@@ -1181,8 +1181,6 @@ it:
avatar_sizes: "Elenco delle dimensioni degli avatar, generate automaticamente."
external_system_avatars_enabled: "Utilizza un servizio esterno per gli avatar."
external_system_avatars_url: "URL del servizio esterno di avatar. Le sostituzioni consentite sono {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "URL dell'immagine di default opengraph."
- twitter_summary_large_image_url: "URL dell'immagine di default della scheda di riepilogo di Twitter (dovrebbe essere almeno 280px in larghezza e almeno 150px in altezza)."
allow_all_attachments_for_group_messages: "Consenti tutti gli allegati sulle email per i messaggi di gruppo."
png_to_jpg_quality: "Qualità del file JPG convertito (1 è la qualità più bassa, 99 è la qualità migliore, 100 per disabilitare)."
allow_staff_to_upload_any_file_in_pm: "Consenti ai membri delle staff di caricare qualsiasi file nei PM."
@@ -1394,7 +1392,6 @@ it:
enable_emoji: "Attiva gli emoji"
enable_emoji_shortcuts: "Smiley comuni come :) :p :( verranno convertiti in emoji"
emoji_set: "Come ti piacerebbero le tue emoji?"
- enforce_square_emoji: "Forza tutte le emoji ad un aspetto di proporzioni quadrate."
approve_post_count: "La quantità di messaggi di un utente nuovo o di base che deve essere approvata"
approve_unless_trust_level: "I messaggi degli utenti al di sotto di questo livello di esperienza devono essere approvati"
approve_new_topics_unless_trust_level: "I nuovi argomenti degli utenti al di sotto di questo livello di esperienza devono essere approvati"
diff --git a/config/locales/server.ko.yml b/config/locales/server.ko.yml
index 9506c7f054..9f3b963a3c 100644
--- a/config/locales/server.ko.yml
+++ b/config/locales/server.ko.yml
@@ -958,8 +958,6 @@ ko:
avatar_sizes: "자동 생성 아바타 사이즈 목록"
external_system_avatars_enabled: "외부 아바타 시스템을 사용하기"
external_system_avatars_url: "외부 아바타 서비스의 URL. {username} {first_letter} {color} {size} 의 대체가 허용됨"
- default_opengraph_image_url: "기본 오픈그래프 이미지의 URL"
- twitter_summary_large_image_url: "기본 Twitter 요약 카드 이미지의 URL( 가로 280px, 세로 150px 이상이어야 함)"
allow_all_attachments_for_group_messages: "그룹 메시지에 모든 이메일 첨부 허용"
png_to_jpg_quality: "변환된 JPG 파일의 퀄리티(1은 최하, 99는 최상, 100은 해제)"
allow_staff_to_upload_any_file_in_pm: "운영진이 보내는 개인메시지에 모든 파일 첨부 허용"
@@ -1151,7 +1149,6 @@ ko:
slug_generation_method: "slug 생성 방식. 'encoded'는 퍼센트 기호로 인코딩해서 생성합니다. 'none'은 slug 자체를 비활성화합니다.."
enable_emoji: "emoji 활성화"
emoji_set: "어떤 emoji가 좋은가요?"
- enforce_square_emoji: "모든 emoji를 정사각형 비율로 강제로 바꿉니다."
approve_unless_trust_level: "허가 받고 글 올려야 하는 유저들 최저 회원등급"
default_email_mailing_list_mode: "기본으로 새로운 포스트가 생길 때마다 이메일 보내기"
default_email_mailing_list_mode_frequency: "이 빈도로 이메일 받기를 설정한 메일링 리스트 가입자"
diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml
index 531b25b983..7456137b84 100644
--- a/config/locales/server.nl.yml
+++ b/config/locales/server.nl.yml
@@ -954,7 +954,6 @@ nl:
avatar_sizes: "Lijst van automatisch gegenereerde avatar groottes."
external_system_avatars_enabled: "Gebruik een avatars service van een extern systeem."
external_system_avatars_url: "URL van de externe avatar service. Toegestaande vervangingen zijn {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "URL van de standaard opengraph afbeelding."
png_to_jpg_quality: "Kwaliteit van het geconverteerde JPG bestand (1 is laagste kwaliteit, 99 is beste kwaliteit, 100 om uit te schakelen)."
strip_image_metadata: "Verwijder metadata uit afbeelding."
enable_flash_video_onebox: "Embedden van swf en flv (Adobe Flash) links toestaan in oneboxen. LET OP: dit kan onveilig zijn"
@@ -1105,7 +1104,6 @@ nl:
slug_generation_method: "Kies een slug generate methode. 'encoded' zal een percentage encoderen string genereren. 'none' zal slug helemaal uitschakelen."
enable_emoji: "Inschakelen emoji"
emoji_set: "Welke emoji wilt u gebruiken?"
- enforce_square_emoji: "Forceer een vierkant aspect ratio bij alle emojis."
approve_post_count: "Het aantal berichten van een nieuwe of normale gebruiker dat moet worden goedgekeurd"
approve_unless_trust_level: "Posts voor gebruikers onder dit vertrouwensniveau moeten worden goedgekeurd"
approve_new_topics_unless_trust_level: "Nieuwe topics voor gebruikers onder dit vertrouwensniveau moeten worden goedgekeurd"
diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml
index 07942d334d..f8dd95f752 100644
--- a/config/locales/server.pl_PL.yml
+++ b/config/locales/server.pl_PL.yml
@@ -1048,8 +1048,6 @@ pl_PL:
avatar_sizes: "Lista automatycznie wygenerowanych rozmiarów awatarów."
external_system_avatars_enabled: "Użyj zewnętrzny system awatarów."
external_system_avatars_url: "Adres URL zewnętrznego dostawcy awatarów. Dozwolone podstawienia: {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "Adres URL domyślnego obrazu otwarciawykresu."
- twitter_summary_large_image_url: "Adres URL domyślnego obrazu karty podsumowanie Twitter (powinien mieć przynajmniej 280px szerokości oraz 150px wysokości)."
allow_all_attachments_for_group_messages: "Zezwól na wszystkie załączniki email dla wiadomości grupowych."
png_to_jpg_quality: "Jakość skonwertowanego pliku JPG (1 to najniższa jakość, 99 to najlepsza jakość, 100 aby dezaktywować)."
allow_staff_to_upload_any_file_in_pm: "Pozwól personelowi przesyłać pliki w wiadomościach."
@@ -1249,7 +1247,6 @@ pl_PL:
slug_generation_method: "Wybierz metodę tworzenia ślimaka. 'Zakodowane\" stworzy procentowy ciąg kodujący, \"żadne\" wyłączy tą metodę."
enable_emoji: "Włącz obsługę emoji"
emoji_set: "Jaki jest twój preferowany styl emoji?"
- enforce_square_emoji: "Narzuć kwadratowy stosunek dla wszystkich emoji."
approve_post_count: "Liczba postów od nowego lub podstawowego użytkownika, które muszą zostać zatwierdzone"
approve_unless_trust_level: "Posty użytkowników poniżej tego poziomu zaufania muszą być zatwierdzane"
approve_new_topics_unless_trust_level: "Nowe wątki dodawane przez użytkowników z poziomem zaufania poniżej muszą zostać zaakceptowane"
diff --git a/config/locales/server.pt.yml b/config/locales/server.pt.yml
index 63912df65d..5c19747db4 100644
--- a/config/locales/server.pt.yml
+++ b/config/locales/server.pt.yml
@@ -907,8 +907,6 @@ pt:
avatar_sizes: "Lista de tamanhos de avatar gerados automaticamente."
external_system_avatars_enabled: "Utilize o serviço do sistema externo de avatars."
external_system_avatars_url: "URL do serviço de avatares externo do sistema. Substituições permitidas são {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "URL da imagem opengraph por defeito."
- twitter_summary_large_image_url: "URL da imagem do cartão de sumário de defeito do Twitter (deverá ser pelo menos 280px em largura, e pelo menos 150px em altura)."
allow_all_attachments_for_group_messages: "Permitir qualquer anexo de email nas mensagens de grupo."
enable_flash_video_onebox: "Ativar a incorporação de hiperligações swf e flv (Adobe Flash) em caixas únicas. AVISO: pode introduzir riscos de segurança."
default_invitee_trust_level: "Nível de Confiança padrão (0-4) para utilizadores convidados."
@@ -1095,7 +1093,6 @@ pt:
slug_generation_method: "Escolha um método de geração slug. 'encoded' irá gerar sequências de caracteres com código percentual. 'none' irá desativar slug por completo."
enable_emoji: "Ativar emoji"
emoji_set: "Como gostaria de ter o seu emoji?"
- enforce_square_emoji: "Forçar uma relação de aspecto quadrado para todos os emojis."
approve_post_count: "A quantidade de publicações de um novo utilizador ou utilizador básico que devem ser aprovadas"
approve_unless_trust_level: "Mensagens para utilizadores abaixo deste nível de confiança devem ser aprovados"
approve_new_topics_unless_trust_level: "Novos tópicos para utilizadores abaixo deste nível de confiança devem ser aprovados"
diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml
index 5c8b246457..b9506e74f3 100644
--- a/config/locales/server.pt_BR.yml
+++ b/config/locales/server.pt_BR.yml
@@ -701,8 +701,6 @@ pt_BR:
no_replies:
self: "Você não respondeu a nenhuma postagem."
others: "Sem Respostas."
- no_drafts:
- others: "Você não tem permissão para ver rascunhos desse usuário."
topic_flag_types:
spam:
title: 'Spam'
@@ -1264,8 +1262,6 @@ pt_BR:
external_system_avatars_url: "URL do sistema externo do serviço de avatares. Substituições permitidas são {username} {first_letter} {color} {size}"
selectable_avatars_enabled: "Force os usuários a escolher um avatar da lista."
selectable_avatars: "Lista de usuários avatares podem escolher."
- default_opengraph_image_url: "URL da imagem opengraph padrão."
- twitter_summary_large_image_url: "URL da imagem do cartão de resumo padrão do Twitter (deve ter pelo menos 280px de largura e pelo menos 150px de altura)."
allow_all_attachments_for_group_messages: "Permitir todos os anexos de e-mail para mensagens de grupo."
png_to_jpg_quality: "Qualidade do arquivo JPG convertido (1 é a qualidade mais baixa, 99 é a melhor qualidade, 100 a desabilitar)."
allow_staff_to_upload_any_file_in_pm: "Permitir que membros da equipe façam upload de arquivos no PM."
@@ -1499,7 +1495,6 @@ pt_BR:
enable_emoji: "Habilitar emoji"
enable_emoji_shortcuts: "Texto em smiley comum como :): p :( será convertido em emojis"
emoji_set: "Como você gostaria do seu emoji?"
- enforce_square_emoji: "Forçar proporção quadrangular para todos emojis."
emoji_autocomplete_min_chars: "Número mínimo de caracteres necessários para acionar o pop-up de emoji de preenchimento automático"
approve_post_count: "A quantidade de postagens de um usuário novo ou básico que deve ser aprovado"
approve_unless_trust_level: "Mensagens para os usuários abaixo deste nível de confiança devem ser aprovados"
diff --git a/config/locales/server.ro.yml b/config/locales/server.ro.yml
index 950558c1d5..5ce98a13ee 100644
--- a/config/locales/server.ro.yml
+++ b/config/locales/server.ro.yml
@@ -914,8 +914,6 @@ ro:
avatar_sizes: "Lista mărimilor avatarurilor generate automat."
external_system_avatars_enabled: "Folosiți un serviciu extern de sisteme de avataruri"
external_system_avatars_url: "URL-ul serviciului extern de sisteme de avataruri. Înlocuirile permise sunt {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "URL-ul pentru imaginea implicită pentru Open Graph"
- twitter_summary_large_image_url: "URL-ul pentru imaginea implicită pentru imaginea card cu rezumatul Twitter (trebuie să aibă minim 280px lățime și 150px înălțime)."
allow_all_attachments_for_group_messages: "Permite toate atașamentele de email pentru mesajele de grup."
enable_flash_video_onebox: "Activează încastrarea adreselor swf și flv (Adobe Flash) în onebox. ATENȚIE: poate aduce riscuri de securitate."
default_invitee_trust_level: "Nivelul de încredere implicit (0-4) pentru utilizatorii invitați."
@@ -1101,7 +1099,6 @@ ro:
slug_generation_method: "Alege o metodă de generare de identificator. 'encodat' va genera șir de caractere encodate cu procentaje. 'nimic' va dezactiva complet identificatorii."
enable_emoji: "Activează emoji"
emoji_set: "Cum ți-ar placea să fie emoji tăi?"
- enforce_square_emoji: "Forțează un aspect pătrățos la toti emoji."
approve_post_count: "Numărul de postări de la un utilizator simplu trebuie să fie aprobat"
approve_unless_trust_level: "Postările utilizatorilor care au un nivel de încredere mai mic decât acesta trebuie să fie aprobate."
approve_new_topics_unless_trust_level: "Crearea de subiecte noi pentru utilizatorii care se află sub acest nivel de încredere, trebuie aprobată"
diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml
index bef3d2209b..45bef1063e 100644
--- a/config/locales/server.ru.yml
+++ b/config/locales/server.ru.yml
@@ -903,7 +903,6 @@ ru:
s3_secret_access_key: "Amazon S3 secret key для загрузки и хранения изображений"
s3_region: "Географический регион Amazon S3, который будет использоваться для хранения изображений"
avatar_sizes: "Список автоматически сгенерированных размеров аватар."
- default_opengraph_image_url: "URL картинки opengraph по-умолчанию."
allow_all_attachments_for_group_messages: "Разрешить все почтовые вложения для групповых сообщений."
enable_flash_video_onebox: "Разрешить умную вставку ссылок sqf и flv (Adobe Flash). ВНИМАНИЕ: повышает риски безопасности сайта."
default_invitee_trust_level: "Уровень доверия приглашенных пользователей по-умолчанию (от 0 до 4)."
@@ -1037,7 +1036,6 @@ ru:
slug_generation_method: "Выберите метод генерации URL. 'encoded' будет изпользовать русские буквы в URL закодированные через проценты. 'none' не будет использовать перегенирацию."
enable_emoji: "Активировать смайлы Emoji"
emoji_set: "Какую коллекцию Emoji использовать?"
- enforce_square_emoji: "Принудительно использовать квадратный формат для всех смайлов."
approve_unless_trust_level: "Сообщения для пользователей ниже этого уровня доверия подлежат проверки"
default_email_mailing_list_mode: "По умолчанию присылать почтовое уведомление, когда появляется новое сообщение."
default_other_external_links_in_new_tab: "По умолчанию открывать внешние ссылки в новой вкладке."
diff --git a/config/locales/server.sk.yml b/config/locales/server.sk.yml
index 94e185d75e..bc292cb6a8 100644
--- a/config/locales/server.sk.yml
+++ b/config/locales/server.sk.yml
@@ -879,7 +879,6 @@ sk:
s3_cdn_url: "CDN URL ktoré sa použije na všetky dáta v s3 (napríklad https://cdn.niekde.com). VAROVANIE: po zmene tohoto nastavenia musíte použiť príkaz rebake na všetky staré príspevky."
avatar_sizes: "Zoznam automaticky generovaných veľkostí avatarov."
external_system_avatars_enabled: "Použiť externú avatar službu."
- default_opengraph_image_url: "URL štandardného opengraph obrázku."
enable_flash_video_onebox: "Povolenia vkladania odkazov na swf a flv (Adobe Flash) v onebox. VAROVANIE: môže vniesť bezpečnostné riziká."
default_invitee_trust_level: "Predvolená stupeň dôvery (0-4) pre pozvaných používateľov."
default_trust_level: "Východzí stupeň dôvery (0-4) pre všekých nových používateľov. UPOZORNENIE: Zmena nastavenia Vás môže vystaviť riziku spamovania. "
@@ -1017,7 +1016,6 @@ sk:
slug_generation_method: "Vybrať metódu generovania koncovej časti adresy. 'encoded' vygeneruje percentami zakódovaní reťazec. 'none' vypne koncovú časť adresy úplne."
enable_emoji: "Zapnúť emoji"
emoji_set: "Aké emoji chcete mať?"
- enforce_square_emoji: "Vynútiť švorcový pomer strán na všetkých emoji."
approve_unless_trust_level: "Príspevky používateľov pod touto úrovňou důvery musia byť schválené"
auto_close_messages_post_count: "Maximálny počet povolených príspevkov v správe kým je automaticky uzavretá (0 znamená vypnuté)"
auto_close_topics_post_count: "Maximálny počet povolených príspevkov v téme kým je automaticky uzavretá (0 znamená vypnuté)"
diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml
index 28550a07c9..3dc52a7de0 100644
--- a/config/locales/server.sq.yml
+++ b/config/locales/server.sq.yml
@@ -759,7 +759,6 @@ sq:
slug_generation_method: "Choose a slug generation method. 'encoded' will generate percent encoding string. 'none' will disable slug at all."
enable_emoji: "Enable emoji"
emoji_set: "How would you like your emoji?"
- enforce_square_emoji: "Force a square aspect ratio to all emojis."
approve_unless_trust_level: "Posts for users below this trust level must be approved"
auto_close_messages_post_count: "Numri më i lartë i lejueshëm i postimeve të lejuara në një mesazh përpara se të mbyllet automatikisht (0 për ta çaktivizuar)"
auto_close_topics_post_count: "Numri më i lartë i lejueshëm i postimeve të lejuara në një temë përpara se të mbyllet automatikisht (0 për ta çaktivizuar)"
diff --git a/config/locales/server.sr.yml b/config/locales/server.sr.yml
index d2b553851d..d3ffb11bc2 100644
--- a/config/locales/server.sr.yml
+++ b/config/locales/server.sr.yml
@@ -166,7 +166,6 @@ sr:
show_create_topics_notice: "Ako sajt ima manje od 5 javnih tema, prikaži poruku koja sugeriše administratorima da kreiraju neke teme."
delete_drafts_older_than_n_days: Izbriši radne verzije poruka starije od (n) dana
enable_emoji: "Omogući emotikone"
- enforce_square_emoji: "Forsiraj kvadratni oblik za sve emotikone."
auto_close_messages_post_count: "Maksimalan broj dozvoljenih poruka pre nego se tema automatski zatvori (0 da se isključi)"
default_email_mailing_list_mode: "Podrazumevano šalji email za svaku novu poruku"
default_email_previous_replies: "Podrazumevano uključi prethodne odgovore u email poruku"
diff --git a/config/locales/server.sv.yml b/config/locales/server.sv.yml
index 07d4b22155..92487130af 100644
--- a/config/locales/server.sv.yml
+++ b/config/locales/server.sv.yml
@@ -861,7 +861,6 @@ sv:
s3_cdn_url: "CDN URL som används för alla S3-tillgångar (till exempel: https://cdn.somewhere.com). VARNING: efter ändring av den här inställningen så måste du uppdatera alla gamla inlägg med rake posts: rebake."
avatar_sizes: "Lista på automatiskt genererade avatar-storlekar."
external_system_avatars_enabled: "Använd externa system för avatar-tjänster."
- default_opengraph_image_url: "URL för standard opengraphbilden."
allow_all_attachments_for_group_messages: "Tillåt alla e-postbilagor för gruppmeddelanden."
enable_flash_video_onebox: "Aktivera inbäddning av swf- och fic- (Adobe Flash) länkar i onebox:ar. VARNING: det kan introducera säkerhetsrisker."
default_invitee_trust_level: "Förvald förtroendenivå (0-4) för inbjudna användare."
@@ -1048,7 +1047,6 @@ sv:
slug_generation_method: "Välj en genereringsmetod för etiketter. Ange 'none' för att inaktivera generering av etiketter. "
enable_emoji: "Aktivera emoji"
emoji_set: "Hur skulle du vilja ha din emoji?"
- enforce_square_emoji: "Tvinga fram en kvadratisk bildkvot för alla emojis."
approve_post_count: "Antalet inlägg från en ny användare eller basanvändare som måste godkännas"
approve_unless_trust_level: "Inlägg för användare under den här förtroendenivån måste godkännas"
approve_new_topics_unless_trust_level: "Nya ämnen för användare under denna förtroendenivå måste bli godkända"
diff --git a/config/locales/server.tr_TR.yml b/config/locales/server.tr_TR.yml
index 475e5a604b..95c0532a4b 100644
--- a/config/locales/server.tr_TR.yml
+++ b/config/locales/server.tr_TR.yml
@@ -793,7 +793,6 @@ tr_TR:
s3_cdn_url: "Tüm s3 öğeleri için CDN URL adresi. (örneğin: https://cdn.somewhere.com). UYARI: bu ayarı değiştirdikten sonra tüm eski gönderileri rebake etmelisiniz."
avatar_sizes: "Otomatik üretilen avatar ölçülerinin listesi."
external_system_avatars_enabled: "Dışsal sistem avatarları hizmeti kullan."
- default_opengraph_image_url: "Öntanımlı opengraph imajının URL'si."
allow_all_attachments_for_group_messages: "Grup iletileri için tüm e-posta eklentilerine izin ver."
enable_flash_video_onebox: "Kutularda swf ve flv (Adobe Flash) yerleştirmelerine izin ver. UYARI: güvenlik açıkları doğurabilir"
default_invitee_trust_level: "Davet edilen kullanıcılar için öntanımlı güven seviyesi (0-4)."
@@ -946,7 +945,6 @@ tr_TR:
slug_generation_method: "Slug üretim yöntemi seçin. 'kodlanmış' seçeneği yüzde kodlamalı metin oluşturur. 'hiçbiri' seçeneği slug'ı devre dışı bırakır."
enable_emoji: "Emojiyi etkinleştir"
emoji_set: "Emojinizi nasıl isterdiniz?"
- enforce_square_emoji: "Tüm emojileri kare en-boy oranına zorla"
approve_unless_trust_level: "Bu güven seviyesi altındaki kullanıcılardan gelen gönderilerin onaylanması gerekir"
default_email_digest_frequency: "Öntanımlı olarak kullanıcılar ne sıklıkla e-posta özeti alacak."
default_email_direct: "Öntanımlı olarak birisi bir kullanıcı hakkında alıntı yapma, cevaplama, bahsetme ya da davet etme eylemlerini gerçekleştirdiğinde e-posta gönder."
diff --git a/config/locales/server.ur.yml b/config/locales/server.ur.yml
index 3e5de752c7..535c43437a 100644
--- a/config/locales/server.ur.yml
+++ b/config/locales/server.ur.yml
@@ -1106,8 +1106,6 @@ ur:
avatar_sizes: "خود کار طریقے سے تیار کردہ اوتار کے سائزوں کی فہرست۔"
external_system_avatars_enabled: "بیرونی سسٹم کی اوتار سروس کا استعمال کریں۔"
external_system_avatars_url: "بیرونی سسٹم کی اوتار سروس کا URL۔ اجازت شدہ متبادلات {username} {first_letter} {color} {size} ہیں"
- default_opengraph_image_url: "ڈِیفالٹ اَوپَن٘گراف تصویر کا URL۔"
- twitter_summary_large_image_url: "ٹویٹر خلاصہ کارڈ کی ڈِیفالٹ تصویر کا URL (کم از کم 280px چوڑائی، اور کم از کم 150px اونچائی کے سائز میں ہونا چاہئے)۔"
allow_all_attachments_for_group_messages: "گروپ کے پیغامات کیلئے تمام ای میل منسلکات کی اجازت دیں۔"
png_to_jpg_quality: "تبدیل شدہ JPG فائل کا معیار (1 سب سے کم معیار ہے، 99 بہترین معیار ہے، 100 غیر فعال)۔"
allow_staff_to_upload_any_file_in_pm: "سٹاف ارکان کو PM میں کوئی بھی فائل اَپ لوڈ کرنے کی اجازت دیں۔"
@@ -1332,7 +1330,6 @@ ur:
enable_emoji: "اِیمَوجی فعال کریں"
enable_emoji_shortcuts: "عام سمائلی ٹیکسٹ جیسا کہ :) :p :( اِیمَوجیوں میں تبدیل کر دیا جائے گا"
emoji_set: "آپ اپنا اِیمَوجی کیسا پسند کریں گے؟"
- enforce_square_emoji: "تمام اِیمَوجیوں کو ایک مربع اَیسپَیکٹ رَیشو پر مجبور کریں۔"
approve_post_count: "ایک نئے یا بَیسِک صارف کی طرف سے پوسٹس کی تعداد جن کا منظور کیے جانا لاذمی ہے "
approve_unless_trust_level: "اِس ٹرسٹ لَیول سے نیچے کے صارفین کیلئے پوسٹس کا منظور شدہ ہونا لازمی ہے"
approve_new_topics_unless_trust_level: "اِس ٹرسٹ لَیول سے نیچے کے صارفین کیلئے نئے ٹاپکس کا منظور شدہ ہونا لازمی ہے"
diff --git a/config/locales/server.vi.yml b/config/locales/server.vi.yml
index 20a35869a9..01d4d1189e 100644
--- a/config/locales/server.vi.yml
+++ b/config/locales/server.vi.yml
@@ -722,7 +722,6 @@ vi:
s3_cdn_url: "CDN URL được sử dụng cho tất cả các tài nguyên S3 (vd: https://cdn.somewhere.com). CHÚ Ý: sau khi thay đổi thiết lập này bạn phải tạo lại các bài viết cũ."
avatar_sizes: "Danh sách những kích thước hình đại diện tự động khởi tạo."
external_system_avatars_enabled: "Sử dụng dịch vụ ảnh đại diện bên ngoài."
- default_opengraph_image_url: "URL của ảnh opengraph mặc định."
allow_all_attachments_for_group_messages: "Cho phép các email có đính kèm trong tin nhắn nhóm."
enable_flash_video_onebox: "Cho phép nhúng liên kết swf và flv (Adobe Flash). CHÚ Ý: có thể chứa đựng các rủi ro bảo mật."
default_invitee_trust_level: "Bậc tin tưởng mặc định (0-4) cho thành viên được mời."
@@ -872,7 +871,6 @@ vi:
slug_generation_method: "Chọn phương thức tạo slug. 'encoded' sẽ tạo ra phần trăm chuỗi mã hóa. 'none' sẽ tắt slug."
enable_emoji: "Kích hoạt emoji"
emoji_set: "Bạn thích dùng gói emoji nào?"
- enforce_square_emoji: "Sử dụng kích thước vuông cho tất cả các emoji."
approve_post_count: "Số lượng bài viết từ một thành viên mới hoặc thành viên cũ phải được duyệt"
approve_unless_trust_level: "Bài viết của thành viên dưới cấp độ tin cậy này phải được duyệt"
default_email_direct: "Gửi email khi ai đó trích dẫn/trả lời/đề cập hoặc mời thành viên theo mặc định."
diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml
index f3778fbbaf..43161daa54 100644
--- a/config/locales/server.zh_CN.yml
+++ b/config/locales/server.zh_CN.yml
@@ -990,8 +990,6 @@ zh_CN:
avatar_sizes: "自动生成的头像大小列表。"
external_system_avatars_enabled: "使用外部系统头像服务。"
external_system_avatars_url: "外部系统头像服务的 URL 地址。可选参数是 {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "opengraph图像的缺省URL。"
- twitter_summary_large_image_url: "默认 Twitter summary 卡片的 URL(需要至少宽 280px 和高 150px)。"
allow_all_attachments_for_group_messages: "允许群组私信中包含任何邮件附件。"
png_to_jpg_quality: "转换 JPG 文件的质量(1 是最低,99 最高,100 禁用)。"
allow_staff_to_upload_any_file_in_pm: "允许管理人员在私信中上传任何文件。"
@@ -1201,7 +1199,6 @@ zh_CN:
slug_generation_method: "选择一个链接生成方式。“encoded”将生成以百分号编码的链接。“none”将禁用自定义链接,只生成默认链接。"
enable_emoji: "启用绘文字(emoji)"
emoji_set: "你喜欢哪一种 emoji?"
- enforce_square_emoji: "强制为所有 emojis 设置正方形比例。"
approve_post_count: "新用户或基础用户需要被审核的帖子数量"
approve_unless_trust_level: "该信任等级之下的用户的帖子必须被审核"
approve_new_topics_unless_trust_level: "低于该信任等级的用户的新帖子需要被审核"
diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml
index 8cbcf3595e..591fb78173 100644
--- a/config/locales/server.zh_TW.yml
+++ b/config/locales/server.zh_TW.yml
@@ -894,8 +894,6 @@ zh_TW:
avatar_sizes: "自動生成的頭像大小列表。"
external_system_avatars_enabled: "使用外部系統頭像服務。"
external_system_avatars_url: "外部系統頭像服務的 URL 地址。可選參數是 {username} {first_letter} {color} {size}"
- default_opengraph_image_url: "opengraph圖像的預設URL。"
- twitter_summary_large_image_url: "預設 Twitter summary 卡片的 URL(需要至少寬 280px 和高 150px)。"
allow_all_attachments_for_group_messages: "允許群組消息中包含任何郵件附件。"
enable_flash_video_onebox: "在連結預覽中啟用 swf 和 flv (Adobe Flash) 嵌入。警告:可能增加安全風險。"
default_invitee_trust_level: "預設的受邀用戶等級 (0-4)"
@@ -1086,7 +1084,6 @@ zh_TW:
slug_generation_method: "選擇一個連結生成方式。“encoded”將生成以百分號編碼的連結。“none”將禁用自定義連結,只生成預設連結。"
enable_emoji: "啟用表情符號"
emoji_set: "你喜歡怎麼樣的表情符號?"
- enforce_square_emoji: "強制所有表情符號成為正方形比例。"
approve_post_count: "新用戶或基礎用戶需要被審核的帖子數量"
approve_unless_trust_level: "該信任等級之下的用戶的帖子必須被審核"
approve_new_topics_unless_trust_level: "低於該信任等級的用戶的新帖子需要被審核"
@@ -1188,9 +1185,6 @@ zh_TW:
other: "%{count} 個帖子被分離到了新主題:%{topic_link}"
existing_topic_moderator_post:
other: "%{count} 個帖子被合併到現存主題:%{topic_link}"
- change_owner:
- post_revision_text: "所有權從 %{old_user} 轉移至 %{new_user}"
- deleted_user: "已經刪除的用戶"
topic_statuses:
archived_enabled: "此討論話題已封存,即已經凍結,無法修改。"
archived_disabled: "此討論話題已被解除封存,即不再凍結,可以修改。"
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 153ecac96f..0360cc7a64 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -479,6 +479,7 @@ posting:
min: 1
default: 20
locale_default:
+ ja: 8
zh_CN: 8
zh_TW: 8
min_first_post_length:
@@ -486,6 +487,7 @@ posting:
min: 1
default: 20
locale_default:
+ ja: 8
zh_CN: 8
zh_TW: 8
min_personal_message_post_length:
@@ -493,6 +495,7 @@ posting:
min: 1
default: 10
locale_default:
+ ja: 3
zh_CN: 3
zh_TW: 3
max_post_length:
@@ -513,6 +516,7 @@ posting:
default: 15
min: 1
locale_default:
+ ja: 6
zh_CN: 6
zh_TW: 6
max_topic_title_length:
@@ -529,7 +533,7 @@ posting:
allow_uppercase_posts:
default: false
locale_default:
- ja: false
+ ja: true
title_prettify:
default: true
locale_default:
@@ -551,6 +555,7 @@ posting:
client: true
default: 10
locale_default:
+ ja: 4
zh_CN: 4
zh_TW: 4
enable_personal_messages:
@@ -629,6 +634,7 @@ posting:
post_excerpt_maxlength:
default: 300
locale_default:
+ ja: 120
zh_CN: 120
zh_TW: 120
show_pinned_excerpt_mobile:
@@ -671,8 +677,6 @@ posting:
default: 'twitter'
client: true
enum: 'EmojiSetSiteSetting'
- enforce_square_emoji:
- default: true
emoji_autocomplete_min_chars:
client: true
default: 0
@@ -733,6 +737,7 @@ email:
digest_min_excerpt_length:
default: 100
locale_default:
+ ja: 50
zh_CN: 50
zh_TW: 50
digest_topics:
@@ -783,7 +788,9 @@ email:
pop3_polling_host: ''
pop3_polling_port: 995
pop3_polling_username: ''
- pop3_polling_password: ''
+ pop3_polling_password:
+ default: ''
+ secret: true
pop3_polling_delete_from_server: true
log_mail_processing_failures: false
incoming_email_prefer_html: true
@@ -837,6 +844,7 @@ email:
mailgun_api_key:
default: ''
regex: '^(key-\h{32}|\h{32}-\h{8}-\h{8})$'
+ secret: true
bounce_score_threshold:
client: true
default: 4
@@ -933,7 +941,7 @@ files:
default: false
client: true
s3_use_iam_profile: false
- s3_access_key_id:
+ s3_access_key_id:
default: ''
secret: true
shadowed_by_global: true
@@ -1157,6 +1165,7 @@ onebox:
post_onebox_maxlength:
default: 500
locale_default:
+ ja: 200
zh_CN: 200
zh_TW: 200
onebox_domains_blacklist:
@@ -1455,6 +1464,7 @@ uncategorized:
default: 'ascii'
enum: 'SlugSetting'
locale_default:
+ ja: 'none'
zh_CN: 'none'
zh_TW: 'none'
@@ -1598,6 +1608,7 @@ uncategorized:
default: 500
client: true
locale_default:
+ ja: 350
zh_CN: 350
zh_TW: 350
diff --git a/db/migrate/20180913200027_remove_enforce_square_emoji.rb b/db/migrate/20180913200027_remove_enforce_square_emoji.rb
new file mode 100644
index 0000000000..a774f94795
--- /dev/null
+++ b/db/migrate/20180913200027_remove_enforce_square_emoji.rb
@@ -0,0 +1,9 @@
+class RemoveEnforceSquareEmoji < ActiveRecord::Migration[5.2]
+ def up
+ execute "DELETE FROM site_settings WHERE name = 'enforce_square_emoji'"
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration
+ end
+end
diff --git a/docs/SECURITY.md b/docs/SECURITY.md
index 01fc37fb19..27d4fefd37 100644
--- a/docs/SECURITY.md
+++ b/docs/SECURITY.md
@@ -6,6 +6,8 @@ We take security very seriously at Discourse. We welcome any peer review of our
In order to give the community time to respond and upgrade we strongly urge you report all security issues privately. Please use our [vulnerability disclosure program at Hacker One](https://hackerone.com/discourse) to provide details and repro steps and we will respond ASAP. If you prefer not to use Hacker One, email us directly at `team@discourse.org` with details and repro steps. Security issues *always* take precedence over bug fixes and feature work. We can and do mark releases as "urgent" if they contain serious security fixes.
+For a list of recent security commits, check [our GitHub commits prefixed with SECURITY](https://github.com/discourse/discourse/search?utf8=%E2%9C%93&q=SECURITY&type=Commits).
+
### Password Storage
Discourse uses the PBKDF2 algorithm to encrypt salted passwords. This algorithm is blessed by NIST. Security experts on the web [tend to agree that PBKDF2 is a secure choice](http://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage).
diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb
index 3419dbda06..0e445fdddc 100644
--- a/lib/email/receiver.rb
+++ b/lib/email/receiver.rb
@@ -910,7 +910,7 @@ module Email
end
def attachment_markdown(upload)
- if FileHelper.is_image?(upload.original_filename)
+ if FileHelper.is_supported_image?(upload.original_filename)
""
else
"#{upload.original_filename} (#{number_to_human_size(upload.filesize)})"
diff --git a/lib/file_helper.rb b/lib/file_helper.rb
index 21c0cd79bc..f146b8b139 100644
--- a/lib/file_helper.rb
+++ b/lib/file_helper.rb
@@ -11,8 +11,8 @@ class FileHelper
)
end
- def self.is_image?(filename)
- filename =~ images_regexp
+ def self.is_supported_image?(filename)
+ filename =~ supported_images_regexp
end
class FakeIO
@@ -48,7 +48,7 @@ class FileHelper
# attempt error API compatibility
io = FakeIO.new
io.status = [response.code, ""]
- raise OpenURI::HTTPError.new("#{response.code} Error", io)
+ raise OpenURI::HTTPError.new("#{response.code} Error: #{response.body}", io)
else
log(:error, "FinalDestination did not work for: #{url}") if verbose
throw :done
@@ -100,14 +100,12 @@ class FileHelper
).optimize_image!(filename)
end
- private
-
- def self.images
- @@images ||= Set.new %w{jpg jpeg png gif tif tiff bmp svg webp ico}
+ def self.supported_images
+ @@supported_images ||= Set.new %w{jpg jpeg png gif svg ico}
end
- def self.images_regexp
- @@images_regexp ||= /\.(#{images.to_a.join("|")})$/i
+ def self.supported_images_regexp
+ @@supported_images_regexp ||= /\.(#{supported_images.to_a.join("|")})$/i
end
end
diff --git a/lib/file_store/s3_store.rb b/lib/file_store/s3_store.rb
index aa444ba1fc..6aca50f9f4 100644
--- a/lib/file_store/s3_store.rb
+++ b/lib/file_store/s3_store.rb
@@ -39,7 +39,7 @@ module FileStore
content_type: opts[:content_type].presence || MiniMime.lookup_by_filename(filename)&.content_type
}
# add a "content disposition" header for "attachments"
- options[:content_disposition] = "attachment; filename=\"#{filename}\"" unless FileHelper.is_image?(filename)
+ options[:content_disposition] = "attachment; filename=\"#{filename}\"" unless FileHelper.is_supported_image?(filename)
# if this fails, it will throw an exception
path = @s3_helper.upload(file, path, options)
# return the upload url
diff --git a/lib/freedom_patches/active_record_base.rb b/lib/freedom_patches/active_record_base.rb
index 4f71a4df38..39687ce2aa 100644
--- a/lib/freedom_patches/active_record_base.rb
+++ b/lib/freedom_patches/active_record_base.rb
@@ -15,7 +15,7 @@ class ActiveRecord::Base
def self.find_or_create_by_safe!(hash)
begin
find_or_create_by!(hash)
- rescue PG::UniqueViolation, ActiveRecord::RecordNotUnique
+ rescue PG::UniqueViolation, ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
# try again cause another transaction could have passed by now
find_or_create_by!(hash)
end
diff --git a/lib/site_settings/defaults_provider.rb b/lib/site_settings/defaults_provider.rb
index 6340ff91b9..9ebae9aa51 100644
--- a/lib/site_settings/defaults_provider.rb
+++ b/lib/site_settings/defaults_provider.rb
@@ -38,8 +38,10 @@ class SiteSettings::DefaultsProvider
end
def get(name, locale = DEFAULT_LOCALE)
- @defaults.dig(locale.to_sym, name.to_sym) ||
- @defaults.dig(DEFAULT_LOCALE.to_sym, name.to_sym)
+ value = @defaults.dig(locale.to_sym, name.to_sym)
+ return value unless value.nil?
+
+ @defaults.dig(DEFAULT_LOCALE.to_sym, name.to_sym)
end
alias [] get
diff --git a/lib/tasks/docker.rake b/lib/tasks/docker.rake
index 6a7088dfd3..65276b759c 100644
--- a/lib/tasks/docker.rake
+++ b/lib/tasks/docker.rake
@@ -39,6 +39,7 @@ task 'docker:test' do
begin
@good = true
unless ENV['SKIP_LINT']
+ puts "travis_fold:start:lint" if ENV["TRAVIS"]
puts "Running linters/prettyfiers"
puts "eslint #{`yarn eslint -v`}"
puts "prettier #{`yarn prettier -v`}"
@@ -64,9 +65,11 @@ task 'docker:test' do
@good &&= run_or_fail('yarn prettier --list-different "plugins/**/*.scss" "plugins/**/*.es6"')
end
end
+ puts "travis_fold:end:lint" if ENV["TRAVIS"]
end
unless ENV['SKIP_TESTS']
+ puts "travis_fold:start:prepare_tests" if ENV["TRAVIS"]
puts "Cleaning up old test tmp data in tmp/test_data"
`rm -fr tmp/test_data && mkdir -p tmp/test_data/redis && mkdir tmp/test_data/pg`
@@ -92,10 +95,16 @@ task 'docker:test' do
@good &&= run_or_fail("bundle exec rake plugin:install_all_official")
end
- @good &&= run_or_fail("bundle exec rake db:migrate")
+ if ENV["SKIP_PLUGINS"]
+ @good &&= run_or_fail("bundle exec rake db:migrate")
+ else
+ @good &&= run_or_fail("LOAD_PLUGINS=1 bundle exec rake db:migrate")
+ end
+
+ puts "travis_fold:end:prepare_tests" if ENV["TRAVIS"]
unless ENV["JS_ONLY"]
-
+ puts "travis_fold:start:ruby_tests" if ENV["TRAVIS"]
unless ENV["SKIP_CORE"]
params = []
if ENV["BISECT"]
@@ -114,10 +123,11 @@ task 'docker:test' do
@good &&= run_or_fail("bundle exec rake plugin:spec")
end
end
-
+ puts "travis_fold:end:ruby_tests" if ENV["TRAVIS"]
end
unless ENV["RUBY_ONLY"]
+ puts "travis_fold:start:js_tests" if ENV["TRAVIS"]
unless ENV["SKIP_CORE"]
@good &&= run_or_fail("bundle exec rake qunit:test['600000']")
@good &&= run_or_fail("bundle exec rake qunit:test['600000','/wizard/qunit']")
@@ -130,11 +140,12 @@ task 'docker:test' do
@good &&= run_or_fail("bundle exec rake plugin:qunit['*','600000']")
end
end
-
+ puts "travis_fold:end:js_tests" if ENV["TRAVIS"]
end
end
ensure
+ puts "travis_fold:start:terminating" if ENV["TRAVIS"]
puts "Terminating"
if ENV['PAUSE_ON_TERMINATE']
@@ -146,6 +157,7 @@ task 'docker:test' do
Process.kill("TERM", @pg_pid) if @pg_pid
Process.wait @redis_pid if @redis_pid
Process.wait @pg_pid if @pg_pid
+ puts "travis_fold:end:terminating" if ENV["TRAVIS"]
end
if !@good
diff --git a/lib/upload_creator.rb b/lib/upload_creator.rb
index 25d2eef45d..2b138950e7 100644
--- a/lib/upload_creator.rb
+++ b/lib/upload_creator.rb
@@ -37,8 +37,8 @@ class UploadCreator
# test for image regardless of input
@image_info = FastImage.new(@file) rescue nil
- is_image = FileHelper.is_image?(@filename)
- is_image ||= @image_info && FileHelper.is_image?("test.#{@image_info.type}")
+ is_image = FileHelper.is_supported_image?(@filename)
+ is_image ||= @image_info && FileHelper.is_supported_image?("test.#{@image_info.type}")
if is_image
extract_image_info!
diff --git a/lib/url_helper.rb b/lib/url_helper.rb
index 5df27575f8..377c7d38cd 100644
--- a/lib/url_helper.rb
+++ b/lib/url_helper.rb
@@ -36,7 +36,7 @@ class UrlHelper
uri = URI.parse(url)
filename = File.basename(uri.path)
- is_attachment = !FileHelper.is_image?(filename)
+ is_attachment = !FileHelper.is_supported_image?(filename)
no_cdn = SiteSetting.login_required || SiteSetting.prevent_anons_from_downloading_files
diff --git a/lib/validators/upload_validator.rb b/lib/validators/upload_validator.rb
index 60074a197f..b546ebf155 100644
--- a/lib/validators/upload_validator.rb
+++ b/lib/validators/upload_validator.rb
@@ -18,7 +18,7 @@ class Validators::UploadValidator < ActiveModel::Validator
extension = File.extname(upload.original_filename)[1..-1] || ""
if is_authorized?(upload, extension)
- if FileHelper.is_image?(upload.original_filename)
+ if FileHelper.is_supported_image?(upload.original_filename)
authorized_image_extension(upload, extension)
maximum_image_file_size(upload)
else
@@ -74,11 +74,11 @@ class Validators::UploadValidator < ActiveModel::Validator
end
def authorized_images(upload)
- authorized_extensions(upload) & FileHelper.images
+ authorized_extensions(upload) & FileHelper.supported_images
end
def authorized_attachments(upload)
- authorized_extensions(upload) - FileHelper.images
+ authorized_extensions(upload) - FileHelper.supported_images
end
def authorizes_all_extensions?(upload)
diff --git a/lib/version.rb b/lib/version.rb
index b68559aa66..56dd01add1 100644
--- a/lib/version.rb
+++ b/lib/version.rb
@@ -5,7 +5,7 @@ module Discourse
MAJOR = 2
MINOR = 2
TINY = 0
- PRE = 'beta1'
+ PRE = 'beta2'
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/package.json b/package.json
index dbeab0e8e5..6f55039c66 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,8 @@
"chrome-remote-interface": "^0.25",
"eslint": "^4.19",
"prettier": "^1.13",
- "puppeteer": "^1.4",
- "pretender": "^1.6"
+ "puppeteer": "1.4",
+ "pretender": "^1.6",
+ "qunit": "2.6"
}
}
diff --git a/plugins/discourse-narrative-bot/config/locales/server.fi.yml b/plugins/discourse-narrative-bot/config/locales/server.fi.yml
index 7b40cefea9..32cd32bc65 100644
--- a/plugins/discourse-narrative-bot/config/locales/server.fi.yml
+++ b/plugins/discourse-narrative-bot/config/locales/server.fi.yml
@@ -7,6 +7,7 @@
fi:
site_settings:
+ discourse_narrative_bot_enabled: 'Ota Discoursen opastava botti käyttöön (discobot)'
disable_discourse_narrative_bot_welcome_post: "Estä bottia lähettämästä tervetuloviestejä"
discourse_narrative_bot_ignored_usernames: "Käyttäjänimet, jotka botin tulisi jättää huomiotta"
discourse_narrative_bot_disable_public_replies: "Estä bottia vastaamasta julkisesti ketjuihin"
diff --git a/plugins/discourse-narrative-bot/config/locales/server.sw.yml b/plugins/discourse-narrative-bot/config/locales/server.sw.yml
index 59103d5ca3..7e6540ed70 100644
--- a/plugins/discourse-narrative-bot/config/locales/server.sw.yml
+++ b/plugins/discourse-narrative-bot/config/locales/server.sw.yml
@@ -7,6 +7,7 @@
sw:
site_settings:
+ discourse_narrative_bot_enabled: 'Ruhusu roboti wa maelezo ya Discourse (discobot)'
disable_discourse_narrative_bot_welcome_post: "Sitisha Roboti wa Discourse kukaribisha watu na taarifa"
discourse_narrative_bot_ignored_usernames: "Majina ya watumiaji ambayo Roboti wa Discourse aya dharau"
discourse_narrative_bot_disable_public_replies: "Sitisha majibu ya umma ya roboti wa Discourse"
diff --git a/plugins/poll/config/locales/server.ar.yml b/plugins/poll/config/locales/server.ar.yml
index b7e922904e..ba4b95b947 100644
--- a/plugins/poll/config/locales/server.ar.yml
+++ b/plugins/poll/config/locales/server.ar.yml
@@ -7,6 +7,7 @@
ar:
site_settings:
+ poll_enabled: "السماح بالإستفتاء"
poll_maximum_options: "أقصى عدد للخيارات في كلّ تصويت."
poll_edit_window_mins: "عدد الدقائق بعد نشر المنشور المسموح فيها بتعديل التصويت."
poll:
diff --git a/script/docker_test.rb b/script/docker_test.rb
index cb3a3bf523..a8f3a1cf45 100644
--- a/script/docker_test.rb
+++ b/script/docker_test.rb
@@ -6,6 +6,8 @@
# => RUN_SMOKE_TESTS executes the smoke tests instead of the regular tests from docker.rake
# See lib/tasks/docker.rake and lib/tasks/smoke_test.rake for more information
+puts "travis_fold:end:starting_docker_container" if ENV["TRAVIS"]
+
def run_or_fail(command)
pid = Process.spawn(command)
Process.wait(pid)
@@ -13,11 +15,18 @@ def run_or_fail(command)
end
unless ENV['NO_UPDATE']
+ puts "travis_fold:start:pulling_latest_discourse" if ENV["TRAVIS"]
run_or_fail("git pull")
checkout = ENV['COMMIT_HASH'] || "HEAD"
run_or_fail("git checkout #{checkout}")
+
+ puts "travis_fold:end:pulling_latest_discourse" if ENV["TRAVIS"]
+ puts "travis_fold:start:bundle" if ENV["TRAVIS"]
+
run_or_fail("bundle")
+
+ puts "travis_fold:end:bundle" if ENV["TRAVIS"]
end
if ENV['RUN_SMOKE_TESTS']
diff --git a/script/downsize_uploads.rb b/script/downsize_uploads.rb
index 9812ca7abf..fae1ab4374 100644
--- a/script/downsize_uploads.rb
+++ b/script/downsize_uploads.rb
@@ -11,7 +11,7 @@ Upload.where("lower(extension) in (?)", ['jpg', 'jpeg', 'gif', 'png', 'bmp', 'ti
count += 1
print "\r%8d".freeze % count
absolute_path = Discourse.store.path_for(upload)
- if absolute_path && FileHelper.is_image?(upload.original_filename)
+ if absolute_path && FileHelper.is_supported_image?(upload.original_filename)
file = File.new(absolute_path) rescue nil
next unless file
diff --git a/script/import_scripts/base/uploader.rb b/script/import_scripts/base/uploader.rb
index 2d25a3e9ae..a9540112ba 100644
--- a/script/import_scripts/base/uploader.rb
+++ b/script/import_scripts/base/uploader.rb
@@ -40,7 +40,7 @@ module ImportScripts
end
def html_for_upload(upload, display_filename)
- if FileHelper.is_image?(upload.url)
+ if FileHelper.is_supported_image?(upload.url)
embedded_image_html(upload)
else
attachment_html(upload, display_filename)
diff --git a/script/import_scripts/ipboard.rb b/script/import_scripts/ipboard.rb
index f1b10b6a5b..316aa983be 100644
--- a/script/import_scripts/ipboard.rb
+++ b/script/import_scripts/ipboard.rb
@@ -788,6 +788,10 @@ EOM
raw.gsub!(/'/, "'")
raw.gsub!(/\[url="(.+?)"\]http.+?\[\/url\]/, "\\1\n")
raw.gsub!(/\[media\](.+?)\[\/media\]/, "\n\\1\n\n")
+ raw.gsub!(/\[php\](.+?)\[\/php\]/m) { |m| "\n\n```php\n\n" + @htmlentities.decode($1.gsub(/\n\n/, "\n")) + "\n\n```\n\n" }
+ raw.gsub!(/\[code\](.+?)\[\/code\]/m) { |m| "\n\n```\n\n" + @htmlentities.decode($1.gsub(/\n\n/, "\n")) + "\n\n```\n\n" }
+ raw.gsub!(/\[list\](.+?)\[\/list\]/m) { |m| "\n" + $1.gsub(/\[\*\]/, "\n- ") + "\n\n" }
+ raw.gsub!(/\[quote\]/, "\n[quote]\n")
raw.gsub!(/\[\/quote\]/, "\n[/quote]\n")
raw.gsub!(/date=\'(.+?)\'/, '')
raw.gsub!(/timestamp=\'(.+?)\' /, '')
@@ -829,9 +833,16 @@ EOM
puts "Attachment #{attach_id} not found."
attach_string = "Attachment #{attach_id} not found."
else
- attach_string = "#{attach_id}\n\n![#{attachments.first['filename']}](#{UPLOADS}/#{attachments.first['loc']})\n"
+ attach_url = "#{UPLOADS}/#{attachments.first['loc'].gsub(' ', '%20')}"
+ if attachments.first['filename'].match(/(png|jpg|jpeg|gif)$/)
+ # images are rendered as a link that contains the image
+ attach_string = "#{attach_id}\n\n[![#{attachments.first['filename']}](#{attach_url})](#{attach_url})\n"
+ else
+ # other attachments are simple download links
+ attach_string = "#{attach_id}\n\n[#{attachments.first['filename']}](#{attach_url})\n"
+ end
end
- raw.gsub!(attach_regex, attach_string)
+ raw.sub!(attach_regex, attach_string)
end
raw
diff --git a/spec/components/file_helper_spec.rb b/spec/components/file_helper_spec.rb
index ec81a94b57..6baa22ccff 100644
--- a/spec/components/file_helper_spec.rb
+++ b/spec/components/file_helper_spec.rb
@@ -28,7 +28,7 @@ describe FileHelper do
expect(e.io.status[0]).to eq("404")
raise
end
- end.to raise_error(OpenURI::HTTPError)
+ end.to raise_error(OpenURI::HTTPError, "404 Error: 404")
end
it "correctly raises an OpenURI HTTP error if it gets a 404" do
diff --git a/spec/components/site_settings/defaults_provider_spec.rb b/spec/components/site_settings/defaults_provider_spec.rb
index e4ca9a9109..948f66e0c0 100644
--- a/spec/components/site_settings/defaults_provider_spec.rb
+++ b/spec/components/site_settings/defaults_provider_spec.rb
@@ -37,14 +37,15 @@ describe SiteSettings::DefaultsProvider do
describe 'expose default cache according to locale' do
before do
settings.setting(:test_override, 'default', locale_default: { zh_CN: 'cn' })
+ settings.setting(:test_boolean_override, true, locale_default: { zh_CN: false })
settings.setting(:test_default, 'test', regex: '^\S+$')
settings.refresh!
end
describe '.all' do
it 'returns all values according to locale' do
- expect(settings.defaults.all).to eq(test_override: 'default', test_default: 'test')
- expect(settings.defaults.all('zh_CN')).to eq(test_override: 'cn', test_default: 'test')
+ expect(settings.defaults.all).to eq(test_override: 'default', test_default: 'test', test_boolean_override: true)
+ expect(settings.defaults.all('zh_CN')).to eq(test_override: 'cn', test_default: 'test', test_boolean_override: false)
end
end
@@ -57,6 +58,15 @@ describe SiteSettings::DefaultsProvider do
expect(settings.defaults.get('test_override')).to eq 'default'
end
+ it 'returns the locale_default value if it exists' do
+ expect(settings.defaults.get(:test_override, :zh_CN)).to eq 'cn'
+ expect(settings.defaults.get(:test_override, :de)).to eq 'default'
+ expect(settings.defaults.get(:test_default, :zh_CN)).to eq 'test'
+ end
+
+ it 'returns the correct locale_default for boolean site settings' do
+ expect(settings.defaults.get(:test_boolean_override, :zh_CN)).to eq false
+ end
end
describe '.set_regardless_of_locale' do
diff --git a/spec/components/stylesheet/importer_spec.rb b/spec/components/stylesheet/importer_spec.rb
index 199fdb1df6..3b65ec307c 100644
--- a/spec/components/stylesheet/importer_spec.rb
+++ b/spec/components/stylesheet/importer_spec.rb
@@ -30,7 +30,7 @@ describe Stylesheet::Importer do
background = Fabricate(:upload_s3)
category = Fabricate(:category, uploaded_background: background)
- expect(compile_css("category_backgrounds")).to include("body.category-#{category.full_slug}{background-image:url(https://s3.cdn/uploads")
+ expect(compile_css("category_backgrounds")).to include("body.category-#{category.full_slug}{background-image:url(https://s3.cdn/original")
end
end
diff --git a/spec/fabricators/upload_fabricator.rb b/spec/fabricators/upload_fabricator.rb
index d9df6633ce..c306a784b3 100644
--- a/spec/fabricators/upload_fabricator.rb
+++ b/spec/fabricators/upload_fabricator.rb
@@ -5,18 +5,27 @@ Fabricator(:upload) do
filesize 1234
width 100
height 200
- url { sequence(:url) { |n| "/uploads/default/#{n}/1234567890123456.png" } }
+
+ url do |attrs|
+ sequence(:url) do |n|
+ Discourse.store.get_path_for(
+ "original", n + 1, attrs[:sha1], ".#{attrs[:extension]}"
+ )
+ end
+ end
+
extension "png"
end
Fabricator(:upload_s3, from: :upload) do
- url { sequence(:url) { |n| "#{Discourse.store.absolute_base_url}/uploads/default/#{n}/1234567890123456.png" } }
-end
-
-Fabricator(:attachment, from: :upload) do
- id 42
- user
- original_filename "archive.zip"
- filesize 1234
- url "/uploads/default/42/66b3ed1503efc936.zip"
+ url do |attrs|
+ sequence(:url) do |n|
+ File.join(
+ Discourse.store.absolute_base_url,
+ Discourse.store.get_path_for(
+ "original", n + 1, attrs[:sha1], ".#{attrs[:extension]}"
+ )
+ )
+ end
+ end
end
diff --git a/spec/fixtures/images/webp_as.bin b/spec/fixtures/images/webp_as.bin
new file mode 100644
index 0000000000..2f8bf8fa1a
Binary files /dev/null and b/spec/fixtures/images/webp_as.bin differ
diff --git a/spec/integrity/site_setting_spec.rb b/spec/integrity/site_setting_spec.rb
index 9c52e9fab6..3cf271cfbe 100644
--- a/spec/integrity/site_setting_spec.rb
+++ b/spec/integrity/site_setting_spec.rb
@@ -23,11 +23,13 @@ describe "site setting integrity checks" do
it "no locale default has different type than default or invalid key" do
yaml.each_value do |category|
- category.each_value do |setting|
+ category.each do |setting_name, setting|
next unless setting.is_a?(Hash)
if setting['locale_default']
setting['locale_default'].each_pair do |k, v|
- expect(LocaleSiteSetting.valid_value?(k.to_s)).to be_truthy
+ expect(LocaleSiteSetting.valid_value?(k.to_s)).to be_truthy,
+ "'#{k}' is not a valid locale_default key for '#{setting_name}' site setting"
+
case setting['default']
when TrueClass, FalseClass
expect(v.class == TrueClass || v.class == FalseClass).to be_truthy
diff --git a/spec/lib/upload_creator_spec.rb b/spec/lib/upload_creator_spec.rb
index 614916ec4f..827288abb7 100644
--- a/spec/lib/upload_creator_spec.rb
+++ b/spec/lib/upload_creator_spec.rb
@@ -43,6 +43,27 @@ RSpec.describe UploadCreator do
expect(File.extname(upload.url)).to eq('.png')
expect(upload.original_filename).to eq('png_as.png')
end
+
+ describe 'for webp format' do
+ before do
+ SiteSetting.authorized_extensions = '.webp|.bin'
+ end
+
+ let(:filename) { "webp_as.bin" }
+ let(:file) { file_from_fixtures(filename) }
+
+ it 'should not correct the coerce filename' do
+ expect do
+ UploadCreator.new(file, filename).create_for(user.id)
+ end.to change { Upload.count }.by(1)
+
+ upload = Upload.last
+
+ expect(upload.extension).to eq('bin')
+ expect(File.extname(upload.url)).to eq('.bin')
+ expect(upload.original_filename).to eq('webp_as.bin')
+ end
+ end
end
describe 'converting to jpeg' do
diff --git a/spec/models/color_scheme_spec.rb b/spec/models/color_scheme_spec.rb
index d1ea51532f..974f9aae1f 100644
--- a/spec/models/color_scheme_spec.rb
+++ b/spec/models/color_scheme_spec.rb
@@ -65,6 +65,13 @@ describe ColorScheme do
expect(ColorScheme.hex_for_name('undefined')).to eq nil
end
+ it "returns the base color for an attribute of a specified scheme" do
+ scheme = ColorScheme.create_from_base(name: "test scheme")
+ ColorSchemeRevisor.revise(scheme, colors: [{ name: "header_background", hex: "9dc927", default_hex: "949493" }])
+ scheme.reload
+ expect(ColorScheme.hex_for_name("header_background", scheme.id)).to eq("9dc927")
+ end
+
it "returns the base color for an attribute" do
expect(ColorScheme.hex_for_name('second_one')).to eq base_colors[:second_one]
end
diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb
index 9cdd34cc4a..a432bb4632 100644
--- a/spec/models/report_spec.rb
+++ b/spec/models/report_spec.rb
@@ -813,6 +813,22 @@ describe Report do
end
end
+ describe "unexpected error on report initialization" do
+ it "returns no report" do
+ class ReportInitError < StandardError; end
+
+ Report.stubs(:new).raises(ReportInitError.new("x"))
+
+ Rails.logger.expects(:error)
+ .with('Couldn’t create report `signups`: ')
+ .once
+
+ report = Report.find('signups')
+
+ expect(report).to be_nil
+ end
+ end
+
describe 'posts' do
let(:report) { Report.find('posts') }
diff --git a/spec/models/stylesheet_cache_spec.rb b/spec/models/stylesheet_cache_spec.rb
index bffa8564d8..f42bc379ba 100644
--- a/spec/models/stylesheet_cache_spec.rb
+++ b/spec/models/stylesheet_cache_spec.rb
@@ -24,5 +24,17 @@ describe StylesheetCache do
expect(StylesheetCache.first.content).to eq "c"
end
+ it "it retains stylesheets for competing targets" do
+ StylesheetCache.destroy_all
+
+ StylesheetCache.add("desktop", SecureRandom.hex, "body { }", "map", max_to_keep: 2)
+ StylesheetCache.add("desktop", SecureRandom.hex, "body { }", "map", max_to_keep: 2)
+ StylesheetCache.add("mobile", SecureRandom.hex, "body { }", "map", max_to_keep: 2)
+ StylesheetCache.add("mobile", SecureRandom.hex, "body { }", "map", max_to_keep: 2)
+ StylesheetCache.add("mobile", SecureRandom.hex, "body { }", "map", max_to_keep: 2)
+
+ expect(StylesheetCache.order(:id).pluck(:target)).to eq(["desktop", "desktop", "mobile", "mobile"])
+ end
+
end
end
diff --git a/spec/models/theme_spec.rb b/spec/models/theme_spec.rb
index 40ae4f164d..15ad9318ca 100644
--- a/spec/models/theme_spec.rb
+++ b/spec/models/theme_spec.rb
@@ -1,8 +1,7 @@
require 'rails_helper'
describe Theme do
-
- before do
+ after do
Theme.clear_cache!
end
diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb
index 0e86a0fb3a..70b7760a38 100644
--- a/spec/models/upload_spec.rb
+++ b/spec/models/upload_spec.rb
@@ -75,23 +75,34 @@ describe Upload do
context ".get_from_url" do
let(:sha1) { "10f73034616a796dfd70177dc54b6def44c4ba6f" }
- let(:url) { "/uploads/default/original/3X/1/0/#{sha1}.png" }
- let(:upload) { Fabricate(:upload, url: url, sha1: sha1) }
+ let(:upload) { Fabricate(:upload, sha1: sha1) }
it "works when the file has been uploaded" do
expect(Upload.get_from_url(upload.url)).to eq(upload)
end
describe 'for an extensionless url' do
- let(:url) { "/uploads/default/original/1X/#{sha1}" }
+ before do
+ upload.update!(url: upload.url.sub('.png', ''))
+ upload.reload
+ end
it 'should return the right upload' do
expect(Upload.get_from_url(upload.url)).to eq(upload)
end
end
- describe 'for a url without a tree' do
- let(:url) { "/uploads/default/original/1X/#{sha1}.png" }
+ describe 'for a url a tree' do
+ before do
+ upload.update!(url:
+ Discourse.store.get_path_for(
+ "original",
+ 16001,
+ upload.sha1,
+ ".#{upload.extension}"
+ )
+ )
+ end
it 'should return the right upload' do
expect(Upload.get_from_url(upload.url)).to eq(upload)
@@ -124,8 +135,8 @@ describe Upload do
end
describe "s3 store" do
- let(:path) { "/original/3X/1/0/10f73034616a796dfd70177dc54b6def44c4ba6f.png" }
- let(:url) { "#{SiteSetting.Upload.absolute_base_url}#{path}" }
+ let(:upload) { Fabricate(:upload_s3) }
+ let(:path) { upload.url.sub(SiteSetting.Upload.s3_base_url, '') }
before do
SiteSetting.enable_s3_uploads = true
@@ -136,7 +147,7 @@ describe Upload do
it "should return the right upload when using base url (not CDN) for s3" do
upload
- expect(Upload.get_from_url(url)).to eq(upload)
+ expect(Upload.get_from_url(upload.url)).to eq(upload)
end
describe 'when using a cdn' do
diff --git a/spec/multisite/distributed_cache_spec.rb b/spec/multisite/distributed_cache_spec.rb
index a6080c7576..cdd25dbfaf 100644
--- a/spec/multisite/distributed_cache_spec.rb
+++ b/spec/multisite/distributed_cache_spec.rb
@@ -1,17 +1,8 @@
require 'rails_helper'
-RSpec.describe 'Multisite SiteSettings' do
+RSpec.describe 'Multisite SiteSettings', type: :multisite do
let(:conn) { RailsMultisite::ConnectionManagement }
- before do
- conn.config_filename = "spec/fixtures/multisite/two_dbs.yml"
- end
-
- after do
- conn.clear_settings!
- ActiveRecord::Base.establish_connection
- end
-
def cache(name, namespace: true)
DistributedCache.new(name, namespace: namespace)
end
diff --git a/spec/multisite/jobs_spec.rb b/spec/multisite/jobs_spec.rb
index 0ffd9f47a5..943f33642c 100644
--- a/spec/multisite/jobs_spec.rb
+++ b/spec/multisite/jobs_spec.rb
@@ -1,24 +1,11 @@
require 'rails_helper'
-RSpec.describe "Running Sidekiq Jobs in Multisite" do
+RSpec.describe "Running Sidekiq Jobs in Multisite", type: :multisite do
let(:conn) { RailsMultisite::ConnectionManagement }
- before do
- conn.config_filename = "spec/fixtures/multisite/two_dbs.yml"
- end
-
- after do
- conn.clear_settings!
- ActiveRecord::Base.establish_connection
- end
-
it 'should revert back to the default connection' do
- expect(RailsMultisite::ConnectionManagement.current_db)
- .to eq('default')
-
- Jobs::DestroyOldDeletionStubs.new.perform({})
-
- expect(RailsMultisite::ConnectionManagement.current_db)
- .to eq('default')
+ expect do
+ Jobs::DestroyOldDeletionStubs.new.perform({})
+ end.to_not change { RailsMultisite::ConnectionManagement.current_db }
end
end
diff --git a/spec/multisite/site_settings_spec.rb b/spec/multisite/site_settings_spec.rb
index bfecad7fd3..5a0d7b4719 100644
--- a/spec/multisite/site_settings_spec.rb
+++ b/spec/multisite/site_settings_spec.rb
@@ -1,12 +1,11 @@
require 'rails_helper'
-RSpec.describe 'Multisite SiteSettings' do
+RSpec.describe 'Multisite SiteSettings', type: :multisite do
let(:conn) { RailsMultisite::ConnectionManagement }
before do
@original_provider = SiteSetting.provider
SiteSetting.provider = SiteSettings::DbProvider.new(SiteSetting)
- conn.config_filename = "spec/fixtures/multisite/two_dbs.yml"
end
after do
@@ -14,9 +13,7 @@ RSpec.describe 'Multisite SiteSettings' do
conn.with_connection(db) { SiteSetting.where(name: 'default_locale').destroy_all }
end
- conn.clear_settings!
SiteSetting.provider = @original_provider
- ActiveRecord::Base.establish_connection
end
describe '#default_locale' do
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index b267a16e0e..c1ac476077 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -175,6 +175,17 @@ RSpec.configure do |config|
end
end
+ config.before(:each, type: :multisite) do
+ RailsMultisite::ConnectionManagement.config_filename =
+ "spec/fixtures/multisite/two_dbs.yml"
+ end
+
+ config.after(:each, type: :multisite) do
+ RailsMultisite::ConnectionManagement.clear_settings!
+ ActiveRecord::Base.clear_active_connections!
+ ActiveRecord::Base.establish_connection
+ end
+
class TestCurrentUserProvider < Auth::DefaultCurrentUserProvider
def log_on_user(user, session, cookies)
session[:current_user_id] = user.id
diff --git a/spec/requests/admin/api_controller_spec.rb b/spec/requests/admin/api_controller_spec.rb
index feee32728b..9cf3b6dc73 100644
--- a/spec/requests/admin/api_controller_spec.rb
+++ b/spec/requests/admin/api_controller_spec.rb
@@ -7,57 +7,70 @@ describe Admin::ApiController do
end
let(:admin) { Fabricate(:admin) }
- before do
- sign_in(admin)
- end
- describe '#index' do
- it "succeeds" do
- get "/admin/api/keys.json"
- expect(response.status).to eq(200)
- end
- end
-
- describe '#regenerate_key' do
- let(:api_key) { Fabricate(:api_key) }
-
- it "returns 404 when there is no key" do
- put "/admin/api/key.json", params: { id: 1234 }
- expect(response.status).to eq(404)
+ context "as an admin" do
+ before do
+ sign_in(admin)
end
- it "delegates to the api key's `regenerate!` method" do
- prev_value = api_key.key
- put "/admin/api/key.json", params: { id: api_key.id }
- expect(response.status).to eq(200)
-
- api_key.reload
- expect(api_key.key).not_to eq(prev_value)
- expect(api_key.created_by.id).to eq(admin.id)
- end
- end
-
- describe '#revoke_key' do
- let(:api_key) { Fabricate(:api_key) }
-
- it "returns 404 when there is no key" do
- delete "/admin/api/key.json", params: { id: 1234 }
- expect(response.status).to eq(404)
+ describe '#index' do
+ it "succeeds" do
+ get "/admin/api/keys.json"
+ expect(response.status).to eq(200)
+ end
end
- it "delegates to the api key's `regenerate!` method" do
- delete "/admin/api/key.json", params: { id: api_key.id }
- expect(response.status).to eq(200)
- expect(ApiKey.where(key: api_key.key).count).to eq(0)
+ describe '#regenerate_key' do
+ let(:api_key) { Fabricate(:api_key) }
+
+ it "returns 404 when there is no key" do
+ put "/admin/api/key.json", params: { id: 1234 }
+ expect(response.status).to eq(404)
+ end
+
+ it "delegates to the api key's `regenerate!` method" do
+ prev_value = api_key.key
+ put "/admin/api/key.json", params: { id: api_key.id }
+ expect(response.status).to eq(200)
+
+ api_key.reload
+ expect(api_key.key).not_to eq(prev_value)
+ expect(api_key.created_by.id).to eq(admin.id)
+ end
+ end
+
+ describe '#revoke_key' do
+ let(:api_key) { Fabricate(:api_key) }
+
+ it "returns 404 when there is no key" do
+ delete "/admin/api/key.json", params: { id: 1234 }
+ expect(response.status).to eq(404)
+ end
+
+ it "delegates to the api key's `regenerate!` method" do
+ delete "/admin/api/key.json", params: { id: api_key.id }
+ expect(response.status).to eq(200)
+ expect(ApiKey.where(key: api_key.key).count).to eq(0)
+ end
end
end
describe '#create_master_key' do
it "creates a record" do
+ sign_in(admin)
expect do
post "/admin/api/key.json"
end.to change(ApiKey, :count).by(1)
expect(response.status).to eq(200)
end
+
+ it "doesn't allow moderators to create master keys" do
+ sign_in(Fabricate(:moderator))
+ expect do
+ post "/admin/api/key.json"
+ end.to change(ApiKey, :count).by(0)
+ expect(response.status).to eq(404)
+ end
+
end
end
diff --git a/spec/requests/admin/flags_controller_spec.rb b/spec/requests/admin/flags_controller_spec.rb
index d252eedc77..13ed77dfe7 100644
--- a/spec/requests/admin/flags_controller_spec.rb
+++ b/spec/requests/admin/flags_controller_spec.rb
@@ -34,6 +34,21 @@ RSpec.describe Admin::FlagsController do
end
context '#agree' do
+ it 'should raise a reasonable error if a flag was deferred and then someone else agreed' do
+ SiteSetting.queue_jobs = false
+
+ _post_action = PostAction.act(user, post_1, PostActionType.types[:spam], message: 'bad')
+
+ post "/admin/flags/defer/#{post_1.id}.json"
+ expect(response.status).to eq(200)
+
+ post "/admin/flags/agree/#{post_1.id}.json", params: { action_on_post: 'keep' }
+ # 409 means conflict which is what is happening here
+ expect(response.status).to eq(409)
+ error = JSON.parse(response.body)["errors"].first
+ expect(error).to eq(I18n.t("flags.errors.already_handled"))
+ end
+
it 'should be able to agree and keep content' do
SiteSetting.queue_jobs = false
diff --git a/spec/requests/drafts_controller_spec.rb b/spec/requests/drafts_controller_spec.rb
index bffc3900b5..b9ebf3ce1f 100644
--- a/spec/requests/drafts_controller_spec.rb
+++ b/spec/requests/drafts_controller_spec.rb
@@ -24,4 +24,12 @@ describe DraftsController do
parsed = JSON.parse(response.body)
expect(parsed["drafts"].length).to eq(0)
end
+
+ it 'does not let a user see drafts stream of another user' do
+ user_b = Fabricate(:user)
+ Draft.set(user_b, 'xxx', 0, '{}')
+ sign_in(Fabricate(:user))
+ get "/drafts.json", params: { username: user_b.username }
+ expect(response.status).to eq(403)
+ end
end
diff --git a/spec/services/search_indexer_spec.rb b/spec/services/search_indexer_spec.rb
index e98d52e365..a9f309a489 100644
--- a/spec/services/search_indexer_spec.rb
+++ b/spec/services/search_indexer_spec.rb
@@ -2,6 +2,7 @@ require 'rails_helper'
describe SearchIndexer do
let(:post_id) { 99 }
+
it 'correctly indexes chinese' do
SiteSetting.default_locale = 'zh_CN'
data = "你好世界"
@@ -37,6 +38,27 @@ describe SearchIndexer do
expect(scrubbed).to eq(" HELLO Heterogeneite Здравствуите هتاف للترحيب 你好 ")
end
+ it "doesn't index local files" do
+ html = <<~HTML
+