Merge branch 'keyboard-binding-new-topics-banner' into dismiss-keyboard-bindings

Conflicts:
	app/assets/javascripts/discourse/lib/keyboard_shortcuts.js
This commit is contained in:
cpradio 2014-08-29 09:36:34 -04:00
commit 096bc0c0ae
118 changed files with 1583 additions and 1067 deletions

View File

@ -226,7 +226,7 @@ GEM
omniauth-twitter (1.0.1)
multi_json (~> 1.3)
omniauth-oauth (~> 1.0)
onebox (1.4.5)
onebox (1.4.8)
moneta (~> 0.7)
multi_json (~> 1.7)
mustache (~> 0.99)

View File

@ -9,7 +9,7 @@ export default Ember.ArrayController.extend({
restoreDisabled: Em.computed.alias("status.restoreDisabled"),
restoreTitle: function() {
if (!Discourse.SiteSettings.allow_restore) {
if (!this.get('status.allowRestore')) {
return I18n.t("admin.backups.operations.restore.is_disabled");
} else if (this.get("status.isOperationRunning")) {
return I18n.t("admin.backups.operation_already_running");

View File

@ -1,16 +1,9 @@
/**
Data model for representing the status of backup/restore
@class BackupStatus
@extends Discourse.Model
@namespace Discourse
@module Discourse
**/
Discourse.BackupStatus = Discourse.Model.extend({
restoreDisabled: Em.computed.not("restoreEnabled"),
restoreEnabled: function() {
return Discourse.SiteSettings.allow_restore && !this.get("isOperationRunning");
}.property("isOperationRunning")
return this.get('allowRestore') && !this.get("isOperationRunning");
}.property("isOperationRunning", "allowRestore")
});

View File

@ -31,7 +31,8 @@ Discourse.AdminBackupsRoute = Discourse.Route.extend({
}).then(function (status) {
return Discourse.BackupStatus.create({
isOperationRunning: status.is_operation_running,
canRollback: status.can_rollback
canRollback: status.can_rollback,
allowRestore: status.allow_restore
});
});
},

View File

@ -15,17 +15,6 @@ Discourse.AdminFlagsRouteType = Discourse.Route.extend({
adminFlagsController.set('query', this.get('filter'));
},
actions: {
/**
Deletes a user and all posts and topics created by that user.
@method deleteSpammer
**/
deleteSpammer: function (user) {
user.deleteAsSpammer(function() { window.location.reload(); });
}
}
});
Discourse.AdminFlagsActiveRoute = Discourse.AdminFlagsRouteType.extend({
@ -50,6 +39,3 @@ Discourse.AdminFlagsActiveRoute = Discourse.AdminFlagsRouteType.extend({
Discourse.AdminFlagsOldRoute = Discourse.AdminFlagsRouteType.extend({
filter: 'old'
});

View File

@ -1,29 +0,0 @@
import DiscoveryController from 'discourse/controllers/discovery';
export default DiscoveryController.extend({
needs: ['discovery'],
period: function() {
return this.get('controllers.discovery.periods').findBy('id', this.get('periodId'));
}.property('periodId'),
topicList: function() {
return this.get('model.' + this.get('periodId'));
}.property('periodId'),
actions: {
refresh: function() {
var self = this;
// Don't refresh if we're still loading
if (this.get('controllers.discovery.loading')) { return; }
this.send('loading');
Discourse.TopList.find().then(function(top_lists) {
self.set('model', top_lists);
self.send('loadingComplete');
});
}
}
});

View File

@ -5,6 +5,9 @@ var controllerOpts = {
needs: ['discovery'],
bulkSelectEnabled: false,
selected: [],
period: null,
redirectedReason: Em.computed.alias('currentUser.redirected_to_top_reason'),
order: 'default',
ascending: false,

View File

@ -105,7 +105,7 @@ export default ObjectController.extend(ModalFunctionality, {
changePostActionType: function(action) {
this.set('selected', action);
}
},
},
canDeleteSpammer: function() {
@ -118,11 +118,6 @@ export default ObjectController.extend(ModalFunctionality, {
}
}.property('selected.name_key', 'userDetails.can_be_deleted', 'userDetails.can_delete_all_posts'),
deleteSpammer: function() {
this.send('closeModal');
this.get('userDetails').deleteAsSpammer(function() { window.location.reload(); });
},
usernameChanged: function() {
this.set('userDetails', null);
this.fetchUserDetails();

View File

@ -496,25 +496,30 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, {
}
var postStream = topicController.get('postStream');
if (data.type === "revised" || data.type === "acted"){
if (data.type === "revised" || data.type === "acted") {
// TODO we could update less data for "acted"
// (only post actions)
postStream.triggerChangedPost(data.id, data.updated_at);
return;
}
if (data.type === "deleted"){
if (data.type === "deleted") {
postStream.triggerDeletedPost(data.id, data.post_number);
return;
}
if (data.type === "recovered"){
if (data.type === "recovered") {
postStream.triggerRecoveredPost(data.id, data.post_number);
return;
}
// Add the new post into the stream
postStream.triggerNewPostInStream(data.id);
if (data.type === "created") {
postStream.triggerNewPostInStream(data.id);
return;
}
// log a warning
Em.Logger.warn("unknown topic bus message type", data);
});
},

View File

@ -18,6 +18,17 @@ export default {
app["Discovery" + filter.capitalize() + "CategoryNoneRoute"] = buildCategoryRoute(filter, {no_subcategories: true});
});
Discourse.DiscoveryTopRoute = buildTopicRoute('top', {
actions: {
willTransition: function() {
Discourse.User.currentProp("should_be_redirected_to_top", false);
Discourse.User.currentProp("redirected_to_top_reason", null);
}
}
});
Discourse.DiscoveryTopCategoryRoute = buildCategoryRoute('top');
Discourse.DiscoveryTopCategoryNoneRoute = buildCategoryRoute('top', {no_subcategories: true});
Discourse.Site.currentProp('periods').forEach(function(period) {
app["DiscoveryTop" + period.capitalize() + "Controller"] = DiscoverySortableController.extend();
app["DiscoveryTop" + period.capitalize() + "Route"] = buildTopicRoute('top/' + period);

View File

@ -31,17 +31,17 @@ Discourse.KeyboardShortcuts = Ember.Object.createWithMixins({
// star topic
'f': '#topic-footer-buttons button.star, .topic-list tr.topic-list-item.selected a.star',
'm m': 'div.notification-options li[data-id="0"] a', // mark topic as muted
'm r': 'div.notification-options li[data-id="1"] a', // mark topic as regular
'm t': 'div.notification-options li[data-id="2"] a', // mark topic as tracking
'm w': 'div.notification-options li[data-id="3"] a', // mark topic as watching
'x r': '#dismiss-new,#dismiss-new-top,#dismiss-posts,#dismiss-posts-top', // dismiss new/posts
'x t': '#dismiss-topics,#dismiss-topics-top', // dismiss topics
'n': '#user-notifications', // open notifications menu
'o,enter': '.topic-list tr.selected a.title', // open selected topic
'shift+r': '#topic-footer-buttons button.create', // reply to topic
'shift+s': '#topic-footer-buttons button.share', // share topic
's': '.topic-post.selected a.post-date' // share post
'm m': 'div.notification-options li[data-id="0"] a', // mark topic as muted
'm r': 'div.notification-options li[data-id="1"] a', // mark topic as regular
'm t': 'div.notification-options li[data-id="2"] a', // mark topic as tracking
'm w': 'div.notification-options li[data-id="3"] a', // mark topic as watching
'n': '#user-notifications', // open notifications menu
'=': '#site-map', // open site map menu
'p': '#current-user', // open current user menu
'o,enter': '.topic-list tr.selected a.title', // open selected topic
'shift+r': '#topic-footer-buttons button.create', // reply to topic
'shift+s': '#topic-footer-buttons button.share', // share topic
's': '.topic-post.selected a.post-date' // share post
},
FUNCTION_BINDINGS: {
@ -54,8 +54,7 @@ Discourse.KeyboardShortcuts = Ember.Object.createWithMixins({
'`': 'nextSection',
'~': 'prevSection',
'/': 'showSearch',
'=': 'showSiteMap', // open site map menu
'p': 'showCurrentUser', // open current user menu
'.': 'showIncomingUpdatedTopics', // show incoming topics
'ctrl+f': 'showBuiltinSearch',
'command+f': 'showBuiltinSearch',
'?': 'showHelpModal', // open keyboard shortcut help
@ -135,6 +134,11 @@ Discourse.KeyboardShortcuts = Ember.Object.createWithMixins({
}
},
showIncomingUpdatedTopics: function() {
$('.alert .alert-info .clickable').click();
return false;
},
toggleProgress: function() {
Discourse.__container__.lookup('controller:topic-progress').send('toggleExpansion', {highlight: true});
},
@ -147,16 +151,6 @@ Discourse.KeyboardShortcuts = Ember.Object.createWithMixins({
return false;
},
showSiteMap: function() {
$('#site-map').click();
$('#site-map-dropdown a:first').focus();
},
showCurrentUser: function() {
$('#current-user').click();
$('#user-dropdown a:first').focus();
},
showHelpModal: function() {
Discourse.__container__.lookup('controller:application').send('showKeyboardShortcutsHelp');
},

View File

@ -23,6 +23,7 @@ Discourse.Search = {
// Only include the data we have
var data = { term: term };
if (opts.typeFilter) data.type_filter = opts.typeFilter;
if (opts.searchForId) data.search_for_id = true;
if (opts.searchContext) {
data.search_context = {

View File

@ -188,6 +188,8 @@ Discourse.Category = Discourse.Model.extend({
}.property('id')
});
var _uncategorized;
Discourse.Category.reopenClass({
NotificationLevel: {
@ -197,6 +199,11 @@ Discourse.Category.reopenClass({
MUTED: 0
},
findUncategorized: function() {
_uncategorized = _uncategorized || Discourse.Category.list().findBy('id', Discourse.Site.currentProp('uncategorized_category_id'));
return _uncategorized;
},
slugFor: function(category) {
if (!category) return "";

View File

@ -1,37 +0,0 @@
/**
A data model representing a list of top topic lists
@class TopList
@extends Discourse.Model
@namespace Discourse
@module Discourse
**/
Discourse.TopList = Discourse.Model.extend({});
Discourse.TopList.reopenClass({
find: function(filter) {
return PreloadStore.getAndRemove("top_lists", function() {
var url = Discourse.getURL("/") + (filter || "top") + ".json";
return Discourse.ajax(url);
}).then(function (result) {
var topList = Discourse.TopList.create({
can_create_topic: result.can_create_topic,
draft: result.draft,
draft_key: result.draft_key,
draft_sequence: result.draft_sequence
});
Discourse.Site.currentProp('periods').forEach(function(period) {
// if there is a list for that period
if (result[period]) {
// instanciate a new topic list with no sorting
topList.set(period, Discourse.TopicList.from(result[period]));
topList.set('periodId', period);
}
});
return topList;
});
}
});

View File

@ -176,6 +176,7 @@ Discourse.TopicList.reopenClass({
draft_key: result.topic_list.draft_key,
draft_sequence: result.topic_list.draft_sequence,
draft: result.topic_list.draft,
for_period: result.topic_list.for_period,
loaded: true
});

View File

@ -136,7 +136,16 @@ var ApplicationRoute = Em.Route.extend({
router.controllerFor('editCategory').set('selectedTab', 'general');
});
}
},
/**
Deletes a user and all posts and topics created by that user.
@method deleteSpammer
**/
deleteSpammer: function (user) {
this.send('closeModal');
user.deleteAsSpammer(function() { window.location.reload(); });
}
},

View File

@ -63,7 +63,7 @@ export default function(filter, params) {
setupController: function(controller, model) {
var topics = this.get('topics'),
periods = this.controllerFor('discovery').get('periods'),
periodId = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
periodId = topics.get('for_period') || (filter.indexOf('/') > 0 ? filter.split('/')[1] : ''),
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
Discourse.set('title', I18n.t('filters.with_category', { filter: filterText, category: model.get('name') }));

View File

@ -12,7 +12,8 @@ export function filterQueryParams(params, defaultParams) {
return findOpts;
}
export default function(filter) {
export default function(filter, extras) {
extras = extras || {};
return Discourse.Route.extend({
queryParams: queryParams,
@ -36,7 +37,7 @@ export default function(filter) {
})));
var periods = this.controllerFor('discovery').get('periods'),
periodId = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
periodId = model.get('for_period') || (filter.indexOf('/') > 0 ? filter.split('/')[1] : ''),
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
if (filter === Discourse.Utilities.defaultHomepage()) {
@ -61,6 +62,6 @@ export default function(filter) {
this.render('navigation/default', { outlet: 'navigation-bar' });
this.render('discovery/topics', { controller: 'discovery/topics', outlet: 'list-container' });
}
});
}, extras);
}

View File

@ -186,7 +186,9 @@ Ember.DiscourseLocation = Ember.Object.extend({
if (self.getURL() === self._previousURL) { return; }
}
var url = self.getURL();
popstateCallbacks.forEach(function(cb) { cb(url); });
popstateCallbacks.forEach(function(cb) {
cb(url);
});
callback(url);
});
},
@ -226,6 +228,16 @@ Ember.CloakedCollectionView.reopen({
_watchForPopState: function() {
var self = this,
cb = function() {
// Sam: This is a hack, but a very important one
// Due to the way we use replace state the back button works strangely
//
// If you visit a topic from the front page, scroll a bit around and then hit back
// you notice that first the page scrolls a bit (within the topic) and then it goes back
// this transition is jarring and adds uneeded rendering costs.
//
// To repro comment the hack out and wack a debugger statement here and in
// topic_route deactivate
$('.posts,#topic-title').hide();
self.cleanUp();
self.set('controller.postStream.loaded', false);
};

View File

@ -1,123 +0,0 @@
/**
Handles the routes related to 'Top'
@class DiscoveryTopRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.DiscoveryTopRoute = Discourse.Route.extend(Discourse.OpenComposer, {
beforeModel: function() {
this.controllerFor('navigation/default').set('filterMode', 'top');
},
model: function() {
return Discourse.TopList.find();
},
setupController: function(controller, model) {
var filterText = I18n.t('filters.top.title');
Discourse.set('title', I18n.t('filters.with_topics', {filter: filterText}));
this.controllerFor('discovery/top').setProperties({ model: model, category: null });
this.controllerFor('navigation/default').set('canCreateTopic', model.get('can_create_topic'));
this.openTopicDraft(model);
},
renderTemplate: function() {
this.render('navigation/default', { outlet: 'navigation-bar' });
this.render('discovery/top', { outlet: 'list-container' });
},
actions: {
willTransition: function () {
Discourse.User.currentProp("should_be_redirected_to_top", false);
Discourse.User.currentProp("redirected_to_top_reason", null);
},
createTopic: function() {
this.openComposer(this.controllerFor('discovery/top'));
}
}
});
/**
Handles the routes related to 'Top' within a category
@class DiscoveryTopCategoryRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.DiscoveryTopCategoryRoute = Discourse.Route.extend(Discourse.OpenComposer, {
model: function(params) {
return Discourse.Category.findBySlug(params.slug, params.parentSlug);
},
afterModel: function(model) {
var self = this,
noSubcategories = this.get('no_subcategories'),
filterMode = 'category/' + Discourse.Category.slugFor(model) + (noSubcategories ? '/none' : '') + '/l/top';
this.controllerFor('search').set('searchContext', model);
var opts = { category: model, filterMode: filterMode };
opts.noSubcategories = noSubcategories;
opts.canEditCategory = model.get('can_edit');
this.controllerFor('navigation/category').setProperties(opts);
return Discourse.TopList.find(filterMode).then(function(list) {
// If all the categories are the same, we can hide them
var hideCategory = !_.any(Discourse.Site.currentProp('periods'), function(period){
if (list[period]) {
return list[period].get('topics').find(function(t) { return t.get('category') !== model; });
}
return false;
});
list.set('hideCategory', hideCategory);
self.set('topList', list);
});
},
setupController: function(controller, model) {
var topList = this.get('topList');
var filterText = I18n.t('filters.top.title');
Discourse.set('title', I18n.t('filters.with_category', {filter: filterText, category: model.get('name').capitalize()}));
this.controllerFor('navigation/category').set('canCreateTopic', topList.get('can_create_topic'));
this.controllerFor('discovery/top').setProperties({
model: topList,
category: model,
noSubcategories: this.get('no_subcategories')
});
this.set('topList', null);
},
renderTemplate: function() {
this.render('navigation/category', { outlet: 'navigation-bar' });
this.render('discovery/top', { controller: 'discovery/top', outlet: 'list-container' });
},
deactivate: function() {
this._super();
this.controllerFor('search').set('searchContext', null);
},
actions: {
willTransition: function () {
Discourse.User.currentProp("should_be_redirected_to_top", false);
Discourse.User.currentProp("redirected_to_top_reason", null);
},
createTopic: function() {
this.openComposer(this.controllerFor('discovery/top'));
}
}
});
Discourse.DiscoveryTopCategoryNoneRoute = Discourse.DiscoveryTopCategoryRoute.extend({no_subcategories: true});

View File

@ -1,24 +0,0 @@
<div class="top-lists">
{{#if currentUser.redirected_to_top_reason}}
<div class="alert alert-info">{{currentUser.redirected_to_top_reason}}</div>
{{/if}}
{{#if topicList}}
<div class="clearfix">
{{top-period-chooser period=period}}
{{basic-topic-list topicList=topicList hideCategory=hideCategory postsAction="showTopicEntrance"}}
{{#if topicList.topics.length}}<a href="{{unbound period.showMoreUrl}}" class='btn btn-default pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
<footer class="topic-list-bottom">
<h3>
{{#if hasDisplayedAllTopLists}}
{{#link-to "discovery.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}} {{i18n or}} {{#link-to 'discovery.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}}.
{{else}}
{{#link-to "discovery.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}}, {{#link-to 'discovery.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}} {{i18n or}} {{i18n filters.top.other_periods}}
{{top-period-buttons period=period}}
{{/if}}
</h3>
</footer>
</div>

View File

@ -1,3 +1,7 @@
{{#if redirectedReason}}
<div class="alert alert-info">{{redirectedReason}}</div>
{{/if}}
{{#if showDismissAtTop}}
<div class="row">
{{#if showDismissRead}}

View File

@ -28,7 +28,6 @@
{{/if}}
{{#if canDeleteSpammer}}
<button class="btn btn-danger" {{action deleteSpammer}} {{bind-attr disabled="submitDisabled"}} title="{{i18n flagging.delete_spammer}}"><i class="fa fa-exclamation-triangle"></i> {{i18n flagging.delete_spammer}}</button>
<button class="btn btn-danger" {{action deleteSpammer userDetails}} {{bind-attr disabled="submitDisabled"}} title="{{i18n flagging.delete_spammer}}"><i class="fa fa-exclamation-triangle"></i> {{i18n flagging.delete_spammer}}</button>
{{/if}}
</div>

View File

@ -27,6 +27,7 @@
<li>{{{i18n keyboard_shortcuts_help.application.site_map_menu}}}</li>
<li>{{{i18n keyboard_shortcuts_help.application.user_profile_menu}}}</li>
<li>{{{i18n keyboard_shortcuts_help.application.search}}}</li>
<li>{{{i18n keyboard_shortcuts_help.application.show_incoming_updated}}}</li>
<li>{{{i18n keyboard_shortcuts_help.application.help}}}</li>
<li>{{{i18n keyboard_shortcuts_help.application.dismiss_new_posts}}}</li>
<li>{{{i18n keyboard_shortcuts_help.application.dismiss_topics}}}</li>

View File

@ -34,7 +34,7 @@ export default ComboboxView.extend({
if (this.get('rootNone')) {
return "category.none";
} else {
return Discourse.Category.list().findBy('id', Discourse.Site.currentProp('uncategorized_category_id'));
return Discourse.Category.findUncategorized();
}
} else {
return 'category.choose';
@ -42,9 +42,20 @@ export default ComboboxView.extend({
}.property(),
template: function(item) {
var category = Discourse.Category.findById(parseInt(item.id,10));
if (!category) return item.text;
var category;
// If we have no id, but text with the uncategorized name, we can use that badge.
if (Em.empty(item.id)) {
var uncat = Discourse.Category.findUncategorized();
if (uncat && uncat.get('name') === item.text) {
category = uncat;
}
} else {
category = Discourse.Category.findById(parseInt(item.id,10));
}
if (!category) return item.text;
var result = badgeHtml(category, {showParent: false, link: false, allowUncategorized: true}),
parentCategoryId = category.get('parent_category_id');
if (parentCategoryId) {
@ -56,7 +67,6 @@ export default ComboboxView.extend({
var description = category.get('description');
// TODO wtf how can this be null?;
if (description && description !== 'null') {
result += '<div class="category-desc">' +
description.substr(0,200) +
(description.length > 200 ? '&hellip;' : '') +

View File

@ -30,7 +30,7 @@ export default Discourse.View.extend({
self.setProperties({ topics: null, loading: false });
return;
}
Discourse.Search.forTerm(title, {typeFilter: 'topic'}).then(function (facets) {
Discourse.Search.forTerm(title, {typeFilter: 'topic', searchForId: true}).then(function (facets) {
if (facets && facets[0] && facets[0].results) {
self.set('topics', facets[0].results);
} else {

View File

@ -8,6 +8,7 @@
background: scale-color($tertiary, $lightness: 90%);
@include box-shadow(0 1px 2px scale-color($tertiary, $lightness: 70%));
z-index: 501;
overflow: auto;
&.overlay {
position: fixed;

View File

@ -4,14 +4,6 @@
#banner {
margin-bottom: 10px;
}
@media all
and (min-width: 1090px) {
width: 1090px;
}
@media all
and (max-width: 1090px) {
width: 100%;
max-width: 1090px;
max-height: 250px;
}

View File

@ -4,4 +4,13 @@
#banner {
margin: 10px;
@media all and (max-height: 499px) {
max-height: 100px;
}
@media all and (min-height: 500px) {
max-height: 180px;
}
}

View File

@ -212,11 +212,14 @@ class ApplicationController < ActionController::Base
Middleware::AnonymousCache.anon_cache(request.env, time_length)
end
def fetch_user_from_params
def fetch_user_from_params(opts=nil)
opts ||= {}
user = if params[:username]
username_lower = params[:username].downcase
username_lower.gsub!(/\.json$/, '')
User.find_by(username_lower: username_lower, active: true)
find_opts = {username_lower: username_lower}
find_opts[:active] = true unless opts[:include_inactive]
User.find_by(find_opts)
elsif params[:external_id]
SingleSignOnRecord.find_by(external_id: params[:external_id]).try(:user)
end

View File

@ -130,43 +130,22 @@ class ListController < ApplicationController
redirect_to latest_path, :status => 301
end
def top(options = nil)
discourse_expires_in 1.minute
top_options = build_topic_list_options
top_options.merge!(options) if options
top = generate_top_lists(top_options)
top.draft_key = Draft::NEW_TOPIC
top.draft_sequence = DraftSequence.current(current_user, Draft::NEW_TOPIC)
top.draft = Draft.get(current_user, top.draft_key, top.draft_sequence) if current_user
respond_to do |format|
format.html do
@top = top
store_preloaded('top_lists', MultiJson.dump(TopListSerializer.new(top, scope: guardian, root: false)))
render 'top'
end
format.json do
render json: MultiJson.dump(TopListSerializer.new(top, scope: guardian, root: false))
end
end
def top(options=nil)
options ||= {}
period = ListController.best_period_for(current_user.try(:previous_visit_at), options[:category])
send("top_#{period}", options)
end
def category_top
options = { category: @category.id }
top(options)
top({ category: @category.id })
end
def category_none_top
options = { category: @category.id, no_subcategories: true }
top(options)
top({ category: @category.id, no_subcategories: true })
end
def parent_category_category_top
options = { category: @category.id }
top(options)
top({ category: @category.id })
end
TopTopic.periods.each do |period|
@ -176,6 +155,7 @@ class ListController < ApplicationController
top_options[:per_page] = SiteSetting.topics_per_period_in_top_page
user = list_target_user
list = TopicQuery.new(user, top_options).list_top_for(period)
list.for_period = period
list.more_topics_url = construct_next_url_with(top_options)
list.prev_topics_url = construct_prev_url_with(top_options)
respond(list)
@ -189,7 +169,7 @@ class ListController < ApplicationController
self.send("top_#{period}", { category: @category.id, no_subcategories: true })
end
define_method("parent_category_category_#{period}") do
define_method("parent_category_category_top_#{period}") do
self.send("top_#{period}", { category: @category.id })
end
end

View File

@ -0,0 +1,12 @@
class PermalinksController < ApplicationController
skip_before_filter :check_xhr, :preload_json
def show
permalink = Permalink.find_by_url(params[:url])
if permalink && permalink.target_url
redirect_to permalink.target_url, status: :moved_permanently
else
raise Discourse::NotFound
end
end
end

View File

@ -8,12 +8,13 @@ class SearchController < ApplicationController
def query
params.require(:term)
search_args = {guardian: guardian}
search_args[:type_filter] = params[:type_filter] if params[:type_filter].present?
if params[:include_blurbs].present?
search_args[:include_blurbs] = params[:include_blurbs] == "true"
end
search_args[:search_for_id] = true if params[:search_for_id].present?
search_context = params[:search_context]
if search_context.present?

View File

@ -54,13 +54,21 @@ class StaticController < ApplicationController
params.delete(:username)
params.delete(:password)
redirect_to(
if params[:redirect].blank? || params[:redirect].match(login_path)
"/"
else
params[:redirect]
destination = "/"
if params[:redirect].present? && !params[:redirect].match(login_path)
begin
forum_uri = URI(Discourse.base_url)
uri = URI(params[:redirect])
if uri.path.present? && (uri.host.blank? || uri.host == forum_uri.host)
destination = uri.path
end
rescue URI::InvalidURIError
# Do nothing if the URI is invalid
end
)
end
redirect_to destination
end
skip_before_filter :verify_authenticity_token, only: [:cdn_asset]

View File

@ -302,7 +302,7 @@ class UsersController < ApplicationController
end
def send_activation_email
@user = fetch_user_from_params
@user = fetch_user_from_params(include_inactive: true)
@email_token = @user.email_tokens.unconfirmed.active.first
enqueue_activation_email if @user
render nothing: true

View File

@ -32,7 +32,11 @@ module ApplicationHelper
end
def html_classes
"#{mobile_view? ? 'mobile-view' : 'desktop-view'} #{mobile_device? ? 'mobile-device' : 'not-mobile-device'} #{rtl_view? ? 'rtl' : ''}"
"#{mobile_view? ? 'mobile-view' : 'desktop-view'} #{mobile_device? ? 'mobile-device' : 'not-mobile-device'} #{rtl_class}"
end
def rtl_class
RTL.new(current_user).css_class
end
def escape_unicode(javascript)
@ -131,21 +135,6 @@ module ApplicationHelper
MobileDetection.mobile_device?(request.user_agent)
end
def rtl_view?
site_default_rtl? || current_user_rtl?
end
def current_user_rtl?
SiteSetting.allow_user_locale && current_user.try(:locale).in?(rtl_locales)
end
def site_default_rtl?
!SiteSetting.allow_user_locale && SiteSetting.default_locale.in?(rtl_locales)
end
def rtl_locales
%w(he ar)
end
def customization_disabled?
controller.class.name.split("::").first == "Admin" || session[:disable_customization]

View File

@ -16,7 +16,10 @@ module Jobs
cp.post_process(args[:bypass_bump])
# If we changed the document, save it
post.update_column(:cooked, cp.html) if cp.dirty?
if cp.dirty?
post.update_column(:cooked, cp.html)
post.publish_change_to_clients! :revised
end
end
end

View File

@ -8,14 +8,14 @@ require_dependency 'email/message_builder'
module Jobs
class PollMailbox < Jobs::Scheduled
every SiteSetting.pop3s_polling_period_mins.minutes
every SiteSetting.pop3_polling_period_mins.minutes
sidekiq_options retry: false
include Email::BuildEmailHelper
def execute(args)
@args = args
if SiteSetting.pop3s_polling_enabled?
poll_pop3s
if SiteSetting.pop3_polling_enabled?
poll_pop3
end
end
@ -72,14 +72,11 @@ module Jobs
end
end
def poll_pop3s
if !SiteSetting.pop3s_polling_insecure
Net::POP3.enable_ssl(OpenSSL::SSL::VERIFY_NONE)
end
Net::POP3.start(SiteSetting.pop3s_polling_host,
SiteSetting.pop3s_polling_port,
SiteSetting.pop3s_polling_username,
SiteSetting.pop3s_polling_password) do |pop|
def poll_pop3
connection = Net::POP3.new(SiteSetting.pop3_polling_host, SiteSetting.pop3_polling_port)
connection.enable_ssl if SiteSetting.pop3_polling_ssl
connection.start(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) do |pop|
unless pop.mails.empty?
pop.each do |mail|
handle_mail(mail)

View File

@ -198,7 +198,11 @@ class UserNotifications < ActionMailer::Base
html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render(
template: 'email/notification',
format: :html,
locals: { context_posts: context_posts, post: post, top: top ? PrettyText.cook(top).html_safe : nil }
locals: { context_posts: context_posts,
post: post,
top: top ? PrettyText.cook(top).html_safe : nil,
classes: RTL.new(user).css_class
}
)
template = "user_notifications.user_#{notification_type}"

View File

@ -126,10 +126,12 @@ class DiscourseSingleSignOn < SingleSignOn
avatar_force_update.to_i != 0 ||
sso_record.external_avatar_url != avatar_url)
begin
tempfile = FileHelper.download(avatar_url, 1.megabyte, "sso-avatar")
tempfile = FileHelper.download(avatar_url, 1.megabyte, "sso-avatar", true)
upload = Upload.create_for(user.id, tempfile, "external-avatar", File.size(tempfile.path), { origin: avatar_url })
ext = FastImage.type(tempfile).to_s
tempfile.rewind
upload = Upload.create_for(user.id, tempfile, "external-avatar." + ext, File.size(tempfile.path), { origin: avatar_url })
user.uploaded_avatar_id = upload.id
if !user.user_avatar.contains_upload?(upload.id)

21
app/models/permalink.rb Normal file
View File

@ -0,0 +1,21 @@
class Permalink < ActiveRecord::Base
belongs_to :topic
belongs_to :post
belongs_to :category
before_validation :normalize_url
def normalize_url
if self.url
self.url = self.url.strip
self.url = self.url[1..-1] if url[0,1] == '/'
end
end
def target_url
return post.url if post
return topic.relative_url if topic
return category.url if category
nil
end
end

View File

@ -87,6 +87,15 @@ class Post < ActiveRecord::Base
end
end
def publish_change_to_clients!(type)
MessageBus.publish("/topic/#{topic_id}", {
id: id,
post_number: post_number,
updated_at: Time.now,
type: type
}, group_ids: topic.secure_group_ids)
end
def trash!(trashed_by=nil)
self.topic_links.each(&:destroy)
super(trashed_by)

View File

@ -375,13 +375,7 @@ class PostAction < ActiveRecord::Base
def notify_subscribers
if (is_like? || is_flag?) && post
MessageBus.publish("/topic/#{post.topic_id}",{
id: post.id,
post_number: post.post_number,
type: "acted"
},
group_ids: post.topic.secure_group_ids
)
post.publish_change_to_clients! :acted
end
end

29
app/models/rtl.rb Normal file
View File

@ -0,0 +1,29 @@
class RTL
attr_reader :user
def initialize(user)
@user = user
end
def enabled?
site_locale_rtl? || current_user_rtl?
end
def current_user_rtl?
SiteSetting.allow_user_locale && user.try(:locale).in?(rtl_locales)
end
def site_locale_rtl?
!SiteSetting.allow_user_locale && SiteSetting.default_locale.in?(rtl_locales)
end
def rtl_locales
%w(he ar)
end
def css_class
enabled? ? 'rtl' : ''
end
end

View File

@ -8,7 +8,8 @@ class TopicList
:draft,
:draft_key,
:draft_sequence,
:filter
:filter,
:for_period
def initialize(filter, current_user, topics)
@filter = filter

View File

@ -4,7 +4,8 @@ class TopicListSerializer < ApplicationSerializer
:more_topics_url,
:draft,
:draft_key,
:draft_sequence
:draft_sequence,
:for_period
has_many :topics, serializer: TopicListItemSerializer, embed: :objects
@ -12,6 +13,10 @@ class TopicListSerializer < ApplicationSerializer
scope.can_create?(Topic)
end
def include_for_period?
for_period.present?
end
def include_more_topics_url?
object.more_topics_url.present? && (object.topics.size == SiteSetting.topics_per_page)
end

View File

@ -1,4 +1,4 @@
<div id='main'>
<div id='main' class=<%= classes %>>
<% if top.present? %>
<div><%= top %></div>

View File

@ -23,7 +23,6 @@
$('#activate-account-form').submit();
}).fail(function() {
$('#activate-account-button').prop('disabled', false);
console.log('test');
});
}

View File

@ -91,7 +91,7 @@ module Discourse
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [
:password,
:pop3s_polling_password,
:pop3_polling_password,
:s3_secret_access_key,
:twitter_consumer_secret,
:facebook_app_secret,
@ -148,6 +148,14 @@ module Discourse
require 'auth'
Discourse.activate_plugins! unless Rails.env.test? and ENV['LOAD_PLUGINS'] != "1"
# FIXME: needs to work with engines such as docker manager
# this mounts routes_last before the engine, one option here if a hook is to hard
# is to add a constraint on the route that ensures its only captured if its a permalink
#
# initializer :add_last_routes, :after => :add_routing_paths do |app|
# app.routes_reloader.paths << File.join(Rails.root, 'config', 'routes_last.rb')
# end
config.after_initialize do
# So open id logs somewhere sane
OpenID::Util.logger = Rails.logger

View File

@ -47,7 +47,7 @@ Discourse::Application.configure do
require 'rbtrace'
if emails = GlobalSetting.developer_emails
config.developer_emails = emails.split(",")
config.developer_emails = emails.split(",").map(&:strip!)
end
end

View File

@ -61,7 +61,7 @@ Discourse::Application.configure do
# developers have god like rights and may impersonate anyone in the system
# normal admins may only impersonate other moderators (not admins)
if emails = GlobalSetting.developer_emails
config.developer_emails = emails.split(",")
config.developer_emails = emails.split(",").map(&:strip!)
end
end

View File

@ -626,7 +626,6 @@ da:
invitee_accepted: "<i title='accepterede din invitation' class='fa fa-user'></i><p><span>{{username}}</span> accepted your invitation</p>"
moved_post: "<i title='indlæg flyttet' class='fa fa-sign-out'></i><p><span>{{username}}</span> moved {{description}}</p>"
linked: "<i title='indlæg linket' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge givet' class='fa fa-certificate'></i><p>You were granted {{description}}</p>"
upload_selector:
title: "Indsæt billede"
title_with_attachments: "Tilføj et billede eller en fil"

View File

@ -287,7 +287,7 @@ de:
muted_categories: "Stummgeschaltet"
muted_categories_instructions: "Du erhältst keine Benachrichtigungen über neue Themen in diesen Kategorien und sie werden nicht in deiner Liste ungelesener Themen aufscheinen."
delete_account: "Lösche mein Benutzerkonto"
delete_account_confirm: "Bist du sicher, dass du dein Benutzerkonto permanent löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden!"
delete_account_confirm: "Möchtest du wirklich dein Benutzerkonto permanent löschen? Diese Aktion kann nicht rückgängig gemacht werden!"
deleted_yourself: "Dein Benutzerkonto wurde erfolgreich gelöscht."
delete_yourself_not_allowed: "Du kannst im Moment dein Benutzerkonto nicht löschen. Kontaktiere einen Administrator, um dein Benutzerkonto löschen zu lassen."
unread_message_count: "Nachrichten"
@ -310,7 +310,7 @@ de:
title: "„Über mich“ ändern"
change_username:
title: "Benutzernamen ändern"
confirm: "Wenn du deinen Benutzernamen änderst, werden alle derzeit vorhandenen Zitate deiner Beiträge und alle Erwähnungen per @Name nicht mehr funktionieren. Bist Du sicher, dass du fortfahren willst?"
confirm: "Wenn du deinen Benutzernamen änderst, werden alle derzeit vorhandenen Zitate deiner Beiträge und alle Erwähnungen per @Name nicht mehr funktionieren. Bist du dir absolut sicher, dass du fortfahren willst?"
taken: "Der Benutzername ist bereits vergeben."
error: "Bei der Änderung deines Benutzernamens ist ein Fehler aufgetreten."
invalid: "Der Benutzernamen ist nicht zulässig. Er darf nur Zahlen und Buchstaben enthalten."
@ -333,16 +333,19 @@ de:
title: "Profilhintergrund"
email:
title: "E-Mail"
instructions: "Wird niemals öffentlich angezeigt."
ok: "Schaut gut aus. Wir schicken dir eine E-Mail zur Bestätigung."
invalid: "Bitte gib eine gültige E-Mail-Adresse ein."
authenticated: "Deine E-Mail-Adresse wurde von {{provider}} bestätigt."
frequency: "Wir werden dir nur E-Mails senden, wenn wir dich kürzlich nicht gesehen haben und wenn du die betroffenen Inhalte noch nicht gesehen hast."
name:
title: "Name"
instructions: "Längere Version deines Namens."
too_short: "Dein Name ist zu kurz."
ok: "Dein Name schaut gut aus."
username:
title: "Benutzername"
instructions: "Muss eindeutig, ohne Leerzeichen und kurz sein."
short_instructions: "Andere Benutzer können dich mit @{{username}} erwähnen."
available: "Dein Benutzername ist verfügbar."
global_match: "Die E-Mail-Adresse stimmt mit dem registrierten Benutzernamen überein."
@ -368,7 +371,7 @@ de:
website: "Website"
email_settings: "E-Mail"
email_digests:
title: "Schicke eine E-Mail mit Neuigkeiten, wenn ich die Seite länger nicht besuche:"
title: "Schicke eine E-Mail mit Neuigkeiten, wenn ich die Website länger nicht besuche:"
daily: "täglich"
weekly: "wöchentlich"
bi_weekly: "alle zwei Wochen"
@ -447,10 +450,13 @@ de:
prev_page: "während des Ladens"
reasons:
network: "Netzwerkfehler"
server: "Server-Fehler"
forbidden: "Zugriff verweigert"
unknown: "Fehler"
desc:
network: "Bitte überprüfe deine Netzwerkverbindung."
network_fixed: "Sieht aus, als wäre es wieder da."
server: "Fehlercode: {{status}}"
unknown: "Etwas ist schief gelaufen."
buttons:
back: "Zurück"
@ -459,8 +465,8 @@ de:
close: "Schließen"
assets_changed_confirm: "Diese Website wurde gerade aktualisiert. Neu laden für die neuste Version?"
read_only_mode:
enabled: "Ein Administrator hat den Nur-Lesen-Modus aktiviert. Du kannst die Seite weiter durchsuchen und lesen. Einige Funktionen werden jedoch wahrscheinlich nicht funktionieren."
login_disabled: "Login ist deaktiviert während sich die Seite im Nur-Lesen-Modus befindet."
enabled: "Ein Administrator hat den Nur-Lesen-Modus aktiviert. Du kannst die Website weiter durchsuchen und lesen. Einige Funktionen werden jedoch wahrscheinlich nicht funktionieren."
login_disabled: "Die Anmeldung ist deaktiviert während sich die Website im Nur-Lesen-Modus befindet."
too_few_topics_notice: "Erstelle mindestens 5 öffentlich sichtbare Themen und %{posts} öffentlich sichtbare Beiträge, um die Unterhaltung ins Rollen zu bringen. Neue Benutzer können ihre Vertrauensstufe nur erhöhen, wenn es für sie etwas zu Lesen gibt. Diese Meldung wird nur Mitarbeitern angezeigt."
learn_more: "mehr erfahren..."
year: 'Jahr'
@ -605,7 +611,7 @@ de:
redo_title: "Wiederholen"
help: "Hilfe zur Markdown-Formatierung"
toggler: "Eingabebereich aus- oder einblenden"
admin_options_title: "Optionale Moderator-Einstellungen für dieses Thema"
admin_options_title: "Optionale Mitarbeiter-Einstellungen für dieses Thema"
auto_close_label: "Schließe das Thema automatisch nach:"
auto_close_units: "(Stunden, Uhrzeit oder Datum)"
auto_close_examples: 'Gib eine Anzahl von Stunden, eine Uhrzeit oder ein Datum ein — 24, 17:00, 2013-11-22 14:00'
@ -626,7 +632,6 @@ de:
invitee_accepted: "<i title='Einladung angenommen' class='fa fa-user'></i><p><span>{{username}}</span> hat deine Einladung angenommen</p>"
moved_post: "<i title='Beitrag verschoben' class='fa fa-sign-out'></i><p><span>{{username}}</span> hat {{description}} verschoben</p>"
linked: "<i title='Beitrag verlinkt' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='Abzeichen verliehen' class='fa fa-certificate'></i><p>Dir wurde das Abzeichen {{description}} verliehen</p>"
upload_selector:
title: "Ein Bild hinzufügen"
title_with_attachments: "Ein Bild oder eine Datei hinzufügen"
@ -651,7 +656,7 @@ de:
site_map: "zu einer anderen Themenliste oder Kategorie wechseln"
go_back: 'zurückgehen'
not_logged_in_user: 'Benutzerseite mit einer Zusammenfassung der Benutzeraktivitäten und Einstellungen'
current_user: 'zu deiner Nutzerseite gehen'
current_user: 'zu deiner Benutzerseite gehen'
starred:
title: 'Favoriten'
help:
@ -662,9 +667,9 @@ de:
reset_read: "Gelesene zurücksetzen"
delete: "Themen löschen"
dismiss_posts: "Beiträge ignorieren"
dismiss_posts_tooltip: "Neue Beiträge in diesen Themen ignorieren, die Themen aber später wieder als ungelesen anzeigen, sobald weitere neue Beiträge verfasst wurden."
dismiss_posts_tooltip: "Neue Beiträge in diesen Themen ignorieren. Die Themen aber später wieder als ungelesen anzeigen, sobald neue Beiträge verfasst werden."
dismiss_topics: "Themen ignorieren"
dismiss_topics_tooltip: "Diese Themen ignorieren und nicht mehr als ungelesen anzeigen, selbst wenn weitere neue Beiträge verfasst wurden."
dismiss_topics_tooltip: "Diese Themen ignorieren und nicht mehr als ungelesen anzeigen, selbst wenn neue Beiträge verfasst werden."
dismiss_new: "Verwerfe neue Themen"
toggle: "zu Massenoperationen auf Themen umschalten"
actions: "Massenoperationen"
@ -789,13 +794,13 @@ de:
description: "Die Anzahl der ungelesenen und neuen Nachrichten wird neben dem Eintrag in der Themenliste angezeigt. Du wirst nur dann benachrichtigt, wenn jemand deinen @Namen erwähnt oder deine Nachricht beantwortet."
tracking:
title: "Verfolgen"
description: "Die Anzahl der ungelesenen und neuen Beiträge wird neben dem Eintrag in der Themenliste angezeigt. Du wirst nur dann benachrichtigt, wenn jemand deinen @Namen erwähnt oder deinen Beitrag beantwortet."
description: "Die Anzahl der ungelesenen und neuen Beiträge wird neben dem Eintrag in der Themenliste angezeigt. Du wirst nur dann benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet."
regular:
title: "Normal"
description: "Du wirst nur dann benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet."
regular_pm:
title: "Normal"
description: "Du wirst nur dann benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag in der privaten Unterhaltung antwortet."
description: "Du wirst nur dann benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deine Nachricht in der privaten Unterhaltung antwortet."
muted_pm:
title: "Stummgeschaltet"
description: "Du erhältst keine Benachrichtigungen über diese private Unterhaltung."
@ -847,10 +852,10 @@ de:
title: 'Einladung'
action: 'Einladung senden'
help: 'Sendet Freunden eine Einladung, so dass mit einem Klick auf dieses Thema antworten können.'
to_topic: "Wir senden deinem Freund eine kurze Email, die ihm ermöglicht direkt auf dieses Thema zu antworten. Hierfür ist kein Login erforderlich."
to_forum: "Wir senden deinem Freund eine kurze Email, die ihm ermöglicht dem Forum beizutreten. Hierfür ist kein Login erforderlich."
to_topic: "Wir senden deinem Freund eine kurze E-Mail, die es ihm ermöglicht, direkt auf dieses Thema zu antworten. Es ist keine Anmeldung erforderlich."
to_forum: "Wir senden deinem Freund eine kurze E-Mail, die es ihm ermöglicht, dem Forum sofort beizutreten. Es ist keine Anmeldung erforderlich."
email_placeholder: 'name@example.com'
success: "Wir haben deine Einladung an <b>{{email}}</b> verschickt. Wir lassen Dich wissen, sobald die Einladung eingelöst wird. In deinem Nutzerprofil kannst Du alle deine Einladungen überwachen."
success: "Wir haben an <b>{{email}}</b> eine Einladung verschickt. Wir werden dich benachrichtigen, sobald die Einladung angenommen wurde. Auf deiner Benutzerseite kannst du den Status deiner Einladungen verfolgen."
error: "Entschuldige, wir konnten diese Person nicht einladen. Vielleicht ist sie schon ein Nutzer?"
login_reply: 'Anmelden, um zu antworten'
filters:
@ -931,7 +936,7 @@ de:
image_upload_not_allowed_for_new_user: "Entschuldige, neue Benutzer dürfen keine Bilder hochladen."
attachment_upload_not_allowed_for_new_user: "Entschuldige, neue Benutzer dürfen keine Dateien hochladen."
abandon:
confirm: "Willst du deinen Beitrag wirklich verwerfen?"
confirm: "Möchtest du deinen Beitrag wirklich verwerfen?"
no_value: "Nein, beibehalten"
yes_value: "Ja, verwerfen"
wiki:
@ -1055,8 +1060,8 @@ de:
zero: keine Bearbeitungen
delete:
confirm:
one: "Bist du sicher, dass du diesen Beitrag löschen willst?"
other: "Bist du sicher, dass du all diese Beiträge löschen willst?"
one: "Möchtest du wirklich diesen Beitrag löschen?"
other: "Möchtest du wirklich all diese Beiträge löschen?"
revisions:
controls:
first: "Erste Überarbeitung"
@ -1098,21 +1103,21 @@ de:
badge_colors: "Plakettenfarben"
background_color: "Hintergrundfarbe"
foreground_color: "Vordergrundfarbe"
name_placeholder: "Sollte kurz und knapp sein."
color_placeholder: "Irgendeine Webfarbe"
delete_confirm: "Bist Du sicher, dass Du diese Kategorie löschen willst?"
name_placeholder: "Ein oder maximal zwei Wörter"
color_placeholder: "Irgendeine Web-Farbe"
delete_confirm: "Möchtest du wirklich diese Kategorie löschen?"
delete_error: "Beim Löschen der Kategorie ist ein Fehler aufgetreten."
list: "Kategorien auflisten"
no_description: "Bitte füge eine Beschreibung für diese Kategorie hinzu."
change_in_category_topic: "Besuche die Themen dieser Kategorie um einen Eindruck für eine gute Beschreibung zu gewinnen."
change_in_category_topic: "Beschreibung bearbeiten"
already_used: 'Diese Farbe wird bereits für eine andere Kategorie verwendet'
security: "Sicherheit"
images: "Bilder"
auto_close_label: "Themen automatisch schließen nach:"
auto_close_units: "Stunden"
email_in: "Benutzerdefinierte Email Adresse:"
email_in: "Benutzerdefinierte Adresse für eingehende E-Mails:"
email_in_allow_strangers: "Akzeptiere E-Mails von nicht registrierten, anonymen Benutzern"
email_in_disabled: "Das Erstellen von neuen Themen per E-Mail ist in den Einstellungen deaktiviert. Um das Erstellen von neuen Themen per E-Mail zu erlauben,"
email_in_disabled: "Das Erstellen von neuen Themen per E-Mail ist in den Website-Einstellungen deaktiviert. Um das Erstellen von neuen Themen per E-Mail zu erlauben,"
email_in_disabled_click: 'aktiviere die Einstellung „email in“.'
allow_badges_label: "Erlaube das Verleihen von Abzeichen in dieser Kategorie"
edit_permissions: "Berechtigungen bearbeiten"
@ -1122,7 +1127,7 @@ de:
default_position: "Standardposition"
position_disabled: "Kategorien werden in der Reihenfolge der Aktivität angezeigt. Um die Reihenfolge von Kategorien in Listen zu steuern,"
position_disabled_click: 'aktiviere die Einstellung „fixed category positions“.'
parent: "Elternkategorie"
parent: "Übergeordnete Kategorie"
notifications:
watching:
title: "Beobachten"
@ -1221,7 +1226,7 @@ de:
categories:
title: "Kategorien"
title_in: "Kategorie - {{categoryName}}"
help: "Alle Themen, gruppiert nach Kategorie"
help: "alle Themen, gruppiert nach Kategorie"
unread:
title:
zero: "Ungelesen"
@ -1284,8 +1289,8 @@ de:
critical_available: "Ein kritisches Update ist verfügbar."
updates_available: "Updates sind verfügbar."
please_upgrade: "Bitte Upgrade durchführen!"
no_check_performed: "Es wurde nicht nach Updates gesucht. Bitte sicherstellen, dass sidekiq lauft."
stale_data: "Es wurde schon länger nicht nach Updates gesucht. Bitte sicherstellen, dass sidekiq lauft."
no_check_performed: "Es wurde nicht nach Updates gesucht. Bitte stelle sicher, dass sidekiq läuft."
stale_data: "Es wurde schon länger nicht nach Updates gesucht. Bitte stelle sicher, dass sidekiq läuft."
version_check_pending: "Sieht so aus, als hättest du vor Kurzem upgedated. Großartig!"
installed_version: "Installiert"
latest_version: "Neueste"
@ -1395,8 +1400,8 @@ de:
generate: "API-Schlüssel generieren"
regenerate: "API-Schlüssel neu generieren"
revoke: "Widerrufen"
confirm_regen: "Bist du sicher, dass du den API Key mit einem neuen ersetzen willst?"
confirm_revoke: "Bist du dir sicher, dass du den API Key widerrufen willst?"
confirm_regen: "Möchtest du wirklich den API Key mit einem neuen ersetzen?"
confirm_revoke: "Möchtest du wirklich den API Key widerrufen?"
info_html: "Dein API-Schlüssel erlaubt Dir das Erstellen und Bearbeiten von Themen via JSON aufrufen."
all_users: "Alle Benutzer"
note_html: "Behalte deinen <strong>Schlüssel</strong> geheim, jeder Benutzer mit diesem Schlüssel kann beliebige Beiträge unter jedem Benutzer im Forum erstellen."
@ -1408,14 +1413,14 @@ de:
none: "Kein Backup verfügbar."
read_only:
enable:
title: "Aktiviere den Nur-Lesen Modus"
text: "Aktiviere Nur-Lesen Modus"
confirm: "Bist du sicher, dass du den Nur-Lesen Modus aktivieren möchtest?"
title: "Nur-Lesen-Modus aktivieren"
text: "Nur-Lesen-Modus aktivieren"
confirm: "Möchtest du wirklich den Nur-Lesen Modus aktivieren?"
disable:
title: "Deaktiviere den Nur-Lesen Modus"
text: "Deaktiviere Nur-Lesen Modus"
title: "Nur-Lesen-Modus deaktivieren"
text: "Nur-Lesen-Modus deaktivieren"
logs:
none: "Noch keine Logs verfügbar..."
none: "Noch keine Protokolleinträge verfügbar..."
columns:
filename: "Dateiname"
size: "Größe"
@ -1429,11 +1434,11 @@ de:
failed: "Der Vorgang '{{operation}}' ist fehlgeschlagen. Bitte überprüfe die Logs."
cancel:
text: "Abbrechen"
title: "Bricht den aktuellen Vorgang ab"
confirm: "Bist du sicher, dass du den aktuellen Vorgang abbrechen möchtest?"
title: "Den aktuellen Vorgang abbrechen"
confirm: "Möchtest du wirklich den aktuellen Vorgang abbrechen?"
backup:
text: "Backup"
title: "Erstellt ein Backup"
title: "Ein Backup erstellen"
confirm: "Willst du ein neues Backup starten?"
without_uploads: "Ja (ohne Upload)"
download:
@ -1441,17 +1446,17 @@ de:
title: "Backup herunterladen"
destroy:
text: "Löschen"
title: "Löscht das Backup"
confirm: "Bist du sicher, dass du das Backup löschen möchtest?"
title: "Das Backup löschen"
confirm: "Möchtest du wirklich das Backup löschen?"
restore:
is_disabled: "Wiederherstellung ist in den Einstellungen deaktiviert."
is_disabled: "Wiederherstellung ist in den Website-Einstellungen deaktiviert."
text: "Wiederherstellen"
title: "Wiederherstellung des Backups"
confirm: "Bist du sicher, dass du dieses Backup wiederherstellen möchtest?"
title: "Das Backup wiederherstellen"
confirm: "Möchtest du wirklich dieses Backup wiederherstellen?"
rollback:
text: "Zurücksetzen"
title: "Setzt die Datenbank auf den letzten funktionierenden Zustand zurück"
confirm: "Bist du sicher, dass du die Datenbank auf den letzten funktionierenden Zustand zurücksetzen möchtest?"
title: "Die Datenbank auf den letzten funktionierenden Zustand zurücksetzen"
confirm: "Möchtest du wirklich die Datenbank auf den letzten funktionierenden Stand zurücksetzen?"
export_csv:
users:
text: "Exportieren"
@ -1459,61 +1464,61 @@ de:
success: "Der Export wurde gestartet. Du wirst in Kürze über den Fortschritt benachrichtigt."
failed: "Der Export ist fehlgeschlagen. Bitte überprüfe die Logs."
customize:
title: "Personalisieren"
long_title: "Seite personalisieren"
header: "Header"
title: "Anpassen"
long_title: "Website-Anpassungen"
header: "Kopfbereich"
css: "Stylesheet"
mobile_header: "Mobiler Header"
mobile_css: "Mobiles Stylesheet"
override_default: "Standard überschreiben?"
mobile_header: "Kopfbereich für Mobilgeräte"
mobile_css: "Stylesheet Mobilgeräte"
override_default: "Das Standard-Stylesheet nicht verwenden"
enabled: "Aktiviert?"
preview: "Vorschau"
undo_preview: "Vorschau entfernen"
rescue_preview: "Standardstil"
explain_preview: "Zeige die Seite mit benutzerdefiniertem Stylesheet"
rescue_preview: "Standard-Style"
explain_preview: "Zeige die Website mit benutzerdefiniertem Stylesheet an"
explain_undo_preview: "Gehe zurück zum aktuell aktivierten benutzerdefinierten Stylesheet"
explain_rescue_preview: "Zeige die Seite mit dem Standard-Stylesheet"
explain_rescue_preview: "Zeige die Website mit dem Standard-Stylesheet an"
save: "Speichern"
new: "Neu"
new_style: "Neuer Stil"
new_style: "Neuer Style"
delete: "Löschen"
delete_confirm: "Diese Anpassung löschen?"
about: "Ändere CSS stylesheets und HTML header auf der Seite. Füge eine Anpassung hinzu um zu starten."
about: "Ändere die Stylesheets (CSS) und den HTML-Header auf der Website. Füge eine Anpassung hinzu, um zu starten."
color: "Farbe"
opacity: "Transparenz"
copy: "Kopieren"
css_html:
title: "CSS, HTML"
title: "CSS/HTML"
long_title: "CSS und HTML Anpassungen"
colors:
title: "Farben"
long_title: "Farb-Schemata"
about: "Farbschemen erlauben dir die auf der Seite benutzen Farben zu ändern ohne CSS schreiben zu müssen. Wähle oder füge eine hinzu, um zu beginnen."
long_title: "Farbschemata"
about: "Farbschemen erlauben dir die auf der Seite benutzen Farben zu ändern ohne CSS schreiben zu müssen. Füge ein Schema hinzu, um zu beginnen."
new_name: "Neues Farbschema"
copy_name_prefix: "Kopie von"
delete_confirm: "Dieses Farbschema löschen?"
undo: "rückgängig"
undo_title: "Änderungen an dieser Farbe bis zum lezten Speichern rückgängig machen"
revert: "verwerfen"
revert_title: "Diese Farbe auf Discourse Standard Farbschema zurücksetzen."
revert_title: "Diese Farbe auf das Discourse-Standard-Farbschema zurücksetzen."
primary:
name: 'erste'
description: 'Die meisten Texte, Bilder und Ränder.'
secondary:
name: 'zweite'
description: 'Die Haupt Hintergrundfarbe, und Textfarbe einiger Schaltflächen.'
description: 'Die Haupthintergrundfarbe und Textfarbe einiger Schaltflächen.'
tertiary:
name: 'tertiär'
description: 'Links, einige Schaltflächen, Benachrichtigungen und Akzentfarben'
name: 'dritte'
description: 'Links, einige Schaltflächen, Benachrichtigungen und Akzentfarben.'
quaternary:
name: "quaternären"
name: "vierte"
description: "Navigations-Links"
header_background:
name: "Hintergrund Kopfbereich"
description: "Hintergrundfarbe des Seitenkopfs."
description: "Hintergrundfarbe des Kopfbereichs der Website."
header_primary:
name: "primärer Kopfbereich"
description: "Texte und Bilder im Kopfbereich der Seite."
description: "Text und Symbole im Kopfbereich der Website."
highlight:
name: 'hervorheben'
description: 'Die Hintergrundfarbe der hervorgehobenen Elemente auf der Seite, so wie Beiträge und Themen.'
@ -1527,33 +1532,33 @@ de:
name: 'Liebe'
description: "Die Farbe des Like-Buttons."
email:
title: "Mailprotokoll"
title: "E-Mail"
settings: "Einstellungen"
all: "Alle"
sending_test: "Versende Testemail..."
sending_test: "Versende Test-E-Mail..."
test_error: "Es gab ein Problem beim Senden der Test-E-Mail. Bitte überprüfe nochmals deine E-Mail-Einstellungen, stelle sicher dass dein Anbieter keine E-Mail-Verbindungen blockiert und probiere es erneut."
sent: "Gesendet"
skipped: "Übersprungen"
sent_at: "Gesendet am"
time: "Zeit"
user: "Benutzer"
email_type: "Mailtyp"
email_type: "E-Mail-Typ"
to_address: "Empfänger"
test_email_address: "Mailadresse zum Testen"
send_test: "Testmail senden"
test_email_address: "E-Mail-Adresse für Test"
send_test: "Test-E-Mail senden"
sent_test: "Gesendet!"
delivery_method: "Versandmethode"
preview_digest: "Vorschau auf Neuigkeiten anzeigen"
preview_digest_desc: "Hiermit kannst du dir anschauen, wie die regelmäßig versendeten Neuigkeits-Mails aussehen."
refresh: "Aktualisieren"
format: "Format"
html: "html"
text: "text"
html: "HTML"
text: "Text"
last_seen_user: "Letzter Benutzer:"
reply_key: "Antwort-Schlüssel"
skipped_reason: "Grund des Überspringens"
logs:
none: "Keine Protokolle gefunden."
none: "Keine Protokolleinträge gefunden."
filters:
title: "Filter"
user_placeholder: "Benutzername"
@ -1568,14 +1573,14 @@ de:
match_count: "Treffer"
ip_address: "IP"
delete: 'Löschen'
edit: 'Editieren'
edit: 'Bearbeiten'
save: 'Speichern'
screened_actions:
block: "blockieren"
do_nothing: "nichts machen"
do_nothing: "nichts tun"
staff_actions:
title: "Mitarbeiter Aktion"
instructions: "Klicke auf die Benutzernamen und Aktionen um die Liste zu filtern. Klicke den Avatar um die Benutzerseite zu sehen."
title: "Mitarbeiter-Aktionen"
instructions: "Klicke auf die Benutzernamen und Aktionen, um die Liste zu filtern. Klicke auf Avatare, um die Benutzerseiten zu sehen."
clear_filters: "Alles anzeigen"
staff_user: "Mitarbeiter"
target_user: "Zielnutzer"
@ -1585,36 +1590,36 @@ de:
details: "Details"
previous_value: "Alt"
new_value: "Neu"
diff: "Diff"
diff: "Vergleich"
show: "Anzeigen"
modal_title: "Details"
no_previous: "Es gibt keinen vorgängigen Wert."
no_previous: "Es gibt keinen vorherigen Wert."
deleted: "Kein neuer Wert. Der Eintrag wurde gelöscht."
actions:
delete_user: "Benutzer löschen"
change_trust_level: "Vertrauensstufe ändern"
change_site_setting: "Seiteneinstellungen ändern"
change_site_customization: "Seitenanpassungen ändern"
delete_site_customization: "Seitenanpassungen löschen"
change_site_setting: "Website-Einstellungen ändern"
change_site_customization: "Website-Anpassungen ändern"
delete_site_customization: "Website-Anpassungen löschen"
suspend_user: "gesperrter Benutzer"
unsuspend_user: "ungesperrter Benutzer"
grant_badge: "Abzeichen verleihen"
revoke_badge: "Abzeichen entziehen"
screened_emails:
title: "Geschützte E-Mails"
title: "Überprüfte E-Mails"
description: "Wenn jemand ein Konto erstellt, werden die folgenden E-Mail-Adressen überprüft und es wird die Anmeldung blockiert oder eine andere Aktion ausgeführt."
email: "E-Mail-Adresse"
actions:
allow: "Erlauben"
screened_urls:
title: "Geschützte URLs"
title: "Überprüfte URLs"
description: "Die aufgelisteten URLs wurden in Beiträgen von identifizierten Spammen verwendet."
url: "URL"
domain: "Domain"
screened_ips:
title: "Geschützte IPs"
title: "Überprüfte IPs"
description: 'IP-Adressen die beobachtet werden. Benutze „Erlauben“ um IP-Adressen auf die Whitelist zu setzen.'
delete_confirm: "Bist du dir sicher, dass du die Rege für %{ip_address} entfernen willst?"
delete_confirm: "Möchtest du wirklich die Regel für %{ip_address} entfernen?"
actions:
block: "Blockieren"
do_nothing: "Erlauben"
@ -1675,11 +1680,11 @@ de:
unsuspend_failed: "Beim Entsperren dieses Benutzers ist etwas schief gegangen {{error}}"
suspend_duration: "Wie lange soll dieser Benutzer gesperrt werden?"
suspend_duration_units: "(Tage)"
suspend_reason_label: "Warum wird gesperrt? Dieser Text ist auf der Profilseite des Benutzers <b>für jeden sichtbar</b> und wird dem Benutzer angezeigt, wenn sich dieser anmelden will. Bitte kurz halten."
suspend_reason_label: "Warum sperrst du? Dieser Text ist auf der Profilseite des Benutzers <b>für jeden sichtbar</b> und wird dem Benutzer angezeigt, wenn sich dieser anmelden will. Bitte kurz halten."
suspend_reason: "Grund"
suspended_by: "Gesperrt von"
delete_all_posts: "Lösche alle Beiträge"
delete_all_posts_confirm: "Du wirst %{posts} Beiträge und %{topics} Themen löschen. Bist du sicher?"
delete_all_posts_confirm: "Du wirst %{posts} Beiträge und %{topics} Themen löschen. Bist du dir sicher?"
suspend: "Sperren"
unsuspend: "Entsperren"
suspended: "Gesperrt?"
@ -1824,9 +1829,9 @@ de:
granted_at: Verliehen am
save: Speichern
delete: Löschen
delete_confirm: Bist du dir sicher, dass du dieses Abzeichen löschen willst?
delete_confirm: Möchtest du wirklich dieses Abzeichen löschen?
revoke: Entziehen
revoke_confirm: Bist du dir sicher, dass du dieses Abzeichen entziehen willst?
revoke_confirm: Möchtest du wirklich dieses Abzeichen entziehen?
edit_badges: Abzeichen bearbeiten
grant_badge: Abzeichen verleihen
granted_badges: Verliehene Abzeichen

View File

@ -2056,6 +2056,7 @@ en:
notifications: '<b>n</b> Open notifications'
site_map_menu: '<b>=</b> Open site map menu'
user_profile_menu: '<b>p</b> Open user profile menu'
show_incoming_updated: '<b>.</b> Show incoming/updated topics'
search: '<b>/</b> Search'
help: '<b>?</b> Open keyboard shortcuts help'
dismiss_new_posts: '<b>x</b>, <b>r</b> Dismiss New/Posts'

View File

@ -626,7 +626,6 @@ es:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span> ha aceptado tu invitación</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> movió {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>Se te ha concedido {{description}}</p>"
upload_selector:
title: "Añadir imagen"
title_with_attachments: "Añadir una imagen o archivo"

View File

@ -625,7 +625,6 @@ fi:
invitee_accepted: "<i title='hyväksyi kutsusi' class='fa fa-user'></i><p><span>{{username}}</span> hyväksyi kutsusi</p>"
moved_post: "<i title='siirsi viestin' class='fa fa-sign-out'></i><p><span>{{username}}</span> siirsi {{description}}</p>"
linked: "<i title='linkattu viesti' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='arvomerkki myönnetty' class='fa fa-certificate'></i><p>Sinulle myönnettiin {{description}}</p>"
upload_selector:
title: "Lisää kuva"
title_with_attachments: "Lisää kuva tai tidosto"

View File

@ -333,16 +333,19 @@ fr:
title: "Arrière plan du profil"
email:
title: "Courriel"
instructions: "Ne sera jamais visible publiquement."
ok: "Cela semble correct. Un courriel de confirmation sera envoyé."
invalid: "Merci de saisir une adresse de courriel valide."
authenticated: "Votre adresse de courriel a été authentifiée par {{provider}}."
frequency: "Nous vous envoyons des courriels contenant uniquement des informations que vous n'avez pas déjà vues lors d'une précédente connexion."
name:
title: "Nom"
instructions: "Nom complet."
too_short: "Votre nom est trop court."
ok: "Votre nom semble correct."
username:
title: "Pseudo"
instructions: "Doit être unique, court et sans espace."
short_instructions: "Les utilisateurs peuvent vous mentionner avec @{{username}}."
available: "Votre pseudo est disponible."
global_match: "L'adresse de courriel correspond au pseudo enregistré."
@ -447,10 +450,13 @@ fr:
prev_page: "lors d'une tentative de chargement"
reasons:
network: "Erreur réseau"
server: "Erreur serveur"
forbidden: "Accès refusé"
unknown: "Erreur"
desc:
network: "Veuillez vérifier votre connexion."
network_fixed: "On dirait que c'est revenu."
server: "Code d'erreur: {{status}}"
unknown: "Une erreur est survenue."
buttons:
back: "Retour"
@ -576,7 +582,7 @@ fr:
view_new_post: "Voir votre nouveau message."
saving: "Sauvegarde…"
saved: "Sauvegardé !"
saved_draft: "Vous un message brouillon en cours. Sélectionner cette barre pour reprendre son édition."
saved_draft: "Vous avez un message brouillon en cours. Sélectionner cette barre pour reprendre son édition."
uploading: "Envoi en cours…"
show_preview: 'afficher la prévisualisation &raquo;'
hide_preview: '&laquo; cacher la prévisualisation'
@ -626,7 +632,6 @@ fr:
invitee_accepted: "<i title='invitation accepté' class='fa fa-user'></i><p><span>{{username}}</span> a accepté votre invitation</p>"
moved_post: "<i title='message déplacé' class='fa fa-sign-out'></i><p><span>{{username}}</span> a déplacé {{description}}</p>"
linked: "<i title='message lié' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge décerné' class='fa fa-certificate'></i><p>On vous a décerné {{description}}</p>"
upload_selector:
title: "Ajouter une image"
title_with_attachments: "Ajouter une image ou un fichier"

View File

@ -615,7 +615,6 @@ he:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span> אישר/ה את הזמנתך</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> הזיז/ה {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>הוענק/ו לך {{description}}</p>"
upload_selector:
title: "הוספת תמונה"
title_with_attachments: "הוספת תמונה או קובץ"

View File

@ -447,6 +447,8 @@ it:
prev_page: "durante il caricamento"
reasons:
network: "Errore di Rete"
server: "Errore del Server"
forbidden: "Accesso Negato"
unknown: "Errore"
desc:
network: "Per favore controlla la tua connessione."
@ -626,7 +628,6 @@ it:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span>ha accettato il tuo invito</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> ha spostato {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>Ti è stato assegnato il grado {{description}}</p>"
upload_selector:
title: "Aggiungi un'immagine"
title_with_attachments: "Aggiungi un'immagine o un file"
@ -1763,6 +1764,8 @@ it:
qualifies: "Requisiti per il livello 3"
will_be_promoted: "Verrà promosso entro 24 ore."
does_not_qualify: "Non si qualifica per il livello 3."
sso:
external_name: "Nome"
site_content:
none: "Scegli un tipo di contenuto per iniziare"
title: 'Contenuto'

View File

@ -584,7 +584,6 @@ ja:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span> accepted your invitation</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> moved {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p> {{description}}バッジを付けられました</p>"
upload_selector:
title: "画像のアップロード"
title_with_attachments: "画像/ファイルをアップロード"

View File

@ -595,7 +595,6 @@ ko:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span> accepted your invitation</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> moved {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>{{description}} 배지를 받았습니다.</p>"
upload_selector:
title: "이미지 추가하기"
title_with_attachments: "이미지 또는 파일 추가하기"

View File

@ -626,7 +626,6 @@ nl:
invitee_accepted: "<i title='heeft jouw uitnodiging geaccepteerd' class='fa fa-user'></i><p><span>{{username}}</span> accepted your invitation</p>"
moved_post: "<i title='heeft bericht verplaatst' class='fa fa-sign-out'></i><p><span>{{username}}</span> moved {{description}}</p>"
linked: "<i title='gelinkt bericht' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge toegekend' class='fa fa-certificate'></i><p>Je hebt {{description}} gekregen</p>"
upload_selector:
title: "Voeg een afbeelding toe"
title_with_attachments: "Voeg een afbeelding of bestand toe"
@ -1292,15 +1291,45 @@ nl:
title: "Meldingen"
old: "Oud"
active: "Actief"
agree: "Akkoord"
agree_title: "Bevestig dat deze melding geldig en correct is"
agree_flag_modal_title: "Akkoord en ... "
agree_flag_hide_post: "Akkoord (verberg bericht en stuur privébericht)"
agree_flag_hide_post_title: "Verberg dit bericht en stuur de gebruiker automatisch een privébericht met het verzoek om het bericht aan te passen. "
agree_flag: "Akkoord met melding"
agree_flag_title: "Akkoord met melding en het bericht ongewijzigd laten"
defer_flag: "Negeer"
defer_flag_title: "Verwijder deze melding; nu geen actie nodig"
delete: "Verwijder"
delete_title: "Verwijder het bericht waar deze melding naar verwijst"
delete_post_defer_flag: "Verwijder bericht en negeer melding"
delete_post_defer_flag_title: "Verwijder bericht; de hele topic als dit het eerste bericht is"
delete_post_agree_flag: "Verwijder bericht en akkoord met melding"
delete_post_agree_flag_title: "Verwijder bericht; de hele topic als dit het eerste bericht is"
delete_flag_modal_title: "Verwijder en ... "
delete_spammer: "Verwijder spammer"
delete_spammer_title: "Verwijder de gebruiker en al hun berichten en topics."
disagree_flag_unhide_post: "Niet akkoord (toon bericht)"
disagree_flag_unhide_post_title: "Verwijder elke melding van dit bericht en maak het weer zichtbaar"
disagree_flag: "Niet akkoord"
disagree_flag_title: "Deze melding is ongeldig of niet correct"
clear_topic_flags: "Gedaan"
clear_topic_flags_title: "Het topic is onderzocht en problemen zijn opgelost. Klik op Gedaan om de meldingen te verwijderen."
more: "(meer antwoorden...)"
dispositions:
agreed: "akkoord"
disagreed: "niet akkoord"
deferred: "genegeerd"
flagged_by: "Gemarkeerd door"
resolved_by: "Opgelost door"
took_action: "Heeft actie ondernomen"
system: "Systeem"
error: "Er ging iets mis"
reply_message: "Reageer"
no_results: "Er zijn geen markeringen"
topic_flagged: "Deze <strong>topic</strong> is gemarkeerd."
visit_topic: "Ga naar de topic om te zien wat er aan de hand is en om actie te ondernemen"
was_edited: "Bericht is gewijzigd na de eerste melding"
summary:
action_type_3:
one: "off-topic"
@ -1379,6 +1408,8 @@ nl:
backup:
text: "Backup"
title: "Maak een backup"
confirm: "Wil je een nieuwe backup starten? "
without_uploads: "Ja (zonder upload)"
download:
text: "Download"
title: "Download de backup"
@ -1395,6 +1426,12 @@ nl:
text: "Rollback"
title: "Herstel de database naar de laatst werkende versie"
confirm: "Weet je zeker dat je de database wil herstellen naar de laatste versie?"
export_csv:
users:
text: "Exporteer gebruikers"
title: "Exporteer gebruikerslijst in *.CSV-formaat"
success: "Exporteren is gestart; over enkele momenten krijg je meer informatie over de voortgang"
failed: "Exporteren is mislukt. Controleer de logbestanden."
customize:
title: "Aanpassingen"
long_title: "Aanpassingen aan de site"
@ -1625,9 +1662,11 @@ nl:
edit_title: "Wijzig titel"
save_title: "Bewaar titel"
refresh_browsers: "Forceer browser refresh"
refresh_browsers_message: "Bericht verstuurd aan alle gebruikers!"
show_public_profile: "Bekijk openbaar profiel"
impersonate: 'Log in als gebruiker'
ip_lookup: "Zoek IP-adres op"
log_out: "Uitloggen"
logged_out: "Gebruiker is uitgelogd op alle apparaten"
revoke_admin: 'Ontneem beheerdersrechten'
grant_admin: 'Geef Beheerdersrechten'
@ -1638,12 +1677,15 @@ nl:
reputation: Reputatie
permissions: Toestemmingen
activity: Activiteit
like_count: '''Vind ik leuks'' gegeven / ontvangen'
last_100_days: 'in de laatste 100 dagen'
private_topics_count: Privétopics
posts_read_count: Berichten gelezen
post_count: Berichten gemaakt
topics_entered: Topics bekeken
flags_given_count: Meldingen gedaan
flags_received_count: Meldigen ontvangen
flags_given_received_count: 'Meldingen gedaan / ontvangen'
approve: 'Accepteer'
approved_by: "Geaccepteerd door"
approve_success: "Gebruiker geaccepteerd en e-mail verzonden met instructies voor activering."
@ -1660,6 +1702,9 @@ nl:
cant_delete_all_too_many_posts:
one: "Kan niet alle berichten verwijderen omdat de gebruiker meer dan 1 bericht heeft (delete_all_posts_max)."
other: "Kan niet alle berichten verwijderen omdat de gebruiker meer dan %{count} berichten heeft (delete_all_posts_max)."
delete_confirm: "Weet je zeker dat je deze gebruiker definitief wil verwijderen? Deze handeling kan niet ongedaan worden gemaakt! "
delete_and_block: "Verwijder en <b>blokkeer</b> dit e-mail- en IP-adres"
delete_dont_block: "Alleen verwijderen"
deleted: "De gebruiker is verwijderd."
delete_failed: "Er ging iets mis bij het verwijderen van deze gebruiker. Zorg er voor dat alle berichten van deze gebruiker eerst verwijderd zijn."
send_activation_email: "Verstuur activatiemail"
@ -1692,9 +1737,16 @@ nl:
posts_read_all_time: "Berichten gelezen (ooit)"
flagged_posts: "Gemarkeerde berichten"
flagged_by_users: "Gebruikers die gemarkeerd hebben"
likes_given: "'Vind ik leuks' gegeven"
likes_received: "'Vind ik leuks' ontvangen"
qualifies: "Komt in aanmerking voor Trust Level 3"
will_be_promoted: "Zal over 24 uur gepromoveerd worden."
does_not_qualify: "Komt niet in aanmerking voor Trust Level 3"
sso:
external_username: "Gebruikersnaam"
external_name: "Naam"
external_email: "E-mail"
external_avatar_url: "URL voor profielfoto"
site_content:
none: "Selecteer een tekst om deze te bewerken"
title: 'Teksten'

View File

@ -126,7 +126,7 @@ pl_PL:
never: "nigdy"
daily: "dziennie"
weekly: "tygodniowo"
every_two_weeks: "na każde dwa tygodnie"
every_two_weeks: "co dwa tygodnie"
max: "maks"
character_count:
one: "1 znak"
@ -185,10 +185,10 @@ pl_PL:
preview: "podgląd"
cancel: "anuluj"
save: "Zapisz zmiany"
saving: "Zapisywanie..."
saving: "Zapisuję…"
saved: "Zapisano!"
upload: "Wgraj"
uploading: "Wgrywanie..."
uploading: "Wysyłam…"
uploaded: "Wgrano!"
enable: "Włącz"
disable: "Wyłącz"
@ -203,16 +203,16 @@ pl_PL:
placeholder: "tutaj wpisz tytuł tematu"
user_action:
user_posted_topic: "<a href='{{userUrl}}'>{{user}}</a> utworzył(-a) <a href='{{topicUrl}}'>temat</a>"
you_posted_topic: "<a href='{{userUrl}}'>Dodałeś(-aś)</a> <a href='{{topicUrl}}'>temat</a>"
user_replied_to_post: "<a href='{{userUrl}}'>{{user}}</a> odpowiedział(-a) na <a href='{{postUrl}}'>{{post_number}}</a>"
you_replied_to_post: "<a href='{{userUrl}}'>Odpisałeś(-aś)</a> na <a href='{{postUrl}}'>{{post_number}}</a>"
user_replied_to_topic: "<a href='{{userUrl}}'>{{user}}</a> odpisał(-a) na <a href='{{topicUrl}}'>temat</a>"
you_replied_to_topic: "<a href='{{userUrl}}'>Dodałeś(-aś) odpowiedź</a> w <a href='{{topicUrl}}'>temacie</a>"
user_mentioned_user: "<a href='{{user1Url}}'>{{user}}</a> wspomniał(-a) o <a href='{{user2Url}}'>{{another_user}}</a>"
you_posted_topic: "<a href='{{userUrl}}'>Dodajesz</a> <a href='{{topicUrl}}'>temat</a>"
user_replied_to_post: "<a href='{{userUrl}}'>{{user}}</a> odpowiada na <a href='{{postUrl}}'>{{post_number}}</a>"
you_replied_to_post: "<a href='{{userUrl}}'>Twoja odpowiedź</a> na <a href='{{postUrl}}'>{{post_number}}</a>"
user_replied_to_topic: "<a href='{{userUrl}}'>{{user}}</a> odpisuje na <a href='{{topicUrl}}'>temat</a>"
you_replied_to_topic: "<a href='{{userUrl}}'>Twoja odpowiedź</a> w <a href='{{topicUrl}}'>temacie</a>"
user_mentioned_user: "<a href='{{user1Url}}'>{{user}}</a> wspomina o <a href='{{user2Url}}'>{{another_user}}</a>"
user_mentioned_you: "<a href='{{user1Url}}'>{{user}}</a> wspomniał o <a href='{{user2Url}}'>tobie</a>"
you_mentioned_user: "<a href=\"{{user1Url}}\">Wspomniałeś/aś</a> o użytkowniku <a href=\"{{user2Url}}\">{{another_user}}</a>"
posted_by_user: "Dodano przez <a href='{{userUrl}}'>{{user}}</a>"
posted_by_you: "Dodano przez <a href='{{userUrl}}'>Ciebie</a>"
posted_by_user: "Dodany przez <a href='{{userUrl}}'>{{user}}</a>"
posted_by_you: "Dodany przez <a href='{{userUrl}}'>Ciebie</a>"
sent_by_user: "Wysłano przez <a href='{{userUrl}}'>{{user}}</a>"
sent_by_you: "Wysłano przez <a href='{{userUrl}}'>Ciebie</a>"
groups:
@ -231,8 +231,8 @@ pl_PL:
members_mods_and_admins: "Tylko członkowie grupy, moderatorzy i administratorzy"
everyone: "Wszyscy"
user_action_groups:
'1': "Polubień"
'2': "Otrzymanych polubień"
'1': "Przyznane polubienia "
'2': "Otrzymane polubienia"
'3': "Zakładki"
'4': "Tematy"
'5': "Wpisy"
@ -248,21 +248,22 @@ pl_PL:
all_subcategories: "wszystkie"
no_subcategory: "żadne"
category: "Kategoria"
posts: "Wpisy"
topics: "Tematy"
latest: "Najnowsze"
latest: "Ostatnie"
latest_by: "najnowsze przez"
toggle_ordering: "przełącz kolejność kontroli"
subcategories: "Podkategorie"
topic_stats: "Liczba nowych tematów."
topic_stat_sentence:
one: "%{count} nowy temat w ciągu ostatnich %{unit}."
few: "%{count} nowych tematów w ciągu ostatnich %{unit}."
other: "%{count} nowych tematów w ciągu ostatnich %{unit}."
one: "%{count} nowy temat ostatni %{unit}."
few: "%{count} nowe tematy ostatni %{unit}."
other: "%{count} nowych tematów ostatni %{unit}."
post_stats: "Liczba nowych wpisów."
post_stat_sentence:
one: "%{count} nowy wpis w ciągu ostatnich %{unit}."
few: "%{count} nowych wpisów w ciągu ostatnich %{unit}."
other: "%{count} nowych wpisów w ciągu ostatnich %{unit}."
one: "%{count} nowy wpis ostatni %{unit}."
few: "%{count} nowe wpisy ostatni %{unit}."
other: "%{count} nowych wpisów ostatni %{unit}."
ip_lookup:
title: Wyszukiwanie adresu IP
hostname: Nazwa hosta
@ -301,9 +302,9 @@ pl_PL:
suspended_reason: "Powód: "
mailing_list_mode: "Otrzymuj email dla każdego wpisu na forum (o ile nie wyciszysz kategorii lub tematu)"
watched_categories: "Obserwowane"
watched_categories_instructions: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach. Otrzymasz powiadomienia o wszystkich nowych wpisach i tematach, a liczba nieprzeczytanych i nowych wpisów będzie wyświetlana obok tytułów na liście tematów."
watched_categories_instructions: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach: liczba nieprzeczytanych i nowych wpisów będzie wyświetlana obok tytułów na liście tematów. Dodatkowo będziesz otrzymywać powiadomienie o każdym nowym wpisie i temacie."
tracked_categories: "Śledzone"
tracked_categories_instructions: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach. Licznik nowych i nieprzeczytanych wpisów pojawi się obok tytułu na liście tematów."
tracked_categories_instructions: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach: licznik nowych i nieprzeczytanych wpisów pojawi się obok tytułu na liście tematów."
muted_categories: "Wyciszone"
muted_categories_instructions: "Nie będziesz powiadamiany o niczym dotyczącym nowych tematów w tych kategoriach, i nie będą się one pojawiać na karcie nieprzeczytanych."
delete_account: "Usuń moje konto"
@ -328,7 +329,7 @@ pl_PL:
title: "Zmień O mnie"
change_username:
title: "Zmień nazwę użytkownika"
confirm: "Jeżeli zmienisz swoją nazwę użytkownika, wszystkie wcześniejsze cytaty z Twoich wpisów i wzmianki przez @nazwa będą uszkodzone. Czy na pewno tego chcesz?"
confirm: "Jeżeli zmienisz swoją nazwę użytkownika, wszystkie stare cytaty twoich wpisów oraz wzmianki przez @nazwę przestaną działać. Czy na pewno tego chcesz?"
taken: "Przykro nam, ale ta nazwa użytkownika jest zajęta."
error: "Podczas zmiany twojej nazwy użytkownika wystąpił błąd."
invalid: "Ta nazwa użytkownika jest niepoprawna. Powinna ona zawierać jedynie liczby i litery."
@ -351,24 +352,27 @@ pl_PL:
title: "Tło profilu"
email:
title: "Email"
instructions: "Nigdy nie będzie wyświetlony publicznie."
ok: "Wygląda dobrze. Wyślemy Ci wiadomość do potwierdzenia."
invalid: "Podaj poprawny adres email."
authenticated: "Twój adres email został potwierdzony przez {{provider}}."
frequency: "Wyślemy do Ciebie email tylko jeżeli dawno Cię nie widzieliśmy i wyłącznie na temat rzeczy których jeszcze nie widziałeś."
name:
title: "Imię"
title: "Pełna nazwa"
instructions: "Pełna wersja twojej nazwy."
too_short: "Twoja nazwa użytkownika jest za krótka."
ok: "Twoja nazwa użytkownika jest poprawna."
username:
title: "Nazwa użytkownika"
short_instructions: "Aby o Tobie wspomnieć, wystarczy napisać @{{username}}."
instructions: "Powinien być unikalny, krótki i bez spacji."
short_instructions: "Aby o tobie wspomnieć, wystarczy napisać @{{username}}."
available: "Ta nazwa użytkownika jest dostępna."
global_match: "Email zgadza się z zarejestrowaną nazwą użytkownika."
global_mismatch: "Zajęta. Może spróbuj {{suggestion}}?"
not_available: "Niedostępna. Może spróbuj {{suggestion}}?"
too_short: "Nazwa użytkownika jest za krótka."
too_long: "Nazwa użytkownika jest za długa."
checking: "Sprawdzanie, czy nazwa użytkownika jest dostępna..."
checking: "Sprawdzanie, czy nazwa użytkownika jest dostępna"
enter_email: 'Nazwa użytkownika znaleziona. Wpisz przypisany adres email.'
prefilled: "Email zgadza się z zarejestrowaną nazwą użytkownika."
locale:
@ -390,7 +394,7 @@ pl_PL:
daily: "codziennie"
weekly: "co tydzień"
bi_weekly: "co 2 tygodnie"
email_direct: "Wyślij powiadomienie, kiedy ktoś mnie cytuje, odpowiada na mój wpis lub wspomina moją @nazwę_użytkownika"
email_direct: "Wyślij powiadomienie, kiedy ktoś mnie cytuje, odpowiada na mój wpis lub wspomina moją @nazwę"
email_private_messages: "Wyślij powiadomienie, kiedy ktoś wyśle mi prywatną wiadomość"
email_always: "Otrzymuj powiadomienia email i wyciągi email nawet gdy jestem aktywny na forum"
other_settings: "Inne"
@ -420,7 +424,7 @@ pl_PL:
few: "po {{count}} minutach"
other: "po {{count}} minutach"
invited:
search: "wpisz aby szukać zaproszeń..."
search: "wpisz aby szukać zaproszeń"
title: "Zaproszenia"
user: "Zaproszony(-a) użytkownik(-czka)"
none: "Jeszcze nikt nie został przez ciebie zaproszony."
@ -464,14 +468,18 @@ pl_PL:
sent_by: "Wysłane przez"
private_message: "prywatna wiadomość"
the_topic: "temat"
loading: "Wczytywanie..."
loading: "Wczytuję…"
errors:
prev_page: "podczas próby wczytania"
reasons:
network: "Błąd sieci"
server: "Błąd serwera"
forbidden: "Brak dostępu"
unknown: "Błąd"
desc:
network: "Sprawdź swoje połączenie."
network_fixed: "Chyba już w porządku."
server: "Kod błędu: {{status}}"
unknown: "Coś poszło nie tak."
buttons:
back: "Cofnij"
@ -483,7 +491,7 @@ pl_PL:
enabled: "Administrator włączył tryb tylko do odczytu. Możesz przeglądać serwis, jednak zmiany nie będą możliwe."
login_disabled: "Logowanie jest zablokowane, gdy strona jest w trybie tylko do odczytu."
too_few_topics_notice: "Utwórz co najmniej 5 publicznych tematów i %{posts} publicznych wpisów by rozpocząć dyskusję. Nowi użytkownicy nie będą mogli podnieść poziomu zaufania jeśli nie będą mieć do czytania wystarczającej ilości treści."
learn_more: "dowiedz się więcej..."
learn_more: "dowiedz się więcej"
year: 'rok'
year_desc: 'tematy dodane w ciągu ostatnich 365 dni'
month: 'miesiąc'
@ -539,7 +547,7 @@ pl_PL:
reset_password: 'Resetuj hasło'
logging_in: "Uwierzytelnianie…"
or: "Lub"
authenticating: "Uwierzytelnianie..."
authenticating: "Uwierzytelnianie"
awaiting_confirmation: "Twoje konto czeka na aktywację. Użyj odnośnika przypomnienia hasła, aby otrzymać kolejny email aktywujący konta."
awaiting_approval: "Twoje konto jeszcze nie zostało zatwierdzone przez osoby z obsługi. Otrzymasz email gdy zostanie zatwierdzone."
requires_invite: "Przepraszamy, dostęp do tego forum jest tylko za zaproszeniem."
@ -569,7 +577,7 @@ pl_PL:
saving_draft_tip: "zapisywanie"
saved_draft_tip: "zapisano"
saved_local_draft_tip: "zapisano lokalnie"
similar_topics: "Twój temat jest podobny do..."
similar_topics: "Twój temat jest podobny do"
drafts_offline: "szkice offline"
min_length:
need_more_for_title: "jeszcze co najmniej {{n}} znaków w tytule"
@ -589,16 +597,16 @@ pl_PL:
create_topic: "Utwórz temat"
create_pm: "Utwórz prywatną wiadomość"
title: "Lub naciśnij Ctrl+Enter"
users_placeholder: "Dodaj użytkownika(-czkę)"
users_placeholder: "Dodaj osobę"
title_placeholder: "O czym jest ta dyskusja w jednym zwartym zdaniu. "
edit_reason_placeholder: "z jakiego powodu edytujesz?"
show_edit_reason: "(dodaj powód edycji)"
reply_placeholder: "Tu wprowadź treść. Użyj składni Markdown lub BBCode do formatowania tekstu. Przeciągnij lub wklej obraz, aby go wgrać."
view_new_post: "Zobacz Twój nowy wpis."
saving: "Zapisywanie..."
saving: "Zapisuję…"
saved: "Zapisano!"
saved_draft: "Posiadasz zachowany szkic wpisu. Kliknij tu aby wznowić jego edycję."
uploading: "Ładowanie..."
uploading: "Wczytuję…"
show_preview: 'pokaż podgląd &raquo;'
hide_preview: '&laquo; schowaj podgląd'
quote_post_title: "Cytuj cały wpis"
@ -631,13 +639,21 @@ pl_PL:
auto_close_examples: 'podaj bezwzględny czas lub liczbę godzin — 24, 17:00, 2013-11-22 14:00'
auto_close_error: "Proszę podaj poprawną wartość."
notifications:
title: "powiadomienia dla wspomnień @name, odpowiedzi do twoich wpisów i tematów, prywatne wiadomości, itp"
title: "powiadomienia dla wspomnień przy użyciu @nazwy, odpowiedzi do twoich wpisów i tematów, prywatne wiadomości, itp"
none: "Aktualnie nie masz żadnych powiadomień."
more: "pokaż starsze powiadomienia"
total_flagged: "wszystkie oflagowane wpisy"
mentioned: "<i title='wspomnienie' class='icon'>@</i><p><span>{{username}}</span> {{description}}</p>"
quoted: "<i title='cytat' class='fa fa-quote-right'></i><p><span>{{username}}</span> {{description}}</p>"
replied: "<i title='odpowiedź' class='fa fa-reply'></i><p><span>{{username}}</span> {{description}}</p>"
posted: "<i title='odpowiedź' class='fa fa-reply'></i><p><span>{{username}}</span> {{description}}</p>"
edited: "<i title='edycja' class='fa fa-pencil'></i><p><span>{{username}}</span> {{description}}</p>"
liked: "<i title='polubienie' class='fa fa-heart'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='przyznanie odznaki' class='fa fa-certificate'></i><p>Przyznano Ci {{description}}</p>"
private_message: "<i title='prywatna wiadomość' class='fa fa-envelope-o'></i><p><span>{{username}}</span> {{description}}</p>"
invited_to_private_message: "<i title='prywatna wiadomość' class='fa fa-envelope-o'></i><p><span>{{username}}</span> {{description}}</p>"
invitee_accepted: "<i title='przyjęcie twojego zaproszenia' class='fa fa-user'></i><p><span>{{username}}</span> przyjmuje twoje zaproszenie</p>"
moved_post: "<i title='przeniesienie wpisu' class='fa fa-sign-out'></i><p><span>{{username}}</span> przenosi {{description}}</p>"
linked: "<i title='powiązany wpis' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
upload_selector:
title: "Dodaj obraz"
title_with_attachments: "Dodaj obraz lub plik"
@ -654,7 +670,7 @@ pl_PL:
search:
title: "szukaj tematów, wpisów, użytkowników lub kategorii"
no_results: "Brak wyników wyszukiwania"
searching: "Wyszukiwanie ..."
searching: "Szukam…"
context:
user: "Szukaj wpisów @{{username}}"
category: "Szukaj w kategorii \"{{category}}\""
@ -672,7 +688,9 @@ pl_PL:
bulk:
reset_read: "Wyzeruj przeczytane"
delete: "Usuń tematy"
dismiss_posts: "Wyczyść liczniki wpisów"
dismiss_posts_tooltip: "Wyczyść liczniki nieprzeczytanych wpisów w tych tematach, ale informuj mnie jeśli pojawią się w nich nowe wpisy w przyszłości."
dismiss_topics: "Wyczyść status termatów"
dismiss_topics_tooltip: "Nie pokazuj tych tematów na mojej liście nieprzeczytanych gdy pojawią się w nich nowe wpisy."
dismiss_new: "Zignoruj nowe"
toggle: "włącz grupowe zaznaczanie tematów"
@ -695,8 +713,8 @@ pl_PL:
category: "Nie ma tematów w kategorii {{category}}."
top: "Brak najlepszych tematów."
educate:
new: '<p>Domyślnie tematy są traktowane jako nowe jeśli zostały utworzone w ciągu ostatnich 2 dni.</p><p>Możesz to zmienić w swoich <a href="%{userPrefsUrl}">ustawieniach</a>.</p>'
unread: '<p>Domyślnie wskażnik Nieprzeczytane pojawia się tylko dla tematów które:</p><ul><li>Utworzyłeś</li><li>Odpowiedziałeś w nich</li><li>Czytałeś dłużej niż 4 minuty</li></ul><p>Lub jeżeli ręcznie przyznałeś status Śledzony lub Obserwowany w ustawieniach powiadomień poniżej każdego tematu.</p><p>Możesz to zmienić w swoich <a href="%{userPrefsUrl}">ustawieniach</a>.</p>'
new: '<p>Domyślnie, tematy są traktowane jako nowe jeśli zostały utworzone w ciągu ostatnich 2 dni.</p><p>Możesz to zmienić w <a href="%{userPrefsUrl}">swoich ustawieniach</a>.</p>'
unread: '<p>Domyślnie, pojawiają się tu tematy:</p><ul><li>twojego autorstwa</li><li>te w których są twoje odpowiedzi </li><li>czytane przez ciebie dłużej niż 4 minuty</li></ul><p>Znajdą się tu też te, którym ręcznie przyznano status Śledzony lub Obserwowany przyciskiem znajdującym się na końcu każdego tematu.</p><p>Możesz zmienić te zachowania w swoich <a href="%{userPrefsUrl}">preferencjach</a>.</p>'
bottom:
latest: "Nie ma więcej najnowszych tematów."
hot: "Nie ma więcej gorących tematów."
@ -724,8 +742,8 @@ pl_PL:
few: '{{count}} nieprzeczytane tematy'
other: '{{count}} nieprzeczytanych tematów'
title: 'Temat'
loading_more: "Ładowanie następnych tematów..."
loading: 'Wczytywanie tematu...'
loading_more: "Wczytuję więcej tematów…"
loading: 'Wczytuję temat…'
invalid_access:
title: "Temat jest prywatny"
description: "Przepraszamy, nie masz dostępu do tego tematu!"
@ -780,38 +798,38 @@ pl_PL:
position: "wpis %{current} z %{total}"
notifications:
reasons:
'3_6': 'Powiadomienia będą wysyłane, ponieważ obserwujesz tę kategorię.'
'3_5': 'Będziesz otrzymywać powiadomienia, ponieważ włączono automatyczne obserwowanie tematu.'
'3_2': 'Będziesz otrzymywał(-a) powiadomienia, ponieważ obserwujesz ten temat.'
'3_1': 'Będziesz otrzymywał(-a) powiadomienia, ponieważ stworzyłeś(-aś) ten temat.'
'3': 'Będziesz otrzymywał(-a) powiadomienia, ponieważ obserwujesz ten temat.'
'2_8': 'Powiadomienia będą wysyłane, ponieważ śledzisz tę kategorię.'
'2_4': 'Będziesz otrzymywać powiadomienia, ponieważ odpowiedziałeś(-aś) w tym temacie.'
'3_6': 'Będziesz otrzymywać powiadomienia o każdym nowym wpisie i temacie, ponieważ obserwujesz tę kategorię.'
'3_5': 'Będziesz otrzymywać powiadomienia o każdym nowym wpisie, ponieważ włączono automatyczne obserwowanie tego tematu.'
'3_2': 'Będziesz otrzymywać powiadomienia o każdym nowym wpisie, ponieważ obserwujesz ten temat.'
'3_1': 'Będziesz otrzymywać powiadomienia, ponieważ jesteś autorem tego tematu.'
'3': 'Będziesz otrzymywać powiadomienia o każdym nowym wpisie, ponieważ obserwujesz ten temat.'
'2_8': 'Będziesz otrzymywać powiadomienia, ponieważ śledzisz tę kategorię.'
'2_4': 'Będziesz otrzymywać powiadomienia, ponieważ jesteś autorem odpowiedzi w tym temacie.'
'2_2': 'Będziesz otrzymywać powiadomienia, ponieważ śledzisz ten temat.'
'2': 'Będziesz otrzymywał(-a) powiadomienia, ponieważ <a href="/users/{{username}}/preferences">przeczytałeś(-aś) ten temat</a>.'
'1_2': 'Dostaniesz powiadomienie tylko gdy ktoś wspomni twój @login lub odpowie na twój wpis.'
'1': 'Dostaniesz powiadomienie tylko gdy ktoś wspomni twój @login lub odpowie na twój wpis.'
'0_7': 'Ignorujesz wszystkie powiadomienia z tej kategorii'
'2': 'Będziesz otrzymywać powiadomienia, ponieważ <a href="/users/{{username}}/preferences">ten temat został uznany za przeczytany.</a>.'
'1_2': 'Dostaniesz powiadomienie jedynie gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis.'
'1': 'Dostaniesz powiadomienie jedynie gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis.'
'0_7': 'Ignorujesz wszystkie powiadomienia z tej kategorii.'
'0_2': 'Ignorujesz wszystkie powiadomienia w tym temacie.'
'0': 'Ignorujesz wszystkie powiadomienia w tym temacie.'
watching_pm:
title: "Obserwowanie"
title: "Obserwuj wszystko"
description: "Dostaniesz powiadomienie o każdym nowym wpisie w tej prywatnej dyskusji. Liczba nowych i nieprzeczytanych wpisów pojawi się obok jej tytułu na liście tematów."
watching:
title: "Obserwowanie"
title: "Obserwuj wszystko"
description: "Dostaniesz powiadomienie o każdym nowym wpisie w tym temacie. Liczba nowych i nieprzeczytanych wpisów pojawi się obok jego tytułu na liście tematów."
tracking_pm:
title: "Śledzenie"
description: "Licznik nowych i nieprzeczytanych wpisów pojawi się obok prywatnej wiadomości. Dostaniesz powiadomienie tylko gdy ktoś wspomni twój @login lub odpisze na twój wpis."
description: "Licznik nowych i nieprzeczytanych wpisów pojawi się obok prywatnej wiadomości. Dostaniesz powiadomienie jedynie gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis."
tracking:
title: "Śledzenie"
description: "Licznik nowych i nieprzeczytanych wpisów pojawi się obok tytułu tego tematu. Dostaniesz powiadomienie jedynie gdy ktoś wspomni twój @login lub odpisze na twój wpis."
description: "Licznik nowych i nieprzeczytanych wpisów pojawi się obok tytułu tego tematu. Dostaniesz powiadomienie jedynie gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis."
regular:
title: "Normalny"
description: "Będziesz powiadamiany(-a) tylko jeśli ktoś wspomni o @Tobie lub odpowie na Twój wpis."
description: "Dostaniesz powiadomienie jedynie gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis."
regular_pm:
title: "Normalny"
description: "Dostaniesz powiadomienie tylko gdy ktoś wspomni twój @login lub odpisze na twój wpis w prywatnej wiadomości."
description: "Dostaniesz powiadomienie jedynie gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis w prywatnej wiadomości."
muted_pm:
title: "Wyciszono"
description: "Nie będziesz dostawać jakichkolwiek powiadomień dotyczących tej prywatnej wiadomości."
@ -819,19 +837,21 @@ pl_PL:
title: "Wyciszenie"
description: "Nie będzie jakichkolwiek powiadomień dotyczących tego tematu i nie będzie się on pojawiać na karcie nieprzeczytanych."
actions:
recover: "Przywróc Temat"
recover: "Przywróć temat"
delete: "Usuń temat"
open: "Otwórz temat"
close: "Zamknij temat"
auto_close: "Zamknij automatycznie"
make_banner: "Ustaw jako baner"
remove_banner: "Wyłącz ten baner"
unpin: "Odepnij temat"
pin: "Przypnij temat"
pin_globally: "Przypnij temat globalnie"
unarchive: "Przywróć z archiwum"
archive: "Archiwizuj temat"
invisible: "Ukryj"
visible: "Pokaż"
reset_read: "Zresetuj Przeczytane Dane"
invisible: "Uczyń niewidocznym"
visible: "Uczyń widocznym"
reset_read: "Zresetuj przeczytane dane"
multi_select: "Wybierz wpisy"
reply:
title: 'Odpowiedz'
@ -846,7 +866,7 @@ pl_PL:
title: 'Zgłoś'
help: 'zgłoś ten temat, aby zwrócić uwagę moderacji lub wyślij powiadomienie o nim'
success_message: 'Ten temat został pomyślnie zgłoszony.'
inviting: "Zapraszanie..."
inviting: "Zapraszam…"
invite_private:
title: 'Zaproś do pisanie Prywatnej Wiadomości'
email_or_username: "Adres email lub nazwa użytkownika zapraszanej osoby"
@ -860,7 +880,7 @@ pl_PL:
action: 'Zaproś przez e-mail'
help: 'wyślij zaproszenia do znajomych by mogli odpowiedzieć na ten temat jednym kliknięciem'
email_placeholder: 'nazwa@example.com'
success: "Wysłaliśmy zaproszenie do <b>{{email}}</b>. Powiadomimy Ciebie jeśli zaproszenie zostanie przyjęte. Sprawdzaj zakładkę zaproszenia na Twoim profilu użytkownika by śledzić swoje zaproszenia."
success: "Wysłaliśmy zaproszenie do <b>{{email}}</b>. Powiadomimy cię gdy zaproszenie zostanie przyjęte. Status swoich zaproszeń możesz śledzić na dedykowanej zakładce w swoim profilu."
error: "Przepraszamy, nie mogliśmy zaprosić tej osoby. Być może jest już na forum?"
login_reply: 'Zaloguj się, aby odpowiedzieć'
filters:
@ -912,7 +932,7 @@ pl_PL:
post:
reply: "Odpowiedz na {{link}} napisany przez {{replyAvatar}} {{username}}"
reply_topic: "Odpowiedz na {{link}}"
quote_reply: "cytuj odpowiedź"
quote_reply: "odpowiedz na ten cytat"
edit: "Edytuj {{link}} napisany przez {{replyAvatar}} {{username}}"
edit_reason: "Powód"
post_number: "wpis {{number}}"
@ -932,7 +952,7 @@ pl_PL:
one: "1 ukryty wpis"
few: "{{count}} ukryte wpisy"
other: "{{count}} ukrytych wpisów"
more_links: "{{count}} więcej..."
more_links: "{{count}} więcej"
unread: "Nieprzeczytany wpis"
has_replies:
one: "Odpowiedź"
@ -960,7 +980,7 @@ pl_PL:
reply: "zacznij tworzyć odpowiedź na ten wpis"
like: "polub ten wpis"
has_liked: "polubiono ten wpis"
undo_like: "cofnij polubienie"
undo_like: "anuluj polubienie"
edit: "edytuj ten wpis"
edit_anonymous: "Przykro nam, ale musisz być zalogowany aby edytować ten wpis."
flag: "oflaguj ten wpis lub wyślij powiadomienie o nim do moderatorów"
@ -996,7 +1016,7 @@ pl_PL:
spam: "Cofnij flagę"
inappropriate: "Cofnij flagę"
bookmark: "Cofnij zakładkę"
like: "Cofnij polubienie"
like: "Anuluj polubienie"
vote: "Cofnij głos"
people:
off_topic: "{{icons}} oznaczyli jako nie-na-temat"
@ -1010,14 +1030,14 @@ pl_PL:
like: "{{icons}} lubi to"
vote: "{{icons}} zagłosowało za tym"
by_you:
off_topic: "Oznaczyłeś(-aś) to jako nie-na-temat"
spam: "Oflagowałeś(-aś) to jako spam"
inappropriate: "Oflagowałeś(-aś) to jako niewłaściwe"
notify_moderators: "Oflagowałeś(-aś) to do moderacji"
off_topic: "Oznaczono jako nie-na-temat"
spam: "Oflagowano jako spam"
inappropriate: "Oznaczono jako niewłaściwe"
notify_moderators: "Oflagowano do moderacji"
notify_user: "Wysłałeś(-aś) prywatną wiadomość do użytkownika(-czki)"
bookmark: "Dodałeś(-aś) ten wpis do zakładek"
like: "Polubiłeś(-aś) to"
vote: "Zagłosowałeś(-aś) za tym wpisem"
bookmark: "Dodano zakładkę w tym wpisie"
like: "Lubisz to"
vote: "Zagłosowano na ten wpis"
by_you_and_others:
off_topic:
one: "Ty i 1 inna osoba oznaczyliście to jako nie-na-temat."
@ -1119,7 +1139,7 @@ pl_PL:
edit: 'edytuj'
edit_long: "Edytuj"
view: 'Pokaż Tematy w Kategorii'
general: 'Ogólna'
general: 'Ogólne'
settings: 'Ustawienia'
delete: 'Usuń kategorię'
create: 'Utwórz kategorię'
@ -1148,6 +1168,8 @@ pl_PL:
auto_close_units: "godzin"
email_in: "Niestandardowy adres poczty przychodządej"
email_in_allow_strangers: "Akceptuj wiadomości email od anonimowych, nieposiadających kont użytkowników "
email_in_disabled: "Tworzenie nowych tematów emailem jest wyłączone w ustawieniach serwisu. "
email_in_disabled_click: 'Kliknij tu, aby włączyć.'
allow_badges_label: "Włącz przyznawanie odznak na podstawie aktywności w tej kategorii"
edit_permissions: "Edytuj uprawnienia"
add_permission: "Dodaj uprawnienie"
@ -1158,16 +1180,17 @@ pl_PL:
parent: "Kategoria rodzica"
notifications:
watching:
title: "Obserwowana"
description: "Będziesz automatycznie obserwować tematy w tych kategoriach. Dostaniesz powiadomienie o każdym nowym wpisie i temacie. Liczba nowych i nieprzeczytanych wpisów pojawi się obok tytułu każdego tematu."
title: "Obserwuj wszystko"
description: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach: liczba nieprzeczytanych i nowych wpisów będzie wyświetlana obok tytułów na liście tematów. Dodatkowo będziesz otrzymywać powiadomienie o każdym nowym wpisie i temacie."
tracking:
title: "Śledzona"
description: "Będziesz automatycznie śledzić wszystkie tematy w tych kategoriach. Licznik nowych i nieprzeczytanych wpisów pojawi się obok ich tytułów na liście tematów."
description: "Będziesz automatycznie śledzić wszystkie tematy w tych kategoriach: licznik nowych i nieprzeczytanych wpisów pojawi się obok ich tytułów na liście tematów."
regular:
title: "Normalny"
description: "Zostaniesz powiadomiony tylko jeśli ktoś wspomni twoją @nazwę w odpowiedzi na twój wpis"
description: "Dostaniesz powiadomienie jedynie gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis."
muted:
title: "Wyciszone"
description: "Nie będziesz powiadamiany o nowych tematach w tych kategoriach i nie będą się one pojawiać w karcie Nieprzeczytane."
flagging:
title: 'Dlaczego chcesz oflagować ten wpis?'
action: 'Oflaguj wpis'
@ -1179,11 +1202,11 @@ pl_PL:
submit_tooltip: "Zapisz prywatną flagę."
take_action_tooltip: "Nie czekaj, aż wpis zostanie zgłoszony przez innych, natychmiast oflaguj do działania . "
cant: "Przepraszamy, nie możesz oflagować teraz tego wpisu."
custom_placeholder_notify_user: "Dlaczego ten wpis wymaga pomówienia z użytkownikiem prywatnie i bezpośrednio? Bądz konkretny, konstuktywny i zawsze miły."
custom_placeholder_notify_user: "Dlaczego ten wpis wymaga bezpośredniej, prywatnej rozmowy z tym użytkownikiem? Napisz konkretnie, konstuktywnie i kulturalnie."
custom_placeholder_notify_moderators: "Dlaczego ten wpis wymaga uwagi moderatora? Daj nam znać co konkretnie Cię zaniepokoiło i dostarcz nam odpowiednie odnośniki jeśli to możliwe."
custom_message:
at_least: "wprowadź co najmniej {{n}} znaków"
more: "{{n}} aby wysłać..."
more: "{{n}} aby wysłać"
left: "{{n}} pozostało"
flagging_topic:
title: "Dlaczego chcesz zgłosić ten temat?"
@ -1191,7 +1214,7 @@ pl_PL:
notify_action: "Wyślij prywatną wiadomość"
topic_map:
title: "Podsumowanie tematu"
links_shown: "pokaż wszystkie {{totalLinks}} odnośników..."
links_shown: "pokaż wszystkie {{totalLinks}} odnośników"
clicks:
one: "1 kliknięcie"
few: "%{count} kliknięć"
@ -1213,25 +1236,28 @@ pl_PL:
invisible:
help: "Ten temat jest niewidzialny - nie będzie wyświetlany na listach tematów i można uzyskać do niego dostęp tylko poprzez bezpośredni odnośnik"
posts: "Wpisy"
posts_lowercase: "wpisów"
posts_lowercase: "wpisy"
posts_long: "jest {{number}} wpisów w tym temacie"
original_post: "Oryginalny wpis"
views: "Wyświetlenia"
views_lowercase: "wyświetleń"
views_lowercase: "wyświetlenia"
replies: "Odpowiedzi"
views_long: "ten temat był oglądany {number}} razy"
activity: "Aktywność"
likes: "Polubienia"
likes_lowercase: "polubienia"
likes_long: "jest {{number}} polubień w tym temacie"
users: "Użytkownicy"
users_lowercase: "użytkowników"
users_lowercase: "użytkownicy"
category_title: "Kategoria"
history: "Historia"
changed_by: "przez {{author}}"
categories_list: "Lista Kategorii"
filters:
with_topics: "%{filter} tematy"
with_category: "%{filter} tematy w %{category} "
latest:
title: "Najnowsze"
title: "Ostatnie"
help: "tematy z ostatnimi wpisami"
hot:
title: "Gorące"
@ -1275,16 +1301,16 @@ pl_PL:
other: "{{categoryName}} ({{count}})"
help: "najnowsze tematy w kategorii {{categoryName}}"
top:
title: "Najpopularniejsze"
help: "najpopularniejsze tematy w ubiegłym roku, miesiącu, tygodniu lub dniu"
title: "Popularne"
help: "popularne tematy w ubiegłym roku, miesiącu, tygodniu lub dniu"
yearly:
title: "Najpopularniejsze w tym roku"
title: "Popularne w tym roku"
monthly:
title: "Najpopularniejsze w tym miesiącu"
title: "Popularne w tym miesiącu"
weekly:
title: "Najpopularniejsze w tym tygodniu"
title: "Popularne w tym tygodniu"
daily:
title: "Najpopularniejsze dzisiaj"
title: "Popularne dzisiaj"
this_year: "W tym roku"
this_month: "W tym miesiącu"
this_week: "W tym tygodniu"
@ -1292,13 +1318,13 @@ pl_PL:
other_periods: "zobacz więcej popularnych tematów"
browser_update: 'Niestety <a href="http://www.discourse.org/faq/#browser">Twoja przeglądarka jest za stara, aby obsługiwała forum Discourse</a>. Proszę <a href="http://browsehappy.com">zaktualizuj swoją przeglądarkę</a>.'
permission_types:
full: "Tworzenie / Odpowiadanie / Oglądanie"
create_post: "Odpowiadanie / Oglądanie"
readonly: "Oglądanie"
full: "tworzyć / odpowiadać / przeglądać"
create_post: "odpowiadać / przeglądać"
readonly: "przeglądać"
admin_js:
type_to_filter: "wpiasz aby filtrować..."
type_to_filter: "pisz, aby filtrować…"
admin:
title: 'Admin Discourse'
title: 'Administrator Discourse'
moderator: 'Moderator'
dashboard:
title: "Kokpit"
@ -1341,16 +1367,45 @@ pl_PL:
title: "Flagi"
old: "Stare"
active: "Aktywność"
agree: "Potwierdź"
agree_title: "Potwierdź to zgłoszenie jako uzasadnione i poprawne"
agree_flag_modal_title: "Potwierdź i..."
agree_flag_hide_post: "Potwierdź (ukryj post i wyślij PW)"
agree_flag_hide_post_title: "Ukryj ten wpis i automatycznie wyślij użytkownikowi prywatną wiadomość informującą, że wpis wymaga przeredagowania"
clear_topic_flags: "Wykonane"
clear_topic_flags_title: "Ten temat został zbadany i problemy zostały rozwiązane. Kliknij Wykone by usunąć oflagowanie."
agree_flag: "Potwierdź flagę"
agree_flag_title: "Potwierdź flagę i zostaw wpis bez zmian"
defer_flag: "Zignoruj"
defer_flag_title: "Usunięcie flagi, nie wymaga dalszych działań."
delete: "Usuń"
delete_title: "Usuń wpis do którego odnosi się flaga."
delete_post_defer_flag: "Usuń wpis i zignoruj flagę"
delete_post_defer_flag_title: "Usuń wpis. Jeśli jest pierwszym w temacie, usuń temat."
delete_post_agree_flag: "Usuń post i potwierdź flagę"
delete_post_agree_flag_title: "Usuń wpis. Jeśli jest pierwszym w temacie, usuń temat."
delete_flag_modal_title: "Usuń i..."
delete_spammer: "Usuń spamera"
delete_spammer_title: "Usuwa konto tego użytkownika oraz wszystkie tematy i wpisy jakie nim utworzono."
disagree_flag_unhide_post: "Wycofaj (pokaż wpis)"
disagree_flag_unhide_post_title: "Usuń wszystkie flagi z tego wpisu i uczyń go widocznym ponownie."
disagree_flag: "Wycofaj"
disagree_flag_title: "Wycofaj nieuzasadnioną flagę."
clear_topic_flags: "Zrobione"
clear_topic_flags_title: "Ten temat został sprawdzony i związane z nim problemy zostały rozwiązane. Kliknij Zrobione, aby usunąć flagi."
more: "(więcej odpowiedzi…)"
flagged_by: "Oflagowany przez"
dispositions:
agreed: "potwierdzono"
disagreed: "wycofano"
deferred: "zignorowano"
flagged_by: "Oflagowano przez"
resolved_by: "Rozwiązano przez"
took_action: "Podjęto działanie"
system: "System"
error: "Coś poszło nie tak"
reply_message: "Odpowiedz"
no_results: "Nie ma flag."
topic_flagged: "Ten <strong>temat</strong> został oflagowany."
visit_topic: "Odwiedź temat by podjąć działania."
was_edited: "Wpis został zmieniony po pierwszej fladze"
summary:
action_type_3:
one: "nie-na-temat"
@ -1362,12 +1417,12 @@ pl_PL:
other: "nieodpowiednie x{{count}}"
action_type_6:
one: "niestandardowy"
few: "x{{count}} niestandardowych"
other: "x{{count}} niestandardowych"
few: "niestandardowe x{{count}}"
other: "niestandardowych x{{count}}"
action_type_7:
one: "niestandardowy"
few: "x{{count}} niestandardowych "
other: "x{{count}} niestandardowych "
few: "niestandardowe x{{count}}"
other: "niestandardowych x{{count}} "
action_type_8:
one: "spam"
few: "spam x{{count}}"
@ -1376,7 +1431,7 @@ pl_PL:
primary: "Główna grupa"
no_primary: "(brak podstawowej grupy)"
title: "Grupy"
edit: "Edytuj Grupy"
edit: "Edytuj grupy"
refresh: "Odśwież"
new: "Nowa"
selector_placeholder: "dodaj użytkowników"
@ -1415,7 +1470,7 @@ pl_PL:
title: "Wyłącz tryb tylko do odczytu"
text: "Wyłącz tryb tylko do odczytu"
logs:
none: "Póki co brak logów..."
none: "Póki co brak logów"
columns:
filename: "Nazwa pliku"
size: "Rozmiar"
@ -1434,6 +1489,8 @@ pl_PL:
backup:
text: "Kopia zapasowa"
title: "Wykonaj kopię zapasową"
confirm: "Czy chcesz wykonać kopię zapasową?"
without_uploads: "Tak (bez wysyłania)"
download:
text: "Pobierz"
title: "Pobierz kopię zapasową"
@ -1546,7 +1603,7 @@ pl_PL:
format: "Format"
html: "html"
text: "text"
last_seen_user: "Użytkownik Ostatnio Widziany:"
last_seen_user: "Ostatnia "
reply_key: "Klucz odpowiedzi"
skipped_reason: "Powód pominięcia"
logs:
@ -1651,13 +1708,13 @@ pl_PL:
few: "odrzuć użytkowników ({{count}})"
other: "odrzuć użytkowników ({{count}})"
titles:
active: 'Aktywni Użytkownicy'
active: 'Aktywni użytkownicy'
new: 'Nowi Użytkownicy'
pending: 'Użytkownicy Oczekujący na Przegląd'
newuser: 'Użytkownicy na Poziomie Zaufania 0 (Nowi Użytkownicy)'
basic: 'Użytkownicy na Poziomie Zaufania 1 (Podstawowi Użytkownicy)'
regular: 'Użytkownicy na Poziomie Zaufania 2 (zwykli użytkownicy)'
leader: 'Użytkownicy na Poziomie Zaufania 3 (Liderzy)'
basic: 'Użytkownicy na Poziomie Zaufania 1 (Podstawowi)'
regular: 'Użytkownicy na Poziomie Zaufania 2 (Zwyczajni)'
leader: 'Użytkownicy na Poziomie Zaufania 3 (Przodownicy)'
elder: 'Użytkownicy na Poziomie Zaufania 4 (Starsi)'
admins: 'Administratorzy'
moderators: 'Moderatoratorzy'
@ -1791,7 +1848,7 @@ pl_PL:
categories:
all_results: 'Wszystkie'
required: 'Wymagane'
basic: 'Podstawowe ustawienia'
basic: 'Podstawowe'
users: 'Użytkownicy'
posting: 'Pisanie'
email: 'Email'
@ -1801,8 +1858,8 @@ pl_PL:
onebox: "Onebox"
seo: 'SEO'
spam: 'Spam'
rate_limits: 'Ograniczenia tempa'
developer: 'Developer'
rate_limits: 'Limity'
developer: 'Deweloperskie'
embedding: "Osadzanie"
legal: "Prawne"
uncategorized: 'Inne'
@ -1841,45 +1898,45 @@ pl_PL:
lightbox:
download: "pobierz"
keyboard_shortcuts_help:
title: 'Skróty Klawiszowe'
title: 'Skróty klawiszowe'
jump_to:
title: 'Przeskocz do'
home: '<b>g</b>, <b>h</b> Początek (Najnowsze)'
latest: '<b>g</b>, <b>l</b> Najnowsze'
title: 'Skocz do'
home: '<b>g</b>, <b>h</b> strona główna (Ostatnie)'
latest: '<b>g</b>, <b>l</b> Ostatnie'
new: '<b>g</b>, <b>n</b> Nowe'
unread: '<b>g</b>, <b>u</b> Nieprzeczytane'
starred: '<b>g</b>, <b>f</b> Oznaczone'
starred: '<b>g</b>, <b>f</b> Ulubione'
categories: '<b>g</b>, <b>c</b> Kategorie'
navigation:
title: 'Nawigacja'
jump: '<b>#</b> Idź to wpisu o numerze'
back: '<b>u</b> Wstecz'
up_down: '<b>k</b>/<b>j</b> Przesuń wybrane w górę/dół'
open: '<b>o</b> or <b>Enter</b> Pokaż wybrany temat'
next_prev: '<b>`</b>/<b>~</b> Następny/poprzedni fragment'
jump: '<b>#</b> idź do wpisu o numerze'
back: '<b>u</b> wstecz'
up_down: '<b>k</b>/<b>j</b> przesuń zaznaczenie w górę/dół'
open: '<b>o</b> lub <b>Enter</b> otwórz wybrany temat'
next_prev: '<b>`</b>/<b>~</b> następna/poprzednia sekcja'
application:
title: 'Aplikacja'
create: '<b>c</b> Utwórz nowy temat'
notifications: '<b>n</b> Pokaż powiadomienia'
search: '<b>/</b> Szukaj'
help: '<b>?</b> Pokaż skróty klawiszowe'
create: '<b>c</b> utwórz nowy temat'
notifications: '<b>n</b> pokaż powiadomienia'
search: '<b>/</b> wyszukaj'
help: '<b>?</b> pokaż skróty klawiszowe'
actions:
title: 'Operacje'
star: '<b>f</b> Gwiazdka dla tematu'
share_topic: '<b>shift s</b> Udostępnij temat'
share_post: '<b>s</b> Udostępnij wpis'
reply_topic: '<b>shift r</b> Odpowiedz w temacie'
reply_post: '<b>r</b> Odpowiedz na wpis'
quote_post: '<b>q</b> Cytuj wpis'
like: '<b>l</b> Polub wpis'
flag: '<b>!</b> Oflaguj wpis'
bookmark: '<b>b</b> Zakładka na wpisie'
edit: '<b>e</b> Edytuj wpis'
delete: '<b>d</b> Usuń wpis'
mark_muted: '<b>m</b>, <b>m</b> Ucisz temat'
mark_regular: '<b>m</b>, <b>r</b> Zwykły (domyślny) temat'
mark_tracking: '<b>m</b>, <b>t</b> Śledź temat'
mark_watching: '<b>m</b>, <b>w</b> Obserwuj temat'
star: '<b>f</b> oznacz temat gwiazdką'
share_topic: '<b>shift s</b> udostępnij temat'
share_post: '<b>s</b> udostępnij wpis'
reply_topic: '<b>shift r</b> odpowiedz w temacie'
reply_post: '<b>r</b> odpowiedz na wpis'
quote_post: '<b>q</b> cytuj wpis'
like: '<b>l</b> polub wpis'
flag: '<b>!</b> oflaguj wpis'
bookmark: '<b>b</b> ustaw zakładkę na wpisie'
edit: '<b>e</b> edytuj wpis'
delete: '<b>d</b> usuń wpis'
mark_muted: '<b>m</b>, <b>m</b> ucisz temat'
mark_regular: '<b>m</b>, <b>r</b> zwykły (domyślny) temat'
mark_tracking: '<b>m</b>, <b>t</b> śledź temat'
mark_watching: '<b>m</b>, <b>w</b> śledź wszystko w temacie'
badges:
title: Odznaki
allow_title: "użycie odznaki jako tytułu?"
@ -1917,10 +1974,10 @@ pl_PL:
name: Podstawowi
description: <a href="https://meta.discourse.org/t/what-do-user-trust-levels-do/4924/4">Przyznano</a> wszystkie podstawowe funkcje
regular_user:
name: Regularność
name: Zwyczajni
description: <a href="https://meta.discourse.org/t/what-do-user-trust-levels-do/4924/5">Przyznano</a> zaproszenia
leader:
name: Liderzy
name: Przodownik
description: <a href="https://meta.discourse.org/t/what-do-user-trust-levels-do/4924/6">Przyznano</a> możliwość zmiany kategorii, nazwy, linków oraz salon
elder:
name: Starszyzna
@ -1932,10 +1989,10 @@ pl_PL:
name: Autobiograf
description: Wypełnienie <a href="/my/preferences">profilu</a> użytkownika
nice_post:
name: Miły Wpis
name: Niezły wpis
description: Otrzymano 10 polubień za wpis. Ta odznaka może być przyznawana wielokrotnie
good_post:
name: Dobry Wpis
name: Dobry wpis
description: Otrzymano 25 polubień za wpis. Ta odznaka może być przyznawana wielokrotnie
great_post:
name: Wspaniały wpis

View File

@ -619,7 +619,6 @@ pt:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span> accepted your invitation</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> moved {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>You were granted {{description}}</p>"
upload_selector:
title: "Adicionar uma imagem"
title_with_attachments: "Adicionar uma imagem ou um ficheiro"

View File

@ -626,7 +626,6 @@ pt_BR:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span> accepted your invitation</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> moved {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>You were granted {{description}}</p>"
upload_selector:
title: "Adicionar uma imagem"
title_with_attachments: "Adicionar uma imagem ou arquivo"

View File

@ -360,16 +360,19 @@ ru:
title: "Фон профиля"
email:
title: "E-mail"
instructions: "Будет всегда скрыт."
ok: "Отлично, мы послали вам письмо с инструкциями."
invalid: "Введите корректный адрес электронной почты."
authenticated: "Ваш адрес электронной почты подтвержден через {{provider}}."
frequency: "В случае вашего отсутствия на форуме вы будете получать уведомления, но только о новых сообщениях."
name:
title: "Имя"
instructions: "Ваше полное имя."
too_short: "Ваше имя слишком короткое."
ok: "Допустимое имя."
username:
title: "Псевдоним"
instructions: "Должен быть уникальным, без пробелов и не очень длинным."
short_instructions: "Пользователи могут упоминать вас по @{{username}}."
available: "Псевдоним доступен."
global_match: "Адрес электронной почты совпадает с зарегистрированным."
@ -478,10 +481,13 @@ ru:
prev_page: "при попытке загрузки"
reasons:
network: "Ошибка сети"
server: "Ошибка сервера"
forbidden: "Доступ закрыт"
unknown: "Ошибка"
desc:
network: "Пожалуйста, проверьте ваше соединение."
network_fixed: "Похоже, сеть появилась."
server: "Ошибка: {{status}}"
unknown: "Что-то пошло не так."
buttons:
back: "Вернуться"
@ -657,7 +663,6 @@ ru:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span> принял(а) ваше приглашение</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> переместил(а) {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>Вы награждены: {{description}}</p>"
upload_selector:
title: "Add an image"
title_with_attachments: "Add an image or a file"
@ -1848,9 +1853,12 @@ ru:
will_be_promoted: "Будет повышен в течение 24 часов."
does_not_qualify: "Не заслуживает уровень доверия 3."
sso:
title: "Технология единого входа SSO"
external_id: "Внешний идентификатор"
external_username: "Псевдоним"
external_name: "Имя"
external_email: "E-mail"
external_avatar_url: "URL-адрес аватарки"
site_content:
none: "Выберите тип контента, чтобы начать редактирование."
title: 'Контент сайта'

View File

@ -20,6 +20,10 @@ zh_CN:
tb: TB
dates:
time: "h:mm a"
long_no_year: "MMM DD h:mm a"
long_no_year_no_time: "MMM D"
long_with_year: "YYYY MMM D h:mm a"
long_with_year_no_time: "YYYY MMM D"
tiny:
half_a_minute: "< 1 分钟"
less_than_x_seconds:
@ -302,16 +306,19 @@ zh_CN:
title: "个人资料背景"
email:
title: "电子邮箱"
instructions: "绝不会被公开显示。"
ok: "看起来不错哦,我们会发送电子邮件让您确认。"
invalid: "请填写正确的电子邮箱地址。"
authenticated: "您的电子邮箱已经被 {{provider}} 确认有效。"
frequency: "只有当您最近一段时间没有访问时,我们才会把您未读过的内容发送到您的电子邮箱。"
name:
title: "名字"
instructions: "名字全称。"
too_short: "您设置的名字太短了。"
ok: "您的名字符合要求。"
username:
title: "用户名"
instructions: "必须唯一,没有空格,简短。"
short_instructions: "其他人可以用 @{{username}} 来提及您。"
available: "您的用户名可用。"
global_match: "电子邮箱与注册用户名相匹配。"
@ -412,10 +419,13 @@ zh_CN:
prev_page: "当尝试载入时"
reasons:
network: "网络错误"
server: "服务器错误"
forbidden: "访问被阻止"
unknown: "错误"
desc:
network: "请检查您的网络连接。"
network_fixed: "似乎恢复正常了。"
server: "错误代码:{{status}}"
unknown: "出错了。"
buttons:
back: "返回"
@ -541,6 +551,7 @@ zh_CN:
view_new_post: "浏览您的新帖子。"
saving: "保存中..."
saved: "已保存!"
saved_draft: "您有一个帖子草稿尚未发表。点击该栏任意位置即可继续编辑。"
uploading: "上传中..."
show_preview: '显示预览 &raquo;'
hide_preview: '&laquo; 隐藏预览'
@ -590,7 +601,6 @@ zh_CN:
invitee_accepted: "<i title='已接受您的邀请' class='fa fa-user'></i><p><span>{{username}}</span> 已接受您的邀请</p>"
moved_post: "<i title='移动了帖子' class='fa fa-sign-out'></i><p><span>{{username}}</span> 移动了 {{description}}</p>"
linked: "<i title='被外链的帖子' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='徽章授予' class='fa fa-certificate'></i><p>您被授予了 {{description}}</p>"
upload_selector:
title: "插入图片"
title_with_attachments: "上传图片或文件"
@ -647,6 +657,9 @@ zh_CN:
hot: "没有热门主题。"
category: "没有 {{category}} 分类的主题。"
top: "没有最佳主题。"
educate:
new: '<p>默认情况下,最近两天创建的主题是新主题。</p><p>您可以在您的<a href="%{userPrefsUrl}">设置</a>里改变这一行为。</p>'
unread: '<p>默认情况下,未读提醒将仅对以下主题显示:</p><ul><li>创建的</li><li>回复的</li><li>阅读超过4分钟的</li></ul><p>或者,如果您在每个主题底部的通知控制中选择了追踪或监视的。</p><p>您可以改变您的<a href="%{userPrefsUrl}">用户设置</a>。</p>'
bottom:
latest: "没有更多主题可看了。"
hot: "没有更多热门主题可看了。"
@ -880,6 +893,8 @@ zh_CN:
confirm: "您确定要放弃编辑您的帖子吗?"
no_value: "否"
yes_value: "是"
wiki:
about: "这个帖子是维基;基础用户能编辑它"
archetypes:
save: '保存选项'
controls:
@ -888,6 +903,7 @@ zh_CN:
has_liked: "您已经赞了本帖"
undo_like: "撤销赞"
edit: "编辑本帖"
edit_anonymous: "抱歉,但是您需要登陆后才能编辑该贴。"
flag: "私下报告本帖以提醒管理人员关注或发送私信通知"
delete: "删除本帖"
undelete: "恢复本帖"
@ -1105,6 +1121,12 @@ zh_CN:
posts: "帖子"
posts_lowercase: "帖子"
posts_long: "本主题有 {{number}} 个帖子"
posts_likes_MF: |
这个主题有 {count, plural, one {1 个帖子}其他{# 帖子数}} {ratio, select,
low {with a high like to like ratio}
med {with a very high post to like ratio}
high {with an extremely high post to like ratio}
other {}}
original_post: "原始帖"
views: "浏览"
views_lowercase: "浏览"
@ -1169,6 +1191,7 @@ zh_CN:
help: "在 {{categoryName}} 分类中热门的主题"
top:
title: "热门"
help: "最近一年、一月、一周或一天的最活跃主题"
yearly:
title: "年度热门"
monthly:
@ -1257,6 +1280,7 @@ zh_CN:
disagree_flag_title: "拒绝这个报告,无效或不正确"
clear_topic_flags: "完成"
clear_topic_flags_title: "这个主题已被调查且提案已被解决。单击<strong>完成</strong>以删除报告。"
more: "(更多回复..."
dispositions:
agreed: "已批准"
disagreed: "未批准"
@ -1270,6 +1294,7 @@ zh_CN:
no_results: "没有报告"
topic_flagged: "这个<strong>主题</strong>已被报告。"
visit_topic: "浏览主题才能操作"
was_edited: "帖子在第一次标记后被编辑"
summary:
action_type_3:
other: "偏离主题 x{{count}}"
@ -1343,6 +1368,8 @@ zh_CN:
backup:
text: "备份"
title: "建立一个备份"
confirm: "您确定要开始建立一个备份吗?"
without_uploads: "是(但不上传)"
download:
text: "下载"
title: "下载该备份"
@ -1529,6 +1556,8 @@ zh_CN:
label: "新:"
ip_address: "IP地址"
add: "添加"
logster:
title: "错误日志"
impersonate:
title: "以用户角度检视"
username_or_email: "用户名或用户电子邮件"
@ -1591,6 +1620,7 @@ zh_CN:
edit_title: "编辑头衔"
save_title: "保存头衔"
refresh_browsers: "强制浏览器刷新"
refresh_browsers_message: "消息发送至所有用户!"
show_public_profile: "显示公开介绍"
impersonate: '检视角度'
ip_lookup: "IP 查询"
@ -1605,12 +1635,15 @@ zh_CN:
reputation: 声誉
permissions: 权限
activity: 活动
like_count: 给出的赞 / 收到的赞
last_100_days: '在最近 100 天'
private_topics_count: 私有主题数量
posts_read_count: 已阅帖子数量
post_count: 创建的帖子数量
topics_entered: 已查看的主题数量
flags_given_count: 所做报告数量
flags_received_count: 收到报告数量
flags_given_received_count: '给出的标记 / 收到的标记'
approve: '批准'
approved_by: "批准人"
approve_success: "用户已被批准, 激活邮件已发送。"
@ -1659,9 +1692,18 @@ zh_CN:
posts_read_all_time: "已读的帖子 (全部)"
flagged_posts: "旗标帖子"
flagged_by_users: "标记的用户"
likes_given: "给出的赞"
likes_received: "收到的赞"
qualifies: "符合等级3的信用度"
will_be_promoted: "在24小时后升级"
does_not_qualify: "未符合等级3的信用度"
sso:
title: "单点登录"
external_id: "外部 ID"
external_username: "用户名"
external_name: "名字"
external_email: "电子邮件"
external_avatar_url: "头像 URL"
site_content:
none: "选择内容类型以开始编辑。"
title: '内容'

View File

@ -589,7 +589,6 @@ zh_TW:
invitee_accepted: "<i title='accepted your invitation' class='fa fa-user'></i><p><span>{{username}}</span>已接受你的邀請</p>"
moved_post: "<i title='moved post' class='fa fa-sign-out'></i><p><span>{{username}}</span> 移動了 {{description}}</p>"
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>你已升級{{description}}</p>"
upload_selector:
title: "加入一張圖片"
title_with_attachments: "加入一張圖片或一個檔案"
@ -1516,6 +1515,8 @@ zh_TW:
label: "新增:"
ip_address: "IP 位址"
add: "加入"
logster:
title: "錯誤紀錄"
impersonate:
title: "以用戶的角度檢視"
username_or_email: "用戶名稱或電子郵件地址"
@ -1593,6 +1594,7 @@ zh_TW:
reputation: 聲望
permissions: 權限
activity: 活動
last_100_days: '在過去 100 天內'
private_topics_count: 私人討論話題
posts_read_count: 讀過的文章
post_count: 已發表的文章
@ -1647,9 +1649,16 @@ zh_TW:
posts_read_all_time: "已讀的文章 (任何時間)"
flagged_posts: "被投訴的文章"
flagged_by_users: "投訴之用戶"
likes_given: "給出的讚"
likes_received: "收到的讚"
qualifies: "符合信任等級 3 的條件。"
will_be_promoted: "將在 24 小時內升級。"
does_not_qualify: "不符合信任等級 3 的條件。"
sso:
external_username: "用戶名稱"
external_name: "名稱"
external_email: "電子郵件"
external_avatar_url: "頭像 URL"
site_content:
none: "選擇要編輯的內容類型。"
title: '內容'
@ -1691,6 +1700,8 @@ zh_TW:
description: 簡述
badge_type: 徽章類型
badge_grouping: 群組
badge_groupings:
modal_title: 徽章群組
granted_by: 升級者為
granted_at: 升級在
save: 儲存

View File

@ -872,7 +872,6 @@ de:
invited_to_private_message: "%{display_username} hat Dich zu einem privaten Gespräch eingeladen: %{link}"
invitee_accepted: "%{display_username} hat Deine Einladung angenommen."
linked: "%{display_username} hat dich auf %{link} verlinkt"
granted_badge: "Dir wurde %{link} verliehen"
search:
within_post: "#%{post_number} von %{username}: %{excerpt}"
types:

View File

@ -858,7 +858,7 @@ en:
leader_promotion_min_duration: "The minimum number of days that a promotion to leader lasts before a user can be demoted."
leader_requires_likes_given: "The minimum number of likes that must be given in the last 100 days to qualify for promotion to leader (3) trust level."
leader_requires_likes_received: "The minimum number of likes that must be received in the last 100 days to qualify for promotion to leader (3) trust level."
leader_links_no_follow: "Whether links from leaders have the nofollow attribute."
leader_links_no_follow: "Do not remove rel=nofollow from leader links."
min_trust_to_create_topic: "The minimum trust level required to create a new topic."
@ -926,13 +926,13 @@ en:
disable_emails: "Prevent Discourse from sending any kind of emails"
pop3s_polling_enabled: "Poll via POP3S for email replies."
pop3s_polling_insecure: "Poll using plain text POP3 without SSL."
pop3s_polling_period_mins: "The period in minutes between checking the POP3S account for email. NOTE: requires restart."
pop3s_polling_port: "The port to poll a POP3S account on."
pop3s_polling_host: "The host to poll for email via POP3S."
pop3s_polling_username: "The username for the POP3S account to poll for email."
pop3s_polling_password: "The password for the POP3S account to poll for email."
pop3_polling_enabled: "Poll via POP3 for email replies."
pop3_polling_ssl: "Use SSL while connecting to the POP3 server. (Recommended)"
pop3_polling_period_mins: "The period in minutes between checking the POP3 account for email. NOTE: requires restart."
pop3_polling_port: "The port to poll a POP3 account on."
pop3_polling_host: "The host to poll for email via POP3."
pop3_polling_username: "The username for the POP3 account to poll for email."
pop3_polling_password: "The password for the POP3 account to poll for email."
email_in: "Allow users to post new topics via email (requires pop3 polling). Configure the addresses in the \"Settings\" tab of each category."
email_in_min_trust: "The minimum trust level a user needs to have to be allowed to post new topics via email."
email_prefix: "The [label] used in the subject of emails. It will default to 'title' if not set."

View File

@ -869,7 +869,6 @@ es:
invited_to_private_message: "%{display_username} te ha invitado a un mensaje privado: %{link}"
invitee_accepted: "%{display_username} ha aceptado tu invitación"
linked: "%{display_username} te enlazó en %{link}"
granted_badge: "Te ha sido concedido %{link}"
search:
within_post: "#%{post_number} por %{username}: %{excerpt}"
types:

View File

@ -878,7 +878,6 @@ fi:
invited_to_private_message: "%{display_username} kutsui sinut yksityisviestiin: %{link}"
invitee_accepted: "%{display_username} hyväksyi kutsusi"
linked: "%{display_username} linkitti sinuun täällä %{link}"
granted_badge: "Sinulle myönnettiin %{link}"
search:
within_post: "#%{post_number} käyttäjältä %{username}: %{excerpt}"
types:

View File

@ -883,7 +883,6 @@ fr:
invited_to_private_message: "%{display_username} vous a invité dans une conversation privée: %{link}"
invitee_accepted: "%{display_username} a accepté votre invitation"
linked: "%{display_username} a mentionné l'un de vos messages : %{link}"
granted_badge: "On vous a décerné %{link}"
search:
within_post: "#%{post_number} par %{username}: %{excerpt}"
types:

View File

@ -831,7 +831,6 @@ he:
invited_to_private_message: "%{display_username} הזמין אותך להודעה פרטית: %{link}"
invitee_accepted: "%{display_username} קיבל את הזמנתך"
linked: "%{display_username} קישר אליך ב %{link}"
granted_badge: "הוענק לך %{link}"
search:
within_post: "#%{post_number} מאת %{username}: %{excerpt}"
types:

View File

@ -618,7 +618,6 @@ it:
invited_to_private_message: "%{display_username} ti ha invitato in un messaggio privato: %{link}"
invitee_accepted: "%{display_username} ha accettato il tuo invito"
linked: "%{display_username} ti ha linkato in %{link}"
granted_badge: "Ti è stato assegnato %{link}"
search:
within_post: "#%{post_number} di %{username}: %{excerpt}"
types:

View File

@ -20,6 +20,7 @@ nl:
posts: "berichten"
loading: "Laden"
powered_by_html: 'Powered by <a href="http://www.discourse.org">Discourse</a>, werkt het beste met JavaScript ingeschakeld'
log_in: "Inloggen"
via: "%{username} via %{site_name}"
is_reserved: "is gereserveerd"
errors:
@ -201,6 +202,7 @@ nl:
title: "ervaren lid"
change_failed_explanation: "Je probeerde %{user_name} te degraderen naar '%{new_trust_level}'. Echter, het trust level is al '%{current_trust_level}'. %{user_name} blijft op trust level '%{current_trust_level}'"
rate_limiter:
slow_down: "Je hebt deze actie te vaak uitgevoerd. Probeer het later nog een keer."
too_many_requests: "Er is een dagelijks limiet voor hoe vaak je dat kan doen. Wacht %{time_left} voordat je dit opnieuw probeert."
hours:
one: "1 uur"
@ -602,7 +604,7 @@ nl:
suppress_uncategorized_badge: "Laat de badge niet zien voor topics zonder categorie in de topiclijsten."
global_notice: "Laat een LET OP, BELANGRIJK-banner zien aan alle gebruikers. Laat leeg om niet te tonen (HTML is toegestaan)."
enable_names: "Gebruikers mogen hun volledige naam laten zien. Zet uit om volledige namen te verbergen."
display_name_on_posts: "Laat de volledige naam van een gebruiker bij zijn berichten zijn, naar de @gebruikersnaam"
display_name_on_posts: "Laat de volledige naam van een gebruiker bij zijn berichten zien, na de @gebruikersnaam"
short_progress_text_threshold: "Als het aantal berichten in een topic meer is dan dit aantal zal de voortgangsbalk alleen het nummer van het huidige bericht tonen. Als je de breedte van de voortgangsbalk verandert, moet je dit getal misschien ook aanpassen."
default_code_lang: "Standaard programmeertaal die gebruikt wordt voor syntax highlighting van GitHub codeblokken (lang-auto, ruby, python etc.)"
tos_accept_required: "Gebruikers moeten een vinkje zetten bij het inschrijven om aan te geven dat ze akkoord gaan met de algemene voorwaarden als deze optie actief is. Ga naar 'Inschijfformulier: Algemene Voorwaarden' in de Inhoud tab om het bericht te wijzigen."
@ -625,11 +627,10 @@ nl:
invited_to_private_message: "%{display_username} heeft je uitgenodigd voor een privé-bericht: %{link}"
invitee_accepted: "%{display_username} heeft je uitnodiging geaccepteerd"
linked: "%{display_username} heeft je gelinkt in %{link}"
granted_badge: "%{link} is aan jou toegekend"
search:
within_post: "#%{post_number} door %{username}: %{excerpt}"
types:
category: 'Categorien'
category: 'Categorieën'
topic: 'Resultaten'
user: 'Leden'
original_poster: "Oorspronkelijk geplaatst door"
@ -880,6 +881,10 @@ nl:
see_more: "Meer"
search_title: "Zoek op deze site"
search_google: "Google"
login_required:
welcome_message: |
#[Welkom op %{title}](#welcome)
Voor dit forum is een account nodig. Maak een account aan of log in om verder te gaan.
terms_of_service:
title: "Algemene Voorwaarden"
user_content_license: |
@ -903,6 +908,7 @@ nl:
sockpuppet: "Een nieuwe gebruiker maakte een nieuwe topic en een andere gebruiker reageerde - vanaf hetzelfde IP-adres. Zie de flag_sockpuppets instelling."
email_log:
no_user: "Kan geen gebruiker met id %{user_id} vinden"
suspended_not_pm: "De gebruiker is geschorst, geen privébericht"
seen_recently: "Gebruiker was recentelijk nog online"
post_not_found: "Kan geen bericht met id %{post_id} vinden"
notification_already_read: "De notificatie waar deze mail voor is is al gezien"
@ -919,6 +925,8 @@ nl:
guidelines: "Regels"
privacy: "Privacy"
edit_this_page: "Wijzig deze pagina"
static_topic_first_reply: |
Verander het eerste bericht in dit Topic om de inhoud van de %{page_name} pagina te wijzigen.
guidelines_topic:
title: "FAQ/Regels"
tos_topic:

View File

@ -47,7 +47,7 @@ pl_PL:
one: "1 odpowiedź więcej"
few: "%{count} odpowiedzi więcej"
other: "%{count} odpowiedzi więcej"
loading: "Wczytywanie dyskusji..."
loading: "Wczytuję dyskusję…"
permalink: "Link bezpośredni"
in_reply_to: "▶ %{username}"
replies:
@ -79,14 +79,14 @@ pl_PL:
just_posted_that: "jest zbyt podobne do tego co umieściłeś niedawno"
has_already_been_used: "został już użyty"
invalid_characters: "zawiera niepoprawne znaki"
is_invalid: "jest niepoprawny; spróbuj opisać to dokładniej"
is_invalid: "jest niewystarczająca spróbuj ją rozwinąć"
next_page: "następna strona →"
prev_page: "← poprzednia strona"
page_num: "Strona %{num}"
topics_in_category: "Tematy w kategorii '%{category}'"
rss_posts_in_topic: "Kanał RSS tematu '%{topic}'"
rss_topics_in_category: "Kanał RSS tematów z kategorii '%{category}'"
author_wrote: "%{author} napisał(-a):"
author_wrote: "%{author} pisze:"
num_posts: "Wpisy:"
num_participants: "Uczestnicy:"
read_full_topic: "Przeczytaj cały temat"
@ -123,11 +123,11 @@ pl_PL:
sequential_replies: |
### Rozważ odpowiadanie na kilka postów jednocześnie
Zamiast umieszczać tyle kolejnych odpowiedzi w jednym temacie, rozważ zastosowanie jednej odpowiedzi, która zawiera cytaty lub odwołania przez @nazwa do poprzednich wpisów.
Zamiast umieszczać odpowiedzi jedna po drugiej w jednym temacie, rozważ zastosowanie jednej odpowiedzi, która zawiera cytaty lub odwołania przez @nazwy do poprzednich wpisów.
Możesz edytować swoją poprzednią odpowiedź by dodać cytat przez zaznaczenie tekstu i kliknięcie pojawiającego się przycisku <b>quote reply</b>.
Możesz edytować swoją poprzednią odpowiedź aby dodać cytat przez zaznaczenie tekstu i kliknięcie <b>odpowiedz na ten cytat</b>.
Łatwiej jest czytać tematy mające mniej głębszych odpowiedzi niż wiele małych, indywidualnych odpowiedzi.
O wiele łatwiej jest czytać tematy mające kilka wyczerpujących odpowiedzi niż wiele krótkich i zdawkowych.
dominating_topic: |
### Pozwól innym dołączyć do rozmowy
@ -154,7 +154,7 @@ pl_PL:
raw: "Treść"
errors:
messages:
is_invalid: "jest niepoprawny; spróbuj opisać go dokładniej"
is_invalid: "jest niewystarczająca spróbuj ją rozwinąć"
has_already_been_used: "jest już użyty"
models:
topic:
@ -317,7 +317,7 @@ pl_PL:
update: 'Zmień hasło'
save: 'Ustaw hasło'
title: 'Zresetuj hasło'
success: "Zmieniłeś(-aś) swoje hasło i zostałeś(-aś) zalogowany(-a)."
success: "Twoje hasło zostało pomyślnie zmienione i nastąpiło zalogowanie.."
success_unapproved: "Zmieniłeś(-a) swoje hasło."
continue: "Przejdź do %{site_name}"
change_email:
@ -486,7 +486,6 @@ pl_PL:
title_nag: "Ustawienie serwisu title nadal ma domyślną wartość. Zmień ją na tytuł Twojego serwisu w <a href='/admin/site_settings'>ustawieniach serwisu</a>."
site_description_missing: "The site_description setting is blank. Write a brief description of this forum in the <a href='/admin/site_settings'>Site Settings</a>."
consumer_email_warning: "Twój serwis jest skonfigurowany by używać Gmaila (lub innego konsumenckiego serwisu poczty) do wysyłania emaili. <a href='http://support.google.com/a/bin/answer.py?hl=en&answer=166852' target='_blank'>Gmail ogranicza jak dużo wiadomości możesz wysłać</a>. Rozważ wykorzystanie dostawcy serwisu pocztowego jak mandrill.com by zagwarantować dostarczanie poczty."
access_password_removal: "Your site was using the access_password setting, which has been removed. The login_required and must_approve_users settings have been enabled, which should be used instead. You can change them in the <a href='/admin/site_settings'>Site Settings</a>. Be sure to <a href='/admin/users/list/pending'>approve users in the Pending Users list</a>. (This message will go away after 2 days.)"
site_contact_username_warning: "The site_contact_username setting is blank. Please update it in the <a href='/admin/site_settings'>Site Settings</a>. Set it to the username of an admin user who should be the sender of system messages."
notification_email_warning: "The notification_email setting is blank. Please update it in the <a href='/admin/site_settings'>Site Settings</a>."
content_types:
@ -516,6 +515,7 @@ pl_PL:
default_locale: "Domyślny język tej instancji Discourse (kod ISO 639-1)"
min_private_message_title_length: "Minimalna ilość znaków w tytule prywatnej wiadomości"
allow_uncategorized_topics: "Pozwól na tworzenie tematów bez kategorii"
uncategorized_description: "Znajdują się tu wątki którym jeszcze nie przypisano odpowiedniej kategorii."
unique_posts_mins: "Ile minut musi upłynąć zanim użytkownik będzie mógł ponownie zrobić wpis z tą samą treścią"
queue_jobs: "DEVELOPER ONLY! WARNING! By default, queue jobs in sidekiq. If disabled, your site will be broken."
category_featured_topics: "Number of topics displayed per category on the /categories page. After changing this value, it takes up to 15 minutes for the categories page to update."
@ -528,18 +528,18 @@ pl_PL:
long_polling_interval: "Interval before a new long poll is issued in milliseconds "
polling_interval: "How often should logged in user clients poll in milliseconds"
anon_polling_interval: "How often should anonymous clients poll in milliseconds"
auto_track_topics_after: "Global default milliseconds before a topic is automatically tracked, users can override (0 for always, -1 for never)"
auto_track_topics_after: "Liczba milisekund zanim temat jest automatycznie dodany do śledzonych. użytkownik może nadpisać tę wartość w swoich preferencjach (0 zawsze, -1 nigdy)"
new_topic_duration_minutes: "Global default number of minutes a topic is considered new, users can override (-1 for always, -2 for last visit)"
flags_required_to_hide_post: "Number of flags that cause a post to be automatically hidden and PM sent to the user (0 for never)"
notify_mods_when_user_blocked: "If a user is automatically blocked, send a message to all moderators."
ga_tracking_code: "Google analytics (ga.js) tracking code code, eg: UA-12345678-9; see http://google.com/analytics"
ga_tracking_code: "Identyfikator Google analytics (ga.js), np: UA-12345678-9; zobacz http://google.com/analytics"
ga_domain_name: "Google analytics (ga.js) domain name, eg: mysite.com; see http://google.com/analytics"
ga_universal_tracking_code: "Identyfikator Google Universal Analytics (analytics.js), np: UA-12345678-9; zobacz http://google.com/analytics"
enable_noscript_support: "Enable standard webcrawler search engine support via the noscript tag"
top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|starred|categories|top|read|posted"
track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default because it rewrites URLs"
track_external_right_clicks: "Śledź zewnętrzne linki kliknięte prawym klawiszem (np. otwierane w nowej zakładce). Domyślnie wyłączone, gdyż wymaga nadpisywania URLi."
port: "DEVELOPER ONLY! WARNING! Use this HTTP port rather than the default of port 80. Leave blank for default of 80."
force_hostname: "DEVELOPER ONLY! WARNING! Specify a hostname in the URL. Leave blank for default."
invite_expiry_days: "How long user invitation keys are valid, in days"
min_password_length: "Minimalna długość hasła."
enable_yahoo_logins: "Enable Yahoo authentication"
enable_twitter_logins: "Enable Twitter authentication, requires twitter_consumer_key and twitter_consumer_secret"
@ -555,6 +555,8 @@ pl_PL:
previous_visit_timeout_hours: "How long a visit lasts before we consider it the 'previous' visit, in hours"
s3_upload_bucket: "The Amazon S3 bucket name that files will be uploaded into. WARNING: must be lowercase, no periods."
min_trust_to_create_topic: "The minimum trust level required to create a new topic."
newuser_max_mentions_per_post: "Maksymalna liczba powiadomień poprzez @nazwę w jednym wpisie (dla nowych użytkowników)."
max_mentions_per_post: "Maksymalna liczba powiadomień poprzez @nazwę w jednym wpisie (dla wszystkich)."
title_fancy_entities: "Convert common ASCII characters to fancy HTML entities in topic titles, ala SmartyPants http://daringfireball.net/projects/smartypants/"
title_prettify: "Prevent common title typos and errors, including all caps, lowercase first character, multiple ! and ?, extra . at end, etc."
faq_url: "If you have a FAQ hosted elsewhere that you want to use, provide the full URL here."
@ -563,22 +565,20 @@ pl_PL:
newuser_spam_host_threshold: "How many times a new user can post a link to the same host within their `newuser_spam_host_posts` posts before being considered spam."
reply_by_email_address: "Template for reply by email incoming email address, for example: %{reply_key}@reply.example.com or replies+%{reply_key}@example.com"
delete_all_posts_max: "The maximum number of posts that can be deleted at once with the Delete All Posts button. If a user has more than this many posts, the posts cannot all be deleted at once and the user can't be deleted."
username_change_period: "The number of days after registration that accounts can change their username (0 to disallow username change)."
email_editable: "Allow users to change their e-mail address after registration."
default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
enable_mobile_theme: "Mobile devices use a mobile-friendly theme, with the ability to switch to the full site. Disable this if you want to use a custom stylesheet that is fully responsive."
notification_types:
mentioned: "%{display_username} wspomniał(-a) o Tobie w %{link}"
mentioned: "%{display_username} wspomina o Tobie w %{link}"
liked: "%{display_username} polubił(-a) Twój wpis w %{link}"
replied: "%{display_username} odpowiedział(-a) na Twój wpis w %{link}"
quoted: "%{display_username} zacytował(-a) Twój wpis w %{link}"
edited: "%{display_username} edytował(-a) Twój wpis w %{link}"
posted: "%{display_username} napisał(-a) w %{link}"
replied: "%{display_username} odpowiada na Twój wpis w %{link}"
quoted: "%{display_username} cytuje Twój wpis w %{link}"
edited: "%{display_username} edytuje Twój wpis w %{link}"
posted: "%{display_username} pisze w %{link}"
moved_post: "%{display_username} przeniósł(-a) Twój wpis do %{link}"
private_message: "%{display_username} wysłał(-a) Ci prywatną wiadomość: %{link}"
private_message: "%{display_username} wysyła Ci prywatną wiadomość: %{link}"
invited_to_private_message: "%{display_username} zaprosił(-a) Cię do prywatnej wiadomości: %{link}"
invitee_accepted: "%{display_username} przyjął(-ęła) Twoje zaproszenie"
granted_badge: "Otrzymałeś %{link}"
search:
types:
category: 'Kategorie'
@ -602,10 +602,10 @@ pl_PL:
closed_enabled: "This topic is now closed. New replies are no longer allowed."
closed_disabled: "This topic is now opened. New replies are allowed."
autoclosed_disabled: "This topic is now opened. New replies are allowed."
pinned_enabled: "This topic is now pinned. It will appear at the top of its category until it is unpinned by staff for everyone, or by individual users for themselves."
pinned_enabled: "Ten temat został przypięty. Pojawi się na górze swojej kategorii dopóki nie zostanie odpięty dla wszystkich przez opiekuna, lub tylko dla siebie przez użytkownika."
pinned_disabled: "This topic is now unpinned. It will no longer appear at the top of its category."
visible_enabled: "This topic is now visible. It will be displayed in topic lists."
visible_disabled: "This topic is now invisible. It will no longer be displayed in any topic lists. The only way to access this topic is via direct link."
visible_disabled: "Ten temat został ustawiony jako niewidoczny. Nie pojawi się na żadnej liście tematów. Aby go otworzyć wymagana będzie znajomość linku bezpośredniego. "
login:
not_approved: "Twoje konto nie zostało jeszcze aktywowane. Zostaniesz powiadomiony emailem gdy będziesz mógł się zalogować."
incorrect_username_email_or_password: "Niepoprawna nazwa użytkownika, email lub hasło"
@ -660,6 +660,10 @@ pl_PL:
system_messages:
post_hidden:
subject_template: "Wpis został ukryty z powodu oflagowania przez społeczność"
usage_tips:
text_body_template: "Ta prywatna wiadomość zawiera kilka szybkich porad na początek:\n\n## Przewijaj!\n\nNie ma przycisków do przejścia na następną stronę ani numerów stron.\nChcesz przeczytać więcej? **Po prostu dalej przewijaj w dół!**\n\nGdy ktoś napisze nową wiadomość, pojawi się ona automatycznie na końcu tematu.\n\n## Gdzie ja jestem? \n\n- Wyszukiwanie, twój profil oraz menu znajdują się **pod ikonami w prawym, górnym rogu**.\n\n- Podczas czytania tematu, możesz przejść na początek &uarr; klikając jego tytuł na górze strony. \nKliknij na pasku postępu na dole strony, aby wyświetlić szczegółową nawigację lub użyj klawiszy <kbd>home</kbd> i <kbd>end</kbd>.\n\n <img src=\"http://www.discourse.org/images/welcome/progress-bar.png\" width=\"190\" height=\"52\">\n\n- Kliknięcie na tytule innego tematu zawsze przenosi do miejsca w którym pojawiają się nieprzeczytane wpisy. \n\n## Jak odpowiadać?\n\n - By odpowiedzieć na ogólny wątek tematu użyj przycisku *Odpowiedz* <img src=\"http://www.discourse.org/images/welcome/reply-topic.png\" width=\"29\" height=\"25\"> na samym końcu tematu.\n\n - By odpowiedzieć na konkretny wpis, użyj przycisku *Odpowiedz* <img src=\"http://www.discourse.org/images/welcome/reply-post.png\" width=\"29\" height=\"25\"> przy danym wpisie.\n\n - By poprowadzić rozmowę w innym kierunku, lecz utrzymać powiązanie, użyj przycisku *Odpowiedz jako nowy temat* <img src=\"http://www.discourse.org/images/welcome/reply-as-new-topic.png\" width=\"33\" height=\"25\"> wyświetlanego po prawej stronie wpisu.\n\n - By zacytować kogoś w swojej odpowiedzi zaznacz fragment którego chcesz użyć:\n<img src=\"http://www.discourse.org/images/welcome/quote-reply.png\" width=\"467\" height=\"172\">\n (możesz też użyć przycisku *Cytuj cały wpis* na pasku edytora, aby uzyskać źródło całej cytowanej wiadomości)\n\n - By odnieść się do kogoś w swojej odpowiedzi użyj nazwy tej osoby poprzedzonej znakiem `@`.\n Jeśli kilka osób ma podobne nazwy, powinno pojawić się małe okno wyboru:\n<img src=\"http://www.discourse.org/images/welcome/username-completion.png\" width=\"307\" height=\"174\">\n\n\
## Co jeszcze mogę zrobić?\n\n<img src=\"http://www.discourse.org/images/welcome/like-link-flag-bookmark.png\" width=\"225\" height=\"61\">\n\n- Wpis który uważasz za wartościowy możesz **polubić** jednym z przycisków widocznych na jego końcu.\n- Jeśli chcesz **udostępnić** dany wpis, możesz skopiować jego *link bezpośredni*.\n- Jeśli z wpisem jest coś nie tak, możesz go **oflagować**, co zasygnalizuje autorowi lub moderatorom, że należy go poprawić.\n- Możesz też stworzyć **zakładkę** zaznaczyć miejsce do którego chcesz wrócić \n\nObsługiwany jest [standard Emoji](http://www.emoji-cheat-sheet.com/): zacznij od `:` lub standardowych emotikon `:)` :smile:\n\n## Kto do mnie pisze?\n\nGdy ktoś odpowie na twój wpis, zacytuje, lub wspomni o tobie używając twojej `@nazwy` w prawym górnym rogu strony, nad dymkiem pojawi się liczba. Klikając na niej dowiesz się kto i gdzie do ciebie pisze.\n\n<img src=\"http://www.discourse.org/images/welcome/notification-panel.png\" width=\"237\" height=\"78\">\n\nPowiadomienie o odpowiedziach oraz prywatnych wiadomościach otrzymasz emailem, jeśli w chwili ich otrzymania nie będziesz na stronie.\n\n## Nowe dyskusje?\n\nDomyślnie wszystkie dyskusje młodsze niż dwa dni są uważane za nowe.\nKażda w której bierzesz udział jest automatycznie śledzona.\n\nObok tych tematów zobaczysz niebieskie wskaźniki nowości oraz ilości nieprzeczytanych wpisów:\n\n<img src=\"http://www.discourse.org/images/welcome/topics-new-unread.png\" width=\"490\" height=\"119\">\n\nMożesz zmienić stan powiadomienia każdego tematu przy użyciu przycisku znajdującego się na jego końcu (kategorie posiadają podobny przycisk).\n\nAby zmienić domyślne ustawienia śledzenia i zdefiniować nowe wejdź w [preferencje](/my/preferences).\n\n## Dlaczego nie mogę wykonać niektórych operacji?\n\nDla ochrony innych, nowi użytkownicy mają nałożone ograniczenia. Udzielając się w dyskusjach zdobędziesz zaufanie społeczności, staniesz się pełnoprawnym jej obywatelem i wspomniane limity zostaną automatycznie zdjęte. Zdobywając odpowiednio wysoki [poziom zaufania](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924)\
\ otrzymasz dostęp do zaawansowanych funkcji dzięki którym będziesz mógł pomóc w zarządzaniu społecznością.\n"
welcome_user:
subject_template: "Witaj na forum %{site_name}!"
welcome_invite:
@ -695,9 +699,9 @@ pl_PL:
unsubscribe:
title: "Wypisz"
description: "Nie chcesz otrzymywać tych emaili? Nie ma problemu! Kliknij poniżej by wypisać się natychmiast:"
reply_by_email: "To respond, reply to this email or visit %{base_url}%{url} in your browser."
reply_by_email: "Aby odpowiedzieć odpisz na ten email lub otwórz %{base_url}%{url} w swojej przeglądarce."
visit_link_to_respond: "To respond, visit %{base_url}%{url} in your browser."
posted_by: "Dodane przez %{username} dnia %{post_date}"
posted_by: "Dodany przez %{username} w dniu %{post_date}"
user_invited_to_private_message_pm:
subject_template: "[%{site_name}] %{username} dołączył ciebie do prywatnego tematu '%{topic_title}'"
text_body_template: |
@ -743,7 +747,7 @@ pl_PL:
digest:
subject_template: "[%{site_name}] Streszczenie dla %{date}"
new_activity: "Nowa aktywność w Twoich tematach i wpisach:"
top_topics: "Najpopularniejsze wpisy"
top_topics: "Popularne wpisy"
other_new_topics: "Popularne wątki"
click_here: "kliknij tutaj"
from: "%{site_name} streszczenie"

View File

@ -579,7 +579,6 @@ pt_BR:
invited_to_private_message: "%{display_username} convidou-te para uma conversa privada: %{link}"
invitee_accepted: "%{display_username} aceitou o seu convite"
linked: "%{display_username} linkou você em %{link}"
granted_badge: "Foi concedido a você %{link}"
search:
within_post: "#%{post_number} por %{username}: %{excerpt}"
types:

View File

@ -772,7 +772,6 @@ ru:
invited_to_private_message: "%{display_username} пригласил вас в частную беседу: %{link}"
invitee_accepted: "%{display_username} принял ваше приглашение"
linked: "пользователь %{display_username} упомянул вас в %{link}"
granted_badge: "Вы награждены: %{link}"
search:
within_post: "#%{post_number} от %{username}: %{excerpt}"
types:

View File

@ -480,7 +480,6 @@ uk:
private_message: "%{display_username} sent you a private message: %{link}"
invited_to_private_message: "%{display_username} invited you to a private message: %{link}"
invitee_accepted: "%{display_username} accepted your invitation"
granted_badge: "Ви отримали %{link}"
search:
within_post: "#%{post_number} by %{username}: %{excerpt}"
types:

View File

@ -190,8 +190,10 @@ zh_CN:
vip_category_name: "贵宾室"
vip_category_description: "高于信任等级3的用户参与讨论的分类。"
meta_category_name: "站务"
meta_category_description: "讨论该站点的站务、组织、如何运作和如何改善它。"
staff_category_name: "职员"
staff_category_description: "职员私有的分类。只有管理员和版主才能阅览主题。"
assets_topic_body: "这是一个永久主题,仅对职员可见,用于存储论坛设计使用的图像和文件。不要删除它!\n\n\n详细教程\n\n\n1. 回复到这个主题。\n2. 上传您想用作站点标志、图标和其他所有图片到这儿。(使用帖子编辑器工具栏中的上传图标,或者拖拽或者粘贴图像。)\n3. 提交您的回复添加帖子。\n4. 在您的新帖子里右键点击图片获得这些已上传图片的链接,或者点击编辑按钮来编辑帖子,获得到图片的相对地址。复制这些相对地址。\n5. 粘贴这些图像的路径到[基础设置](/admin/site_settings/category/required)。\n\n\n如果您需要运行额外的上传文件类型在[文件设置](/admin/site_settings/category/files)中编辑 `authorized_extensions`。"
lounge_welcome:
title: "欢迎来到贵宾室"
body: |2
@ -243,6 +245,7 @@ zh_CN:
title: "资深用户"
change_failed_explanation: "您尝试将 %{user_name} 降至 '%{new_trust_level}'。然而他们的信任等级已经是 '%{current_trust_level}'。%{user_name} 将仍是 '%{current_trust_level}'"
rate_limiter:
slow_down: "您已经重复这一操作太多次了,请一会再重试"
too_many_requests: "您的请求过于频繁,请等待 %{time_left} 之后再试。"
hours:
other: "%{count} 小时"
@ -374,6 +377,7 @@ zh_CN:
email_body: "%{link}\n\n%{message}"
flagging:
you_must_edit: '<p>您的帖子被社群成员标记了。请<a href="/my/private-messages">查看您的私信</a>。</p>'
user_must_edit: '<p>您的帖子已经被社群标记并被临时隐藏。</p>'
archetypes:
regular:
title: "常规主题"
@ -503,6 +507,9 @@ zh_CN:
education_new_topic:
title: "新用户培训:第一个主题"
description: "在新用户发表前两个主题时,自动在编辑器上方弹出的帮助信息。"
usage_tips:
title: "新用户指引"
description: "新用户指引和重要信息"
welcome_user:
title: "欢迎:新用户"
description: "当新用户注册后自动发送给他们的欢迎私信。"
@ -653,6 +660,7 @@ zh_CN:
sso_overrides_email: "用 SSO 信息中的外部邮件地址覆盖本地邮件地址(警告:因为对本地邮件的统一处理,这个邮件地址可能不同)"
sso_overrides_username: "用 SSO 信息中的外部用户名覆盖用户名(警告:因为对本地用户名的统一处理,用户名的长度或者要求可能不同)"
sso_overrides_name: "用 SSO 信息中的外部名字覆盖本地名字(警告:因为对本地名字的统一处理,这个名字可能不同)"
sso_overrides_avatar: "用单点登录信息中的外部站点头像覆盖用户头像。如果启用,强烈建议禁用 allow_uploaded_avatars"
enable_local_logins: "启用本地用户名和密码验证。(注意:邀请特性需要该选项)"
allow_new_registrations: "允许新用户注册。取消选择将阻止任何人创建一个新账户。"
enable_google_logins: "(废弃)启用 Google 验证。这是 OpenID 的验证方案,已被 Google 废弃。新论坛将无法使用它。使用 Google Oauth2 替代它。现存论坛必须在2015年4月20日前切换至 Google Oauth。"
@ -672,6 +680,7 @@ zh_CN:
allow_restore: "允许导入数据,这将能替换所有全站数据!除非您计划导入数据,否则请保持设置为 false"
maximum_backups: "磁盘保存的最大备份数量。老的备份将自动删除"
backup_daily: "每天自动创建站点备份。"
enable_s3_backups: "当完成备份后上传备份到 S3。重要确定在文件设置中的 S3 验证信息有效。"
s3_backup_bucket: "远端备份 bucket。警告确认它使私有的 bucket。"
active_user_rate_limit_secs: "更新'最后一次见到'数据的间隔,单位为秒"
previous_visit_timeout_hours: "系统判断一次访问之后多少小时后为'上一次'访问"
@ -691,7 +700,9 @@ zh_CN:
clean_up_uploads: "移除孤立的已上传资料。警告:您可能想要在启用这个设定前备份一下 /uploads 目录。"
clean_orphan_uploads_grace_period_hours: "删除孤立上传资料的宽限期(单位:小时)"
purge_deleted_uploads_grace_period_days: "移除已删除的孤立上传资料的宽限期(单位:小时)"
purge_inactive_users_grace_period_days: "移除不活跃用户的宽限期(单位:天)。"
enable_s3_uploads: "上传文件到 Amazon S3。"
s3_use_iam_profile: '使用 AWS EC2 IAM 角色来获得 key。注意启用这个会覆盖“S3 access key id”和“S3 secret access key” 设置。'
s3_upload_bucket: "上传文件保存于 Amazon S3 的 bucket 名字。警告:必须为小写,无句点(.)。"
s3_access_key_id: "将用于上传图片的 Amazon S3 access key。"
s3_secret_access_key: "将用于上传图片的 Amazon S3 secret key。"
@ -717,6 +728,8 @@ zh_CN:
leader_requires_posts_read_all_time: "用户升至领导信任等级(3)所需查看的最小帖子数量。"
leader_requires_max_flagged: "用户在最近 100 天内升至领导(3)信任等级0或更高所需的必须没有超过 x 个帖子被 x 个不同的用户标记数量x为数量。"
leader_promotion_min_duration: "领导可被降级前最小持续天数。"
leader_requires_likes_given: "在最近 100 天内升至领导(3)信任等级所需给出的赞。"
leader_requires_likes_received: "在最近 100 天内升至领导(3)信任等级所需收到的赞。"
leader_links_no_follow: "领导的链接是否使用 nofollow 属性。"
min_trust_to_create_topic: "创建主题所需的最低信任等级。"
min_trust_to_edit_wiki_post: "能编辑维基模式帖子的最小信任等级"
@ -742,6 +755,12 @@ zh_CN:
authorized_extensions: "允许上传文件的扩展名列表('*' 表示允许所有文件类型)"
max_similar_results: "当用户撰写新主题时,显示多少类似主题给用户。比较是根据标题和内容进行的。"
title_prettify: "防止常见标题里的错别字和错误,包括全部大写,第一个字符小写,多个''和'',结尾多余的'.'等等。"
topic_views_heat_low: "多少次浏览后,该视图将稍稍高亮。"
topic_views_heat_medium: "多少次浏览后,该视图将明显高亮。"
topic_views_heat_high: "多少次浏览后,该视图将强烈高亮。"
cold_age_days_low: "在讨论开始多少天后,最后活跃日期将轻微高亮。"
cold_age_days_medium: "在讨论开始多少天后,最后活跃日期将明显高亮。"
cold_age_days_high: "在讨论开始多少天后,最后活跃日期将强烈高亮。"
faq_url: "如果您的 FAQ 文档在外部,那么请在此填写其完整 URL 地址。"
tos_url: "如果您的服务条款文档在外部,那么请在此填写其完整 URL 地址。"
privacy_policy_url: "如果您的隐私政策文档在外部,那么请在此填写其完整 URL 地址。"
@ -831,7 +850,6 @@ zh_CN:
invited_to_private_message: "%{display_username} 邀请您进行私信:%{link}"
invitee_accepted: "%{display_username} 接受了您的邀请"
linked: "%{display_username} 在 %{link} 里链接了您"
granted_badge: "您被授予了 %{link}"
search:
within_post: "#%{post_number} %{username} %{excerpt}"
types:
@ -1286,6 +1304,10 @@ zh_CN:
see_more: "更多"
search_title: "搜索该网页"
search_google: "Google"
login_required:
welcome_message: |
#[欢迎来到 %{title}](#welcome)
您需要一个账号。请创建一个账号或者登录以继续。
terms_of_service:
title: "服务条款"
user_content_license: |
@ -1310,6 +1332,7 @@ zh_CN:
spam_hosts: "新用户试图创建链接到同一个域名的多个帖子。查看站点设置的 newuser_spam_host_threshold。"
email_log:
no_user: "不能找到用户 ID 为 %{user_id} 的用户"
suspended_not_pm: "用户被封禁,这不是私信"
seen_recently: "用户最近活跃"
post_not_found: "不能找到帖子 ID 为 %{post_id} 的帖子"
notification_already_read: "这封邮件中的通知已经被阅读了"

View File

@ -641,7 +641,6 @@ zh_TW:
invited_to_private_message: "%{display_username} 邀請你進行私人通訊:%{link}"
invitee_accepted: "%{display_username} 接受了你的邀請"
linked: "%{display_username} 在 %{link} 關連了你"
granted_badge: "你被授與了 %{link}"
search:
within_post: "#%{post_number} by %{username}: %{excerpt}"
types:

View File

@ -425,4 +425,5 @@ Discourse::Application.routes.draw do
# special case for top
root to: "list#top", constraints: HomePageConstraint.new("top"), :as => "top_lists"
# See config/routes_last.rb for more
end

10
config/routes_last.rb Normal file
View File

@ -0,0 +1,10 @@
# These routes must be loaded after all others.
# Routes are loaded in this order:
#
# 1. config/routes.rb
# 2. routes in engines
# 3. config/routes_last.rb
Discourse::Application.routes.draw do
get "*url", to: 'permalinks#show'
end

View File

@ -326,7 +326,7 @@ posting:
default: 15
enable_private_messages: true
ninja_edit_window: 300
post_edit_time_limit: 525600
post_edit_time_limit: 262800
edit_history_visible_to_public:
client: true
default: true
@ -385,13 +385,13 @@ email:
email_custom_headers: 'Auto-Submitted: auto-generated'
reply_by_email_enabled: false
reply_by_email_address: ''
pop3s_polling_enabled: false
pop3s_polling_insecure: false
pop3s_polling_period_mins: 5
pop3s_polling_host: ''
pop3s_polling_port: 995
pop3s_polling_username: ''
pop3s_polling_password: ''
pop3_polling_enabled: false
pop3_polling_ssl: true
pop3_polling_period_mins: 5
pop3_polling_host: ''
pop3_polling_port: 995
pop3_polling_username: ''
pop3_polling_password: ''
email_in:
default: false
client: true
@ -628,7 +628,7 @@ legal:
backups:
allow_restore:
client: true
client: false
default: false
maximum_backups:
client: true

View File

@ -0,0 +1,9 @@
class RenameSettingsPop3sToPop3 < ActiveRecord::Migration
def up
execute "UPDATE site_settings SET name = replace(name, 'pop3s', 'pop3') WHERE name ILIKE 'pop3%'"
end
def down
execute "UPDATE site_settings SET name = replace(name, 'pop3', 'pop3s') WHERE name ILIKE 'pop3%'"
end
end

View File

@ -0,0 +1,14 @@
class CreatePermalinks < ActiveRecord::Migration
def change
create_table :permalinks do |t|
t.string :url, null: false
t.integer :topic_id
t.integer :post_id
t.integer :category_id
t.timestamps
end
add_index :permalinks, :url
end
end

View File

@ -0,0 +1,10 @@
class MakeUrlColBiggerInPermalinks < ActiveRecord::Migration
def up
remove_index :permalinks, :url
change_column :permalinks, :url, :string, limit: 1000, null: false
add_index :permalinks, :url, unique: true
end
def down
end
end

View File

@ -161,7 +161,7 @@ Do you want...
- Multiple Discourse sites on the same server? [Configure multisite](https://meta.discourse.org/t/multisite-configuration-with-docker/14084).
- A Content Delivery Network to speed up worldwide access? [Configure a CDN](https://meta.discourse.org/t/enable-a-cdn-for-your-discourse/14857).
- A Content Delivery Network to speed up worldwide access? [Configure a CDN](https://meta.discourse.org/t/enable-a-cdn-for-your-discourse/14857). We recommend [Fastly](http://www.fastly.com/).
- Import old content from vBulletin, PHPbb, Vanilla, Drupal, BBPress, etc? [See our open source importers](https://github.com/discourse/discourse/tree/master/script/import_scripts)

View File

@ -56,6 +56,7 @@ module BackupRestore
{
is_operation_running: is_operation_running?,
can_rollback: can_rollback?,
allow_restore: Rails.env.development? || SiteSetting.allow_restore
}
end

120
lib/email/html_cleaner.rb Normal file
View File

@ -0,0 +1,120 @@
module Email
# HtmlCleaner cleans up the extremely dirty HTML that many email clients
# generate by stripping out any excess divs or spans, removing styling in
# the process (which also makes the html more suitable to be parsed as
# Markdown).
class HtmlCleaner
# Elements to hoist all children out of
HTML_HOIST_ELEMENTS = %w(div span font table tbody th tr td)
# Node types to always delete
HTML_DELETE_ELEMENT_TYPES = [Nokogiri::XML::Node::DTD_NODE,
Nokogiri::XML::Node::COMMENT_NODE,
]
# Private variables:
# @doc - nokogiri document
# @out - same as @doc, but only if trimming has occured
def initialize(html)
if String === html
@doc = Nokogiri::HTML(html)
else
@doc = html
end
end
class << self
# Email::HtmlCleaner.trim(inp, opts={})
#
# Arguments:
# inp - Either a HTML string or a Nokogiri document.
# Options:
# :return => :doc, :string
# Specify the desired return type.
# Defaults to the type of the input.
# A value of :string is equivalent to calling get_document_text()
# on the returned document.
def trim(inp, opts={})
cleaner = HtmlCleaner.new(inp)
opts[:return] ||= ((String === inp) ? :string : :doc)
if opts[:return] == :string
cleaner.output_html
else
cleaner.output_document
end
end
# Email::HtmlCleaner.get_document_text(doc)
#
# Get the body portion of the document, including html, as a string.
def get_document_text(doc)
body = doc.xpath('//body')
if body
body.inner_html
else
doc.inner_html
end
end
end
def output_document
@out ||= begin
doc = @doc
trim_process_node doc
add_newlines doc
doc
end
end
def output_html
HtmlCleaner.get_document_text(output_document)
end
private
def add_newlines(doc)
doc.xpath('//br').each do |br|
br.replace(Nokogiri::XML::Text.new("\n", doc))
end
end
def trim_process_node(node)
if should_hoist?(node)
hoisted = trim_hoist_element node
hoisted.each { |child| trim_process_node child }
elsif should_delete?(node)
node.remove
else
if children = node.children
children.each { |child| trim_process_node child }
end
end
node
end
def trim_hoist_element(element)
hoisted = []
element.children.each do |child|
element.before(child)
hoisted << child
end
element.remove
hoisted
end
def should_hoist?(node)
return false unless node.element?
HTML_HOIST_ELEMENTS.include? node.name
end
def should_delete?(node)
return true if HTML_DELETE_ELEMENT_TYPES.include? node.type
return true if node.element? && node.name == 'head'
return true if node.text? && node.text.strip.blank?
false
end
end
end

View File

@ -1,3 +1,4 @@
require 'email/html_cleaner'
#
# Handles an incoming message
#
@ -26,20 +27,12 @@ module Email
def process
raise EmptyEmailError if @raw.blank?
@message = Mail.new(@raw)
message = Mail.new(@raw)
# First remove the known discourse stuff.
parse_body
raise EmptyEmailError if @body.blank?
# Then run the github EmailReplyParser on it in case we didn't catch it
@body = EmailReplyParser.read(@body).visible_text.force_encoding('UTF-8')
discourse_email_parser
raise EmailUnparsableError if @body.blank?
body = parse_body message
dest_info = {type: :invalid, obj: nil}
@message.to.each do |to_address|
message.to.each do |to_address|
if dest_info[:type] == :invalid
dest_info = check_address to_address
end
@ -47,6 +40,10 @@ module Email
raise BadDestinationAddress if dest_info[:type] == :invalid
# TODO get to a state where we can remove this
@message = message
@body = body
if dest_info[:type] == :category
raise BadDestinationAddress unless SiteSetting.email_in
category = dest_info[:obj]
@ -74,6 +71,8 @@ module Email
create_reply
end
rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError => e
raise EmailUnparsableError.new(e)
end
def check_address(address)
@ -94,57 +93,64 @@ module Email
{type: :invalid, obj: nil}
end
private
def parse_body(message)
body = select_body message
encoding = body.encoding
raise EmptyEmailError if body.strip.blank?
def parse_body
body = discourse_email_trimmer body
raise EmptyEmailError if body.strip.blank?
body = EmailReplyParser.parse_reply body
raise EmptyEmailError if body.strip.blank?
body.force_encoding(encoding).encode("UTF-8")
end
def select_body(message)
html = nil
# If the message is multipart, find the best type for our purposes
if @message.multipart?
if p = @message.text_part
@body = p.charset ? p.body.decoded.force_encoding(p.charset).encode("UTF-8").to_s : p.body.to_s
return @body
elsif p = @message.html_part
html = p.charset ? p.body.decoded.force_encoding(p.charset).encode("UTF-8").to_s : p.body.to_s
# If the message is multipart, return that part (favor html)
if message.multipart?
html = fix_charset message.html_part
text = fix_charset message.text_part
# TODO picking text if available may be better
if text && !html
return text
end
elsif message.content_type =~ /text\/html/
html = fix_charset message
end
if @message.content_type =~ /text\/html/
if defined? @message.charset
html = @message.body.decoded.force_encoding(@message.charset).encode("UTF-8").to_s
else
html = @message.body.to_s
end
if html
body = HtmlCleaner.new(html).output_html
else
body = fix_charset message
end
if html.present?
@body = scrub_html(html)
return @body
end
@body = @message.charset ? @message.body.decoded.force_encoding(@message.charset).encode("UTF-8").to_s.strip : @message.body.to_s
# Certain trigger phrases that means we didn't parse correctly
@body = nil if @body =~ /Content\-Type\:/ ||
@body =~ /multipart\/alternative/ ||
@body =~ /text\/plain/
if body =~ /Content\-Type\:/ || body =~ /multipart\/alternative/ || body =~ /text\/plain/
raise EmptyEmailError
end
@body
body
end
def scrub_html(html)
# If we have an HTML message, strip the markup
doc = Nokogiri::HTML(html)
# Force encoding to UTF-8 on a Mail::Message or Mail::Part
def fix_charset(object)
return nil if object.nil?
# Blackberry is annoying in that it only provides HTML. We can easily extract it though
content = doc.at("#BB10_response_div")
return content.text if content.present?
doc.xpath("//text()").text
if object.charset
object.body.decoded.force_encoding(object.charset).encode("UTF-8").to_s
else
object.body.to_s
end
end
def discourse_email_parser
lines = @body.scrub.lines.to_a
REPLYING_HEADER_LABELS = ['From', 'Sent', 'To', 'Subject', 'Reply To']
REPLYING_HEADER_REGEX = Regexp.union(REPLYING_HEADER_LABELS.map { |lbl| "#{lbl}:" })
def discourse_email_trimmer(body)
lines = body.scrub.lines.to_a
range_end = 0
lines.each_with_index do |l, idx|
@ -155,11 +161,15 @@ module Email
# Let's try it and see how well it works.
(l =~ /\d{4}/ && l =~ /\d:\d\d/ && l =~ /\:$/)
# Headers on subsequent lines
break if (0..2).all? { |off| lines[idx+off] =~ REPLYING_HEADER_REGEX }
# Headers on the same line
break if REPLYING_HEADER_LABELS.count { |lbl| l.include? lbl } >= 3
range_end = idx
end
@body = lines[0..range_end].join
@body.strip!
lines[0..range_end].join.strip
end
def wrap_body_in_quote(user_email)
@ -168,37 +178,37 @@ module Email
[/quote]"
end
private
def create_reply
create_post_with_attachments(email_log.user, @body, @email_log.topic_id, @email_log.post.post_number)
create_post_with_attachments(@email_log.user,
raw: @body,
topic_id: @email_log.topic_id,
reply_to_post_number: @email_log.post.post_number)
end
def create_new_topic
topic = TopicCreator.new(
@user,
Guardian.new(@user),
category: @category_id,
title: @message.subject,
).create
post = create_post_with_attachments(@user, @body, topic.id)
post = create_post_with_attachments(@user,
raw: @body,
title: @message.subject,
category: @category_id)
EmailLog.create(
email_type: "topic_via_incoming_email",
to_address: @message.to.first,
topic_id: topic.id,
to_address: @message.from.first, # pick from address because we want the user's email
topic_id: post.topic.id,
user_id: @user.id,
)
post
end
def create_post_with_attachments(user, raw, topic_id, reply_to_post_number=nil)
def create_post_with_attachments(user, post_opts={})
options = {
raw: raw,
topic_id: topic_id,
cooking_options: { traditional_markdown_linebreaks: true },
}
options[:reply_to_post_number] = reply_to_post_number if reply_to_post_number
}.merge(post_opts)
raw = options[:raw]
# deal with attachments
@message.attachments.each do |attachment|
@ -215,9 +225,10 @@ module Email
ensure
tmp.close!
end
end
options[:raw] = raw
create_post(user, options)
end
@ -232,9 +243,11 @@ module Email
def create_post(user, options)
creator = PostCreator.new(user, options)
post = creator.create
if creator.errors.present?
raise InvalidPost, creator.errors.full_messages.join("\n")
end
post
end

View File

@ -58,6 +58,7 @@ module Email
style('.user-avatar', 'vertical-align:top;width:55px;')
style('.user-avatar img', nil, width: '45', height: '45')
style('hr', 'background-color: #ddd; height: 1px; border: 1px;')
style('.rtl', 'direction: rtl;')
# we can do this but it does not look right
# style('#main', 'font-family:"Helvetica Neue", Helvetica, Arial, sans-serif')
style('td.body', 'padding-top:5px;', colspan: "2")

View File

@ -270,14 +270,7 @@ class PostCreator
return if @opts[:import_mode]
return unless @post.post_number > 1
MessageBus.publish("/topic/#{@post.topic_id}",{
id: @post.id,
created_at: @post.created_at,
user: BasicUserSerializer.new(@post.user).as_json(root: false),
post_number: @post.post_number
},
group_ids: @topic.secure_group_ids
)
@post.publish_change_to_clients! :created
end
def extract_links
@ -288,8 +281,8 @@ class PostCreator
def track_topic
return if @opts[:auto_track] == false
TopicUser.change(@post.user.id,
@post.topic.id,
TopicUser.change(@post.user_id,
@topic.id,
posted: true,
last_read_post_number: @post.post_number,
seen_post_count: @post.post_number)

View File

@ -51,7 +51,7 @@ class PostDestroyer
def staff_recovered
@post.recover!
publish("recovered")
@post.publish_change_to_clients! :recovered
end
# When a post is properly deleted. Well, it's still soft deleted, but it will no longer
@ -75,21 +75,8 @@ class PostDestroyer
update_associated_category_latest_topic
update_user_counts
end
publish("deleted")
end
def publish(message)
# edge case, topic is already destroyed
return unless @post.topic
MessageBus.publish("/topic/#{@post.topic_id}",{
id: @post.id,
post_number: @post.post_number,
updated_at: @post.updated_at,
type: message
},
group_ids: @post.topic.secure_group_ids
)
@post.publish_change_to_clients! :deleted if @post.topic
end
# When a user 'deletes' their own post. We just change the text.
@ -100,6 +87,9 @@ class PostDestroyer
@post.update_flagged_posts_count
@post.topic_links.each(&:destroy)
end
# covered by PostRevisor
# @post.publish_change_to_clients! :revised
end
def user_recovered
@ -109,6 +99,9 @@ class PostDestroyer
@post.revise(@user, @post.revisions.last.modifications["raw"][0], force_new_version: true)
@post.update_flagged_posts_count
end
# covered by PostRevisor
# @post.publish_change_to_clients! :revised
end

View File

@ -21,6 +21,7 @@ class PostRevisor
@opts = opts
@new_raw = TextCleaner.normalize_whitespaces(new_raw).strip
# TODO this is not in a transaction - dangerous!
return false unless should_revise?
@post.acting_user = @editor
revise_post
@ -30,7 +31,7 @@ class PostRevisor
update_topic_word_counts
@post.advance_draft_sequence
PostAlerter.new.after_save_post(@post)
publish_revision
@post.publish_change_to_clients! :revised
BadgeGranter.queue_badge_grant(Badge::Trigger::PostRevision, post: @post)
true
@ -38,17 +39,6 @@ class PostRevisor
private
def publish_revision
MessageBus.publish("/topic/#{@post.topic_id}",{
id: @post.id,
post_number: @post.post_number,
updated_at: @post.updated_at,
type: "revised"
},
group_ids: @post.topic.secure_group_ids
)
end
def should_revise?
@post.raw != @new_raw || @opts[:changed_owner]
end

View File

@ -111,7 +111,8 @@ class Search
return nil if @term.blank? || @term.length < (@opts[:min_search_term_length] || SiteSetting.min_search_term_length)
# If the term is a number or url to a topic, just include that topic
if @results.type_filter == 'topic'
if @opts[:search_for_id] && @results.type_filter == 'topic'
return single_topic(@term.to_i).as_json if @term =~ /^\d+$/
begin
route = Rails.application.routes.recognize_path(@term)
return single_topic(route[:topic_id]).as_json if route[:topic_id].present?
@ -279,13 +280,16 @@ class Search
def aggregate_search
cols = ['topics.id', 'topics.title', 'topics.slug']
topics = posts_query(@limit, aggregate_search: true).group(*cols).pluck(*cols)
topics = posts_query(@limit, aggregate_search: true)
.group(*cols)
.pluck('min(posts.post_number)',*cols)
topics.each do |t|
@results.add_result(SearchResult.new(type: :topic,
topic_id: t[0],
id: t[0],
title: t[1],
url: "/t/#{t[2]}/#{t[0]}"))
topic_id: t[1],
id: t[1],
title: t[2],
url: "/t/#{t[3]}/#{t[1]}/#{t[0]}"))
end
end

View File

@ -1,6 +1,6 @@
# we need to run seed_fu every time we run rake db:migrate
task 'db:migrate' => 'environment' do
I18n.locale = SiteSetting.default_locale rescue :en
I18n.locale = (SiteSetting.default_locale || :en) rescue :en
SeedFu.seed
if SiteSetting.vacuum_db_days > 0 &&

View File

@ -350,8 +350,26 @@ class ImportScripts::VBulletin < ImportScripts::Base
raw = raw.gsub(/(\\r)?\\n/, "\n")
.gsub("\\t", "\t")
# remove attachments
raw = raw.gsub(/\[attach\]\d+\[\/attach\]/i, "")
# replace all chevrons with HTML entities
# NOTE: must be before any of the "quote" processing
raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub("<", "\u2603") + "`" }
.gsub("<", "&lt;")
.gsub("\u2603", "<")
raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub(">", "\u2603") + "`" }
.gsub(">", "&gt;")
.gsub("\u2603", ">")
# [URL=...]...[/URL]
raw = raw.gsub(/\[url="?(.+?)"?\](.+)\[\/url\]/i) { "[#{$2}](#{$1})" }
# [URL]...[/URL]
raw = raw.gsub(/\[url\](.+?)\[\/url\]/i) { $1.to_s }
# [MP3]...[/MP3]
raw = raw.gsub(/\[\/?url\]/i, "")
.gsub(/\[\/?mp3\]/i, "")
# [MENTION]<username>[/MENTION]
raw = raw.gsub(/\[mention\](.+?)\[\/mention\]/i) do
@ -363,7 +381,7 @@ class ImportScripts::VBulletin < ImportScripts::Base
end
# [MENTION=<user_id>]<username>[/MENTION]
raw = raw.gsub(/\[mention=(\d+)\](.+?)\[\/mention\]/i) do
raw = raw.gsub(/\[mention="?(\d+)"?\](.+?)\[\/mention\]/i) do
user_id, old_username = $1, $2
if user = @users.select { |u| u[:userid] == user_id }.first
old_username = @old_username_to_new_usernames[user[:username]] || user[:username]
@ -384,37 +402,29 @@ class ImportScripts::VBulletin < ImportScripts::Base
end
# [HTML]...[/HTML]
raw = raw.gsub(/\[html\]/i, "\n```html\n")
.gsub(/\[\/html\]/i, "\n```\n")
# [PHP]...[/PHP]
["html", "php"].each do |language|
raw = raw.gsub(/\[#{language}\](.+?)\[\/#{language}\]/im) { "\n```#{language}\n#{$1}\n```\n" }
end
raw = raw.gsub(/\[php\]/i, "\n```php\n")
.gsub(/\[\/php\]/i, "\n```\n")
# [HIGHLIGHT="..."]
raw = raw.gsub(/\[highlight="?(\w+)"?\]/i) { "\n```#{$1.downcase}\n" }
# [CODE]...[/CODE]
raw = raw.gsub(/\[code\](.+?)\[\/code\]/im) { "\n```\n#{$1}\n```\n" }
# [HIGHLIGHT]...[/HIGHLIGHT]
raw = raw.gsub(/\[\/?code\]/i, "\n```\n")
.gsub(/\[\/?highlight\]/i, "\n```\n")
# [HIGHLIGHT="..."]...[/HIGHLIGHT]
raw = raw.gsub(/\[highlight(?:[^\]]*)\](.+)\[\/highlight\]/im) { "\n```\n#{$1}\n```\n" }
# [SAMP]...[SAMP]
raw = raw.gsub(/\[samp\](.+?)\[\/samp\]/i) { "`#{$1}`" }
# [SAMP]...[/SAMP]
raw = raw.gsub(/\[\/?samp\]/i, "`")
# [YOUTUBE]<id>[/YOUTUBE]
raw = raw.gsub(/\[youtube\](.+?)\[\/youtube\]/i) { "\n//youtu.be/#{$1}\n" }
# [VIDEO=youtube;<id>]...[/VIDEO]
raw = raw.gsub(/\[video=youtube;([^\]]+)\].*\[\/video\]/i) { "\n//youtu.be/#{$1}\n" }
# [MP3]<url>[/MP3]
raw = raw.gsub(/\[MP3\](.+?)\[\/MP3\]/i) { "\n#{$1}\n" }
# replace all chevrons with HTML entities
raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub("<", "\u2603") + "`" }
.gsub("<", "&lt;")
.gsub("\u2603", "<")
raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub(">", "\u2603") + "`" }
.gsub(">", "&gt;")
.gsub("\u2603", ">")
raw = raw.gsub(/\[video=youtube;([^\]]+)\].*?\[\/video\]/i) { "\n//youtu.be/#{$1}\n" }
raw
end

View File

@ -8,122 +8,233 @@ describe Email::Receiver do
before do
SiteSetting.reply_by_email_address = "reply+%{reply_key}@appmail.adventuretime.ooo"
SiteSetting.email_in = false
SiteSetting.title = "Discourse"
end
describe 'invalid emails' do
describe 'parse_body' do
def test_parse_body(mail_string)
Email::Receiver.new(nil).parse_body(Mail::Message.new mail_string)
end
it "raises EmptyEmailError if the message is blank" do
expect { Email::Receiver.new("").process }.to raise_error(Email::Receiver::EmptyEmailError)
expect { test_parse_body("") }.to raise_error(Email::Receiver::EmptyEmailError)
end
it "raises EmptyEmailError if the message is not an email" do
expect { Email::Receiver.new("asdf" * 30).process}.to raise_error(Email::Receiver::EmptyEmailError)
expect { test_parse_body("asdf" * 30) }.to raise_error(Email::Receiver::EmptyEmailError)
end
it "raises EmailUnparsableError if there is no reply content" do
expect { Email::Receiver.new(fixture_file("emails/no_content_reply.eml")).process}.to raise_error(Email::Receiver::EmailUnparsableError)
it "raises EmptyEmailError if there is no reply content" do
expect { test_parse_body(fixture_file("emails/no_content_reply.eml")) }.to raise_error(Email::Receiver::EmptyEmailError)
end
end
describe "with multipart" do
let(:reply_below) { fixture_file("emails/multipart.eml") }
let(:receiver) { Email::Receiver.new(reply_below) }
it "processes correctly" do
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq(
"So presumably all the quoted garbage and my (proper) signature will get
stripped from my reply?")
pending "raises EmailUnparsableError if the headers are corrupted" do
expect { ; }.to raise_error(Email::Receiver::EmailUnparsableError)
end
end
describe "html only" do
let(:reply_below) { fixture_file("emails/html_only.eml") }
let(:receiver) { Email::Receiver.new(reply_below) }
it "processes correctly" do
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq("The EC2 instance - I've seen that there tends to be odd and " +
"unrecommended settings on the Bitnami installs that I've checked out.")
it "can parse the html section" do
test_parse_body(fixture_file("emails/html_only.eml")).should == "The EC2 instance - I've seen that there tends to be odd and " +
"unrecommended settings on the Bitnami installs that I've checked out."
end
end
describe "it supports a dutch reply" do
let(:dutch) { fixture_file("emails/dutch.eml") }
let(:receiver) { Email::Receiver.new(dutch) }
it "processes correctly" do
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq("Dit is een antwoord in het Nederlands.")
it "supports a Dutch reply" do
test_parse_body(fixture_file("emails/dutch.eml")).should == "Dit is een antwoord in het Nederlands."
end
end
describe "It supports a non english reply" do
let(:hebrew) { fixture_file("emails/hebrew.eml") }
let(:receiver) { Email::Receiver.new(hebrew) }
it "processes correctly" do
it "supports a Hebrew reply" do
I18n.expects(:t).with('user_notifications.previous_discussion').returns('כלטוב')
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq("שלום")
# The force_encoding call is only needed for the test - it is passed on fine to the cooked post
test_parse_body(fixture_file("emails/hebrew.eml")).should == "שלום"
end
end
describe "It supports a non UTF-8 reply" do
let(:big5) { fixture_file("emails/big5.eml") }
let(:receiver) { Email::Receiver.new(big5) }
it "processes correctly" do
it "supports a BIG5-encoded reply" do
I18n.expects(:t).with('user_notifications.previous_discussion').returns('媽!我上電視了!')
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq("媽!我上電視了!")
# The force_encoding call is only needed for the test - it is passed on fine to the cooked post
test_parse_body(fixture_file("emails/big5.eml")).should == "媽!我上電視了!"
end
end
describe "via" do
let(:wrote) { fixture_file("emails/via_line.eml") }
let(:receiver) { Email::Receiver.new(wrote) }
it "removes 'via' lines if they match the site title" do
SiteSetting.title = "Discourse"
it "removes via lines if we know them" do
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq("Hello this email has content!")
test_parse_body(fixture_file("emails/via_line.eml")).should == "Hello this email has content!"
end
end
describe "if wrote is on a second line" do
let(:wrote) { fixture_file("emails/multiline_wrote.eml") }
let(:receiver) { Email::Receiver.new(wrote) }
it "processes correctly" do
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq("Thanks!")
it "removes the 'Previous Discussion' marker" do
test_parse_body(fixture_file("emails/previous.eml")).should == "This will not include the previous discussion that is present in this email."
end
end
describe "remove previous discussion" do
let(:previous) { fixture_file("emails/previous.eml") }
let(:receiver) { Email::Receiver.new(previous) }
it "processes correctly" do
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq("This will not include the previous discussion that is present in this email.")
end
end
describe "multiple paragraphs" do
let(:paragraphs) { fixture_file("emails/paragraphs.eml") }
let(:receiver) { Email::Receiver.new(paragraphs) }
it "processes correctly" do
expect { receiver.process}.to raise_error(Email::Receiver::EmailLogNotFound)
expect(receiver.body).to eq(
it "handles multiple paragraphs" do
test_parse_body(fixture_file("emails/paragraphs.eml")).
should == (
"Is there any reason the *old* candy can't be be kept in silos while the new candy
is imported into *new* silos?
The thing about candy is it stays delicious for a long time -- we can just keep
it there without worrying about it too much, imo.
Thanks for listening.")
Thanks for listening."
)
end
it "converts back to UTF-8 at the end" do
result = test_parse_body(fixture_file("emails/big5.eml"))
result.encoding.should == Encoding::UTF_8
# should not throw
TextCleaner.normalize_whitespaces(
test_parse_body(fixture_file("emails/big5.eml"))
)
end
end
describe "posting replies" do
let(:reply_key) { raise "Override this in a lower describe block" }
let(:email_raw) { raise "Override this in a lower describe block" }
# ----
let(:receiver) { Email::Receiver.new(email_raw) }
let(:post) { create_post }
let(:topic) { post.topic }
let(:posting_user) { post.user }
let(:replying_user_email) { 'jake@adventuretime.ooo' }
let(:replying_user) { Fabricate(:user, email: replying_user_email, trust_level: 2)}
let(:email_log) { EmailLog.new(reply_key: reply_key,
post: post,
post_id: post.id,
topic_id: post.topic_id,
email_type: 'user_posted',
user: replying_user,
user_id: replying_user.id,
to_address: replying_user_email
) }
before do
email_log.save
end
# === Success Posting ===
describe "valid_reply.eml" do
let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' }
let!(:email_raw) { fixture_file("emails/valid_reply.eml") }
it "creates a post with the correct content" do
start_count = topic.posts.count
receiver.process
topic.posts.count.should == (start_count + 1)
topic.posts.last.cooked.strip.should == fixture_file("emails/valid_reply.cooked").strip
end
end
describe "paragraphs.eml" do
let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' }
let!(:email_raw) { fixture_file("emails/paragraphs.eml") }
it "cooks multiple paragraphs with traditional Markdown linebreaks" do
start_count = topic.posts.count
receiver.process
topic.posts.count.should == (start_count + 1)
topic.posts.last.cooked.strip.should == fixture_file("emails/paragraphs.cooked").strip
topic.posts.last.cooked.should_not match /<br/
end
end
describe "attachment.eml" do
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
let!(:email_raw) {
fixture_file("emails/attachment.eml")
.gsub("TO", "reply+#{reply_key}@appmail.adventuretime.ooo")
.gsub("FROM", replying_user_email)
}
let(:upload_sha) { '04df605be528d03876685c52166d4b063aabb78a' }
it "creates a post with an attachment" do
start_count = topic.posts.count
Upload.find_by(sha1: upload_sha).try :destroy
receiver.process
topic.posts.count.should == (start_count + 1)
topic.posts.last.cooked.should match /<img src=['"](\/uploads\/default\/\d+\/\w{16}\.png)['"] width=['"]289['"] height=['"]126['"]>/
Upload.find_by(sha1: upload_sha).should_not be_nil
end
end
# === Failure Conditions ===
describe "too_short.eml" do
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
let!(:email_raw) {
fixture_file("emails/too_short.eml")
.gsub("TO", "reply+#{reply_key}@appmail.adventuretime.ooo")
.gsub("FROM", replying_user_email)
.gsub("SUBJECT", "re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'")
}
it "raises an InvalidPost error" do
SiteSetting.min_post_length = 5
expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost)
end
end
describe "too_many_mentions.eml" do
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
let!(:email_raw) { fixture_file("emails/too_many_mentions.eml") }
it "raises an InvalidPost error" do
SiteSetting.max_mentions_per_post = 10
(1..11).each do |i|
Fabricate(:user, username: "user#{i}").save
end
expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost)
end
end
end
describe "posting a new topic" do
let(:category_destination) { raise "Override this in a lower describe block" }
let(:email_raw) { raise "Override this in a lower describe block" }
let(:allow_strangers) { false }
# ----
let(:receiver) { Email::Receiver.new(email_raw) }
let(:user_email) { 'jake@adventuretime.ooo' }
let(:user) { Fabricate(:user, email: user_email, trust_level: 2)}
let(:category) { Fabricate(:category, email_in: category_destination, email_in_allow_strangers: allow_strangers) }
before do
SiteSetting.email_in = true
user.save
category.save
end
describe "too_short.eml" do
let!(:category_destination) { 'incoming+amazing@appmail.adventuretime.ooo' }
let(:email_raw) {
fixture_file("emails/too_short.eml")
.gsub("TO", category_destination)
.gsub("FROM", user_email)
.gsub("SUBJECT", "A long subject that passes the checks")
}
it "does not create a topic if the post fails" do
before_topic_count = Topic.count
expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost)
Topic.count.should == before_topic_count
end
end
end
def fill_email(mail, from, to, body = nil, subject = nil)
@ -181,12 +292,6 @@ greatest show ever created. Everyone should watch it.
expect(receiver.body).to eq(reply_body)
expect(receiver.email_log).to eq(email_log)
attachment_email = fixture_file("emails/attachment.eml")
attachment_email = fill_email(attachment_email, "test@test.com", to)
r = Email::Receiver.new(attachment_email)
expect { r.process }.to_not raise_error
expect(r.body).to match(/here is an image attachment\n<img src='\/uploads\/default\/\d+\/\w{16}\.png' width='289' height='126'>\n/)
end
end

Some files were not shown because too many files have changed in this diff Show More